Unverified Commit 952498c1 authored by Mayank Mittal's avatar Mayank Mittal Committed by GitHub

Adds clearer initialization errors for asset classes (#509)

# Description

Earlier, the error message for initializing asset classes (with invalid
prims) only checked "length != 1". However, the error messages are
clearer if we separate them for the null and many cases, respectively.
This MR fixes this for better error messages.

## Type of change

- New feature (non-breaking change which adds functionality)

## Checklist

- [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with
`./orbit.sh --format`
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] I have run all the tests with `./orbit.sh --test` and they pass
- [ ] I have updated the changelog and the corresponding version in the
extension's `config/extension.toml` file
- [x] I have added my name to the `CONTRIBUTORS.md` or my name already
exists there
parent 779107fc
......@@ -546,15 +546,23 @@ class Articulation(RigidObject):
if template_prim is None:
raise RuntimeError(f"Failed to find prim for expression: '{self.cfg.prim_path}'.")
template_prim_path = template_prim.GetPath().pathString
# find articulation root prims
root_prims = sim_utils.get_all_matching_child_prims(
template_prim_path, predicate=lambda prim: prim.HasAPI(UsdPhysics.ArticulationRootAPI)
)
if len(root_prims) != 1:
if len(root_prims) == 0:
raise RuntimeError(
f"Failed to find an articulation when resolving '{self.cfg.prim_path}'."
" Please ensure that the prim has 'USD ArticulationRootAPI' applied."
)
if len(root_prims) > 1:
raise RuntimeError(
f"Failed to find a single articulation root when resolving '{self.cfg.prim_path}'."
f" Found roots '{root_prims}' under '{template_prim_path}'."
f"Failed to find a single articulation when resolving '{self.cfg.prim_path}'."
f" Found multiple '{root_prims}' under '{template_prim_path}'."
" Please ensure that there is only one articulation in the prim path tree."
)
# resolve articulation root prim back into regex expression
root_prim_path = root_prims[0].GetPath().pathString
root_prim_path_expr = self.cfg.prim_path + root_prim_path[len(template_prim_path) :]
......
......@@ -300,25 +300,35 @@ class RigidObject(AssetBase):
if template_prim is None:
raise RuntimeError(f"Failed to find prim for expression: '{self.cfg.prim_path}'.")
template_prim_path = template_prim.GetPath().pathString
# find rigid root prims
root_prims = sim_utils.get_all_matching_child_prims(
template_prim_path, predicate=lambda prim: prim.HasAPI(UsdPhysics.RigidBodyAPI)
)
if len(root_prims) != 1:
if len(root_prims) == 0:
raise RuntimeError(
f"Failed to find a rigid body when resolving '{self.cfg.prim_path}'."
" Please ensure that the prim has 'USD RigidBodyAPI' applied."
)
if len(root_prims) > 1:
raise RuntimeError(
f"Failed to find a single rigid body when resolving '{self.cfg.prim_path}'."
f" Found multiple '{root_prims}' under '{template_prim_path}'."
" Please ensure that there is only one rigid body in the prim path tree."
)
# resolve root prim back into regex expression
root_prim_path = root_prims[0].GetPath().pathString
root_prim_path_expr = self.cfg.prim_path + root_prim_path[len(template_prim_path) :]
# -- object view
self._root_physx_view = self._physics_sim_view.create_rigid_body_view(root_prim_path_expr.replace(".*", "*"))
# log information about the articulation
carb.log_info(f"Rigid body initialized at: {self.cfg.prim_path} with root '{root_prim_path_expr}'.")
carb.log_info(f"Number of instances: {self.num_instances}")
carb.log_info(f"Number of bodies: {self.num_bodies}")
carb.log_info(f"Body names: {self.body_names}")
# create buffers
self._create_buffers()
# process configuration
......
......@@ -35,12 +35,13 @@ from omni.isaac.orbit.utils.assets import ISAAC_NUCLEUS_DIR
from omni.isaac.orbit.utils.math import default_orientation, random_orientation
def generate_cubes_scene(num_cubes: int = 1, height=1.0) -> tuple[RigidObject, torch.Tensor]:
def generate_cubes_scene(num_cubes: int = 1, height=1.0, has_api: bool = True) -> tuple[RigidObject, torch.Tensor]:
"""Generate a scene with the provided number of cubes.
Args:
num_cubes: Number of cubes to generate.
height: Height of the cubes.
has_api: Whether the cubes have a rigid body API on them.
Returns:
RigidObject: The rigid object representing the cubes.
......@@ -52,10 +53,21 @@ def generate_cubes_scene(num_cubes: int = 1, height=1.0) -> tuple[RigidObject, t
for i, origin in enumerate(origins):
prim_utils.create_prim(f"/World/Table_{i}", "Xform", translation=origin)
# Resolve spawn configuration
if has_api:
spawn_cfg = sim_utils.UsdFileCfg(
usd_path=f"{ISAAC_NUCLEUS_DIR}/Props/Blocks/DexCube/dex_cube_instanceable.usd",
)
else:
# since no rigid body properties defined, this is just a static collider
spawn_cfg = sim_utils.CuboidCfg(
size=(0.1, 0.1, 0.1),
collision_props=sim_utils.CollisionPropertiesCfg(),
)
# Create rigid object
cube_object_cfg = RigidObjectCfg(
prim_path="/World/Table_.*/Object",
spawn=sim_utils.UsdFileCfg(usd_path=f"{ISAAC_NUCLEUS_DIR}/Props/Blocks/DexCube/dex_cube_instanceable.usd"),
spawn=spawn_cfg,
init_state=RigidObjectCfg.InitialStateCfg(pos=(0.0, 0.0, height)),
)
cube_object = RigidObject(cfg=cube_object_cfg)
......@@ -99,6 +111,23 @@ class TestRigidObject(unittest.TestCase):
# update object
cube_object.update(sim.cfg.dt)
def test_initialization_with_no_rigid_body(self):
"""Test that initialization fails when no rigid body is found at the provided prim path."""
for num_cubes in (1, 2):
for device in ("cuda:0", "cpu"):
with self.subTest(num_cubes=num_cubes, device=device):
with build_simulation_context(device=device, auto_add_lighting=True) as sim:
cube_object, _ = generate_cubes_scene(num_cubes=num_cubes, has_api=False)
# Check that boundedness of rigid object is correct
self.assertEqual(ctypes.c_long.from_address(id(cube_object)).value, 1)
# Play sim
sim.reset()
# Check if object is initialized
self.assertFalse(cube_object._is_initialized)
def test_external_force_on_single_body(self):
"""Test application of external force on the base of the object.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment