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.