Basic API interface

7 replies [Last post]
oleg
oleg's picture
Offline
Joined: Sep 7 2009

And here I start the long-awaited topic on the basic interface / set-of-functions that should be available for developers once a device is installed in a system.

Before we propose our own or comment already proposed (by Adrian) solutions, lets observe several existing APIs. If someone thinks I violate any rights or expose commercial secrets by publishing this document, let me know.

oleg
oleg's picture
Offline
Joined: Sep 7 2009
Re: Basic API interface

About ETU-Driver.

ETU-Driver uses so called "API conversion" modules, each knows how to communication with a particular device and each exposes same set of function. There are 10 main functions:
- create/destroy (load and unload resources, such as SDK libraries),
- connect/disconnect (make the device ready for calibration)
- calibrate/stopCalibration/correctDrift (calibration and re-calibration routines)
- start/stop
- showOptions (show the dialog to adjust the device connection, calibration and tracking options)

There are additional 5 functions also:
- getName (return the name of the module, which reflect the type of device it serves for)
- get/setDeviceState (retrieves some basic info about the device)
- passValue (obsolete)
- setOnSynkEvent (not implemented)

For client applications ETU-Driver exposes some of these functions (calibration-, tracking- and options- related), and lots of other auxiliary function, of which the most important areaddExtraEvent(logging custom events) andcaptureImage(captures the screen shot and save into JPG file). ETU-Driver notifies client about recording start/stop, finished calibration, new data, and some other events. Last data is always available via propertiesLastSample,LastFixation,LastBlink. The easiest way to change the input device and other options is to callshowRecordingOptionsmethod and make necessary adjustments, but it possible to alter them in code via ETU-Driver properties (Index,Recordingoptions,RecordingSetupData). Device-related options are stored in a specific file nameged by ETU-Driver, but other options are stored in a file that is set viaOptionsFileproperty.Active,Calibrated,Readyproperty indicate the state of a device.

The was the short overview of the ETU-Driver interface, more detailed info (although not quite much) is available in its manual (there is also API-Converter SDK manual )

Sure, the interface is a bit clumsy... Functions and properties of various types are mixed altogether, making it hard to use for developers. But it was the first try, and in those times I was very raw with COM technology.

oleg
oleg's picture
Offline
Joined: Sep 7 2009
Re: Basic API interface

Now it is time to start making suggestions about basic API interface. Actually, the first one is here already:

adrian wrote:

    public interface ITracker
    {
    event GazeDataChangedEventHandler GazeDataChanged;

    bool Connect();
    void CleanUp();

    bool Calibrate();

    void Record();

    long GetCurrentTime();

    void ChangeSettings();
    }

As one may notice, the methods are in general identical to those in the existing APIs, and, indeed, cover most of basic communication between ET system and client application. The only unusual thing here: I do not see any function to stop recording... or does "CleanUp" stands for this purpose?

Actually, at first I had the same plan: expose similar functions (connect/disconnect, start/stop, calibrate/ showOptions and getTimestamp), plus status properties (IsConnected/IsCalibrate/IsTracking), plus getInfo/getParams/setParams, plus a callback (event) function to receive data.

Now I wonder: why do we need "(dis)connect" functions? The API we are going to use should know about the devices installed in the system, so the connections functions and IsConnected property are obsolete. Instead, there should be a function that enumerated system that this API is capable to communicate with: say "enumDevices". A couple of event will be required to handle device status change (available/unavailable). This is somewhat similar to what Tobii TetServerBrowser class does. The read/write property DeviceID will point to what ET system is actually in use what all function in the interface refer to.

Lars Hildebrandt
Re: Basic API interface

It's me again keep posting my usual warnings ;)

These API where very often not designed with a special application in mind. Much of the interface of LC, EyeLink, SMI is there because the eye tracker was able to support these functions or it required some functions to operate.

By defining a standard I would not search for the least common denominator. Look from the application side and decide what data the manufacturer has to support to make the user happy. It then the job of the hardware manufacturer to meet your standards.

Let me pretend to be a hardcore researcher. I am doing gaze contingency experiments, I am doing reading studies, I am implementing customized stimuli for cognitive, neurologic, behavioral experiments. What do I want from the perfect API?

I am not talking about specific functions and API calls at this point. I am talking about funcionallity.

- infrastructure functionality (open,close,version, device etc)
- subject calibration and feedback about calibration quality
- online feedback about tracking quality, ideally a graphical feedback
- real time raw data ( binouclar gaze, pupil diameter, head speed etc. )

Now I am a market researcher or usablity tester. I am implemeting and analyzing scan pathes, heat maps, I am comparing the area of interest sequence of several subjects. What functionallity do I want from the perfect API?

- infrastructure functionality (open,close,version, device etc)
- subject calibration and feedback about calibration quality
- online feedback about tracking quality, ideally a graphical feedback
- online eye events like fixations, saccades, blinks

Last but not least I am a programmer of a gaze interaction software. The functionallity that would make me happy is.
(Remember back the times when you have written your eye games, without knowing much about the eye tracking technology, what kind of API would have make your life easy and enjoyable?)

- infrastructure functionality (open,close,version, device etc)
- subject calibration and feedback about calibration quality
- online feedback about tracking quality, ideally a graphical feedback
- online GUI element activation, attention shift on the user interface, eye gestures GUI element selection

The goal is now to make the API that versatile so that the gaze interaction guy doesn't have to worry about researchers stuff and visa versa. There is functionallity that all users want to have in common. Design the API as if it would be ideal and let the manufacturers do their homework and provide all the functionallity to fit into the API.

The question now is. Is the user list complete? Do you have other application fields in mind? Is the functionallity per user group complete?
Then we can start thinking about how the functions could look like and how the seperation in functionallity could be implemented to the API easy to use for everyone.

Lars Hildebrandt

VP Development

www.alea-technologies.de

oleg
oleg's picture
Offline
Joined: Sep 7 2009
Re: Basic API interface

Lars, I wouldn't make better summary - yours is absolutely perfect! I was trying to think of other user groups or extra needs of those you listed already, but could not find anything better. Thanks a lot!

I was already started making a list of concrete requirement of API when I found this post. Your summary will help me finalizing it.

After the requirements are published, I'll try to make a list of functions, as you suggested, and separate into logical groups (these will be COM interfaces, I guess).

oleg
oleg's picture
Offline
Joined: Sep 7 2009
Re: Basic API interface

After a good discussion, it is time to propose something that may go into standard specification... Lets say, that all the API for Windows is based on COM technology, and the functionality is separated into interfaces. First, some thought of what each interface function may return:

a) S_OK if the context allows to call it, it is supported by API, and arguments are valid,
b) E_NOINTERFACE or E_NOTIMPL if the interface or its function is not supported by API,
c) E_INVALIDARG if one or more arguments are not valid,
d) E_UNEXPECTED (catastrophic failure – the application may be unstable) or E_FAIL (not critical – safe to continue using API) if the function fails for unknown reason, or
e) a specific error value listed in a function description,

Naming: each name has starts with a letter "I" for interface, "D" for events interface, "S" for structures, and "E" for enumeration. Then "ETUDE_" follows, and finally the name itself (for events there is "Events" at the end). BWT, is this name - "ETUDE" is OK? Or "SETAPI" ir better (Standard Eye Tracking API)? Or suggest better name :)

oleg
oleg's picture
Offline
Joined: Sep 7 2009
Re: Basic API interface
OK... time to post something I had already, but was busy with other stuff. Now I drop it "as is" and later edit this post... it is so far from the final form yet...

IETUDE_Browser
• scan()
Recreates a collection of active systems. This is a blocking function and it may take many seconds to complete, therefore it is recommended to run scanning process in a background process at the time the ETSYB object has been created, making the explicit call of this function not necessary (if the implicit scan is in progress at the function call, this function should return after the scan is complete).
• get_SystemsCollection(IETUDE_SystemCollection** aCollection)
• get_SupportingSystemsCollection(IETUDE_SupportingSystemCollection** aCollection)
DETUDE_BrowserEvents
• OnSystemAdded(long aIndex)
aIndex is the index in IETUDE_SupportingSystemCollection.
• OnSystemRemoved(IETUDE_System* aSystem)
aIndex is the index in IETUDE_SupportingSystemCollection. The interface is still available and is listed in the this collection, but its get_IsAvailable() function return 0 (FALSE).
IETUDE_SupportingSystemCollection
• get_Count(long* aCount)
• get_Item(IETUDE_SupporingSystem* aSystem)
IETUDE_SupportingSystem
• get_Manufacturer(BSTR* aValue)
• get_Name(BSTR* aValue)
• get_MinVersion(BSTR* aValue)
• get_MaxVersion(BSTR* aValue)
IETUDE_SystemCollection
• get_Count(long* aCount)
• get_Item(IETUDE_System* aSystem)
IETUDE_System
• get_IsAvailable(long* aResult)
• get_IsCalibrated(long* aResult)
• get_IsTracking(long* aResult)
each class instance hold its own flag of tracking.
• set_IsTracking(long aIsTracking)
Set non-zero value to aIsTracking to start receiving gaze data, otherwise set it to 0.
• get_Manufacturer(BSTR* aValue)
• get_Name(BSTR* aValue)
• get_Version(BSTR* aValue)
• get_Calibration(IETUDE_Calibration** aCalibration)
• get_ConfigurationsCollection(IETUDE_ConfigurationsCollection** aValue)
Optional (may return NULL)
• get_VendorPropertyCollection(IETUDE_PropertyCollection** aPropertyCollection)
Optional (may return NULL)
• showOptions()
Returns S_OK if user presses OK, or S_FALSE if user presses Cancel
• get_TrackQualityReporter(IETUDE_TrackQualityReporter** aReporter)
• get_TimeStamp(double* aTimeStamp)
The parameter gets current system time in seconds
DETUDE_SystemEvents
• OnCalibrated()
Fires when the system calibration state has been changed.
• OnDisconnected()
Fires when the system availability flag changes to "unavailable".
IETUDE_ConfigurationsCollection
• get_Count(long* aCount)
• get_Item(IETUDE_Configuration* aConfiguration)
• get_Active(long* aIndex)
Default value is 0
• set_Active(long aIndex)
IETUDE_Configuration
• get_Name(BSTR* aName)
• get_PropertiesCollection(IETUDE_PropertiesCollection** aPropertiesCollection)
All properties are read-only in this collection (set_Value of each property in the collection does nothing)
IETUDE_PropertiesCollection
• get_Count(long* aCount)
• get_Item(IETUDE_Property* aProperty)
IETUDE_Property
• get_Name(BSTR* aName)
• get_Unit(BSTR* aValue)
• get_Value(VARIANT* aValue)
if VARIANT type is VT_UNKNOWN, then this property is a container of other properties (for the reason of logical grouping) and its value is
IETUDE_PropertiesCollection
• set_Value(VARIANT aValue)
• get_MinValue(VARIANT* aValue)
• get_MaxValue(VARIANT* aValue)
• get_ValueCount(long* aCount)
• get_ValidValue(long aIndex,VARIANT* aValue)
IETUDE_Calibration
• run(float* aQuality)
Returns a value (0..1) of quality of currently set calibration (negative value if the quality evaluation was not performed)
• get_Custom(IETUDE_CustomCalibration** aCustomCalibration)
Returns NULL if not supported
• get_PropertyCollection(IETUDE_PropertyCollection** aPropertyCollection)
Returns NULL if not supported
IETUDE_CustomCalibration
• clear(float aX,float aY,float aRadius)
Clears points in a constructing calibration. Set negative value to radius to clear all calibration points (x and y are ignored in this case)
• addPoint(float aX,float aY)
• getValidity(float aX,float aY,float aRadius,long aCalibration,float* aValidity)
Returns a value between 0 and 1 indicating calibration validity. Set x, y and radius to get the validity of a certain calibration point(s), or set negative value of radius to get overall validity value. Set aCalibration may get the following values: a) -2 to get evaluation of the calibration under construction, b) -1 to get evaluation of the current calibration, c) an index of a named calibration in database.
• getPoints(float aX,float aY,float aRadius,IETUDE_GazePointsCollection** aGazePoints)
Returns a collection of the gaze points of the calibration point(s) at certain area. aGazePoints contains basic binocular samples.
• save(BSTR aName)
Set the calibration in construction as the current calibration. Name is optional.
• get_Count(long* aCount)
Returns the number of saved named calibrations.
• get_Name(long aIndex,BSTR* aName)
Returns the name of saved calibrations.
• load(long aIndex)
Set the calibration of a certain name as the current calibration.
• delete(long aIndex)
Deletes a named calibration from database. Does not affect current calibration.
IETUDE_TrackQualityReporter
• get_TimeWindow(long* aValue)
• set_TimeWindow(long aValue)
• get_CurrentValue(float* aValue)
• get_AlarmThreshold(float* aValue)
• set_AlarmThreshold(float aValue)
• get_WarningThreshold(float* aValue)
• set_WarningThreshold(float aValue)
DETUDE_TrackQualityReporterEvents
• OnAlarm(bool aEntered)
aEntered indicates the direction of quality change (true if quality has dropped)
• OnWarning(bool aEntered)
aEntered indicates the direction of quality change (true if quality has dropped)
IETUDE_TrackStatus
ActiveX component
• setSystem(IETUDE_System aSystem)
• get_IsFull(OLEBOOL* aValue)
• set_IsFull(OLEBOOL aValue)
IETUDE_Mapper
The interface manages a set of objects. The manager allows organizing objects in multiple views, so that it is easy to switch between set of constant objects.
• get_ModelCount (int* aCount)
• get_ModelObject (IETUDE_InteractionModell** aModel)
• get_Model (int* aModelIndex)
• set_Model (int aModelIndex)
• setObjects (int* aView,IETUDE_InteractionObjectCollection* aObjects)
• setView (int aView)
• save (BSTR aFileName)
• load (BSTR aFileName)
IETUDE_InteractionModel
What interaction models could be? Dwell-time based in the simplest one. I suggest using the “secum-time” based model (secum-time = selection cumulative time). The algorithm is the following: the object that receives a sample adds the inter-sample duration value to its secum variable, and other objects extract this value from their secum variable (the resulting value should be limited by 0). When the object’s secum time becomes positive, the event Enter fires; when it becomes 0, the event Leave fires. When this variable becomes greater than SecumTime value, the selection events fires (thus, this model requires one parameter to set - SecumTime).
• get_PropertyCollection(IETUDE_PropertyCollection** aPropertyCollection)
• showOptions()
IETUDE_InteractionObjectCollection
• get_Count(long* aCount)
• get_Item(IETUDE_Object* aObject)
IETUDE_InteractionObject
• get_X(long* aValue)
• set_X(long aValue)
• get_Y(long* aValue)
• set_Y(long aValue)
• get_Width(long* aValue)
• set_Width(long aValue)
• get_Height(long* aValue)
• set_Height(long aValue)
• get_Handle(long* aValue)
• set_Handle(long aValue)
DETUDE_MapperEvents
• OnEnter (IETUDE_Object* aObject)
• OnLeave (IETUDE_Object* aObject)
• OnSelect (IETUDE_Object* aObject)

It should be noted that a GT system is treated as compatible with this standard, it is enough to implement the following interfaces:
IETUDE_Browser
DETUDE_BrowserEvents
IETUDE_SupportingSystemCollection
IETUDE_SupportingSystem
IETUDE_SystemCollection
IETUDE_System
DETUDE_SystemEvents
IETUDE_ConfigurationsCollection
IETUDE_Configuration
IETUDE_PropertiesCollection
IETUDE_Property
IETUDE_Calibration
IETUDE_Data
DETUDE_DataEvents
...plus the simplest data interface (will be described soon in "Gaze data" stream)
oleg
oleg's picture
Offline
Joined: Sep 7 2009
Temporal lock

This branch is temporally locked due to hard spamming. Please, contact administrator if you wish to post any message here.