实验速度

1. via topic

上图是以前ROS课上做的一个实验,内容是测试一个publisher和一个subscriber之间通讯所用的时间。两个node都很简单,publisher发送一个字符串,字符串带有标号;subscriber回显该字符串,字符串长度不超过20个char。

怎么去标定发送时间是接收时间呢?目前使用的方法就是在publisher发送前使用ROS_INFO输出一个消息,消息会带有ROS的时间戳;subscriber的callback函数里边也使用ROS_INFO输出一个带时间戳的消息。虽然说这种方法并不是非常精准,但目前也没有想到更好的办法了,哪怕是使用header里边的time stamp也有一个获得当前时间和赋值的过程,难以百分百精确,所以目前只能这样粗略测量。

根据实验数据可以发现在同一台机器上,两个node通过topic通讯,大致产生0.7ms的延迟。(本人机子i5-3210M/4G)

2. via service

这张图是今天自己做的测试,可以看到平均时间大约在3ms左右。

测量的方法也是跟上面的类似。Client在call之前先输出一个带时间戳的消息,server在接收到请求执行操作前也会输出一个带时间戳的消息。这次client与server之间传递的消息更短,是两个int。

从上图我们不难发现,通过service通讯居然比topic延迟要高?实在是不愿意相信,因为这跟我一开始的理解是相违背的。为了控制实验环境平台的一致性(我从groovy换到了indigo),于是重做了以前的那个实验,粗测通过topic传输的延迟时间,发现依然是0.7ms左右。


理论速度

为何前面的实验结果让我如此惊讶?

官方文档中写明,client与server之间维持着一个持久连接。对于这种RPC请求/回复机制,官方给出的评价是“面对低鲁棒性的服务程序变更有着更好的性能表现”(higher performance at the cost of less robustness to service provider changes)1

说到持久连接,不禁让人想起ROSTCP。照这么说,如果在ROS架构下node之间通讯的底层实现都是通过ROSTCP/ROSUDP的话,那理应via service应该跟via topic的速度相当,如果将“持久性”纳入考虑范围的话,service甚至应该比topic更快一些才对。但实际情况是via service的时延是via topic的4倍左右。如此大的差距,实在让人百思不得其解。


实现机制——同步与异步

其实在开始写这篇博文的时候,我都依然没有想明白这个问题。边写边查资料,看到ros answer上一位大大在描述这两种机制时,用到了asynchronous和synchronous这两个字眼2。回到宿舍一边洗着冷水澡一边在想,忽然灵光一现!是的,实验的结果是没有问题的,有问题的是我的实验方法!

- Asynchronous Topic

Topic是异步的。简简单单的一句话,里边却隐含了千言万语。让我关注起这一点的原因除了ros answer上面的那篇问答,还有一个就是自己做的另一个实验:创建一个publisher,pub的速度是100Hz,发送缓冲区的大小只有1;创建一个subscriber,调用callback函数的的速度是1Hz(用spinOnce),但接收缓冲区的大小是1000。这样的效果就是,publisher近乎匀速地发送着数据,每秒100次;而subscriber每一秒调用一次callback函数(spinOnce),每次调用都一次性地处理接收缓冲区内的所有数据。由于接收缓冲区大小远大于发送频率,所以接收缓冲区不存在满的情况,所以就能看到subscriber每秒都会很快地处理完100条消息,然后进入休眠,再被唤醒执行callback,再休眠……

而之前用于测试的subscriber,我使用的是spin。这也就意味着,回调函数一直是处于类似于忙等待的状态的,一旦发现接收缓冲区内有数据,即刻取出作运算(前提当然是获得CPU分片时间)。这也就说明了为什么实验得出的结果via topic会更快!但要注意了,忙等待是会占用硬件资源的。在这种简单的实验条件下,via topic固然是很快,但当一个大项目跑起来时,它之前的高性能表现可能要大打折扣。

- Synchronous Service

至于server,在基于RPC请求/回复机制的前提下,它在接收到调用请求前都是处于休眠状态的。Client的call请求将server唤醒,然后server执行请求,再返回结果给client。所以之前在计时的时候,大部分的时间都是消耗在将server从休眠状态唤醒上了!所以才会看起来比via topic慢。

分析到这里,我就在想,那真正的client与server之间通讯的时延,是不是可以利用server返回结果给client这段时间算出呢?这才是真正抛开了将server从休眠唤醒的时间影响,是client与server通讯的真正时延!于是又有了下图: 

果不其然!表中数据的中位数应该在0.3ms左右,也就是说,从server返回结果到client接收到结果,只需要0.3ms的时间!尽管使用spin通过topic转发数据类似于忙等待(也许ROS的内部机制会对spin的频率作最高限制),但也需要大约0.7ms的时间!而service机制中,client发出call请求之后就会进入阻塞状态,直至server返回结果,期间的时延是via topic的一半而已!

而从这个数据我们还可以估计出将休眠状态的server唤醒,所需要的时间大约是2.7ms。如果计算一来一回,client从发出call请求到接收返回结果,除去请求被执行的时间,在通讯上耗费的时间约是3.3ms,其中将server唤醒的时间约占82%!

- Conclusion

Topic与Service各有优劣。在设计项目的时候,要周全考虑各个方面的因素。Service比较适合用于执行复杂的、调度次数较低的任务。而topic则适合在通讯频率高的情况下使用。再者,使用ros::Rate和sleep合理设置程序的执行速率,能使程序弹性更大,增强可维护性。使用topic时,也别忘了关注一下缓冲区的大小设置。


优劣分析

Service

- 优点:

  • Client只需要关注发出命令请求、接收反馈,而无须关注底层实现,系统可维护性高
  • Client维护着一个与server的持久连接(persistent connection),在单纯的数据传输上可以做到更快,尤其是在分布式作业时

- 缺点:

  • 当server单方改变执行模式或者存在bug的时候,client无法得知具体情况,因为server程序对client而言是透明的。在这种情况下,client只能得到一个错误的数据,或者被告知执行失败,甚至是等待超时
  • Server唤醒耗时太大,不建议用于通讯频率高的情况

Topic

- 优点:

  • 能非常方便地通过监听topic的方法查看各个node的运行状态等信息,可维护性高
  • 能根据实际情况调整发送速率、发送/接收缓冲区大小,使之适应项目需求
  • Topic是多对多的,可操作性强;而service只能一对多(一个server应对多个client)

- 缺点:

    • 因为是异步架构,回调函数的执行频率设计对系统整体性能影响很大
    • 对于使用频率不高的程序,若使用topic进行信息交换,想要减少额外系统开销的办法就是降低回调的速率。但一旦降低回调的速率,同时受到负面影响的还有系统的实时性

【转】ROS之topic和service通信比较的更多相关文章

  1. ROS(二)Service通信

    使用自定义的消息类型,实现service方式的节点间双向通信 在package目录下创建msg和srv目录,存放package需要使用的.msg和.srv文件. 在ROS中,message被设计为一种 ...

  2. ROS Node/Topic/Message/Service的一些问题

    1.Node http://blog.exbot.net/archives/1412 (摘自老王说ros) node干的什么活?callback queue里的活.这个callback queue里的 ...

  3. ROS学习(七)—— 理解ROS Topic

    一.准备工作 1.打开roscore roscore 2.turtlesim 打开一个turtulesim节点 rosrun turtlesim turtlesim_node 3.turtle key ...

  4. Service通信

    1.简介 Service通信是双向的, 它不仅可以发送消息, 同时还会有反馈. 所以service包括两部分, 一部分是请求方( Clinet) , 另一部分是应答方/服务提供方( Server) . ...

  5. 为应用程序池“XX”提供服务的进程在与 Windows Process Activation Service 通信时出现严重错误

    场景 WCF应用程序部署在IIS7中,使用net.tcp协议对外给几百台客户端提供服务,应用程序池不断崩溃重启. 分析过程 在事件查看器中看到的错误信息类似于 为应用程序池“XX”提供服务的进程在与 ...

  6. 通过AIDL在两个APP之间Service通信

    一.项目介绍 [知识准备] ①Android Interface definition language(aidl,android接口定义语言),其目的实现跨进程的调用.进程是程序在os中执行的载体, ...

  7. [转帖]为应用程序池“XXX”提供服务的进程在与 Windows Process Activation Service 通信时出现严重错误。该进程 ID 为“XXXX”。数据字段包含错误号。

    [终极解决方案]为应用程序池“XXX”提供服务的进程在与 Windows Process Activation Service 通信时出现严重错误.该进程 ID 为“XXXX”.数据字段包含错误号. ...

  8. IIS 为应用程序池提供服务的进程在与 Windows Process Activation Service 通信时出现严重错误的解决方法

    系统环境:Windows Server 2008 R2 64位, IIS 7.0 错误信息: 为应用程序池提供服务的进程在与 Windows Process Activation Service 通信 ...

  9. Activity与Service通信

    Activity与Service通信的方式有三种: 继承Binder类 这个方式只有当你的Acitivity和Service处于同一个Application和进程时,才可以用,比如你后台有一个播放背景 ...

随机推荐

  1. Android webview 问题记录

    1. Android 7.1真机安装调试apk时报错,解析安装包失败 原因:sdk版本不支持7.1版本,需要调整minSdkVersion等参数,支持低版本 解决方法: android { compi ...

  2. scala 两个map合并,key相同时value相加/相减都可

    scala 两个map合并,key相同时value相加 1.map自带的合并操作 2.map函数 2.1示例 2.2合并两个map 3.用foldLeft 3.1 语法 3.2 合并两个map 1.m ...

  3. 使用Spring StateMachine框架实现状态机

    spring statemachine刚出来不久,但是对于一些企业的大型应用的使用还是十分有借鉴意义的. 最近使用了下这个,感觉还是挺好的. 下面举个例子来说下吧: 创建一个Spring Boot的基 ...

  4. linux 一分钟搭建zookeeper linux 单机版(亲测可用)

    wget https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.4.14/zookeeper-3.4.14.tar.gzt ...

  5. 通过SignalR技术整合即时通讯(IM)在.NET中应用落地

    1.引言 即时通讯(IM)是RDIFramework.NET敏捷开发框架全新提供的一个基于Web的即时通讯.内部聊天沟通的工具.界面美观大方对于框架内部进行消息的沟通非常方便.基于RDIFramewo ...

  6. Codeforces Round #594 (Div. 2) D1 - The World Is Just a Programming Task (贪心)

    思路:枚举换的位置i,j 然后我们要先判断改序列能否完全匹配 如果可以 那我们就需要把差值最大的位置换过来 然后直接判断就行

  7. 【uva 11491】Erasing and Winning(算法效率--贪心+单调队列)

    题意:有一个N位整数,要求输出删除其中D个数字之后的最大整数. 解法:贪心.(P.S.要小心,我WA了2次...)由于规定了整数的位数,那么我们要尽量让高位的数字大一些,也就是要尽量删去前面小的数字. ...

  8. 数学知识-欧拉函数&快速幂

    欧拉函数 定义 对于正整数n,欧拉函数是小于或等于n的正整数中与n互质的数的数目,记作φ(n). 算法思路 既然求解每个数的欧拉函数,都需要知道他的质因子,而不需要个数 因此,我们只需求出他的质因子, ...

  9. Selenium刚玩一会儿,就感受了私人秘书的体验

    学习python的过程中,少不了接触第三方库,毕竟作为胶水语言python的强大之处也就是第三方库体量庞大,无疑大大增强了python的战斗力. 有时候想完成网页自动化操作,这时候Selenium进入 ...

  10. Oracle数据库故障处理方法

    1.启动数据库报错:ORA-01102:cannot mount database in EXCLUSIVE mode 给客户处理oracle故障,遇到如下报错: 以sys登录至数据库,执行shutd ...