通止规装配:配置段进 site.yaml + 中文手册 + 成败判定「不看 $?」

配置(site.yaml → gauge_assembly:,38 键全部带中文注释)
------------------------------------------------------
- 键名/单位/类型/交叉矛盾由 gauge_config.py 校验:拼错键名报错并给最相近的候选,
  单位后缀(_deg/_mm/_m/_s/_pct/_delta)逐条对表,`contact_safe_delta ≤
  contact_tangential_delta` 这类矛盾启动就拦(R1.2:没接线的键不许静默存在)。
- 借机清掉 4 个**没接线**的键(require_preview / track_*_s / hover_m:前两个是
  stage1 那层的、后两个是 servo 那层的,放在这里等于第二份真相),
  并把 contact_speed_m_s / coarse_timeout_s / 夹爪力速 真的接上。
- site.example.yaml 由 site.yaml 生成(gen_site_example.py --check 通过)。

成败判定:`ros2 launch` 的退出码**恒为 0**
------------------------------------------
实测(Humble):子进程 exit 3,`ros2 launch` 仍返回 0。用 `$?` 判成败的脚本会把
"装配失败"记成"成功"——没人会去查一个说成功的脚本。改成:

- 节点把结论**落盘**(--result-file,默认 /tmp/gauge_assembly_result.json,原子写、
  先落盘再发话题),任何"没跑到收尾"的退出也会补一份 ok=false;
- 脚本读结论文件判成败:0=成功、1=失败、**文件不存在也算失败**并说清;
- 新增 test_gauge_result_gate.py:把脚本里那段判成败的 Python 抽出来,
  对成功/失败/干跑/缺文件/坏 JSON 五种输入断言退出码 —— 判据本身也有测试。

顺带修掉两个"看着像玄学"的现象
------------------------------
- **流程打完了终端不回提示符**:launch 里的静态 TF 发布者是常驻的,主节点退出
  带不走它 —— 挂 OnProcessExit → Shutdown。
- **"已装 1/2 孔"**:结果里 hole_index 是 0 基当前孔号,不是"装完几个",
  新增 holes_done 给人和脚本看。

文档(全部中文,含"怎么调参/还没做")
------------------------------------
- 新增 docs/GAUGE_ASSEMBLY.md:状态机全图、每步判据表、E1 掉件处理(**按实现**:
  掉件后该孔作废、换下一个孔;最后一个孔掉件则序号被夹住=重试本孔)、
  话题契约、调参顺序、验收命令、踩过的坑。
- FRAMEWORK_RULES 新增 R5.8(同一份数学只许一份 + 守卫测试)、R5.9(自检的
  期望类型与调用处同源)、R5.10(缺依赖 skip,别留常年红)、R6.9(硬退出前打
  traceback)、R6.10(ros2 launch 退出码恒 0)+ R5.7 补真机/仿真"生效方式不同"
  (真机软链即改即生效,仿真拷贝必须重编)+ 5 条症状反例、.cursor/rules 同步。
- WORKSPACE / INTERFACES / SITE_CONFIG / HANDBOOK / 两份 README 索引与决策表补齐。

验证(本机真跑)
----------------
  pytest(仿真环境)  436 passed, 14 skipped(缺 onnx 跳过)
  干跑 --sim --dry-run  → 脚本退出码 0,结论 ok=true  已装 2/2 孔
  不干跑 --sim          → 脚本退出码 1,S00 拦住,未发任何运动指令

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
arm_dev
2026-09-24 10:30:11 +08:00
parent dfc945b7e0
commit bda2fa7129
16 changed files with 741 additions and 37 deletions
+10 -1
View File
@@ -81,7 +81,8 @@ bash ~/ros2/scripts/run_all.sh --arm 89 # T3 三段串联(
| D435 手外相机(S03 粗定位兜底) | ❌ **还没做手眼标定**,链路不可用 | 见 `devices/cameras/README.md` |
| 自动启动全部服务(一条命令拉起所有进程) | ❌ 还没做,目前靠三个终端手工起 | 见第 6 节待办 |
| 「规有没有被夹住」自检 | ❌ 还没做 | 见第 6 节待办 |
| 装配合格判定(通/止) | ❌ 还没做。当前只输出几何与力的原始结果 | `/tmp/stage3_result.json` |
| 装配合格判定(通/止) | ⚠️ **通止规装配流程**能按力矩判据拧到底/拧出来,但"通/止合格"结论还没做 | `run_gauge_assembly.sh --arm 89 --dry-run` |
| 通止规装配流程(S00–S11 状态机) | ⚠️ **干跑与单测通过,真机未跑**(无真机)。详见 [`GAUGE_ASSEMBLY.md`](GAUGE_ASSEMBLY.md) | 同上(干跑不动臂) |
| Gazebo 仿真 | ✅ 场景、相机、触觉、夹爪可跑 | [`devices/sim/gazebo/README.md`](../devices/sim/gazebo/README.md) |
> 这张表是**承诺书**:❌ 的别当成已具备。文档说"已就绪"而实际没有,
@@ -175,6 +176,7 @@ D405 YOLO 手眼 T 伺服 ros2_cont
| 算法权重(换模型) | `models/<分组>/` + `site.yaml` 的路径 | `scripts/weights.sh list` | [`models/README.md`](../models/README.md) |
| 接一个新品牌设备 | `devices/<类别>/<品牌>/` + `registry.yaml` 一行 | `ros2 run arm_interfaces device_check` | [`devices/README.md`](../devices/README.md) |
| 命名位姿(回零点等) | `src/arm_control/config/named_poses_89.yaml` / `_91.yaml` | `go_home.sh --arm 89` | [`INTERFACES.md`](INTERFACES.md) |
| 通止规装配的参数(预绕角/力阈值/孔数) | `site.yaml` → `gauge_assembly:`(每个键都有注释) | `run_gauge_assembly.sh --arm 89 --dry-run` | [`GAUGE_ASSEMBLY.md`](GAUGE_ASSEMBLY.md) |
| 框架规矩本身 | `docs/FRAMEWORK_RULES.md`,**同时**改 `.cursor/rules/` | `python3 scripts/check_text_only.py` | R6.1 |
### 3.2 改一个现场数值(最高频)
@@ -397,6 +399,9 @@ python3 -m pytest src/arm_sim_gazebo/test -q
让人跑去查夹爪代码(R4.12)。
- 上一轮的**残留进程**伪造出"代码写错了"的现场 —— 两个同名适配器抢话题/服务,
残留的 `static_transform_publisher` 把旧外参按在新仿真上,读数全是乱的(R4.11)。
- **同一份数学写了四份**(四元数换算),退化角度的公式各不相同 ——
没有哪一份"看起来坏",只是不同 launch 发出来的手眼 TF 不一样(R5.8)。
- 测试长期十几条红,于是**没人再看测试结果** —— 真出问题时也看不出来(R5.10)。
**所以**:
@@ -442,6 +447,10 @@ python3 -m pytest src/arm_sim_gazebo/test -q
| 仿真镜头位置不对、只看得见地面 | 相机 `rpy` 复合顺序 | 仿真手册坑 5 |
| 脚本说"已停止",进程还在 | 进程模式表漏项 | R4.10 |
| 孔检测在仿真里怎么都不过 | 图幅与真机不同,像素门槛失效 | 仿真手册 §4.3 |
| `site.yaml` 改了参数,行为一点没变 | 那个键**没接线**(配置表里有、代码里从没读) | R1.2 |
| 流程退出码 1,日志里一个字都没有 | 入口 `os._exit()` 把异常吞了 | R6.9 |
| 同一个手眼 TF,换个脚本跑出来不一样 | 四元数换算被抄了多份 | R5.8 |
| 通止规流程 S00 就停住、说不缺的东西缺了 | 自检的"期望类型"与流程实际调用的类型不一致 | R5.9 |
---