Files
yiliao2026/docs/crucial_change/2026-07-23-fastdds-164-network-change.md

56 KiB
Raw Blame History

Fast DDS .164 专用链路设计与回滚规格

  • 日期2026-07-23
  • 适用环境RDKx5ROS 2 Humble与 WSLROS 2 Humble
  • ROS Domain22
  • 状态设计已确认DDS 配置尚未部署

1. 目标

将 WSL 与 RDKx5 之间的 ROS 2/DDS 数据固定在以下链路:

WSL 192.168.10.151 <-> RDKx5 192.168.10.164 (wlx200db0c3fca5)

RDKx5 的 192.168.10.210wlan0)继续用于 SSH 和 VS Code不承担 WSL 与 RDKx5 之间的 DDS 数据。

本次不开发 obstacle_nav_web,只优化 DDS 网络选择。

2. 已确认的现状

RDKx5

  • 主机:sunrise@192.168.10.210
  • ROS 2Humble
  • 默认 RMWrmw_fastrtps_cpp
  • ~/.bashrc 已设置 ROS_DOMAIN_ID=22
  • DDS 专用网卡:wlx200db0c3fca5,地址 192.168.10.164/24
  • 管理网卡:wlan0,地址 192.168.10.210/24
  • 两张网卡处于同一子网,普通路由优先级为 .210 的 metric 600、.164 的 metric 601。因此不能依赖普通路由保证 DDS 使用 .164

WSL

  • 用户:hikos
  • 默认 RMWrmw_fastrtps_cpp
  • ROS 2 接口:eth4,地址 192.168.10.151/24
  • .164.210 均经 eth4 直连
  • WSL 端配置必须放在 /home/hikos/Yiliao2026/

3. 采用方案

继续使用 Fast DDS不修改系统路由、网卡 metric 或防火墙。双方通过 Fast DDS 默认 participant profile 显式选择接口,并设置对端 discovery peer。

跨主机 UDP

  • RDKx5 的自定义 UDPv4 transport 只允许本地地址 192.168.10.164
  • WSL 的自定义 UDPv4 transport 只允许本地地址 192.168.10.151
  • RDKx5 discovery peer 指向 192.168.10.151
  • WSL discovery peer 指向 192.168.10.164
  • 不对单个 DDS 端口做端口转发DDS 发现和数据端口由 Fast DDS 按 Domain 和 participant 管理。

同主机通信

配置保留 SHM transport。RDKx5 内部 ROS 节点之间及 WSL 内部 ROS 节点之间优先使用共享内存,避免将同主机的大流量消息无意义地送入无线链路。

生效范围

只有从指定环境脚本启动的 ROS 2 participant 才受该配置约束。为保证实际 Nav2 数据都走 .164RDKx5 的底盘、雷达、obstacle_scanner 和 Nav2 必须从同一个已加载 RDK 环境脚本的终端或其子进程启动WSL 现有软件必须从已加载 WSL 环境脚本的终端或其子进程启动。

4. 计划新增文件

RDKx5

/home/sunrise/yiliao_ws/config/dds/fastdds_rdk_164.xml
/home/sunrise/yiliao_ws/config/dds/use_rdk_dds_164.sh

WSL

/home/hikos/Yiliao2026/config/dds/fastdds_wsl_151.xml
/home/hikos/Yiliao2026/config/dds/use_wsl_dds_164_link.sh

变更与回滚记录

/home/sunrise/yiliao_ws/docs/crucial_change/2026-07-23-fastdds-164-network-change.md

当前设计规格即保存在上述变更文档中。实施时必须在同一文档中追加实际文件内容、执行命令、验证结果、文件校验值和回滚结果,不另建无法互相对应的零散说明。

5. 环境脚本行为

两个脚本均设计为由 Bash source 加载,不作为独立子进程执行。

脚本必须:

  1. 检查当前主机是否存在预期的本地 IP不存在时输出明确错误并返回非零。
  2. 检查 XML 文件存在且可读。
  3. 设置 ROS_DOMAIN_ID=22
  4. 设置 RMW_IMPLEMENTATION=rmw_fastrtps_cpp
  5. 将 Humble 使用的 FASTRTPS_DEFAULT_PROFILES_FILE 指向对应 XML如当前 Fast DDS 同时支持新变量,则将 FASTDDS_DEFAULT_PROFILES_FILE 指向同一文件。
  6. 输出本次选择的 Domain、RMW、配置文件和本地 DDS 地址,便于启动前人工核对。
  7. 不修改 ~/.bashrc~/.profile 或系统服务环境。

6. 使用流程

RDKx5

source /opt/ros/humble/setup.bash
source /home/sunrise/yiliao_ws/install/setup.bash
source /home/sunrise/yiliao_ws/config/dds/use_rdk_dds_164.sh
ros2 launch obstacle_nav2 obstacle_nav2.launch.py

WSL

source /opt/ros/humble/setup.bash
source /home/hikos/Yiliao2026/config/dds/use_wsl_dds_164_link.sh
# 在同一终端启动现有软件

7. 精简验证

实施后只执行以下必要验证:

  1. 双端加载环境脚本,确认本地 IP、XML、ROS_DOMAIN_ID=22rmw_fastrtps_cpp 正确。
  2. 使用唯一命名的临时 ROS 2 话题验证 WSL 与 RDKx5 能互相发现并收发消息。
  3. 从该环境启动实际 ros2 launch,确认 WSL 能看到关键话题;观察 DDS 数据经过 .164.210 上的 SSH 保持正常,并且没有 WSL 相关 DDS 数据使用 .210

验证记录应包含执行命令、成功或失败、关键输出摘要。无需进行长时间带宽统计、完整 Nav2 功能回归或 costmap 性能调优。

8. 失败保护和回滚

快速回滚

  1. 停止从专用 DDS 环境启动的 ROS 2 节点。
  2. 关闭已加载环境脚本的终端,或在当前终端取消 DDS 配置变量。
  3. 新开终端,仅加载原有 ROS 2 和工作空间环境,然后按原命令重新启动。
  4. 验证默认 ROS graph 恢复。

文件级回滚

配置验证失败且不再保留时,只删除本规格第 4 节列出的四个新增配置文件;如果目录为空,再删除新增的 config/dds 目录。不得删除工作空间、现有 package、路由表或其他用户文件。

实施文档必须记录精确的删除命令。在执行删除前,应再次解析并核对绝对路径分别位于:

  • /home/sunrise/yiliao_ws/config/dds/
  • /home/hikos/Yiliao2026/config/dds/

不需要回滚的项目

因为本方案不修改以下项目,所以回滚不得操作它们:

  • RDKx5 与 WSL 的路由表
  • 防火墙规则
  • 网卡 metric
  • ~/.bashrc~/.profile
  • obstacle_nav2obstacle_scanner 和其他 ROS package
  • SSH 与 VS Code 配置

9. 变更记录要求

实施时,本文件必须追加:

  • 每个新增文件的绝对路径与完整内容
  • 修改前的网络和 ROS 环境摘要
  • 实际执行命令及执行顺序
  • 每项精简验证的结果
  • 新增文件的 SHA-256
  • 完整回滚命令
  • 若发生失败,失败现象、停止位置以及是否已回滚

如果实施内容与本设计不一致,必须先在本文件记录差异及原因,再执行该项变更。

10. 验收标准

  • WSL 与 RDKx5 在 Domain 22 中能发现并收发 ROS 2 消息。
  • 由专用环境启动的跨主机 DDS 通信只使用 WSL .151 与 RDKx5 .164
  • .210 上的 SSH 和 VS Code 管理链路保持可用。
  • 未修改路由表、系统启动文件、现有 ROS package 或 Nav2 参数。
  • 所有实际修改、验证和回滚方式均记录在本文件中。

Fast DDS .164 专用链路实施计划

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: 让从专用环境启动的 WSL 与 RDKx5 ROS 2 participant 只通过 .151 <-> .164 交换跨主机 DDS 数据,同时保持 .210 的管理链路不变。

Architecture: 双端保持 rmw_fastrtps_cpp 和 Domain 22分别加载一个 Fast DDS 默认 participant profile。profile 保留 SHM 供同主机通信,并用带接口白名单的自定义 UDPv4 transport 约束跨主机通信sourceable Bash 脚本负责前置检查和环境变量设置。

Tech Stack: ROS 2 Humble、Fast DDS 2.6.x、Bash、Fast DDS XML profiles、tcpdump、Git。


文件职责

  • /home/sunrise/yiliao_ws/config/dds/fastdds_rdk_164.xmlRDKx5 participant transport只允许 UDPv4 使用 .164peer 为 WSL .151
  • /home/sunrise/yiliao_ws/config/dds/use_rdk_dds_164.sh:验证 RDKx5 网卡和 XML 后,导出 Domain、RMW 和 profile 环境变量。
  • /home/hikos/Yiliao2026/config/dds/fastdds_wsl_151.xmlWSL participant transport只允许 UDPv4 使用 .151peer 为 RDKx5 .164
  • /home/hikos/Yiliao2026/config/dds/use_wsl_dds_164_link.sh:验证 WSL 网卡和 XML 后,导出 Domain、RMW 和 profile 环境变量。
  • /home/sunrise/yiliao_ws/docs/crucial_change/2026-07-23-fastdds-164-network-change.md:设计、计划、实际变更、证据、提交号和回滚命令的唯一记录。

Task 1实施前保护与基线

Files:

  • Modify: /home/sunrise/yiliao_ws/docs/crucial_change/2026-07-23-fastdds-164-network-change.md

  • Step 1确认目标文件不会被覆盖

在 RDKx5 执行:

for path in \
  /home/sunrise/yiliao_ws/config/dds/fastdds_rdk_164.xml \
  /home/sunrise/yiliao_ws/config/dds/use_rdk_dds_164.sh; do
  if [ -e "$path" ]; then
    echo "STOP: existing file: $path" >&2
    exit 1
  fi
done

在 WSL 执行:

for path in \
  /home/hikos/Yiliao2026/config/dds/fastdds_wsl_151.xml \
  /home/hikos/Yiliao2026/config/dds/use_wsl_dds_164_link.sh; do
  if [ -e "$path" ]; then
    echo "STOP: existing file: $path" >&2
    exit 1
  fi
done

Expected两段命令均无输出且返回 0。任何文件已存在都停止实施先将其路径、SHA-256 和内容写入本文件,不能覆盖。

  • Step 2采集最小基线

RDKx5

ip -br -4 addr
ip -4 route
source /opt/ros/humble/setup.bash
python3 -c 'from rclpy.utilities import get_rmw_implementation_identifier; print(get_rmw_implementation_identifier())'
grep -n 'ROS_DOMAIN_ID' /home/sunrise/.bashrc
git -C /home/sunrise/yiliao_ws status --short

WSL

ip -br -4 addr
ip -4 route get 192.168.10.164
source /opt/ros/humble/setup.bash
python3 -c 'from rclpy.utilities import get_rmw_implementation_identifier; print(get_rmw_implementation_identifier())'
git -C /home/hikos/Yiliao2026 status --short

ExpectedRDKx5 存在 .164.210WSL 存在 .151,双方 RMW 均为 rmw_fastrtps_cpp。记录现有 dirty files后续提交不得包含它们。

  • Step 3把基线摘要追加到唯一变更文档

apply_patch 在本文件末尾增加 ## 实施记录### 实施前基线,写入上述命令的关键输出、实施开始时间以及“目标文件原先不存在”。不要粘贴无关的大段 package 列表。

  • Step 4提交基线记录
cd /home/sunrise/yiliao_ws
git add -- docs/crucial_change/2026-07-23-fastdds-164-network-change.md
git diff --cached --check
git diff --cached --name-only
git commit -m "docs: record Fast DDS network baseline" -- \
  docs/crucial_change/2026-07-23-fastdds-164-network-change.md

Expected待提交文件列表只有该 Markdown 文档。

Task 2RDKx5 Fast DDS 配置

Files:

  • Create: /home/sunrise/yiliao_ws/config/dds/fastdds_rdk_164.xml

  • Create: /home/sunrise/yiliao_ws/config/dds/use_rdk_dds_164.sh

  • Modify: /home/sunrise/yiliao_ws/docs/crucial_change/2026-07-23-fastdds-164-network-change.md

  • Step 1运行存在性测试并确认失败

test -f /home/sunrise/yiliao_ws/config/dds/fastdds_rdk_164.xml && \
test -f /home/sunrise/yiliao_ws/config/dds/use_rdk_dds_164.sh

Expected返回非零因为两个文件尚未创建。

  • Step 2创建 RDKx5 XML

创建目录 /home/sunrise/yiliao_ws/config/dds

mkdir -p /home/sunrise/yiliao_ws/config/dds

然后用 apply_patch 创建 fastdds_rdk_164.xml,完整内容为:

<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com/XMLSchemas/fastRTPS_Profiles">
  <transport_descriptors>
    <transport_descriptor>
      <transport_id>rdk_udp_164</transport_id>
      <type>UDPv4</type>
      <interfaceWhiteList>
        <address>192.168.10.164</address>
      </interfaceWhiteList>
    </transport_descriptor>
    <transport_descriptor>
      <transport_id>rdk_shm</transport_id>
      <type>SHM</type>
    </transport_descriptor>
  </transport_descriptors>

  <participant profile_name="rdk_dds_164" is_default_profile="true">
    <rtps>
      <builtin>
        <initialPeersList>
          <locator>
            <udpv4>
              <address>192.168.10.151</address>
            </udpv4>
          </locator>
        </initialPeersList>
      </builtin>
      <userTransports>
        <transport_id>rdk_udp_164</transport_id>
        <transport_id>rdk_shm</transport_id>
      </userTransports>
      <useBuiltinTransports>false</useBuiltinTransports>
    </rtps>
  </participant>
</profiles>
  • Step 3创建 RDKx5 环境脚本

apply_patch 创建 use_rdk_dds_164.sh,完整内容为:

#!/usr/bin/env bash

if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
  echo "ERROR: source this file instead of executing it" >&2
  exit 64
fi

_rdk_dds_profile="/home/sunrise/yiliao_ws/config/dds/fastdds_rdk_164.xml"

if ! ip -4 addr show dev wlx200db0c3fca5 2>/dev/null | grep -q 'inet 192\.168\.10\.164/'; then
  echo "ERROR: wlx200db0c3fca5 does not own 192.168.10.164" >&2
  unset _rdk_dds_profile
  return 1
fi

if [[ ! -r "${_rdk_dds_profile}" ]]; then
  echo "ERROR: unreadable Fast DDS profile: ${_rdk_dds_profile}" >&2
  unset _rdk_dds_profile
  return 1
fi

export ROS_DOMAIN_ID=22
export RMW_IMPLEMENTATION=rmw_fastrtps_cpp
export ROS_LOCALHOST_ONLY=0
export FASTRTPS_DEFAULT_PROFILES_FILE="${_rdk_dds_profile}"
export FASTDDS_DEFAULT_PROFILES_FILE="${_rdk_dds_profile}"

printf 'DDS link enabled: domain=%s rmw=%s local=192.168.10.164 profile=%s\n' \
  "${ROS_DOMAIN_ID}" "${RMW_IMPLEMENTATION}" "${_rdk_dds_profile}"
unset _rdk_dds_profile

设置权限:

chmod 0644 /home/sunrise/yiliao_ws/config/dds/fastdds_rdk_164.xml
chmod 0755 /home/sunrise/yiliao_ws/config/dds/use_rdk_dds_164.sh
  • Step 4验证语法和 Fast DDS 实际加载
bash -n /home/sunrise/yiliao_ws/config/dds/use_rdk_dds_164.sh
python3 -c "import xml.etree.ElementTree as ET; ET.parse('/home/sunrise/yiliao_ws/config/dds/fastdds_rdk_164.xml'); print('XML well-formed')"
source /opt/ros/humble/setup.bash
source /home/sunrise/yiliao_ws/config/dds/use_rdk_dds_164.sh
python3 -c "import rclpy; rclpy.init(); n=rclpy.create_node('rdk_dds_profile_check'); print('RMW participant created'); n.destroy_node(); rclpy.shutdown()"

Expected依次输出 XML well-formed、环境摘要和 RMW participant createdstderr 中没有 XML profile 或 transport 错误。

  • Step 5记录 RDKx5 文件内容与校验值
sha256sum \
  /home/sunrise/yiliao_ws/config/dds/fastdds_rdk_164.xml \
  /home/sunrise/yiliao_ws/config/dds/use_rdk_dds_164.sh

apply_patch 在本文件的实施记录中加入两个文件的完整内容、权限、SHA-256 和 Step 4 的结果。

  • Step 6只提交 RDKx5 配置和文档
cd /home/sunrise/yiliao_ws
git add -- \
  config/dds/fastdds_rdk_164.xml \
  config/dds/use_rdk_dds_164.sh \
  docs/crucial_change/2026-07-23-fastdds-164-network-change.md
git diff --cached --check
git diff --cached --name-only
git commit -m "feat: add dedicated Fast DDS 164 profile" -- \
  config/dds/fastdds_rdk_164.xml \
  config/dds/use_rdk_dds_164.sh \
  docs/crucial_change/2026-07-23-fastdds-164-network-change.md

Expected提交只包含上述三个路径。

Task 3WSL Fast DDS 配置

Files:

  • Create: /home/hikos/Yiliao2026/config/dds/fastdds_wsl_151.xml

  • Create: /home/hikos/Yiliao2026/config/dds/use_wsl_dds_164_link.sh

  • Modify: /home/sunrise/yiliao_ws/docs/crucial_change/2026-07-23-fastdds-164-network-change.md

  • Step 1运行存在性测试并确认失败

test -f /home/hikos/Yiliao2026/config/dds/fastdds_wsl_151.xml && \
test -f /home/hikos/Yiliao2026/config/dds/use_wsl_dds_164_link.sh

Expected返回非零因为两个文件尚未创建。

  • Step 2创建 WSL XML

创建目录 /home/hikos/Yiliao2026/config/dds

mkdir -p /home/hikos/Yiliao2026/config/dds

然后用 apply_patch 创建 fastdds_wsl_151.xml,完整内容为:

<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com/XMLSchemas/fastRTPS_Profiles">
  <transport_descriptors>
    <transport_descriptor>
      <transport_id>wsl_udp_151</transport_id>
      <type>UDPv4</type>
      <interfaceWhiteList>
        <address>192.168.10.151</address>
      </interfaceWhiteList>
    </transport_descriptor>
    <transport_descriptor>
      <transport_id>wsl_shm</transport_id>
      <type>SHM</type>
    </transport_descriptor>
  </transport_descriptors>

  <participant profile_name="wsl_dds_151" is_default_profile="true">
    <rtps>
      <builtin>
        <initialPeersList>
          <locator>
            <udpv4>
              <address>192.168.10.164</address>
            </udpv4>
          </locator>
        </initialPeersList>
      </builtin>
      <userTransports>
        <transport_id>wsl_udp_151</transport_id>
        <transport_id>wsl_shm</transport_id>
      </userTransports>
      <useBuiltinTransports>false</useBuiltinTransports>
    </rtps>
  </participant>
</profiles>
  • Step 3创建 WSL 环境脚本

apply_patch 创建 use_wsl_dds_164_link.sh,完整内容为:

#!/usr/bin/env bash

if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
  echo "ERROR: source this file instead of executing it" >&2
  exit 64
fi

_wsl_dds_profile="/home/hikos/Yiliao2026/config/dds/fastdds_wsl_151.xml"

if ! ip -4 addr show dev eth4 2>/dev/null | grep -q 'inet 192\.168\.10\.151/'; then
  echo "ERROR: eth4 does not own 192.168.10.151" >&2
  unset _wsl_dds_profile
  return 1
fi

if [[ ! -r "${_wsl_dds_profile}" ]]; then
  echo "ERROR: unreadable Fast DDS profile: ${_wsl_dds_profile}" >&2
  unset _wsl_dds_profile
  return 1
fi

export ROS_DOMAIN_ID=22
export RMW_IMPLEMENTATION=rmw_fastrtps_cpp
export ROS_LOCALHOST_ONLY=0
export FASTRTPS_DEFAULT_PROFILES_FILE="${_wsl_dds_profile}"
export FASTDDS_DEFAULT_PROFILES_FILE="${_wsl_dds_profile}"

printf 'DDS link enabled: domain=%s rmw=%s local=192.168.10.151 peer=192.168.10.164 profile=%s\n' \
  "${ROS_DOMAIN_ID}" "${RMW_IMPLEMENTATION}" "${_wsl_dds_profile}"
unset _wsl_dds_profile

设置权限:

chmod 0644 /home/hikos/Yiliao2026/config/dds/fastdds_wsl_151.xml
chmod 0755 /home/hikos/Yiliao2026/config/dds/use_wsl_dds_164_link.sh
  • Step 4验证语法和 Fast DDS 实际加载
bash -n /home/hikos/Yiliao2026/config/dds/use_wsl_dds_164_link.sh
python3 -c "import xml.etree.ElementTree as ET; ET.parse('/home/hikos/Yiliao2026/config/dds/fastdds_wsl_151.xml'); print('XML well-formed')"
source /opt/ros/humble/setup.bash
source /home/hikos/Yiliao2026/config/dds/use_wsl_dds_164_link.sh
python3 -c "import rclpy; rclpy.init(); n=rclpy.create_node('wsl_dds_profile_check'); print('RMW participant created'); n.destroy_node(); rclpy.shutdown()"

Expected依次输出 XML well-formed、环境摘要和 RMW participant createdstderr 中没有 XML profile 或 transport 错误。

  • Step 5记录 WSL 文件并提交
sha256sum \
  /home/hikos/Yiliao2026/config/dds/fastdds_wsl_151.xml \
  /home/hikos/Yiliao2026/config/dds/use_wsl_dds_164_link.sh
cd /home/hikos/Yiliao2026
git add -- \
  config/dds/fastdds_wsl_151.xml \
  config/dds/use_wsl_dds_164_link.sh
git diff --cached --check
git diff --cached --name-only
git commit -m "feat: bind WSL Fast DDS to 192.168.10.151" -- \
  config/dds/fastdds_wsl_151.xml \
  config/dds/use_wsl_dds_164_link.sh
git rev-parse HEAD

Expected提交只包含两个 WSL 配置文件。用 apply_patch 把文件完整内容、权限、SHA-256、加载验证结果和 WSL commit 写入 RDKx5 的唯一变更文档,然后单独提交该文档:

cd /home/sunrise/yiliao_ws
git add -- docs/crucial_change/2026-07-23-fastdds-164-network-change.md
git diff --cached --check
git diff --cached --name-only
git commit -m "docs: record WSL Fast DDS deployment" -- \
  docs/crucial_change/2026-07-23-fastdds-164-network-change.md

ExpectedRDKx5 本次提交只包含该 Markdown 文档。

Task 4双向通信与网卡检查

Files:

  • Modify: /home/sunrise/yiliao_ws/docs/crucial_change/2026-07-23-fastdds-164-network-change.md

  • Step 1清理 ROS 2 daemon 并加载双方环境

RDKx5

source /opt/ros/humble/setup.bash
source /home/sunrise/yiliao_ws/install/setup.bash
source /home/sunrise/yiliao_ws/config/dds/use_rdk_dds_164.sh
ros2 daemon stop || true

WSL

source /opt/ros/humble/setup.bash
source /home/hikos/Yiliao2026/config/dds/use_wsl_dds_164_link.sh
ros2 daemon stop || true

Expected两个终端显示 Domain 22、Fast DDS 和各自本地专用地址。

  • Step 2验证 WSL 到 RDKx5

先在 RDKx5 运行:

timeout 20 ros2 topic echo /dds_164_smoke_20260723 std_msgs/msg/String --once

随后在 WSL 运行:

ros2 topic pub --once /dds_164_smoke_20260723 std_msgs/msg/String "{data: wsl_to_rdk}"

ExpectedRDKx5 输出 data: wsl_to_rdk

  • Step 3验证 RDKx5 到 WSL

先在 WSL 运行:

timeout 20 ros2 topic echo /dds_164_smoke_return_20260723 std_msgs/msg/String --once

随后在 RDKx5 运行:

ros2 topic pub --once /dds_164_smoke_return_20260723 std_msgs/msg/String "{data: rdk_to_wsl}"

ExpectedWSL 输出 data: rdk_to_wsl

  • Step 4确认 DDS 使用 .164 而非 .210

在 RDKx5 两个终端同时开始短抓包:

sudo timeout 15 tcpdump -ni wlx200db0c3fca5 -c 5 'udp and host 192.168.10.151'
sudo timeout 15 tcpdump -ni wlan0 -c 1 'udp and host 192.168.10.151'

抓包期间重复 Step 2 的一次发布。Expectedwlx200db0c3fca5 捕获到 UDPwlan0 超时且捕获 0 packets。当前 SSH 命令仍能返回:

ssh sunrise@192.168.10.210 'echo management-link-ok'
  • Step 5记录并提交精简验证结果

apply_patch 写入双向消息结果、两张网卡的抓包摘要和 management-link-ok。如果任一步失败,停止到 Task 6 的快速回滚,不启动 Nav2。

cd /home/sunrise/yiliao_ws
git add -- docs/crucial_change/2026-07-23-fastdds-164-network-change.md
git diff --cached --check
git commit -m "docs: record dedicated DDS link verification" -- \
  docs/crucial_change/2026-07-23-fastdds-164-network-change.md

Task 5实际 obstacle_nav2 最小验证

Files:

  • Modify: /home/sunrise/yiliao_ws/docs/crucial_change/2026-07-23-fastdds-164-network-change.md

  • Step 1安全启动 Nav2

在已加载 RDKx5 专用 DDS 环境的终端运行:

ros2 launch obstacle_nav2 obstacle_nav2.launch.py enable_motion:=false

Expectedlaunch 启动,真实底盘速度输出仍映射到 /cmd_vel_disabled

  • Step 2WSL 检查关键话题

在已加载 WSL 专用 DDS 环境的终端运行:

ros2 topic list | grep -E '^/obstacles$|^/local_costmap/costmap$|^/global_costmap/costmap$'

Expected至少出现 /obstacles,并出现 local/global costmap 话题;如果当前 Nav2 使用 costmap_raw 命名,则记录实际名称,不修改 Nav2 参数。

  • Step 3结束测试并记录结果

使用 Ctrl+C 正常停止本次 launch。用 apply_patch 记录启动命令、关键话题、停止方式和最终结论;不执行运动目标、不修改 costmap 参数。

  • Step 4提交最终记录
cd /home/sunrise/yiliao_ws
git add -- docs/crucial_change/2026-07-23-fastdds-164-network-change.md
git diff --cached --check
git commit -m "docs: finalize Fast DDS 164 deployment record" -- \
  docs/crucial_change/2026-07-23-fastdds-164-network-change.md

Task 6回滚演练说明与最终核对

Files:

  • Modify: /home/sunrise/yiliao_ws/docs/crucial_change/2026-07-23-fastdds-164-network-change.md

  • Step 1写明快速回滚命令

停止由专用环境启动的 ROS 节点后,在当前终端执行:

unset FASTRTPS_DEFAULT_PROFILES_FILE
unset FASTDDS_DEFAULT_PROFILES_FILE
unset RMW_IMPLEMENTATION
unset ROS_LOCALHOST_ONLY
export ROS_DOMAIN_ID=22

推荐的实际快速回滚方式是关闭该终端并新开终端,避免残留环境变量。将上述命令原样保存在实施记录中。

  • Step 2写明文件级回滚命令但成功时不执行

只有用户要求撤销或部署失败时才执行。执行前分别确认四个绝对路径仍位于批准目录,然后删除具体文件,不递归删除工作空间:

rm -- \
  /home/sunrise/yiliao_ws/config/dds/fastdds_rdk_164.xml \
  /home/sunrise/yiliao_ws/config/dds/use_rdk_dds_164.sh
rmdir --ignore-fail-on-non-empty /home/sunrise/yiliao_ws/config/dds
rm -- \
  /home/hikos/Yiliao2026/config/dds/fastdds_wsl_151.xml \
  /home/hikos/Yiliao2026/config/dds/use_wsl_dds_164_link.sh
rmdir --ignore-fail-on-non-empty /home/hikos/Yiliao2026/config/dds
  • Step 3最终范围核对
git -C /home/sunrise/yiliao_ws status --short
git -C /home/sunrise/yiliao_ws log -5 --oneline
git -C /home/hikos/Yiliao2026 status --short
git -C /home/hikos/Yiliao2026 log -3 --oneline

Expected新提交只涉及四个 DDS 配置文件和本 Markdown原有 dirty files 仍保持原状态,未被暂存、修改或清理。

实施记录

实施前基线

  • 实施日期2026-07-23Asia/Shanghai
  • 用户已明确允许直接在 RDKx5 master 和 WSL zbw 当前分支实施,并要求仅按明确路径提交。
  • 四个目标配置文件在实施前均不存在,未覆盖任何已有文件。
  • RDKx5
    • wlx200db0c3fca5UP,地址 192.168.10.164/24
    • wlan0UP,地址 192.168.10.210/24
    • 默认路由优先使用 wlan0metric 600.164 网卡 metric 为 601。
    • ~/.bashrc:141export ROS_DOMAIN_ID=22
    • 当前 RMW 为 rmw_fastrtps_cpp
    • 实施开始时仓库已有用户内容:?? src/origincar_birdseye/
  • WSL
    • eth4UP,地址 192.168.10.151/24
    • ip route get 192.168.10.164 的结果为 dev eth4 src 192.168.10.151
    • 当前 RMW 为 rmw_fastrtps_cpp
    • 实施开始时仓库已有用户内容:.vscode/browse.vc.db* 修改,以及 .codexresource/src/navigation/src/obstacle_scanner/src/origincar_birdseye/src/third_party/tf_bag/ 等未跟踪路径。
  • 本任务不会暂存、修改或清理上述已有用户内容。

RDKx5 配置实施结果

  • 新增目录:/home/sunrise/yiliao_ws/config/dds/
  • /home/sunrise/yiliao_ws/config/dds/fastdds_rdk_164.xml
    • 权限:0644
    • SHA-256f6714ed471930500bc42d5100113782fb585ce50d48326118a0d0a3c8903d1be
  • /home/sunrise/yiliao_ws/config/dds/use_rdk_dds_164.sh
    • 权限:0755
    • SHA-2565b40b2d3c61bd9d7eedfdb11ef1bb43dd60b3cdbb67ddcb1e2da01ab79996059

XML 完整内容:

<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com/XMLSchemas/fastRTPS_Profiles">
  <transport_descriptors>
    <transport_descriptor>
      <transport_id>rdk_udp_164</transport_id>
      <type>UDPv4</type>
      <interfaceWhiteList>
        <address>192.168.10.164</address>
      </interfaceWhiteList>
    </transport_descriptor>
    <transport_descriptor>
      <transport_id>rdk_shm</transport_id>
      <type>SHM</type>
    </transport_descriptor>
  </transport_descriptors>

  <participant profile_name="rdk_dds_164" is_default_profile="true">
    <rtps>
      <builtin>
        <initialPeersList>
          <locator>
            <udpv4>
              <address>192.168.10.151</address>
            </udpv4>
          </locator>
        </initialPeersList>
      </builtin>
      <userTransports>
        <transport_id>rdk_udp_164</transport_id>
        <transport_id>rdk_shm</transport_id>
      </userTransports>
      <useBuiltinTransports>false</useBuiltinTransports>
    </rtps>
  </participant>
</profiles>

环境脚本完整内容:

#!/usr/bin/env bash

if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
  echo "ERROR: source this file instead of executing it" >&2
  exit 64
fi

_rdk_dds_profile="/home/sunrise/yiliao_ws/config/dds/fastdds_rdk_164.xml"

if ! ip -4 addr show dev wlx200db0c3fca5 2>/dev/null | grep -q 'inet 192\.168\.10\.164/'; then
  echo "ERROR: wlx200db0c3fca5 does not own 192.168.10.164" >&2
  unset _rdk_dds_profile
  return 1
fi

if [[ ! -r "${_rdk_dds_profile}" ]]; then
  echo "ERROR: unreadable Fast DDS profile: ${_rdk_dds_profile}" >&2
  unset _rdk_dds_profile
  return 1
fi

export ROS_DOMAIN_ID=22
export RMW_IMPLEMENTATION=rmw_fastrtps_cpp
export ROS_LOCALHOST_ONLY=0
export FASTRTPS_DEFAULT_PROFILES_FILE="${_rdk_dds_profile}"
export FASTDDS_DEFAULT_PROFILES_FILE="${_rdk_dds_profile}"

printf 'DDS link enabled: domain=%s rmw=%s local=192.168.10.164 profile=%s\n' \
  "${ROS_DOMAIN_ID}" "${RMW_IMPLEMENTATION}" "${_rdk_dds_profile}"
unset _rdk_dds_profile

验证结果:

  • bash -n:通过。
  • XML well-formed通过。
  • Fast DDS/RMW participant 实际创建:通过,输出 RMW participant created
  • 环境摘要Domain 22、RMW rmw_fastrtps_cpp、本地 DDS 地址 .164
  • 首次从 PowerShell 直接拼接远端 python3 -c 时,引号在 SSH 边界被破坏Python 在读取 XML 前即报 SyntaxError。该失败与 XML 内容无关,未修改配置;改为通过 WSL Bash 和 stdin 传入验证程序后,相同验证完整通过。

WSL 配置实施结果

  • 新增目录:/home/hikos/Yiliao2026/config/dds/
  • /home/hikos/Yiliao2026/config/dds/fastdds_wsl_151.xml
    • 权限:0644
    • SHA-256bcf9c6e8e8b724cda1c6d83f02491ae0ad9ad7faec5be5dc01b8d60ea826d7ba
  • /home/hikos/Yiliao2026/config/dds/use_wsl_dds_164_link.sh
    • 权限:0755
    • SHA-2567fe539eab3ddaa5b79a32145cd1d10834468ae47a73de239944b34c61be61f52
  • WSL Git commitb8840ec94bca8668f7d56d80b75c9db0298d18a3,该提交只包含上述两个文件。

XML 完整内容:

<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com/XMLSchemas/fastRTPS_Profiles">
  <transport_descriptors>
    <transport_descriptor>
      <transport_id>wsl_udp_151</transport_id>
      <type>UDPv4</type>
      <interfaceWhiteList>
        <address>192.168.10.151</address>
      </interfaceWhiteList>
    </transport_descriptor>
    <transport_descriptor>
      <transport_id>wsl_shm</transport_id>
      <type>SHM</type>
    </transport_descriptor>
  </transport_descriptors>

  <participant profile_name="wsl_dds_151" is_default_profile="true">
    <rtps>
      <builtin>
        <initialPeersList>
          <locator>
            <udpv4>
              <address>192.168.10.164</address>
            </udpv4>
          </locator>
        </initialPeersList>
      </builtin>
      <userTransports>
        <transport_id>wsl_udp_151</transport_id>
        <transport_id>wsl_shm</transport_id>
      </userTransports>
      <useBuiltinTransports>false</useBuiltinTransports>
    </rtps>
  </participant>
</profiles>

环境脚本完整内容:

#!/usr/bin/env bash

if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
  echo "ERROR: source this file instead of executing it" >&2
  exit 64
fi

_wsl_dds_profile="/home/hikos/Yiliao2026/config/dds/fastdds_wsl_151.xml"

if ! ip -4 addr show dev eth4 2>/dev/null | grep -q 'inet 192\.168\.10\.151/'; then
  echo "ERROR: eth4 does not own 192.168.10.151" >&2
  unset _wsl_dds_profile
  return 1
fi

if [[ ! -r "${_wsl_dds_profile}" ]]; then
  echo "ERROR: unreadable Fast DDS profile: ${_wsl_dds_profile}" >&2
  unset _wsl_dds_profile
  return 1
fi

export ROS_DOMAIN_ID=22
export RMW_IMPLEMENTATION=rmw_fastrtps_cpp
export ROS_LOCALHOST_ONLY=0
export FASTRTPS_DEFAULT_PROFILES_FILE="${_wsl_dds_profile}"
export FASTDDS_DEFAULT_PROFILES_FILE="${_wsl_dds_profile}"

printf 'DDS link enabled: domain=%s rmw=%s local=192.168.10.151 peer=192.168.10.164 profile=%s\n' \
  "${ROS_DOMAIN_ID}" "${RMW_IMPLEMENTATION}" "${_wsl_dds_profile}"
unset _wsl_dds_profile

验证结果:

  • bash -n:通过。
  • XML well-formed通过。
  • Fast DDS/RMW participant 实际创建:通过,输出 RMW participant created
  • 环境摘要Domain 22、RMW rmw_fastrtps_cpp、本地 DDS 地址 .151、peer .164
  • WSL 提交命令在工具等待窗口内没有返回,但后台提交随后正常完成;复核 commit b8840ec9 只包含两个批准的配置文件,原有 .vscode 暂存内容未进入该提交。

实施偏差WSL 接口名不稳定

  • 发现时间2026-07-23 双向通信复核期间。
  • 复现WSL 重启前 .151 位于 eth4;重启后仍为 192.168.10.151/24,但接口名变为 eth3。原脚本执行时返回 ERROR: eth4 does not own 192.168.10.151
  • 根因WSL 镜像网络接口编号会在实例重启后变化,接口名不是稳定标识。
  • 修正WSL 环境脚本不再要求接口名为 eth4,改为在所有本地 IPv4 接口中查找 192.168.10.151/。Fast DDS XML 仍按稳定 IP .151 建立 interface whitelist网络约束不变。
  • 范围:只修改 /home/hikos/Yiliao2026/config/dds/use_wsl_dds_164_link.sh 的前置检查和错误文本;不修改 XML、路由表、RDKx5 配置或 ROS package。
  • 失败保护:如果 .151 在任何接口上都不存在,脚本仍返回非零并拒绝启用 DDS 环境。

实施偏差:关闭 Domain 22 内建发现多播

  • 发现时间2026-07-23 受控双向通信与双网卡抓包期间。
  • 受控条件:测试前 RDKx5 无其他 Domain 22 socketRDK 测试 participant 的 UDP socket 只绑定 .164WSL 测试 participant 只绑定 .151
  • 消息结果WSL 到 RDKx5 发布/订阅成功。
  • 抓包结果:.164 捕获 189 个 Domain 22 包;.210 捕获 3 个包,三者均为 WSL .151 发往 239.255.0.1:12900 的 SPDP 多播,没有发往 .210 的 Domain 22 单播。
  • 根因:配置 initial peer 不会自动关闭 Fast DDS 内建发现多播;同一局域网中的两张 RDKx5 网卡都会收到该多播帧。
  • 修正:在 RDKx5 和 WSL profile 的 <builtin> 中加入 <avoid_builtin_multicast>true</avoid_builtin_multicast>,保留双端 initial peer 进行单播发现。
  • 范围:只修改两个已批准的 Fast DDS XML不修改系统网卡的多播设置、路由、防火墙或 ROS package。
  • 修正后的必要验收:双向消息仍成功,.164 Domain 22 抓包大于零,.210 Domain 22 抓包为零。

WSL 接口名修正结果

  • 修正提交:9349f53cbc78851d9d053799af26f8055f58f9d3
  • 修正后脚本 SHA-2564dd272d34bbc480e7f5d112348fad7bb59532f155cdabbdc7e7b98dda7ff6155
  • 当前 WSL 接口为 eth3、地址仍为 .151 时,脚本加载通过。
  • 实际 participant socket 为 .151:12900.151:12910.151:12911.151 上的自定义 UDP socket没有绑定 WSL 的其他地址。

修正后脚本完整内容:

#!/usr/bin/env bash

if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
  echo "ERROR: source this file instead of executing it" >&2
  exit 64
fi

_wsl_dds_profile="/home/hikos/Yiliao2026/config/dds/fastdds_wsl_151.xml"

if ! ip -o -4 addr show 2>/dev/null | grep -q 'inet 192\.168\.10\.151/'; then
  echo "ERROR: no local IPv4 interface owns 192.168.10.151" >&2
  unset _wsl_dds_profile
  return 1
fi

if [[ ! -r "${_wsl_dds_profile}" ]]; then
  echo "ERROR: unreadable Fast DDS profile: ${_wsl_dds_profile}" >&2
  unset _wsl_dds_profile
  return 1
fi

export ROS_DOMAIN_ID=22
export RMW_IMPLEMENTATION=rmw_fastrtps_cpp
export ROS_LOCALHOST_ONLY=0
export FASTRTPS_DEFAULT_PROFILES_FILE="${_wsl_dds_profile}"
export FASTDDS_DEFAULT_PROFILES_FILE="${_wsl_dds_profile}"

printf 'DDS link enabled: domain=%s rmw=%s local=192.168.10.151 peer=192.168.10.164 profile=%s\n' \
  "${ROS_DOMAIN_ID}" "${RMW_IMPLEMENTATION}" "${_wsl_dds_profile}"
unset _wsl_dds_profile

关闭发现多播的文件结果

  • RDKx5 XML
    • 新 SHA-2569c7acb168af9eacd93b41e03e02f8554570c94853ab5cd485782ba9483b72be8
    • commite7c3fe9
  • WSL XML
    • 新 SHA-256990904e92ff54c76e04b70a7aa27fc9331484b2292635f1c22dddaeb0b16d52d
    • commit4b11f35
  • 两个 XML 均只在 <builtin> 下新增:
<avoid_builtin_multicast>true</avoid_builtin_multicast>
  • 两端 XML well-formed 检查通过Fast DDS/RMW participant 实际创建通过,没有 profile 或 transport 解析错误。

双向与网卡验证过程

  1. 首次使用 ros2 topic CLI 测试时,既有 Domain 0 daemon 干扰等待逻辑,改用不依赖 CLI daemon 的临时 rclpy 发布/订阅节点。
  2. 关闭发现多播前的受控测试:双向消息成功,.164 捕获 189 个 Domain 22 包,.210 只捕获 3 个 SPDP 多播包,没有 .210 单播。
  3. 关闭发现多播后的首次重测开始前RDKx5 上出现一套由其他终端启动的未配置 obstacle_nav2,其 Domain 22 socket 绑定 0.0.0.0,破坏了“无其他 participant”的受控前提。该次消息超时不作为 XML 结论。
  4. 当前运行命令确认为 ros2 launch obstacle_nav2 obstacle_nav2.launch.py enable_motion:=true,来源终端 pts/3;进程环境只有 ROS_DOMAIN_ID=22ROS_LOCALHOST_ONLY=0,没有 Fast DDS profile 变量。
  5. 因该 launch 已启用真实运动,实施者未擅自终止。最终双向和双网卡验证等待该 launch 停止,或获得明确授权后用专用 DDS 环境重新启动。

双向与网卡最终验证结果

  • 用户在收到“需要停止或明确授权”的说明后指示继续;实施者对 PID 12541enable_motion:=true launch 发送一次 SIGINT
  • launch 在正常清理后退出,复核子进程数为 0;未终止其父 shell未修改启动文件。
  • 在 RDKx5 无其他 Domain 22 participant 的受控条件下:
    • RDK 测试 participant socket 只绑定 .164
    • WSL 测试 participant socket 只绑定 .151
    • WSL -> RDKx5收到 wsl_to_rdk
    • RDKx5 -> WSL收到 rdk_to_wsl
    • 抓包探针消息 capture_probe 收到。
    • wlx200db0c3fca5 的 Domain 22 抓包:163 packets captured
    • wlan0 的 Domain 22 抓包:0 packets captured
    • .210 SSH 返回 management-link-ok
  • 结论:对从专用环境启动的 Domain 22 participant跨主机 DDS 数据只使用 WSL .151 与 RDKx5 .164.210 保持为管理链路。

实施偏差:为同主机多进程增加本机 bootstrap peer

  • 发现时间2026-07-23 obstacle_nav2 最小实际验证。
  • 安全条件:使用专用 RDK 环境启动 enable_motion:=false,底盘速度被重映射到 /cmd_vel_hardware_disabled,未发布导航目标。
  • 现象:底盘、雷达、obstacle_scanner 和 Nav2 进程均启动,但 lifecycle manager 持续输出 Waiting for service controller_server/get_state...WSL 只能看到 /scan 等基础话题,未看到 /obstacles 和 costmap。
  • 根因:关闭 SPDP 多播后RDK profile 的 initial peer 只有远端 WSL .151。同一 RDK 上的多个 participant 没有本机单播 bootstrap peerSHM transport 本身不替代 participant discovery。
  • 修正:
    • RDK initial peer 同时包含本机 .164 和对端 .151
    • WSL initial peer 同时包含本机 .151 和对端 .164,保证 WSL 现有软件由多个 participant 组成时也能本机发现。
  • 范围:只在两个 Fast DDS XML 的 <initialPeersList> 中各增加一个本机 locator继续保持 avoid_builtin_multicast=true 和接口白名单。
  • 必要复测Nav2 lifecycle 完成配置/激活WSL 可见 /obstacles 与 local/global costmap.210 Domain 22 抓包仍为零。

实施偏差:扩大单播 initial peer 扫描范围

  • 发现时间2026-07-23 增加本机 peer 后的 Nav2 复测。
  • 现象:两个 RDK 测试 participant 能通过本机 .164 peer 互相发现,但包含约 16 个 participant 的 Nav2 launch 仍无法让 lifecycle manager 找到 controller_server/get_state
  • 根因initial peer locator 未显式指定端口时Fast DDS 只扫描有限数量的 participant ID默认范围足够两节点测试不足以覆盖 Nav2 多进程。
  • 版本证据WSL Fast DDS 2.6.11 与 RDKx5 Fast DDS 2.6.8 的库均包含 maxInitialPeersRange 配置项。
  • 修正:在双端自定义 UDPv4 transport descriptor 中加入 <maxInitialPeersRange>64</maxInitialPeersRange>
  • 范围依据64 覆盖当前约 16 个 RDK participant 和 WSL 现有软件,并保留余量;不固定具体 UDP 端口,不引入 discovery server。
  • 必要复测:本机多 participant 发现、Nav2 lifecycle 激活、WSL 关键话题可见、.210 Domain 22 仍为零。

peer 扫描范围修正与 Nav2 最终结果

  • RDKx5 XML
    • 最终 SHA-256ecf275c084d4b8a1d2445a2613e079ab78182ac91dabd7ba53b48c10dde9c6d8
    • maxInitialPeersRange commite365bce
  • WSL XML
    • 最终 SHA-256d5de39799e4daa030025629fe5ee5eac1800f1c6def2c44971108ffe6ee6d54d
    • maxInitialPeersRange commit441bf80
  • 两个 RDK participant 的本机单播测试通过:SUB_RECEIVED ... local_okPUB_SENT ... local_ok
  • 实际启动命令:
source /opt/ros/humble/setup.bash
source /home/sunrise/yiliao_ws/install/setup.bash
source /home/sunrise/yiliao_ws/config/dds/use_rdk_dds_164.sh
ros2 launch obstacle_nav2 obstacle_nav2.launch.py enable_motion:=false
  • Nav2 lifecycle 完成配置与激活,日志包含 Managed nodes are active
  • WSL 专用环境可见:
    • /obstacles
    • /local_costmap/costmap
    • /local_costmap/costmap_raw
    • /global_costmap/costmap
    • /global_costmap/costmap_raw
    • /cmd_vel_hardware_disabled
  • 实际 Nav2 participant socket 抽查均绑定 192.168.10.164
  • 验证脚本输出 NAV2_VERIFY_OK;验证结束后通过 SIGINT 停止 launch未发布运动目标。

RDKx5 最终 XML 完整内容:

<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com/XMLSchemas/fastRTPS_Profiles">
  <transport_descriptors>
    <transport_descriptor>
      <transport_id>rdk_udp_164</transport_id>
      <type>UDPv4</type>
      <maxInitialPeersRange>64</maxInitialPeersRange>
      <interfaceWhiteList>
        <address>192.168.10.164</address>
      </interfaceWhiteList>
    </transport_descriptor>
    <transport_descriptor>
      <transport_id>rdk_shm</transport_id>
      <type>SHM</type>
    </transport_descriptor>
  </transport_descriptors>

  <participant profile_name="rdk_dds_164" is_default_profile="true">
    <rtps>
      <builtin>
        <avoid_builtin_multicast>true</avoid_builtin_multicast>
        <initialPeersList>
          <locator>
            <udpv4>
              <address>192.168.10.164</address>
            </udpv4>
          </locator>
          <locator>
            <udpv4>
              <address>192.168.10.151</address>
            </udpv4>
          </locator>
        </initialPeersList>
      </builtin>
      <userTransports>
        <transport_id>rdk_udp_164</transport_id>
        <transport_id>rdk_shm</transport_id>
      </userTransports>
      <useBuiltinTransports>false</useBuiltinTransports>
    </rtps>
  </participant>
</profiles>

最终交付、校验与回滚记录

最终文件状态2026-07-23 复核):

  • RDKx5 /home/sunrise/yiliao_ws/config/dds/fastdds_rdk_164.xml
    • 权限/属主:0644 sunrise:sunrise
    • SHA-256ecf275c084d4b8a1d2445a2613e079ab78182ac91dabd7ba53b48c10dde9c6d8
  • RDKx5 /home/sunrise/yiliao_ws/config/dds/use_rdk_dds_164.sh
    • 权限/属主:0755 sunrise:sunrise
    • SHA-2565b40b2d3c61bd9d7eedfdb11ef1bb43dd60b3cdbb67ddcb1e2da01ab79996059
  • WSL /home/hikos/Yiliao2026/config/dds/fastdds_wsl_151.xml
    • 权限/属主:0644 hikos:hikos
    • SHA-256d5de39799e4daa030025629fe5ee5eac1800f1c6def2c44971108ffe6ee6d54d
  • WSL /home/hikos/Yiliao2026/config/dds/use_wsl_dds_164_link.sh
    • 权限/属主:0755 hikos:hikos
    • SHA-2564dd272d34bbc480e7f5d112348fad7bb59532f155cdabbdc7e7b98dda7ff6155

最终精简验证结果:

  • 双向 rclpy 通信通过RDKx5 与 WSL 均能接收对端消息。
  • RDKx5 抓包结果:.164 网卡捕获 163 packets.210 网卡捕获 0 packets.210 SSH 管理链路正常。
  • ros2 launch obstacle_nav2 obstacle_nav2.launch.py enable_motion:=false 通过lifecycle 日志包含 Managed nodes are activeWSL 可见 /obstacles、local/global costmap 与 /cmd_vel_hardware_disabled,验证脚本输出 NAV2_VERIFY_OK
  • 验证时未发布导航目标,速度输出被重映射到 /cmd_vel_hardware_disabled
  • 验证 launch 已通过 SIGINT 正常退出最终进程复核时RDKx5 与 WSL 均无本任务 Nav2、DDS 验证脚本或 tcpdump 残留进程。

快速回滚(不删除文件):先停止从专用环境启动的 ROS 2 节点。最稳妥方式是关闭该终端并新开终端,只加载原 ROS 2 与工作空间环境。若必须复用当前终端,执行:

unset FASTRTPS_DEFAULT_PROFILES_FILE
unset FASTDDS_DEFAULT_PROFILES_FILE
unset RMW_IMPLEMENTATION
unset ROS_LOCALHOST_ONLY
export ROS_DOMAIN_ID=22

文件级逆向还原(本次验证成功,以下命令仅留档,未执行):

# RDKx5先解析并核对两个目标均位于批准目录再删除明确文件。
realpath /home/sunrise/yiliao_ws/config/dds/fastdds_rdk_164.xml
realpath /home/sunrise/yiliao_ws/config/dds/use_rdk_dds_164.sh
rm -- \
  /home/sunrise/yiliao_ws/config/dds/fastdds_rdk_164.xml \
  /home/sunrise/yiliao_ws/config/dds/use_rdk_dds_164.sh
rmdir --ignore-fail-on-non-empty /home/sunrise/yiliao_ws/config/dds
# WSL先解析并核对两个目标均位于批准目录再删除明确文件。
realpath /home/hikos/Yiliao2026/config/dds/fastdds_wsl_151.xml
realpath /home/hikos/Yiliao2026/config/dds/use_wsl_dds_164_link.sh
rm -- \
  /home/hikos/Yiliao2026/config/dds/fastdds_wsl_151.xml \
  /home/hikos/Yiliao2026/config/dds/use_wsl_dds_164_link.sh
rmdir --ignore-fail-on-non-empty /home/hikos/Yiliao2026/config/dds

如需连同 Git 记录一起逆向还原,应在确认工作区无其他人的重叠修改后,按提交逆序使用 git revert <commit>;不得使用 git reset --hard,不得清理本节所列之外的 dirty files。相关提交

  • RDKx5edbe450e7c3fe932a253ae365bce,以及对应实施记录提交;最近一次成功验证记录为 985550a
  • WSLb8840ec9349f534b11f353195933441bf80

最终 Git 范围核对:

  • RDKx5 当前分支为 master。除本 Markdown 的最终记录外,保留了任务开始前/用户已有的 obstacle_nav2 两个修改文件、三个 nav2_params.yaml.bak.*src/origincar_birdseye/,未暂存、未清理、未纳入本任务提交。
  • WSL 当前分支为 zbw。保留了 .vscode/browse.vc.db*.codexresource/src/navigation/src/obstacle_scanner/src/origincar_birdseye/src/third_party/tf_bag/ 等已有 dirty files未暂存、未清理、未纳入本任务提交。
  • 未修改 .bashrc、路由表、防火墙、网卡 metric、Nav2 参数、ROS package、SSH 或 VS Code 配置;配置仅在终端中显式 source 后生效。

2026-07-23 18:51 后续卡顿诊断与恢复计划

只读诊断证据

  • 重启前 ip route get 192.168.10.151 from 192.168.10.164 返回 dev wlx200db0c3fca5 table 164;活动 Nav2 participant 的专用 UDP socket 绑定 192.168.10.164。因此已加载专用 profile 的 DDS 当时确实走 .164
  • 同一启动周期累计计数显示:.210wlan0 发送约 11.58 GB / 3611 万包.164 网卡发送约 64.5 MB / 22 万包。该数量差异表明 .210 另有非专用 DDS 环境的流量。
  • Windows 对 .210 的 20 次 ping 为平均 4 ms、最大 55 ms.164 为平均 2 ms、最大 5 ms
  • 18:52:55 启动的两个只读 tcpdump 均由 timeout 8 控制,并在 18:53:03 正常关闭 sudo session没有遗留 tcpdump。随后 RDK 网络失联并在 18:57:03 重新启动,上一启动日志末尾没有正常 shutdown 记录,因此只能确认发生了非正常重启,不能从现有日志证明触发源。
  • 重启后 wlx200db0c3fca5NO-CARRIER,没有 .164 地址、table 164 或 source ruleopenwrt_5G 当前扫描不可见。
  • .210 管理网卡改连 kskbl_2.4G,协商 TX 约 52 Mbit/s。一个未设置 FASTRTPS_DEFAULT_PROFILES_FILE 的 ROS 2 daemon 绑定 192.168.10.210,说明未显式 source 专用脚本的 ROS CLI 会绕过 .164 配置。

方案与实施顺序

采用回退连接方案:保留 /etc/NetworkManager/dispatcher.d/90-wlx164-policy-route.210 管理连接和两个 Fast DDS XML 不变;克隆现有 kskbl_2.4G 凭据为只绑定 wlx200db0c3fca5 的回退 profile。原 openwrt_5G 1 保持为 .164 的 5G profile并将其自动连接优先级设为 100;回退 profile 优先级为 50

执行步骤:

  1. RED 基线:确认 .164 不存在、use_rdk_dds_164.sh 返回失败、错误 ROS daemon 的环境中没有 Fast DDS profile 且 socket 位于 .210
  2. 创建 kskbl_2.4G-rdk164,绑定 wlx200db0c3fca5 并试连接。只有 DHCP 返回 192.168.10.164 才继续;否则立即断开并删除该 profile。
  3. 确认现有 dispatcher 自动恢复 from 192.168.10.164/32 lookup 164,且 .164 -> .151 走 USB 网卡不直接编辑路由表、dispatcher、网卡 metric 或防火墙。
  4. 停止错误环境创建的 ROS 2 daemon从专用 DDS 环境启动新的 daemon检查其环境变量与 UDP socket。
  5. 使用双向一次性 ROS 2 消息、短时只计数抓包和 ping 验证 .164 承载 DDS、.210 没有同一批 DDS 包且 SSH 保持可用。
  6. 将实际 profile UUID、命令、结果、Git 状态和残留进程检查追加到本节,只提交本 Markdown。

精确回滚:

nmcli connection down 'kskbl_2.4G-rdk164' 2>/dev/null || true
nmcli connection delete 'kskbl_2.4G-rdk164'
nmcli connection modify 'openwrt_5G 1' connection.autoconnect-priority 0

上述回滚只删除本次新增的回退 profile并把既有 openwrt_5G 1 优先级恢复为实施前的 0;不得删除 kskbl_2.4Gopenwrt_5G 1、策略路由脚本或 DDS 文件。

后续恢复实施结果

  • RDK 非正常重启后,openwrt_5G 扫描不可见,既有 .164 profile 无法连接;wlx200db0c3fca5 没有地址,专用 DDS 脚本按设计返回失败。
  • 新增 NetworkManager 回退连接:
    • 名称:kskbl_2.4G-rdk164
    • UUID98eb5d04-3bf5-49a2-96e7-4ec44171154f
    • 绑定接口:wlx200db0c3fca5
    • 自动连接优先级:50
    • DHCP 实际地址:192.168.10.164/24
  • 既有 openwrt_5G 1 UUID 9e4f4ea7-f087-4369-8faf-fa3d0faa9839 继续绑定 USB 网卡,自动连接优先级由 0 改为 100,保持 5G 为下次启动时的首选。
  • 既有 /etc/NetworkManager/dispatcher.d/90-wlx164-policy-route 未修改;回退连接成功后自动恢复:
1000: from 192.168.10.164 lookup 164
192.168.10.173 from 192.168.10.164 dev wlx200db0c3fca5 table 164
  • WSL/Windows 有线 LAN 的 DHCP 地址在网络重启后变为 192.168.10.173。仅在 WSL 内临时添加 .151WSL 能发出但 RDK 无法反向 ARP该临时地址随后已删除。
  • 尝试用 Windows New-NetIPAddress 添加持久 .151 辅助地址时系统返回 Access is denied,没有产生 Windows 地址或路由修改。
  • .173 是当前真实可双向访问的 LAN 地址,最终将 WSL Fast DDS 本地地址和 RDK initial peer 从 .151 调整为 .173
    • RDK /home/sunrise/yiliao_ws/config/dds/fastdds_rdk_164.xml:仅把远端 peer 192.168.10.151 改为 192.168.10.173
    • WSL XML 从 fastdds_wsl_151.xml 重命名为 fastdds_wsl_173.xmltransport/profile ID 改为 wsl_udp_173 / wsl_dds_173,本地白名单与本机 peer 改为 .173,对端仍为 .164
    • WSL use_wsl_dds_164_link.sh 改为检查 .173 并加载 fastdds_wsl_173.xml
  • 新文件校验:
    • RDK XML0644 sunrise:sunriseSHA-256 41c2fcac3c23218c40c3d4cf4273504f8233296e5db6ac44c3bc120c5d989dd1
    • RDK 脚本未变SHA-256 5b40b2d3c61bd9d7eedfdb11ef1bb43dd60b3cdbb67ddcb1e2da01ab79996059
    • WSL XML0644 hikos:hikosSHA-256 fa95118ced19bb0888789c8a0a59cbee1db2a01b00d3592a31b4bd9214ef7b4a
    • WSL 脚本:0755 hikos:hikosSHA-256 85a1390cbda47fed4f42c01210067a575775b79c267def83d24abdde0f232543
  • Git 提交RDK XML 87f562dWSL XML/脚本 c383338。两个提交均只包含上述明确路径。

daemon 与运行中节点恢复

  • 重启后发现 Domain 22 的 ROS 2 daemon 没有 Fast DDS profileUDP socket 位于 .210。普通 ros2 daemon stopSIGTERM 均未使该孤儿进程退出;在严格核对命令行后仅对该 daemon 使用 SIGKILL
  • 新 RDK Domain 22 daemon 从专用环境启动,环境包含两个 Fast DDS profile 变量UDP socket 全部位于 .164
  • WSL 旧 daemon 同样绑定已失效 .151,按相同方式清理后从 .173 环境重启UDP socket 全部位于 .173
  • WSL 原有 origincar_birdseye offline_validation.launch.py 的父进程没有 DDS profile两个子节点仍绑定 .151。对明确 PID/命令行发送 SIGINT 正常停止后,用原命令在 .173 专用环境重启;synthetic_camera_nodebirdseye_node 的 socket 均位于 .173
  • .210 仍有一个 ROS_DOMAIN_ID=23 的独立 daemon它不属于本任务的 Domain 22未终止、未修改。

最终数据路径与延迟证据

  • 双向一次性 ROS 2 消息通过WSL 收到 rdk_to_wsl_via_164RDK 收到 wsl_to_rdk_via_164
  • 在 RDK 从专用环境订阅 WSL /image 8 秒,第一次接口增量:
    • .164 RX 88,225,838 bytesTX 345,016 bytes
    • .210 RX 2,042 bytesTX 1,092 bytes
  • 第二次同样负载:
    • .164 RX 90,334,970 bytesTX 346,092 bytes
    • .210 RX 1,194 bytesTX 1,092 bytes
  • 结论:这两批约 8486 MiB 的图像 DDS 数据经过 .164,没有经过 .210
  • 无负载时 .210 的 20 次 ping 为 0% 丢包、平均 2 ms、最大 8 ms。约 90 MB/8 秒图像负载期间15 次 ping 仍为 0% 丢包、平均 5 ms、最大 52 ms
  • 剩余延迟尖峰不是 IP/DDS 泄漏:当前 .164 回退网卡与 .210 管理网卡都连接同一个 kskbl_2.4G AP共享 2.4 GHz 空口。只有 openwrt_5G 恢复可见并由优先级 100 的 profile 在启动时选中,或使用独立有线/5G 链路,才能进一步消除射频竞争。

后续配置精确回滚

# RDK撤销 peer 地址提交,并删除本次新增回退连接。
cd /home/sunrise/yiliao_ws
git revert 87f562d
nmcli connection down 'kskbl_2.4G-rdk164' 2>/dev/null || true
nmcli connection delete 'kskbl_2.4G-rdk164'
nmcli connection modify 'openwrt_5G 1' connection.autoconnect-priority 0
# WSL恢复 .151 文件名、XML 与脚本。
cd /home/hikos/Yiliao2026
git revert c383338

回滚后应停止并重新启动 Domain 22 daemon/ROS 节点,使 participant 重新读取旧 XML。不要删除 .210 管理连接、现有策略路由脚本、Domain 23 daemon 或用户 dirty files。

WSL 最终 XML 完整内容(本节以下为最初 .151 版本的历史快照;当前生效版本和精确差异以上述后续实施结果为准):

<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com/XMLSchemas/fastRTPS_Profiles">
  <transport_descriptors>
    <transport_descriptor>
      <transport_id>wsl_udp_151</transport_id>
      <type>UDPv4</type>
      <maxInitialPeersRange>64</maxInitialPeersRange>
      <interfaceWhiteList>
        <address>192.168.10.151</address>
      </interfaceWhiteList>
    </transport_descriptor>
    <transport_descriptor>
      <transport_id>wsl_shm</transport_id>
      <type>SHM</type>
    </transport_descriptor>
  </transport_descriptors>

  <participant profile_name="wsl_dds_151" is_default_profile="true">
    <rtps>
      <builtin>
        <avoid_builtin_multicast>true</avoid_builtin_multicast>
        <initialPeersList>
          <locator>
            <udpv4>
              <address>192.168.10.151</address>
            </udpv4>
          </locator>
          <locator>
            <udpv4>
              <address>192.168.10.164</address>
            </udpv4>
          </locator>
        </initialPeersList>
      </builtin>
      <userTransports>
        <transport_id>wsl_udp_151</transport_id>
        <transport_id>wsl_shm</transport_id>
      </userTransports>
      <useBuiltinTransports>false</useBuiltinTransports>
    </rtps>
  </participant>
</profiles>