diff --git a/docs/GAUGE_ASSEMBLY.md b/docs/GAUGE_ASSEMBLY.md index 8dcbf10..b7446a4 100644 --- a/docs/GAUGE_ASSEMBLY.md +++ b/docs/GAUGE_ASSEMBLY.md @@ -252,12 +252,45 @@ S07 接触(腕部 FT):轴向 +48.37N 相对基线 -21.82N 超过 +8.0N( 250|--- +## 6.5 仿真跑之前:三件事(顺序别换) + +第 7 节的验收命令**都要求仿真已经在跑**,而这里以前只写了"先编",没写"怎么起" +和"起之前要清干净"——2026-09-28 实测就是在这两步上栽的。 + +```bash +# 1) 编(改过 src/ 之后必须;仿真 install_sim/ 是拷贝,不是 symlink —— 坑 2) +bash ~/ros2/scripts/build_sim.sh + +# 2) 清干净:上一轮的仿真进程、以及**在真机域上跑着的 mock 栈** +bash ~/ros2/scripts/stop_sim_gz.sh # 仿真栈(进程组 + install_sim/ 兜底) +bash ~/ros2/scripts/stop_real.sh --list # 真机/mock 侧(应为空) + +# 3) 起仿真(默认无头;要看画面加 --gui) +bash ~/ros2/scripts/run_sim_gz.sh +``` + +第 2 步里的 `stop_real.sh` **不是可选的礼貌动作**,实测踩过一次: + +> `run_sim.sh`(mock 栈)名为 sim,用的却是**真机的 `install/`**、节点名与真机 +> 完全一样,而且它当时**不管 `ROS_DOMAIN_ID`** —— 调用者 shell 里带着 77 +> (之前跑过仿真)就落到**仿真的域**上。于是 mock 的 `joint_state_publisher` +> 与 Gazebo 争 `/joint_states`:**控制器 `feedback` 与 `reference` 完全一致** +> (控制器没坏),TF 却显示末端**一动不动**。 +> +> 表现是"仿真上料失败、臂摆不到竖直位姿",顺着现象查会一路查到 IK / TF / 时钟上。 +> 现在两侧的域都钉死了(`run_sim.sh` → 真机域 0,`run_sim_gz.sh` → 仿真域 77, +> 见 `scripts/lib/ros_domain.sh`),但**残留进程本身**仍要靠第 2 步清掉。 + ## 7. 验收命令(都是真跑过的) ```bash # 1) 纯逻辑层(不需要机器人) -PYTHONPATH=src/arm_application python3 -m pytest src/arm_application/test -q -# 仿真环境:454 passed, 14 skipped(缺 onnx 的用例跳过,不伪装成失败) +bash ~/ros2/scripts/run_unit_tests.sh src/arm_application +# 真机环境:557 passed(`onnx` 齐);仿真环境会少几项 —— 缺 onnx 的用例 skip, +# 不伪装成失败(R5.10)。 +# 别用裸 `PYTHONPATH=src/... python3 -m pytest`:那样导入不到 ament/ROS、 +# 收集阶段就报 error,看起来像"测试挂了",其实只是环境没装 —— 用上面这个 +# 运行器(它负责切 conda、按包拼 PYTHONPATH)。 # 2) 干跑全流程:S00→S01→…→S11→DONE,脚本退出码 0,结论 ok=true bash ~/ros2/scripts/run_gauge_assembly.sh --arm 89 --sim --dry-run diff --git a/docs/HANDBOOK.md b/docs/HANDBOOK.md index 3a0b445..c64037b 100644 --- a/docs/HANDBOOK.md +++ b/docs/HANDBOOK.md @@ -357,7 +357,7 @@ bash scripts/weights.sh doctor --check-engines ### 4.3 单元测试怎么跑 -**每个功能包都有自己的测试**,改完对应包就跑一下。当前 pytest 收集 **1118 项** +**每个功能包都有自己的测试**,改完对应包就跑一下。当前 pytest 收集 **1128 项** (另有 1 项按环境 skip)。 ```bash diff --git a/scripts/run_gauge_assembly.sh b/scripts/run_gauge_assembly.sh index 54f56c9..113d537 100755 --- a/scripts/run_gauge_assembly.sh +++ b/scripts/run_gauge_assembly.sh @@ -120,7 +120,15 @@ if [[ "${USE_SIM}" == true ]]; then ARGS+=(use_sim_time:=true); fi if [[ "${USE_SIM}" == true ]]; then ARGS+=(publish_handeye_tf:=false) echo "=== 刷新仿真手眼真值(sim_eye_in_hand.yaml / sim_d435_eye_to_hand.yaml) ===" - if ! python3 "${ROOT}/scripts/gen_sim_handeye.py" --arm "${ROBOT_SN:-sim}"; then + # ⚠️ 这里**必须**用仿真台的别名,不能用 ${ROBOT_SN}。 + # 真值要按**仿真 URDF 的帧名**导出(sim_flange / sim_d405_color_optical_frame)。 + # 而 `--arm 89 --sim` 是个**合法且有意的**用法(见上面 _HAD_ARM 那段: + # "想用仿真核对某台真机的点位时会这么用")——那时 ROBOT_SN=Rizon4-063989, + # 帧名就成了 Rizon4-063989_flange,仿真里根本没有这个帧: + # 导出会先等 20s 再报"仿真栈起来了吗?",把人引去重启一个明明在跑的仿真。 + # 实测(2026-09-28)就是这么踩的 —— 文档 §7 里写的就是 `--arm 89 --sim`, + # 照着敲必然失败。 + if ! python3 "${ROOT}/scripts/gen_sim_handeye.py" --arm "${SIM_ARM_ALIAS:-sim}"; then echo "ERROR: 仿真手眼真值导出失败(上面有原因)。仿真栈起来了吗?" >&2 echo " bash scripts/run_sim_gz.sh 之后重试。" >&2 exit 1