ROS2 网络故障分析
环境
- 机器人端:192.168.0.166,ROS 2 Humble,发布 /tf 30 Hz、/scan 10 Hz
- 笔记本端:ROS 2 Humble,pixi/robostack 环境,RMW 实现为 FastDDS,ROS_DOMAIN_ID 为 42
- 笔记本存在多张网络接口:内置 Intel 无线网卡、USB 无线网卡 0e8d:7612 MediaTek Inc. MT7612U 802.11a/b/g/n/ac Wireless Adapter、Clash TUN 虚拟接口、Tailscale 虚拟接口、docker0 与 virbr0 等
故障现象
ros2 topic list 可列出远端话题,ros2 topic hz /tf 无任何数据:
PS /home/ztl/my_ros_ws> ros2 topic hz /tf
# 长时间无任何输出,Ctrl-C 终止
rviz2 启动日志中存在 QoS 警告,且画面无显示:
[WARN] [1788600955.222080698] [rviz]: New publisher discovered on topic '/scan', offering incompatible QoS. No messages will be sent to it. Last incompatible policy: RELIABILITY_QOS_POLICY
初步处理链路问题后,/tf 恢复接收但频率远低于发布端,最大消息间隔达 1.4 s:
PS /home/ztl/my_ros_ws> ros2 topic hz /tf
average rate: 2.643
min: 0.011s max: 1.408s std dev: 0.51957s window: 5
作为对照,机器人本机同一话题的发布频率为 30 Hz 且间隔稳定:
PS /home/ztl/my_ros_ws> ssh ztl@192.168.0.166 "source /opt/ros/humble/setup.bash;export ROS_DOMAIN_ID=42;ros2 topic hz /tf"
average rate: 29.920
min: 0.001s max: 0.056s std dev: 0.01996s window: 184
发布端正常而订阅端异常,可判定故障位于传输路径或订阅端配置。
排查过程
0. 排除 ROS_DOMAIN_ID
使用 demo_nodes_cpp 的 talker 与 listener 进行跨机双向测试,通信正常,排除 DOMAIN_ID 配置错误。应先以最小示例隔离变量,避免无依据猜测。
1. 无线链路质量
排除 DOMAIN_ID 后 hz /tf 仅为 2 至 17 Hz,最大消息间隔 1.4 s。该波形符合 reliable QoS 下丢包触发重传的特征。
iw dev wlxe0e1a9101c1c link 显示 signal 为 -59 dBm,rx bitrate 仅为 1.0 Mbit/s。信号强度正常而协商速率降至 802.11b 最低档,原因包括 2.4 GHz 信道拥挤、网卡省电模式、USB 3.0 接口对 2.4 GHz 频段的射频干扰。
切换至 5 GHz 后 signal 为 -28 dBm,tx bitrate 为 866.7 Mbit/s,/tf 恢复 30 Hz。
需要注意,/scan 等大尺寸消息依赖 UDP 分片传输,任一分片丢失即导致整条消息失效,因此链路质量下降时大数据流受影响最为严重。
2. 多网卡路由
两张无线网卡先后接入同一 SSID,在同一网段分别持有 192.168.0.136 与 192.168.0.148 两个地址。使用 ip route get 192.168.0.166 确认出口接口。
3. DDS 监听地址包含虚拟接口
sudo ss -unap '( dport >= :7400 or sport >= :7400 )'
rviz2 的 DDS socket 绑定在以下地址:
| 地址 | 对应接口 |
|---|---|
| 192.168.0.136 | 无线网卡,唯一可达路径 |
| 100.122.95.49 | Tailscale 虚拟接口 |
| 198.18.0.1 | Clash TUN 虚拟接口 |
DDS 会将全部本地 locator 通告给对端。对端可能选择 198.18.0.1 作为数据目的地址,该地址不在可达路径上,数据无法送达。此机制对应发现阶段正常、topic list 可见、但数据传输缺失或不稳定的典型现象。
修复方式为配置 FastDDS 接口白名单,由环境变量 FASTRTPS_DEFAULT_PROFILES_FILE 指向 XML 配置文件:
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com/XMLSchemas/fastRTPS_Profiles">
<transport_descriptors>
<transport_descriptor>
<transport_id>wlan_only</transport_id>
<type>UDPv4</type>
<interfaceWhiteList>
<address>192.168.0.136</address>
<address>127.0.0.1</address>
</interfaceWhiteList>
</transport_descriptor>
<transport_descriptor>
<transport_id>shm</transport_id>
<type>SHM</type>
</transport_descriptor>
</transport_descriptors>
<participant profile_name="robot_wlan" is_default_profile="true">
<rtps>
<useBuiltinTransports>false</useBuiltinTransports>
<userTransports>
<transport_id>wlan_only</transport_id>
<transport_id>shm</transport_id>
</userTransports>
</rtps>
</participant>
</profiles>
配置中需同时保留 127.0.0.1 与 SHM transport,否则本机节点间通信将受到影响。
实施中遇到三个问题:
- interfaceWhiteList 仅接受 IP 地址,不识别接口名。填写接口名时报错
All whitelist interfaces were filtered out,且 UDP 传输层整体失效 - XML 文件路径错误时报
XMLPARSER Error: realpath failed,配置不生效 - 白名单中的地址来自 DHCP 分配,地址变更后配置失效
验收标准:ss 输出中 DDS socket 仅剩 192.168.0.136、127.0.0.1 与组播地址 239.255.0.1。
4. rviz2 显示配置
网络恢复正常后 rviz2 仅显示 TF,存在两个应用层原因:
- 雷达驱动以 best_effort 发布,rviz2 display 默认为 reliable 订阅,QoS 不兼容导致消息被丢弃。将 display 的 Reliability Policy 改为 Best Effort。rviz2 启动日志中已存在 RELIABILITY_QOS_POLICY 相关警告,应优先阅读
- Fixed Frame 设置为 map,但导航栈未启动,TF 树中不存在 map 坐标系,所有 display 因此失效
结论
按以下顺序分层排查:物理链路、路由、DDS transport、QoS、应用配置。各层症状与对应工具如下:
| 症状 | 工具 | 对应层 |
|---|---|---|
| 协商速率降至 1 Mbit/s | iw dev <iface> link |
物理链路 |
| 流量经错误接口发出 | ip route get <ip> |
路由 |
| hz 频率低且最大间隔达秒级 | ros2 topic hz |
链路丢包引发重传 |
| topic list 可见但 hz 无数据或不稳定 | ss -unap '( dport >= :7400 )' |
DDS 绑定虚拟接口 |
| hz 有数据但 rviz2 无显示 | display Status、ros2 topic info -v |
QoS 或 Fixed Frame |
在运行 ROS 2 的主机上应谨慎使用 Clash TUN、Tailscale 等创建虚拟接口的工具。如需共存,应通过接口白名单将 DDS 限定于物理网卡。
TODO
- 当前环境存在多个中间 AP,机器经不同 AP 接入时会获取不同地址,固定 IP 白名单在该场景下不具备通用性。候选方案:各 AP 配置 MAC 静态绑定;改用静态 IP;评估迁移至 CycloneDDS 并以 NetworkInterface 接口名替代固定地址