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
Review the Core Tutorial series and Contact Sensor GUI example prior to beginning this tutorial.
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
radius
parameter specifies the distance of the contact force that it would sensor_periodenabled
parameter determines if the sensor is running or notemin threshold
parameter specifies the minimum amount fo force to trigger a contactmax threshold
parameter specifies the maximum amount of force the sensor will outputsensor 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
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.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.
To change the position and orientation of the contact sensor, use Translate and Orientate tab.
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.
API Documentation#
See the API Documentation for complete usage information.