mjlab.sensor

Contents

mjlab.sensor#

Sensor implementations.

Classes:

BuiltinSensor

Wrapper over MuJoCo builtin sensors.

BuiltinSensorCfg

BuiltinSensorCfg(name: 'str', sensor_type: 'SensorType', obj: 'ObjRef | None' = None, ref: 'ObjRef | None' = None, cutoff: 'float' = 0.0)

ObjRef

Reference to a MuJoCo object (body, joint, site, etc.).

ContactData

Contact sensor output (only requested fields are populated).

ContactMatch

Specifies what to match on one side of a contact.

ContactSensor

Tracks contacts with automatic pattern expansion to multiple MuJoCo sensors.

ContactSensorCfg

Tracks contacts between primary and secondary patterns.

Sensor

Base sensor interface with typed data.

SensorCfg

Base configuration for a sensor.

class mjlab.sensor.BuiltinSensor[source]#

Bases: Sensor[Tensor]

Wrapper over MuJoCo builtin sensors.

Can add a new sensor to the spec, or wrap an existing sensor from entity XML. Returns raw MuJoCo sensordata as torch.Tensor with shape depending on sensor type (e.g., accelerometer: (N, 3), framequat: (N, 4)).

Methods:

__init__([cfg, name])

from_existing(name)

Wrap an existing sensor already defined in entity XML.

edit_spec(scene_spec, entities)

Edit the scene spec to add this sensor.

initialize(mj_model, model, data, device)

Initialize the sensor after model compilation.

Attributes:

data

Get the current sensor data.

__init__(cfg: BuiltinSensorCfg | None = None, name: str | None = None) None[source]#
classmethod from_existing(name: str) BuiltinSensor[source]#

Wrap an existing sensor already defined in entity XML.

edit_spec(scene_spec: MjSpec, entities: dict[str, Entity]) None[source]#

Edit the scene spec to add this sensor.

This is called during scene construction to add sensor elements to the MjSpec.

Parameters:
  • scene_spec – The scene MjSpec to edit.

  • entities – Dictionary of entities in the scene, keyed by name.

initialize(mj_model: MjModel, model: mujoco_warp.Model, data: mujoco_warp.Data, device: str) None[source]#

Initialize the sensor after model compilation.

This is called after the MjSpec is compiled into an MjModel and the simulation is ready to run. Use this to cache sensor indices, allocate buffers, etc.

Parameters:
  • mj_model – The compiled MuJoCo model.

  • model – The mjwarp model wrapper.

  • data – The mjwarp data arrays.

  • device – Device for tensor operations (e.g., “cuda”, “cpu”).

property data: Tensor#

Get the current sensor data.

This property returns the sensor’s current data in its specific type. The data type is specified by the type parameter T.

Returns:

The sensor data in the format specified by type parameter T.

class mjlab.sensor.BuiltinSensorCfg[source]#

Bases: SensorCfg

BuiltinSensorCfg(name: ‘str’, sensor_type: ‘SensorType’, obj: ‘ObjRef | None’ = None, ref: ‘ObjRef | None’ = None, cutoff: ‘float’ = 0.0)

Attributes:

sensor_type

Which builtin sensor to use.

obj

The type and name of the object the sensor is attached to.

ref

The type and name of object to which the frame-of-reference is attached to.

cutoff

When this value is positive, it limits the absolute value of the sensor output.

Methods:

build()

Build sensor instance from this config.

__init__(name, sensor_type[, obj, ref, cutoff])

sensor_type: Literal['accelerometer', 'velocimeter', 'gyro', 'force', 'torque', 'magnetometer', 'rangefinder', 'jointpos', 'jointvel', 'jointlimitpos', 'jointlimitvel', 'jointlimitfrc', 'jointactuatorfrc', 'tendonpos', 'tendonvel', 'tendonactuatorfrc', 'actuatorpos', 'actuatorvel', 'actuatorfrc', 'framepos', 'framequat', 'framexaxis', 'frameyaxis', 'framezaxis', 'framelinvel', 'frameangvel', 'framelinacc', 'frameangacc', 'subtreecom', 'subtreelinvel', 'subtreeangmom', 'e_potential', 'e_kinetic', 'clock']#

Which builtin sensor to use.

obj: ObjRef | None = None#

The type and name of the object the sensor is attached to.

ref: ObjRef | None = None#

The type and name of object to which the frame-of-reference is attached to.

cutoff: float = 0.0#

When this value is positive, it limits the absolute value of the sensor output.

build() BuiltinSensor[source]#

Build sensor instance from this config.

__init__(name: str, sensor_type: Literal['accelerometer', 'velocimeter', 'gyro', 'force', 'torque', 'magnetometer', 'rangefinder', 'jointpos', 'jointvel', 'jointlimitpos', 'jointlimitvel', 'jointlimitfrc', 'jointactuatorfrc', 'tendonpos', 'tendonvel', 'tendonactuatorfrc', 'actuatorpos', 'actuatorvel', 'actuatorfrc', 'framepos', 'framequat', 'framexaxis', 'frameyaxis', 'framezaxis', 'framelinvel', 'frameangvel', 'framelinacc', 'frameangacc', 'subtreecom', 'subtreelinvel', 'subtreeangmom', 'e_potential', 'e_kinetic', 'clock'], obj: ObjRef | None = None, ref: ObjRef | None = None, cutoff: float = 0.0) None#
name: str#
class mjlab.sensor.ObjRef[source]#

Bases: object

Reference to a MuJoCo object (body, joint, site, etc.).

Used to specify which object a sensor is attached to and its frame of reference. The entity field allows scoping objects to specific entity namespaces.

Attributes:

type

Type of the object.

name

Name of the object.

entity

Optional entity prefix for the object name.

Methods:

prefixed_name()

Get the full name with entity prefix if applicable.

__init__(type, name[, entity])

type: Literal['body', 'xbody', 'joint', 'geom', 'site', 'actuator', 'tendon', 'camera']#

Type of the object.

name: str#

Name of the object.

entity: str | None = None#

Optional entity prefix for the object name.

prefixed_name() str[source]#

Get the full name with entity prefix if applicable.

__init__(type: Literal['body', 'xbody', 'joint', 'geom', 'site', 'actuator', 'tendon', 'camera'], name: str, entity: str | None = None) None#
class mjlab.sensor.ContactData[source]#

Bases: object

Contact sensor output (only requested fields are populated).

Attributes:

found

[B, N] 0=no contact, >0=match count

force

[B, N, 3] contact frame (global if reduce="netforce" or global_frame=True)

torque

[B, N, 3] contact frame (global if reduce="netforce" or global_frame=True)

dist

[B, N] penetration depth

pos

[B, N, 3] global frame

normal

[B, N, 3] global frame, primary→secondary

tangent

[B, N, 3] global frame

current_air_time

[B, N] time in air (if track_air_time=True)

last_air_time

[B, N] duration of last air phase (if track_air_time=True)

current_contact_time

[B, N] time in contact (if track_air_time=True)

last_contact_time

[B, N] duration of last contact phase (if track_air_time=True)

Methods:

__init__([found, force, torque, dist, pos, ...])

found: Tensor | None = None#

[B, N] 0=no contact, >0=match count

force: Tensor | None = None#

[B, N, 3] contact frame (global if reduce=”netforce” or global_frame=True)

torque: Tensor | None = None#

[B, N, 3] contact frame (global if reduce=”netforce” or global_frame=True)

dist: Tensor | None = None#

[B, N] penetration depth

pos: Tensor | None = None#

[B, N, 3] global frame

normal: Tensor | None = None#

[B, N, 3] global frame, primary→secondary

tangent: Tensor | None = None#

[B, N, 3] global frame

current_air_time: Tensor | None = None#

[B, N] time in air (if track_air_time=True)

last_air_time: Tensor | None = None#

[B, N] duration of last air phase (if track_air_time=True)

current_contact_time: Tensor | None = None#

[B, N] time in contact (if track_air_time=True)

last_contact_time: Tensor | None = None#

[B, N] duration of last contact phase (if track_air_time=True)

__init__(found: Tensor | None = None, force: Tensor | None = None, torque: Tensor | None = None, dist: Tensor | None = None, pos: Tensor | None = None, normal: Tensor | None = None, tangent: Tensor | None = None, current_air_time: Tensor | None = None, last_air_time: Tensor | None = None, current_contact_time: Tensor | None = None, last_contact_time: Tensor | None = None) None#
class mjlab.sensor.ContactMatch[source]#

Bases: object

Specifies what to match on one side of a contact.

mode: “geom”, “body”, or “subtree” pattern: Regex or tuple of regexes (expands within entity if specified) entity: Entity name to search within (None = treat pattern as literal MuJoCo name) exclude: Filter out matches using these regex patterns or exact names.

Attributes:

Methods:

__init__(mode, pattern[, entity, exclude])

mode: Literal['geom', 'body', 'subtree']#
pattern: str | tuple[str, ...]#
entity: str | None = None#
exclude: tuple[str, ...] = ()#
__init__(mode: Literal['geom', 'body', 'subtree'], pattern: str | tuple[str, ...], entity: str | None = None, exclude: tuple[str, ...] = ()) None#
class mjlab.sensor.ContactSensor[source]#

Bases: Sensor[ContactData]

Tracks contacts with automatic pattern expansion to multiple MuJoCo sensors.

Methods:

__init__(cfg)

edit_spec(scene_spec, entities)

Expand patterns and add MuJoCo sensors (one per primary x field pair).

initialize(mj_model, model, data, device)

Map sensors to sensordata buffer and allocate air time state.

reset([env_ids])

Reset sensor state for specified environments.

update(dt)

Update sensor state after a simulation step.

compute_first_contact(dt[, abs_tol])

Returns [B, N] bool: True for contacts established within last dt seconds.

compute_first_air(dt[, abs_tol])

Returns [B, N] bool: True for contacts broken within last dt seconds.

Attributes:

data

Get the current sensor data.

__init__(cfg: ContactSensorCfg) None[source]#
edit_spec(scene_spec: MjSpec, entities: dict[str, Entity]) None[source]#

Expand patterns and add MuJoCo sensors (one per primary x field pair).

initialize(mj_model: MjModel, model: mujoco_warp.Model, data: mujoco_warp.Data, device: str) None[source]#

Map sensors to sensordata buffer and allocate air time state.

property data: ContactData#

Get the current sensor data.

This property returns the sensor’s current data in its specific type. The data type is specified by the type parameter T.

Returns:

The sensor data in the format specified by type parameter T.

reset(env_ids: Tensor | slice | None = None) None[source]#

Reset sensor state for specified environments.

Base implementation does nothing. Override in subclasses that maintain internal state.

Parameters:

env_ids – Environment indices to reset. If None, reset all environments.

update(dt: float) None[source]#

Update sensor state after a simulation step.

Base implementation does nothing. Override in subclasses that need per-step updates.

Parameters:

dt – Time step in seconds.

compute_first_contact(dt: float, abs_tol: float = 1e-08) Tensor[source]#

Returns [B, N] bool: True for contacts established within last dt seconds.

compute_first_air(dt: float, abs_tol: float = 1e-08) Tensor[source]#

Returns [B, N] bool: True for contacts broken within last dt seconds.

class mjlab.sensor.ContactSensorCfg[source]#

Bases: SensorCfg

Tracks contacts between primary and secondary patterns.

Output shape: [B, N * num_slots] or [B, N * num_slots, 3] where N = # of primaries

Fields (choose subset):
  • found: 0=no contact, >0=match count before reduction

  • force, torque: 3D vectors in contact frame (or global if reduce=”netforce”)

  • dist: penetration depth

  • pos, normal, tangent: 3D vectors in global frame (normal: primary→secondary)

Reduction modes (selects top num_slots from all matches):
  • “none”: fast, non-deterministic

  • “mindist”, “maxforce”: closest/strongest contacts

  • “netforce”: sum all forces (global frame)

Policies:
  • secondary_policy: “first”, “any”, or “error” when secondary matches multiple

  • track_air_time: enables landing/takeoff detection

  • global_frame: rotates force/torque to global (requires normal+tangent fields)

Attributes:

Methods:

build()

Build sensor instance from this config.

__init__(name, primary[, secondary, fields, ...])

primary: ContactMatch#
secondary: ContactMatch | None = None#
fields: tuple[str, ...] = ('found', 'force')#
reduce: Literal['none', 'mindist', 'maxforce', 'netforce'] = 'maxforce'#
num_slots: int = 1#
secondary_policy: Literal['first', 'any', 'error'] = 'first'#
track_air_time: bool = False#
global_frame: bool = False#
debug: bool = False#
build() ContactSensor[source]#

Build sensor instance from this config.

__init__(name: str, primary: ContactMatch, secondary: ContactMatch | None = None, fields: tuple[str, ...] = ('found', 'force'), reduce: Literal['none', 'mindist', 'maxforce', 'netforce'] = 'maxforce', num_slots: int = 1, secondary_policy: Literal['first', 'any', 'error'] = 'first', track_air_time: bool = False, global_frame: bool = False, debug: bool = False) None#
name: str#
class mjlab.sensor.Sensor[source]#

Bases: ABC, Generic[T]

Base sensor interface with typed data.

Type parameter T specifies the type of data returned by the sensor. For example: - Sensor[torch.Tensor] for sensors returning raw tensors - Sensor[ContactData] for sensors returning structured contact data

Methods:

edit_spec(scene_spec, entities)

Edit the scene spec to add this sensor.

initialize(mj_model, model, data, device)

Initialize the sensor after model compilation.

reset([env_ids])

Reset sensor state for specified environments.

update(dt)

Update sensor state after a simulation step.

Attributes:

data

Get the current sensor data.

abstractmethod edit_spec(scene_spec: mujoco.MjSpec, entities: dict[str, Entity]) None[source]#

Edit the scene spec to add this sensor.

This is called during scene construction to add sensor elements to the MjSpec.

Parameters:
  • scene_spec – The scene MjSpec to edit.

  • entities – Dictionary of entities in the scene, keyed by name.

abstractmethod initialize(mj_model: MjModel, model: mujoco_warp.Model, data: mujoco_warp.Data, device: str) None[source]#

Initialize the sensor after model compilation.

This is called after the MjSpec is compiled into an MjModel and the simulation is ready to run. Use this to cache sensor indices, allocate buffers, etc.

Parameters:
  • mj_model – The compiled MuJoCo model.

  • model – The mjwarp model wrapper.

  • data – The mjwarp data arrays.

  • device – Device for tensor operations (e.g., “cuda”, “cpu”).

abstract property data: T#

Get the current sensor data.

This property returns the sensor’s current data in its specific type. The data type is specified by the type parameter T.

Returns:

The sensor data in the format specified by type parameter T.

reset(env_ids: Tensor | slice | None = None) None[source]#

Reset sensor state for specified environments.

Base implementation does nothing. Override in subclasses that maintain internal state.

Parameters:

env_ids – Environment indices to reset. If None, reset all environments.

update(dt: float) None[source]#

Update sensor state after a simulation step.

Base implementation does nothing. Override in subclasses that need per-step updates.

Parameters:

dt – Time step in seconds.

class mjlab.sensor.SensorCfg[source]#

Bases: ABC

Base configuration for a sensor.

Attributes:

Methods:

build()

Build sensor instance from this config.

__init__(name)

name: str#
abstractmethod build() Sensor[Any][source]#

Build sensor instance from this config.

__init__(name: str) None#