This is example 15. This example demonstrates the following:

  1. Processing drift-check results on drift-check procedure completion

This example is based on example 6. It extends the onModeChange() event handler function to print drift-check results.

Source code

Source file: example15.c

onModeChange()

In the onModeChange() event handler function we dump drift-check results on completion of the drift-check procedure.

static int onModeChange(EyeVec* eyevec, int64_t eventtime,
    const EyeVecModeChangeEventData* modedata, void* cldata)
{
    (void)eyevec;

    ClientData* clientdata = (ClientData*)cldata;
    if (clientdata == NULL) return 0;

    clientdata->trackermode = modedata->newmode;

    if (clientdata->showmodechanges) {
        printf("onModeChange:\n");
        printf("    eventtime:                  %" PRId64 "\n",
            eventtime);
        printf("    oldmode:                    %s\n",
            eyevec_tracker_mode_string(modedata->oldmode));
        printf("    newmode:                    %s\n",
            eyevec_tracker_mode_string(modedata->newmode));
        printf("    exitstatus:                 %s\n",
            eyevec_exit_status_string(modedata->exitstatus));
//        printf("    deviceerror:                %d\n",
//            modedata->deviceerror);
    }

    EyeVecResult err;
    int status;
    switch (modedata->oldmode) { (1)
        case EYEVEC_TRACKER_MODE_OFF:
        case EYEVEC_TRACKER_MODE_IDLE:
        case EYEVEC_TRACKER_MODE_SETUP:
        case EYEVEC_TRACKER_MODE_SETUP_TEST:
        case EYEVEC_TRACKER_MODE_SETUP_EVALUATION:
        case EYEVEC_TRACKER_MODE_SETUP_BASELINE:
        case EYEVEC_TRACKER_MODE_SETUP_CALIBRATION:
        case EYEVEC_TRACKER_MODE_SETUP_VALIDATION:
            break;
        case EYEVEC_TRACKER_MODE_SETUP_DRIFT_CHECK: (1)
        case EYEVEC_TRACKER_MODE_DRIFT_CHECK: (1)
            if (clientdata->showprocresults < 1) break;
            if (modedata->exitstatus != EYEVEC_EXIT_STATUS_OK) break; (2)
            err = eyevec_get_drift_check_status(eyevec, &status); (3)
            if (err)
                printError("eyevec_get_drift_check_status()", err);
            else {
                printf("eyevec_get_drift_check_status() -> %d\n", status);
                if (status <= 0) break; // No drift-check performed.
                EyeVecDriftCheckResult result;
                err = eyevec_get_drift_check_result(eyevec, &result); (4)
                if (err) {
                    printError("eyevec_get_drift_check_result()", err);
                }
                else {
                    printf("eyevec_get_drift_check_result() ->\n");
                    if (result.havedata) { (5)
                        printf("    status                      %s\n",
                            eyevec_target_status_string(result.status));
                        for (int n = EYEVEC_RIGHT_EYE; n <= EYEVEC_MEAN_EYE;
                                n++) {
                            if (result.haveeye[n]) {
                                printf("    error_mm[%d]                 %+.1f, %+.1f, %.1f\n",
                                    n,
                                    (double)result.error_mm[n].x,
                                    (double)result.error_mm[n].y,
                                    (double)hypotf(result.error_mm[n].x,
                                        result.error_mm[n].y));
                                printf("    error_deg[%d]                %+.2f, %+.2f, %.2f\n",
                                    n,
                                    (double)result.error_deg[n].x,
                                    (double)result.error_deg[n].y,
                                    (double)hypotf(result.error_deg[n].x,
                                        result.error_deg[n].y));
                            }
                        }
                        printf("    windowstart\t\t%" PRId64 "\n",
                            result.windowstart);
                        printf("    windowlength\t%d\n",
                            result.windowlength);
                    }
                    else {
                        printf("    no data\n");
                    }
                }

                if (clientdata->showprocresults < 2) break;
                EyeVecDriftCheckPointResult pointresult;
                . (6)
                .
                .
            }
            break;
        case EYEVEC_TRACKER_MODE_SETUP_RECORDING:
        case EYEVEC_TRACKER_MODE_DATA:
//        case EYEVEC_TRACKER_MODE_DRIFT_CHECK: See above.
//            break;
        case EYEVEC_TRACKER_MODE_RECORDING:
            break;
    }
    switch (modedata->newmode) {
        case EYEVEC_TRACKER_MODE_OFF:
        case EYEVEC_TRACKER_MODE_IDLE:
        case EYEVEC_TRACKER_MODE_SETUP:
        case EYEVEC_TRACKER_MODE_SETUP_TEST:
        case EYEVEC_TRACKER_MODE_SETUP_EVALUATION:
        case EYEVEC_TRACKER_MODE_SETUP_BASELINE:
        case EYEVEC_TRACKER_MODE_SETUP_CALIBRATION:
        case EYEVEC_TRACKER_MODE_SETUP_VALIDATION:
        case EYEVEC_TRACKER_MODE_SETUP_DRIFT_CHECK:
        case EYEVEC_TRACKER_MODE_SETUP_RECORDING:
        case EYEVEC_TRACKER_MODE_DATA:
        case EYEVEC_TRACKER_MODE_DRIFT_CHECK:
        case EYEVEC_TRACKER_MODE_RECORDING:
            break;
    }

    return 0;
}
1 Check if the eye-tracker is leaving drift-check mode, signifying drift-check procedure completion.
2 Check exitstatus of the drift-check procedure. If not OK, there’s nothing to print.
3 Check if drift-check results are available.
4 Retrieve the drift-checkresults into an EyeVecDriftCheckResult struct.
5 Check if the result struct contains data and if so proceed with printing the drift-check results.
6 Processing drift-check point results omitted for brevity. See source file.

Running

After a succesful build run the program:

  1. Press x to call eyevec_set_show_gui_on_setup_mode(). This sets the show-gui-on-setup-mode flag to make the user-interface show on setup mode enter.

  2. Press o to call eyevec_open(). Eye-tracker should go from off mode to idle mode.

  3. Press s to call eyevec_enter_setup_mode(). Eye-tracker should go from idle mode to setup mode. Now perform the baseline measurement, calibration and drift-check. You can either do the drift-check from setup mode or from data mode. The processing in onModeChange() handles both cases equally.

  4. Press q to quit.

Output might look like this (empty lines added for clarity):

eyevec_initialize(): OK
Type q to quit, ? for help.

[x]
eyevec_set_show_gui_on_setup_mode(true): OK

[o]
onModeChange:
    eventtime:                  1750680743731160
    oldmode:                    TRACKER_MODE_OFF
    newmode:                    TRACKER_MODE_IDLE
eyevec_open(): OK
    exitstatus:                 EXIT_STATUS_NONE

[s]
onModeChange:
    eventtime:                  1750680745558204
    oldmode:                    TRACKER_MODE_IDLE
    newmode:                    TRACKER_MODE_SETUP
    exitstatus:                 EXIT_STATUS_NONE
eyevec_enter_setup_mode(): OK

onModeChange:
    eventtime:                  1750680750351534
    oldmode:                    TRACKER_MODE_SETUP
    newmode:                    TRACKER_MODE_SETUP_BASELINE
    exitstatus:                 EXIT_STATUS_NONE
onModeChange:
    eventtime:                  1750680753619219
    oldmode:                    TRACKER_MODE_SETUP_BASELINE
    newmode:                    TRACKER_MODE_SETUP
    exitstatus:                 EXIT_STATUS_OK

onModeChange:
    eventtime:                  1750680758089364
    oldmode:                    TRACKER_MODE_SETUP
    newmode:                    TRACKER_MODE_SETUP_CALIBRATION
    exitstatus:                 EXIT_STATUS_NONE
onModeChange:
    eventtime:                  1750680770693969
    oldmode:                    TRACKER_MODE_SETUP_CALIBRATION
    newmode:                    TRACKER_MODE_SETUP
    exitstatus:                 EXIT_STATUS_OK

onModeChange:
    eventtime:                  1750680777064697
    oldmode:                    TRACKER_MODE_SETUP
    newmode:                    TRACKER_MODE_SETUP_DRIFT_CHECK
    exitstatus:                 EXIT_STATUS_NONE
onModeChange:
    eventtime:                  1750680779075531
    oldmode:                    TRACKER_MODE_SETUP_DRIFT_CHECK
    newmode:                    TRACKER_MODE_SETUP
    exitstatus:                 EXIT_STATUS_OK

eyevec_get_drift_check_status() -> 1
eyevec_get_drift_check_result() ->
    status                      TARGET_STATUS_GOOD
    error_mm[0]                 -2.0, -0.8, 2.2
    error_deg[0]                -0.15, -0.06, 0.16
    error_mm[1]                 +1.3, +1.3, 1.9
    error_deg[1]                +0.10, +0.09, 0.13
    error_mm[2]                 -0.4, +0.3, 0.4
    error_deg[2]                -0.03, +0.02, 0.03
    windowstart                 1750680759390412
    windowlength                88

[q]
eyevec_cleanup(): OK
eyevec_destroy_thread(): OK

The results printed are the same as shown in the user-interface.

Repeating the above with showprocresults in the client data struct raised to 2 will output additional results for the drift-check target.