This is example 13. This example demonstrates the following:

  1. Processing calibration results on calibration procedure completion

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

Source code

Source file: example13.c

onModeChange()

In the onModeChange() event handler function we dump calibration results on completion of the calibration 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:
            break;
        case EYEVEC_TRACKER_MODE_SETUP_CALIBRATION: (1)
            if (clientdata->showprocresults < 1) break;
            if (modedata->exitstatus != EYEVEC_EXIT_STATUS_OK) break; (2)
            err = eyevec_get_calibration_status(eyevec, &status); (3)
            if (err)
                printError("eyevec_get_calibration_status()", err);
            else {
                printf("eyevec_get_calibration_status() -> %d\n", status);
                if (status <= 0) break; // No calibration performed.
                EyeVecCalibrationResult result;
                err = eyevec_get_calibration_result(eyevec, &result); (4)
                if (err) {
                    printError("eyevec_get_calibration_result()", err);
                }
                else {
                    printf("eyevec_get_calibration_result() ->\n");
                    if (result.havedata) { (5)
                        printf("    npoints                     %d\n",
                            result.npoints);
                        printf("    npointsskipped              %d\n",
                            result.npointsskipped);
                        printf("    npointsinvalid              %d\n",
                            result.npointsinvalid);
                        printf("    npointsbad                  %d\n",
                            result.npointsbad);
                        printf("    npointspoor                 %d\n",
                            result.npointspoor);
                        printf("    npointsfair                 %d\n",
                            result.npointsfair);
                        printf("    npointsgood                 %d\n",
                            result.npointsgood);
                        printf("    npointssynthetic            %d\n",
                            result.npointssynthetic);
                        for (int n = EYEVEC_RIGHT_EYE; n <= EYEVEC_MEAN_EYE;
                                n++) {
                            if (result.haveeye[n]) {
                                printf("    mean_mm[%d]                  %.3f\n",
                                    n,
                                    (double)result.mean_mm[n]);
                                printf("    sd_mm[%d]                    %.3f\n",
                                    n,
                                    (double)result.sd_mm[n]);
                                printf("    min_mm[%d]                   %.3f\n",
                                    n,
                                    (double)result.min_mm[n]);
                                printf("    max_mm[%d]                   %.3f\n",
                                    n,
                                    (double)result.max_mm[n]);
                                printf("    mean_deg[%d]                 %.3f\n",
                                    n,
                                    (double)result.mean_deg[n]);
                                printf("    sd_deg[%d]                   %.3f\n",
                                    n,
                                    (double)result.sd_deg[n]);
                                printf("    min_deg[%d]                  %.3f\n",
                                    n,
                                    (double)result.min_deg[n]);
                                printf("    max_deg[%d]                  %.3f\n",
                                    n,
                                    (double)result.max_deg[n]);
                            }
                        }
                    }
                    else {
                        printf("    no data\n");
                    }
                }

                if (clientdata->showprocresults < 2) break;
                EyeVecCalibrationPointResult pointresult;
                . (6)
                .
                .
            }
            break;
        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;
    }
    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 calibration mode, signifying calibration procedure completion.
2 Check exitstatus of the calibration procedure. If not OK, there’s nothing to print.
3 Check if calibration results are available.
4 Retrieve the calibration results into an EyeVecCalibrationResult struct.
5 Check if the result struct contains data and if so proceed with printing the calibration results.
6 Processing calibration 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 and calibration.

  4. Press q to quit.

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

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

[x]
eyevec_set_show_gui_on_setup_mode(true): OK

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

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

onModeChange:
    eventtime:                  1750680071664136
    oldmode:                    TRACKER_MODE_SETUP
    newmode:                    TRACKER_MODE_SETUP_BASELINE
    exitstatus:                 EXIT_STATUS_NONE
onModeChange:
    eventtime:                  1750680075811974
    oldmode:                    TRACKER_MODE_SETUP_BASELINE
    newmode:                    TRACKER_MODE_SETUP
    exitstatus:                 EXIT_STATUS_OK

onModeChange:
    eventtime:                  1750680078835940
    oldmode:                    TRACKER_MODE_SETUP
    newmode:                    TRACKER_MODE_SETUP_CALIBRATION
    exitstatus:                 EXIT_STATUS_NONE
onModeChange:
    eventtime:                  1750680089421271
    oldmode:                    TRACKER_MODE_SETUP_CALIBRATION
    newmode:                    TRACKER_MODE_SETUP
    exitstatus:                 EXIT_STATUS_OK

eyevec_get_calibration_status() -> 1
eyevec_get_calibration_result() ->
    npoints                     5
    npointsskipped              0
    npointsinvalid              0
    npointsbad                  0
    npointspoor                 0
    npointsfair                 0
    npointsgood                 5
    npointssynthetic            4
    mean_mm[0]                  0.449
    sd_mm[0]                    0.374
    min_mm[0]                   0.270
    max_mm[0]                   1.119
    mean_deg[0]                 0.031
    sd_deg[0]                   0.026
    min_deg[0]                  0.017
    max_deg[0]                  0.077
    mean_mm[1]                  0.470
    sd_mm[1]                    0.403
    min_mm[1]                   0.193
    max_mm[1]                   1.180
    mean_deg[1]                 0.032
    sd_deg[1]                   0.028
    min_deg[1]                  0.012
    max_deg[1]                  0.081
    mean_mm[2]                  0.055
    sd_mm[2]                    0.032
    min_mm[2]                   0.014
    max_mm[2]                   0.096
    mean_deg[2]                 0.004
    sd_deg[2]                   0.002
    min_deg[2]                  0.001
    max_deg[2]                  0.007

[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 each calibration target.