Skip to content

feat(thread_configurator): support multiple ROS domain IDs with a single config #41

@atsushi421

Description

@atsushi421

Summary

Currently, thread_configurator_node can only communicate with nodes in a single ROS domain (the one it is launched in). If target applications span multiple ROS_DOMAIN_IDs, users must manually launch separate thread_configurator_node instances for each domain, each with its own environment and configuration — a cumbersome and error-prone process.

This issue proposes adding a --domains option so that a single thread_configurator_node (and a single YAML config file) can discover and configure threads across multiple ROS domains at once.

Reference: agnocast implementation

Current Behavior

  • thread_configurator_node creates its subscriptions in the default ROS domain (inherited from ROS_DOMAIN_ID environment variable).
  • To configure nodes on a different domain, users must launch the configurator with the matching ROS_DOMAIN_ID:
    sudo bash -c "export ROS_DOMAIN_ID=1; source install/setup.bash; \
      ros2 run cie_thread_configurator thread_configurator_node --config-file config.yaml"
  • There is no way to handle multiple domains from a single process or a single YAML file.

Proposed Behavior

CLI

Add a --domains option that accepts a comma-separated list of domain IDs:

# Prerun mode — discover threads from domains 0 and 1
ros2 run cie_thread_configurator thread_configurator_node --prerun --domains 0,1

# Config mode — apply configuration to nodes in domains 0 and 1
ros2 run cie_thread_configurator thread_configurator_node --config-file config.yaml --domains 0,1

When --domains is not specified, the current behavior is preserved (single domain from ROS_DOMAIN_ID env var).

Implementation Approach

For each specified domain ID, create a separate rclcpp::Context with the corresponding domain ID and instantiate dedicated subscriber nodes within that context. All subscriber nodes feed into the same ThreadConfiguratorNode / PrerunNode logic so that:

  • Prerun mode: callback group IDs from all domains are collected into a single template.yaml.
  • Config mode: a single YAML config is loaded and thread configurations are applied regardless of which domain the thread info message originated from.

Key Design Points

  1. Separate DDS participants per domain: Each domain requires its own rclcpp::Context initialized with the target ROS_DOMAIN_ID. This means creating lightweight "relay" nodes — one per domain — that subscribe to /cie_thread_configurator/callback_group_info and /cie_thread_configurator/non_ros_thread_info and forward messages to the central configuration logic.

  2. Single YAML config: The YAML schema does not need to change. Callback group IDs already contain the node namespace and name, which are unique across domains. If disambiguation is needed in the future, domain information could be optionally prefixed, but this is not required for the initial implementation.

  3. Backward compatibility: When --domains is omitted, the behavior is identical to today — no extra contexts are created.

Tasks

  • Parse --domains CLI argument in main.cpp
  • Create per-domain rclcpp::Context and subscriber nodes
  • Wire per-domain subscribers into ThreadConfiguratorNode and PrerunNode
  • Update PrerunNode::dump_yaml_config() to merge results from all domains
  • Add documentation and usage examples to README
  • Test with nodes running on different ROS_DOMAIN_IDs

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions