When scaling up multi-robot simulations or running complex network-isolated state estimators in Gazebo Harmonic, relying on the standard gz_ros2_control shared memory architecture can become a bottleneck or present domain isolation challenges.
To solve this, I’ve open-sourced emcon_gz_hardware_interface.
It acts as a standard ros2_control SystemInterface, but instead of routing simulation traffic through ROS 2 DDS, it acts as a “data diode” and subscribes/publishes directly to native gz-transport topics.
Key Features:
Total DDS Bypass: Keeps your ROS_DOMAIN_ID completely isolated from high-frequency simulation traffic.
Strict Real-Time Safety: Uses realtime_tools::RealtimeBuffer to ensure the control loop never blocks.
Fully Parameterized: Configurable directly via URDF <hardware> tags.
I’ve already opened an RFC with the ros-controls team to see if this fits upstream, but the standalone package is fully CI-tested and ready to use for ROS 2 Jazzy! I’d love to hear feedback from anyone running massive fleets or strict network simulations.
You are right. It is indeed bypassing the entire RMW layer directly in favor of gz-transport.
A rmw_gz_transport would certainly be an interesting project, though a huge undertaking.
This is a fantastic architectural optimization for Gazebo users. Bypassing DDS for high-frequency simulation traffic effectively removes the ‘digital noise’ that often masks controller performance issues.
I see a great synergy between your project and mine, ros2_kinematic_guard. While emcon_gz ensures a clean data pipe in simulation, my guard handles the ‘physical’ consequences when robots eventually leave the clean simulation and face real-world DDS jitter over 5G/Wi-Fi.
Essentially, your interface provides the performance for the simulation phase, and my guard provides the kinematic safety for the deployment phase. It would be very interesting to see a pipeline where we use emcon_gz to stress-test controllers, and then use the kinematic_guard to ensure those same controllers don’t produce ‘Ghost Commands’ when the real network starts to jitter.
Great job on the realtime_tools integration as well!