Files
ros_contorl/docs/WORKSPACE.md
T
arm_dev fac2d5384d 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>
2026-09-24 09:05:09 +08:00

228 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 左右指视触觉 |
| `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` | 关节轨迹回放 |
---
## 别人克隆后
> 不知道从哪读起?先看 **[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 权重文件