实验速度

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. Spring Boot 微服务应用集成Prometheus + Grafana 实现监控告警

    Spring Boot 微服务应用集成Prometheus + Grafana 实现监控告警 一.添加依赖 1.1 Actuator 的 /prometheus端点 二.Prometheus 配置 部 ...

  2. 使用Docker Compose编排Spring Cloud微服务

    文章目录 微服务构建实例 简化Compose的编写 编排高可用的Eureka Server 编排高可用Spring Cloud微服务集群及动态伸缩 微服务项目名称 项目微服务中的角色 microser ...

  3. 4. DHCP配置(Windows2012)

    1.点击服务器管理器 2.选择添加角色和功能 3. 按照添加角色和功能向导来添加 保持默认,下一步 保持默认,下一步 保持默认,下一步 勾选DHCP服务器,在弹出的小窗点击添加功能. 保持默认,下一步 ...

  4. Jenkins(3)拉取git仓库代码,执行python自动化脚本

    前言 python自动化的脚本开发完成后需提交到git代码仓库,接下来就是用Jenkins拉取代码去构建自动化代码了 新建项目 打开Jenkins新建一个自由风格的项目 源码管理 Repository ...

  5. HDU5740 Glorious Brilliance【最短路 KM匹配】

    HDU5740 Glorious Brilliance 题意: 给出一张不一定合法的染色图,每次可以交换相邻两点的颜色,问最少多少次能使染色图合法 合法的染色图相邻点的颜色不能相同 题解: 首先要确定 ...

  6. 抓取QQ音乐歌单

    抓取QQ音乐歌单1.通过分析歌曲下载路径来分析所需参数: 通过比较, 得出其中歌曲下载url与参数vkey是可变的,歌曲下载url中可变得值是请求歌单返回的歌曲数据的strMediaMid参数, 而v ...

  7. 错误: 未能完成程序集的安装(hr = 0x8007000b)。探测终止。

     解决方案:VS中"工具"->"选项"->"Web项目"->"对网站和项目使用IIS Express的64位版& ...

  8. 7.PowerShell DSC之模式

    DSC两种模式 DSC有两种模式,Push模式和Pull模式 Push模式 基本流程 写配置--编译生成mof--推送到目标服务器,由目标服务器LCM执行mof并进行指定的配置 优点 架构简单.成本低 ...

  9. 【非原创】codeforces 1025D - Recovering BST【区间dp+二叉搜索树】

    题目:戳这里 题意:给一个不下降序列,有n个数.问能否构造一个二叉搜索树,满足父亲和儿子之间的gcd>1. 解题思路:其实这题就是构造个二叉搜索树,只不过多了个条件.主要得了解二叉搜索树的性质, ...

  10. leetcode17 电话号码的字母组合 dfs

    就dfs吧.... 然后,我傻了.前一道题不用考虑空,这道题就要考虑.... 还有注意vector要引用传递 class Solution { public: void dfs(string temp ...