newton.sensors.ContactSensor#

class newton.sensors.ContactSensor(model, sensing_obj_bodies=None, sensing_obj_shapes=None, counterpart_bodies=None, counterpart_shapes=None, match_fn=None, include_total=True, prune_noncolliding=False, verbose=None)[source]#

Bases: object

Sensor for contact forces between bodies or shapes.

The ContactSensor allows you to define a set of “sensing objects” (bodies or shapes) and optionally a set of “counterpart” objects (bodies or shapes) to sense contact forces against. The sensor can be configured to report the total contact force or per-counterpart readings.

The ContactSensor produces a matrix of force readings, where each row corresponds to one sensing object and each column corresponds to one counterpart. Each entry of this matrix is the net contact force vector between the sensing object and the counterpart. If no counterparts are specified, the sensor will read the net contact force for each sensing object.

If include_total is True, inserts a wildcard before all other counterparts, such that the first column of the force matrix will read the total contact force for each sensing object.

If prune_noncolliding is True, the force matrix will be sparse, containing only readings for shape pairs that can collide. In this case, force matrix will have as many columns as the maximum number of active counterparts for any sensing object, and the reading_indices attribute can be used to recover the active counterparts for each sensing object.

Terms used

  • Sensing Object: The body or shape “carrying” a contact sensor.

  • Counterpart: The other body or shape involved in a contact interaction with a sensing object.

  • Force Matrix: The matrix organizing the force data by rows of sensing objects and columns of counterparts.

  • Force Reading: An individual force measurement within the matrix.

Raises:

ValueError – If the configuration of sensing/counterpart objects is invalid.

__init__(model, sensing_obj_bodies=None, sensing_obj_shapes=None, counterpart_bodies=None, counterpart_shapes=None, match_fn=None, include_total=True, prune_noncolliding=False, verbose=None)#

Initialize a ContactSensor.

Exactly one of sensing_obj_bodies or sensing_obj_shapes must be specified to define the sensing objects. At most one of counterpart_bodies or counterpart_shapes may be specified. If neither is specified, the sensor will read the net contact force for each sensing object.

Parameters:
  • sensing_obj_bodies (str | list[str] | None) – Pattern(s) to select which bodies are sensing objects.

  • sensing_obj_shapes (str | list[str] | None) – Pattern(s) to select which shapes are sensing objects.

  • counterpart_bodies (str | list[str] | None) – Pattern(s) to select which bodies are considered as counterparts.

  • counterpart_shapes (str | list[str] | None) – Pattern(s) to select which shapes are considered as counterparts.

  • match_fn (Callable[[str, str], bool] | None) – Function to match names to patterns. If None, uses fnmatch.

  • include_total (bool) – If True and counterparts are specified, add a reading for the total contact force for each sensing object. Does nothing when no counterparts are specified.

  • prune_noncolliding (bool) – If True, omit force readings for shape pairs that never collide from the force matrix. Does nothing when no counterparts are specified.

  • verbose (bool | None) – If True, print details. If None, uses wp.config.verbose.

eval(contacts)#

Evaluate the contact sensor readings based on the provided contacts.

Process the given Contacts object and updates the internal net force readings for each sensing_obj-counterpart pair.

Parameters:

contacts (Contacts) – The contact data to evaluate.

get_total_force()#

Get the total net force measured by the contact sensor.

Returns:

The net force array, shaped according to the sensor configuration.

Return type:

array(ndim=2, dtype=vec3f)

counterparts: list[tuple[int, MatchKind]]#

Index and kind of each counterpart, length n_counterparts. Corresponds to the columns of the force matrix, unless prune_noncolliding is True.

net_force: array(ndim=2, dtype=vec3f)#

Net force matrix.

reading_indices: list[list[int]]#

List of active counterpart indices per sensing object.

sensing_objs: list[tuple[int, MatchKind]]#

Index and kind of each sensing object, length n_sensing_objs. Corresponds to the rows of the force matrix.

shape: tuple[int, int]#

Shape of the force matrix (n_sensing_objs, n_counterparts) if prune_noncolliding is False, and (n_sensing_objs, max_active_counterparts) if it is True.