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

How to set callback queue size in rospy

asked 2017-08-29 12:23:26 -0500

Haarslev gravatar image

Hello,

I'm currently working on a project where I use a network written in TensorFlow to segment some point clouds. I have created a node which subscribes to the point cloud topic. The callback function then passes the point cloud through the network, and publishes the results on a different topic.

This all works well, but I have a problem:

The time it takes to run the point cloud through the network is greater than the publish rate of the LiDAR. This creates an ever increasing delay between the input and the output of the node, as a new thread is created for each callback function, which then waits until the network is available.

I would therefore like a way to cancel all callbacks until the network is available again, so all other point clouds than the latest gets discarded.

Currently I do the following

# Callback
def segment(pointcloud):
    feed_dict = {ops['pointclouds_pl']: pointcloud,
                ops['is_training_pl']: False}
    labels = sess.run(ops['pred'], feed_dict=feed_dict)
    publisher.publish(labels)

The subscriber is declared like this

subscriber = rospy.Subscriber('aligned_pointcloud', PointCloud2, segment, queue_size=1)

I would assume that setting the queue_size to one would do the trick but that is not the case.

 while not rospy.is_shutdown():
        pc = rospy.wait_for_message('aligned_pointcloud', PointCloud2)
        segment(pc)

The above code is also a possibility I have tried which sorta work. The problem is that it first listens for messages after the function has terminated, instead of keeping the latest ready. So if a message is published right before segment() terminates, the message is not received and the node waits for the next message to be published.

edit retag flag offensive close merge delete

Comments

Why are you explicitly calling your callback? You may want to make this an action instead which may give you what you're looking for.

jayess gravatar image jayess  ( 2017-08-29 12:46:27 -0500 )edit

In the bottom example I have not declared a subscriber. I simply wait for a message on the topic, and call the function when a message is received. It is therefore not a callback function. I'll have a look at actions

Haarslev gravatar image Haarslev  ( 2017-08-29 16:13:14 -0500 )edit

Can you try setting the queue size to None? That might actually work the way you want.

You'll get a warning, but it should work.

gvdhoorn gravatar image gvdhoorn  ( 2017-09-23 16:20:03 -0500 )edit

I'll try as soon as I'm near my workstation again, thank you

Haarslev gravatar image Haarslev  ( 2017-09-24 12:38:16 -0500 )edit

2 Answers

Sort by ยป oldest newest most voted
2

answered 2017-09-25 03:29:34 -0500

Haarslev gravatar image

As pointed out by gvdhoorn, the fix was to set queue_size=None

subscriber = rospy.Subscriber('aligned_pointcloud', PointCloud2, segment, queue_size=None)

Now only the latest published point cloud is segmented, after the previous callback returns.

edit flag offensive delete link more

Comments

Can't take credit for this unfortunately :) Discussed this with @imcmahon at ROSCon17.

gvdhoorn gravatar image gvdhoorn  ( 2017-09-25 03:34:29 -0500 )edit
0

answered 2017-09-18 14:08:47 -0500

mayuzumi gravatar image

updated 2017-09-18 14:41:05 -0500

I have the same question exactly. I thought that I should always process the latest message when queue_size is set to 1. But rospy actually queues up a long list of old messages.

And roscpp and rospy seems to give different behaviors in terms of this situation.

One way to walk around is that use the pointcloud callback to update a global variable, and process this variable in another spinner.

edit flag offensive delete link more

Comments

This is more of a comment than an answer, and posting it as a comment would have been more appropriate. The last sentence does describe one alternative approach though, so you could post that as an answer.

gvdhoorn gravatar image gvdhoorn  ( 2017-09-20 16:30:47 -0500 )edit

@mayuzumi, can you provide an example of this work around? I didn't understand how to run 2 spinners at the same time, one to obtain the value of global variable and the other to process it.

thejose gravatar image thejose  ( 2020-08-18 08:20:08 -0500 )edit

Question Tools

3 followers

Stats

Asked: 2017-08-29 12:23:26 -0500

Seen: 3,561 times

Last updated: Sep 25 '17