Files
ros_contorl/scripts/check_robot_network.sh
arm_dev f5ed44a987 配置:消灭代码里的硬编码臂 SN,并给"换臂漏改"加一把尺子
## 为什么

"设备 ID 全部可配置"这条要求在代码里只做了一半:site.yaml 能配,
但**代码和静态配置里到处躺着 Rizon4-063989 当兜底**。这类兜底的危害
不是"改起来麻烦",而是它把"配置没生效"伪装成"配置生效了":

  * `robot_sn` 默认 `Rizon4-063989` → 换臂后节点去订**上一台臂**的关节话题,
    节点起来了、不报错、什么都不动;
  * launch 里用 `ee_frame == "Rizon4-063989_flange"` 当"用户没指定"的哨兵 →
    换个站点这个判断永远不成立,于是 site.yaml 里的 ee_frame 再也不会被用上,
    静态 TF 挂错坐标系、点还照样查得到;
  * `if SN == "Rizon4-063989"` 决定要不要拉触觉服务 → 换臂后触觉静默消失。

## 改了什么

1. **删掉所有"兜底成某台臂"的默认值**(15 处脚本 + 6 个 launch + 6 个节点)。
   没配就为空 / 直接 `:?` 报错,宁可起不来也不要连错机器:
   - `scripts/lib/export_site_env.py`:别名解析改为从 `robots[]` 现算
     (`arm_short_id` / `resolve_robot_sn` / `describe_arms`),选不出臂时
     抛 `ValueError`;`main()` 捕获后打人话 + 退出码 2(供 shell `eval`);
   - 手眼文件/路点/工作目录由当前臂 short id 派生,不再写死 `89_*`;
   - `ROBOT_HAS_TACTILE` 改为读 site.yaml 的 `robots[].tactile`;
   - `arm_application/site_io.py` 新增 `joint_prefix_default()` /
     `base_frame_default()` / `ee_frame_default()`:优先读 `SITE_*`,
     退而由 `SITE_ROBOT_SN` 现算,**不写死 SN**;
   - `arm.urdf.xacro` 的 `robot_sn` 默认值改成明显的占位符 `UNSET_ARM_SN`
     (关节名会带出来,报错信息自解释);
   - `ros2_control.launch.py` / `move_group.launch.py` **原先根本不传
     robot_sn**,靠 xacro 写死默认值"蒙对"本机,现在都从环境取。

2. **新增 `scripts/check_arm_prefixes.py`**:Flexiv 把 SN 编进关节名,
   所以有一批一级配置(SRDF/controllers/joint_names/bringup/servo/...)
   必须跟着当前臂走。漏改的症状是"MoveIt 规划成功但机械臂不动",很难查。
   这个脚本逐文件逐行列出对不上的地方,并直接给出修法。
   `--list` 还会说明 SN 来自 site.yaml 还是被 `ROBOT_SN` 覆盖。

3. **文档**:`FRAMEWORK_RULES.md` 新增 R1.1.1(两类含臂名文件怎么分、
   换臂四步)+ 检查清单第 12 条 + 反例 2 条;`HANDBOOK.md` 新增 3.6.1
   与症状表 2 行。

4. **顺带修掉的真 bug**(都是这次改动带出来、被 pyflakes + 真跑抓住的):
   - `convert_flexiv_traj.py` / `rdk_drag_bridge.py` 用了 `os` 但没 import
     → `--help` 直接 NameError;
   - `check_arm_prefixes.py` 第一版正则用 `\b` 收尾,而关节名是
     `Rizon4-063989_joint1`(`_` 属于 \w,`\b` 不成立)→ SRDF 里 24 处
     硬编码**一处都没报**,还打印 OK。已加负向测试钉住;
   - 删掉若干死代码/死 import(`pos_line`/`flat`/`names`、`IfCondition` 等)。

## 验收(都真跑过)

- `python3 -m pyflakes <全部改过的 py>` → 干净
- 逐包 pytest:233 + 69 + 78 + 24 + 236 = **640 passed**
- `env -u ROBOT_SN python3 scripts/check_arm_prefixes.py` → OK(8 文件)
- 换成 SN=Rizon4-777001 的临时 site.yaml → 报出**8 个**文件不一致并给修法(退出码 1)
- 故意不给 SITE_* → 各 launch 的 `robot_sn` / `ee_frame` / `handeye_file`
  默认值为 `''`,不再悄悄指向上一台臂
- `ros2 launch ... --show-args` 对 stack/sim/ros2_control/mock_control/
  move_group/display/visual_servo **全部通过**
- `convert_flexiv_traj.py --help` 正常;拿 `xunhuan.traj` 真转 5 个路点,
  输出 `joint_prefix: "Rizon4-063989_"` 来自 site.yaml

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-24 09:18:44 +08:00

91 lines
2.5 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# 检查 PC ↔ Flexiv 机器人网络(地址取自 site.yaml)
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
# shellcheck disable=SC1091
source "${ROOT}/scripts/lib/load_site_config.sh" 2>/dev/null || true
ROBOT_IP="${ROBOT_IP:-${SITE_ROBOT_IP:-192.168.100.1}}"
ROBOT_SN="${ROBOT_SN:-${SITE_ROBOT_SN:-}}"
PC_IP="${PC_IP:-${SITE_PC_IP:-192.168.100.10}}"
pick_iface() {
if [[ -n "${IFACE:-}" ]]; then
echo "$IFACE"
return
fi
if [[ -n "${SITE_NET_IFACE:-}" && -d "/sys/class/net/${SITE_NET_IFACE}" ]]; then
echo "${SITE_NET_IFACE}"
return
fi
local d
for d in enp4s0 enp5s0 eth0; do
[[ -d /sys/class/net/$d ]] && echo "$d" && return
done
for d in $(ls /sys/class/net); do
[[ "$d" == lo ]] && continue
[[ "$d" == en* || "$d" == eth* ]] || continue
local state
state=$(cat /sys/class/net/"$d"/operstate 2>/dev/null || echo down)
[[ "$state" == up ]] && echo "$d" && return
done
echo enp4s0
}
IFACE="$(pick_iface)"
echo "=== 本机网卡 ==="
ip -4 -br addr
echo
echo "=== 目标机器人(site.yaml) ==="
echo " SN $ROBOT_SN"
echo " 标签 ${SITE_ROBOT_LABEL:-}"
echo " 目录 ${SITE_ROBOT_CATALOG:-}"
echo " IP $ROBOT_IP"
echo " 本机 $PC_IP"
echo " 网卡 $IFACE"
if ping -c 1 -W 1 "$ROBOT_IP" >/dev/null 2>&1; then
echo " ping UP — 链路 OK"
else
echo " ping DOWN — PC 与机器人必须同网段(本机 ${PC_IP} ↔ 机器人 ${ROBOT_IP})"
echo
echo " 一键修复(交换机 / 有线):"
echo " bash ~/ros2/scripts/fix_robot_lan.sh"
echo " 独立交换机(不要办公网 DHCP)可用:"
echo " bash ~/ros2/scripts/fix_robot_lan.sh --only"
fi
echo
echo "=== 常见地址探测 ==="
CANDIDATES=(
"$ROBOT_IP"
192.168.2.100 192.168.2.10 192.168.101.1 192.168.101.10
192.168.100.1 192.168.100.10
192.168.100.1 192.168.100.2 192.168.100.10
192.168.1.1
)
seen=""
for ip in "${CANDIDATES[@]}"; do
[[ " ${seen} " == *" ${ip} "* ]] && continue
seen+=" ${ip}"
if ping -c 1 -W 1 "$ip" >/dev/null 2>&1; then
echo " UP $ip"
else
echo " down $ip"
fi
done
echo
echo "=== 当前邻居 (ARP) ==="
ip neigh | grep -v FAILED || true
echo
echo "说明:"
echo "1) 网线接机器人控制柜网口 ↔ 本机 $IFACE。"
echo "2) 示教器开启 RDK / 远程控制后再连。"
echo "3) RDK 连接用 SN(不是 IP):flexivrdk.Robot('$ROBOT_SN')"
echo "4) 切换机械臂:改 ~/ros2/config/site.yaml 的 robot.sn"
echo "5) 手册: https://flexiv.cn/software/rdk/manual/index.html"