ROS的回调处理函数spin/spinOnce

  • 作用
  • 区别
  • 使用

作用

spin/spinOnce是ROS消息回调处理函数。它俩通常会出现在ROS的主循环中,程序需要不断调用ros::spin() 或 ros::spinOnce(),两者区别在于前者调用后不会再返回,也就是你的主程序到这儿就不往下执行了,而后者在调用后还可以继续执行之后的程序。

如果你的程序写了相关的消息订阅函数,那么程序在执行过程中,除了主程序以外,ROS还会自动在后台按照你规定的格式,接受订阅的消息,但是所接到的消息并不是立刻就被处理,而是必须要等到ros::spin()或ros::spinOnce()执行的时候才被调用,这就是消息回到函数的原理。

区别

ros::spin() 在调用后不会再返回,也就是你的主程序到这儿就不往下执行了,而 ros::spinOnce() 后者在调用后还可以继续执行之后的程序。ros::spin()函数一般不会出现在循环中,因为程序执行到spin()后就不调用其他语句了,也就是说该循环没有任何意义。ros::spinOnce()的用法相对来说很灵活,但往往需要考虑调用消息的时机,调用频率,以及消息池的大小,这些都要根据现实情况协调好,不然会造成数据丢包或者延迟的错误。

使用

##ros::spin()

publisher
#include "ros/ros.h"
#include "std_msgs/String.h"
#include <sstream>int main(int argc, char **argv)
{ros::init(argc, argv, "talker");ros::NodeHandle n;ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);ros::Rate loop_rate(10);int count = 0;while (ros::ok()){std_msgs::String msg;std::stringstream ss;ss << "hello world " << count;msg.data = ss.str();ROS_INFO("%s", msg.data.c_str());/*** 向 Topic: chatter 发送消息, 发送频率为10Hz(1秒发10次);消息池最大容量1000。*/chatter_pub.publish(msg);loop_rate.sleep();++count;}return 0;
}
subscriber
#include "ros/ros.h"
#include "std_msgs/String.h"void chatterCallback(const std_msgs::String::ConstPtr& msg)
{ROS_INFO("I heard: [%s]", msg->data.c_str());
}int main(int argc, char **argv)
{ros::init(argc, argv, "listener");ros::NodeHandle n;ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);/*** ros::spin() 将会进入循环, 一直调用回调函数chatterCallback(),每次调用1000个数据。* 当用户输入Ctrl+C或者ROS主进程关闭时退出,*/ros::spin();return 0;
}

##ros::spinOnce()

#include "ros/ros.h"
#include "std_msgs/String.h"void chatterCallback(const std_msgs::String::ConstPtr &msg)
{ROS_INFO("I heard: [%s]", msg->data.c_str());
}int main(int argc, char **argv)
{ros::init(argc, argv, "listener2");ros::NodeHandle n;ros::Subscriber sub = n.subscribe("chatter", 2, chatterCallback);ros::Rate loop_rate(5);while (ros::ok()){/*...TODO...*/ros::spinOnce();loop_rate.sleep();}return 0;
}

spin是没有问题的,而对于ros::spinOnce()的使用,虽说比ros::spin()更自由,可以出现在程序的各个部位,但是需要注意的因素也更多。

比如对于有些传输特别快的消息,尤其需要注意合理控制消息池大小和ros::spinOnce()执行频率; 比如消息送达频率为10Hz, ros::spinOnce()的调用频率为5Hz,那么消息池的大小就一定要大于2,才能保证数据不丢失,无延迟。我们设计了一个回调慢一点的函数,可以看到监听到的数据就存在丢失了。

[ INFO] [1599531419.076638802]: I heard: [hello world 7123]
[ INFO] [1599531419.076741485]: I heard: [hello world 7124]
[ INFO] [1599531419.276584099]: I heard: [hello world 7127]
[ INFO] [1599531419.276618426]: I heard: [hello world 7128]
[ INFO] [1599531419.476654136]: I heard: [hello world 7131]
[ INFO] [1599531419.476744663]: I heard: [hello world 7132]
[ INFO] [1599531419.676645419]: I heard: [hello world 7135]

ros::spin() 和 ros::spinOnce()相关推荐

  1. ros::spin() 和 ros::spinOnce() 区别及详解

    1 函数意义 首先要知道,这俩兄弟学名叫ROS消息回调处理函数.它俩通常会出现在ROS的主循环中,程序需要不断调用ros::spin() 或 ros::spinOnce(),两者区别在于前者调用后不会 ...

  2. 【ROS进阶】常用函数——ros::ok(),ros::Rate,ros::spin()和ros::spinOnce()

    (一)ros::ok() 用于检查系统状态,适用于在while循环中判断状态 语法: while(ros::ok()) {//... } ros::ok()在以下几种情况下会返回false: 1.按下 ...

  3. ros::spin() 和 ros::spinOnce() 区别及用法

    1 函数意义 ros::spin() 和 ros::spinOnce() 是ROS消息回调处理函数.它俩通常会出现在ROS的主循环中,程序需要不断调用ros::spin() 或 ros::spinOn ...

  4. ros::spin()和ros::AsyncSpinner

    1)区别 ros::spin():是一个单线程,它根据消息到达的时间一一执行对应的回调函数,只有当前一个回调函数执行结束后,新的回调函数才能执行,如果前一个回调函数执行太长时间,有可能阻塞新的回调函数 ...

  5. 一文搞懂ROS2的spin_some, spin和ROS的spinOnce

    目录 写在前面 1. ROS里的spin和spinOnce 1.1 回调机制浅析 1.2 为什么订阅话题时要指定queue_size? 1.3 设置queue_size的小技巧 1.4 spin和sp ...

  6. ROSNOTE : ros::spin() / ros::spinOnce() /rospy.spin()

    如果写了消息订阅函数,那一定要写ros::spin() 或者ros::spinOnce(),不然是得不到另一边发出的消息或者信息 #include "ros/ros.h" #inc ...

  7. ros中关于ros::Rate 和ros::spin()等的理解

    1.关于ros::Rate rate()和rate.sleep()的使用和理解 这两个函数是用来控制发布频率的,控制的是循环的频率,不是消息和服务的发布频率,通过控制循环频率从而可以控制发布频率 ro ...

  8. ros spin spinone 详细解释

    函数意义: 先了解这个 http://wiki.ros.org/roscpp/Overview/Publishers%20and%20Subscribers ros的消息订阅和发布机制官方教程,最简单 ...

  9. 【ROS笔记本】ros::Rate loop_rate( ) loop_rate.sleep()

    ros::Rate是一个类 1 ros::Rate loop_rate( ) & loop_rate.sleep() 这两个函数必须一起使用,控制的是循环的频率,与消息或者服务的发布频率无直接 ...

最新文章

  1. Ubuntu常用服务器环境搭建——Nginx+PHP篇
  2. 你辛苦来人间一趟,不是来作任务的,你应该好好享受阳光、雨露和爱 ...
  3. 学pyqt5之前需要学python吗_快速学习pyqt5(1)--入门
  4. HTML系列(四):编辑图像
  5. oracle中只存储两年数据,Oracle中作为永久存储机制的嵌套表的数据追加
  6. 题目:输入两个正整数m和n,求其最大公约数和最小公倍数。
  7. 一篇真正教会你开发移动端页面的文章(二)
  8. 计算机毕业设计——基于Spring Boot框架的网络游戏虚拟交易平台的设计与实现
  9. windows server 2019 中文语言包
  10. 北京思科CCNP和思科 CCIE考试常见问题GRE虚拟专用网络详解
  11. POI读取PPT图表模板,动态改变图表数据,操作图表
  12. PS常用工具理解及常用快捷键大全
  13. 树莓派python虚拟环境的设置与使用
  14. 宝塔linux面板 伪静态,AMH主机面板伪静态规则大全,
  15. ColdFusion mx 7.0 函数分类列表
  16. 洛谷P4767 [IOI2000]邮局(决策单调DP,四边形不等式优化)
  17. 哈希传递PTH、密钥传递PTT、票据传递PTK的实现和比较
  18. java 北京时间 东八区时间 Android calendar时区无效问题
  19. 区块链的奥卡姆剃刀在哪里?(1)
  20. matlab心线代码,matlab心形线

热门文章

  1. 两个有序链表序列的交集_腾讯50题---合并两个有序链表(简单)
  2. iphone微信美颜插件_iOS13.5 插件分享
  3. 日志查看技巧_10种Git技巧,让你省时省力又省心!
  4. python二级考试选择题公共基础知识_计算机二级Python易忘考点整理
  5. 532 -数组中的K-diff对
  6. C/C++脚本接口神器:Lua
  7. Centos6.9下RocketMQ3.4.6高可用集群部署记录(双主双从+Nameserver+Console)
  8. HTML5中的Web Notification桌面通知(右下角提示)
  9. Linux下shell命令 1
  10. IOS时间和秒的转换