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

[rclcpp] How to unsubscribe from a topic

asked 2020-06-12 13:07:21 -0600

vale gravatar image

updated 2020-07-17 05:28:42 -0600

Hi, I'm trying to implement a dynamic subscribing behaviour to a ros2 node. When a topic becomes obsolete for the node I would like it to unsubscribe from that topic. How could this be accomplished?

The object the node is holding is a rclcpp::Subscription which is created by its parents method create_subscription(Just like in the basic Tutorial at

Any suggestion would be appreciated, if I have overlooked some documentation please point me to it.

I have had a look at the innerworkings of the Node. The callback group keeps a weak_ptr to every subcriptions ever added to the group. Now I didnt find any routine removing them from the vector, if they are not used anymore. Of course its not piling on a huge memory load with the objects them self being deleted. But running my node for a while the vector just keeps growing, never removing the weak_ptr from the vector.

edit retag flag offensive close merge delete


Have been checking and is quite curious there is no specific function for that (at least i didn't found it neither)!

I'm thinking that maybe you could call the destructor inherited for the SubscriptionBase ( . this way maybe it works!

Solrac3589 gravatar image Solrac3589  ( 2020-06-19 06:39:51 -0600 )edit

I have tried this in the meantime. When the rclcpp::Subscription::SharedPtris not referenced anymore the callback function doesnt get called by messages to the topic anymore. But the entry in the callback group does not get removed. I cant find any way to remove the subscription from the CallbackGroup either, that could be triggered by the code inside the node (

vale gravatar image vale  ( 2020-06-26 06:26:36 -0600 )edit

This is interesting but I unfortunately don't have an environment to test it. I believe what you want is achievable by using

  rclcpp::SubscriptionBase::SharedPtr subscription,
  rclcpp::CallbackGroup::SharedPtr callback_group)

function instead of create_subscription. I might have checked the source code very badly but did you try digging add_subscription() one? There are test codes in the rclcpp repo for reference of usage.

Orhan gravatar image Orhan  ( 2020-07-18 19:34:23 -0600 )edit

Hey there!

Did you manage to stop/deactivate/shut down your subscriber without shutting down the entire node? I´m working with eloquent and to be honest I dont know how to unreference the Subscription Shared Pointer...

Let´s say my subscriber looks like this:

m_camera_info_sub = this->create_subscription<sensor_msgs::msg::CameraInfo>("/img_topic", 1, std::bind(&CameraAdapter::cbCameraImage, this, _1));

I get the camera info once, then i never need it again so in Ros1 I would do


But what can I do in Ros2 to achieve this?

EDIT: m_camera_info_sub.reset() seems to do the trick! Only briefly tested this so there might be something I´m missing but so far it´s looking good!

TheBee gravatar image TheBee  ( 2020-08-12 03:45:06 -0600 )edit

So you call reset() on your Subscription? I was not able to find that function in the documentation or the class definition of the Subscription.

vale gravatar image vale  ( 2020-08-13 06:48:38 -0600 )edit

reset() is likely a method of the SharedPtr, not of the subscription object itself. It essentially releases the pointed-to, which results in it going out-of-scope, leading to destruction.

gvdhoorn gravatar image gvdhoorn  ( 2020-08-13 06:57:33 -0600 )edit

In my experience, reset() seems to work, i.e the callback is not served anymore. Is it safe to use as a ROS1 shutdown() replacement ? Is there any risk of memory leakage in case of frequent subscription/ reset cycles ?

doisyg gravatar image doisyg  ( 2020-08-13 07:00:49 -0600 )edit

Thanks, you are right. I did delete the object a different way but that works as well. I am not sure though if the DDS layer is still receiving the multicast messages, after the deleting the Subscription. And for sure it does not change the fact that weak pointers keep piling up in the callbackgroup.

vale gravatar image vale  ( 2020-08-13 07:01:30 -0600 )edit

2 Answers

Sort by » oldest newest most voted

answered 2020-08-04 17:16:00 -0600

Josh Whitley gravatar image

It looks like this simply doesn't exist yet. This appears to be confirmed by this TODO in image_common. rclcpp does not yet support it but, I think, even lower, the rmws don't get support it (couldn't find any reference in Cyclone or FastRTPS). You'll want to start by getting the RMW vendors to support it first (I think).

edit flag offensive delete link more


That comment might be out of date (I've fixed other things like this recently that were out of date because the port was done quite a while ago). For reference, RVIZ actually does disconnect from the topic when you disable a display (confirmed using ros2 topic info and seeing that the subscriber count falls back to 0). From what I can see, RVIZ displays simply reset the shared_ptr to the subscriber. It is possible the weak_ptrs are still piling up though...

fergs gravatar image fergs  ( 2020-08-18 09:12:35 -0600 )edit

Thanks for the clarification. Do you have a link to somewhere in the RViz code that this happens? I'll update my answer with the link and suggestion.

Josh Whitley gravatar image Josh Whitley  ( 2020-08-18 22:23:36 -0600 )edit

answered 2020-08-18 09:27:32 -0600

fergs gravatar image

It appears that RVIZ properly unsubscribes when displays are disabled by simply calling reset() on the Subscription shared_ptr. I confirmed this checking that the subscriber count falls when using "ros2 topic info".

With regards to the weak_ptrs piling up - it looks like every time you add a new timer, service, or subscription to a callback group it will remove any weak_ptrs that are expired

edit flag offensive delete link more

Question Tools



Asked: 2020-06-12 13:07:21 -0600

Seen: 4,899 times

Last updated: Aug 18 '20