I am working on a robotic system using ROS 2, where I have implemented a singleton class in C++ to handle CAN interface communications. This singleton is used by two nodes; ros2_control_node, which belongs to the controller_manager package, and another node sensors_publisher I implemented to retrieve sensor data from CAN and publish them. The same launch file starts both nodes.

The problem: When launching the system, I observed that these nodes operate in separate processes, meaning they don't share the singleton instance as intended.

The question: How can I ensure that those two nodes are spawned within the same process to share the same singleton for communication in a ROS 2 environment?


2 Answers 2


To run multiple nodes in one process, you can just instantiate them in the same main() and add them to an executor, see e.g. the minimal composition example.

There are different types of executors, e.g. SingleThreadedExecutor, MultiThreadedExecutor, StaticSingleThreadedExecutor, EventExecutor, etc but that is somewhat out of the scope of this question. See the documentation on executors as well as the examples.

An alternative solution is mentioned in following tutorial: Composing multiple nodes in a single proces, and in the corresponding how-to guide: Using ROS 2 launch to launch composable nodes.

  • $\begingroup$ Thank you, @JRTG! Your reply is very relevant, but there is a challenge. I do not think I have much control over ros2_control_node because it is instantiated using the hardware_interface of ros2_control. There is no main() like writing the node from scratch. Please tell me if my explanation is unclear. If you got what I meant, please feel free to share your thoughts. $\endgroup$
    – Robotawi
    Dec 27, 2023 at 15:38
  • $\begingroup$ You could instantiate the controller_manager in a custom node, without using ros2_control_node. But I think you should give the hardware_components a try, see the other answer. $\endgroup$ Dec 27, 2023 at 17:00

In the sense of ros2_control framework, you should:

  • write a hardware_component implementing your CAN communication and export state and command interfaces all at once. This is a single thread from the ressource_manager being part of the CM.
  • write/use a controller claiming the necessary interfaces (state+command)
  • write a sensor broadcaster claiming the exported state interfaces and publishing them as topics (basically, your sensors_publisher)
  • $\begingroup$ Thanks, @Christoph! I have implemented those points. I have 1 and 2 handled by the hardware_compoenet but separated 3 in its own node for clean design. Now, I end up with two nodes. How can I make the two nodes operate in a single process? This is my question. $\endgroup$
    – Robotawi
    Dec 27, 2023 at 12:46
  • $\begingroup$ I'm not sure if this is possible at all. Why do you think your design would be cleaner? Maybe you could write two hardware_components, as we demonstrate here. $\endgroup$ Dec 27, 2023 at 12:49
  • $\begingroup$ Thanks for sharing that, Cristoph! I think my sensors_publisher should be implemented using the hardware_interface::SensorInterface. I will give it a try. $\endgroup$
    – Robotawi
    Dec 27, 2023 at 15:50
  • $\begingroup$ I implemented the hardware_interface::BaseInterface<hardware_interface::SensorInterface> for reading the robot's multiple range sensors. Every sensor reading is just one value expressing distance from the obstacle. The error I got is Loader for controller 'sensors_broadcaster' not found. Does this mean my plugin is not detected? Please notice I am using ROS 2 Foxy due to the robot's available OS. I would appreciate your help. Thank you! $\endgroup$
    – Robotawi
    Dec 28, 2023 at 10:10
  • $\begingroup$ So you implemented a SensorInterface like in this example? Your error is from a controller, which controller do you want to spawn? What does ros2 control list_hardware_components tell you, was your SensorInterface loaded correctly? $\endgroup$ Dec 28, 2023 at 11:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.