第 6 节

开发问题与排查

作者:董佳辉

开发问题与排查

SSH 连接 ysu.local 时解析到 MID360 网口地址

原因

现象是:电脑与工控机连接同一个 Wi-Fi,直接 ping 工控机的 Wi-Fi 地址 192.168.2.183 正常,也能通过这个地址 SSH 登录;但使用 ssh ysu@ysu.local 时,主机名却解析到 192.168.1.50,提示 Connection closed by 192.168.1.50 port 22。 此前拔掉 MID360 网线并重启工控机后,主机名又能解析到 Wi-Fi 地址,但保留两张网卡时问题再次出现。

工控机同时使用 Wi-Fi 和有线网口,两张网卡的用途不同:

接口或设备本次地址用途
工控机 Wi-Fi wlp4s0192.168.2.183/24SSH、局域网通信和联网,地址由 DHCP 分配
工控机雷达有线口 enp3s0192.168.1.50/24接收 MID360 点云和 IMU 数据
MID360192.168.1.107向配置的上位机地址发送数据

**192.168.1.50 是雷达数据的接收端地址,不是 MID360 的默认网关。 **该地址填写在驱动配置的 host_net_info 中,雷达自身地址填写在 lidar_configs 中。 Wi-Fi 和雷达使用不同的 /24 网段,本次故障不是这两个网段重叠造成的。

2026-10-19 保留两张网卡复现后,抓包和进程跟踪确认:工控机上的 NoMachine 9.7.3 在 Wi-Fi 上错误发布了 ysu.local → 192.168.1.50,与 Avahi 发布的正确地址冲突。

发布进程在 Wi-Fi 上返回的 A 记录记录有效期 TTL
avahi-daemon,PID 735ysu.local → 192.168.2.183120 秒
nxserver.bin,PID 3955,发送线程 4400ysu.local → 192.168.1.50600 秒

在工控机 wlp4s0 上抓到的响应均来自 192.168.2.183:5353,但记录内容分别为 .183 和 .50。进一步跟踪系统调用,确认 NoMachine 的发送线程将包含 .50 的记录从 Wi-Fi socket 发出,而 Avahi 发出的是 .183。因此不是单凭“哪个进程监听了 5353 端口”推测原因,已经定位到错误记录的实际发送进程。

两个服务使用同一个主机名给出不同的地址,电脑收到并缓存错误记录后,就会把 SSH 发往雷达网段。 600 秒表示记录有效期,并不是地址优先级;实际解析结果还受响应先后和缓存更新影响,所以会出现有时正常、有时指向 .50 的现象。

本次电脑去往 .50 的实际路由还进入了 FlClash TUN,去往 .183 则直接经过 Wi-Fi。 错误地址来自工控机 NoMachine 的 mDNS 发布;FlClash 接管去往错误地址的连接,是后续路径问题。 不能仅凭 Connection closed 判断工控机的 SSH 服务故障。

Avahi 当时已正确回答 Wi-Fi 地址,systemd-resolved 的 mDNS 未启用,两端检查的 hosts 文件中也没有静态配置 ysu.local → .50。先关闭 NoMachine 自带的局域网发现后,主机名立即恢复正常,验证了故障来源;单独重启 Avahi 或限制其接口,无法阻止 NoMachine 继续发送错误记录。随后进一步通过 NoMachine 自身的 NXDListenAddress 配置绑定 Wi-Fi 地址,恢复原生自动发现,并补上 DHCP 地址变化时的同步。下面先记录临时方案,再说明本机最终采用的完整修复。

临时方案:关闭 NoMachine 自动发现

1. 临时连接:使用工控机当前的 Wi-Fi 地址。(前提是你得知道它的 IP 地址)

以下命令在电脑端执行,本次地址为:

ssh ysu@192.168.2.183

Wi-Fi 地址可能随 DHCP 租约变化,可以在工控机本地或路由器客户端列表中查询。工控机上也可以执行:

nmcli -f DEVICE,TYPE,STATE,CONNECTION device status
ip -br -4 addr

本次工控机 Wi-Fi 接口为 wlp4s0,雷达有线接口为 enp3s0。排查其他机器时,以实际输出为准。

2. 工控机:确认 NoMachine 也在使用 mDNS。

以下操作在工控机上执行,不是在用于远程连接的电脑上执行:

sudo ss -ulpn 'sport = :5353'
sudo /etc/NX/nxserver --version

修复前,5353 UDP 端口同时由 avahi-daemon 和 nxserver.bin 使用。本次 NoMachine 版本为 9.7.3。多个进程监听同一端口本身不代表一定故障,应结合实际回答的地址判断;本次已通过抓包和进程跟踪确认 NoMachine 发布错误记录。

3. 工控机:关闭 NoMachine 的局域网自动发现。

先备份配置。下面的备份文件名用于本次排查;再次操作时换一个文件名,保留已有备份:

sudo cp -a /usr/NX/etc/server.cfg /usr/NX/etc/server.cfg.before-mdns-fix-20261019
sudoedit /usr/NX/etc/server.cfg

找到本次安装版本中的配置项:

#EnableLocalNetworkBroadcast 1

去掉开头的 # 并改为:

EnableLocalNetworkBroadcast 0

这会关闭 NoMachine 的局域网自动发现,其他电脑不再通过它的广播自动发现该工控机;仍可通过 IP 或能够正常解析的主机名手动连接 NoMachine。 无需卸载 NoMachine,也无需停掉 Avahi。NoMachine 官方端口与配置说明

不同版本的配置项可能不同,旧资料中还会出现 EnableNetworkBroadcast。应以安装版本的 server.cfg 注释和对应文档为准,不能把旧名称直接添加到本次 9.7.3 的配置中。

4. 工控机:重启 NoMachine,使配置生效。

先结束正在使用的 NoMachine 远程桌面会话,再执行;重启会暂时中断该服务:

sudo /etc/NX/nxserver --restart
sudo /etc/NX/nxserver --status

随后检查:

sudo ss -ulpn 'sport = :5353'
sudo ss -ltnp 'sport = :4000'

临时方案生效后,5353 端口只剩 Avahi,NoMachine 的 nxserver、nxnode 和 nxd 服务恢复运行,4000 TCP 端口继续监听。配置保存在文件中,系统重启后仍会读取;本次没有修改 Avahi 配置,也没有修改 Wi-Fi、雷达 IP 或路由。

5. 电脑端:验证主机名和 SSH。

getent ahostsv4 ysu.local
avahi-resolve-host-name -4 ysu.local
ssh ysu@ysu.local

预期解析到工控机当前的 Wi-Fi 地址,本次为 192.168.2.183,并且可以正常登录。已经缓存的错误记录可能需要等待过期或被正确记录更新;若仍返回 .50,应继续抓包确认是否还有错误发布源,不能仅凭服务状态认定修复完成。

如需抓包,在工控机执行以下命令,将接口名换成实际 Wi-Fi 接口:

sudo tcpdump -ni wlp4s0 -vv 'udp port 5353'

观察 ysu.local 的 A 记录内容,而不只是数据包的源 IP。本次错误响应的数据包源 IP 也是 .183,真正错误的是其中的 A 记录指向了 .50。

临时方案验证结果

2026-10-19 完成上述修改并重启 NoMachine 后:

检查项目结果
电脑端三次名称查询均得到 192.168.2.183
工控机 Wi-Fi 上的三次 mDNS 查询响应均为 Avahi 返回的 .183,该轮抓包未再出现 .50
ssh ysu@ysu.local密码登录成功,远端 hostname 返回 ysu
NoMachine 状态服务正常,4000 TCP 端口继续监听
电脑断开并重新连接原 Wi-Fi 后主机名仍解析到 .183

临时方案只将 /usr/NX/etc/server.cfg 中的 EnableLocalNetworkBroadcast 设为 0,原配置备份在同目录的 server.cfg.before-mdns-fix-20261019。后续已恢复自动发现,最终状态以下面的完整修复为准。

完整修复:让 NoMachine 自动跟随 Wi-Fi 当前 IP

这里固定的是用于远程连接的 Wi-Fi 接口,不是某一个 IP。NXDListenAddress 本身需要填写具体地址,不能靠写一行配置就自动追踪 DHCP。动态效果来自下面的同步程序:每次读取 Wi-Fi 当前地址,再把它写入 NoMachine 配置。

例如当前地址为 .183,程序就写入 .183;以后 DHCP 分配了其他地址,程序会用新地址替换它。不要手动把 NXDListenAddress 永久写成 192.168.2.183,也不要把 ysu.local 填进这个字段来解析自己;电脑端连接时才使用 ysu.local。NoMachine 监听和广播地址配置说明

本机已完成下面的部署,现有工控机无需重复安装。下面给出完整步骤,方便在其他机器复用;首次部署会重启 NoMachine,应先结束正在使用的远程桌面会话。

1. 工控机:确认需要跟随的 Wi-Fi 接口。

nmcli -f DEVICE,TYPE,STATE,CONNECTION device status
ip -br -4 addr

本机 Wi-Fi 为 wlp4s0,雷达网口为 enp3s0。后面的 Python 脚本和 NetworkManager 事件脚本中各有一处接口设置,其他机器应把两处 wlp4s0 都换成实际 Wi-Fi 接口名。Wi-Fi 继续使用 DHCP,无需固定 IP,也无需修改雷达网口。

2. 工控机:安装读取当前 IP 的同步程序。

创建文件:

sudoedit /usr/local/sbin/nomachine-wifi-sync

填入下面的内容。脚本中只指定接口名 INTERFACE,没有写死 Wi-Fi IP;PORT 对应本机 NoMachine 默认的 4000 端口。

#!/usr/bin/python3
"""Keep NoMachine bound to the robot's management Wi-Fi IPv4 address."""

import fcntl
import json
import os
from pathlib import Path
import re
import stat
import subprocess
import tempfile


INTERFACE = "wlp4s0"
CONFIG = Path("/usr/NX/etc/server.cfg")
PORT = 4000


def run(*args):
    return subprocess.check_output(args, text=True, timeout=10)


def replace_config(content):
    metadata = CONFIG.stat()
    temporary = None
    try:
        with tempfile.NamedTemporaryFile(mode="w", dir=CONFIG.parent, delete=False) as output:
            temporary = Path(output.name)
            output.write(content)
            output.flush()
            os.fchown(output.fileno(), metadata.st_uid, metadata.st_gid)
            os.fchmod(output.fileno(), stat.S_IMODE(metadata.st_mode))
            os.fsync(output.fileno())
        os.replace(temporary, CONFIG)
    finally:
        if temporary is not None and temporary.exists():
            temporary.unlink()


def main():
    with open("/run/nomachine-wifi-sync.lock", "w") as lock:
        fcntl.flock(lock, fcntl.LOCK_EX)
        interfaces = json.loads(run("/usr/sbin/ip", "-j", "-4", "address", "show", "dev", INTERFACE))
        addresses = [
            address["local"]
            for interface in interfaces
            for address in interface.get("addr_info", [])
            if address.get("scope") == "global" and address.get("valid_life_time") != 0
        ]
        if not addresses:
            print(f"{INTERFACE} has no IPv4 address; leaving configuration unchanged.", flush=True)
            return
        if len(addresses) != 1:
            raise RuntimeError(f"Expected one Wi-Fi IPv4 address; got {addresses!r}")
        address = addresses[0]
        old = CONFIG.read_text()
        updated, count = re.subn(
            r"(?m)^[ \t]*#?NXDListenAddress[^\S\n]+[^\n]*$",
            f'NXDListenAddress "{address}"',
            old,
        )
        if count != 1:
            raise RuntimeError(f"Expected one NXDListenAddress entry; got {count}")
        listeners = run("/usr/bin/ss", "-H", "-ltn", f"sport = :{PORT}")
        bound = any(line.split()[3] == f"{address}:{PORT}" for line in listeners.splitlines())
        if updated == old and bound:
            print(f"NoMachine already bound to {INTERFACE} {address}:{PORT}; no restart.", flush=True)
            return
        if updated != old:
            replace_config(updated)
        print(f"Synchronizing NoMachine to {INTERFACE} {address}:{PORT}.", flush=True)
        subprocess.run(["/etc/NX/nxserver", "--restart"], check=True, timeout=75)
        listeners = run("/usr/bin/ss", "-H", "-ltn", f"sport = :{PORT}")
        if not any(line.split()[3] == f"{address}:{PORT}" for line in listeners.splitlines()):
            raise RuntimeError(f"NoMachine is not listening on {address}:{PORT} after restart")
        print(f"Verified NoMachine listener {address}:{PORT}.", flush=True)


if __name__ == "__main__":
    main()

这个程序读取接口当前的唯一全局 IPv4,更新现有的 NXDListenAddress 配置项。当前地址和监听都正确时直接退出;地址改变或监听未恢复时,才重启 NoMachine 并检查结果。接口暂时没有 IPv4 时不修改配置,存在多个 IPv4 时明确报错,避免随意选择地址。

3. 工控机:设置开机同步和网络变化触发。

创建一次性同步服务:

sudoedit /etc/systemd/system/nomachine-wifi-sync.service

填入:

[Unit]
Description=Bind NoMachine to the current management Wi-Fi IPv4 address
Wants=network-online.target
After=network-online.target nxserver.service

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/nomachine-wifi-sync
TimeoutStartSec=100

[Install]
WantedBy=multi-user.target

再创建 NetworkManager 事件脚本:

sudoedit /etc/NetworkManager/dispatcher.d/90-nomachine-wifi

填入:

#!/bin/sh
# NetworkManager runs this as root after connection/address changes.
case "${1:-}:${2:-}" in
    wlp4s0:up|wlp4s0:dhcp4-change|wlp4s0:reapply)
        /usr/bin/systemctl --no-block start nomachine-wifi-sync.service
        ;;
esac

设置文件所有者和执行权限:

sudo chown root:root /usr/local/sbin/nomachine-wifi-sync /etc/systemd/system/nomachine-wifi-sync.service /etc/NetworkManager/dispatcher.d/90-nomachine-wifi
sudo chmod 755 /usr/local/sbin/nomachine-wifi-sync /etc/NetworkManager/dispatcher.d/90-nomachine-wifi
sudo chmod 644 /etc/systemd/system/nomachine-wifi-sync.service

这样,Wi-Fi 连接、DHCPv4 租约变化或重新应用连接配置时,系统都会触发同步。NetworkManager 官方事件说明

上述三个文件是本次部署的辅助配置,不是 NoMachine 自带功能;只修改 server.cfg、没有安装事件脚本,地址就不会自动跟随 DHCP。

4. 工控机:启用同步,再恢复 NoMachine 自动发现。

先加载并启用同步服务,让程序根据当前 Wi-Fi 地址生成 NXDListenAddress:

sudo systemctl daemon-reload
sudo systemctl enable --now nomachine-wifi-sync.service

然后编辑 NoMachine 配置:

sudoedit /usr/NX/etc/server.cfg

将局域网自动发现配置项改为:

EnableLocalNetworkBroadcast 1

**NXDListenAddress 这一行交给同步程序维护,不手动填写 .183。**首次打开自动发现后,重启 NoMachine,使该开关生效:

sudo /etc/NX/nxserver --restart

后续 IP 变化由同步服务自动处理,无需再手动修改配置或重启;地址发生变化时的服务重启会中断原有 NoMachine 会话。

可以检查程序生成的地址和日志:

sudo grep '^NXDListenAddress' /usr/NX/etc/server.cfg
systemctl is-enabled nomachine-wifi-sync.service
sudo journalctl -u nomachine-wifi-sync.service -n 30 --no-pager

这里看到的是程序最后一次同步的具体地址,应与 wlp4s0 当前 IPv4 一致,不代表给网卡设置了静态 IP。服务是一次性任务,执行成功后显示 inactive 属于正常情况,应看日志和 Result,不要求它一直处于 active。

需要手动重新同步时执行:

sudo systemctl start nomachine-wifi-sync.service

NoMachine 恢复自动发现后仍会使用 5353 UDP 端口。此时不能把“看到 nxserver.bin 监听 5353”直接当作故障,应检查它发布的地址是否与当前 Wi-Fi IP 一致。

5. 电脑端:始终使用主机名连接。

avahi-browse -rt _nomachine._tcp
getent ahostsv4 ysu.local
ssh ysu@ysu.local

自动发现的 A 记录和 TXT 中的 ip= 应等于工控机此时的 Wi-Fi IPv4,而不是永远等于本次排查时的 .183。本次 NoMachine 的 SRV 记录端口为 0,实际 NX 连接端口由 TXT 中的 service=nx:4000 给出,不能据此误判服务没有监听。

手动创建 NoMachine 连接时使用主机名:

协议:NX
主机:ysu.local
端口:4000
用户名:ysu

电脑仍需与工控机处于能够进行局域网发现和互访的网络中。IP 变化时,由 Avahi 更新主机名记录、同步程序更新 NoMachine 绑定地址,电脑端继续使用 ysu.local。

完整修复验证结果

检查项目结果
原生 NoMachine 自动发现已恢复,能发现 ysu,A 记录和 TXT 的 IP 均为 .183
Wi-Fi 抓包Avahi 和 NoMachine 都回答 .183,该轮未再出现 .50
4000 TCP 端口绑定 192.168.2.183:4000,电脑端实际 TCP 连接成功
SSH 主机名连接ssh ysu@ysu.local hostname 密码登录成功,返回 ysu
配置残留旧 IP 的模拟将保存地址临时改成 .254 后触发 DHCP 变化处理,同步任务自动恢复 .183、重启服务并验证监听成功
地址未变化的事件同步任务直接退出,不重启 NoMachine
开机同步服务已启用

完整修复前的配置备份为 /usr/NX/etc/server.cfg.before-wifi-binding-20261019。本次没有改变工控机实际 Wi-Fi IP,也没有做整机重启或图形桌面登录测试;模拟旧配置验证了同步处理流程,真实换 IP 和完整图形会话仍应在实际使用时确认。

ROS 2 远端查看 MID360 点云导致降频、延迟和 RViz 不显示

原因

现象是:电脑通过 Wi-Fi 打开 RViz,或者仅运行远端 ros2 topic hz,工控机上的 MID360 点云和 IMU 就明显降频,连工控机本地测频也受到影响;关闭远端订阅后恢复。切换手机热点和其他 Wi-Fi 都未直接解决问题。

本次排查发现了两个独立问题:

  1. 电脑端 DDS 公布了不适合本次跨机通信的地址。
    电脑端 DDS 同时公布了 Wi-Fi 地址、Docker 网桥地址 172.17.0.1 和 Clash TUN 虚拟网卡地址 198.20.0.1。工控机根据这些地址发送数据,其中发往 Clash TUN 地址的数据被路由到雷达网口的网关 192.168.1.1,邻居解析未完成。实测部分 UDP 发送调用阻塞约 250~330 毫秒,发送阻塞拖慢发布,点云和 IMU 出现积压。
    本次定位到的明显阻塞与 Clash TUN 地址有关,没有单独验证 Docker 地址是否造成同样阻塞。不过,电脑 Docker 网桥地址也不适合作为本次跨机接收地址,应一并排除。选择接口的原则是:只使用 ROS 对端实际可达、并且本次通信确实需要的接口。
  2. 电脑端 UDP 接收缓冲不足以承受本次点云突发流量。
    修正接口并重建电脑端 daemon 后,工控机已恢复点云约 20 Hz、IMU 约 200 Hz,但电脑端点云仍只有约 12.8 Hz,接收 socket 仍有缓冲丢包。此时默认接收缓冲约为 208 KiB;将请求值增大到 4 MiB 后,电脑端点云恢复约 20 Hz,测试期间该 socket 的缓冲丢包计数为零。
    因此,缓冲丢包不能全部归因于选错网卡。大点云的分片集中到达、接收线程短暂来不及处理时,正确接口也可能出现缓冲溢出。增大接收缓冲是按数据量选择的优化;本次 MID360 接收环境有实测依据,建议保留 4 MiB。Fast DDS 大数据传输说明

ros2 topic hz 会订阅完整消息来统计频率,同样需要接收整帧点云,因此仅开启远端测频也可能触发上述问题。ROS 2 Humble 测频实现

点云延迟到十几秒甚至几十秒后,点云时间戳可能早于 RViz 保存的 TF 历史。即使 TF 树连通、最新变换正常,RViz 仍无法完成点云时间戳对应的坐标变换,表现为不显示点云。本次将 Fixed Frame 临时改为点云自身的 front_mid360 后出现点云,验证了这个方向;解决传输积压后,就可以使用正常的显示坐标系。

解决方法

1. 工控机:建议保留异步发布。

在实际运行 ROS 的用户的 ~/.bashrc 中加入。

export RMW_FASTRTPS_PUBLICATION_MODE=ASYNCHRONOUS

修改后执行:

source ~/.bashrc

然后在加载了该环境的终端中重新启动 MID360 驱动,使新进程继承设置。

异步发布将实际发送交给后台线程,可以减轻网络发送对驱动发布线程的直接影响;单独设置它未能解决本次问题,仍需配合下面的电脑端配置。Fast DDS 在 ROS 2 Humble 中的发布模式说明

2. 电脑端:通过 source 加载工程内的 dds_env.bash。

先查询自己网络网卡:

ip -br -4 addr

看ip就能看出来,只有10.xx.xx.xx和192.168.xx.xx这种才是NAT4下发的ip。 所以这个wlp0s20f3才是你和ROS用于局域网通信的网卡。

也可以点击WIFI按钮确认一下ip,和上方说的一模一样:

当前脚本位于工程根目录:

/ysu2026_rm_sentry_nav/dds_env.bash

现在初始化当前终端后即可正常使用 rviz2 和 ros2 命令。

这份配置应首先加载到电脑端,因为接收地址由电脑 DDS 公布,接收缓冲也属于电脑上的接收进程。工控机使用电脑公布的地址发送点云;增大工控机的接收缓冲不能替代电脑端设置。

脚本读取所选接口当前的 IPv4,生成 XML,并导出 FASTRTPS_DEFAULT_PROFILES_FILE。UDP 使用所选地址和本机回环地址 127.0.0.1,同时保留本机 SHM 通信。XML 保存在工程根目录,文件名为 .dds-env-<用户ID>-<配置摘要>.xml,已加入 Git 忽略规则。Fast DDS 接口白名单

以下命令在电脑的 ROS 终端执行。两端 ROS_DOMAIN_ID 必须一致,本次为 6;网卡名 wlp0s20f3 应按实际接口修改:

source /opt/ros/humble/setup.bash
export ROS_DOMAIN_ID=6

export DDS_INTERFACE=wlp0s20f3
export DDS_RECV_BUFFER=4MiB
source /你的存放工程的路径/ysu2026_rm_sentry_nav/dds_env.bash

比如:source /home/tungchiahui/UserFolder/MySource/ysu2026_rm_sentry/ysu2026_rm_sentry_nav/dds_env.bash

两个参数可以分别配置:

参数用法
DDS_INTERFACE指定网卡名称,支持逗号分隔的多个接口;未设置时自动选择唯一处于 UP 状态且有 IPv4 的物理网卡,多个候选时返回错误,要求明确选择
DDS_RECV_BUFFER不设置或 0 表示系统默认;纯整数表示字节;支持 B、KB、MB、GB、KiB、MiB、GiB 单位,数值须为非负整数

4MiB 等于 4194304 字节,4MB 等于 4000000 字节。缓冲参数是脚本定义的选项,最终会转换为字节写入 Fast DDS XML。本次接收 MID360 点云建议使用已验证有效的 4MiB。请求值还受系统 net.core.rmem_max 上限约束,超出上限时脚本会提示,但不会自动修改系统参数。

脚本成功加载时不打印,出错或系统上限不足时给出提示。它仅配置 Fast DDS,不改变 ROS_DOMAIN_ID、消息 QoS 或当前 shell 的选项。

我电脑容器使用 host 网络,可以访问宿主 Wi-Fi 接口。其他 Docker 网络模式应选择容器实际可见且对端可达的接口; 接口白名单不能替代 bridge 网络所需的 NAT 或发现配置。跨容器使用 SHM 还取决于 IPC 配置。(一劳永逸,直接host即可)

3. 首次启用或切换网络后,重建电脑端 daemon。

先关闭旧的 RViz 和远端测频进程,在已加载上述 DDS 配置的终端执行:

ros2 daemon stop
ros2 daemon start

daemon 本身也会创建 DDS Participant,应继承相同的接口配置,避免保留原先的虚拟网卡地址。本次排查中,重建 daemon 是恢复正常通信的一步;不必每次测频都重启它。

4. 直接打开 RViz 和测频。

在已加载配置的电脑终端中打开 RViz:

rviz2

另一个终端也先加载第 2 步相同的 ROS 和 DDS 环境,再运行:

ros2 topic hz /livox/lidar/pointcloud --window 40

--window 40 只是缩短统计窗口,方便观察近期变化;真正起作用的是网卡白名单和接收缓冲设置。

5. 日常使用:可加入电脑 ROS 用户的 .bashrc。

将以下三行放在已有 ROS 环境加载语句之后。当前电脑容器使用 root,对应 /root/.bashrc:

export DDS_INTERFACE=wlp0s20f3
export DDS_RECV_BUFFER=4MiB
source /你的存放工程的路径/ysu2026_rm_sentry_nav/dds_env.bash

比如:source /home/tungchiahui/UserFolder/MySource/ysu2026_rm_sentry/ysu2026_rm_sentry_nav/dds_env.bash

这样,新打开并读取 .bashrc 的终端会自动初始化 DDS。通过服务或非交互方式启动的 ROS 程序,需要在其启动环境中主动加载配置。脚本位于个人工程中,加载现有 /opt/ros/humble/setup.bash 不会修改 ROS 安装文件。

切换 Wi-Fi、改变所选接口或接收缓冲后,应重新 source 脚本,重建 daemon,并重新启动相关 ROS 程序;已经运行的进程不会自动读取新的环境变量或 XML。脚本本身不会重启这些进程。

本次验证结果

完成接口限制、daemon 重建和 4 MiB 接收缓冲配置后的现场远端实测结果如下:

测量位置点云频率IMU 频率
工控机本地约 20 Hz约 200 Hz
电脑端约 20 Hz约 197~199 Hz

放大缓冲后的测试节点接收缓冲丢包计数为零。打开 RViz 后,工控机仍保持正常频率,点云持续显示,延迟不再增长到几十秒。这是本次测试期间的结果。

上表来自整理新脚本之前的现场远端测试。后续新增 dds_env.bash,在 ysu_ros_humble 中验证了 XML 加载、接收缓冲生效、本机约 262 KB 点云接收 20/20 帧,以及单位转换、静默加载和参数错误时保留原环境。新版脚本的验证范围包含这些项目;上述远端频率仍引用此前现场实测。

配置整理在工程中新增了 DDS 环境脚本和生成 XML 的 Git 忽略规则;本次排查未修改 MID360 驱动、SLAM 或控制节点的业务代码。