Skip to content

feat: ros2 connector domain id separation#786

Open
maciejmajek wants to merge 3 commits intomainfrom
feat/rai-sim-domain-id
Open

feat: ros2 connector domain id separation#786
maciejmajek wants to merge 3 commits intomainfrom
feat/rai-sim-domain-id

Conversation

@maciejmajek
Copy link
Copy Markdown
Member

@maciejmajek maciejmajek commented Apr 9, 2026

Purpose

  • Enable running multiple O3DE simulation instances and robotic stacks in parallel, each isolated on its own ROS2 domain ID so their topics, services, and actions do not interfere.

Proposed Changes

src/rai_core/rai/communication/ros2/connectors/base.py

Added context: Optional[int | rclpy.Context] = None to ROS2BaseConnector.__init__

Value Behaviour Who shuts down the context
None (default) Uses the process-global default context. Behaviour is unchanged from before. Caller (external rclpy.init / ROS2Context)
int Domain ID shorthand. Connector creates a fresh rclpy.Context, initialises it with rclpy.init(context=..., domain_id=value), and owns it. Connector — shutdown() calls rclpy.shutdown(context=...)
rclpy.Context Caller-supplied, already-initialised context. Connector uses it as-is. Caller — shutdown() leaves it untouched

Ownership is tracked via _owns_context: bool. The Node, executor (MultiThreadedExecutor / SingleThreadedExecutor), and TF buffer all receive the resolved context, so every ROS2 primitive participates in the correct DDS domain.

src/rai_sim/rai_sim/o3de/o3de_bridge.py

  • Added domain_id: Optional[int] = None to O3DExROS2SimulationConfig. When set, _launch_binary injects ROS_DOMAIN_ID into the O3DE subprocess environment so the simulator joins the right domain.
  • launch_robotic_stack gains a matching domain_id: Optional[int] = None parameter, forwarded to ROS2LaunchManager.start.

src/rai_sim/rai_sim/launch_manager.py

start() and _run_process() accept domain_id: Optional[int] = None. The child process sets os.environ["ROS_DOMAIN_ID"] before the launch service starts, so every node in the LaunchDescription joins the intended domain.

tests/rai_sim/test_o3de_bridge.py

  • test_launch_binary: updated expected Popen call to include env=ANY.
  • test_launch_robotic_stack: updated expected manager.start call to include domain_id=None.

Issues

  • N/A

Testing

All 18 tests in tests/rai_sim/test_o3de_bridge.py pass.

Running two parallel sim instances on different domains:

# Instance A — connector owns its context (domain 10)
connector_a = ROS2Connector(context=10)
bridge_a = O3DExROS2Bridge(connector_a)
config_a = O3DExROS2SimulationConfig(binary_path=Path("/sim/o3de"), domain_id=10, ...)
bridge_a.init_simulation(config_a)
bridge_a.launch_robotic_stack(..., domain_id=10)

# Instance B — fully isolated on domain 11
connector_b = ROS2Connector(context=11)
bridge_b = O3DExROS2Bridge(connector_b)
config_b = O3DExROS2SimulationConfig(binary_path=Path("/sim/o3de"), domain_id=11, ...)
bridge_b.init_simulation(config_b)
bridge_b.launch_robotic_stack(..., domain_id=11)

# Instance C — sharing an externally managed context
ctx = rclpy.Context()
rclpy.init(context=ctx, domain_id=20)
connector_c = ROS2Connector(context=ctx)  # caller owns ctx; shutdown() won't touch it

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 9, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 73.39%. Comparing base (f3a4598) to head (fc20183).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #786      +/-   ##
==========================================
+ Coverage   73.17%   73.39%   +0.22%     
==========================================
  Files          82       82              
  Lines        3579     3590      +11     
==========================================
+ Hits         2619     2635      +16     
+ Misses        960      955       -5     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant