VPN 两端的两个 ROS 2 节点可以互相列出对方的话题,却仍然一条消息都送不到。发现和用户数据是两条独立通路的独立交换,发现服务器并不转发载荷。只检查其中一个就假定另一个也没问题,正是隧道压根没承载数据时团队去换中间件的常见原因。下面的流程会先区分这两个结果,再决定是否更换任何组件。

发现服务器实际承载什么

在 Fast DDS 中,Discovery Server 分发端点信息:谁发布、谁订阅,以及各自期望什么 QoS。对端彼此知道之后,用户数据直接在它们之间传输,而不是经过那台服务器。能连上服务器只能证明牵线的代理会应答,仅此而已。经过路由的 VPN 仍然需要在对端通告的地址之间具备双向可用的通路。

这一区别也能解释部分故障:已有对端继续交换数据,而新的发现却停止工作。请把它们当成两项独立排查。

读取节点真正使用的 RMW

ROS 2 可以加载不同的中间件,而你在某个 shell 里导出的变量并不会传到别处启动的进程。请问正在运行的系统,而不是翻终端历史。

printenv RMW_IMPLEMENTATION
ros2 doctor --report | head -n 20

变量未设置通常意味着使用已安装的默认值,而同一实验里不同机器上的默认值可能不同。报告还会列出所用的发行版和中间件,所以先比较隧道两端的这两项,再假定它们一致。ROS 命令行守护进程会缓存状态,因此改完环境后要重启它,而不是让过期的守护进程按旧配置作答。趁着会话还开着,把两端主机的发行版和 RMW 记进测试笔记。

把发现和送达当作两个结果来测

挑一个无害的话题,把“认识彼此”和“真正送达”分开测量。info 命令列出端点和 QoS,而 echo 能证明一条消息是否真的穿过了链路。

ros2 topic info /chatter --verbose
ros2 topic echo /chatter --once

info 输出里出现端点,属于发现结果。消息到达订阅者,属于传输结果,只有后者才真正检验应用所需的通路。发现正常而 echo 超时的时候,要去查通告地址和回程路由,而不是查发现服务。从每一端都运行这两条命令,因为不对称的 VPN 路由往往只从一侧暴露出来。

一次只改一个依赖

数据通路失败时,不要在同一个会话里同时更换中间件、发现模式和消息大小,否则事后无法归因。Zenoh RMW 是合理的替代方案,但它的路由器会成为另一个必须能经隧道访问的依赖。

export RMW_IMPLEMENTATION=rmw_zenoh_cpp
ros2 run rmw_zenoh_cpp rmw_zenohd

在这种 RMW 下,路由器按 Jazzy 的默认布局承载发现,而组播发现在那里是关闭的,所以这项依赖应写进笔记,而不是照搬另一套中间件的假设。改一个设置时保持工作负载不变,然后重跑 echo 测试,记录方向、消息速率和链路状况。比较要跑两次,才能把真实改善和一次侥幸重连区分开。如果某项改动改善了发现,而送达情况没变,那你移动的是牵线服务,不是数据通路。

相关文章