真机落地前的仿真补齐:夹持/腕力/真值位姿,让仿真能验证 S07–S09
这批是 09-24 那轮仿真工作的收尾,一直没提交。内容按目的分四块: 1) 仿真真能「夹住」工件 sim_grasp_lock:给规与夹爪之间加接触锁(默认关,run_gauge_assembly --sim 才开)。 没有它时仿真里规只靠摩擦,S08 棘轮一转就滑出指间,于是把「仿真不真」误读成 「力判据不对」。新增 test_sim_grasp_lock.py。 2) 腕部力传感器进仿真 sim_wrist_ft(+ config/wrist_ft.yaml):S07 的首选判据是腕部 FT 的轴向突变, 而仿真里以前根本没有腕部力,S07 只能退到触觉兜底,两套判据从没在同一场景下比过。 现在两条通道都在,接触判定可对照。 3) 真值位姿可查(不再靠猜) sim_live_pose / sim_pose_service:把 Gazebo 里刚体的实测位姿发布出来, stage2 的真值路径按**实测**位姿算孔位,而不是按场景文件里的标称位姿。 顺带把真值孔位的推导(truth_holes)独立出来并补测。 4) 工具几何成为可配置项 config/sim_tool_geometry.yaml + stage2 的 tool_tip_below_flange_m 启动参数: 仿真里规会在指间下滑,工具长每次装夹都不同(实测见过 243/254mm), 悬停高度与 S07 下探预算必须按实测值算,不能再写死。 应用层同时跟进:gauge_fsm / gauge_config 把「悬停时工具尖端入没入工件」的判据 (hover_z_guard)与拖件判定(drag_verdict)收成纯函数并补测;stage3 搜孔、 site 导出、run_gauge_assembly 与若干文档同步。 新增 test_gauge_exit_lift / test_gauge_gripper_client / test_node_handler_collisions。 测试:全仓库 1085 passed。
This commit is contained in:
@@ -99,6 +99,58 @@ gates_px:
|
||||
insert_ring_radius: [6, 30]
|
||||
hole_spacing: [90, 700]
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 世界模型位姿回读 —— 仿真里唯一能发现"物体被撞走/掉下去了"的手段
|
||||
# ---------------------------------------------------------------------------
|
||||
# 为什么需要它(2026-09-24 花了一整轮排查换来的,值得完整读一遍):
|
||||
# `perception.source=truth` 是**纯几何**的:它按下面 objects 里的**名义位姿**
|
||||
# 把孔投到像素上,**从不问 Gazebo 物体现在到底在哪**。
|
||||
# 于是工件一旦被碰走,"真值"就开始撒谎,而且每一处现象都指向别的原因:
|
||||
#
|
||||
# 实测:工件掉进台面通槽、落到地面(z≈0),而 scene.yaml 仍写着 z=0.40。
|
||||
# S05 拿"名义孔位"的像素去查**真实**深度图 → 孔位处看到的是槽底/地面
|
||||
# (0.6m,而工件面其实只有 0.21m)→ 三角化出 k1/k2 间距 169mm
|
||||
# (真值 58mm)→ 被间距门槛丢掉 → 精拍连丢 9 拍 → S05 超时 ABORT。
|
||||
# 现场现象像"检测坏了 / 标定坏了 / 阈值调高了",全都不是。
|
||||
# 真正的信息只有一句:"**工件现在不在 scene.yaml 说的位置**。"
|
||||
#
|
||||
# Gazebo 自己会把每个模型的实际位姿发在 /world/<world>/pose/info
|
||||
# (gz.msgs.Pose_V),桥成 tf2_msgs/TFMessage 之后,漂移监视器
|
||||
# (sim_truth_perception)就能把"名义位姿 vs 实际位姿"直接对比出来并**指名报错**。
|
||||
#
|
||||
# 话题名里的 world 名必须与 worlds/assembly.world 的文件名一致(`assembly`)。
|
||||
pose_info:
|
||||
gz_topic: "/world/assembly/pose/info"
|
||||
ros_topic: "/sim/world_pose_info"
|
||||
# 类型固定这两条:ros_gz_bridge 原生支持 Pose_V ↔ TFMessage(实测确认,
|
||||
# 见 ros_gz_sim_demos 的 tf_bridge.launch.py)。写错类型不会有任何报错,
|
||||
# 只会"桥接器起来了但一个消息都没有" —— 所以别改。
|
||||
ros_type: "tf2_msgs/msg/TFMessage"
|
||||
gz_type: "gz.msgs.Pose_V"
|
||||
# 漂移判据:**两个**阈值,别合成一个(2026-09-24 的教训)。
|
||||
#
|
||||
# drift_tol_m(2mm)= **告警**线:真值几何已经跟着**实测**位姿走
|
||||
# (见 arm_sim_gazebo/sim_live_pose.py),所以 2mm 不再意味着"几何错了",
|
||||
# 只意味着"这个场景跟 scene.yaml 写的不一样了"。而 2~3mm 是**天天都有**的:
|
||||
# spawn 落地就偏 2.6mm,工件骑在通槽上静置十几分钟还会再挪 1.9mm。
|
||||
# 2mm 的来历:真值投影在相机到工件 0.17m 处,fx≈447 ⇒ 1mm 位姿误差 ≈ 2.6px,
|
||||
# 而 S05 的稳定判据是 2px —— 2mm 是"开始影响二阶段"的量级。
|
||||
# yaw 取 2°:两孔间距 58mm,绕中心转 2° 会让孔横移 1mm(约 2.6px),同量级。
|
||||
drift_tol_m: 0.002
|
||||
drift_tol_deg: 2.0
|
||||
# drift_stop_m 才是**停发**线:到这个量级说明工件掉了/被搬走了,场景前提没了
|
||||
# (再发点等于指挥机械臂去装一个不存在的工件)。20mm 的来历:工件一半宽 70mm、
|
||||
# 掉下台面是 400mm 量级,而"顺手碰一下"是几毫米 —— 20mm 两边都分得开。
|
||||
drift_stop_m: 0.02
|
||||
# 启动复位:开局把被盯的物体 set_pose 回名义位姿(仿真专有,默认关,这里开)。
|
||||
# 为什么还要它:上面两条线是"容差",这一条是**消除源头** ——
|
||||
# 物体是"在名义位姿上方 spawn、再落下来"的,落地那 2.6mm 偏差纯属 spawn
|
||||
# 的落点问题(实测 set_pose 回名义位姿后它就停在那儿不动)。
|
||||
# 只在开局 20s 窗口内、且只做一次 —— 运行中的漂移必须报错,不能悄悄搬回去
|
||||
# (那会抹掉"谁把它撞歪了"的现场,还可能把工件从爪里拽走)。
|
||||
# 实现见 sim_truth_perception._maybe_startup_reset(含完整理由)。
|
||||
reset_on_start: true
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 场景物体
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user