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

Avoiding overhead when nothing subscribed

asked 2012-04-26 03:56:22 -0600

thebyohazard gravatar image

updated 2012-05-09 08:06:30 -0600

Formerly entitled "Does ROS publish messages if no nodes are subscribed"

I'm making a node to process data from a kinect and return a transform. I'll only need the transform message every once in a while in a service, so I was debating different ways of setting the node up and how efficient those ways are. I see two options:

Option 1: I could make the node offer a service to get the desired transform. This way, I would use waitForMessage in the node's service function to get the kinect data and return a response for each request.

Option 2: I could make the node subscribe to the kinect topic and continuously publish the transform. Since in this scenario, I don't want to do something EVERY time I get the transform message, I could use waitForMessage in the client to get a transform message at the proper time.

Now the problem comes with adding debug messages while keeping it efficient. It would be nice to publish image messages at different points in the node's pipeline and to publish the transform message that would be retrieved from a request without actually having to make a request.

Option 1 isn't so great for doing this. Since in the service you have to make a request in order to get the transform, you'd have to make a separate image callback function subscribed to the kinect topic. This callback would have basically the same code as the service code, only this time publishing extra images. To keep it efficient, you could have some way to enable and disable the callback code.

Option 2 seems easier and seems more like the ROS way to do things, but it's inefficient if the computation is done at all times without the client code caring and without rviz subscribing to debug.

So if nothing is subscribed or waiting on a topic, is the computation still performed? Or is there another reason why I should choose one option or another? The best practice on using services vs topics hasn't been written yet.

EDIT FOR POSTERITY: I've realized that I didn't name this question very well. (I wonder if I should rename it..) I'm concerned about all the computation in a callback, not just the publishing. The wiki says right here that publish() doesn't do anything if nothing is subscribed.

I really wanted to know if the computation that creates the data to publish still gets done. And the answer is yes: the callback isn't result oriented, it's a result of getting a message, and if you get a message, it'll execute whether there are subscribers or not.

So as the answers suggest, this question is really about the best way to solve the scenario above.

EDIT 2 I changed the name of the question for your searching convenience.

edit retag flag offensive close merge delete

Comments

Quite right. As you say, the title is confusing. Perhaps something like: "How to avoid message creation overhead when no nodes are subscribed?"

joq gravatar image joq  ( 2012-04-27 04:33:56 -0600 )edit

3 Answers

Sort by ยป oldest newest most voted
9

answered 2012-04-26 08:52:05 -0600

joq gravatar image

I recommend the following simple logic in your publisher:

/** @brief Callback for raw scan messages. */
void Convert::processScan(const velodyne_msgs::VelodyneScan::ConstPtr &scanMsg)
{
  if (output_.getNumSubscribers() == 0)         // no one listening?
    return;                                     // avoid much work

  ...                                           // PointCloud2 conversion

  output_.publish(outMsg);                      // publish the message
}
edit flag offensive delete link more

Comments

1

Thanks, this is exactly what I wanted! Though when I tried it, there's still a bit of a delay (at least 30 seconds on my computer) between the time a subscriber (such as rviz or the waitForMessage function in a client) closes and the time my node realises there are no more subscribers.

thebyohazard gravatar image thebyohazard  ( 2012-04-27 04:30:28 -0600 )edit

Interesting, I didn't know the delay was that long.

joq gravatar image joq  ( 2012-04-27 04:45:31 -0600 )edit
2

See this question and ticket 3403 for another discussion on this time delay.

Stephan gravatar image Stephan  ( 2012-04-27 05:04:10 -0600 )edit
1

answered 2012-04-26 21:47:07 -0600

damonkohler gravatar image

I think the answer depends on how much work you're doing to produce the transform, how often you need the transform, and how fresh the data needs to be when you get it.

If producing the transform doesn't require a lot of work, just publish it continuously.

If it requires a lot of work (i.e. it's a long running process) and you really don't need it often, then actionlib may be best since it's designed for interacting with remote operations that take time to complete.

If it requires a lot of work, you need it periodically, and you don't care how fresh it is, then just publish the transform at a low rate on a latched topic. This would also allow you to output the debugging messages you described.

edit flag offensive delete link more
1

answered 2012-04-26 04:16:41 -0600

Lorenz gravatar image

updated 2012-04-26 04:17:12 -0600

You can use this version of advertise where you can specify a connect and a disconnect callback. The callbacks get executed when a node subscribes and disconnects. You can just set a flag to start processing on connect and clear the flag at disconnect to stop processing.

edit flag offensive delete link more

Comments

So does ros::topic::waitForMessage count as a subscriber that will call those functions or is it only for subscribe() and unsubscribe()? Also, is there any documentation for unsubscribing? I can't find anything on the wiki.

thebyohazard gravatar image thebyohazard  ( 2012-04-26 06:31:24 -0600 )edit

I think waitForMessages creates a subscriber and shuts it down again, but I'm not sure on that.

Lorenz gravatar image Lorenz  ( 2012-04-26 06:33:44 -0600 )edit

You are correct: ros::topic::waitForMessage's underlying code does open up a subscriber.

thebyohazard gravatar image thebyohazard  ( 2012-04-27 03:42:56 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2012-04-26 03:56:22 -0600

Seen: 2,324 times

Last updated: May 09 '12