attachment:doDriftCorrection.m of EyeTrackingWithMatlab - Meg Wiki
location: attachment:doDriftCorrection.m of EyeTrackingWithMatlab

Attachment 'doDriftCorrection.m'

Download

   1 % Calibration routine for SMI IViewX eyetracker and Psychtoolbox,
   2 % using the serial port for communication. This function carries out
   3 % a one-point drift correction. It's generally a good idea to pass the
   4 % exact same params struct here as you provided to calibrateEyeTracker.
   5 % The fixation must be accepted manually. You can do this yourself using
   6 % the response key (alternatively, tell subject to press when properly
   7 % fixating.
   8 % Syntax:
   9 % success = doDriftCorrection(window,ET_serial,ET_params)
  10 % Inputs (all params are optional):
  11 % window - Psychtoolbox screen handle
  12 % ET_serial - Opened serial port object for scanner.
  13 % ET_params - struct with eye tracking parameters. All are optional.
  14 %   npoints - (13) calibration points. DO NOT change between calib and
  15 %       drift correction
  16 % 	bgcolour - ([128 128 128]) background colour (RGB)
  17 % 	targcolour - ([255 255 255]) target colour (RGB)
  18 % 	targsize - (20) target height/width in pixels
  19 % 	acceptkey - ([spacebar]) key for forcing point acceptance
  20 % 	quitkey - ([escapekey]) key for aborting calibration
  21 % 		Use KbName('UnifyKeyNames') to get names for other keys
  22 % 13/4/2010 J Carlin
  23 function ready = doDriftCorrection(window,ET_serial,ET_params)
  24 
  25 % If no serial object entered, crash out
  26 if ~exist('ET_serial','var') || isempty(ET_serial)
  27     error('ET_serial must be defined! See calibrateEyeTracker')
  28 end
  29 
  30 % By default, calls time out in 10 SECONDS.
  31 % This is clearly unacceptably slow for our
  32 % purposes. Now 100 ms.
  33 set(ET_serial,'timeout',.1);
  34 % The downside is that Matlab spits out a lot of
  35 % warnings. Let's disable these...
  36 wstate=warning('off','MATLAB:serial:fgetl:unsuccessfulRead');
  37 
  38 % If you don't know what you want, we will fill this in with
  39 % defaults.
  40 if ~exist('ET_params','var')
  41 	ET_params = struct;
  42 end
  43 
  44 % Screen settings
  45 sc = Screen('Resolution',window);
  46 schw = [sc.width sc.height];
  47 
  48 KbName('UnifyKeyNames');
  49 
  50 % These are the default settings
  51 default_params = struct(...
  52 	'bgcolour',[128 128 128],...
  53 	'targcolour',[255 255 255],...
  54 	'targsize',20, ...
  55 	'npoints',13, ...
  56 	'acceptkey',KbName('space'), ...
  57 	'quitkey',KbName('escape') ...
  58 	);
  59 
  60 % Now put in defaults for whatever was left undefined
  61 fns = fieldnames(default_params);
  62 for fn = fns'
  63 	if ~isfield(ET_params,fn{1})
  64 		ET_params.(fn{1}) = default_params.(fn{1});
  65 	end
  66 end
  67 
  68 % Draw background
  69 Screen(window,'FillRect',ET_params.bgcolour);
  70 
  71 % Display settings for targets
  72 % Make a cross - studiously avoiding alpha blending here to
  73 % maximise compatibility (but you will need to im processing toolbox)
  74 % Settings
  75 cross_orgsize = 100;
  76 cross_linewidth = .05;
  77 % Build cross
  78 cs = round((cross_orgsize / 2) - (cross_orgsize * cross_linewidth));
  79 ce = round((cross_orgsize / 2) + (cross_orgsize * cross_linewidth));
  80 cr = zeros(cross_orgsize);
  81 cr(:,cs:ce) = 1;
  82 cr(cs:ce,:) = 1;
  83 % Resize - Since square, no point to bicubic interpolation
  84 cr_rs = imresize(cr,[ET_params.targsize ET_params.targsize],'nearest');
  85 % Make target uint8, colour
  86 rgb_t = ET_params.targcolour;
  87 cros = uint8(cat(3,cr_rs*rgb_t(1),cr_rs*rgb_t(2),cr_rs*rgb_t(3)));
  88 % Make an appropriately-coloured background
  89 rgb = ET_params.bgcolour;
  90 bg = uint8(ones(ET_params.targsize));
  91 bg_rgb =cat(3,bg*rgb(1),bg*rgb(2),bg*rgb(3));
  92 % Put background and target together
  93 target = bg_rgb;
  94 target(find(cros)) = cros(find(cros));
  95 % Draw texture
  96 targetbuf = Screen('MakeTexture',window,target);
  97 % Set up basic rect
  98 targetrect = [0 0 size(target,1) size(target,2)];
  99 
 100 % Start drift correction
 101 fprintf(ET_serial,sprintf('ET_RCL'));
 102 ready = 0;
 103 ntries = 0;
 104 points = zeros(ET_params.npoints,2);
 105 
 106 rc = 0;
 107 while ~ready
 108 	ntries = ntries+1;
 109 
 110 	% If no connection with serial, return anyway
 111 	if ntries > 500
 112 		fprintf('Serial port communication failure!\n')
 113 		break
 114 	end
 115 
 116 	% Check for manual attempts to move things along
 117 	[keyisdown, secs, keyCode] = KbCheck;
 118 	if keyisdown
 119 		k = find(keyCode);
 120 		k = k(1);
 121 		% Force acceptance of current point
 122 		if k == ET_params.acceptkey
 123 			fprintf('Accepting point...\n')
 124             WaitSecs(.2); % Time to let go of key...
 125 			fprintf(ET_serial,'ET_ACC');
 126 		% Give up on calibration
 127 		elseif k == ET_params.quitkey
 128 			fprintf('Calibration attempt aborted!\n')
 129 			fprintf(ET_serial,'ET_BRK');
 130 			break
 131 		end
 132     end
 133 
 134 	% Check if the eye tracker has something to say
 135     response = fgetl(ET_serial);
 136     
 137 	% What might the eye tracker have to say?
 138 	if ~isempty(response)
 139 		% Save each response - mainly for debugging
 140 		rc = rc+1;
 141         resplog{rc} = response;
 142 		% Split by spaces
 143 		command_etc = strread(regexprep(response,' ',' '),'%s');
 144 		command = command_etc{1};
 145 
 146 		%%% What we do next depends on the command we got:
 147 		% Calibration point change
 148         if strcmp(command,'ET_CHG')
 149             % Coordinates for point
 150             xy = points(str2num(command_etc{2}),:);
 151 			% Rect for point
 152 			pointrect = CenterRectOnPoint(targetrect,xy(1),xy(2));
 153 			% Draw into rect
 154 			Screen('DrawTexture',window,targetbuf,[],pointrect);
 155             Screen(window,'Flip');
 156             % Reset timeout counter
 157             ntries = 0;
 158 
 159             % Calibation point definition
 160         elseif strcmp(command,'ET_PNT')
 161             points(str2num(command_etc{2}),:) = ...
 162 				[str2num(command_etc{3}) str2num(command_etc{4})];
 163        
 164         % Validation finished
 165         elseif strcmp(command,'ET_FIN')
 166             ready = 1;
 167             
 168         
 169         % Various commands we don't care about
 170         elseif strcmp(command,'ET_REC') || ...
 171                 strcmp(command,'ET_CLR') || ...
 172                 strcmp(command,'ET_CAL') || ...
 173                 strcmp(command,'ET_CSZ') || ...
 174                 strcmp(command,'ET_ACC') || ...
 175                 strcmp(command,'ET_VLS') || ...
 176                 strcmp(command,'ET_CPA') || ...
 177                 strcmp(command,'ET_LEV')
 178             continue
 179 
 180 		% Catch all
 181 		else
 182 			fprintf(sprintf(['Drift correction failed - received unrecognised '...
 183 				'input: %s\n'],response));
 184             fprintf(ET_serial,'ET_BRK');
 185 			break % DEBUG
 186 		end % Resp interpretation
 187 	end % Resp check
 188 end % While
 189 
 190 % Clear the target texture from memory
 191 Screen('Close',targetbuf);
 192 % Return warning state to whatever it started as
 193 warning(wstate.state,wstate.identifier);

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2010-06-10 15:38:10, 14.5 KB) [[attachment:ET_tools_10.zip]]
  • [get | view] (2010-06-10 15:40:21, 9.5 KB) [[attachment:calibrateEyeTracker.m]]
  • [get | view] (2010-06-10 15:40:08, 6.2 KB) [[attachment:doDriftCorrection.m]]
  • [get | view] (2010-06-10 15:40:31, 8.3 KB) [[attachment:validateCalibration.m]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.