Data produced by the Tobii module
One entity, named Tobii_Data, id assigned once when the module starts. Gaze, pupillometry and
head pose ride together on the same entity, published at Interval cadence - see
Configure for why that matters more than it does on most modules.
Video, when enabled, publishes as separate frames for the same entity id - see below.
Gaze
Populated on GazeComponent: left_gaze_origin,
right_gaze_origin, left_eye_position, right_eye_position, left_eye_occluded,
right_eye_occluded, gaze_screen_point.
left_eye_occluded/right_eye_occluded are derived from whether Tobii reports that eye’s
position tracking as valid - not from a blink detector. gaze_screen_point comes from Tobii’s
own combined, filtered gaze point callback, which the vendor SDK’s own documentation describes as
the recommended source for where the user is looking on screen.
This module does not populate gaze_direction, left_gaze_direction, right_gaze_direction,
combined_eye_position, blink, has_glasses, gaze_point, or any quality field. If you are
used to a 3D gaze-direction ray from another eye tracker in this catalogue - HTC Vive gaze,
Varjo, SmartEye all publish one - this module does not provide the equivalent. It gives you eye
origin and position points, plus a 2D screen-space gaze point, and nothing else.
Pupillometry
Populated on PupillometryDataComponent:
left_eye_pupil_diameter, right_eye_pupil_diameter (millimetres),
left_eyelid_openness/right_eyelid_openness, and their quality fields - each quality is a
binary 1.0 (valid) or 0.0 (invalid) from Tobii’s own validity flag, not a graduated score.
Combined (non-per-eye) fields and other_pupil_data are not populated.
Head pose
Populated on SpatialComponent.pose: position directly from Tobii’s reported head position;
orientation converted from Tobii’s Euler angles (x = pitch, y = yaw, z = roll, per Tobii’s own
SDK documentation) to a quaternion. The whole pose is only replaced when position or rotation
validity is true - but when it is replaced, both halves are rebuilt from scratch, not merged
with the previous pose. If only one half is valid that update, the other half resets to a
default pose (no position, no rotation) rather than keeping its last known real value. A
position update while rotation briefly drops out, for instance, momentarily reports the head
facing a default orientation, not its last known real one.
Video
When CaptureVideoFeed is on, the tracker’s infrared camera feed publishes as its own
SimulationFrames, one per completed H264 access unit, independent of the gaze/pupil/pose
frames above and not bounded by Interval. Each carries only
StreamComponent: one VideoSource named camera.ir,
codec: "H264", frame_rate: 33, Annex-B access units with SPS/PPS on IDR frames. This module
does not decode the video; a consumer needs its own H264 decoder and must wait for an IDR frame
before it can start decoding.
If the tracker’s camera format is ever anything other than 8-bit greyscale, or the H264 encoder fails to initialize, video is disabled for that session with an error logged once; gaze, pupillometry and head pose keep publishing normally.