diff --git a/docs/source/_static/css/environment-browser.js b/docs/source/_static/css/environment-browser.js index 1bd8f03505b5..472ac168f50a 100644 --- a/docs/source/_static/css/environment-browser.js +++ b/docs/source/_static/css/environment-browser.js @@ -25,7 +25,7 @@ ["Isaac-Lift-Cable-Franka-Camera", "rsl_rl", "newton_mjwarp_vbd_proxy", "isaacsim_rtx,newton_renderer,ovrtx", "ik,joint", "tasks/manipulation/franka_lift_cable.jpg", false, {"*": ["joint"]}], ["Isaac-Lift-Cloth-Franka", "rsl_rl", "isaacsim_physx,newton_mjwarp_vbd_proxy", "", "ik,joint", "tasks/manipulation/franka_lift_cloth.jpg", false, {"*": ["joint"]}], ["Isaac-Lift-Cloth-Franka-Camera", "rsl_rl", "isaacsim_physx,newton_mjwarp_vbd_proxy", "isaacsim_rtx,newton_renderer,ovrtx", "ik,joint", "tasks/manipulation/franka_lift_cloth.jpg", false, {"*": ["joint"]}], - ["Isaac-Lift-Franka", "rsl_rl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "cube,shapes", "", false, {"*": ["shapes"]}], + ["Isaac-Lift-Franka", "rsl_rl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "cube,minimal,shapes", "", false, {"*": ["shapes"]}], ["Isaac-Lift-KukaAllegro", "rsl_rl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "cube,shapes", "tasks/manipulation/kuka_allegro_lift.jpg", false, {"*": ["shapes"]}], ["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"], @@ -33,8 +33,8 @@ ["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-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", "", "diffik,diffik_abs,joint_pos,minimal,newton_ik", "tasks/manipulation/franka_reach.jpg", true, {"*": ["joint_pos"]}], + ["Isaac-Reach-Franka-OSC", "rsl_rl", "isaacsim_physx,newton_mjwarp,ovphysx", "", "diffik_abs,minimal", "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], diff --git a/examples/haply_teleoperation.py b/examples/haply_teleoperation.py index 129d9fa3e674..6408287f330d 100644 --- a/examples/haply_teleoperation.py +++ b/examples/haply_teleoperation.py @@ -131,6 +131,7 @@ class FrankaHaplySceneCfg(InteractiveSceneCfg): 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 ded79b628ec6..269301a30c2f 100644 --- a/scripts/tutorials/05_controllers/run_diff_ik.py +++ b/scripts/tutorials/05_controllers/run_diff_ik.py @@ -9,6 +9,9 @@ The differential IK controller can be configured in different modes. It uses the Jacobians computed by PhysX. This helps perform parallelized computation of the inverse kinematics. +The Franka high-PD preset uses the same USD and effort limits as the base preset, with stiffer gains +for tracking IK targets. Other tasks can retain their calibrated actuator gains. + .. code-block:: bash # Usage @@ -53,7 +56,7 @@ ## # Pre-defined configs ## -from isaaclab_assets import FRANKA_PANDA_LEGACY_HIGH_PD_CFG, UR10_CFG # isort:skip +from isaaclab_assets import FRANKA_PANDA_HIGH_PD_CFG, UR10_CFG # isort:skip @configclass @@ -82,7 +85,8 @@ class TableTopSceneCfg(InteractiveSceneCfg): # articulation if args_cli.robot == "franka_panda": - robot = replace(FRANKA_PANDA_LEGACY_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") + robot = replace(FRANKA_PANDA_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") + robot.spawn.variants["Physics"] = "physx" 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 d1769389c14a..5a0266957b61 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_LEGACY_HIGH_PD_CFG # isort:skip +from isaaclab_assets import FRANKA_PANDA_HIGH_PD_CFG # isort:skip @configclass @@ -97,11 +97,10 @@ class SceneCfg(InteractiveSceneCfg): debug_vis=False, ) - robot = replace(FRANKA_PANDA_LEGACY_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_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") + robot.spawn.variants["Physics"] = "physx" + 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.added.rst b/source/isaaclab/changelog.d/maximiliank-diffik-action-offset.added.rst new file mode 100644 index 000000000000..91e4e0e728c9 --- /dev/null +++ b/source/isaaclab/changelog.d/maximiliank-diffik-action-offset.added.rst @@ -0,0 +1,2 @@ +* 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/changelog.d/maximiliank-diffik-action-offset.minor b/source/isaaclab/changelog.d/maximiliank-diffik-action-offset.minor new file mode 100644 index 000000000000..e69de29bb2d1 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 6d039894c528..afceba8dbd87 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 2b2af9e3ba68..4b91b1158cff 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_LEGACY_HIGH_PD_CFG, UR10_CFG # isort:skip +from isaaclab_assets import FRANKA_PANDA_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_LEGACY_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") + robot_cfg = replace(FRANKA_PANDA_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 2e7a3e4b09a9..76ed5a42165f 100644 --- a/source/isaaclab/test/controllers/test_operational_space.py +++ b/source/isaaclab/test/controllers/test_operational_space.py @@ -95,6 +95,7 @@ def sim(): # clone the env xform cloner.usd_replicate(stage, [env_fmt.format(0)], [env_fmt], env_ids, positions=env_origins) + # 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"): diff --git a/source/isaaclab/test/envs/test_diffik_jacobian_aliasing.py b/source/isaaclab/test/envs/test_diffik_jacobian_aliasing.py index 4193f3e90fc8..4453491e0812 100644 --- a/source/isaaclab/test/envs/test_diffik_jacobian_aliasing.py +++ b/source/isaaclab/test/envs/test_diffik_jacobian_aliasing.py @@ -3,7 +3,7 @@ # # SPDX-License-Identifier: BSD-3-Clause -"""Regression tests for task-space body offsets and DiffIK Jacobian aliasing (NVBug 6043099). +"""Tests for task-space action processing, body offsets, and Jacobian aliasing (NVBug 6043099). ``DifferentialInverseKinematicsAction._compute_frame_jacobian`` historically aliased the parent Jacobian and applied the body-offset correction in place. @@ -19,6 +19,8 @@ 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, OperationalSpaceControllerAction, @@ -63,6 +65,41 @@ def _make_stub(num_envs: int, num_joints: int, body_offset_pos, body_offset_rot, return _Stub(num_envs, num_joints, body_offset_pos, body_offset_rot, backing_buffer) +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) + + def test_compute_frame_jacobian_is_idempotent_within_step(): """Two consecutive calls under the same state must return identical Jacobians. diff --git a/source/isaaclab_assets/changelog.d/franka-collision-configs.added.rst b/source/isaaclab_assets/changelog.d/franka-collision-configs.added.rst new file mode 100644 index 000000000000..96bf616c60a6 --- /dev/null +++ b/source/isaaclab_assets/changelog.d/franka-collision-configs.added.rst @@ -0,0 +1,2 @@ +* Added ``FRANKA_MINIMAL_CFG`` using the same USD and actuator settings as ``FRANKA_PANDA_CFG`` with only + hand and fingertip colliders for applications that do not need arm contacts. diff --git a/source/isaaclab_assets/changelog.d/franka-collision-configs.changed.rst b/source/isaaclab_assets/changelog.d/franka-collision-configs.changed.rst new file mode 100644 index 000000000000..8b01bedc5921 --- /dev/null +++ b/source/isaaclab_assets/changelog.d/franka-collision-configs.changed.rst @@ -0,0 +1,3 @@ +* **Breaking:** Enabled full primitive arm and gripper collisions in ``FRANKA_PANDA_CFG`` and its high-PD + derivative. Use ``FRANKA_MINIMAL_CFG`` or select ``Colliders=gripper_only`` to retain the previous reduced + collision scope. Requalify policies against the chosen robot configuration. diff --git a/source/isaaclab_assets/changelog.d/franka-collision-configs.major b/source/isaaclab_assets/changelog.d/franka-collision-configs.major new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/source/isaaclab_assets/isaaclab_assets/__init__.pyi b/source/isaaclab_assets/isaaclab_assets/__init__.pyi index 60581e12024f..5eecf4fbe84b 100644 --- a/source/isaaclab_assets/isaaclab_assets/__init__.pyi +++ b/source/isaaclab_assets/isaaclab_assets/__init__.pyi @@ -22,6 +22,7 @@ __all__ = [ "GR1T2_CFG", "GR1T2_HIGH_PD_CFG", "FRANKA_PANDA_CFG", + "FRANKA_MINIMAL_CFG", "FRANKA_PANDA_LEGACY_CFG", "FRANKA_PANDA_LEGACY_HIGH_PD_CFG", "FRANKA_PANDA_HIGH_PD_CFG", @@ -91,6 +92,7 @@ from .robots import ( GR1T2_CFG, GR1T2_HIGH_PD_CFG, FRANKA_PANDA_CFG, + FRANKA_MINIMAL_CFG, FRANKA_PANDA_LEGACY_CFG, FRANKA_PANDA_LEGACY_HIGH_PD_CFG, FRANKA_PANDA_HIGH_PD_CFG, diff --git a/source/isaaclab_assets/isaaclab_assets/robots/__init__.pyi b/source/isaaclab_assets/isaaclab_assets/robots/__init__.pyi index 11b23110e810..553e588acb41 100644 --- a/source/isaaclab_assets/isaaclab_assets/robots/__init__.pyi +++ b/source/isaaclab_assets/isaaclab_assets/robots/__init__.pyi @@ -22,6 +22,7 @@ __all__ = [ "GR1T2_CFG", "GR1T2_HIGH_PD_CFG", "FRANKA_PANDA_CFG", + "FRANKA_MINIMAL_CFG", "FRANKA_PANDA_LEGACY_CFG", "FRANKA_PANDA_LEGACY_HIGH_PD_CFG", "FRANKA_PANDA_HIGH_PD_CFG", @@ -84,6 +85,7 @@ from .cassie import CASSIE_CFG from .fourier import GR1T2_CFG, GR1T2_HIGH_PD_CFG from .franka import ( FRANKA_PANDA_CFG, + FRANKA_MINIMAL_CFG, FRANKA_PANDA_LEGACY_CFG, FRANKA_PANDA_LEGACY_HIGH_PD_CFG, FRANKA_PANDA_HIGH_PD_CFG, diff --git a/source/isaaclab_assets/isaaclab_assets/robots/franka.py b/source/isaaclab_assets/isaaclab_assets/robots/franka.py index 8084402b2eee..d3253150b44d 100644 --- a/source/isaaclab_assets/isaaclab_assets/robots/franka.py +++ b/source/isaaclab_assets/isaaclab_assets/robots/franka.py @@ -8,6 +8,7 @@ The following configurations are available: * :obj:`FRANKA_PANDA_CFG`: Shared flat asset for maintained Franka tasks +* :obj:`FRANKA_MINIMAL_CFG`: Shared asset with gripper-only colliders * :obj:`FRANKA_PANDA_HIGH_PD_CFG`: Flat asset with stiffer PD control * :obj:`FRANKA_PANDA_LEGACY_CFG`: Legacy asset and actuators * :obj:`FRANKA_PANDA_LEGACY_HIGH_PD_CFG`: Legacy high-PD configuration @@ -98,7 +99,7 @@ FRANKA_PANDA_CFG = ArticulationCfg( spawn=sim_utils.UsdFileCfg( usd_path=f"{ISAACLAB_NUCLEUS_DIR}/Robots/FrankaEmika/franka_panda.usda", - variants={"Physics": "physx", "Colliders": "gripper_only"}, + variants={"Physics": "physx", "Colliders": "primitives"}, activate_contact_sensors=False, rigid_props=PhysxRigidBodyCfg(disable_gravity=False, max_depenetration_velocity=5.0), articulation_props=[ @@ -138,13 +139,23 @@ """Configuration of the Franka Emika Panda robot. The flat asset contains PhysX and MuJoCo physics variants and gripper-only, primitive, and convex-hull -collider variants. The gripper-only collider variant is the default. Explicit solver properties keep +collider variants. Full primitive arm and gripper collisions are enabled by default. Explicit solver properties keep the actuator contract consistent across physics payloads. Only the leading finger has an active drive; the authored mimic constraint moves the passive follower. The standalone configuration selects the PhysX payload by default; direct Newton consumers must select the ``mujoco`` physics variant explicitly. """ +FRANKA_MINIMAL_CFG = clone(FRANKA_PANDA_CFG) +FRANKA_MINIMAL_CFG.spawn.variants["Colliders"] = "gripper_only" +"""Configuration of Franka with only hand and fingertip collision geometry. + +This configuration shares the main USD, inertial properties, actuators, and backend payloads. +Use it when arm contacts are not required to reduce collision-processing cost. Policies must be +qualified for the selected collision scope. +""" + + FRANKA_PANDA_HIGH_PD_CFG = clone(FRANKA_PANDA_CFG) FRANKA_PANDA_HIGH_PD_CFG.spawn.rigid_props.disable_gravity = True FRANKA_PANDA_HIGH_PD_CFG.actuators["panda_arm"].stiffness = 400.0 diff --git a/source/isaaclab_mimic/changelog.d/franka-curobo-world.fixed.rst b/source/isaaclab_mimic/changelog.d/franka-curobo-world.fixed.rst new file mode 100644 index 000000000000..af413df18d43 --- /dev/null +++ b/source/isaaclab_mimic/changelog.d/franka-curobo-world.fixed.rst @@ -0,0 +1 @@ +* Excluded the robot subtree from cuRobo world obstacles even when custom world ignore substrings were configured. diff --git a/source/isaaclab_mimic/isaaclab_mimic/motion_planners/curobo/curobo_planner.py b/source/isaaclab_mimic/isaaclab_mimic/motion_planners/curobo/curobo_planner.py index 8f750469ced9..bbc888d33b6b 100644 --- a/source/isaaclab_mimic/isaaclab_mimic/motion_planners/curobo/curobo_planner.py +++ b/source/isaaclab_mimic/isaaclab_mimic/motion_planners/curobo/curobo_planner.py @@ -358,6 +358,7 @@ def _initialize_static_world(self) -> None: self._static_world_config = self.usd_helper.get_obstacles_from_stage( only_paths=[env_prim_path], + ignore_paths=[robot_prim_path], reference_prim_path=robot_prim_path, ignore_substring=ignore_list, ) diff --git a/source/isaaclab_rl/changelog.d/maximiliank-diffik-zero-agent.fixed.rst b/source/isaaclab_rl/changelog.d/maximiliank-diffik-zero-agent.fixed.rst new file mode 100644 index 000000000000..fd41ae7bbab3 --- /dev/null +++ b/source/isaaclab_rl/changelog.d/maximiliank-diffik-zero-agent.fixed.rst @@ -0,0 +1 @@ +* Corrected zero-agent hold actions for absolute differential IK configured with a nonzero action offset. diff --git a/source/isaaclab_rl/isaaclab_rl/entrypoints/simple_agents.py b/source/isaaclab_rl/isaaclab_rl/entrypoints/simple_agents.py index dede07e2e328..084a7342e8d5 100644 --- a/source/isaaclab_rl/isaaclab_rl/entrypoints/simple_agents.py +++ b/source/isaaclab_rl/isaaclab_rl/entrypoints/simple_agents.py @@ -192,7 +192,7 @@ def pink_policy() -> torch.Tensor: def differential_ik_policy() -> torch.Tensor: ee_pos, ee_quat = term._compute_frame_pose() command = ee_pos if term.cfg.controller.command_type == "position" else torch.cat((ee_pos, ee_quat), dim=-1) - return _unscale_action(command, term._scale) + return _unscale_action(command - term._offset, term._scale) return differential_ik_policy diff --git a/source/isaaclab_rl/test/test_entrypoints.py b/source/isaaclab_rl/test/test_entrypoints.py index 7c24021bdb32..40ad3f3f7192 100644 --- a/source/isaaclab_rl/test/test_entrypoints.py +++ b/source/isaaclab_rl/test/test_entrypoints.py @@ -71,6 +71,7 @@ class DifferentialInverseKinematicsAction: action_dim = 7 cfg = SimpleNamespace(controller=SimpleNamespace(use_relative_mode=False, command_type="pose")) _scale = torch.tensor([2.0, 2.0, 2.0, 1.0, 1.0, 1.0, 1.0]) + _offset = torch.tensor([0.2, -0.4, 0.6, 0.0, 0.0, 0.0, 0.0]) def _compute_frame_pose(self): return torch.tensor([[2.0, 4.0, 6.0]]), torch.tensor([[0.0, 0.0, 0.0, 1.0]]) @@ -148,7 +149,7 @@ class JointAction: ).flatten(start_dim=1) expected = torch.cat( ( - torch.tensor([[1.0, 2.0, 3.0, 0.0, 0.0, 0.0, 1.0]]), + torch.tensor([[0.9, 2.2, 2.7, 0.0, 0.0, 0.0, 1.0]]), torch.tensor([[3.0, 2.0, 1.0, 0.0, 0.0, 1.0, 0.0]]), expected_pink_poses, torch.tensor([[0.2, 0.4]]), @@ -169,6 +170,7 @@ class DifferentialInverseKinematicsAction: action_dim = 7 cfg = SimpleNamespace(controller=SimpleNamespace(use_relative_mode=False, command_type="pose")) _scale = torch.ones(7) + _offset = torch.zeros(7) def _compute_frame_pose(self): return torch.full((1, 3), torch.nan), torch.tensor([[0.0, 0.0, 0.0, 1.0]]) diff --git a/source/isaaclab_tasks/changelog.d/franka-minimal-preset.added.rst b/source/isaaclab_tasks/changelog.d/franka-minimal-preset.added.rst new file mode 100644 index 000000000000..3cfa59d5b0df --- /dev/null +++ b/source/isaaclab_tasks/changelog.d/franka-minimal-preset.added.rst @@ -0,0 +1,2 @@ +* Added ``presets=minimal`` to Franka Reach and rigid Lift, selecting the ``FRANKA_MINIMAL_CFG`` + gripper-only colliders while preserving task controls and independent physics backend selection. diff --git a/source/isaaclab_tasks/changelog.d/maximiliank-franka-reach-drawer.changed.rst b/source/isaaclab_tasks/changelog.d/maximiliank-franka-reach-drawer.changed.rst new file mode 100644 index 000000000000..c76f7f38a7ac --- /dev/null +++ b/source/isaaclab_tasks/changelog.d/maximiliank-franka-reach-drawer.changed.rst @@ -0,0 +1,3 @@ +* **Breaking:** Migrated maintained Franka Reach, Drawer, rigid and deformable Lift, and related + contributed tasks to the main ``FRANKA_PANDA_CFG`` with backend-specific physics and full arm and + gripper collisions. Existing checkpoints require requalification against the changed robot dynamics. diff --git a/source/isaaclab_tasks/changelog.d/maximiliank-franka-reach-drawer.fixed.rst b/source/isaaclab_tasks/changelog.d/maximiliank-franka-reach-drawer.fixed.rst new file mode 100644 index 000000000000..55e51ecf9d8e --- /dev/null +++ b/source/isaaclab_tasks/changelog.d/maximiliank-franka-reach-drawer.fixed.rst @@ -0,0 +1 @@ +* Corrected the Reach action and controller contracts for the shared asset. diff --git a/source/isaaclab_tasks/changelog.d/maximiliank-franka-reach-drawer.major b/source/isaaclab_tasks/changelog.d/maximiliank-franka-reach-drawer.major new file mode 100644 index 000000000000..e69de29bb2d1 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 54250dde7ca9..40fed5e1c641 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_LEGACY_HIGH_PD_CFG +from isaaclab_assets.robots.franka import FRANKA_PANDA_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_LEGACY_HIGH_PD_CFG, + FRANKA_PANDA_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot", - init_state=replace(FRANKA_PANDA_LEGACY_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_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 76000c041c8d..79101158284c 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 @@ -5,15 +5,10 @@ from isaaclab.controllers.differential_ik_cfg import DifferentialIKControllerCfg from isaaclab.envs.mdp.actions.actions_cfg import DifferentialInverseKinematicsActionCfg -from isaaclab.utils import configclass, replace +from isaaclab.utils import configclass from isaaclab_tasks.core.cabinet.config.franka import joint_pos_env_cfg -## -# Pre-defined configs -## -from isaaclab_assets.robots.franka import FRANKA_PANDA_LEGACY_HIGH_PD_CFG # isort: skip - @configclass class FrankaCabinetEnvCfg(joint_pos_env_cfg.FrankaCabinetEnvCfg): @@ -21,9 +16,10 @@ def __post_init__(self): # post init of parent super().__post_init__() - # Set Franka as robot - # We switch here to a stiffer PD controller for IK tracking to be better. - self.scene.robot = replace(FRANKA_PANDA_LEGACY_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") + # Use stiffer arm gains for IK without replacing the task's robot configuration. + self.scene.robot.spawn.rigid_props.disable_gravity = True + self.scene.robot.actuators["panda_arm"].stiffness = 400.0 + self.scene.robot.actuators["panda_arm"].damping = 80.0 # 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 e8da541c7b09..2b458d8f31e2 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 @@ -5,15 +5,10 @@ from isaaclab.controllers.differential_ik_cfg import DifferentialIKControllerCfg from isaaclab.envs.mdp.actions.actions_cfg import DifferentialInverseKinematicsActionCfg -from isaaclab.utils import configclass, replace +from isaaclab.utils import configclass from isaaclab_tasks.core.cabinet.config.franka import joint_pos_env_cfg -## -# Pre-defined configs -## -from isaaclab_assets.robots.franka import FRANKA_PANDA_LEGACY_HIGH_PD_CFG # isort: skip - @configclass class FrankaCabinetEnvCfg(joint_pos_env_cfg.FrankaCabinetEnvCfg): @@ -21,9 +16,10 @@ def __post_init__(self): # post init of parent super().__post_init__() - # Set Franka as robot - # We switch here to a stiffer PD controller for IK tracking to be better. - self.scene.robot = replace(FRANKA_PANDA_LEGACY_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") + # Use stiffer arm gains for IK without replacing the task's robot configuration. + self.scene.robot.spawn.rigid_props.disable_gravity = True + self.scene.robot.actuators["panda_arm"].stiffness = 400.0 + self.scene.robot.actuators["panda_arm"].damping = 80.0 # 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_abs_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/contrib/lift/config/franka/ik_abs_env_cfg.py index 4c76b049a78c..d942f1d36ff1 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 @@ -5,16 +5,10 @@ from isaaclab.controllers.differential_ik_cfg import DifferentialIKControllerCfg from isaaclab.envs.mdp.actions.actions_cfg import DifferentialInverseKinematicsActionCfg -from isaaclab.utils import configclass, replace +from isaaclab.utils import configclass from isaaclab_tasks.contrib.lift.config.franka import joint_pos_env_cfg -## -# Pre-defined configs -## -from isaaclab_assets.robots.franka import FRANKA_PANDA_LEGACY_HIGH_PD_CFG # isort: skip - - ## # Rigid object lift environment. ## @@ -26,9 +20,10 @@ def __post_init__(self): # post init of parent super().__post_init__() - # Set Franka as robot - # We switch here to a stiffer PD controller for IK tracking to be better. - self.scene.robot = replace(FRANKA_PANDA_LEGACY_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") + # Use stiffer arm gains for IK without replacing the task's robot configuration. + self.scene.robot.spawn.rigid_props.disable_gravity = True + self.scene.robot.actuators["panda_arm"].stiffness = 400.0 + self.scene.robot.actuators["panda_arm"].damping = 80.0 # 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 141125da0b23..318fbb780a65 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 @@ -5,15 +5,10 @@ from isaaclab.controllers.differential_ik_cfg import DifferentialIKControllerCfg from isaaclab.envs.mdp.actions.actions_cfg import DifferentialInverseKinematicsActionCfg -from isaaclab.utils import configclass, replace +from isaaclab.utils import configclass from isaaclab_tasks.contrib.lift.config.franka import joint_pos_env_cfg -## -# Pre-defined configs -## -from isaaclab_assets.robots.franka import FRANKA_PANDA_LEGACY_HIGH_PD_CFG # isort: skip - @configclass class FrankaCubeLiftEnvCfg(joint_pos_env_cfg.FrankaCubeLiftEnvCfg): @@ -21,9 +16,10 @@ def __post_init__(self): # post init of parent super().__post_init__() - # Set Franka as robot - # We switch here to a stiffer PD controller for IK tracking to be better. - self.scene.robot = replace(FRANKA_PANDA_LEGACY_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") + # Use stiffer arm gains for IK without replacing the task's robot configuration. + self.scene.robot.spawn.rigid_props.disable_gravity = True + self.scene.robot.actuators["panda_arm"].stiffness = 400.0 + self.scene.robot.actuators["panda_arm"].damping = 80.0 # 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 8a1dd9feebc8..8ee29befc26a 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_LEGACY_CFG # isort: skip +from isaaclab_assets.robots.franka import FRANKA_PANDA_CFG # isort: skip @configclass @@ -29,7 +29,8 @@ def __post_init__(self): super().__post_init__() # Set Franka as robot - self.scene.robot = replace(FRANKA_PANDA_LEGACY_CFG, prim_path="{ENV_REGEX_NS}/Robot") + self.scene.robot = replace(FRANKA_PANDA_CFG, prim_path="{ENV_REGEX_NS}/Robot") + self.scene.robot.spawn.variants["Physics"] = "physx" # Set actions for the specific robot type (franka) self.actions.arm_action = mdp.JointPositionActionCfg( @@ -67,12 +68,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 d93e3ee74cf4..ca773bd4c6fa 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_LEGACY_HIGH_PD_CFG # isort: skip +from isaaclab_assets.robots.franka import FRANKA_PANDA_HIGH_PD_CFG # isort: skip @configclass @@ -22,7 +22,9 @@ def __post_init__(self): super().__post_init__() # Set Franka as robot - self.scene.robot = replace(FRANKA_PANDA_LEGACY_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") + robot_variants = self.scene.robot.spawn.variants + self.scene.robot = replace(FRANKA_PANDA_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") + self.scene.robot.spawn.variants = robot_variants # 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 a5795efc2bec..2940779fb7f0 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 @@ -19,12 +19,13 @@ from isaaclab_tasks.contrib.stack import mdp from isaaclab_tasks.contrib.stack.mdp import franka_stack_events from isaaclab_tasks.contrib.stack.stack_env_cfg import StackEnvCfg +from isaaclab_tasks.utils import preset ## # Pre-defined configs ## from isaaclab.markers.config import FRAME_MARKER_CFG # isort: skip -from isaaclab_assets.robots.franka import FRANKA_PANDA_LEGACY_CFG # isort: skip +from isaaclab_assets.robots.franka import FRANKA_PANDA_CFG # isort: skip @configclass @@ -96,7 +97,8 @@ def __post_init__(self): self.events = EventCfg() # Set Franka as robot - self.scene.robot = replace(FRANKA_PANDA_LEGACY_CFG, prim_path="{ENV_REGEX_NS}/Robot") + self.scene.robot = replace(FRANKA_PANDA_CFG, prim_path="{ENV_REGEX_NS}/Robot") + self.scene.robot.spawn.variants["Physics"] = preset(default="physx", newton_mjwarp="mujoco") self.scene.robot.spawn.semantic_tags = [("class", "robot")] # Add semantics to table @@ -182,26 +184,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 cdd70c01e7f4..0748316aaceb 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_LEGACY_HIGH_PD_CFG # isort: skip +from isaaclab_assets.robots.franka import FRANKA_PANDA_HIGH_PD_CFG # isort: skip def _build_franka_stack_pipeline(): @@ -114,7 +114,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_LEGACY_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") + robot_variants = self.scene.robot.spawn.variants + self.scene.robot = replace(FRANKA_PANDA_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") + self.scene.robot.spawn.variants = robot_variants # 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 a379eb0b5aba..cfeaf541d90b 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_LEGACY_HIGH_PD_CFG # isort: skip +from isaaclab_assets.robots.franka import FRANKA_PANDA_HIGH_PD_CFG # isort: skip def image( @@ -217,7 +217,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_LEGACY_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") + robot_variants = self.scene.robot.spawn.variants + self.scene.robot = replace(FRANKA_PANDA_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") + self.scene.robot.spawn.variants = robot_variants 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 515e69b18e18..c3927de7f7f0 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 @@ -12,19 +12,12 @@ ) from isaaclab.managers import SceneEntityCfg from isaaclab.managers import TerminationTermCfg as DoneTerm -from isaaclab.utils import configclass, replace +from isaaclab.utils import configclass from isaaclab_tasks.contrib.stack.stack_env_cfg import mdp from . import stack_joint_pos_env_cfg -## -# Pre-defined configs -## -from isaaclab_assets.robots.franka import ( # isort: skip - FRANKA_PANDA_LEGACY_HIGH_PD_CFG, -) - @configclass class FrankaCubeStackEnvCfg(stack_joint_pos_env_cfg.FrankaCubeStackEnvCfg): @@ -32,14 +25,10 @@ def __post_init__(self): # post init of parent super().__post_init__() - # Set Franka as robot - # Use a stiffer PD controller for better IK tracking. - robot_init_state = self.scene.robot.init_state - robot_semantic_tags = self.scene.robot.spawn.semantic_tags - self.scene.robot = replace( - FRANKA_PANDA_LEGACY_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot", init_state=robot_init_state - ) - self.scene.robot.spawn.semantic_tags = robot_semantic_tags + # Use stiffer arm gains for IK without replacing the task's robot configuration. + self.scene.robot.spawn.rigid_props.disable_gravity = True + self.scene.robot.actuators["panda_arm"].stiffness = 400.0 + self.scene.robot.actuators["panda_arm"].damping = 80.0 # 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_env_cfg_skillgen.py b/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_ik_rel_env_cfg_skillgen.py index 8861d9a3a5b8..ba43142cda88 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_LEGACY_HIGH_PD_CFG # isort: skip +from isaaclab_assets.robots.franka import FRANKA_PANDA_HIGH_PD_CFG # isort: skip @configclass @@ -107,7 +107,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_LEGACY_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") + robot_variants = self.scene.robot.spawn.variants + self.scene.robot = replace(FRANKA_PANDA_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") + self.scene.robot.spawn.variants = robot_variants # 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 3de75bb15a36..652273d368b9 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 @@ -5,15 +5,10 @@ from isaaclab.controllers.differential_ik_cfg import DifferentialIKControllerCfg from isaaclab.envs.mdp.actions.actions_cfg import DifferentialInverseKinematicsActionCfg -from isaaclab.utils import configclass, replace +from isaaclab.utils import configclass from . import stack_joint_pos_instance_randomize_env_cfg -## -# Pre-defined configs -## -from isaaclab_assets.robots.franka import FRANKA_PANDA_LEGACY_HIGH_PD_CFG # isort: skip - @configclass class FrankaCubeStackInstanceRandomizeEnvCfg( @@ -23,9 +18,10 @@ def __post_init__(self): # post init of parent super().__post_init__() - # Set Franka as robot - # We switch here to a stiffer PD controller for IK tracking to be better. - self.scene.robot = replace(FRANKA_PANDA_LEGACY_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") + # Use stiffer arm gains for IK without replacing the task's robot configuration. + self.scene.robot.spawn.rigid_props.disable_gravity = True + self.scene.robot.actuators["panda_arm"].stiffness = 400.0 + self.scene.robot.actuators["panda_arm"].damping = 80.0 # 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 ebd249665e19..f0ded56af6cd 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 @@ -22,13 +22,14 @@ from isaaclab_tasks.contrib.stack import mdp from isaaclab_tasks.contrib.stack.mdp import franka_stack_events from isaaclab_tasks.contrib.stack.stack_env_cfg import StackEnvCfg +from isaaclab_tasks.utils import preset from isaaclab_tasks.utils.presets import set_isaac_rtx_global_settings ## # Pre-defined configs ## from isaaclab.markers.config import FRAME_MARKER_CFG # isort: skip -from isaaclab_assets.robots.franka import FRANKA_PANDA_LEGACY_HIGH_PD_CFG # isort: skip +from isaaclab_assets.robots.franka import FRANKA_PANDA_HIGH_PD_CFG # isort: skip # Default arm + gripper joint pose _FRANKA_STACK_IK_REL_INIT_JOINT_POS: dict[str, float] = { @@ -221,10 +222,11 @@ 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_LEGACY_HIGH_PD_CFG, + FRANKA_PANDA_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot", init_state=ArticulationCfg.InitialStateCfg(joint_pos=_FRANKA_STACK_IK_REL_INIT_JOINT_POS), ) + self.scene.robot.spawn.variants["Physics"] = preset(default="physx", newton_mjwarp="mujoco") # Add semantics to table self.scene.table.spawn.semantic_tags = [("class", "table")] @@ -304,26 +306,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 +337,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 7f4517f4f8f3..03ae2cbb68ce 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 @@ -13,11 +13,12 @@ apply_default_semantics, make_ee_frame_cfg, ) +from isaaclab_tasks.utils import preset ## # Pre-defined configs ## -from isaaclab_assets.robots.franka import FRANKA_PANDA_LEGACY_CFG # isort: skip +from isaaclab_assets.robots.franka import FRANKA_PANDA_CFG # isort: skip # Default arm + gripper joint pose _FRANKA_STACK_IK_REL_INIT_JOINT_POS: dict[str, float] = { @@ -51,10 +52,11 @@ def __post_init__(self): # Set Franka as robot self.scene.robot = replace( - FRANKA_PANDA_LEGACY_CFG, + FRANKA_PANDA_CFG, prim_path="{ENV_REGEX_NS}/Robot", init_state=ArticulationCfg.InitialStateCfg(joint_pos=_FRANKA_STACK_IK_REL_INIT_JOINT_POS), ) + self.scene.robot.spawn.variants["Physics"] = preset(default="physx", newton_mjwarp="mujoco") # Tag the table / ground / robot semantic classes. apply_default_semantics(self.scene) @@ -76,11 +78,11 @@ 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 a48386cfd4c8..78047c8cb235 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_LEGACY_CFG # isort: skip +from isaaclab_assets.robots.franka import FRANKA_PANDA_CFG # isort: skip @configclass @@ -73,7 +73,8 @@ def __post_init__(self): self.events = EventCfg() # Set Franka as robot - self.scene.robot = replace(FRANKA_PANDA_LEGACY_CFG, prim_path="{ENV_REGEX_NS}/Robot") + self.scene.robot = replace(FRANKA_PANDA_CFG, prim_path="{ENV_REGEX_NS}/Robot") + self.scene.robot.spawn.variants["Physics"] = "physx" # Set actions for the specific robot type (franka) self.actions.arm_action = mdp.JointPositionActionCfg( @@ -175,26 +176,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 f8b746bd4fef..3e2b134691ee 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_LEGACY_CFG +from isaaclab_tasks.utils import preset + +from isaaclab_assets.robots.franka import FRANKA_PANDA_CFG from ...cabinet_direct_env_cfg import CabinetDirectEnvCfg, CabinetDirectSceneCfg @@ -18,7 +20,8 @@ class FrankaCabinetDirectSceneCfg(CabinetDirectSceneCfg): """Direct-workflow cabinet scene configured for the Franka robot.""" - robot = replace(FRANKA_PANDA_LEGACY_CFG, prim_path="{ENV_REGEX_NS}/Robot") + robot = replace(FRANKA_PANDA_CFG, prim_path="{ENV_REGEX_NS}/Robot") + robot.spawn.variants["Physics"] = preset(default="mujoco", isaacsim_physx="physx", physx="physx", ovphysx="physx") @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 6a15539219a4..a9f70641cf27 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_LEGACY_CFG +from isaaclab_tasks.utils import preset + +from isaaclab_assets.robots.franka import FRANKA_PANDA_CFG from ... import mdp from ...cabinet_env_cfg import FRAME_MARKER_SMALL_CFG, CabinetEnvCfg, CabinetSceneCfg @@ -19,28 +21,29 @@ class FrankaCabinetSceneCfg(CabinetSceneCfg): """Cabinet scene configured for the Franka robot.""" - robot = replace(FRANKA_PANDA_LEGACY_CFG, prim_path="{ENV_REGEX_NS}/Robot") + robot = replace(FRANKA_PANDA_CFG, prim_path="{ENV_REGEX_NS}/Robot") + robot.spawn.variants["Physics"] = preset(default="mujoco", isaacsim_physx="physx", physx="physx", ovphysx="physx") 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/lift/config/franka/franka_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/franka/franka_env_cfg.py index 3fd5a0d2b251..17d06d825d8a 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/franka/franka_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/franka/franka_env_cfg.py @@ -5,7 +5,6 @@ """Configuration for the Franka lift environment.""" -from isaaclab.actuators import ImplicitActuatorCfg from isaaclab.assets import ArticulationCfg from isaaclab.managers import EventTermCfg as EventTerm from isaaclab.managers import ObservationTermCfg as ObsTerm @@ -14,9 +13,10 @@ from isaaclab.sensors import ContactSensorCfg from isaaclab.sim import MeshCapsuleCfg, MeshCuboidCfg, MeshSphereCfg from isaaclab.utils import clone, configclass, replace -from isaaclab.utils.assets import ISAACLAB_NUCLEUS_DIR -from isaaclab_assets.robots import FRANKA_PANDA_LEGACY_CFG +from isaaclab_tasks.utils import preset + +from isaaclab_assets.robots import FRANKA_MINIMAL_CFG, FRANKA_PANDA_CFG from ... import lift_env_cfg as lift from ... import mdp @@ -25,20 +25,14 @@ # Scene assets ## -# The lift tasks run the menagerie-converted asset (identified inertials, authored finger coupling) with -# actuators calibrated for it, while the other Franka tasks keep the stock asset. -FRANKA_PANDA_LIFT_CFG = clone(FRANKA_PANDA_LEGACY_CFG) -FRANKA_PANDA_LIFT_CFG.spawn.usd_path = f"{ISAACLAB_NUCLEUS_DIR}/Robots/FrankaEmika/franka_panda.usda" -# Reset clearance was calibrated for these arm meshes; the asset's primitive colliders intersect the ground. -FRANKA_PANDA_LIFT_CFG.spawn.variants = {"Colliders": "convex_hulls"} +# Lift inherits the shared asset and overrides its calibrated manipulation actuators. +FRANKA_PANDA_LIFT_CFG = clone(FRANKA_PANDA_CFG) FRANKA_PANDA_LIFT_CFG.actuators = { # inspired by libfranka's joint_impedance_control.cpp; ``actuator_velocity_limit`` is the soft task # limit and ``joint_velocity_limit`` the separate solver request - "panda_arm": ImplicitActuatorCfg( - joint_names_expr=["panda_joint[1-7]"], - joint_effort_limit={"panda_joint[1-4]": 87.0, "panda_joint[5-7]": 12.0}, + "panda_arm": replace( + FRANKA_PANDA_CFG.actuators["panda_arm"], actuator_velocity_limit={"panda_joint[1-4]": 2.175, "panda_joint[5-7]": 2.61}, - joint_velocity_limit={"panda_joint[1-4]": 20.0, "panda_joint[5-7]": 25.0}, stiffness={ "panda_joint[1-4]": 600.0, "panda_joint5": 250.0, @@ -57,8 +51,8 @@ "panda_joint[5-7]": 0.2055, }, ), - "panda_hand": ImplicitActuatorCfg( - joint_names_expr=["panda_finger_joint1"], + "panda_hand": replace( + FRANKA_PANDA_CFG.actuators["panda_hand"], joint_effort_limit=70.0, actuator_velocity_limit=0.2, joint_velocity_limit=2.0, @@ -66,13 +60,11 @@ damping=175.0, armature=0.1, ), - "panda_finger2_passive": ImplicitActuatorCfg( - joint_names_expr=["panda_finger_joint2"], + "panda_finger2_passive": replace( + FRANKA_PANDA_CFG.actuators["panda_finger2_passive"], joint_effort_limit=1.0, actuator_velocity_limit=0.2, joint_velocity_limit=2.0, - stiffness=0.0, - damping=0.0, armature=0.1, ), } @@ -102,6 +94,13 @@ class FrankaSceneCfg(lift.SceneCfg): def __post_init__(self): super().__post_init__() + self.robot.spawn.variants["Physics"] = preset( + default="mujoco", isaacsim_physx="physx", physx="physx", ovphysx="physx" + ) + self.robot.spawn.variants["Colliders"] = preset( + default=FRANKA_PANDA_CFG.spawn.variants["Colliders"], + minimal=FRANKA_MINIMAL_CFG.spawn.variants["Colliders"], + ) self.robot.spawn.activate_contact_sensors = True # the base is rotated by 180 degrees about z so the workspace lies at positive x self.robot.init_state.rot = (0.0, 0.0, 1.0, 0.0) diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/franka_soft/franka_soft_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/franka_soft/franka_soft_env_cfg.py index 4879c8fa0625..4365bd3095c2 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/franka_soft/franka_soft_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/core/lift/config/franka_soft/franka_soft_env_cfg.py @@ -21,7 +21,6 @@ from isaaclab_physx.sim.spawners.materials import PhysxDeformableBodyMaterialCfg import isaaclab.sim as sim_utils -from isaaclab.actuators import ImplicitActuatorCfg from isaaclab.assets import ArticulationCfg, AssetBaseCfg, VisualMaterialCfg from isaaclab.assets.deformable_object import DeformableObjectCfg from isaaclab.controllers import DifferentialIKControllerCfg @@ -47,7 +46,7 @@ from isaaclab_tasks.utils import PresetCfg, preset from isaaclab_tasks.utils.presets import MultiBackendRendererCfg -from isaaclab_assets.robots.franka import FRANKA_PANDA_MENAGERIE_CFG +from isaaclab_assets.robots.franka import FRANKA_PANDA_CFG from ... import mdp @@ -55,7 +54,7 @@ # Scene assets ## -# shared volume material parameters; the Newton configuration uses the equivalent Lame parameters +# Shared volume material parameters. The Newton config below uses the equivalent Lame parameters. YOUNGS_MODULUS = 2e5 POISSONS_RATIO = 0.3 @@ -189,12 +188,8 @@ class PhysicsCfg(PresetCfg): class FrankaSoftBaseSceneCfg(InteractiveSceneCfg): """Scene for the Franka deformable environment, also the base of the cloth and cable scenes.""" - robot: ArticulationCfg = replace(FRANKA_PANDA_MENAGERIE_CFG, prim_path="{ENV_REGEX_NS}/Robot") - robot.spawn.variants = preset( - default={"Physics": "mujoco"}, - isaacsim_physx={"Physics": "physx"}, - physx={"Physics": "physx"}, - ) + robot: ArticulationCfg = replace(FRANKA_PANDA_CFG, prim_path="{ENV_REGEX_NS}/Robot") + robot.spawn.variants["Physics"] = preset(default="mujoco", isaacsim_physx="physx", physx="physx", ovphysx="physx") # end-effector frame for reward shaping ee_frame: FrameTransformerCfg = FrameTransformerCfg( @@ -241,11 +236,11 @@ class FrankaSoftBaseSceneCfg(InteractiveSceneCfg): ) def __post_init__(self): + # Inherit shared joint properties and override the checkpoint's task-specific gains and limits. self.robot.actuators = { # inspired by libfranka's joint_impedance_control.cpp - "panda_arm": ImplicitActuatorCfg( - joint_names_expr=["panda_joint[1-7]"], - joint_effort_limit={"panda_joint[1-4]": 87.0, "panda_joint[5-7]": 12.0}, + "panda_arm": replace( + FRANKA_PANDA_CFG.actuators["panda_arm"], joint_velocity_limit={"panda_joint[1-4]": 2.175, "panda_joint[5-7]": 2.61}, stiffness={ "panda_joint[1-4]": 600.0, @@ -265,22 +260,20 @@ def __post_init__(self): "panda_joint[5-7]": 0.2055, }, ), - "panda_hand": ImplicitActuatorCfg( - joint_names_expr=["panda_finger_joint1"], - joint_effort_limit=70.0, + "panda_hand": replace( + FRANKA_PANDA_CFG.actuators["panda_hand"], + joint_effort_limit=500.0, actuator_velocity_limit=0.2, joint_velocity_limit=2.0, - stiffness=350.0, - damping=175.0, + stiffness=1000.0, + damping=100.0, armature=0.1, ), - "panda_finger2_passive": ImplicitActuatorCfg( - joint_names_expr=["panda_finger_joint2"], + "panda_finger2_passive": replace( + FRANKA_PANDA_CFG.actuators["panda_finger2_passive"], joint_effort_limit=1.0, actuator_velocity_limit=0.2, joint_velocity_limit=2.0, - stiffness=0.0, - damping=0.0, armature=0.1, ), } @@ -289,11 +282,6 @@ def __post_init__(self): # source of steady-state IK tracking error self.robot.spawn.rigid_props.disable_gravity = True - # increase franka gripper stiffness - self.robot.actuators["panda_hand"].joint_effort_limit = 500.0 - self.robot.actuators["panda_hand"].stiffness = 1000.0 - self.robot.actuators["panda_hand"].damping = 100.0 - @configclass class FrankaSoftBaseCameraSceneCfg(FrankaSoftBaseSceneCfg): diff --git a/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/utils.py b/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/utils.py index 96926a118a82..5742aa999ba9 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/utils.py +++ b/source/isaaclab_tasks/isaaclab_tasks/core/lift/mdp/utils.py @@ -288,7 +288,9 @@ def farthest_point_sampling( def collect_collision_meshes(root_prim, owner_frame_fn: Callable) -> dict[int, trimesh.Trimesh]: - """Collect collision meshes under ``root_prim``, grouped in caller-selected frames. + """Collect enabled collision meshes under ``root_prim``, grouped in caller-selected frames. + + Disabled colliders and visual-only geometry are excluded from reset clearance checks. Args: root_prim: Prim whose subtree is searched for collision meshes. @@ -311,7 +313,11 @@ def collect_collision_meshes(root_prim, owner_frame_fn: Callable) -> dict[int, t mesh_types = PRIMITIVE_MESH_TYPES + ["Mesh"] mesh_prims = sim_utils.get_all_matching_child_prims( root_prim.GetPath(), - lambda prim: prim.GetTypeName() in mesh_types and prim.HasAPI(UsdPhysics.CollisionAPI), + lambda prim: ( + prim.GetTypeName() in mesh_types + and prim.HasAPI(UsdPhysics.CollisionAPI) + and UsdPhysics.CollisionAPI(prim).GetCollisionEnabledAttr().Get() + ), ) meshes_by_owner: dict[int, list[trimesh.Trimesh]] = {} 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 16fad7b84776..8d61cef9baaa 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 @@ -28,7 +28,10 @@ from isaaclab_tasks.utils import PresetCfg, preset -from isaaclab_assets import FRANKA_PANDA_LEGACY_CFG, FRANKA_PANDA_MENAGERIE_CFG +## +# Pre-defined configs +## +from isaaclab_assets import FRANKA_MINIMAL_CFG, FRANKA_PANDA_CFG # isort: skip from ...reach_env_cfg import ReachEnvCfg @@ -61,7 +64,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", @@ -96,13 +101,13 @@ 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_LEGACY_CFG.spawn.usd_path, - physx=FRANKA_PANDA_LEGACY_CFG.spawn.usd_path, - ovphysx=FRANKA_PANDA_LEGACY_CFG.spawn.usd_path, + self.scene.robot = replace(FRANKA_PANDA_CFG, prim_path="{ENV_REGEX_NS}/Robot") + self.scene.robot.spawn.variants["Physics"] = preset( + default="mujoco", isaacsim_physx="physx", physx="physx", ovphysx="physx" + ) + self.scene.robot.spawn.variants["Colliders"] = preset( + default=FRANKA_PANDA_CFG.spawn.variants["Colliders"], + minimal=FRANKA_MINIMAL_CFG.spawn.variants["Colliders"], ) # IK targets need backend-native gravity control to hold steady between commands. self.scene.robot.spawn.rigid_props = [ 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/core/test_lift_env_cfg.py b/source/isaaclab_tasks/test/core/test_lift_env_cfg.py index 59f4bc4e40f8..f63b71f137d7 100644 --- a/source/isaaclab_tasks/test/core/test_lift_env_cfg.py +++ b/source/isaaclab_tasks/test/core/test_lift_env_cfg.py @@ -11,15 +11,14 @@ import torch import warp as wp -from pxr import Usd +from pxr import Usd, UsdGeom, UsdPhysics from isaaclab.assets import Asset from isaaclab.managers import CommandTerm, ObservationTermCfg, SceneEntityCfg -from isaaclab.sim import select_usd_variants +from isaaclab.sim import use_stage from isaaclab.utils.warp import ProxyArray 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.franka_soft.franka_soft_env_cfg import FrankaSoftEnvCfg from isaaclab_tasks.core.lift.mdp.commands import pose_commands from isaaclab_tasks.core.lift.mdp.commands.pose_commands import ( @@ -27,6 +26,7 @@ DeformableUniformPoseCommand, ObjectUniformPoseCommand, ) +from isaaclab_tasks.core.lift.mdp.utils import collect_collision_meshes from isaaclab_tasks.utils.hydra import resolve_presets @@ -63,29 +63,24 @@ def test_franka_soft_robot_physics_variant_matches_backend( """The Franka USD physics payload must match the selected simulation backend.""" cfg = resolve_presets(FrankaSoftEnvCfg(), selected=selected_presets) - assert cfg.scene.robot.spawn.variants == {"Physics": expected_physics} + assert cfg.scene.robot.spawn.variants == {"Physics": expected_physics, "Colliders": "primitives"} -def test_franka_rigid_task_selects_collision_meshes_for_reset_clearance() -> None: - """Reset validation keeps the original arm meshes when the asset defaults to capsules.""" - cfg = FrankaLiftEnvCfg() +def test_reset_clearance_ignores_disabled_collision_geometry() -> None: + """Disabled colliders and visual-only geometry must not reject reset candidates.""" stage = Usd.Stage.CreateInMemory() - robot = stage.DefinePrim("/Robot", "Xform") - colliders = robot.GetVariantSets().AddVariantSet("Colliders") - for selection, prim_path, prim_type in ( - ("convex_hulls", "/Robot/link1_c/link1_c", "Mesh"), - ("primitives", "/Robot/link1_capsule", "Capsule"), - ): - colliders.AddVariant(selection) - colliders.SetVariantSelection(selection) - with colliders.GetVariantEditContext(): - stage.DefinePrim(prim_path, prim_type) - colliders.SetVariantSelection("primitives") - - select_usd_variants("/Robot", cfg.scene.robot.spawn.variants or {}, stage=stage) - - assert stage.GetPrimAtPath("/Robot/link1_c/link1_c").IsValid() - assert not stage.GetPrimAtPath("/Robot/link1_capsule").IsValid() + root = stage.DefinePrim("/Object", "Xform") + for name, enabled in (("default_enabled", None), ("explicit_enabled", True), ("disabled", False)): + prim = UsdGeom.Cube.Define(stage, f"/Object/{name}").GetPrim() + collision = UsdPhysics.CollisionAPI.Apply(prim) + if enabled is not None: + collision.CreateCollisionEnabledAttr(enabled) + UsdGeom.Cube.Define(stage, "/Object/visual_only") + + with use_stage(stage): + meshes = collect_collision_meshes(root, lambda prim: (prim.GetName(), root)) + + assert set(meshes) == {"default_enabled", "explicit_enabled"} def _make_vision_camera(data_type: str, images: torch.Tensor) -> tuple[mdp.vision_camera, SimpleNamespace]: 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..632798d0c4d7 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,16 @@ 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"] +) +def test_franka_cabinet_ik_preserves_newton_asset_variant(task_id): + """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=("newton_mjwarp",)) + + assert cfg.scene.robot.spawn.variants["Physics"] == "mujoco" + + def test_registered_manager_based_configs_name_their_env_class(): """A manager-based task's ``class_type`` constructs the env class its registration names.""" 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..5de619997240 100644 --- a/source/isaaclab_tasks/test/core/test_reach_franka_presets.py +++ b/source/isaaclab_tasks/test/core/test_reach_franka_presets.py @@ -3,8 +3,6 @@ # # SPDX-License-Identifier: BSD-3-Clause -from types import SimpleNamespace - import pytest import torch from gymnasium.envs.registration import registry @@ -12,9 +10,8 @@ from isaaclab_newton.sim.schemas import MujocoRigidBodyCfg from isaaclab_physx.sim.schemas import PhysxRigidBodyCfg -import isaaclab.envs.mdp as mdp from isaaclab.actuators import IdealPDActuatorCfg -from isaaclab.utils import replace, to_dict, validate +from isaaclab.utils import to_dict, validate import isaaclab_tasks # noqa: F401 from isaaclab_tasks.utils.hydra import PresetCfg, resolve_presets @@ -22,7 +19,7 @@ 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_CFG _TASK = "Isaac-Reach-Franka" _OSC_TASK = "Isaac-Reach-Franka-OSC" @@ -48,12 +45,29 @@ def _without_controller_dependent_cfg(cfg): return cfg_dict +@pytest.mark.parametrize( + ("task", "presets"), + [ + (_TASK, ("isaacsim_physx", "diffik")), + (_OSC_TASK, ("newton_mjwarp",)), + ("Isaac-Lift-Franka", ("ovphysx",)), + ], +) +def test_minimal_preset_changes_only_collision_scope(task, presets): + full = to_dict(_load_reach_env_cfg(task, *presets)) + minimal = to_dict(_load_reach_env_cfg(task, *presets, "minimal")) + + assert full["scene"]["robot"]["spawn"]["variants"]["Colliders"] == "primitives" + assert minimal["scene"]["robot"]["spawn"]["variants"]["Colliders"] == "gripper_only" + minimal["scene"]["robot"]["spawn"]["variants"]["Colliders"] = "primitives" + assert minimal == full + + def test_reach_diffik_abs_legacy_task_is_a_deprecated_alias(): spec = registry[_CONTRIB_DIFFIK_ABS_TASK] assert spec.kwargs["deprecated"] == {"alias": "--task Isaac-Reach-Franka physics=isaacsim_physx presets=diffik_abs"} - with pytest.warns(FutureWarning, match="presets=diffik_abs"): - legacy_cfg = load_cfg_from_registry(_CONTRIB_DIFFIK_ABS_TASK, "env_cfg_entry_point") + legacy_cfg = load_cfg_from_registry(_CONTRIB_DIFFIK_ABS_TASK, "env_cfg_entry_point") canonical_cfg = _load_env_cfg("diffik_abs", "isaacsim_physx") legacy_cfg = resolve_presets(legacy_cfg) @@ -136,7 +150,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": "primitives"} + + +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 +177,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": "primitives"} # Native SE(3) command convention: one relative 6-DoF pose objective. pose_objectives = [ @@ -163,66 +195,16 @@ def test_reach_default_preset_does_not_configure_se3_teleop_devices(): assert cfg.teleop_devices.devices == {} -def test_reach_success_requires_position_and_orientation(): - 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"]} - - angles = torch.tensor([0.19, 0.19, 0.21]) - body_quaternions = torch.zeros(3, 1, 4) - body_quaternions[:, 0, 2] = torch.sin(angles / 2) - body_quaternions[:, 0, 3] = torch.cos(angles / 2) - command_values = torch.zeros(3, 7) - command_values[:, 6] = 1.0 - robot_data = SimpleNamespace( - root_pos_w=SimpleNamespace(torch=torch.zeros(3, 3)), - root_quat_w=SimpleNamespace(torch=torch.tensor([[0.0, 0.0, 0.0, 1.0]]).repeat(3, 1)), - body_pos_w=SimpleNamespace(torch=torch.tensor([[[0.04, 0.0, 0.0]], [[0.06, 0.0, 0.0]], [[0.04, 0.0, 0.0]]])), - body_quat_w=SimpleNamespace(torch=body_quaternions), - ) - command = object.__new__(mdp.UniformPoseCommand) - command.robot = SimpleNamespace(data=robot_data) - command.body_idx = 0 - command.pose_command_b = command_values - command.pose_command_w = torch.zeros_like(command_values) - command.cfg = cfg.commands.ee_pose - command._env = SimpleNamespace(num_envs=3, device=torch.device("cpu")) - 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) - - 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) - - 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_limits(): + """Replacing the arm actuator with a zero-gain effort model must preserve its solver limits.""" cfg = _load_reach_env_cfg(_OSC_TASK) arm_actuator = cfg.scene.robot.actuators["panda_arm"] + source_actuator = FRANKA_PANDA_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 def test_reach_osc_resolves_controller_preset_values_to_defaults(): @@ -240,7 +222,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 == {"diffik_abs", "minimal"} def test_reach_osc_diffik_abs_is_a_deprecated_no_op_alias(): diff --git a/source/isaaclab_tasks/test/rendering_test_utils.py b/source/isaaclab_tasks/test/rendering_test_utils.py index 85474622395a..dbd83c27f1b3 100644 --- a/source/isaaclab_tasks/test/rendering_test_utils.py +++ b/source/isaaclab_tasks/test/rendering_test_utils.py @@ -2474,6 +2474,9 @@ def rendering_test_franka_cable( if env_cfg.curriculum is not None: env_cfg.curriculum.gravity = None + # Settling the USD pose must not trigger randomized RL resets during golden capture. + env_cfg.terminations.joint_vel_out_of_limit = None + _maybe_enable_physx_determinism_for_motion(env_cfg, physics_backend, _motion_data_type(data_types)) test_name = "franka_cable" @@ -2496,7 +2499,8 @@ def rendering_test_franka_cable( return # Let the cable settle under gravity so golden frames are not first-frame spawn poses. - env.step(zero_actions) + _, _, terminated, truncated, _ = env.step(zero_actions) + assert not torch.any(terminated | truncated), "Cable golden capture unexpectedly reset the scene." validate_camera_outputs( test_name,