-
Notifications
You must be signed in to change notification settings - Fork 36
Sphere and initial object velocity #479
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
e022cf4
548ef02
5dfb963
17b5413
1dde292
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,6 +10,7 @@ | |
|
|
||
| if TYPE_CHECKING: | ||
| from isaaclab_arena.assets.hdr_image import HDRImage | ||
| from isaaclab.assets import RigidObjectCfg | ||
| from isaaclab.sim.spawners.from_files.from_files_cfg import GroundPlaneCfg | ||
| from isaaclab.utils.assets import ISAAC_NUCLEUS_DIR, ISAACLAB_NUCLEUS_DIR | ||
|
|
||
|
|
@@ -419,6 +420,61 @@ def __init__( | |
| super().__init__(instance_name=instance_name, prim_path=prim_path, initial_pose=initial_pose) | ||
|
|
||
|
|
||
| @register_asset | ||
| class Sphere(LibraryObject): | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nice!! |
||
| """ | ||
| A sphere with rigid body physics (dynamic by default). | ||
| """ | ||
|
|
||
| name = "sphere" | ||
| tags = ["object"] | ||
| object_type = ObjectType.SPAWNER | ||
| scale = (1.0, 1.0, 1.0) | ||
| default_spawner_cfg = sim_utils.SphereCfg( | ||
| radius=0.1, | ||
| visual_material=sim_utils.PreviewSurfaceCfg(diffuse_color=(0.8, 0.2, 0.2)), | ||
| collision_props=sim_utils.CollisionPropertiesCfg(), | ||
| rigid_props=sim_utils.RigidBodyPropertiesCfg( | ||
| solver_position_iteration_count=16, | ||
| solver_velocity_iteration_count=1, | ||
| max_angular_velocity=1000.0, | ||
| max_linear_velocity=1000.0, | ||
| max_depenetration_velocity=5.0, | ||
| disable_gravity=False, | ||
| ), | ||
| mass_props=sim_utils.MassPropertiesCfg(mass=0.25), | ||
| ) | ||
|
Comment on lines
+437
to
+446
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there some reason we need to change these |
||
|
|
||
| def __init__( | ||
| self, | ||
| instance_name: str | None = None, | ||
| prim_path: str | None = None, | ||
| initial_pose: Pose | None = None, | ||
| scale: tuple[float, float, float] | None = None, | ||
| spawner_cfg: sim_utils.SphereCfg = default_spawner_cfg, | ||
| ): | ||
| self.spawner_cfg = spawner_cfg | ||
| super().__init__( | ||
| instance_name=instance_name, | ||
| prim_path=prim_path, | ||
| initial_pose=initial_pose, | ||
| scale=scale, | ||
| ) | ||
|
|
||
| def _generate_spawner_cfg(self) -> RigidObjectCfg: | ||
| object_cfg = RigidObjectCfg( | ||
| prim_path=self.prim_path, | ||
| spawn=self.spawner_cfg, | ||
| ) | ||
| object_cfg = self._add_initial_pose_to_cfg(object_cfg) | ||
| if self.initial_velocity is not None: | ||
| object_cfg.init_state.lin_vel = self.initial_velocity | ||
| return object_cfg | ||
|
|
||
| def _requires_reset_pose_event(self) -> bool: | ||
| return self.get_initial_pose() is not None and self.reset_pose | ||
|
Comment on lines
+464
to
+475
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a bit messy. We don't want to define these functions per object in the library. The problem you're trying to get around here is that the spawner object type only supports I think we need to solve this at a level higher in the heirachy though. Solving this per-specific library object is going to lead to a lot of duplication in the future. I think we need to separate "does something provide a custom spawner?" from "what type of object is this?". Right now they are coupled together through |
||
|
|
||
|
|
||
| @register_asset | ||
| class DomeLight(LibraryObject): | ||
| """A dome light, optionally textured with an HDR image environment map. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,6 +12,9 @@ | |
| HEADLESS = True | ||
| INITIAL_POSITION_EPS = 0.1 # The cracker box falls slightly. | ||
|
|
||
| # For object initial velocity test: min displacement in velocity direction | ||
| OBJECT_VELOCITY_MIN_DISPLACEMENT = 0.05 # minimum movement in meters | ||
|
|
||
|
|
||
| def _test_set_object_pose_per_env_event(simulation_app): | ||
| """Returns a scene which we use for these tests.""" | ||
|
|
@@ -107,6 +110,76 @@ def _test_set_object_pose_per_env_event(simulation_app): | |
| return True | ||
|
|
||
|
|
||
| def _test_object_moves_with_initial_velocity(simulation_app): | ||
| """Test that a sphere moves with the given initial velocity after reset.""" | ||
| import isaaclab.sim as sim_utils | ||
|
|
||
| from isaaclab_arena.assets.asset_registry import AssetRegistry | ||
| from isaaclab_arena.cli.isaaclab_arena_cli import get_isaaclab_arena_cli_parser | ||
| from isaaclab_arena.environments.arena_env_builder import ArenaEnvBuilder | ||
| from isaaclab_arena.environments.isaaclab_arena_environment import IsaacLabArenaEnvironment | ||
| from isaaclab_arena.scene.scene import Scene | ||
| from isaaclab_arena.utils.pose import Pose | ||
|
|
||
| asset_registry = AssetRegistry() | ||
| no_gravity_cfg = sim_utils.SphereCfg( | ||
| radius=0.1, | ||
| visual_material=sim_utils.PreviewSurfaceCfg(diffuse_color=(0.8, 0.2, 0.2)), | ||
| collision_props=sim_utils.CollisionPropertiesCfg(), | ||
| rigid_props=sim_utils.RigidBodyPropertiesCfg( | ||
| solver_position_iteration_count=16, | ||
| solver_velocity_iteration_count=1, | ||
| max_angular_velocity=1000.0, | ||
| max_linear_velocity=1000.0, | ||
| max_depenetration_velocity=5.0, | ||
| disable_gravity=True, | ||
| ), | ||
| mass_props=sim_utils.MassPropertiesCfg(mass=0.25), | ||
| ) | ||
| sphere = asset_registry.get_asset_by_name("sphere")(spawner_cfg=no_gravity_cfg) | ||
|
Comment on lines
+125
to
+139
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You shouldn't need to copy all these configs just to turn the gravity off. I think you should be able to access the particular property as an attribute.
That should work (and if it doesn't we have a problem). |
||
|
|
||
| initial_velocity = (-0.5, 0.0, 0.0) # There is a wall in +x | ||
| sphere.set_initial_pose(Pose(position_xyz=(0.0, 0.0, 0.5), rotation_wxyz=(1.0, 0.0, 0.0, 0.0))) | ||
| sphere.set_initial_linear_velocity(initial_velocity) | ||
|
|
||
| scene = Scene(assets=[sphere]) | ||
| isaaclab_arena_environment = IsaacLabArenaEnvironment( | ||
| name="object_initial_velocity_test", | ||
| scene=scene, | ||
| ) | ||
|
|
||
| args_cli = get_isaaclab_arena_cli_parser().parse_args([]) | ||
| args_cli.num_envs = 1 | ||
| env_builder = ArenaEnvBuilder(isaaclab_arena_environment, args_cli) | ||
| env = env_builder.make_registered() | ||
| env.reset() | ||
|
|
||
| try: | ||
| initial_position = env.unwrapped.scene[sphere.name].data.root_pose_w[0, :3].clone() | ||
| initial_position[:3] -= env.unwrapped.scene.env_origins[0] | ||
|
|
||
| for _ in tqdm.tqdm(range(NUM_STEPS)): | ||
| with torch.inference_mode(): | ||
| actions = torch.zeros(env.action_space.shape, device=env.unwrapped.device) | ||
| env.step(actions) | ||
|
|
||
| final_position = env.unwrapped.scene[sphere.name].data.root_pose_w[0, :3].clone() | ||
| final_position[:3] -= env.unwrapped.scene.env_origins[0] | ||
| displacement = final_position - initial_position | ||
| assert ( | ||
| displacement[0].item() < -OBJECT_VELOCITY_MIN_DISPLACEMENT # - x because initial velocity is in -x | ||
| ), f"Object did not move with given velocity: displacement in x was {displacement[0].item()}" | ||
|
Comment on lines
+170
to
+171
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems like a bit of a loose test. Shouldn't we be able to bound this amount more tightly? Shouldn't the amount moved be roughly equal to the |
||
|
|
||
| except Exception as e: | ||
| print(f"Error: {e}") | ||
| return False | ||
|
|
||
| finally: | ||
| env.close() | ||
|
|
||
| return True | ||
|
|
||
|
|
||
| def test_set_object_post_per_env_event(): | ||
| result = run_simulation_app_function( | ||
| _test_set_object_pose_per_env_event, | ||
|
|
@@ -115,5 +188,14 @@ def test_set_object_post_per_env_event(): | |
| assert result, f"Test {test_set_object_post_per_env_event.__name__} failed" | ||
|
|
||
|
|
||
| def test_object_moves_with_initial_velocity(): | ||
| result = run_simulation_app_function( | ||
| _test_object_moves_with_initial_velocity, | ||
| headless=HEADLESS, | ||
| ) | ||
| assert result, f"Test {test_object_moves_with_initial_velocity.__name__} failed" | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| test_set_object_post_per_env_event() | ||
| test_object_moves_with_initial_velocity() | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are these two conditions possible to be false?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, because self.object_cfg can exist but not have "lin_vel" attribure (e.g. the walls). Only articulated and rigid objects have it