dcnieho / Titta

Matlab and PsychToolbox interface to Tobii eye trackers using Tobii Pro SDK
Other
42 stars 15 forks source link

Cannot reliably find Spectrum Pro #72

Open iandol opened 10 months ago

iandol commented 10 months ago

Hi Dee, I am finally back to doing Tobii stuff, and should be doing lab stuff over the next week. I was trying to set up to test the new advanced calibration, but I can't connect to the Spectrum! ETM works and connects, but Titta is not finding the Spectrum:

>> clear all
>> settings = Titta.getDefaults('Tobii Pro Spectrum');
>> settings.debugMode=true;
>> t = Titta(settings)
>> t.init
Warning: Titta: No eye trackers of model 'Tobii Pro Spectrum' connected 
> In Titta/init (line 540) 
Warning: Titta: No eye trackers of model 'Tobii Pro Spectrum' connected 
> In Titta/init (line 540) 
Warning: Titta: No eye trackers of model 'Tobii Pro Spectrum' connected 
> In Titta/init (line 540) 
Error using Titta/init
Titta: No eye trackers of model 'Tobii Pro Spectrum' connected
No eye trackers connected. 

Interestingly, the MATLAB Pro SDK also fails:

>> e=EyeTrackingOperations;
>> e.find_all_eyetrackers()
ans =
     []

BUT Python SDK does work:

>>> import tobii_research as tr
>>> e=tr.find_all_eyetrackers()
>>> e[0].model
'Tobii Pro Spectrum'
>>> e[0].address
'tet-tcp://169.254.7.39'

Passing Address

So although the MATLAB SDK cannot find the Spectrum, if I pass the address found from Python then it can find the Spectrum:

>> clear all
>> e=EyeTrackingOperations;
>> e.find_all_eyetrackers()
ans =
     []
>> e.get_eyetracker('tet-tcp://169.254.7.39')
ans = 
  EyeTracker with properties:

                  Name: 'TPSP1-010109521381'
          SerialNumber: 'TPSP1-010109521381'
                 Model: 'Tobii Pro Spectrum'
       FirmwareVersion: '2.9.0-oculus-0'
        RuntimeVersion: 'Legacy TTP (4.24.0/33)'
               Address: 'tet-tcp://169.254.7.39'
    DeviceCapabilities: [1 2 4 8 32 256 512]

BUT Titta does not accept an address at initialisation. I tried to pass the serial number but no luck:

>> settings = Titta.getDefaults('Tobii Pro Spectrum');
>> settings.serialNumber='TPSP1-010109521381'
settings = 
  struct with fields:

             tracker: 'Tobii Pro Spectrum'
        trackingMode: 'human'
                freq: 600
        calibrateEye: 'both'
        serialNumber: 'TPSP1-010109521381'
         licenseFile: ''
       nTryReConnect: 3
    connectRetryWait: [1 2]
                  UI: [1×1 struct]
                 cal: [1×1 struct]
                 val: [1×1 struct]
              advcal: [1×1 struct]
           debugMode: 0
>> t=Titta(settings)
t = 
  Titta with properties:

                    geom: []
        calibrateHistory: []
                  buffer: []
              deviceName: []
            serialNumber: []
                   model: []
         firmwareVersion: []
          runtimeVersion: []
                 address: []
            capabilities: []
    supportedFrequencies: []
          supportedModes: []
              systemInfo: []
               frequency: []
            trackingMode: []
>> t.init()
Warning: Titta: No eye trackers of model 'Tobii Pro Spectrum' connected 
> In Titta/init (line 540) 
Warning: Titta: No eye trackers of model 'Tobii Pro Spectrum' connected 
> In Titta/init (line 540) 
Warning: Titta: No eye trackers of model 'Tobii Pro Spectrum' connected 
> In Titta/init (line 540) 
Error using Titta/init
Titta: No eye trackers of model 'Tobii Pro Spectrum' connected
No eye trackers connected. 

So, I suspect there is a new SDK Linux bug with mDNS/Avahi that affects discovery for C and MATLAB (but not Python), which is annoying, but the workaround (using an address to find the ET), is not available in Titta. It would be good if we could pass an address, it may help this case?

iandol commented 10 months ago

I modified Titta.init() to pass an optional address, if the address is passed it skips finding eyetrackers, and passes the address to TittaMex.init, and this works.

Patch:

diff --git a/Titta.m b/Titta.m
index 132c34f..b6e59f7 100644
--- a/Titta.m
+++ b/Titta.m
@@ -499,15 +499,18 @@ classdef Titta < handle
             end
         end

-        function out = init(obj)
+        function out = init(obj, address)
             % Initialize Titta instance
             %
-            %    Titta.init() uses the currently active settings to 
+            %    Titta.init([address]) uses the currently active settings to 
             %    connects to the indicated Tobii eye tracker and
-            %    initializes it.
+            %    initializes it. If you pass an optional [address], instead
+           %    of searching for eyetrackers it tries to open [address].
             % 
             %    See also TITTA.TITTA, TITTA.GETOPTIONS, TITTA.SETOPTIONS

+           if ~exist('address','var'); address = []; end
+
             % Load in our callback buffer mex
             obj.buffer = TittaMex();
             obj.buffer.startLogging();
@@ -519,7 +522,7 @@ classdef Titta < handle
             else
                 wfunc = @pause;
             end
-            while true
+            while isempty(address)
                 if iTry<obj.settings.nTryReConnect+1
                     func = @warning;
                 else
@@ -575,8 +578,12 @@ classdef Titta < handle
                     break;
                 end
            end
-            % get our instance
+
+           if isempty(address)
                theTracker = trackers(qTracker);
+           else
+               theTracker.address = address;
+           end

             % provide callback buffer mex with eye tracker
             obj.buffer.init(theTracker.address);

I can make a pull request (adding docs to readme) if you want...

dcnieho commented 10 months ago

Hi Ian, I do not know where the problem comes from, haven't seen it (but then i do not regularly use Linux). Is this one system or do you see it on others too? Glad you found this solution (and glad i exposed the constructor using the address in the MEX, even if the matlab-side didn't use it. Yes, I'd love a pull request, lets make this available, there are probably more use cases than yours.

iandol commented 10 months ago

I think this is an mDNS problem somewhere, Tobii uses mDNS to find their eyetrackers, so a change in either their code or the avahi daemon which manages this is the likely culprit. I haven't checked on other machines yet, so it is possible this is some local glitch. I've posted a support request to Tobii anyway to see if they can reproduce.

Pull: https://github.com/dcnieho/Titta/pull/73

I'll have a look through the controller idea later today, the new advanced UI looks nice though I had problems getting a good calibration with it compared to a basic automatic on myself.

dcnieho commented 9 months ago

I'll leave this open as i can't be sure where the problem is for now... Would you mind testing if https://pypi.org/project/TittaPy/ shows the issue:

import TittaPy
ets = TittaPy.find_all_eye_trackers()
print(ets)

run that a few times in a loop as it may fail every now and then

iandol commented 9 months ago

Hi @dcnieho — yes it seems to work fine in TittaPy (Python 3.12), which confuses me as i thought tittaPy was a wrapper for the C SDK and therefore should have the same problem?

iandol commented 9 months ago

Note, the feedback from tobii engineers was this discovery problem is some mDNS issue but they couldn't reproduce it on their setup...

dcnieho commented 9 months ago

Hi @iandol. Yeah, TittaPy is just a wrapper around the C SDK, same as TittaMex is, which is why i asked you to test. So, very strange!...

iandol commented 9 months ago
Python 3.12.1 (main, Jan 16 2024, 10:35:26) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import TittaPy
>>> ets = TittaPy.find_all_eye_trackers()
>>> print(ets)
[{'device_name': 'TPSP1-010109521381', 'serial_number': 'TPSP1-010109521381', 'model': 'Tobii Pro Spectrum', 'firmware_version': '2.9.0-oculus-0', 'runtime_version': 'Legacy TTP (4.24.0/33)', 'address': 'tet-tcp://169.254.7.39', 'frequency': 600.0, 'tracking_mode': 'human', 'capabilities': [<capability.can_set_display_area: 1>, <capability.has_external_signal: 2>, <capability.has_eye_images: 4>, <capability.has_gaze_data: 8>, <capability.can_do_screen_based_calibration: 32>, <capability.can_do_monocular_calibration: 256>, <capability.has_eye_openness_data: 512>], 'supported_frequencies': [1200.0, 600.0, 300.0, 150.0, 120.0, 60.0], 'supported_modes': ['human', 'monkey', 'great_ape', 'small_monkey']}]

But still nothing in MATLAB, e.g.

>> settings = Titta.getDefaults('Tobii Pro Spectrum');
>> t = Titta(settings);
>> t.init
Warning: Titta: No eye trackers of model 'Tobii Pro Spectrum' connected 
> In Titta/init (line 557) 
Warning: Titta: No eye trackers of model 'Tobii Pro Spectrum' connected 
> In Titta/init (line 557) 
Warning: Titta: No eye trackers of model 'Tobii Pro Spectrum' connected 
> In Titta/init (line 557) 
Error using Titta/init
Titta: No eye trackers of model 'Tobii Pro Spectrum' connected
No eye trackers connected. 
>> e=EyeTrackingOperations;
>> e.find_all_eyetrackers()
ans =
     []

There is something being triggered only via the MATLAB interface...

dcnieho commented 9 months ago

I really cannot imagine what that would be. Its exactly the same code under the hood of course, just different wrapper around it for calling that Titta function and converting the return value. Is this only on one system?

iandol commented 9 months ago

I've seen the same problem on two different workstations, but that could be that I use the same software tools on each (I use a script to automate my Linux install). But apart from using zerotier as a seperate private network, my network setup is very standard. I use a seperate PCIE network card only for Tobii using the recommended settings, something which always worked without issue before. Passing the address is a fair workaround for the moment... Anyway I think we can close this, thanks @dcnieho!

dcnieho commented 9 months ago

I hope this is one of these things that resolves itself again. Glad you can work with what you have now, and thanks for the new feature!

On Sat, Jan 27, 2024 at 10:03 AM Ian Max Andolina @.***> wrote:

I've seen the same problem on two different workstations, but that could be that I use the same software tools on each (I use a script to automate my Linux install). But apart from using zerotier as a seperate private network, my network setup is very standard. I use a seperate PCIE network card only for Tobii using the recommended settings, something which always worked without issue before. Passing the address is a fair workaround for the moment... Anyway I think we can close this, thanks @dcnieho https://github.com/dcnieho!

— Reply to this email directly, view it on GitHub https://github.com/dcnieho/Titta/issues/72#issuecomment-1913084221, or unsubscribe https://github.com/notifications/unsubscribe-auth/AANUOGMUED3JXMBZAXX2KCTYQS7EJAVCNFSM6AAAAABCD2727GVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSMJTGA4DIMRSGE . You are receiving this because you were mentioned.Message ID: @.***>

paul-gallenkemper commented 2 weeks ago

Just wanted to drop here that also we have trouble connecting to the Pro Spectrum from our Linux (Ubuntu 24) Matlab without passing the Eyetracker's address to Titta. Also, for some reason, the address is not the one listed in the Tobii Eye Tracker Manager (tobii-prp:///169.254.11.151) but tet-tcp://169.254.11.151 Just in case anyone runs into similar issues

dcnieho commented 1 week ago

Thanks for adding that @paul-gallenkemper! It would help others. I think (but do not know) this may have something to do with the release of Tobii Pro SDK 2.0. They apparently have a different way of connecting to eye trackers there that should be more reliable (yay!). I suppose this new way of connecting also comes with a new address. More generally, i understand they are looking to improve their support on non-Windows platforms, so hopefully these issues, if they still persist, will be resolved.

However, the new SDK also drops support for all eye trackers other than the ones currently sold, which means i can't easily upgrade. Plenty of these (e.g. the TX300, X2-60, etc) still see a lot of use, and i don't want to drop support for it, nor get to a place where the last version of titta that supported all these "legacy" eye trackers is a certain version, and users of those wouldn't benefit of any new features.

So I'll have to redesign the Titta backend, dynamically loading both dlls and using the appropriate one depending on indicated eye tracker type (eye tracker discovery should presumably use both...). Hairy and complicated, I'm not ready to implement that yet.

The alternative is to keep two mex files around, one for the 1.0 sdk and one for the 2.0 sdk. Then the logic can just be kept to the MATLAB and Python code which simplifies things a bunch. Don't know yet...

iandol commented 1 week ago

Yikes, breaking backwards compatibility with their own still-working hardware isn't the ideal way for them to go (Eyelink API continues to work almost identically across everything they've made in the last decades). I think your latter approach sounds more sensible and less difficult for you, though I wonder if the SDK features themselves diverge what problem you might face going forwards?

dcnieho commented 1 week ago

@iandol: I also wish it wasn't this way. Yes, that is a worry indeed. So far, there are no functional differences of interest (except the new way to connect), so i have just stuck with the latest 1.x SDK. It would be nicer to solve it all behind the scenes. I'll keep thinking about it, there may be other solutions still, such as wrapping each SDK version in my own DLL, which then function as plugins for the main Titta C++ code.