47ad9d9a8b
相机链路(devices/sim/gazebo/config/cameras.yaml 是唯一真相)
- sim_cameras.py 纯逻辑:话题映射 / 深度换算 / 内参 / 视场一致性比对
- sim_camera_adapter.py 改光学系 frame_id、32FC1 米 → 16UC1 毫米、覆盖内参
- gazebo_sim.launch.py 桥接 + 适配器 + 世界相机的静态 TF(位姿从 world 解析)
本轮修掉两个**静默**的几何错误(都能出图、都能查到 TF,但点位是错的)
1. gz 发的 camera_info 是错的:恒为 fx=fy=277, cx=160, cy=120
(等于它的默认 60° 视场 + 半分辨率主点),而渲染用的是配置的 87° 视场。
照抄它做三维反投影,点会偏半米量级;单目预览完全正常。
用已知地面平面做最小二乘反解,得 fy=337.2 / cy=239.5,与
640/(2·tan(87°/2))=337.2、480/2=240 吻合(残差中位 0.2mm)。
改为由 sim_cameras.intrinsics() 按 cameras.yaml 的视场重算并覆盖。
代价:cameras.yaml 的 horizontal_fov 必须与 SDF 一致,启动时自动比对告警。
2. assembly.world 里 D435 的 rpy 写成 (0, 50°, 180°),
而 URDF 相机的视线是**本体 X 轴**、rpy 复合顺序又是 Rz·Ry·Rx,
于是"先俯 50° 再偏航 180°"把视线翻到了背面:相机背对台面、只看地面。
它不报错,而且几何自洽(点确实落在真实地面上),只查数值发现不了。
改为 (0, 50°, 0),并加回归测试锁住。
新增验收工具 + 测试
- scripts/check_sim_cameras.py 反投影深度、要求命中地面/台面才算通过。
"有图像"不是验收标准;实测 d435 台面 11.9%/地面 75.3%、d405 台面 37.8%。
- 97 项单测(新增 sim_cameras 22 项、sim_site 16 项)
顺带修掉一处"改了配置静默无效"
- sim.world 此前硬编码在 robot_description._WORLD_REL,而 site.yaml 与
manifest.yaml 都宣称改它就生效。现在真的读了:
优先级 --world > site.yaml:sim.world > 内置默认(相对路径按仓库根解析)。
- physics_enable / joint_prefix 仍未接线,但若其值与实际状态冲突,
启动时会告警(sim_site.unwired_warnings),不再静默忽略。
文档
- devices/sim/gazebo/README.md 重写:原文还写着"仿真不是 Gazebo"、
相机插件用 libgazebo_ros_camera.so,与实现早已不符。现分三部分:
哪个"仿真"是真的 / 现状与缺什么 / 五条静默失效的坑及怎么验。
Co-authored-by: Cursor <cursoragent@cursor.com>
47 lines
3.0 KiB
Markdown
47 lines
3.0 KiB
Markdown
# scripts — 唯一操作入口
|
||
|
||
实现细节在 [docs/WORKSPACE.md](../docs/WORKSPACE.md) 和 [docs/](../docs/)。
|
||
|
||
**每天:** `run_real.sh` · `run_camera_d405.sh` · `run_visual_servo_rt.sh` · `go_home.sh`
|
||
**三阶段串联:** `run_all.sh --arm 89 [--hole k2] [--skip-stage1]`(`run_pipeline.sh` 是它的旧名别名)
|
||
**手眼:** `run_handeye.sh`(`teach` / `merge` / `calibrate` / `show`)
|
||
**夹爪:** `run_gripper.sh --arm 89|91` · `run_dual_gripper.sh`
|
||
**入孔:** `run_hole_detect.sh --arm … [--preview]`
|
||
**触觉:** `run_tactile.sh [--cli]`
|
||
**权重:** `weights.sh`(`list` / `labels` / `convert` / `doctor` / `show`)
|
||
- 转换:`weights.sh convert <文件> --name <模型名>` —— PT→ONNX→TensorRT,自动改名归位 + 固化标签
|
||
- 标签:`weights.sh labels <模型名>` 看,`--set "工件,通止规"` 改
|
||
- 体检:`weights.sh doctor --check-engines`(能查出 engine 与 TensorRT 版本不匹配这类静默失效)
|
||
- 规则写在 [models/README.md](../models/README.md)。`export_yolo_trt.sh` 现在是它的兼容转发壳。
|
||
**配置:** `show_site_config.sh` · `lib/export_site_env.py`
|
||
**仿真:** `run_sim_gz.sh`(Gazebo 物理仿真,唯一能做接触/力控验证的入口)
|
||
- 环境是独立 conda 环境 `ros_gz_sim`(`install_sim_env.sh` 装、`sim_env.sh` 激活),与真机环境隔离
|
||
- 相机验收:`python3 scripts/check_sim_cameras.py` —— **别用 `ros2 topic hz` 或肉眼看图验收相机**,
|
||
仿真相机的错误几乎全是静默的(深度单位、frame_id、内参、位姿方向),都能出图却是错的。
|
||
这条命令把深度反投影到 world,要求命中已知平面(地面/台面)才算通过。
|
||
- 注意 `run_sim.sh` 不是 Gazebo,它走 mock 驱动(假数据 + RViz),永远不会产生接触力
|
||
**环境:** `env.sh` · `build_all.sh`
|
||
**RDK:** `test_rdk_python.sh` · `rdk_switch_tool.sh` · `rdk_drag_bridge.py`
|
||
**搁置未用:** `fetch_isaac_flexiv.sh`(拉 Flexiv 的 Isaac Sim / RDK 源码到 `thirdparty/`;Isaac 路线目前搁置,Gazebo 是选定平台)
|
||
|
||
`lib/parse_arm_args.sh` 解析 `--arm 89|91`。
|
||
`lib/load_site_config.sh` 把 `config/site.yaml` 变成 `SITE_*`。
|
||
|
||
## 排查脚本卡住时的常识
|
||
|
||
几个脚本开头会等外部条件(控制器 ACTIVE、相机出图、触觉就绪)。**正确的判活顺序是
|
||
先 `ros2 service list` / `ros2 topic list` 看目标在不在,再去 call / echo**:
|
||
|
||
```bash
|
||
# 对:服务不存在时立刻返回
|
||
timeout 3 ros2 service list | grep -q '^/controller_manager/list_controllers$' || exit 1
|
||
timeout 3 ros2 service call /controller_manager/list_controllers ...
|
||
|
||
# 错:服务不存在时每次 call 都要耗满超时才返回,
|
||
# 30 次循环 = 白等两三分钟(实测 63s),看起来就像脚本卡死了
|
||
for _i in $(seq 1 30); do timeout 5 ros2 service call ... ; done
|
||
```
|
||
|
||
`run_all.sh` / `run_stage2_locate.sh` / `run_stage3_search.sh` 已按正确顺序改过;
|
||
`run_handeye.sh` 一开始就是对的。
|