专栏首页书山有路勤为径ROS通信架构(上)

ROS通信架构(上)

Node&Master

在ROS的世界里,最小的进程单元就是节点(node)。一个软件包里可以有多个可执行文件,可执行文件在运行之后就成了一个进程(process),这个进程在ROS中就叫做节点。 例如有一个node来控制底盘轮子的运动,有一个node驱动摄像头获取图像,有一个node驱动激光雷达,有一个node根据传感器信息进行路径规划……这样做可以降低程序发生崩溃的可能性

Master

由于机器人的元器件很多,功能庞大,因此实际运行时往往会运行众多的node,负责感知世界、控制运动、决策和计算等功能。那么如何合理的进行调配、管理这些node?这就要利用ROS提供给我们的节点管理器master, master在整个网络通信架构里相当于管理中心,管理着各个node。node首先在master处进行注册,之后master会将该node纳入整个ROS程序中。node之间的通信也是先由master进行“牵线”,才能两两的进行点对点通信。当ROS程序启动时,第一步首先启动master,由节点管理器处理依次启动node。

启动master和node

启动ROS时,

roscore

此时ROS master启动,同时启动的还有 rosout 和 parameter server ,其中 rosout 是负责日志输出的一个节点,其作用是告知用户当前系统的状态,包括输出系统的error、warning等等,并且将log记录于日志文件中, parameter server 即是参数服务器,它并不是一个node,而是存储参数配置的一个服务器,后文我们会单独介绍。每一次我们运行ROS的节点前,都需要把master启动起来,这样才能够让节点启动和注册。 具体启动node的语句是:

rosrun pkg_name node_name

通常我们运行ROS,就是按照这样的顺序启动,有时候节点太多,我们会选择用launch文件来启动,下一小节会有介绍。 Master、Node之间以及Node之间的关系如下图所示:

rosrun &rosnode

rosrun命令的详细用法如下:

rosrun  [--prefix cmd] [--debug] pkg_name node_name [ARGS]

rosrun将会寻找PACKAGE下的名为EXECUTABLE的可执行程序 rosnode 命令的详细作用列表如下:

以上命令中常用的为前三个,在开发调试时经常会需要查看当前node以及node信息

roslaunch

通常一个机器人运行操作时要开启很多个node,并不需要每个节点依次进行rosrun,ROS为我们提供了一个命令能一次性启动master和多个node。该命令是:

roslaunch pkg_name file_name.launch

roslaunch命令首先会自动进行检测系统的roscore有没有运行,也即是确认节点管理器是否在运行状态中,如果master没有启动,那么roslaunch就会首先启动master,然后再按照launch的规则执行。launch文件里已经配置好了启动的规则。 所以 roslaunch 就像是一个启动工具,能够一次性把多个节点按照我们预先的配置启动起来,减少我们在终端中一条条输入指令的麻烦。 launch文件写法及格式:

<launch> <!--根标签-->
    <node> <!--需要启动的node及其参数-->
    <include> <!--包含其他launch-->
    <machine> <!--指定运行的机器-->
    <env-loader> <!--设置环境变量-->
    <param> <!--定义参数到参数服务器-->
    <rosparam> <!--启动yaml文件参数到参数服务器-->
    <arg> <!--定义变量-->
    <remap> <!--设定参数映射-->
    <group> <!--设定命名空间-->
</launch> <!--根标签-->

参考链接:http://wiki.ros.org/roslaunch/XML

通信方式

ROS的通信方式是ROS最为核心的概念,ROS系统的精髓就在于它提供的通信架构。ROS的通信方式有以下四种:

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

Topic

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

通信示例

以摄像头画面的发布、处理、显示为例讲讲topic通信的流程: 在机器人上的摄像头拍摄程序是一个node(圆圈表示,我们记作node1),当node1运行启动之后,它作为一个Publisher就开始发布topic。比如它发布了一个topic(方框表示),叫做/camera_rgb,是rgb颜色信息,即采集到的彩色图像。同时,node2假如是图像处理程序,它订阅了/camera_rgb这个topic,经过节点管理器的介绍,它就能建立和摄像头节点(node1)的连接。 在node1每发布一次消息之后,就会继续执行下一个动作,至于消息是什么状态、被怎样处理,它不需要了解;而对于node2图像处理程序,它只管接收和处理/camera_rgb上的消息,至于是谁发来的,它不会关心。所以node1、node2两者都是各司其责,不存在协同工作,我们称这样的通信方式是异步的。

ROS是一种分布式的架构,一个topic可以被多个节点同时发布,也可以同时被多个节点接收。比如在这个场景中用户可以再加入一个图像显示的节点,我们在想看看摄像头节点的画面,则可以用自己的笔记本连接到机器人上的节点管理器,然后在自己的电脑上启动图像显示节点。 这就体现了分布式系统通信的好处:扩展性好、软件复用率高。 总结三点:

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

Topic有很严格的格式要求,,比如上节的摄像头进程中的rgb图像topic,它就必然要遵循ROS中定义好的rgb图像格式。这种数据格式就是Message。Message按照定义解释就是topic内容的数据类型,也称之为topic的格式标准。这里和我们平常用到的Massage直观概念有所不同,这里的Message不单单指一条发布或者订阅的消息,也指定为topic的格式标准。 我们用一个具体的msg来了解,例如上例中的msg sensor_msg/image,位置存放在sensor_msgs/msg/image.msg里.

std_msg/Header header
    uint32    seq
    time    stamp
    string    frame_id
uint32    height
uint32    width
string    encoding
uint8    is_bigendian
uint32    step
uint8[]    data

观察上面msg的定义,是不是很类似C语言中的结构体呢?通过具体的定义图像的宽度,高度等等来规范图像的格式。所以这就解释了Message不仅仅是我们平时理解的一条一条的消息,而且更是ROS中topic的格式规范。或者可以理解msg是一个“类”,那么我们每次发布的内容可以理解为“对象”,这么对比来理解可能更加容易。

操作命令
操作演示
roslaunch robot_sim_demo robot_spawn.launch
rostopic list
rostopic info /camera/rgb/image_raw
rosrun image_view image_view image:=/camera/rgb/image_raw
rostopic info /camera/depth/image_raw

类型依旧是sensor_mags/Image,所以依旧可以用 image_view node来查看

rosrun robpt_sim_demo robot_keyboard_teleop.py

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 认识ROS

    1.节点(node)--软件模块 执行任务的进程 2.节点管理器(ROS Master)控制中心,提供参数管理 记录每个节点信息 3.话题(topic)...

    小飞侠xp
  • 排序数组转换为二叉查找树

    已知一个排序的数组,将该数组转换为一个高度平衡的二叉查找树。 平衡的定义: 二叉查找树中,任意节点的两颗子树高度差不超过1. LeetCode 108

    小飞侠xp
  • 2.ROS基础-ROS通信编程

    程序逻辑: 1.头文件 2.ROS节点初始化,前两个参数和main()函数参数一致,最后一个参数定义节点名称。 3.创建节点句柄 比较方便的去管理节点的资...

    小飞侠xp
  • Keeplived+mysql双master高可用如何实现?

    https://oscimg.oschina.net/oscnet/up-18b70e55451e4e69d0f449e6329034bdcfa.png

    网络技术联盟站
  • PHPer 学产品[2]|扁平化设计

    猿哥
  • 使用Java生成带有下划线字体的文字

    ydymz
  • 《【面试突击】— Redis篇》-- Redis的主从复制?哨兵机制?

    高并发:redis的单机吞吐量可以达到几万不是问题,如果想提高redis的读写能力,可以用redis的主从架构,redis天热支持一主多从的准备模式,单主负责写...

    编程大道
  • MVC架构在Asp.net中的应用和实现

    摘要:本文主要论述了MVC架构的原理、优缺点以及MVC所能为Web应用带来的好处。并以“成都市信息化资产管理系统”框架设计为例,详细介绍其在Asp.net环境下...

    莫问今朝
  • ASP.NET MVC学习笔记03视图

    早在ASP.NET MVC 3就引入了Razor视图引擎( Razor view engine)。Razor视图模板文件使用.cshtml文件扩展名,并提供了...

    李郑
  • 利用云计算实现网络智能

    美国国家安全局总顾问Glenn Gerstell最近在《纽约时报》发表了一篇评论文章,描述了美国在二战之后开发的国家安全系统如何可靠地对外国军事发展(如发射导弹...

    静一

扫码关注云+社区

领取腾讯云代金券