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

Revision history [back]

click to hide/show revision 1
initial version

The design document on loaned messages provides some more background and info: https://design.ros2.org/articles/zero_copy.html

It mentions that what actually happens when borrowing loaned messages depends on the middleware used and that not all support this concept, but that ROS 2 should fall back to allocating a message 'as normal'. This means you should never be worse off when using the borrowing method, and in some configurations you would be saving some unnecessary copies. So you could choose to use this method as your default safely.

However, one situation that is also mentioned where it won't give much benefit is when you need to keep the message around after publishing it. Because you have to relinquish ownership in zero-copy setup to prevent issues like data races, you need to make a copy in your node of the message to be able to keep it around. That would partky defeat the purpose of zero-copy publishing. You may still end up with less copying in the end but I don't dare guaranteeing it :).

Finally, message borrowing does not work together with [intra-process communication] (http://design.ros2.org/articles/intraprocess_communications.html), ROS 2's own middleware-bypassing zero-copy solution. You also give up ownership of the data with that too make zero-copy possible, and you can't give something away that you only borrowed!

So with all that I would suggest the following policy:

  • If you need to retain ownership of the message after publishing it, use standard message creation, with make_unique as you mentioned, but it could also be make_shared or heap allocation based on the further usage of the message and resulting ownership semantics. If possible perform message reuse yourself within your node, possibly with a message pool if needed.
  • If you don't need to retain ownership, use intra-process communication and unique_ptrs. I don't think the default middlewares of Foxy and upcoming Galactic support message loaning, so by default intra-process communication is the way to go for zero-copy.
  • If you're a public package maintainer you can add optionalsupport for message loaning to make your package more widely useful. You could also still do this for your own packages just in case since it doesn't hurt things, but unless you explicitly run with a middlewares that supports it, I feel that'd just muddle things with additional boilerplate and I would first like to see some profiling showing that message copying is indeed a performance bottleneck for your use case.

The design document on loaned messages provides some more background and info: https://design.ros2.org/articles/zero_copy.html

It mentions that what actually happens when borrowing loaned messages depends on the middleware used and that not all support this concept, but that ROS 2 should fall back to allocating a message 'as normal'. This means you should never not be worse off when using the borrowing method, and in some configurations you would be saving some unnecessary copies. So you could choose to use this method as your default safely.

However, one situation that is also mentioned where it won't give much benefit is when you need to keep the message around after publishing it. Because you have to relinquish ownership in zero-copy setup to prevent issues like data races, you need to make a copy in your node of the message to be able to keep it around. That would partky defeat the purpose of zero-copy publishing. You may still end up with less copying in the end but I don't dare guaranteeing it :).

Finally, message borrowing does not work together with [intra-process communication] (http://design.ros2.org/articles/intraprocess_communications.html), ROS 2's own middleware-bypassing zero-copy solution. You also give up ownership of the data with that too make zero-copy possible, and you can't give something away that you only borrowed!

So with all that I would suggest the following policy:

  • If you need to retain ownership of the message after publishing it, use standard message creation, with make_unique as you mentioned, but it could also be make_shared or heap allocation based on the further usage of the message and resulting ownership semantics. If possible perform message reuse yourself within your node, possibly with a message pool if needed.
  • If you don't need to retain ownership, use intra-process communication and unique_ptrs. I don't think the default middlewares of Foxy and upcoming Galactic support message loaning, so by default intra-process communication is the way to go for zero-copy.
  • If you're a public package maintainer you can add optionalsupport optional support for message loaning to make your package more widely useful. You could also still do this for your own packages just in case since it doesn't hurt things, things (though see @gvdhoorn's comment below), but unless you explicitly run with a middlewares middleware that supports it, I feel that'd just muddle things with additional boilerplate and I would first like to see some profiling showing that message copying is indeed a performance bottleneck for your use case.