Skip to content

Commit cee0550

Browse files
ooctipuskellyguo11
andauthored
[Newton]Replaces PhysxSchema API call with string Token get and set (#4102)
# Description PhysxSchema requires omni.physx packages which is not available if ov is not available. Since it is not a pxr pacakge, we use string rather than api to avoid dependency on ov. ## Checklist - [ ] I have read and understood the [contribution guidelines](https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html) - [ ] I have run the [`pre-commit` checks](https://pre-commit.com/) with `./isaaclab.sh --format` - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] I have updated the changelog and the corresponding version in the extension's `config/extension.toml` file - [ ] I have added my name to the `CONTRIBUTORS.md` or my name already exists there <!-- As you go through the checklist above, you can mark something as done by putting an x character in it For example, - [x] I have done this task - [ ] I have not done this task --> --------- Signed-off-by: ooctipus <[email protected]> Signed-off-by: Kelly Guo <[email protected]> Co-authored-by: Kelly Guo <[email protected]>
1 parent c063da6 commit cee0550

File tree

8 files changed

+123
-111
lines changed

8 files changed

+123
-111
lines changed

source/isaaclab/isaaclab/envs/ui/base_env_window.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import omni.kit.app
1616
import omni.kit.commands
1717
import omni.usd
18-
from pxr import PhysxSchema, Sdf, Usd, UsdGeom, UsdPhysics
18+
from pxr import Sdf, Usd, UsdGeom, UsdPhysics
1919

2020
from isaaclab.sim.utils.stage import get_current_stage
2121
from isaaclab.ui.widgets import ManagerLiveVisualizer
@@ -352,11 +352,11 @@ def _toggle_recording_animation_fn(self, value: bool):
352352
# if prim has articulation then disable it
353353
if prim.HasAPI(UsdPhysics.ArticulationRootAPI):
354354
prim.RemoveAPI(UsdPhysics.ArticulationRootAPI)
355-
prim.RemoveAPI(PhysxSchema.PhysxArticulationAPI)
355+
prim.RemoveAppliedSchema("PhysxArticulationAPI")
356356
# if prim has rigid body then disable it
357357
if prim.HasAPI(UsdPhysics.RigidBodyAPI):
358358
prim.RemoveAPI(UsdPhysics.RigidBodyAPI)
359-
prim.RemoveAPI(PhysxSchema.PhysxRigidBodyAPI)
359+
prim.RemoveAppliedSchema("PhysxRigidBodyAPI")
360360
# if prim is a joint type then disable it
361361
if prim.IsA(UsdPhysics.Joint):
362362
prim.GetAttribute("physics:jointEnabled").Set(False)

source/isaaclab/isaaclab/markers/visualization_markers.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
import omni.kit.commands
2828
import omni.physx.scripts.utils as physx_utils
29-
from pxr import Gf, PhysxSchema, Sdf, Usd, UsdGeom, UsdPhysics, Vt
29+
from pxr import Gf, Sdf, Usd, UsdGeom, UsdPhysics, Vt
3030

3131
import isaaclab.sim as sim_utils
3232
import isaaclab.sim.utils.stage as stage_utils
@@ -390,10 +390,10 @@ def _process_prototype_prim(self, prim: Usd.Prim):
390390
# check if it is physics body -> if so, remove it
391391
if child_prim.HasAPI(UsdPhysics.ArticulationRootAPI):
392392
child_prim.RemoveAPI(UsdPhysics.ArticulationRootAPI)
393-
child_prim.RemoveAPI(PhysxSchema.PhysxArticulationAPI)
393+
child_prim.RemoveAppliedSchema("PhysxArticulationAPI")
394394
if child_prim.HasAPI(UsdPhysics.RigidBodyAPI):
395395
child_prim.RemoveAPI(UsdPhysics.RigidBodyAPI)
396-
child_prim.RemoveAPI(PhysxSchema.PhysxRigidBodyAPI)
396+
child_prim.RemoveAppliedSchema("PhysxRigidBodyAPI")
397397
if child_prim.IsA(UsdPhysics.Joint):
398398
child_prim.GetAttribute("physics:jointEnabled").Set(False)
399399
# check if prim is instanced -> if so, make it uninstanceable

source/isaaclab/isaaclab/scene/interactive_scene.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import carb
1212
from isaacsim.core.prims import XFormPrim
1313
from isaacsim.core.version import get_version
14-
from pxr import PhysxSchema
1514

1615
import isaaclab.sim as sim_utils
1716
from isaaclab.assets import Articulation, ArticulationCfg, AssetBaseCfg
@@ -290,7 +289,7 @@ def physics_scene_path(self) -> str:
290289
"""The path to the USD Physics Scene."""
291290
if self._physics_scene_path is None:
292291
for prim in self.stage.Traverse():
293-
if prim.HasAPI(PhysxSchema.PhysxSceneAPI):
292+
if "PhysxSceneAPI" in prim.GetAppliedSchemas():
294293
self._physics_scene_path = prim.GetPrimPath().pathString
295294
logger.info(f"Physics scene prim path: {self._physics_scene_path}")
296295
break

source/isaaclab/isaaclab/sim/converters/mesh_converter.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
import omni
1111
import omni.kit.commands
12-
import omni.usd
1312
from isaacsim.core.utils.extensions import enable_extension
1413
from pxr import Gf, Tf, Usd, UsdGeom, UsdPhysics, UsdUtils
1514

source/isaaclab/isaaclab/sim/schemas/schemas.py

Lines changed: 81 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,16 @@
1111

1212
import omni.physx.scripts.utils as physx_utils
1313
from omni.physx.scripts import deformableUtils as deformable_utils
14-
from pxr import PhysxSchema, Usd, UsdPhysics
14+
from pxr import Usd, UsdPhysics
1515

1616
from isaaclab.sim.utils.stage import get_current_stage
17+
from isaaclab.utils.string import to_camel_case
1718

1819
from ..utils import (
1920
apply_nested,
2021
find_global_fixed_joint_prim,
2122
get_all_matching_child_prims,
23+
safe_set_attribute_on_usd_prim,
2224
safe_set_attribute_on_usd_schema,
2325
)
2426
from . import schemas_cfg
@@ -116,9 +118,10 @@ def modify_articulation_root_properties(
116118
if not UsdPhysics.ArticulationRootAPI(articulation_prim):
117119
return False
118120
# retrieve the articulation api
119-
physx_articulation_api = PhysxSchema.PhysxArticulationAPI(articulation_prim)
120-
if not physx_articulation_api:
121-
physx_articulation_api = PhysxSchema.PhysxArticulationAPI.Apply(articulation_prim)
121+
122+
applied_schemas = articulation_prim.GetAppliedSchemas()
123+
if "PhysxArticulationAPI" not in applied_schemas:
124+
articulation_prim.AddAppliedSchema("PhysxArticulationAPI")
122125

123126
# convert to dict
124127
cfg = cfg.to_dict()
@@ -127,7 +130,10 @@ def modify_articulation_root_properties(
127130

128131
# set into physx api
129132
for attr_name, value in cfg.items():
130-
safe_set_attribute_on_usd_schema(physx_articulation_api, attr_name, value, camel_case=True)
133+
# safe_set_attribute_on_usd_schema(physx_articulation_api, attr_name, value, camel_case=True)
134+
safe_set_attribute_on_usd_prim(
135+
articulation_prim, f"physxArticulation:{to_camel_case(attr_name)}", value, camel_case=True
136+
)
131137

132138
# fix root link based on input
133139
# we do the fixed joint processing later to not interfere with setting other properties
@@ -165,23 +171,28 @@ def modify_articulation_root_properties(
165171
parent_prim = articulation_prim.GetParent()
166172
# apply api to parent
167173
UsdPhysics.ArticulationRootAPI.Apply(parent_prim)
168-
PhysxSchema.PhysxArticulationAPI.Apply(parent_prim)
174+
parent_applied_schemas = parent_prim.GetAppliedSchemas()
175+
if "PhysxArticulationAPI" not in parent_applied_schemas:
176+
parent_prim.AddAppliedSchema("PhysxArticulationAPI")
169177

170178
# copy the attributes
171179
# -- usd attributes
172180
usd_articulation_api = UsdPhysics.ArticulationRootAPI(articulation_prim)
173181
for attr_name in usd_articulation_api.GetSchemaAttributeNames():
174182
attr = articulation_prim.GetAttribute(attr_name)
175-
parent_prim.GetAttribute(attr_name).Set(attr.Get())
183+
parent_attr = parent_prim.GetAttribute(attr_name)
184+
if not parent_attr:
185+
parent_attr = parent_prim.CreateAttribute(attr_name, attr.GetTypeName())
186+
parent_attr.Set(attr.Get())
176187
# -- physx attributes
177-
physx_articulation_api = PhysxSchema.PhysxArticulationAPI(articulation_prim)
178-
for attr_name in physx_articulation_api.GetSchemaAttributeNames():
179-
attr = articulation_prim.GetAttribute(attr_name)
180-
parent_prim.GetAttribute(attr_name).Set(attr.Get())
188+
for attr_name, value in cfg.items():
189+
safe_set_attribute_on_usd_prim(
190+
parent_prim, f"physxArticulation:{to_camel_case(attr_name)}", value, camel_case=True
191+
)
181192

182193
# remove api from root
183194
articulation_prim.RemoveAPI(UsdPhysics.ArticulationRootAPI)
184-
articulation_prim.RemoveAPI(PhysxSchema.PhysxArticulationAPI)
195+
articulation_prim.RemoveAppliedSchema("PhysxArticulationAPI")
185196

186197
# success
187198
return True
@@ -268,9 +279,9 @@ def modify_rigid_body_properties(
268279
# retrieve the USD rigid-body api
269280
usd_rigid_body_api = UsdPhysics.RigidBodyAPI(rigid_body_prim)
270281
# retrieve the physx rigid-body api
271-
physx_rigid_body_api = PhysxSchema.PhysxRigidBodyAPI(rigid_body_prim)
272-
if not physx_rigid_body_api:
273-
physx_rigid_body_api = PhysxSchema.PhysxRigidBodyAPI.Apply(rigid_body_prim)
282+
applied_schemas = rigid_body_prim.GetAppliedSchemas()
283+
if "PhysxRigidBodyAPI" not in applied_schemas:
284+
rigid_body_prim.AddAppliedSchema("PhysxRigidBodyAPI")
274285

275286
# convert to dict
276287
cfg = cfg.to_dict()
@@ -280,7 +291,9 @@ def modify_rigid_body_properties(
280291
safe_set_attribute_on_usd_schema(usd_rigid_body_api, attr_name, value, camel_case=True)
281292
# set into PhysX API
282293
for attr_name, value in cfg.items():
283-
safe_set_attribute_on_usd_schema(physx_rigid_body_api, attr_name, value, camel_case=True)
294+
safe_set_attribute_on_usd_prim(
295+
rigid_body_prim, f"physxRigidBody:{to_camel_case(attr_name)}", value, camel_case=True
296+
)
284297
# success
285298
return True
286299

@@ -365,9 +378,9 @@ def modify_collision_properties(
365378
# retrieve the mesh collision api
366379
usd_mesh_collision_api = UsdPhysics.MeshCollisionAPI(collider_prim)
367380
# retrieve the collision api
368-
physx_collision_api = PhysxSchema.PhysxCollisionAPI(collider_prim)
369-
if not physx_collision_api:
370-
physx_collision_api = PhysxSchema.PhysxCollisionAPI.Apply(collider_prim)
381+
applied_schemas = collider_prim.GetAppliedSchemas()
382+
if "PhysxCollisionAPI" not in applied_schemas:
383+
collider_prim.AddAppliedSchema("PhysxCollisionAPI")
371384

372385
# convert to dict
373386
cfg = cfg.to_dict()
@@ -380,7 +393,9 @@ def modify_collision_properties(
380393
safe_set_attribute_on_usd_schema(usd_mesh_collision_api, attr_name, value, camel_case=True)
381394
# set into PhysX API
382395
for attr_name, value in cfg.items():
383-
safe_set_attribute_on_usd_schema(physx_collision_api, attr_name, value, camel_case=True)
396+
safe_set_attribute_on_usd_prim(
397+
collider_prim, f"physxCollision:{to_camel_case(attr_name)}", value, camel_case=True
398+
)
384399
# success
385400
return True
386401

@@ -515,17 +530,18 @@ def activate_contact_sensors(prim_path: str, threshold: float = 0.0, stage: Usd.
515530
# check its children
516531
if child_prim.HasAPI(UsdPhysics.RigidBodyAPI):
517532
# set sleep threshold to zero
518-
rb = PhysxSchema.PhysxRigidBodyAPI.Get(stage, prim.GetPrimPath())
519-
rb.CreateSleepThresholdAttr().Set(0.0)
533+
applied_schemas = child_prim.GetAppliedSchemas()
534+
if "PhysxRigidBodyAPI" not in applied_schemas:
535+
child_prim.AddAppliedSchema("PhysxRigidBodyAPI")
536+
safe_set_attribute_on_usd_prim(child_prim, "PhysxRigidBodyAPI:sleep_threshold", 0.0, camel_case=True)
520537
# add contact report API with threshold of zero
521-
if not child_prim.HasAPI(PhysxSchema.PhysxContactReportAPI):
538+
if "PhysxContactReportAPI" not in applied_schemas:
522539
logger.debug(f"Adding contact report API to prim: '{child_prim.GetPrimPath()}'")
523-
cr_api = PhysxSchema.PhysxContactReportAPI.Apply(child_prim)
540+
child_prim.AddAppliedSchema("PhysxContactReportAPI")
524541
else:
525542
logger.debug(f"Contact report API already exists on prim: '{child_prim.GetPrimPath()}'")
526-
cr_api = PhysxSchema.PhysxContactReportAPI.Get(stage, child_prim.GetPrimPath())
527543
# set threshold to zero
528-
cr_api.CreateThresholdAttr().Set(threshold)
544+
safe_set_attribute_on_usd_prim(child_prim, "physxContactReport:threshold", threshold, camel_case=True)
529545
# increment number of contact sensors
530546
num_contact_sensors += 1
531547
else:
@@ -600,17 +616,19 @@ def modify_joint_drive_properties(
600616
return False
601617
# check that prim is not a tendon child prim
602618
# note: root prim is what "controls" the tendon so we still want to apply the drive to it
603-
if prim.HasAPI(PhysxSchema.PhysxTendonAxisAPI) and not prim.HasAPI(PhysxSchema.PhysxTendonAxisRootAPI):
619+
applied_schemas = prim.GetAppliedSchemas()
620+
has_tendon_axis = "PhysxTendonAxisAPI" in applied_schemas
621+
has_tendon_axis_root = "PhysxTendonAxisRootAPI" in applied_schemas
622+
if has_tendon_axis and not has_tendon_axis_root:
604623
return False
605624

606625
# check if prim has joint drive applied on it
607626
usd_drive_api = UsdPhysics.DriveAPI(prim, drive_api_name)
608627
if not usd_drive_api:
609628
usd_drive_api = UsdPhysics.DriveAPI.Apply(prim, drive_api_name)
610629
# check if prim has Physx joint drive applied on it
611-
physx_joint_api = PhysxSchema.PhysxJointAPI(prim)
612-
if not physx_joint_api:
613-
physx_joint_api = PhysxSchema.PhysxJointAPI.Apply(prim)
630+
if "PhysxJointAPI" not in applied_schemas:
631+
prim.AddAppliedSchema("PhysxJointAPI")
614632

615633
# mapping from configuration name to USD attribute name
616634
cfg_to_usd_map = {
@@ -639,7 +657,7 @@ def modify_joint_drive_properties(
639657
for attr_name in ["max_velocity"]:
640658
value = cfg.pop(attr_name, None)
641659
attr_name = cfg_to_usd_map[attr_name]
642-
safe_set_attribute_on_usd_schema(physx_joint_api, attr_name, value, camel_case=True)
660+
safe_set_attribute_on_usd_prim(prim, f"physxJoint:{to_camel_case(attr_name)}", value, camel_case=True)
643661
# set into USD API
644662
for attr_name, attr_value in cfg.items():
645663
attr_name = cfg_to_usd_map.get(attr_name, attr_name)
@@ -691,24 +709,22 @@ def modify_fixed_tendon_properties(
691709
# get USD prim
692710
tendon_prim = stage.GetPrimAtPath(prim_path)
693711
# check if prim has fixed tendon applied on it
694-
has_root_fixed_tendon = tendon_prim.HasAPI(PhysxSchema.PhysxTendonAxisRootAPI)
712+
applied_schemas = tendon_prim.GetAppliedSchemas()
713+
has_root_fixed_tendon = "PhysxTendonAxisRootAPI" in applied_schemas
695714
if not has_root_fixed_tendon:
696715
return False
697716

717+
cfg = cfg.to_dict()
698718
# resolve all available instances of the schema since it is multi-instance
699-
for schema_name in tendon_prim.GetAppliedSchemas():
719+
for schema_name in applied_schemas:
700720
# only consider the fixed tendon schema
701721
if "PhysxTendonAxisRootAPI" not in schema_name:
702722
continue
703-
# retrieve the USD tendon api
704-
instance_name = schema_name.split(":")[-1]
705-
physx_tendon_axis_api = PhysxSchema.PhysxTendonAxisRootAPI(tendon_prim, instance_name)
706-
707-
# convert to dict
708-
cfg = cfg.to_dict()
709723
# set into PhysX API
710724
for attr_name, value in cfg.items():
711-
safe_set_attribute_on_usd_schema(physx_tendon_axis_api, attr_name, value, camel_case=True)
725+
safe_set_attribute_on_usd_prim(
726+
tendon_prim, f"{schema_name}:{to_camel_case(attr_name)}", value, camel_case=True
727+
)
712728
# success
713729
return True
714730

@@ -757,29 +773,24 @@ def modify_spatial_tendon_properties(
757773
# get USD prim
758774
tendon_prim = stage.GetPrimAtPath(prim_path)
759775
# check if prim has spatial tendon applied on it
760-
has_spatial_tendon = tendon_prim.HasAPI(PhysxSchema.PhysxTendonAttachmentRootAPI) or tendon_prim.HasAPI(
761-
PhysxSchema.PhysxTendonAttachmentLeafAPI
776+
applied_schemas = tendon_prim.GetAppliedSchemas()
777+
has_spatial_tendon = ("PhysxTendonAttachmentRootAPI" in applied_schemas) or (
778+
"PhysxTendonAttachmentLeafAPI" in applied_schemas
762779
)
763780
if not has_spatial_tendon:
764781
return False
765782

783+
cfg = cfg.to_dict()
766784
# resolve all available instances of the schema since it is multi-instance
767-
for schema_name in tendon_prim.GetAppliedSchemas():
785+
for schema_name in applied_schemas:
768786
# only consider the spatial tendon schema
769-
# retrieve the USD tendon api
770-
if "PhysxTendonAttachmentRootAPI" in schema_name:
771-
instance_name = schema_name.split(":")[-1]
772-
physx_tendon_spatial_api = PhysxSchema.PhysxTendonAttachmentRootAPI(tendon_prim, instance_name)
773-
elif "PhysxTendonAttachmentLeafAPI" in schema_name:
774-
instance_name = schema_name.split(":")[-1]
775-
physx_tendon_spatial_api = PhysxSchema.PhysxTendonAttachmentLeafAPI(tendon_prim, instance_name)
776-
else:
787+
if "PhysxTendonAttachmentRootAPI" not in schema_name and "PhysxTendonAttachmentLeafAPI" not in schema_name:
777788
continue
778-
# convert to dict
779-
cfg = cfg.to_dict()
780789
# set into PhysX API
781790
for attr_name, value in cfg.items():
782-
safe_set_attribute_on_usd_schema(physx_tendon_spatial_api, attr_name, value, camel_case=True)
791+
safe_set_attribute_on_usd_prim(
792+
tendon_prim, f"{schema_name}:{to_camel_case(attr_name)}", value, camel_case=True
793+
)
783794
# success
784795
return True
785796

@@ -837,8 +848,9 @@ def define_deformable_body_properties(
837848
# get deformable-body USD prim
838849
mesh_prim = matching_prims[0]
839850
# check if prim has deformable-body applied on it
840-
if not PhysxSchema.PhysxDeformableBodyAPI(mesh_prim):
841-
PhysxSchema.PhysxDeformableBodyAPI.Apply(mesh_prim)
851+
applied_schemas = mesh_prim.GetAppliedSchemas()
852+
if "PhysxDeformableBodyAPI" not in applied_schemas:
853+
mesh_prim.AddAppliedSchema("PhysxDeformableBodyAPI")
842854
# set deformable body properties
843855
modify_deformable_body_properties(mesh_prim.GetPrimPath(), cfg, stage)
844856

@@ -895,14 +907,10 @@ def modify_deformable_body_properties(
895907
deformable_body_prim = stage.GetPrimAtPath(prim_path)
896908

897909
# check if the prim is valid and has the deformable-body API
898-
if not deformable_body_prim.IsValid() or not PhysxSchema.PhysxDeformableBodyAPI(deformable_body_prim):
910+
applied_schemas = deformable_body_prim.GetAppliedSchemas()
911+
if not deformable_body_prim.IsValid() or "PhysxDeformableBodyAPI" not in applied_schemas:
899912
return False
900913

901-
# retrieve the physx deformable-body api
902-
physx_deformable_body_api = PhysxSchema.PhysxDeformableBodyAPI(deformable_body_prim)
903-
# retrieve the physx deformable api
904-
physx_deformable_api = PhysxSchema.PhysxDeformableAPI(physx_deformable_body_api)
905-
906914
# convert to dict
907915
cfg = cfg.to_dict()
908916
# set into deformable body API
@@ -930,15 +938,22 @@ def modify_deformable_body_properties(
930938
if not status:
931939
return False
932940

933-
# obtain the PhysX collision API (this is set when the deformable body is added)
934-
physx_collision_api = PhysxSchema.PhysxCollisionAPI(deformable_body_prim)
941+
applied_schemas = deformable_body_prim.GetAppliedSchemas()
942+
if "PhysxCollisionAPI" not in applied_schemas:
943+
deformable_body_prim.AddAppliedSchema("PhysxCollisionAPI")
944+
if "PhysxDeformableAPI" not in applied_schemas:
945+
deformable_body_prim.AddAppliedSchema("PhysxDeformableAPI")
935946

936947
# set into PhysX API
937948
for attr_name, value in cfg.items():
938949
if attr_name in ["rest_offset", "contact_offset"]:
939-
safe_set_attribute_on_usd_schema(physx_collision_api, attr_name, value, camel_case=True)
950+
safe_set_attribute_on_usd_prim(
951+
deformable_body_prim, f"physxCollision:{to_camel_case(attr_name)}", value, camel_case=True
952+
)
940953
else:
941-
safe_set_attribute_on_usd_schema(physx_deformable_api, attr_name, value, camel_case=True)
954+
safe_set_attribute_on_usd_prim(
955+
deformable_body_prim, f"physxDeformable:{to_camel_case(attr_name)}", value, camel_case=True
956+
)
942957

943958
# success
944959
return True

0 commit comments

Comments
 (0)