From c49774d796210c6ee436252b2187c396e2207b39 Mon Sep 17 00:00:00 2001 From: Maximilian Krause Date: Tue, 29 Sep 2026 19:15:09 +0200 Subject: [PATCH 1/4] Migrate Franka Reach and Drawer to flat asset --- examples/haply_teleoperation.py | 9 +- .../tutorials/05_controllers/run_diff_ik.py | 4 +- scripts/tutorials/05_controllers/run_osc.py | 10 +- ...maximiliank-diffik-action-offset.minor.rst | 5 + .../isaaclab/envs/mdp/actions/actions_cfg.py | 2 + .../envs/mdp/actions/task_space_actions.py | 22 ++-- .../test/controllers/test_differential_ik.py | 4 +- .../controllers/test_operational_space.py | 5 +- .../envs/test_diffik_action_processing.py | 56 ++++++++++ .../maximiliank-franka-reach-drawer.major.rst | 11 ++ .../render_benchmark_env_cfg.py | 9 +- .../cabinet/config/franka/ik_abs_env_cfg.py | 6 +- .../cabinet/config/franka/ik_rel_env_cfg.py | 6 +- .../contrib/franka_pour/pour_env_cfg.py | 45 ++------ .../lift/config/franka/ik_abs_env_cfg.py | 4 +- .../lift/config/franka/ik_rel_env_cfg.py | 4 +- .../lift/config/franka/joint_pos_env_cfg.py | 8 +- .../config/franka/bin_stack_ik_rel_env_cfg.py | 4 +- .../franka/bin_stack_joint_pos_env_cfg.py | 12 +-- .../config/franka/stack_ik_abs_env_cfg.py | 4 +- .../franka/stack_ik_rel_blueprint_env_cfg.py | 4 +- .../config/franka/stack_ik_rel_env_cfg.py | 4 +- .../franka/stack_ik_rel_env_cfg_skillgen.py | 4 +- ...stack_ik_rel_instance_randomize_env_cfg.py | 4 +- .../stack_ik_rel_visuomotor_cosmos_env_cfg.py | 2 +- .../franka/stack_ik_rel_visuomotor_env_cfg.py | 14 +-- .../config/franka/stack_joint_pos_env_cfg.py | 20 ++-- ...ck_joint_pos_instance_randomize_env_cfg.py | 12 +-- .../config/franka/cabinet_direct_env_cfg.py | 11 +- .../config/franka/joint_pos_env_cfg.py | 19 ++-- .../config/franka/franka_reach_env_cfg.py | 50 +++++++-- .../config/franka/franka_reach_osc_env_cfg.py | 7 +- .../benchmark/test_render_benchmark_cfg.py | 13 +-- .../test/contrib/test_franka_pour_env_cfg.py | 2 +- .../test/core/test_reach_franka_presets.py | 101 ++++++++++++++---- 35 files changed, 334 insertions(+), 163 deletions(-) create mode 100644 source/isaaclab/changelog.d/maximiliank-diffik-action-offset.minor.rst create mode 100644 source/isaaclab/test/envs/test_diffik_action_processing.py create mode 100644 source/isaaclab_tasks/changelog.d/maximiliank-franka-reach-drawer.major.rst diff --git a/examples/haply_teleoperation.py b/examples/haply_teleoperation.py index 129d9fa3e674..679150eac477 100644 --- a/examples/haply_teleoperation.py +++ b/examples/haply_teleoperation.py @@ -33,7 +33,7 @@ from isaaclab.utils import configclass, instantiate, replace from isaaclab.utils.assets import ISAAC_NUCLEUS_DIR -from isaaclab_assets import FRANKA_PANDA_HIGH_PD_CFG +from isaaclab_assets import FRANKA_PANDA_FLAT_HIGH_PD_CFG if TYPE_CHECKING: from isaaclab.assets import Articulation, RigidObject @@ -127,10 +127,11 @@ class FrankaHaplySceneCfg(InteractiveSceneCfg): init_state=AssetBaseCfg.InitialStateCfg(pos=(0.50, 0.0, 1.05), rot=(0.707, 0, 0, 0.707)), ) - robot_cfg: ArticulationCfg = replace(FRANKA_PANDA_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") + robot_cfg: ArticulationCfg = replace(FRANKA_PANDA_FLAT_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") robot = instantiate(robot_cfg) robot.init_state.pos = (-0.02, 0.0, 1.05) robot.spawn.activate_contact_sensors = True + robot.spawn.variants["Physics"] = "mujoco" if args_cli.physics == "newton_mjwarp" else "physx" cube = RigidObjectCfg( prim_path="{ENV_REGEX_NS}/Cube", @@ -146,7 +147,7 @@ class FrankaHaplySceneCfg(InteractiveSceneCfg): ) left_finger_contact_sensor = ContactSensorCfg( - prim_path="{ENV_REGEX_NS}/Robot/panda_leftfinger", + prim_path="{ENV_REGEX_NS}/Robot/(Geometry/.*/)?panda_leftfinger", update_period=0.0, history_length=3, debug_vis=True, @@ -154,7 +155,7 @@ class FrankaHaplySceneCfg(InteractiveSceneCfg): ) right_finger_contact_sensor = ContactSensorCfg( - prim_path="{ENV_REGEX_NS}/Robot/panda_rightfinger", + prim_path="{ENV_REGEX_NS}/Robot/(Geometry/.*/)?panda_rightfinger", update_period=0.0, history_length=3, debug_vis=True, diff --git a/scripts/tutorials/05_controllers/run_diff_ik.py b/scripts/tutorials/05_controllers/run_diff_ik.py index 9f91b6596195..2acd470b6fb6 100644 --- a/scripts/tutorials/05_controllers/run_diff_ik.py +++ b/scripts/tutorials/05_controllers/run_diff_ik.py @@ -53,7 +53,7 @@ ## # Pre-defined configs ## -from isaaclab_assets import FRANKA_PANDA_HIGH_PD_CFG, UR10_CFG # isort:skip +from isaaclab_assets import FRANKA_PANDA_FLAT_HIGH_PD_CFG, UR10_CFG # isort:skip @configclass @@ -82,7 +82,7 @@ class TableTopSceneCfg(InteractiveSceneCfg): # articulation if args_cli.robot == "franka_panda": - robot = replace(FRANKA_PANDA_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") + robot = replace(FRANKA_PANDA_FLAT_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") elif args_cli.robot == "ur10": robot = replace(UR10_CFG, prim_path="{ENV_REGEX_NS}/Robot") else: diff --git a/scripts/tutorials/05_controllers/run_osc.py b/scripts/tutorials/05_controllers/run_osc.py index f2dddf957364..03b8e886c75e 100644 --- a/scripts/tutorials/05_controllers/run_osc.py +++ b/scripts/tutorials/05_controllers/run_osc.py @@ -57,7 +57,7 @@ ## # Pre-defined configs ## -from isaaclab_assets import FRANKA_PANDA_HIGH_PD_CFG # isort:skip +from isaaclab_assets import FRANKA_PANDA_FLAT_HIGH_PD_CFG # isort:skip @configclass @@ -97,11 +97,9 @@ class SceneCfg(InteractiveSceneCfg): debug_vis=False, ) - robot = replace(FRANKA_PANDA_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") - robot.actuators["panda_shoulder"].stiffness = 0.0 - robot.actuators["panda_shoulder"].damping = 0.0 - robot.actuators["panda_forearm"].stiffness = 0.0 - robot.actuators["panda_forearm"].damping = 0.0 + robot = replace(FRANKA_PANDA_FLAT_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") + robot.actuators["panda_arm"].stiffness = 0.0 + robot.actuators["panda_arm"].damping = 0.0 robot.spawn.rigid_props.disable_gravity = True diff --git a/source/isaaclab/changelog.d/maximiliank-diffik-action-offset.minor.rst b/source/isaaclab/changelog.d/maximiliank-diffik-action-offset.minor.rst new file mode 100644 index 000000000000..2af70b827142 --- /dev/null +++ b/source/isaaclab/changelog.d/maximiliank-diffik-action-offset.minor.rst @@ -0,0 +1,5 @@ +Added +^^^^^ + +* Added an ``offset`` to ``DifferentialInverseKinematicsActionCfg`` so normalized policies can use + an affine task-space action transform. The default is zero and preserves existing configurations. diff --git a/source/isaaclab/isaaclab/envs/mdp/actions/actions_cfg.py b/source/isaaclab/isaaclab/envs/mdp/actions/actions_cfg.py index 6bd98583073e..ecb0ef1dabe2 100644 --- a/source/isaaclab/isaaclab/envs/mdp/actions/actions_cfg.py +++ b/source/isaaclab/isaaclab/envs/mdp/actions/actions_cfg.py @@ -325,6 +325,8 @@ class OffsetCfg: """Offset of target frame w.r.t. to the body frame. Defaults to None, in which case no offset is applied.""" scale: float | tuple[float, ...] = 1.0 """Scale factor for the action. Defaults to 1.0.""" + offset: float | tuple[float, ...] = 0.0 + """Offset applied to the scaled action in controller-specific units. Defaults to 0.0.""" controller: DifferentialIKControllerCfg = MISSING """The configuration for the differential IK controller.""" diff --git a/source/isaaclab/isaaclab/envs/mdp/actions/task_space_actions.py b/source/isaaclab/isaaclab/envs/mdp/actions/task_space_actions.py index 3b077356cea5..e089047e49b7 100644 --- a/source/isaaclab/isaaclab/envs/mdp/actions/task_space_actions.py +++ b/source/isaaclab/isaaclab/envs/mdp/actions/task_space_actions.py @@ -34,15 +34,15 @@ class DifferentialInverseKinematicsAction(ActionTerm): r"""Inverse Kinematics action term. - This action term performs pre-processing of the raw actions using scaling transformation. + This action term pre-processes raw actions using an affine transformation. .. math:: - \text{action} = \text{scaling} \times \text{input action} + \text{action} = \text{offset} + \text{scaling} \times \text{input action} \text{joint position} = J^{-} \times \text{action} - where :math:`\text{scaling}` is the scaling applied to the input action, and :math:`\text{input action}` - is the input action from the user, :math:`J` is the Jacobian over the articulation's actuated joints, - and \text{joint position} is the desired joint position command for the articulation's joints. + where :math:`\text{offset}` and :math:`\text{scaling}` define the affine transformation, + :math:`\text{input action}` is the input action from the user, :math:`J` is the Jacobian over the + articulation's actuated joints, and \text{joint position} is the desired joint position command. """ cfg: actions_cfg.DifferentialInverseKinematicsActionCfg @@ -50,7 +50,9 @@ class DifferentialInverseKinematicsAction(ActionTerm): _asset: Articulation """The articulation asset on which the action term is applied.""" _scale: torch.Tensor - """The scaling factor applied to the input action. Shape is (1, action_dim).""" + """The scaling factor applied to the input action. Shape is (num_envs, action_dim).""" + _offset: torch.Tensor + """The offset applied to the scaled action. Shape is (num_envs, action_dim).""" _clip: torch.Tensor """The clip applied to the input action.""" @@ -100,9 +102,11 @@ def __init__(self, cfg: actions_cfg.DifferentialInverseKinematicsActionCfg, env: # owned buffer; _compute_frame_jacobian mutates this, not the data-layer view. self._jacobian_b = torch.zeros(self.num_envs, 6, len(self._jacobi_joint_ids), device=self.device) - # save the scale as tensors + # save the affine transform as tensors self._scale = torch.zeros((self.num_envs, self.action_dim), device=self.device) self._scale[:] = torch.tensor(self.cfg.scale, device=self.device) + self._offset = torch.zeros((self.num_envs, self.action_dim), device=self.device) + self._offset[:] = torch.tensor(self.cfg.offset, device=self.device) # convert the fixed offsets to torch tensors of batched shape if self.cfg.body_offset is not None: @@ -160,6 +164,7 @@ def IO_descriptor(self) -> GenericActionIODescriptor: - body_name: The name of the body. - joint_names: The names of the joints. - scale: The scale of the action term. + - offset: The offset of the action term. - clip: The clip of the action term. - controller_cfg: The configuration of the controller. - body_offset: The offset of the body. @@ -174,6 +179,7 @@ def IO_descriptor(self) -> GenericActionIODescriptor: self._IO_descriptor.body_name = self._body_name self._IO_descriptor.joint_names = self._joint_names self._IO_descriptor.scale = self._scale + self._IO_descriptor.offset = self._offset if self.cfg.clip is not None: self._IO_descriptor.clip = self.cfg.clip else: @@ -189,7 +195,7 @@ def IO_descriptor(self) -> GenericActionIODescriptor: def process_actions(self, actions: torch.Tensor): # store the raw actions self._raw_actions[:] = actions - self._processed_actions[:] = self.raw_actions * self._scale + self._processed_actions[:] = self.raw_actions * self._scale + self._offset if self.cfg.clip is not None: self._processed_actions = torch.clamp( self._processed_actions, min=self._clip[:, :, 0], max=self._clip[:, :, 1] diff --git a/source/isaaclab/test/controllers/test_differential_ik.py b/source/isaaclab/test/controllers/test_differential_ik.py index 4b91b1158cff..4df4cad5d92d 100644 --- a/source/isaaclab/test/controllers/test_differential_ik.py +++ b/source/isaaclab/test/controllers/test_differential_ik.py @@ -31,7 +31,7 @@ ## # Pre-defined configs ## -from isaaclab_assets import FRANKA_PANDA_HIGH_PD_CFG, UR10_CFG # isort:skip +from isaaclab_assets import FRANKA_PANDA_FLAT_HIGH_PD_CFG, UR10_CFG # isort:skip pytestmark = pytest.mark.integration @@ -441,7 +441,7 @@ def test_franka_ik_pose_abs(sim): sim_context, num_envs, ee_pose_b_des_set = sim # Create robot instance - robot_cfg = replace(FRANKA_PANDA_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") + robot_cfg = replace(FRANKA_PANDA_FLAT_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") robot = Articulation(cfg=robot_cfg) # Create IK controller diff --git a/source/isaaclab/test/controllers/test_operational_space.py b/source/isaaclab/test/controllers/test_operational_space.py index 2dd6e63e4028..76ed5a42165f 100644 --- a/source/isaaclab/test/controllers/test_operational_space.py +++ b/source/isaaclab/test/controllers/test_operational_space.py @@ -50,7 +50,7 @@ subtract_frame_transforms, ) -from isaaclab_assets import FRANKA_PANDA_CFG, G1_29DOF_CFG # isort:skip +from isaaclab_assets import FRANKA_PANDA_LEGACY_CFG, G1_29DOF_CFG # isort:skip pytestmark = pytest.mark.integration @@ -95,7 +95,8 @@ def sim(): # clone the env xform cloner.usd_replicate(stage, [env_fmt.format(0)], [env_fmt], env_ids, positions=env_origins) - robot_cfg = replace(FRANKA_PANDA_CFG, prim_path="{ENV_REGEX_NS}/Robot") + # Keep controller regressions on their original plant; canonical asset parity is tested by each backend. + robot_cfg = replace(FRANKA_PANDA_LEGACY_CFG, prim_path="{ENV_REGEX_NS}/Robot") # Explicit torque actuators enforce effort limits on the commands sent to the simulator. for actuator_name in ("panda_shoulder", "panda_forearm"): actuator_cfg = robot_cfg.actuators[actuator_name] diff --git a/source/isaaclab/test/envs/test_diffik_action_processing.py b/source/isaaclab/test/envs/test_diffik_action_processing.py new file mode 100644 index 000000000000..8a6d9634a9ea --- /dev/null +++ b/source/isaaclab/test/envs/test_diffik_action_processing.py @@ -0,0 +1,56 @@ +# 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 + +"""Unit tests for differential inverse-kinematics action processing.""" + +from types import SimpleNamespace + +import pytest +import torch + +from isaaclab.controllers import DifferentialIKControllerCfg +from isaaclab.envs.mdp.actions.actions_cfg import DifferentialInverseKinematicsActionCfg +from isaaclab.envs.mdp.actions.task_space_actions import DifferentialInverseKinematicsAction + +pytestmark = pytest.mark.unit + + +def test_process_actions_applies_scale_then_offset(monkeypatch: pytest.MonkeyPatch) -> None: + """DiffIK actions use the configured affine transformation before reaching the controller.""" + num_envs = 2 + controller_cfg = DifferentialIKControllerCfg(command_type="position", use_relative_mode=False, ik_method="dls") + cfg = DifferentialInverseKinematicsActionCfg( + asset_name="robot", + joint_names=[".*"], + body_name="tool", + scale=(0.5, 2.0, -1.0), + offset=(0.1, -0.2, 0.3), + controller=controller_cfg, + ) + asset = SimpleNamespace( + find_joints=lambda _names: ([0, 1, 2], ["joint1", "joint2", "joint3"]), + find_bodies=lambda _name: ([0], ["tool"]), + num_joints=3, + num_base_dofs=0, + is_fixed_base=False, + ) + env = SimpleNamespace(scene={"robot": asset}, num_envs=num_envs, device="cpu") + action = DifferentialInverseKinematicsAction(cfg, env) + ee_pos = torch.zeros(num_envs, 3) + ee_quat = torch.tensor([[0.0, 0.0, 0.0, 1.0]]).repeat(num_envs, 1) + monkeypatch.setattr(action, "_compute_frame_pose", lambda: (ee_pos, ee_quat)) + + raw_actions = torch.tensor([[1.0, -2.0, 0.5], [-1.0, 0.25, -0.5]]) + expected = torch.tensor([[0.6, -4.2, -0.2], [-0.4, 0.3, 0.8]]) + + action.process_actions(raw_actions) + + torch.testing.assert_close(action.raw_actions, raw_actions) + torch.testing.assert_close(action.processed_actions, expected) + torch.testing.assert_close(action._ik_controller.ee_pos_des, expected) + + +if __name__ == "__main__": + pytest.main([__file__, "-v"]) diff --git a/source/isaaclab_tasks/changelog.d/maximiliank-franka-reach-drawer.major.rst b/source/isaaclab_tasks/changelog.d/maximiliank-franka-reach-drawer.major.rst new file mode 100644 index 000000000000..d3e71b259a74 --- /dev/null +++ b/source/isaaclab_tasks/changelog.d/maximiliank-franka-reach-drawer.major.rst @@ -0,0 +1,11 @@ +Changed +^^^^^^^ + +* Migrated maintained Franka Reach, Drawer, and related contributed tasks to the shared flat asset with + backend-specific physics and gripper-only collisions by default. Select ``arm_collisions`` where arm + contacts are required. Existing checkpoints should be requalified against the changed robot dynamics. + +Fixed +^^^^^ + +* Corrected the Reach action and controller contracts for the shared asset. diff --git a/source/isaaclab_tasks/isaaclab_tasks/benchmark/render_benchmark/render_benchmark_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/benchmark/render_benchmark/render_benchmark_env_cfg.py index a09bdf673811..3e1c4ba20fce 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/benchmark/render_benchmark/render_benchmark_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/benchmark/render_benchmark/render_benchmark_env_cfg.py @@ -25,10 +25,10 @@ from isaaclab.utils import configclass, replace from isaaclab.utils.assets import ISAAC_NUCLEUS_DIR -from isaaclab_tasks.utils import PresetCfg +from isaaclab_tasks.utils import PresetCfg, preset from isaaclab_tasks.utils.presets import MultiBackendRendererCfg -from isaaclab_assets.robots.franka import FRANKA_PANDA_HIGH_PD_CFG +from isaaclab_assets.robots.franka import FRANKA_PANDA_FLAT_HIGH_PD_CFG BenchmarkMode = Literal["render", "physics_render"] """Animation mode used by the render benchmark. @@ -144,10 +144,11 @@ class RenderBenchmarkSceneCfg(InteractiveSceneCfg): init_state=RigidObjectCfg.InitialStateCfg(pos=(0.0, 0.0, -0.05)), ) robot: ArticulationCfg = replace( - FRANKA_PANDA_HIGH_PD_CFG, + FRANKA_PANDA_FLAT_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot", - init_state=replace(FRANKA_PANDA_HIGH_PD_CFG.init_state, pos=(1.0, 0.0, 0.0), rot=(0.0, 0.0, 1.0, 0.0)), + init_state=replace(FRANKA_PANDA_FLAT_HIGH_PD_CFG.init_state, pos=(1.0, 0.0, 0.0), rot=(0.0, 0.0, 1.0, 0.0)), ) + robot.spawn.variants["Physics"] = preset(default="mujoco", isaacsim_physx="physx", ovphysx="physx", physx="physx") cabinet: ArticulationCfg = ArticulationCfg( prim_path="{ENV_REGEX_NS}/Cabinet", spawn=sim_utils.UsdFileCfg( diff --git a/source/isaaclab_tasks/isaaclab_tasks/contrib/cabinet/config/franka/ik_abs_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/contrib/cabinet/config/franka/ik_abs_env_cfg.py index 7707d97e8a7e..8a7da6c667c5 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/contrib/cabinet/config/franka/ik_abs_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/contrib/cabinet/config/franka/ik_abs_env_cfg.py @@ -12,7 +12,7 @@ ## # Pre-defined configs ## -from isaaclab_assets.robots.franka import FRANKA_PANDA_HIGH_PD_CFG # isort: skip +from isaaclab_assets.robots.franka import FRANKA_PANDA_FLAT_HIGH_PD_CFG # isort: skip @configclass @@ -23,7 +23,9 @@ def __post_init__(self): # Set Franka as robot # We switch here to a stiffer PD controller for IK tracking to be better. - self.scene.robot = replace(FRANKA_PANDA_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") + physics_variants = self.scene.robot.spawn.variants + self.scene.robot = replace(FRANKA_PANDA_FLAT_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") + self.scene.robot.spawn.variants = physics_variants # Set actions for the specific robot type (franka) self.actions.arm_action = DifferentialInverseKinematicsActionCfg( diff --git a/source/isaaclab_tasks/isaaclab_tasks/contrib/cabinet/config/franka/ik_rel_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/contrib/cabinet/config/franka/ik_rel_env_cfg.py index 7e2e96e9460e..aae63d444a09 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/contrib/cabinet/config/franka/ik_rel_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/contrib/cabinet/config/franka/ik_rel_env_cfg.py @@ -12,7 +12,7 @@ ## # Pre-defined configs ## -from isaaclab_assets.robots.franka import FRANKA_PANDA_HIGH_PD_CFG # isort: skip +from isaaclab_assets.robots.franka import FRANKA_PANDA_FLAT_HIGH_PD_CFG # isort: skip @configclass @@ -23,7 +23,9 @@ def __post_init__(self): # Set Franka as robot # We switch here to a stiffer PD controller for IK tracking to be better. - self.scene.robot = replace(FRANKA_PANDA_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") + physics_variants = self.scene.robot.spawn.variants + self.scene.robot = replace(FRANKA_PANDA_FLAT_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") + self.scene.robot.spawn.variants = physics_variants # Set actions for the specific robot type (franka) self.actions.arm_action = DifferentialInverseKinematicsActionCfg( diff --git a/source/isaaclab_tasks/isaaclab_tasks/contrib/franka_pour/pour_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/contrib/franka_pour/pour_env_cfg.py index 1dc988351a67..687eaa69c89e 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/contrib/franka_pour/pour_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/contrib/franka_pour/pour_env_cfg.py @@ -40,7 +40,7 @@ from isaaclab_contrib.coupling import CouplerEntryCfg, CouplerProxyCfg, CouplerProxyMappingCfg -from isaaclab_assets.robots.franka import FRANKA_PANDA_CFG +from isaaclab_assets.robots.franka import FRANKA_PANDA_FLAT_CFG from . import mdp from .geometry import ( @@ -182,7 +182,7 @@ def spawn_franka_with_arm_collisions( orientation: tuple[float, float, float, float] | None = None, **kwargs, ): - """Spawn the canonical Franka with the intended mimic and arm-collision schemas.""" + """Spawn the canonical Franka with writable convex-hull arm colliders.""" from pxr import Usd, UsdPhysics # noqa: PLC0415 robot_prim = sim_utils.spawn_from_usd(prim_path, cfg, translation, orientation, **kwargs) @@ -191,29 +191,6 @@ def spawn_franka_with_arm_collisions( if not self_collision or not self_collision.Set(True): raise RuntimeError(f"Franka asset at {root_prim.GetPath()} has no writable Newton self-collision flag.") - finger_joints = { - prim.GetName(): prim - for prim in Usd.PrimRange(root_prim, Usd.TraverseInstanceProxies()) - if prim.GetName() in {"panda_finger_joint1", "panda_finger_joint2"} - } - if finger_joints.keys() != {"panda_finger_joint1", "panda_finger_joint2"}: - missing = sorted({"panda_finger_joint1", "panda_finger_joint2"}.difference(finger_joints)) - raise RuntimeError(f"Franka asset at {root_prim.GetPath()} is missing finger joints: {missing}.") - - leader_schemas = finger_joints["panda_finger_joint1"].GetMetadata("apiSchemas") - follower_schemas = finger_joints["panda_finger_joint2"].GetMetadata("apiSchemas") - leader_schema_names = [] if leader_schemas is None else list(leader_schemas.GetAppliedItems()) - follower_schema_names = [] if follower_schemas is None else list(follower_schemas.GetAppliedItems()) - if "NewtonMimicAPI" not in leader_schema_names or "PhysxMimicJointAPI:linear" not in follower_schema_names: - raise RuntimeError( - "The pinned Franka physics payload no longer has the expected duplicate finger-mimic schemas. " - "Update the asset hash and task-side override together." - ) - if not finger_joints["panda_finger_joint1"].RemoveAppliedSchema("NewtonMimicAPI"): - raise RuntimeError("Failed to remove the redundant Franka Newton finger-mimic schema.") - if finger_joints["panda_finger_joint1"].HasAPI("NewtonMimicAPI"): - raise RuntimeError("The redundant Franka Newton finger-mimic schema is still composed after removal.") - proxy_roots = { prim.GetName(): prim.GetParent().GetPath() for prim in Usd.PrimRange(root_prim, Usd.TraverseInstanceProxies()) @@ -337,9 +314,9 @@ class PourSceneCfg(InteractiveSceneCfg): prim_path="/World/light", spawn=sim_utils.DomeLightCfg(color=(0.75, 0.75, 0.75), intensity=3000.0), ) - robot = replace(FRANKA_PANDA_CFG, prim_path="{ENV_REGEX_NS}/Robot") + robot = replace(FRANKA_PANDA_FLAT_CFG, prim_path="{ENV_REGEX_NS}/Robot") robot.spawn.usd_path = FRANKA_POUR_ROBOT_USD_PATH - robot.spawn.variants = {"Colliders": "convex_hulls"} + robot.spawn.variants = {"Physics": "mujoco", "Colliders": "convex_hulls"} robot.spawn.func = spawn_franka_with_arm_collisions # The pouring asset relies on arm self-collision; author it in both namespaces so whichever # backend resolves the articulation sees the flag. @@ -355,16 +332,10 @@ class PourSceneCfg(InteractiveSceneCfg): ) for name, actuator_cfg in robot.actuators.items() } - robot.actuators["panda_shoulder"].stiffness = { - key: FRANKA_POUR_ARM_DRIVE_STIFFNESS[key] for key in ("panda_joint[1-2]", "panda_joint[3-4]") - } - robot.actuators["panda_shoulder"].damping = { - key: FRANKA_POUR_ARM_DRIVE_DAMPING[key] for key in ("panda_joint[1-2]", "panda_joint[3-4]") - } - robot.actuators["panda_forearm"].stiffness = { - "panda_joint[5-7]": FRANKA_POUR_ARM_DRIVE_STIFFNESS["panda_joint[5-7]"] - } - robot.actuators["panda_forearm"].damping = {"panda_joint[5-7]": FRANKA_POUR_ARM_DRIVE_DAMPING["panda_joint[5-7]"]} + robot.actuators["panda_arm"].stiffness = dict(FRANKA_POUR_ARM_DRIVE_STIFFNESS) + robot.actuators["panda_arm"].damping = dict(FRANKA_POUR_ARM_DRIVE_DAMPING) + robot.actuators["panda_finger2_passive"].stiffness = 0.0 + robot.actuators["panda_finger2_passive"].damping = 0.0 robot.spawn.joint_drive_props = MujocoJointCfg(actuatorgravcomp=True) robot.init_state.joint_pos.update(dict(zip(_ARM_JOINT_NAMES, _ARM_HOME, strict=True))) robot.init_state.joint_pos["panda_finger_joint.*"] = _GRIPPER_OPEN_POSITION 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 8bee40e4b2be..3a6521e107f9 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 @@ -12,7 +12,7 @@ ## # Pre-defined configs ## -from isaaclab_assets.robots.franka import FRANKA_PANDA_HIGH_PD_CFG # isort: skip +from isaaclab_assets.robots.franka import FRANKA_PANDA_FLAT_HIGH_PD_CFG # isort: skip ## @@ -28,7 +28,7 @@ def __post_init__(self): # Set Franka as robot # We switch here to a stiffer PD controller for IK tracking to be better. - self.scene.robot = replace(FRANKA_PANDA_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") + self.scene.robot = replace(FRANKA_PANDA_FLAT_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") # Set actions for the specific robot type (franka) self.actions.arm_action = DifferentialInverseKinematicsActionCfg( 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 4869b30b8521..ff44c6c2c9a5 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 @@ -12,7 +12,7 @@ ## # Pre-defined configs ## -from isaaclab_assets.robots.franka import FRANKA_PANDA_HIGH_PD_CFG # isort: skip +from isaaclab_assets.robots.franka import FRANKA_PANDA_FLAT_HIGH_PD_CFG # isort: skip @configclass @@ -23,7 +23,7 @@ def __post_init__(self): # Set Franka as robot # We switch here to a stiffer PD controller for IK tracking to be better. - self.scene.robot = replace(FRANKA_PANDA_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") + self.scene.robot = replace(FRANKA_PANDA_FLAT_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") # Set actions for the specific robot type (franka) self.actions.arm_action = DifferentialInverseKinematicsActionCfg( diff --git a/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/joint_pos_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/joint_pos_env_cfg.py index 5935bb95c19c..aabd132f7154 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/joint_pos_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/joint_pos_env_cfg.py @@ -19,7 +19,7 @@ # Pre-defined configs ## from isaaclab.markers.config import FRAME_MARKER_CFG # isort: skip -from isaaclab_assets.robots.franka import FRANKA_PANDA_CFG # isort: skip +from isaaclab_assets.robots.franka import FRANKA_PANDA_FLAT_CFG # isort: skip @configclass @@ -29,7 +29,7 @@ def __post_init__(self): super().__post_init__() # Set Franka as robot - self.scene.robot = replace(FRANKA_PANDA_CFG, prim_path="{ENV_REGEX_NS}/Robot") + self.scene.robot = replace(FRANKA_PANDA_FLAT_CFG, prim_path="{ENV_REGEX_NS}/Robot") # Set actions for the specific robot type (franka) self.actions.arm_action = mdp.JointPositionActionCfg( @@ -67,12 +67,12 @@ def __post_init__(self): marker_cfg.markers["frame"].scale = (0.1, 0.1, 0.1) marker_cfg.prim_path = "/Visuals/FrameTransformer" self.scene.ee_frame = FrameTransformerCfg( - prim_path="{ENV_REGEX_NS}/Robot/panda_link0", + prim_path="{ENV_REGEX_NS}/Robot/(Geometry/)?panda_link0", debug_vis=False, visualizer_cfg=marker_cfg, target_frames=[ FrameTransformerCfg.FrameCfg( - prim_path="{ENV_REGEX_NS}/Robot/panda_hand", + prim_path="{ENV_REGEX_NS}/Robot/(Geometry/.*/)?panda_hand", name="end_effector", offset=OffsetCfg( pos=[0.0, 0.0, 0.1034], diff --git a/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/bin_stack_ik_rel_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/bin_stack_ik_rel_env_cfg.py index 858c095779aa..8b68516ff17d 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/bin_stack_ik_rel_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/bin_stack_ik_rel_env_cfg.py @@ -12,7 +12,7 @@ ## # Pre-defined configs ## -from isaaclab_assets.robots.franka import FRANKA_PANDA_HIGH_PD_CFG # isort: skip +from isaaclab_assets.robots.franka import FRANKA_PANDA_FLAT_HIGH_PD_CFG # isort: skip @configclass @@ -22,7 +22,7 @@ def __post_init__(self): super().__post_init__() # Set Franka as robot - self.scene.robot = replace(FRANKA_PANDA_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") + self.scene.robot = replace(FRANKA_PANDA_FLAT_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") # Set actions for the specific robot type (franka) self.actions.arm_action = DifferentialInverseKinematicsActionCfg( diff --git a/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/bin_stack_joint_pos_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/bin_stack_joint_pos_env_cfg.py index 5d4e533e98a0..fdcc0587fa31 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/bin_stack_joint_pos_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/bin_stack_joint_pos_env_cfg.py @@ -24,7 +24,7 @@ # Pre-defined configs ## from isaaclab.markers.config import FRAME_MARKER_CFG # isort: skip -from isaaclab_assets.robots.franka import FRANKA_PANDA_CFG # isort: skip +from isaaclab_assets.robots.franka import FRANKA_PANDA_FLAT_CFG # isort: skip @configclass @@ -96,7 +96,7 @@ def __post_init__(self): self.events = EventCfg() # Set Franka as robot - self.scene.robot = replace(FRANKA_PANDA_CFG, prim_path="{ENV_REGEX_NS}/Robot") + self.scene.robot = replace(FRANKA_PANDA_FLAT_CFG, prim_path="{ENV_REGEX_NS}/Robot") self.scene.robot.spawn.semantic_tags = [("class", "robot")] # Add semantics to table @@ -182,26 +182,26 @@ def __post_init__(self): marker_cfg.markers["frame"].scale = (0.1, 0.1, 0.1) marker_cfg.prim_path = "/Visuals/FrameTransformer" self.scene.ee_frame = FrameTransformerCfg( - prim_path="{ENV_REGEX_NS}/Robot/panda_link0", + prim_path="{ENV_REGEX_NS}/Robot/(Geometry/)?panda_link0", debug_vis=False, visualizer_cfg=marker_cfg, target_frames=[ FrameTransformerCfg.FrameCfg( - prim_path="{ENV_REGEX_NS}/Robot/panda_hand", + prim_path="{ENV_REGEX_NS}/Robot/(Geometry/.*/)?panda_hand", name="end_effector", offset=OffsetCfg( pos=(0.0, 0.0, 0.0), ), ), FrameTransformerCfg.FrameCfg( - prim_path="{ENV_REGEX_NS}/Robot/panda_rightfinger", + prim_path="{ENV_REGEX_NS}/Robot/(Geometry/.*/)?panda_rightfinger", name="tool_rightfinger", offset=OffsetCfg( pos=(0.0, 0.0, 0.046), ), ), FrameTransformerCfg.FrameCfg( - prim_path="{ENV_REGEX_NS}/Robot/panda_leftfinger", + prim_path="{ENV_REGEX_NS}/Robot/(Geometry/.*/)?panda_leftfinger", name="tool_leftfinger", offset=OffsetCfg( pos=(0.0, 0.0, 0.046), diff --git a/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_ik_abs_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_ik_abs_env_cfg.py index 7024329b8e57..18e6efc6db2c 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_ik_abs_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_ik_abs_env_cfg.py @@ -18,7 +18,7 @@ ## # Pre-defined configs ## -from isaaclab_assets.robots.franka import FRANKA_PANDA_HIGH_PD_CFG # isort: skip +from isaaclab_assets.robots.franka import FRANKA_PANDA_FLAT_HIGH_PD_CFG # isort: skip def _build_franka_stack_pipeline(): @@ -114,7 +114,7 @@ def __post_init__(self): # Set Franka as robot # We switch here to a stiffer PD controller for IK tracking to be better. - self.scene.robot = replace(FRANKA_PANDA_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") + self.scene.robot = replace(FRANKA_PANDA_FLAT_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") # Set actions for the specific robot type (franka) self.actions.arm_action = DifferentialInverseKinematicsActionCfg( diff --git a/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_ik_rel_blueprint_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_ik_rel_blueprint_env_cfg.py index 2c74266768ff..74fd959e1d65 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_ik_rel_blueprint_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_ik_rel_blueprint_env_cfg.py @@ -31,7 +31,7 @@ ## # Pre-defined configs ## -from isaaclab_assets.robots.franka import FRANKA_PANDA_HIGH_PD_CFG # isort: skip +from isaaclab_assets.robots.franka import FRANKA_PANDA_FLAT_HIGH_PD_CFG # isort: skip def image( @@ -217,7 +217,7 @@ def __post_init__(self): # Set Franka as robot # We switch here to a stiffer PD controller for IK tracking to be better. - self.scene.robot = replace(FRANKA_PANDA_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") + self.scene.robot = replace(FRANKA_PANDA_FLAT_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") self.scene.robot.spawn.semantic_tags = [("class", "robot")] # Set actions for the specific robot type (franka) diff --git a/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_ik_rel_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_ik_rel_env_cfg.py index 559058ab8673..18cb199c8a5e 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_ik_rel_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_ik_rel_env_cfg.py @@ -22,7 +22,7 @@ # Pre-defined configs ## from isaaclab_assets.robots.franka import ( # isort: skip - FRANKA_PANDA_HIGH_PD_CFG, + FRANKA_PANDA_FLAT_HIGH_PD_CFG, ) @@ -37,7 +37,7 @@ def __post_init__(self): robot_init_state = self.scene.robot.init_state robot_semantic_tags = self.scene.robot.spawn.semantic_tags self.scene.robot = replace( - FRANKA_PANDA_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot", init_state=robot_init_state + FRANKA_PANDA_FLAT_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot", init_state=robot_init_state ) self.scene.robot.spawn.semantic_tags = robot_semantic_tags diff --git a/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_ik_rel_env_cfg_skillgen.py b/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_ik_rel_env_cfg_skillgen.py index 9563cdc4f2fc..355e91789ccc 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_ik_rel_env_cfg_skillgen.py +++ b/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_ik_rel_env_cfg_skillgen.py @@ -16,7 +16,7 @@ ## # Pre-defined configs ## -from isaaclab_assets.robots.franka import FRANKA_PANDA_HIGH_PD_CFG # isort: skip +from isaaclab_assets.robots.franka import FRANKA_PANDA_FLAT_HIGH_PD_CFG # isort: skip @configclass @@ -107,7 +107,7 @@ def __post_init__(self): # Set Franka as robot # We switch here to a stiffer PD controller for IK tracking to be better. - self.scene.robot = replace(FRANKA_PANDA_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") + self.scene.robot = replace(FRANKA_PANDA_FLAT_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") # Set actions for the specific robot type (franka) self.actions.arm_action = DifferentialInverseKinematicsActionCfg( diff --git a/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_ik_rel_instance_randomize_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_ik_rel_instance_randomize_env_cfg.py index 3ab5af14e90c..e7afec6d6a76 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_ik_rel_instance_randomize_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_ik_rel_instance_randomize_env_cfg.py @@ -12,7 +12,7 @@ ## # Pre-defined configs ## -from isaaclab_assets.robots.franka import FRANKA_PANDA_HIGH_PD_CFG # isort: skip +from isaaclab_assets.robots.franka import FRANKA_PANDA_FLAT_HIGH_PD_CFG # isort: skip @configclass @@ -25,7 +25,7 @@ def __post_init__(self): # Set Franka as robot # We switch here to a stiffer PD controller for IK tracking to be better. - self.scene.robot = replace(FRANKA_PANDA_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") + self.scene.robot = replace(FRANKA_PANDA_FLAT_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") # Set actions for the specific robot type (franka) self.actions.arm_action = DifferentialInverseKinematicsActionCfg( diff --git a/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_ik_rel_visuomotor_cosmos_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_ik_rel_visuomotor_cosmos_env_cfg.py index 4a923b7d618e..24576ff975b0 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_ik_rel_visuomotor_cosmos_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_ik_rel_visuomotor_cosmos_env_cfg.py @@ -115,7 +115,7 @@ def __post_init__(self): # Set cameras # Set wrist camera self.scene.wrist_cam = CameraCfg( - prim_path="{ENV_REGEX_NS}/Robot/panda_hand/wrist_cam", + prim_path="{ENV_REGEX_NS}/Robot/(Geometry/.*/)?panda_hand/wrist_cam", update_period=0.0, height=200, width=200, diff --git a/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_ik_rel_visuomotor_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_ik_rel_visuomotor_env_cfg.py index 3d5572611523..163008d2d4de 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_ik_rel_visuomotor_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_ik_rel_visuomotor_env_cfg.py @@ -28,7 +28,7 @@ # Pre-defined configs ## from isaaclab.markers.config import FRAME_MARKER_CFG # isort: skip -from isaaclab_assets.robots.franka import FRANKA_PANDA_HIGH_PD_CFG # isort: skip +from isaaclab_assets.robots.franka import FRANKA_PANDA_FLAT_HIGH_PD_CFG # isort: skip # Default arm + gripper joint pose _FRANKA_STACK_IK_REL_INIT_JOINT_POS: dict[str, float] = { @@ -221,7 +221,7 @@ def __post_init__(self): # Set Franka as robot # We switch here to a stiffer PD controller for IK tracking to be better. self.scene.robot = replace( - FRANKA_PANDA_HIGH_PD_CFG, + FRANKA_PANDA_FLAT_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot", init_state=ArticulationCfg.InitialStateCfg(joint_pos=_FRANKA_STACK_IK_REL_INIT_JOINT_POS), ) @@ -304,26 +304,26 @@ def __post_init__(self): marker_cfg.markers["frame"].scale = (0.1, 0.1, 0.1) marker_cfg.prim_path = "/Visuals/FrameTransformer" self.scene.ee_frame = FrameTransformerCfg( - prim_path="{ENV_REGEX_NS}/Robot/panda_link0", + prim_path="{ENV_REGEX_NS}/Robot/(Geometry/)?panda_link0", debug_vis=False, visualizer_cfg=marker_cfg, target_frames=[ FrameTransformerCfg.FrameCfg( - prim_path="{ENV_REGEX_NS}/Robot/panda_hand", + prim_path="{ENV_REGEX_NS}/Robot/(Geometry/.*/)?panda_hand", name="end_effector", offset=OffsetCfg( pos=[0.0, 0.0, 0.1034], ), ), FrameTransformerCfg.FrameCfg( - prim_path="{ENV_REGEX_NS}/Robot/panda_rightfinger", + prim_path="{ENV_REGEX_NS}/Robot/(Geometry/.*/)?panda_rightfinger", name="tool_rightfinger", offset=OffsetCfg( pos=(0.0, 0.0, 0.046), ), ), FrameTransformerCfg.FrameCfg( - prim_path="{ENV_REGEX_NS}/Robot/panda_leftfinger", + prim_path="{ENV_REGEX_NS}/Robot/(Geometry/.*/)?panda_leftfinger", name="tool_leftfinger", offset=OffsetCfg( pos=(0.0, 0.0, 0.046), @@ -335,7 +335,7 @@ def __post_init__(self): # Set cameras # Set wrist camera self.scene.wrist_cam = CameraCfg( - prim_path="{ENV_REGEX_NS}/Robot/panda_hand/wrist_cam", + prim_path="{ENV_REGEX_NS}/Robot/(Geometry/.*/)?panda_hand/wrist_cam", update_period=0.0, height=200, width=200, diff --git a/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_joint_pos_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_joint_pos_env_cfg.py index b384e71293b9..639eeb00341e 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_joint_pos_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_joint_pos_env_cfg.py @@ -17,7 +17,7 @@ ## # Pre-defined configs ## -from isaaclab_assets.robots.franka import FRANKA_PANDA_CFG # isort: skip +from isaaclab_assets.robots.franka import FRANKA_PANDA_FLAT_CFG # isort: skip # Default arm + gripper joint pose _FRANKA_STACK_IK_REL_INIT_JOINT_POS: dict[str, float] = { @@ -51,7 +51,7 @@ def __post_init__(self): # Set Franka as robot self.scene.robot = replace( - FRANKA_PANDA_CFG, + FRANKA_PANDA_FLAT_CFG, prim_path="{ENV_REGEX_NS}/Robot", init_state=ArticulationCfg.InitialStateCfg(joint_pos=_FRANKA_STACK_IK_REL_INIT_JOINT_POS), ) @@ -76,11 +76,19 @@ def __post_init__(self): # End-effector frame (the shared cubes/spawns come from the base scene). self.scene.ee_frame = make_ee_frame_cfg( - base_prim_path="{ENV_REGEX_NS}/Robot/panda_link0", + base_prim_path="{ENV_REGEX_NS}/Robot/(Geometry/)?panda_link0", target_specs=[ - ("{ENV_REGEX_NS}/Robot/panda_hand", "end_effector", (0.0, 0.0, 0.1034)), - ("{ENV_REGEX_NS}/Robot/panda_rightfinger", "tool_rightfinger", (0.0, 0.0, 0.046)), - ("{ENV_REGEX_NS}/Robot/panda_leftfinger", "tool_leftfinger", (0.0, 0.0, 0.046)), + ("{ENV_REGEX_NS}/Robot/(Geometry/.*/)?panda_hand", "end_effector", (0.0, 0.0, 0.1034)), + ( + "{ENV_REGEX_NS}/Robot/(Geometry/.*/)?panda_rightfinger", + "tool_rightfinger", + (0.0, 0.0, 0.046), + ), + ( + "{ENV_REGEX_NS}/Robot/(Geometry/.*/)?panda_leftfinger", + "tool_leftfinger", + (0.0, 0.0, 0.046), + ), ], marker_scale=(0.1, 0.1, 0.1), ) diff --git a/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_joint_pos_instance_randomize_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_joint_pos_instance_randomize_env_cfg.py index c9700331c462..07b483953cd9 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_joint_pos_instance_randomize_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_joint_pos_instance_randomize_env_cfg.py @@ -25,7 +25,7 @@ # Pre-defined configs ## from isaaclab.markers.config import FRAME_MARKER_CFG # isort: skip -from isaaclab_assets.robots.franka import FRANKA_PANDA_CFG # isort: skip +from isaaclab_assets.robots.franka import FRANKA_PANDA_FLAT_CFG # isort: skip @configclass @@ -73,7 +73,7 @@ def __post_init__(self): self.events = EventCfg() # Set Franka as robot - self.scene.robot = replace(FRANKA_PANDA_CFG, prim_path="{ENV_REGEX_NS}/Robot") + self.scene.robot = replace(FRANKA_PANDA_FLAT_CFG, prim_path="{ENV_REGEX_NS}/Robot") # Set actions for the specific robot type (franka) self.actions.arm_action = mdp.JointPositionActionCfg( @@ -175,26 +175,26 @@ def __post_init__(self): marker_cfg.markers["frame"].scale = (0.1, 0.1, 0.1) marker_cfg.prim_path = "/Visuals/FrameTransformer" self.scene.ee_frame = FrameTransformerCfg( - prim_path="{ENV_REGEX_NS}/Robot/panda_link0", + prim_path="{ENV_REGEX_NS}/Robot/(Geometry/)?panda_link0", debug_vis=False, visualizer_cfg=marker_cfg, target_frames=[ FrameTransformerCfg.FrameCfg( - prim_path="{ENV_REGEX_NS}/Robot/panda_hand", + prim_path="{ENV_REGEX_NS}/Robot/(Geometry/.*/)?panda_hand", name="end_effector", offset=OffsetCfg( pos=[0.0, 0.0, 0.1034], ), ), FrameTransformerCfg.FrameCfg( - prim_path="{ENV_REGEX_NS}/Robot/panda_rightfinger", + prim_path="{ENV_REGEX_NS}/Robot/(Geometry/.*/)?panda_rightfinger", name="tool_rightfinger", offset=OffsetCfg( pos=(0.0, 0.0, 0.046), ), ), FrameTransformerCfg.FrameCfg( - prim_path="{ENV_REGEX_NS}/Robot/panda_leftfinger", + prim_path="{ENV_REGEX_NS}/Robot/(Geometry/.*/)?panda_leftfinger", name="tool_leftfinger", offset=OffsetCfg( pos=(0.0, 0.0, 0.046), diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/cabinet/config/franka/cabinet_direct_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/core/cabinet/config/franka/cabinet_direct_env_cfg.py index b6f5f3e16ef0..5c924518d1af 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/cabinet/config/franka/cabinet_direct_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/core/cabinet/config/franka/cabinet_direct_env_cfg.py @@ -9,7 +9,9 @@ from isaaclab.utils import configclass, replace -from isaaclab_assets.robots.franka import FRANKA_PANDA_CFG +from isaaclab_tasks.utils import preset + +from isaaclab_assets.robots.franka import FRANKA_PANDA_FLAT_CFG from ...cabinet_direct_env_cfg import CabinetDirectEnvCfg, CabinetDirectSceneCfg @@ -18,7 +20,12 @@ class FrankaCabinetDirectSceneCfg(CabinetDirectSceneCfg): """Direct-workflow cabinet scene configured for the Franka robot.""" - robot = replace(FRANKA_PANDA_CFG, prim_path="{ENV_REGEX_NS}/Robot") + robot = replace(FRANKA_PANDA_FLAT_CFG, prim_path="{ENV_REGEX_NS}/Robot") + # Drawer interaction only requires hand and fingertip contacts. + robot.spawn.variants = { + "Physics": preset(default="mujoco", isaacsim_physx="physx", physx="physx", ovphysx="physx"), + "Colliders": preset(default="gripper_only", arm_collisions="primitives"), + } @configclass diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/cabinet/config/franka/joint_pos_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/core/cabinet/config/franka/joint_pos_env_cfg.py index 11fb2caee420..63fa550dce65 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/cabinet/config/franka/joint_pos_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/core/cabinet/config/franka/joint_pos_env_cfg.py @@ -9,7 +9,9 @@ from isaaclab.sensors.frame_transformer import OffsetCfg from isaaclab.utils import configclass, replace -from isaaclab_assets.robots.franka import FRANKA_PANDA_CFG +from isaaclab_tasks.utils import preset + +from isaaclab_assets.robots.franka import FRANKA_PANDA_FLAT_CFG from ... import mdp from ...cabinet_env_cfg import FRAME_MARKER_SMALL_CFG, CabinetEnvCfg, CabinetSceneCfg @@ -19,28 +21,33 @@ class FrankaCabinetSceneCfg(CabinetSceneCfg): """Cabinet scene configured for the Franka robot.""" - robot = replace(FRANKA_PANDA_CFG, prim_path="{ENV_REGEX_NS}/Robot") + robot = replace(FRANKA_PANDA_FLAT_CFG, prim_path="{ENV_REGEX_NS}/Robot") + # Drawer interaction only requires hand and fingertip contacts. + robot.spawn.variants = { + "Physics": preset(default="mujoco", isaacsim_physx="physx", physx="physx", ovphysx="physx"), + "Colliders": preset(default="gripper_only", arm_collisions="primitives"), + } ee_frame = FrameTransformerCfg( - prim_path="{ENV_REGEX_NS}/Robot/panda_link0", + prim_path="{ENV_REGEX_NS}/Robot/(Geometry/)?panda_link0", debug_vis=False, visualizer_cfg=replace(FRAME_MARKER_SMALL_CFG, prim_path="/Visuals/EndEffectorFrameTransformer"), target_frames=[ FrameTransformerCfg.FrameCfg( - prim_path="{ENV_REGEX_NS}/Robot/panda_hand", + prim_path="{ENV_REGEX_NS}/Robot/(Geometry/.*/)?panda_hand", name="ee_tcp", offset=OffsetCfg( pos=(0.0, 0.0, 0.1034), ), ), FrameTransformerCfg.FrameCfg( - prim_path="{ENV_REGEX_NS}/Robot/panda_leftfinger", + prim_path="{ENV_REGEX_NS}/Robot/(Geometry/.*/)?panda_leftfinger", name="tool_leftfinger", offset=OffsetCfg( pos=(0.0, 0.0, 0.046), ), ), FrameTransformerCfg.FrameCfg( - prim_path="{ENV_REGEX_NS}/Robot/panda_rightfinger", + prim_path="{ENV_REGEX_NS}/Robot/(Geometry/.*/)?panda_rightfinger", name="tool_rightfinger", offset=OffsetCfg( pos=(0.0, 0.0, 0.046), diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/reach/config/franka/franka_reach_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/core/reach/config/franka/franka_reach_env_cfg.py index 1fb5f4847ea5..95059747f04a 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/reach/config/franka/franka_reach_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/core/reach/config/franka/franka_reach_env_cfg.py @@ -24,13 +24,19 @@ from isaaclab.devices.keyboard import Se3KeyboardCfg from isaaclab.devices.spacemouse import Se3SpaceMouseCfg from isaaclab.envs.mdp.actions.actions_cfg import DifferentialInverseKinematicsActionCfg +from isaaclab.managers import RewardTermCfg as RewTerm +from isaaclab.managers import SceneEntityCfg +from isaaclab.managers import TerminationTermCfg as DoneTerm from isaaclab.utils import configclass, replace from isaaclab_tasks.utils import PresetCfg, preset -from isaaclab_assets import FRANKA_PANDA_CFG, FRANKA_PANDA_MENAGERIE_CFG +## +# Pre-defined configs +## +from isaaclab_assets import FRANKA_PANDA_FLAT_CFG # isort: skip -from ...reach_env_cfg import ReachEnvCfg +from ...reach_env_cfg import ReachEnvCfg, RewardsCfg, TerminationsCfg ## # Environment configuration @@ -61,7 +67,9 @@ class FrankaArmActionCfg(PresetCfg): diffik, controller=replace(diffik.controller, use_relative_mode=False, ik_params={"lambda_val": 0.45}), body_offset=None, - scale=1.0, + # Normalize position actions around the center and half-spans of the commanded workspace. + scale=(0.15, 0.2, 0.175, 1.0, 1.0, 1.0, 1.0), + offset=(0.5, 0.0, 0.325, 0.0, 0.0, 0.0, 0.0), ) newton_ik: NewtonInverseKinematicsActionCfg = NewtonInverseKinematicsActionCfg( asset_name="robot", @@ -82,10 +90,32 @@ class FrankaArmActionCfg(PresetCfg): default: mdp.JointPositionActionCfg = joint_pos +@configclass +class FrankaReachRewardsCfg(RewardsCfg): + """Keep continuous pose-tracking rewards specific to Franka Reach.""" + + end_effector_position_tracking_fine_grained = RewTerm( + func=mdp.position_command_error_tanh, + weight=0.1, + params={"asset_cfg": SceneEntityCfg("robot", body_names="panda_hand"), "std": 0.1, "command_name": "ee_pose"}, + ) + success: RewTerm | None = None + + +@configclass +class FrankaReachTerminationsCfg(TerminationsCfg): + """Track Franka Reach success without ending the episode early.""" + + success: DoneTerm | None = None + + @configclass class FrankaReachEnvCfg(ReachEnvCfg): """Franka Reach configuration with selectable arm and physics presets.""" + rewards: FrankaReachRewardsCfg = FrankaReachRewardsCfg() + terminations: FrankaReachTerminationsCfg = FrankaReachTerminationsCfg() + def validate_config(self) -> None: """Validate the selected controller and physics backend.""" if isinstance(self.actions.arm_action, NewtonInverseKinematicsActionCfg) and not isinstance( @@ -96,14 +126,12 @@ def validate_config(self) -> None: def __post_init__(self): super().__post_init__() - # Use the collision-complete legacy asset in PhysX until the Menagerie asset is corrected. - self.scene.robot = replace(FRANKA_PANDA_MENAGERIE_CFG, prim_path="{ENV_REGEX_NS}/Robot") - self.scene.robot.spawn.usd_path = preset( - default=self.scene.robot.spawn.usd_path, - isaacsim_physx=FRANKA_PANDA_CFG.spawn.usd_path, - physx=FRANKA_PANDA_CFG.spawn.usd_path, - ovphysx=FRANKA_PANDA_CFG.spawn.usd_path, - ) + # Reach has no robot-scene contact objective, so use the fast gripper collider preset. + self.scene.robot = replace(FRANKA_PANDA_FLAT_CFG, prim_path="{ENV_REGEX_NS}/Robot") + self.scene.robot.spawn.variants = { + "Physics": preset(default="mujoco", isaacsim_physx="physx", physx="physx", ovphysx="physx"), + "Colliders": preset(default="gripper_only", arm_collisions="primitives"), + } # IK targets need backend-native gravity control to hold steady between commands. self.scene.robot.spawn.rigid_props = [ PhysxRigidBodyCfg( diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/reach/config/franka/franka_reach_osc_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/core/reach/config/franka/franka_reach_osc_env_cfg.py index 09c6d8fab2cd..63739cafde7e 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/reach/config/franka/franka_reach_osc_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/core/reach/config/franka/franka_reach_osc_env_cfg.py @@ -42,13 +42,18 @@ def __post_init__(self): super().__post_init__() # Use an explicit actuator to enforce the USD-authored effort limits for effort control. Keep the - # asset's solver velocity limit: the Menagerie USD authors none, so dropping it leaves the arm unbounded. + # asset's solver velocity limit: the canonical USD authors none, so dropping it leaves the arm unbounded. arm_actuator = self.scene.robot.actuators["panda_arm"] self.scene.robot.actuators["panda_arm"] = IdealPDActuatorCfg( joint_names_expr=arm_actuator.joint_names_expr, + joint_effort_limit=arm_actuator.joint_effort_limit, joint_velocity_limit=arm_actuator.joint_velocity_limit, stiffness=0.0, damping=0.0, + armature=arm_actuator.armature, + friction=arm_actuator.friction, + dynamic_friction=arm_actuator.dynamic_friction, + viscous_friction=arm_actuator.viscous_friction, ) for rigid_props in self.scene.robot.spawn.rigid_props: if isinstance(rigid_props, PhysxRigidBodyCfg): diff --git a/source/isaaclab_tasks/test/benchmark/test_render_benchmark_cfg.py b/source/isaaclab_tasks/test/benchmark/test_render_benchmark_cfg.py index 29f4b018c052..e836f2eba01b 100644 --- a/source/isaaclab_tasks/test/benchmark/test_render_benchmark_cfg.py +++ b/source/isaaclab_tasks/test/benchmark/test_render_benchmark_cfg.py @@ -155,18 +155,19 @@ def test_benchmark_mode_orders_joint_updates_and_rendering(mode): @pytest.mark.parametrize( - ("presets", "expected_type"), + ("presets", "expected_type", "expected_asset_physics"), [ - ((), NewtonCfg), - (("physx",), PhysxAutoCfg), - (("isaacsim_physx",), PhysxCfg), - (("ovphysx",), OvPhysxCfg), + ((), NewtonCfg, "mujoco"), + (("physx",), PhysxAutoCfg, "physx"), + (("isaacsim_physx",), PhysxCfg, "physx"), + (("ovphysx",), OvPhysxCfg, "physx"), ], ) -def test_physics_presets_resolve_to_expected_backend(presets, expected_type): +def test_physics_presets_resolve_to_expected_backend(presets, expected_type, expected_asset_physics): cfg = resolve_presets(_load_cfg(), selected=presets) assert isinstance(cfg.sim.physics, expected_type) + assert cfg.scene.robot.spawn.variants["Physics"] == expected_asset_physics @pytest.mark.parametrize("physics_preset", ["ovphysx", "physx"]) diff --git a/source/isaaclab_tasks/test/contrib/test_franka_pour_env_cfg.py b/source/isaaclab_tasks/test/contrib/test_franka_pour_env_cfg.py index 4e80cafc5d71..1728396c2f9a 100644 --- a/source/isaaclab_tasks/test/contrib/test_franka_pour_env_cfg.py +++ b/source/isaaclab_tasks/test/contrib/test_franka_pour_env_cfg.py @@ -113,7 +113,7 @@ def test_reset_dataset_contract_stores_root_relative_robot_asset_path(): robot_asset = _reset_dataset_task_contract(cfg)["robot_asset"] assert robot_asset == "Robots/FrankaEmika/franka_panda.usda" assert f"{ISAACLAB_NUCLEUS_DIR}/{robot_asset}" == FRANKA_POUR_ROBOT_ASSET_ID - assert cfg.scene.robot.spawn.variants == {"Colliders": "convex_hulls"} + assert cfg.scene.robot.spawn.variants == {"Physics": "mujoco", "Colliders": "convex_hulls"} def test_capacity_resolution_only_updates_world_dependent_solver_limits(): diff --git a/source/isaaclab_tasks/test/core/test_reach_franka_presets.py b/source/isaaclab_tasks/test/core/test_reach_franka_presets.py index dcb0fe7f7728..05f10be6fec6 100644 --- a/source/isaaclab_tasks/test/core/test_reach_franka_presets.py +++ b/source/isaaclab_tasks/test/core/test_reach_franka_presets.py @@ -22,11 +22,26 @@ from isaaclab_tasks.utils.preset_cli import enumerate_task_presets from isaaclab_tasks.utils.preset_target import PresetTarget -from isaaclab_assets import FRANKA_PANDA_MENAGERIE_CFG +from isaaclab_assets import FRANKA_PANDA_FLAT_CFG _TASK = "Isaac-Reach-Franka" _OSC_TASK = "Isaac-Reach-Franka-OSC" _CONTRIB_DIFFIK_ABS_TASK = "IsaacContrib-Reach-Franka-IK-Abs" +_RIGID_FRANKA_TASKS = ( + _TASK, + _OSC_TASK, + "Isaac-Open-Drawer-Franka", + "Isaac-Open-Drawer-Franka-Direct", + "Isaac-Lift-Franka", +) +_SOFT_FRANKA_TASKS = ( + "Isaac-Lift-Soft-Franka", + "Isaac-Lift-Cloth-Franka", + "Isaac-Lift-Cable-Franka", + "Isaac-Lift-Soft-Franka-Camera", + "Isaac-Lift-Cloth-Franka-Camera", + "Isaac-Lift-Cable-Franka-Camera", +) def _load_env_cfg(*presets: str): @@ -48,6 +63,28 @@ def _without_controller_dependent_cfg(cfg): return cfg_dict +@pytest.mark.parametrize("task", _RIGID_FRANKA_TASKS + _SOFT_FRANKA_TASKS) +def test_franka_tasks_select_the_canonical_asset_and_backend_payload(task): + default_cfg = _load_reach_env_cfg(task) + physx_cfg = _load_reach_env_cfg(task, "isaacsim_physx") + + for cfg, physics_variant in ((default_cfg, "mujoco"), (physx_cfg, "physx")): + assert cfg.scene.robot.spawn.usd_path == FRANKA_PANDA_FLAT_CFG.spawn.usd_path + assert cfg.scene.robot.spawn.variants == { + "Physics": physics_variant, + "Colliders": "gripper_only", + } + + +@pytest.mark.parametrize("task", _RIGID_FRANKA_TASKS) +def test_rigid_franka_arm_collisions_are_an_independent_domain_preset(task): + newton_cfg = _load_reach_env_cfg(task, "arm_collisions") + physx_cfg = _load_reach_env_cfg(task, "arm_collisions", "isaacsim_physx") + + assert newton_cfg.scene.robot.spawn.variants == {"Physics": "mujoco", "Colliders": "primitives"} + assert physx_cfg.scene.robot.spawn.variants == {"Physics": "physx", "Colliders": "primitives"} + + def test_reach_diffik_abs_legacy_task_is_a_deprecated_alias(): spec = registry[_CONTRIB_DIFFIK_ABS_TASK] @@ -95,6 +132,10 @@ def test_reach_ur10_physics_presets_change_only_physics(): physx = _load_reach_env_cfg("Isaac-Reach-UR10", "isaacsim_physx") newton = _load_reach_env_cfg("Isaac-Reach-UR10", "newton_mjwarp") + assert physx.rewards.success.func is mdp.is_terminated_term + assert physx.terminations.success.func is mdp.pose_command_success + assert not hasattr(physx.rewards, "end_effector_position_tracking_fine_grained") + physx_cfg = to_dict(physx) newton_cfg = to_dict(newton) physx_cfg["sim"].pop("physics") @@ -136,7 +177,24 @@ def test_reach_diffik_physx_configures_teleop_physics(): assert physx_props.max_depenetration_velocity == pytest.approx(5.0) assert not cfg.scene.robot.spawn.make_uninstanceable assert cfg.scene.robot.spawn.collision_props is None - assert cfg.scene.robot.spawn.usd_path.endswith("/FrankaEmika/Legacy/panda_instanceable.usd") + assert cfg.scene.robot.spawn.usd_path.endswith("/FrankaEmika/franka_panda.usda") + assert cfg.scene.robot.spawn.variants == {"Physics": "physx", "Colliders": "gripper_only"} + + +def test_reach_diffik_abs_normalizes_position_actions_to_command_workspace(): + cfg = _load_env_cfg("diffik_abs", "isaacsim_physx") + action = cfg.actions.arm_action + ranges = cfg.commands.ee_pose.ranges + + position_scale = torch.tensor(action.scale[:3]) + position_offset = torch.tensor(action.offset[:3]) + expected_lower = torch.tensor([ranges.pos_x[0], ranges.pos_y[0], ranges.pos_z[0]]) + expected_upper = torch.tensor([ranges.pos_x[1], ranges.pos_y[1], ranges.pos_z[1]]) + + torch.testing.assert_close(position_offset - position_scale, expected_lower) + torch.testing.assert_close(position_offset + position_scale, expected_upper) + assert action.scale[3:] == (1.0, 1.0, 1.0, 1.0) + assert action.offset[3:] == (0.0, 0.0, 0.0, 0.0) def test_reach_newton_ik_configures_gravity_compensation(): @@ -146,6 +204,7 @@ def test_reach_newton_ik_configures_gravity_compensation(): mujoco_props = next(props for props in rigid_props if isinstance(props, MujocoRigidBodyCfg)) assert mujoco_props.gravcomp == pytest.approx(1.0) assert cfg.scene.robot.spawn.usd_path.endswith("/FrankaEmika/franka_panda.usda") + assert cfg.scene.robot.spawn.variants == {"Physics": "mujoco", "Colliders": "gripper_only"} # Native SE(3) command convention: one relative 6-DoF pose objective. pose_objectives = [ @@ -163,17 +222,17 @@ def test_reach_default_preset_does_not_configure_se3_teleop_devices(): assert cfg.teleop_devices.devices == {} -def test_reach_success_requires_position_and_orientation(): +def test_reach_tracks_success_without_terminating(): cfg = _load_env_cfg() - success = cfg.terminations.success assert cfg.commands.ee_pose.position_success_threshold == pytest.approx(0.05) assert cfg.commands.ee_pose.orientation_success_threshold == pytest.approx(0.2) - assert success.func is mdp.pose_command_success - assert success.params == {"command_name": "ee_pose"} - assert cfg.rewards.success.func.__name__ == "is_terminated_term" - assert cfg.rewards.success.weight == pytest.approx(10.0) - assert cfg.rewards.success.params == {"term_keys": ["success"]} + assert cfg.terminations.success is None + assert cfg.terminations.time_out.func is mdp.time_out + assert cfg.rewards.success is None + assert cfg.rewards.end_effector_position_tracking_fine_grained.func is mdp.position_command_error_tanh + assert cfg.rewards.end_effector_position_tracking_fine_grained.weight == pytest.approx(0.1) + assert cfg.rewards.end_effector_position_tracking_fine_grained.params["std"] == pytest.approx(0.1) angles = torch.tensor([0.19, 0.19, 0.21]) body_quaternions = torch.zeros(3, 1, 4) @@ -197,32 +256,32 @@ def test_reach_success_requires_position_and_orientation(): command._track_success = True command._succeeded = torch.zeros(3, dtype=torch.bool) - class CommandManager: - def get_term(self, name): - assert name == "ee_pose" - return command - - env = SimpleNamespace(command_manager=CommandManager()) - succeeded = mdp.pose_command_success(env, **success.params) + succeeded = command.compute_success() assert torch.equal(succeeded, torch.tensor([True, False, False])) assert torch.equal(command._succeeded, succeeded) command.cfg = replace(command.cfg, orientation_success_threshold=None) command._succeeded.zero_() - position_only_succeeded = mdp.pose_command_success(env, **success.params) + position_only_succeeded = command.compute_success() assert torch.equal(position_only_succeeded, torch.tensor([True, False, True])) -def test_reach_osc_effort_actuator_keeps_menagerie_velocity_limit(): - """The zero-gain effort actuator must keep the asset's solver velocity limit; the USD authors none.""" +def test_reach_osc_effort_actuator_keeps_canonical_solver_properties(): + """Replacing the arm actuator with a zero-gain effort model must preserve its solver properties.""" cfg = _load_reach_env_cfg(_OSC_TASK) arm_actuator = cfg.scene.robot.actuators["panda_arm"] + source_actuator = FRANKA_PANDA_FLAT_CFG.actuators["panda_arm"] assert isinstance(arm_actuator, IdealPDActuatorCfg) assert arm_actuator.stiffness == 0.0 and arm_actuator.damping == 0.0 - assert arm_actuator.joint_velocity_limit == FRANKA_PANDA_MENAGERIE_CFG.actuators["panda_arm"].joint_velocity_limit + assert arm_actuator.joint_effort_limit == source_actuator.joint_effort_limit + assert arm_actuator.joint_velocity_limit == source_actuator.joint_velocity_limit + assert arm_actuator.armature == source_actuator.armature + assert arm_actuator.friction == source_actuator.friction + assert arm_actuator.dynamic_friction == source_actuator.dynamic_friction + assert arm_actuator.viscous_friction == source_actuator.viscous_friction def test_reach_osc_resolves_controller_preset_values_to_defaults(): @@ -240,7 +299,7 @@ def test_reach_osc_resolves_controller_preset_values_to_defaults(): assert physx_props.disable_gravity is True assert mujoco_props.gravcomp == pytest.approx(1.0) assert cfg.teleop_devices.devices == {} - assert domain_presets == {"diffik_abs"} + assert domain_presets == {"arm_collisions", "diffik_abs"} def test_reach_osc_diffik_abs_is_a_deprecated_no_op_alias(): From a221ff411206b735ecb3b24ca148f8018a83f8b2 Mon Sep 17 00:00:00 2001 From: Maximilian Krause Date: Tue, 29 Sep 2026 19:16:15 +0200 Subject: [PATCH 2/4] Update Franka environment browser presets --- docs/source/_static/css/environment-browser.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/source/_static/css/environment-browser.js b/docs/source/_static/css/environment-browser.js index 1bd8f03505b5..6ef9788869c6 100644 --- a/docs/source/_static/css/environment-browser.js +++ b/docs/source/_static/css/environment-browser.js @@ -30,11 +30,11 @@ ["Isaac-Lift-KukaAllegro-Camera", "rsl_rl", "isaacsim_physx,newton_mjwarp,ovphysx", "isaacsim_rtx,newton_renderer,ovrtx", "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", "tasks/manipulation/kuka_allegro_lift.jpg", false, {"*": ["rgb64", "shapes", "single_camera"]}], ["Isaac-Lift-Soft-Franka", "rsl_rl", "isaacsim_physx,newton_mjwarp_vbd_proxy", "", "ik,joint", "newton/franka-mjwarp-vbd-coupling.png", false, {"*": ["joint"]}, {}, "tetrahedralization"], ["Isaac-Lift-Soft-Franka-Camera", "rsl_rl", "isaacsim_physx,newton_mjwarp_vbd_proxy", "isaacsim_rtx,newton_renderer,ovrtx", "ik,joint", "newton/franka-mjwarp-vbd-coupling.png", false, {"*": ["joint"]}, {}, "tetrahedralization"], - ["Isaac-Open-Drawer-Franka-Direct", "rl_games,rsl_rl,skrl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "", "tasks/manipulation/franka_open_drawer.jpg"], - ["Isaac-Open-Drawer-Franka", "rl_games,rsl_rl,skrl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "", "tasks/manipulation/franka_open_drawer.jpg"], + ["Isaac-Open-Drawer-Franka-Direct", "rl_games,rsl_rl,skrl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "arm_collisions", "tasks/manipulation/franka_open_drawer.jpg"], + ["Isaac-Open-Drawer-Franka", "rl_games,rsl_rl,skrl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "arm_collisions", "tasks/manipulation/franka_open_drawer.jpg"], ["Isaac-Pendulum-MARL-Direct", "rl_games,skrl", "isaacsim_physx,newton_kamino,newton_mjwarp,ovphysx", "", "", "tasks/classic/cart_double_pendulum.jpg", false, {}, {"skrl": "MAPPO"}], - ["Isaac-Reach-Franka", "rl_games,rsl_rl,skrl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "diffik,diffik_abs,joint_pos,newton_ik", "tasks/manipulation/franka_reach.jpg", true, {"*": ["joint_pos"]}], - ["Isaac-Reach-Franka-OSC", "rsl_rl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "diffik_abs", "tasks/manipulation/franka_reach.jpg", false, {"*": ["diffik_abs"]}], + ["Isaac-Reach-Franka", "rl_games,rsl_rl,skrl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "arm_collisions,diffik,diffik_abs,joint_pos,newton_ik", "tasks/manipulation/franka_reach.jpg", true, {"*": ["joint_pos"]}], + ["Isaac-Reach-Franka-OSC", "rsl_rl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "arm_collisions,diffik_abs", "tasks/manipulation/franka_reach.jpg", false, {"*": ["diffik_abs"]}], ["Isaac-Reach-UR10", "rl_games,rsl_rl,skrl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "", "tasks/manipulation/ur10_reach.jpg", true], ["Isaac-RenderBenchmark-Franka-Cabinet", "", "isaacsim_physx,newton_mjwarp,ovphysx", "isaacsim_rtx,newton_renderer,ovrtx", "albedo,depth,rgb,simple_shading_constant_diffuse,simple_shading_diffuse_mdl,simple_shading_full_mdl", "", false, {"*": ["rgb"]}], ["Isaac-Reorient-Cube-Allegro-Direct", "rl_games,rsl_rl,skrl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "", "tasks/manipulation/allegro_cube.jpg", true], @@ -91,12 +91,12 @@ ["IsaacContrib-Lift-Cube-Franka-IK-Abs", "", "", "", "", "tasks/manipulation/franka_lift.jpg"], ["IsaacContrib-Lift-Cube-Franka-IK-Rel", "", "", "", "", "tasks/manipulation/franka_lift.jpg"], ["IsaacContrib-Lift-Cube-OpenArm", "rl_games,rsl_rl", "", "", "", "tasks/manipulation/openarm_uni_lift.jpg"], - ["IsaacContrib-Multitask-Manipulation", "rsl_rl", "", "", "", "tasks/manipulation/multitask_manipulation.jpg"], + ["IsaacContrib-Multitask-Manipulation", "rsl_rl", "", "", "arm_collisions", "tasks/manipulation/multitask_manipulation.jpg"], ["IsaacContrib-Navigation-3DObstacles-ARL-Robot-1", "rl_games,rsl_rl,skrl", "", "", "", "tasks/drone_arl/arl_robot_1_navigation.jpg"], ["IsaacContrib-Navigation-Flat-AnymalC", "rsl_rl,skrl", "", "", "", "tasks/navigation/anymal_c_nav.jpg"], ["IsaacContrib-NutPour-GR1T2-Pink-IK-Abs", "", "", "", ""], - ["IsaacContrib-Open-Drawer-Franka-IK-Abs", "rsl_rl", "isaacsim_physx,newton_mjwarp,ovphysx", "", ""], - ["IsaacContrib-Open-Drawer-Franka-IK-Rel", "rsl_rl", "isaacsim_physx,newton_mjwarp,ovphysx", "", ""], + ["IsaacContrib-Open-Drawer-Franka-IK-Abs", "rsl_rl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "arm_collisions"], + ["IsaacContrib-Open-Drawer-Franka-IK-Rel", "rsl_rl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "arm_collisions"], ["IsaacContrib-Open-Drawer-OpenArm", "rl_games,rsl_rl", "", "", "", "tasks/manipulation/openarm_uni_open_drawer.jpg"], ["IsaacContrib-PickPlace-FixedBaseUpperBodyIK-G1-Abs", "", "", "isaacsim_rtx,newton_renderer,ovrtx", "", "tasks/manipulation/g1_pick_place_fixed_base.jpg"], ["IsaacContrib-PickPlace-G1-InspireFTP-Abs", "", "", "", "", "tasks/manipulation/g1_pick_place.jpg"], From 683e886e7e81a73c9ea08ed77633546e6163b113 Mon Sep 17 00:00:00 2001 From: Maximilian Krause Date: Tue, 29 Sep 2026 19:19:44 +0200 Subject: [PATCH 3/4] Verify backend payload selection for cabinet IK --- .../test/core/test_preset_kit_decision.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/source/isaaclab_tasks/test/core/test_preset_kit_decision.py b/source/isaaclab_tasks/test/core/test_preset_kit_decision.py index 5d9a125df4f4..544a8c888b6b 100644 --- a/source/isaaclab_tasks/test/core/test_preset_kit_decision.py +++ b/source/isaaclab_tasks/test/core/test_preset_kit_decision.py @@ -23,7 +23,7 @@ import isaaclab_tasks # noqa: F401 from isaaclab_tasks.utils import resolve_task_config -from isaaclab_tasks.utils.hydra import collect_presets +from isaaclab_tasks.utils.hydra import collect_presets, resolve_presets from isaaclab_tasks.utils.parse_cfg import load_cfg_from_registry from isaaclab_tasks.utils.preset_cli import enumerate_task_presets from isaaclab_tasks.utils.preset_target import PresetTarget @@ -127,6 +127,20 @@ def test_registered_task_physx_presets_keep_auto_selection_explicit(): assert fields.get("isaacsim_physx") == fields["physx"], location +@pytest.mark.parametrize( + "task_id", ["IsaacContrib-Open-Drawer-Franka-IK-Abs", "IsaacContrib-Open-Drawer-Franka-IK-Rel"] +) +@pytest.mark.parametrize( + ("physics_preset", "expected_asset_physics"), + [("newton_mjwarp", "mujoco"), ("isaacsim_physx", "physx"), ("ovphysx", "physx")], +) +def test_franka_cabinet_ik_asset_variant_matches_backend(task_id, physics_preset, expected_asset_physics): + """The IK robot override retains the cabinet task's backend-aware asset selection.""" + cfg = resolve_presets(load_cfg_from_registry(task_id, "env_cfg_entry_point"), selected=(physics_preset,)) + + assert cfg.scene.robot.spawn.variants["Physics"] == expected_asset_physics + + def test_registered_manager_based_configs_name_their_env_class(): """A manager-based task's ``class_type`` constructs the env class its registration names.""" From 8cf024030cc9d60c3a5882b7d0254c076e83659e Mon Sep 17 00:00:00 2001 From: Maximilian Krause Date: Tue, 29 Sep 2026 19:24:01 +0200 Subject: [PATCH 4/4] Scope shared-asset tests to migrated rigid tasks --- .../test/core/test_reach_franka_presets.py | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/source/isaaclab_tasks/test/core/test_reach_franka_presets.py b/source/isaaclab_tasks/test/core/test_reach_franka_presets.py index 05f10be6fec6..21794de95c49 100644 --- a/source/isaaclab_tasks/test/core/test_reach_franka_presets.py +++ b/source/isaaclab_tasks/test/core/test_reach_franka_presets.py @@ -32,15 +32,6 @@ _OSC_TASK, "Isaac-Open-Drawer-Franka", "Isaac-Open-Drawer-Franka-Direct", - "Isaac-Lift-Franka", -) -_SOFT_FRANKA_TASKS = ( - "Isaac-Lift-Soft-Franka", - "Isaac-Lift-Cloth-Franka", - "Isaac-Lift-Cable-Franka", - "Isaac-Lift-Soft-Franka-Camera", - "Isaac-Lift-Cloth-Franka-Camera", - "Isaac-Lift-Cable-Franka-Camera", ) @@ -63,7 +54,7 @@ def _without_controller_dependent_cfg(cfg): return cfg_dict -@pytest.mark.parametrize("task", _RIGID_FRANKA_TASKS + _SOFT_FRANKA_TASKS) +@pytest.mark.parametrize("task", _RIGID_FRANKA_TASKS) def test_franka_tasks_select_the_canonical_asset_and_backend_payload(task): default_cfg = _load_reach_env_cfg(task) physx_cfg = _load_reach_env_cfg(task, "isaacsim_physx")