Files
ros_contorl/.cursor/rules/sim-gazebo.mdc
T
arm_dev d78e66ce98 P5a 框架规则文档:M1-M3 元规则 + R1-R6 分领域规矩 + 反例清单
背景:这个框架踩过的坑几乎都是同一类——"没报错但结果是错的"。
之前这些教训只存在于聊天记录和零散注释里,改一次代码就要重踩一遍。
现在收敛成一份可引用的文档,并压缩成 .cursor/rules/ 常驻规则。

docs/FRAMEWORK_RULES.md(414 行)
  第 0 节  三条元规则:M1 静默失效是头号敌人 / M2 单一数据源 / M3 口径必须显式
  第 1 节  配置与数据 R1.1-R1.5(分层优先级、site.yaml 新键必须接线或告警、设备走 devices/、权重走 models/)
  第 2 节  几何/单位/坐标系 R2.1-R2.7(米与弧度、frame_id 必须是光学系、深度 mm↔m、
           rpy=Rz·Ry·Rx、Gazebo camera_info 不可信、像素门槛绑图幅、位姿容差要写理由)
  第 3 节  触觉与力 R3.1-R3.6(力是相对基线的增量、fnormal 压为正、轴向映射必须实测、
           接触布尔要用超时、force_scale 口径、仿真图像只能占位)
  第 4 节  仿真 R4.1-R4.10(唯一 site.yaml、world 里写 plugin 会挤掉默认系统、搜索路径要在
           launch 前设好、上游 description 不许改、场景走 scene.yaml、校验要逐碰撞体、
           不用"有话题就算通"验收、停仿真用 stop_sim_gz.sh)
  第 5 节  代码与测试 R5.1-R5.7(纯逻辑抽纯函数、校验要有测试证明有效、不许把降级写成通过、
           解析外部输出先确认真实格式、删除前扫全仓库引用、别在中文路径 colcon build、真机仿真产物隔离)
  第 6 节  文档与提交 R6.1-R6.4(文档与实现不一致立刻修文档、每份文档说明记录什么事实、
           结论数字要可复现、提交信息讲为什么并附实测数据)
  第 7 节  改动前检查清单
  第 8 节  历史反例清单——按"你看到的症状"查表,不是按道理排序
  第 9 节  给 AI 的具体指令

.cursor/rules/*.mdc  三份压缩版(常驻)
  framework-core.mdc       alwaysApply,元规则 + 检查清单 + 禁止项
  sim-gazebo.mdc           globs=devices/sim/**,src/arm_sim_gazebo/**
  config-and-devices.mdc   globs=config/**,devices/**,models/**,src/arm_interfaces/**

顺手修掉文档与实现不一致(R6.1)
  docs/WORKSPACE.md  此前【完全没有 devices/ 这一层】——通用化落点却没进目录总表。
                     补 devices/ 一节(kind/brand 目录约定、registry.yaml 与 manifest.yaml 分工、
                     assets[].required 缺失会报错),补 build_sim/install_sim/log_sim 与 .cursor/rules/,
                     并把 FRAMEWORK_RULES.md 标为 docs/ 首行
  README.md          文档表首行加 FRAMEWORK_RULES.md

顺手删死代码(R5.5:先扫引用)
  src/arm_interfaces/arm_interfaces/paths.py  删 assets_root()
    它返回 ros2_root()/"assets",而仓库里从来没有 assets/ 这个目录——实际权重树是 models/,
    且 models/ 的定位已由 arm_application.weights_layout.default_weights_root() 负责
    (带 SITE_WEIGHTS_ROOT 覆盖,且能从 install/ 反查仓库根)。
    两个实现并存违反 M2,且这个还指向不存在的路径,属于"照着名字用就踩空"。
  src/arm_interfaces/test/test_real_devices.py  从清环境变量列表里去掉 SITE_ASSETS_ROOT

验收
  src/arm_application 233 passed / arm_driver_flexiv 69 / arm_interfaces 46 /
  arm_kinematics 24 / arm_sim_gazebo 236 = 608 passed
  (flexiv_rdk 的 test 需装厂商 flexivrdk 包,仿真环境无此依赖,与本改动无关)

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-23 17:16:47 +08:00

32 lines
2.3 KiB
Plaintext
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.
---
description: Gazebo 仿真的改动规则(静默失效高发区:路径/内参/接触力/描述归一化)
globs: devices/sim/**,src/arm_sim_gazebo/**
---
# 仿真改动规则
权威全文:`docs/FRAMEWORK_RULES.md` 第 4 节;平台手册:`devices/sim/gazebo/README.md`。
R4.1–R4.10 全部适用,以下是**最容易踩的几条**:
- **world 里声明任何一个 `<plugin>` 都会挤掉默认系统**(Physics / UserCommands /
SceneBroadcaster)。少了 UserCommands,模型根本没进 Gazebo,而 `create` **仍然打印**
`OK creation of entity`。要加插件时必须把这几个系统一起显式声明。
- **插件/资源搜索路径必须在 `ros2 launch` 之前设好**(conda 激活不会加
`$CONDA_PREFIX/lib`)。不要绕过 `scripts/sim_env.sh` 直接 launch。
- **不许改上游描述文件**(`flexiv_description` 等):`<mimic>` 会被 `sdformat` 丢弃、
零质量 link 会出 NaN 惯性、无质量根 link 会连子树被丢。一律走启动时归一化。
- **gz 发的 `camera_info` 是错的**(恒为 60° 视场的默认值),内参必须按
`cameras.yaml` 的 `horizontal_fov` 与图幅重算并覆盖。
- **深度单位**:gz 是 `32FC1` 米,真机是 `16UC1` 毫米。换算只做一次(适配器)。
- **相机 `frame_id` 必须是光学系**;`rpy` 的复合顺序是 `Rz·Ry·Rx`。
- **触觉**:轴向映射必须实测(不许从 URDF 推导);接触布尔必须用超时判据
(接触消息是事件式的,没有"离开"事件);`force_scale` 决定仿真与真机能否共用阈值。
- **验收不用"有图像 / TF 查得到"**:跑 `scripts/check_sim_cameras.py` 与
`scripts/check_sim_scene.py`(判据是物理量:反投影命中平面、像素门槛、位姿一致)。
- **停仿真用 `scripts/stop_sim_gz.sh`**,不要 `pkill -f`(会先杀掉调用它的 shell)。
给栈里加了新进程时,记得加进该脚本的模式表 —— 它末尾会复查残留,漏项会报出来。
- **模型约定**:原点在**底面中心**、单位米、目录名 = `<model name>` =
`model.config` 的 `<name>` = 推理类别名;碰撞体用简单几何,`visual` 可以加
只服务于检测的细节(如工件上的亮环),但 `visual` **名字有意义**,改名字要同步改
`sim_scene.features_from_workpiece`。