Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rospy: queue_size documentation #507

Closed
davetcoleman opened this issue Oct 8, 2014 · 9 comments
Closed

rospy: queue_size documentation #507

davetcoleman opened this issue Oct 8, 2014 · 9 comments

Comments

@davetcoleman
Copy link

Moved from RethinkRobotics/baxter_interface#38 (comment)

davetcoleman:

@dirk-thomas it would be nice if someone with a good understanding of the general implications of different values for queue_size would document that on the wiki to help everyone upgrading to indigo.

this is in my opinion a classic example of ROS becoming harder for the average user to understand and use. my specialty and interest is not in message passing

dirk-thomas:

There is no magic formula to select the value. It all depends on publish frequency, system load and responsiveness of the subscriber. The description in the wiki is as good as it gets - I couldn't come up with more information.

@davetcoleman
Copy link
Author

Questions that could be address in wiki:

  1. None of the code examples on the wiki use the (almost) required queue_size value.

  2. Is there a difference between None and 0, and what is it?

  3. Is there a good rule of thumb for correlation between refresh rate (hz) and a queue size?

  4. Different applications require different settings. e.g. @rethink-rlinsalata said:

We've been discussing whether the Publisher queue_size for joint commands should be just 1? The thinking being that in any "critical" commands where you always want to make sure to use the latest command available, you want to override any old msgs to be published if you have a newer one -- i.e. never use old commands if newer exist.

More background: Generation Robots told us that the joint action server / control performed much better when they changed the queue_size for the joint_states Subscriber to just 1 (and set tcp_nodelay). This prevented the control loops from ever using old joint_state data if there was a newer msg available (and ameliorated the batching problem). See #20 from v1.0.0 release.

Meanwhile, the "interaction", indicator, I/O commands could have a larger queue size (e.g. digital_io, etc).

I would document all this myself, but am not confident enough in my knowledge

@dirk-thomas
Copy link
Member

1) There are simply so many wiki pages that we can not touch them all. The wiki is a community effort - please feel free to update any wiki page you find. But keep in mind that those should still work with Groovy and older ROS distros (if they don't contain separate tabs for each ROS distro).

2) Please read the wiki page you referenced - it clearly answers your question under 1.2.1: queue_size: publish() behavior and queuing

3) Imo there is no "good rule of thumb". If your system is not overloaded you could argue that a queued message should be picked up by the dispatcher thread within a tenth of a second. So a queue size of 1 / 2 / 3 would be absolutely fine when using 10 Hz. But some nodes e.g. publish multiple messages directly after each other - in this case a queue size of 1 would lead to dropping all previous messages but the last one. Generally speaking using a bigger queue_size will only use more memory when you are actually behind with the processing - so I would recommend to pick a value which is bigger then it needs to be rather then a too small value.

4) Setting the queue_size to 1 is a valid approach if you want to make sure that a new published value will always prevent any older not yet sent values to be dropped. (Assuming that you do not want to record all published values including the dropped ones.)

@rethink-rlinsalata
Copy link
Contributor

The aspect I think is missing/most unclear to me is how the queue_size number / async threading is distributed over multiple subscribers vs. multiple (sequential) messages.

For example, the documentation uses the example of a subscriber with a bad connection blocking everyone else in the old synchronous publishing scheme; when that is switched to an asynchronous scheme with a finite queue_size > 1 (e.g. 10), what happens to the available queue #'s / 'slots', if one of the subscribers gets held up on a given message...

Does it dedicate one thread to each subscriber, so therefore the other subscribers continue to get message 1, message 2, message 3, etc. while the blocked subscriber sits and waits on message 1?
Or does each unique message-subscriber get a queue, and the blocked subscriber starts eating up the available queue's as message 2, message 3, and so on come in?

Is each subscriber designated its own thread? Will the backlog of messages waiting to go out to the bad subscriber start filling up the other queue slots?

I'm not sure if this is how it ACTUALLY works, but one way I could understand it working is queues are really just about subscribers, not messages, and bad subscribers only take up one queue slot, no matter how many messages come in. IF this is accurate, it would mean the queue_size variable would essentially be "how many blocked subscriber-connections before your publisher is completely blocked"

@dirk-thomas
Copy link
Member

The queue size defines the size of the queue aka the maximum number of messages to buffer.

Each subscriber has his own queue and dispatching thread in order to achieve asynchronous publishing which does never block other subscribers if one is blocked.

@davetcoleman
Copy link
Author

@dirk-thomas I appologize if I sounded acusational or agressive - I know OSRF resources are limited and ROS is a community effort. I've contributed to many wiki pages and am always looking to improve them, which is why I am posting here. I infact have edited this rospy page before and read it again before posting this issue.

Imo there is no "good rule of thumb"

I've used ROS for several years now without ever having to think about this, and I've never had an issue, so there must be something users can use quickly without having to worry about it. Previously, that was None

I'll attempt to take all this information now and update the wiki, please feel free to review.

@davetcoleman
Copy link
Author

Each subscriber has his own queue and dispatching thread in order to achieve asynchronous publishing

This is still a little unclear - if queue_size is only for the size of the queue, why is it also the trigger for using asyncronous behavior? Seems like mixed purposes. Didn't the syncronous publishing also have a queue?

@davetcoleman
Copy link
Author

I just added a detailed section titled Choosing a good queue_size
http://wiki.ros.org/action/info/rospy/Overview/Publishers%20and%20Subscribers?action=diff&rev2=30&rev1=29

@dirk-thomas
Copy link
Member

Thank you for improving the docs with the detailed guidelines.
I have tweaked them a bit further (http://wiki.ros.org/action/diff/rospy/Overview/Publishers%20and%20Subscribers?action=diff&rev1=31&rev2=32).

Synchronous publishing does not require a queue. Every published message will be sent to every subscriber in a blocking fashion. Asynchronous publishing does require a queue to store the messages until they have been dispatched to all subscribers. So I don't there is any mixed purpose here.

@davetcoleman
Copy link
Author

Now I understand, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants