d32e6ae53f
一、场景物料(新增)
devices/sim/gazebo/models/workpiece/ 带三个孔的铝板。碰撞体是"带方孔的平板",
视觉额外加两个 φ14/φ7 亮环 —— 因为真机的 HoughCircles 就是靠这两个亮环找孔,
只按碰撞体建视觉会让"孔检测"在仿真里永远失败,而那看起来像算法问题。
devices/sim/gazebo/models/gauge/ 通止规:通端/套环/握柄/止端四段,各段异色
便于肉眼判断方向。接触刚度刻意比台面软 —— 位置控制器会"刚性压进去",
用默认刚度会被弹飞(注释里写了原因,不是随手抄的参数)。
devices/sim/gazebo/models/gauge_stand/ 规座(static)。规直接站在台面上会立刻倒,
加个方孔底座把它立住。
三个模型都是 model.sdf + model.config,原点在**底面中心**,单位米。
二、场景配置与校验(新增)
config/scene.yaml 物体不再写死在 world 里,改为 scene.yaml + 启动时动态 spawn。
理由:world 是"环境"(地面/台面/相机/系统插件),场景是"这一批活做什么"。
动 world 的风险面太大 —— 它只要丢一个系统声明,所有模型都 spawn 不进去(见旧坑 2)。
含 operating(相机到工件的距离等作业条件)与 gates_px(像素门槛)。
sim_scene.py 摆放校验:从 SDF **逐碰撞体**解析 AABB(不抄尺寸,避免漂移),
检查原点在底面 / 不穿台面 / 不出界 / 物体之间不嵌入。
重叠判定必须逐碰撞体三维判,不能拿总包围盒相交 ——
正常装配里本来就有嵌套(规立在规座方孔里),粗判会误报,
而误报的后果是人把检查整个关掉,之后真重叠也抓不到。
另有成像几何:把亮环/孔间距按相机距离换算成像素,与门槛比对。
scripts/check_sim_scene.py 验收工具(退出码可用):摆放 + 门槛漂移 + 成像几何 +
悬停高度 vs 工作空间 + 手外相机是否**完整**看得见工件 + Gazebo 实际位姿。
三、修掉两处静默失效(都是"看起来一切正常")
1) parse_spawned_poses 一直是**死代码**:它按 "x: N / y: N / z: N" 解析,
而 Fortress 实际输出是方括号两行(XYZ / RPY)。对不上 → 永远返回空 →
调用方按设计"降级成跳过位姿核对" → 位姿检查**从来没跑过**,
而日志只说"跳过",看起来像正常降级。
现在两种格式都支持,并用真实抓下来的输出样本做回归测试。
教训:宽容降级会把"没检查"伪装成"检查通过"。
2) stop_sim_gz.sh 的模式表里漏了 robot_state_publisher(而注释里写着它有覆盖):
脚本报"已停止",它却还在发上一份 /robot_description 与 TF,
下一次启动就会"改了描述却不生效"。
顺带修掉同源的两个问题:awk 用 -v 传模式导致它匹配到自己、每次复查都多报
一个空命令行的幽灵 PID;以及"杀的时候"和"复查的时候"两份扫描实现会各自漂移。
现在共用同一个 scan_pids(),模式改用环境变量传递,并在杀完之后**再扫一遍**:
有残留就报出来并非零退出 —— 下次再有漏项,不再静默。
实测:--list 列出全套 9 个进程;停止后 rc=0 且 pgrep 干净。
四、相机:D405 分辨率对齐真机
仿真的 D405 此前渲染 640x480,而真机跑 848x480(fx 337 而非 447)。后果是
58mm 的两孔间距成像只剩 85px,低于 hole_distance_min=90 ——
孔检测在仿真里根本不可能通过,而现象看起来像"算法不行"。
已把 xacro 与 cameras.yaml 一起改成 848x480,并把启动时的比对从"只比视场"
扩成"视场 + 图幅"(sim_cameras.check_camera_consistency),
不一致时说明它对像素门槛的影响。
五、文档
devices/sim/gazebo/README.md 重写为中文手册:使用方法 / 建模要求 / 导入格式 /
配置方式(含"改哪里才真的生效"的接线表)/ 11 条实测坑(每条都有"怎么发现")。
manifest.yaml 的进度、assets、description、坑清单与本轮状态对齐。
scripts/README.md 补两个验收工具与停止脚本;根 README 补仿真入口与手册链接。
cameras.yaml 里一处过期的函数名(check_fov_consistency)修正。
六、测试
新增 test_sim_scene.py(79 条,此前 sim_scene.py 完全没有单测 —— 这正是
位姿解析死掉却无人发现的原因)与 test_check_sim_scene.py(21 条),
含三条回归:world_boxes 的偏移碰撞体不能被对称化放大(假重叠)、
center_bore 不能被 _bore 后缀吃掉、Fortress 位姿输出格式。
全量:src/arm_sim_gazebo + arm_interfaces + arm_application 共 515 通过。
同时附上 config/site.example.yaml 的重新生成(此前 site.yaml 的注释改动没同步,
它的 parity 测试是红的)。
Co-authored-by: Cursor <cursoragent@cursor.com>
99 lines
4.6 KiB
Markdown
99 lines
4.6 KiB
Markdown
# 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/show_site_config.sh` |
|
||
|
||
89 与 91 **各有** 手眼、相机序列号、锁高、named poses,禁止混用。
|
||
|
||
## 文档
|
||
|
||
| 文档 | 内容 |
|
||
|------|------|
|
||
| [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 的说明和仓库实际状态不一致。)
|