Home › Forums › Software Development › Get Eye XYZ Position – cannot find the functions for TX_INTERACTIONBEHAVIORTYPE_
Tagged: c/c++, EyePosition, EyePositonDataEvent, eyex sdk, TobiiX
- This topic has 15 replies, 5 voices, and was last updated 8 years, 9 months ago by
Robert [Tobii].
- AuthorPosts
- 10/07/2014 at 16:12 #1330
Laser Erich
ParticipantHello,
I’m searching for the functions for the TX_INTERACTIONBEHAVIORTYPE_EYEPOSITIONDATA.
I’m tracking the GAZEPOINT as follows:setting the TX_GAZEPOINTDATAPRAMS parms = { TX_GAZEPOINTDATAMODE_LIGHTLYFILTERED };
create the InteractionBehavior:
txCreateInteractorBehavior( … TX_INTERACTIONBEHAVIORYPE_GAZEPOINTDATA)
txSetGazePointDataBehaviorParams( …);creat an EventHandler using txGetGazePointDataEventParams(…)
the same procedure works for FIXATIONDATAPARM …
but I cannot find the corresponding methods for EYEPOSTIONDATAI cannot find the TX_EYEPOSITIONPARAMS and the txSetEyePositonDataBehaviorParams()
(TX_INTERACTIONBEHAVIORTYPE_EYEPOSITIONDATA and txGetEyePostijonDataEventParams() are available)10/07/2014 at 16:25 #1331Anders
ParticipantHi Manuel,
since there are no parameters to be specified for the eye position data stream, you should use the generic function txCreateInteractorBehavior instead.11/07/2014 at 11:38 #1338Laser Erich
ParticipantThank you for the hint.
I create the InteractorBehavior for TX_INTERACTIONBEHAVIORTYPE_EYEPOSITIONDATA now without params.
I registered an eventhandler for TX_INTERACTIONBEHAVIORTYPE_EYEPOSITIONDATA and for TX_INTERACTIONBEHAVIORTYPE_GAZEPOINTDATA but don’t get any EyePositionData Events (only TX_INTERACTIONBEHAVIORTYPE_GAZEPOINTDATA Events)
How do I get Tobii to create EYEPOSITIONDATA Events?
11/07/2014 at 13:25 #1339Laser Erich
ParticipantAdditinally (I think I found my error):
I create the behavior for the EyePositionInteractor via
txCreateInteractorBehavior(eyePositionInteractor, &eyePositionBehavior, TX_INTERACTIONBEHAVIORTYPE_EYEPOSITIONDATA);And if I check if the result is
TX_RESULT_OK
that’s false.How am I supposed to change?
11/07/2014 at 14:46 #1340Laser Erich
ParticipantI’m still trying to get the gazePosition and eyePosition from TobiiEyeX simultaniously.
I can initiate and register TX_INTERACTIONBEHAVIORTYPE_EYEPOSITIONDATA and TX_INTERACTIONBEHAVIORTYPE_GAZEPOINTDATA seperatly, but when try to create two interactors, the second one won’t work.
I tried to create two seperate TX_CONTEXTHANDLEs and two different Interactors with no success.
Is it possible to track gazepoint and eyeposition simultaniously?11/07/2014 at 15:15 #1342Anders
ParticipantHi Manuel,
it’s certainly possible to get gaze position and eye position simultaneously.You can use one interactor or two, that doesn’t matter. But you should only set up one context and one event handler function.
Here’s how I did it. I started from the MinimalGazeDataStream.c sample and modified the InitializeGlobalInteractorSnapshot function like so:
BOOL InitializeGlobalInteractorSnapshot(TX_CONTEXTHANDLE hContext) { ... TX_HANDLE hBehavior = TX_EMPTY_HANDLE; ... success &= txCreateInteractorBehavior(hInteractor, &hBehavior, TX_INTERACTIONBEHAVIORTYPE_EYEPOSITIONDATA) == TX_RESULT_OK; txReleaseObject(&hBehavior); txReleaseObject(&hInteractor); return success; }
Note that hBehavior has to be initialized to TX_EMPTY_HANDLE or else the call will fail.
And then, in the HandleEvent function I added a clause like so:
if (txGetEventBehavior(hEvent, &hBehavior, TX_INTERACTIONBEHAVIORTYPE_EYEPOSITIONDATA) == TX_RESULT_OK) { printf("gotcha!\n"); txReleaseObject(&hBehavior); }
11/07/2014 at 15:36 #1344Laser Erich
ParticipantFirst of all thank you.
That’s exactly what I’m doing:
TX_HANDLE eyePositionInteractor = TX_EMPTY_HANDLE; TX_HANDLE eyePositionBehavior = TX_EMPTY_HANDLE; bool success; success = txCreateGlobalInteractorSnapshot(hContext, InteractorId2, &g_hGlobalInteractorSnapshot, &eyePositionInteractor) == TX_RESULT_OK; success &= txCreateInteractorBehavior(eyePositionInteractor, &eyePositionBehavior, TX_INTERACTIONBEHAVIORTYPE_EYEPOSITIONDATA) == TX_RESULT_OK; txReleaseObject(&eyePositionBehavior); txReleaseObject(&eyePositionInteractor); return success;
And then, for the second interactor i call
TX_HANDLE gazeInteractor = TX_EMPTY_HANDLE; TX_HANDLE gazeBehavior = TX_EMPTY_HANDLE; TX_GAZEPOINTDATAPARAMS params = { TX_GAZEPOINTDATAMODE_LIGHTLYFILTERED }; bool success; success = txCreateGlobalInteractorSnapshot(hContext, InteractorId, &g_hGlobalInteractorSnapshot, &gazeInteractor) == TX_RESULT_OK; success &= txCreateInteractorBehavior(gazeInteractor, &gazeBehavior, TX_INTERACTIONBEHAVIORTYPE_GAZEPOINTDATA) == TX_RESULT_OK; success &= txSetGazePointDataBehaviorParams(gazeBehavior, ¶ms) == TX_RESULT_OK; txReleaseObject(&gazeBehavior); txReleaseObject(&gazeInteractor); return success;
But only the first initialized interactor will do it’s work…
PS: the second initialization returns false
11/07/2014 at 16:18 #1347Laser Erich
Participantok – found a solution.
when using just one TX_HANDLE INTERACTOR and assigning it to both TX_HANDLE BEHAVIORs I get an event containing both datastreams.
21/10/2014 at 14:45 #1876Edward Ryklin
ParticipantSince upgrading to TobiiEyeXSdk-Cpp-0.32.384, this problem reemerges.
Code used before the upgrade that use to work, but now only the first call to CreateIteractorBehavior will work (in this case gaze data) :
BOOL BeethovenTobiiEyeX::InitializeGlobalInteractorSnapshot(TX_CONTEXTHANDLE hContext)
{
TX_HANDLE hInteractor = TX_EMPTY_HANDLE;
TX_HANDLE hBehavior = TX_EMPTY_HANDLE;
TX_GAZEPOINTDATAPARAMS params = { TX_GAZEPOINTDATAMODE_LIGHTLYFILTERED };
BOOL success;success = txCreateGlobalInteractorSnapshot(
hContext,
InteractorId,
&g_hGlobalInteractorSnapshot,
&hInteractor) == TX_RESULT_OK;success &= txCreateInteractorBehavior(hInteractor, &hBehavior, TX_BEHAVIORTYPE_GAZEPOINTDATA) == TX_RESULT_OK;
success &= txSetGazePointDataBehaviorParams(hBehavior, ¶ms) == TX_RESULT_OK;success &= txCreateInteractorBehavior(hInteractor, &hBehavior, TX_BEHAVIORTYPE_EYEPOSITIONDATA) == TX_RESULT_OK;
success &= txSetGazePointDataBehaviorParams(hBehavior, ¶ms) == TX_RESULT_OK;txReleaseObject(&hBehavior);
txReleaseObject(&hInteractor);
return success;
}Code after :
BOOL BeethovenTobiiEyeX::InitializeGlobalInteractorSnapshot(TX_CONTEXTHANDLE hContext)
{
TX_HANDLE hInteractor = TX_EMPTY_HANDLE;TX_GAZEPOINTDATAPARAMS params = { TX_GAZEPOINTDATAMODE_UNFILTERED };
BOOL success;success = txCreateGlobalInteractorSnapshot(
hContext,
InteractorId,
&g_hGlobalInteractorSnapshot,
&hInteractor) == TX_RESULT_OK;success &= txCreateGazePointDataBehavior(hInteractor, ¶ms) == TX_RESULT_OK;
txReleaseObject(&hInteractor);
return success;
}Note, that here the function
txCreateInteractorBehaviorhas been replaced with
txCreateGazePointDataBehaviorand
txSetGazePointDataBehaviorParams
has been removed.there is no function “like” txCreateGazePointDataBehavior for EyePointData.
21/10/2014 at 14:46 #1877Edward Ryklin
ParticipantIn addition, since upgrading to TobiiEyeXSdk-Cpp-0.32.384
The eye position coordinates are inverted, which requires we multiply by -1.
The eye position is offset with screenWidth/2 and screenHeight/2
Please follow up to confirm.
21/10/2014 at 19:24 #1880Anders
ParticipantHi Edward,
I think the problem in your code snippet (“code before”) is that the hBehavior handle isn’t released between the calls to txCreateInteractorBehavior. If you add a txReleaseHandle in between, the code should still work. The EyeX API now validates that the handles are set to TX_EMPTY_HANDLE on input, and since the handle is set to a valid behavior by the first call the validation will fail.
Note that you still have the choice to use the txCreateInteractorBehavior/txSetXyzBehaviorParams form, as you did in your “Code before” sample. You don’t have to use the shorthand form as shown in your “Code after” sample.
Here is a code snippet demonstrating how to add multiple data streams. (Cut and paste into the MinimalGazeDataStreams sample if you want to try it.)
BOOL InitializeGlobalInteractorSnapshot(TX_CONTEXTHANDLE hContext) { TX_HANDLE hInteractor = TX_EMPTY_HANDLE; TX_GAZEPOINTDATAPARAMS params = { TX_GAZEPOINTDATAMODE_LIGHTLYFILTERED }; TX_FIXATIONDATAPARAMS fixationDataParams = { TX_FIXATIONDATAMODE_SENSITIVE }; TX_HANDLE hBehaviorWithoutParameters = TX_EMPTY_HANDLE; BOOL success; success = txCreateGlobalInteractorSnapshot( hContext, InteractorId, &g_hGlobalInteractorSnapshot, &hInteractor) == TX_RESULT_OK; success &= txCreateGazePointDataBehavior(hInteractor, ¶ms) == TX_RESULT_OK; // add a second behavior to the same interactor: fixation data success &= txCreateFixationDataBehavior(hInteractor, &fixationDataParams) == TX_RESULT_OK; // add a third behavior to the same interactor: eye position data. // this one is a bit different because it doesn't take any parameters. // therefore we use the generic txCreateInteractorBehavior function (and remember to release the handle!) success &= txCreateInteractorBehavior(hInteractor, &hBehaviorWithoutParameters, TX_BEHAVIORTYPE_EYEPOSITIONDATA) == TX_RESULT_OK; txReleaseObject(&hBehaviorWithoutParameters); txReleaseObject(&hInteractor); return success; }
As for the question regarding eye position coordinates: you are absolutely correct that the coordinate system used has its origin at the center of the screen. But what makes me puzzled is that it has been that way (in the EyeX API, not in the Gaze API!) for as long as I can remember.
04/11/2014 at 06:53 #1959zhangmeng
Participantthe right code is like this:
BOOL InitializeGlobalInteractorSnapshot(TX_CONTEXTHANDLE hContext) { TX_HANDLE hInteractor = TX_EMPTY_HANDLE; TX_GAZEPOINTDATAPARAMS params = { TX_GAZEPOINTDATAMODE_LIGHTLYFILTERED }; TX_FIXATIONDATAPARAMS fixationDataParams = { TX_FIXATIONDATAMODE_SENSITIVE }; TX_HANDLE hBehaviorWithoutParameters = TX_EMPTY_HANDLE; BOOL success; success = txCreateGlobalInteractorSnapshot( hContext, InteractorId, &g_hGlobalInteractorSnapshot, &hInteractor) == TX_RESULT_OK; success &= txCreateGazePointDataBehavior(hInteractor, ¶ms) == TX_RESULT_OK; // add a second behavior to the same interactor: fixation data success &= txCreateFixationDataBehavior(hInteractor, &fixationDataParams) == TX_RESULT_OK; // add a third behavior to the same interactor: eye position data. // this one is a bit different because it doesn't take any parameters. // therefore we use the generic txCreateInteractorBehavior function (and remember to release the handle!) success &= txCreateInteractorBehavior(hInteractor, &hBehaviorWithoutParameters, TX_BEHAVIORTYPE_EYEPOSITIONDATA) == TX_RESULT_OK; txReleaseObject(&hBehaviorWithoutParameters); txReleaseObject(&hInteractor); return success; } and get data, the code is: void OnGazeDataEvent(TX_HANDLE hGazeDataBehavior) { //TX_GAZEPOINTDATAEVENTPARAMS eventParams; TX_EYEPOSITIONDATAEVENTPARAMS eventParams; //printf ("%d", txGetEyePositionDataEventParams(hGazeDataBehavior, &eventParams)); //printf ("%d", TX_RESULT_OK);//TX_RESULT_INVALIDBEHAVIORTYPE //printf ("%d", TX_RESULT_INVALIDBEHAVIORTYPE); if (txGetEyePositionDataEventParams(hGazeDataBehavior, &eventParams) == TX_RESULT_OK) { //if (txGetGazePointDataEventParams(hGazeDataBehavior, &eventParams) == TX_RESULT_OK) { printf("Gaze Data: timestamp %d ms\n", eventParams.HasLeftEyePosition); //printf("Gaze Data: (%.1f, %.1f) timestamp %.0f ms\n", eventParams.X, eventParams.Y, eventParams.Timestamp); } else { printf("Failed to interpret gaze data event packet.\n"); printf ("Error code: %d.\n", txGetEyePositionDataEventParams(hGazeDataBehavior, &eventParams)); } } Next, there is a small detail you should not ignore: if (txGetEventBehavior(hEvent, &hBehavior, TX_BEHAVIORTYPE_EYEPOSITIONDATA) == TX_RESULT_OK) { OnGazeDataEvent(hBehavior); txReleaseObject(&hBehavior); }
That is all, So the eye data can be got successfully.
01/12/2014 at 05:53 #2129Edward Ryklin
ParticipantAfter upgrading to Tobii EyeX 1.0.0 the RIGHT eye position is noticeably broken. Yes I also upgraded to SDK for C++ 1.1
Furthermore, the code samples above are inadequate. There is some asynchronous problem that ensues. Again this was not an issue in earlier versions.
This is a huge waste of my time. I don’t want to debug your product for you.
01/12/2014 at 15:45 #2132Robert [Tobii]
ParticipantHi Edward,
I’m sure we can work out a solution for you. Can you please just be a bit more specific on what the problems are, i.e:
1) In which way is the right eye position broken? Do you get any data at all or is the data just noisier than before?
2) What kind of asynchronous problems have you experienced?
3) When you are referring to “earlier versions” of Tobii SDKs, do you mean the Gaze SDK or Analytics SDK?01/12/2014 at 16:33 #2135Edward Ryklin
ParticipantThis did not happen in earlier versions of the eyeX SDK. This has no bearing on the Gaze SDK for Rex, or Analytics SDK which doesn’t even work with the EyeX.
Lets burn more time on this…
when the HandleEvent function is called, and the event type is determined to be TX_BEHAVIORTYPE_EYEPOSITIONDATA, we were instructed to process it as follows:
if (txGetEventBehavior(hEvent, &hBehavior, TX_BEHAVIORTYPE_EYEPOSITIONDATA) == TX_RESULT_OK) {
OnPositionDataEvent(hBehavior);
txReleaseObject(&hBehavior);
}The OnPositionDataEvent function gets the eyeposition information by the following method:
if (txGetEyePositionDataEventParams(hPositionDataBehavior, &eventParams) == TX_RESULT_OK) {
}
here, the eventParams.RightEyeX and eventParams.RightEyeY return invalid values, for no apparent reason.
Specifically, they will be both set to a value such as -9.2559631349317831e+061
While the LeftEyeX and LeftEyeY values will be set to acceptable values corresponding to the range of pixels found in my display.
The EyeDetection Indicator widget shows both my eyes are detected properly.
Regarding the asynchronous problem… I can’t provide you with exact details yet, however I can say this much. It is logical that for each gaze coordinate their is an eye position value. That would be necessary to render the location of the eyes and gaze simultaneously. It seems that the SDK is designed to deliver these parameters asynchronously, and therefore can not guarantee that there is an eye and gaze coordinate for each sample. In fact, I believe that the HandleEvent function can be called by an eye position event while it is still processing a gaze position event. That is likely to be the problem. This did not happen in earlier versions of the EyeX SDK.
It is particularly frustrating and a huge time drain when SDK upgrades break existing functionality and force developers to reprogram previously working code for ostensibly no good reason! Please do not release SDK updates until you have tested and retested every single unit, and do not deprecate functions every time there is an update. I am neither interested in refactoring function names just because your developers thought of a better naming convention, nor of posting these rants online.
- AuthorPosts
- You must be logged in to reply to this topic.