- Using Isaac URDF Importer I imported usd file of robot arm with
Case 1. self collision disabled
Case 2. self collision enabled
Note! in all cases instaceable is enabled - I passed root_path and robot prim to be checked for collision(self, ground and with other colliders).
by parsing the meshes and callingomni.physx.get_physx_scene_query_interface().overlap_mesh(path_id_0, path_id_1, self.on_hit, False)
method for each meshes. as show in the snap code below - When testing for case 1(i.e self collision disabled) it reports for self collision, i.e all the adjacent robot links are in collision
- 1 Then I enabled Collision Enabled properties for all the joints → nothing changed and the problem
exist - When testing for case 2(i.e self collision enabled) it detects collision with ground and other objects correctly but can’t report self collision correctly. as shown in a demo below.
sample code
def check_collision(self, prim: Usd.Prim, target_path: str):
"""
Check for collision of given root prim for self-collision, collision with ground, collision with other collision objects
in a world
args:
prim (Usd.Prim): Root prim for the collision check
target_path (str): Path of the already placed xform prim where the asset is added
return:
bool[self-collision], bool[collision with ground], bool[collision with other objects], List[objects path in collision]
"""
self.self_collision, self.ground_collision, self.object_collision = \
False, False, False
self.overlaps = []
self.collision_root_path = target_path
prim = prim
import omni.physx
interface = omni.physx.get_physx_scene_query_interface()
meshes = []
get_collision_check_meshes(prim, meshes)
# Iterate on all meshes in the added prim
for mesh_path in meshes:
# Get the encoded path
path_id_0, path_id_1 = PhysicsSchemaTools.encodeSdfPath(mesh_path)
# Look for collisions. We cannot use the direct hit count beca>
interface.overlap_mesh(path_id_0, path_id_1, self.on_hit, False)
#if len(self.overlaps) > 0:
# prim.GetReferences().ClearReferences()
# break
# Return detected overlaps
return {"self collision": self.self_collision, "ground collision": self.ground_collision, "object collision": self.object_collision, "overlaps": self.overlaps}
def on_hit(self, hit) -> bool:
"""
Callback method for checking a given mesh for collisions
Args:
hit (SceneQueryHits): Structure containing information about collision hits
Returns:
bool: True to continue scanning for collisions
"""
# Check that we are not hitting the ground plane (this is normal), and not having self collision
if ("ground_plane" in hit.rigid_body or "defaultGroundPlane"):
self.ground_collision = True
if(self.collision_root_path in hit.rigid_body):
self.self_collision = True
if (hit.rigid_body not in self.overlaps):
self.overlaps.append(hit.rigid_body)
return True
def get_collision_check_meshes(prim: Usd.Prim, meshes: List[str]) -> None:
"""
Get paths to children of a prim to which collision can be added. Temporarily removes instancing
to find subprims that are meshes.
Args:
prim (Usd.Prim): Root prim for the collision check
meshes (List[str]): List of children that are UsdGeomMesh for collision check. Includes
subprims of instanceable prims.
"""
instanceables = []
for child in prim.GetChildren():
# If the prim is instanceable, temporarily make it not instanced to get subprims.
if child.IsInstanceable():
child.SetInstanceable(False)
instanceables.append(child)
# Select only meshes
if child.IsA(UsdGeom.Mesh):
meshes.append(child.GetPath().pathString)
continue
# Recursively call the method on subprims
get_collision_check_meshes(child, meshes)
for modified_prim in instanceables:
modified_prim.SetInstanceable(True)
Thanks for your time:)