真机落地前的仿真补齐:夹持/腕力/真值位姿,让仿真能验证 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:
arm_dev
2026-09-28 10:17:06 +08:00
parent 1b4d6168d9
commit c1cd862eea
41 changed files with 5327 additions and 115 deletions
+50
View File
@@ -0,0 +1,50 @@
# =============================================================================
# devices/sim/gazebo/config/wrist_ft.yaml
#
# 仿真腕部力扭矩传感器(wrist force/torque)的话题与口径。
# sim_wrist_ft.py、gazebo_sim.launch.py 从这里读;改这里不用重编译。
#
# 真机的对应物:Flexiv 的 flexiv_robot_states_broadcaster 自动发
# /<sn>/ft_sensor_wrench geometry_msgs/msg/WrenchStamped(法兰系)
# 不需要任何配置 —— 它在真机 bringup 里无条件启动。
#
# -----------------------------------------------------------------------------
# 为什么仿真与真机能共用一套判据(这与触觉**相反**)
# -----------------------------------------------------------------------------
# 手指触觉(tactile.yaml)两边单位不同,所以阈值必须各配一套;腕部 FT 不同:
#
# 真机 ft_sensor_wrench 单位就是牛顿,坐标系是法兰系。
# 仿真 force_torque 传感器单位也是牛顿,挂 joint7 取 child(link7) 系,
# 而 link7 的 z 轴 = 工具轴(工具竖直朝下时即竖直方向)。
#
# 于是两边的"z 分量"都是**轴向力,单位牛顿** —— 公式一致,只有具体阈值
# 可以按现场标定分开配(见 site.yaml 的 gauge_assembly.contact_axial_delta)。
#
# ⚠️ 与触觉一样,这也是一处"选错不报错"的口径:口径错了只会表现为
# "判据不触发"或"一碰就炸",看起来像算法问题。
# -----------------------------------------------------------------------------
# gz 侧话题名。**必须与应用层按 sn 推出来的名字一致**:
# 应用层算 f"/{sn}/ft_sensor_wrench",仿真臂 sn = "sim"
# ⇒ /sim/ft_sensor_wrench
# 改 sn(config/site.yaml 的 robot.arms[sim])时必须同步改这里。
# 也同时写死在 arm.sim.sensors.xacro 的 wrist_ft_topic 默认值里 —— 两处
# 必须一致,check_sim_wrist_ft.py 会核对 xacro 展开结果里有没有这个话题。
topic: "/sim/ft_sensor_wrench"
# 挂载关节。改这里必须同步改 arm.sim.sensors.xacro 里的 <gazebo reference>。
# 为什么是 joint7 见 xacro 里那段注释(不能挂 fixed 关节:物理引擎不把它当
# 独立关节求解,传感器永远没输出且不报错)。
joint: "sim_joint7"
# 期望消息类型(ROS 侧)。gz.msgs.Wrench → WrenchStamped 由 ros_gz_bridge
# 直接支持(实测确认,无需中间适配器节点)。
#
# 为什么是 WrenchStamped 而不是 Wrench:真机发的就是 WrenchStamped。
# 类型一致,应用层才能不加分支地两边通用。
ros_type: "geometry_msgs/msg/WrenchStamped"
gz_type: "gz.msgs.Wrench"
# 传感器输出率 [Hz]。与真机 broadcaster 对齐(100Hz)。
# 下游按"数据够不够新"判活,率太低会被误判成掉线。
publish_hz: 100.0