Bootstrap

IsaacLab最新2025教程(6)-导入接触力传感器contact sensor并读取数据

前言

最近做仿真时候需要处理力反馈数据,之前用isaacsim 2023.1.1版本时候使用的是F/T sensor,直接或许UR机械臂末端的传感器数据,但是特别烂,值完全不对,gripper夹取一个3kg垂直提升时候读取数据是200还是300N,而且physics_dt值不同时候数值也跟着变,无语了,最近isaaclab这个直接contact force更新的更完善了,出个经验贴给大家分享一下,做locomotion或者力控都很有用。

官方文档介绍:Contact Sensor — Isaac Lab Documentation

之前的安装教程:IsaacLab最新2025教程-环境配置(IsaacSim 4.5.0/Ubuntu22.04) 原创_isaacsim4.5-CSDN博客

如果下载了最新的isaaclab可以直接在文件夹中运行:

## cd IsaacLab进入isaaclab下面的文件夹
## 注意我使用的conda虚拟环境,可以直接用python运行,可以看我之前的安装教程
python scripts/demos/sensors/contact_sensor.py

1. Contact Sensor

Isaaclab中的接触力是检测两个physical object的接触力,现在只看了rigid body,deformable object后续再研究,但是大体思路是互通的。而且接触力可以选取特定的两个object的接触,比如机械狗上台阶的时候,可能卡在台阶上,轮子踩着一个台阶同时,轮子顶着高一阶的台阶(如果不理解下次上楼时候,脚踩着地面往前蹭,直到顶着下一个台阶蹭不动了就行了),但是我们只关心和踩着的台阶的接触力,不在乎和更高的台阶的接触力,这时候就可以设置一个filter只获取指定的两个object的接触力就可以了,下面是文档里的代码,依旧是复制过来加一些自己的tips。

2. 代码示例:在 Isaac Lab 中定义接触传感器

以下代码展示了如何在 Isaac Lab 中定义一个包含接触传感器的场景。我们以一个四足机器人(Anymal Quadruped)和一个立方体为例,展示如何为机器人的足部定义接触传感器。

场景配置

首先,我们定义一个场景配置类 ContactSensorSceneCfg,其中包含地面、灯光、机器人和立方体的配置。

"""
这里的内容都很简单,就当成是复习之前搭建scene的流程了

"""

@configclass
class ContactSensorSceneCfg(InteractiveSceneCfg):
    # 地面
    ground = AssetBaseCfg(prim_path="/World/defaultGroundPlane", spawn=sim_util)
    
    # 灯光
    dome_light = AssetBaseCfg(
        prim_path="/World/Light", spawn=sim_utils.DomeLightCfg(intensity=3000.0)
    )
    
    # 机器人
    robot = ANYMAL_C_CFG.replace(prim_path="{ENV_REGEX_NS}/Robot")
    
    # 立方体
    cube = RigidObjectCfg(
        prim_path="{ENV_REGEX_NS}/Cube",
        spawn=sim_utils.CuboidCfg(
            size=(0.5, 0.5, 0.1),
            rigid_props=sim_utils.RigidBodyPropertiesCfg(),
            mass_props=sim_utils.MassPropertiesCfg(mass=100.0),
            collision_props=sim_utils.CollisionPropertiesCfg(),
            physics_material=sim_utils.RigidBodyMaterialCfg(static_friction=1.0),
            visual_material=sim_utils.PreviewSurfaceCfg(diffuse_color=(0.0, 1.0, 0.0)),
        ),
        init_state=RigidObjectCfg.InitialStateCfg(pos=(0.5, 0.5, 0.05)),
    )

定义接触传感器

接下来,我们为机器人的足部定义接触传感器。前足(左前足和右前足)分别定义为独立的传感器,而后足(左后足和右后足)则定义为单个传感器。

"""
这里面是加载传感器,目测直接加在需要的rigid body的prim path上就行了

"""

## 注意这里的filter_prim_paths_expr就是之前说的选取特定的接触物体,这样就不会考虑与其他物体的接触力了

contact_forces_LF = ContactSensorCfg(
    prim_path="{ENV_REGEX_NS}/Robot/LF_FOOT",
    update_period=0.0,
    history_length=6,
    debug_vis=True,
    filter_prim_paths_expr=["{ENV_REGEX_NS}/Cube"],
)

contact_forces_RF = ContactSensorCfg(
    prim_path="{ENV_REGEX_NS}/Robot/RF_FOOT",
    update_period=0.0,
    history_length=6,
    debug_vis=True,
    filter_prim_paths_expr=["{ENV_REGEX_NS}/Cube"],
)

## 这个意思是把两条后腿当成整体进行受力分析了,之前都是把单独一条腿进行受力分析,跟初中物理的受力分析一个道理哈

contact_forces_H = ContactSensorCfg(
    prim_path="{ENV_REGEX_NS}/Robot/.*H_FOOT",
    update_period=0.0,
    history_length=6,
    debug_vis=True,
)

运行仿真并打印传感器数据

在定义好传感器后,我们可以运行仿真并打印传感器的数据。

def run_simulator(sim: sim.utils.SimulationContext, scene: InteractiveScene):
    while simulation_app.is_running():
        # 打印传感器信息
        print("---")
        print(scene["contact_forces_LF"])
        print("Received force matrix of: ", scene["contact_forces_LF"].data.force_matrix)
        print("Received contact force of: ", scene["contact_forces_LF"].data.net_force)
        print("---")
        print(scene["contact_forces_RF"])
        print("Received force matrix of: ", scene["contact_forces_RF"].data.force_matrix)
        print("Received contact force of: ", scene["contact_forces_RF"].data.net_force)
        print("---")
        print(scene["contact_forces_H"])
        print("Received force matrix of: ", scene["contact_forces_H"].data.force_matrix)
        print("Received contact force of: ", scene["contact_forces_H"].data.net_force)

看看结果:

传感器数据解析

在仿真过程中,我们可以观察到以下传感器数据:

  • 前左足传感器

    • 净接触力:tensor([[[[-1.3923e-05, 1.5727e-04, 1.1032e+02]]]]

    • 力矩阵:tensor([[[[-1.3923e-05, 1.5727e-04, 1.1032e+02]]]]

  • 前右足传感器

    • 净接触力:tensor([[[1.3529e-05, 0.0000e+00, 1.0069e+02]]]

    • 力矩阵:tensor([[[[0., 0., 0.]]]])

  • 后足传感器

    • 净接触力:tensor([[[9.7227e-06, 0.0000e+00, 7.2364e+01], [2.4322e-05, 0.0000e+00, 1.8102e+02]]]

    • 力矩阵:None

从数据中可以看出,前左足传感器报告了来自立方体的接触力,而前右足传感器没有报告任何力,因为它没有站在立方体上。后足传感器由于是多个刚体的传感器,因此力矩阵为 None,但净接触力包含了两个刚体的力信息。大概理解是,net_forces_w是这个物体在多个物体接触的情况下受到的合力,force_matrix_w是与filter指定的物体的特定接触力,w意思就是在世界坐标系下。

这是单独的关于力传感器的tutorial,如果要结合具体的强化学习训练示例,可以看官方环境中的locomotion里面的任务,基本上都要用到接触力。

 

;