P5c-5 触觉链路打通:接触传感器此前是"完全静默失效",已定位并修复
两条独立的静默坑,都不报错、不告警,只会"永远收不到数据":
1) world 里没声明 contact-system 系统插件。
gz-sim 的 <sensor type="contact"> 不由 ignition-sensors 库实现,而是由
ignition-gazebo6-contact-system 插件实现 —— 所以环境里根本没有
libignition-sensors6-contact.so(相机/IMU/lidar 的后端都在,唯独缺它),
那不是包缺失。不声明插件的症状:话题不出现、日志空白。
实测:加上插件后 /tactile/left/raw、/tactile/right/raw 立刻出现。
2) 接触传感器的三个必备写法,错一个就静默失效:
- <contact><collision> 必须写 URDF→SDF 自动生成的 collision 名;
留空 <contact/> 会被补成 SDF 规范的默认值 __default__(不存在的
collision)。实测生成名:
sim_left_finger_mount_fixed_joint_lump__sim_left_finger_tip_collision
- 话题必须写在 <contact><topic> 里,写在外层 <sensor><topic> 无效,
gz 会静默改用默认 scoped 话题名。
- 传感器必须挂在有碰撞体的 link 上(指尖),不是另建的空 link。
两处均已按实测结果修正,并把"为什么这么写"写进文件注释。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -131,55 +131,70 @@
|
||||
=======================================================================
|
||||
真机上是视触觉:一块弹性体 + 内置相机,读出三向力、深度图、力矢量图。
|
||||
仿真里没法真的模拟弹性体形变成像,采取的务实方案是:
|
||||
用 Gazebo 内置的 contact sensor 取接触点的三向力,
|
||||
再由自定义插件(devices/sim/gazebo/sensor_plugins/)把它
|
||||
按 Orisys 的 TactileStatus 消息格式发布出去,
|
||||
含切向/法向分解,使 P6 的力判据在仿真里可跑。
|
||||
用 Gazebo 内置的 contact sensor 取接触处的真实接触力,
|
||||
再由 sim_tactile_adapter 把力投影到指尖坐标系,
|
||||
按 Orisys 的 TactileStatus 消息格式发布出去。
|
||||
|
||||
这里只挂 contact sensor 与自定义插件的位置占位;
|
||||
插件的实现与消息映射在 P5c-5 完成。
|
||||
⚠️ 这里**不再**新建空的 tactile link。
|
||||
曾经的做法是建两个空的 sim_tactile_*_link(既无 visual 也无
|
||||
collision),挂在 **法兰** 的 tcp 上(不是指尖),而 <contact> 里
|
||||
又引用了一个 <collision>sim_tactile_left_link_collision</collision>
|
||||
—— 那个 collision 元素根本不存在。三重错叠在一起,
|
||||
结果是传感器**永远收不到任何数据**,而 Gazebo 不会为此报任何错:
|
||||
话题在、没有输出、看起来像"还没接触"。极难查。
|
||||
这也正是把传感器挂到真实碰撞体所在的 link(指尖)上的理由 ——
|
||||
"接触到的就是读到的",中间不再有需要对齐的第二套几何。
|
||||
|
||||
为什么要挂两个(left/right):
|
||||
真机是双指各贴一片,tangential_1/2 + normal 三路力分别来自两片,
|
||||
单指的数据无法复现"旋拧时切向力从哪一侧来"这个判据。
|
||||
|
||||
⚠️ 单位不是牛顿!真机读数是**形变任意单位**、基线会漂移,
|
||||
所有阈值都按"相对静止均值的增量"使用(见
|
||||
devices/sensors/orisys/manifest.yaml)。仿真给的是牛顿,
|
||||
所以两者的数值**不能直接共用阈值** —— 标度换算由
|
||||
config/tactile.yaml 的 force_scale 负责,详见该文件与 README。
|
||||
======================================================================= -->
|
||||
<xacro:if value="${tactile_enable}">
|
||||
<link name="${prefix}tactile_left_link"/>
|
||||
<link name="${prefix}tactile_right_link"/>
|
||||
|
||||
<joint name="${prefix}tactile_left_joint" type="fixed">
|
||||
<parent link="${prefix}tcp"/>
|
||||
<child link="${prefix}tactile_left_link"/>
|
||||
<origin xyz="0 0.035 0.005" rpy="0 0 0"/>
|
||||
</joint>
|
||||
<joint name="${prefix}tactile_right_joint" type="fixed">
|
||||
<parent link="${prefix}tcp"/>
|
||||
<child link="${prefix}tactile_right_link"/>
|
||||
<origin xyz="0 -0.035 0.005" rpy="0 0 0"/>
|
||||
</joint>
|
||||
|
||||
<gazebo reference="${prefix}tactile_left_link">
|
||||
<gazebo reference="${prefix}left_finger_tip">
|
||||
<sensor name="tactile_left" type="contact">
|
||||
<always_on>true</always_on>
|
||||
<update_rate>100</update_rate>
|
||||
<!-- 话题名与真机 tactile_node 发布的完全一致:
|
||||
/tactile/left/status (arm_msgs/TactileStatus)
|
||||
这样 P6 的状态机在仿真/真机之间不用改一行判断。 -->
|
||||
<contact>
|
||||
<collision>${prefix}tactile_left_link_collision</collision>
|
||||
<!-- ⚠️ 这个名字不是我们起的,是 sdformat 从 URDF 转 SDF 时**自动生成**的:
|
||||
规则 =「fixed 关节链的父 link」+ "_fixed_joint_lump__" +「本 link」
|
||||
+ "_" + collision 名。本机实测生成名(2026-09-23,Fortress 6.16):
|
||||
sim_left_finger_mount_fixed_joint_lump__sim_left_finger_tip_collision
|
||||
|
||||
为什么不得不写死一个"自动生成的名字"(很脆,但有理由):
|
||||
a) URDF 的 <collision> 不能命名,所以没法给它一个稳定名字;
|
||||
b) 留空 <contact/> 不会"监测全部",而是被补成 SDF 规范的默认值
|
||||
`collision=__default__` —— 一个不存在的 collision。
|
||||
症状是传感器**永远没有输出**,gz 不报错、话题也不出现。
|
||||
已实测确认(这是本节最大的一条坑)。
|
||||
所以只能写死,并用启动检查兜住改名:
|
||||
robot_description.check_tactile_collisions() 会把展开后的
|
||||
URDF 转成 SDF,核对这两个名字是否存在 —— 一旦 sdformat 改了命名
|
||||
规则,启动时就会明确报错,而不是静默失效。 -->
|
||||
<collision>${prefix}left_finger_mount_fixed_joint_lump__${prefix}left_finger_tip_collision</collision>
|
||||
<!-- ⚠️ 话题必须写在**这里**(contact/topic),不能写在外层的
|
||||
<sensor><topic> 里 —— 接触传感器只认 contact/topic。
|
||||
写错位置不会报错:gz 会静默改用默认的 scoped 话题名
|
||||
/world/<world>/model/<model>/link/<link>/sensor/<sensor>/contact
|
||||
于是"按 /tactile/left/raw 去订阅"永远收不到东西。实测确认。 -->
|
||||
<topic>/tactile/left/raw</topic>
|
||||
</contact>
|
||||
<topic>/tactile/left/raw</topic>
|
||||
</sensor>
|
||||
</gazebo>
|
||||
|
||||
<gazebo reference="${prefix}tactile_right_link">
|
||||
<gazebo reference="${prefix}right_finger_tip">
|
||||
<sensor name="tactile_right" type="contact">
|
||||
<always_on>true</always_on>
|
||||
<update_rate>100</update_rate>
|
||||
<contact>
|
||||
<collision>${prefix}tactile_right_link_collision</collision>
|
||||
<collision>${prefix}right_finger_mount_fixed_joint_lump__${prefix}right_finger_tip_collision</collision>
|
||||
<topic>/tactile/right/raw</topic>
|
||||
</contact>
|
||||
<topic>/tactile/right/raw</topic>
|
||||
</sensor>
|
||||
</gazebo>
|
||||
</xacro:if>
|
||||
|
||||
Reference in New Issue
Block a user