Contact Reports#
Contact reports can be received in Python code by adding a PhysxSchema.PhysxContactReportAPI to the body or articulation Prim.
Subscribing to the contact event report, contacts are sent through a callback function in two arrays.
The contact report first array contains contact headers, which can be of type:
ContactEventType.CONTACT_FOUNDContactEventType.CONTACT_PERSISTSContactEventType.CONTACT_LOST
These events send the additional dictionary with contact information:
actor0 - Usd path to rigid body actor 0 decoded into two ints.
PhysicsSchemaTools.encodeSdfPathwill return SdfPath.actor1 - Usd path to rigid body actor 1 decoded into two ints.
PhysicsSchemaTools.encodeSdfPathwill return SdfPath.collider0 - Usd path to collider 0 decoded into two ints.
PhysicsSchemaTools.encodeSdfPathwill return SdfPath.collider1 - Usd path to collider 1 decoded into two ints.
PhysicsSchemaTools.encodeSdfPathwill return SdfPath.stage_id - Stage that the report is coming from.
contact_data_offset - Offset to the contact data array.
num_contact_data - Number of contacts in the contact data array for this header.
The actual contact data are in the second array. Contact data contains this information:
position - Contact position.
normal - Contact normal.
impulse - Contact impulse.
separation - Separation value for collisions.
face_index0 - Face index of the collider0 (filled only if available 0xFFFFFFFF otherwise).
face_index1 - Face index of the collider1 (filled only if available 0xFFFFFFFF otherwise).
material0 - Material of collider0.
material1 - Material of collider1.
The following code will not execute and is just kept here as a guidance. Instead of copy pasting the snippet code, review the Physics Demo Sample - contactReportDemo.
from omni.physx.scripts.physicsUtils import *
from pxr import Usd, UsdGeom, Sdf, Gf, Tf, Vt, UsdPhysics, PhysxSchema
from omni.physx._physx import SimulationEvent
from omni.physx import get_physx_interface
# acquire the physx interface
self._physx = _physx.acquire_physx_interface()
# subscribe to physics contact report event, this callback is issued after each simulation step
self._contact_report_sub = get_physx_simulation_interface().subscribe_contact_report_events(self._on_contact_report_event)
# Spheres
spherePath = "/sphere"
radius = 30.0
position = Gf.Vec3f(0.0, 0.0, 800.0)
orientation = Gf.Quatf(1.0)
color = Gf.Vec3f(71.0 / 255.0, 165.0 / 255.0, 1.0)
density = 1000.0
linvel = Gf.Vec3f(0.0)
add_rigid_sphere(stage, spherePath, radius, position, orientation, color, density, linvel, Gf.Vec3f(0.0))
# apply contact report
spherePrim = stage.GetPrimAtPath(spherePath)
contactReportAPI = PhysxSchema.PhysxContactReportAPI.Apply(spherePrim)
contactReportAPI.CreatePhysxContactReportThresholdAttr().Set(200000)
def _on_contact_report_event(self, contact_headers, contact_data):
for contact_header in contact_headers:
print("Got contact header type: " + str(contact_header.type))
print("Actor0: " + str(PhysicsSchemaTools.intToSdfPath(contact_header.actor0)))
print("Actor1: " + str(PhysicsSchemaTools.intToSdfPath(contact_header.actor1)))
print("Collider0: " + str(PhysicsSchemaTools.intToSdfPath(contact_header.collider0)))
print("Collider1: " + str(PhysicsSchemaTools.intToSdfPath(contact_header.collider1)))
print("StageId: " + str(contact_header.stage_id))
print("Number of contacts: " + str(contact_header.num_contact_data))
contact_data_offset = contact_header.contact_data_offset
num_contact_data = contact_header.num_contact_data
for index in range(contact_data_offset, contact_data_offset + num_contact_data, 1):
print("Contact:")
print("Contact position: " + str(contact_data[index].position))
print("Contact normal: " + str(contact_data[index].normal))
print("Contact impulse: " + str(contact_data[index].impulse))
print("Contact separation: " + str(contact_data[index].separation))
print("Contact faceIndex0: " + str(contact_data[index].face_index0))
print("Contact faceIndex1: " + str(contact_data[index].face_index1))
print("Contact material0: " + str(PhysicsSchemaTools.intToSdfPath(contact_data[index].material0)))
print("Contact material1: " + str(PhysicsSchemaTools.intToSdfPath(contact_data[index].material1)))