• ROS通信介绍


    ROS通信介绍

    一、简单介绍

    ROS的通信方式有以下四种:

    • Topic 主题
    • Service 服务
    • Actionlib 动作库
    • Parameter Service 参数服务器

    二、Topic

    ROS中的通信方式中,topic是常用的一种。对于实时性、周期性的消息,使用topic来传输是最佳的选择。topic是一种点对点的单向通信方式,这里的“点”指的是node,也就是说node之间可以通过topic方式来传递信息。topic要经历下面几步的初始化过程:首先,publisher节点和subscriber节点都要到节点管理器进行注册,然后publisher会发布topic,subscriber在master的指挥下会订阅该topic,从而建立起sub-pub之间的通信。注意整个过程是单向的。其结构示意图如下:

    Subscriber接收消息会进行处理,一般这个过程叫做回调(Callback)。所谓回调就是提前定义好了一个处理函数(写在代码中),当有消息来就会触发这个处理函数,函数会对消息进行处理。

    上图就是ROS的topic通信方式的流程示意图。topic通信属于一种异步的通信方式。下面我们通过一个示例来了解下如何使用topic通信。

    通信示例:

    参考下图,我们以摄像头画面的发布、处理、显示为例讲讲topic通信的流程。在机器人上的摄像头拍摄程序是一个node(圆圈表示,我们记作node1),当node1运行启动之后,它作为一个Publisher就开始发布topic。比如它发布了一个topic(方框表示),叫做/camera_rgb,是rgb颜色信息,即采集到的彩色图像。同时,node2假如是图像处理程序,它订阅了/camera_rgb这个topic,经过节点管理器的介绍,它就能建立和摄像头节点(node1)的连接。

    那么怎么样来理解“异步”这个概念呢?在node1每发布一次消息之后,就会继续执行下一个动作,至于消息是什么状态、被怎样处理,它不需要了解;而对于node2图像处理程序,它只管接收和处理/camera_rgb上的消息,至于是谁发来的,它不会关心。所以node1、node2两者都是各司其责,不存在协同工作,我们称这样的通信方式是异步的。

    ROS是一种分布式的架构,一个topic可以被多个节点同时发布,也可以同时被多个节点接收。比如在这个场景中用户可以再加入一个图像显示的节点,我们在想看看摄像头节点的画面,则可以用自己的笔记本连接到机器人上的节点管理器,然后在自己的电脑上启动图像显示节点。

    这就体现了分布式系统通信的好处:扩展性好、软件复用率高。

    总结三点:

    1. topic通信方式是异步的,发送时调用publish()方法,发送完成立即返回,不用等待反馈。
    2. subscriber通过回调函数的方式来处理消息。
    3. topic可以同时有多个subscribers,也可以同时有多个publishers。ROS中这样的例子有:/rosout、/tf等等。

    在实际应用中,我们应该熟悉topic的几种使用命令,下表详细的列出了各自的命令及其作用。

    命令 作用
    rostopic list 列出当前所有的topic
    rostopic info topic_name 显示某个topic的属性信息
    rostopic echo topic_name 显示某个topic的内容
    rostopic pub topic_name ... 向某个topic发布内容
    rostopic bw topic_name 查看某个topic的带宽
    rostopic hz topic_name 查看某个topic的频率
    rostopic find topic_type 查找某个类型的topic
    rostopic type topic_name 查看某个topic的类型(msg)

    如果你一时忘记了命令的写法,可以通过rostopic helprostopic command -h查看具体用法。

    三、Service

    上一节我们介绍了ROS的通信方式中的topic(主题)通信,我们知道topic是ROS中的一种单向的异步通信方式。然而有些时候单向的通信满足不了通信要求,比如当一些节点只是临时而非周期性的需要某些数据,如果用topic通信方式时就会消耗大量不必要的系统资源,造成系统的低效率高功耗。
    这种情况下,就需要有另外一种请求-查询式的通信模型。这节我们来介绍ROS通信中的另一种通信方式——service(服务)。

    工作原理

    为了解决以上问题,service方式在通信模型上与topic做了区别。Service通信是双向的,它不仅可以发送消息,同时还会有反馈。所以service包括两部分,一部分是请求方(Clinet),另一部分是应答方/服务提供方(Server)。这时请求方(Client)就会发送一个request,要等待server处理,反馈回一个reply,这样通过类似“请求-应答”的机制完成整个服务通信。

    这种通信方式的示意图如下:
    Node B是server(应答方),提供了一个服务的接口,叫做/Service,我们一般都会用string类型来指定service的名称,类似于topic。Node A向Node B发起了请求,经过处理后得到了反馈。

    过程

    Service是同步通信方式,所谓同步就是说,此时NodeA发布请求后会在原地等待reply,直到NodeB处理完了请求并且完成了reply,NodeA才会继续执行。NodeA等待过程中,是处于阻塞状态的。这样的通信模型没有频繁的消息传递,没有对系统资源的高占用。只有接受请求才执行服务,简单而且高效。

    Topic VS Service

    我们对比一下这两种最常见的通信方式,加深我们对两者的理解和认识,具体见下表:

    名称 Topic Service
    通信方式 异步通信(就是不用等,只管发就行) 同步通信
    实现原理 TCP/IP TCP/IP
    通信模型 Publish-Subscribe(发布-订阅) Request-Reply(请求-响应)
    映射关系 Publish-Subscribe(多对多) Request-Reply(多对一)
    特点 接收者收到数据后进行回调(callback) 远程过程调用(RPC)服务器端的服务
    应用场景 连续、高频的数据发布 偶尔使用的功能/具体的任务
    举例 激光雷达、里程计发布数据 开关传感器、拍照、逆解计算

    注意:远程过程调用(Remote Procedure Call,RPC),可以简单通俗地理解为在一个进程里面调用另外一个进程的函数。

    操作命令

    在实际应用中,service通信方式的命令是rosservice,具体的命令参数如下表:

    rosservice命令 作用
    rosservice list 显示服务列表
    rosservice info 打印服务消息
    rosservice type 打印服务类型
    rosservice uri 打印服务ROSRPC uri
    rosservice find 按服务类型查找服务
    rosservice call 使用所提供的args调用服务
    rosservice args 打印服务参数

    四、Parameter server

    前文介绍了ROS中常见的两种通信方式——主题和服务,这节介绍另外一种通信方式——参数服务器(parameter server)。与前两种通信方式不同,参数服务器也可以说是特殊的“通信方式”。特殊点在于参数服务器是节点存储参数的地方、用于配置参数,全局共享参数。参数服务器使用互联网传输,在节点管理器中运行,实现整个通信过程。

    参数服务器,作为ROS中另外一种数据传输方式,有别于topic和service,它更加的静态。参数服务器维护着一个数据字典,字典里存储着各种参数和配置。

    字典简介

    何为字典,其实就是一个个的键值对,我们小时候学习语文的时候,常常都会有一本字典,当遇到不认识的字了我们可以根据部首查到这个字,获取这个字的读音、意思等等,而这里的字典可以对比理解记忆。键值key可以理解为语文里的“部首”这个概念,每一个key都是唯一的,参照下图:

    每一个key不重复,且每一个key对应着一个value。也可以说字典就是一种映射关系,在实际的项目应用中,因为字典的这种静态映射特点,我们往往将一些不常用到的参数和配置放入参数服务器的字典里,这样对这些数据读写都将方便高效。

    维护方式

    参数服务器的维护方式非常的简单灵活,总的来讲有三种方式:

    • 命令行维护
    • launch文件内读写
    • node源码

    下面分别介绍着三种维护方式:

    命令行维护

    使用命令行来维护参数服务器,主要使用rosparam语句来进行操作的各自命令,如下表:

    rosparam命令 作用
    rosparam set param_key param_value 设置参数
    rosparam get param_key 获取参数
    rosparam load file_name 从文件读取参数
    rosparam dump file_name 将参数保存至文件
    rosparam delete 删除参数
    rosparam list 列出参数名称
    load&&dump文件

    load和dump文件需要遵从YAML格式,YAML格式具体示例如下:

    name:'Zhangsan'
    age:20
    gender:'M'
    score{Chinese:80,Math:90}
    score_history:[85,82,88,90]
    
    launch文件读写

    launch文件中有很多标签,而与参数服务器相关的标签只有两个,一个是<param>,另一个是<rosparam>。这两个标签功能比较相近,但<param>一般只设置一个参数。

    node源码

    除了上述最常用的两种读写参数服务器的方法,还有一种就是修改ROS的源码,也就是利用API来对参数服务器进行操作。

    五、Action

    Actionlib是ROS中一个很重要的库,类似service通信机制,actionlib也是一种请求响应机制的通信方式,actionlib主要弥补了service通信的一个不足,就是当机器人执行一个长时间的任务时,假如利用service通信方式,那么publisher会很长时间接受不到反馈的reply,致使通信受阻。当service通信不能很好的完成任务时候,actionlib则可以比较适合实现长时间的通信过程,actionlib通信过程可以随时被查看过程进度,也可以终止请求,这样的一个特性,使得它在一些特别的机制中拥有很高的效率。

    通信原理

    Action的工作原理是client-server模式,也是一个双向的通信模式。通信双方在ROS Action Protocol下通过消息进行数据的交流通信。client和server为用户提供一个简单的API来请求目标(在客户端)或通过函数调用和回调来执行目标(在服务器端)。

    工作模式的结构示意图如下:

    通信双方在 ROS Action Protocal 下进行交流通信是通过接口来实现,如下图:

    我们可以看到,客户端会向服务器发送目标指令和取消动作指令,而服务器则可以给客户端发送实时的状态信息,结果信息,反馈信息等等,从而完成了service没法做到的部分。

    Action规范

    利用动作库进行请求响应,动作的内容格式应包含三个部分,目标、反馈、结果。

    • 目标

      机器人执行一个动作,应该有明确的移动目标信息,包括一些参数的设定,方向、角度、速度等等。

    • 反馈

      在动作进行的过程中,应该有实时的状态信息反馈给服务器的实施者,告诉实施者动作完成的状态,可以使实施者做出准确的判断去修正命令。

    • 结果

      当运动完成时,动作服务器把本次运动的结果数据发送给客户端,使客户端得到本次动作的全部信息,例如可能包含机器人的运动时长,最终姿势等等。

    Action规范文件格式

    Action规范文件的后缀名是.action,它的内容格式如下:

    # Define the goal
    uint32 dishwasher_id  # Specify which dishwasher we want to use
    ---
    # Define the result
    uint32 total_dishes_cleaned
    ---
    # Define a feedback message
    float32 percent_complete
    
    Action实例详解

    Actionlib是一个用来实现action的一个功能包集合。我们在demo中设置一个场景,执行一个搬运的action,搬运过程中客户端会不断的发回反馈过程信息,最终完成整个搬运过程。

    首先写handing.action文件,类比如上的格式,包括三个部分,目标、结果、反馈。如下:

    # Define the goal
    uint32 handling_id 
    ---
    # Define the result
    uint32 Handling_completed
    ---
    # Define a feedback message
    float32 percent_complete
    

    写完之后修改文件夹里CmakeLists.txt如下内容:

    1. find_package(catkin REQUIRED genmsg actionlib_msgs actionlib)
    2. add_action_files(DIRECTORY action FILES DoDishes.action)
    3. add_action_files(DIRECTORY action FILES Handling.action)
    4. generate_messages( DEPENDENCIES actionlib_msgs)

    修改package.xml,添加所需要的依赖如下:

    1. <build_depend>actionlib </build_depend>
    2. <build_depend>actionlib_msgs</build_depend>
    3. <run_depend>actionlib</run_depend>
    4. <run_depend>actionlib_msgs</run_depend>

    然后回到工作空间catkin_ws进行编译。

    六、原文链接

    https://blog.csdn.net/sru_alo/article/details/100100761?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-1&spm=1001.2101.3001.4242

    https://blog.csdn.net/lustyoung/article/details/103946472

    http://wiki.ros.org/ROS/Tutorials/reading msgs from a bag file

    ROS官方教程:http://wiki.ros.org/ROS/Tutorials/ExaminingPublisherSubscriber

  • 相关阅读:
    [HNOI2004]宠物收养所 题解
    文艺平衡树(区间翻转)(Splay模板)
    搜索专题 题解
    Gorgeous Sequence 题解 (小清新线段树)
    花神游历各国 题解(小清新线段树/树状数组+并查集)
    [HNOI2012]永无乡 题解
    poj 3683 2-sat问题,输出任意一组可行解
    hdu 1824 2-sat问题(判断)
    hdu 4115 石头剪子布(2-sat问题)
    hdu 4421 和poj3678类似二级制操作(2-sat问题)
  • 原文地址:https://www.cnblogs.com/huaibin/p/15016602.html
Copyright © 2020-2023  润新知