Bootstrap

ROS多线程服务话题定时器等回调函数处理

首先,Timer, topic, service都会有相对应到回调函数。在ROS机制中,通过注册相对应到句柄,他们的所有回调函数都会注册到全局回调队列里面。也就是GlobalCallbackQueue. 这个全局回调队列会被单线程ros::spin()或者是别的多线程给调用。当线程数满载处理回调函数,其他回调函数则会被阻塞,排队等待处理。

为了可以让自己需要到回调函数一直运行,不会被别的回调函数阻塞,可以自己自定义一个回调队列callback queues。

ros::NodeHandle nh;
nh.setCallbackQueue(&my_callback_queue);

首先这样做可以让自己想要的定时器、话题、服务等回调函数注册到自己定义的回调队列,而不会注册到默认的全局回调队列。这也意味着,自定义的回调队列不会被ros::spin和ros::spinOnce()进行回调处理。所以,自定义回调队列必须自定义处理,通过ros::CallbackQueue::callAvailable() 和 ros::CallbackQueue::callOne() 的方法。 callOne只会每次回调一次队列里面的回调函数,而available会处理回调队列里面的回调函数。

接着开启另一个线程实时处理自定义队列的回调函数。也就是该nodehandle句柄下的回调函数。

可以使用

ros::AsyncSpinner spinner(0, &my_callback_queue);
spinner.start();

或者

ros::MultiThreadedSpinner spinner(0);
spinner.spin(&my_callback_queue);

剩下句柄的回调函数都在全局回调队列中,有单线程spin或者多线程自动处理。默认情况下多线程后面没有回调队列指针,则处理全局回调队列

 

;