P5b 新手手册:这台机器在干什么 / 改哪里 / 怎么验 / 出问题查哪

此前仓库有规则文档(FRAMEWORK_RULES)、有目录表(WORKSPACE)、有各模块说明,
但**缺一份"从零进来的人读什么"**:业务目标没有一处讲清("通止规装配"散落在
7 个文件里各提一句),测试怎么跑在 docs/ 里一次都没写过,改一个东西该动哪个文件
要靠翻源码猜。

docs/HANDBOOK.md(416 行,新增)
  1. 这台机器在干什么 —— 通止规是检验螺纹的量具(通端应旋到底、止端应旋不进);
     为什么值得自动化(留下可追溯的力曲线);三段主线的数据流;日志三行判进度。
     ★ 1.4 节是**承诺书**:逐项标 ✅/⚠️/❌,并给出"哪条命令能证明它已就绪"。
       如实写明还没做的四项:自动拉起全部服务、夹爪持规自检、D435 手眼标定、
       装配合格判定。指不出验证命令的,就老实标 ❌(R6.1)。
  2. 系统长什么样 —— 三层各有硬边界;两块**独占资源**(RDK、D405 USB)
     以及各自的冲突表现;从像素到关节的全链路加上"每步的口径写错会怎么表现"。
  3. 我要改东西,改哪里 —— 决策表(改 X → 动 Y → 用 Z 验),覆盖换臂/悬高/夹爪/
     入孔/触觉/相机/仿真场景/权重/新品牌设备/命名位姿。每行都外链权威文档,
     不复制内容(M2)。
  4. 怎么验 —— 三层验收(不报错不算验收 / 物理量命中真值 / 任务成功)+ 命令清单 +
     **单元测试怎么跑**(此前 docs/ 里没有任何一处写过)。含 608 项分包清单。
     4.4 节专讲"验收工具自己也会失效",把 M1/R5.3/R6.6 串成一条线。
  5. 出问题按现象查 —— 三处权威文档的分工表 + 15 行"现象 → 先怀疑什么",
     覆盖 8 条仿真坑与全部触觉坑(坑 1/2/5/6/7/9/10)。
  6. 术语表 + 未做的事(按优先级)+ 往下读的路线。

顺带写进规则的(docs/FRAMEWORK_RULES.md)
  R6.7 验收命令必须真跑过 —— 本仓库已经因此踩过两次(CRLF 死脚本被五处文档推荐)
  R6.8 install/ 构建产物会互相污染 —— 见下面这个发现
  第 7 节清单加两条(第 10 条真跑过命令、第 11 条构建环境对不对)
  第 8 节反例表加三行症状

★ 顺带发现一个哑弹(R6.8,**已记录未修**)
  colcon build 会把当时激活的那个 python 的绝对路径写进每个入口脚本的 shebang。
  实测:install/ 里 31/59 条指向仿真环境 ros_gz_sim,install_sim/ 里 31/55 条
  (后者是对的)—— 说明真机 install/ 是在仿真 conda 环境里构建出来的,违反 R5.7。

      $ head -1 install/arm_interfaces/lib/arm_interfaces/device_check
      #!/home/cc/anaconda3/envs/ros_gz_sim/bin/python3.11

  为什么现在没炸:两个 conda 环境的 Python 依赖当前完全相同(pyrealsense2 / serial /
  cv2 / numpy / torch / ultralytics / tensorrt 都在),指错了也照样 import 成功。
  这是一颗哑弹 —— 哪天某个环境多装或少装一个包,真机栈就会以"模块找不到"的形式炸,
  而人是不会想到去查 shebang 的。

  修法(写进 R6.8,待执行):在真机 conda 环境里重建 install/,再
  `grep -l ros_gz_sim install/*/lib/*/* | wc -l` 应当变成 0。
  预防:构建脚本开头应断言当前 conda 环境与目标一致(待补)。

验收
  - 文档内所有相对链接与反引号路径引用均存在(脚本检查,0 坏链)
  - 文档里给的每条命令都实际执行过:
      ros2 run arm_interfaces device_check        通过
      device_check --list-brands                  列出 5 类设备
      scripts/show_site_config.sh                 存在
      check_sim_cameras.py / check_sim_scene.py / check_text_only.py  存在
      for d in src/*/test ... pytest 循环          608 passed
  - 单测 608 passed,与改动前一致(本次只改文档)

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
arm_dev
2026-09-24 09:05:09 +08:00
parent a91fa93339
commit fac2d5384d
5 changed files with 497 additions and 0 deletions
+54
View File
@@ -385,6 +385,56 @@ f-string 插值"这类问题;而"为了中文语序把两个插值换个显示
- 验能用:`bash <脚本> --help`
- 验行尾:`file <文件>`,或看 `.gitattributes` 有没有覆盖到
### R6.7 验收命令必须是**真跑过**的
写进文档的任何命令,都要当场执行一遍再写。理由是这个仓库已经踩过两次:
- `run_hole_detect.sh` / `run_dual_gripper.sh` 是 CRLF,五处文档让用户跑,
一敲就死(R6.6);
- `bash -n` 对其中一个还报 OK。
推论:
- 文档里的命令**复制粘贴要能跑**,别凭记忆写;
- 外链先确认目标文件存在(改完文档跑一次链接检查);
- 文档说"已就绪"的能力,要能指出**用哪条命令**证明它已就绪(R6.1)。
指不出来的,就老实标 ❌。
### R6.8 真机与仿真的 `install/` 产物会互相污染(已发现,待修)
`colcon build` 会把**当时激活的那个 python 的绝对路径**写进每个 console script 的
shebang。于是:
```
$ head -1 install/arm_interfaces/lib/arm_interfaces/device_check
#!/home/cc/anaconda3/envs/ros_gz_sim/bin/python3.11 ← 仿真环境的 python
```
`.gitattributes` 管不到这件事,`install/` 也不入库,所以它只能靠**规矩**和**检查**:
```bash
# 真机 install/ 里有多少入口脚本的 shebang 指向仿真环境(正常应当是 0)
grep -l ros_gz_sim install/*/lib/*/* | wc -l
```
当前实测:`install/` 是 **31 / 59**,`install_sim/` 是 31 / 55(后者是对的)。
即真机产物是在仿真 conda 环境里构建出来的,违反 R5.7。
**为什么现在没炸**:两个 conda 环境的 Python 依赖当前**完全相同**
(`pyrealsense2` / `serial` / `cv2` / `numpy` / `torch` / `ultralytics` / `tensorrt` 都在),
所以指错了也照样 import 成功。这是一颗**哑弹**:哪天某个环境多装/少装一个包,
真机栈就会以"模块找不到"的形式炸,而人是不会想到去查 shebang 的。
**修法**:在真机 conda 环境里重建 `install/`:
```bash
source scripts/env.sh # 确认 python3 指向 ros_flexiv
./scripts/build.sh # 只重建 arm_* 与 flexiv_description
grep -l ros_gz_sim install/*/lib/*/* | wc -l # 应当变成 0
```
**预防**:构建脚本开头应当**断言**当前 conda 环境与目标一致(待补)。
---
## 7. 改动前的检查清单
@@ -402,6 +452,8 @@ f-string 插值"这类问题;而"为了中文语序把两个插值换个显示
| 7 | 改完跑了验收工具吗(`check_sim_cameras` / `check_sim_scene`)? | R4.9 |
| 8 | 文档里的状态标注与实现还一致吗? | R6.1 |
| 9 | 提交信息里有"为什么"和实测数据吗? | R6.4 |
| 10 | 我写进文档的命令,自己跑过一遍吗? | R6.7 |
| 11 | 这次构建是在**目标环境**里做的吗?(`head -1 install/*/lib/*/*`) | R6.8、R5.7 |
---
@@ -437,6 +489,8 @@ f-string 插值"这类问题;而"为了中文语序把两个插值换个显示
| 脚本报 `$'\r': 未找到命令`、`set: pipefail: 无效的选项名` | 脚本是 CRLF 行尾,`\r` 被当成标识符的一部分 | R6.6 |
| `bash -n` 说没问题,真跑立刻死 | `bash -n` 对 CRLF 会漏报 —— 静态检查≠能用 | R6.6 |
| 代码里一半英文 docstring 一半中文注释 | 没有统一口径,谁写谁定 | R6.5 |
| 真机栈哪天突然报"模块找不到",明明装过 | `install/` 的入口脚本 shebang 指向**仿真环境**的 python(哑弹) | R6.8 |
| 照着文档敲命令,命令根本不存在 | 写文档时没真跑过 | R6.7 |
---