Contact sensors#

Genesis World provides sensors for detecting and measuring contact forces. These are essential for manipulation tasks, grasping, and understanding physical interactions.

ContactForceSensor#

The ContactForceSensor measures the total contact force being applied to the associated rigid link in its local frame.

Usage#

import genesis as gs

gs.init()
scene = gs.Scene()
robot = scene.add_entity(gs.morphs.URDF(file="gripper.urdf"))
finger = robot.get_link("finger_link")

# Add contact force sensor to gripper finger
contact_sensor = scene.add_sensor(
    gs.sensors.ContactForce(
        entity_idx=robot.idx,
        link_idx_local=finger.idx_local,
    )
)

scene.build()

# Simulation loop
for i in range(1000):
    scene.step()

    # Get contact force (plain tensor, not NamedTuple)
    force = contact_sensor.read()  # ([n_envs,] 3) force in Newtons
    print(f"Contact force: {force}")

Output format#

read() returns a plain torch.Tensor (float32):

Shape

Description

([n_envs,] 3)

Total contact force in local link frame (Newtons)

The options passed to gs.sensors.ContactForce (offsets, force clamping, noise) are documented in the reference below.

ContactSensor#

The ContactSensor detects whether the associated rigid link is in contact (boolean).

Usage#

import genesis as gs

gs.init()
scene = gs.Scene()
robot = scene.add_entity(gs.morphs.URDF(file="robot.urdf"))

contact = scene.add_sensor(
    gs.sensors.Contact(
        entity_idx=robot.idx,
        link_idx_local=robot.get_link("base").idx_local,
    )
)

scene.build()
scene.step()
in_contact = contact.read()  # ([n_envs,] 1) boolean tensor

Output format#

read() returns a plain torch.Tensor (bool):

Shape

Description

([n_envs,] 1)

True if link is in contact

API reference#

gs.sensors.ContactForce#

class genesis.options.sensors.options.ContactForce(*, history_length: int = 0, delay: float = 0.0, jitter: float = 0.0, draw_debug: bool = False, entity_idx: int = -1, resolution: tuple[float, float, float] = 0.0, bias: tuple[float, ...] | float = 0.0, noise: tuple[float, ...] | float = 0.0, random_walk: tuple[float, ...] | float = 0.0, link_idx_local: int = 0, pos_offset: tuple[float, float, float] = (0.0, 0.0, 0.0), euler_offset: tuple[float, float, float] = (0.0, 0.0, 0.0), min_force: tuple[float, float, float] = 0.0, max_force: tuple[float, float, float] = inf, debug_color: tuple[float, float, float, float] = (1.0, 0.0, 1.0, 0.5), debug_scale: float = 0.01) None[source]#

Sensor that returns the total contact force being applied to the associated RigidLink in its local frame.

Parameters:
  • min_force (float | array-like[float, float, float], optional) – The minimum detectable absolute force per each axis. Values below this will be treated as 0. Default is 0.

  • max_force (float | array-like[float, float, float], optional) – The maximum output absolute force per each axis. Values above this will be clipped. Default is infinity.

  • debug_color (array-like[float, float, float, float], optional) – The rgba color of the debug arrow. Defaults to (1.0, 0.0, 1.0, 0.5).

  • debug_scale (float, optional) – The scale factor for the debug force arrow. Defaults to 0.01.

class genesis.engine.sensors.contact_force.ContactForceSensor(options: ContactForce, idx: int, shared_context, shared_metadata, manager: SensorManager)[source]#

Bases: RigidSensorMixin[ContactForceSensorMetadata], SimpleSensor[ContactForce, None, ContactForceSensorMetadata, tuple]

Sensor that returns the total contact force being applied to the associated RigidLink in its local frame.

build()[source]#

Initialize all shared metadata needed to update all noisy sensors.

Time-related state (delays_ts, jitter_ts) is pushed by Sensor.build(); this method adds the imperfection-parameter state.

gs.sensors.Contact#

class genesis.options.sensors.options.Contact(*, history_length: int = 0, delay: float = 0.0, jitter: float = 0.0, draw_debug: bool = False, entity_idx: int = -1, resolution: tuple[float, ...] | float = 0.0, bias: tuple[float, ...] | float = 0.0, noise: tuple[float, ...] | float = 0.0, random_walk: tuple[float, ...] | float = 0.0, link_idx_local: int = 0, pos_offset: tuple[float, float, float] = (0.0, 0.0, 0.0), euler_offset: tuple[float, float, float] = (0.0, 0.0, 0.0), filter_link_idx: tuple[int, ...] = <factory>, threshold: float = 0.0, debug_sphere_radius: float = 0.05, debug_color: tuple[float, float, float, float] = (1.0, 0.0, 1.0, 0.5)) None[source]#

Sensor that returns bool based on whether associated RigidLink is in contact.

Parameters:
  • filter_link_idx (array-like[int], optional) – Global rigid link indices (solver link space). Contacts with the sensor link where the other participant is one of these links are ignored. Default is empty (no filtering).

  • threshold (float, optional) – The bool-conversion threshold applied at read time to the underlying float contact magnitude (kernel produces float). A bin reads True iff its magnitude exceeds this value. Default 0.0 so any positive magnitude registers as contact.

  • debug_sphere_radius (float, optional) – The radius of the debug sphere. Defaults to 0.05.

  • debug_color (array-like[float, float, float, float], optional) – The rgba color of the debug sphere. Defaults to (1.0, 0.0, 1.0, 0.5).

class genesis.engine.sensors.contact_force.ContactSensor(options: Contact, idx: int, shared_context, shared_metadata, manager: SensorManager)[source]#

Bases: SimpleSensor[Contact, None, ContactSensorMetadata, tuple]

Sensor that returns bool based on whether associated RigidLink is in contact.

build()[source]#

Initialize all shared metadata needed to update all noisy sensors.

Time-related state (delays_ts, jitter_ts) is pushed by Sensor.build(); this method adds the imperfection-parameter state.

See also#