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

ros::getGlobalCallbackQueue()->enable() removes all the previous subscriptions

asked 2016-05-18 06:59:31 -0500

MrGeva gravatar image

updated 2016-05-22 03:17:23 -0500

I am trying to suspend my node and resume later upon request.

I have the global queue receiving messages from a few topic subscriptions. When I disable the global queue and enable it back all the subscriptions are gone and callbacks no longer respond upon sending messages to the node. Same happens when I clear the global queue.

I tried suspending the global queue by calling in my node to:

ros::getGlobalCallbackQueue()->disable()

And then resume by calling:

ros::getGlobalCallbackQueue()->enable()

Then when I send a message to the node the callbacks never gets executed.

How can I get my node to stop receiving messages for a while and then resume receiving all messages?

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
0

answered 2016-05-22 09:28:04 -0500

updated 2016-05-25 12:39:43 -0500

Callback queue, as far as I remember, do not call any callbacks by itself. The callbacks are invoked by callAvailable() and callOne() functions from a spinner, e.g. when you call ros::spinOnce() or ros::spin().

One of the options would be to use AsyncSpinner instead of default one, and then start and stop it at the required moments.

Please see Callbacks and Spinning for more details.


EDIT:

Here is a small example with AsyncSpinner and custom callback queue. For me it seems to work fine.

There are several threads started by the node. The main thread serves global callback queue in while-loop and process enable/disable messages. AsyncSpinner at the same time uses several threads (equal to the number of processor cores) and process heartbeat messages on a custom callback queue.

Before enabling the AsyncSpinner back the custom queue is cleared to get rid of old messages.

To test it, run roscore, node and publish heartbeat messages with:

$ rostopic pub -r 1 /heartbeat std_msgs/Empty "{}"

In another terminal call:

$ rostopic pub /enable std_msgs/Bool "data: false"

and after some time:

$ rostopic pub /enable std_msgs/Bool "data: true"

Here is the output I get:

[ INFO] [1464000092.062925000]: Spinner enabled
[ INFO] [1464000100.748733000]: Heartbeat
...
[ INFO] [1464000108.748233000]: Heartbeat
[ INFO] [1464000109.747078000]: Heartbeat
[ INFO] [1464000110.438352000]: Spinner disabled
[ INFO] [1464000125.958848000]: Spinner enabled
[ INFO] [1464000135.381541000]: Heartbeat
[ INFO] [1464000136.383072000]: Heartbeat

EDIT 2:

To 'reverse' the behaviour, i.e. to start and stop spinner on global queue, use the AsyncSpinner without the queue parameter. Here is the code that does this.

To summarize. Do not attempt to disable the queue, but disable the spinner that works on it. By default all spinners, including the one called via ros::spinOnce(), are using the global queue. In case it is not convenient to skip ros::spinOnce() use AsyncSpinner and then start and stop on request.

edit flag offensive delete link more

Comments

I am calling ros::spin() but after I disable and enable the global queue back all the subscriptions no longer work. When I send a message on the topic the callback is no longer executed. I also tried using the AsyncSpinner and got the same bad behaviour.

MrGeva gravatar image MrGeva  ( 2016-05-22 09:59:06 -0500 )edit

What are you trying to achieve? If that is to stop callbacks being called for a while, then you can try to stop the spinner instead of the queue itself. Have you tried that?

Boris gravatar image Boris  ( 2016-05-22 10:22:44 -0500 )edit

I tried stopping AsyncSpinner and the starting it again, but the subscriptions were removed. I also tried not calling spinOnce() but when I resume I got old messages that were waiting in the queue which is not good for my use case. calling clear() on the global queue removed my subscriptions.

MrGeva gravatar image MrGeva  ( 2016-05-22 23:38:50 -0500 )edit

This solution uses the global queue for enable\disable and the custom queue for the heart beat topic subscription. My problem is that I need the opposite - the global queue is the one I am trying to start\stop spinning and after clearing the global queue the subscriptions are gone

MrGeva gravatar image MrGeva  ( 2016-05-25 00:16:34 -0500 )edit

Question Tools

2 followers

Stats

Asked: 2016-05-18 06:59:31 -0500

Seen: 643 times

Last updated: May 25 '16