2 This example is more comprehensive than most, as it aims to illustrate 3 how you can put together a complete, ready-to-run script, by combining 4 information from different examples. Note that running this script 5 will produce a small CSV data file in the parent directory. 12 import tobii_research
as tr
18 EYETRACKER_ADDRESS =
"" 22 gaze_data_samples = []
28 if EYETRACKER_ADDRESS:
29 eyetracker = tr.EyeTracker(EYETRACKER_ADDRESS)
31 sys.exit(
"Specified eye tracker not found, please check the address.")
35 all_eyetrackers = tr.find_all_eyetrackers()
36 if not all_eyetrackers:
38 "No connected eye trackers found. Please check the connection " 39 "and/or install any missing drivers with Tobii Pro Eye Tracker Manager." 41 return all_eyetrackers[0]
44 def gaze_data_callback(gaze_data):
49 global gaze_data_samples
50 gaze_data_samples.append(gaze_data)
53 def buffer_overflow_notifications_callback(notification_data):
55 f
"Buffer overflow occurred at system time: {notification_data['system_time_stamp']}" 59 def calibrate(eyetracker):
60 calibration = tr.ScreenBasedCalibration(eyetracker)
63 calibration.enter_calibration_mode()
64 print(
"Entered calibration mode for eye tracker with serial number {0}.".format(eyetracker.serial_number))
68 points_to_calibrate = [(0.5, 0.5), (0.1, 0.1), (0.1, 0.9), (0.9, 0.1), (0.9, 0.9)]
70 for point
in points_to_calibrate:
73 print(
"Show a point on screen at {0}.".format(point))
78 print(
"Collecting data at {0}.".format(point))
79 if calibration.collect_data(point[0], point[1]) != tr.CALIBRATION_STATUS_SUCCESS:
82 calibration.collect_data(point[0], point[1])
84 print(
"Computing and applying calibration.")
85 calibration_result = calibration.compute_and_apply()
86 print(
"Compute and apply returned {0} and collected at {1} points.".
87 format(calibration_result.status, len(calibration_result.calibration_points)))
90 recalibrate_point = (0.1, 0.1)
91 print(
"Removing calibration point at {0}.".format(recalibrate_point))
92 calibration.discard_data(recalibrate_point[0], recalibrate_point[1])
95 print(
"Show a point on screen at {0}.".format(recalibrate_point))
96 calibration.collect_data(recalibrate_point[0], recalibrate_point[1])
99 print(
"Computing and applying calibration.")
100 calibration_result = calibration.compute_and_apply()
101 print(
"Compute and apply returned {0} and collected at {1} points.".
102 format(calibration_result.status, len(calibration_result.calibration_points)))
107 calibration.leave_calibration_mode()
109 print(
"Left calibration mode.")
112 def save_gaze_data(gaze_samples_list):
113 if not gaze_samples_list:
114 print(
"No gaze samples were collected. Skipping saving")
118 print(
"Sample dictionary keys:", gaze_samples_list[0].keys())
121 file_handle = open(
"my_gaze_data.csv",
"w")
122 gaze_writer = csv.writer(file_handle)
123 gaze_writer.writerow([
"time_seconds",
"left_x",
"left_y",
"right_x",
"right_y"])
124 start_time = gaze_samples_list[0][
"system_time_stamp"]
125 for recording_dict
in gaze_samples_list:
126 sample_time_from_start = recording_dict[
"system_time_stamp"] - start_time
128 sample_time_from_start = sample_time_from_start / (10**(6))
131 left_x, left_y = recording_dict[
"left_gaze_point_on_display_area"]
132 right_x, right_y = recording_dict[
"right_gaze_point_on_display_area"]
133 gaze_writer.writerow(
134 [sample_time_from_start, left_x, left_y, right_x, right_y]
140 eyetracker = get_eyetracker()
142 print(
"Subscribing to gaze data for eye tracker with serial number {0}.".format(eyetracker.serial_number))
143 eyetracker.subscribe_to(tr.EYETRACKER_GAZE_DATA, gaze_data_callback, as_dictionary=
True)
145 eyetracker.subscribe_to(
146 tr.EYETRACKER_NOTIFICATION_STREAM_BUFFER_OVERFLOW,
147 buffer_overflow_notifications_callback,
150 calibrate(eyetracker)
152 print(
"Unsubscribing from gaze data for eye tracker with serial number {0}.".format(eyetracker.serial_number))
153 eyetracker.unsubscribe_from(tr.EYETRACKER_GAZE_DATA, gaze_data_callback)
155 save_gaze_data(gaze_data_samples)
162 if __name__ ==
"__main__":