ROS2 多机消息串扰隔离方案教程 📅 2026/8/16 15:26:01 适用场景多架无人机机载电脑连接同一局域网如 192.168.144.x时机内 ROS2 消息互相串扰。 方案ROS_LOCALHOST_ONLY1让每架飞机的 ROS2 成为 本机私有图。1. 背景与问题1.1 现象两架飞机A、B的机载电脑连接同一个网络时地面站发给 A 的任务B 也会执行A 的无人机状态 / 遥测地面站会显示到 B 名下或反之。序列号SN不同但消息仍然串。1.2 根因消息链路分为两段表格段机制是否按 SN 隔离MQTT地面站 ⇄ 机载TCP 直连 brokerxx.xxx.xxx.xxx按/{SN}/xxx主题收发✅ 已隔离没问题ROS2机内话题/ros2/*、/mavros/*DDS 默认走网卡组播同一网段所有机器互通❌ 未隔离串的原因一句话MQTT 按序列号分了家但机内 ROS2 话题是固定名DDS 广播让同网络的飞机互相听得到。1.3 结论只需隔离 ROS2 一层即可。MQTT、TCP图传 / 云台、MAVLink飞控 / 地面站、网段全部不受影响。2. 方案 A 原理2.1 是什么ROS_LOCALHOST_ONLY1是 ROS2Foxy 及以上含 Humble官方的环境变量开关作用让 DDS 只使用本机回环接口127.0.0.1消息不出网卡。127.0.0.1 永远只代表 本机自己任何其他电脑都无法通过它收到消息设置后A 机 ROS2 消息只在 A 机电脑内传播B 机物理上收不到→ 不可能串。本质ROS2 的通信协议 DDS 天生是为 跨机器分布式通信 设计的 —— 默认通过网卡组播在局域网里互相发现、互相收发。这个设置的本质是把 DDS 绑定的网络接口从 网卡 换成 内核回环127.0.0.1把 ROS2 通信从 跨机网络通信 降级为 单机进程间通信 。 | 维度 | 默认状态 | 设置后 | |---|---|---| | DDS 绑定的网络接口 | 物理网卡192.168.144.x | 回环接口127.0.0.1 | | 报文走的路 | 网卡 → 交换机 → 局域网其他设备 | 内核回环路径不出物理网卡 | | 通信能力 | 跨机分布式通信DDS 的本职 | 只剩单机进程间通信 | | 能发现谁 | 同网段所有 ROS2 节点 | 只有本机节点 | 一句话DDS 是分布式协议默认 联网这个开关把它的联网能力关掉了让它退化成本机专用其他设备物理上无法参与。2.2 生效前提本项目全部满足每架飞机所有 ROS2 节点运行在同一台电脑上本项目所有节点均部署在机载电脑由 systemd 统一管理✅每架飞机 MQTT 配置独立UAV_SN、mqtt_client_ID各机不同MQTT 层本来就不串靠此保证✅无跨机 ROS2 通信需求当前跨机只有 MQTT 和 TCP✅2.3 隔离是双向的、物理强制的不依赖别人是否设置只要你这架飞机设置了不管其他飞机设置与否你的 ROS2 消息只在自己电脑内部传播消息不出你的网卡 → 其他飞机收不到你的消息同理你也收不到其他飞机的消息你的 DDS 只在127.0.0.1收发到达你网卡的 DDS 报文直接不处理注意隔离是 各管各的——A 设置了A 与任何人都不串但B、C 若都没设置它们之间照样会串。建议所有飞机统一设置。A机已设置 B机没设置 ROS2 ──只在127.0.0.1── 消息不出网卡 ──╳── 收不到A的消息 B自己的ROS2 ──走网卡广播── 局域网收到 ── A机网卡收到 但A的DDS只在127.0.0.1监听不处理3. 实施步骤每架飞机都要执行3.1 创建 systemd 全局环境变量配置核心1 步运行sudo mkdir -p /etc/systemd/system.conf.d sudo tee /etc/systemd/system.conf.d/ros_localhost.conf EOF [Manager] DefaultEnvironmentROS_LOCALHOST_ONLY1 EOF为什么放在/etc/systemd/system.conf.d/位置会被 OTA 覆盖吗结论.service文件/etc/systemd/system/✅ 会update.sh 同步不能放script/*.sh/home/cat/ros2_ws/script/✅ 会update.sh 同步不能放/etc/systemd/system.conf.d/❌ 不会放这里✅此配置对所有 systemd 服务生效含以后 OTA 新部署的服务永久有效。3.2 可选但建议让手动敲的 ros2 命令也带上变量运行echo export ROS_LOCALHOST_ONLY1 | sudo tee /etc/profile.d/ros_localhost.sh配完重新登录 / 重新 ssh生效。不配也能用但手动验证时结果会不准。3.3 重载并重启运行sudo systemctl daemon-reload sudo reboot注意reboot会重启飞机请确认飞机不在飞行状态、允许重启时再执行。3.4 检查配置是否生效无需重启即可查运行systemctl show-environment | grep ROS看到ROS_LOCALHOST_ONLY1→ 配置已生效看不到 → 检查 3.1 的文件内容是否正确。4. 验证关键两架飞机都要做4.1 设置前可选用于确认问题存在运行ros2 node list能看到对方飞机的节点如对方的ros2_sdk_node→ 确认存在串扰。4.2 设置后运行ros2 node list只能看到自己飞机上的节点→ 隔离成功还能看到对方节点 → 见 FAQ 排查。4.3 交叉验证端到端地面站给 B 机发送一条任务确认 A 机不执行再给 A 机发送任务确认 A 正常执行、B 无反应。4.4 验证注意事项手动终端必须带变量重新登录后执行或先export ROS_LOCALHOST_ONLY1再执行用ros2 daemon stop可清除 CLI 后台缓存后再验证。5. 回退方法随时可还原运行# 1. 删除配置 sudo rm /etc/systemd/system.conf.d/ros_localhost.conf sudo rm /etc/profile.d/ros_localhost.sh # 如果配了 3.2 # 2. 重载并重启 sudo systemctl daemon-reload sudo reboot回退后即恢复原状ROS2 恢复走网卡串扰问题会回来其他功能不受影响。6. 持久性与 OTA 更新6.1 每次开机systemd 每次开机都会重新读取/etc/systemd/system.conf.d/*.conf把DefaultEnvironment应用到所有服务。配置一次每次开机生效。6.2 OTA 更新update.sh 实际覆盖范围目录update.sh 行为本方案配置/etc/systemd/system/*.service从发布包复制覆盖不受影响/home/cat/ros2_ws/script/同步覆盖不受影响/home/cat/ros2_ws/config/只加新文件不覆盖已有不受影响/home/cat/ros2_ws/install/整体替换不受影响/etc/systemd/system.conf.d/完全不碰✅ 永久保留/etc/profile.d/完全不碰✅ 永久保留OTA 更新的标准收尾就是 重启以加载新版本重启时方案 A 自然生效无需额外操作。7. 影响范围与注意事项7.1 影响范围通信走什么受影响吗ROS2 话题/ros2/*、/mavros/*之前走网卡组播✅ 改走本机 127.0.0.1MQTT地面站 xx.xxx.xxx.xxxTCP 网卡❌ 照常TCP图传 / 云台TCP 127.0.0.1❌ 照常MAVLink飞控串口 / 地面站 UDP串口 / UDP❌ 照常网段 / IP / 路由器192.168.144.x网络层❌ 完全不动非 ROS2 服务ZLMediaKit、frpc 等—❌ 无影响不读该变量7.2 注意事项不要在.service文件中显式设置EnvironmentROS_LOCALHOST_ONLY0等会覆盖默认值目前现有 service 均未设置无冲突已知边界机上 ROS2无法与外部机器 DDS 通信当前架构无此需求MQTT/TCP 跨机通道不受影响若某架飞机由两台电脑分别跑 ROS2 节点它们之间会断开本项目每架一台机载不适用。8. FAQQ1为什么不用 ROS_DOMAIN_ID有效范围只有 0~232同网段必须全局唯一机队规模大时无法分配运维成本高。Q2为什么不用 namespace话题带 SN改动面大10 文件SDK、桥、mavros、tcp、launch 等漏改一处会导致本机功能断裂或残留串扰且单机测不出来需双机联调。方案 A 一行配置即达到等价效果且无漏改风险。Q3验证时还能看到对方节点按顺序排查确认终端带了变量export ROS_LOCALHOST_ONLY1后重试确认systemctl show-environment | grep ROS有输出确认 3.1 的文件内容无误后sudo systemctl daemon-reload并重启相关服务。Q4会串进别的网络吗不会。该方案仅影响本机 ROS2 的通信接口选择不改变任何网络配置。Q5以后想恢复多机 ROS2 互通信怎么办删除 3.1 的配置文件并重启即可恢复或改用 namespace 方案另议。Q6其他飞机没设置会收到我的消息吗不会。只要你设置了你的消息不出自己网卡物理上到不了任何其他飞机与对方是否设置无关详见 2.3。但若对方也没设置它仍会与其他同样没设置的飞机互串所以建议全机队统一设置。