WIP: optitrack: disable closed-source natnet by default and update libmoti… - #30
WIP: optitrack: disable closed-source natnet by default and update libmoti…#30Lorite wants to merge 8 commits into
Conversation
|
It's a bit complicated with so many submodules. I need to create a PR in the libmotioncapture repo first and then update this PR with the correct submodule. But I want to get your thoughts first. The main issue I had was a segfault when running with |
|
Thanks! I am also fine with generally disabling the closed_source version by default. I wouldn't touch the cache itself - your new instructions in the readme are enough for people to know how to trigger a clean build. Would be very interested in your libmotioncapture changes. Which Motive version are you using (we test with 3.1)? |
Pulls the optitrack handshake refactor so Motive routes unicast frames to the data socket (port 1511) instead of the ephemeral command-socket port. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Three fixes around shutdown and connection robustness:
1. Run MotionCapture::connect() in std::async and poll rclcpp::ok()
in the main thread. The previous blocking call would hang
forever on Ctrl+C if the NatNet server was unreachable
(e.g. wrong host, Motive not running), because the constructor's
non-throwing receive_from loop silently retried on EINTR.
2. Wrap mocap->waitForNextFrame() in try/catch. SIGINT during the
blocking UDP recv inside boost::asio causes the next recv to
return EBADF (the socket gets closed by rclcpp's shutdown path
while boost::asio is mid-retry), which boost::asio rethrows as
system_error("close: Bad file descriptor") and crashes with
std::terminate. Catch and break the loop if rclcpp::ok() is false;
otherwise re-throw the unexpected error.
3. Bump libmotioncapture submodule to pick up the NAT_KEEPALIVE
unicast-session fix (see libmotioncapture/docs/optitrack_natnet_keepalive.md).
Without it, Motive expires the unicast session after ~10 s with
NAT_DISCONNECTBYTIMEOUT and the stream silently stops.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The connect path used std::async(std::launch::async, ...). When SIGINT arrived during the blocking NatNet handshake, the main loop saw rclcpp::ok() flip false, logged "Shutdown requested while connecting — exiting." and tried to return — but the std::async future's destructor blocks until the async task completes, and the handshake worker was stuck in libmotioncapture's receive_message retry loop (up to ~400 s when no NAT_MODELDEF reply arrives). The process therefore appeared hung after the log line, requiring a manual kill. Replace std::async with std::thread plus a shared_ptr<atomic<>> handoff, and detach() on the abort path. The detached worker is reaped by the OS when the process exits; the shared_ptr keeps the result slot alive for any late write so the abandoned worker can never reference a stack local that has already unwound. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Pulls the optitrack fix that re-issues NAT_REQUEST_MODELDEF whenever Motive flips the bTrackedModelsChanged frame bit or a frame carries a rigid-body ID we don't have a name for, so assets enabled mid-session get their real name instead of being stuck on rigid_body_<ID>. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…st retry Pulls in cd665e1 (bound the handshake wait by time instead of 200 receives, re-send the request every 2 s, report discarded-packet counts) and d6406a2 (record the measured fragmented-UDP evidence). See the 2026-07-30 fragment-ceiling findings in the main repo's cross_host_ros2_dds_discovery.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
libmotioncapture has supported cfg["interface_ip"] (pin the NatNet multicast group join on multi-homed hosts) since the fork work, but the node never passed it, so Motive multicast mode was unreceivable on any host whose default route points away from the mocap network. Declares interface_ip (default 0.0.0.0 = kernel picks, the old behavior) and forwards it. Submodule bump picks up the wildcard-bind fix (abb66aa) that makes the pin actually work for multicast reception.
Please read the comment below as well :)