ROS2 节点发现与多机通讯
ROS2节点发现与多机通信机制 ROS2通过DDS实现节点间的自动发现与通信,核心机制包括: 域隔离:通过ROS_DOMAIN_ID(0-232)实现逻辑隔离,不同域节点无法通信。域ID影响DDS端口计算,需避开系统临时端口范围(Linux/Mac/Windows各有差异)。 发现流程:分两阶段: 参与者发现:节点启动时通过多播广播自身信息,建立基础通信层。 端点发现:发布者/订阅者、服务端/客户
1. 域ID
域ID 是一个逻辑隔离标识符,用于在软件层面决定哪些节点可以相互通信,每一个域参与者都有一个唯一且在该域内全局唯一的 participantId,participantId 从0开始,取值范围为(0-119),域ID直接影响DDS所使用的物理端口号。
在DDS中端口计算方式如下:
| DiscoveryMulticastPort | UserMulticastPort | DiscoveryUnicastPort | UserUnicastPort | |
|---|---|---|---|---|
| 用途 | 接收发现元数据的多播端口,当一个节点启动时,它会向这个多播组发送一个“公告”消息,说“我来了!”。网络上的所有其他节点都会收到这个消息,从而知道新节点的存在。 | 接收用户数据(实际的应用消息)的多播端口,DDS 也支持通过多播传输用户数据。这对于“一对多”的场景非常高效,例如一个 talker 向成百上千个 listener 发送数据。所有订阅者只需监听这个多播组即可 | 接收其他参与者发送给它的发现元数据的单播端口,在通过多播初步认识后,节点之间会通过单播进行更详细的信息交换(例如,交换关于发布者、订阅者、服务等端点的详细信息) | 用于接收用户数据(实际的应用消息)的单播端口 |
| 计算方式 | 7400 + (Domain_ID * 250) | 7401 + (Domain_ID * 250) | 7410 + (Domain_ID * 250) + participantId * 2 | 7411 + (Domain_ID * 250) + participantId * 2 |
ROS 2 允许在单个进程中创建多个节点,并让它们共享同一个域参与者。这是通过在使用 rclcpp::init 后,在创建第二个及以后的节点时,传入第一个节点的 NodeOptions 并设置其上下文来实现的。
auto node1 = std::make_shared<rclcpp::Node>("node1");
auto node2 = std::make_shared<rclcpp::Node>("node2", options.use_context(node1->get_context()));
ROS_DOMAIN_ID 是一个数字(默认0,范围0-232),它定义了一个逻辑通信域。只有在同一个域ID下的ROS 2节点才能相互发现和通信,为了避免冲突,需要跳过操作系统的临时端口,下面是三种操作系统的临时端口范围和可用的域ID范围:
| 操作系统 | 临时端口 | 可用域ID |
|---|---|---|
| Linux | 32768-60999 | 0-101 和 215-232 |
| MacOS | 49152-65535 | 0-166 |
| Windows | 49152-65535 | 0-166 |
2. 节点发现
发现过程主要分为两个阶段:
- 参与者发现
- 端点发现
2.1 参与者发现
- 每个 ROS 2 节点在启动时,都会在 DDS 域中创建一个“域参与者”。
- 节点通过多播(默认)或单播的方式,向网络发送包含自身信息(如节点名、GUID等)的“公告”消息。
- 网络上的其他域参与者会收到这些公告,并回复自己的信息。
- 通过这种方式,网络中的所有 DDS 域参与者都相互知道了彼此的存在。这建立了一个基础的通信层。
2.2 端点发现
在参与者发现之后,更具体的通信端点(发布者、订阅者、服务端、客户端)才开始相互发现。
发布者与订阅者发现:
- 当一个节点创建一个发布者(Publisher)时,它会通过其域参与者向网络广播一条消息:“我有一个发布者,话题名称是 /chatter,消息类型是 std_msgs/String。”
- 当一个节点创建一个订阅者(Subscriber)时,它同样会广播:“我需要一个订阅者,话题名称是 /chatter,消息类型是 std_msgs/String。”
- 当一个发布者和一个订阅者在话题名称和消息类型上匹配时,它们就“发现”了彼此。之后,它们会直接建立点对点的连接,数据将通过这个连接直接传输,无需再经过广播。
服务端-客户端发现:
- 原理类似。服务端会广播其服务名称(如 /add_two_ints),客户端也会广播它要寻找的服务名称。
- 当名称和类型匹配后,它们之间会建立一对专用的连接来处理请求和响应。
关键特性与优势
- 去中心化:没有单点故障,整个系统更加健壮。
- 自动发现:开发者无需手动配置节点间的连接,极大地简化了编程。
- 动态性:节点可以随时加入或离开网络,系统会自动处理连接的建立和断开。
基于 DDS 域:通过 ROS_DOMAIN_ID 环境变量,可以将网络逻辑隔离。只有在同一个域 ID 下的节点才能相互发现。这允许多个独立的 ROS 2 网络在同一物理网络上运行而互不干扰。
更多推荐



所有评论(0)