首页 > 其他分享 >关于ros中的回旋函数

关于ros中的回旋函数

时间:2024-04-09 13:59:00浏览次数:22  
标签:订阅 回调 函数 队列 subscriber 回旋 消息 ros

首先spinOnce和spin区别:

spin就会进入一个循环体,一直检测消息队列的回调函数,而spinonce则只检测一遍消息队列,然后接着运行下面的语句。

首先要了解:

ROS中,publisher和subscriber都有一个消息队列用于数据收发时候的缓存。ROS话题的通信是异步的,也就是publisher只管不停的发但不管是否被接收,publisher是向Topic的消息队列发布信息,而不是publisher直接push给subscriber,publisher发送数据后,订阅该topic的subscriber则会过来读取,系统会通过位置指针管理不同subscriber读取消息队列的位置,因此可以支持任意多个subscriber对话题进行读取,每个subscriber读取到数据后,会将数据放置到自己的缓存队列上,然后通过回旋函数spin来调用回调函数。

   综上所述,publisher不停将消息发布到消息队列上,直到队列占满,然后新到的消息把最老的消息挤出队列,因此,publisher消息队列的作用就是,缓存一定数量的历史信息,让不能及时订阅的subscriber能读取到之前发布的信息。如果没这个需求或是想让subscriber读取到最新的消息,那么让消息队列长度设为1 。
    而subscriber的消息队列的作用是,将回调函数来不及处理的信息及时的缓存,这样不至于因为回调函数执行或调用过慢,导致数据的丢失。

两个消息队列都是先进先出的规则,即新到的消息把最老的消息挤出队列。然后subscriber的消息队列每个收到的消息还对应着回调函数,有几个消息就有即次回调函数。所有subscriber还有一个共用的全局消息队列用来存储待触发的回调函数,可以称其为回调队列。

注意:发布方和订阅方之间的通信和有没有回旋函数spin无关,即只要网络正常,发布方一发信息订阅方就会接收到并存储在消息队列中,当程序执行spin时,会按照订阅方的消息队列中的顺序来执行回调函数。

一些结论

​ 每次调用ros::spinOnce()都会执行与消息队列中缓存的信息数量相同次数的回调函数,只要回调函数执行够快的话,就能清空队列。当多个不同的subscriber都需要调用回调函数时,则按顺序依次执行各个subscriber的回调函数。这个顺序就是全局消息队列里接收消息的顺序,所有subscriber有一个共用的全局消息队列,用来存放待执行的回调函数。

spinOnce()在执行的那一刻,并不是只处理队列中的一个回调函数就返回了,而是会处理当时队列中存在的所有回调函数。

注意:执行回调函数的时候,每个订阅方自己的消息队列并不会被锁定住。每个订阅方不是对应两个消息队列吗,一个是每个订阅方自己储存收到的数据的消息队列,另一个则是所有订阅方共用的储存回调函数执行顺序的全局消息队列。当spinonce调用时,共用的回调函数的全局消息队列这个锁定,比如有七个回调函数要执行就按七个来,然后根据全局消息队列里的顺序依次执行回调函数,每个回调函数去寻找对应的订阅方自己的存储数据的消息队列,然后取得对应的数据。然而,每个订阅方自己的存储数据的消息队列是没有锁住的,即是在不断接收消息的,新的消息会将旧的消息顶出去,来替代旧的消息。也就是每个回调函数有一个指针指向订阅方自己的消息队列的固定的地址,但这个地址里的数据是会被新的顶掉的。

关于回调函数的定义

回调函数的形参的数据类型为发布方所发布的消息的数据类型。

例如发布方为:

ros::Publisher pub = nh.advertise<std_msgs::String>("chatter",10);

则订阅方的回调函数为:

void doMsg(const std_msgs::String::ConstPtr& msg_p){
    ROS_INFO("我听见:%s",msg_p->data.c_str());
}

标签:订阅,回调,函数,队列,subscriber,回旋,消息,ros
From: https://blog.csdn.net/weixin_43902341/article/details/137526462

相关文章

  • 关于ros中导航用到的栅格地图
    首先了解到导航所用的栅格地图的消息类型经查阅资料可知为nav_msgs/OccupancyGrid。$rosmsgshownav_msgs/OccupancyGridstd_msgs/Headerheader#数据的消息头uint32seq#数据的序号timestamp#数据的时......
  • ES查询之聚合函数、分组查询
    目录一、前言二、准备数据三、avg四、max五、min六、sum七、多个聚合和嵌套聚合七、分组查询一、前言聚合函数大家都不陌生,同数据库的聚合函数一样,elasticsearch中也没玩出新花样,所以,这一章相对简单,只需要记得下面几个用法即可:avgmaxminsum聚合的两个主要的......
  • 【论文笔记-4】Cross-lingual learning for text processing: A survey
    跨语言知识迁移学习分类:转移资源:“什么”正在帮助转移multilingualwordembeddings:即来自多种语言的词汇共享一个语义向量空间。已经提出了许多用于训练多语言词嵌入(MWE)的模型(Mikolov,Le,&Sutskever,2013;Ammaretal.,2016;Gouws&Søgaard,2015)。Ruder(2017)提......
  • Item30:inline函数
    芝士wa2024.4.9原理内联函数是C++的增强特性之一,用来降低程序的运行时间。作用机理:把内联函数的函数体在编译器预处理的时候替换到函数调用处(副本),这样代码运行到这里的时候就不需要花时间去调用函数(减少了函数调用过程的入栈出栈开销)。此外,内联函数仅仅是对编译器的内联建议......
  • C++与Qt中回调函数的两种实现方法
    一.回调函数介绍1.概念回调函数是一种在程序运行期间通过函数指针调用的函数,它通常用于实现事件驱动、异步通信、消息传递等功能。在回调函数中,被调用的函数通常称为回调函数(CallbackFunction),而调用回调函数的函数通常称为回调函数容器(CallbackContainer)。回调函数容器可......
  • 20240408,C++数组,函数,指针
    是谁说回老家学习结果摆烂了两天,是我,Π—Π! Π—Π!! 一,数组——同C1.1一维数组1.0  相同类型,连续内存,1.1  定义格式:数据类型数组名【长度】;数组类型数组名【长度】={1,2,3,……};数组类型数组名【】={1,2,3,……};1.2  遍历数组,初始化,下标【0-N】1.3  数组名:数......
  • 【简单讲解下C++max函数的使用】
    ......
  • react 函数组件和hook
    函数组件1.函数组件没有生命周期2.函数组件没有this3.函数组件通过hook完成各种操作4.函数组件本身就是render函数5.props在函数第一个参数解释useState参考https://www.cnblogs.com/ssszjh/p/14581014.htmlprops参考https://www.cnblogs.com/ssszjh/p/18118746生命周期......
  • 【Kotlin】运算符函数、解构函数、中缀函数
    1一元运算符函数1.1符号和函数符号函数+aa.unaryPlus()-aa.unaryMinus()!aa.not()a++a.dec()a--a.inc()1.2案例funmain(){varstu=Student("Tom",13)println(-stu)//打印:[moT,31]}classStudent(varname:String,va......
  • 【Kotlin】扩展属性、扩展函数
    1类的扩展​Kotlin提供了扩展类或接口的操作,而无需通过类继承或使用装饰器等设计模式,来为某个类添加一些额外的属性或函数,我们只需要通过一个被称为扩展的特殊声明来完成。通过这种机制,我们可以将那些第三方类不具备的功能强行进行扩展,方便我们的操作。1.1扩展内置类1.1......