I am trying to troubleshoot using an NDI trakSTAR electromagnetic 3D tracker using OpenIGTLinkIF. I have gotten the same system working on other computers, but am running into an odd error where the tracked transforms are not being streamed/updated over the connection, which otherwise looks OK.
Plus Server Launcher reports a successful connection, and OpenIGTLinkIF connects and gets an initial transform for all tracked transforms (and other transforms provided in the configuration file. But those transforms are never updated afterwards. Also, I don’t think the initial transforms reported are actually affected by the locations of the tracked sensors, but I’m not sure.
On another laptop I set up last year with the same software, everything works fine and the tracked transforms are updated continuously, using the same configuration file, the same tracker hardware, etc.
The new computer, where it is not working, has a newer version of Slicer (5.6.1 vs 5.2.1), but is otherwise similar (both Windows 10 laptops), same version of Plus. The messages in the log for Plus Server Launcher look identical. There are no messages in the Slicer error log. If I use fCal on the new computer and record transforms, I get varying locations if I move the sensors. I’m a bit at a loss for how to continue troubleshooting.
I just downloaded Slicer 5.2.1 onto the new computer and verified that I get the same behavior (no updating of transforms), so it is not the Slicer version difference. I tried configuring SendValidTransformsOnly to “false” instead of “true” with no effect.
Has anyone else run into a similar issue or have any ideas about how to troubleshoot this?
i am facing a similar issue, did you manage to find a solution?
The initial transform connection is successful, however the transform coordinates doesnt update afterwards, also doesnt seem to change depending on the initial coordinates of the tool to the camera
The root cause seemed to be somewhere in the security stack of software running at my job. I did not get a satisfying answer from out IT department, but everything works fine outside of the corporate network, and shows the behavior above inside the corporate network, so it’s some blockage of communication happening there. I have had temporary success by changing the port number, but after some time, that new port number shows the same behavior (initial connection OK, no error message, but no ongoing communication). My guess is that there is some sort of adaptive filter which is flagging some communication pattern as suspicious and shutting it down, but when I have raised this theory with IT folks, they didn’t seem aware of that as a possibility. Still, since the identical code works on a different port number, and also works outside the corporate network, it seems like the issue has to be somewhere in the corporate security software. It’s a little frustrating, because I’m running the OpenIGTLink server on the same local machine, so there isn’t actually any traffic going out to or in from the wider network, just local communication on the same machine, but I think the method of communication is one that gets intercepted and inspected by the security software and treated as if it were network communication. So, I don’t have a solution for you, but the problem may not be anywhere in your code or setup.
thanks for the fast reply, actually after going in circles and debugging with the help of Claude, i found out what my issue was, it was an issue related to CRC (Cyclic Redundancy Check) is a error-detection algorithm. It takes a block of data and produces a short fixed-size number (the “checksum”) that acts as a fingerprint of that data. If even a single bit in the data changes, the checksum will be completely different.
i was using a wrong (maybe old) polynomial in my application
”CRC64_POLY = 0x95AC9329AC4BC9B5ULL;”
when the right one is the ECMA-182 standard CRC64 polynomial.
CRC64_POLY = 0x42F0E1EBA9EA3693ULL;
When Slicer received each TRANSFORM message, it parsed the header correctly (registering the node name and type), but when it ran CRC validation on the 48-byte body inside its Unpack() function, the checksum didn’t match. Slicer silently discarded every single message to protect the MRML scene from potentially corrupt data. No error was logged, no warning was shown — which is why it was so difficult to diagnose.
When the tracker sends a TRANSFORM message over TCP to Slicer:
[58-byte header] [48-byte body (rotation + translation matrix)]
↓
CRC64 computed
↓
Checksum stored in header bytes 50-57
When Slicer receives it:
Slicer receives the 48-byte body
↓
Slicer computes its own CRC64 of that body
↓
Compares its result against the checksum in the header
↓
Match → accepts and updates MRML node ✓
No match → silently discards the message ✗
i don’t know if that can relate to your issue, but maybe it could help anyone facing the same symptoms.
Just FYI if you are having trouble using the networking you could try using shared memory instead. With modern python versions it’s very easy to do and is cross platform. It can also be handy to use RPyC to coordinate between client and server. We’ve been using this pattern for some simulation experiments (SlicerTMS and SlicerSOFA) but it should also work well for trackers.
Thanks for sharing your solution. Where do you set this CRC algorithm? If it’s possible for this to drift out of sync somehow (or something innocently changes the header) it could possibly be related to the issues I am seeing.
Thanks so much for mentioning this, @pieper , I will look into it. For our purposes, we never need to broadcast the messages over an actual network, the tracker hardware is always connected directly to the same laptop which is running the IGTLink server and Slicer, so an alternate means of communication which sidesteps possible firewall issues sounds great.