Files
ros_contorl/docs/WORKSPACE.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

230 lines
11 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.
# 工作空间地图
本仓库 **`~/ros2`** 是完整的 Flexiv Rizon **眼在手上视觉伺服** 工作空间:实机驱动、腕部 D405、手眼标定、YOLO 跟踪、法兰悬停、DH 夹爪、入孔检测、Orisys 视触觉读数。
**不依赖** `camera_test` / `ros_flexiv` HMI。装配插入运动不在这里。
路径必须是 ASCII(推荐 `~/ros2`)。不要在中文目录里 `colcon build` 消息包。
日常只改 **`config/site.yaml`**(从 `config/site.example.yaml` 复制,**不进 git**)。
日常只跑 **`scripts/*.sh`**。包内 yaml 是默认值,被 site 覆盖。
---
## 顶层
| 路径 | 进 git? | 做什么 |
|------|----------|--------|
| `README.md` | 是 | 克隆后怎么跑 |
| `docs/` | 是 | 说明文档(本文件是目录总表);**规矩在 [`FRAMEWORK_RULES.md`](FRAMEWORK_RULES.md)** |
| `config/site.example.yaml` | 是 | 现场配置模板 |
| `config/site.yaml` | **否** | 本机 SN / IP / 相机 / 锁高 |
| `config/fastdds_visual_servo.xml` | 是 | 可选 FastDDS;默认不用 |
| `scripts/` | 是 | 唯一操作入口 |
| `src/` | 是 | ROS 2 包源码 |
| `devices/` | 是 | **设备模块树**(机器人/夹爪/相机/传感器/仿真),见下节 |
| `handeye/` | 目录是;`tmp/` 内容 **否** | 手眼标定配置 / 采点 / 结果,见 `handeye/README.md` |
| `models/` | 目录与 `.labels.yaml` 是;权重二进制 **否** | 算法权重模块,见 `models/README.md` |
| `build/` `install/` `log/` | **否** | 真机环境的 `colcon` 产物 |
| `build_sim/` `install_sim/` `log_sim/` | **否** | **仿真环境**的产物(`scripts/build_sim.sh`)。两套并存是刻意的:同一份源码、两个环境的依赖路径不同,共用 `install/` 会互相覆盖 |
| `.cursor/rules/` | 是 | 给 AI 的常驻规则(`FRAMEWORK_RULES.md` 的压缩版,权威仍是那份文档) |
| `thirdparty/` `vendor/` | **否** | 可选离线 RDK / Isaac 克隆 |
| `.gitignore` | 是 | 上面「否」的规则 |
---
## `devices/` — 设备模块树(换品牌 = 加目录,不改代码)
这一层是"通用化"的落点:上层按 `manifest.yaml` **选型**,不认具体品牌名。
所以换一台机器人/夹爪/相机/传感器,是**新增一个 `<品牌>` 目录**,
而不是改现有目录或改应用代码。
```
devices/<kind>/<brand>/
├── manifest.yaml # id/label/kind/vendor/version + assets + driver + capabilities + models + config_schema
├── driver/ # 与厂商 SDK 对接的实现(可替换)
└── models/<型号>/ # 该品牌的型号专属文件
```
| kind | 现有品牌 | 说明 |
|------|----------|------|
| `robots/` | `flexiv` | Flexiv Rizon / AICO(RDK) |
| `grippers/` | `dh_pgea` | 大寰 PGEA 平行爪 / RGI 旋转爪 |
| `cameras/` | `realsense` | Intel RealSense D405 / D435 |
| `sensors/` | `orisys` | Orisys 视触觉(三向力 + 深度图 + 力矢量图) |
| `sim/` | `gazebo` | Gazebo 物理仿真平台,手册见 `devices/sim/gazebo/README.md` |
`devices/registry.yaml` 声明"本仓库装了哪些品牌";`manifest.yaml` 里
`assets[].required: true` 的物料缺失时框架会报错,并给出**格式与命名要求**。
> 选型与接线细节见 [`FRAMEWORK_RULES.md`](FRAMEWORK_RULES.md) 第 1 节(R1.3)。
---
## `config/` — 现场配置
| 文件 | 作用 |
|------|------|
| `site.example.yaml` | 克隆后 `cp` 成 `site.yaml`,填你的 SN、IP、相机序列号、权重路径 |
| `site.yaml` | 本机唯一入口。`robots[]` 里 89/91 各写相机、手眼、锁高、夹爪 |
| `fastdds_visual_servo.xml` | 仅当 DDS 丢图时再把路径填进 `site.yaml` → `paths.fastdds_profile` |
`site.yaml` 如何进节点:`scripts/lib/export_site_env.py` 按 `--arm` 合并 `robots[]`,导出 `SITE_*` 和环境,launch 再覆盖 `perception.yaml` / `servo.yaml`。
---
## `scripts/` — 操作入口
先:`conda activate ros_flexiv && source ~/ros2/scripts/env.sh`
### 每天用
| 脚本 | 作用 |
|------|------|
| `run_real.sh --arm 89\|91` | Flexiv RDK + ros2_control。示教器 AUTO + Remote Ethernet,先关 Studio |
| `run_camera_d405.sh --arm … --preview` | 该臂腕部 D405。89→`/d405_left/`,91→`/d405_right/` |
| `run_camera_d435.sh --preview` | 顶视 D435(手外,可选) |
| `list_realsense.sh` | 列出已接 RealSense 序列号 |
| `run_visual_servo_rt.sh --arm … [--control]` | YOLO + 伺服。无 `--control` 只看框;有则动臂。从当前姿态开始,不回 home |
| `go_home.sh --arm …` | 回 named pose `home`(会先停伺服) |
| `show_site_config.sh` | 打印当前臂解析出的路径/锁高/相机 |
### 手眼
| 脚本 | 作用 |
|------|------|
| `run_handeye.sh --arm … teach` | RDK 软拖拽记点。必须先停 `run_real.sh`(RDK 独占)。`--mode eye_in_hand\|eye_to_hand`、`--points N`、`--ros --auto-solve` |
| `run_handeye.sh --arm … merge` | 把 `handeye/tmp/<臂号>/taught_poses.txt` 写入该臂 `handeye/poses/<臂号>_<模式>.yaml` |
| `run_handeye.sh --arm … calibrate` | 走一遍示教点拍棋盘,解 T,写入 `handeye/results/<臂号>_<模式>.yaml`。需要 T1 实机 + T2 相机 |
| `run_handeye.sh --arm … show` | 打印该臂板尺寸、poses 路径、点数 |
| `merge_handeye_poses.py` | merge 的实现,一般不直接调 |
### 夹爪 / 网络 / 编译
| 脚本 | 作用 |
|------|------|
| `run_gripper.sh --arm 89\|91 --cli …` | 左 PGEA / 右 RGI。无 `--cli` 起该臂 ROS 节点 |
| `run_dual_gripper.sh` | 双爪同一 ROS 节点(`arm_msgs`) |
| `run_hole_detect.sh --arm … [--preview]` | 入孔检测(只出像素孔心,不插入) |
| `run_tactile.sh [--cli]` | Orisys 左右指视触觉 |
| `run_gauge_assembly.sh --arm …` | **通止规装配**(S00–S11)。`--dry-run` 只验编排不动臂;前置服务要自己先起(见 [GAUGE_ASSEMBLY.md](GAUGE_ASSEMBLY.md)) |
| `env.sh` | 加载 conda + ROS + `install/setup.bash` + `site.yaml` |
| `build_all.sh` | `build.sh`(arm 包)+ `build_real.sh`(Flexiv 硬件包) |
| `build.sh` | colcon:`arm_*` + `flexiv_description` |
| `build_real.sh` | colcon:`flexiv_hardware` 等,需本机已装 RDK(`~/flexiv_install`) |
| `check_robot_network.sh` `fix_robot_lan.sh` | 查/修工控机到机器人网段 |
| `test_rdk_python.sh` | 测 RDK Python 能否连上 |
| `rdk_switch_tool.sh` | 切换 Studio Tools 名(`site.yaml` `robot.tool_name`) |
| `weights.sh` | 权重模块入口(list / labels / convert / doctor / show),见 `models/README.md` |
| `export_yolo_trt.sh` | **旧命令**,转发壳 → `weights.sh convert --to engine` |
| `run_sim.sh` `run_mock_demo.sh` | 无真机 mock |
| `run_display.sh` | RViz 等显示 |
| `convert_traj.sh` `convert_flexiv_traj.py` | 非夕轨迹 → ROS |
| `fetch_flexiv.sh` `build_flexiv_rdk.sh` `install_rdk_offline.sh` `use_local_flexiv.sh` | 拉/编官方 RDK(新机器) |
| `rdk_drag_bridge.py` `rdk_gripper.py` | 底层 RDK 辅助,由 wrapper 调用 |
### `scripts/lib/`
| 文件 | 作用 |
|------|------|
| `parse_arm_args.sh` | 解析 `--arm 89\|91\|left\|right` |
| `load_site_config.sh` | 调 Python,把 `site.yaml` 变成 bash `SITE_*` |
| `export_site_env.py` | 合并当前臂 overlay;`--print` 给人看 |
---
## `src/` — ROS 2 包
### 本仓库业务(改跟踪/手眼看这里)
| 包 | 作用 |
|----|------|
| `arm_application` | 相机发布、预览、YOLO、伺服、手眼、PGEA/RGI 夹爪、入孔检测、Orisys 触觉 |
| `arm_bringup` | `stack.launch.py`:`backend:=real\|mock`,被 `run_real.sh` 调用 |
| `arm_control` | 命名位姿 `/set_named_pose`、状态、轨迹适配。点位:`config/named_poses_89.yaml` / `_91.yaml` |
| `arm_msgs` | 本栈消息 / 服务 / action |
| `arm_description` | 本栈用的机器人描述(若与 flexiv_description 并存,以 bringup 为准) |
| `arm_moveit_config` | MoveIt 配置(跟踪主路径不用) |
`arm_application` 节点见该包 README。手眼结果:
- `handeye/results/<臂号>_<模式>.yaml` — **相机→法兰** `T_4x4`,标定写入(见 `handeye/README.md`)
- `handeye/poses/<臂号>_<模式>.yaml` — 示教关节
- `perception.yaml` `servo.yaml` — 默认值,被 site 覆盖;标定参数在 `handeye/calibrate.yaml`
### Flexiv 官方(一般不要改)
| 包 | 作用 |
|----|------|
| `flexiv_hardware` | ros2_control 硬件接口,RDK 发关节 |
| `flexiv_bringup` | 官方 launch |
| `flexiv_msgs` | 官方消息 |
| `flexiv_gripper` | 官方夹爪(本栈 **不用**;腕部爪走 IPC Modbus) |
| `flexiv_description` | URDF / 网格 |
| `flexiv_controllers` `flexiv_moveit_config` `flexiv_test_nodes` | 官方控制器 / MoveIt / 测试 |
| `flexiv_rdk` | RDK 源码树(编译安装到 `~/flexiv_install`) |
| `flexiv_ros2/` | 官方仓库的完整拷贝;`build_real.sh` 选其中的包 |
---
## `models/` — 算法权重模块
权重、标签与转换规则见 **`models/README.md`**(布局 `models/<分组>/<模型名>.{pt,onnx,engine}`
与旁挂 `<模型名>.labels.yaml`、`weights.sh` 用法)。
工件跟踪权重走 `site.yaml` → `paths.yolo_weights`;入孔孔模型走 `hole_detect.weights`。
二进制不进 git(`.labels.yaml` 进),`backend: tensorrt` 时必须有同名 `.engine`。
---
## `docs/`
| 文件 | 内容 |
|------|------|
| `HANDBOOK.md` | **新手手册**(从「这是干什么的」到「我能自己改」;建议第一份读它) |
| `FRAMEWORK_RULES.md` | **框架规则**(硬规矩,改代码前先读;第 8 节是按症状查的反例表) |
| `WORKSPACE.md` | 本页,目录与职责 |
| `QUICKSTART.md` | 环境、编译、第一次实机 |
| `ARCHITECTURE.md` | 进程与数据流 |
| `SITE_CONFIG.md` | `site.yaml` 字段 |
| `HANDEYE.md` | 示教 / merge / 标定 |
| `TRACKING.md` | 视觉伺服、hover、锁高 |
| `GRIPPER.md` | PGEA + RGI |
| `HOLE_DETECT.md` | 入孔检测 |
| `TACTILE.md` | Orisys 视触觉 |
| `INTERFACES.md` | 脚本 / ROS topic / 参数契约 |
| `TRAJECTORIES.md` | 关节轨迹回放 |
| `GAUGE_ASSEMBLY.md` | **通止规装配流程**(状态机、判据、E1 掉件处理、怎么调参、验收命令) |
---
## 别人克隆后
> 不知道从哪读起?先看 **[HANDBOOK.md](HANDBOOK.md)**(这台机器在干什么、
> 改东西改哪里、出问题查哪)。想改代码先看 [FRAMEWORK_RULES.md](FRAMEWORK_RULES.md)。
```bash
cd ~/ros2
cp config/site.example.yaml config/site.yaml # 填硬件
# 权重放到 models/<分组>/(布局见 models/README.md),改 site.yaml paths.yolo_weights
conda activate ros_flexiv
source scripts/env.sh
./scripts/build_all.sh
source scripts/env.sh
```
示教器 Remote Ethernet,关 Studio。三终端同一 `--arm`:
```bash
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
```
91 把 `89` 换成 `91`。91 必须用自己的手眼文件,不要拷 89 的 `T_4x4`。
## 本仓库不包含
- `camera_test` 训练 GUI / `infer_realtime.py`
- `ros_flexiv` 装配 HMI、孔插入运动
- colcon 的 `build/` `install/` `log/`
- 本机 `site.yaml` 与 YOLO 权重文件