ROS通信机制全解析

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

  • Topic 主题

  • Service 服务

  • Parameter Service 参数服务器

  • Actionlib 动作库

Topic(发布/订阅)

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

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

注意整个过程是单向的。

  • Talker向ROS Master注册

  • Listener向ROS Master注册

  • ROS Master通过RPC向Listener发送Talker的地址信息

  • Listener接收到地址信息,通过RPC向Talker发送连接请求

  • Talker确认连接请求,通过RPC向Listener确认连接

  • Listener与Talker建立网络连接

  • Talker向Listener发布数据

总结:前五步的通信协议都是RPC,最后两步传输数据才用TCP

通信示例

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

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

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

总结三点

  1. topic通信方式是异步的,发送时调用publish()方法,发送完成立即返回,不用等待反馈。

  2. subscriber通过回调函数的方式来处理消息。

  3. topic可以同时有多个subscribers,也可以同时有多个publishers。ROS中这样的例子有:/rosout、/tf等等。

操作命令

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

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

topic的通信方式是ROS中比较常见的单向异步通信方式,它在很多时候的通信是比较易用且高效的。但是有些需要交互的通信时该方式就显露出自己的不足之处了,后续我们会介绍双向同步的通信方式service

Message

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

结构与类型

基本的msg包括bool、int8、int16、int32、int64(以及uint)、float、float64、string、time、duration、header、可变长数组array[]、固定长度数组array[C]。那么具体的一个msg是怎么组成的呢?我们用一个具体的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是一个“类”,那么我们每次发布的内容可以理解为“对象”,这么对比来理解可能更加容易。 我们实际通常不会把Message概念分的那么清,通常说Message既指的是类,也是指它的对象。而msg文件则相当于类的定义了。

操作命令

rosmsg的命令相比topic就比较少了,只有两个如下:

### ROS通信机制原理概述 ROS(Robot Operating System)的通信机制设计旨在支持分布式系统的高效协作,其核心理念在于解耦各个功能模块,使它们能够作为独立的进程运行。这种架构允许开发者灵活地构建复杂机器人应用[^3]。 #### 1. 核心组件 - **节点管理器 (ROS Master)** ROS Master 是整个系统的核心组件,负责协调各节点之间的交互。它维护着所有活动节点的信息表,并提供名称解析服务。当新节点加入时,ROS Master 将该节点注册到局列表中,以便其他节点可以通过名称找到目标节点[^4]。 - **节点 (Node)** 每个节点代表一个独立的工作单元或进程,通常对应具体的功能实现,比如传感器数据采集、路径规划或者电机驱动控制等操作。多个节点共同构成完整的机器人应用程序体系结构[^1]。 #### 2. 主要通信形式 ##### (1)话题通信 (Topic Communication) - 这种模式采用发布/订阅的方式让生产方与消费方共享信息流。 - 发布者会持续不断地向某主题广播最新状态更新;而订阅者则监听感兴趣的主题来接收相应的内容推送。 - 特点包括异步性、高吞吐量以及缺乏即时确认机制等特点使其非常适合用于大规模连续型传感数据分发场合。 ```python import rospy from std_msgs.msg import String def talker(): pub = rospy.Publisher('chatter', String, queue_size=10) rospy.init_node('talker', anonymous=True) rate = rospy.Rate(10) # 10hz while not rospy.is_shutdown(): hello_str = "hello world %s" % rospy.get_time() rospy.loginfo(hello_str) pub.publish(hello_str) rate.sleep() if __name__ == '__main__': try: talker() except rospy.ROSInterruptException: pass ``` ##### (2)服务调用 (Service Call) - 请求/响应式的互动方式使得一方能主动发起询问另一方给予答复完成一次事务处理过程。 - 整个交易期间双方保持紧密联系直到最终结果返回为止因此具备较强的时效保障能力特别适合那些需要精确操控指令下达的应用环境之中[^5]。 ```python #!/usr/bin/env python import rospy from beginner_tutorials.srv import AddTwoInts,AddTwoIntsResponse def handle_add_two_ints(req): print ("Returning [%s + %s = %s]"%(req.a, req.b, (req.a + req.b))) return AddTwoIntsResponse(req.a + req.b) def add_two_ints_server(): rospy.init_node('add_two_ints_server') s = rospy.Service('add_two_ints', AddTwoInts, handle_add_two_ints) print("Ready to add two ints.") rospy.spin() if __name__ == "__main__": add_two_ints_server() ``` ##### (3)行为树 (Actionlib) - 结合长时间任务的特点融合了上述两种方法的优点既保留了长期跟踪进度的能力又不失快速反应的优势成为执行较复杂动作序列的理想工具之一。 --- ### 数据传输基础 无论是哪种类型的通讯手段背后均依赖底层网络协议栈来进行实际的消息打包拆包作业其中最常用的就是TCP/IP族成员——即通过标准socket API达成跨机器边界的有效沟通目的同时为了简化开发难度还额外引入了一层封装好的API接口方便程序员直接操纵而不必关心太多细节部分[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

芯动大师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值