newton.sensors.SensorContact#
- class newton.sensors.SensorContact(model, *, sensing_bodies=None, sensing_shapes=None, counterpart_bodies=None, counterpart_shapes=None, measure_total=True, verbose=None, request_contact_attributes=True, **kwargs)[source]#
Bases:
objectMeasures contact forces on a set of sensing objects (bodies or shapes).
In its simplest form the sensor reports
total_force— the total contact force on each sensing object. Optionally, specify counterparts to get a per-counterpart breakdown inforce_matrix.total_forceandforce_matrixare each nullable:total_forceisNonewhenmeasure_total=False;force_matrixisNonewhen no counterparts are specified. Their friction counterpartstotal_force_frictionandforce_matrix_frictionfollow the same rules.Multi-world behavior
When the model contains multiple worlds, counterpart mappings are resolved per-world. The collision pipeline and solver are expected to produce only within-world contacts, so cross-world force accumulation does not arise in practice. Global counterparts (e.g. ground plane) contribute to every world they contact.
In single-world models where no
add_world()call was made (all entities are global /world=-1), the sensor treats the entire model as one implicit world and all entities are valid sensing objects.When counterparts are specified, the force matrix has shape
(sum_of_sensors_across_worlds, max_counterparts)wheremax_counterpartsis the maximum counterpart count of any single world. Row order matchessensing_indices. Columns beyond a world’s own counterpart count are zero-padded.sensing_indicesandcounterpart_indicesare flat lists that describe the structure of the output arrays.Terms
Sensing object – body or shape carrying a contact sensor.
Counterpart – the other body or shape in a contact interaction.
Construction and update order
SensorContactrequests theforceextended attribute from the model at init, so aContactsobject created afterwards (viaModel.contacts()or directly) will include it automatically.update()reads fromcontacts.force. Callsolver.update_contacts(contacts)beforesensor.update()so that contact forces are current.Parameters that select bodies or shapes accept label patterns – see Label Matching.
Example
Measure total contact force on a sphere resting on the ground:
import warp as wp import newton from newton.sensors import SensorContact builder = newton.ModelBuilder() builder.add_ground_plane() body = builder.add_body(xform=wp.transform((0, 0, 0.1), wp.quat_identity())) builder.add_shape_sphere(body, radius=0.1, label="ball") model = builder.finalize() sensor = SensorContact(model, sensing_shapes="ball") solver = newton.solvers.SolverMuJoCo(model) state = model.state() contacts = model.contacts() solver.step(state, state, None, None, dt=1.0 / 60.0) solver.update_contacts(contacts) sensor.update(state, contacts) force = sensor.total_force.numpy() # (n_sensing, 3)
- Raises:
ValueError – If the configuration of sensing/counterpart objects is invalid.
- __init__(model, *, sensing_bodies=None, sensing_shapes=None, counterpart_bodies=None, counterpart_shapes=None, measure_total=True, verbose=None, request_contact_attributes=True, **kwargs)#
Initialize the SensorContact.
Exactly one of
sensing_bodiesorsensing_shapesmust be specified to define the sensing objects. At most one ofcounterpart_bodiesorcounterpart_shapesmay be specified. If neither is specified, onlytotal_forceandtotal_force_frictionare available (no per-counterpart breakdown).- Parameters:
model (Model) – The simulation model providing shape/body definitions and world layout.
sensing_bodies (str | list[str] | list[int] | None) – List of body indices, single pattern to match against body labels, or list of patterns where any one matches.
sensing_shapes (str | list[str] | list[int] | None) – List of shape indices, single pattern to match against shape labels, or list of patterns where any one matches.
counterpart_bodies (str | list[str] | list[int] | None) – List of body indices, single pattern to match against body labels, or list of patterns where any one matches.
counterpart_shapes (str | list[str] | list[int] | None) – List of shape indices, single pattern to match against shape labels, or list of patterns where any one matches.
measure_total (bool) – If True (default),
total_forceandtotal_force_frictionare allocated. If False, both are None.verbose (bool | None) – If True, print details. If False, suppress details. If None, print details when
wp.config.log_levelis configured for debug logging.request_contact_attributes (bool) – If True (default), transparently request the extended contact attribute
forcefrom the model.
- update(state, contacts)#
Update the contact sensor readings based on the provided state and contacts.
Computes world-frame transforms for all sensing objects and evaluates contact forces and their friction (tangential) components (total and/or per-counterpart, depending on sensor configuration).
- Parameters:
- Raises:
ValueError – If
contacts.forceis None.ValueError – If
contacts.devicedoes not match the sensor’s device.
- counterpart_indices: list[list[int]]#
Counterpart body or shape indices per sensing object.
counterpart_indices[i]lists the counterparts for rowi. Global counterparts appear first, followed by per-world locals in ascending index order.
- counterpart_type: Literal['body', 'shape'] | None#
Whether
counterpart_indicescontains body indices ("body") or shape indices ("shape").Nonewhen no counterparts are specified.
- force_matrix: wp.array(dtype=wp.vec3f, ndim=2) | None#
Per-counterpart contact forces [N], shape
(n_sensing, max_counterparts), dtypevec3. Entry[i, j]is the force on sensing objectifrom counterpartcounterpart_indices[i][j], in world frame.Nonewhen no counterparts are specified.
- force_matrix_friction: wp.array(dtype=wp.vec3f, ndim=2) | None#
Per-counterpart friction (tangential) contact forces [N], shape
(n_sensing, max_counterparts), dtypevec3. Entry[i, j]is the friction force on sensing objectifrom counterpartcounterpart_indices[i][j], in world frame.Nonewhen no counterparts are specified.
- sensing_indices: list[int]#
Body or shape index per sensing object, matching the row of output arrays. For
list[int]inputs the caller’s order is preserved; for string patterns the order follows ascending body/shape index.
- property sensing_obj_idx: list[int]#
Deprecated alias for
sensing_indices.Deprecated since version 1.4: Use
sensing_indicesinstead.
- property sensing_obj_transforms: wp.array(dtype=wp.transformf, ndim=1)#
Deprecated alias for
sensing_transforms.Deprecated since version 1.4: Use
sensing_transformsinstead.
- property sensing_obj_type: Literal['body', 'shape']#
Deprecated alias for
sensing_type.Deprecated since version 1.4: Use
sensing_typeinstead.
- sensing_transforms: wp.array(dtype=wp.transformf, ndim=1)#
World-frame transforms of sensing objects [m, unitless quaternion], shape
(n_sensing,), dtypetransform.
- sensing_type: Literal['body', 'shape']#
Whether
sensing_indicescontains body indices ("body") or shape indices ("shape").