P5c-5 触觉三向力落地:改用力指关节 force_torque 传感器(接触消息根本没有力)
此前方案是"从接触传感器拿力",实测证明**行不通**: gz.msgs.Contacts 虽然 schema 里有 wrench/force 字段,但 Fortress 的 Contact 系统从不填充它们 —— 一条接触消息全文只有 header + 碰撞体名 + 接触点坐标,连 normal/depth 都是空的;该系统的二进制里连一个 "wrench" 字符串都搜不到。所以那不是配置问题,是设计上只有位置。 改为: - 三向力 ← <sensor type="force_torque"> 挂在**指尖关节**上 (转动关节物理上要承受三向约束力,读到的即整条手指链的力) - 是否接触 ← 保留接触传感器(几何接触,比力阈值准) - URDF 无"关节传感器"语法,用 sdformat 扩展 <gazebo reference="关节名"> 表达;已验证转换后传感器确实落在 <joint> 内 踩坑(与 contact-system 同一个坑的第二次): world 里声明了任何 <plugin> 后 gz 不再加载默认系统列表,所以 forcetorque-system 必须显式声明,否则 /tactile/*/wrench 话题**不出现**、 日志一片空白。补上后立即出现。 已实测确认: - wrench 话题 ~100Hz **持续发布**(无接触也发零)—— 这点关键,接触传感器 只在接触时发消息,若适配器只靠它驱动,下游会误判"话题断流" - 静止读数 = 远端三个 link 重量 2.94mN,物理自洽 - 轴向:静止重量落在 child x(竖直),child z = 世界 +x,故法向 = child y; 符号与 force_scale 一起作为可配置标定项 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -130,20 +130,33 @@
|
||||
Orisys 视触觉传感器
|
||||
=======================================================================
|
||||
真机上是视触觉:一块弹性体 + 内置相机,读出三向力、深度图、力矢量图。
|
||||
仿真里没法真的模拟弹性体形变成像,采取的务实方案是:
|
||||
用 Gazebo 内置的 contact sensor 取接触处的真实接触力,
|
||||
再由 sim_tactile_adapter 把力投影到指尖坐标系,
|
||||
按 Orisys 的 TactileStatus 消息格式发布出去。
|
||||
仿真里没法真的模拟弹性体形变成像,采取的务实方案是**两个内置传感器协作**:
|
||||
|
||||
⚠️ 这里**不再**新建空的 tactile link。
|
||||
曾经的做法是建两个空的 sim_tactile_*_link(既无 visual 也无
|
||||
collision),挂在 **法兰** 的 tcp 上(不是指尖),而 <contact> 里
|
||||
又引用了一个 <collision>sim_tactile_left_link_collision</collision>
|
||||
—— 那个 collision 元素根本不存在。三重错叠在一起,
|
||||
结果是传感器**永远收不到任何数据**,而 Gazebo 不会为此报任何错:
|
||||
话题在、没有输出、看起来像"还没接触"。极难查。
|
||||
这也正是把传感器挂到真实碰撞体所在的 link(指尖)上的理由 ——
|
||||
"接触到的就是读到的",中间不再有需要对齐的第二套几何。
|
||||
力的三分量 ← <sensor type="force_torque"> 挂在**指尖关节**上
|
||||
是否接触 ← <sensor type="contact"> 挂在**指尖 link** 上
|
||||
接触位置 ← 同上,取接触点坐标 → 映射成 centroid_u/v
|
||||
|
||||
⚠️ 为什么力必须用 force_torque,而不是从接触传感器拿 —— 这条很反直觉,
|
||||
而且已经为此走过一次弯路,务必看完:
|
||||
|
||||
gz.msgs.Contacts(接触传感器发的消息)**不带任何力**。它的
|
||||
Contact 消息体里确实有 wrench/force 字段(ros_gz_interfaces/Contact.msg
|
||||
也照着声明了 wrenches),但 Fortress 的 Contact 系统**从不填充它们**:
|
||||
实测一条接触消息全文只有 header + 碰撞体名 + 接触点坐标,
|
||||
连 normal / depth 都是空的。而 Contact 系统的二进制里连一个
|
||||
"wrench" 字符串都搜不到 —— 所以这不是配置问题,是它设计上就只有位置。
|
||||
|
||||
正确的力来源是关节:**转动关节在物理上要承受三个方向的约束力**
|
||||
(它只放开绕轴转动这一个自由度)。所以挂在指尖关节上的
|
||||
force_torque 传感器,读到的就是"整条手指链传过来的力" ≈ 接触力
|
||||
(相差一个手指自身重力的偏置,正好由适配器做基线相减消掉,
|
||||
这与真机 Orisys "相对静止基线取增量"的口径天然一致)。
|
||||
由 Gazebo 内置的 forcetorque-system 实现,**无需自写 C++ 插件**。
|
||||
|
||||
⚠️ URDF 语法里没有"关节传感器"。这里靠 sdformat 的扩展写法实现:
|
||||
<gazebo reference="关节名"><sensor .../></gazebo>
|
||||
sdformat 的 URDF 解析器会把这类 sensor **移进对应的 <joint> 块**
|
||||
(已实测确认,生成的 SDF 里传感器确实在 joint 内)。
|
||||
|
||||
为什么要挂两个(left/right):
|
||||
真机是双指各贴一片,tangential_1/2 + normal 三路力分别来自两片,
|
||||
@@ -197,6 +210,54 @@
|
||||
</contact>
|
||||
</sensor>
|
||||
</gazebo>
|
||||
|
||||
<!-- =====================================================================
|
||||
三向力:指尖关节上的 force_torque 传感器
|
||||
=====================================================================
|
||||
挂在**指尖关节**(left/right_inner_finger_joint)上,而不是指尖 link ——
|
||||
force_torque 在 SDF 里只能属于关节。这个关节是手指链上最靠近指尖的
|
||||
一个(child = finger_mount,tip 用固定关节连在它下面),
|
||||
所以它传过去的力就是整条手指链的力 ≈ 接触力。
|
||||
|
||||
三个非轴方向的约束力就是我们要的"三向力":
|
||||
frame=child → 力的表达在 finger_mount 坐标系里
|
||||
measure_direction=parent_to_child
|
||||
→ 读"父 link 施加给子 link 的力"。
|
||||
静止时它等于 -(接触力 + 手指自重),
|
||||
所以真正符号如何、哪根轴对应"法向",
|
||||
以实测为准(见 config/tactile.yaml 的
|
||||
axis_* 映射项与 README 的实测记录)。
|
||||
|
||||
⚠️ 这个传感器是**持续发布**的(即使没有任何接触,也按 update_rate
|
||||
发零力)。这一点很关键:接触传感器只在接触时发消息,如果适配器
|
||||
只靠接触消息驱动,那么"离开工件"这段时间下游会认为话题断流。
|
||||
真机 Orisys 也是持续发布的,所以这里必须与真机一致。
|
||||
===================================================================== -->
|
||||
<gazebo reference="${prefix}left_inner_finger_joint">
|
||||
<sensor name="tactile_left_wrench" type="force_torque">
|
||||
<always_on>true</always_on>
|
||||
<update_rate>100</update_rate>
|
||||
<!-- force_torque 的话题写在外层 <topic> 即可(这点与 contact 不同:
|
||||
contact 只认 contact/topic,写外层会被静默忽略)。 -->
|
||||
<topic>/tactile/left/wrench</topic>
|
||||
<force_torque>
|
||||
<frame>child</frame>
|
||||
<measure_direction>parent_to_child</measure_direction>
|
||||
</force_torque>
|
||||
</sensor>
|
||||
</gazebo>
|
||||
|
||||
<gazebo reference="${prefix}right_inner_finger_joint">
|
||||
<sensor name="tactile_right_wrench" type="force_torque">
|
||||
<always_on>true</always_on>
|
||||
<update_rate>100</update_rate>
|
||||
<topic>/tactile/right/wrench</topic>
|
||||
<force_torque>
|
||||
<frame>child</frame>
|
||||
<measure_direction>parent_to_child</measure_direction>
|
||||
</force_torque>
|
||||
</sensor>
|
||||
</gazebo>
|
||||
</xacro:if>
|
||||
|
||||
</xacro:macro>
|
||||
|
||||
Reference in New Issue
Block a user