不同计算机之间的 ROS 通信

本文详细介绍了在ROS环境中实现多台计算机间通信的过程,包括时间同步、网络配置、环境变量设置及节点运行等步骤,确保了不同设备间的有效通信。

ROS的一个典型应用场景是:在机器人上安装一台笔记本或单板机,然后在桌面计算机上监视或控制机器人,这时就需要在机器人与桌面计算机之间进行通信。ROS使得多台机器观察同一套话题、服务和参数变得相当容易。

1. 使用 chrony 进行时间同步

ROS网络中的很多消息都带有时间戳,机器之间的时间同步往往很非常关键。一种使计算机保持同步状态的简单方法是在桌面计算机和机器人上同时安装 chrony 数据包。该数据包会保持计算机上的时钟与互联网服务器上的时钟一致,从而使得每台计算机的时间都同步。

安装 chrony

$ sudo apt install chrony

安装完成之后,chrony守护进程会自动启动并且开始让计算机与数台互联网服务器直接同步时间。

2. 使用 Zeroconf 进行 ROS 联网

Ubuntu 支持 Zeroconf技术,允许同一子网下的不同设备通过本地主机名而不是 IP 地址来连接彼此。

使用 hostname 命令来获取所使用设备的短名称,该命令会输出你在 Ubuntu 初始化设置时设置的主机名称。

$ hostname
my_desktop

假设桌面计算机的名称为 my_desktop,机器人的名称为 my_robot。则对应的 Zeroconf名称分别为 my_desktop.localmy_robot.local

3. 测试连通性

使用ping命令来确保两台电脑之间基本的连通性。

(1)在桌面计算机上 ping 机器人

$ ping my_robot.local
PING my_robot.local (192.168.1.7) 56(84) bytes of data.
64 bytes from my_robot (192.168.1.7)
### ROS分布式通信协议的实现方式 ROS(Robot Operating System)通过其内置的分布式通信机制,支持节点间的跨进程、跨机器通信。这种通信主要依赖于发布/订阅模型和中间件协议[^1]。在ROS中,每个节点可以作为消息的发布者或订阅者,它们通过话题(Topic)进行数据交换。为了确保通信的正确性,发布者和订阅者必须使用相同类型的消息格式[^3]。 #### 1. 发布/订阅模型 在ROS中,发布/订阅模型是节点间通信的核心机制之一。该模型允许一个或多个节点(发布者)将消息发送到特定的话题,而其他节点(订阅者)可以从该话题接收消息。这种松耦合的设计使得节点之间的依赖关系最小化,从而提高了系统的灵活性和可扩展性[^1]。 #### 2. 中间件协议 ROS通信依赖于一种名为TCPROS的中间件协议。TCPROS基于TCP/IP协议栈,提供了可靠的点对点通信。此外,对于实时性要求较高的场景,ROS还支持UDPROS协议,这是一种基于UDP的轻量级传输方式。 #### 3. 消息格式 为了确保不同节点之间能够正确地解析和处理数据,ROS定义了一套标准化的消息格式。这些消息格式被封装为`.msg`文件,并可以通过命令如`rosmsg show`查看其详细信息[^3]。每个消息类型都有明确的字段定义,例如整数、浮点数、字符串等,确保了数据在不同节点间的互操作性。 #### 4. 跨机器通信ROS节点分布在不同计算机上时,通信需要借助ROS Master进行协调。ROS Master充当名称注册服务的角色,负责将节点的发布者和订阅者信息进行匹配[^2]。一旦匹配成功,节点之间可以直接建立点对点连接,而无需持续依赖ROS Master。 #### 5. ROS2中的DDS 在ROS2中,分布式通信机制得到了进一步增强,引入了DDS(Data Distribution Service)作为底层中间件[^4]。DDS提供了一种高效、可靠的数据分发服务,支持多种传输协议和质量保证策略(QoS)。通过设置域ID(ROS_DOMAIN_ID),可以控制哪些节点能够相互发现并通信。默认情况下,所有节点共享同一个域ID(0),因此在同一网络中无需额外配置即可实现分布式通信。 ```python # 设置ROS2域ID的示例 export ROS_DOMAIN_ID=10 ``` ### 示例代码:创建一个简单的发布者和订阅者 以下是一个简单的ROS2节点示例,展示了如何通过话题实现节点间的通信: ```python # 发布者节点 import rclpy from rclpy.node import Node from std_msgs.msg import String class MinimalPublisher(Node): def __init__(self): super().__init__('minimal_publisher') self.publisher_ = self.create_publisher(String, 'topic', 10) timer_period = 0.5 # seconds self.timer = self.create_timer(timer_period, self.timer_callback) self.i = 0 def timer_callback(self): msg = String() msg.data = f'Hello World: {self.i}' self.publisher_.publish(msg) self.get_logger().info(f'Publishing: "{msg.data}"') self.i += 1 def main(args=None): rclpy.init(args=args) minimal_publisher = MinimalPublisher() rclpy.spin(minimal_publisher) minimal_publisher.destroy_node() rclpy.shutdown() if __name__ == '__main__': main() ``` ```python # 订阅者节点 import rclpy from rclpy.node import Node from std_msgs.msg import String class MinimalSubscriber(Node): def __init__(self): super().__init__('minimal_subscriber') self.subscription = self.create_subscription( String, 'topic', self.listener_callback, 10) self.subscription # prevent unused variable warning def listener_callback(self, msg): self.get_logger().info(f'I heard: "{msg.data}"') def main(args=None): rclpy.init(args=args) minimal_subscriber = MinimalSubscriber() rclpy.spin(minimal_subscriber) minimal_subscriber.destroy_node() rclpy.shutdown() if __name__ == '__main__': main() ```
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值