ROS多线程订阅消息(ros::asyncspinner)
2018-03-03 16:29
1041 查看
ROS多线程订阅消息(ros::asyncspinner)
2018-1-26http://blog.csdn.net/sunanger/article/details/53283327
对于一些只订阅一个话题的简单节点来说,我们使用ros::spin()进入接收循环,每当有订阅的话题发布时,进入回调函数接收和处理消息数据。但是更多的时候,一个节点往往要接收和处理不同来源的数据,并且这些数据的产生频率也各不相同,当我们在一个回调函数里耗费太多时间时,会导致其他回调函数被阻塞,导致数据丢失。这种场合需要给一个节点开辟多个线程,保证数据流的畅通。
为了观察不同话题的消息被阻塞的情况,可以参考以下实验代码
https://github.com/wenglihong/wlh_ros_demo/blob/master/multi_thread_demo/src/multi_topic_pub.cpp
https://github.com/wenglihong/wlh_ros_demo/blob/master/multi_thread_demo/src/multi_topic_sub.cpp
可以看到,发布程序中,以10hz的频率发布了chatter1和chatter2两个话题,在订阅程序中,回调函数1中加入了2s的延时,导致了回调函数2也只能2s才能接收到一个数据,为了是回调函数2能正常接收数据,我研究一下在一个ROS节点中开辟多个线程的方法。
在ROS中,有两种方法可以在一个节点中开辟多个线程
1.ros::MultiThreadedSpinner
MultiThreadedSpinner类似于ros::spin(),在构造过程中可以指定它所用线程数,但如果不指定线程数或者线程数设置为0,它将在每个cpu内核开辟一个线程。
用法如下
ros::MultiThreadedSpinnerspinner(4); // Use 4 threads
spinner.spin();// spin() will not return until the node has been shutdown
2.ros::AsyncSpinner
AsyncSpinner比MultiThreadedSpinner更优,它有start() 和stop() 函数,并且在销毁的时候会自动停止。下面的用法等价于上面的MultiThreadedSpinner例子。
ros::AsyncSpinner spinner(4); // Use4 threads
spinner.start();
ros::waitForShutdown();
以上代码片参考了ROS wiki
http://wiki.ros.org/roscpp/Overview/Callbacks%20and%20Spinning
完整的工程代码可以参考
https://github.com/wenglihong/wlh_ros_demo/tree/master/multi_thread_demo
另一种解释
什么时候用ros::spin()和ros::spinOnce()呢,如果仅仅只是响应topic,就用ros::spin()。当程序中除了响应回调函数还有其他重复性工作的时候,那就在循环中做那些工作,然后调用ros::spinOnce()。如下面的用spinOnce,循环调用print( )函数。
http://blog.csdn.net/yaked/article/details/50776224
因为在一些点云处理的程序中,出现多个订阅者订阅同一个topic,由于内部处理的时间不同,最后造成显示界面出现卡顿,现象就是用鼠标拖动点云的视角会感觉非常卡,不顺畅。为此,决定先走一遍官方的多线程系列教程。
https://github.com/ros/ros_tutorials/tree/jade-devel/roscpp_tutorials
http://wiki.ros.org/roscpp_tutorials/Tutorials
关于Spin和SpinOnce的解释来自英文书《A Gentle Introduction to ROS》P59页
spinOnce( )较常用的做法是while里放publisher所要发布的msg的赋值处理,然后一直循环发布topic。
ros::Rate loop_rate(10);
1.
2. while (ros::ok())
3. {
4. std_msgs::String msg;
5.
6. std::stringstream ss;
7. ss << "hello world " << count;
8. msg.data = ss.str();
9.
10. chatter_pub.publish(msg);
11.
12. ros::spinOnce();
13. loop_rate.sleep();
14. }
相关文章推荐
- ROS多线程订阅消息(ros::asyncspinner)
- 【ROS学习】(六)ROS多线程订阅消息
- ROS总结——ROS消息发布和订阅
- ros的topic:创建消息类型、发布、订阅
- ROS学习(-)基本概念+发布&订阅消息
- 我的ROS入门(五):总算搞通ROS的服务节点订阅发布消息话题了
- ROS 基础: 在同一个节点里订阅和发布消息
- ROS学习笔记2 消息发布与订阅
- ros(robot operating system机器人操作系统)订阅函数的多线程使用方法(C++: 外部变量控制跳出for循环)
- ROS订阅自定义消息
- ROS下视频消息发布与订阅
- 用Python编写ROS中的订阅和发布,导入消息类型问题
- ros::spin() ros:;spinOnce() 及多线程订阅
- 通过rosjava实现android订阅ROS自定义消息
- ROS中订阅两个消息,发布一个数据。
- ros 参数服务器 消息发布和订阅 机器人避障
- ROS:三个节点相互传递消息,每个节点都可以同时发布和订阅主题
- 消息订阅发布系统Apache Kafka分布式集群环境搭建和简单测试
- 事件的发布和订阅 以及消息队列
- RocketMq案例,生产者,消费者,消息订阅