Files
ros_contorl/devices
arm_dev b29339e522 仿真感知:真值孔位 + 真值相机 + 补 /home,让流程不改代码就能跑仿真
三块补齐,目标是"同一个流程节点,仿真/真机都不改代码":

1. 真值孔位(truth_holes.py):把 scene.yaml 与模型 SDF 里已知的孔几何
   直接投影到相机像素坐标,替代 HoughCircles。perception.source 选:
     yolo / truth / external —— truth 就走这条路。
   为什么不用 Hough:仿真里孔是"方孔 + 贴片亮环"的近似(SDF 没有布尔运算),
   靠图像门槛去凑 radus 区间很脆;而孔位本来就是场景里已知量,直接投影
   既准又稳,还能当真实检测算法的对照基线。

2. 真值相机(sim_truth_perception.py):同理,直接算物体位姿,供
   visual_servo/filtered_point 用,绕开 ONNX。

3. 补 /home 与 set_named_pose 服务(sim_home_service.py):真机上这两个
   由 Flexiv 驱动提供,仿真里没有 —— 缺了 S01 直接超时。

4. sim_tactile_adapter 容错导入 ros_gz_interfaces:那一路只是"接触点",
   力本身走 geometry_msgs/Wrench。typesupport 加载不了时退化成
   contact 恒 False + centroid 恒 0,三力判据(S07 用的)不受影响 ——
   宁可用退化模式跑,也不要整个适配器起不来。

5. repo_root 解析(已装包要能找回源码仓库根,见 test_repo_root.py 的用例)
   与 use_sim_time 向子 launch 的传递。

另:scripts/gen_sim_handeye.py 把 URDF 真值导出手眼文件(仿真不标定)。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-24 14:43:13 +08:00
..

devices/ —— 设备与外部文件总目录

这个目录存在的唯一目的:把「换个硬件」从改代码变成改配置。

设计原则(务必先读)

1. 选型与数值分离

关注点 放在哪 谁改
用哪个品牌的哪个驱动 devices/registry.yaml 集成工程师(很少改)
设备号 / 速度 / 阈值 / 悬高 config/site.yaml 现场操作人员(经常改)

devices/ 下不允许出现任何现场数值。 数值只有 config/site.yaml 一个来源。 这样可以避免现在这种「同一个值三处定义、改了不生效」的问题。

2. 目录约定

devices/
├── registry.yaml        # 选型开关(唯一入口)
├── robots/              # 机械臂:RDK + 适配器
├── grippers/            # 夹爪
├── sensors/
│   └── orisys/          # ★ 视触觉核心,长期迭代,单独占一个大文件夹
├── cameras/             # 相机
└── sim/                 # 仿真平台(当前 Gazebo)

每个品牌一个子目录,子目录内固定结构:

<类别>/<品牌>/
├── manifest.yaml        # 我是谁 / 支持什么能力 / 需要哪些配置 / 外部文件放哪
├── driver/              # 适配器(把厂商 API 翻译成框架接口)
└── <厂商物料>/          # 如 rdk/、sdk/,原样放置,不要改名

3. 一个新品牌要接进来,只需要四步

  1. 丢物料:把厂商的 RDK / SDK / 驱动包放进 <类别>/<品牌>/ 下对应文件夹 (格式和命名要求写在该类别的 README.md 里,必须按它要求放)。
  2. 填 manifest:复制同类别的 manifest.yaml 改四个字段(id / label / driver.package / config_schema)。
  3. 写适配器:在 driver/ 下实现框架的接口契约(见 src/arm_interfaces/)。 这一步的工作量取决于厂商 —— 如果厂商本来就提供符合契约的 ROS 2 驱动,这一步几乎为零。
  4. 改一行选型:把 registry.yaml 里对应类别的值改成新品牌 id。

诚实说明:第 3 步无法完全避免。Flexiv 的 RDK 是 C++/Python 库而不是 ROS 2 驱动, 所以它外面永远需要一层薄适配器。框架能做的是把这层适配器写到最薄(只做 API 翻译, 不含任何业务逻辑),而不是让你零代码接入。

4. 启动时的校验

框架启动会依次读 registry.yaml → 各 manifest.yaml → config/site.yaml, 校验三件事:

  • 选中的品牌目录存在,且 manifest.yaml 可解析;
  • manifest 里 assets 声明的必需物料文件都在;
  • config_schema 里标记 required: true 的配置键,在 site.yaml 里都有值。

任何一项不满足立即报错并明确指出该去哪个文件补什么,不允许静默降级。 这是替代现在「run_handeye.sh 传了 5 个节点没声明的参数、调参静默失效」那类问题的机制。