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.You are not allowed to attach a file to this page.