ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

ROS2 Best practices: multiple nodes in the same process

asked 2018-12-05 19:02:01 -0500

alsora gravatar image

updated 2018-12-05 19:02:42 -0500


I was wondering if there are any best practices for implementing multiple ROS2 nodes in the same process.

So far I see the following options:

  • std::thread / pthread
  • SingleThreadedExecutor
  • MultiThreadedExecutor
  • composition API

From my understanding of the topic, the composition API should be used whenever we want to define which nodes to use at runtime.

On the other hand, all the other methods require the nodes to be specified at compile time.

I'm currently using mainly std::thread or pthread, as they integrate nicely with other non-ROS code. However I'm also trying to make some experiments about the performance of the ROS executors, to see how they compare with simply spawning a new thread for each node I have.

I noticed that all the examples in the ROS2 tutorial use the executors, what's their advantage?


edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted

answered 2018-12-05 22:34:37 -0500

William gravatar image

Composition just means that you provide the node (as a class that inherits from node) and someone else (like a boilerplate main function or composition executable) provide the threading with an executor of some sort.

Composition uses executors to execute one or more nodes in a thread (in the case of SingleThreadedExecutor) or in multiple threads (in the case of MultiThreadedExecutor).

The single threaded executor just runs in the thread in which you call executor.spin().

The multi threaded executor creates threads using std::thread and then dispatches work to them from the thread in which you call executor.spin().

So if you use the composition demo ( ) then it will most likely be using a single threaded executor in the main thread, e.g.:

But there's no reason for that really, another composition example might use a multi threaded executor or a single threaded executor in a thread created with pthread.

In fact, if you used a multi threaded executor to load one or more component nodes (again nodes implemented as a sub class of rclcpp::Node), then you're using most of the things you listed: composition, MultiThreadedExecutor, std::thread, and pthread (because std::thread is probably implemented with pthread on your machine).

I'll also mention that the single and multi threaded executor are just the two built in executors, but you can create your own if you'd like to do something different with the creation of threads, or scheduling of callbacks, or the distribution of callbacks to certain threads, etc...

My recommendation is put all of your "business logic" for your node in one set of source files and implement it as a sub class of rclcpp::Node, but avoid creating any executors or calling spin anywhere. And in a separate file, you can have one of these "boilerplate main" functions which creates an executor, creates an instance of your node, adds your node to the executor, and then calls spin().

Then in the future you'll easily be able to take advantage of composition because the only thing anyone needs to do in order to compose your node into a process is instantiate it and add it to an executor.

edit flag offensive delete link more


Thank you for the detailed answer! Actually, talking about composition, I was referring to where the LoadNode service is used.

alsora gravatar image alsora  ( 2018-12-06 12:36:01 -0500 )edit

That works for any node that is setup like the talker and listener examples in the demo, specifically: your node is a subclass of rclcpp::Node, you register it in your C++ (CLASS_LOADER_REGISTER_CLASS(composition::Talker, rclcpp::Node)), and you register it in cmake.

William gravatar image William  ( 2018-12-06 15:39:12 -0500 )edit

I will say there's ongoing work to make this process easier and simpler, and to provide more out-of-the-box component containers and to integrate it with launch, watch for progress: (maybe a different issue in the future)

William gravatar image William  ( 2018-12-06 15:40:45 -0500 )edit

@alsora the link is dead.

aby gravatar image aby  ( 2020-04-09 14:48:23 -0500 )edit

Question Tools



Asked: 2018-12-05 19:02:01 -0500

Seen: 8,333 times

Last updated: Dec 05 '18