From 1934124c40c9d8e087af798c5f7722dd1f802583 Mon Sep 17 00:00:00 2001 From: PhysicistJohn <54456354+PhysicistJohn@users.noreply.github.com> Date: Fri, 12 Jun 2026 10:01:57 -0700 Subject: [PATCH] Fix DDS init on modern kernels: idempotent ChannelFactory.Init + relax cyclonedds pin Two stacked failures on Ubuntu 24.04 (kernel 6.x): 1. cyclonedds 0.10.2's Domain creation hangs indefinitely on recent kernels, so run_sim_loop.py dies at ChannelFactoryInitialize with no error. Relax the pin to >=0.10.2,<12 (the SDK works unmodified against cyclonedds 11.x). 2. With cyclonedds >= 11, re-creating a Domain for the same id in one process raises DDSException ("Occurred upon initialisation of a cyclonedds.domain.Domain"). run_sim_loop.py initializes the channel factory from both the control loop and the simulator, so the second Init failed the whole loop: ChannelFactoryInitialize(0, 'lo') # ok ChannelFactoryInitialize(0, 'lo') # raises ChannelFactory is already a Singleton; make Init a no-op when the domain is live. --- external_dependencies/unitree_sdk2_python/setup.py | 2 +- .../unitree_sdk2_python/unitree_sdk2py/core/channel.py | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/external_dependencies/unitree_sdk2_python/setup.py b/external_dependencies/unitree_sdk2_python/setup.py index 54d8cac8a..ad2252e61 100644 --- a/external_dependencies/unitree_sdk2_python/setup.py +++ b/external_dependencies/unitree_sdk2_python/setup.py @@ -14,7 +14,7 @@ }, python_requires='>=3.8', install_requires=[ - "cyclonedds==0.10.2", + "cyclonedds>=0.10.2,<12", "numpy", "opencv-python", ], diff --git a/external_dependencies/unitree_sdk2_python/unitree_sdk2py/core/channel.py b/external_dependencies/unitree_sdk2_python/unitree_sdk2py/core/channel.py index daacc6323..1f7f603d6 100644 --- a/external_dependencies/unitree_sdk2_python/unitree_sdk2py/core/channel.py +++ b/external_dependencies/unitree_sdk2_python/unitree_sdk2py/core/channel.py @@ -196,6 +196,13 @@ def __init__(self): super().__init__() def Init(self, id: int, networkInterface: str = None, qos: Qos = None): + # Idempotent: the factory is a Singleton, and re-creating the Domain for + # the same process raises on cyclonedds >= 11 ("Occurred upon + # initialisation of a cyclonedds.domain.Domain"). gear_sonic initializes + # from both the control loop and the simulator in one process, so a + # second Init with an already-live domain must be a no-op. + if self.__domain is not None: + return True config = None # choose config if networkInterface is None: