You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
143 lines
6.4 KiB
Matlab
143 lines
6.4 KiB
Matlab
function [eyeamp,headcontrib,headamp,bodycontrib,bodyamp,eyeposn,neckposn,torsoposn,targetposn,y]=control_body_head_eye(vistarget,eyepaninit,neckpaninit,torsopaninit,W,V,interconnects,y,display)
|
|
%Performs coordinated body, head and eye movements to foveate a visual target.
|
|
%This is achieved in 5 steps:
|
|
% 1) calculates W given R+E+N+T.
|
|
% 2) calculates E given W calculated in (1) and R centred at zero.
|
|
% 3) calculates N given W calculated in (1) E calculated in (2) and R centred at zero.
|
|
% 4) calculates T given W calculated in (1) E calculated in (2) N calculated in (3) and R centred at zero.
|
|
% 5) estimates R given W calculated in (1) and E calculated in (2) and N calculated in (3) and T calculated in (4)
|
|
% (the "RF remapping step - this does not contribute to the performace of the movement)
|
|
%These steps may be repeated to perform corrective saccades
|
|
nSteps=5;
|
|
numSaccades=3;
|
|
inertiaNeck=0.05;
|
|
inertiaTorso=0.05;
|
|
|
|
if nargin<1 || isempty(vistarget)
|
|
vistarget=-32.6;
|
|
end
|
|
if nargin<2 || isempty(eyepaninit)
|
|
eyepaninit=-4.4;
|
|
end
|
|
if nargin<3 || isempty(neckpaninit)
|
|
neckpaninit=8.1;
|
|
end
|
|
if nargin<4 || isempty(torsopaninit)
|
|
torsopaninit=5;
|
|
end
|
|
if nargin<5 || isempty(W)
|
|
%define network for performing sensory-sensory and sensory-motor mappings
|
|
[W,V,interconnects]=define_network(3);
|
|
end
|
|
if nargin<8
|
|
y=[];
|
|
end
|
|
if nargin<9 || isempty(display)
|
|
display=1;
|
|
end
|
|
figoff=0;
|
|
|
|
%define inputs to perform task
|
|
[angles,ranges,partitions,values,stdx,stdw,partitionLabels]=simulate_agent();
|
|
nullR=zeros(1,length(values{1,1}));
|
|
nullE=zeros(1,length(values{1,2}));
|
|
nullH=zeros(1,length(values{1,3}));
|
|
nullN=zeros(1,length(values{2,2}));
|
|
nullB=zeros(1,length(values{2,3}));
|
|
nullT=zeros(1,length(values{3,2}));
|
|
nullW=zeros(1,length(values{3,3}));
|
|
eyeposn(1)=decode(code(eyepaninit,values{1,2},stdx),values{1,2}); %eyepaninit;
|
|
neckposn(1)=decode(code(neckpaninit,values{2,2},stdx),values{2,2}); %neckpaninit;
|
|
torsoposn(1)=decode(code(torsopaninit,values{3,2},stdx),values{3,2}); %torsopaninit;
|
|
targetposn(1)=vistarget;
|
|
trueworldtarget=simulate_agent_retina_to_world(vistarget,eyepaninit,neckpaninit,torsopaninit);
|
|
|
|
%present test cases to network and record results
|
|
for saccade=1:numSaccades
|
|
%step 1) calculate the world-centred representation of the visual target
|
|
%input eye position, neck position, torso position and retinal input (R+E+N+T->W)
|
|
x{1}=[code(vistarget,values{1,1},stdx),code(eyeposn(saccade),values{1,2},stdx),nullH]';
|
|
x{2}=[nullH,code(neckposn(saccade),values{2,2},stdx),nullB]';
|
|
x{3}=[nullB,code(torsoposn(saccade),values{3,2},stdx),nullW]';
|
|
[y,e,r]=dim_activation_hierarchical(W,x,V,interconnects,y);
|
|
if display,
|
|
figured(figoff+(saccade-1)*nSteps+1),clf,plot_network(x,r,y,partitions,values,partitionLabels);
|
|
if saccade==1, print -dpdf control_body_head_eye1.pdf; end
|
|
end
|
|
worldtarget=decode(r{3}(partitions{3,3})',values{3,3});
|
|
worldrep=r{3}(partitions{3,3})';
|
|
|
|
%perform memory-guided saccade when target is beyond the field of view
|
|
if vistarget>80
|
|
worldtarget=50;
|
|
elseif vistarget<-80
|
|
worldtarget=-50;
|
|
end
|
|
|
|
%step 2) calculate the eye position required to foveate the target
|
|
%input the world-centred position, (weakened current neck and torso positions)
|
|
%and foveal retinal input (R+W+(N)+(T)->E)
|
|
x{1}=[code(0,values{1,1},stdx),nullE,nullH]';
|
|
x{2}=[nullH,code(neckposn(saccade),values{2,2},stdx).*inertiaNeck,nullB]';
|
|
x{3}=[nullB,code(torsoposn(saccade),values{3,2},stdx).*inertiaTorso,code(worldtarget,values{3,3},stdx)]';
|
|
[y,e,r]=dim_activation_hierarchical(W,x,V,interconnects,[]);%<-reset network activity
|
|
if display,
|
|
figured(figoff+(saccade-1)*nSteps+2),clf,plot_network(x,r,y,partitions,values,partitionLabels);
|
|
if saccade==1, print -dpdf control_body_head_eye2.pdf; end
|
|
end
|
|
eyetarget=decode(r{1}(partitions{1,2})',values{1,2});
|
|
|
|
%step 3) calculate the neck position required to foveate the target
|
|
%input world-centred position, new eye position (weakened current torso
|
|
%position) and foveal retinal input (R+W+E+(T)->N)
|
|
x{1}=[code(0,values{1,1},stdx),code(eyetarget,values{1,2},stdx),nullH]';
|
|
x{2}=[nullH,nullN,nullB]';
|
|
x{3}=[nullB,code(torsoposn(saccade),values{3,2},stdx).*inertiaTorso,code(worldtarget,values{3,3},stdx)]';
|
|
[y,e,r]=dim_activation_hierarchical(W,x,V,interconnects,y);
|
|
if display,
|
|
figured(figoff+(saccade-1)*nSteps+3),clf,plot_network(x,r,y,partitions,values,partitionLabels);
|
|
if saccade==1, print -dpdf control_body_head_eye3.pdf; end
|
|
end
|
|
necktarget=decode(r{2}(partitions{2,2})',values{2,2});
|
|
|
|
%step 4) calculate the torso position required to foveate the target
|
|
%input world-centred position, new eye and neck positions and foveal retinal
|
|
%input (R+W+E+N->T)
|
|
x{1}=[code(0,values{1,1},stdx),code(eyetarget,values{1,2},stdx),nullH]';
|
|
x{2}=[nullH,code(necktarget,values{2,2},stdx),nullB]';
|
|
x{3}=[nullB,nullT,code(worldtarget,values{3,3},stdx)]';
|
|
[y,e,r]=dim_activation_hierarchical(W,x,V,interconnects,y);
|
|
if display,
|
|
figured(figoff+(saccade-1)*nSteps+4),clf,plot_network(x,r,y,partitions,values,partitionLabels);
|
|
if saccade==1, print -dpdf control_body_head_eye4.pdf; end
|
|
end
|
|
torsotarget=decode(r{3}(partitions{3,2})',values{3,2});
|
|
|
|
%step 5) remapping, calculate the visual input expected after upcoming saccade
|
|
%input world-centred representation and planned eye, neck and torso positions (E+N+T+W->R)
|
|
x{1}=[nullR,code(eyetarget,values{1,2},stdx),nullH]';
|
|
x{2}=[nullH,code(necktarget,values{2,2},stdx),nullB]';
|
|
x{3}=[nullB,code(torsotarget,values{3,2},stdx),worldrep]';
|
|
[y,e,r]=dim_activation_hierarchical(W,x,V,interconnects,y);
|
|
if display,
|
|
figured(figoff+(saccade-1)*nSteps+5),clf,plot_network(x,r,y,partitions,values,partitionLabels);
|
|
if saccade==1, print -dpdf control_body_head_eye5.pdf; end
|
|
end
|
|
|
|
%perform movement (update visual input after saccade)
|
|
vistarget=simulate_agent_world_to_retina(trueworldtarget,eyetarget,necktarget,torsotarget);
|
|
|
|
%record movements made over time
|
|
eyeposn(saccade+1)=eyetarget;
|
|
neckposn(saccade+1)=necktarget;
|
|
torsoposn(saccade+1)=torsotarget;
|
|
targetposn(saccade+1)=vistarget;
|
|
end
|
|
|
|
[eyeamp,ind]=max(abs(eyeposn-eyeposn(1))); %see McCluskey Cullen p.2979 (Freedman Sparks use eye amp, don't seem to define it!)
|
|
headcontrib=abs(neckposn(ind)-neckposn(1)); %see Freedman Sparks Fig 1
|
|
headamp=max(abs(neckposn-neckposn(1))); %see Freedman Sparks Fig 1 & McCluskey Cullen p.2979
|
|
|
|
bodycontrib=abs(torsoposn(ind)-torsoposn(1));
|
|
bodyamp=max(abs(torsoposn-torsoposn(1)));
|