背景:这个框架踩过的坑几乎都是同一类——"没报错但结果是错的"。
之前这些教训只存在于聊天记录和零散注释里,改一次代码就要重踩一遍。
现在收敛成一份可引用的文档,并压缩成 .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>
10 KiB
工作空间地图
本仓库 ~/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 |
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第 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.yamlservo.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/
| 文件 | 内容 |
|---|---|
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 |
关节轨迹回放 |
别人克隆后
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 ~/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.pyros_flexiv装配 HMI、孔插入运动- colcon 的
build/install/log/ - 本机
site.yaml与 YOLO 权重文件