Using Sensors: Contact Sensor

Learning Objectives

This tutorial introduces how to use a contact sensor for sensing an environment in Omniverse Isaac Sim. After this tutorial, you will know how to add a contact sensor to the scene, activate, and measure contact force in a scene.

10-15 Minute Tutorial

Getting Started

Prerequisites

This tutorial demonstrates how to integrate the contact sensor into an Omniverse Isaac Sim simulation, by going over the three methods to create an Contact sensor. The methods to set contact sensor properties, read Contact sensor data, and finally the omnigraph nodes for reading and visualizing the contact sensor.

Contact Sensor Properties

  1. radius parameter specifies the distance of the contact force that it would sensor_period

  2. enabled parameter determines if the sensor is running or note

  3. min threshold parameter specifies the minimum amount fo force to trigger a contact

  4. max threshold parameter specifies the maximum amount of force the sensor will output

  5. sensor period parameter specifies the time inbetween sensor measurement. A sensor period that’s lower than the physics downtime will always output the latest physics data. The sensor frequency cannot go beyond the physics frequency.

Creating and Modifying the Contact Sensor

Using the GUI

  1. To create a Physics Scene, go to the top Menu Bar and Click Create > Physics > Physics Scene. There should now be a PhysicsScene Prim in the Stage panel on the right.

  2. To create a contact sensor, first left click on the prim to attach the contact sensor on the stage, then go to the top Menu Bar and Click Create > Isaac > Sensors > Contact_sensor.

  3. To change the position and orientation of the contact sensor, use Translate and Orientate tab.

  4. To change other contact sensor properties, click Raw USD Properties, and properties such as min/max force threshold, enable/disable sensor, sensor period will be available to modify.

Using Python Command

Contact sensors can also be created via python using the command call with the available parameters to set below. The only required parameter is the parent path and everything else can be filled with default values.

 1import omni.kit.commands
 2from pxr import Gf
 3
 4success, _isaac_sensor_prim = omni.kit.commands.execute(
 5    "IsaacSensorCreateContactSensor",
 6    path="Contact_Sensor",
 7    parent="/World/Cube",
 8    sensor_period=1,
 9    min_threshold=0.0001,
10    max_threshold=100000,
11    translation = Gf.Vec3d(0, 0, 0),
12)

Using Python Wrapper

The contact sensor can also be created using a python wrapper class. The benefit of using a wrapper class is that it come with additional helper functions to set the contact sensor properties and retrieve sensor data.

 1from omni.isaac.sensor import ContactSensor
 2import numpy as np
 3
 4sensor = ContactSensor(
 5    prim_path="/World/Cube/Contact_Sensor",
 6    name="Contact_Sensor",
 7    frequency=60,
 8    translation=np.array([0, 0, 0]),
 9    min_threshold=0,
10    max_threshold=10000000,
11    radius=-1
12)

Note

Translation and Position cannot both be defined, frequency and dt also cannot both be defined.

Creating a contact sensor can only be done on a prim with a collider API, and it depends on a Contact Report API. It automatically adds a contact report API to one. However, if you want to manually add the contact report API:

1import omni
2from pxr import PhysxSchema
3
4stage = omni.usd.get_context().get_stage()
5parent_prim = stage.GetPrimAtPath("/World/Cube")
6contact_report = PhysxSchema.PhysxContactReportAPI.Apply(parent_prim)
7# Set a minimum threshold for the contact report to zero
8contact_report.CreateThresholdAttr(0.0)

To modify sensor parameters, you can use built-in class api calls such as set_frequency, set_dt, or usd attribute api calls.

Reading Sensor Output

The contact sensors are created dynamically on PLAY. Moving the sensor prim while the simulation is running will invalidate the sensor. If you need to make hierarchical changes to the contact sensor like changing its rigid body parent, please stop the simulator, make the changes, and then restart the simulation.

There are also three methods for reading the sensor output, using get_sensor_reading() in the sensor interface (recommended), get_current_frame() in the contact sensor python class, and the omnigraph node Isaac Read Contact Sensor.

get_sensor_reading(sensor_path, use_latest_data = False)

the get sensor reading function takes in two parameters, the prim_path to any contact sensor prim and use latest data flag (optional) for retrieving the data point from the current physics step if the sensor is running at a slower rate than physics rate. The function will return an CsSensorReading object which contains is_valid, time, value, and in_contact.

Sample usage to get the reading from the current frame:

1from omni.isaac.sensor import _sensor
2
3_contact_sensor_interface = _sensor.acquire_contact_sensor_interface()
4_contact_sensor_interface.get_sensor_reading("/World/Cube/Contact_Sensor", use_latest_data = True)

get_current_frame()

The get_current_frame() function is a wrapper around get_sensor_reading(path_to_current_sensor) function and get_contact_sensor_raw_data, and it is also a member function of the ContactSensor class. This function returns a dictionary with in_contact, force, number_of_contacts, time, body0, body1, position, normal, impulse, contacts, and physics_step as keys for the IMU measurement. The get_current_frame() function uses the default parameters of get_sensor_reading, so it will give you the sensor measurement at reading time.

Sample usage

 1from omni.isaac.sensor import ContactSensor
 2import numpy as np
 3
 4sensor = ContactSensor(
 5    prim_path="/World/Cube/Contact_Sensor",
 6    name="Contact_Sensor",
 7    frequency=60,
 8    translation=np.array([0, 0, 0]),
 9    min_threshold=0,
10    max_threshold=10000000,
11    radius=-1
12)
13
14value = sensor.get_current_frame()
15print(value)

Isaac Read Contact Sensor Node

For reading contact sensor data using the Omnigraph, see this tutorial: Contact Sensor Node.

get_contact_sensor_raw_data()

The contact sensor raw data will output a list of raw contact api data CsRawData which contains time, dt, body0, body1, position, normal, and impulse. The raw data disregards sensor thresholds, so contacts with the parent body below the force threshold will still appear here even though those are discarded in the processed sensor reading CsSensorReading.

1from omni.isaac.sensor import _sensor
2
3_contact_sensor_interface = _sensor.acquire_contact_sensor_interface()
4raw_data = _contact_sensor_interface.get_contact_sensor_raw_data("/World/Cube/Contact_Sensor")
5print(str(raw_data))

Warning

This function is deprecated and will be replaced in a future release.

Visualizing Sensor

The Contact sensor position and radius can be visualized using the Isaac xPrim Radius Visualizer Node, simply connect the xPrim input to the Contact Sensor Prim, connect Tick to Exec in. Then insert the correct radius and configure the desired color and line thickness visualization, and the Contact sensor will be visible on PLAY

Note

The spherical region only determines the boundary for contacts that will be accounted for, but all contacts will still only happen at the surface of the object bounded by the spherical region.

Contact Sensor Visualization Action Graph set up

API Documentation

See the API Documentation for complete usage information.