Skip to content

Commit 6b989e3

Browse files
authored
Merge pull request #31 from marcobarilari/marco_eyeTracker
add Eye Tracker code
2 parents 81521c0 + a603326 commit 6b989e3

File tree

2 files changed

+225
-2
lines changed

2 files changed

+225
-2
lines changed

README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
[![All Contributors](https://img.shields.io/badge/all_contributors-3-orange.svg?style=flat-square)](#contributors-)
55
<!-- ALL-CONTRIBUTORS-BADGE:END -->
66

7-
This is List of Crossmodal Perpeption and Plasticity lab (CPP) PsychToolBox (PTB) toolbox.
7+
This is List of Crossmodal Perception and Plasticity lab (CPP) PsychToolBox (PTB) toolbox.
88

99
Those functions are mostly wrappers around some PTB functions to facilitate their use and to have a codebase to facilitate their reuse.
1010

@@ -17,7 +17,7 @@ For instructions see the following links:
1717

1818
| Requirements | Used version |
1919
|----------------------------------------------------------|--------------|
20-
| [PsychToolBox](http://psychtoolbox.org/) Duuuuhh | >=3.0.14 |
20+
| [PsychToolBox](http://psychtoolbox.org/) Duuuuhh | >=3.0.14 |
2121
| [Matlab](https://www.mathworks.com/products/matlab.html) | 201?? |
2222
| or [octave](https://www.gnu.org/software/octave/) | 4.? |
2323

@@ -134,6 +134,10 @@ and returns a structure with an additional field with Pix suffix holding that ne
134134

135135
Define the parameters of the fixation cross in `cfg` and `expParameters` and this does the rest.
136136

137+
### eyeTracker
138+
139+
This will handle the Eye Tracker (EyeLink set up) and can be called to initialize the connection and start the calibration, start/stop eye(s) movement recordings and save the `*.edf` file (named with BIDS specification from cpp-lln-lab/CPP_BIDS).
140+
137141
### pressSpace4me
138142

139143
Use that to stop your script and only restart when the space bar is pressed.

eyeTracker.m

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
function [ el, edfFile ] = eyeTracker(input, cfg, expParameters, varargin)
2+
3+
if ~cfg.eyeTracker
4+
5+
el = [];
6+
7+
else
8+
9+
switch input
10+
11+
case 'Calibration'
12+
13+
%% STEP 2
14+
% Provide Eyelink with details about the graphics environment
15+
% and perform some initializations. The information is returned
16+
% in a structure that also contains useful defaults
17+
% and control codes (e.g. tracker state bit and Eyelink key values).
18+
el = EyelinkInitDefaults(cfg.win);
19+
20+
% calibration has silver background with black targets, sound and smaller
21+
% targets
22+
el.backgroundcolour = [ 192 192 192, (cfg.win)];
23+
el.msgfontcolour = BlackIndex(cfg.win);
24+
el.calibrationtargetcolour = BlackIndex(cfg.win);
25+
el.calibrationtargetsize = 1;
26+
el.calibrationtargetwidth = 0.5;
27+
el.displayCalResults = 1;
28+
29+
% call this function for changes to the calibration structure to take
30+
% affect
31+
EyelinkUpdateDefaults(el);
32+
33+
% STEP 3
34+
% Initialization of the connection with the Eyelink Gazetracker.
35+
% exit program if this fails.
36+
37+
% make sure EL is initialized.
38+
ELinit = Eyelink('Initialize');
39+
if ELinit~=0
40+
fprintf('Eyelink is not initialized, aborted.\n');
41+
Eyelink('Shutdown');
42+
Screen('CloseAll');
43+
return;
44+
end
45+
46+
% make sure we're still connected.
47+
ELconnection = Eyelink('IsConnected');
48+
if ELconnection~=1
49+
fprintf('Eyelink is not connected, aborted.\n');
50+
Eyelink('Shutdown');
51+
Screen('CloseAll');
52+
return;
53+
end
54+
55+
%
56+
if ~EyelinkInit(0, 1)
57+
fprintf('Eyelink Init aborted.\n');
58+
return;
59+
end
60+
61+
% Open the edf file to write the data
62+
edfFile = 'demo.edf';
63+
Eyelink('Openfile', edfFile);
64+
65+
[el.v, el.vs] = Eyelink('GetTrackerVersion');
66+
fprintf('Running experiment on a ''%s'' tracker.\n', el.vs );
67+
68+
% make sure that we get gaze data from the Eyelink
69+
Eyelink('Command', 'link_sample_data = LEFT,RIGHT,GAZE,AREA');
70+
71+
% STEP 4
72+
% SET UP TRACKER CONFIGURATION
73+
% Setting the proper recording resolution, proper calibration type,
74+
% as well as the data file content;
75+
% Eyelink('command', 'add_file_preamble_text ''Recorded by EyelinkToolbox demo-experiment''');
76+
77+
% This command is crucial to map the gaze positions from the tracker to
78+
% screen pixel positions to determine fixation
79+
Eyelink('command','screen_pixel_coords = %ld %ld %ld %ld', 0, 0, 0, 0);
80+
Eyelink('message', 'DISPLAY_COORDS %ld %ld %ld %ld', 0, 0, 0, 0);
81+
82+
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
83+
% DEFAULT CALIBRATION
84+
% set calibration type.
85+
Eyelink('command', 'calibration_type = HV5');
86+
87+
% you must send this command with value NO for custom calibration
88+
% you must also reset it to YES for subsequent experiments
89+
Eyelink('command', 'generate_default_targets = YES');
90+
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
91+
92+
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
93+
% % CUSTOM CALIBRATION
94+
% % (SET MANUALLY THE DOTS COORDINATES, HERE FOR 6 DOTS)
95+
% Eyelink('command', 'calibration_type = HV5');
96+
% % you must send this command with value NO for custom calibration
97+
% % you must also reset it to YES for subsequent experiments
98+
% Eyelink('command', 'generate_default_targets = NO');
99+
%
100+
% % calibration and validation target locations
101+
% [width, height]=Screen('WindowSize', screenNumber);
102+
% Eyelink('command','calibration_samples = 6');
103+
% Eyelink('command','calibration_sequence = 0,1,2,3,4,5');
104+
% Eyelink('command','calibration_targets = %d,%d %d,%d %d,%d %d,%d %d,%d',...
105+
% 640,512, ... %width/2,height/2
106+
% 640,102, ... %width/2,height*0.1
107+
% 640,614, ... %width/2,height*0.6
108+
% 128,341, ... %width*0.1,height*1/3
109+
% 1152,341 ); %width-width*0.1,height*1/3
110+
%
111+
% Eyelink('command','validation_samples = 5');
112+
% Eyelink('command','validation_sequence = 0,1,2,3,4,5');
113+
% Eyelink('command','validation_targets = %d,%d %d,%d %d,%d %d,%d %d,%d',...
114+
% 640,512, ... %width/2,height/2
115+
% 640,102, ... %width/2,height*0.1
116+
% 640,614, ... %width/2,height*0.6
117+
% 128,341, ... %width*0.1,height*1/3
118+
% 1152,341 ); %width-width*0.1,height*1/3
119+
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
120+
121+
% % set parser (conservative saccade thresholds)
122+
% Eyelink('command', 'saccade_velocity_threshold = 35');
123+
% Eyelink('command', 'saccade_acceleration_threshold = 9500');
124+
125+
% set EDF file contents (not clear what this lines are used for)
126+
el.vsn = regexp(el.vs,'\d','match'); % wont work on EL
127+
128+
% enter Eyetracker camera setup mode, calibration and validation
129+
EyelinkDoTrackerSetup(el);
130+
131+
% % % do a final check of calibration using driftcorrection
132+
% % % You have to hit esc before return.
133+
% % EyelinkDoDriftCorrection(el);
134+
%
135+
% % % do a final check of calibration using driftcorrection
136+
% % success=EyelinkDoDriftCorrection(el);
137+
% % if success~=1
138+
% % Eyelink('shutdown');
139+
% % Screen('CloseAll');
140+
% % return;
141+
% % end
142+
143+
% Go back to black screen
144+
Screen('FillRect', cfg.win, [0 0 0]);
145+
Screen('Flip', cfg.win);
146+
147+
case 'StartRecording'
148+
149+
% STEP 5
150+
% EyeLink Start recording the block
151+
Eyelink('Command', 'set_idle_mode');
152+
WaitSecs(0.05);
153+
Eyelink('StartRecording');
154+
% % here to tag the recording, in the past caused delays during the
155+
% % presentation so I avoided to use it
156+
% Eyelink('message',['TRIALID ',num2str(blocks),'_startTrial']);
157+
158+
% check recording status, stop display if error
159+
checkrec=Eyelink('checkrecording');
160+
if(checkrec~=0)
161+
fprintf('\nEyelink is not recording.\n\n');
162+
Eyelink('Shutdown');
163+
Screen('CloseAll');
164+
return;
165+
end
166+
167+
% record a few samples before we actually start displaying
168+
% otherwise you may lose a few msec of data
169+
WaitSecs(0.1);
170+
171+
% HERE START THE STIMALTION OF THE BLOCK
172+
% to mark the beginning of the trial
173+
Eyelink('Message', 'SYNCTIME');
174+
175+
case 'StopRecordings'
176+
177+
% STEP 8
178+
% finish up: stop recording eye-movements,
179+
% EyeLink Stop recording the block
180+
Eyelink('Message', 'BLANK_SCREEN');
181+
% adds 100 msec of data to catch final events
182+
WaitSecs(0.1);
183+
% close graphics window, close data file and shut down tracker
184+
Eyelink('StopRecording');
185+
186+
case 'Shutdown'
187+
188+
edfFileName = expParameters.fileName.eyetracker;
189+
edfFile = 'demo.edf';
190+
191+
% STEP 6
192+
% At the end of the experiment, save the edf file and shut down connection
193+
% with Eyelink
194+
195+
Eyelink('Command', 'set_idle_mode');
196+
WaitSecs(0.5);
197+
Eyelink('CloseFile');
198+
199+
% download data file
200+
try
201+
fprintf('Receiving data file ''%s''\n', edfFileName );
202+
status=Eyelink('ReceiveFile','',[expParameters.outputDir, filesep, 'eyetracker', filesep, edfFileName]);
203+
if status > 0
204+
fprintf('ReceiveFile status %d\n', status);
205+
end
206+
if 2==exist([expParameters.outputDir, filesep, 'eyetracker', filesep, edfFileName], 'file')
207+
fprintf('Data file ''%s'' can be found in ''%s''\n', edfFileName, [expParameters.outputDir, filesep, 'eyetracker', filesep] );
208+
end
209+
catch
210+
fprintf('Problem receiving data file ''%s''\n', edfFileName );
211+
end
212+
213+
Eyelink('shutdown');
214+
Screen('CloseAll');
215+
216+
217+
end
218+
219+
end

0 commit comments

Comments
 (0)