From 740705b1e20307f2efd3ad999eb1918bccf18db8 Mon Sep 17 00:00:00 2001 From: Octi Zhang Date: Sun, 2 Aug 2026 05:56:44 -0700 Subject: [PATCH 1/3] Merge DexSuite into Lift --- .github/workflows/build.yaml | 8 +- .../source/_static/css/environment-browser.js | 1 - ...sfer_policies_between_physx_and_newton.rst | 4 +- .../newton/mjwarp-solver.rst | 2 +- .../newton/supported-features.rst | 2 +- docs/source/overview/environments.rst | 20 +- scripts/benchmarks/benchmark_hydra_resolve.py | 4 +- scripts/benchmarks/benchmark_lazy_export.py | 2 +- .../state_machine/lift_cube_sm.py | 2 +- .../changelog.d/mhaiderbhai-unify-lift.skip | 1 + ...on_state_recorder_term_task_integration.py | 2 +- .../changelog.d/mhaiderbhai-unify-lift.skip | 1 + source/isaaclab_physx/test/sim/test_cloner.py | 2 +- .../changelog.d/mhaiderbhai-unify-lift.skip | 1 + .../export/leapp_initialized_checkpoints.py | 2 +- .../test/export/test_leapp_export_flow.py | 4 +- .../test/export/test_rsl_rl_export_flow.py | 4 +- .../mhaiderbhai-unify-lift.major.rst | 16 + .../contrib/lift/config/franka/__init__.py | 19 +- .../lift}/config/franka/agents/__init__.py | 0 .../franka/agents/rl_games_ppo_cfg.yaml | 2 +- .../config/franka/agents/robomimic/bc.json | 0 .../config/franka/agents/robomimic/bcq.json | 0 .../config/franka/agents/rsl_rl_ppo_cfg.py | 41 ++ .../config/franka/agents/sb3_ppo_cfg.yaml | 0 .../config/franka/agents/skrl_ppo_cfg.yaml | 2 +- .../lift/config/franka/ik_abs_env_cfg.py | 2 +- .../lift/config/franka/ik_rel_env_cfg.py | 2 +- .../lift/config/franka/joint_pos_env_cfg.py | 4 +- .../lift/config/openarm/joint_pos_env_cfg.py | 24 +- ...ift_openarm_env_cfg.py => lift_env_cfg.py} | 50 +- .../dexsuite => contrib/lift}/mdp/__init__.py | 2 + .../contrib/lift/mdp/__init__.pyi | 17 + .../contrib/lift/mdp/observations.py | 32 + .../contrib/lift/mdp/rewards.py | 94 +++ .../isaaclab_tasks/core/dexsuite/__init__.py | 26 - .../core/dexsuite/config/__init__.py | 9 - .../core/dexsuite/config/franka/__init__.py | 34 - .../config/franka/agents/rsl_rl_ppo_cfg.py | 68 -- .../core/dexsuite/dexsuite_env_cfg.py | 604 ------------------ .../core/dexsuite/mdp/__init__.pyi | 71 -- .../core/dexsuite/mdp/observations.py | 259 -------- .../core/dexsuite/mdp/rewards.py | 369 ----------- .../core/dexsuite/mdp/terminations.py | 70 -- .../isaaclab_tasks/core/lift/__init__.py | 23 +- .../core/{dexsuite => lift}/adr_curriculum.py | 0 .../core/lift/config/__init__.py | 2 +- .../core/lift/config/franka/__init__.py | 25 +- .../config/franka/agents/rsl_rl_ppo_cfg.py | 87 ++- .../config/franka/franka_env_cfg.py} | 52 +- .../config/kuka_allegro/__init__.py | 18 +- .../config/kuka_allegro/agents/__init__.py | 0 .../config/kuka_allegro/agents/models.py | 2 +- .../kuka_allegro/agents/rsl_rl_ppo_cfg.py | 20 +- .../config/kuka_allegro/camera_cfg.py | 8 +- .../kuka_allegro_camera_env_cfg.py} | 22 +- .../kuka_allegro/kuka_allegro_env_cfg.py} | 24 +- .../isaaclab_tasks/core/lift/lift_env_cfg.py | 583 ++++++++++++++--- .../isaaclab_tasks/core/lift/mdp/__init__.py | 2 - .../isaaclab_tasks/core/lift/mdp/__init__.pyi | 76 ++- .../mdp/commands/__init__.py | 0 .../mdp/commands/__init__.pyi | 0 .../mdp/commands/pose_commands.py | 0 .../mdp/commands/pose_commands_cfg.py | 0 .../{dexsuite => lift}/mdp/curriculums.py | 0 .../core/{dexsuite => lift}/mdp/events.py | 2 +- .../core/{dexsuite => lift}/mdp/events_cfg.py | 2 +- .../core/lift/mdp/observations.py | 274 ++++++-- .../isaaclab_tasks/core/lift/mdp/rewards.py | 429 ++++++++++--- .../core/lift/mdp/terminations.py | 111 ++-- .../core/{dexsuite => lift}/mdp/utils.py | 0 .../test/benchmarking/configs.yaml | 4 +- .../test/core/test_environment_determinism.py | 2 +- source/isaaclab_tasks/test/core/test_hydra.py | 2 +- .../test/core/test_lift_env_cfg.py | 60 ++ ...s.py => test_lift_kuka_ovphysx_presets.py} | 2 +- .../test/core/test_lift_package_structure.py | 52 ++ ....py => test_rendering_lift_kuka_hetero.py} | 10 +- ...est_rendering_lift_kuka_hetero_kitless.py} | 14 +- ...ro.py => test_rendering_lift_kuka_homo.py} | 10 +- ... test_rendering_lift_kuka_homo_kitless.py} | 14 +- .../newton-isaacsim_rtx_renderer-albedo.png | 0 .../newton-isaacsim_rtx_renderer-depth.png | 0 ...aacsim_rtx_renderer-distance_to_camera.png | 0 ...m_rtx_renderer-distance_to_image_plane.png | 0 ...renderer-instance_id_segmentation_fast.png | 0 ...sim_rtx_renderer-instance_segmentation.png | 0 .../newton-isaacsim_rtx_renderer-normals.png | 0 .../newton-isaacsim_rtx_renderer-rgb.png | 0 .../newton-isaacsim_rtx_renderer-rgba.png | 0 ...sim_rtx_renderer-semantic_segmentation.png | 0 ...nderer-simple_shading_constant_diffuse.png | 0 ...tx_renderer-simple_shading_diffuse_mdl.png | 0 ...m_rtx_renderer-simple_shading_full_mdl.png | 0 .../newton-newton_renderer-depth.png | 0 ...ton-newton_renderer-distance_to_camera.png | 0 ...ewton_renderer-distance_to_image_plane.png | 0 ...-newton_renderer-instance_segmentation.png | 0 .../newton-newton_renderer-normals.png | 0 .../newton-newton_renderer-rgb.png | 0 .../newton-newton_renderer-rgba.png | 0 ...-newton_renderer-semantic_segmentation.png | 0 .../newton-ovrtx_renderer-albedo.png | 0 .../newton-ovrtx_renderer-depth.png | 0 ...wton-ovrtx_renderer-distance_to_camera.png | 0 ...ovrtx_renderer-distance_to_image_plane.png | 0 ...n-ovrtx_renderer-instance_segmentation.png | 0 .../newton-ovrtx_renderer-normals.png | 0 .../newton-ovrtx_renderer-rgb.png | 0 .../newton-ovrtx_renderer-rgba.png | 0 ...n-ovrtx_renderer-semantic_segmentation.png | 0 ...nderer-simple_shading_constant_diffuse.png | 0 ...tx_renderer-simple_shading_diffuse_mdl.png | 0 ...ovrtx_renderer-simple_shading_full_mdl.png | 0 .../physx-isaacsim_rtx_renderer-albedo.png | 0 .../physx-isaacsim_rtx_renderer-depth.png | 0 ...aacsim_rtx_renderer-distance_to_camera.png | 0 ...m_rtx_renderer-distance_to_image_plane.png | 0 ...renderer-instance_id_segmentation_fast.png | 0 ...sim_rtx_renderer-instance_segmentation.png | 0 ...x-isaacsim_rtx_renderer-motion_vectors.png | 0 .../physx-isaacsim_rtx_renderer-normals.png | 0 .../physx-isaacsim_rtx_renderer-rgb.png | 0 .../physx-isaacsim_rtx_renderer-rgba.png | 0 ...sim_rtx_renderer-semantic_segmentation.png | 0 ...nderer-simple_shading_constant_diffuse.png | 0 ...tx_renderer-simple_shading_diffuse_mdl.png | 0 ...m_rtx_renderer-simple_shading_full_mdl.png | 0 .../physx-newton_renderer-depth.png | 0 ...ysx-newton_renderer-distance_to_camera.png | 0 ...ewton_renderer-distance_to_image_plane.png | 0 ...-newton_renderer-instance_segmentation.png | 0 .../physx-newton_renderer-normals.png | 0 .../physx-newton_renderer-rgb.png | 0 .../physx-newton_renderer-rgba.png | 0 ...-newton_renderer-semantic_segmentation.png | 0 .../newton-isaacsim_rtx_renderer-albedo.png | 0 .../newton-isaacsim_rtx_renderer-depth.png | 0 ...aacsim_rtx_renderer-distance_to_camera.png | 0 ...m_rtx_renderer-distance_to_image_plane.png | 0 ...renderer-instance_id_segmentation_fast.png | 0 ...sim_rtx_renderer-instance_segmentation.png | 0 .../newton-isaacsim_rtx_renderer-normals.png | 0 .../newton-isaacsim_rtx_renderer-rgb.png | 0 .../newton-isaacsim_rtx_renderer-rgba.png | 0 ...sim_rtx_renderer-semantic_segmentation.png | 0 ...nderer-simple_shading_constant_diffuse.png | 0 ...tx_renderer-simple_shading_diffuse_mdl.png | 0 ...m_rtx_renderer-simple_shading_full_mdl.png | 0 .../newton-newton_renderer-depth.png | 0 ...ton-newton_renderer-distance_to_camera.png | 0 ...ewton_renderer-distance_to_image_plane.png | 0 ...-newton_renderer-instance_segmentation.png | 0 .../newton-newton_renderer-normals.png | 0 .../newton-newton_renderer-rgb.png | 0 .../newton-newton_renderer-rgba.png | 0 ...-newton_renderer-semantic_segmentation.png | 0 .../newton-ovrtx_renderer-albedo.png | 0 .../newton-ovrtx_renderer-depth.png | 0 ...wton-ovrtx_renderer-distance_to_camera.png | 0 ...ovrtx_renderer-distance_to_image_plane.png | 0 ...n-ovrtx_renderer-instance_segmentation.png | 0 .../newton-ovrtx_renderer-normals.png | 0 .../newton-ovrtx_renderer-rgb.png | 0 .../newton-ovrtx_renderer-rgba.png | 0 ...n-ovrtx_renderer-semantic_segmentation.png | 0 ...nderer-simple_shading_constant_diffuse.png | 0 ...tx_renderer-simple_shading_diffuse_mdl.png | 0 ...ovrtx_renderer-simple_shading_full_mdl.png | 0 .../ovphysx-newton_renderer-depth.png | 0 ...ysx-newton_renderer-distance_to_camera.png | 0 ...ewton_renderer-distance_to_image_plane.png | 0 ...-newton_renderer-instance_segmentation.png | 0 .../ovphysx-newton_renderer-normals.png | 0 .../ovphysx-newton_renderer-rgb.png | 0 .../ovphysx-newton_renderer-rgba.png | 0 ...-newton_renderer-semantic_segmentation.png | 0 .../ovphysx-ovrtx_renderer-albedo.png | 0 .../ovphysx-ovrtx_renderer-depth.png | 0 ...hysx-ovrtx_renderer-distance_to_camera.png | 0 ...ovrtx_renderer-distance_to_image_plane.png | 0 ...x-ovrtx_renderer-instance_segmentation.png | 0 .../ovphysx-ovrtx_renderer-motion_vectors.png | 0 .../ovphysx-ovrtx_renderer-normals.png | 0 .../ovphysx-ovrtx_renderer-rgb.png | 0 .../ovphysx-ovrtx_renderer-rgba.png | 0 ...x-ovrtx_renderer-semantic_segmentation.png | 0 ...nderer-simple_shading_constant_diffuse.png | 0 ...tx_renderer-simple_shading_diffuse_mdl.png | 0 ...ovrtx_renderer-simple_shading_full_mdl.png | 0 .../physx-isaacsim_rtx_renderer-albedo.png | 0 .../physx-isaacsim_rtx_renderer-depth.png | 0 ...aacsim_rtx_renderer-distance_to_camera.png | 0 ...m_rtx_renderer-distance_to_image_plane.png | 0 ...renderer-instance_id_segmentation_fast.png | 0 ...sim_rtx_renderer-instance_segmentation.png | 0 ...x-isaacsim_rtx_renderer-motion_vectors.png | 0 .../physx-isaacsim_rtx_renderer-normals.png | 0 .../physx-isaacsim_rtx_renderer-rgb.png | 0 .../physx-isaacsim_rtx_renderer-rgba.png | 0 ...sim_rtx_renderer-semantic_segmentation.png | 0 ...nderer-simple_shading_constant_diffuse.png | 0 ...tx_renderer-simple_shading_diffuse_mdl.png | 0 ...m_rtx_renderer-simple_shading_full_mdl.png | 0 .../physx-newton_renderer-depth.png | 0 ...ysx-newton_renderer-distance_to_camera.png | 0 ...ewton_renderer-distance_to_image_plane.png | 0 ...-newton_renderer-instance_segmentation.png | 0 .../physx-newton_renderer-normals.png | 0 .../physx-newton_renderer-rgb.png | 0 .../physx-newton_renderer-rgba.png | 0 ...-newton_renderer-semantic_segmentation.png | 0 .../test/rendering_test_utils.py | 44 +- .../test/test_parametrization_helpers.py | 8 +- tools/test_settings.py | 4 +- 215 files changed, 1804 insertions(+), 2063 deletions(-) create mode 100644 source/isaaclab/changelog.d/mhaiderbhai-unify-lift.skip create mode 100644 source/isaaclab_physx/changelog.d/mhaiderbhai-unify-lift.skip create mode 100644 source/isaaclab_rl/changelog.d/mhaiderbhai-unify-lift.skip create mode 100644 source/isaaclab_tasks/changelog.d/mhaiderbhai-unify-lift.major.rst rename source/isaaclab_tasks/isaaclab_tasks/{core/dexsuite => contrib/lift}/config/franka/agents/__init__.py (100%) rename source/isaaclab_tasks/isaaclab_tasks/{core => contrib}/lift/config/franka/agents/rl_games_ppo_cfg.yaml (98%) rename source/isaaclab_tasks/isaaclab_tasks/{core => contrib}/lift/config/franka/agents/robomimic/bc.json (100%) rename source/isaaclab_tasks/isaaclab_tasks/{core => contrib}/lift/config/franka/agents/robomimic/bcq.json (100%) create mode 100644 source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/agents/rsl_rl_ppo_cfg.py rename source/isaaclab_tasks/isaaclab_tasks/{core => contrib}/lift/config/franka/agents/sb3_ppo_cfg.yaml (100%) rename source/isaaclab_tasks/isaaclab_tasks/{core => contrib}/lift/config/franka/agents/skrl_ppo_cfg.yaml (98%) rename source/isaaclab_tasks/isaaclab_tasks/{core => contrib}/lift/config/franka/joint_pos_env_cfg.py (96%) rename source/isaaclab_tasks/isaaclab_tasks/contrib/lift/{config/openarm/lift_openarm_env_cfg.py => lift_env_cfg.py} (79%) rename source/isaaclab_tasks/isaaclab_tasks/{core/dexsuite => contrib/lift}/mdp/__init__.py (73%) create mode 100644 source/isaaclab_tasks/isaaclab_tasks/contrib/lift/mdp/__init__.pyi create mode 100644 source/isaaclab_tasks/isaaclab_tasks/contrib/lift/mdp/observations.py create mode 100644 source/isaaclab_tasks/isaaclab_tasks/contrib/lift/mdp/rewards.py delete mode 100644 source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/__init__.py delete mode 100644 source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/__init__.py delete mode 100644 source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/franka/__init__.py delete mode 100644 source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/franka/agents/rsl_rl_ppo_cfg.py delete mode 100644 source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/dexsuite_env_cfg.py delete mode 100644 source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/__init__.pyi delete mode 100644 source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/observations.py delete mode 100644 source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/rewards.py delete mode 100644 source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/terminations.py rename source/isaaclab_tasks/isaaclab_tasks/core/{dexsuite => lift}/adr_curriculum.py (100%) rename source/isaaclab_tasks/isaaclab_tasks/core/{dexsuite/config/franka/dexsuite_franka_env_cfg.py => lift/config/franka/franka_env_cfg.py} (83%) rename source/isaaclab_tasks/isaaclab_tasks/core/{dexsuite => lift}/config/kuka_allegro/__init__.py (64%) rename source/isaaclab_tasks/isaaclab_tasks/core/{dexsuite => lift}/config/kuka_allegro/agents/__init__.py (100%) rename source/isaaclab_tasks/isaaclab_tasks/core/{dexsuite => lift}/config/kuka_allegro/agents/models.py (99%) rename source/isaaclab_tasks/isaaclab_tasks/core/{dexsuite => lift}/config/kuka_allegro/agents/rsl_rl_ppo_cfg.py (84%) rename source/isaaclab_tasks/isaaclab_tasks/core/{dexsuite => lift}/config/kuka_allegro/camera_cfg.py (97%) rename source/isaaclab_tasks/isaaclab_tasks/core/{dexsuite/config/kuka_allegro/dexsuite_kuka_allegro_camera_env_cfg.py => lift/config/kuka_allegro/kuka_allegro_camera_env_cfg.py} (64%) rename source/isaaclab_tasks/isaaclab_tasks/core/{dexsuite/config/kuka_allegro/dexsuite_kuka_allegro_env_cfg.py => lift/config/kuka_allegro/kuka_allegro_env_cfg.py} (89%) rename source/isaaclab_tasks/isaaclab_tasks/core/{dexsuite => lift}/mdp/commands/__init__.py (100%) rename source/isaaclab_tasks/isaaclab_tasks/core/{dexsuite => lift}/mdp/commands/__init__.pyi (100%) rename source/isaaclab_tasks/isaaclab_tasks/core/{dexsuite => lift}/mdp/commands/pose_commands.py (100%) rename source/isaaclab_tasks/isaaclab_tasks/core/{dexsuite => lift}/mdp/commands/pose_commands_cfg.py (100%) rename source/isaaclab_tasks/isaaclab_tasks/core/{dexsuite => lift}/mdp/curriculums.py (100%) rename source/isaaclab_tasks/isaaclab_tasks/core/{dexsuite => lift}/mdp/events.py (99%) rename source/isaaclab_tasks/isaaclab_tasks/core/{dexsuite => lift}/mdp/events_cfg.py (99%) rename source/isaaclab_tasks/isaaclab_tasks/core/{dexsuite => lift}/mdp/utils.py (100%) create mode 100644 source/isaaclab_tasks/test/core/test_lift_env_cfg.py rename source/isaaclab_tasks/test/core/{test_dexsuite_kuka_ovphysx_presets.py => test_lift_kuka_ovphysx_presets.py} (94%) create mode 100644 source/isaaclab_tasks/test/core/test_lift_package_structure.py rename source/isaaclab_tasks/test/core/{test_rendering_dexsuite_kuka_homo.py => test_rendering_lift_kuka_hetero.py} (74%) rename source/isaaclab_tasks/test/core/{test_rendering_dexsuite_kuka_hetero_kitless.py => test_rendering_lift_kuka_hetero_kitless.py} (68%) rename source/isaaclab_tasks/test/core/{test_rendering_dexsuite_kuka_hetero.py => test_rendering_lift_kuka_homo.py} (74%) rename source/isaaclab_tasks/test/core/{test_rendering_dexsuite_kuka_homo_kitless.py => test_rendering_lift_kuka_homo_kitless.py} (65%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/newton-isaacsim_rtx_renderer-albedo.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/newton-isaacsim_rtx_renderer-depth.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/newton-isaacsim_rtx_renderer-distance_to_camera.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/newton-isaacsim_rtx_renderer-distance_to_image_plane.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/newton-isaacsim_rtx_renderer-instance_id_segmentation_fast.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/newton-isaacsim_rtx_renderer-instance_segmentation.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/newton-isaacsim_rtx_renderer-normals.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/newton-isaacsim_rtx_renderer-rgb.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/newton-isaacsim_rtx_renderer-rgba.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/newton-isaacsim_rtx_renderer-semantic_segmentation.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/newton-isaacsim_rtx_renderer-simple_shading_constant_diffuse.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/newton-isaacsim_rtx_renderer-simple_shading_diffuse_mdl.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/newton-isaacsim_rtx_renderer-simple_shading_full_mdl.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/newton-newton_renderer-depth.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/newton-newton_renderer-distance_to_camera.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/newton-newton_renderer-distance_to_image_plane.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/newton-newton_renderer-instance_segmentation.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/newton-newton_renderer-normals.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/newton-newton_renderer-rgb.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/newton-newton_renderer-rgba.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/newton-newton_renderer-semantic_segmentation.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/newton-ovrtx_renderer-albedo.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/newton-ovrtx_renderer-depth.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/newton-ovrtx_renderer-distance_to_camera.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/newton-ovrtx_renderer-distance_to_image_plane.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/newton-ovrtx_renderer-instance_segmentation.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/newton-ovrtx_renderer-normals.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/newton-ovrtx_renderer-rgb.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/newton-ovrtx_renderer-rgba.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/newton-ovrtx_renderer-semantic_segmentation.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/newton-ovrtx_renderer-simple_shading_constant_diffuse.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/newton-ovrtx_renderer-simple_shading_diffuse_mdl.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/newton-ovrtx_renderer-simple_shading_full_mdl.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/physx-isaacsim_rtx_renderer-albedo.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/physx-isaacsim_rtx_renderer-depth.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/physx-isaacsim_rtx_renderer-distance_to_camera.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/physx-isaacsim_rtx_renderer-distance_to_image_plane.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/physx-isaacsim_rtx_renderer-instance_id_segmentation_fast.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/physx-isaacsim_rtx_renderer-instance_segmentation.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/physx-isaacsim_rtx_renderer-motion_vectors.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/physx-isaacsim_rtx_renderer-normals.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/physx-isaacsim_rtx_renderer-rgb.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/physx-isaacsim_rtx_renderer-rgba.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/physx-isaacsim_rtx_renderer-semantic_segmentation.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/physx-isaacsim_rtx_renderer-simple_shading_constant_diffuse.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/physx-isaacsim_rtx_renderer-simple_shading_diffuse_mdl.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/physx-isaacsim_rtx_renderer-simple_shading_full_mdl.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/physx-newton_renderer-depth.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/physx-newton_renderer-distance_to_camera.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/physx-newton_renderer-distance_to_image_plane.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/physx-newton_renderer-instance_segmentation.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/physx-newton_renderer-normals.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/physx-newton_renderer-rgb.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/physx-newton_renderer-rgba.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_hetero => lift_kuka_hetero}/physx-newton_renderer-semantic_segmentation.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/newton-isaacsim_rtx_renderer-albedo.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/newton-isaacsim_rtx_renderer-depth.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/newton-isaacsim_rtx_renderer-distance_to_camera.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/newton-isaacsim_rtx_renderer-distance_to_image_plane.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/newton-isaacsim_rtx_renderer-instance_id_segmentation_fast.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/newton-isaacsim_rtx_renderer-instance_segmentation.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/newton-isaacsim_rtx_renderer-normals.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/newton-isaacsim_rtx_renderer-rgb.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/newton-isaacsim_rtx_renderer-rgba.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/newton-isaacsim_rtx_renderer-semantic_segmentation.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/newton-isaacsim_rtx_renderer-simple_shading_constant_diffuse.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/newton-isaacsim_rtx_renderer-simple_shading_diffuse_mdl.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/newton-isaacsim_rtx_renderer-simple_shading_full_mdl.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/newton-newton_renderer-depth.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/newton-newton_renderer-distance_to_camera.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/newton-newton_renderer-distance_to_image_plane.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/newton-newton_renderer-instance_segmentation.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/newton-newton_renderer-normals.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/newton-newton_renderer-rgb.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/newton-newton_renderer-rgba.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/newton-newton_renderer-semantic_segmentation.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/newton-ovrtx_renderer-albedo.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/newton-ovrtx_renderer-depth.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/newton-ovrtx_renderer-distance_to_camera.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/newton-ovrtx_renderer-distance_to_image_plane.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/newton-ovrtx_renderer-instance_segmentation.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/newton-ovrtx_renderer-normals.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/newton-ovrtx_renderer-rgb.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/newton-ovrtx_renderer-rgba.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/newton-ovrtx_renderer-semantic_segmentation.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/newton-ovrtx_renderer-simple_shading_constant_diffuse.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/newton-ovrtx_renderer-simple_shading_diffuse_mdl.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/newton-ovrtx_renderer-simple_shading_full_mdl.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/ovphysx-newton_renderer-depth.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/ovphysx-newton_renderer-distance_to_camera.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/ovphysx-newton_renderer-distance_to_image_plane.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/ovphysx-newton_renderer-instance_segmentation.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/ovphysx-newton_renderer-normals.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/ovphysx-newton_renderer-rgb.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/ovphysx-newton_renderer-rgba.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/ovphysx-newton_renderer-semantic_segmentation.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/ovphysx-ovrtx_renderer-albedo.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/ovphysx-ovrtx_renderer-depth.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/ovphysx-ovrtx_renderer-distance_to_camera.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/ovphysx-ovrtx_renderer-distance_to_image_plane.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/ovphysx-ovrtx_renderer-instance_segmentation.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/ovphysx-ovrtx_renderer-motion_vectors.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/ovphysx-ovrtx_renderer-normals.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/ovphysx-ovrtx_renderer-rgb.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/ovphysx-ovrtx_renderer-rgba.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/ovphysx-ovrtx_renderer-semantic_segmentation.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/ovphysx-ovrtx_renderer-simple_shading_constant_diffuse.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/ovphysx-ovrtx_renderer-simple_shading_diffuse_mdl.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/ovphysx-ovrtx_renderer-simple_shading_full_mdl.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/physx-isaacsim_rtx_renderer-albedo.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/physx-isaacsim_rtx_renderer-depth.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/physx-isaacsim_rtx_renderer-distance_to_camera.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/physx-isaacsim_rtx_renderer-distance_to_image_plane.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/physx-isaacsim_rtx_renderer-instance_id_segmentation_fast.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/physx-isaacsim_rtx_renderer-instance_segmentation.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/physx-isaacsim_rtx_renderer-motion_vectors.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/physx-isaacsim_rtx_renderer-normals.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/physx-isaacsim_rtx_renderer-rgb.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/physx-isaacsim_rtx_renderer-rgba.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/physx-isaacsim_rtx_renderer-semantic_segmentation.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/physx-isaacsim_rtx_renderer-simple_shading_constant_diffuse.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/physx-isaacsim_rtx_renderer-simple_shading_diffuse_mdl.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/physx-isaacsim_rtx_renderer-simple_shading_full_mdl.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/physx-newton_renderer-depth.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/physx-newton_renderer-distance_to_camera.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/physx-newton_renderer-distance_to_image_plane.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/physx-newton_renderer-instance_segmentation.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/physx-newton_renderer-normals.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/physx-newton_renderer-rgb.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/physx-newton_renderer-rgba.png (100%) rename source/isaaclab_tasks/test/golden_images/{dexsuite_kuka_homo => lift_kuka_homo}/physx-newton_renderer-semantic_segmentation.png (100%) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 853698d0aece..2524575de36f 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -774,8 +774,8 @@ jobs: extra-pip-packages: "pytetwild[all]>=0.3.0,<0.4" include-files: >- test_rendering_cartpole.py, - test_rendering_dexsuite_kuka_hetero.py, - test_rendering_dexsuite_kuka_homo.py, + test_rendering_lift_kuka_hetero.py, + test_rendering_lift_kuka_homo.py, test_rendering_franka_cloth.py, test_rendering_franka_soft.py, test_rendering_registered_tasks.py, @@ -824,8 +824,8 @@ jobs: wheelhouse-packages: ${{ env.USE_OVPHYSX_WHEELHOUSE == 'true' && 'ovphysx' || '' }} include-files: >- test_rendering_cartpole_kitless.py, - test_rendering_dexsuite_kuka_hetero_kitless.py, - test_rendering_dexsuite_kuka_homo_kitless.py, + test_rendering_lift_kuka_hetero_kitless.py, + test_rendering_lift_kuka_homo_kitless.py, test_rendering_franka_cloth_kitless.py, test_rendering_franka_soft_kitless.py, test_rendering_shadow_hand_kitless.py diff --git a/docs/source/_static/css/environment-browser.js b/docs/source/_static/css/environment-browser.js index efd1e3bb6942..6afe9749b7e6 100644 --- a/docs/source/_static/css/environment-browser.js +++ b/docs/source/_static/css/environment-browser.js @@ -27,7 +27,6 @@ ["Isaac-Humanoid-Direct-Warp-v0", "rl_games,rsl_rl,skrl", "", "", ""], ["Isaac-Humanoid-Warp-v0", "rl_games,rsl_rl,skrl,sb3", "", "", ""], ["Isaac-Lift-Cloth-Franka", "rsl_rl", "newton_mjwarp_vbd_proxy", "", ""], - ["Isaac-Lift-Cube-Franka", "rl_games,rsl_rl,skrl,sb3", "", "", ""], ["Isaac-Lift-Franka", "rsl_rl", "newton_mjwarp,physx", "", "cube,shapes"], ["Isaac-Lift-KukaAllegro", "rsl_rl", "newton_mjwarp,ovphysx,physx", "", "cube,shapes"], ["Isaac-Lift-KukaAllegro-Camera", "rsl_rl", "newton_mjwarp,ovphysx,physx", "isaacsim_rtx,newton_renderer,ovrtx,rtx", "albedo128,albedo256,albedo64,cube,depth128,depth256,depth64,duo_camera,raycaster_depth128,raycaster_depth256,raycaster_depth64,rgb128,rgb256,rgb64,semantic_segmentation128,semantic_segmentation256,semantic_segmentation64,shapes,simple_shading_constant_diffuse128,simple_shading_constant_diffuse256,simple_shading_constant_diffuse64,simple_shading_diffuse_mdl128,simple_shading_diffuse_mdl256,simple_shading_diffuse_mdl64,simple_shading_full_mdl128,simple_shading_full_mdl256,simple_shading_full_mdl64,single_camera"], diff --git a/docs/source/how-to/transfer_policies_between_physx_and_newton.rst b/docs/source/how-to/transfer_policies_between_physx_and_newton.rst index 60cf7d582004..144f4e910eaa 100644 --- a/docs/source/how-to/transfer_policies_between_physx_and_newton.rst +++ b/docs/source/how-to/transfer_policies_between_physx_and_newton.rst @@ -234,7 +234,7 @@ in MJWarp: physics=isaacsim_physx # Replace RUN_DIRECTORY and ITERATION with the values produced by training. - PHYSX_CHECKPOINT="/absolute/path/to/logs/rsl_rl/dexsuite_franka/RUN_DIRECTORY/model_ITERATION.pt" + PHYSX_CHECKPOINT="/absolute/path/to/logs/rsl_rl/lift_franka/RUN_DIRECTORY/model_ITERATION.pt" # PP: reproduce the PhysX source baseline. uv run isaaclab play --rl_library rsl_rl \ @@ -262,7 +262,7 @@ PhysX: physics=newton_mjwarp # Replace RUN_DIRECTORY and ITERATION with the values produced by training. - MJWARP_CHECKPOINT="/absolute/path/to/logs/rsl_rl/dexsuite_franka/RUN_DIRECTORY/model_ITERATION.pt" + MJWARP_CHECKPOINT="/absolute/path/to/logs/rsl_rl/lift_franka/RUN_DIRECTORY/model_ITERATION.pt" # NN: reproduce the MJWarp source baseline. uv run isaaclab play --rl_library rsl_rl \ diff --git a/docs/source/overview/core-concepts/physical-backends/newton/mjwarp-solver.rst b/docs/source/overview/core-concepts/physical-backends/newton/mjwarp-solver.rst index d6ffe25161ac..a53f9e4f8535 100644 --- a/docs/source/overview/core-concepts/physical-backends/newton/mjwarp-solver.rst +++ b/docs/source/overview/core-concepts/physical-backends/newton/mjwarp-solver.rst @@ -229,7 +229,7 @@ dense-manipulation patterns. Then configure :class:`~isaaclab_newton.physics.NewtonCollisionPipelineCfg` on :class:`~isaaclab_newton.physics.NewtonCfg`. The maintained rough-terrain presets use ``default_shape_cfg.margin=0.01`` and raise ``max_triangle_pairs`` from ``1_000_000`` to -``2_500_000``; the Dexsuite pattern raises ``rigid_contact_max`` for its unusually dense scene. +``2_500_000``; the Lift pattern raises ``rigid_contact_max`` for its unusually dense scene. Increase those capacities only in response to the matching overflow or missing-contact evidence. ``collision_decimation=0`` collides once per physics tick. A positive value re-collides every N diff --git a/docs/source/overview/core-concepts/physical-backends/newton/supported-features.rst b/docs/source/overview/core-concepts/physical-backends/newton/supported-features.rst index 262f9576a888..3293b4e62e15 100644 --- a/docs/source/overview/core-concepts/physical-backends/newton/supported-features.rst +++ b/docs/source/overview/core-concepts/physical-backends/newton/supported-features.rst @@ -78,7 +78,7 @@ Manager-based workflows: * Locomotion velocity, flat terrain: A1, AnymalB, AnymalC, AnymalD, Cassie, Unitree G1, Go1, Go2, Unitree H1, Spot * Locomotion velocity, rough terrain: AnymalC, Cassie, Go1, Go2 -* Manipulation: reach (Franka, UR10), cabinet, dexsuite +* Manipulation: reach (Franka, UR10), cabinet, lift and reorient (Franka, KukaAllegro) * Manipulation lift with deformable objects: Franka soft-body lift, Franka cloth lift (via MJWarp and VBD proxy coupling) diff --git a/docs/source/overview/environments.rst b/docs/source/overview/environments.rst index 055651964bd6..504c300a16d7 100644 --- a/docs/source/overview/environments.rst +++ b/docs/source/overview/environments.rst @@ -117,7 +117,7 @@ for all available backend names and how the typed selectors work. .. note:: - The DexSuite Kuka Allegro tasks use the homogeneous ``cube`` object preset with + The KukaAllegro lift and reorient tasks use the homogeneous ``cube`` object preset with ``physics=ovphysx``. The heterogeneous ``shapes`` preset is not supported with OvPhysX; selecting both causes configuration validation to fail. Use ``presets=cube`` or choose another supported physics backend. @@ -386,7 +386,7 @@ for the lift-cube environment: .. |reach-franka-link| replace:: :isaaclab-source:`Isaac-Reach-Franka ` .. |reach-ur10-link| replace:: :isaaclab-source:`Isaac-Reach-UR10 ` .. |deploy-reach-ur10e-link| replace:: :isaaclab-source:`IsaacContrib-Deploy-Reach-UR10e ` -.. |lift-cube-link| replace:: :isaaclab-source:`Isaac-Lift-Cube-Franka ` +.. |lift-cube-link| replace:: :isaaclab-source:`IsaacContrib-Lift-Cube-Franka ` .. |lift-cube-ik-abs-link| replace:: :isaaclab-source:`IsaacContrib-Lift-Cube-Franka-IK-Abs ` .. |lift-cube-ik-rel-link| replace:: :isaaclab-source:`IsaacContrib-Lift-Cube-Franka-IK-Rel ` .. |lift-soft-franka-link| replace:: :isaaclab-source:`Isaac-Lift-Soft-Franka ` @@ -407,10 +407,10 @@ for the lift-cube environment: .. |short-suction-link| replace:: :isaaclab-source:`IsaacContrib-Stack-Cube-UR10-Short-Suction-IK-Rel ` .. |gr1_pp_waist-link| replace:: :isaaclab-source:`IsaacContrib-PickPlace-GR1T2-WaistEnabled-Abs ` .. |galbot_stack-link| replace:: :isaaclab-source:`IsaacContrib-Stack-Cube-Galbot-Left-Arm-Gripper-RmpFlow ` -.. |kuka-allegro-lift-link| replace:: :isaaclab-source:`Isaac-Lift-KukaAllegro ` -.. |kuka-allegro-reorient-link| replace:: :isaaclab-source:`Isaac-Reorient-KukaAllegro ` -.. |ka-lift-cam-link| replace:: :isaaclab-source:`Isaac-Lift-KukaAllegro-Camera ` -.. |ka-reorient-cam-link| replace:: :isaaclab-source:`Isaac-Reorient-KukaAllegro-Camera ` +.. |kuka-allegro-lift-link| replace:: :isaaclab-source:`Isaac-Lift-KukaAllegro ` +.. |kuka-allegro-reorient-link| replace:: :isaaclab-source:`Isaac-Reorient-KukaAllegro ` +.. |ka-lift-cam-link| replace:: :isaaclab-source:`Isaac-Lift-KukaAllegro-Camera ` +.. |ka-reorient-cam-link| replace:: :isaaclab-source:`Isaac-Reorient-KukaAllegro-Camera ` .. |cube-shadow-link| replace:: :isaaclab-source:`Isaac-Reorient-Cube-Shadow-Direct ` .. |cube-shadow-ff-link| replace:: :isaaclab-source:`Isaac-Reorient-Cube-Shadow-OpenAI-FF-Direct ` .. |cube-shadow-lstm-link| replace:: :isaaclab-source:`Isaac-Reorient-Cube-Shadow-OpenAI-LSTM-Direct ` @@ -1035,10 +1035,6 @@ including disabling runtime perturbations used for training. - **rsl_rl** (PPO) - | **physics=** ``newton_mjwarp_vbd_proxy``, ``ovphysx`` | **renderer=** ``isaacsim_rtx``, ``newton_renderer``, ``ovrtx``, ``rtx`` - * - Isaac-Lift-Cube-Franka - - Manager Based - - **rl_games** (PPO), **rsl_rl** (PPO), **skrl** (PPO), **sb3** (PPO) - - * - Isaac-Lift-Franka - Manager Based - **rsl_rl** (PPO) @@ -1284,6 +1280,10 @@ including disabling runtime perturbations used for training. - Direct - **skrl** (AMP) - + * - IsaacContrib-Lift-Cube-Franka + - Manager Based + - **rl_games** (PPO), **rsl_rl** (PPO), **skrl** (PPO), **sb3** (PPO) + - * - IsaacContrib-Lift-Cube-Franka-IK-Abs - Manager Based - diff --git a/scripts/benchmarks/benchmark_hydra_resolve.py b/scripts/benchmarks/benchmark_hydra_resolve.py index 3295d1eb7d72..80002aba8544 100644 --- a/scripts/benchmarks/benchmark_hydra_resolve.py +++ b/scripts/benchmarks/benchmark_hydra_resolve.py @@ -63,7 +63,7 @@ class Case: Case("cartpole_manager", "Isaac-Cartpole"), Case("cartpole_camera_presets", "Isaac-Cartpole-Camera-Direct", "rl_games_cfg_entry_point"), Case("anymal_rough", "IsaacContrib-Velocity-Rough-AnymalC"), - Case("franka_lift_cube", "Isaac-Lift-Cube-Franka"), + Case("franka_lift_cube", "IsaacContrib-Lift-Cube-Franka"), Case( "cartpole_camera_newton_ovrtx", "Isaac-Cartpole-Camera-Direct", @@ -81,7 +81,7 @@ class Case: Case("ant_manager", "Isaac-Ant"), Case("humanoid_manager", "Isaac-Humanoid", "rsl_rl_cfg_entry_point"), Case("franka_reach", "Isaac-Reach-Franka"), - Case("franka_lift_cube_agent", "Isaac-Lift-Cube-Franka", "sb3_cfg_entry_point"), + Case("franka_lift_cube_agent", "IsaacContrib-Lift-Cube-Franka", "sb3_cfg_entry_point"), Case("kuka_allegro_lift", "Isaac-Lift-KukaAllegro", "rsl_rl_cfg_entry_point"), Case( "kuka_allegro_lift_single_camera", diff --git a/scripts/benchmarks/benchmark_lazy_export.py b/scripts/benchmarks/benchmark_lazy_export.py index 1b5e021d8d35..ce3338aee563 100644 --- a/scripts/benchmarks/benchmark_lazy_export.py +++ b/scripts/benchmarks/benchmark_lazy_export.py @@ -50,7 +50,7 @@ "Isaac-Humanoid", "Isaac-Velocity-Flat-AnymalD", "Isaac-Reach-Franka", - "Isaac-Lift-Cube-Franka", + "IsaacContrib-Lift-Cube-Franka", "Isaac-Reorient-KukaAllegro", "IsaacContrib-Navigation-Flat-AnymalC", "IsaacContrib-Stack-Cube-Franka", diff --git a/scripts/environments/state_machine/lift_cube_sm.py b/scripts/environments/state_machine/lift_cube_sm.py index 343823d70d9a..f4ad37bf44f9 100644 --- a/scripts/environments/state_machine/lift_cube_sm.py +++ b/scripts/environments/state_machine/lift_cube_sm.py @@ -47,7 +47,7 @@ from isaaclab.assets.rigid_object.rigid_object_data import RigidObjectData import isaaclab_tasks # noqa: F401 -from isaaclab_tasks.core.lift.lift_env_cfg import LiftEnvCfg +from isaaclab_tasks.contrib.lift.lift_env_cfg import LiftEnvCfg from isaaclab_tasks.utils.parse_cfg import parse_env_cfg # initialize warp diff --git a/source/isaaclab/changelog.d/mhaiderbhai-unify-lift.skip b/source/isaaclab/changelog.d/mhaiderbhai-unify-lift.skip new file mode 100644 index 000000000000..caccdb55b1be --- /dev/null +++ b/source/isaaclab/changelog.d/mhaiderbhai-unify-lift.skip @@ -0,0 +1 @@ +Test-only: updated the lift task IDs renamed by this PR. diff --git a/source/isaaclab/test/envs/test_action_state_recorder_term_task_integration.py b/source/isaaclab/test/envs/test_action_state_recorder_term_task_integration.py index f9e53a9f5881..2886310e1d15 100644 --- a/source/isaaclab/test/envs/test_action_state_recorder_term_task_integration.py +++ b/source/isaaclab/test/envs/test_action_state_recorder_term_task_integration.py @@ -90,7 +90,7 @@ def check_initial_state_recorder_term(env): assert are_states_equal, output_log -@pytest.mark.parametrize("task_name", ["Isaac-Lift-Cube-Franka"]) +@pytest.mark.parametrize("task_name", ["IsaacContrib-Lift-Cube-Franka"]) @pytest.mark.parametrize("device", ["cuda:0", "cpu"]) @pytest.mark.parametrize("num_envs", [1, 2]) def test_action_state_recorder_terms(task_name, device, num_envs, temp_dir): diff --git a/source/isaaclab_physx/changelog.d/mhaiderbhai-unify-lift.skip b/source/isaaclab_physx/changelog.d/mhaiderbhai-unify-lift.skip new file mode 100644 index 000000000000..caccdb55b1be --- /dev/null +++ b/source/isaaclab_physx/changelog.d/mhaiderbhai-unify-lift.skip @@ -0,0 +1 @@ +Test-only: updated the lift task IDs renamed by this PR. diff --git a/source/isaaclab_physx/test/sim/test_cloner.py b/source/isaaclab_physx/test/sim/test_cloner.py index 68b7a36e60be..f1c278e39383 100644 --- a/source/isaaclab_physx/test/sim/test_cloner.py +++ b/source/isaaclab_physx/test/sim/test_cloner.py @@ -235,7 +235,7 @@ def test_physx_replicate_isolated_source_loaded_without_replication(sim, device) def test_physx_replicate_heterogeneous_isolated_sources(sim, device): """physx_replicate handles heterogeneous sources excluding self from world lists. - This is the Dexsuite scenario: multiple object types, each with a designated proto-env. + This is the Lift scenario: multiple object types, each with a designated proto-env. With ``exclude_self_replication=True`` (default), self is removed from the world list only when the source also maps to other environments. Self-only sources keep self so that ``rep.replicate()`` still fires and the source prim gets its physics body (since diff --git a/source/isaaclab_rl/changelog.d/mhaiderbhai-unify-lift.skip b/source/isaaclab_rl/changelog.d/mhaiderbhai-unify-lift.skip new file mode 100644 index 000000000000..caccdb55b1be --- /dev/null +++ b/source/isaaclab_rl/changelog.d/mhaiderbhai-unify-lift.skip @@ -0,0 +1 @@ +Test-only: updated the lift task IDs renamed by this PR. diff --git a/source/isaaclab_rl/test/export/leapp_initialized_checkpoints.py b/source/isaaclab_rl/test/export/leapp_initialized_checkpoints.py index 956e41afea93..8ba2d9dd04f4 100644 --- a/source/isaaclab_rl/test/export/leapp_initialized_checkpoints.py +++ b/source/isaaclab_rl/test/export/leapp_initialized_checkpoints.py @@ -299,7 +299,7 @@ def main(argv: Sequence[str] | None = None) -> None: python leapp_initialized_checkpoints.py --checkpoint_root /tmp/ckpt \\ --preset newton_mjwarp \\ --spec rsl_rl Isaac-Cartpole \\ - --spec rsl_rl Isaac-Lift-Cube-Franka _ + --spec rsl_rl IsaacContrib-Lift-Cube-Franka _ """ import argparse import os diff --git a/source/isaaclab_rl/test/export/test_leapp_export_flow.py b/source/isaaclab_rl/test/export/test_leapp_export_flow.py index 68feddb5a198..6f1dc60c18df 100644 --- a/source/isaaclab_rl/test/export/test_leapp_export_flow.py +++ b/source/isaaclab_rl/test/export/test_leapp_export_flow.py @@ -68,7 +68,7 @@ def agent_cfg_entry_points(self) -> tuple[str, ...]: # binary gripper + cabinet articulation "Isaac-Open-Drawer-Franka", # classic lift: object_position_in_robot_root_frame + quat math - "Isaac-Lift-Cube-Franka", + "IsaacContrib-Lift-Cube-Franka", # history buffers + Object-cloud / contact observations "Isaac-Lift-KukaAllegro", # manager-based locomotion with contact-rich body observations @@ -105,7 +105,7 @@ def agent_cfg_entry_points(self) -> tuple[str, ...]: _SIM_PRESET = "newton_mjwarp" # These tasks reject any preset token; export uses their authored default backend. -_TASKS_WITHOUT_PRESET = frozenset({"Isaac-Lift-Cube-Franka"}) +_TASKS_WITHOUT_PRESET = frozenset({"IsaacContrib-Lift-Cube-Franka"}) def _ensure_text(output: str | bytes | None) -> str: diff --git a/source/isaaclab_rl/test/export/test_rsl_rl_export_flow.py b/source/isaaclab_rl/test/export/test_rsl_rl_export_flow.py index 49aa61cb4051..a279b3d39ea9 100644 --- a/source/isaaclab_rl/test/export/test_rsl_rl_export_flow.py +++ b/source/isaaclab_rl/test/export/test_rsl_rl_export_flow.py @@ -70,10 +70,10 @@ "Isaac-Reach-Franka", "Isaac-Reach-UR10", # Manipulation Lift - "Isaac-Lift-Cube-Franka", + "Isaac-Lift-Franka", # Manipulation Cabinet "Isaac-Open-Drawer-Franka", - # Dexsuite + # Dexterous manipulation "Isaac-Reorient-KukaAllegro", "Isaac-Lift-KukaAllegro", ] diff --git a/source/isaaclab_tasks/changelog.d/mhaiderbhai-unify-lift.major.rst b/source/isaaclab_tasks/changelog.d/mhaiderbhai-unify-lift.major.rst new file mode 100644 index 000000000000..366addb8cc31 --- /dev/null +++ b/source/isaaclab_tasks/changelog.d/mhaiderbhai-unify-lift.major.rst @@ -0,0 +1,16 @@ +Changed +^^^^^^^ + +* **Breaking:** Merged the ``isaaclab_tasks.core.dexsuite`` package into + :mod:`isaaclab_tasks.core.lift`, so the dexterous lift and reorient tasks share one package and + MDP module. Task IDs and training behavior were unchanged, but environment configuration entry + points moved and the ``Dexsuite`` class-name prefix was removed. For example, + ``isaaclab_tasks.core.dexsuite.config.franka.dexsuite_franka_env_cfg:DexsuiteFrankaLiftEnvCfg`` + became ``isaaclab_tasks.core.lift.config.franka.franka_env_cfg:FrankaLiftEnvCfg``. +* **Breaking:** Moved the tutorial single-cube Franka lift task to :mod:`isaaclab_tasks.contrib.lift`. + Use ``--task IsaacContrib-Lift-Cube-Franka`` instead of + ``--task Isaac-Lift-Cube-Franka``. The rigid tutorial MDP terms moved with it; deformable + Lift terms remain in :mod:`isaaclab_tasks.core.lift.mdp`. +* **Breaking:** Renamed the dexterous RSL-RL experiment directories from + ``dexsuite_franka`` and ``dexsuite_kuka_allegro*`` to ``lift_franka`` and + ``lift_kuka_allegro*``. Update existing checkpoint paths under ``logs/rsl_rl/dexsuite_*``. diff --git a/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/__init__.py b/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/__init__.py index 0dc3650aaac6..435f896d4410 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/__init__.py +++ b/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/__init__.py @@ -4,12 +4,29 @@ # SPDX-License-Identifier: BSD-3-Clause import gymnasium as gym -from isaaclab_tasks.core.lift.config.franka import agents +from isaaclab_tasks.contrib.lift.config.franka import agents ## # Register Gym environments. ## +## +# Joint Position Control +## + +gym.register( + id="IsaacContrib-Lift-Cube-Franka", + entry_point="isaaclab.envs:ManagerBasedRLEnv", + kwargs={ + "env_cfg_entry_point": f"{__name__}.joint_pos_env_cfg:FrankaCubeLiftEnvCfg", + "rsl_rl_cfg_entry_point": f"{agents.__name__}.rsl_rl_ppo_cfg:LiftCubePPORunnerCfg", + "skrl_cfg_entry_point": f"{agents.__name__}:skrl_ppo_cfg.yaml", + "rl_games_cfg_entry_point": f"{agents.__name__}:rl_games_ppo_cfg.yaml", + "sb3_cfg_entry_point": f"{agents.__name__}:sb3_ppo_cfg.yaml", + }, + disable_env_checker=True, +) + ## # Inverse Kinematics - Absolute Pose Control ## diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/franka/agents/__init__.py b/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/agents/__init__.py similarity index 100% rename from source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/franka/agents/__init__.py rename to source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/agents/__init__.py diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/franka/agents/rl_games_ppo_cfg.yaml b/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/agents/rl_games_ppo_cfg.yaml similarity index 98% rename from source/isaaclab_tasks/isaaclab_tasks/core/lift/config/franka/agents/rl_games_ppo_cfg.yaml rename to source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/agents/rl_games_ppo_cfg.yaml index 77360c1b91bb..bf9a9ebed414 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/franka/agents/rl_games_ppo_cfg.yaml +++ b/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/agents/rl_games_ppo_cfg.yaml @@ -45,7 +45,7 @@ params: load_path: '' # path to the checkpoint to load config: - name: franka_lift + name: lift_cube_franka env_name: rlgpu device: 'cuda:0' device_name: 'cuda:0' diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/franka/agents/robomimic/bc.json b/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/agents/robomimic/bc.json similarity index 100% rename from source/isaaclab_tasks/isaaclab_tasks/core/lift/config/franka/agents/robomimic/bc.json rename to source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/agents/robomimic/bc.json diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/franka/agents/robomimic/bcq.json b/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/agents/robomimic/bcq.json similarity index 100% rename from source/isaaclab_tasks/isaaclab_tasks/core/lift/config/franka/agents/robomimic/bcq.json rename to source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/agents/robomimic/bcq.json diff --git a/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/agents/rsl_rl_ppo_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/agents/rsl_rl_ppo_cfg.py new file mode 100644 index 000000000000..0f304a488d41 --- /dev/null +++ b/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/agents/rsl_rl_ppo_cfg.py @@ -0,0 +1,41 @@ +# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md). +# All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause + +from isaaclab.utils.configclass import configclass + +from isaaclab_rl.rsl_rl import RslRlMLPModelCfg, RslRlOnPolicyRunnerCfg, RslRlPpoAlgorithmCfg + + +@configclass +class LiftCubePPORunnerCfg(RslRlOnPolicyRunnerCfg): + num_steps_per_env = 24 + max_iterations = 1500 + save_interval = 50 + experiment_name = "lift_cube_franka" + actor = RslRlMLPModelCfg( + hidden_dims=[256, 128, 64], + activation="elu", + obs_normalization=False, + distribution_cfg=RslRlMLPModelCfg.GaussianDistributionCfg(init_std=1.0), + ) + critic = RslRlMLPModelCfg( + hidden_dims=[256, 128, 64], + activation="elu", + obs_normalization=False, + ) + algorithm = RslRlPpoAlgorithmCfg( + value_loss_coef=1.0, + use_clipped_value_loss=True, + clip_param=0.2, + entropy_coef=0.006, + num_learning_epochs=5, + num_mini_batches=4, + learning_rate=1.0e-4, + schedule="adaptive", + gamma=0.98, + lam=0.95, + desired_kl=0.01, + max_grad_norm=1.0, + ) diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/franka/agents/sb3_ppo_cfg.yaml b/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/agents/sb3_ppo_cfg.yaml similarity index 100% rename from source/isaaclab_tasks/isaaclab_tasks/core/lift/config/franka/agents/sb3_ppo_cfg.yaml rename to source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/agents/sb3_ppo_cfg.yaml diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/franka/agents/skrl_ppo_cfg.yaml b/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/agents/skrl_ppo_cfg.yaml similarity index 98% rename from source/isaaclab_tasks/isaaclab_tasks/core/lift/config/franka/agents/skrl_ppo_cfg.yaml rename to source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/agents/skrl_ppo_cfg.yaml index 3f39d0c4afc4..c94dc92afbe0 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/franka/agents/skrl_ppo_cfg.yaml +++ b/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/agents/skrl_ppo_cfg.yaml @@ -71,7 +71,7 @@ agent: time_limit_bootstrap: False # logging and checkpoint experiment: - directory: "franka_lift" + directory: "lift_cube_franka" experiment_name: "" write_interval: auto checkpoint_interval: auto diff --git a/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/ik_abs_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/ik_abs_env_cfg.py index 59f0e8685e34..765344d61a71 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/ik_abs_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/ik_abs_env_cfg.py @@ -7,7 +7,7 @@ from isaaclab.envs.mdp.actions.actions_cfg import DifferentialInverseKinematicsActionCfg from isaaclab.utils.configclass import configclass -from isaaclab_tasks.core.lift.config.franka import joint_pos_env_cfg +from isaaclab_tasks.contrib.lift.config.franka import joint_pos_env_cfg ## # Pre-defined configs diff --git a/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/ik_rel_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/ik_rel_env_cfg.py index f40e41613302..18c65a844e69 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/ik_rel_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/ik_rel_env_cfg.py @@ -7,7 +7,7 @@ from isaaclab.envs.mdp.actions.actions_cfg import DifferentialInverseKinematicsActionCfg from isaaclab.utils.configclass import configclass -from isaaclab_tasks.core.lift.config.franka import joint_pos_env_cfg +from isaaclab_tasks.contrib.lift.config.franka import joint_pos_env_cfg ## # Pre-defined configs diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/franka/joint_pos_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/joint_pos_env_cfg.py similarity index 96% rename from source/isaaclab_tasks/isaaclab_tasks/core/lift/config/franka/joint_pos_env_cfg.py rename to source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/joint_pos_env_cfg.py index 8a157192f1f4..17f5b995417f 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/franka/joint_pos_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/joint_pos_env_cfg.py @@ -11,8 +11,8 @@ from isaaclab.utils.assets import ISAAC_NUCLEUS_DIR from isaaclab.utils.configclass import configclass -from isaaclab_tasks.core.lift import mdp -from isaaclab_tasks.core.lift.lift_env_cfg import LiftEnvCfg +from isaaclab_tasks.contrib.lift import mdp +from isaaclab_tasks.contrib.lift.lift_env_cfg import LiftEnvCfg ## # Pre-defined configs diff --git a/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/openarm/joint_pos_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/openarm/joint_pos_env_cfg.py index 28be35b9e653..12195054395c 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/openarm/joint_pos_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/openarm/joint_pos_env_cfg.py @@ -7,14 +7,15 @@ import math from isaaclab.assets import RigidObjectCfg +from isaaclab.managers import SceneEntityCfg from isaaclab.sensors import FrameTransformerCfg from isaaclab.sim.schemas.schemas_cfg import RigidBodyPropertiesCfg from isaaclab.sim.spawners.from_files.from_files_cfg import UsdFileCfg from isaaclab.utils.assets import ISAAC_NUCLEUS_DIR from isaaclab.utils.configclass import configclass -from isaaclab_tasks.contrib.lift.config.openarm.lift_openarm_env_cfg import LiftEnvCfg -from isaaclab_tasks.core.lift import mdp +from isaaclab_tasks.contrib.lift import mdp +from isaaclab_tasks.contrib.lift.lift_env_cfg import LiftEnvCfg from isaaclab_assets.robots.openarm import OPENARM_UNI_CFG @@ -23,6 +24,10 @@ ## from isaaclab.markers.config import FRAME_MARKER_CFG # isort: skip +# The OpenArm is smaller than the Franka, so the goal workspace and the joint-scoped +# terms are re-tuned for it relative to the shared lift base. +OPENARM_JOINTS = ["openarm_joint.*", "openarm_finger_joint.*"] + @configclass class OpenArmCubeLiftEnvCfg(LiftEnvCfg): @@ -33,6 +38,21 @@ def __post_init__(self): # Set OpenArm as robot self.scene.robot = OPENARM_UNI_CFG.replace(prim_path="{ENV_REGEX_NS}/Robot") + # Scope the joint-space terms to the OpenArm's own joints. + openarm_cfg = SceneEntityCfg("robot", joint_names=OPENARM_JOINTS) + self.observations.policy.joint_pos.params = {"asset_cfg": openarm_cfg} + self.observations.policy.joint_vel.params = {"asset_cfg": openarm_cfg} + self.rewards.joint_vel.params["asset_cfg"] = openarm_cfg + + # Shrink the goal workspace to the smaller arm's reach. + self.commands.object_pose.ranges.pos_x = (0.2, 0.4) + self.commands.object_pose.ranges.pos_y = (-0.2, 0.2) + self.commands.object_pose.ranges.pos_z = (0.15, 0.4) + + # Re-tuned reach weight, and no success tracking on this task. + self.rewards.reaching_object.weight = 1.1 + del self.rewards.object_goal_tracking.params["success_threshold"] + # Set actions for the specific robot type (OpenArm) self.actions.arm_action = mdp.JointPositionActionCfg( asset_name="robot", diff --git a/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/openarm/lift_openarm_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/lift_env_cfg.py similarity index 79% rename from source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/openarm/lift_openarm_env_cfg.py rename to source/isaaclab_tasks/isaaclab_tasks/contrib/lift/lift_env_cfg.py index e4423a0a23fc..cc05b96ac826 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/openarm/lift_openarm_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/lift_env_cfg.py @@ -3,11 +3,6 @@ # # SPDX-License-Identifier: BSD-3-Clause -""" -We modified parts of the environment, such as the target's position and orientation, -as well as certain object properties, to better suit the smaller robot. -""" - from dataclasses import MISSING from isaaclab_physx.assets import DeformableObjectCfg @@ -29,7 +24,7 @@ from isaaclab.utils.assets import ISAAC_NUCLEUS_DIR from isaaclab.utils.configclass import configclass -from isaaclab_tasks.core.lift import mdp +from isaaclab_tasks.contrib.lift import mdp ## # Scene definition @@ -38,10 +33,7 @@ @configclass class ObjectTableSceneCfg(InteractiveSceneCfg): - """Configuration for the lift scene with a robot and a object. - This is the abstract base implementation, the exact scene is defined in the derived classes - which need to set the target object, robot and end-effector frames - """ + """Configuration for the lift scene with a robot and a object.""" # robots: will be populated by agent env cfg robot: ArticulationCfg = MISSING @@ -50,7 +42,7 @@ class ObjectTableSceneCfg(InteractiveSceneCfg): # target object: will be populated by agent env cfg object: RigidObjectCfg | DeformableObjectCfg = MISSING - # Table + # table table = AssetBaseCfg( prim_path="{ENV_REGEX_NS}/Table", init_state=AssetBaseCfg.InitialStateCfg(pos=[0.5, 0, 0], rot=[0, 0, 0.707, 0.707]), @@ -82,16 +74,11 @@ class CommandsCfg: object_pose = mdp.UniformPoseCommandCfg( asset_name="robot", - body_name=MISSING, # will be set by agent env cfg + body_name=MISSING, # will be set by derived env cfg resampling_time_range=(5.0, 5.0), debug_vis=True, ranges=mdp.UniformPoseCommandCfg.Ranges( - pos_x=(0.2, 0.4), - pos_y=(-0.2, 0.2), - pos_z=(0.15, 0.4), - roll=(0.0, 0.0), - pitch=(0.0, 0.0), - yaw=(0.0, 0.0), + pos_x=(0.4, 0.6), pos_y=(-0.25, 0.25), pos_z=(0.25, 0.5), roll=(0.0, 0.0), pitch=(0.0, 0.0), yaw=(0.0, 0.0) ), ) @@ -100,7 +87,7 @@ class CommandsCfg: class ActionsCfg: """Action specifications for the MDP.""" - # will be set by agent env cfg + # will be set by derived env cfg arm_action: mdp.JointPositionActionCfg | mdp.DifferentialInverseKinematicsActionCfg = MISSING gripper_action: mdp.BinaryJointPositionActionCfg = MISSING @@ -113,14 +100,8 @@ class ObservationsCfg: class PolicyCfg(ObsGroup): """Observations for policy group.""" - joint_pos = ObsTerm( - func=mdp.joint_pos_rel, - params={"asset_cfg": SceneEntityCfg("robot", joint_names=["openarm_joint.*", "openarm_finger_joint.*"])}, - ) - joint_vel = ObsTerm( - func=mdp.joint_vel_rel, - params={"asset_cfg": SceneEntityCfg("robot", joint_names=["openarm_joint.*", "openarm_finger_joint.*"])}, - ) + joint_pos = ObsTerm(func=mdp.joint_pos_rel) + joint_vel = ObsTerm(func=mdp.joint_vel_rel) object_position = ObsTerm(func=mdp.object_position_in_robot_root_frame) target_object_position = ObsTerm(func=mdp.generated_commands, params={"command_name": "object_pose"}) actions = ObsTerm(func=mdp.last_action) @@ -154,13 +135,13 @@ class EventCfg: class RewardsCfg: """Reward terms for the MDP.""" - reaching_object = RewTerm(func=mdp.object_ee_distance, params={"std": 0.1}, weight=1.1) + reaching_object = RewTerm(func=mdp.object_ee_distance, params={"std": 0.1}, weight=1.0) lifting_object = RewTerm(func=mdp.object_is_lifted, params={"minimal_height": 0.04}, weight=15.0) object_goal_tracking = RewTerm( func=mdp.object_goal_distance, - params={"std": 0.3, "minimal_height": 0.04, "command_name": "object_pose"}, + params={"std": 0.3, "minimal_height": 0.04, "command_name": "object_pose", "success_threshold": 0.05}, weight=16.0, ) @@ -176,7 +157,7 @@ class RewardsCfg: joint_vel = RewTerm( func=mdp.joint_vel_l2, weight=-1e-4, - params={"asset_cfg": SceneEntityCfg("robot", joint_names=["openarm_joint.*", "openarm_finger_joint.*"])}, + params={"asset_cfg": SceneEntityCfg("robot")}, ) @@ -187,8 +168,7 @@ class TerminationsCfg: time_out = DoneTerm(func=mdp.time_out, time_out=True) object_dropping = DoneTerm( - func=mdp.root_height_below_minimum, - params={"minimum_height": -0.05, "asset_cfg": SceneEntityCfg("object")}, + func=mdp.root_height_below_minimum, params={"minimum_height": -0.05, "asset_cfg": SceneEntityCfg("object")} ) @@ -197,13 +177,11 @@ class CurriculumCfg: """Curriculum terms for the MDP.""" action_rate = CurrTerm( - func=mdp.modify_reward_weight, - params={"term_name": "action_rate", "weight": -1e-1, "num_steps": 10000}, + func=mdp.modify_reward_weight, params={"term_name": "action_rate", "weight": -1e-1, "num_steps": 10000} ) joint_vel = CurrTerm( - func=mdp.modify_reward_weight, - params={"term_name": "joint_vel", "weight": -1e-1, "num_steps": 10000}, + func=mdp.modify_reward_weight, params={"term_name": "joint_vel", "weight": -1e-1, "num_steps": 10000} ) diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/__init__.py b/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/mdp/__init__.py similarity index 73% rename from source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/__init__.py rename to source/isaaclab_tasks/isaaclab_tasks/contrib/lift/mdp/__init__.py index e14e0f6d52c5..1c3431f2637c 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/__init__.py +++ b/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/mdp/__init__.py @@ -3,6 +3,8 @@ # # SPDX-License-Identifier: BSD-3-Clause +"""This sub-module contains the functions that are specific to the lift environments.""" + from isaaclab.utils.module import lazy_export lazy_export() diff --git a/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/mdp/__init__.pyi b/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/mdp/__init__.pyi new file mode 100644 index 000000000000..b433bfc5c865 --- /dev/null +++ b/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/mdp/__init__.pyi @@ -0,0 +1,17 @@ +# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md). +# All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause + +__all__ = [ + # observations + "object_position_in_robot_root_frame", + # rewards + "object_ee_distance", + "object_goal_distance", + "object_is_lifted", +] + +from .observations import object_position_in_robot_root_frame +from .rewards import object_ee_distance, object_goal_distance, object_is_lifted +from isaaclab.envs.mdp import * diff --git a/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/mdp/observations.py b/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/mdp/observations.py new file mode 100644 index 000000000000..52ef38b540e0 --- /dev/null +++ b/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/mdp/observations.py @@ -0,0 +1,32 @@ +# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md). +# All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause + +"""Observation functions for the rigid lift tasks.""" + +from __future__ import annotations + +from typing import TYPE_CHECKING + +import torch + +from isaaclab.managers import SceneEntityCfg +from isaaclab.utils.math import subtract_frame_transforms + +if TYPE_CHECKING: + from isaaclab.assets import RigidObject + from isaaclab.envs import ManagerBasedRLEnv + + +def object_position_in_robot_root_frame( + env: ManagerBasedRLEnv, + robot_cfg: SceneEntityCfg = SceneEntityCfg("robot"), + object_cfg: SceneEntityCfg = SceneEntityCfg("object"), +) -> torch.Tensor: + """The position of the object in the robot's root frame.""" + robot: RigidObject = env.scene[robot_cfg.name] + object: RigidObject = env.scene[object_cfg.name] + object_pos_w = object.data.root_pos_w.torch[:, :3] + object_pos_b, _ = subtract_frame_transforms(robot.data.root_pos_w.torch, robot.data.root_quat_w.torch, object_pos_w) + return object_pos_b diff --git a/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/mdp/rewards.py b/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/mdp/rewards.py new file mode 100644 index 000000000000..f51cb101de56 --- /dev/null +++ b/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/mdp/rewards.py @@ -0,0 +1,94 @@ +# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md). +# All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause + +"""Reward functions for the rigid lift tasks.""" + +from __future__ import annotations + +from typing import TYPE_CHECKING + +import torch + +from isaaclab.managers import ManagerTermBase, RewardTermCfg, SceneEntityCfg +from isaaclab.utils.math import combine_frame_transforms + +if TYPE_CHECKING: + from isaaclab.assets import RigidObject + from isaaclab.envs import ManagerBasedRLEnv + from isaaclab.sensors import FrameTransformer + + +def object_is_lifted( + env: ManagerBasedRLEnv, minimal_height: float, object_cfg: SceneEntityCfg = SceneEntityCfg("object") +) -> torch.Tensor: + """Reward the agent for lifting the object above the minimal height.""" + object: RigidObject = env.scene[object_cfg.name] + return torch.where(object.data.root_pos_w.torch[:, 2] > minimal_height, 1.0, 0.0) + + +def object_ee_distance( + env: ManagerBasedRLEnv, + std: float, + object_cfg: SceneEntityCfg = SceneEntityCfg("object"), + ee_frame_cfg: SceneEntityCfg = SceneEntityCfg("ee_frame"), +) -> torch.Tensor: + """Reward the agent for reaching the object using tanh-kernel.""" + # extract the used quantities (to enable type-hinting) + object: RigidObject = env.scene[object_cfg.name] + ee_frame: FrameTransformer = env.scene[ee_frame_cfg.name] + # Target object position: (num_envs, 3) + cube_pos_w = object.data.root_pos_w.torch + # End-effector position: (num_envs, 3) + ee_w = ee_frame.data.target_pos_w.torch[..., 0, :] + # Distance of the end-effector to the object: (num_envs,) + object_ee_distance = torch.linalg.norm(cube_pos_w - ee_w, dim=1) + + return 1 - torch.tanh(object_ee_distance / std) + + +class object_goal_distance(ManagerTermBase): + """Reward the agent for tracking the object-to-goal pose using a tanh kernel. + + If ``success_threshold`` is provided in the term params, this also tracks per-episode + success (sticky binary: object ever within ``success_threshold`` of the commanded goal + while lifted above ``minimal_height``) and logs the mean across environments under + ``Metrics/success_rate`` on reset. + """ + + def __init__(self, cfg: RewardTermCfg, env: ManagerBasedRLEnv): + super().__init__(cfg, env) + self._track_success = cfg.params.get("success_threshold") is not None + if self._track_success: + self._succeeded = torch.zeros(env.num_envs, dtype=torch.bool, device=env.device) + + def reset(self, env_ids: torch.Tensor): + if self._track_success: + self._env.extras.setdefault("log", {})["Metrics/success_rate"] = ( + self._succeeded[env_ids].float().mean().item() + ) + self._succeeded[env_ids] = False + + def __call__( + self, + env: ManagerBasedRLEnv, + std: float, + minimal_height: float, + command_name: str, + robot_cfg: SceneEntityCfg = SceneEntityCfg("robot"), + object_cfg: SceneEntityCfg = SceneEntityCfg("object"), + success_threshold: float | None = None, + ) -> torch.Tensor: + robot: RigidObject = env.scene[robot_cfg.name] + obj: RigidObject = env.scene[object_cfg.name] + command = env.command_manager.get_command(command_name) + des_pos_w, _ = combine_frame_transforms( + robot.data.root_pos_w.torch, robot.data.root_quat_w.torch, command[:, :3] + ) + object_pos_w = obj.data.root_pos_w.torch + distance = torch.linalg.norm(des_pos_w - object_pos_w, dim=1) + is_lifted = object_pos_w[:, 2] > minimal_height + if success_threshold is not None: + self._succeeded |= is_lifted & (distance < success_threshold) + return is_lifted.float() * (1 - torch.tanh(distance / std)) diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/__init__.py b/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/__init__.py deleted file mode 100644 index cb7aaceec9c2..000000000000 --- a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/__init__.py +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md). -# All rights reserved. -# -# SPDX-License-Identifier: BSD-3-Clause - -"""Dexsuite environments. - -Implementation Reference: - -Reorient: -@article{petrenko2023dexpbt, - title={Dexpbt: Scaling up dexterous manipulation for hand-arm systems with population based training}, - author={Petrenko, Aleksei and Allshire, Arthur and State, Gavriel and Handa, Ankur and Makoviychuk, Viktor}, - journal={arXiv preprint arXiv:2305.12127}, - year={2023} -} - -Lift: -@article{singh2024dextrah, - title={Dextrah-rgb: Visuomotor policies to grasp anything with dexterous hands}, - author={Singh, Ritvik and Allshire, Arthur and Handa, Ankur and Ratliff, Nathan and Van Wyk, Karl}, - journal={arXiv preprint arXiv:2412.01791}, - year={2024} -} - -""" diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/__init__.py b/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/__init__.py deleted file mode 100644 index d6250c019573..000000000000 --- a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md). -# All rights reserved. -# -# SPDX-License-Identifier: BSD-3-Clause - -"""Configurations for the dexsuite environments.""" - -# We leave this file empty since we don't want to expose any configs in this package directly. -# We still need this file to import the "config" module in the parent package. diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/franka/__init__.py b/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/franka/__init__.py deleted file mode 100644 index 2613721eecaa..000000000000 --- a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/franka/__init__.py +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md). -# All rights reserved. -# -# SPDX-License-Identifier: BSD-3-Clause - -"""Dexsuite Franka reorient and lift environments.""" - -import gymnasium as gym - -from . import agents - -## -# Register Gym environments. -## - -gym.register( - id="Isaac-Reorient-Franka", - entry_point="isaaclab.envs:ManagerBasedRLEnv", - disable_env_checker=True, - kwargs={ - "env_cfg_entry_point": f"{__name__}.dexsuite_franka_env_cfg:DexsuiteFrankaReorientEnvCfg", - "rsl_rl_cfg_entry_point": f"{agents.__name__}.rsl_rl_ppo_cfg:DexsuiteFrankaPPORunnerCfg", - }, -) - -gym.register( - id="Isaac-Lift-Franka", - entry_point="isaaclab.envs:ManagerBasedRLEnv", - disable_env_checker=True, - kwargs={ - "env_cfg_entry_point": f"{__name__}.dexsuite_franka_env_cfg:DexsuiteFrankaLiftEnvCfg", - "rsl_rl_cfg_entry_point": f"{agents.__name__}.rsl_rl_ppo_cfg:DexsuiteFrankaPPORunnerCfg", - }, -) diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/franka/agents/rsl_rl_ppo_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/franka/agents/rsl_rl_ppo_cfg.py deleted file mode 100644 index fc317c9aa2a3..000000000000 --- a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/franka/agents/rsl_rl_ppo_cfg.py +++ /dev/null @@ -1,68 +0,0 @@ -# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md). -# All rights reserved. -# -# SPDX-License-Identifier: BSD-3-Clause - -from dataclasses import MISSING - -from isaaclab.utils.configclass import configclass - -from isaaclab_rl.rsl_rl import ( - RslRlMLPModelCfg, - RslRlOnPolicyRunnerCfg, - RslRlPpoAlgorithmCfg, -) - -from isaaclab_tasks.utils import PresetCfg - -STATE_POLICY_CFG = RslRlMLPModelCfg( - distribution_cfg=RslRlMLPModelCfg.GaussianDistributionCfg(init_std=1.0), - obs_normalization=True, - hidden_dims=[512, 256, 128], - activation="elu", -) - -STATE_CRITIC_CFG = RslRlMLPModelCfg( - obs_normalization=True, - hidden_dims=[512, 256, 128], - activation="elu", -) - - -ALGO_CFG = RslRlPpoAlgorithmCfg( - value_loss_coef=1.0, - use_clipped_value_loss=True, - clip_param=0.2, - entropy_coef=0.005, - num_learning_epochs=5, - num_mini_batches=4, - learning_rate=1.0e-3, - schedule="adaptive", - gamma=0.995, - lam=0.90, - desired_kl=0.01, - max_grad_norm=1.0, -) - - -@configclass -class DexsuiteFrankaPPOBaseRunnerCfg(RslRlOnPolicyRunnerCfg): - num_steps_per_env = 32 - max_iterations = 15000 - save_interval = 250 - experiment_name = (MISSING,) # type: ignore - obs_groups = (MISSING,) # type: ignore - actor = (MISSING,) # type: ignore - critic = (MISSING,) # type: ignore - algorithm = MISSING # type: ignore - - -@configclass -class DexsuiteFrankaPPORunnerCfg(PresetCfg): - default = DexsuiteFrankaPPOBaseRunnerCfg().replace( - experiment_name="dexsuite_franka", - obs_groups={"actor": ["policy", "proprio", "perception"], "critic": ["policy", "proprio", "perception"]}, - actor=STATE_POLICY_CFG, - critic=STATE_CRITIC_CFG, - algorithm=ALGO_CFG, - ) diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/dexsuite_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/dexsuite_env_cfg.py deleted file mode 100644 index 5e12ae5bf28f..000000000000 --- a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/dexsuite_env_cfg.py +++ /dev/null @@ -1,604 +0,0 @@ -# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md). -# All rights reserved. -# -# SPDX-License-Identifier: BSD-3-Clause - -from dataclasses import MISSING - -from isaaclab_newton.physics import MJWarpSolverCfg, NewtonCfg, NewtonCollisionPipelineCfg, NewtonShapeCfg -from isaaclab_physx.physics import PhysxCfg - -import isaaclab.sim as sim_utils -from isaaclab.assets import ArticulationCfg, AssetBaseCfg, RigidObjectCfg -from isaaclab.envs import ManagerBasedRLEnvCfg, ViewerCfg -from isaaclab.managers import EventTermCfg as EventTerm -from isaaclab.managers import ObservationGroupCfg as ObsGroup -from isaaclab.managers import ObservationTermCfg as ObsTerm -from isaaclab.managers import RewardTermCfg as RewTerm -from isaaclab.managers import SceneEntityCfg -from isaaclab.managers import TerminationTermCfg as DoneTerm -from isaaclab.markers import VisualizationMarkersCfg -from isaaclab.physics import PhysxAutoCfg -from isaaclab.scene import InteractiveSceneCfg -from isaaclab.sim import MeshCapsuleCfg, MeshConeCfg, MeshCuboidCfg, MeshSphereCfg, RigidBodyMaterialCfg -from isaaclab.utils.assets import ISAAC_NUCLEUS_DIR -from isaaclab.utils.configclass import configclass -from isaaclab.utils.noise import UniformNoiseCfg as Unoise - -from isaaclab_tasks.utils import PresetCfg - -from . import mdp -from .adr_curriculum import CurriculumCfg - -TABLE_SPAWN_CFG = sim_utils.CuboidCfg( - size=(0.8, 1.5, 0.04), - rigid_props=sim_utils.RigidBodyPropertiesCfg(kinematic_enabled=True), - collision_props=sim_utils.CollisionPropertiesCfg(), - # trick: we let visualizer's color to show the table with success coloring - visible=False, -) - - -OBJECT_PHYSICS = { - "physics_material": RigidBodyMaterialCfg(static_friction=0.5), - "collision_props": sim_utils.CollisionPropertiesCfg(contact_offset=0.002), -} - - -@configclass -class ObjectCfg(PresetCfg): - shapes = sim_utils.MultiAssetSpawnerCfg( - assets_cfg=[ - MeshCuboidCfg(size=(0.05, 0.1, 0.1), **OBJECT_PHYSICS), - MeshCuboidCfg(size=(0.05, 0.05, 0.1), **OBJECT_PHYSICS), - MeshCuboidCfg(size=(0.025, 0.1, 0.1), **OBJECT_PHYSICS), - MeshCuboidCfg(size=(0.025, 0.05, 0.1), **OBJECT_PHYSICS), - MeshCuboidCfg(size=(0.025, 0.025, 0.1), **OBJECT_PHYSICS), - MeshCuboidCfg(size=(0.01, 0.1, 0.1), **OBJECT_PHYSICS), - MeshSphereCfg(radius=0.05, **OBJECT_PHYSICS), - MeshSphereCfg(radius=0.025, **OBJECT_PHYSICS), - MeshCapsuleCfg(radius=0.04, height=0.025, **OBJECT_PHYSICS), - MeshCapsuleCfg(radius=0.04, height=0.01, **OBJECT_PHYSICS), - MeshCapsuleCfg(radius=0.04, height=0.1, **OBJECT_PHYSICS), - MeshCapsuleCfg(radius=0.025, height=0.1, **OBJECT_PHYSICS), - MeshCapsuleCfg(radius=0.025, height=0.2, **OBJECT_PHYSICS), - MeshCapsuleCfg(radius=0.01, height=0.2, **OBJECT_PHYSICS), - MeshConeCfg(radius=0.05, height=0.1, **OBJECT_PHYSICS), - MeshConeCfg(radius=0.025, height=0.1, **OBJECT_PHYSICS), - ], - rigid_props=sim_utils.RigidBodyPropertiesCfg( - solver_position_iteration_count=16, - solver_velocity_iteration_count=0, - disable_gravity=False, - ), - collision_props=sim_utils.CollisionPropertiesCfg(), - mass_props=sim_utils.MassPropertiesCfg(mass=0.2), - ) - cube = sim_utils.CuboidCfg( - size=(0.05, 0.05, 0.05), - physics_material=RigidBodyMaterialCfg(static_friction=0.5), - rigid_props=sim_utils.RigidBodyPropertiesCfg( - solver_position_iteration_count=16, - solver_velocity_iteration_count=0, - disable_gravity=False, - ), - collision_props=sim_utils.CollisionPropertiesCfg(), - mass_props=sim_utils.MassPropertiesCfg(mass=0.2), - ) - default = shapes - - -@configclass -class SceneCfg(InteractiveSceneCfg): - """Dexsuite Scene for multi-objects Lifting""" - - # robot - robot: ArticulationCfg = MISSING - - # object - object: RigidObjectCfg = RigidObjectCfg( - prim_path="{ENV_REGEX_NS}/Object", - spawn=ObjectCfg(), # type: ignore - init_state=RigidObjectCfg.InitialStateCfg(pos=(-0.55, 0.1, 0.35)), - ) - - # table - table: RigidObjectCfg = RigidObjectCfg( - prim_path="{ENV_REGEX_NS}/table", - spawn=TABLE_SPAWN_CFG, - init_state=RigidObjectCfg.InitialStateCfg(pos=(-0.55, 0.0, 0.235), rot=(0.0, 0.0, 0.0, 1.0)), - ) - - # plane - plane = AssetBaseCfg( - prim_path="/World/GroundPlane", - init_state=AssetBaseCfg.InitialStateCfg(), - spawn=sim_utils.GroundPlaneCfg(color=(1.0, 1.0, 1.0)), - collision_group=-1, - ) - - # lights - sky_light = AssetBaseCfg( - prim_path="/World/skyLight", - spawn=sim_utils.DomeLightCfg( - intensity=750.0, - texture_file=f"{ISAAC_NUCLEUS_DIR}/Materials/Textures/Skies/PolyHaven/kloofendal_43d_clear_puresky_4k.hdr", - ), - ) - - -@configclass -class CommandsCfg: - """Command terms for the MDP.""" - - object_pose = mdp.ObjectUniformPoseCommandCfg( - asset_name="robot", - object_name="object", - resampling_time_range=(3.0, 5.0), - debug_vis=False, - ranges=mdp.ObjectUniformPoseCommandCfg.Ranges( - pos_x=(-0.7, -0.3), - pos_y=(-0.25, 0.25), - pos_z=(0.55, 0.95), - roll=(-3.14, 3.14), - pitch=(-3.14, 3.14), - yaw=(0.0, 0.0), - ), - success_vis_asset_name="table", - success_visualizer_cfg=VisualizationMarkersCfg( - prim_path="/Visuals/SuccessMarkers", - markers={ - "failure": TABLE_SPAWN_CFG.replace( - visual_material=sim_utils.PreviewSurfaceCfg(diffuse_color=(0.25, 0.15, 0.15)), visible=True - ), - "success": TABLE_SPAWN_CFG.replace( - visual_material=sim_utils.PreviewSurfaceCfg(diffuse_color=(0.15, 0.25, 0.15)), visible=True - ), - }, - ), - ) - - -@configclass -class ObservationsCfg: - """Observation specifications for the MDP.""" - - @configclass - class PolicyCfg(ObsGroup): - """Observations for policy group.""" - - object_quat_b = ObsTerm(func=mdp.object_quat_b, noise=Unoise(n_min=-0.0, n_max=0.0)) - target_object_pose_b = ObsTerm(func=mdp.generated_commands, params={"command_name": "object_pose"}) - actions = ObsTerm(func=mdp.last_action) - - def __post_init__(self): - self.enable_corruption = True - self.concatenate_terms = True - self.history_length = 5 - - @configclass - class ProprioObsCfg(ObsGroup): - """Observations for proprioception group.""" - - joint_pos = ObsTerm(func=mdp.joint_pos, noise=Unoise(n_min=-0.0, n_max=0.0)) - joint_vel = ObsTerm(func=mdp.joint_vel, noise=Unoise(n_min=-0.0, n_max=0.0)) - hand_tips_state_b = ObsTerm( - func=mdp.body_state_b, - noise=Unoise(n_min=-0.0, n_max=0.0), - # good behaving number for position in m, velocity in m/s, rad/s, - # and quaternion are unlikely to exceed -2 to 2 range - clip=(-2.0, 2.0), - params={ - # pose-only: body velocities are the most engine-sensitive observables - # (derivative signals amplify solver differences) and do not transfer - # across physics backends; the observation history carries velocity info - "include_vel": False, - "body_asset_cfg": SceneEntityCfg("robot"), - "base_asset_cfg": SceneEntityCfg("robot"), - }, - ) - contact: ObsTerm = MISSING - - def __post_init__(self): - self.enable_corruption = True - self.concatenate_terms = True - self.history_length = 5 - - @configclass - class PerceptionObsCfg(ObsGroup): - """Observations for perception group.""" - - object_point_cloud = ObsTerm( - func=mdp.object_point_cloud_b, - noise=Unoise(n_min=-0.0, n_max=0.0), - clip=(-2.0, 2.0), # clamp between -2 m to 2 m - params={"num_points": 64, "flatten": True}, - ) - - def __post_init__(self): - self.enable_corruption = True - self.concatenate_dim = 0 - self.concatenate_terms = True - self.flatten_history_dim = True - self.history_length = 5 - - # observation groups - policy: PolicyCfg = PolicyCfg() - proprio: ProprioObsCfg = ProprioObsCfg() - perception: PerceptionObsCfg = PerceptionObsCfg() - - -@configclass -class EventCfg: - """Reset-mode events (shared by all physics backends).""" - - robot_physics_material = EventTerm( - func=mdp.randomize_rigid_body_material, - mode="startup", - params={ - "asset_cfg": SceneEntityCfg("robot", body_names=".*"), - "static_friction_range": [0.5, 1.0], - "dynamic_friction_range": [0.5, 1.0], - "restitution_range": [0.0, 0.0], - "num_buckets": 250, - }, - ) - - object_physics_material = EventTerm( - func=mdp.randomize_rigid_body_material, - mode="startup", - params={ - "asset_cfg": SceneEntityCfg("object", body_names=".*"), - "static_friction_range": [0.5, 1.0], - "dynamic_friction_range": [0.5, 1.0], - "restitution_range": [0.0, 0.0], - "num_buckets": 250, - }, - ) - - object_physics_inertia = EventTerm( - func=mdp.randomize_rigid_body_inertia, - mode="startup", - params={ - "asset_cfg": SceneEntityCfg("object"), - "inertia_distribution_params": [0.01, 0.01], - "operation": "add", - "diagonal_only": True, - }, - ) - - joint_stiffness_and_damping = EventTerm( - func=mdp.randomize_actuator_gains, - mode="startup", - params={ - "asset_cfg": SceneEntityCfg("robot", joint_names=".*"), - "stiffness_distribution_params": [0.5, 2.0], - "damping_distribution_params": [0.5, 2.0], - "operation": "scale", - }, - ) - - joint_friction = EventTerm( - func=mdp.randomize_joint_parameters, - mode="startup", - params={ - "asset_cfg": SceneEntityCfg("robot", joint_names=".*"), - "friction_distribution_params": [0.0, 5.0], - "operation": "scale", - }, - ) - - object_scale_mass = EventTerm( - func=mdp.randomize_rigid_body_mass, - mode="startup", - params={ - "asset_cfg": SceneEntityCfg("object"), - "mass_distribution_params": [0.2, 2.5], - "operation": "scale", - }, - ) - - # Gravity scheduling is a deliberate curriculum trick — starting with no - # gravity (easy) and gradually introducing full gravity (hard) makes learning - # smoother and removes the need for a separate "Lift" reward. - variable_gravity = EventTerm( - func=mdp.randomize_physics_scene_gravity, - mode="reset", - params={ - "gravity_distribution_params": ([0.0, 0.0, 0.0], [0.0, 0.0, 0.0]), - "operation": "abs", - }, - ) - - # robot configs add their static-obstacle geometry to ``params["valid_criteria"]`` - conditional_reset = EventTerm( - func="isaaclab_tasks.core.dexsuite.mdp.events:conditional_reset", - mode="reset", - params={ - "terms": { - "reset_root": EventTerm( - func=mdp.reset_root_state_uniform, - mode="reset", - params={ - "pose_range": {"x": [-0.0, 0.0], "y": [-0.0, 0.0], "yaw": [-0.0, 0.0]}, - "velocity_range": {"x": [-0.0, 0.0], "y": [-0.0, 0.0], "z": [-0.0, 0.0]}, - "asset_cfg": SceneEntityCfg("robot"), - }, - ), - "reset_robot_joints": EventTerm( - func=mdp.reset_joints_by_offset, - mode="reset", - params={ - "position_range": [-0.50, 0.50], - "velocity_range": [0.0, 0.0], - }, - ), - "reset_robot_wrist_joint": EventTerm( - func=mdp.reset_joints_by_offset, - mode="reset", - params={ - "asset_cfg": SceneEntityCfg("robot", joint_names=["wrist"]), - "position_range": [-3, 3], - "velocity_range": [0.0, 0.0], - }, - ), - "reset_object": EventTerm( - func=mdp.reset_root_state_uniform, - mode="reset", - params={ - "pose_range": { - "x": [-0.2, 0.2], - "y": [-0.2, 0.2], - "z": [0.0, 0.4], - "roll": [-3.14, 3.14], - "pitch": [-3.14, 3.14], - "yaw": [-3.14, 3.14], - }, - "velocity_range": {"x": [-0.0, 0.0], "y": [-0.0, 0.0], "z": [-0.0, 0.0]}, - "asset_cfg": SceneEntityCfg("object"), - }, - ), - # spawn-in-hand curriculum: a small share of episodes starts with the - # object at the gripper (uniform random orientation, small body-frame - # offset); interpenetrating draws are rejected by object_robot_clearance. - # Must stay LAST: it reads the gripper pose after the robot reset terms. - "reset_object_to_target": EventTerm( - func="isaaclab_tasks.core.dexsuite.mdp.events:reset_to_target", - mode="reset", - params={ - "pose_range": {"x": [-0.04, 0.04], "y": [-0.04, 0.04], "z": [-0.04, 0.04]}, - "velocity_range": {}, - "probability": 0.25, - # robot configs must point this at their gripper body and may shift - # the z range along the approach axis (e.g. between the fingertips) - "target_cfg": MISSING, - "asset_cfg": SceneEntityCfg("object"), - }, - ), - }, - "buffer_size_per_group": 1024, - # harvest more candidates than the bank holds and keep the subset that is spread widest - # over the diversity feature; ``1.0`` keeps the states first-come instead. - "diversity_feature": mdp.GraspTravelDistanceCfg( - asset_name="robot", - body_names=MISSING, # overridden by robot configs - object_name="object", - command_name="object_pose", - ), - "valid_criteria": { - "object_robot_clearance": mdp.MeshClearanceCfg( - asset_name="robot", - body_names=".*", - object_name="object", - num_object_points=64, - min_clearance=0.0, - ), - "robot_table_clearance": mdp.SlabClearanceCfg( - asset_name="robot", - body_names=MISSING, # overridden by robot configs - object_name="object", - obstacle_slabs=[((-0.95, -0.15), (-0.75, 0.75), 0.255), (None, None, 0.0)], # table dimension - num_object_points=64, - min_clearance=0.02, - ), - }, - # restart from the banked states the policy solves about half the time rather than - # drawing uniformly, which keeps the already-mastered and still-hopeless states from - # taking up most of the episodes - "success_monitor": mdp.SuccessMonitorCfg(target_success_rate=0.5), - }, - ) - - -@configclass -class ActionsCfg: - pass - - -@configclass -class RewardsCfg: - """Reward terms for the MDP.""" - - action_l2 = RewTerm(func=mdp.action_l2, weight=-0.01) - - fingers_to_object = RewTerm(func=mdp.object_ee_distance, params={"std": 0.4}, weight=0.05) - - # Progress rewards pay once per ``min_improvement`` of ground gained on the best error so far, - # so ground already credited cannot be earned again by backing off and re-approaching. - position_tracking = RewTerm( - func=mdp.position_command_progress, - weight=5.0, - params={ - "asset_cfg": SceneEntityCfg("robot"), - "min_improvement": 0.0025, - "command_name": "object_pose", - "align_asset_cfg": SceneEntityCfg("object"), - }, - ) - - orientation_tracking = RewTerm( - func=mdp.orientation_command_progress, - weight=10.0, - params={ - "asset_cfg": SceneEntityCfg("robot"), - "min_improvement": 0.015, - "command_name": "object_pose", - "align_asset_cfg": SceneEntityCfg("object"), - }, - ) - - success = RewTerm( - func=mdp.success_reward, - weight=10, - params={ - "asset_cfg": SceneEntityCfg("robot"), - "pos_std": 0.05, - "rot_std": 0.5, - "command_name": "object_pose", - "align_asset_cfg": SceneEntityCfg("object"), - }, - ) - - early_termination = RewTerm(func=mdp.is_terminated_term, weight=-50, params={"term_keys": ["abnormal_robot"]}) - - -@configclass -class TerminationsCfg: - """Termination terms for the MDP.""" - - time_out = DoneTerm(func=mdp.time_out, time_out=True) - - object_out_of_bound = DoneTerm( - func=mdp.out_of_bound, - params={ - "in_bound_range": {"x": (-1.5, 0.5), "y": (-2.0, 2.0), "z": (0.3, 2.0)}, - "asset_cfg": SceneEntityCfg("object"), - }, - ) - - abnormal_robot = DoneTerm(func=mdp.joint_vel_out_of_limit) - - -@configclass -class PhysicsCfg(PresetCfg): - isaacsim_physx = PhysxCfg( - bounce_threshold_velocity=0.01, - gpu_max_rigid_patch_count=4 * 5 * 2**15, - gpu_found_lost_pairs_capacity=2**26, - ) - newton_mjwarp = NewtonCfg( - solver_cfg=MJWarpSolverCfg( - solver="newton", - integrator="implicitfast", - njmax=300, - nconmax=200, - impratio=1.0, - cone="pyramidal", - update_data_interval=2, - iterations=100, - ls_iterations=15, - use_mujoco_contacts=False, - ccd_iterations=35, - ), - collision_cfg=NewtonCollisionPipelineCfg(rigid_contact_max=4000000), - default_shape_cfg=NewtonShapeCfg(), - num_substeps=2, - debug_mode=False, - ) - physx = PhysxAutoCfg(isaacsim_physx=isaacsim_physx) - default = physx - - -@configclass -class DexsuiteReorientEnvCfg(ManagerBasedRLEnvCfg): - """Dexsuite reorientation task definition, also the base definition for derivative Lift task and evaluation task""" - - # Scene settings - viewer: ViewerCfg = ViewerCfg(eye=(-2.25, 0.0, 0.75), lookat=(0.0, 0.0, 0.45), origin_type="env") - scene: SceneCfg = SceneCfg(num_envs=4096, env_spacing=3, replicate_physics=True) - # Basic settings - observations: ObservationsCfg = ObservationsCfg() - actions: ActionsCfg = ActionsCfg() - commands: CommandsCfg = CommandsCfg() - # MDP settings - rewards: RewardsCfg = RewardsCfg() - terminations: TerminationsCfg = TerminationsCfg() - events: EventCfg = EventCfg() - curriculum: CurriculumCfg | None = CurriculumCfg() - - def validate_config(self): - """Check for invalid preset combinations after resolution.""" - - warp_supported = { - "rgb", - "depth", - "distance_to_camera", - "distance_to_image_plane", - "normals", - "semantic_segmentation", - "instance_segmentation", - } - for cam_attr in ("base_camera", "wrist_camera"): - cam = getattr(self.scene, cam_attr, None) - if cam is None: - continue - renderer_type = getattr(getattr(cam, "renderer_cfg", None), "renderer_type", None) - if renderer_type == "newton_warp": - unsupported = set(cam.data_types) - warp_supported - if unsupported: - raise ValueError( - f"Warp renderer only supports data types {sorted(warp_supported)}, " - f"but '{cam_attr}' is configured with unsupported types: {sorted(unsupported)}. " - "Choose a compatible preset, e.g. presets=newton_renderer,rgb128." - ) - - def __post_init__(self): - """Post initialization.""" - # general settings - self.decimation = 4 # 50 Hz - - # *single-goal setup - self.commands.object_pose.resampling_time_range = (2.0, 3.0) - self.commands.object_pose.position_only = False - self.episode_length_s = 6.0 - self.is_finite_horizon = False - - # simulation settings - self.sim.dt = 1 / 120 - self.sim.render_interval = self.decimation - self.sim.physics = PhysicsCfg() - - def play_mode(self): - # play-mode overrides of parent - super().play_mode() - - self.commands.object_pose.debug_vis = True - # the bank shapes what a policy trains on; at play it only has to supply starts for the - # handful of environments the parent left, so it is harvested small and taken as it comes - # rather than making the viewer wait through an oversampled prefill and its spread pass - reset_params = self.events.conditional_reset.params - reset_params["buffer_size_per_group"] = 32 - reset_params["oversample_factor"] = 1.0 - reset_params["diversity_feature"] = None - if self.curriculum is not None: - self.curriculum.adr.params["init_difficulty"] = self.curriculum.adr.params["max_difficulty"] - self.curriculum.adr.params["promotion_only"] = True - # the parent turned observation corruption off, which leaves the noise terms nothing to scale - self.curriculum.disable_observation_noise_terms() - - -class DexsuiteLiftEnvCfg(DexsuiteReorientEnvCfg): - """Dexsuite lift task definition""" - - def __post_init__(self): - super().__post_init__() - self.rewards.orientation_tracking = None # no orientation reward - self.commands.object_pose.position_only = True - if self.curriculum is not None: - self.rewards.success.params["rot_std"] = None # make success reward not consider orientation - - def play_mode(self): - # play-mode overrides of parent - super().play_mode() - - self.commands.object_pose.position_only = True diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/__init__.pyi b/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/__init__.pyi deleted file mode 100644 index a36828d922a3..000000000000 --- a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/__init__.pyi +++ /dev/null @@ -1,71 +0,0 @@ -# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md). -# All rights reserved. -# -# SPDX-License-Identifier: BSD-3-Clause - -__all__ = [ - "GraspTravelDistanceCfg", - "MeshClearanceCfg", - "SlabClearanceCfg", - "SuccessMonitor", - "SuccessMonitorCfg", - "grasp_travel_distance", - "mesh_clearance", - "slab_clearance", - "conditional_reset", - "reset_joints_shared_offset", - "reset_to_target", - "get_reset_state", - "set_reset_state", - "ObjectUniformPoseCommandCfg", - "DifficultyScheduler", - "initial_final_interpolate_fn", - "body_state_b", - "fingers_contact_force_b", - "object_point_cloud_b", - "object_quat_b", - "vision_camera", - "contacts", - "contact_count", - "object_ee_distance", - "orientation_command_error_tanh", - "orientation_command_progress", - "position_command_error_tanh", - "position_command_progress", - "success_reward", - "abnormal_robot_state", - "out_of_bound", -] - -from .commands import ObjectUniformPoseCommandCfg -from .curriculums import DifficultyScheduler, initial_final_interpolate_fn -from .events import ( - SuccessMonitor, - conditional_reset, - grasp_travel_distance, - mesh_clearance, - reset_joints_shared_offset, - reset_to_target, - slab_clearance, -) -from .utils import get_reset_state, set_reset_state -from .events_cfg import GraspTravelDistanceCfg, MeshClearanceCfg, SlabClearanceCfg, SuccessMonitorCfg -from .observations import ( - body_state_b, - fingers_contact_force_b, - object_point_cloud_b, - object_quat_b, - vision_camera, -) -from .rewards import ( - contacts, - contact_count, - object_ee_distance, - orientation_command_error_tanh, - orientation_command_progress, - position_command_error_tanh, - position_command_progress, - success_reward, -) -from .terminations import abnormal_robot_state, out_of_bound -from isaaclab.envs.mdp import * diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/observations.py b/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/observations.py deleted file mode 100644 index 37f8718723a1..000000000000 --- a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/observations.py +++ /dev/null @@ -1,259 +0,0 @@ -# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md). -# All rights reserved. -# -# SPDX-License-Identifier: BSD-3-Clause - -from __future__ import annotations - -from typing import TYPE_CHECKING - -import torch - -from isaaclab.managers import ManagerTermBase, SceneEntityCfg -from isaaclab.utils.math import quat_apply, quat_apply_inverse, quat_inv, quat_mul, subtract_frame_transforms - -if TYPE_CHECKING: - from isaaclab.assets import Articulation, RigidObject - from isaaclab.envs import ManagerBasedRLEnv - from isaaclab.managers import ObservationTermCfg - from isaaclab.sensors import Camera - - -def object_quat_b( - env: ManagerBasedRLEnv, - robot_cfg: SceneEntityCfg = SceneEntityCfg("robot"), - object_cfg: SceneEntityCfg = SceneEntityCfg("object"), -) -> torch.Tensor: - """Object orientation in the robot's root frame. - - Args: - env: The environment. - robot_cfg: Scene entity for the robot (reference frame). Defaults to ``SceneEntityCfg("robot")``. - object_cfg: Scene entity for the object. Defaults to ``SceneEntityCfg("object")``. - - Returns: - Tensor of shape ``(num_envs, 4)``: object quaternion ``(w, x, y, z)`` in the robot root frame. - """ - robot: RigidObject = env.scene[robot_cfg.name] - object: RigidObject = env.scene[object_cfg.name] - return quat_mul(quat_inv(robot.data.root_quat_w.torch), object.data.root_quat_w.torch) - - -class body_state_b(ManagerTermBase): - """Body state (pos, quat, lin vel, ang vel) in the base asset's root frame. - - The state for each body is stacked horizontally as - ``[position(3), quaternion(4)(wxyz), linvel(3), angvel(3)]`` and then concatenated over bodies. - - The body indices are baked to a device tensor at construction. - """ - - def __init__(self, cfg: ObservationTermCfg, env: ManagerBasedRLEnv): - super().__init__(cfg, env) - body_ids = cfg.params["body_asset_cfg"].body_ids - if isinstance(body_ids, list): - body_ids = torch.tensor(body_ids, dtype=torch.long, device=env.device) - self._body_ids = body_ids - - def __call__( - self, - env: ManagerBasedRLEnv, - body_asset_cfg: SceneEntityCfg, - base_asset_cfg: SceneEntityCfg, - include_vel: bool = True, - ) -> torch.Tensor: - """Compute the stacked body states. - - Args: - env: The environment. - body_asset_cfg: Scene entity for the articulated body whose links are observed. - base_asset_cfg: Scene entity providing the reference (root) frame. - include_vel: Whether to append the body linear/angular velocities. - - Returns: - Tensor of shape ``(num_envs, num_bodies * 13)`` (``num_bodies * 7`` without - velocities) with per-body states expressed in the base root frame. - """ - body_asset: Articulation = env.scene[body_asset_cfg.name] - base_asset: Articulation = env.scene[base_asset_cfg.name] - # get world pose of bodies - body_pos_w = body_asset.data.body_pos_w.torch[:, self._body_ids].view(-1, 3) - body_quat_w = body_asset.data.body_quat_w.torch[:, self._body_ids].view(-1, 4) - num_bodies = int(body_pos_w.shape[0] / env.num_envs) - # get world pose of base frame - root_pos_w = base_asset.data.root_link_pos_w.torch.unsqueeze(1).repeat_interleave(num_bodies, dim=1).view(-1, 3) - root_quat_w = ( - base_asset.data.root_link_quat_w.torch.unsqueeze(1).repeat_interleave(num_bodies, dim=1).view(-1, 4) - ) - # transform from world body pose to local body pose - body_pos_b, body_quat_b = subtract_frame_transforms(root_pos_w, root_quat_w, body_pos_w, body_quat_w) - # note: body velocities are the most engine/solver-sensitive observables (derivative - # signals amplify integrator and contact-response differences); pose-only states with - # observation history transfer across physics backends, velocity states do not. - if include_vel: - body_lin_vel_w = body_asset.data.body_lin_vel_w.torch[:, self._body_ids].view(-1, 3) - body_ang_vel_w = body_asset.data.body_ang_vel_w.torch[:, self._body_ids].view(-1, 3) - body_lin_vel_b = quat_apply_inverse(root_quat_w, body_lin_vel_w) - body_ang_vel_b = quat_apply_inverse(root_quat_w, body_ang_vel_w) - out = torch.cat((body_pos_b, body_quat_b, body_lin_vel_b, body_ang_vel_b), dim=1) - else: - out = torch.cat((body_pos_b, body_quat_b), dim=1) - return out.view(env.num_envs, -1) - - -class object_point_cloud_b(ManagerTermBase): - """Object surface point cloud expressed in a reference asset's root frame. - - Points are pre-sampled on the object's surface in its local frame and transformed to world, - then into the reference (e.g., robot) root frame. Optionally visualizes the points. - - Args (from ``cfg.params``): - object_cfg: Scene entity for the object to sample. Defaults to ``SceneEntityCfg("object")``. - ref_asset_cfg: Scene entity providing the reference frame. Defaults to ``SceneEntityCfg("robot")``. - num_points: Number of points to sample on the object surface. Defaults to ``10``. - visualize: Whether to draw markers for the points. Defaults to ``True``. - static: If ``True``, cache world-space points on reset and reuse them (no per-step resampling). - - Returns (from ``__call__``): - If ``flatten=False``: tensor of shape ``(num_envs, num_points, 3)``. - If ``flatten=True``: tensor of shape ``(num_envs, 3 * num_points)``. - """ - - def __init__(self, cfg, env: ManagerBasedRLEnv): - super().__init__(cfg, env) - - self.object_cfg: SceneEntityCfg = cfg.params.get("object_cfg", SceneEntityCfg("object")) - self.ref_asset_cfg: SceneEntityCfg = cfg.params.get("ref_asset_cfg", SceneEntityCfg("robot")) - num_points: int = cfg.params.get("num_points", 10) - self.object: RigidObject = env.scene[self.object_cfg.name] - self.ref_asset: Articulation = env.scene[self.ref_asset_cfg.name] - # lazy initialize visualizer and point cloud - if cfg.params.get("visualize", True): - from isaaclab.markers import VisualizationMarkers - from isaaclab.markers.config import RAY_CASTER_MARKER_CFG - - ray_cfg = RAY_CASTER_MARKER_CFG.replace(prim_path="/Visuals/ObservationPointCloud") - ray_cfg.markers["hit"].radius = 0.0025 - self.visualizer = VisualizationMarkers(ray_cfg) - from .utils import sample_object_point_cloud - - self.points_local = sample_object_point_cloud( - env.num_envs, num_points, self.object.cfg.prim_path, device=env.device - ) - self.points_w = torch.zeros_like(self.points_local) - - def __call__( - self, - env: ManagerBasedRLEnv, - ref_asset_cfg: SceneEntityCfg = SceneEntityCfg("robot"), - object_cfg: SceneEntityCfg = SceneEntityCfg("object"), - num_points: int = 10, - flatten: bool = False, - visualize: bool = True, - ): - """Compute the object point cloud in the reference asset's root frame. - - Note: - Points are pre-sampled at initialization using ``self.num_points``; the ``num_points`` argument is - kept for API symmetry and does not change the sampled set at runtime. - - Args: - env: The environment. - ref_asset_cfg: Reference frame provider (root). Defaults to ``SceneEntityCfg("robot")``. - object_cfg: Object to sample. Defaults to ``SceneEntityCfg("object")``. - num_points: Unused at runtime; see note above. - flatten: If ``True``, return a flattened tensor ``(num_envs, 3 * num_points)``. - visualize: If ``True``, draw markers for the points. - - Returns: - Tensor of shape ``(num_envs, num_points, 3)`` or flattened if requested. - """ - ref_pos_w = self.ref_asset.data.root_pos_w.torch.unsqueeze(1).repeat(1, num_points, 1) - ref_quat_w = self.ref_asset.data.root_quat_w.torch.unsqueeze(1).repeat(1, num_points, 1) - - object_pos_w = self.object.data.root_pos_w.torch.unsqueeze(1).repeat(1, num_points, 1) - object_quat_w = self.object.data.root_quat_w.torch.unsqueeze(1).repeat(1, num_points, 1) - # apply rotation + translation - self.points_w = quat_apply(object_quat_w, self.points_local) + object_pos_w - if visualize: - self.visualizer.visualize(translations=self.points_w.view(-1, 3)) - object_point_cloud_pos_b, _ = subtract_frame_transforms(ref_pos_w, ref_quat_w, self.points_w, None) - - return object_point_cloud_pos_b.view(env.num_envs, -1) if flatten else object_point_cloud_pos_b - - -def fingers_contact_force_b( - env: ManagerBasedRLEnv, - contact_sensor_names: list[str], - asset_cfg: SceneEntityCfg = SceneEntityCfg("robot"), -) -> torch.Tensor: - """base-frame contact forces from listed sensors, concatenated per env. - - Args: - env: The environment. - contact_sensor_names: Names of contact sensors in ``env.scene.sensors`` to read. - - Returns: - Tensor of shape ``(num_envs, 3 * num_sensors)`` with forces stacked horizontally as - ``[fx, fy, fz]`` per sensor. - """ - force_w = [env.scene.sensors[name].data.force_matrix_w.torch.view(env.num_envs, 3) for name in contact_sensor_names] - force_w = torch.stack(force_w, dim=1) - robot: Articulation = env.scene[asset_cfg.name] - root_link_quat_w = robot.data.root_link_quat_w.torch - forces_b = quat_apply_inverse(root_link_quat_w.unsqueeze(1).repeat(1, force_w.shape[1], 1), force_w) - return forces_b.view(env.num_envs, -1) - - -class vision_camera(ManagerTermBase): - def __init__(self, cfg, env: ManagerBasedRLEnv): - super().__init__(cfg, env) - sensor_cfg: SceneEntityCfg = cfg.params.get("sensor_cfg", SceneEntityCfg("tiled_camera")) - self.sensor: Camera = env.scene.sensors[sensor_cfg.name] - self.sensor_type = self.sensor.cfg.data_types[0] - self.norm_fn = ( - self._depth_norm - if self.sensor_type == "distance_to_image_plane" or self.sensor_type == "depth" - else self._rgb_norm - ) - - def __call__( - self, env: ManagerBasedRLEnv, sensor_cfg: SceneEntityCfg, normalize: bool = True - ) -> torch.Tensor: # obtain the input image - images = self.sensor.data.output[self.sensor_type] - torch.nan_to_num_(images, nan=1e6) - if normalize: - images = self.norm_fn(images) - images = images.permute(0, 3, 1, 2).contiguous() - return images - - def _rgb_norm(self, images: torch.Tensor) -> torch.Tensor: - return images.float() / 255.0 - 0.5 - - def _depth_norm(self, images: torch.Tensor) -> torch.Tensor: - # same [-0.5, 0.5) span as the RGB normalization: a wider depth range doubles the - # encoder's effective input scale and halves the stable learning-rate budget - return torch.tanh(images / 2) - 0.5 - - def show_collage(self, images: torch.Tensor, save_path: str = "collage.png"): - import matplotlib - import numpy as np - from PIL import Image - - a = images.detach().cpu().numpy() - n, h, w, c = a.shape - s = int(np.ceil(np.sqrt(n))) - canvas = np.full((s * h, s * w, 3), 255, np.uint8) - turbo = matplotlib.colormaps["turbo"] - for i in range(n): - r, col = divmod(i, s) - img = a[i] - if c == 1: - d = img[..., 0] - d = (d - d.min()) / (np.ptp(d) + 1e-8) - rgb = (turbo(d)[..., :3] * 255).astype(np.uint8) - else: - x = img if img.max() > 1 else img * 255 - rgb = np.clip(x, 0, 255).astype(np.uint8) - canvas[r * h : (r + 1) * h, col * w : (col + 1) * w] = rgb - Image.fromarray(canvas).save(save_path) diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/rewards.py b/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/rewards.py deleted file mode 100644 index b39db6263dde..000000000000 --- a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/rewards.py +++ /dev/null @@ -1,369 +0,0 @@ -# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md). -# All rights reserved. -# -# SPDX-License-Identifier: BSD-3-Clause - -from __future__ import annotations - -import warnings -from collections.abc import Sequence -from typing import TYPE_CHECKING - -import torch - -from isaaclab.managers import ManagerTermBase, SceneEntityCfg -from isaaclab.utils import math as math_utils -from isaaclab.utils.math import combine_frame_transforms, compute_pose_error - -if TYPE_CHECKING: - from isaaclab.assets import RigidObject - from isaaclab.envs import ManagerBasedRLEnv - from isaaclab.sensors import ContactSensor - - -def object_ee_distance( - env: ManagerBasedRLEnv, - std: float, - thumb_name: str, - finger_names: list[str], - contact_threshold: float = 1.0, - object_cfg: SceneEntityCfg = SceneEntityCfg("object"), - asset_cfg: SceneEntityCfg = SceneEntityCfg("robot"), -) -> torch.Tensor: - """Reward reaching the object using a tanh-kernel on end-effector distance with contact bonus. - - The reward is close to 1 when the distance is small. The reward is scaled by contact: - - Full reward (1x) when good contact (thumb + finger) - - Reduced reward (0.1x) when no contact - - Args: - env: The environment instance. - std: Standard deviation for tanh kernel. - thumb_name: Name of the thumb contact sensor. - finger_names: Names of the finger contact sensors. - contact_threshold: Contact force magnitude threshold. - object_cfg: Configuration for the object. - asset_cfg: Configuration for the robot asset. - """ - asset: RigidObject = env.scene[asset_cfg.name] - obj: RigidObject = env.scene[object_cfg.name] - asset_pos = asset.data.body_pos_w.torch[:, asset_cfg.body_ids] - object_pos = obj.data.root_pos_w.torch - distance = torch.linalg.norm(asset_pos - object_pos[:, None, :], dim=-1).max(dim=-1).values - contact_bonus = contacts(env, contact_threshold, thumb_name, finger_names).float().clamp(0.1, 1.0) - return (1 - torch.tanh(distance / std)) * contact_bonus - - -def _contact_force_mag(sensor: ContactSensor, num_envs: int) -> torch.Tensor: - """Extract per-environment contact force magnitude from a sensor's force_matrix_w.""" - force = sensor.data.force_matrix_w.torch.view(num_envs, 3) - return torch.linalg.norm(force, dim=-1) - - -def contacts(env: ManagerBasedRLEnv, threshold: float, thumb_name: str, finger_names: list[str]) -> torch.Tensor: - """Reward for good contact: thumb + at least one finger above threshold. - - Args: - env: The environment instance. - threshold: Contact force magnitude threshold. - thumb_name: Name of the thumb contact sensor in the scene. - finger_names: Names of the finger contact sensors in the scene. - - Returns: - Boolean tensor indicating good contact condition per environment. - """ - thumb_mag = _contact_force_mag(env.scene.sensors[thumb_name], env.num_envs) - - any_finger_contact = torch.zeros(env.num_envs, dtype=torch.bool, device=env.device) - for finger_name in finger_names: - finger_mag = _contact_force_mag(env.scene.sensors[finger_name], env.num_envs) - any_finger_contact = any_finger_contact | (finger_mag > threshold) - - return (thumb_mag > threshold) & any_finger_contact - - -def contact_count(env: ManagerBasedRLEnv, threshold: float, sensor_names: list[str]) -> torch.Tensor: - """Count the number of contact sensors with force above threshold. - - For each sensor that detects contact above the threshold, add 1 to the total. - This provides a reward proportional to the number of fingers in contact. - - Args: - env: The environment instance. - threshold: Contact force magnitude threshold. - sensor_names: Names of the contact sensors in the scene. - - Returns: - Tensor of shape (num_envs,) with the count of sensors in contact per environment. - """ - count = torch.zeros(env.num_envs, dtype=torch.float32, device=env.device) - - for sensor_name in sensor_names: - mag = _contact_force_mag(env.scene.sensors[sensor_name], env.num_envs) - count += (mag > threshold).float() - return count / len(sensor_names) - - -class success_reward(ManagerTermBase): - """Reward success by comparing commanded pose to the object pose using tanh kernels on error. - - The reward is gated by contact: only given when thumb + at least one finger are in contact. - - Maintains a sticky ``succeeded`` boolean tensor per environment that flips to ``True`` once - the success condition is met during an episode and resets to ``False`` on environment reset. - - Args: - cfg: Configuration object specifying term parameters. - env: The manager-based RL environment. - """ - - def __init__(self, cfg, env: ManagerBasedRLEnv): - super().__init__(cfg, env) - self.succeeded = torch.zeros(env.num_envs, dtype=torch.bool, device=env.device) - - def reset(self, env_ids: Sequence[int] | None = None): - if env_ids is None: - env_ids = slice(None) - self.succeeded[env_ids] = False - - def __call__( - self, - env: ManagerBasedRLEnv, - command_name: str, - asset_cfg: SceneEntityCfg, - align_asset_cfg: SceneEntityCfg, - pos_std: float, - thumb_name: str, - finger_names: list[str], - contact_threshold: float = 0.01, - rot_std: float | None = None, - ) -> torch.Tensor: - asset: RigidObject = env.scene[asset_cfg.name] - obj: RigidObject = env.scene[align_asset_cfg.name] - command = env.command_manager.get_command(command_name) - des_pos_w, des_quat_w = combine_frame_transforms( - asset.data.root_pos_w.torch, - asset.data.root_quat_w.torch, - command[:, :3], - command[:, 3:7], - ) - pos_err, rot_err = compute_pose_error( - des_pos_w, - des_quat_w, - obj.data.root_pos_w.torch, - obj.data.root_quat_w.torch, - ) - pos_dist = torch.linalg.norm(pos_err, dim=1) - contact_mask = contacts(env, contact_threshold, thumb_name, finger_names) - - if rot_std: - rot_dist = torch.linalg.norm(rot_err, dim=1) - reward = (1 - torch.tanh(pos_dist / pos_std)) * (1 - torch.tanh(rot_dist / rot_std)) * contact_mask.float() - self.succeeded |= (pos_dist < pos_std) & (rot_dist < rot_std) & contact_mask - else: - reward = ((1 - torch.tanh(pos_dist / pos_std)) ** 2) * contact_mask.float() - self.succeeded |= (pos_dist < pos_std) & contact_mask - - return reward - - -def position_command_error_tanh( - env: ManagerBasedRLEnv, - std: float, - command_name: str, - asset_cfg: SceneEntityCfg, - align_asset_cfg: SceneEntityCfg, - thumb_name: str, - finger_names: list[str], - contact_threshold: float = 0.1, -) -> torch.Tensor: - """Reward tracking of commanded position using tanh kernel, gated by contact presence. - - .. deprecated:: - Use :class:`position_command_progress`, which pays per increment of ground gained on the - best error so far instead of paying every step the object is near the goal. Replace - ``std`` with ``min_improvement``. - """ - warnings.warn( - "The reward term 'position_command_error_tanh' is deprecated. Use 'position_command_progress' instead," - " replacing 'std' with 'min_improvement'.", - DeprecationWarning, - stacklevel=2, - ) - asset: RigidObject = env.scene[asset_cfg.name] - obj: RigidObject = env.scene[align_asset_cfg.name] - command = env.command_manager.get_command(command_name) - des_pos_w, _ = combine_frame_transforms( - asset.data.root_pos_w.torch, - asset.data.root_quat_w.torch, - command[:, :3], - ) - distance = torch.linalg.norm(obj.data.root_pos_w.torch - des_pos_w, dim=1) - return (1 - torch.tanh(distance / std)) * contacts(env, contact_threshold, thumb_name, finger_names).float() - - -def orientation_command_error_tanh( - env: ManagerBasedRLEnv, - std: float, - command_name: str, - asset_cfg: SceneEntityCfg, - align_asset_cfg: SceneEntityCfg, - thumb_name: str, - finger_names: list[str], - contact_threshold: float = 0.1, -) -> torch.Tensor: - """Reward tracking of commanded orientation using tanh kernel, gated by contact presence. - - .. deprecated:: - Use :class:`orientation_command_progress`, which pays per increment of ground gained on the - best error so far instead of paying every step the object is near the goal. Replace - ``std`` with ``min_improvement``. - """ - warnings.warn( - "The reward term 'orientation_command_error_tanh' is deprecated. Use 'orientation_command_progress' instead," - " replacing 'std' with 'min_improvement'.", - DeprecationWarning, - stacklevel=2, - ) - asset: RigidObject = env.scene[asset_cfg.name] - obj: RigidObject = env.scene[align_asset_cfg.name] - command = env.command_manager.get_command(command_name) - des_quat_w = math_utils.quat_mul(asset.data.root_link_quat_w.torch, command[:, 3:7]) - quat_distance = math_utils.quat_error_magnitude(obj.data.root_quat_w.torch, des_quat_w) - return (1 - torch.tanh(quat_distance / std)) * contacts(env, contact_threshold, thumb_name, finger_names).float() - - -class _ProgressReward(ManagerTermBase): - """Base class for rewards that only pay out when a tracking error reaches a new episode best. - - The term holds a per-environment bar equal to the smallest error credited so far in the episode. - A fixed reward of ``1.0`` is paid on every step that pushes the error below that bar by at least - ``min_improvement``, and nothing is paid otherwise. Since the bar moves only when a reward is - paid, ground that was already credited cannot be farmed again by backing off and re-approaching, - and the episodic reward sum counts how many improvements the policy actually made. - - The bar is seeded with the error measured on the first step of an episode, so holding the starting - pose earns nothing. Progress made while the gating condition is false does not move the bar, so it - stays claimable once the condition is met again. The bar is measured against the command in force, - so it is re-seeded whenever the command resamples and never carries across goals. - """ - - def __init__(self, cfg, env: ManagerBasedRLEnv): - super().__init__(cfg, env) - # inf marks an environment whose bar has not been seeded yet against its current command - self.best_error = torch.full((env.num_envs,), float("inf"), device=env.device) - self._prev_command: torch.Tensor | None = None - - def reset(self, env_ids: Sequence[int] | None = None): - if env_ids is None: - env_ids = slice(None) - self.best_error[env_ids] = float("inf") - - def _progress( - self, error: torch.Tensor, gate: torch.Tensor, min_improvement: float, command: torch.Tensor - ) -> torch.Tensor: - """Return 1.0 for the environments that beat their best error under the command in force. - - Args: - error: Current tracking error per environment. - gate: Environments allowed to be credited this step. - min_improvement: Amount the error must beat the bar by to be paid again. - command: Command being tracked; a change re-seeds the bar for that environment. - - Returns: - Tensor of shape ``(num_envs,)`` that is ``1.0`` where a payout is due. - """ - # a resampled command changes the error's reference, so the bar it was measured against no - # longer applies; dropping it to inf re-seeds from the first error under the new command - if self._prev_command is None: - self._prev_command = command.clone() - else: - self.best_error[(self._prev_command != command).any(dim=1)] = float("inf") - self._prev_command.copy_(command) - unseeded = torch.isinf(self.best_error) - self.best_error[unseeded] = error[unseeded] - improved = gate & (error < self.best_error - min_improvement) - self.best_error[improved] = error[improved] - return improved.float() - - -class position_command_progress(_ProgressReward): - """Reward every step that brings the object closer to the commanded position than ever before. - - See :class:`_ProgressReward` for the progress bookkeeping. The reward is gated by contact, so - only positional gains made while the thumb and at least one finger are touching are credited. - """ - - def __call__( - self, - env: ManagerBasedRLEnv, - command_name: str, - asset_cfg: SceneEntityCfg, - align_asset_cfg: SceneEntityCfg, - thumb_name: str, - finger_names: list[str], - contact_threshold: float = 0.1, - min_improvement: float = 0.01, - ) -> torch.Tensor: - """Compute the progress reward. - - Args: - env: The environment instance. - command_name: Name of the pose command to track. - asset_cfg: Configuration for the asset the command is expressed relative to. - align_asset_cfg: Configuration for the asset that must reach the command. - thumb_name: Name of the thumb contact sensor. - finger_names: Names of the finger contact sensors. - contact_threshold: Contact force magnitude threshold [N]. - min_improvement: Distance [m] the object must gain on the episode best to be paid again. - """ - asset: RigidObject = env.scene[asset_cfg.name] - obj: RigidObject = env.scene[align_asset_cfg.name] - command = env.command_manager.get_command(command_name) - des_pos_w, _ = combine_frame_transforms( - asset.data.root_pos_w.torch, - asset.data.root_quat_w.torch, - command[:, :3], - ) - distance = torch.linalg.norm(obj.data.root_pos_w.torch - des_pos_w, dim=1) - gate = contacts(env, contact_threshold, thumb_name, finger_names) - return self._progress(distance, gate, min_improvement, command) - - -class orientation_command_progress(_ProgressReward): - """Reward every step that brings the object closer to the commanded orientation than ever before. - - See :class:`_ProgressReward` for the progress bookkeeping. The reward is gated by contact, so - only rotational gains made while the thumb and at least one finger are touching are credited. - """ - - def __call__( - self, - env: ManagerBasedRLEnv, - command_name: str, - asset_cfg: SceneEntityCfg, - align_asset_cfg: SceneEntityCfg, - thumb_name: str, - finger_names: list[str], - contact_threshold: float = 0.1, - min_improvement: float = 0.05, - ) -> torch.Tensor: - """Compute the progress reward. - - Args: - env: The environment instance. - command_name: Name of the pose command to track. - asset_cfg: Configuration for the asset the command is expressed relative to. - align_asset_cfg: Configuration for the asset that must reach the command. - thumb_name: Name of the thumb contact sensor. - finger_names: Names of the finger contact sensors. - contact_threshold: Contact force magnitude threshold [N]. - min_improvement: Angle [rad] the object must gain on the episode best to be paid again. - """ - asset: RigidObject = env.scene[asset_cfg.name] - obj: RigidObject = env.scene[align_asset_cfg.name] - command = env.command_manager.get_command(command_name) - des_quat_w = math_utils.quat_mul(asset.data.root_link_quat_w.torch, command[:, 3:7]) - quat_distance = math_utils.quat_error_magnitude(obj.data.root_quat_w.torch, des_quat_w) - gate = contacts(env, contact_threshold, thumb_name, finger_names) - return self._progress(quat_distance, gate, min_improvement, command) diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/terminations.py b/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/terminations.py deleted file mode 100644 index 5edd0d1539fb..000000000000 --- a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/terminations.py +++ /dev/null @@ -1,70 +0,0 @@ -# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md). -# All rights reserved. -# -# SPDX-License-Identifier: BSD-3-Clause - -"""Common functions that can be used to activate certain terminations for the dexsuite task. - -The functions can be passed to the :class:`isaaclab.managers.TerminationTermCfg` object to enable -the termination introduced by the function. -""" - -from __future__ import annotations - -from typing import TYPE_CHECKING - -import torch - -from isaaclab.managers import ManagerTermBase, SceneEntityCfg, TerminationTermCfg - -if TYPE_CHECKING: - from isaaclab.assets import Articulation, RigidObject - from isaaclab.envs import ManagerBasedRLEnv - - -class out_of_bound(ManagerTermBase): - """Termination condition for when the object falls out of bound. - - The world-space bounds are cached and rebuilt per axis only when the corresponding - ``in_bound_range`` entry changes. This keeps the hot path free of host-to-device - transfers while still honoring runtime updates (e.g. from a curriculum term). - """ - - def __init__(self, cfg: TerminationTermCfg, env: ManagerBasedRLEnv): - super().__init__(cfg, env) - - asset_cfg: SceneEntityCfg = cfg.params.get("asset_cfg", SceneEntityCfg("object")) - self._object: RigidObject = env.scene[asset_cfg.name] - - # Pre-apply env_origins so we can compare directly against world-space positions. - self._origins = env.scene.env_origins # (N, 3) - self._lower = self._origins.clone() # (N, 3) - self._upper = self._origins.clone() # (N, 3) - self._cached_axis: list[tuple[float, ...] | None] = [None, None, None] - - def __call__( - self, - env: ManagerBasedRLEnv, - asset_cfg: SceneEntityCfg = SceneEntityCfg("object"), - in_bound_range: dict[str, tuple[float, float]] = {}, - ) -> torch.Tensor: - # rebuild only the axes whose bounds changed (curriculum typically only moves one) - for i, key in enumerate(["x", "y", "z"]): - bounds = tuple(in_bound_range.get(key, (0.0, 0.0))) - if bounds != self._cached_axis[i]: - lo, hi = bounds - self._lower[:, i] = self._origins[:, i] + lo - self._upper[:, i] = self._origins[:, i] + hi - self._cached_axis[i] = bounds - - pos_w = self._object.data.root_pos_w.torch - return ((pos_w < self._lower) | (pos_w > self._upper)).any(dim=1) - - -def abnormal_robot_state(env: ManagerBasedRLEnv, asset_cfg: SceneEntityCfg = SceneEntityCfg("robot")) -> torch.Tensor: - """Terminating environment when violation of velocity limits detects, this usually indicates unstable physics caused - by very bad, or aggressive action""" - robot: Articulation = env.scene[asset_cfg.name] - joint_vel = robot.data.joint_vel.torch - joint_vel_limits = robot.data.joint_vel_limits.torch - return (joint_vel.abs() > (joint_vel_limits * 2)).any(dim=1) diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/lift/__init__.py b/source/isaaclab_tasks/isaaclab_tasks/core/lift/__init__.py index 1211ee056649..b99bc3e8fe36 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/lift/__init__.py +++ b/source/isaaclab_tasks/isaaclab_tasks/core/lift/__init__.py @@ -3,7 +3,24 @@ # # SPDX-License-Identifier: BSD-3-Clause -"""Configurations for the object lift environments.""" +"""Lift environments. -# We leave this file empty since we don't want to expose any configs in this package directly. -# We still need this file to import the "config" module in the parent package. +Implementation Reference: + +Reorient: +@article{petrenko2023dexpbt, + title={Dexpbt: Scaling up dexterous manipulation for hand-arm systems with population based training}, + author={Petrenko, Aleksei and Allshire, Arthur and State, Gavriel and Handa, Ankur and Makoviychuk, Viktor}, + journal={arXiv preprint arXiv:2305.12127}, + year={2023} +} + +Lift: +@article{singh2024dextrah, + title={Dextrah-rgb: Visuomotor policies to grasp anything with dexterous hands}, + author={Singh, Ritvik and Allshire, Arthur and Handa, Ankur and Ratliff, Nathan and Van Wyk, Karl}, + journal={arXiv preprint arXiv:2412.01791}, + year={2024} +} + +""" diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/adr_curriculum.py b/source/isaaclab_tasks/isaaclab_tasks/core/lift/adr_curriculum.py similarity index 100% rename from source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/adr_curriculum.py rename to source/isaaclab_tasks/isaaclab_tasks/core/lift/adr_curriculum.py diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/__init__.py b/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/__init__.py index 1211ee056649..eccab38a80ce 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/__init__.py +++ b/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/__init__.py @@ -3,7 +3,7 @@ # # SPDX-License-Identifier: BSD-3-Clause -"""Configurations for the object lift environments.""" +"""Configurations for the lift environments.""" # We leave this file empty since we don't want to expose any configs in this package directly. # We still need this file to import the "config" module in the parent package. diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/franka/__init__.py b/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/franka/__init__.py index 62c3b0a656c2..a70b00cb6f65 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/franka/__init__.py +++ b/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/franka/__init__.py @@ -3,27 +3,32 @@ # # SPDX-License-Identifier: BSD-3-Clause +"""Lift Franka reorient and lift environments.""" + import gymnasium as gym -from isaaclab_tasks.core.lift.config.franka import agents +from . import agents ## # Register Gym environments. ## -## -# Joint Position Control -## +gym.register( + id="Isaac-Reorient-Franka", + entry_point="isaaclab.envs:ManagerBasedRLEnv", + disable_env_checker=True, + kwargs={ + "env_cfg_entry_point": f"{__name__}.franka_env_cfg:FrankaReorientEnvCfg", + "rsl_rl_cfg_entry_point": f"{agents.__name__}.rsl_rl_ppo_cfg:FrankaPPORunnerCfg", + }, +) gym.register( - id="Isaac-Lift-Cube-Franka", + id="Isaac-Lift-Franka", entry_point="isaaclab.envs:ManagerBasedRLEnv", disable_env_checker=True, kwargs={ - "env_cfg_entry_point": f"{__name__}.joint_pos_env_cfg:FrankaCubeLiftEnvCfg", - "rsl_rl_cfg_entry_point": f"{agents.__name__}.rsl_rl_ppo_cfg:LiftCubePPORunnerCfg", - "skrl_cfg_entry_point": f"{agents.__name__}:skrl_ppo_cfg.yaml", - "rl_games_cfg_entry_point": f"{agents.__name__}:rl_games_ppo_cfg.yaml", - "sb3_cfg_entry_point": f"{agents.__name__}:sb3_ppo_cfg.yaml", + "env_cfg_entry_point": f"{__name__}.franka_env_cfg:FrankaLiftEnvCfg", + "rsl_rl_cfg_entry_point": f"{agents.__name__}.rsl_rl_ppo_cfg:FrankaPPORunnerCfg", }, ) diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/franka/agents/rsl_rl_ppo_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/franka/agents/rsl_rl_ppo_cfg.py index 6dbea70f59be..a98326e1f8ae 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/franka/agents/rsl_rl_ppo_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/franka/agents/rsl_rl_ppo_cfg.py @@ -3,39 +3,66 @@ # # SPDX-License-Identifier: BSD-3-Clause +from dataclasses import MISSING + from isaaclab.utils.configclass import configclass -from isaaclab_rl.rsl_rl import RslRlMLPModelCfg, RslRlOnPolicyRunnerCfg, RslRlPpoAlgorithmCfg +from isaaclab_rl.rsl_rl import ( + RslRlMLPModelCfg, + RslRlOnPolicyRunnerCfg, + RslRlPpoAlgorithmCfg, +) + +from isaaclab_tasks.utils import PresetCfg + +STATE_POLICY_CFG = RslRlMLPModelCfg( + distribution_cfg=RslRlMLPModelCfg.GaussianDistributionCfg(init_std=1.0), + obs_normalization=True, + hidden_dims=[512, 256, 128], + activation="elu", +) + +STATE_CRITIC_CFG = RslRlMLPModelCfg( + obs_normalization=True, + hidden_dims=[512, 256, 128], + activation="elu", +) + + +ALGO_CFG = RslRlPpoAlgorithmCfg( + value_loss_coef=1.0, + use_clipped_value_loss=True, + clip_param=0.2, + entropy_coef=0.005, + num_learning_epochs=5, + num_mini_batches=4, + learning_rate=1.0e-3, + schedule="adaptive", + gamma=0.995, + lam=0.90, + desired_kl=0.01, + max_grad_norm=1.0, +) @configclass -class LiftCubePPORunnerCfg(RslRlOnPolicyRunnerCfg): - num_steps_per_env = 24 - max_iterations = 1500 - save_interval = 50 - experiment_name = "franka_lift" - actor = RslRlMLPModelCfg( - hidden_dims=[256, 128, 64], - activation="elu", - obs_normalization=False, - distribution_cfg=RslRlMLPModelCfg.GaussianDistributionCfg(init_std=1.0), - ) - critic = RslRlMLPModelCfg( - hidden_dims=[256, 128, 64], - activation="elu", - obs_normalization=False, - ) - algorithm = RslRlPpoAlgorithmCfg( - value_loss_coef=1.0, - use_clipped_value_loss=True, - clip_param=0.2, - entropy_coef=0.006, - num_learning_epochs=5, - num_mini_batches=4, - learning_rate=1.0e-4, - schedule="adaptive", - gamma=0.98, - lam=0.95, - desired_kl=0.01, - max_grad_norm=1.0, +class FrankaPPOBaseRunnerCfg(RslRlOnPolicyRunnerCfg): + num_steps_per_env = 32 + max_iterations = 15000 + save_interval = 250 + experiment_name = (MISSING,) # type: ignore + obs_groups = (MISSING,) # type: ignore + actor = (MISSING,) # type: ignore + critic = (MISSING,) # type: ignore + algorithm = MISSING # type: ignore + + +@configclass +class FrankaPPORunnerCfg(PresetCfg): + default = FrankaPPOBaseRunnerCfg().replace( + experiment_name="lift_franka", + obs_groups={"actor": ["policy", "proprio", "perception"], "critic": ["policy", "proprio", "perception"]}, + actor=STATE_POLICY_CFG, + critic=STATE_CRITIC_CFG, + algorithm=ALGO_CFG, ) diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/franka/dexsuite_franka_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/franka/franka_env_cfg.py similarity index 83% rename from source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/franka/dexsuite_franka_env_cfg.py rename to source/isaaclab_tasks/isaaclab_tasks/core/lift/config/franka/franka_env_cfg.py index c214d6520cef..cfeaf46464b8 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/franka/dexsuite_franka_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/franka/franka_env_cfg.py @@ -16,15 +16,15 @@ from isaaclab_assets.robots import FRANKA_PANDA_CFG -from ... import dexsuite_env_cfg as dexsuite +from ... import lift_env_cfg as lift from ... import mdp -# Dexsuite runs the menagerie-converted asset (identified inertials, authored finger +# Lift runs the menagerie-converted asset (identified inertials, authored finger # coupling) with actuators calibrated for it; the stock FRANKA_PANDA_CFG stays on the # legacy asset so the upstream franka tasks keep their demos and baselines. -FRANKA_PANDA_DEXSUITE_CFG = FRANKA_PANDA_CFG.copy() -FRANKA_PANDA_DEXSUITE_CFG.spawn.usd_path = f"{ISAACLAB_NUCLEUS_DIR}/Robots/FrankaEmika/franka_panda.usda" -FRANKA_PANDA_DEXSUITE_CFG.actuators = { +FRANKA_PANDA_LIFT_CFG = FRANKA_PANDA_CFG.copy() +FRANKA_PANDA_LIFT_CFG.spawn.usd_path = f"{ISAACLAB_NUCLEUS_DIR}/Robots/FrankaEmika/franka_panda.usda" +FRANKA_PANDA_LIFT_CFG.actuators = { # inspired by libfranka's joint_impedance_control.cpp "panda_arm": ImplicitActuatorCfg( joint_names_expr=["panda_joint[1-7]"], @@ -75,10 +75,10 @@ @configclass -class FrankaSceneCfg(dexsuite.SceneCfg): - """Franka scene for the dexsuite lift/reorient tasks.""" +class FrankaSceneCfg(lift.SceneCfg): + """Franka scene for the Lift and Reorient tasks.""" - robot: ArticulationCfg = FRANKA_PANDA_DEXSUITE_CFG.replace(prim_path="{ENV_REGEX_NS}/Robot") + robot: ArticulationCfg = FRANKA_PANDA_LIFT_CFG.replace(prim_path="{ENV_REGEX_NS}/Robot") def __post_init__(self): super().__post_init__() @@ -100,22 +100,22 @@ def __post_init__(self): ), ) graspable_shape_assets_cfg = [ - MeshCuboidCfg(size=(0.05, 0.05, 0.05), **dexsuite.OBJECT_PHYSICS), - MeshCuboidCfg(size=(0.025, 0.05, 0.05), **dexsuite.OBJECT_PHYSICS), - MeshCuboidCfg(size=(0.025, 0.025, 0.05), **dexsuite.OBJECT_PHYSICS), - MeshCuboidCfg(size=(0.01, 0.05, 0.05), **dexsuite.OBJECT_PHYSICS), - MeshSphereCfg(radius=0.02, **dexsuite.OBJECT_PHYSICS), - MeshCapsuleCfg(radius=0.025, height=0.1, **dexsuite.OBJECT_PHYSICS), - MeshCapsuleCfg(radius=0.025, height=0.2, **dexsuite.OBJECT_PHYSICS), - MeshCapsuleCfg(radius=0.01, height=0.2, **dexsuite.OBJECT_PHYSICS), + MeshCuboidCfg(size=(0.05, 0.05, 0.05), **lift.OBJECT_PHYSICS), + MeshCuboidCfg(size=(0.025, 0.05, 0.05), **lift.OBJECT_PHYSICS), + MeshCuboidCfg(size=(0.025, 0.025, 0.05), **lift.OBJECT_PHYSICS), + MeshCuboidCfg(size=(0.01, 0.05, 0.05), **lift.OBJECT_PHYSICS), + MeshSphereCfg(radius=0.02, **lift.OBJECT_PHYSICS), + MeshCapsuleCfg(radius=0.025, height=0.1, **lift.OBJECT_PHYSICS), + MeshCapsuleCfg(radius=0.025, height=0.2, **lift.OBJECT_PHYSICS), + MeshCapsuleCfg(radius=0.01, height=0.2, **lift.OBJECT_PHYSICS), ] self.object.spawn.shapes.assets_cfg = graspable_shape_assets_cfg self.object.spawn.default.assets_cfg = graspable_shape_assets_cfg @configclass -class StateObservationCfg(dexsuite.ObservationsCfg): - """State observations for the Franka dexsuite tasks.""" +class StateObservationCfg(lift.ObservationsCfg): + """State observations for the Franka lift tasks.""" def __post_init__(self): super().__post_init__() @@ -133,7 +133,7 @@ class FrankaRelJointPosActionCfg: @configclass -class FrankaReorientRewardCfg(dexsuite.RewardsCfg): +class FrankaReorientRewardCfg(lift.RewardsCfg): good_finger_contact = RewTerm( func=mdp.contacts, weight=0.75, @@ -161,7 +161,7 @@ def __post_init__(self): @configclass -class FrankaEventCfg(dexsuite.EventCfg): +class FrankaEventCfg(lift.EventCfg): """Franka-specific event configuration.""" # closing speed = kp * action_scale / kd; kd range derived for 0.2 .. 0.01 m/s so it @@ -174,8 +174,8 @@ class FrankaEventCfg(dexsuite.EventCfg): "asset_cfg": SceneEntityCfg("robot", joint_names="panda_finger_joint1"), "damping_distribution_params": ( 0.0, - FRANKA_PANDA_DEXSUITE_CFG.actuators["panda_hand"].stiffness * 0.1 / 0.01 - - FRANKA_PANDA_DEXSUITE_CFG.actuators["panda_hand"].damping, + FRANKA_PANDA_LIFT_CFG.actuators["panda_hand"].stiffness * 0.1 / 0.01 + - FRANKA_PANDA_LIFT_CFG.actuators["panda_hand"].damping, ), "operation": "add", }, @@ -190,7 +190,7 @@ def __post_init__(self): reset_terms["reset_robot_joints"].params["asset_cfg"] = SceneEntityCfg("robot", joint_names="panda_joint.*") fingers = SceneEntityCfg("robot", joint_names="panda_finger_joint.*") reset_terms["reset_gripper_width"] = EventTerm( - func="isaaclab_tasks.core.dexsuite.mdp.events:reset_joints_shared_offset", + func="isaaclab_tasks.core.lift.mdp.events:reset_joints_shared_offset", mode="reset", params={"position_range": [-0.04, 0.0], "asset_cfg": fingers}, ) @@ -217,7 +217,7 @@ class FrankaMixinCfg: actions: FrankaRelJointPosActionCfg = FrankaRelJointPosActionCfg() events: FrankaEventCfg = FrankaEventCfg() - def __post_init__(self: dexsuite.DexsuiteReorientEnvCfg): + def __post_init__(self: lift.ReorientEnvCfg): super().__post_init__() self.commands.object_pose.body_name = "panda_hand" # Franka base is rotated 180 deg about z, so the workspace mirrors to positive x. @@ -226,7 +226,7 @@ def __post_init__(self: dexsuite.DexsuiteReorientEnvCfg): @configclass -class DexsuiteFrankaReorientEnvCfg(FrankaMixinCfg, dexsuite.DexsuiteReorientEnvCfg): +class FrankaReorientEnvCfg(FrankaMixinCfg, lift.ReorientEnvCfg): def play_mode(self): # play-mode overrides of parent super().play_mode() @@ -237,7 +237,7 @@ def play_mode(self): @configclass -class DexsuiteFrankaLiftEnvCfg(FrankaMixinCfg, dexsuite.DexsuiteLiftEnvCfg): +class FrankaLiftEnvCfg(FrankaMixinCfg, lift.LiftEnvCfg): def play_mode(self): # play-mode overrides of parent super().play_mode() diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/kuka_allegro/__init__.py b/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/kuka_allegro/__init__.py similarity index 64% rename from source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/kuka_allegro/__init__.py rename to source/isaaclab_tasks/isaaclab_tasks/core/lift/config/kuka_allegro/__init__.py index 832198061fe0..797027f05667 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/kuka_allegro/__init__.py +++ b/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/kuka_allegro/__init__.py @@ -3,7 +3,7 @@ # # SPDX-License-Identifier: BSD-3-Clause -"""Dexsuite KukaAllegro reorient and lift environments.""" +"""Lift KukaAllegro reorient and lift environments.""" import gymnasium as gym @@ -18,8 +18,8 @@ entry_point="isaaclab.envs:ManagerBasedRLEnv", disable_env_checker=True, kwargs={ - "env_cfg_entry_point": f"{__name__}.dexsuite_kuka_allegro_env_cfg:DexsuiteKukaAllegroReorientEnvCfg", - "rsl_rl_cfg_entry_point": f"{agents.__name__}.rsl_rl_ppo_cfg:DexsuiteKukaAllegroPPORunnerCfg", + "env_cfg_entry_point": f"{__name__}.kuka_allegro_env_cfg:KukaAllegroReorientEnvCfg", + "rsl_rl_cfg_entry_point": f"{agents.__name__}.rsl_rl_ppo_cfg:KukaAllegroPPORunnerCfg", }, ) @@ -28,8 +28,8 @@ entry_point="isaaclab.envs:ManagerBasedRLEnv", disable_env_checker=True, kwargs={ - "env_cfg_entry_point": f"{__name__}.dexsuite_kuka_allegro_env_cfg:DexsuiteKukaAllegroLiftEnvCfg", - "rsl_rl_cfg_entry_point": f"{agents.__name__}.rsl_rl_ppo_cfg:DexsuiteKukaAllegroPPORunnerCfg", + "env_cfg_entry_point": f"{__name__}.kuka_allegro_env_cfg:KukaAllegroLiftEnvCfg", + "rsl_rl_cfg_entry_point": f"{agents.__name__}.rsl_rl_ppo_cfg:KukaAllegroPPORunnerCfg", }, ) @@ -42,8 +42,8 @@ entry_point="isaaclab.envs:ManagerBasedRLEnv", disable_env_checker=True, kwargs={ - "env_cfg_entry_point": f"{__name__}.dexsuite_kuka_allegro_camera_env_cfg:DexsuiteKukaAllegroReorientCameraEnvCfg", - "rsl_rl_cfg_entry_point": f"{agents.__name__}.rsl_rl_ppo_cfg:DexsuiteKukaAllegroPPORunnerCfg", + "env_cfg_entry_point": f"{__name__}.kuka_allegro_camera_env_cfg:KukaAllegroReorientCameraEnvCfg", + "rsl_rl_cfg_entry_point": f"{agents.__name__}.rsl_rl_ppo_cfg:KukaAllegroPPORunnerCfg", }, ) @@ -52,7 +52,7 @@ entry_point="isaaclab.envs:ManagerBasedRLEnv", disable_env_checker=True, kwargs={ - "env_cfg_entry_point": f"{__name__}.dexsuite_kuka_allegro_camera_env_cfg:DexsuiteKukaAllegroLiftCameraEnvCfg", - "rsl_rl_cfg_entry_point": f"{agents.__name__}.rsl_rl_ppo_cfg:DexsuiteKukaAllegroPPORunnerCfg", + "env_cfg_entry_point": f"{__name__}.kuka_allegro_camera_env_cfg:KukaAllegroLiftCameraEnvCfg", + "rsl_rl_cfg_entry_point": f"{agents.__name__}.rsl_rl_ppo_cfg:KukaAllegroPPORunnerCfg", }, ) diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/kuka_allegro/agents/__init__.py b/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/kuka_allegro/agents/__init__.py similarity index 100% rename from source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/kuka_allegro/agents/__init__.py rename to source/isaaclab_tasks/isaaclab_tasks/core/lift/config/kuka_allegro/agents/__init__.py diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/kuka_allegro/agents/models.py b/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/kuka_allegro/agents/models.py similarity index 99% rename from source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/kuka_allegro/agents/models.py rename to source/isaaclab_tasks/isaaclab_tasks/core/lift/config/kuka_allegro/agents/models.py index b664490a9388..284edaa273b5 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/kuka_allegro/agents/models.py +++ b/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/kuka_allegro/agents/models.py @@ -3,7 +3,7 @@ # # SPDX-License-Identifier: BSD-3-Clause -"""Custom RSL-RL models for the dexsuite camera tasks.""" +"""Custom RSL-RL models for the lift camera tasks.""" from __future__ import annotations diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/kuka_allegro/agents/rsl_rl_ppo_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/kuka_allegro/agents/rsl_rl_ppo_cfg.py similarity index 84% rename from source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/kuka_allegro/agents/rsl_rl_ppo_cfg.py rename to source/isaaclab_tasks/isaaclab_tasks/core/lift/config/kuka_allegro/agents/rsl_rl_ppo_cfg.py index 05d7157caebb..661322278586 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/kuka_allegro/agents/rsl_rl_ppo_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/kuka_allegro/agents/rsl_rl_ppo_cfg.py @@ -19,14 +19,14 @@ @configclass class RslRlSpatialSoftmaxCNNModelCfg(RslRlCNNModelCfg): - """Configuration for the dexsuite spatial-softmax camera actor. + """Configuration for the lift spatial-softmax camera actor. The convolutional feature map is reduced to per-channel keypoint coordinates instead of being flattened, which shrinks the latent by roughly an order of magnitude while keeping the spatial information a pixels-only policy depends on. See :class:`.models.SpatialSoftmaxCNNModel`. """ - class_name: str = "isaaclab_tasks.core.dexsuite.config.kuka_allegro.agents.models:SpatialSoftmaxCNNModel" + class_name: str = "isaaclab_tasks.core.lift.config.kuka_allegro.agents.models:SpatialSoftmaxCNNModel" """The model class name resolved by rsl-rl.""" init_temperature: float = 1.0 @@ -85,7 +85,7 @@ class RslRlSpatialSoftmaxCNNModelCfg(RslRlCNNModelCfg): @configclass -class DexsuiteKukaAllegroPPOBaseRunnerCfg(RslRlOnPolicyRunnerCfg): +class KukaAllegroPPOBaseRunnerCfg(RslRlOnPolicyRunnerCfg): num_steps_per_env = 32 max_iterations = 15000 save_interval = 250 @@ -97,25 +97,25 @@ class DexsuiteKukaAllegroPPOBaseRunnerCfg(RslRlOnPolicyRunnerCfg): @configclass -class DexsuiteKukaAllegroPPORunnerCfg(PresetCfg): - default = DexsuiteKukaAllegroPPOBaseRunnerCfg().replace( - experiment_name="dexsuite_kuka_allegro", +class KukaAllegroPPORunnerCfg(PresetCfg): + default = KukaAllegroPPOBaseRunnerCfg().replace( + experiment_name="lift_kuka_allegro", obs_groups={"actor": ["policy", "proprio", "perception"], "critic": ["policy", "proprio", "perception"]}, actor=STATE_POLICY_CFG, critic=STATE_CRITIC_CFG, algorithm=ALGO_CFG, ) - single_camera = DexsuiteKukaAllegroPPOBaseRunnerCfg().replace( - experiment_name="dexsuite_kuka_allegro_single_camera", + single_camera = KukaAllegroPPOBaseRunnerCfg().replace( + experiment_name="lift_kuka_allegro_single_camera", obs_groups={"actor": ["policy", "proprio", "base_image"], "critic": ["policy", "proprio", "perception"]}, actor=CNN_POLICY_CFG, critic=STATE_CRITIC_CFG, algorithm=CAMERA_ALGO_CFG, ) - duo_camera = DexsuiteKukaAllegroPPOBaseRunnerCfg().replace( - experiment_name="dexsuite_kuka_allegro_duo_camera", + duo_camera = KukaAllegroPPOBaseRunnerCfg().replace( + experiment_name="lift_kuka_allegro_duo_camera", obs_groups={ "actor": ["policy", "proprio", "base_image", "wrist_image"], "critic": ["policy", "proprio", "perception"], diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/kuka_allegro/camera_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/kuka_allegro/camera_cfg.py similarity index 97% rename from source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/kuka_allegro/camera_cfg.py rename to source/isaaclab_tasks/isaaclab_tasks/core/lift/config/kuka_allegro/camera_cfg.py index 8b6fb9909afd..cf749386ddce 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/kuka_allegro/camera_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/kuka_allegro/camera_cfg.py @@ -16,7 +16,7 @@ from isaaclab_tasks.utils import PresetCfg from isaaclab_tasks.utils.presets import MultiBackendRendererCfg -from ... import dexsuite_env_cfg as dexsuite +from ... import lift_env_cfg as lift from ... import mdp FINGERTIP_LIST = ["index_link_3", "middle_link_3", "ring_link_3", "thumb_link_3"] @@ -191,10 +191,10 @@ class WristTiledCameraCfg(PresetCfg): @configclass -class StateObservationCfg(dexsuite.ObservationsCfg): - """Kuka Allegro participant scene for Dexsuite Lifting/Reorientation""" +class StateObservationCfg(lift.ObservationsCfg): + """Kuka Allegro participant scene for Lift Lifting/Reorientation""" - def __post_init__(self: dexsuite.ObservationsCfg): + def __post_init__(self: lift.ObservationsCfg): super().__post_init__() self.proprio.contact = ObsTerm( func=mdp.fingers_contact_force_b, diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/kuka_allegro/dexsuite_kuka_allegro_camera_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/kuka_allegro/kuka_allegro_camera_env_cfg.py similarity index 64% rename from source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/kuka_allegro/dexsuite_kuka_allegro_camera_env_cfg.py rename to source/isaaclab_tasks/isaaclab_tasks/core/lift/config/kuka_allegro/kuka_allegro_camera_env_cfg.py index 0ca28e41ee03..348631c72b98 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/kuka_allegro/dexsuite_kuka_allegro_camera_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/kuka_allegro/kuka_allegro_camera_env_cfg.py @@ -3,11 +3,11 @@ # # SPDX-License-Identifier: BSD-3-Clause -"""Camera (vision) variants of the KukaAllegro dexsuite reorient/lift tasks. +"""Camera (vision) variants of the KukaAllegro Lift and Reorient tasks. Each task is exposed as a :class:`~isaaclab_tasks.utils.PresetCfg` whose ``single_camera`` / ``duo_camera`` variants add base (and wrist) cameras plus the matching image observations on top of -the state env config in :mod:`.dexsuite_kuka_allegro_env_cfg`. The camera data type / resolution and +the state env config in :mod:`.kuka_allegro_env_cfg`. The camera data type / resolution and renderer backend remain ``presets=`` selectable through the camera configs. """ @@ -22,9 +22,9 @@ SingleCameraObservationsCfg, WristTiledCameraCfg, ) -from .dexsuite_kuka_allegro_env_cfg import ( - DexsuiteKukaAllegroLiftEnvCfg, - DexsuiteKukaAllegroReorientEnvCfg, +from .kuka_allegro_env_cfg import ( + KukaAllegroLiftEnvCfg, + KukaAllegroReorientEnvCfg, KukaAllegroSceneCfg, ) @@ -52,14 +52,14 @@ def _camera_env(base_cls, scene_cls, obs_cls): @configclass -class DexsuiteKukaAllegroReorientCameraEnvCfg(PresetCfg): - single_camera = _camera_env(DexsuiteKukaAllegroReorientEnvCfg, SingleCameraSceneCfg, SingleCameraObservationsCfg) - duo_camera = _camera_env(DexsuiteKukaAllegroReorientEnvCfg, DuoCameraSceneCfg, DuoCameraObservationsCfg) +class KukaAllegroReorientCameraEnvCfg(PresetCfg): + single_camera = _camera_env(KukaAllegroReorientEnvCfg, SingleCameraSceneCfg, SingleCameraObservationsCfg) + duo_camera = _camera_env(KukaAllegroReorientEnvCfg, DuoCameraSceneCfg, DuoCameraObservationsCfg) default = single_camera @configclass -class DexsuiteKukaAllegroLiftCameraEnvCfg(PresetCfg): - single_camera = _camera_env(DexsuiteKukaAllegroLiftEnvCfg, SingleCameraSceneCfg, SingleCameraObservationsCfg) - duo_camera = _camera_env(DexsuiteKukaAllegroLiftEnvCfg, DuoCameraSceneCfg, DuoCameraObservationsCfg) +class KukaAllegroLiftCameraEnvCfg(PresetCfg): + single_camera = _camera_env(KukaAllegroLiftEnvCfg, SingleCameraSceneCfg, SingleCameraObservationsCfg) + duo_camera = _camera_env(KukaAllegroLiftEnvCfg, DuoCameraSceneCfg, DuoCameraObservationsCfg) default = single_camera diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/kuka_allegro/dexsuite_kuka_allegro_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/kuka_allegro/kuka_allegro_env_cfg.py similarity index 89% rename from source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/kuka_allegro/dexsuite_kuka_allegro_env_cfg.py rename to source/isaaclab_tasks/isaaclab_tasks/core/lift/config/kuka_allegro/kuka_allegro_env_cfg.py index 589d1e808d6f..dbc75bfdbea9 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/config/kuka_allegro/dexsuite_kuka_allegro_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/kuka_allegro/kuka_allegro_env_cfg.py @@ -17,7 +17,7 @@ from isaaclab_assets.robots import KUKA_ALLEGRO_CFG -from ... import dexsuite_env_cfg as dexsuite +from ... import lift_env_cfg as lift from ... import mdp from .camera_cfg import StateObservationCfg @@ -27,30 +27,30 @@ @configclass -class KukaAllegroObjectCfg(dexsuite.ObjectCfg): +class KukaAllegroObjectCfg(lift.ObjectCfg): """Object presets supported by the Kuka Allegro tasks.""" - ovphysx = dexsuite.ObjectCfg().cube + ovphysx = lift.ObjectCfg().cube @configclass -class KukaAllegroPhysicsCfg(dexsuite.PhysicsCfg): +class KukaAllegroPhysicsCfg(lift.PhysicsCfg): """Physics presets supported by the Kuka Allegro tasks.""" ovphysx = OvPhysxCfg( gpu_max_rigid_patch_count=4 * 5 * 2**15, gpu_found_lost_pairs_capacity=2**26, ) - physx = PhysxAutoCfg(isaacsim_physx=dexsuite.PhysicsCfg().isaacsim_physx, ovphysx=ovphysx) + physx = PhysxAutoCfg(isaacsim_physx=lift.PhysicsCfg().isaacsim_physx, ovphysx=ovphysx) default = physx @configclass -class KukaAllegroSceneCfg(dexsuite.SceneCfg): - """KukaAllegro scene for the dexsuite lift/reorient tasks. +class KukaAllegroSceneCfg(lift.SceneCfg): + """KukaAllegro scene for the Lift and Reorient tasks. The ``base_camera`` / ``wrist_camera`` slots are left unset (``None``) for the state task; the - camera env config populates them (see ``dexsuite_kuka_allegro_camera_env_cfg``). + camera env config populates them (see ``kuka_allegro_camera_env_cfg``). """ robot: ArticulationCfg = KUKA_ALLEGRO_CFG.replace(prim_path="{ENV_REGEX_NS}/Robot") @@ -77,7 +77,7 @@ class KukaAllegroRelJointPosActionCfg: @configclass -class KukaAllegroReorientRewardCfg(dexsuite.RewardsCfg): +class KukaAllegroReorientRewardCfg(lift.RewardsCfg): good_finger_contact = RewTerm( func=mdp.contacts, weight=1.0, @@ -111,7 +111,7 @@ class KukaAllegroMixinCfg: observations: StateObservationCfg = StateObservationCfg() actions: KukaAllegroRelJointPosActionCfg = KukaAllegroRelJointPosActionCfg() - def __post_init__(self: dexsuite.DexsuiteReorientEnvCfg): + def __post_init__(self: lift.ReorientEnvCfg): super().__post_init__() self.sim.physics = KukaAllegroPhysicsCfg() self.commands.object_pose.body_name = "palm_link" @@ -169,10 +169,10 @@ def __post_init__(self: dexsuite.DexsuiteReorientEnvCfg): @configclass -class DexsuiteKukaAllegroReorientEnvCfg(KukaAllegroMixinCfg, dexsuite.DexsuiteReorientEnvCfg): +class KukaAllegroReorientEnvCfg(KukaAllegroMixinCfg, lift.ReorientEnvCfg): pass @configclass -class DexsuiteKukaAllegroLiftEnvCfg(KukaAllegroMixinCfg, dexsuite.DexsuiteLiftEnvCfg): +class KukaAllegroLiftEnvCfg(KukaAllegroMixinCfg, lift.LiftEnvCfg): pass diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/lift/lift_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/core/lift/lift_env_cfg.py index 4cc7c27adda7..e12f5e0c7963 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/lift/lift_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/core/lift/lift_env_cfg.py @@ -5,93 +5,160 @@ from dataclasses import MISSING -from isaaclab_physx.assets import DeformableObjectCfg +from isaaclab_newton.physics import MJWarpSolverCfg, NewtonCfg, NewtonCollisionPipelineCfg, NewtonShapeCfg from isaaclab_physx.physics import PhysxCfg import isaaclab.sim as sim_utils from isaaclab.assets import ArticulationCfg, AssetBaseCfg, RigidObjectCfg -from isaaclab.envs import ManagerBasedRLEnvCfg -from isaaclab.managers import CurriculumTermCfg as CurrTerm +from isaaclab.envs import ManagerBasedRLEnvCfg, ViewerCfg from isaaclab.managers import EventTermCfg as EventTerm from isaaclab.managers import ObservationGroupCfg as ObsGroup from isaaclab.managers import ObservationTermCfg as ObsTerm from isaaclab.managers import RewardTermCfg as RewTerm from isaaclab.managers import SceneEntityCfg from isaaclab.managers import TerminationTermCfg as DoneTerm +from isaaclab.markers import VisualizationMarkersCfg +from isaaclab.physics import PhysxAutoCfg from isaaclab.scene import InteractiveSceneCfg -from isaaclab.sensors.frame_transformer.frame_transformer_cfg import FrameTransformerCfg -from isaaclab.sim.spawners.from_files.from_files_cfg import GroundPlaneCfg, UsdFileCfg +from isaaclab.sim import MeshCapsuleCfg, MeshConeCfg, MeshCuboidCfg, MeshSphereCfg, RigidBodyMaterialCfg from isaaclab.utils.assets import ISAAC_NUCLEUS_DIR from isaaclab.utils.configclass import configclass +from isaaclab.utils.noise import UniformNoiseCfg as Unoise -from isaaclab_tasks.core.lift import mdp +from isaaclab_tasks.utils import PresetCfg -## -# Scene definition -## +from . import mdp +from .adr_curriculum import CurriculumCfg + +TABLE_SPAWN_CFG = sim_utils.CuboidCfg( + size=(0.8, 1.5, 0.04), + rigid_props=sim_utils.RigidBodyPropertiesCfg(kinematic_enabled=True), + collision_props=sim_utils.CollisionPropertiesCfg(), + # trick: we let visualizer's color to show the table with success coloring + visible=False, +) + + +OBJECT_PHYSICS = { + "physics_material": RigidBodyMaterialCfg(static_friction=0.5), + "collision_props": sim_utils.CollisionPropertiesCfg(contact_offset=0.002), +} + + +@configclass +class ObjectCfg(PresetCfg): + shapes = sim_utils.MultiAssetSpawnerCfg( + assets_cfg=[ + MeshCuboidCfg(size=(0.05, 0.1, 0.1), **OBJECT_PHYSICS), + MeshCuboidCfg(size=(0.05, 0.05, 0.1), **OBJECT_PHYSICS), + MeshCuboidCfg(size=(0.025, 0.1, 0.1), **OBJECT_PHYSICS), + MeshCuboidCfg(size=(0.025, 0.05, 0.1), **OBJECT_PHYSICS), + MeshCuboidCfg(size=(0.025, 0.025, 0.1), **OBJECT_PHYSICS), + MeshCuboidCfg(size=(0.01, 0.1, 0.1), **OBJECT_PHYSICS), + MeshSphereCfg(radius=0.05, **OBJECT_PHYSICS), + MeshSphereCfg(radius=0.025, **OBJECT_PHYSICS), + MeshCapsuleCfg(radius=0.04, height=0.025, **OBJECT_PHYSICS), + MeshCapsuleCfg(radius=0.04, height=0.01, **OBJECT_PHYSICS), + MeshCapsuleCfg(radius=0.04, height=0.1, **OBJECT_PHYSICS), + MeshCapsuleCfg(radius=0.025, height=0.1, **OBJECT_PHYSICS), + MeshCapsuleCfg(radius=0.025, height=0.2, **OBJECT_PHYSICS), + MeshCapsuleCfg(radius=0.01, height=0.2, **OBJECT_PHYSICS), + MeshConeCfg(radius=0.05, height=0.1, **OBJECT_PHYSICS), + MeshConeCfg(radius=0.025, height=0.1, **OBJECT_PHYSICS), + ], + rigid_props=sim_utils.RigidBodyPropertiesCfg( + solver_position_iteration_count=16, + solver_velocity_iteration_count=0, + disable_gravity=False, + ), + collision_props=sim_utils.CollisionPropertiesCfg(), + mass_props=sim_utils.MassPropertiesCfg(mass=0.2), + ) + cube = sim_utils.CuboidCfg( + size=(0.05, 0.05, 0.05), + physics_material=RigidBodyMaterialCfg(static_friction=0.5), + rigid_props=sim_utils.RigidBodyPropertiesCfg( + solver_position_iteration_count=16, + solver_velocity_iteration_count=0, + disable_gravity=False, + ), + collision_props=sim_utils.CollisionPropertiesCfg(), + mass_props=sim_utils.MassPropertiesCfg(mass=0.2), + ) + default = shapes @configclass -class ObjectTableSceneCfg(InteractiveSceneCfg): - """Configuration for the lift scene with a robot and a object.""" +class SceneCfg(InteractiveSceneCfg): + """Lift Scene for multi-objects Lifting""" - # robots: will be populated by agent env cfg + # robot robot: ArticulationCfg = MISSING - # end-effector sensor: will be populated by agent env cfg - ee_frame: FrameTransformerCfg = MISSING - # target object: will be populated by agent env cfg - object: RigidObjectCfg | DeformableObjectCfg = MISSING + + # object + object: RigidObjectCfg = RigidObjectCfg( + prim_path="{ENV_REGEX_NS}/Object", + spawn=ObjectCfg(), # type: ignore + init_state=RigidObjectCfg.InitialStateCfg(pos=(-0.55, 0.1, 0.35)), + ) # table - table = AssetBaseCfg( - prim_path="{ENV_REGEX_NS}/Table", - init_state=AssetBaseCfg.InitialStateCfg(pos=[0.5, 0, 0], rot=[0, 0, 0.707, 0.707]), - spawn=UsdFileCfg(usd_path=f"{ISAAC_NUCLEUS_DIR}/Props/Mounts/SeattleLabTable/table_instanceable.usd"), + table: RigidObjectCfg = RigidObjectCfg( + prim_path="{ENV_REGEX_NS}/table", + spawn=TABLE_SPAWN_CFG, + init_state=RigidObjectCfg.InitialStateCfg(pos=(-0.55, 0.0, 0.235), rot=(0.0, 0.0, 0.0, 1.0)), ) # plane plane = AssetBaseCfg( prim_path="/World/GroundPlane", - init_state=AssetBaseCfg.InitialStateCfg(pos=[0, 0, -1.05]), - spawn=GroundPlaneCfg(), + init_state=AssetBaseCfg.InitialStateCfg(), + spawn=sim_utils.GroundPlaneCfg(color=(1.0, 1.0, 1.0)), + collision_group=-1, ) # lights - light = AssetBaseCfg( - prim_path="/World/light", - spawn=sim_utils.DomeLightCfg(color=(0.75, 0.75, 0.75), intensity=3000.0), + sky_light = AssetBaseCfg( + prim_path="/World/skyLight", + spawn=sim_utils.DomeLightCfg( + intensity=750.0, + texture_file=f"{ISAAC_NUCLEUS_DIR}/Materials/Textures/Skies/PolyHaven/kloofendal_43d_clear_puresky_4k.hdr", + ), ) -## -# MDP settings -## - - @configclass class CommandsCfg: """Command terms for the MDP.""" - object_pose = mdp.UniformPoseCommandCfg( + object_pose = mdp.ObjectUniformPoseCommandCfg( asset_name="robot", - body_name=MISSING, # will be set by derived env cfg - resampling_time_range=(5.0, 5.0), - debug_vis=True, - ranges=mdp.UniformPoseCommandCfg.Ranges( - pos_x=(0.4, 0.6), pos_y=(-0.25, 0.25), pos_z=(0.25, 0.5), roll=(0.0, 0.0), pitch=(0.0, 0.0), yaw=(0.0, 0.0) + object_name="object", + resampling_time_range=(3.0, 5.0), + debug_vis=False, + ranges=mdp.ObjectUniformPoseCommandCfg.Ranges( + pos_x=(-0.7, -0.3), + pos_y=(-0.25, 0.25), + pos_z=(0.55, 0.95), + roll=(-3.14, 3.14), + pitch=(-3.14, 3.14), + yaw=(0.0, 0.0), + ), + success_vis_asset_name="table", + success_visualizer_cfg=VisualizationMarkersCfg( + prim_path="/Visuals/SuccessMarkers", + markers={ + "failure": TABLE_SPAWN_CFG.replace( + visual_material=sim_utils.PreviewSurfaceCfg(diffuse_color=(0.25, 0.15, 0.15)), visible=True + ), + "success": TABLE_SPAWN_CFG.replace( + visual_material=sim_utils.PreviewSurfaceCfg(diffuse_color=(0.15, 0.25, 0.15)), visible=True + ), + }, ), ) -@configclass -class ActionsCfg: - """Action specifications for the MDP.""" - - # will be set by derived env cfg - arm_action: mdp.JointPositionActionCfg | mdp.DifferentialInverseKinematicsActionCfg = MISSING - gripper_action: mdp.BinaryJointPositionActionCfg = MISSING - - @configclass class ObservationsCfg: """Observation specifications for the MDP.""" @@ -100,66 +167,300 @@ class ObservationsCfg: class PolicyCfg(ObsGroup): """Observations for policy group.""" - joint_pos = ObsTerm(func=mdp.joint_pos_rel) - joint_vel = ObsTerm(func=mdp.joint_vel_rel) - object_position = ObsTerm(func=mdp.object_position_in_robot_root_frame) - target_object_position = ObsTerm(func=mdp.generated_commands, params={"command_name": "object_pose"}) + object_quat_b = ObsTerm(func=mdp.object_quat_b, noise=Unoise(n_min=-0.0, n_max=0.0)) + target_object_pose_b = ObsTerm(func=mdp.generated_commands, params={"command_name": "object_pose"}) actions = ObsTerm(func=mdp.last_action) def __post_init__(self): self.enable_corruption = True self.concatenate_terms = True + self.history_length = 5 + + @configclass + class ProprioObsCfg(ObsGroup): + """Observations for proprioception group.""" + + joint_pos = ObsTerm(func=mdp.joint_pos, noise=Unoise(n_min=-0.0, n_max=0.0)) + joint_vel = ObsTerm(func=mdp.joint_vel, noise=Unoise(n_min=-0.0, n_max=0.0)) + hand_tips_state_b = ObsTerm( + func=mdp.body_state_b, + noise=Unoise(n_min=-0.0, n_max=0.0), + # good behaving number for position in m, velocity in m/s, rad/s, + # and quaternion are unlikely to exceed -2 to 2 range + clip=(-2.0, 2.0), + params={ + # pose-only: body velocities are the most engine-sensitive observables + # (derivative signals amplify solver differences) and do not transfer + # across physics backends; the observation history carries velocity info + "include_vel": False, + "body_asset_cfg": SceneEntityCfg("robot"), + "base_asset_cfg": SceneEntityCfg("robot"), + }, + ) + contact: ObsTerm = MISSING + + def __post_init__(self): + self.enable_corruption = True + self.concatenate_terms = True + self.history_length = 5 + + @configclass + class PerceptionObsCfg(ObsGroup): + """Observations for perception group.""" + + object_point_cloud = ObsTerm( + func=mdp.object_point_cloud_b, + noise=Unoise(n_min=-0.0, n_max=0.0), + clip=(-2.0, 2.0), # clamp between -2 m to 2 m + params={"num_points": 64, "flatten": True}, + ) + + def __post_init__(self): + self.enable_corruption = True + self.concatenate_dim = 0 + self.concatenate_terms = True + self.flatten_history_dim = True + self.history_length = 5 # observation groups policy: PolicyCfg = PolicyCfg() + proprio: ProprioObsCfg = ProprioObsCfg() + perception: PerceptionObsCfg = PerceptionObsCfg() @configclass class EventCfg: - """Configuration for events.""" + """Reset-mode events (shared by all physics backends).""" - reset_all = EventTerm(func=mdp.reset_scene_to_default, mode="reset") + robot_physics_material = EventTerm( + func=mdp.randomize_rigid_body_material, + mode="startup", + params={ + "asset_cfg": SceneEntityCfg("robot", body_names=".*"), + "static_friction_range": [0.5, 1.0], + "dynamic_friction_range": [0.5, 1.0], + "restitution_range": [0.0, 0.0], + "num_buckets": 250, + }, + ) + + object_physics_material = EventTerm( + func=mdp.randomize_rigid_body_material, + mode="startup", + params={ + "asset_cfg": SceneEntityCfg("object", body_names=".*"), + "static_friction_range": [0.5, 1.0], + "dynamic_friction_range": [0.5, 1.0], + "restitution_range": [0.0, 0.0], + "num_buckets": 250, + }, + ) + + object_physics_inertia = EventTerm( + func=mdp.randomize_rigid_body_inertia, + mode="startup", + params={ + "asset_cfg": SceneEntityCfg("object"), + "inertia_distribution_params": [0.01, 0.01], + "operation": "add", + "diagonal_only": True, + }, + ) - reset_object_position = EventTerm( - func=mdp.reset_root_state_uniform, + joint_stiffness_and_damping = EventTerm( + func=mdp.randomize_actuator_gains, + mode="startup", + params={ + "asset_cfg": SceneEntityCfg("robot", joint_names=".*"), + "stiffness_distribution_params": [0.5, 2.0], + "damping_distribution_params": [0.5, 2.0], + "operation": "scale", + }, + ) + + joint_friction = EventTerm( + func=mdp.randomize_joint_parameters, + mode="startup", + params={ + "asset_cfg": SceneEntityCfg("robot", joint_names=".*"), + "friction_distribution_params": [0.0, 5.0], + "operation": "scale", + }, + ) + + object_scale_mass = EventTerm( + func=mdp.randomize_rigid_body_mass, + mode="startup", + params={ + "asset_cfg": SceneEntityCfg("object"), + "mass_distribution_params": [0.2, 2.5], + "operation": "scale", + }, + ) + + # Gravity scheduling is a deliberate curriculum trick — starting with no + # gravity (easy) and gradually introducing full gravity (hard) makes learning + # smoother and removes the need for a separate "Lift" reward. + variable_gravity = EventTerm( + func=mdp.randomize_physics_scene_gravity, mode="reset", params={ - "pose_range": {"x": (-0.1, 0.1), "y": (-0.25, 0.25), "z": (0.0, 0.0)}, - "velocity_range": {}, - "asset_cfg": SceneEntityCfg("object", body_names="Object"), + "gravity_distribution_params": ([0.0, 0.0, 0.0], [0.0, 0.0, 0.0]), + "operation": "abs", + }, + ) + + # robot configs add their static-obstacle geometry to ``params["valid_criteria"]`` + conditional_reset = EventTerm( + func="isaaclab_tasks.core.lift.mdp.events:conditional_reset", + mode="reset", + params={ + "terms": { + "reset_root": EventTerm( + func=mdp.reset_root_state_uniform, + mode="reset", + params={ + "pose_range": {"x": [-0.0, 0.0], "y": [-0.0, 0.0], "yaw": [-0.0, 0.0]}, + "velocity_range": {"x": [-0.0, 0.0], "y": [-0.0, 0.0], "z": [-0.0, 0.0]}, + "asset_cfg": SceneEntityCfg("robot"), + }, + ), + "reset_robot_joints": EventTerm( + func=mdp.reset_joints_by_offset, + mode="reset", + params={ + "position_range": [-0.50, 0.50], + "velocity_range": [0.0, 0.0], + }, + ), + "reset_robot_wrist_joint": EventTerm( + func=mdp.reset_joints_by_offset, + mode="reset", + params={ + "asset_cfg": SceneEntityCfg("robot", joint_names=["wrist"]), + "position_range": [-3, 3], + "velocity_range": [0.0, 0.0], + }, + ), + "reset_object": EventTerm( + func=mdp.reset_root_state_uniform, + mode="reset", + params={ + "pose_range": { + "x": [-0.2, 0.2], + "y": [-0.2, 0.2], + "z": [0.0, 0.4], + "roll": [-3.14, 3.14], + "pitch": [-3.14, 3.14], + "yaw": [-3.14, 3.14], + }, + "velocity_range": {"x": [-0.0, 0.0], "y": [-0.0, 0.0], "z": [-0.0, 0.0]}, + "asset_cfg": SceneEntityCfg("object"), + }, + ), + # spawn-in-hand curriculum: a small share of episodes starts with the + # object at the gripper (uniform random orientation, small body-frame + # offset); interpenetrating draws are rejected by object_robot_clearance. + # Must stay LAST: it reads the gripper pose after the robot reset terms. + "reset_object_to_target": EventTerm( + func="isaaclab_tasks.core.lift.mdp.events:reset_to_target", + mode="reset", + params={ + "pose_range": {"x": [-0.04, 0.04], "y": [-0.04, 0.04], "z": [-0.04, 0.04]}, + "velocity_range": {}, + "probability": 0.25, + # robot configs must point this at their gripper body and may shift + # the z range along the approach axis (e.g. between the fingertips) + "target_cfg": MISSING, + "asset_cfg": SceneEntityCfg("object"), + }, + ), + }, + "buffer_size_per_group": 1024, + # harvest more candidates than the bank holds and keep the subset that is spread widest + # over the diversity feature; ``1.0`` keeps the states first-come instead. + "diversity_feature": mdp.GraspTravelDistanceCfg( + asset_name="robot", + body_names=MISSING, # overridden by robot configs + object_name="object", + command_name="object_pose", + ), + "valid_criteria": { + "object_robot_clearance": mdp.MeshClearanceCfg( + asset_name="robot", + body_names=".*", + object_name="object", + num_object_points=64, + min_clearance=0.0, + ), + "robot_table_clearance": mdp.SlabClearanceCfg( + asset_name="robot", + body_names=MISSING, # overridden by robot configs + object_name="object", + obstacle_slabs=[((-0.95, -0.15), (-0.75, 0.75), 0.255), (None, None, 0.0)], # table dimension + num_object_points=64, + min_clearance=0.02, + ), + }, + # restart from the banked states the policy solves about half the time rather than + # drawing uniformly, which keeps the already-mastered and still-hopeless states from + # taking up most of the episodes + "success_monitor": mdp.SuccessMonitorCfg(target_success_rate=0.5), }, ) +@configclass +class ActionsCfg: + pass + + @configclass class RewardsCfg: """Reward terms for the MDP.""" - reaching_object = RewTerm(func=mdp.object_ee_distance, params={"std": 0.1}, weight=1.0) + action_l2 = RewTerm(func=mdp.action_l2, weight=-0.01) - lifting_object = RewTerm(func=mdp.object_is_lifted, params={"minimal_height": 0.04}, weight=15.0) - - object_goal_tracking = RewTerm( - func=mdp.object_goal_distance, - params={"std": 0.3, "minimal_height": 0.04, "command_name": "object_pose", "success_threshold": 0.05}, - weight=16.0, - ) + fingers_to_object = RewTerm(func=mdp.object_ee_distance, params={"std": 0.4}, weight=0.05) - object_goal_tracking_fine_grained = RewTerm( - func=mdp.object_goal_distance, - params={"std": 0.05, "minimal_height": 0.04, "command_name": "object_pose"}, + # Progress rewards pay once per ``min_improvement`` of ground gained on the best error so far, + # so ground already credited cannot be earned again by backing off and re-approaching. + position_tracking = RewTerm( + func=mdp.position_command_progress, weight=5.0, + params={ + "asset_cfg": SceneEntityCfg("robot"), + "min_improvement": 0.0025, + "command_name": "object_pose", + "align_asset_cfg": SceneEntityCfg("object"), + }, ) - # action penalty - action_rate = RewTerm(func=mdp.action_rate_l2, weight=-1e-4) + orientation_tracking = RewTerm( + func=mdp.orientation_command_progress, + weight=10.0, + params={ + "asset_cfg": SceneEntityCfg("robot"), + "min_improvement": 0.015, + "command_name": "object_pose", + "align_asset_cfg": SceneEntityCfg("object"), + }, + ) - joint_vel = RewTerm( - func=mdp.joint_vel_l2, - weight=-1e-4, - params={"asset_cfg": SceneEntityCfg("robot")}, + success = RewTerm( + func=mdp.success_reward, + weight=10, + params={ + "asset_cfg": SceneEntityCfg("robot"), + "pos_std": 0.05, + "rot_std": 0.5, + "command_name": "object_pose", + "align_asset_cfg": SceneEntityCfg("object"), + }, ) + early_termination = RewTerm(func=mdp.is_terminated_term, weight=-50, params={"term_keys": ["abnormal_robot"]}) + @configclass class TerminationsCfg: @@ -167,35 +468,54 @@ class TerminationsCfg: time_out = DoneTerm(func=mdp.time_out, time_out=True) - object_dropping = DoneTerm( - func=mdp.root_height_below_minimum, params={"minimum_height": -0.05, "asset_cfg": SceneEntityCfg("object")} + object_out_of_bound = DoneTerm( + func=mdp.out_of_bound, + params={ + "in_bound_range": {"x": (-1.5, 0.5), "y": (-2.0, 2.0), "z": (0.3, 2.0)}, + "asset_cfg": SceneEntityCfg("object"), + }, ) + abnormal_robot = DoneTerm(func=mdp.joint_vel_out_of_limit) -@configclass -class CurriculumCfg: - """Curriculum terms for the MDP.""" - action_rate = CurrTerm( - func=mdp.modify_reward_weight, params={"term_name": "action_rate", "weight": -1e-1, "num_steps": 10000} +@configclass +class PhysicsCfg(PresetCfg): + isaacsim_physx = PhysxCfg( + bounce_threshold_velocity=0.01, + gpu_max_rigid_patch_count=4 * 5 * 2**15, + gpu_found_lost_pairs_capacity=2**26, ) - - joint_vel = CurrTerm( - func=mdp.modify_reward_weight, params={"term_name": "joint_vel", "weight": -1e-1, "num_steps": 10000} + newton_mjwarp = NewtonCfg( + solver_cfg=MJWarpSolverCfg( + solver="newton", + integrator="implicitfast", + njmax=300, + nconmax=200, + impratio=1.0, + cone="pyramidal", + update_data_interval=2, + iterations=100, + ls_iterations=15, + use_mujoco_contacts=False, + ccd_iterations=35, + ), + collision_cfg=NewtonCollisionPipelineCfg(rigid_contact_max=4000000), + default_shape_cfg=NewtonShapeCfg(), + num_substeps=2, + debug_mode=False, ) - - -## -# Environment configuration -## + physx = PhysxAutoCfg(isaacsim_physx=isaacsim_physx) + default = physx @configclass -class LiftEnvCfg(ManagerBasedRLEnvCfg): - """Configuration for the lifting environment.""" +class ReorientEnvCfg(ManagerBasedRLEnvCfg): + """Lift reorientation task definition, also the base definition for derivative Lift task and evaluation task""" # Scene settings - scene: ObjectTableSceneCfg = ObjectTableSceneCfg(num_envs=4096, env_spacing=2.5) + viewer: ViewerCfg = ViewerCfg(eye=(-2.25, 0.0, 0.75), lookat=(0.0, 0.0, 0.45), origin_type="env") + scene: SceneCfg = SceneCfg(num_envs=4096, env_spacing=3, replicate_physics=True) # Basic settings observations: ObservationsCfg = ObservationsCfg() actions: ActionsCfg = ActionsCfg() @@ -204,20 +524,81 @@ class LiftEnvCfg(ManagerBasedRLEnvCfg): rewards: RewardsCfg = RewardsCfg() terminations: TerminationsCfg = TerminationsCfg() events: EventCfg = EventCfg() - curriculum: CurriculumCfg = CurriculumCfg() + curriculum: CurriculumCfg | None = CurriculumCfg() + + def validate_config(self): + """Check for invalid preset combinations after resolution.""" + + warp_supported = { + "rgb", + "depth", + "distance_to_camera", + "distance_to_image_plane", + "normals", + "semantic_segmentation", + "instance_segmentation", + } + for cam_attr in ("base_camera", "wrist_camera"): + cam = getattr(self.scene, cam_attr, None) + if cam is None: + continue + renderer_type = getattr(getattr(cam, "renderer_cfg", None), "renderer_type", None) + if renderer_type == "newton_warp": + unsupported = set(cam.data_types) - warp_supported + if unsupported: + raise ValueError( + f"Warp renderer only supports data types {sorted(warp_supported)}, " + f"but '{cam_attr}' is configured with unsupported types: {sorted(unsupported)}. " + "Choose a compatible preset, e.g. presets=newton_renderer,rgb128." + ) def __post_init__(self): """Post initialization.""" # general settings - self.decimation = 2 - self.episode_length_s = 5.0 + self.decimation = 4 # 30 Hz + + # *single-goal setup + self.commands.object_pose.resampling_time_range = (2.0, 3.0) + self.commands.object_pose.position_only = False + self.episode_length_s = 6.0 + self.is_finite_horizon = False + # simulation settings - self.sim.dt = 0.01 # 100Hz + self.sim.dt = 1 / 120 self.sim.render_interval = self.decimation + self.sim.physics = PhysicsCfg() + + def play_mode(self): + # play-mode overrides of parent + super().play_mode() + + self.commands.object_pose.debug_vis = True + # the bank shapes what a policy trains on; at play it only has to supply starts for the + # handful of environments the parent left, so it is harvested small and taken as it comes + # rather than making the viewer wait through an oversampled prefill and its spread pass + reset_params = self.events.conditional_reset.params + reset_params["buffer_size_per_group"] = 32 + reset_params["oversample_factor"] = 1.0 + reset_params["diversity_feature"] = None + if self.curriculum is not None: + self.curriculum.adr.params["init_difficulty"] = self.curriculum.adr.params["max_difficulty"] + self.curriculum.adr.params["promotion_only"] = True + # the parent turned observation corruption off, which leaves the noise terms nothing to scale + self.curriculum.disable_observation_noise_terms() + + +class LiftEnvCfg(ReorientEnvCfg): + """Lift task definition.""" - self.sim.physics = PhysxCfg( - bounce_threshold_velocity=0.01, - gpu_found_lost_aggregate_pairs_capacity=1024 * 1024 * 4, - gpu_total_aggregate_pairs_capacity=16 * 1024, - friction_correlation_distance=0.00625, - ) + def __post_init__(self): + super().__post_init__() + self.rewards.orientation_tracking = None # no orientation reward + self.commands.object_pose.position_only = True + if self.curriculum is not None: + self.rewards.success.params["rot_std"] = None # make success reward not consider orientation + + def play_mode(self): + # play-mode overrides of parent + super().play_mode() + + self.commands.object_pose.position_only = True diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/__init__.py b/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/__init__.py index 1c3431f2637c..e14e0f6d52c5 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/__init__.py +++ b/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/__init__.py @@ -3,8 +3,6 @@ # # SPDX-License-Identifier: BSD-3-Clause -"""This sub-module contains the functions that are specific to the lift environments.""" - from isaaclab.utils.module import lazy_export lazy_export() diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/__init__.pyi b/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/__init__.pyi index 40ff99138e80..93cb88f1efd8 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/__init__.pyi +++ b/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/__init__.pyi @@ -4,43 +4,91 @@ # SPDX-License-Identifier: BSD-3-Clause __all__ = [ - # observations - "object_position_in_robot_root_frame", - "deformable_com_in_robot_root_frame", + "GraspTravelDistanceCfg", + "MeshClearanceCfg", + "SlabClearanceCfg", + "SuccessMonitor", + "SuccessMonitorCfg", + "grasp_travel_distance", + "mesh_clearance", + "slab_clearance", + "conditional_reset", + "reset_joints_shared_offset", + "reset_to_target", + "get_reset_state", + "set_reset_state", + "ObjectUniformPoseCommandCfg", + "DifficultyScheduler", + "initial_final_interpolate_fn", "DeformableSampledPointsInRobotRootFrame", - # rewards - "object_ee_distance", - "object_goal_distance", - "object_is_lifted", - "deformable_lifted", - "deformable_ee_distance", + "body_state_b", + "deformable_com_in_robot_root_frame", + "fingers_contact_force_b", + "object_point_cloud_b", + "object_quat_b", + "vision_camera", + "contacts", + "contact_count", "deformable_com_goal_distance", + "deformable_ee_distance", + "deformable_lifted", "gripper_close_action", - # terminations - "object_reached_goal", + "object_ee_distance", + "orientation_command_error_tanh", + "orientation_command_progress", + "position_command_error_tanh", + "position_command_progress", + "success_reward", + "abnormal_robot_state", "deformable_com_below_minimum", "deformable_outside_table_bounds", "ee_below_minimum", + "object_reached_goal", + "out_of_bound", ] +from .commands import ObjectUniformPoseCommandCfg +from .curriculums import DifficultyScheduler, initial_final_interpolate_fn +from .events import ( + SuccessMonitor, + conditional_reset, + grasp_travel_distance, + mesh_clearance, + reset_joints_shared_offset, + reset_to_target, + slab_clearance, +) +from .utils import get_reset_state, set_reset_state +from .events_cfg import GraspTravelDistanceCfg, MeshClearanceCfg, SlabClearanceCfg, SuccessMonitorCfg from .observations import ( DeformableSampledPointsInRobotRootFrame, + body_state_b, deformable_com_in_robot_root_frame, - object_position_in_robot_root_frame, + fingers_contact_force_b, + object_point_cloud_b, + object_quat_b, + vision_camera, ) from .rewards import ( + contacts, + contact_count, deformable_com_goal_distance, deformable_ee_distance, deformable_lifted, gripper_close_action, object_ee_distance, - object_goal_distance, - object_is_lifted, + orientation_command_error_tanh, + orientation_command_progress, + position_command_error_tanh, + position_command_progress, + success_reward, ) from .terminations import ( + abnormal_robot_state, deformable_com_below_minimum, deformable_outside_table_bounds, ee_below_minimum, object_reached_goal, + out_of_bound, ) from isaaclab.envs.mdp import * diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/commands/__init__.py b/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/commands/__init__.py similarity index 100% rename from source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/commands/__init__.py rename to source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/commands/__init__.py diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/commands/__init__.pyi b/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/commands/__init__.pyi similarity index 100% rename from source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/commands/__init__.pyi rename to source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/commands/__init__.pyi diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/commands/pose_commands.py b/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/commands/pose_commands.py similarity index 100% rename from source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/commands/pose_commands.py rename to source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/commands/pose_commands.py diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/commands/pose_commands_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/commands/pose_commands_cfg.py similarity index 100% rename from source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/commands/pose_commands_cfg.py rename to source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/commands/pose_commands_cfg.py diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/curriculums.py b/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/curriculums.py similarity index 100% rename from source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/curriculums.py rename to source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/curriculums.py diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/events.py b/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/events.py similarity index 99% rename from source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/events.py rename to source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/events.py index 1639313b991c..cc4f86a2a3ef 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/events.py +++ b/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/events.py @@ -3,7 +3,7 @@ # # SPDX-License-Identifier: BSD-3-Clause -"""Event terms for the dexsuite tasks.""" +"""Event terms for the lift tasks.""" from __future__ import annotations diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/events_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/events_cfg.py similarity index 99% rename from source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/events_cfg.py rename to source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/events_cfg.py index fb0d80bf8901..8a901fd7c99d 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/events_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/events_cfg.py @@ -3,7 +3,7 @@ # # SPDX-License-Identifier: BSD-3-Clause -"""Configuration for the dexsuite event terms.""" +"""Configuration for the lift event terms.""" from __future__ import annotations diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/observations.py b/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/observations.py index 84d01fac2c7d..a7b253906b0b 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/observations.py +++ b/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/observations.py @@ -3,8 +3,6 @@ # # SPDX-License-Identifier: BSD-3-Clause -"""Observation functions for the rigid and deformable lift tasks.""" - from __future__ import annotations from collections.abc import Sequence @@ -14,40 +12,261 @@ import warp as wp from isaaclab.managers import ManagerTermBase, SceneEntityCfg -from isaaclab.utils.math import subtract_frame_transforms +from isaaclab.utils.math import quat_apply, quat_apply_inverse, quat_inv, quat_mul, subtract_frame_transforms if TYPE_CHECKING: from isaaclab.assets import Articulation, DeformableObject, RigidObject from isaaclab.envs import ManagerBasedRLEnv from isaaclab.managers import ObservationTermCfg + from isaaclab.sensors import Camera -def object_position_in_robot_root_frame( +def object_quat_b( env: ManagerBasedRLEnv, robot_cfg: SceneEntityCfg = SceneEntityCfg("robot"), object_cfg: SceneEntityCfg = SceneEntityCfg("object"), ) -> torch.Tensor: - """The position of the object in the robot's root frame.""" + """Object orientation in the robot's root frame. + + Args: + env: The environment. + robot_cfg: Scene entity for the robot (reference frame). Defaults to ``SceneEntityCfg("robot")``. + object_cfg: Scene entity for the object. Defaults to ``SceneEntityCfg("object")``. + + Returns: + Tensor of shape ``(num_envs, 4)``: object quaternion ``(w, x, y, z)`` in the robot root frame. + """ robot: RigidObject = env.scene[robot_cfg.name] object: RigidObject = env.scene[object_cfg.name] - object_pos_w = object.data.root_pos_w.torch[:, :3] - object_pos_b, _ = subtract_frame_transforms(robot.data.root_pos_w.torch, robot.data.root_quat_w.torch, object_pos_w) - return object_pos_b + return quat_mul(quat_inv(robot.data.root_quat_w.torch), object.data.root_quat_w.torch) -def deformable_com_in_robot_root_frame( +class body_state_b(ManagerTermBase): + """Body state (pos, quat, lin vel, ang vel) in the base asset's root frame. + + The state for each body is stacked horizontally as + ``[position(3), quaternion(4)(wxyz), linvel(3), angvel(3)]`` and then concatenated over bodies. + + The body indices are baked to a device tensor at construction. + """ + + def __init__(self, cfg: ObservationTermCfg, env: ManagerBasedRLEnv): + super().__init__(cfg, env) + body_ids = cfg.params["body_asset_cfg"].body_ids + if isinstance(body_ids, list): + body_ids = torch.tensor(body_ids, dtype=torch.long, device=env.device) + self._body_ids = body_ids + + def __call__( + self, + env: ManagerBasedRLEnv, + body_asset_cfg: SceneEntityCfg, + base_asset_cfg: SceneEntityCfg, + include_vel: bool = True, + ) -> torch.Tensor: + """Compute the stacked body states. + + Args: + env: The environment. + body_asset_cfg: Scene entity for the articulated body whose links are observed. + base_asset_cfg: Scene entity providing the reference (root) frame. + include_vel: Whether to append the body linear/angular velocities. + + Returns: + Tensor of shape ``(num_envs, num_bodies * 13)`` (``num_bodies * 7`` without + velocities) with per-body states expressed in the base root frame. + """ + body_asset: Articulation = env.scene[body_asset_cfg.name] + base_asset: Articulation = env.scene[base_asset_cfg.name] + # get world pose of bodies + body_pos_w = body_asset.data.body_pos_w.torch[:, self._body_ids].view(-1, 3) + body_quat_w = body_asset.data.body_quat_w.torch[:, self._body_ids].view(-1, 4) + num_bodies = int(body_pos_w.shape[0] / env.num_envs) + # get world pose of base frame + root_pos_w = base_asset.data.root_link_pos_w.torch.unsqueeze(1).repeat_interleave(num_bodies, dim=1).view(-1, 3) + root_quat_w = ( + base_asset.data.root_link_quat_w.torch.unsqueeze(1).repeat_interleave(num_bodies, dim=1).view(-1, 4) + ) + # transform from world body pose to local body pose + body_pos_b, body_quat_b = subtract_frame_transforms(root_pos_w, root_quat_w, body_pos_w, body_quat_w) + # note: body velocities are the most engine/solver-sensitive observables (derivative + # signals amplify integrator and contact-response differences); pose-only states with + # observation history transfer across physics backends, velocity states do not. + if include_vel: + body_lin_vel_w = body_asset.data.body_lin_vel_w.torch[:, self._body_ids].view(-1, 3) + body_ang_vel_w = body_asset.data.body_ang_vel_w.torch[:, self._body_ids].view(-1, 3) + body_lin_vel_b = quat_apply_inverse(root_quat_w, body_lin_vel_w) + body_ang_vel_b = quat_apply_inverse(root_quat_w, body_ang_vel_w) + out = torch.cat((body_pos_b, body_quat_b, body_lin_vel_b, body_ang_vel_b), dim=1) + else: + out = torch.cat((body_pos_b, body_quat_b), dim=1) + return out.view(env.num_envs, -1) + + +class object_point_cloud_b(ManagerTermBase): + """Object surface point cloud expressed in a reference asset's root frame. + + Points are pre-sampled on the object's surface in its local frame and transformed to world, + then into the reference (e.g., robot) root frame. Optionally visualizes the points. + + Args (from ``cfg.params``): + object_cfg: Scene entity for the object to sample. Defaults to ``SceneEntityCfg("object")``. + ref_asset_cfg: Scene entity providing the reference frame. Defaults to ``SceneEntityCfg("robot")``. + num_points: Number of points to sample on the object surface. Defaults to ``10``. + visualize: Whether to draw markers for the points. Defaults to ``True``. + static: If ``True``, cache world-space points on reset and reuse them (no per-step resampling). + + Returns (from ``__call__``): + If ``flatten=False``: tensor of shape ``(num_envs, num_points, 3)``. + If ``flatten=True``: tensor of shape ``(num_envs, 3 * num_points)``. + """ + + def __init__(self, cfg, env: ManagerBasedRLEnv): + super().__init__(cfg, env) + + self.object_cfg: SceneEntityCfg = cfg.params.get("object_cfg", SceneEntityCfg("object")) + self.ref_asset_cfg: SceneEntityCfg = cfg.params.get("ref_asset_cfg", SceneEntityCfg("robot")) + num_points: int = cfg.params.get("num_points", 10) + self.object: RigidObject = env.scene[self.object_cfg.name] + self.ref_asset: Articulation = env.scene[self.ref_asset_cfg.name] + # lazy initialize visualizer and point cloud + if cfg.params.get("visualize", True): + from isaaclab.markers import VisualizationMarkers + from isaaclab.markers.config import RAY_CASTER_MARKER_CFG + + ray_cfg = RAY_CASTER_MARKER_CFG.replace(prim_path="/Visuals/ObservationPointCloud") + ray_cfg.markers["hit"].radius = 0.0025 + self.visualizer = VisualizationMarkers(ray_cfg) + from .utils import sample_object_point_cloud + + self.points_local = sample_object_point_cloud( + env.num_envs, num_points, self.object.cfg.prim_path, device=env.device + ) + self.points_w = torch.zeros_like(self.points_local) + + def __call__( + self, + env: ManagerBasedRLEnv, + ref_asset_cfg: SceneEntityCfg = SceneEntityCfg("robot"), + object_cfg: SceneEntityCfg = SceneEntityCfg("object"), + num_points: int = 10, + flatten: bool = False, + visualize: bool = True, + ): + """Compute the object point cloud in the reference asset's root frame. + + Note: + Points are pre-sampled at initialization using ``self.num_points``; the ``num_points`` argument is + kept for API symmetry and does not change the sampled set at runtime. + + Args: + env: The environment. + ref_asset_cfg: Reference frame provider (root). Defaults to ``SceneEntityCfg("robot")``. + object_cfg: Object to sample. Defaults to ``SceneEntityCfg("object")``. + num_points: Unused at runtime; see note above. + flatten: If ``True``, return a flattened tensor ``(num_envs, 3 * num_points)``. + visualize: If ``True``, draw markers for the points. + + Returns: + Tensor of shape ``(num_envs, num_points, 3)`` or flattened if requested. + """ + ref_pos_w = self.ref_asset.data.root_pos_w.torch.unsqueeze(1).repeat(1, num_points, 1) + ref_quat_w = self.ref_asset.data.root_quat_w.torch.unsqueeze(1).repeat(1, num_points, 1) + + object_pos_w = self.object.data.root_pos_w.torch.unsqueeze(1).repeat(1, num_points, 1) + object_quat_w = self.object.data.root_quat_w.torch.unsqueeze(1).repeat(1, num_points, 1) + # apply rotation + translation + self.points_w = quat_apply(object_quat_w, self.points_local) + object_pos_w + if visualize: + self.visualizer.visualize(translations=self.points_w.view(-1, 3)) + object_point_cloud_pos_b, _ = subtract_frame_transforms(ref_pos_w, ref_quat_w, self.points_w, None) + + return object_point_cloud_pos_b.view(env.num_envs, -1) if flatten else object_point_cloud_pos_b + + +def fingers_contact_force_b( env: ManagerBasedRLEnv, - asset_cfg: SceneEntityCfg = SceneEntityCfg("deformable"), - robot_cfg: SceneEntityCfg = SceneEntityCfg("robot"), + contact_sensor_names: list[str], + asset_cfg: SceneEntityCfg = SceneEntityCfg("robot"), ) -> torch.Tensor: - """Position of the deformable object's COM in the robot's root frame [m]. + """base-frame contact forces from listed sensors, concatenated per env. - The COM is the mean of the deformable's nodal positions (see - :attr:`~isaaclab.assets.DeformableObject.data.root_pos_w`). + Args: + env: The environment. + contact_sensor_names: Names of contact sensors in ``env.scene.sensors`` to read. Returns: - Tensor of shape ``(num_envs, 3)``. + Tensor of shape ``(num_envs, 3 * num_sensors)`` with forces stacked horizontally as + ``[fx, fy, fz]`` per sensor. """ + force_w = [env.scene.sensors[name].data.force_matrix_w.torch.view(env.num_envs, 3) for name in contact_sensor_names] + force_w = torch.stack(force_w, dim=1) + robot: Articulation = env.scene[asset_cfg.name] + root_link_quat_w = robot.data.root_link_quat_w.torch + forces_b = quat_apply_inverse(root_link_quat_w.unsqueeze(1).repeat(1, force_w.shape[1], 1), force_w) + return forces_b.view(env.num_envs, -1) + + +class vision_camera(ManagerTermBase): + def __init__(self, cfg, env: ManagerBasedRLEnv): + super().__init__(cfg, env) + sensor_cfg: SceneEntityCfg = cfg.params.get("sensor_cfg", SceneEntityCfg("tiled_camera")) + self.sensor: Camera = env.scene.sensors[sensor_cfg.name] + self.sensor_type = self.sensor.cfg.data_types[0] + self.norm_fn = ( + self._depth_norm + if self.sensor_type == "distance_to_image_plane" or self.sensor_type == "depth" + else self._rgb_norm + ) + + def __call__( + self, env: ManagerBasedRLEnv, sensor_cfg: SceneEntityCfg, normalize: bool = True + ) -> torch.Tensor: # obtain the input image + images = self.sensor.data.output[self.sensor_type] + torch.nan_to_num_(images, nan=1e6) + if normalize: + images = self.norm_fn(images) + images = images.permute(0, 3, 1, 2).contiguous() + return images + + def _rgb_norm(self, images: torch.Tensor) -> torch.Tensor: + return images.float() / 255.0 - 0.5 + + def _depth_norm(self, images: torch.Tensor) -> torch.Tensor: + # same [-0.5, 0.5) span as the RGB normalization: a wider depth range doubles the + # encoder's effective input scale and halves the stable learning-rate budget + return torch.tanh(images / 2) - 0.5 + + def show_collage(self, images: torch.Tensor, save_path: str = "collage.png"): + import matplotlib + import numpy as np + from PIL import Image + + a = images.detach().cpu().numpy() + n, h, w, c = a.shape + s = int(np.ceil(np.sqrt(n))) + canvas = np.full((s * h, s * w, 3), 255, np.uint8) + turbo = matplotlib.colormaps["turbo"] + for i in range(n): + r, col = divmod(i, s) + img = a[i] + if c == 1: + d = img[..., 0] + d = (d - d.min()) / (np.ptp(d) + 1e-8) + rgb = (turbo(d)[..., :3] * 255).astype(np.uint8) + else: + x = img if img.max() > 1 else img * 255 + rgb = np.clip(x, 0, 255).astype(np.uint8) + canvas[r * h : (r + 1) * h, col * w : (col + 1) * w] = rgb + Image.fromarray(canvas).save(save_path) + + +def deformable_com_in_robot_root_frame( + env: ManagerBasedRLEnv, + asset_cfg: SceneEntityCfg = SceneEntityCfg("deformable"), + robot_cfg: SceneEntityCfg = SceneEntityCfg("robot"), +) -> torch.Tensor: + """Position of the deformable object's COM in the robot's root frame [m].""" asset: DeformableObject = env.scene[asset_cfg.name] robot: Articulation = env.scene[robot_cfg.name] com_w = wp.to_torch(asset.data.root_pos_w) @@ -56,11 +275,7 @@ def deformable_com_in_robot_root_frame( class DeformableSampledPointsInRobotRootFrame(ManagerTermBase): - """Sampled deformable nodal points expressed in the robot's root frame. - - The point indices are sampled on reset, then reused within the episode so - each observed point follows the same material node over time. - """ + """Sampled deformable nodal points expressed in the robot's root frame.""" def __init__(self, cfg: ObservationTermCfg, env: ManagerBasedRLEnv): super().__init__(cfg, env) @@ -96,18 +311,7 @@ def __call__( robot_cfg: SceneEntityCfg = SceneEntityCfg("robot"), num_points: int = 20, ) -> torch.Tensor: - """Sample deformable nodal positions in the robot's root frame. - - Args: - env: The environment instance. - asset_cfg: The deformable object entity. - robot_cfg: The robot entity providing the reference frame. - num_points: Number of sampled points. - - Returns: - Flattened tensor of shape ``(num_envs, 3 * num_points)`` with sampled - point positions [m] in the robot root frame. - """ + """Return sampled deformable nodal positions in the robot's root frame [m].""" asset: DeformableObject = env.scene[asset_cfg.name] robot: Articulation = env.scene[robot_cfg.name] if num_points != self.num_points: @@ -117,13 +321,9 @@ def __call__( nodal_pos_w = asset.data.nodal_pos_w.torch sampled_points_w = nodal_pos_w.gather(1, self.node_ids.unsqueeze(-1).expand(-1, -1, 3)) - - flat_sampled_points_w = sampled_points_w.reshape(-1, 3) root_pos_w = robot.data.root_pos_w.torch.unsqueeze(1).expand(-1, num_points, -1) root_quat_w = robot.data.root_quat_w.torch.unsqueeze(1).expand(-1, num_points, -1) sampled_points_b, _ = subtract_frame_transforms( - root_pos_w.reshape(-1, 3), - root_quat_w.reshape(-1, 4), - flat_sampled_points_w, + root_pos_w.reshape(-1, 3), root_quat_w.reshape(-1, 4), sampled_points_w.reshape(-1, 3) ) return sampled_points_b.view(env.num_envs, -1) diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/rewards.py b/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/rewards.py index bbee850bcb43..54cdff0fa54b 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/rewards.py +++ b/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/rewards.py @@ -3,96 +3,371 @@ # # SPDX-License-Identifier: BSD-3-Clause -"""Reward functions for the rigid and deformable lift tasks.""" - from __future__ import annotations +import warnings +from collections.abc import Sequence from typing import TYPE_CHECKING import torch import warp as wp -from isaaclab.managers import ManagerTermBase, RewardTermCfg, SceneEntityCfg -from isaaclab.utils.math import combine_frame_transforms +from isaaclab.managers import ManagerTermBase, SceneEntityCfg +from isaaclab.utils import math as math_utils +from isaaclab.utils.math import combine_frame_transforms, compute_pose_error if TYPE_CHECKING: from isaaclab.assets import Articulation, DeformableObject, RigidObject from isaaclab.envs import ManagerBasedRLEnv - from isaaclab.sensors import FrameTransformer + from isaaclab.sensors import ContactSensor, FrameTransformer -def object_is_lifted( - env: ManagerBasedRLEnv, minimal_height: float, object_cfg: SceneEntityCfg = SceneEntityCfg("object") +def object_ee_distance( + env: ManagerBasedRLEnv, + std: float, + thumb_name: str, + finger_names: list[str], + contact_threshold: float = 1.0, + object_cfg: SceneEntityCfg = SceneEntityCfg("object"), + asset_cfg: SceneEntityCfg = SceneEntityCfg("robot"), ) -> torch.Tensor: - """Reward the agent for lifting the object above the minimal height.""" - object: RigidObject = env.scene[object_cfg.name] - return torch.where(object.data.root_pos_w.torch[:, 2] > minimal_height, 1.0, 0.0) + """Reward reaching the object using a tanh-kernel on end-effector distance with contact bonus. + The reward is close to 1 when the distance is small. The reward is scaled by contact: + - Full reward (1x) when good contact (thumb + finger) + - Reduced reward (0.1x) when no contact -def object_ee_distance( + Args: + env: The environment instance. + std: Standard deviation for tanh kernel. + thumb_name: Name of the thumb contact sensor. + finger_names: Names of the finger contact sensors. + contact_threshold: Contact force magnitude threshold. + object_cfg: Configuration for the object. + asset_cfg: Configuration for the robot asset. + """ + asset: RigidObject = env.scene[asset_cfg.name] + obj: RigidObject = env.scene[object_cfg.name] + asset_pos = asset.data.body_pos_w.torch[:, asset_cfg.body_ids] + object_pos = obj.data.root_pos_w.torch + distance = torch.linalg.norm(asset_pos - object_pos[:, None, :], dim=-1).max(dim=-1).values + contact_bonus = contacts(env, contact_threshold, thumb_name, finger_names).float().clamp(0.1, 1.0) + return (1 - torch.tanh(distance / std)) * contact_bonus + + +def _contact_force_mag(sensor: ContactSensor, num_envs: int) -> torch.Tensor: + """Extract per-environment contact force magnitude from a sensor's force_matrix_w.""" + force = sensor.data.force_matrix_w.torch.view(num_envs, 3) + return torch.linalg.norm(force, dim=-1) + + +def contacts(env: ManagerBasedRLEnv, threshold: float, thumb_name: str, finger_names: list[str]) -> torch.Tensor: + """Reward for good contact: thumb + at least one finger above threshold. + + Args: + env: The environment instance. + threshold: Contact force magnitude threshold. + thumb_name: Name of the thumb contact sensor in the scene. + finger_names: Names of the finger contact sensors in the scene. + + Returns: + Boolean tensor indicating good contact condition per environment. + """ + thumb_mag = _contact_force_mag(env.scene.sensors[thumb_name], env.num_envs) + + any_finger_contact = torch.zeros(env.num_envs, dtype=torch.bool, device=env.device) + for finger_name in finger_names: + finger_mag = _contact_force_mag(env.scene.sensors[finger_name], env.num_envs) + any_finger_contact = any_finger_contact | (finger_mag > threshold) + + return (thumb_mag > threshold) & any_finger_contact + + +def contact_count(env: ManagerBasedRLEnv, threshold: float, sensor_names: list[str]) -> torch.Tensor: + """Count the number of contact sensors with force above threshold. + + For each sensor that detects contact above the threshold, add 1 to the total. + This provides a reward proportional to the number of fingers in contact. + + Args: + env: The environment instance. + threshold: Contact force magnitude threshold. + sensor_names: Names of the contact sensors in the scene. + + Returns: + Tensor of shape (num_envs,) with the count of sensors in contact per environment. + """ + count = torch.zeros(env.num_envs, dtype=torch.float32, device=env.device) + + for sensor_name in sensor_names: + mag = _contact_force_mag(env.scene.sensors[sensor_name], env.num_envs) + count += (mag > threshold).float() + return count / len(sensor_names) + + +class success_reward(ManagerTermBase): + """Reward success by comparing commanded pose to the object pose using tanh kernels on error. + + The reward is gated by contact: only given when thumb + at least one finger are in contact. + + Maintains a sticky ``succeeded`` boolean tensor per environment that flips to ``True`` once + the success condition is met during an episode and resets to ``False`` on environment reset. + + Args: + cfg: Configuration object specifying term parameters. + env: The manager-based RL environment. + """ + + def __init__(self, cfg, env: ManagerBasedRLEnv): + super().__init__(cfg, env) + self.succeeded = torch.zeros(env.num_envs, dtype=torch.bool, device=env.device) + + def reset(self, env_ids: Sequence[int] | None = None): + if env_ids is None: + env_ids = slice(None) + self.succeeded[env_ids] = False + + def __call__( + self, + env: ManagerBasedRLEnv, + command_name: str, + asset_cfg: SceneEntityCfg, + align_asset_cfg: SceneEntityCfg, + pos_std: float, + thumb_name: str, + finger_names: list[str], + contact_threshold: float = 0.01, + rot_std: float | None = None, + ) -> torch.Tensor: + asset: RigidObject = env.scene[asset_cfg.name] + obj: RigidObject = env.scene[align_asset_cfg.name] + command = env.command_manager.get_command(command_name) + des_pos_w, des_quat_w = combine_frame_transforms( + asset.data.root_pos_w.torch, + asset.data.root_quat_w.torch, + command[:, :3], + command[:, 3:7], + ) + pos_err, rot_err = compute_pose_error( + des_pos_w, + des_quat_w, + obj.data.root_pos_w.torch, + obj.data.root_quat_w.torch, + ) + pos_dist = torch.linalg.norm(pos_err, dim=1) + contact_mask = contacts(env, contact_threshold, thumb_name, finger_names) + + if rot_std: + rot_dist = torch.linalg.norm(rot_err, dim=1) + reward = (1 - torch.tanh(pos_dist / pos_std)) * (1 - torch.tanh(rot_dist / rot_std)) * contact_mask.float() + self.succeeded |= (pos_dist < pos_std) & (rot_dist < rot_std) & contact_mask + else: + reward = ((1 - torch.tanh(pos_dist / pos_std)) ** 2) * contact_mask.float() + self.succeeded |= (pos_dist < pos_std) & contact_mask + + return reward + + +def position_command_error_tanh( env: ManagerBasedRLEnv, std: float, - object_cfg: SceneEntityCfg = SceneEntityCfg("object"), - ee_frame_cfg: SceneEntityCfg = SceneEntityCfg("ee_frame"), + command_name: str, + asset_cfg: SceneEntityCfg, + align_asset_cfg: SceneEntityCfg, + thumb_name: str, + finger_names: list[str], + contact_threshold: float = 0.1, ) -> torch.Tensor: - """Reward the agent for reaching the object using tanh-kernel.""" - # extract the used quantities (to enable type-hinting) - object: RigidObject = env.scene[object_cfg.name] - ee_frame: FrameTransformer = env.scene[ee_frame_cfg.name] - # Target object position: (num_envs, 3) - cube_pos_w = object.data.root_pos_w.torch - # End-effector position: (num_envs, 3) - ee_w = ee_frame.data.target_pos_w.torch[..., 0, :] - # Distance of the end-effector to the object: (num_envs,) - object_ee_distance = torch.linalg.norm(cube_pos_w - ee_w, dim=1) + """Reward tracking of commanded position using tanh kernel, gated by contact presence. - return 1 - torch.tanh(object_ee_distance / std) + .. deprecated:: + Use :class:`position_command_progress`, which pays per increment of ground gained on the + best error so far instead of paying every step the object is near the goal. Replace + ``std`` with ``min_improvement``. + """ + warnings.warn( + "The reward term 'position_command_error_tanh' is deprecated. Use 'position_command_progress' instead," + " replacing 'std' with 'min_improvement'.", + DeprecationWarning, + stacklevel=2, + ) + asset: RigidObject = env.scene[asset_cfg.name] + obj: RigidObject = env.scene[align_asset_cfg.name] + command = env.command_manager.get_command(command_name) + des_pos_w, _ = combine_frame_transforms( + asset.data.root_pos_w.torch, + asset.data.root_quat_w.torch, + command[:, :3], + ) + distance = torch.linalg.norm(obj.data.root_pos_w.torch - des_pos_w, dim=1) + return (1 - torch.tanh(distance / std)) * contacts(env, contact_threshold, thumb_name, finger_names).float() -class object_goal_distance(ManagerTermBase): - """Reward the agent for tracking the object-to-goal pose using a tanh kernel. +def orientation_command_error_tanh( + env: ManagerBasedRLEnv, + std: float, + command_name: str, + asset_cfg: SceneEntityCfg, + align_asset_cfg: SceneEntityCfg, + thumb_name: str, + finger_names: list[str], + contact_threshold: float = 0.1, +) -> torch.Tensor: + """Reward tracking of commanded orientation using tanh kernel, gated by contact presence. - If ``success_threshold`` is provided in the term params, this also tracks per-episode - success (sticky binary: object ever within ``success_threshold`` of the commanded goal - while lifted above ``minimal_height``) and logs the mean across environments under - ``Metrics/success_rate`` on reset. + .. deprecated:: + Use :class:`orientation_command_progress`, which pays per increment of ground gained on the + best error so far instead of paying every step the object is near the goal. Replace + ``std`` with ``min_improvement``. """ + warnings.warn( + "The reward term 'orientation_command_error_tanh' is deprecated. Use 'orientation_command_progress' instead," + " replacing 'std' with 'min_improvement'.", + DeprecationWarning, + stacklevel=2, + ) + asset: RigidObject = env.scene[asset_cfg.name] + obj: RigidObject = env.scene[align_asset_cfg.name] + command = env.command_manager.get_command(command_name) + des_quat_w = math_utils.quat_mul(asset.data.root_link_quat_w.torch, command[:, 3:7]) + quat_distance = math_utils.quat_error_magnitude(obj.data.root_quat_w.torch, des_quat_w) + return (1 - torch.tanh(quat_distance / std)) * contacts(env, contact_threshold, thumb_name, finger_names).float() - def __init__(self, cfg: RewardTermCfg, env: ManagerBasedRLEnv): + +class _ProgressReward(ManagerTermBase): + """Base class for rewards that only pay out when a tracking error reaches a new episode best. + + The term holds a per-environment bar equal to the smallest error credited so far in the episode. + A fixed reward of ``1.0`` is paid on every step that pushes the error below that bar by at least + ``min_improvement``, and nothing is paid otherwise. Since the bar moves only when a reward is + paid, ground that was already credited cannot be farmed again by backing off and re-approaching, + and the episodic reward sum counts how many improvements the policy actually made. + + The bar is seeded with the error measured on the first step of an episode, so holding the starting + pose earns nothing. Progress made while the gating condition is false does not move the bar, so it + stays claimable once the condition is met again. The bar is measured against the command in force, + so it is re-seeded whenever the command resamples and never carries across goals. + """ + + def __init__(self, cfg, env: ManagerBasedRLEnv): super().__init__(cfg, env) - self._track_success = cfg.params.get("success_threshold") is not None - if self._track_success: - self._succeeded = torch.zeros(env.num_envs, dtype=torch.bool, device=env.device) + # inf marks an environment whose bar has not been seeded yet against its current command + self.best_error = torch.full((env.num_envs,), float("inf"), device=env.device) + self._prev_command: torch.Tensor | None = None - def reset(self, env_ids: torch.Tensor): - if self._track_success: - self._env.extras.setdefault("log", {})["Metrics/success_rate"] = ( - self._succeeded[env_ids].float().mean().item() - ) - self._succeeded[env_ids] = False + def reset(self, env_ids: Sequence[int] | None = None): + if env_ids is None: + env_ids = slice(None) + self.best_error[env_ids] = float("inf") + + def _progress( + self, error: torch.Tensor, gate: torch.Tensor, min_improvement: float, command: torch.Tensor + ) -> torch.Tensor: + """Return 1.0 for the environments that beat their best error under the command in force. + + Args: + error: Current tracking error per environment. + gate: Environments allowed to be credited this step. + min_improvement: Amount the error must beat the bar by to be paid again. + command: Command being tracked; a change re-seeds the bar for that environment. + + Returns: + Tensor of shape ``(num_envs,)`` that is ``1.0`` where a payout is due. + """ + # a resampled command changes the error's reference, so the bar it was measured against no + # longer applies; dropping it to inf re-seeds from the first error under the new command + if self._prev_command is None: + self._prev_command = command.clone() + else: + self.best_error[(self._prev_command != command).any(dim=1)] = float("inf") + self._prev_command.copy_(command) + unseeded = torch.isinf(self.best_error) + self.best_error[unseeded] = error[unseeded] + improved = gate & (error < self.best_error - min_improvement) + self.best_error[improved] = error[improved] + return improved.float() + + +class position_command_progress(_ProgressReward): + """Reward every step that brings the object closer to the commanded position than ever before. + + See :class:`_ProgressReward` for the progress bookkeeping. The reward is gated by contact, so + only positional gains made while the thumb and at least one finger are touching are credited. + """ def __call__( self, env: ManagerBasedRLEnv, - std: float, - minimal_height: float, command_name: str, - robot_cfg: SceneEntityCfg = SceneEntityCfg("robot"), - object_cfg: SceneEntityCfg = SceneEntityCfg("object"), - success_threshold: float | None = None, + asset_cfg: SceneEntityCfg, + align_asset_cfg: SceneEntityCfg, + thumb_name: str, + finger_names: list[str], + contact_threshold: float = 0.1, + min_improvement: float = 0.01, ) -> torch.Tensor: - robot: RigidObject = env.scene[robot_cfg.name] - obj: RigidObject = env.scene[object_cfg.name] + """Compute the progress reward. + + Args: + env: The environment instance. + command_name: Name of the pose command to track. + asset_cfg: Configuration for the asset the command is expressed relative to. + align_asset_cfg: Configuration for the asset that must reach the command. + thumb_name: Name of the thumb contact sensor. + finger_names: Names of the finger contact sensors. + contact_threshold: Contact force magnitude threshold [N]. + min_improvement: Distance [m] the object must gain on the episode best to be paid again. + """ + asset: RigidObject = env.scene[asset_cfg.name] + obj: RigidObject = env.scene[align_asset_cfg.name] command = env.command_manager.get_command(command_name) des_pos_w, _ = combine_frame_transforms( - robot.data.root_pos_w.torch, robot.data.root_quat_w.torch, command[:, :3] + asset.data.root_pos_w.torch, + asset.data.root_quat_w.torch, + command[:, :3], ) - object_pos_w = obj.data.root_pos_w.torch - distance = torch.linalg.norm(des_pos_w - object_pos_w, dim=1) - is_lifted = object_pos_w[:, 2] > minimal_height - if success_threshold is not None: - self._succeeded |= is_lifted & (distance < success_threshold) - return is_lifted.float() * (1 - torch.tanh(distance / std)) + distance = torch.linalg.norm(obj.data.root_pos_w.torch - des_pos_w, dim=1) + gate = contacts(env, contact_threshold, thumb_name, finger_names) + return self._progress(distance, gate, min_improvement, command) + + +class orientation_command_progress(_ProgressReward): + """Reward every step that brings the object closer to the commanded orientation than ever before. + + See :class:`_ProgressReward` for the progress bookkeeping. The reward is gated by contact, so + only rotational gains made while the thumb and at least one finger are touching are credited. + """ + + def __call__( + self, + env: ManagerBasedRLEnv, + command_name: str, + asset_cfg: SceneEntityCfg, + align_asset_cfg: SceneEntityCfg, + thumb_name: str, + finger_names: list[str], + contact_threshold: float = 0.1, + min_improvement: float = 0.05, + ) -> torch.Tensor: + """Compute the progress reward. + + Args: + env: The environment instance. + command_name: Name of the pose command to track. + asset_cfg: Configuration for the asset the command is expressed relative to. + align_asset_cfg: Configuration for the asset that must reach the command. + thumb_name: Name of the thumb contact sensor. + finger_names: Names of the finger contact sensors. + contact_threshold: Contact force magnitude threshold [N]. + min_improvement: Angle [rad] the object must gain on the episode best to be paid again. + """ + asset: RigidObject = env.scene[asset_cfg.name] + obj: RigidObject = env.scene[align_asset_cfg.name] + command = env.command_manager.get_command(command_name) + des_quat_w = math_utils.quat_mul(asset.data.root_link_quat_w.torch, command[:, 3:7]) + quat_distance = math_utils.quat_error_magnitude(obj.data.root_quat_w.torch, des_quat_w) + gate = contacts(env, contact_threshold, thumb_name, finger_names) + return self._progress(quat_distance, gate, min_improvement, command) def deformable_lifted( @@ -100,16 +375,7 @@ def deformable_lifted( minimal_height: float, asset_cfg: SceneEntityCfg = SceneEntityCfg("deformable"), ) -> torch.Tensor: - """Reward if the deformable COM is above a minimum height. - - Args: - env: The environment instance. - minimal_height: Minimum COM height [m]. - asset_cfg: The deformable object entity. - - Returns: - Reward tensor with shape ``(num_envs,)``. - """ + """Reward if the deformable COM is above a minimum height.""" asset: DeformableObject = env.scene[asset_cfg.name] com_z = wp.to_torch(asset.data.root_pos_w)[:, 2] return torch.where(com_z > minimal_height, 1.0, 0.0) @@ -121,17 +387,7 @@ def deformable_ee_distance( asset_cfg: SceneEntityCfg = SceneEntityCfg("deformable"), ee_frame_cfg: SceneEntityCfg = SceneEntityCfg("ee_frame"), ) -> torch.Tensor: - """Reward reaching the deformable's nearest nodal point with the end-effector. - - Args: - env: The environment instance. - std: The tanh kernel standard deviation [m]. - asset_cfg: The deformable object entity. - ee_frame_cfg: The end-effector frame entity. - - Returns: - Reward tensor with shape ``(num_envs,)``. - """ + """Reward reaching the deformable's nearest nodal point with the end-effector.""" asset: DeformableObject = env.scene[asset_cfg.name] ee_frame: FrameTransformer = env.scene[ee_frame_cfg.name] nodal_pos_w = wp.to_torch(asset.data.nodal_pos_w) @@ -148,17 +404,12 @@ def deformable_com_goal_distance( robot_cfg: SceneEntityCfg = SceneEntityCfg("robot"), asset_cfg: SceneEntityCfg = SceneEntityCfg("deformable"), ) -> torch.Tensor: - """Reward tracking of the goal position by the deformable's COM (tanh kernel). - - Only credits when the COM is above ``minimal_height`` (i.e. the object is lifted). - The command is interpreted as ``[x, y, z, qw, qx, qy, qz]`` in the robot's root frame. - """ + """Reward tracking of the goal position by the deformable's COM.""" robot: Articulation = env.scene[robot_cfg.name] asset: DeformableObject = env.scene[asset_cfg.name] command = env.command_manager.get_command(command_name) - des_pos_b = command[:, :3] des_pos_w, _ = combine_frame_transforms( - wp.to_torch(robot.data.root_pos_w), wp.to_torch(robot.data.root_quat_w), des_pos_b + wp.to_torch(robot.data.root_pos_w), wp.to_torch(robot.data.root_quat_w), command[:, :3] ) com_w = wp.to_torch(asset.data.root_pos_w) distance = torch.linalg.norm(des_pos_w - com_w, dim=1) @@ -166,18 +417,6 @@ def deformable_com_goal_distance( def gripper_close_action(env: ManagerBasedRLEnv, action_name: str = "gripper_action") -> torch.Tensor: - """Penalty signal for commanding the gripper to close. - - The binary gripper action uses negative float actions for close commands and - non-negative actions for open commands. - - Args: - env: The environment instance. - action_name: Name of the gripper action term. - - Returns: - Tensor with shape ``(num_envs,)`` containing ``1`` when the gripper is - commanded closed and ``0`` otherwise. - """ + """Return one when the binary gripper action commands closing and zero otherwise.""" gripper_action = env.action_manager.get_term(action_name).raw_actions return torch.any(gripper_action < 0.0, dim=1).float() diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/terminations.py b/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/terminations.py index 0a82fc85bdeb..166bd9e805db 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/terminations.py +++ b/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/terminations.py @@ -3,7 +3,7 @@ # # SPDX-License-Identifier: BSD-3-Clause -"""Termination functions for the rigid and deformable lift tasks. +"""Common functions that can be used to activate certain terminations for the lift task. The functions can be passed to the :class:`isaaclab.managers.TerminationTermCfg` object to enable the termination introduced by the function. @@ -16,15 +16,63 @@ import torch import warp as wp -from isaaclab.managers import SceneEntityCfg +from isaaclab.managers import ManagerTermBase, SceneEntityCfg, TerminationTermCfg from isaaclab.utils.math import combine_frame_transforms if TYPE_CHECKING: - from isaaclab.assets import DeformableObject, RigidObject + from isaaclab.assets import Articulation, DeformableObject, RigidObject from isaaclab.envs import ManagerBasedRLEnv from isaaclab.sensors import FrameTransformer +class out_of_bound(ManagerTermBase): + """Termination condition for when the object falls out of bound. + + The world-space bounds are cached and rebuilt per axis only when the corresponding + ``in_bound_range`` entry changes. This keeps the hot path free of host-to-device + transfers while still honoring runtime updates (e.g. from a curriculum term). + """ + + def __init__(self, cfg: TerminationTermCfg, env: ManagerBasedRLEnv): + super().__init__(cfg, env) + + asset_cfg: SceneEntityCfg = cfg.params.get("asset_cfg", SceneEntityCfg("object")) + self._object: RigidObject = env.scene[asset_cfg.name] + + # Pre-apply env_origins so we can compare directly against world-space positions. + self._origins = env.scene.env_origins # (N, 3) + self._lower = self._origins.clone() # (N, 3) + self._upper = self._origins.clone() # (N, 3) + self._cached_axis: list[tuple[float, ...] | None] = [None, None, None] + + def __call__( + self, + env: ManagerBasedRLEnv, + asset_cfg: SceneEntityCfg = SceneEntityCfg("object"), + in_bound_range: dict[str, tuple[float, float]] = {}, + ) -> torch.Tensor: + # rebuild only the axes whose bounds changed (curriculum typically only moves one) + for i, key in enumerate(["x", "y", "z"]): + bounds = tuple(in_bound_range.get(key, (0.0, 0.0))) + if bounds != self._cached_axis[i]: + lo, hi = bounds + self._lower[:, i] = self._origins[:, i] + lo + self._upper[:, i] = self._origins[:, i] + hi + self._cached_axis[i] = bounds + + pos_w = self._object.data.root_pos_w.torch + return ((pos_w < self._lower) | (pos_w > self._upper)).any(dim=1) + + +def abnormal_robot_state(env: ManagerBasedRLEnv, asset_cfg: SceneEntityCfg = SceneEntityCfg("robot")) -> torch.Tensor: + """Terminating environment when violation of velocity limits detects, this usually indicates unstable physics caused + by very bad, or aggressive action""" + robot: Articulation = env.scene[asset_cfg.name] + joint_vel = robot.data.joint_vel.torch + joint_vel_limits = robot.data.joint_vel_limits.torch + return (joint_vel.abs() > (joint_vel_limits * 2)).any(dim=1) + + def object_reached_goal( env: ManagerBasedRLEnv, command_name: str = "object_pose", @@ -32,32 +80,12 @@ def object_reached_goal( robot_cfg: SceneEntityCfg = SceneEntityCfg("robot"), object_cfg: SceneEntityCfg = SceneEntityCfg("object"), ) -> torch.Tensor: - """Termination condition for the object reaching the goal position. - - Args: - env: The environment. - command_name: The name of the command that is used to control the object. - threshold: The threshold for the object to reach the goal position. Defaults to 0.02. - robot_cfg: The robot configuration. Defaults to SceneEntityCfg("robot"). - object_cfg: The object configuration. Defaults to SceneEntityCfg("object"). - - """ - # extract the used quantities (to enable type-hinting) + """Return whether the rigid object reached the commanded goal position.""" robot: RigidObject = env.scene[robot_cfg.name] object: RigidObject = env.scene[object_cfg.name] command = env.command_manager.get_command(command_name) - # compute the desired position in the world frame - des_pos_b = command[:, :3] - # Convert to torch for combine_frame_transforms (robot data may be Warp arrays under Newton) - root_pos_w = robot.data.root_pos_w.torch - root_quat_w = robot.data.root_quat_w.torch - des_pos_w, _ = combine_frame_transforms(root_pos_w, root_quat_w, des_pos_b) - # distance of the end-effector to the object: (num_envs,) - object_pos_w = object.data.root_pos_w.torch - distance = torch.linalg.norm(des_pos_w - object_pos_w[:, :3], dim=1) - - # rewarded if the object is lifted above the threshold - return distance < threshold + des_pos_w, _ = combine_frame_transforms(robot.data.root_pos_w.torch, robot.data.root_quat_w.torch, command[:, :3]) + return torch.linalg.norm(des_pos_w - object.data.root_pos_w.torch[:, :3], dim=1) < threshold def deformable_com_below_minimum( @@ -65,10 +93,9 @@ def deformable_com_below_minimum( minimum_height: float, asset_cfg: SceneEntityCfg = SceneEntityCfg("deformable"), ) -> torch.Tensor: - """Termination signal when the deformable's COM falls below ``minimum_height`` [m].""" + """Return whether the deformable object's COM is below the minimum height [m].""" asset: DeformableObject = env.scene[asset_cfg.name] - com_z = wp.to_torch(asset.data.root_pos_w)[:, 2] - return com_z < minimum_height + return wp.to_torch(asset.data.root_pos_w)[:, 2] < minimum_height def deformable_outside_table_bounds( @@ -77,17 +104,7 @@ def deformable_outside_table_bounds( y_bounds: tuple[float, float], asset_cfg: SceneEntityCfg = SceneEntityCfg("deformable"), ) -> torch.Tensor: - """Terminate if any deformable nodal point leaves the table footprint. - - Args: - env: The environment instance. - x_bounds: Allowed x-position range in the environment frame [m]. - y_bounds: Allowed y-position range in the environment frame [m]. - asset_cfg: The deformable object entity. - - Returns: - Boolean tensor with shape ``(num_envs,)``. - """ + """Return whether any deformable node left the table footprint [m].""" asset: DeformableObject = env.scene[asset_cfg.name] nodal_pos = wp.to_torch(asset.data.nodal_pos_w) - env.scene.env_origins.unsqueeze(1) outside_x = (nodal_pos[..., 0] < x_bounds[0]) | (nodal_pos[..., 0] > x_bounds[1]) @@ -100,19 +117,7 @@ def ee_below_minimum( minimum_height: float, ee_frame_cfg: SceneEntityCfg = SceneEntityCfg("ee_frame"), ) -> torch.Tensor: - """Termination signal when the end-effector falls below ``minimum_height`` [m]. - - Height is measured in the environment frame (``z`` of the EE position with the env - origin subtracted), so the threshold is independent of the environment's xy offset. - - Args: - env: The environment instance. - minimum_height: Minimum allowed EE height in the environment frame [m]. - ee_frame_cfg: The end-effector frame entity. - - Returns: - Boolean tensor with shape ``(num_envs,)``. - """ + """Return whether the end-effector is below the minimum environment-frame height [m].""" ee_frame: FrameTransformer = env.scene[ee_frame_cfg.name] ee_z = wp.to_torch(ee_frame.data.target_pos_w)[..., 0, 2] - env.scene.env_origins[:, 2] return ee_z < minimum_height diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/utils.py b/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/utils.py similarity index 100% rename from source/isaaclab_tasks/isaaclab_tasks/core/dexsuite/mdp/utils.py rename to source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/utils.py diff --git a/source/isaaclab_tasks/test/benchmarking/configs.yaml b/source/isaaclab_tasks/test/benchmarking/configs.yaml index 9ee7411780f7..d33109b90e17 100644 --- a/source/isaaclab_tasks/test/benchmarking/configs.yaml +++ b/source/isaaclab_tasks/test/benchmarking/configs.yaml @@ -61,7 +61,7 @@ fast: episode_length: 875 upper_thresholds: duration: 1800 - sb3:Isaac-Lift-Cube-Franka: + sb3:IsaacContrib-Lift-Cube-Franka: max_iterations: 150 lower_thresholds: reward: 1.5 @@ -159,7 +159,7 @@ full: episode_length: 400 upper_thresholds: duration: 1000 - Isaac-Lift-Cube-Franka: + IsaacContrib-Lift-Cube-Franka: max_iterations: 300 lower_thresholds: reward: 90 diff --git a/source/isaaclab_tasks/test/core/test_environment_determinism.py b/source/isaaclab_tasks/test/core/test_environment_determinism.py index 70d64b733ea4..780b5357bf87 100644 --- a/source/isaaclab_tasks/test/core/test_environment_determinism.py +++ b/source/isaaclab_tasks/test/core/test_environment_determinism.py @@ -37,7 +37,7 @@ def setup_environment(): "task_name", [ "Isaac-Open-Drawer-Franka", - "Isaac-Lift-Cube-Franka", + "IsaacContrib-Lift-Cube-Franka", ], ) @pytest.mark.parametrize("device", ["cuda", "cpu"]) diff --git a/source/isaaclab_tasks/test/core/test_hydra.py b/source/isaaclab_tasks/test/core/test_hydra.py index 453931cc678a..0c5526619a40 100644 --- a/source/isaaclab_tasks/test/core/test_hydra.py +++ b/source/isaaclab_tasks/test/core/test_hydra.py @@ -1180,7 +1180,7 @@ class ConflictEnvCfg: def test_apply_overrides_aliased_globals_no_conflict(): """Two global presets resolving to equal values do not raise. - Mirrors the dexsuite ObjectCfg pattern where ``newton_mjwarp = cube`` creates + Mirrors the Lift ObjectCfg pattern where ``newton_mjwarp = cube`` creates separate but equal dataclass instances after @configclass processing. """ diff --git a/source/isaaclab_tasks/test/core/test_lift_env_cfg.py b/source/isaaclab_tasks/test/core/test_lift_env_cfg.py new file mode 100644 index 000000000000..482492f7afc1 --- /dev/null +++ b/source/isaaclab_tasks/test/core/test_lift_env_cfg.py @@ -0,0 +1,60 @@ +# Copyright (c) 2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md). +# All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause + +"""Configuration gates for the unified dexterous Lift and Reorient tasks.""" + +import torch + +from isaaclab_tasks.core.lift import mdp +from isaaclab_tasks.core.lift.config.franka.franka_env_cfg import FrankaLiftEnvCfg +from isaaclab_tasks.core.lift.config.kuka_allegro.agents.rsl_rl_ppo_cfg import KukaAllegroPPORunnerCfg +from isaaclab_tasks.core.lift.config.kuka_allegro.kuka_allegro_env_cfg import ( + KukaAllegroLiftEnvCfg, + KukaAllegroReorientEnvCfg, +) +from isaaclab_tasks.utils import resolve_presets + + +def test_lift_keeps_the_upstream_reset_and_progress_training_terms() -> None: + """The package move must retain the rewritten reset bank and progress rewards.""" + for raw_env_cfg in (FrankaLiftEnvCfg(), KukaAllegroLiftEnvCfg()): + env_cfg = resolve_presets(raw_env_cfg) + reset_params = env_cfg.events.conditional_reset.params + + assert reset_params["success_monitor"].target_success_rate == 0.5 + assert reset_params["diversity_feature"] is not None + assert env_cfg.rewards.position_tracking.func is mdp.position_command_progress + assert env_cfg.rewards.orientation_tracking is None + assert len(env_cfg.scene.object.spawn.assets_cfg) > 1 + + +def test_reorient_keeps_orientation_progress_separate_from_lift() -> None: + """Reorient must retain orientation tracking while Lift disables only that term.""" + env_cfg = KukaAllegroReorientEnvCfg() + + assert env_cfg.rewards.position_tracking.func is mdp.position_command_progress + assert env_cfg.rewards.orientation_tracking.func is mdp.orientation_command_progress + assert env_cfg.commands.object_pose.position_only is False + + +def test_camera_runner_keeps_the_stable_encoder_settings() -> None: + """Camera presets must retain the fixed-rate spatial-softmax training configuration.""" + runner_cfg = KukaAllegroPPORunnerCfg() + + assert runner_cfg.single_camera.algorithm.schedule == "fixed" + assert runner_cfg.single_camera.algorithm.learning_rate == 7.0e-5 + assert runner_cfg.duo_camera.actor.class_name == ( + "isaaclab_tasks.core.lift.config.kuka_allegro.agents.models:SpatialSoftmaxCNNModel" + ) + assert runner_cfg.duo_camera.actor.cnn_cfg.output_channels == [16, 32, 32] + + +def test_camera_normalization_is_stationary() -> None: + """RGB and depth normalization must not depend on per-frame statistics.""" + rgb = torch.tensor([0.0, 127.5, 255.0]) + depth = torch.tensor([0.0, 2.0]) + + assert torch.allclose(mdp.vision_camera._rgb_norm(None, rgb), torch.tensor([-0.5, 0.0, 0.5])) + assert torch.allclose(mdp.vision_camera._depth_norm(None, depth), torch.tanh(depth / 2) - 0.5) diff --git a/source/isaaclab_tasks/test/core/test_dexsuite_kuka_ovphysx_presets.py b/source/isaaclab_tasks/test/core/test_lift_kuka_ovphysx_presets.py similarity index 94% rename from source/isaaclab_tasks/test/core/test_dexsuite_kuka_ovphysx_presets.py rename to source/isaaclab_tasks/test/core/test_lift_kuka_ovphysx_presets.py index 293b5b70632c..d77855b1568e 100644 --- a/source/isaaclab_tasks/test/core/test_dexsuite_kuka_ovphysx_presets.py +++ b/source/isaaclab_tasks/test/core/test_lift_kuka_ovphysx_presets.py @@ -3,7 +3,7 @@ # # SPDX-License-Identifier: BSD-3-Clause -"""Tests for DexSuite Kuka Allegro OVPhysX object preset compatibility.""" +"""Tests for Lift Kuka Allegro OVPhysX object preset compatibility.""" import sys diff --git a/source/isaaclab_tasks/test/core/test_lift_package_structure.py b/source/isaaclab_tasks/test/core/test_lift_package_structure.py new file mode 100644 index 000000000000..1512ac58ecd5 --- /dev/null +++ b/source/isaaclab_tasks/test/core/test_lift_package_structure.py @@ -0,0 +1,52 @@ +# Copyright (c) 2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md). +# All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause + +"""Architecture gates for the unified core Lift task package.""" + +from pathlib import Path + +_TASKS_PACKAGE = Path(__file__).parents[2] / "isaaclab_tasks" +_LIFT_PACKAGE = _TASKS_PACKAGE / "core" / "lift" + +_REQUIRED_DEXTEROUS_LIFT_FILES = { + "adr_curriculum.py", + "lift_env_cfg.py", + "config/franka/franka_env_cfg.py", + "config/kuka_allegro/agents/models.py", + "config/kuka_allegro/camera_cfg.py", + "config/kuka_allegro/kuka_allegro_camera_env_cfg.py", + "config/kuka_allegro/kuka_allegro_env_cfg.py", + "mdp/commands/pose_commands.py", + "mdp/commands/pose_commands_cfg.py", + "mdp/curriculums.py", + "mdp/events.py", + "mdp/events_cfg.py", + "mdp/observations.py", + "mdp/rewards.py", + "mdp/terminations.py", + "mdp/utils.py", +} + + +def test_lift_owns_the_complete_dexterous_task_tree() -> None: + """The unified package must own every module needed by current dexterous training.""" + actual_files = {path.relative_to(_LIFT_PACKAGE).as_posix() for path in _LIFT_PACKAGE.rglob("*.py")} + + assert actual_files >= _REQUIRED_DEXTEROUS_LIFT_FILES + + +def test_dexsuite_package_and_dependencies_are_absent() -> None: + """DexSuite must not survive as a package, alias, or dependency of core Lift.""" + assert not (_TASKS_PACKAGE / "core" / "dexsuite").exists() + + offenders = [] + for path in _LIFT_PACKAGE.rglob("*"): + if path.suffix not in {".py", ".pyi"}: + continue + source = path.read_text(encoding="utf-8") + if "dexsuite" in path.name.casefold() or "dexsuite" in source.casefold(): + offenders.append(path.relative_to(_TASKS_PACKAGE).as_posix()) + + assert offenders == [] diff --git a/source/isaaclab_tasks/test/core/test_rendering_dexsuite_kuka_homo.py b/source/isaaclab_tasks/test/core/test_rendering_lift_kuka_hetero.py similarity index 74% rename from source/isaaclab_tasks/test/core/test_rendering_dexsuite_kuka_homo.py rename to source/isaaclab_tasks/test/core/test_rendering_lift_kuka_hetero.py index 07b28c0639e8..db0a022036cd 100644 --- a/source/isaaclab_tasks/test/core/test_rendering_dexsuite_kuka_homo.py +++ b/source/isaaclab_tasks/test/core/test_rendering_lift_kuka_hetero.py @@ -3,7 +3,7 @@ # # SPDX-License-Identifier: BSD-3-Clause -"""Rendering correctness tests for Dexsuite KukaAllegro Lift backend combinations.""" +"""Rendering correctness tests for Lift KukaAllegro Lift backend combinations.""" # Launch Isaac Sim Simulator first for kit-based combinations. from isaaclab.app import AppLauncher @@ -19,7 +19,7 @@ make_attach_comparison_properties_fixture, make_determinism_fixture, make_generate_html_report_fixture, - rendering_test_dexsuite_kuka, + rendering_test_lift_kuka, ) pytestmark = pytest.mark.isaacsim_ci @@ -32,6 +32,6 @@ @pytest.mark.parametrize("physics_backend,renderer,data_type", PHYSICS_RENDERER_AOV_COMBINATIONS) -def test_rendering_dexsuite_kuka_homo(physics_backend, renderer, data_type): - """Test dexsuite kuka allegro lift environment rendering correctness.""" - rendering_test_dexsuite_kuka(physics_backend, renderer, data_type, True, _COMPARISON_SCORES) +def test_rendering_lift_kuka_hetero(physics_backend, renderer, data_type): + """Test Lift KukaAllegro lift environment rendering correctness.""" + rendering_test_lift_kuka(physics_backend, renderer, data_type, False, _COMPARISON_SCORES) diff --git a/source/isaaclab_tasks/test/core/test_rendering_dexsuite_kuka_hetero_kitless.py b/source/isaaclab_tasks/test/core/test_rendering_lift_kuka_hetero_kitless.py similarity index 68% rename from source/isaaclab_tasks/test/core/test_rendering_dexsuite_kuka_hetero_kitless.py rename to source/isaaclab_tasks/test/core/test_rendering_lift_kuka_hetero_kitless.py index 0e1a9addbfdc..8140747fe632 100644 --- a/source/isaaclab_tasks/test/core/test_rendering_dexsuite_kuka_hetero_kitless.py +++ b/source/isaaclab_tasks/test/core/test_rendering_lift_kuka_hetero_kitless.py @@ -3,7 +3,7 @@ # # SPDX-License-Identifier: BSD-3-Clause -"""Kit-less rendering correctness tests for Dexsuite KukaAllegro Lift backend combinations.""" +"""Kit-less rendering correctness tests for Lift KukaAllegro Lift backend combinations.""" from pathlib import Path @@ -12,14 +12,14 @@ make_attach_comparison_properties_fixture, make_determinism_fixture, make_generate_html_report_fixture, - make_kitless_rendering_params_dexsuite, + make_kitless_rendering_params_lift, make_require_ovlibs_install_fixture, - rendering_test_dexsuite_kuka, + rendering_test_lift_kuka, ) pytestmark = pytest.mark.isaacsim_ci -_RENDERING_PARAMS = make_kitless_rendering_params_dexsuite() +_RENDERING_PARAMS = make_kitless_rendering_params_lift() _COMPARISON_SCORES: list[dict] = [] _determinism_fixture = make_determinism_fixture() @@ -31,10 +31,10 @@ @pytest.mark.parametrize( "ovstage_variant,physics_backend,renderer,data_type", _RENDERING_PARAMS, indirect=["ovstage_variant"] ) -def test_rendering_dexsuite_kuka_hetero_kitless(ovstage_variant, physics_backend, renderer, data_type): - """Camera output must match golden images (Dexsuite KukaAllegro Lift, single camera).""" +def test_rendering_lift_kuka_hetero_kitless(ovstage_variant, physics_backend, renderer, data_type): + """Camera output must match golden images (Lift KukaAllegro Lift, single camera).""" if physics_backend == "ovphysx": pytest.skip( "The OVPhysX preset selects the homogeneous cube because heterogeneous multi-asset scenes are unsupported." ) - rendering_test_dexsuite_kuka(physics_backend, renderer, data_type, False, _COMPARISON_SCORES) + rendering_test_lift_kuka(physics_backend, renderer, data_type, False, _COMPARISON_SCORES) diff --git a/source/isaaclab_tasks/test/core/test_rendering_dexsuite_kuka_hetero.py b/source/isaaclab_tasks/test/core/test_rendering_lift_kuka_homo.py similarity index 74% rename from source/isaaclab_tasks/test/core/test_rendering_dexsuite_kuka_hetero.py rename to source/isaaclab_tasks/test/core/test_rendering_lift_kuka_homo.py index 815d7d8e58ed..32d21d55717d 100644 --- a/source/isaaclab_tasks/test/core/test_rendering_dexsuite_kuka_hetero.py +++ b/source/isaaclab_tasks/test/core/test_rendering_lift_kuka_homo.py @@ -3,7 +3,7 @@ # # SPDX-License-Identifier: BSD-3-Clause -"""Rendering correctness tests for Dexsuite KukaAllegro Lift backend combinations.""" +"""Rendering correctness tests for Lift KukaAllegro Lift backend combinations.""" # Launch Isaac Sim Simulator first for kit-based combinations. from isaaclab.app import AppLauncher @@ -19,7 +19,7 @@ make_attach_comparison_properties_fixture, make_determinism_fixture, make_generate_html_report_fixture, - rendering_test_dexsuite_kuka, + rendering_test_lift_kuka, ) pytestmark = pytest.mark.isaacsim_ci @@ -32,6 +32,6 @@ @pytest.mark.parametrize("physics_backend,renderer,data_type", PHYSICS_RENDERER_AOV_COMBINATIONS) -def test_rendering_dexsuite_kuka_hetero(physics_backend, renderer, data_type): - """Test dexsuite kuka allegro lift environment rendering correctness.""" - rendering_test_dexsuite_kuka(physics_backend, renderer, data_type, False, _COMPARISON_SCORES) +def test_rendering_lift_kuka_homo(physics_backend, renderer, data_type): + """Test Lift KukaAllegro lift environment rendering correctness.""" + rendering_test_lift_kuka(physics_backend, renderer, data_type, True, _COMPARISON_SCORES) diff --git a/source/isaaclab_tasks/test/core/test_rendering_dexsuite_kuka_homo_kitless.py b/source/isaaclab_tasks/test/core/test_rendering_lift_kuka_homo_kitless.py similarity index 65% rename from source/isaaclab_tasks/test/core/test_rendering_dexsuite_kuka_homo_kitless.py rename to source/isaaclab_tasks/test/core/test_rendering_lift_kuka_homo_kitless.py index 5f6b8f7524a5..6064e8a6b31c 100644 --- a/source/isaaclab_tasks/test/core/test_rendering_dexsuite_kuka_homo_kitless.py +++ b/source/isaaclab_tasks/test/core/test_rendering_lift_kuka_homo_kitless.py @@ -3,7 +3,7 @@ # # SPDX-License-Identifier: BSD-3-Clause -"""Kit-less rendering correctness tests for Dexsuite KukaAllegro Lift backend combinations.""" +"""Kit-less rendering correctness tests for Lift KukaAllegro Lift backend combinations.""" from pathlib import Path @@ -12,14 +12,14 @@ make_attach_comparison_properties_fixture, make_determinism_fixture, make_generate_html_report_fixture, - make_kitless_rendering_params_dexsuite, + make_kitless_rendering_params_lift, make_require_ovlibs_install_fixture, - rendering_test_dexsuite_kuka, + rendering_test_lift_kuka, ) pytestmark = [pytest.mark.isaacsim_ci, pytest.mark.arm_ci] -_RENDERING_PARAMS = make_kitless_rendering_params_dexsuite() +_RENDERING_PARAMS = make_kitless_rendering_params_lift() _COMPARISON_SCORES: list[dict] = [] _determinism_fixture = make_determinism_fixture() @@ -31,6 +31,6 @@ @pytest.mark.parametrize( "ovstage_variant,physics_backend,renderer,data_type", _RENDERING_PARAMS, indirect=["ovstage_variant"] ) -def test_rendering_dexsuite_kuka_homo_kitless(ovstage_variant, physics_backend, renderer, data_type): - """Camera output must match golden images (Dexsuite KukaAllegro Lift, single camera).""" - rendering_test_dexsuite_kuka(physics_backend, renderer, data_type, True, _COMPARISON_SCORES) +def test_rendering_lift_kuka_homo_kitless(ovstage_variant, physics_backend, renderer, data_type): + """Camera output must match golden images (Lift KukaAllegro Lift, single camera).""" + rendering_test_lift_kuka(physics_backend, renderer, data_type, True, _COMPARISON_SCORES) diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-isaacsim_rtx_renderer-albedo.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-isaacsim_rtx_renderer-albedo.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-isaacsim_rtx_renderer-albedo.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-isaacsim_rtx_renderer-albedo.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-isaacsim_rtx_renderer-depth.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-isaacsim_rtx_renderer-depth.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-isaacsim_rtx_renderer-depth.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-isaacsim_rtx_renderer-depth.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-isaacsim_rtx_renderer-distance_to_camera.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-isaacsim_rtx_renderer-distance_to_camera.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-isaacsim_rtx_renderer-distance_to_camera.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-isaacsim_rtx_renderer-distance_to_camera.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-isaacsim_rtx_renderer-distance_to_image_plane.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-isaacsim_rtx_renderer-distance_to_image_plane.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-isaacsim_rtx_renderer-distance_to_image_plane.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-isaacsim_rtx_renderer-distance_to_image_plane.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-isaacsim_rtx_renderer-instance_id_segmentation_fast.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-isaacsim_rtx_renderer-instance_id_segmentation_fast.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-isaacsim_rtx_renderer-instance_id_segmentation_fast.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-isaacsim_rtx_renderer-instance_id_segmentation_fast.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-isaacsim_rtx_renderer-instance_segmentation.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-isaacsim_rtx_renderer-instance_segmentation.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-isaacsim_rtx_renderer-instance_segmentation.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-isaacsim_rtx_renderer-instance_segmentation.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-isaacsim_rtx_renderer-normals.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-isaacsim_rtx_renderer-normals.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-isaacsim_rtx_renderer-normals.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-isaacsim_rtx_renderer-normals.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-isaacsim_rtx_renderer-rgb.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-isaacsim_rtx_renderer-rgb.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-isaacsim_rtx_renderer-rgb.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-isaacsim_rtx_renderer-rgb.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-isaacsim_rtx_renderer-rgba.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-isaacsim_rtx_renderer-rgba.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-isaacsim_rtx_renderer-rgba.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-isaacsim_rtx_renderer-rgba.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-isaacsim_rtx_renderer-semantic_segmentation.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-isaacsim_rtx_renderer-semantic_segmentation.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-isaacsim_rtx_renderer-semantic_segmentation.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-isaacsim_rtx_renderer-semantic_segmentation.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-isaacsim_rtx_renderer-simple_shading_constant_diffuse.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-isaacsim_rtx_renderer-simple_shading_constant_diffuse.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-isaacsim_rtx_renderer-simple_shading_constant_diffuse.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-isaacsim_rtx_renderer-simple_shading_constant_diffuse.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-isaacsim_rtx_renderer-simple_shading_diffuse_mdl.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-isaacsim_rtx_renderer-simple_shading_diffuse_mdl.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-isaacsim_rtx_renderer-simple_shading_diffuse_mdl.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-isaacsim_rtx_renderer-simple_shading_diffuse_mdl.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-isaacsim_rtx_renderer-simple_shading_full_mdl.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-isaacsim_rtx_renderer-simple_shading_full_mdl.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-isaacsim_rtx_renderer-simple_shading_full_mdl.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-isaacsim_rtx_renderer-simple_shading_full_mdl.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-newton_renderer-depth.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-newton_renderer-depth.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-newton_renderer-depth.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-newton_renderer-depth.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-newton_renderer-distance_to_camera.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-newton_renderer-distance_to_camera.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-newton_renderer-distance_to_camera.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-newton_renderer-distance_to_camera.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-newton_renderer-distance_to_image_plane.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-newton_renderer-distance_to_image_plane.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-newton_renderer-distance_to_image_plane.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-newton_renderer-distance_to_image_plane.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-newton_renderer-instance_segmentation.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-newton_renderer-instance_segmentation.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-newton_renderer-instance_segmentation.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-newton_renderer-instance_segmentation.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-newton_renderer-normals.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-newton_renderer-normals.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-newton_renderer-normals.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-newton_renderer-normals.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-newton_renderer-rgb.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-newton_renderer-rgb.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-newton_renderer-rgb.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-newton_renderer-rgb.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-newton_renderer-rgba.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-newton_renderer-rgba.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-newton_renderer-rgba.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-newton_renderer-rgba.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-newton_renderer-semantic_segmentation.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-newton_renderer-semantic_segmentation.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-newton_renderer-semantic_segmentation.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-newton_renderer-semantic_segmentation.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-ovrtx_renderer-albedo.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-ovrtx_renderer-albedo.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-ovrtx_renderer-albedo.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-ovrtx_renderer-albedo.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-ovrtx_renderer-depth.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-ovrtx_renderer-depth.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-ovrtx_renderer-depth.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-ovrtx_renderer-depth.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-ovrtx_renderer-distance_to_camera.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-ovrtx_renderer-distance_to_camera.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-ovrtx_renderer-distance_to_camera.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-ovrtx_renderer-distance_to_camera.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-ovrtx_renderer-distance_to_image_plane.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-ovrtx_renderer-distance_to_image_plane.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-ovrtx_renderer-distance_to_image_plane.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-ovrtx_renderer-distance_to_image_plane.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-ovrtx_renderer-instance_segmentation.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-ovrtx_renderer-instance_segmentation.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-ovrtx_renderer-instance_segmentation.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-ovrtx_renderer-instance_segmentation.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-ovrtx_renderer-normals.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-ovrtx_renderer-normals.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-ovrtx_renderer-normals.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-ovrtx_renderer-normals.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-ovrtx_renderer-rgb.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-ovrtx_renderer-rgb.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-ovrtx_renderer-rgb.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-ovrtx_renderer-rgb.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-ovrtx_renderer-rgba.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-ovrtx_renderer-rgba.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-ovrtx_renderer-rgba.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-ovrtx_renderer-rgba.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-ovrtx_renderer-semantic_segmentation.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-ovrtx_renderer-semantic_segmentation.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-ovrtx_renderer-semantic_segmentation.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-ovrtx_renderer-semantic_segmentation.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-ovrtx_renderer-simple_shading_constant_diffuse.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-ovrtx_renderer-simple_shading_constant_diffuse.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-ovrtx_renderer-simple_shading_constant_diffuse.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-ovrtx_renderer-simple_shading_constant_diffuse.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-ovrtx_renderer-simple_shading_diffuse_mdl.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-ovrtx_renderer-simple_shading_diffuse_mdl.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-ovrtx_renderer-simple_shading_diffuse_mdl.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-ovrtx_renderer-simple_shading_diffuse_mdl.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-ovrtx_renderer-simple_shading_full_mdl.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-ovrtx_renderer-simple_shading_full_mdl.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/newton-ovrtx_renderer-simple_shading_full_mdl.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/newton-ovrtx_renderer-simple_shading_full_mdl.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-isaacsim_rtx_renderer-albedo.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-isaacsim_rtx_renderer-albedo.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-isaacsim_rtx_renderer-albedo.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-isaacsim_rtx_renderer-albedo.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-isaacsim_rtx_renderer-depth.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-isaacsim_rtx_renderer-depth.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-isaacsim_rtx_renderer-depth.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-isaacsim_rtx_renderer-depth.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-isaacsim_rtx_renderer-distance_to_camera.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-isaacsim_rtx_renderer-distance_to_camera.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-isaacsim_rtx_renderer-distance_to_camera.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-isaacsim_rtx_renderer-distance_to_camera.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-isaacsim_rtx_renderer-distance_to_image_plane.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-isaacsim_rtx_renderer-distance_to_image_plane.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-isaacsim_rtx_renderer-distance_to_image_plane.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-isaacsim_rtx_renderer-distance_to_image_plane.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-isaacsim_rtx_renderer-instance_id_segmentation_fast.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-isaacsim_rtx_renderer-instance_id_segmentation_fast.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-isaacsim_rtx_renderer-instance_id_segmentation_fast.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-isaacsim_rtx_renderer-instance_id_segmentation_fast.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-isaacsim_rtx_renderer-instance_segmentation.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-isaacsim_rtx_renderer-instance_segmentation.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-isaacsim_rtx_renderer-instance_segmentation.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-isaacsim_rtx_renderer-instance_segmentation.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-isaacsim_rtx_renderer-motion_vectors.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-isaacsim_rtx_renderer-motion_vectors.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-isaacsim_rtx_renderer-motion_vectors.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-isaacsim_rtx_renderer-motion_vectors.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-isaacsim_rtx_renderer-normals.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-isaacsim_rtx_renderer-normals.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-isaacsim_rtx_renderer-normals.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-isaacsim_rtx_renderer-normals.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-isaacsim_rtx_renderer-rgb.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-isaacsim_rtx_renderer-rgb.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-isaacsim_rtx_renderer-rgb.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-isaacsim_rtx_renderer-rgb.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-isaacsim_rtx_renderer-rgba.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-isaacsim_rtx_renderer-rgba.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-isaacsim_rtx_renderer-rgba.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-isaacsim_rtx_renderer-rgba.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-isaacsim_rtx_renderer-semantic_segmentation.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-isaacsim_rtx_renderer-semantic_segmentation.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-isaacsim_rtx_renderer-semantic_segmentation.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-isaacsim_rtx_renderer-semantic_segmentation.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-isaacsim_rtx_renderer-simple_shading_constant_diffuse.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-isaacsim_rtx_renderer-simple_shading_constant_diffuse.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-isaacsim_rtx_renderer-simple_shading_constant_diffuse.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-isaacsim_rtx_renderer-simple_shading_constant_diffuse.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-isaacsim_rtx_renderer-simple_shading_diffuse_mdl.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-isaacsim_rtx_renderer-simple_shading_diffuse_mdl.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-isaacsim_rtx_renderer-simple_shading_diffuse_mdl.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-isaacsim_rtx_renderer-simple_shading_diffuse_mdl.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-isaacsim_rtx_renderer-simple_shading_full_mdl.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-isaacsim_rtx_renderer-simple_shading_full_mdl.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-isaacsim_rtx_renderer-simple_shading_full_mdl.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-isaacsim_rtx_renderer-simple_shading_full_mdl.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-newton_renderer-depth.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-newton_renderer-depth.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-newton_renderer-depth.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-newton_renderer-depth.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-newton_renderer-distance_to_camera.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-newton_renderer-distance_to_camera.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-newton_renderer-distance_to_camera.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-newton_renderer-distance_to_camera.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-newton_renderer-distance_to_image_plane.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-newton_renderer-distance_to_image_plane.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-newton_renderer-distance_to_image_plane.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-newton_renderer-distance_to_image_plane.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-newton_renderer-instance_segmentation.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-newton_renderer-instance_segmentation.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-newton_renderer-instance_segmentation.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-newton_renderer-instance_segmentation.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-newton_renderer-normals.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-newton_renderer-normals.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-newton_renderer-normals.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-newton_renderer-normals.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-newton_renderer-rgb.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-newton_renderer-rgb.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-newton_renderer-rgb.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-newton_renderer-rgb.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-newton_renderer-rgba.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-newton_renderer-rgba.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-newton_renderer-rgba.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-newton_renderer-rgba.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-newton_renderer-semantic_segmentation.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-newton_renderer-semantic_segmentation.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_hetero/physx-newton_renderer-semantic_segmentation.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_hetero/physx-newton_renderer-semantic_segmentation.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-isaacsim_rtx_renderer-albedo.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-isaacsim_rtx_renderer-albedo.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-isaacsim_rtx_renderer-albedo.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-isaacsim_rtx_renderer-albedo.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-isaacsim_rtx_renderer-depth.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-isaacsim_rtx_renderer-depth.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-isaacsim_rtx_renderer-depth.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-isaacsim_rtx_renderer-depth.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-isaacsim_rtx_renderer-distance_to_camera.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-isaacsim_rtx_renderer-distance_to_camera.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-isaacsim_rtx_renderer-distance_to_camera.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-isaacsim_rtx_renderer-distance_to_camera.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-isaacsim_rtx_renderer-distance_to_image_plane.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-isaacsim_rtx_renderer-distance_to_image_plane.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-isaacsim_rtx_renderer-distance_to_image_plane.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-isaacsim_rtx_renderer-distance_to_image_plane.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-isaacsim_rtx_renderer-instance_id_segmentation_fast.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-isaacsim_rtx_renderer-instance_id_segmentation_fast.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-isaacsim_rtx_renderer-instance_id_segmentation_fast.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-isaacsim_rtx_renderer-instance_id_segmentation_fast.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-isaacsim_rtx_renderer-instance_segmentation.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-isaacsim_rtx_renderer-instance_segmentation.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-isaacsim_rtx_renderer-instance_segmentation.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-isaacsim_rtx_renderer-instance_segmentation.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-isaacsim_rtx_renderer-normals.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-isaacsim_rtx_renderer-normals.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-isaacsim_rtx_renderer-normals.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-isaacsim_rtx_renderer-normals.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-isaacsim_rtx_renderer-rgb.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-isaacsim_rtx_renderer-rgb.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-isaacsim_rtx_renderer-rgb.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-isaacsim_rtx_renderer-rgb.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-isaacsim_rtx_renderer-rgba.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-isaacsim_rtx_renderer-rgba.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-isaacsim_rtx_renderer-rgba.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-isaacsim_rtx_renderer-rgba.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-isaacsim_rtx_renderer-semantic_segmentation.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-isaacsim_rtx_renderer-semantic_segmentation.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-isaacsim_rtx_renderer-semantic_segmentation.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-isaacsim_rtx_renderer-semantic_segmentation.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-isaacsim_rtx_renderer-simple_shading_constant_diffuse.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-isaacsim_rtx_renderer-simple_shading_constant_diffuse.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-isaacsim_rtx_renderer-simple_shading_constant_diffuse.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-isaacsim_rtx_renderer-simple_shading_constant_diffuse.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-isaacsim_rtx_renderer-simple_shading_diffuse_mdl.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-isaacsim_rtx_renderer-simple_shading_diffuse_mdl.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-isaacsim_rtx_renderer-simple_shading_diffuse_mdl.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-isaacsim_rtx_renderer-simple_shading_diffuse_mdl.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-isaacsim_rtx_renderer-simple_shading_full_mdl.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-isaacsim_rtx_renderer-simple_shading_full_mdl.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-isaacsim_rtx_renderer-simple_shading_full_mdl.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-isaacsim_rtx_renderer-simple_shading_full_mdl.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-newton_renderer-depth.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-newton_renderer-depth.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-newton_renderer-depth.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-newton_renderer-depth.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-newton_renderer-distance_to_camera.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-newton_renderer-distance_to_camera.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-newton_renderer-distance_to_camera.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-newton_renderer-distance_to_camera.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-newton_renderer-distance_to_image_plane.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-newton_renderer-distance_to_image_plane.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-newton_renderer-distance_to_image_plane.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-newton_renderer-distance_to_image_plane.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-newton_renderer-instance_segmentation.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-newton_renderer-instance_segmentation.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-newton_renderer-instance_segmentation.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-newton_renderer-instance_segmentation.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-newton_renderer-normals.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-newton_renderer-normals.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-newton_renderer-normals.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-newton_renderer-normals.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-newton_renderer-rgb.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-newton_renderer-rgb.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-newton_renderer-rgb.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-newton_renderer-rgb.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-newton_renderer-rgba.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-newton_renderer-rgba.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-newton_renderer-rgba.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-newton_renderer-rgba.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-newton_renderer-semantic_segmentation.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-newton_renderer-semantic_segmentation.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-newton_renderer-semantic_segmentation.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-newton_renderer-semantic_segmentation.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-ovrtx_renderer-albedo.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-ovrtx_renderer-albedo.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-ovrtx_renderer-albedo.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-ovrtx_renderer-albedo.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-ovrtx_renderer-depth.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-ovrtx_renderer-depth.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-ovrtx_renderer-depth.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-ovrtx_renderer-depth.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-ovrtx_renderer-distance_to_camera.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-ovrtx_renderer-distance_to_camera.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-ovrtx_renderer-distance_to_camera.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-ovrtx_renderer-distance_to_camera.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-ovrtx_renderer-distance_to_image_plane.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-ovrtx_renderer-distance_to_image_plane.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-ovrtx_renderer-distance_to_image_plane.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-ovrtx_renderer-distance_to_image_plane.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-ovrtx_renderer-instance_segmentation.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-ovrtx_renderer-instance_segmentation.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-ovrtx_renderer-instance_segmentation.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-ovrtx_renderer-instance_segmentation.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-ovrtx_renderer-normals.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-ovrtx_renderer-normals.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-ovrtx_renderer-normals.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-ovrtx_renderer-normals.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-ovrtx_renderer-rgb.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-ovrtx_renderer-rgb.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-ovrtx_renderer-rgb.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-ovrtx_renderer-rgb.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-ovrtx_renderer-rgba.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-ovrtx_renderer-rgba.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-ovrtx_renderer-rgba.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-ovrtx_renderer-rgba.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-ovrtx_renderer-semantic_segmentation.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-ovrtx_renderer-semantic_segmentation.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-ovrtx_renderer-semantic_segmentation.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-ovrtx_renderer-semantic_segmentation.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-ovrtx_renderer-simple_shading_constant_diffuse.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-ovrtx_renderer-simple_shading_constant_diffuse.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-ovrtx_renderer-simple_shading_constant_diffuse.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-ovrtx_renderer-simple_shading_constant_diffuse.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-ovrtx_renderer-simple_shading_diffuse_mdl.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-ovrtx_renderer-simple_shading_diffuse_mdl.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-ovrtx_renderer-simple_shading_diffuse_mdl.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-ovrtx_renderer-simple_shading_diffuse_mdl.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-ovrtx_renderer-simple_shading_full_mdl.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-ovrtx_renderer-simple_shading_full_mdl.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/newton-ovrtx_renderer-simple_shading_full_mdl.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/newton-ovrtx_renderer-simple_shading_full_mdl.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-newton_renderer-depth.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-newton_renderer-depth.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-newton_renderer-depth.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-newton_renderer-depth.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-newton_renderer-distance_to_camera.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-newton_renderer-distance_to_camera.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-newton_renderer-distance_to_camera.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-newton_renderer-distance_to_camera.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-newton_renderer-distance_to_image_plane.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-newton_renderer-distance_to_image_plane.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-newton_renderer-distance_to_image_plane.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-newton_renderer-distance_to_image_plane.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-newton_renderer-instance_segmentation.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-newton_renderer-instance_segmentation.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-newton_renderer-instance_segmentation.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-newton_renderer-instance_segmentation.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-newton_renderer-normals.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-newton_renderer-normals.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-newton_renderer-normals.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-newton_renderer-normals.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-newton_renderer-rgb.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-newton_renderer-rgb.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-newton_renderer-rgb.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-newton_renderer-rgb.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-newton_renderer-rgba.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-newton_renderer-rgba.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-newton_renderer-rgba.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-newton_renderer-rgba.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-newton_renderer-semantic_segmentation.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-newton_renderer-semantic_segmentation.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-newton_renderer-semantic_segmentation.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-newton_renderer-semantic_segmentation.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-ovrtx_renderer-albedo.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-ovrtx_renderer-albedo.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-ovrtx_renderer-albedo.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-ovrtx_renderer-albedo.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-ovrtx_renderer-depth.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-ovrtx_renderer-depth.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-ovrtx_renderer-depth.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-ovrtx_renderer-depth.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-ovrtx_renderer-distance_to_camera.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-ovrtx_renderer-distance_to_camera.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-ovrtx_renderer-distance_to_camera.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-ovrtx_renderer-distance_to_camera.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-ovrtx_renderer-distance_to_image_plane.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-ovrtx_renderer-distance_to_image_plane.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-ovrtx_renderer-distance_to_image_plane.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-ovrtx_renderer-distance_to_image_plane.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-ovrtx_renderer-instance_segmentation.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-ovrtx_renderer-instance_segmentation.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-ovrtx_renderer-instance_segmentation.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-ovrtx_renderer-instance_segmentation.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-ovrtx_renderer-motion_vectors.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-ovrtx_renderer-motion_vectors.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-ovrtx_renderer-motion_vectors.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-ovrtx_renderer-motion_vectors.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-ovrtx_renderer-normals.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-ovrtx_renderer-normals.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-ovrtx_renderer-normals.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-ovrtx_renderer-normals.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-ovrtx_renderer-rgb.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-ovrtx_renderer-rgb.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-ovrtx_renderer-rgb.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-ovrtx_renderer-rgb.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-ovrtx_renderer-rgba.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-ovrtx_renderer-rgba.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-ovrtx_renderer-rgba.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-ovrtx_renderer-rgba.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-ovrtx_renderer-semantic_segmentation.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-ovrtx_renderer-semantic_segmentation.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-ovrtx_renderer-semantic_segmentation.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-ovrtx_renderer-semantic_segmentation.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-ovrtx_renderer-simple_shading_constant_diffuse.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-ovrtx_renderer-simple_shading_constant_diffuse.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-ovrtx_renderer-simple_shading_constant_diffuse.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-ovrtx_renderer-simple_shading_constant_diffuse.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-ovrtx_renderer-simple_shading_diffuse_mdl.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-ovrtx_renderer-simple_shading_diffuse_mdl.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-ovrtx_renderer-simple_shading_diffuse_mdl.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-ovrtx_renderer-simple_shading_diffuse_mdl.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-ovrtx_renderer-simple_shading_full_mdl.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-ovrtx_renderer-simple_shading_full_mdl.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/ovphysx-ovrtx_renderer-simple_shading_full_mdl.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/ovphysx-ovrtx_renderer-simple_shading_full_mdl.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-isaacsim_rtx_renderer-albedo.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-isaacsim_rtx_renderer-albedo.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-isaacsim_rtx_renderer-albedo.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-isaacsim_rtx_renderer-albedo.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-isaacsim_rtx_renderer-depth.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-isaacsim_rtx_renderer-depth.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-isaacsim_rtx_renderer-depth.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-isaacsim_rtx_renderer-depth.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-isaacsim_rtx_renderer-distance_to_camera.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-isaacsim_rtx_renderer-distance_to_camera.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-isaacsim_rtx_renderer-distance_to_camera.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-isaacsim_rtx_renderer-distance_to_camera.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-isaacsim_rtx_renderer-distance_to_image_plane.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-isaacsim_rtx_renderer-distance_to_image_plane.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-isaacsim_rtx_renderer-distance_to_image_plane.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-isaacsim_rtx_renderer-distance_to_image_plane.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-isaacsim_rtx_renderer-instance_id_segmentation_fast.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-isaacsim_rtx_renderer-instance_id_segmentation_fast.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-isaacsim_rtx_renderer-instance_id_segmentation_fast.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-isaacsim_rtx_renderer-instance_id_segmentation_fast.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-isaacsim_rtx_renderer-instance_segmentation.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-isaacsim_rtx_renderer-instance_segmentation.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-isaacsim_rtx_renderer-instance_segmentation.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-isaacsim_rtx_renderer-instance_segmentation.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-isaacsim_rtx_renderer-motion_vectors.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-isaacsim_rtx_renderer-motion_vectors.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-isaacsim_rtx_renderer-motion_vectors.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-isaacsim_rtx_renderer-motion_vectors.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-isaacsim_rtx_renderer-normals.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-isaacsim_rtx_renderer-normals.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-isaacsim_rtx_renderer-normals.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-isaacsim_rtx_renderer-normals.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-isaacsim_rtx_renderer-rgb.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-isaacsim_rtx_renderer-rgb.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-isaacsim_rtx_renderer-rgb.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-isaacsim_rtx_renderer-rgb.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-isaacsim_rtx_renderer-rgba.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-isaacsim_rtx_renderer-rgba.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-isaacsim_rtx_renderer-rgba.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-isaacsim_rtx_renderer-rgba.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-isaacsim_rtx_renderer-semantic_segmentation.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-isaacsim_rtx_renderer-semantic_segmentation.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-isaacsim_rtx_renderer-semantic_segmentation.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-isaacsim_rtx_renderer-semantic_segmentation.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-isaacsim_rtx_renderer-simple_shading_constant_diffuse.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-isaacsim_rtx_renderer-simple_shading_constant_diffuse.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-isaacsim_rtx_renderer-simple_shading_constant_diffuse.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-isaacsim_rtx_renderer-simple_shading_constant_diffuse.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-isaacsim_rtx_renderer-simple_shading_diffuse_mdl.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-isaacsim_rtx_renderer-simple_shading_diffuse_mdl.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-isaacsim_rtx_renderer-simple_shading_diffuse_mdl.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-isaacsim_rtx_renderer-simple_shading_diffuse_mdl.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-isaacsim_rtx_renderer-simple_shading_full_mdl.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-isaacsim_rtx_renderer-simple_shading_full_mdl.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-isaacsim_rtx_renderer-simple_shading_full_mdl.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-isaacsim_rtx_renderer-simple_shading_full_mdl.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-newton_renderer-depth.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-newton_renderer-depth.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-newton_renderer-depth.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-newton_renderer-depth.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-newton_renderer-distance_to_camera.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-newton_renderer-distance_to_camera.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-newton_renderer-distance_to_camera.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-newton_renderer-distance_to_camera.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-newton_renderer-distance_to_image_plane.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-newton_renderer-distance_to_image_plane.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-newton_renderer-distance_to_image_plane.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-newton_renderer-distance_to_image_plane.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-newton_renderer-instance_segmentation.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-newton_renderer-instance_segmentation.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-newton_renderer-instance_segmentation.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-newton_renderer-instance_segmentation.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-newton_renderer-normals.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-newton_renderer-normals.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-newton_renderer-normals.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-newton_renderer-normals.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-newton_renderer-rgb.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-newton_renderer-rgb.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-newton_renderer-rgb.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-newton_renderer-rgb.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-newton_renderer-rgba.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-newton_renderer-rgba.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-newton_renderer-rgba.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-newton_renderer-rgba.png diff --git a/source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-newton_renderer-semantic_segmentation.png b/source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-newton_renderer-semantic_segmentation.png similarity index 100% rename from source/isaaclab_tasks/test/golden_images/dexsuite_kuka_homo/physx-newton_renderer-semantic_segmentation.png rename to source/isaaclab_tasks/test/golden_images/lift_kuka_homo/physx-newton_renderer-semantic_segmentation.png diff --git a/source/isaaclab_tasks/test/rendering_test_utils.py b/source/isaaclab_tasks/test/rendering_test_utils.py index b86b10d7e12a..8ee5ec85b54a 100644 --- a/source/isaaclab_tasks/test/rendering_test_utils.py +++ b/source/isaaclab_tasks/test/rendering_test_utils.py @@ -54,8 +54,8 @@ # headroom above that without masking real regressions, which the SSIM gate still catches. "shadow_hand": 5.0, # Texture aliasing artifacts on the ground (NVBUG#6116767) - "dexsuite_kuka_homo": 8.0, - "dexsuite_kuka_hetero": 8.0, + "lift_kuka_homo": 8.0, + "lift_kuka_hetero": 8.0, } # Allow OVRTX Cartpole RGB/RGBA variation tracked by NVBUG#6152566; the SSIM gate remains enabled. @@ -71,8 +71,8 @@ # (not globally) to keep the strict gate active everywhere it already passes. _SSIM_THRESHOLD_BY_ENV_NAME = { # Texture aliasing artifacts on the ground (NVBUG#6116767) - "dexsuite_kuka_homo": 0.95, - "dexsuite_kuka_hetero": 0.95, + "lift_kuka_homo": 0.95, + "lift_kuka_hetero": 0.95, } # Data types for which the SSIM gate is not enforced. SSIM assumes natural-image statistics and is unreliable on @@ -159,7 +159,7 @@ ) _OVRTX_TEXTURE_READINESS_XFAIL_REASON = "OVRTX 0.4 may return before textured materials are ready (NVBUG#6505191)." _KITLESS_STAGE_VARIANTS = ("legacy", "ovstage") -_DEXSUITE_RENDERER_CRASH_SKIP_REASON = "Dexsuite kitless OVRTX rendering may crash or time out (NVBUG#6524987)." +_LIFT_RENDERER_CRASH_SKIP_REASON = "Lift kitless OVRTX rendering may crash or time out (NVBUG#6524987)." _NEWTON_WARP_MISSING_TABLE_XFAIL_REASON = "Missing table in Newton Warp renderer (OMPE-103086)." _OVRTX_CLOTH_MOTION_XFAIL_REASON = "Missing cloth in OVRTX 0.4 motion vectors (NVBUG#6489754)." @@ -316,12 +316,12 @@ def _make_sensor_data_type_params( ) -def make_kitless_rendering_params_dexsuite() -> list[pytest.param]: - """Create kitless Dexsuite parameters with known native-crash cases skipped.""" +def make_kitless_rendering_params_lift() -> list[pytest.param]: + """Create kitless Lift parameters with known native-crash cases skipped.""" return make_skip_rendering_params( make_kitless_rendering_params(KITLESS_PHYSICS_RENDERER_AOV_COMBINATIONS), { - (variant, "newton", "ovrtx_renderer", data_type): _DEXSUITE_RENDERER_CRASH_SKIP_REASON + (variant, "newton", "ovrtx_renderer", data_type): _LIFT_RENDERER_CRASH_SKIP_REASON for variant in _KITLESS_STAGE_VARIANTS for data_type in ("simple_shading_diffuse_mdl", "simple_shading_full_mdl") }, @@ -1616,7 +1616,7 @@ class _CartpoleCameraTestEnvCfg(CartpoleCameraEnvCfg): env = None -def rendering_test_dexsuite_kuka( +def rendering_test_lift_kuka( physics_backend: str, renderer: str, data_type: str, @@ -1629,22 +1629,22 @@ def rendering_test_dexsuite_kuka( from isaaclab.sensors import CameraCfg from isaaclab.utils.configclass import configclass - from isaaclab_tasks.core.dexsuite.config.kuka_allegro.camera_cfg import ( + from isaaclab_tasks.core.lift.config.kuka_allegro.camera_cfg import ( BASE_CAMERA_CFG, BaseTiledCameraCfg, SingleCameraObservationsCfg, ) - from isaaclab_tasks.core.dexsuite.config.kuka_allegro.dexsuite_kuka_allegro_camera_env_cfg import ( + from isaaclab_tasks.core.lift.config.kuka_allegro.kuka_allegro_camera_env_cfg import ( _SCENE_KWARGS, - DexsuiteKukaAllegroLiftCameraEnvCfg, + KukaAllegroLiftCameraEnvCfg, SingleCameraSceneCfg, ) - from isaaclab_tasks.core.dexsuite.config.kuka_allegro.dexsuite_kuka_allegro_env_cfg import ( - DexsuiteKukaAllegroLiftEnvCfg, + from isaaclab_tasks.core.lift.config.kuka_allegro.kuka_allegro_env_cfg import ( + KukaAllegroLiftEnvCfg, ) @configclass - class _DexsuiteBaseTiledCameraTestCfg(BaseTiledCameraCfg): + class _LiftBaseTiledCameraTestCfg(BaseTiledCameraCfg): distance_to_camera64 = BASE_CAMERA_CFG.replace(data_types=["distance_to_camera"], width=64, height=64) distance_to_camera128 = BASE_CAMERA_CFG.replace(data_types=["distance_to_camera"], width=128, height=128) distance_to_camera256 = BASE_CAMERA_CFG.replace(data_types=["distance_to_camera"], width=256, height=256) @@ -1675,13 +1675,13 @@ class _DexsuiteBaseTiledCameraTestCfg(BaseTiledCameraCfg): motion_vectors256 = BASE_CAMERA_CFG.replace(data_types=["motion_vectors"], width=256, height=256) @configclass - class _DexsuiteSingleCameraTestSceneCfg(SingleCameraSceneCfg): - base_camera: CameraCfg = _DexsuiteBaseTiledCameraTestCfg() + class _LiftSingleCameraTestSceneCfg(SingleCameraSceneCfg): + base_camera: CameraCfg = _LiftBaseTiledCameraTestCfg() @configclass - class _DexsuiteKukaAllegroLiftCameraTestEnvCfg(DexsuiteKukaAllegroLiftCameraEnvCfg): - single_camera = DexsuiteKukaAllegroLiftEnvCfg( - scene=_DexsuiteSingleCameraTestSceneCfg(**_SCENE_KWARGS), + class _KukaAllegroLiftCameraTestEnvCfg(KukaAllegroLiftCameraEnvCfg): + single_camera = KukaAllegroLiftEnvCfg( + scene=_LiftSingleCameraTestSceneCfg(**_SCENE_KWARGS), observations=SingleCameraObservationsCfg(), ) default = single_camera @@ -1693,7 +1693,7 @@ class _DexsuiteKukaAllegroLiftCameraTestEnvCfg(DexsuiteKukaAllegroLiftCameraEnvC if setup_homogeneous_envs: override_arg += ",cube" - env_cfg = _DexsuiteKukaAllegroLiftCameraTestEnvCfg() + env_cfg = _KukaAllegroLiftCameraTestEnvCfg() env_cfg = _apply_overrides_to_env_cfg(env_cfg, [override_arg]) env_cfg.scene.num_envs = 4 @@ -1718,7 +1718,7 @@ class _DexsuiteKukaAllegroLiftCameraTestEnvCfg(DexsuiteKukaAllegroLiftCameraEnvC for marker_cfg in env_cfg.commands.object_pose.success_visualizer_cfg.markers.values(): marker_cfg.visible = False - test_name = f"dexsuite_kuka_{'homo' if setup_homogeneous_envs else 'hetero'}" + test_name = f"lift_kuka_{'homo' if setup_homogeneous_envs else 'hetero'}" env = None diff --git a/source/isaaclab_tasks/test/test_parametrization_helpers.py b/source/isaaclab_tasks/test/test_parametrization_helpers.py index 901d3e5f1bd1..aa20c53e9767 100644 --- a/source/isaaclab_tasks/test/test_parametrization_helpers.py +++ b/source/isaaclab_tasks/test/test_parametrization_helpers.py @@ -14,8 +14,8 @@ attach_comparison_properties, generate_html_report, make_kitless_rendering_params, - make_kitless_rendering_params_dexsuite, make_kitless_rendering_params_franka, + make_kitless_rendering_params_lift, make_skip_rendering_params, make_xfail_rendering_params, ) @@ -94,9 +94,9 @@ def test_make_skip_rendering_params_overrides_xfail_and_flaky_marks() -> None: assert marked[0].marks[0].kwargs["reason"] == "Native renderer crash." -def test_dexsuite_factory_applies_shared_native_crash_policy() -> None: - """Both stage variants should share the ticketed Dexsuite MDL skips.""" - params = {param.id: param for param in make_kitless_rendering_params_dexsuite()} +def test_lift_factory_applies_shared_native_crash_policy() -> None: + """Both stage variants should share the ticketed Lift MDL skips.""" + params = {param.id: param for param in make_kitless_rendering_params_lift()} for variant in ("legacy", "ovstage"): for data_type in ("simple_shading_diffuse_mdl", "simple_shading_full_mdl"): diff --git a/tools/test_settings.py b/tools/test_settings.py index 0d9ba8f7e8ac..540a76ad3b39 100644 --- a/tools/test_settings.py +++ b/tools/test_settings.py @@ -72,7 +72,7 @@ # Every kitless rendering file runs each AOV twice (the ``ovstage_variant`` fixture covers the # legacy and ovstage OVRTX code paths). At 76 cases the Kuka Allegro scene overruns the default # budget; the remaining kitless files still fit but have little headroom. - "test_rendering_dexsuite_kuka_homo_kitless.py": 2000, + "test_rendering_lift_kuka_homo_kitless.py": 2000, # Budgets ~45s per AOV: one full RTX env is built and torn down per parametrized data type. # Bump this when renderer cases are added to _DEFAULT_SENSOR_DATA_TYPES in rendering_test_utils.py. "test_rendering_shadow_hand.py": 1500, @@ -149,7 +149,7 @@ "Isaac-Ant", "Isaac-Cartpole", # manipulation - "Isaac-Lift-Cube-Franka", + "Isaac-Lift-Franka", "Isaac-Open-Drawer-Franka", # dexterous manipulation "Isaac-Reorient-Cube-Allegro", From 5226284cdc01ab15a43b12db91ef0bdce2e74353 Mon Sep 17 00:00:00 2001 From: Octi Zhang Date: Mon, 3 Aug 2026 01:46:40 -0700 Subject: [PATCH 2/3] Use int32 body indices in Lift observation --- .../isaaclab_tasks/isaaclab_tasks/core/lift/mdp/observations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/observations.py b/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/observations.py index a7b253906b0b..d08dc7ec6e88 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/observations.py +++ b/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/observations.py @@ -54,7 +54,7 @@ def __init__(self, cfg: ObservationTermCfg, env: ManagerBasedRLEnv): super().__init__(cfg, env) body_ids = cfg.params["body_asset_cfg"].body_ids if isinstance(body_ids, list): - body_ids = torch.tensor(body_ids, dtype=torch.long, device=env.device) + body_ids = torch.tensor(body_ids, dtype=torch.int32, device=env.device) self._body_ids = body_ids def __call__( From 6ff12395a25cb4e374e5d75695fef34fd6e7e273 Mon Sep 17 00:00:00 2001 From: Octi Zhang Date: Mon, 3 Aug 2026 03:08:19 -0700 Subject: [PATCH 3/3] Revert "Use int32 body indices in Lift observation" Restore int64 indices because LEAPP's ONNX GatherND export requires them. --- .../isaaclab_tasks/isaaclab_tasks/core/lift/mdp/observations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/observations.py b/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/observations.py index d08dc7ec6e88..a7b253906b0b 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/observations.py +++ b/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/observations.py @@ -54,7 +54,7 @@ def __init__(self, cfg: ObservationTermCfg, env: ManagerBasedRLEnv): super().__init__(cfg, env) body_ids = cfg.params["body_asset_cfg"].body_ids if isinstance(body_ids, list): - body_ids = torch.tensor(body_ids, dtype=torch.int32, device=env.device) + body_ids = torch.tensor(body_ids, dtype=torch.long, device=env.device) self._body_ids = body_ids def __call__(