Home Forums Software Development Checking whether if the eye tracker is connected

Viewing 15 posts - 1 through 15 (of 18 total)
  • Author
    Posts
  • #412
    Cheng Guo
    Participant

    Hello,

    I am currently using the .Net binding of the eyeX library. I would like to know if there is a method that would allow me to check if an eye tracker is physically connected to the computer.

    Also, what is the correct procedure for disconnecting the eye tracker (e.g. when a program quits)?

    Thanks!

    #423
    Robert [Tobii]
    Participant

    Hi,

    1) The connection state of the eye tracker can be checked by adding an event handler to the InteractionContext.ConnectionStateChanged event. Look how this is done in the MinimalGazeDataStream sample in the Unity package.

    2) To disconnect the eye tracker properly, dispose the InteractionContextand InteractionSysteminstances respectivly.

    #427
    Cheng Guo
    Participant

    Hi Robert,

    Thanks for the reply.

    I disconnected the eye tracker from my computer, and I run the MinimalGazeDataStream sample. I see “The connection state is now connected” printed in the console.

    In the eye tracker control panel, it says “No eye tracker was found. Please plug in your eye tracker.”

    Do you know why this is happening? (My guess is that the ConnectionStateChanged means connecting with the eye tracker engine but not the physical connection between the eye tracker and the computer?)

    For disconnect the eye tracker properply, I did this

    
    context.DisableConnection(); // context is InteractionContext
    context = null;
    

    In the MinimalGazeDataStream sample, the InteractionSystem is never instantiated, so I am not sure how to dispose it. Thus, all I can do is to dispose the InteractionContext object. Please let me know if this is correct.

    Thanks.

    #429
    Robert [Tobii]
    Participant

    Sorry, I was thinking of the wrong sample. As you suspected, the ConnectionStateChangedonly checks the connection to the EyeX Engine.

    EDIT: See next reply for an answer to the first question.

    For the other question, it is recommended to instantiate both the InteractionSystem and InteractionContext and dispose them on exit. We might have missed one of these steps on some samples, sorry about that.

    #436
    Jenny [Tobii]
    Participant

    Hi!

    Robert asked me to give you an example of how to retrieve the eye tracking device status. Normally, when the eye tracking device is connected to the computer and up and running, its status would be “Tracking”. If the user has selected “Disable Eye Tracking” in the tray icon menu, the status is normally “Tracking Paused”.

    This is how you can retrieve information about the eye tracking device status through the .NET binding:

    First, where all handlers are registered, register a notification handler and register the context as a settings observer as well:

    context.RegisterNotificationHandler(HandleNotification);
     context.RegisterSettingsObserver(SettingsPaths.EyeTracking);

    Then, add methods for handling notification callbacks:

    private void HandleNotification(InteractionNotification notification)
     {
         if (NotificationType.SettingsChanged == notification.NotificationType)
         {
             OnSettingsReceived((SettingsBag)notification.Data);
         }
     }
    
     private void OnSettingsReceived(SettingsBag data)
     {
         EyeTrackingDeviceStatus deviceStatus;
         var success = data.TryGetSettingValue(out deviceStatus, "eyetracking.state");
    
         if (success)
         {
             Console.WriteLine("Eye Tracking Device Status is: " + deviceStatus);
         }
     }

    Does that give you the information you need?

    #441
    Cheng Guo
    Participant

    Hello Jenny:

    Thanks for the response. I have tried your method that this is what I did:

    1) I have the eye tracker connected and running
    2) I started my program with your code added
    3) while my program is running, I right clicked on the EyeX icon in the system tray (I am running on windows 8) and selected “Disable Eye Tracking”

    After I did step #3, I received an error message in Visual Studio 2012:

    “Tobii.EyeX.Client.InteractionApiException” “Result = InvalidArgument”

    The error was caused by this line of code:

    var success = data.TryGetSettingValue(out deviceStatus, "eyetracking.state");

    oh, I forgot to mention that I am using the REX desktop version hardware.

    What I am trying to solve is to detect eye tracker’s physical connection on program startup. I want to know if the eye tracker is connected so that I can decide to fire up my program or not.

    The solution you provide seems to require the eye tracker to be physically connected first. (I tried to run your code without the eye tracker connected and it would not capture any error).

    #451
    Jenny [Tobii]
    Participant

    Hi again,

    Yep, there was a bug in the client library… It worked well on my computer for some reason, but not on Robert’s. The bug is fixed and I have uploaded new SDK packages that include the fix.

    Ok, so let’s go back to what you actually want to achieve 🙂

    If I understand you correctly, you have an application that there is no point in starting if there is no working eye tracking?

    I believe the Eye Tracking Device Status is what you should use. It does not require the eye tracker to be physically connected and it has a state for when the eye tracker is not connected. But I think the best thing you could do is to make sure that this status is “Tracking” before starting your application. Then everything should be up and running and usable with eye tracking (eye tracker connected, correct screen mapping, calibration – all the ground work that is handled by the EyeX Engine). If the status is not “Tracking”, then something is missing in the setup, or eye tracking is disabled, so eye tracking cannot be used with the application.

    But, something is missing to the code I gave you in the last reply – that code only reports changes to the status.

    This is what you have to do to request the current status:
    After the connection to the EyeX Engine has been established (when there has been a ConnectionStateChanged event with status ConnectionState.Connected), you can make this asynchronous call to retrieve the Eye Tracking Device Status:

    context.GetSettingsAsync(SettingsPaths.EyeTracking, OnSettingsReceived);

    The callback method OnSettingsReceived is the same as in the reply above.

    If you are only interested in making a single call to ask the current status, the above line of code plus the callback method is all you need. If you also want to react to changes to the status, you should keep the other code as well.

    #462
    Cheng Guo
    Participant

    Hello Jenny:

    Great job! Everything works fine now on my computer. The problem is fixed by the new SDK. Thanks for the quick update 🙂

    #2013
    Benjamin Robert
    Participant

    Hello !

    I have the same issue with the C/C++ SDK. Seems like it’s a little bit different.

    Should I create a txCreateInteractorBehavior with a hBehaviorWithoutParameters ? I need to detect whenever the device is plugged or unppluged.

    Thanks

    #2015
    Anders
    Participant

    Hi Benjamin,
    take a look at the MinimalStatusNotifications sample in the C/C++ SDK, it should be a good starting point.

    What you want to do, in the EyeX lingo, is to register a state-changed handler for the TX_STATEPATH_EYETRACKINGSTATE engine state. You don’t have to create any interactors in this case.

    #2017
    Benjamin Robert
    Participant

    Thanks a lot !

    #2020
    Benjamin Robert
    Participant

    Hello again,

    I tried to use the state-change handler and I have an error. Here’s what I do :

    success = txCreateGlobalInteractorSnapshot(
    		_context,
    		InteractorId,
    		&g_hGlobalInteractorSnapshot,
    		&hInteractor) == TX_RESULT_OK;
    
    	success &= txCreateGazePointDataBehavior(hInteractor, &params) == TX_RESULT_OK;
    	
    	success &= txCreateStateBag(_context, &hStateBag, TX_STATEPATH_EYETRACKINGSTATE) == TX_RESULT_OK;
    

    First I create a state bag in my context. Everything is going well at this point but I show you in case I don’t do it the right way. Then I register my State Handler :

    bool EyeXHost::RegisterStateChangedHandler()
    {
    	auto stateChangedTrampoline = [](TX_CONSTHANDLE hState, TX_USERPARAM userParam)
    	{
    		static_cast<EyeXHost*>(userParam)->OnEngineStateChanged(hState);
    	};
    
    	bool success = txRegisterStateChangedHandler(_context, &_stateChangedTicket, TX_STATEPATH_USERPRESENCE, stateChangedTrampoline, this) == TX_RESULT_OK;
    	return success;
    }

    Same way that I do for the engine connection which works fine. Then on the method OnEngineStateChanged :

    void EyeXHost::OnEngineStateChanged(TX_CONSTHANDLE hState)
    {
    	TX_HANDLE hStateBag = TX_EMPTY_HANDLE;
    	TX_BOOL success;
    	TX_INTEGER eyeTrackingState;
    
    	txGetAsyncDataContent(hState, &hStateBag);
    
    	success = txGetStateValueAsInteger(hStateBag, TX_STATEPATH_EYETRACKINGSTATE, &eyeTrackingState) == TX_RESULT_OK;
    	if (success) {
    		switch (eyeTrackingState) {
    		case TX_EYETRACKINGDEVICESTATUS_TRACKING:
    			printf("Eye Tracking Device Status: 'CONNECTED'");
    			connectionSuccess = true;
    			break;
    
    		case TX_EYETRACKINGDEVICESTATUS_DEVICENOTCONNECTED:
    			printf("Eye Tracking Device Status: 'NOT CONNECTED'");
    			connectionSuccess = false;
    			break;
    
    		default:
    			connectionSuccess = true;
    		}
    	}
    	else
    		printf("ERROR");
    
    	txReleaseObject(&hStateBag);
    }

    At this point I always get “ERROR”. But I don’t really understand why txGetStateValueAsInteger won’t return true. It works with the interactor and the Engine Connection callback so I’m not really sure where that come from. If you have any idea it would be great. Sorry if it’s a simple mistake.

    #2030
    Robert [Tobii]
    Participant

    Hi Benjamin,

    It looks like a simple copy/paste error. If you want to listen for changes in the User Presence state, try to replace TX_STATEPATH_EYETRACKINGSTATE with TX_STATEPATH_USERPRESENCE in the txGetStateValueAsInteger function call (row 9 in the last code snippet).

    Then you need to check if the result is TX_USERPRESENCE_PRESENT or TX_USERPRESENCE_NOTPRESENT.

    Moreover, I don’t think the txCreateStateBag row is necessary.

    Please let me know how it goes.

    #2034
    Benjamin Robert
    Participant

    Thanks for your answer.
    I’m a little bit confuse here. In your C example, you have

    success = (txGetStateValueAsInteger(hStateBag, TX_STATEPATH_EYETRACKINGSTATE, &eyeTrackingState) == TX_RESULT_OK);
    	if (success) {
    		switch (eyeTrackingState) {
    		case TX_EYETRACKINGDEVICESTATUS_TRACKING:
    			printf("Eye Tracking Device Status: 'TRACKING'.\n"
    				"That means that the eye tracker is up and running and trying to track your eyes.\n");
    			break;
    
    		default:
    			printf("The eye tracking device is not tracking.\n"
    				"It could be a that the eye tracker is not connected, or that a screen setup or\n"
    				"user calibration is missing. The status code is %d.\n", eyeTrackingState);
    		}
    	}

    txGetStateValueAsInteger takes TX_STATEPATH_EYETRACKINGSTATE has an argument to check if the device is tracking. I want to check if the device is connected, I should check with the same parameter I guess because the parameter is TX_EYETRACKINGDEVICESTATUS_NOTCONNECTED and not something like TX_USERPRESENCE_NOTCONNECTED. I tried with the user presence param but it’s not working to track if the device is connected or not.

    My code :

    void EyeXHost::OnEngineStateChanged(TX_CONSTHANDLE hState)
    {
    	TX_HANDLE hStateBag = TX_EMPTY_HANDLE;
    	TX_BOOL success;
    	TX_INTEGER eyeTrackingState;
    	TX_INTEGER presenceData;
    
    	txGetAsyncDataContent(hState, &hStateBag);
    
    	success = (txGetStateValueAsInteger(hStateBag, TX_STATEPATH_EYETRACKINGSTATE, &eyeTrackingState) == TX_RESULT_OK);
    	if (success) {
    		switch (eyeTrackingState) {
    		case TX_EYETRACKINGDEVICESTATUS_TRACKING:
    			printf("TRACKING");
    			break;
    
    		case TX_EYETRACKINGDEVICESTATUS_DEVICENOTCONNECTED:
    			printf("NOT CONNECTED");
    			break;
    
    		default:
    			printf("The status code is %d.\n", eyeTrackingState);
    		}
    	}
    
    	success = (txGetStateValueAsInteger(hStateBag, TX_STATEPATH_USERPRESENCE, &presenceData) == TX_RESULT_OK);
    	if (success) {
    		printf("User is %s\n", presenceData == TX_USERPRESENCE_PRESENT ? "present" : "NOT present");
    	}
    
    	txReleaseObject(&hStateBag);
    }
    #2037
    Robert [Tobii]
    Participant

    Ok, now I understand. If you are interested in the eye tracker connection you need to pass TX_STATEPATH_EYETRACKINGSTATE in the call to txRegisterStateChangedHandler (row 8 in the second code snippet in post #2020)

    Then, in the switch statement you can choose to handle the device status value you are interested in, one or many of these:
    TX_EYETRACKINGDEVICESTATUS_INITIALIZING,
    TX_EYETRACKINGDEVICESTATUS_NOTAVAILABLE,
    TX_EYETRACKINGDEVICESTATUS_INVALIDCONFIGURATION,
    TX_EYETRACKINGDEVICESTATUS_DEVICENOTCONNECTED,
    TX_EYETRACKINGDEVICESTATUS_TRACKING,
    TX_EYETRACKINGDEVICESTATUS_TRACKINGPAUSED,
    TX_EYETRACKINGDEVICESTATUS_CONFIGURING,
    TX_EYETRACKINGDEVICESTATUS_UNKNOWNERROR,
    TX_EYETRACKINGDEVICESTATUS_CONNECTIONERROR

    See the header documentation in EyeXFrameworkTypes.h to learn more about what each enum value mean.

Viewing 15 posts - 1 through 15 (of 18 total)
  • You must be logged in to reply to this topic.