Outputting eye signals via VPixx

Hi Chris,

I hope you had a good vacation! Over the past week, I’ve been working on implementing the analog outputs of the eye signals to the Vpixx, but I’ve run into two issues with the datapixx_analog_output() command. Issue #1 seems to be that I’m not able to multiply eye_h by any constants within the command itself. As an example, for the eye’s y coordinate, I would ideally input: value = 5*(eye_v/display_bounds(‘top’)). Unfortunately, this doesn’t even seem to generate a response on the Blackrock side, and I’ve even tried inputting (1*eye_v), and this also doesn’t seem to work. This is very strange to me, considering that inputting eye_v alone does generate a signal.

In order to get around this, I’ve resorted to using variable associated actions to change a new variable, eye_y, every time the calibrated eye signal (eye_v) changes, and then input eye_y into the analog output command. This would be fine, except for issue #2, a continuous stream of the same warning:

WARNING: Scheduled task (/Users/cstawarz/mworks-buildbot/worker/build_for_macos/build/plugins/core/EyeLink/Eyelink.cpp:342: eyelink) falling behind, dropping 1 scheduled executions (priority = 2, interval = 1000, task = 0x600001afa120)

At first, I thought that this delay was caused by the constant execution of the variable associated actions, but now I see that this is even happening when I just input eye_v into the analog output without any change in scale.

Do you have any insights as to how we might go about solving either of these issues? Let me know when you get a chance!

All of the best,

Jack

Hi Jack,

Issue #1 seems to be that I’m not able to multiply eye_h by any constants within the command itself. As an example, for the eye’s y coordinate, I would ideally input: value = 5*(eye_v/display_bounds(‘top’)). Unfortunately, this doesn’t even seem to generate a response on the Blackrock side, and I’ve even tried inputting (1*eye_v), and this also doesn’t seem to work. This is very strange to me, considering that inputting eye_v alone does generate a signal.

Yes, the value parameter must be set to the name of a variable. This is true for all output parameters in MWorks.

In order to get around this, I’ve resorted to using variable associated actions to change a new variable, eye_y, every time the calibrated eye signal (eye_v) changes, and then input eye_y into the analog output command. This would be fine, except for issue #2, a continuous stream of the same warning

That is what I would have recommended, although I didn’t anticipate the issue you’re seeing. Here’s what’s happening:

Variable-attached actions are executed when a new value is assigned to the variable in question. In this case, the assignment happens inside MWorks’ EyeLink interface, which is polling the eye tracker for new data at the rate specified by its data_interval parameter. The problem is that sending the analog output values to the VIEWPixx takes a finite amount of time, and apparently that interval is long enough that it’s causing the EyeLink interface to fall behind its desired update schedule, hence the warnings.

The first thing you could try is setting the eyelink device’s data_interval to a higher value. That won’t result in less data being received from the EyeLink (the tracker has its own sampling frequency, which MWorks doesn’t control), but MWorks will receive it less frequently and in “bursts” of multiple values. All the values in a given burst will get the same MWorks time stamp, which may or may not be an issue. Also, it’s possible that you still won’t be able to send all the values to the VIEWPixx fast enough to prevent the dropped execution warnings.

Another solution is to keep the actions that send the eye signals to the VIEWPixx out of the EyeLink interface’s data-polling loop. Scheduled actions are probably the right tool for this job. To use them, first add a couple variables to your experiment:

var eye_data_transfer_interval = 1ms // Not sure about this value
var eye_data_transfer_cancel = false

Then, after starting the EyeLink and VIEWPixx interfaces, begin sending eye data to the VIEWPixx like this:

eye_data_transfer_cancel = false

schedule (
    delay = eye_data_transfer_interval
    duration = eye_data_transfer_interval
    repeats = -999  // Repeat until cancelled
    cancel = eye_data_transfer_cancel
    ) {
    if (eye_h != -32768 and eye_v != -32768) {  // -32768 indicates no data
        eye_h_output = 5 * (eye_h / display_bounds('right'))
        eye_v_output = 5 * (eye_v / display_bounds('top'))
    }
}

If you want to stop transferring the eye data, perhaps because you’re pausing eye tracking, set the “cancel” variable to true:

eye_data_transfer_cancel = true

The only tricky part is picking the value of eye_data_transfer_interval. Ideally, it should be less than (maybe half of) the EyeLink interface’s data_interval value, so that you don’t miss an eye data. However, you still have to contend with the time it takes to send the analog data to the VIEWPixx. If eye_data_transfer_interval is too small, then you’ll get warnings that the scheduled action is falling behind schedule. Probably the best approach is to determine via testing how small you can make it without getting warnings.

I apologize for not foreseeing this issue. Hopefully one or the other of the workarounds I suggested will resolve it.

Cheers,
Chris

Hi Chris,

Thank you so much for your help with this! We’re still testing everything,
but it does seem like the latter solution works (the first solution
requires a data_interval greater than 20 ms) with
an eye_data_transfer_interval of 2 ms.

Also, Yasmine won’t be available tomorrow morning, and Margaret and I would
like to work more on implementing these analog eye signals, so I don’t
think we need to have our weekly meeting. I’ll keep you updated if we have
any questions about anything!

Thanks again,

Jack