4. ROS2网络发现机制
在ROS2中,节点之间之所以能够“自动找到彼此”,并不依赖中心化的Master,而是由底层DDS中间件通过一套标准化的发现协议完成。理解这套机制,是排查多机通信故障、优化网络配置、控制发现流量的基础。本节围绕简单发现协议、参与者发现、端点发现以及多播/单播配置四个层面展开。
一、核心原理:从SPDP到SEDP的两阶段发现
ROS2默认使用的DDS实现(如Fast DDS、Cyclone DDS)遵循OMG DDSI-RTPS规范,其发现过程分为两个阶段:参与者发现和端点发现。前者解决“网络上有哪些DomainParticipant”,后者解决“这些参与者内部有哪些DataWriter和DataReader,以及它们的数据类型和QoS是否匹配”。
简单发现协议(Simple Discovery Protocol,SDP)是RTPS规范中定义的基础发现机制,它由两个子协议组成:
- SPDP(Simple Participant Discovery Protocol):负责参与者级别的发现,周期性发送心跳式的公告报文。
- SEDP(Simple Endpoint Discovery Protocol):负责端点级别的发现,交换话题、服务、数据类型、QoS等信息。
只有SPDP和SEDP都成功匹配后,两个节点之间才会真正建立数据通信通道。因此,多机通信失败时,需要先判断是“参与者没发现”还是“端点没匹配”。
二、参与者发现:SPDP如何工作
SPDP的核心是“周期公告 + 监听响应”。每个DomainParticipant启动后,会周期性地向约定的多播地址发送公告报文,报文中包含:
- 参与者的GUID(全局唯一标识);
- 可用的单播IP地址和端口;
- 协议版本、厂商信息、租约时长(Lease Duration)。
同一网段内的其他参与者监听该多播地址,收到公告后记录对方信息,并回复自己的公告。若在租约时长内未收到对方心跳,则认为对方离线,清理其端点信息。默认租约时长通常为20秒左右,公告周期约为3秒,具体取决于DDS实现。
三、端点发现:SEDP如何匹配
当两个参与者通过SPDP互相认识后,会通过单播建立可靠通道,进入SEDP阶段。每个参与者把自己内部的DataWriter和DataReader信息发送给对端,包括:
- 端点GUID、所属参与者GUID;
- 话题名称、数据类型名称;
- QoS策略:可靠性、持久性、历史深度、截止时间等;
- 端点角色:Writer还是Reader。
接收方根据话题名、类型和QoS进行匹配。只有Writer和Reader的话题名一致、类型一致、QoS兼容时,才会建立关联。例如,Writer为Reliable而Reader为BestEffort通常可以匹配;反之则可能不兼容。
四、多播与单播配置
SPDP默认依赖多播,但很多云服务器、跨网段、VPN或企业网络会禁用多播。此时需要配置“初始对等节点列表”(Initial Peers),让参与者直接向指定IP单播发送SPDP公告,从而绕过多播限制。
以Fast DDS为例,可通过XML配置文件指定初始对等节点:
<participant profile_name="peer_profile">
<rtps>
<builtin>
<discovery_config>
<initialPeersList>
<locator>
<udpv4>
<address>192.168.1.20</address>
<port>7410</port>
</udpv4>
</locator>
</initialPeersList>
</discovery_config>
</builtin>
</rtps>
</participant>
在ROS2中,可通过环境变量指定配置文件:
export FASTRTPS_DEFAULT_PROFILES_FILE=/path/to/peer_profile.xml
export ROS_DOMAIN_ID=42
ros2 run demo_nodes_cpp talker
对于Cyclone DDS,则使用CYCLONEDDS_URI指定网络接口和Peers。多机场景下,建议明确绑定网卡,避免发现报文从错误接口发出。
| 配置项 | 作用 | 典型值/示例 |
|---|---|---|
| ROS_DOMAIN_ID | 隔离不同ROS2域,避免跨域发现 | 0~232,多机需一致 |
| 多播地址 | SPDP默认公告地址 | 239.255.0.1:7400 |
| Initial Peers | 多播不可用时指定单播对端 | 192.168.1.20:7410 |
| Lease Duration | 判定参与者离线的超时时间 | 默认约20s |
| 网卡绑定 | 指定发现与数据使用的网络接口 | eth0 / wlan0 |
五、案例与排障复盘
假设两台机器分别运行talker和listener,ros2 node list只能看到本机节点。排查顺序如下:
- 确认
ROS_DOMAIN_ID一致,且未设置ROS_LOCALHOST_ONLY=1。 - 用
ros2 multicast send和ros2 multicast receive测试多播是否可达。 - 若多播不通,配置Initial Peers,改为单播发现。
- 检查防火墙是否放行7400/7410等DDS端口段。
- 确认两端话题名、类型和QoS兼容,必要时用
ros2 topic info -v查看端点QoS。
掌握SPDP与SEDP的分工,理解多播与单播的适用边界,就能在多机ROS2系统中快速定位发现层问题,并为后续的QoS调优和网络隔离打下基础。