EyeTrackingWithMatlab - Meg Wiki

Revision 12 as of 2017-08-08 16:02:01

Clear message
location: EyeTrackingWithMatlab

Eye tracking with Matlab (Psychtoolbox / Cogent)

Currently all eye trackers apart from the MRI tracker have been upgraded to a new version that no longer supports the tools described below. Unless you are using MRI the discussion below is irrelevant. You should probably use the SMI Matlab SDK instead.

Note also that another update broke the code below by changing the Baud rate of the serial port to 115200 (was 9600). So if you find that your old code mysteriously fails to connect with the tracker this is the first thing to check.

Functions are available for eye tracker calibration, validation, and drift correction. You can get all these functions as part of Johan Carlin's StudyTools package or in a slightly modified standalone format (see [EyeTrackingCalibrationScanner|this wiki entry]. This package also includes a wrapper function (fullCalibrationRoutine) that takes you through calibration and validation with a minimum of fuss.

Initialising the serial connection

The serial port needs to be set up. After this, we send text strings that the eye tracker PC interprets. These commands take the format "ET_X."

eyetracking = input('Eyetracking (1 to enable, 0 to disable): ');

if eyetracking
        ET_serial = serial('COM1', 'BaudRate', 115200, 'Databits', 8);
        fopen(ET_serial); % Open serial port
        fprintf(ET_serial,'ET_CLR'); % Clear recording buffer
        fprintf(ET_serial,'ET_REC'); % Start recording
        display(sprintf('%s\t%s','Eyetracking:','enabled'))
else
        display(sprintf('%s\t%s','Eyetracking:','disabled'))
end

Calibration using Psychtoolbox

Use the calibrateEyeTracker.m function if you are already using Psychtoolbox for your experiment. See function help:

% Calibration routine for SMI IViewX eyetracker and Psychtoolbox,
% using the serial port for communication.
% This function is fairly robust - if calibration fails for some
% reason it will quietly print out some warnings and return. If
% calibration failures are catastrophic for your experiment, you will
% need to check the output flag for success==1 in your own script.
% Syntax:
% success = calibrateEyeTracker(window,[ET_serial],[ET_params])
% Inputs (all optional except the Psychtoolbox window):
% window - Psychtoolbox screen handle
% ET_serial - Opened serial port object for scanner. Initialise with e.g.
%               ET_serial = serial('COM1','BaudRate',115200,'Databits',8);
%       fopen(ET_serial);
%               If left undefined, we open a serial port with the above settings.
% ET_params - struct with eye tracking parameters. All are optional.
%       npoints - (13) number of calibration points
%       calibarea - ([screenx screeny]) calibration area on screen
%       bgcolour - ([128 128 128]) background colour (RGB)
%       targcolour - ([255 255 255]) target colour (RGB)
%       targsize - (20) target height/width in pixels
%       acceptkey - ([spacebar]) key for forcing point acceptance
%       quitkey - ([escapekey]) key for aborting calibration
%               Use KbName('UnifyKeyNames') to get names for other keys
%   waitforvalid - (0) wait for valid data during calibration
%   randompointorder - (0) randomise point order during calibration
%   autoaccept - (1) Auto-accept points after some fixation dur.
%   checklevel - (2) Fussiness when accepting points (0-3). SMI recommends
%       2 for every-day use. Drop if subject is problematic.
% 13/4/2010 J Carlin, heavily indebted to Maarten van Caasteren's
% VB script for E-Prime

If you aren't using Psychtoolbox but you still want to do calibration within Matlab, you can write a simple wrapper script to run before starting your experiment. Run something like this script from the same folder where you keep calibrateEyeTracker.m:

ET_serial = serial('COM1', 'BaudRate', 115200, 'Databits', 8);
fopen(ET_serial); % Open serial port
fprintf(ET_serial,'ET_CLR'); % Clear recording buffer
fprintf(ET_serial,'ET_REC'); % Start recording

% Specify custom parameters here, if you want
params = struct;
% For example, let's make the calibration area a bit smaller,
% as this usually helps.
params.calibarea = [800 600];

err = 0;
try
    screen = Screen(0,'OpenWindow');
    success = calibrateEyeTracker(screen,ET_serial,params); 

    if ~success
        error('Calibration failed...')
    end
catch
    err = 1;
end;
fclose(ET_serial);
Screen('CloseAll');
if err, rethrow(lasterror); end;

Validating your calibration

The validation routine runs through the calibration a second time, each time recording the deviation between the recorded eye position and the position of the target. Large deviations imply that the calibration didn't work as intended. The validation routine provides various performance metrics. Currently we don't have any good rule of thumbs regarding what sort of values count as 'good enough' - it would be hugely helpful if someone could record validation outputs for a number of subjects to provide an idea of what sort of quality is to be expected.

validateCalibration.m will carry out a validation routine. It depends on many of the same parameters as calibrateEyeTracker, so the two are perhaps best combined.

% Calibration routine for SMI IViewX eyetracker and Psychtoolbox,
% using the serial port for communication. This function validates
% a previous calibration. It's generally a good idea to pass the
% exact same params struct here as you provided to calibrateEyeTracker.
% NB, MeanDevXY is in deg visual angle, so is completely dependent on
% you appropriately configuring IViewX settings to match your setup. The
% other values are in pixels.
% Currently only reports validation parameters for the left eye if tracking
% binocular. As near as I can tell, this information is never transmitted,
% so little can be done at this end.
% Syntax:
% [success,RMSdev,RMSdevdist,MeanDevXY] = validateCalibration(window,ET_serial,ET_params)
% Inputs (all params are optional):
% window - Psychtoolbox screen handle
% ET_serial - Opened serial port object for scanner.
% ET_params - struct with eye tracking parameters. All are optional.
%   npoints - (13) calibration points. DO NOT change between calib and
%       validation.
%       bgcolour - ([128 128 128]) background colour (RGB)
%       targcolour - ([255 255 255]) target colour (RGB)
%       targsize - (20) target height/width in pixels
%       acceptkey - ([spacebar]) key for forcing point acceptance
%       quitkey - ([escapekey]) key for aborting calibration
%               Use KbName('UnifyKeyNames') to get names for other keys
% 13/4/2010 J Carlin

Carrying out a drift correction

A drift correction is essentially a rigid-body linear re-calibration of the eye tracker. The volunteer fixates on a central cross, and the calibration parameters are shifted to re-align the calibrated centre with the current fixation. Because a drift correction is fast and easy, it can be profitably used as a stop-gap fix in between full calibrations. However, because drift correction only really shuffles the calibration space around, it cannot compensate for large distortions, e.g. head movement. It is best to re-calibrate quite frequently (e.g. every 10 minutes), and place say a single drift correction 5 minutes into each run.

doDriftCorrection.m carries out a drift correction in Matlab. Once again, it relies on the same variables as calibrateEyeTracker and validateCalibration.

% Calibration routine for SMI IViewX eyetracker and Psychtoolbox,
% using the serial port for communication. This function carries out
% a one-point drift correction. It's generally a good idea to pass the
% exact same params struct here as you provided to calibrateEyeTracker.
% The fixation must be accepted manually. You can do this yourself using
% the response key (alternatively, tell subject to press when properly
% fixating).
% Syntax:
% success = doDriftCorrection(window,ET_serial,ET_params)
% Inputs (all params are optional):
% window - Psychtoolbox screen handle
% ET_serial - Opened serial port object for scanner.
% ET_params - struct with eye tracking parameters. All are optional.
%   npoints - (13) calibration points. DO NOT change between calib and
%       drift correction
%       bgcolour - ([128 128 128]) background colour (RGB)
%       targcolour - ([255 255 255]) target colour (RGB)
%       targsize - (20) target height/width in pixels
%       acceptkey - ([spacebar]) key for forcing point acceptance
%       quitkey - ([escapekey]) key for aborting calibration
%               Use KbName('UnifyKeyNames') to get names for other keys
% 13/4/2010 J Carlin

Sending events

If you send ET_REM [x] to the eyetracker, [x] gets written as an event in the eyetracking log. This can then be used to identify your events in an analysis. Note that BeGaze can automatically match up your events with images, and for this to work the string you send must be the exact filename of the image you wish to associate the event with. So for instance, if your fixation cross image is fixation.png, sending 'ET_REM fixation.png' will then make it reasonably easy to overlay heatmaps etc over the fixation image in BeGaze.

% One way to send a trial string. You need to do this for each onset you are interested in, e.g., start of each trial.
trialname = 'mystimimage'; % Whatever your stimulus is.
fprintf(ET_serial,sprintf('ET_REM %s.png',trialname));

Finishing the recording, saving your data

Once your experiment has finished, you need to stop the eyetracking recording, and close the serial port connection. You can also use a remote command to save your data - setting this up is highly recommended, as the data otherwise gets overwritten if you forget to save manually before starting the next run!

% Stop recording
fprintf(ET_serial,'ET_STP');
% Save the data - file path on eye tracking PC
% NB this will fail if the directory does not exist
fpath = 'C:\Johan\TestData.idf';
fprintf(ET_serial,sprintf('ET_SAV "%s"',filepath))
% Close to flush buffer
fclose(ET_serial);
end

General notes

The most common errors you will see are related to the serial port being busy. This happens when a) you forgot to disable WinCAL before starting your experiment script, b) your script crashed and you are trying to restart without properly closing the serial port (fclose(ET_serial) above). When in doubt, restart Matlab and try again.