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

Difference between loaned message and normal way of message creation

asked 2021-05-14 00:50:30 -0500

BhanuKiran.Chaluvadi gravatar image

Hi,

I am going through the ros2 demos and came across talker.cpp and talker_loaned_message.cpp. In talker_loaned_message.cpp, there is a bit of explanation regarding POD (plain old data types) and non-POD and corresponding allocation on stack and heap.

Question: Now that i have two ways of creating message instance.. direct allocation using (std::make_unique) and other using borrow_loaned_message.

// talker.cpp
msg_ = std::make_unique<std_msgs::msg::String>();

// talker_loaned_message.cpp
auto pod_loaned_msg = pod_pub_->borrow_loaned_message();
auto non_pod_loaned_msg = non_pod_pub_->borrow_loaned_message();

Which one is preferred way of doing it and why ?

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
2

answered 2021-05-14 04:22:30 -0500

sgvandijk gravatar image

updated 2021-05-14 07:17:59 -0500

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

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 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/intra...), 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 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 (though see @gvdhoorn's comment below), but unless you explicitly run with a 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.
edit flag offensive delete link more

Comments

2

This is a good answer, but I'd just like to add: if you don't know why you'd be potentially interested in using messages (pre)allocated by the RMW, or you don't know why you should care, you should probably not be using borrow_loaned_message().

There are quite a few nuances to using it, some of which could introduce subtle bugs and would need proper use of the appropriate pointer types and methods.

For "simple" ROS 2 nodes, using the normal way of instantiating a message yourself and then passing it to your normal publisher would probably be a good default.

If/when you start running into performance issues, or have other reasons to not allocate your own messages (such as determinism requirements), using loaned message support from the RMWs which have support for it could be interesting to look into.

gvdhoorn gravatar image gvdhoorn  ( 2021-05-14 04:28:02 -0500 )edit

Question Tools

3 followers

Stats

Asked: 2021-05-14 00:50:30 -0500

Seen: 857 times

Last updated: May 14 '21