Files
ros_contorl/README.md
T
arm_dev bda2fa7129 通止规装配:配置段进 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>
2026-09-24 10:30:11 +08:00

102 lines
5.0 KiB
Markdown
Raw 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.
# Flexiv Rizon 视觉伺服(`~/ros2`)
独立工作空间:腕部 D405 眼在手上、手眼标定、YOLO 找工件、法兰悬停跟踪、DH 夹爪、入孔检测。
**一份仓库即可跑完整跟踪与检测**,不依赖 `camera_test` 或装配 HMI。
工作目录必须是 ASCII 路径(推荐克隆到 `~/ros2`)。
| 项 | 值 |
|----|-----|
| 配置 | [`config/site.yaml`](config/site.example.yaml)(从 example 复制,不进 git) |
| 操作 | [`scripts/`](scripts/README.md) |
| 目录说明 | **[docs/WORKSPACE.md](docs/WORKSPACE.md)**(每个文件夹做什么) |
| Conda | `ros_flexiv` |
| ROS | Humble |
## 克隆后
```bash
cd ~/ros2
cp config/site.example.yaml config/site.yaml
# 编辑 site.yaml:robot.sn / robots[].ip / camera.serial / paths.yolo_weights
# 权重文件放到 models/<分组>/(二进制不在 git 里;布局与标签见 models/README.md)
conda activate ros_flexiv
source scripts/env.sh
./scripts/build_all.sh
source scripts/env.sh
```
示教器:**AUTO + Remote Ethernet**,关掉 Flexiv Studio(RDK 独占)。
```bash
# 三个终端必须带同一个 --arm(89=左 91=右)
bash ~/ros2/scripts/run_real.sh --arm 89
bash ~/ros2/scripts/run_camera_d405.sh --arm 89 --preview
bash ~/ros2/scripts/run_visual_servo_rt.sh --arm 89 --control
```
改 `site.yaml`:锁高 / YOLO / 伺服 → 重启第三终端;分辨率 / 曝光 → 重启相机。
## 功能入口
| 功能 | 命令 |
|------|------|
| 实机 | `scripts/run_real.sh --arm 89\|91` |
| 腕部相机 | `scripts/run_camera_d405.sh --arm … --preview` |
| 顶视 D435 | `scripts/run_camera_d435.sh --preview` |
| 列出相机 | `scripts/list_realsense.sh` |
| 跟踪 | `scripts/run_visual_servo_rt.sh --arm … [--control]` |
| 回 home | `scripts/go_home.sh --arm …` |
| 手眼 | `scripts/run_handeye.sh --arm … teach` → `merge` → `calibrate` |
| PGEA / RGI 夹爪 | `scripts/run_gripper.sh --arm 89\|91 --cli …` |
| 双爪 ROS | `scripts/run_dual_gripper.sh` |
| 入孔检测 | `scripts/run_hole_detect.sh --arm … --preview` |
| Orisys 触觉 | `scripts/run_tactile.sh [--cli]` |
| Gazebo 仿真 | `scripts/run_sim_gz.sh [--gui]`(停:`scripts/stop_sim_gz.sh`) |
| 通止规装配 | `scripts/run_gauge_assembly.sh --arm … [--dry-run]` |
| 看配置 | `scripts/show_site_config.sh` |
89 与 91 **各有** 手眼、相机序列号、锁高、named poses,禁止混用。
## 文档
| 文档 | 内容 |
|------|------|
| [docs/HANDBOOK.md](docs/HANDBOOK.md) | **新手手册**(这台机器在干什么 / 改哪里 / 怎么验 / 出问题查哪) |
| [docs/FRAMEWORK_RULES.md](docs/FRAMEWORK_RULES.md) | **框架规则**(改代码前先读;含历史反例的症状表) |
| [docs/WORKSPACE.md](docs/WORKSPACE.md) | 每个目录 / 脚本 / 包 |
| [docs/QUICKSTART.md](docs/QUICKSTART.md) | 环境与第一次跑通 |
| [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) | 进程与几何 |
| [docs/SITE_CONFIG.md](docs/SITE_CONFIG.md) | `site.yaml` 字段 |
| [docs/HANDEYE.md](docs/HANDEYE.md) | 手眼标定 |
| [docs/TRACKING.md](docs/TRACKING.md) | 视觉伺服 |
| [docs/GRIPPER.md](docs/GRIPPER.md) | PGEA + RGI |
| [docs/HOLE_DETECT.md](docs/HOLE_DETECT.md) | 入孔检测 |
| [docs/TACTILE.md](docs/TACTILE.md) | Orisys 视触觉 |
| [devices/sim/gazebo/README.md](devices/sim/gazebo/README.md) | Gazebo 仿真手册(使用方法 / 建模要求 / 导入格式 / 配置方式 / 避坑清单) |
| [docs/INTERFACES.md](docs/INTERFACES.md) | ROS / 脚本接口 |
| [docs/TRAJECTORIES.md](docs/TRAJECTORIES.md) | 轨迹回放 |
## 上传 git 时
- **要提交**:`src/` `scripts/` `docs/` `devices/` `config/site.example.yaml` `models/README.md` `models/**/*.labels.yaml` `handeye/`
- **不要提交**:`config/site.yaml`(含本机 IP/序列号)、`handeye/tmp/`(临时产物)、`build/` `install/` `log/`、YOLO `.pt/.onnx/.engine`、`thirdparty/` `vendor/`
- 规则已写在 `.gitignore`
### `handeye/` 是个例外,说明一下
`handeye/poses/`(示教点)与 `handeye/results/`(标定结果)**是入库的**,
尽管它们属于某台现场的数据。理由是:手眼标定要用真机示教十几分钟,
是费了真机时间换来的资产,入库才有一份可回滚的备份;一旦没入库,
一次误删就得重新上真机采点。所以这两类文件按"资产"对待,而不是按"配置"。
因此**别人克隆后必须重新标定,并把结果覆盖到 `handeye/results/<臂号>_<模式>.yaml`**。
不要直接用仓库里现成的 `T_4x4` —— 那是属于另一台机器、另一个相机安装位的,
用错的表现是跟踪始终差几厘米,且很难怀疑到标定值上。
示教点同理:`handeye/poses/` 里的关节角只在对应的那台臂上有意义。
(注:`config/site.yaml` 不入库、而 `handeye/` 入库,看似矛盾,其实是
"配置属于站点、不入库;标定成果属于资产、入库"这条区分。早期这两类的
边界没写清,导致 README 的说明和仓库实际状态不一致。)