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

subscription callback types ROS1 vs. ROS2

asked 2019-09-19 22:34:40 -0500

eric1221bday gravatar image

Hi everyone

I've been creating some subscriptions in ROS2 lately, and had a question regarding the callback signature of any subscription or service creation. In ROS1, the callback signature of any message type could've been any one of the MsgType, MsgTypePtr, MsgTypeConstPtr, and additional const qualification and references of all of the previous. However as far as I can tell in ROS2, there seems to only be a limited subset of the above which would constitute a compilable callback signature.

To give a couple of examples in ROS2:

  "/foo", 5, [this](std_msgs::msg::String::ConstSharedPtr msg)  // this works
  "/foo", 5, [this](std_msgs::msg::String::UniquePtr msg)  // also works
  "/foo", 5, [this](const std_msgs::msg::String::ConstSharedPtr msg)  // doesn't seem to work
  "/foo", 5, [this](std_msgs::msg::String::ConstSharedPtr& msg)  // doesn't work either
  "/foo", 5, [this](std_msgs::msg::String::ConstUniquePtr msg)  // neither does this

It seems that the internal templates do not allow some of these patterns. Is it possible with the current design to perhaps extend subscription callback signatures so that it can accept some of the above signatures?

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted

answered 2019-09-20 01:29:33 -0500

tfoote gravatar image

At a high level there's two patterns that we want to support. Read only access and read+write access. If you want Read Only use a ConstSharedPtr, if you want to be able to modify the message use the UniquePtr to subscribe.

We could extend the API to cover more permutations, but keeping it simple will make users code more homogeneous and consequently more standardized which will make it both more readable and easier to audit.

This will also facilitate sharing of code if everything standardizes on using these two variations of the datatypes.

Specifically looking at the permutations you suggestion.

create_subscription<std_msgs::msg::string>( "/foo", 5, this // doesn't seem to work

This makes the shared pointer itself const, and you're getting it by value such that you'd be getting a copy and it consequently wouldn't be reference counted correctly.

create_subscription<std_msgs::msg::string>( "/foo", 5, this // doesn't work either

Keeping a reference to a shared pointer doesn't make much sense, you should have your own reference counted handle to the shared pointer so that it's known that you're using the contents and that you don't have to rely on someone else persisting the lifetime of the shared pointer.

create_subscription<std_msgs::msg::string>( "/foo", 5, this // neither does this

You don't want to ask for a UniquePtr that's const. The reason to require a UniquePtr is so that you can know that you have full ownership of the message datatype to allow you to modify it. Under the hood if two subscribers request a UniquePtr datatype the subscription is required to make a copy of the message to give both subscribers unique pointers. If you just want const access to the message you should use the ConstSharedPtr and not force the subscriber to copy the data to give you a const instance if there might be other const subscribers.

edit flag offensive delete link more



Hey, thanks for the answer, interestingly I also saw a slightly different pattern today in one of the demo nodes here

[this](const typename std_msgs::msg::String::SharedPtr msg) -> void

Which seems to be an attempt to get the shared_ptr to be const and have it compile. Would this then be an incorrect usage?

eric1221bday gravatar image eric1221bday  ( 2019-09-20 04:50:01 -0500 )edit

Question Tools

1 follower


Asked: 2019-09-19 22:34:40 -0500

Seen: 1,211 times

Last updated: Sep 20 '19