From 0d215182f2af559779251e15ff125d5df1bd88f4 Mon Sep 17 00:00:00 2001 From: Maximilian Krause Date: Tue, 29 Sep 2026 19:12:55 +0200 Subject: [PATCH 01/14] Add flat Franka asset and backend body-resolution support --- ...aximiliank-direct-body-prim-resolution.rst | 4 + source/isaaclab/isaaclab/sim/utils/queries.py | 8 ++ source/isaaclab/test/sim/test_cloner.py | 8 ++ .../maximiliank-franka-flat-config.minor.rst | 14 ++ .../isaaclab_assets/__init__.pyi | 6 + .../isaaclab_assets/robots/__init__.pyi | 6 + .../isaaclab_assets/robots/franka.py | 124 +++++++++++++++--- .../test/test_valid_configs.py | 20 +++ ...miliank-franka-material-body-selection.rst | 4 + .../assets/articulation/articulation.py | 8 +- .../isaaclab_newton/envs/mdp/events.py | 10 +- .../test/assets/test_articulation.py | 52 ++++---- ...iliank-frame-transformer-nested-bodies.rst | 5 + .../frame_transformer/frame_transformer.py | 10 +- .../test/assets/test_articulation.py | 34 ++++- .../test/sensors/test_frame_transformer.py | 42 ++++++ ...iliank-frame-transformer-nested-bodies.rst | 5 + .../frame_transformer/frame_transformer.py | 12 +- .../test/assets/test_articulation.py | 26 ++-- .../test/sensors/test_frame_transformer.py | 39 ++++++ 20 files changed, 360 insertions(+), 77 deletions(-) create mode 100644 source/isaaclab/changelog.d/maximiliank-direct-body-prim-resolution.rst create mode 100644 source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.minor.rst create mode 100644 source/isaaclab_newton/changelog.d/maximiliank-franka-material-body-selection.rst create mode 100644 source/isaaclab_ov/changelog.d/maximiliank-frame-transformer-nested-bodies.rst create mode 100644 source/isaaclab_physx/changelog.d/maximiliank-frame-transformer-nested-bodies.rst diff --git a/source/isaaclab/changelog.d/maximiliank-direct-body-prim-resolution.rst b/source/isaaclab/changelog.d/maximiliank-direct-body-prim-resolution.rst new file mode 100644 index 000000000000..4ead32834c86 --- /dev/null +++ b/source/isaaclab/changelog.d/maximiliank-direct-body-prim-resolution.rst @@ -0,0 +1,4 @@ +Fixed +^^^^^ + +* Fixed direct rigid-body path queries so nested rigid-body descendants are not selected when the requested body matches. diff --git a/source/isaaclab/isaaclab/sim/utils/queries.py b/source/isaaclab/isaaclab/sim/utils/queries.py index 0994b049c44c..b73ae060289a 100644 --- a/source/isaaclab/isaaclab/sim/utils/queries.py +++ b/source/isaaclab/isaaclab/sim/utils/queries.py @@ -387,6 +387,7 @@ def resolve_matching_prims_from_source( env_regex_ns: str = "/World/envs/env_[^/]+", raise_if_no_matches: bool = True, traverse_instance_prims: bool = True, + prefer_direct_matches: bool = False, ) -> list[tuple[Usd.Prim, str]]: """Resolve matching prims from a single(source) instance when multiple instances are present. @@ -402,6 +403,8 @@ def resolve_matching_prims_from_source( env_regex_ns: Namespace pattern that marks one instance root when no clone plan applies. raise_if_no_matches: Whether to raise if no prim matches ``path_expr``. Defaults to True. traverse_instance_prims: Whether to traverse instance prims when applying ``predicate``. + prefer_direct_matches: Prefer matching prims named by ``path_expr`` over their matching descendants. + Descendants remain a fallback when no direct prim satisfies ``predicate``. Returns: A list of ``(source_prim, destination_expr)`` pairs. Empty only when @@ -481,6 +484,11 @@ def resolve_matching_prims_from_source( unique_matches.setdefault(child_path, (child, dest + child_path[len(source_path) :])) results = list(unique_matches.values()) + if prefer_direct_matches: + direct_matches = [pair for pair in results if re.fullmatch(path_expr, pair[0].GetPath().pathString)] + if direct_matches: + results = direct_matches + if expected_num_matches is not None and len(results) != expected_num_matches: raise RuntimeError(f"Expected {expected_num_matches} prims at '{path_expr}', found {len(results)}.") if raise_if_no_matches and not results: diff --git a/source/isaaclab/test/sim/test_cloner.py b/source/isaaclab/test/sim/test_cloner.py index 51bfc38077f8..7ea2acef280c 100644 --- a/source/isaaclab/test/sim/test_cloner.py +++ b/source/isaaclab/test/sim/test_cloner.py @@ -285,3 +285,11 @@ def test_resolve_matching_prims_from_source(sim, with_clone_plan): "/World/envs/env_[^/]+/Robot/foo/bar", "/World/envs/env_[^/]+/Robot/other/bar", ] + + matches = queries.resolve_matching_prims_from_source( + r"/World/envs/env_[^/]+/Robot/foo", + predicate=lambda prim: prim.GetName() in {"foo", "bar"}, + expected_num_matches=1, + prefer_direct_matches=True, + ) + assert [prim.GetPath().pathString for prim, _ in matches] == ["/World/envs/env_0/Robot/foo"] diff --git a/source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.minor.rst b/source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.minor.rst new file mode 100644 index 000000000000..6618848f9c25 --- /dev/null +++ b/source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.minor.rst @@ -0,0 +1,14 @@ +Added +^^^^^ + +* Added ``FRANKA_PANDA_FLAT_CFG`` and ``FRANKA_PANDA_FLAT_HIGH_PD_CFG`` for the shared flat Franka + asset. These configurations selected gripper-only colliders and the ``panda_arm`` actuator group; + select the ``Physics`` variant for the target backend. + +Deprecated +^^^^^^^^^^ + +* Deprecated ``FRANKA_PANDA_CFG``, ``FRANKA_PANDA_HIGH_PD_CFG``, and + ``FRANKA_PANDA_MENAGERIE_CFG``. Their previous asset and actuator contracts remained available + during the deprecation window. Use the corresponding ``FRANKA_PANDA_FLAT_*`` configuration to + migrate to the shared flat asset, and replace shoulder/forearm actuator overrides with ``panda_arm``. diff --git a/source/isaaclab_assets/isaaclab_assets/__init__.pyi b/source/isaaclab_assets/isaaclab_assets/__init__.pyi index 2c491a499d7d..b38edb800a5f 100644 --- a/source/isaaclab_assets/isaaclab_assets/__init__.pyi +++ b/source/isaaclab_assets/isaaclab_assets/__init__.pyi @@ -22,7 +22,10 @@ __all__ = [ "GR1T2_CFG", "GR1T2_HIGH_PD_CFG", "FRANKA_PANDA_CFG", + "FRANKA_PANDA_FLAT_CFG", + "FRANKA_PANDA_FLAT_HIGH_PD_CFG", "FRANKA_PANDA_HIGH_PD_CFG", + "FRANKA_PANDA_LEGACY_CFG", "FRANKA_PANDA_MENAGERIE_CFG", "FRANKA_ROBOTIQ_GRIPPER_CFG", "FOURBAR_POLE_CFG", @@ -89,7 +92,10 @@ from .robots import ( GR1T2_CFG, GR1T2_HIGH_PD_CFG, FRANKA_PANDA_CFG, + FRANKA_PANDA_FLAT_CFG, + FRANKA_PANDA_FLAT_HIGH_PD_CFG, FRANKA_PANDA_HIGH_PD_CFG, + FRANKA_PANDA_LEGACY_CFG, FRANKA_PANDA_MENAGERIE_CFG, FRANKA_ROBOTIQ_GRIPPER_CFG, FOURBAR_POLE_CFG, diff --git a/source/isaaclab_assets/isaaclab_assets/robots/__init__.pyi b/source/isaaclab_assets/isaaclab_assets/robots/__init__.pyi index 023c8e801230..e54481a15ee5 100644 --- a/source/isaaclab_assets/isaaclab_assets/robots/__init__.pyi +++ b/source/isaaclab_assets/isaaclab_assets/robots/__init__.pyi @@ -22,7 +22,10 @@ __all__ = [ "GR1T2_CFG", "GR1T2_HIGH_PD_CFG", "FRANKA_PANDA_CFG", + "FRANKA_PANDA_FLAT_CFG", + "FRANKA_PANDA_FLAT_HIGH_PD_CFG", "FRANKA_PANDA_HIGH_PD_CFG", + "FRANKA_PANDA_LEGACY_CFG", "FRANKA_PANDA_MENAGERIE_CFG", "FRANKA_ROBOTIQ_GRIPPER_CFG", "FOURBAR_POLE_CFG", @@ -82,7 +85,10 @@ from .cassie import CASSIE_CFG from .fourier import GR1T2_CFG, GR1T2_HIGH_PD_CFG from .franka import ( FRANKA_PANDA_CFG, + FRANKA_PANDA_FLAT_CFG, + FRANKA_PANDA_FLAT_HIGH_PD_CFG, FRANKA_PANDA_HIGH_PD_CFG, + FRANKA_PANDA_LEGACY_CFG, FRANKA_PANDA_MENAGERIE_CFG, FRANKA_ROBOTIQ_GRIPPER_CFG, ) diff --git a/source/isaaclab_assets/isaaclab_assets/robots/franka.py b/source/isaaclab_assets/isaaclab_assets/robots/franka.py index c8749fab4fdd..11849e12b234 100644 --- a/source/isaaclab_assets/isaaclab_assets/robots/franka.py +++ b/source/isaaclab_assets/isaaclab_assets/robots/franka.py @@ -7,14 +7,23 @@ The following configurations are available: -* :obj:`FRANKA_PANDA_CFG`: Franka Emika Panda robot with Panda hand -* :obj:`FRANKA_PANDA_MENAGERIE_CFG`: Franka Emika Panda robot converted from MuJoCo Menagerie -* :obj:`FRANKA_PANDA_HIGH_PD_CFG`: Franka Emika Panda robot with Panda hand with stiffer PD control +* :obj:`FRANKA_PANDA_FLAT_CFG`: Shared flat asset for maintained Franka tasks +* :obj:`FRANKA_PANDA_FLAT_HIGH_PD_CFG`: Flat asset with stiffer PD control +* :obj:`FRANKA_PANDA_LEGACY_CFG`: Legacy Franka Emika Panda asset configuration +* :obj:`FRANKA_PANDA_CFG`: Deprecated alias retaining the legacy asset and actuators +* :obj:`FRANKA_PANDA_HIGH_PD_CFG`: Deprecated legacy high-PD configuration +* :obj:`FRANKA_PANDA_MENAGERIE_CFG`: Deprecated nested-instance Menagerie configuration * :obj:`FRANKA_ROBOTIQ_GRIPPER_CFG`: Franka robot with Robotiq_2f_85 gripper +The old public names retain their original configuration contracts for the deprecation window. Use +``FRANKA_PANDA_FLAT_CFG`` for new code and select its ``Physics`` variant for the chosen backend. + Reference: https://github.com/frankaemika/franka_ros """ +import warnings +from typing import TYPE_CHECKING + from isaaclab_newton.sim.schemas import NewtonArticulationCfg from isaaclab_physx.sim.schemas import PhysxArticulationCfg, PhysxRigidBodyCfg @@ -28,7 +37,7 @@ # Configuration ## -FRANKA_PANDA_CFG = ArticulationCfg( +FRANKA_PANDA_LEGACY_CFG = ArticulationCfg( spawn=sim_utils.UsdFileCfg( usd_path=f"{ISAACLAB_NUCLEUS_DIR}/Robots/FrankaEmika/Legacy/panda_instanceable.usd", activate_contact_sensors=False, @@ -77,45 +86,120 @@ }, soft_joint_pos_limit_factor=1.0, ) -"""Configuration of Franka Emika Panda robot.""" +"""Configuration of the legacy Franka Emika Panda robot asset.""" -FRANKA_PANDA_MENAGERIE_CFG = clone(FRANKA_PANDA_CFG) -FRANKA_PANDA_MENAGERIE_CFG.spawn.usd_path = f"{ISAACLAB_NUCLEUS_DIR}/Robots/FrankaEmika/franka_panda.usda" -FRANKA_PANDA_MENAGERIE_CFG.actuators = { +FRANKA_PANDA_FLAT_CFG = clone(FRANKA_PANDA_LEGACY_CFG) +FRANKA_PANDA_FLAT_CFG.spawn.usd_path = f"{ISAACLAB_NUCLEUS_DIR}/Robots/FrankaEmika/franka_panda.usda" +FRANKA_PANDA_FLAT_CFG.spawn.variants = {"Physics": "physx", "Colliders": "gripper_only"} +next( + props for props in FRANKA_PANDA_FLAT_CFG.spawn.articulation_props if isinstance(props, PhysxArticulationCfg) +).enabled_self_collisions = False +next( + props for props in FRANKA_PANDA_FLAT_CFG.spawn.articulation_props if isinstance(props, NewtonArticulationCfg) +).self_collision_enabled = False +FRANKA_PANDA_FLAT_CFG.actuators = { "panda_arm": ImplicitActuatorCfg( joint_names_expr=["panda_joint[1-7]"], + joint_effort_limit={"panda_joint[1-4]": 100.0, "panda_joint[5-7]": 12.0}, joint_velocity_limit={"panda_joint[1-4]": 20.0, "panda_joint[5-7]": 25.0}, stiffness=None, damping=None, + viscous_friction=0.0, ), "panda_hand": ImplicitActuatorCfg( - joint_names_expr=["panda_finger_joint.*"], + joint_names_expr=["panda_finger_joint1"], + joint_effort_limit=200.0, stiffness=None, damping=None, + viscous_friction=0.0, + ), + "panda_finger2_passive": ImplicitActuatorCfg( + joint_names_expr=["panda_finger_joint2"], + joint_effort_limit=200.0, + stiffness=0.0, + damping=0.0, + viscous_friction=0.0, ), } -"""Configuration of the MuJoCo Menagerie-derived Franka Emika Panda robot. +"""Configuration of the Franka Emika Panda robot. -The converted model has different inertial and drive authoring from the legacy asset used by -:attr:`FRANKA_PANDA_CFG`. The solver velocity limits provide consistent behavior across physics -backends, while the arm and hand retain their USD-authored drives. +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 +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_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_shoulder"].stiffness = 400.0 -FRANKA_PANDA_HIGH_PD_CFG.actuators["panda_shoulder"].damping = 80.0 -FRANKA_PANDA_HIGH_PD_CFG.actuators["panda_forearm"].stiffness = 400.0 -FRANKA_PANDA_HIGH_PD_CFG.actuators["panda_forearm"].damping = 80.0 +FRANKA_PANDA_FLAT_HIGH_PD_CFG = clone(FRANKA_PANDA_FLAT_CFG) +FRANKA_PANDA_FLAT_HIGH_PD_CFG.spawn.rigid_props.disable_gravity = True +FRANKA_PANDA_FLAT_HIGH_PD_CFG.actuators["panda_arm"].stiffness = 400.0 +FRANKA_PANDA_FLAT_HIGH_PD_CFG.actuators["panda_arm"].damping = 80.0 """Configuration of Franka Emika Panda robot with stiffer PD control. This configuration is useful for task-space control using differential IK. """ -FRANKA_ROBOTIQ_GRIPPER_CFG = clone(FRANKA_PANDA_CFG) +_FRANKA_PANDA_COMPAT_CFG = clone(FRANKA_PANDA_LEGACY_CFG) + + +_FRANKA_PANDA_LEGACY_HIGH_PD_CFG = clone(FRANKA_PANDA_LEGACY_CFG) +_FRANKA_PANDA_LEGACY_HIGH_PD_CFG.spawn.rigid_props.disable_gravity = True +for actuator in ("panda_shoulder", "panda_forearm"): + _FRANKA_PANDA_LEGACY_HIGH_PD_CFG.actuators[actuator].stiffness = 400.0 + _FRANKA_PANDA_LEGACY_HIGH_PD_CFG.actuators[actuator].damping = 80.0 + + +_FRANKA_PANDA_NESTED_MENAGERIE_CFG = clone(FRANKA_PANDA_LEGACY_CFG) +_FRANKA_PANDA_NESTED_MENAGERIE_CFG.spawn.usd_path = ( + f"{ISAACLAB_NUCLEUS_DIR}/Robots/FrankaEmika/franka_panda_nestedInstance.usda" +) +_FRANKA_PANDA_NESTED_MENAGERIE_CFG.actuators = { + "panda_arm": ImplicitActuatorCfg( + joint_names_expr=["panda_joint[1-7]"], + joint_velocity_limit={"panda_joint[1-4]": 20.0, "panda_joint[5-7]": 25.0}, + stiffness=None, + damping=None, + ), + "panda_hand": ImplicitActuatorCfg( + joint_names_expr=["panda_finger_joint.*"], + stiffness=None, + damping=None, + ), +} + + +_DEPRECATED_FRANKA_CFGS = { + "FRANKA_PANDA_CFG": (_FRANKA_PANDA_COMPAT_CFG, "FRANKA_PANDA_FLAT_CFG"), + "FRANKA_PANDA_HIGH_PD_CFG": (_FRANKA_PANDA_LEGACY_HIGH_PD_CFG, "FRANKA_PANDA_FLAT_HIGH_PD_CFG"), + "FRANKA_PANDA_MENAGERIE_CFG": (_FRANKA_PANDA_NESTED_MENAGERIE_CFG, "FRANKA_PANDA_FLAT_CFG"), +} + +if TYPE_CHECKING: + FRANKA_PANDA_CFG: ArticulationCfg + FRANKA_PANDA_HIGH_PD_CFG: ArticulationCfg + FRANKA_PANDA_MENAGERIE_CFG: ArticulationCfg + + +def __getattr__(name: str) -> ArticulationCfg: + if name not in _DEPRECATED_FRANKA_CFGS: + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") + cfg, replacement = _DEPRECATED_FRANKA_CFGS[name] + warnings.warn( + f"{name} is deprecated; use {replacement} for the flat Franka asset.", + FutureWarning, + stacklevel=2, + ) + return cfg + + +def __dir__() -> list[str]: + return sorted(set(globals()) | _DEPRECATED_FRANKA_CFGS.keys()) + + +FRANKA_ROBOTIQ_GRIPPER_CFG = clone(FRANKA_PANDA_LEGACY_CFG) FRANKA_ROBOTIQ_GRIPPER_CFG.spawn.usd_path = f"{ISAAC_NUCLEUS_DIR}/Robots/FrankaRobotics/FrankaPanda/franka.usd" FRANKA_ROBOTIQ_GRIPPER_CFG.spawn.variants = {"Gripper": "Robotiq_2F_85"} FRANKA_ROBOTIQ_GRIPPER_CFG.spawn.rigid_props.disable_gravity = True diff --git a/source/isaaclab_assets/test/test_valid_configs.py b/source/isaaclab_assets/test/test_valid_configs.py index 3832e196def1..b267e4862bd4 100644 --- a/source/isaaclab_assets/test/test_valid_configs.py +++ b/source/isaaclab_assets/test/test_valid_configs.py @@ -19,6 +19,26 @@ from isaaclab.test.utils import DeviceScope, test_devices import isaaclab_assets as lab_assets # noqa: F401 +import isaaclab_assets.robots.franka as franka_assets + + +def test_franka_legacy_configs_warn_and_keep_their_contract() -> None: + """Deprecated Franka names retain their previous asset and actuator contracts.""" + with pytest.warns(FutureWarning, match="FRANKA_PANDA_CFG.*deprecated"): + legacy_cfg = franka_assets.FRANKA_PANDA_CFG + assert legacy_cfg.spawn.usd_path.endswith("/Legacy/panda_instanceable.usd") + assert set(legacy_cfg.actuators) == {"panda_shoulder", "panda_forearm", "panda_hand"} + + with pytest.warns(FutureWarning, match="FRANKA_PANDA_HIGH_PD_CFG.*deprecated"): + high_pd_cfg = franka_assets.FRANKA_PANDA_HIGH_PD_CFG + assert high_pd_cfg.spawn.usd_path == legacy_cfg.spawn.usd_path + assert high_pd_cfg.actuators["panda_shoulder"].stiffness == 400.0 + assert high_pd_cfg.actuators["panda_forearm"].stiffness == 400.0 + + with pytest.warns(FutureWarning, match="FRANKA_PANDA_MENAGERIE_CFG.*deprecated"): + menagerie_cfg = franka_assets.FRANKA_PANDA_MENAGERIE_CFG + assert menagerie_cfg.spawn.usd_path.endswith("/franka_panda_nestedInstance.usda") + assert set(menagerie_cfg.actuators) == {"panda_arm", "panda_hand"} @pytest.fixture(scope="module") diff --git a/source/isaaclab_newton/changelog.d/maximiliank-franka-material-body-selection.rst b/source/isaaclab_newton/changelog.d/maximiliank-franka-material-body-selection.rst new file mode 100644 index 000000000000..f3763ed81629 --- /dev/null +++ b/source/isaaclab_newton/changelog.d/maximiliank-franka-material-body-selection.rst @@ -0,0 +1,4 @@ +Fixed +^^^^^ + +* Fixed Newton articulation material randomization for bodies whose shapes are interleaved in the native shape array. diff --git a/source/isaaclab_newton/isaaclab_newton/assets/articulation/articulation.py b/source/isaaclab_newton/isaaclab_newton/assets/articulation/articulation.py index e905d1adb0e7..66d8c4bb07d1 100644 --- a/source/isaaclab_newton/isaaclab_newton/assets/articulation/articulation.py +++ b/source/isaaclab_newton/isaaclab_newton/assets/articulation/articulation.py @@ -271,7 +271,7 @@ def num_bodies(self) -> int: @property def num_shapes_per_body(self) -> list[int]: - """Number of collision shapes per body in public body-name order. + """Number of shapes per body in public body-name order. Each element corresponds to the body at the same index in :attr:`body_names`. Backend-order counts are cached; a nonidentity body @@ -287,11 +287,11 @@ def num_shapes_per_body(self) -> list[int]: @property def backend_num_shapes_per_body(self) -> list[int]: - """Number of collision shapes per body in active backend solver-view order. + """Number of shapes per body in active backend solver-view order. Each element corresponds to the body at the same index in - :attr:`backend_body_names`, matching the shape axis of the backend - solver arrays. The counts are cached on first access. Use + :attr:`backend_body_names`. Shapes belonging to one body need not be + contiguous in the backend shape arrays. The counts are cached on first access. Use :attr:`num_shapes_per_body` for public body order. Returns: diff --git a/source/isaaclab_newton/isaaclab_newton/envs/mdp/events.py b/source/isaaclab_newton/isaaclab_newton/envs/mdp/events.py index e7c5faa973af..4724037e0869 100644 --- a/source/isaaclab_newton/isaaclab_newton/envs/mdp/events.py +++ b/source/isaaclab_newton/isaaclab_newton/envs/mdp/events.py @@ -63,14 +63,10 @@ def __init__(self, cfg: EventTermCfg, env: ManagerBasedEnv) -> None: self._restitution_binding = asset._root_view.get_attribute("shape_material_restitution", model)[:, 0] # type: ignore if isinstance(asset, assets.Articulation) and asset_cfg.body_ids != slice(None): - # Shape counts use backend body order. - num_shapes_per_body = asset.backend_num_shapes_per_body - shape_indices_list = [] backend_body_ids = asset.map_body_ids_to_backend(asset_cfg.body_ids) - for body_id in backend_body_ids: - start_idx = sum(num_shapes_per_body[:body_id]) - end_idx = start_idx + num_shapes_per_body[body_id] - shape_indices_list.extend(range(start_idx, end_idx)) + shape_indices_list = [ + shape for body_id in backend_body_ids for shape in asset.root_view.body_shapes[body_id] + ] self._shape_indices = torch.tensor(shape_indices_list, dtype=torch.long) else: self._shape_indices = torch.arange(self._friction_binding.shape[1], dtype=torch.long) diff --git a/source/isaaclab_newton/test/assets/test_articulation.py b/source/isaaclab_newton/test/assets/test_articulation.py index f0f4b5da6dbc..9cc6e1787eac 100644 --- a/source/isaaclab_newton/test/assets/test_articulation.py +++ b/source/isaaclab_newton/test/assets/test_articulation.py @@ -66,9 +66,14 @@ ## # Pre-defined configs ## -from isaaclab_assets import ANYMAL_C_CFG, FRANKA_PANDA_CFG, FRANKA_PANDA_HIGH_PD_CFG # isort:skip +from isaaclab_assets import ANYMAL_C_CFG, FRANKA_PANDA_FLAT_CFG, FRANKA_PANDA_FLAT_HIGH_PD_CFG # isort:skip from isaaclab_assets.robots.shadow_hand import SHADOW_HAND_NEWTON_CFG +_FRANKA_PANDA_NEWTON_CFG = FRANKA_PANDA_FLAT_CFG.copy() +_FRANKA_PANDA_NEWTON_CFG.spawn.variants = {"Physics": "mujoco", "Colliders": "gripper_only"} +_FRANKA_PANDA_HIGH_PD_NEWTON_CFG = FRANKA_PANDA_FLAT_HIGH_PD_CFG.copy() +_FRANKA_PANDA_HIGH_PD_NEWTON_CFG.spawn.variants = {"Physics": "mujoco", "Colliders": "gripper_only"} + SIM_CFGs = { "humanoid": SimulationCfg( physics=NewtonCfg( @@ -227,7 +232,7 @@ def generate_articulation_cfg( actuators={"body": ImplicitActuatorCfg(joint_names_expr=[".*"], stiffness=stiffness, damping=damping)}, ) elif articulation_type == "panda": - articulation_cfg = FRANKA_PANDA_CFG + articulation_cfg = _FRANKA_PANDA_NEWTON_CFG elif articulation_type == "anymal": articulation_cfg = ANYMAL_C_CFG elif articulation_type == "shadow_hand": @@ -438,7 +443,7 @@ def generate_articulation( def _setup_franka_at_home_pose(sim, *, zero_actuator_pd: bool = False, disable_gravity: bool = True): """Build a Franka articulation at its configured home pose. - Constructs :data:`FRANKA_PANDA_HIGH_PD_CFG`, optionally zeroes the + Constructs :data:`_FRANKA_PANDA_HIGH_PD_NEWTON_CFG`, optionally zeroes the arm-actuator PD gains, resets the simulator, and teleports the arm joints to :attr:`default_joint_pos` (the env reset path that normally does this is not invoked for standalone tests, so the @@ -447,23 +452,21 @@ def _setup_franka_at_home_pose(sim, *, zero_actuator_pd: bool = False, disable_g Args: sim: The simulation context to use. - zero_actuator_pd: If True, sets the panda_shoulder/panda_forearm - actuator stiffness and damping to zero. Used by the OSC test + zero_actuator_pd: If True, sets the ``panda_arm`` actuator stiffness + and damping to zero. Used by the OSC test so OSC's joint-effort output is not opposed by the implicit-PD's residual ``kp·(target − q)``. disable_gravity: Per-body gravity flag written to the spawn config. - :data:`FRANKA_PANDA_HIGH_PD_CFG` ships with gravity disabled; + :data:`_FRANKA_PANDA_HIGH_PD_NEWTON_CFG` ships with gravity disabled; pass False for tests where the arm must feel scene gravity. Returns: Tuple of ``(robot, ee_frame_idx, ee_jacobi_idx, arm_joint_ids)``. """ - cfg = replace(clone(FRANKA_PANDA_HIGH_PD_CFG), prim_path="/World/Env_[^/]*/Robot") + cfg = replace(_FRANKA_PANDA_HIGH_PD_NEWTON_CFG, prim_path="/World/Env_[^/]*/Robot") if zero_actuator_pd: - cfg.actuators["panda_shoulder"].stiffness = 0.0 - cfg.actuators["panda_shoulder"].damping = 0.0 - cfg.actuators["panda_forearm"].stiffness = 0.0 - cfg.actuators["panda_forearm"].damping = 0.0 + cfg.actuators["panda_arm"].stiffness = 0.0 + cfg.actuators["panda_arm"].damping = 0.0 cfg.spawn.rigid_props.disable_gravity = disable_gravity sim_utils.create_prim("/World/Env_0", "Xform", translation=(0.0, 0.0, 0.0)) clone_plan_from_env_0(CloneCfg(clone_template="/World/Env_{}"), (cfg,), 1, 0.0) @@ -1738,7 +1741,6 @@ def test_out_of_range_default_joint_state(sim, device, articulation_type, state_ quantity = "positions" if state_field == "joint_pos" else "velocities" replicate(sim.get_clone_plan()) with pytest.raises(ValueError, match=f"default {quantity} out of the limits"): - replicate(sim.get_clone_plan()) sim.reset() @@ -2511,29 +2513,31 @@ def test_write_joint_viscous_friction_to_sim(sim, num_articulations, device, art Static joint friction writes also propagate directly to the Newton model. """ - articulation_cfg = generate_articulation_cfg(articulation_type) - articulation_cfg.actuators["panda_shoulder"].viscous_friction = 0.25 + articulation_cfg = clone(generate_articulation_cfg(articulation_type)) + articulation_cfg.actuators["panda_arm"].viscous_friction = 0.25 + articulation_cfg.actuators["panda_arm"].damping = 2.0 articulation, _ = generate_articulation(articulation_cfg, num_articulations, device) replicate(sim.get_clone_plan()) sim.reset() - shoulder_joint_ids = articulation.actuators["panda_shoulder"].joint_indices - expected_viscous_friction = torch.full((articulation.num_instances, 4), 0.25, device=device) + arm_joint_ids = articulation.actuators["panda_arm"].joint_indices + expected_viscous_friction = torch.full((articulation.num_instances, len(arm_joint_ids)), 0.25, device=device) torch.testing.assert_close( - articulation.data.joint_viscous_friction_coeff.torch[:, shoulder_joint_ids], expected_viscous_friction + articulation.data.joint_viscous_friction_coeff.torch[:, arm_joint_ids], expected_viscous_friction ) torch.testing.assert_close( wp.to_torch(articulation.root_view.get_attribute("joint_damping", SimulationManager.get_model()))[ - :, 0, shoulder_joint_ids + :, 0, arm_joint_ids ], expected_viscous_friction, ) - expected_pd_damping = torch.full_like(expected_viscous_friction, 4.0) - torch.testing.assert_close(articulation.data.joint_damping.torch[:, shoulder_joint_ids], expected_pd_damping) + expected_pd_damping = torch.full_like(expected_viscous_friction, 2.0) + assert not torch.allclose(expected_pd_damping, expected_viscous_friction) + torch.testing.assert_close(articulation.data.joint_damping.torch[:, arm_joint_ids], expected_pd_damping) torch.testing.assert_close( wp.to_torch(articulation.root_view.get_attribute("joint_target_kd", SimulationManager.get_model()))[ - :, 0, shoulder_joint_ids + :, 0, arm_joint_ids ], expected_pd_damping, ) @@ -2840,7 +2844,7 @@ def test_heterogeneous_scene_per_view_shapes(sim, device, add_ground_plane, arti # per-articulation shape gate without that pre-existing quirk. num_per_type = 1 - franka_cfg = replace(FRANKA_PANDA_CFG, prim_path="/World/Env_[^/]*/Franka") + franka_cfg = replace(_FRANKA_PANDA_NEWTON_CFG, prim_path="/World/Env_[^/]*/Franka") anymal_cfg = replace(ANYMAL_C_CFG, prim_path="/World/Env_[^/]*/Anymal") anymal_cfg.init_state.pos = (0.0, 5.0, anymal_cfg.init_state.pos[2]) @@ -3142,7 +3146,7 @@ def test_get_gravity_compensation_forces_static_equilibrium(sim, num_articulatio # gravity-comp signal. Default Franka cfg has stiffness=80 / damping=4 # which would absorb gravity through PD bias and hide accessor bugs. cfg = replace(base_cfg, actuators={"all": ImplicitActuatorCfg(joint_names_expr=[".*"], stiffness=0.0, damping=0.0)}) - # FRANKA_PANDA_CFG has rigid_props.disable_gravity=False already, but be + # FRANKA_PANDA_FLAT_CFG has rigid_props.disable_gravity=False already, but be # defensive — gravity must be ON for τ_gc to have anything to cancel. cfg = replace(cfg, spawn=replace(cfg.spawn, rigid_props=replace(cfg.spawn.rigid_props, disable_gravity=False))) @@ -3160,7 +3164,7 @@ def test_get_gravity_compensation_forces_static_equilibrium(sim, num_articulatio articulation.write_joint_velocity_to_sim_index(velocity=default_qd) articulation.update(sim.cfg.dt) - # Default joint pose from FRANKA_PANDA_CFG bends the elbow + # Default joint pose from FRANKA_PANDA_FLAT_CFG bends the elbow # (joint2=-0.569, joint4=-2.81, joint6=3.04) so several links carry a # gravity load — τ_gc is non-trivial in this configuration. A natural- # hang pose (all zeros) would produce near-zero τ_gc and make this diff --git a/source/isaaclab_ov/changelog.d/maximiliank-frame-transformer-nested-bodies.rst b/source/isaaclab_ov/changelog.d/maximiliank-frame-transformer-nested-bodies.rst new file mode 100644 index 000000000000..02a80fb24471 --- /dev/null +++ b/source/isaaclab_ov/changelog.d/maximiliank-frame-transformer-nested-bodies.rst @@ -0,0 +1,5 @@ +Fixed +^^^^^ + +* Fixed frame-transformer path expressions that directly match a rigid body from also selecting + nested rigid-body descendants. diff --git a/source/isaaclab_ov/isaaclab_ov/sensors/frame_transformer/frame_transformer.py b/source/isaaclab_ov/isaaclab_ov/sensors/frame_transformer/frame_transformer.py index 0dec1c3c1368..f5a001c43eff 100644 --- a/source/isaaclab_ov/isaaclab_ov/sensors/frame_transformer/frame_transformer.py +++ b/source/isaaclab_ov/isaaclab_ov/sensors/frame_transformer/frame_transformer.py @@ -176,7 +176,11 @@ def has_rigid_body_api(prim) -> bool: return bool(prim.HasAPI(UsdPhysics.RigidBodyAPI)) matches = resolve_matching_prims_from_source( - prim_path, predicate=has_rigid_body_api, raise_if_no_matches=False + prim_path, + predicate=has_rigid_body_api, + expected_num_matches=1 if frame_type == "source" else None, + raise_if_no_matches=False, + prefer_direct_matches=True, ) if not matches: raise ValueError( @@ -296,8 +300,8 @@ def has_rigid_body_api(prim) -> bool: # -- target frames: use relative prim path for unique identification self._target_frame_body_names = [self._get_relative_body_path(prim_path) for prim_path in sorted_prim_paths] - # -- source frame: use relative prim path for unique identification - self._source_frame_body_name = self._get_relative_body_path(self.cfg.prim_path) + # -- source frame: retain the concrete body resolved from the configured expression + self._source_frame_body_name = tracked_body_names[0] source_frame_index = self._target_frame_body_names.index(self._source_frame_body_name) # Only remove source frame from tracked bodies if it is not also a target frame diff --git a/source/isaaclab_ov/test/assets/test_articulation.py b/source/isaaclab_ov/test/assets/test_articulation.py index 40cea80c376a..0c7a57456c27 100644 --- a/source/isaaclab_ov/test/assets/test_articulation.py +++ b/source/isaaclab_ov/test/assets/test_articulation.py @@ -98,7 +98,7 @@ ## # Pre-defined configs ## -from isaaclab_assets import ANYMAL_C_CFG, CARTPOLE_CFG, FRANKA_PANDA_CFG, SHADOW_HAND_PHYSX_CFG # isort:skip +from isaaclab_assets import ANYMAL_C_CFG, CARTPOLE_CFG, FRANKA_PANDA_FLAT_CFG, SHADOW_HAND_PHYSX_CFG # isort:skip wp.init() @@ -437,7 +437,7 @@ def generate_articulation_cfg( actuators={"body": ImplicitActuatorCfg(joint_names_expr=[".*"], stiffness=stiffness, damping=damping)}, ) elif articulation_type == "panda": - articulation_cfg = FRANKA_PANDA_CFG + articulation_cfg = FRANKA_PANDA_FLAT_CFG elif articulation_type == "anymal": articulation_cfg = ANYMAL_C_CFG elif articulation_type == "shadow_hand": @@ -528,6 +528,32 @@ def generate_articulation( return articulation, translations +@pytest.mark.parametrize("device", ["cuda:0"]) +@pytest.mark.parametrize("gravity_enabled", [False]) +def test_franka_newton_mimic_constraint_tracks_passive_finger(sim, device, gravity_enabled): + """Drive only the Franka leader finger and preserve mimic tracking in every clone.""" + articulation, _ = generate_articulation(FRANKA_PANDA_FLAT_CFG, 2, device) + sim.reset() + + leader_id = articulation.find_joints("panda_finger_joint1")[0][0] + follower_id = articulation.find_joints("panda_finger_joint2")[0][0] + initial_leader_pos = articulation.data.joint_pos.torch[:, leader_id].clone() + leader_target = torch.full((articulation.num_instances, 1), 0.01, device=device) + articulation.actuators.target_command.set_position_index(value=leader_target, joint_ids=[leader_id]) + + for _ in range(120): + articulation.write_data_to_sim() + sim.step() + articulation.update(sim.cfg.dt) + assert torch.isfinite(articulation.data.joint_pos.torch).all() + assert torch.isfinite(articulation.data.joint_vel.torch).all() + + leader_pos = articulation.data.joint_pos.torch[:, leader_id] + follower_pos = articulation.data.joint_pos.torch[:, follower_id] + assert torch.all(torch.abs(leader_pos - initial_leader_pos) > 0.005) + torch.testing.assert_close(follower_pos, leader_pos, rtol=0.0, atol=5.0e-4) + + @pytest.mark.parametrize("device", ["cuda:0"]) def test_newton_native_explicit_actuator_submits_ovphysx_effort(device): """Run a Newton-native explicit actuator through the current OVPhysX state and effort binding.""" @@ -1745,7 +1771,7 @@ def test_out_of_range_default_joint_vel(sim, device): 1. The articulation fails to initialize when joint velocities are out of range 2. The error is properly handled """ - articulation_cfg = replace(FRANKA_PANDA_CFG, prim_path="/World/Robot") + articulation_cfg = replace(FRANKA_PANDA_FLAT_CFG, prim_path="/World/Robot") articulation_cfg.init_state.joint_vel = { "panda_joint1": 100.0, "panda_joint[2, 4]": -60.0, @@ -2555,7 +2581,7 @@ def test_com_orientation_write_invalidates_static_inertia_cache_with_body_orderi below forbids cross-device staging, so this test is CPU-only. """ sim._app_control_on_stop_handle = None - articulation_cfg = replace(FRANKA_PANDA_CFG, body_ordering=PANDA_ROOT_PRESERVING_REVERSED_BODY_NAMES) + articulation_cfg = replace(FRANKA_PANDA_FLAT_CFG, body_ordering=PANDA_ROOT_PRESERVING_REVERSED_BODY_NAMES) articulation, _ = generate_articulation(articulation_cfg, 1, device=device) sim.reset() diff --git a/source/isaaclab_ov/test/sensors/test_frame_transformer.py b/source/isaaclab_ov/test/sensors/test_frame_transformer.py index 4f520bd382b0..45aadfb9735b 100644 --- a/source/isaaclab_ov/test/sensors/test_frame_transformer.py +++ b/source/isaaclab_ov/test/sensors/test_frame_transformer.py @@ -50,6 +50,7 @@ from isaaclab.utils import configclass, replace # noqa: E402 from isaaclab_assets.robots.anymal import ANYMAL_C_CFG # noqa: E402 +from isaaclab_assets.robots.franka import FRANKA_PANDA_FLAT_CFG # noqa: E402 wp.init() @@ -668,3 +669,44 @@ class MultiRobotSceneCfg(InteractiveSceneCfg): assert any(torch.allclose(rf_pos, expected, atol=1e-5) for expected in expected_rf_positions), ( f"RF_SHANK position {rf_pos} doesn't match either configured body offset" ) + + +@pytest.mark.parametrize("device", ["cpu", "cuda:0"]) +def test_frame_transformer_nested_rigid_bodies(device): + """Test that a matched rigid body does not include nested rigid-body descendants.""" + with _ovphysx_sim_context(device=device) as sim: + sim._app_control_on_stop_handle = None + scene_cfg = _SceneCfg(num_envs=2, env_spacing=5.0, lazy_sensor_update=False) + scene_cfg.robot = replace(FRANKA_PANDA_FLAT_CFG, prim_path="{ENV_REGEX_NS}/Robot") + scene_cfg.frame_transformer = FrameTransformerCfg( + prim_path="{ENV_REGEX_NS}/Robot/(Geometry/)?panda_link0", + target_frames=[ + FrameTransformerCfg.FrameCfg( + name="hand", + prim_path="{ENV_REGEX_NS}/Robot/(Geometry/.*/)?panda_hand", + ), + FrameTransformerCfg.FrameCfg( + name="left_finger", + prim_path="{ENV_REGEX_NS}/Robot/(Geometry/.*/)?panda_leftfinger", + ), + FrameTransformerCfg.FrameCfg( + name="right_finger", + prim_path="{ENV_REGEX_NS}/Robot/(Geometry/.*/)?panda_rightfinger", + ), + ], + ) + scene = InteractiveScene(scene_cfg) + + sim.reset() + scene.update(sim.get_physics_dt()) + + robot = scene.articulations["robot"] + source_id = robot.find_bodies("panda_link0")[0][0] + target_ids = robot.find_bodies(["panda_hand", "panda_leftfinger", "panda_rightfinger"])[0] + frame_data = scene.sensors["frame_transformer"].data + + assert frame_data.target_frame_names == ["hand", "left_finger", "right_finger"] + torch.testing.assert_close(frame_data.source_pos_w.torch, robot.data.body_pos_w.torch[:, source_id]) + torch.testing.assert_close(frame_data.source_quat_w.torch, robot.data.body_quat_w.torch[:, source_id]) + torch.testing.assert_close(frame_data.target_pos_w.torch, robot.data.body_pos_w.torch[:, target_ids]) + torch.testing.assert_close(frame_data.target_quat_w.torch, robot.data.body_quat_w.torch[:, target_ids]) diff --git a/source/isaaclab_physx/changelog.d/maximiliank-frame-transformer-nested-bodies.rst b/source/isaaclab_physx/changelog.d/maximiliank-frame-transformer-nested-bodies.rst new file mode 100644 index 000000000000..02a80fb24471 --- /dev/null +++ b/source/isaaclab_physx/changelog.d/maximiliank-frame-transformer-nested-bodies.rst @@ -0,0 +1,5 @@ +Fixed +^^^^^ + +* Fixed frame-transformer path expressions that directly match a rigid body from also selecting + nested rigid-body descendants. diff --git a/source/isaaclab_physx/isaaclab_physx/sensors/frame_transformer/frame_transformer.py b/source/isaaclab_physx/isaaclab_physx/sensors/frame_transformer/frame_transformer.py index 9a9055e10c98..1f17ce8463b2 100644 --- a/source/isaaclab_physx/isaaclab_physx/sensors/frame_transformer/frame_transformer.py +++ b/source/isaaclab_physx/isaaclab_physx/sensors/frame_transformer/frame_transformer.py @@ -191,7 +191,13 @@ def _initialize_impl(self): def has_rigid_body_api(prim) -> bool: return bool(prim.HasAPI(UsdPhysics.RigidBodyAPI)) - matches = resolve_matching_prims_from_source(prim_path, has_rigid_body_api, raise_if_no_matches=False) + matches = resolve_matching_prims_from_source( + prim_path, + has_rigid_body_api, + expected_num_matches=1 if frame_type == "source" else None, + raise_if_no_matches=False, + prefer_direct_matches=True, + ) if not matches: raise ValueError( f"Failed to create frame transformer for frame '{frame}' with path '{prim_path}'." @@ -298,8 +304,8 @@ def extract_env_num_and_prim_path(item: str) -> tuple[int, str]: # -- target frames: use relative prim path for unique identification self._target_frame_body_names = [self._get_relative_body_path(prim_path) for prim_path in sorted_prim_paths] - # -- source frame: use relative prim path for unique identification - self._source_frame_body_name = self._get_relative_body_path(self.cfg.prim_path) + # -- source frame: retain the concrete body resolved from the configured expression + self._source_frame_body_name = tracked_body_names[0] source_frame_index = self._target_frame_body_names.index(self._source_frame_body_name) # Only remove source frame from tracked bodies if it is not also a target frame diff --git a/source/isaaclab_physx/test/assets/test_articulation.py b/source/isaaclab_physx/test/assets/test_articulation.py index 7078c528911e..81e6007b18e4 100644 --- a/source/isaaclab_physx/test/assets/test_articulation.py +++ b/source/isaaclab_physx/test/assets/test_articulation.py @@ -51,8 +51,8 @@ ## from isaaclab_assets import ( # isort:skip ANYMAL_C_CFG, - FRANKA_PANDA_CFG, - FRANKA_PANDA_HIGH_PD_CFG, + FRANKA_PANDA_FLAT_CFG, + FRANKA_PANDA_FLAT_HIGH_PD_CFG, ) from isaaclab_assets.robots.shadow_hand import SHADOW_HAND_PHYSX_CFG @@ -98,7 +98,7 @@ def generate_articulation_cfg( actuators={"body": ImplicitActuatorCfg(joint_names_expr=[".*"], stiffness=stiffness, damping=damping)}, ) elif articulation_type == "panda": - articulation_cfg = FRANKA_PANDA_CFG + articulation_cfg = FRANKA_PANDA_FLAT_CFG elif articulation_type == "anymal": articulation_cfg = ANYMAL_C_CFG elif articulation_type == "shadow_hand": @@ -217,7 +217,7 @@ def _setup_franka_at_home_pose(sim): Returns: Tuple of ``(robot, ee_frame_idx, ee_jacobi_idx, arm_joint_ids)``. """ - cfg = replace(clone(FRANKA_PANDA_HIGH_PD_CFG), prim_path="/World/Env_[^/]*/Robot") + cfg = replace(clone(FRANKA_PANDA_FLAT_HIGH_PD_CFG), prim_path="/World/Env_[^/]*/Robot") sim_utils.create_prim("/World/Env_0", "Xform", translation=(0.0, 0.0, 0.0)) robot = Articulation(cfg) sim.reset() @@ -309,7 +309,7 @@ def sim(request): def test_live_manual_root_preserving_ordering_reorders_backend_reads_and_writes(sim, device, gravity_enabled): """Smoke-test non-identity joint/body ordering through a live PhysX articulation.""" articulation_cfg = replace( - FRANKA_PANDA_CFG, + FRANKA_PANDA_FLAT_CFG, prim_path="/World/Robot", joint_ordering=tuple(reversed(PANDA_JOINT_NAMES)), body_ordering=PANDA_ROOT_PRESERVING_REVERSED_BODY_NAMES, @@ -433,13 +433,13 @@ def test_reversed_joint_dynamics_use_public_joint_basis(sim, device, gravity_ena @pytest.mark.parametrize("gravity_enabled", [False]) def test_live_floating_root_writers_match_identity_after_body_reordering(sim, device, gravity_enabled): """Keep floating-base root writes invariant when public body order moves the root.""" - floating_spawn = replace(FRANKA_PANDA_CFG.spawn, fix_root_link=False) + floating_spawn = replace(FRANKA_PANDA_FLAT_CFG.spawn, fix_root_link=False) identity = Articulation( - replace(FRANKA_PANDA_CFG, prim_path="/World/IdentityRobot", spawn=floating_spawn, body_ordering=None) + replace(FRANKA_PANDA_FLAT_CFG, prim_path="/World/IdentityRobot", spawn=floating_spawn, body_ordering=None) ) ordered = Articulation( replace( - FRANKA_PANDA_CFG, + FRANKA_PANDA_FLAT_CFG, prim_path="/World/OrderedRobot", spawn=floating_spawn, body_ordering=tuple(reversed(PANDA_BODY_NAMES)), @@ -511,7 +511,9 @@ def test_live_direct_view_mass_inertia_writes_become_visible(sim, device, gravit ``user_to_backend``. """ body_ordering_arg = None if body_ordering == "identity" else PANDA_ROOT_PRESERVING_REVERSED_BODY_NAMES - articulation = Articulation(replace(FRANKA_PANDA_CFG, prim_path="/World/Robot", body_ordering=body_ordering_arg)) + articulation = Articulation( + replace(FRANKA_PANDA_FLAT_CFG, prim_path="/World/Robot", body_ordering=body_ordering_arg) + ) sim.reset() assert articulation.is_initialized @@ -861,7 +863,7 @@ def test_out_of_range_default_joint_vel(sim, device): 1. The articulation fails to initialize when joint velocities are out of range 2. The error is properly handled """ - articulation_cfg = replace(FRANKA_PANDA_CFG, prim_path="/World/Robot") + articulation_cfg = replace(FRANKA_PANDA_FLAT_CFG, prim_path="/World/Robot") articulation_cfg.init_state.joint_vel = { "panda_joint1": 100.0, "panda_joint[2, 4]": -60.0, @@ -2141,7 +2143,7 @@ def test_get_gravity_compensation_forces_static_equilibrium(sim, num_articulatio # gravity-comp signal. Default Franka cfg has stiffness=80 / damping=4 # which would absorb gravity through PD bias and hide accessor bugs. cfg = replace(base_cfg, actuators={"all": ImplicitActuatorCfg(joint_names_expr=[".*"], stiffness=0.0, damping=0.0)}) - # FRANKA_PANDA_CFG has rigid_props.disable_gravity=False already, but be + # FRANKA_PANDA_FLAT_CFG has rigid_props.disable_gravity=False already, but be # defensive — gravity must be ON for τ_gc to have anything to cancel. cfg = replace(cfg, spawn=replace(cfg.spawn, rigid_props=replace(cfg.spawn.rigid_props, disable_gravity=False))) @@ -2157,7 +2159,7 @@ def test_get_gravity_compensation_forces_static_equilibrium(sim, num_articulatio articulation.write_joint_state_to_sim(default_q, default_qd) articulation.update(sim.cfg.dt) - # Default joint pose from FRANKA_PANDA_CFG bends the elbow + # Default joint pose from FRANKA_PANDA_FLAT_CFG bends the elbow # (joint2=-0.569, joint4=-2.81, joint6=3.04) so several links carry a # gravity load — τ_gc is non-trivial in this configuration. A natural- # hang pose (all zeros) would produce near-zero τ_gc and make this diff --git a/source/isaaclab_physx/test/sensors/test_frame_transformer.py b/source/isaaclab_physx/test/sensors/test_frame_transformer.py index 7d0ffb0d918a..8775fa47d35f 100644 --- a/source/isaaclab_physx/test/sensors/test_frame_transformer.py +++ b/source/isaaclab_physx/test/sensors/test_frame_transformer.py @@ -32,6 +32,7 @@ # Pre-defined configs ## from isaaclab_assets.robots.anymal import ANYMAL_C_CFG # isort:skip +from isaaclab_assets.robots.franka import FRANKA_PANDA_FLAT_CFG # isort:skip def quat_from_euler_rpy(roll, pitch, yaw, degrees=False): @@ -720,3 +721,41 @@ def test_frame_transformer_invalidation_drops_cached_launch_state(monkeypatch): assert sensor._frame_physx_view is None assert sensor._raw_transforms is None assert sensor._update_cmd is None + + +def test_frame_transformer_nested_rigid_bodies(sim): + """Test that a matched rigid body does not include nested rigid-body descendants.""" + scene_cfg = MySceneCfg(num_envs=2, env_spacing=5.0, lazy_sensor_update=False) + scene_cfg.robot = replace(FRANKA_PANDA_FLAT_CFG, prim_path="{ENV_REGEX_NS}/Robot") + scene_cfg.frame_transformer = FrameTransformerCfg( + prim_path="{ENV_REGEX_NS}/Robot/(Geometry/)?panda_link0", + target_frames=[ + FrameTransformerCfg.FrameCfg( + name="hand", + prim_path="{ENV_REGEX_NS}/Robot/(Geometry/.*/)?panda_hand", + ), + FrameTransformerCfg.FrameCfg( + name="left_finger", + prim_path="{ENV_REGEX_NS}/Robot/(Geometry/.*/)?panda_leftfinger", + ), + FrameTransformerCfg.FrameCfg( + name="right_finger", + prim_path="{ENV_REGEX_NS}/Robot/(Geometry/.*/)?panda_rightfinger", + ), + ], + ) + scene = InteractiveScene(scene_cfg) + + sim.reset() + scene.update(sim.get_physics_dt()) + + robot = scene.articulations["robot"] + source_id = robot.find_bodies("panda_link0")[0][0] + target_ids = robot.find_bodies(["panda_hand", "panda_leftfinger", "panda_rightfinger"])[0] + frame_data = scene.sensors["frame_transformer"].data + + assert frame_data.target_frame_names == ["hand", "left_finger", "right_finger"] + torch.testing.assert_close(frame_data.source_pos_w.torch, robot.data.body_pos_w.torch[:, source_id]) + torch.testing.assert_close(frame_data.source_quat_w.torch, robot.data.body_quat_w.torch[:, source_id]) + torch.testing.assert_close(frame_data.target_pos_w.torch, robot.data.body_pos_w.torch[:, target_ids]) + torch.testing.assert_close(frame_data.target_quat_w.torch, robot.data.body_quat_w.torch[:, target_ids]) From c40b2adf1955806f0bce7389e1536b48fbc3ad7f Mon Sep 17 00:00:00 2001 From: Maximilian Krause Date: Tue, 29 Sep 2026 23:31:54 +0200 Subject: [PATCH 02/14] Preserve Franka compatibility and fix direct clone matching --- source/isaaclab/isaaclab/sim/utils/queries.py | 3 +- source/isaaclab/test/sim/test_cloner.py | 18 +++ .../maximiliank-franka-flat-config.minor.rst | 8 +- .../isaaclab_assets/__init__.pyi | 2 - .../isaaclab_assets/robots/__init__.pyi | 2 - .../isaaclab_assets/robots/franka.py | 122 +++++++++--------- .../test/test_valid_configs.py | 6 +- .../test/assets/test_articulation.py | 4 +- .../frame_transformer/frame_transformer.py | 6 +- .../test/assets/test_articulation.py | 2 +- .../frame_transformer/frame_transformer.py | 6 +- 11 files changed, 100 insertions(+), 79 deletions(-) diff --git a/source/isaaclab/isaaclab/sim/utils/queries.py b/source/isaaclab/isaaclab/sim/utils/queries.py index b73ae060289a..dc5c973ba033 100644 --- a/source/isaaclab/isaaclab/sim/utils/queries.py +++ b/source/isaaclab/isaaclab/sim/utils/queries.py @@ -471,6 +471,7 @@ def resolve_matching_prims_from_source( path = prim.GetPath().pathString if path == instance_root or path.startswith(instance_root + "/"): results.append((prim, instance_expr + path[len(instance_root) :])) + direct_source_paths = {source.GetPath().pathString for source, _ in results} if prefer_direct_matches else set() if predicate is not None: # Whole-path regexes can select both a prim and its ancestors; their descendant sets overlap. unique_matches = {} @@ -485,7 +486,7 @@ def resolve_matching_prims_from_source( results = list(unique_matches.values()) if prefer_direct_matches: - direct_matches = [pair for pair in results if re.fullmatch(path_expr, pair[0].GetPath().pathString)] + direct_matches = [pair for pair in results if pair[0].GetPath().pathString in direct_source_paths] if direct_matches: results = direct_matches diff --git a/source/isaaclab/test/sim/test_cloner.py b/source/isaaclab/test/sim/test_cloner.py index 7ea2acef280c..ea45ced6568e 100644 --- a/source/isaaclab/test/sim/test_cloner.py +++ b/source/isaaclab/test/sim/test_cloner.py @@ -293,3 +293,21 @@ def test_resolve_matching_prims_from_source(sim, with_clone_plan): prefer_direct_matches=True, ) assert [prim.GetPath().pathString for prim, _ in matches] == ["/World/envs/env_0/Robot/foo"] + + +def test_resolve_direct_match_from_external_prototype(sim): + """Prefer the requested body even when its prototype is outside the destination namespace.""" + stage = sim_utils.get_current_stage() + stage.DefinePrim("/World/template/Robot/foo/bar", "Xform") + asset = AssetBaseCfg(prim_path="/World/envs/env_[^/]+/Robot", spawn=SpawnerCfg(spawn_path="/World/template/Robot")) + sim.set_clone_plan(make_clone_plan((asset,), ((0,),), 2)) + + matches = queries.resolve_matching_prims_from_source( + r"/World/envs/env_[^/]+/Robot/foo", + predicate=lambda prim: prim.GetName() in {"foo", "bar"}, + expected_num_matches=1, + prefer_direct_matches=True, + ) + assert [(prim.GetPath().pathString, path) for prim, path in matches] == [ + ("/World/template/Robot/foo", "/World/envs/env_[^/]+/Robot/foo") + ] diff --git a/source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.minor.rst b/source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.minor.rst index 6618848f9c25..33ce4a3d797c 100644 --- a/source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.minor.rst +++ b/source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.minor.rst @@ -9,6 +9,8 @@ Deprecated ^^^^^^^^^^ * Deprecated ``FRANKA_PANDA_CFG``, ``FRANKA_PANDA_HIGH_PD_CFG``, and - ``FRANKA_PANDA_MENAGERIE_CFG``. Their previous asset and actuator contracts remained available - during the deprecation window. Use the corresponding ``FRANKA_PANDA_FLAT_*`` configuration to - migrate to the shared flat asset, and replace shoulder/forearm actuator overrides with ``panda_arm``. + ``FRANKA_PANDA_MENAGERIE_CFG`` for removal in Isaac Lab 4.0. The legacy Panda USD and actuator + groups remain available through the first two names. **Breaking:** the nested Menagerie USD moved + from ``franka_panda.usda`` to ``franka_panda_nestedInstance.usda``; code that reads or overrides + its path must use the new filename. Migrate to the corresponding ``FRANKA_PANDA_FLAT_*`` config, + replace shoulder/forearm actuator overrides with ``panda_arm``, and select the backend's ``Physics`` variant. diff --git a/source/isaaclab_assets/isaaclab_assets/__init__.pyi b/source/isaaclab_assets/isaaclab_assets/__init__.pyi index b38edb800a5f..2c71864ac40e 100644 --- a/source/isaaclab_assets/isaaclab_assets/__init__.pyi +++ b/source/isaaclab_assets/isaaclab_assets/__init__.pyi @@ -25,7 +25,6 @@ __all__ = [ "FRANKA_PANDA_FLAT_CFG", "FRANKA_PANDA_FLAT_HIGH_PD_CFG", "FRANKA_PANDA_HIGH_PD_CFG", - "FRANKA_PANDA_LEGACY_CFG", "FRANKA_PANDA_MENAGERIE_CFG", "FRANKA_ROBOTIQ_GRIPPER_CFG", "FOURBAR_POLE_CFG", @@ -95,7 +94,6 @@ from .robots import ( FRANKA_PANDA_FLAT_CFG, FRANKA_PANDA_FLAT_HIGH_PD_CFG, FRANKA_PANDA_HIGH_PD_CFG, - FRANKA_PANDA_LEGACY_CFG, FRANKA_PANDA_MENAGERIE_CFG, FRANKA_ROBOTIQ_GRIPPER_CFG, FOURBAR_POLE_CFG, diff --git a/source/isaaclab_assets/isaaclab_assets/robots/__init__.pyi b/source/isaaclab_assets/isaaclab_assets/robots/__init__.pyi index e54481a15ee5..aed6774c314c 100644 --- a/source/isaaclab_assets/isaaclab_assets/robots/__init__.pyi +++ b/source/isaaclab_assets/isaaclab_assets/robots/__init__.pyi @@ -25,7 +25,6 @@ __all__ = [ "FRANKA_PANDA_FLAT_CFG", "FRANKA_PANDA_FLAT_HIGH_PD_CFG", "FRANKA_PANDA_HIGH_PD_CFG", - "FRANKA_PANDA_LEGACY_CFG", "FRANKA_PANDA_MENAGERIE_CFG", "FRANKA_ROBOTIQ_GRIPPER_CFG", "FOURBAR_POLE_CFG", @@ -88,7 +87,6 @@ from .franka import ( FRANKA_PANDA_FLAT_CFG, FRANKA_PANDA_FLAT_HIGH_PD_CFG, FRANKA_PANDA_HIGH_PD_CFG, - FRANKA_PANDA_LEGACY_CFG, FRANKA_PANDA_MENAGERIE_CFG, FRANKA_ROBOTIQ_GRIPPER_CFG, ) diff --git a/source/isaaclab_assets/isaaclab_assets/robots/franka.py b/source/isaaclab_assets/isaaclab_assets/robots/franka.py index 11849e12b234..dabb72a2025d 100644 --- a/source/isaaclab_assets/isaaclab_assets/robots/franka.py +++ b/source/isaaclab_assets/isaaclab_assets/robots/franka.py @@ -9,14 +9,14 @@ * :obj:`FRANKA_PANDA_FLAT_CFG`: Shared flat asset for maintained Franka tasks * :obj:`FRANKA_PANDA_FLAT_HIGH_PD_CFG`: Flat asset with stiffer PD control -* :obj:`FRANKA_PANDA_LEGACY_CFG`: Legacy Franka Emika Panda asset configuration * :obj:`FRANKA_PANDA_CFG`: Deprecated alias retaining the legacy asset and actuators * :obj:`FRANKA_PANDA_HIGH_PD_CFG`: Deprecated legacy high-PD configuration * :obj:`FRANKA_PANDA_MENAGERIE_CFG`: Deprecated nested-instance Menagerie configuration * :obj:`FRANKA_ROBOTIQ_GRIPPER_CFG`: Franka robot with Robotiq_2f_85 gripper -The old public names retain their original configuration contracts for the deprecation window. Use -``FRANKA_PANDA_FLAT_CFG`` for new code and select its ``Physics`` variant for the chosen backend. +The old public names remain available during deprecation. Use ``FRANKA_PANDA_FLAT_CFG`` for new code +and select its ``Physics`` variant for the chosen backend. The former Menagerie asset was relocated to +``franka_panda_nestedInstance.usda``; the flat asset now occupies ``franka_panda.usda``. Reference: https://github.com/frankaemika/franka_ros """ @@ -37,7 +37,7 @@ # Configuration ## -FRANKA_PANDA_LEGACY_CFG = ArticulationCfg( +_FRANKA_PANDA_LEGACY_CFG = ArticulationCfg( spawn=sim_utils.UsdFileCfg( usd_path=f"{ISAACLAB_NUCLEUS_DIR}/Robots/FrankaEmika/Legacy/panda_instanceable.usd", activate_contact_sensors=False, @@ -89,7 +89,7 @@ """Configuration of the legacy Franka Emika Panda robot asset.""" -FRANKA_PANDA_FLAT_CFG = clone(FRANKA_PANDA_LEGACY_CFG) +FRANKA_PANDA_FLAT_CFG = clone(_FRANKA_PANDA_LEGACY_CFG) FRANKA_PANDA_FLAT_CFG.spawn.usd_path = f"{ISAACLAB_NUCLEUS_DIR}/Robots/FrankaEmika/franka_panda.usda" FRANKA_PANDA_FLAT_CFG.spawn.variants = {"Physics": "physx", "Colliders": "gripper_only"} next( @@ -142,64 +142,7 @@ """ -_FRANKA_PANDA_COMPAT_CFG = clone(FRANKA_PANDA_LEGACY_CFG) - - -_FRANKA_PANDA_LEGACY_HIGH_PD_CFG = clone(FRANKA_PANDA_LEGACY_CFG) -_FRANKA_PANDA_LEGACY_HIGH_PD_CFG.spawn.rigid_props.disable_gravity = True -for actuator in ("panda_shoulder", "panda_forearm"): - _FRANKA_PANDA_LEGACY_HIGH_PD_CFG.actuators[actuator].stiffness = 400.0 - _FRANKA_PANDA_LEGACY_HIGH_PD_CFG.actuators[actuator].damping = 80.0 - - -_FRANKA_PANDA_NESTED_MENAGERIE_CFG = clone(FRANKA_PANDA_LEGACY_CFG) -_FRANKA_PANDA_NESTED_MENAGERIE_CFG.spawn.usd_path = ( - f"{ISAACLAB_NUCLEUS_DIR}/Robots/FrankaEmika/franka_panda_nestedInstance.usda" -) -_FRANKA_PANDA_NESTED_MENAGERIE_CFG.actuators = { - "panda_arm": ImplicitActuatorCfg( - joint_names_expr=["panda_joint[1-7]"], - joint_velocity_limit={"panda_joint[1-4]": 20.0, "panda_joint[5-7]": 25.0}, - stiffness=None, - damping=None, - ), - "panda_hand": ImplicitActuatorCfg( - joint_names_expr=["panda_finger_joint.*"], - stiffness=None, - damping=None, - ), -} - - -_DEPRECATED_FRANKA_CFGS = { - "FRANKA_PANDA_CFG": (_FRANKA_PANDA_COMPAT_CFG, "FRANKA_PANDA_FLAT_CFG"), - "FRANKA_PANDA_HIGH_PD_CFG": (_FRANKA_PANDA_LEGACY_HIGH_PD_CFG, "FRANKA_PANDA_FLAT_HIGH_PD_CFG"), - "FRANKA_PANDA_MENAGERIE_CFG": (_FRANKA_PANDA_NESTED_MENAGERIE_CFG, "FRANKA_PANDA_FLAT_CFG"), -} - -if TYPE_CHECKING: - FRANKA_PANDA_CFG: ArticulationCfg - FRANKA_PANDA_HIGH_PD_CFG: ArticulationCfg - FRANKA_PANDA_MENAGERIE_CFG: ArticulationCfg - - -def __getattr__(name: str) -> ArticulationCfg: - if name not in _DEPRECATED_FRANKA_CFGS: - raise AttributeError(f"module {__name__!r} has no attribute {name!r}") - cfg, replacement = _DEPRECATED_FRANKA_CFGS[name] - warnings.warn( - f"{name} is deprecated; use {replacement} for the flat Franka asset.", - FutureWarning, - stacklevel=2, - ) - return cfg - - -def __dir__() -> list[str]: - return sorted(set(globals()) | _DEPRECATED_FRANKA_CFGS.keys()) - - -FRANKA_ROBOTIQ_GRIPPER_CFG = clone(FRANKA_PANDA_LEGACY_CFG) +FRANKA_ROBOTIQ_GRIPPER_CFG = clone(_FRANKA_PANDA_LEGACY_CFG) FRANKA_ROBOTIQ_GRIPPER_CFG.spawn.usd_path = f"{ISAAC_NUCLEUS_DIR}/Robots/FrankaRobotics/FrankaPanda/franka.usd" FRANKA_ROBOTIQ_GRIPPER_CFG.spawn.variants = {"Gripper": "Robotiq_2F_85"} FRANKA_ROBOTIQ_GRIPPER_CFG.spawn.rigid_props.disable_gravity = True @@ -259,3 +202,56 @@ def __dir__() -> list[str]: """Configuration of Franka Emika Panda robot with Robotiq_2f_85 gripper.""" + + +_FRANKA_PANDA_LEGACY_HIGH_PD_CFG = clone(_FRANKA_PANDA_LEGACY_CFG) +_FRANKA_PANDA_LEGACY_HIGH_PD_CFG.spawn.rigid_props.disable_gravity = True +for actuator in ("panda_shoulder", "panda_forearm"): + _FRANKA_PANDA_LEGACY_HIGH_PD_CFG.actuators[actuator].stiffness = 400.0 + _FRANKA_PANDA_LEGACY_HIGH_PD_CFG.actuators[actuator].damping = 80.0 + + +_FRANKA_PANDA_NESTED_MENAGERIE_CFG = clone(_FRANKA_PANDA_LEGACY_CFG) +_FRANKA_PANDA_NESTED_MENAGERIE_CFG.spawn.usd_path = ( + f"{ISAACLAB_NUCLEUS_DIR}/Robots/FrankaEmika/franka_panda_nestedInstance.usda" +) +_FRANKA_PANDA_NESTED_MENAGERIE_CFG.actuators = { + "panda_arm": ImplicitActuatorCfg( + joint_names_expr=["panda_joint[1-7]"], + joint_velocity_limit={"panda_joint[1-4]": 20.0, "panda_joint[5-7]": 25.0}, + stiffness=None, + damping=None, + ), + "panda_hand": ImplicitActuatorCfg( + joint_names_expr=["panda_finger_joint.*"], + stiffness=None, + damping=None, + ), +} + + +_DEPRECATED_FRANKA_CFGS = { + "FRANKA_PANDA_CFG": (_FRANKA_PANDA_LEGACY_CFG, "FRANKA_PANDA_FLAT_CFG"), + "FRANKA_PANDA_HIGH_PD_CFG": (_FRANKA_PANDA_LEGACY_HIGH_PD_CFG, "FRANKA_PANDA_FLAT_HIGH_PD_CFG"), + "FRANKA_PANDA_MENAGERIE_CFG": (_FRANKA_PANDA_NESTED_MENAGERIE_CFG, "FRANKA_PANDA_FLAT_CFG"), +} + +if TYPE_CHECKING: + FRANKA_PANDA_CFG: ArticulationCfg + FRANKA_PANDA_HIGH_PD_CFG: ArticulationCfg + FRANKA_PANDA_MENAGERIE_CFG: ArticulationCfg + + +def __getattr__(name: str) -> ArticulationCfg: + if name not in _DEPRECATED_FRANKA_CFGS: + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") + cfg, replacement = _DEPRECATED_FRANKA_CFGS[name] + message = f"{name} is deprecated and will be removed in Isaac Lab 4.0. Use {replacement}." + if name == "FRANKA_PANDA_MENAGERIE_CFG": + message += " The nested asset moved from franka_panda.usda to franka_panda_nestedInstance.usda." + warnings.warn(message, DeprecationWarning, stacklevel=2) + return cfg + + +def __dir__() -> list[str]: + return sorted(set(globals()) | _DEPRECATED_FRANKA_CFGS.keys()) diff --git a/source/isaaclab_assets/test/test_valid_configs.py b/source/isaaclab_assets/test/test_valid_configs.py index b267e4862bd4..e520f072f532 100644 --- a/source/isaaclab_assets/test/test_valid_configs.py +++ b/source/isaaclab_assets/test/test_valid_configs.py @@ -24,18 +24,18 @@ def test_franka_legacy_configs_warn_and_keep_their_contract() -> None: """Deprecated Franka names retain their previous asset and actuator contracts.""" - with pytest.warns(FutureWarning, match="FRANKA_PANDA_CFG.*deprecated"): + with pytest.warns(DeprecationWarning, match="FRANKA_PANDA_CFG.*removed in Isaac Lab 4.0"): legacy_cfg = franka_assets.FRANKA_PANDA_CFG assert legacy_cfg.spawn.usd_path.endswith("/Legacy/panda_instanceable.usd") assert set(legacy_cfg.actuators) == {"panda_shoulder", "panda_forearm", "panda_hand"} - with pytest.warns(FutureWarning, match="FRANKA_PANDA_HIGH_PD_CFG.*deprecated"): + with pytest.warns(DeprecationWarning, match="FRANKA_PANDA_HIGH_PD_CFG.*removed in Isaac Lab 4.0"): high_pd_cfg = franka_assets.FRANKA_PANDA_HIGH_PD_CFG assert high_pd_cfg.spawn.usd_path == legacy_cfg.spawn.usd_path assert high_pd_cfg.actuators["panda_shoulder"].stiffness == 400.0 assert high_pd_cfg.actuators["panda_forearm"].stiffness == 400.0 - with pytest.warns(FutureWarning, match="FRANKA_PANDA_MENAGERIE_CFG.*deprecated"): + with pytest.warns(DeprecationWarning, match="franka_panda_nestedInstance.usda"): menagerie_cfg = franka_assets.FRANKA_PANDA_MENAGERIE_CFG assert menagerie_cfg.spawn.usd_path.endswith("/franka_panda_nestedInstance.usda") assert set(menagerie_cfg.actuators) == {"panda_arm", "panda_hand"} diff --git a/source/isaaclab_newton/test/assets/test_articulation.py b/source/isaaclab_newton/test/assets/test_articulation.py index 9cc6e1787eac..fb8838de2943 100644 --- a/source/isaaclab_newton/test/assets/test_articulation.py +++ b/source/isaaclab_newton/test/assets/test_articulation.py @@ -69,9 +69,9 @@ from isaaclab_assets import ANYMAL_C_CFG, FRANKA_PANDA_FLAT_CFG, FRANKA_PANDA_FLAT_HIGH_PD_CFG # isort:skip from isaaclab_assets.robots.shadow_hand import SHADOW_HAND_NEWTON_CFG -_FRANKA_PANDA_NEWTON_CFG = FRANKA_PANDA_FLAT_CFG.copy() +_FRANKA_PANDA_NEWTON_CFG = clone(FRANKA_PANDA_FLAT_CFG) _FRANKA_PANDA_NEWTON_CFG.spawn.variants = {"Physics": "mujoco", "Colliders": "gripper_only"} -_FRANKA_PANDA_HIGH_PD_NEWTON_CFG = FRANKA_PANDA_FLAT_HIGH_PD_CFG.copy() +_FRANKA_PANDA_HIGH_PD_NEWTON_CFG = clone(FRANKA_PANDA_FLAT_HIGH_PD_CFG) _FRANKA_PANDA_HIGH_PD_NEWTON_CFG.spawn.variants = {"Physics": "mujoco", "Colliders": "gripper_only"} SIM_CFGs = { diff --git a/source/isaaclab_ov/isaaclab_ov/sensors/frame_transformer/frame_transformer.py b/source/isaaclab_ov/isaaclab_ov/sensors/frame_transformer/frame_transformer.py index f5a001c43eff..f0d393863a0d 100644 --- a/source/isaaclab_ov/isaaclab_ov/sensors/frame_transformer/frame_transformer.py +++ b/source/isaaclab_ov/isaaclab_ov/sensors/frame_transformer/frame_transformer.py @@ -178,7 +178,6 @@ def has_rigid_body_api(prim) -> bool: matches = resolve_matching_prims_from_source( prim_path, predicate=has_rigid_body_api, - expected_num_matches=1 if frame_type == "source" else None, raise_if_no_matches=False, prefer_direct_matches=True, ) @@ -187,6 +186,11 @@ def has_rigid_body_api(prim) -> bool: f"Failed to create frame transformer for frame '{frame}' with path '{prim_path}'." " No matching rigid-body prims were found." ) + if frame_type == "source" and len(matches) != 1: + raise ValueError( + f"Expected one source rigid-body prim for frame '{frame}' with path '{prim_path}'," + f" found {len(matches)}." + ) for prim, matching_prim_path in matches: # Get the name of the body: use relative prim path for unique identification body_name = self._get_relative_body_path(matching_prim_path) diff --git a/source/isaaclab_ov/test/assets/test_articulation.py b/source/isaaclab_ov/test/assets/test_articulation.py index 0c7a57456c27..996d8d934cc6 100644 --- a/source/isaaclab_ov/test/assets/test_articulation.py +++ b/source/isaaclab_ov/test/assets/test_articulation.py @@ -530,7 +530,7 @@ def generate_articulation( @pytest.mark.parametrize("device", ["cuda:0"]) @pytest.mark.parametrize("gravity_enabled", [False]) -def test_franka_newton_mimic_constraint_tracks_passive_finger(sim, device, gravity_enabled): +def test_franka_ovphysx_mimic_constraint_tracks_passive_finger(sim, device, gravity_enabled): """Drive only the Franka leader finger and preserve mimic tracking in every clone.""" articulation, _ = generate_articulation(FRANKA_PANDA_FLAT_CFG, 2, device) sim.reset() diff --git a/source/isaaclab_physx/isaaclab_physx/sensors/frame_transformer/frame_transformer.py b/source/isaaclab_physx/isaaclab_physx/sensors/frame_transformer/frame_transformer.py index 1f17ce8463b2..bd9d6a2a1b56 100644 --- a/source/isaaclab_physx/isaaclab_physx/sensors/frame_transformer/frame_transformer.py +++ b/source/isaaclab_physx/isaaclab_physx/sensors/frame_transformer/frame_transformer.py @@ -194,7 +194,6 @@ def has_rigid_body_api(prim) -> bool: matches = resolve_matching_prims_from_source( prim_path, has_rigid_body_api, - expected_num_matches=1 if frame_type == "source" else None, raise_if_no_matches=False, prefer_direct_matches=True, ) @@ -203,6 +202,11 @@ def has_rigid_body_api(prim) -> bool: f"Failed to create frame transformer for frame '{frame}' with path '{prim_path}'." " No matching rigid-body prims were found." ) + if frame_type == "source" and len(matches) != 1: + raise ValueError( + f"Expected one source rigid-body prim for frame '{frame}' with path '{prim_path}'," + f" found {len(matches)}." + ) for prim, matching_prim_path in matches: # Get the name of the body: use relative prim path for unique identification body_name = self._get_relative_body_path(matching_prim_path) From 69031a3f683ded5a99daa6201bb602fa482510b6 Mon Sep 17 00:00:00 2001 From: Maximilian Krause Date: Tue, 29 Sep 2026 23:36:16 +0200 Subject: [PATCH 03/14] Align Reach preset test with preserved Menagerie asset --- .../changelog.d/maximiliank-franka-menagerie-path-test.skip | 0 source/isaaclab_tasks/test/core/test_reach_franka_presets.py | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 source/isaaclab_tasks/changelog.d/maximiliank-franka-menagerie-path-test.skip diff --git a/source/isaaclab_tasks/changelog.d/maximiliank-franka-menagerie-path-test.skip b/source/isaaclab_tasks/changelog.d/maximiliank-franka-menagerie-path-test.skip new file mode 100644 index 000000000000..e69de29bb2d1 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..a3c29be66171 100644 --- a/source/isaaclab_tasks/test/core/test_reach_franka_presets.py +++ b/source/isaaclab_tasks/test/core/test_reach_franka_presets.py @@ -145,7 +145,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.usd_path.endswith("/FrankaEmika/franka_panda_nestedInstance.usda") # Native SE(3) command convention: one relative 6-DoF pose objective. pose_objectives = [ From 6f4affdee0e6838b25d30c12a5edde8fd29546ef Mon Sep 17 00:00:00 2001 From: Maximilian Krause Date: Wed, 30 Sep 2026 00:05:01 +0200 Subject: [PATCH 04/14] Keep published Menagerie URL during Franka migration --- .../maximiliank-franka-flat-config.minor.rst | 11 ++++++----- .../isaaclab_assets/robots/franka.py | 18 +++++++----------- .../isaaclab_assets/test/test_valid_configs.py | 4 ++-- ...maximiliank-franka-menagerie-path-test.skip | 0 .../test/core/test_reach_franka_presets.py | 2 +- 5 files changed, 16 insertions(+), 19 deletions(-) delete mode 100644 source/isaaclab_tasks/changelog.d/maximiliank-franka-menagerie-path-test.skip diff --git a/source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.minor.rst b/source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.minor.rst index 33ce4a3d797c..9e18484ab1d4 100644 --- a/source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.minor.rst +++ b/source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.minor.rst @@ -9,8 +9,9 @@ Deprecated ^^^^^^^^^^ * Deprecated ``FRANKA_PANDA_CFG``, ``FRANKA_PANDA_HIGH_PD_CFG``, and - ``FRANKA_PANDA_MENAGERIE_CFG`` for removal in Isaac Lab 4.0. The legacy Panda USD and actuator - groups remain available through the first two names. **Breaking:** the nested Menagerie USD moved - from ``franka_panda.usda`` to ``franka_panda_nestedInstance.usda``; code that reads or overrides - its path must use the new filename. Migrate to the corresponding ``FRANKA_PANDA_FLAT_*`` config, - replace shoulder/forearm actuator overrides with ``panda_arm``, and select the backend's ``Physics`` variant. + ``FRANKA_PANDA_MENAGERIE_CFG`` for removal in Isaac Lab 4.0. Their USD paths and actuator groups + remain available during deprecation. **Breaking:** the published ``franka_panda.usda`` now contains + the flat asset; consumers needing the old nested hierarchy can explicitly select + ``franka_panda_nestedInstance.usda``. Migrate maintained tasks to the corresponding + ``FRANKA_PANDA_FLAT_*`` config, replace shoulder/forearm actuator overrides with ``panda_arm``, + and select the backend's ``Physics`` variant. diff --git a/source/isaaclab_assets/isaaclab_assets/robots/franka.py b/source/isaaclab_assets/isaaclab_assets/robots/franka.py index dabb72a2025d..58c11d833c83 100644 --- a/source/isaaclab_assets/isaaclab_assets/robots/franka.py +++ b/source/isaaclab_assets/isaaclab_assets/robots/franka.py @@ -11,12 +11,12 @@ * :obj:`FRANKA_PANDA_FLAT_HIGH_PD_CFG`: Flat asset with stiffer PD control * :obj:`FRANKA_PANDA_CFG`: Deprecated alias retaining the legacy asset and actuators * :obj:`FRANKA_PANDA_HIGH_PD_CFG`: Deprecated legacy high-PD configuration -* :obj:`FRANKA_PANDA_MENAGERIE_CFG`: Deprecated nested-instance Menagerie configuration +* :obj:`FRANKA_PANDA_MENAGERIE_CFG`: Deprecated Menagerie actuator configuration * :obj:`FRANKA_ROBOTIQ_GRIPPER_CFG`: Franka robot with Robotiq_2f_85 gripper The old public names remain available during deprecation. Use ``FRANKA_PANDA_FLAT_CFG`` for new code -and select its ``Physics`` variant for the chosen backend. The former Menagerie asset was relocated to -``franka_panda_nestedInstance.usda``; the flat asset now occupies ``franka_panda.usda``. +and select its ``Physics`` variant for the chosen backend. The published ``franka_panda.usda`` is now +the flat asset; the former nested-instance file remains available as an explicit USD-path override. Reference: https://github.com/frankaemika/franka_ros """ @@ -211,11 +211,9 @@ _FRANKA_PANDA_LEGACY_HIGH_PD_CFG.actuators[actuator].damping = 80.0 -_FRANKA_PANDA_NESTED_MENAGERIE_CFG = clone(_FRANKA_PANDA_LEGACY_CFG) -_FRANKA_PANDA_NESTED_MENAGERIE_CFG.spawn.usd_path = ( - f"{ISAACLAB_NUCLEUS_DIR}/Robots/FrankaEmika/franka_panda_nestedInstance.usda" -) -_FRANKA_PANDA_NESTED_MENAGERIE_CFG.actuators = { +_FRANKA_PANDA_MENAGERIE_COMPAT_CFG = clone(_FRANKA_PANDA_LEGACY_CFG) +_FRANKA_PANDA_MENAGERIE_COMPAT_CFG.spawn.usd_path = f"{ISAACLAB_NUCLEUS_DIR}/Robots/FrankaEmika/franka_panda.usda" +_FRANKA_PANDA_MENAGERIE_COMPAT_CFG.actuators = { "panda_arm": ImplicitActuatorCfg( joint_names_expr=["panda_joint[1-7]"], joint_velocity_limit={"panda_joint[1-4]": 20.0, "panda_joint[5-7]": 25.0}, @@ -233,7 +231,7 @@ _DEPRECATED_FRANKA_CFGS = { "FRANKA_PANDA_CFG": (_FRANKA_PANDA_LEGACY_CFG, "FRANKA_PANDA_FLAT_CFG"), "FRANKA_PANDA_HIGH_PD_CFG": (_FRANKA_PANDA_LEGACY_HIGH_PD_CFG, "FRANKA_PANDA_FLAT_HIGH_PD_CFG"), - "FRANKA_PANDA_MENAGERIE_CFG": (_FRANKA_PANDA_NESTED_MENAGERIE_CFG, "FRANKA_PANDA_FLAT_CFG"), + "FRANKA_PANDA_MENAGERIE_CFG": (_FRANKA_PANDA_MENAGERIE_COMPAT_CFG, "FRANKA_PANDA_FLAT_CFG"), } if TYPE_CHECKING: @@ -247,8 +245,6 @@ def __getattr__(name: str) -> ArticulationCfg: raise AttributeError(f"module {__name__!r} has no attribute {name!r}") cfg, replacement = _DEPRECATED_FRANKA_CFGS[name] message = f"{name} is deprecated and will be removed in Isaac Lab 4.0. Use {replacement}." - if name == "FRANKA_PANDA_MENAGERIE_CFG": - message += " The nested asset moved from franka_panda.usda to franka_panda_nestedInstance.usda." warnings.warn(message, DeprecationWarning, stacklevel=2) return cfg diff --git a/source/isaaclab_assets/test/test_valid_configs.py b/source/isaaclab_assets/test/test_valid_configs.py index e520f072f532..7f9a0e4b57d9 100644 --- a/source/isaaclab_assets/test/test_valid_configs.py +++ b/source/isaaclab_assets/test/test_valid_configs.py @@ -35,9 +35,9 @@ def test_franka_legacy_configs_warn_and_keep_their_contract() -> None: assert high_pd_cfg.actuators["panda_shoulder"].stiffness == 400.0 assert high_pd_cfg.actuators["panda_forearm"].stiffness == 400.0 - with pytest.warns(DeprecationWarning, match="franka_panda_nestedInstance.usda"): + with pytest.warns(DeprecationWarning, match="FRANKA_PANDA_MENAGERIE_CFG.*removed in Isaac Lab 4.0"): menagerie_cfg = franka_assets.FRANKA_PANDA_MENAGERIE_CFG - assert menagerie_cfg.spawn.usd_path.endswith("/franka_panda_nestedInstance.usda") + assert menagerie_cfg.spawn.usd_path.endswith("/franka_panda.usda") assert set(menagerie_cfg.actuators) == {"panda_arm", "panda_hand"} diff --git a/source/isaaclab_tasks/changelog.d/maximiliank-franka-menagerie-path-test.skip b/source/isaaclab_tasks/changelog.d/maximiliank-franka-menagerie-path-test.skip deleted file mode 100644 index e69de29bb2d1..000000000000 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 a3c29be66171..dcb0fe7f7728 100644 --- a/source/isaaclab_tasks/test/core/test_reach_franka_presets.py +++ b/source/isaaclab_tasks/test/core/test_reach_franka_presets.py @@ -145,7 +145,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_nestedInstance.usda") + assert cfg.scene.robot.spawn.usd_path.endswith("/FrankaEmika/franka_panda.usda") # Native SE(3) command convention: one relative 6-DoF pose objective. pose_objectives = [ From b78c6f046d910d344bcce07167cd7bc56c563842 Mon Sep 17 00:00:00 2001 From: Maximilian Krause Date: Wed, 30 Sep 2026 15:19:36 +0200 Subject: [PATCH 05/14] Preserve mixed body matches and correct Franka migration defaults --- .../maximiliank-direct-body-prim-resolution.rst | 3 ++- source/isaaclab/isaaclab/sim/utils/queries.py | 17 +++++++---------- source/isaaclab/test/sim/test_cloner.py | 12 ++++++++++++ .../maximiliank-franka-flat-config.minor.rst | 8 +++++--- .../isaaclab_assets/robots/franka.py | 4 ++-- .../isaaclab_assets/test/test_valid_configs.py | 6 +++--- 6 files changed, 31 insertions(+), 19 deletions(-) diff --git a/source/isaaclab/changelog.d/maximiliank-direct-body-prim-resolution.rst b/source/isaaclab/changelog.d/maximiliank-direct-body-prim-resolution.rst index 4ead32834c86..b5f3478e73a5 100644 --- a/source/isaaclab/changelog.d/maximiliank-direct-body-prim-resolution.rst +++ b/source/isaaclab/changelog.d/maximiliank-direct-body-prim-resolution.rst @@ -1,4 +1,5 @@ Fixed ^^^^^ -* Fixed direct rigid-body path queries so nested rigid-body descendants are not selected when the requested body matches. +* Fixed direct rigid-body path queries so nested rigid-body descendants are not selected when the requested body matches, + while preserving descendant matches below other requested non-rigid prims. diff --git a/source/isaaclab/isaaclab/sim/utils/queries.py b/source/isaaclab/isaaclab/sim/utils/queries.py index dc5c973ba033..1c569dd6c130 100644 --- a/source/isaaclab/isaaclab/sim/utils/queries.py +++ b/source/isaaclab/isaaclab/sim/utils/queries.py @@ -404,7 +404,7 @@ def resolve_matching_prims_from_source( raise_if_no_matches: Whether to raise if no prim matches ``path_expr``. Defaults to True. traverse_instance_prims: Whether to traverse instance prims when applying ``predicate``. prefer_direct_matches: Prefer matching prims named by ``path_expr`` over their matching descendants. - Descendants remain a fallback when no direct prim satisfies ``predicate``. + For each matched prim, descendants remain a fallback if that prim does not satisfy ``predicate``. Returns: A list of ``(source_prim, destination_expr)`` pairs. Empty only when @@ -471,25 +471,22 @@ def resolve_matching_prims_from_source( path = prim.GetPath().pathString if path == instance_root or path.startswith(instance_root + "/"): results.append((prim, instance_expr + path[len(instance_root) :])) - direct_source_paths = {source.GetPath().pathString for source, _ in results} if prefer_direct_matches else set() if predicate is not None: # Whole-path regexes can select both a prim and its ancestors; their descendant sets overlap. unique_matches = {} for source, dest in results: source_path = source.GetPath().pathString - children = get_all_matching_child_prims( - source_path, predicate, traverse_instance_prims=traverse_instance_prims - ) + if prefer_direct_matches and predicate(source): + children = [source] + else: + children = get_all_matching_child_prims( + source_path, predicate, traverse_instance_prims=traverse_instance_prims + ) for child in children: child_path = child.GetPath().pathString unique_matches.setdefault(child_path, (child, dest + child_path[len(source_path) :])) results = list(unique_matches.values()) - if prefer_direct_matches: - direct_matches = [pair for pair in results if pair[0].GetPath().pathString in direct_source_paths] - if direct_matches: - results = direct_matches - if expected_num_matches is not None and len(results) != expected_num_matches: raise RuntimeError(f"Expected {expected_num_matches} prims at '{path_expr}', found {len(results)}.") if raise_if_no_matches and not results: diff --git a/source/isaaclab/test/sim/test_cloner.py b/source/isaaclab/test/sim/test_cloner.py index ea45ced6568e..9ff68c54165d 100644 --- a/source/isaaclab/test/sim/test_cloner.py +++ b/source/isaaclab/test/sim/test_cloner.py @@ -294,6 +294,18 @@ def test_resolve_matching_prims_from_source(sim, with_clone_plan): ) assert [prim.GetPath().pathString for prim, _ in matches] == ["/World/envs/env_0/Robot/foo"] + # A direct match must not hide another matched root's predicate-matching descendants. + matches = queries.resolve_matching_prims_from_source( + r"/World/envs/env_[^/]+/Robot/(foo|other)", + predicate=lambda prim: prim.GetName() in {"foo", "bar"}, + expected_num_matches=2, + prefer_direct_matches=True, + ) + assert [(prim.GetPath().pathString, path) for prim, path in matches] == [ + ("/World/envs/env_0/Robot/foo", "/World/envs/env_[^/]+/Robot/foo"), + ("/World/envs/env_0/Robot/other/bar", "/World/envs/env_[^/]+/Robot/other/bar"), + ] + def test_resolve_direct_match_from_external_prototype(sim): """Prefer the requested body even when its prototype is outside the destination namespace.""" diff --git a/source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.minor.rst b/source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.minor.rst index 9e18484ab1d4..873eb0c06d63 100644 --- a/source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.minor.rst +++ b/source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.minor.rst @@ -3,14 +3,16 @@ Added * Added ``FRANKA_PANDA_FLAT_CFG`` and ``FRANKA_PANDA_FLAT_HIGH_PD_CFG`` for the shared flat Franka asset. These configurations selected gripper-only colliders and the ``panda_arm`` actuator group; - select the ``Physics`` variant for the target backend. + select the ``Physics`` variant for the target backend. Arm effort limits matched the Panda's + 87 Nm shoulder and 12 Nm forearm limits; checkpoints trained with different limits require requalification. Deprecated ^^^^^^^^^^ * Deprecated ``FRANKA_PANDA_CFG``, ``FRANKA_PANDA_HIGH_PD_CFG``, and - ``FRANKA_PANDA_MENAGERIE_CFG`` for removal in Isaac Lab 4.0. Their USD paths and actuator groups - remain available during deprecation. **Breaking:** the published ``franka_panda.usda`` now contains + ``FRANKA_PANDA_MENAGERIE_CFG`` with visible import warnings for removal in Isaac Lab 4.0. + Their USD paths and actuator groups remain available during deprecation. + **Breaking:** the published ``franka_panda.usda`` now contains the flat asset; consumers needing the old nested hierarchy can explicitly select ``franka_panda_nestedInstance.usda``. Migrate maintained tasks to the corresponding ``FRANKA_PANDA_FLAT_*`` config, replace shoulder/forearm actuator overrides with ``panda_arm``, diff --git a/source/isaaclab_assets/isaaclab_assets/robots/franka.py b/source/isaaclab_assets/isaaclab_assets/robots/franka.py index 58c11d833c83..f5c30772b5c4 100644 --- a/source/isaaclab_assets/isaaclab_assets/robots/franka.py +++ b/source/isaaclab_assets/isaaclab_assets/robots/franka.py @@ -101,7 +101,7 @@ FRANKA_PANDA_FLAT_CFG.actuators = { "panda_arm": ImplicitActuatorCfg( joint_names_expr=["panda_joint[1-7]"], - joint_effort_limit={"panda_joint[1-4]": 100.0, "panda_joint[5-7]": 12.0}, + joint_effort_limit={"panda_joint[1-4]": 87.0, "panda_joint[5-7]": 12.0}, joint_velocity_limit={"panda_joint[1-4]": 20.0, "panda_joint[5-7]": 25.0}, stiffness=None, damping=None, @@ -245,7 +245,7 @@ def __getattr__(name: str) -> ArticulationCfg: raise AttributeError(f"module {__name__!r} has no attribute {name!r}") cfg, replacement = _DEPRECATED_FRANKA_CFGS[name] message = f"{name} is deprecated and will be removed in Isaac Lab 4.0. Use {replacement}." - warnings.warn(message, DeprecationWarning, stacklevel=2) + warnings.warn(message, FutureWarning, stacklevel=2) return cfg diff --git a/source/isaaclab_assets/test/test_valid_configs.py b/source/isaaclab_assets/test/test_valid_configs.py index 7f9a0e4b57d9..0033be07057d 100644 --- a/source/isaaclab_assets/test/test_valid_configs.py +++ b/source/isaaclab_assets/test/test_valid_configs.py @@ -24,18 +24,18 @@ def test_franka_legacy_configs_warn_and_keep_their_contract() -> None: """Deprecated Franka names retain their previous asset and actuator contracts.""" - with pytest.warns(DeprecationWarning, match="FRANKA_PANDA_CFG.*removed in Isaac Lab 4.0"): + with pytest.warns(FutureWarning, match="FRANKA_PANDA_CFG.*removed in Isaac Lab 4.0"): legacy_cfg = franka_assets.FRANKA_PANDA_CFG assert legacy_cfg.spawn.usd_path.endswith("/Legacy/panda_instanceable.usd") assert set(legacy_cfg.actuators) == {"panda_shoulder", "panda_forearm", "panda_hand"} - with pytest.warns(DeprecationWarning, match="FRANKA_PANDA_HIGH_PD_CFG.*removed in Isaac Lab 4.0"): + with pytest.warns(FutureWarning, match="FRANKA_PANDA_HIGH_PD_CFG.*removed in Isaac Lab 4.0"): high_pd_cfg = franka_assets.FRANKA_PANDA_HIGH_PD_CFG assert high_pd_cfg.spawn.usd_path == legacy_cfg.spawn.usd_path assert high_pd_cfg.actuators["panda_shoulder"].stiffness == 400.0 assert high_pd_cfg.actuators["panda_forearm"].stiffness == 400.0 - with pytest.warns(DeprecationWarning, match="FRANKA_PANDA_MENAGERIE_CFG.*removed in Isaac Lab 4.0"): + with pytest.warns(FutureWarning, match="FRANKA_PANDA_MENAGERIE_CFG.*removed in Isaac Lab 4.0"): menagerie_cfg = franka_assets.FRANKA_PANDA_MENAGERIE_CFG assert menagerie_cfg.spawn.usd_path.endswith("/franka_panda.usda") assert set(menagerie_cfg.actuators) == {"panda_arm", "panda_hand"} From 691c593ee24abbe60c574538ff72fbd4692d3cda Mon Sep 17 00:00:00 2001 From: Maximilian Krause Date: Wed, 30 Sep 2026 18:34:42 +0200 Subject: [PATCH 06/14] Declare the canonical Franka configuration independently --- .../isaaclab_assets/robots/franka.py | 98 ++++++++++--------- 1 file changed, 54 insertions(+), 44 deletions(-) diff --git a/source/isaaclab_assets/isaaclab_assets/robots/franka.py b/source/isaaclab_assets/isaaclab_assets/robots/franka.py index f5c30772b5c4..da3674e44f23 100644 --- a/source/isaaclab_assets/isaaclab_assets/robots/franka.py +++ b/source/isaaclab_assets/isaaclab_assets/robots/franka.py @@ -37,6 +37,20 @@ # Configuration ## +_FRANKA_PANDA_INITIAL_STATE = ArticulationCfg.InitialStateCfg( + joint_pos={ + "panda_joint1": 0.0, + "panda_joint2": -0.569, + "panda_joint3": 0.0, + "panda_joint4": -2.810, + "panda_joint5": 0.0, + "panda_joint6": 3.037, + "panda_joint7": 0.741, + "panda_finger_joint.*": 0.04, + }, +) + + _FRANKA_PANDA_LEGACY_CFG = ArticulationCfg( spawn=sim_utils.UsdFileCfg( usd_path=f"{ISAACLAB_NUCLEUS_DIR}/Robots/FrankaEmika/Legacy/panda_instanceable.usd", @@ -50,18 +64,7 @@ ], # collision_props=sim_utils.CollisionPropertiesCfg(contact_offset=0.005, rest_offset=0.0), ), - init_state=ArticulationCfg.InitialStateCfg( - joint_pos={ - "panda_joint1": 0.0, - "panda_joint2": -0.569, - "panda_joint3": 0.0, - "panda_joint4": -2.810, - "panda_joint5": 0.0, - "panda_joint6": 3.037, - "panda_joint7": 0.741, - "panda_finger_joint.*": 0.04, - }, - ), + init_state=clone(_FRANKA_PANDA_INITIAL_STATE), actuators={ "panda_shoulder": ImplicitActuatorCfg( joint_names_expr=["panda_joint[1-4]"], @@ -89,39 +92,46 @@ """Configuration of the legacy Franka Emika Panda robot asset.""" -FRANKA_PANDA_FLAT_CFG = clone(_FRANKA_PANDA_LEGACY_CFG) -FRANKA_PANDA_FLAT_CFG.spawn.usd_path = f"{ISAACLAB_NUCLEUS_DIR}/Robots/FrankaEmika/franka_panda.usda" -FRANKA_PANDA_FLAT_CFG.spawn.variants = {"Physics": "physx", "Colliders": "gripper_only"} -next( - props for props in FRANKA_PANDA_FLAT_CFG.spawn.articulation_props if isinstance(props, PhysxArticulationCfg) -).enabled_self_collisions = False -next( - props for props in FRANKA_PANDA_FLAT_CFG.spawn.articulation_props if isinstance(props, NewtonArticulationCfg) -).self_collision_enabled = False -FRANKA_PANDA_FLAT_CFG.actuators = { - "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}, - joint_velocity_limit={"panda_joint[1-4]": 20.0, "panda_joint[5-7]": 25.0}, - stiffness=None, - damping=None, - viscous_friction=0.0, - ), - "panda_hand": ImplicitActuatorCfg( - joint_names_expr=["panda_finger_joint1"], - joint_effort_limit=200.0, - stiffness=None, - damping=None, - viscous_friction=0.0, - ), - "panda_finger2_passive": ImplicitActuatorCfg( - joint_names_expr=["panda_finger_joint2"], - joint_effort_limit=200.0, - stiffness=0.0, - damping=0.0, - viscous_friction=0.0, +FRANKA_PANDA_FLAT_CFG = ArticulationCfg( + spawn=sim_utils.UsdFileCfg( + usd_path=f"{ISAACLAB_NUCLEUS_DIR}/Robots/FrankaEmika/franka_panda.usda", + variants={"Physics": "physx", "Colliders": "gripper_only"}, + activate_contact_sensors=False, + rigid_props=PhysxRigidBodyCfg(disable_gravity=False, max_depenetration_velocity=5.0), + articulation_props=[ + PhysxArticulationCfg( + enabled_self_collisions=False, solver_position_iteration_count=8, solver_velocity_iteration_count=0 + ), + NewtonArticulationCfg(self_collision_enabled=False), + ], ), -} + init_state=clone(_FRANKA_PANDA_INITIAL_STATE), + actuators={ + "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}, + joint_velocity_limit={"panda_joint[1-4]": 20.0, "panda_joint[5-7]": 25.0}, + stiffness=None, + damping=None, + viscous_friction=0.0, + ), + "panda_hand": ImplicitActuatorCfg( + joint_names_expr=["panda_finger_joint1"], + joint_effort_limit=200.0, + stiffness=None, + damping=None, + viscous_friction=0.0, + ), + "panda_finger2_passive": ImplicitActuatorCfg( + joint_names_expr=["panda_finger_joint2"], + joint_effort_limit=200.0, + stiffness=0.0, + damping=0.0, + viscous_friction=0.0, + ), + }, + soft_joint_pos_limit_factor=1.0, +) """Configuration of the Franka Emika Panda robot. The flat asset contains PhysX and MuJoCo physics variants and gripper-only, primitive, and convex-hull From 2b64e784216ffd288ccafe0294ba37e87bc8351c Mon Sep 17 00:00:00 2001 From: Maximilian Krause Date: Thu, 1 Oct 2026 00:17:11 +0200 Subject: [PATCH 07/14] Migrate Franka changelog fragments to Towncrier --- ...maximiliank-direct-body-prim-resolution.fixed.rst} | 3 --- .../maximiliank-franka-flat-config.added.rst | 4 ++++ ... => maximiliank-franka-flat-config.deprecated.rst} | 11 ----------- .../changelog.d/maximiliank-franka-flat-config.minor | 0 ...imiliank-franka-material-body-selection.fixed.rst} | 3 --- ...miliank-frame-transformer-nested-bodies.fixed.rst} | 3 --- ...miliank-frame-transformer-nested-bodies.fixed.rst} | 3 --- 7 files changed, 4 insertions(+), 23 deletions(-) rename source/isaaclab/changelog.d/{maximiliank-direct-body-prim-resolution.rst => maximiliank-direct-body-prim-resolution.fixed.rst} (93%) create mode 100644 source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.added.rst rename source/isaaclab_assets/changelog.d/{maximiliank-franka-flat-config.minor.rst => maximiliank-franka-flat-config.deprecated.rst} (58%) create mode 100644 source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.minor rename source/isaaclab_newton/changelog.d/{maximiliank-franka-material-body-selection.rst => maximiliank-franka-material-body-selection.fixed.rst} (90%) rename source/{isaaclab_physx/changelog.d/maximiliank-frame-transformer-nested-bodies.rst => isaaclab_ov/changelog.d/maximiliank-frame-transformer-nested-bodies.fixed.rst} (90%) rename source/{isaaclab_ov/changelog.d/maximiliank-frame-transformer-nested-bodies.rst => isaaclab_physx/changelog.d/maximiliank-frame-transformer-nested-bodies.fixed.rst} (90%) diff --git a/source/isaaclab/changelog.d/maximiliank-direct-body-prim-resolution.rst b/source/isaaclab/changelog.d/maximiliank-direct-body-prim-resolution.fixed.rst similarity index 93% rename from source/isaaclab/changelog.d/maximiliank-direct-body-prim-resolution.rst rename to source/isaaclab/changelog.d/maximiliank-direct-body-prim-resolution.fixed.rst index b5f3478e73a5..57e1244eea39 100644 --- a/source/isaaclab/changelog.d/maximiliank-direct-body-prim-resolution.rst +++ b/source/isaaclab/changelog.d/maximiliank-direct-body-prim-resolution.fixed.rst @@ -1,5 +1,2 @@ -Fixed -^^^^^ - * Fixed direct rigid-body path queries so nested rigid-body descendants are not selected when the requested body matches, while preserving descendant matches below other requested non-rigid prims. diff --git a/source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.added.rst b/source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.added.rst new file mode 100644 index 000000000000..33cbdd88ed0d --- /dev/null +++ b/source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.added.rst @@ -0,0 +1,4 @@ +* Added ``FRANKA_PANDA_FLAT_CFG`` and ``FRANKA_PANDA_FLAT_HIGH_PD_CFG`` for the shared flat Franka + asset. These configurations selected gripper-only colliders and the ``panda_arm`` actuator group; + select the ``Physics`` variant for the target backend. Arm effort limits matched the Panda's + 87 Nm shoulder and 12 Nm forearm limits; checkpoints trained with different limits require requalification. diff --git a/source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.minor.rst b/source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.deprecated.rst similarity index 58% rename from source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.minor.rst rename to source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.deprecated.rst index 873eb0c06d63..3062168065c8 100644 --- a/source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.minor.rst +++ b/source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.deprecated.rst @@ -1,14 +1,3 @@ -Added -^^^^^ - -* Added ``FRANKA_PANDA_FLAT_CFG`` and ``FRANKA_PANDA_FLAT_HIGH_PD_CFG`` for the shared flat Franka - asset. These configurations selected gripper-only colliders and the ``panda_arm`` actuator group; - select the ``Physics`` variant for the target backend. Arm effort limits matched the Panda's - 87 Nm shoulder and 12 Nm forearm limits; checkpoints trained with different limits require requalification. - -Deprecated -^^^^^^^^^^ - * Deprecated ``FRANKA_PANDA_CFG``, ``FRANKA_PANDA_HIGH_PD_CFG``, and ``FRANKA_PANDA_MENAGERIE_CFG`` with visible import warnings for removal in Isaac Lab 4.0. Their USD paths and actuator groups remain available during deprecation. diff --git a/source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.minor b/source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.minor new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/source/isaaclab_newton/changelog.d/maximiliank-franka-material-body-selection.rst b/source/isaaclab_newton/changelog.d/maximiliank-franka-material-body-selection.fixed.rst similarity index 90% rename from source/isaaclab_newton/changelog.d/maximiliank-franka-material-body-selection.rst rename to source/isaaclab_newton/changelog.d/maximiliank-franka-material-body-selection.fixed.rst index f3763ed81629..ffeafb8d49c8 100644 --- a/source/isaaclab_newton/changelog.d/maximiliank-franka-material-body-selection.rst +++ b/source/isaaclab_newton/changelog.d/maximiliank-franka-material-body-selection.fixed.rst @@ -1,4 +1 @@ -Fixed -^^^^^ - * Fixed Newton articulation material randomization for bodies whose shapes are interleaved in the native shape array. diff --git a/source/isaaclab_physx/changelog.d/maximiliank-frame-transformer-nested-bodies.rst b/source/isaaclab_ov/changelog.d/maximiliank-frame-transformer-nested-bodies.fixed.rst similarity index 90% rename from source/isaaclab_physx/changelog.d/maximiliank-frame-transformer-nested-bodies.rst rename to source/isaaclab_ov/changelog.d/maximiliank-frame-transformer-nested-bodies.fixed.rst index 02a80fb24471..2b8ebda96109 100644 --- a/source/isaaclab_physx/changelog.d/maximiliank-frame-transformer-nested-bodies.rst +++ b/source/isaaclab_ov/changelog.d/maximiliank-frame-transformer-nested-bodies.fixed.rst @@ -1,5 +1,2 @@ -Fixed -^^^^^ - * Fixed frame-transformer path expressions that directly match a rigid body from also selecting nested rigid-body descendants. diff --git a/source/isaaclab_ov/changelog.d/maximiliank-frame-transformer-nested-bodies.rst b/source/isaaclab_physx/changelog.d/maximiliank-frame-transformer-nested-bodies.fixed.rst similarity index 90% rename from source/isaaclab_ov/changelog.d/maximiliank-frame-transformer-nested-bodies.rst rename to source/isaaclab_physx/changelog.d/maximiliank-frame-transformer-nested-bodies.fixed.rst index 02a80fb24471..2b8ebda96109 100644 --- a/source/isaaclab_ov/changelog.d/maximiliank-frame-transformer-nested-bodies.rst +++ b/source/isaaclab_physx/changelog.d/maximiliank-frame-transformer-nested-bodies.fixed.rst @@ -1,5 +1,2 @@ -Fixed -^^^^^ - * Fixed frame-transformer path expressions that directly match a rigid body from also selecting nested rigid-body descendants. From be3f19e83fb01f17aa356157985fcb953d9a8d7f Mon Sep 17 00:00:00 2001 From: Mustafa Haiderbhai Date: Wed, 30 Sep 2026 17:07:42 -0700 Subject: [PATCH 08/14] Fix Franka Pour startup with the synced asset --- .../franka-pour-synced-mimic.fixed.rst | 2 + .../contrib/franka_pour/pour_env_cfg.py | 45 ++++--------------- .../test/contrib/test_franka_pour_env_cfg.py | 2 +- 3 files changed, 11 insertions(+), 38 deletions(-) create mode 100644 source/isaaclab_tasks/changelog.d/franka-pour-synced-mimic.fixed.rst diff --git a/source/isaaclab_tasks/changelog.d/franka-pour-synced-mimic.fixed.rst b/source/isaaclab_tasks/changelog.d/franka-pour-synced-mimic.fixed.rst new file mode 100644 index 000000000000..f68ef8e4c47f --- /dev/null +++ b/source/isaaclab_tasks/changelog.d/franka-pour-synced-mimic.fixed.rst @@ -0,0 +1,2 @@ +* Fixed Franka Pour startup with the shared Franka asset by selecting its MuJoCo physics payload + and removing the obsolete duplicate-mimic workaround. 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/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(): From d875614aad908268df75627ea3ea005f5edd6804 Mon Sep 17 00:00:00 2001 From: Mustafa Haiderbhai Date: Wed, 30 Sep 2026 17:07:42 -0700 Subject: [PATCH 09/14] Consolidate Franka regression coverage --- source/isaaclab/test/sim/test_cloner.py | 39 +++++++------------ .../test/test_valid_configs.py | 20 ---------- .../test/assets/test_articulation.py | 39 ++++++------------- .../test/sensors/test_frame_transformer.py | 3 +- 4 files changed, 29 insertions(+), 72 deletions(-) diff --git a/source/isaaclab/test/sim/test_cloner.py b/source/isaaclab/test/sim/test_cloner.py index 9ff68c54165d..fdf88ccc1130 100644 --- a/source/isaaclab/test/sim/test_cloner.py +++ b/source/isaaclab/test/sim/test_cloner.py @@ -286,14 +286,6 @@ def test_resolve_matching_prims_from_source(sim, with_clone_plan): "/World/envs/env_[^/]+/Robot/other/bar", ] - matches = queries.resolve_matching_prims_from_source( - r"/World/envs/env_[^/]+/Robot/foo", - predicate=lambda prim: prim.GetName() in {"foo", "bar"}, - expected_num_matches=1, - prefer_direct_matches=True, - ) - assert [prim.GetPath().pathString for prim, _ in matches] == ["/World/envs/env_0/Robot/foo"] - # A direct match must not hide another matched root's predicate-matching descendants. matches = queries.resolve_matching_prims_from_source( r"/World/envs/env_[^/]+/Robot/(foo|other)", @@ -306,20 +298,19 @@ def test_resolve_matching_prims_from_source(sim, with_clone_plan): ("/World/envs/env_0/Robot/other/bar", "/World/envs/env_[^/]+/Robot/other/bar"), ] + if with_clone_plan: + stage.DefinePrim("/World/template/Robot/foo/bar", "Xform") + asset = AssetBaseCfg( + prim_path="/World/envs/env_[^/]+/Robot", spawn=SpawnerCfg(spawn_path="/World/template/Robot") + ) + sim.set_clone_plan(make_clone_plan((asset,), ((0,),), 2)) -def test_resolve_direct_match_from_external_prototype(sim): - """Prefer the requested body even when its prototype is outside the destination namespace.""" - stage = sim_utils.get_current_stage() - stage.DefinePrim("/World/template/Robot/foo/bar", "Xform") - asset = AssetBaseCfg(prim_path="/World/envs/env_[^/]+/Robot", spawn=SpawnerCfg(spawn_path="/World/template/Robot")) - sim.set_clone_plan(make_clone_plan((asset,), ((0,),), 2)) - - matches = queries.resolve_matching_prims_from_source( - r"/World/envs/env_[^/]+/Robot/foo", - predicate=lambda prim: prim.GetName() in {"foo", "bar"}, - expected_num_matches=1, - prefer_direct_matches=True, - ) - assert [(prim.GetPath().pathString, path) for prim, path in matches] == [ - ("/World/template/Robot/foo", "/World/envs/env_[^/]+/Robot/foo") - ] + matches = queries.resolve_matching_prims_from_source( + r"/World/envs/env_[^/]+/Robot/foo", + predicate=lambda prim: prim.GetName() in {"foo", "bar"}, + expected_num_matches=1, + prefer_direct_matches=True, + ) + assert [(prim.GetPath().pathString, path) for prim, path in matches] == [ + ("/World/template/Robot/foo", "/World/envs/env_[^/]+/Robot/foo") + ] diff --git a/source/isaaclab_assets/test/test_valid_configs.py b/source/isaaclab_assets/test/test_valid_configs.py index 0033be07057d..3832e196def1 100644 --- a/source/isaaclab_assets/test/test_valid_configs.py +++ b/source/isaaclab_assets/test/test_valid_configs.py @@ -19,26 +19,6 @@ from isaaclab.test.utils import DeviceScope, test_devices import isaaclab_assets as lab_assets # noqa: F401 -import isaaclab_assets.robots.franka as franka_assets - - -def test_franka_legacy_configs_warn_and_keep_their_contract() -> None: - """Deprecated Franka names retain their previous asset and actuator contracts.""" - with pytest.warns(FutureWarning, match="FRANKA_PANDA_CFG.*removed in Isaac Lab 4.0"): - legacy_cfg = franka_assets.FRANKA_PANDA_CFG - assert legacy_cfg.spawn.usd_path.endswith("/Legacy/panda_instanceable.usd") - assert set(legacy_cfg.actuators) == {"panda_shoulder", "panda_forearm", "panda_hand"} - - with pytest.warns(FutureWarning, match="FRANKA_PANDA_HIGH_PD_CFG.*removed in Isaac Lab 4.0"): - high_pd_cfg = franka_assets.FRANKA_PANDA_HIGH_PD_CFG - assert high_pd_cfg.spawn.usd_path == legacy_cfg.spawn.usd_path - assert high_pd_cfg.actuators["panda_shoulder"].stiffness == 400.0 - assert high_pd_cfg.actuators["panda_forearm"].stiffness == 400.0 - - with pytest.warns(FutureWarning, match="FRANKA_PANDA_MENAGERIE_CFG.*removed in Isaac Lab 4.0"): - menagerie_cfg = franka_assets.FRANKA_PANDA_MENAGERIE_CFG - assert menagerie_cfg.spawn.usd_path.endswith("/franka_panda.usda") - assert set(menagerie_cfg.actuators) == {"panda_arm", "panda_hand"} @pytest.fixture(scope="module") diff --git a/source/isaaclab_ov/test/assets/test_articulation.py b/source/isaaclab_ov/test/assets/test_articulation.py index d77c7c41d906..34d9a51c1c2a 100644 --- a/source/isaaclab_ov/test/assets/test_articulation.py +++ b/source/isaaclab_ov/test/assets/test_articulation.py @@ -529,32 +529,6 @@ def generate_articulation( return articulation, translations -@pytest.mark.parametrize("device", ["cuda:0"]) -@pytest.mark.parametrize("gravity_enabled", [False]) -def test_franka_ovphysx_mimic_constraint_tracks_passive_finger(sim, device, gravity_enabled): - """Drive only the Franka leader finger and preserve mimic tracking in every clone.""" - articulation, _ = generate_articulation(FRANKA_PANDA_FLAT_CFG, 2, device) - sim.reset() - - leader_id = articulation.find_joints("panda_finger_joint1")[0][0] - follower_id = articulation.find_joints("panda_finger_joint2")[0][0] - initial_leader_pos = articulation.data.joint_pos.torch[:, leader_id].clone() - leader_target = torch.full((articulation.num_instances, 1), 0.01, device=device) - articulation.actuators.target_command.set_position_index(value=leader_target, joint_ids=[leader_id]) - - for _ in range(120): - articulation.write_data_to_sim() - sim.step() - articulation.update(sim.cfg.dt) - assert torch.isfinite(articulation.data.joint_pos.torch).all() - assert torch.isfinite(articulation.data.joint_vel.torch).all() - - leader_pos = articulation.data.joint_pos.torch[:, leader_id] - follower_pos = articulation.data.joint_pos.torch[:, follower_id] - assert torch.all(torch.abs(leader_pos - initial_leader_pos) > 0.005) - torch.testing.assert_close(follower_pos, leader_pos, rtol=0.0, atol=5.0e-4) - - @pytest.mark.parametrize("device", ["cuda:0"]) def test_newton_native_explicit_actuator_submits_ovphysx_effort(device): """Run a Newton-native explicit actuator through the current OVPhysX state and effort binding.""" @@ -2346,7 +2320,7 @@ def test_reset(sim, num_articulations, device): @pytest.mark.parametrize("device", test_devices()) @pytest.mark.parametrize("add_ground_plane", [True]) def test_apply_joint_command(sim, num_articulations, device, add_ground_plane): - """Test applying of joint position target functions correctly for a robotic arm.""" + """Arm targets track commands while the passive finger follows the driven finger.""" articulation_cfg = generate_articulation_cfg(articulation_type="panda") articulation, _ = generate_articulation( articulation_cfg=articulation_cfg, num_articulations=num_articulations, device=device @@ -2364,6 +2338,10 @@ def test_apply_joint_command(sim, num_articulations, device, add_ground_plane): # reset dof state joint_pos = articulation.data.default_joint_pos.torch.clone() joint_pos[:, 3] = 0.0 + leader_id = articulation.find_joints("panda_finger_joint1")[0][0] + follower_id = articulation.find_joints("panda_finger_joint2")[0][0] + initial_leader_pos = articulation.data.joint_pos.torch[:, leader_id].clone() + joint_pos[:, [leader_id, follower_id]] = 0.01 # apply action to the articulation articulation.set_joint_position_target_index(target=joint_pos) @@ -2380,6 +2358,13 @@ def test_apply_joint_command(sim, num_articulations, device, add_ground_plane): # every joint toward zero instead (the wrist ends near 0.3 rad instead of 3.0 rad). torch.testing.assert_close(articulation.data.joint_pos.torch[:, 3:], joint_pos[:, 3:], atol=0.1, rtol=0.0) + leader_pos = articulation.data.joint_pos.torch[:, leader_id] + follower_pos = articulation.data.joint_pos.torch[:, follower_id] + assert torch.isfinite(articulation.data.joint_pos.torch).all() + assert torch.isfinite(articulation.data.joint_vel.torch).all() + assert torch.all(torch.abs(leader_pos - initial_leader_pos) > 0.005) + torch.testing.assert_close(follower_pos, leader_pos, rtol=0.0, atol=5.0e-4) + @pytest.mark.parametrize("num_articulations", [2]) @pytest.mark.parametrize("device", test_devices()) diff --git a/source/isaaclab_ov/test/sensors/test_frame_transformer.py b/source/isaaclab_ov/test/sensors/test_frame_transformer.py index 45aadfb9735b..328c7f475903 100644 --- a/source/isaaclab_ov/test/sensors/test_frame_transformer.py +++ b/source/isaaclab_ov/test/sensors/test_frame_transformer.py @@ -47,6 +47,7 @@ from isaaclab.sensors import BaseFrameTransformer, FrameTransformerCfg, OffsetCfg # noqa: E402 from isaaclab.sim import SimulationCfg, build_simulation_context # noqa: E402 from isaaclab.terrains import TerrainImporterCfg # noqa: E402 +from isaaclab.test.utils import DeviceScope, test_devices # noqa: E402 from isaaclab.utils import configclass, replace # noqa: E402 from isaaclab_assets.robots.anymal import ANYMAL_C_CFG # noqa: E402 @@ -671,7 +672,7 @@ class MultiRobotSceneCfg(InteractiveSceneCfg): ) -@pytest.mark.parametrize("device", ["cpu", "cuda:0"]) +@pytest.mark.parametrize("device", test_devices(DeviceScope.DEFAULT_CUDA)) def test_frame_transformer_nested_rigid_bodies(device): """Test that a matched rigid body does not include nested rigid-body descendants.""" with _ovphysx_sim_context(device=device) as sim: From dc7415d42c5ba7d73acf4c9daa8e2a59f1518895 Mon Sep 17 00:00:00 2001 From: Mustafa Haiderbhai Date: Wed, 30 Sep 2026 17:32:48 -0700 Subject: [PATCH 10/14] Simplify Franka config names and Pour overrides --- .../isaaclab_assets/robots/franka.py | 61 +++++++++---------- .../contrib/franka_pour/pour_env_cfg.py | 8 --- 2 files changed, 29 insertions(+), 40 deletions(-) diff --git a/source/isaaclab_assets/isaaclab_assets/robots/franka.py b/source/isaaclab_assets/isaaclab_assets/robots/franka.py index da3674e44f23..fda1c309798b 100644 --- a/source/isaaclab_assets/isaaclab_assets/robots/franka.py +++ b/source/isaaclab_assets/isaaclab_assets/robots/franka.py @@ -37,21 +37,7 @@ # Configuration ## -_FRANKA_PANDA_INITIAL_STATE = ArticulationCfg.InitialStateCfg( - joint_pos={ - "panda_joint1": 0.0, - "panda_joint2": -0.569, - "panda_joint3": 0.0, - "panda_joint4": -2.810, - "panda_joint5": 0.0, - "panda_joint6": 3.037, - "panda_joint7": 0.741, - "panda_finger_joint.*": 0.04, - }, -) - - -_FRANKA_PANDA_LEGACY_CFG = ArticulationCfg( +FRANKA_PANDA_LEGACY_CFG = ArticulationCfg( spawn=sim_utils.UsdFileCfg( usd_path=f"{ISAACLAB_NUCLEUS_DIR}/Robots/FrankaEmika/Legacy/panda_instanceable.usd", activate_contact_sensors=False, @@ -64,7 +50,18 @@ ], # collision_props=sim_utils.CollisionPropertiesCfg(contact_offset=0.005, rest_offset=0.0), ), - init_state=clone(_FRANKA_PANDA_INITIAL_STATE), + init_state=ArticulationCfg.InitialStateCfg( + joint_pos={ + "panda_joint1": 0.0, + "panda_joint2": -0.569, + "panda_joint3": 0.0, + "panda_joint4": -2.810, + "panda_joint5": 0.0, + "panda_joint6": 3.037, + "panda_joint7": 0.741, + "panda_finger_joint.*": 0.04, + }, + ), actuators={ "panda_shoulder": ImplicitActuatorCfg( joint_names_expr=["panda_joint[1-4]"], @@ -105,7 +102,7 @@ NewtonArticulationCfg(self_collision_enabled=False), ], ), - init_state=clone(_FRANKA_PANDA_INITIAL_STATE), + init_state=clone(FRANKA_PANDA_LEGACY_CFG.init_state), actuators={ "panda_arm": ImplicitActuatorCfg( joint_names_expr=["panda_joint[1-7]"], @@ -152,7 +149,7 @@ """ -FRANKA_ROBOTIQ_GRIPPER_CFG = clone(_FRANKA_PANDA_LEGACY_CFG) +FRANKA_ROBOTIQ_GRIPPER_CFG = clone(FRANKA_PANDA_LEGACY_CFG) FRANKA_ROBOTIQ_GRIPPER_CFG.spawn.usd_path = f"{ISAAC_NUCLEUS_DIR}/Robots/FrankaRobotics/FrankaPanda/franka.usd" FRANKA_ROBOTIQ_GRIPPER_CFG.spawn.variants = {"Gripper": "Robotiq_2F_85"} FRANKA_ROBOTIQ_GRIPPER_CFG.spawn.rigid_props.disable_gravity = True @@ -214,16 +211,16 @@ """Configuration of Franka Emika Panda robot with Robotiq_2f_85 gripper.""" -_FRANKA_PANDA_LEGACY_HIGH_PD_CFG = clone(_FRANKA_PANDA_LEGACY_CFG) -_FRANKA_PANDA_LEGACY_HIGH_PD_CFG.spawn.rigid_props.disable_gravity = True +FRANKA_PANDA_LEGACY_HIGH_PD_CFG = clone(FRANKA_PANDA_LEGACY_CFG) +FRANKA_PANDA_LEGACY_HIGH_PD_CFG.spawn.rigid_props.disable_gravity = True for actuator in ("panda_shoulder", "panda_forearm"): - _FRANKA_PANDA_LEGACY_HIGH_PD_CFG.actuators[actuator].stiffness = 400.0 - _FRANKA_PANDA_LEGACY_HIGH_PD_CFG.actuators[actuator].damping = 80.0 + FRANKA_PANDA_LEGACY_HIGH_PD_CFG.actuators[actuator].stiffness = 400.0 + FRANKA_PANDA_LEGACY_HIGH_PD_CFG.actuators[actuator].damping = 80.0 -_FRANKA_PANDA_MENAGERIE_COMPAT_CFG = clone(_FRANKA_PANDA_LEGACY_CFG) -_FRANKA_PANDA_MENAGERIE_COMPAT_CFG.spawn.usd_path = f"{ISAACLAB_NUCLEUS_DIR}/Robots/FrankaEmika/franka_panda.usda" -_FRANKA_PANDA_MENAGERIE_COMPAT_CFG.actuators = { +FRANKA_PANDA_LEGACY_MENAGERIE_CFG = clone(FRANKA_PANDA_LEGACY_CFG) +FRANKA_PANDA_LEGACY_MENAGERIE_CFG.spawn.usd_path = f"{ISAACLAB_NUCLEUS_DIR}/Robots/FrankaEmika/franka_panda.usda" +FRANKA_PANDA_LEGACY_MENAGERIE_CFG.actuators = { "panda_arm": ImplicitActuatorCfg( joint_names_expr=["panda_joint[1-7]"], joint_velocity_limit={"panda_joint[1-4]": 20.0, "panda_joint[5-7]": 25.0}, @@ -238,10 +235,10 @@ } -_DEPRECATED_FRANKA_CFGS = { - "FRANKA_PANDA_CFG": (_FRANKA_PANDA_LEGACY_CFG, "FRANKA_PANDA_FLAT_CFG"), - "FRANKA_PANDA_HIGH_PD_CFG": (_FRANKA_PANDA_LEGACY_HIGH_PD_CFG, "FRANKA_PANDA_FLAT_HIGH_PD_CFG"), - "FRANKA_PANDA_MENAGERIE_CFG": (_FRANKA_PANDA_MENAGERIE_COMPAT_CFG, "FRANKA_PANDA_FLAT_CFG"), +DEPRECATED_FRANKA_CFGS = { + "FRANKA_PANDA_CFG": (FRANKA_PANDA_LEGACY_CFG, "FRANKA_PANDA_FLAT_CFG"), + "FRANKA_PANDA_HIGH_PD_CFG": (FRANKA_PANDA_LEGACY_HIGH_PD_CFG, "FRANKA_PANDA_FLAT_HIGH_PD_CFG"), + "FRANKA_PANDA_MENAGERIE_CFG": (FRANKA_PANDA_LEGACY_MENAGERIE_CFG, "FRANKA_PANDA_FLAT_CFG"), } if TYPE_CHECKING: @@ -251,13 +248,13 @@ def __getattr__(name: str) -> ArticulationCfg: - if name not in _DEPRECATED_FRANKA_CFGS: + if name not in DEPRECATED_FRANKA_CFGS: raise AttributeError(f"module {__name__!r} has no attribute {name!r}") - cfg, replacement = _DEPRECATED_FRANKA_CFGS[name] + cfg, replacement = DEPRECATED_FRANKA_CFGS[name] message = f"{name} is deprecated and will be removed in Isaac Lab 4.0. Use {replacement}." warnings.warn(message, FutureWarning, stacklevel=2) return cfg def __dir__() -> list[str]: - return sorted(set(globals()) | _DEPRECATED_FRANKA_CFGS.keys()) + return sorted(set(globals()) | DEPRECATED_FRANKA_CFGS.keys()) 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 687eaa69c89e..6e521d15deb5 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 @@ -326,16 +326,8 @@ class PourSceneCfg(InteractiveSceneCfg): next( frag for frag in robot.spawn.articulation_props if isinstance(frag, NewtonArticulationCfg) ).self_collision_enabled = True - robot.actuators = { - name: replace( - actuator_cfg, effort_limit_sim=None, velocity_limit_sim=None, stiffness=None, damping=None, armature=None - ) - for name, actuator_cfg in robot.actuators.items() - } 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 From a1b4b84017b856b62c96170ad7269753b3373db3 Mon Sep 17 00:00:00 2001 From: Mustafa Haiderbhai Date: Wed, 30 Sep 2026 17:48:18 -0700 Subject: [PATCH 11/14] Make flat Franka the main config and name legacy configs explicitly --- .../tutorials/05_controllers/run_diff_ik.py | 4 +- scripts/tutorials/05_controllers/run_osc.py | 4 +- .../test/controllers/test_differential_ik.py | 4 +- .../controllers/test_operational_space.py | 4 +- .../maximiliank-franka-flat-config.added.rst | 4 -- ...maximiliank-franka-flat-config.changed.rst | 8 +++ ...imiliank-franka-flat-config.deprecated.rst | 8 --- ...r => maximiliank-franka-flat-config.major} | 0 .../isaaclab_assets/__init__.pyi | 8 +-- .../isaaclab_assets/robots/__init__.pyi | 8 +-- .../isaaclab_assets/robots/franka.py | 63 ++++++------------- .../test/assets/test_articulation.py | 10 +-- .../test/assets/test_articulation.py | 8 +-- .../test/sensors/test_frame_transformer.py | 4 +- .../test/assets/test_articulation.py | 26 ++++---- .../test/sensors/test_frame_transformer.py | 4 +- .../render_benchmark_env_cfg.py | 6 +- .../cabinet/config/franka/ik_abs_env_cfg.py | 4 +- .../cabinet/config/franka/ik_rel_env_cfg.py | 4 +- .../contrib/franka_pour/pour_env_cfg.py | 4 +- .../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 | 4 +- .../config/franka/bin_stack_ik_rel_env_cfg.py | 4 +- .../franka/bin_stack_joint_pos_env_cfg.py | 4 +- .../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 +- .../franka/stack_ik_rel_visuomotor_env_cfg.py | 4 +- .../config/franka/stack_joint_pos_env_cfg.py | 4 +- ...ck_joint_pos_instance_randomize_env_cfg.py | 4 +- .../config/franka/cabinet_direct_env_cfg.py | 4 +- .../config/franka/joint_pos_env_cfg.py | 4 +- .../core/lift/config/franka/franka_env_cfg.py | 4 +- .../config/franka/franka_reach_env_cfg.py | 8 +-- 37 files changed, 113 insertions(+), 144 deletions(-) delete mode 100644 source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.added.rst create mode 100644 source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.changed.rst delete mode 100644 source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.deprecated.rst rename source/isaaclab_assets/changelog.d/{maximiliank-franka-flat-config.minor => maximiliank-franka-flat-config.major} (100%) diff --git a/scripts/tutorials/05_controllers/run_diff_ik.py b/scripts/tutorials/05_controllers/run_diff_ik.py index 9f91b6596195..ded79b628ec6 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_LEGACY_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_LEGACY_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..d1769389c14a 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_LEGACY_HIGH_PD_CFG # isort:skip @configclass @@ -97,7 +97,7 @@ class SceneCfg(InteractiveSceneCfg): debug_vis=False, ) - robot = replace(FRANKA_PANDA_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot") + 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 diff --git a/source/isaaclab/test/controllers/test_differential_ik.py b/source/isaaclab/test/controllers/test_differential_ik.py index 4b91b1158cff..2b2af9e3ba68 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_LEGACY_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_LEGACY_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..2e7a3e4b09a9 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,7 @@ 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") + 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_assets/changelog.d/maximiliank-franka-flat-config.added.rst b/source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.added.rst deleted file mode 100644 index 33cbdd88ed0d..000000000000 --- a/source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.added.rst +++ /dev/null @@ -1,4 +0,0 @@ -* Added ``FRANKA_PANDA_FLAT_CFG`` and ``FRANKA_PANDA_FLAT_HIGH_PD_CFG`` for the shared flat Franka - asset. These configurations selected gripper-only colliders and the ``panda_arm`` actuator group; - select the ``Physics`` variant for the target backend. Arm effort limits matched the Panda's - 87 Nm shoulder and 12 Nm forearm limits; checkpoints trained with different limits require requalification. diff --git a/source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.changed.rst b/source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.changed.rst new file mode 100644 index 000000000000..914acc9f2ee1 --- /dev/null +++ b/source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.changed.rst @@ -0,0 +1,8 @@ +* **Breaking:** changed ``FRANKA_PANDA_CFG`` and ``FRANKA_PANDA_HIGH_PD_CFG`` to use the shared + flat Franka asset with gripper-only collisions, a single ``panda_arm`` actuator group, + and a driven leader finger with a passive mimic follower. + Use ``FRANKA_PANDA_LEGACY_CFG`` and ``FRANKA_PANDA_LEGACY_HIGH_PD_CFG`` to retain the + original USD path, shoulder/forearm actuator groups, gains, and collision settings. + Select the ``Physics`` variant for the backend when using the main configs. +* **Breaking:** the published ``franka_panda.usda`` now contains the flat asset. Consumers + needing the former nested hierarchy can explicitly select ``franka_panda_nestedInstance.usda``. diff --git a/source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.deprecated.rst b/source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.deprecated.rst deleted file mode 100644 index 3062168065c8..000000000000 --- a/source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.deprecated.rst +++ /dev/null @@ -1,8 +0,0 @@ -* Deprecated ``FRANKA_PANDA_CFG``, ``FRANKA_PANDA_HIGH_PD_CFG``, and - ``FRANKA_PANDA_MENAGERIE_CFG`` with visible import warnings for removal in Isaac Lab 4.0. - Their USD paths and actuator groups remain available during deprecation. - **Breaking:** the published ``franka_panda.usda`` now contains - the flat asset; consumers needing the old nested hierarchy can explicitly select - ``franka_panda_nestedInstance.usda``. Migrate maintained tasks to the corresponding - ``FRANKA_PANDA_FLAT_*`` config, replace shoulder/forearm actuator overrides with ``panda_arm``, - and select the backend's ``Physics`` variant. diff --git a/source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.minor b/source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.major similarity index 100% rename from source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.minor rename to source/isaaclab_assets/changelog.d/maximiliank-franka-flat-config.major diff --git a/source/isaaclab_assets/isaaclab_assets/__init__.pyi b/source/isaaclab_assets/isaaclab_assets/__init__.pyi index 2c71864ac40e..60581e12024f 100644 --- a/source/isaaclab_assets/isaaclab_assets/__init__.pyi +++ b/source/isaaclab_assets/isaaclab_assets/__init__.pyi @@ -22,8 +22,8 @@ __all__ = [ "GR1T2_CFG", "GR1T2_HIGH_PD_CFG", "FRANKA_PANDA_CFG", - "FRANKA_PANDA_FLAT_CFG", - "FRANKA_PANDA_FLAT_HIGH_PD_CFG", + "FRANKA_PANDA_LEGACY_CFG", + "FRANKA_PANDA_LEGACY_HIGH_PD_CFG", "FRANKA_PANDA_HIGH_PD_CFG", "FRANKA_PANDA_MENAGERIE_CFG", "FRANKA_ROBOTIQ_GRIPPER_CFG", @@ -91,8 +91,8 @@ from .robots import ( GR1T2_CFG, GR1T2_HIGH_PD_CFG, FRANKA_PANDA_CFG, - FRANKA_PANDA_FLAT_CFG, - FRANKA_PANDA_FLAT_HIGH_PD_CFG, + FRANKA_PANDA_LEGACY_CFG, + FRANKA_PANDA_LEGACY_HIGH_PD_CFG, FRANKA_PANDA_HIGH_PD_CFG, FRANKA_PANDA_MENAGERIE_CFG, FRANKA_ROBOTIQ_GRIPPER_CFG, diff --git a/source/isaaclab_assets/isaaclab_assets/robots/__init__.pyi b/source/isaaclab_assets/isaaclab_assets/robots/__init__.pyi index aed6774c314c..11b23110e810 100644 --- a/source/isaaclab_assets/isaaclab_assets/robots/__init__.pyi +++ b/source/isaaclab_assets/isaaclab_assets/robots/__init__.pyi @@ -22,8 +22,8 @@ __all__ = [ "GR1T2_CFG", "GR1T2_HIGH_PD_CFG", "FRANKA_PANDA_CFG", - "FRANKA_PANDA_FLAT_CFG", - "FRANKA_PANDA_FLAT_HIGH_PD_CFG", + "FRANKA_PANDA_LEGACY_CFG", + "FRANKA_PANDA_LEGACY_HIGH_PD_CFG", "FRANKA_PANDA_HIGH_PD_CFG", "FRANKA_PANDA_MENAGERIE_CFG", "FRANKA_ROBOTIQ_GRIPPER_CFG", @@ -84,8 +84,8 @@ from .cassie import CASSIE_CFG from .fourier import GR1T2_CFG, GR1T2_HIGH_PD_CFG from .franka import ( FRANKA_PANDA_CFG, - FRANKA_PANDA_FLAT_CFG, - FRANKA_PANDA_FLAT_HIGH_PD_CFG, + FRANKA_PANDA_LEGACY_CFG, + FRANKA_PANDA_LEGACY_HIGH_PD_CFG, FRANKA_PANDA_HIGH_PD_CFG, FRANKA_PANDA_MENAGERIE_CFG, FRANKA_ROBOTIQ_GRIPPER_CFG, diff --git a/source/isaaclab_assets/isaaclab_assets/robots/franka.py b/source/isaaclab_assets/isaaclab_assets/robots/franka.py index fda1c309798b..084218cf228f 100644 --- a/source/isaaclab_assets/isaaclab_assets/robots/franka.py +++ b/source/isaaclab_assets/isaaclab_assets/robots/franka.py @@ -7,23 +7,21 @@ The following configurations are available: -* :obj:`FRANKA_PANDA_FLAT_CFG`: Shared flat asset for maintained Franka tasks -* :obj:`FRANKA_PANDA_FLAT_HIGH_PD_CFG`: Flat asset with stiffer PD control -* :obj:`FRANKA_PANDA_CFG`: Deprecated alias retaining the legacy asset and actuators -* :obj:`FRANKA_PANDA_HIGH_PD_CFG`: Deprecated legacy high-PD configuration -* :obj:`FRANKA_PANDA_MENAGERIE_CFG`: Deprecated Menagerie actuator configuration +* :obj:`FRANKA_PANDA_CFG`: Shared flat asset for maintained Franka tasks +* :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 +* :obj:`FRANKA_PANDA_MENAGERIE_CFG`: Menagerie actuator configuration * :obj:`FRANKA_ROBOTIQ_GRIPPER_CFG`: Franka robot with Robotiq_2f_85 gripper -The old public names remain available during deprecation. Use ``FRANKA_PANDA_FLAT_CFG`` for new code -and select its ``Physics`` variant for the chosen backend. The published ``franka_panda.usda`` is now -the flat asset; the former nested-instance file remains available as an explicit USD-path override. +Use ``FRANKA_PANDA_CFG`` for new code and select its ``Physics`` variant for the chosen backend. +Use the explicit ``LEGACY`` configurations to retain the original USD path and actuator groups. +The published ``franka_panda.usda`` is now the flat asset; the former nested-instance file remains +available as an explicit USD-path override. Reference: https://github.com/frankaemika/franka_ros """ -import warnings -from typing import TYPE_CHECKING - from isaaclab_newton.sim.schemas import NewtonArticulationCfg from isaaclab_physx.sim.schemas import PhysxArticulationCfg, PhysxRigidBodyCfg @@ -89,7 +87,7 @@ """Configuration of the legacy Franka Emika Panda robot asset.""" -FRANKA_PANDA_FLAT_CFG = ArticulationCfg( +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"}, @@ -139,10 +137,10 @@ """ -FRANKA_PANDA_FLAT_HIGH_PD_CFG = clone(FRANKA_PANDA_FLAT_CFG) -FRANKA_PANDA_FLAT_HIGH_PD_CFG.spawn.rigid_props.disable_gravity = True -FRANKA_PANDA_FLAT_HIGH_PD_CFG.actuators["panda_arm"].stiffness = 400.0 -FRANKA_PANDA_FLAT_HIGH_PD_CFG.actuators["panda_arm"].damping = 80.0 +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 +FRANKA_PANDA_HIGH_PD_CFG.actuators["panda_arm"].damping = 80.0 """Configuration of Franka Emika Panda robot with stiffer PD control. This configuration is useful for task-space control using differential IK. @@ -216,11 +214,12 @@ for actuator in ("panda_shoulder", "panda_forearm"): FRANKA_PANDA_LEGACY_HIGH_PD_CFG.actuators[actuator].stiffness = 400.0 FRANKA_PANDA_LEGACY_HIGH_PD_CFG.actuators[actuator].damping = 80.0 +"""Configuration of the legacy Franka Emika Panda robot with stiffer PD control.""" -FRANKA_PANDA_LEGACY_MENAGERIE_CFG = clone(FRANKA_PANDA_LEGACY_CFG) -FRANKA_PANDA_LEGACY_MENAGERIE_CFG.spawn.usd_path = f"{ISAACLAB_NUCLEUS_DIR}/Robots/FrankaEmika/franka_panda.usda" -FRANKA_PANDA_LEGACY_MENAGERIE_CFG.actuators = { +FRANKA_PANDA_MENAGERIE_CFG = clone(FRANKA_PANDA_LEGACY_CFG) +FRANKA_PANDA_MENAGERIE_CFG.spawn.usd_path = f"{ISAACLAB_NUCLEUS_DIR}/Robots/FrankaEmika/franka_panda.usda" +FRANKA_PANDA_MENAGERIE_CFG.actuators = { "panda_arm": ImplicitActuatorCfg( joint_names_expr=["panda_joint[1-7]"], joint_velocity_limit={"panda_joint[1-4]": 20.0, "panda_joint[5-7]": 25.0}, @@ -233,28 +232,4 @@ damping=None, ), } - - -DEPRECATED_FRANKA_CFGS = { - "FRANKA_PANDA_CFG": (FRANKA_PANDA_LEGACY_CFG, "FRANKA_PANDA_FLAT_CFG"), - "FRANKA_PANDA_HIGH_PD_CFG": (FRANKA_PANDA_LEGACY_HIGH_PD_CFG, "FRANKA_PANDA_FLAT_HIGH_PD_CFG"), - "FRANKA_PANDA_MENAGERIE_CFG": (FRANKA_PANDA_LEGACY_MENAGERIE_CFG, "FRANKA_PANDA_FLAT_CFG"), -} - -if TYPE_CHECKING: - FRANKA_PANDA_CFG: ArticulationCfg - FRANKA_PANDA_HIGH_PD_CFG: ArticulationCfg - FRANKA_PANDA_MENAGERIE_CFG: ArticulationCfg - - -def __getattr__(name: str) -> ArticulationCfg: - if name not in DEPRECATED_FRANKA_CFGS: - raise AttributeError(f"module {__name__!r} has no attribute {name!r}") - cfg, replacement = DEPRECATED_FRANKA_CFGS[name] - message = f"{name} is deprecated and will be removed in Isaac Lab 4.0. Use {replacement}." - warnings.warn(message, FutureWarning, stacklevel=2) - return cfg - - -def __dir__() -> list[str]: - return sorted(set(globals()) | DEPRECATED_FRANKA_CFGS.keys()) +"""Configuration of the Franka Emika Panda robot with Menagerie actuator settings.""" diff --git a/source/isaaclab_newton/test/assets/test_articulation.py b/source/isaaclab_newton/test/assets/test_articulation.py index 2b7076837451..1639b55450cb 100644 --- a/source/isaaclab_newton/test/assets/test_articulation.py +++ b/source/isaaclab_newton/test/assets/test_articulation.py @@ -68,12 +68,12 @@ ## # Pre-defined configs ## -from isaaclab_assets import ANYMAL_C_CFG, FRANKA_PANDA_FLAT_CFG, FRANKA_PANDA_FLAT_HIGH_PD_CFG # isort:skip +from isaaclab_assets import ANYMAL_C_CFG, FRANKA_PANDA_CFG, FRANKA_PANDA_HIGH_PD_CFG # isort:skip from isaaclab_assets.robots.shadow_hand import SHADOW_HAND_NEWTON_CFG -_FRANKA_PANDA_NEWTON_CFG = clone(FRANKA_PANDA_FLAT_CFG) +_FRANKA_PANDA_NEWTON_CFG = clone(FRANKA_PANDA_CFG) _FRANKA_PANDA_NEWTON_CFG.spawn.variants = {"Physics": "mujoco", "Colliders": "gripper_only"} -_FRANKA_PANDA_HIGH_PD_NEWTON_CFG = clone(FRANKA_PANDA_FLAT_HIGH_PD_CFG) +_FRANKA_PANDA_HIGH_PD_NEWTON_CFG = clone(FRANKA_PANDA_HIGH_PD_CFG) _FRANKA_PANDA_HIGH_PD_NEWTON_CFG.spawn.variants = {"Physics": "mujoco", "Colliders": "gripper_only"} SIM_CFGs = { @@ -3178,7 +3178,7 @@ def test_get_gravity_compensation_forces_static_equilibrium(sim, num_articulatio # gravity-comp signal. Default Franka cfg has stiffness=80 / damping=4 # which would absorb gravity through PD bias and hide accessor bugs. cfg = replace(base_cfg, actuators={"all": ImplicitActuatorCfg(joint_names_expr=[".*"], stiffness=0.0, damping=0.0)}) - # FRANKA_PANDA_FLAT_CFG has rigid_props.disable_gravity=False already, but be + # FRANKA_PANDA_CFG has rigid_props.disable_gravity=False already, but be # defensive — gravity must be ON for τ_gc to have anything to cancel. cfg = replace(cfg, spawn=replace(cfg.spawn, rigid_props=replace(cfg.spawn.rigid_props, disable_gravity=False))) @@ -3196,7 +3196,7 @@ def test_get_gravity_compensation_forces_static_equilibrium(sim, num_articulatio articulation.write_joint_velocity_to_sim_index(velocity=default_qd) articulation.update(sim.cfg.dt) - # Default joint pose from FRANKA_PANDA_FLAT_CFG bends the elbow + # Default joint pose from FRANKA_PANDA_CFG bends the elbow # (joint2=-0.569, joint4=-2.81, joint6=3.04) so several links carry a # gravity load — τ_gc is non-trivial in this configuration. A natural- # hang pose (all zeros) would produce near-zero τ_gc and make this diff --git a/source/isaaclab_ov/test/assets/test_articulation.py b/source/isaaclab_ov/test/assets/test_articulation.py index 34d9a51c1c2a..afa35339aab7 100644 --- a/source/isaaclab_ov/test/assets/test_articulation.py +++ b/source/isaaclab_ov/test/assets/test_articulation.py @@ -99,7 +99,7 @@ ## # Pre-defined configs ## -from isaaclab_assets import ANYMAL_C_CFG, CARTPOLE_CFG, FRANKA_PANDA_FLAT_CFG, SHADOW_HAND_PHYSX_CFG # isort:skip +from isaaclab_assets import ANYMAL_C_CFG, CARTPOLE_CFG, FRANKA_PANDA_CFG, SHADOW_HAND_PHYSX_CFG # isort:skip wp.init() @@ -438,7 +438,7 @@ def generate_articulation_cfg( actuators={"body": ImplicitActuatorCfg(joint_names_expr=[".*"], stiffness=stiffness, damping=damping)}, ) elif articulation_type == "panda": - articulation_cfg = FRANKA_PANDA_FLAT_CFG + articulation_cfg = FRANKA_PANDA_CFG elif articulation_type == "anymal": articulation_cfg = ANYMAL_C_CFG elif articulation_type == "shadow_hand": @@ -1746,7 +1746,7 @@ def test_out_of_range_default_joint_vel(sim, device): 1. The articulation fails to initialize when joint velocities are out of range 2. The error is properly handled """ - articulation_cfg = replace(FRANKA_PANDA_FLAT_CFG, prim_path="/World/Robot") + articulation_cfg = replace(FRANKA_PANDA_CFG, prim_path="/World/Robot") articulation_cfg.init_state.joint_vel = { "panda_joint1": 100.0, "panda_joint[2, 4]": -60.0, @@ -2583,7 +2583,7 @@ def test_com_orientation_write_invalidates_static_inertia_cache_with_body_orderi below forbids cross-device staging, so this test is CPU-only. """ sim._app_control_on_stop_handle = None - articulation_cfg = replace(FRANKA_PANDA_FLAT_CFG, body_ordering=PANDA_ROOT_PRESERVING_REVERSED_BODY_NAMES) + articulation_cfg = replace(FRANKA_PANDA_CFG, body_ordering=PANDA_ROOT_PRESERVING_REVERSED_BODY_NAMES) articulation, _ = generate_articulation(articulation_cfg, 1, device=device) sim.reset() diff --git a/source/isaaclab_ov/test/sensors/test_frame_transformer.py b/source/isaaclab_ov/test/sensors/test_frame_transformer.py index 328c7f475903..07f4f3c80f07 100644 --- a/source/isaaclab_ov/test/sensors/test_frame_transformer.py +++ b/source/isaaclab_ov/test/sensors/test_frame_transformer.py @@ -51,7 +51,7 @@ from isaaclab.utils import configclass, replace # noqa: E402 from isaaclab_assets.robots.anymal import ANYMAL_C_CFG # noqa: E402 -from isaaclab_assets.robots.franka import FRANKA_PANDA_FLAT_CFG # noqa: E402 +from isaaclab_assets.robots.franka import FRANKA_PANDA_CFG # noqa: E402 wp.init() @@ -678,7 +678,7 @@ def test_frame_transformer_nested_rigid_bodies(device): with _ovphysx_sim_context(device=device) as sim: sim._app_control_on_stop_handle = None scene_cfg = _SceneCfg(num_envs=2, env_spacing=5.0, lazy_sensor_update=False) - scene_cfg.robot = replace(FRANKA_PANDA_FLAT_CFG, prim_path="{ENV_REGEX_NS}/Robot") + scene_cfg.robot = replace(FRANKA_PANDA_CFG, prim_path="{ENV_REGEX_NS}/Robot") scene_cfg.frame_transformer = FrameTransformerCfg( prim_path="{ENV_REGEX_NS}/Robot/(Geometry/)?panda_link0", target_frames=[ diff --git a/source/isaaclab_physx/test/assets/test_articulation.py b/source/isaaclab_physx/test/assets/test_articulation.py index a2b8f369ffa0..e0a81ef3aa97 100644 --- a/source/isaaclab_physx/test/assets/test_articulation.py +++ b/source/isaaclab_physx/test/assets/test_articulation.py @@ -52,8 +52,8 @@ ## from isaaclab_assets import ( # isort:skip ANYMAL_C_CFG, - FRANKA_PANDA_FLAT_CFG, - FRANKA_PANDA_FLAT_HIGH_PD_CFG, + FRANKA_PANDA_CFG, + FRANKA_PANDA_HIGH_PD_CFG, ) from isaaclab_assets.robots.shadow_hand import SHADOW_HAND_PHYSX_CFG @@ -99,7 +99,7 @@ def generate_articulation_cfg( actuators={"body": ImplicitActuatorCfg(joint_names_expr=[".*"], stiffness=stiffness, damping=damping)}, ) elif articulation_type == "panda": - articulation_cfg = FRANKA_PANDA_FLAT_CFG + articulation_cfg = FRANKA_PANDA_CFG elif articulation_type == "anymal": articulation_cfg = ANYMAL_C_CFG elif articulation_type == "shadow_hand": @@ -218,7 +218,7 @@ def _setup_franka_at_home_pose(sim): Returns: Tuple of ``(robot, ee_frame_idx, ee_jacobi_idx, arm_joint_ids)``. """ - cfg = replace(clone(FRANKA_PANDA_FLAT_HIGH_PD_CFG), prim_path="/World/Env_[^/]*/Robot") + cfg = replace(clone(FRANKA_PANDA_HIGH_PD_CFG), prim_path="/World/Env_[^/]*/Robot") sim_utils.create_prim("/World/Env_0", "Xform", translation=(0.0, 0.0, 0.0)) robot = Articulation(cfg) sim.reset() @@ -310,7 +310,7 @@ def sim(request): def test_live_manual_root_preserving_ordering_reorders_backend_reads_and_writes(sim, device, gravity_enabled): """Smoke-test non-identity joint/body ordering through a live PhysX articulation.""" articulation_cfg = replace( - FRANKA_PANDA_FLAT_CFG, + FRANKA_PANDA_CFG, prim_path="/World/Robot", joint_ordering=tuple(reversed(PANDA_JOINT_NAMES)), body_ordering=PANDA_ROOT_PRESERVING_REVERSED_BODY_NAMES, @@ -434,13 +434,13 @@ def test_reversed_joint_dynamics_use_public_joint_basis(sim, device, gravity_ena @pytest.mark.parametrize("gravity_enabled", [False]) def test_live_floating_root_writers_match_identity_after_body_reordering(sim, device, gravity_enabled): """Keep floating-base root writes invariant when public body order moves the root.""" - floating_spawn = replace(FRANKA_PANDA_FLAT_CFG.spawn, fix_root_link=False) + floating_spawn = replace(FRANKA_PANDA_CFG.spawn, fix_root_link=False) identity = Articulation( - replace(FRANKA_PANDA_FLAT_CFG, prim_path="/World/IdentityRobot", spawn=floating_spawn, body_ordering=None) + replace(FRANKA_PANDA_CFG, prim_path="/World/IdentityRobot", spawn=floating_spawn, body_ordering=None) ) ordered = Articulation( replace( - FRANKA_PANDA_FLAT_CFG, + FRANKA_PANDA_CFG, prim_path="/World/OrderedRobot", spawn=floating_spawn, body_ordering=tuple(reversed(PANDA_BODY_NAMES)), @@ -512,9 +512,7 @@ def test_live_direct_view_mass_inertia_writes_become_visible(sim, device, gravit ``user_to_backend``. """ body_ordering_arg = None if body_ordering == "identity" else PANDA_ROOT_PRESERVING_REVERSED_BODY_NAMES - articulation = Articulation( - replace(FRANKA_PANDA_FLAT_CFG, prim_path="/World/Robot", body_ordering=body_ordering_arg) - ) + articulation = Articulation(replace(FRANKA_PANDA_CFG, prim_path="/World/Robot", body_ordering=body_ordering_arg)) sim.reset() assert articulation.is_initialized @@ -864,7 +862,7 @@ def test_out_of_range_default_joint_vel(sim, device): 1. The articulation fails to initialize when joint velocities are out of range 2. The error is properly handled """ - articulation_cfg = replace(FRANKA_PANDA_FLAT_CFG, prim_path="/World/Robot") + articulation_cfg = replace(FRANKA_PANDA_CFG, prim_path="/World/Robot") articulation_cfg.init_state.joint_vel = { "panda_joint1": 100.0, "panda_joint[2, 4]": -60.0, @@ -2160,7 +2158,7 @@ def test_get_gravity_compensation_forces_static_equilibrium(sim, num_articulatio # gravity-comp signal. Default Franka cfg has stiffness=80 / damping=4 # which would absorb gravity through PD bias and hide accessor bugs. cfg = replace(base_cfg, actuators={"all": ImplicitActuatorCfg(joint_names_expr=[".*"], stiffness=0.0, damping=0.0)}) - # FRANKA_PANDA_FLAT_CFG has rigid_props.disable_gravity=False already, but be + # FRANKA_PANDA_CFG has rigid_props.disable_gravity=False already, but be # defensive — gravity must be ON for τ_gc to have anything to cancel. cfg = replace(cfg, spawn=replace(cfg.spawn, rigid_props=replace(cfg.spawn.rigid_props, disable_gravity=False))) @@ -2176,7 +2174,7 @@ def test_get_gravity_compensation_forces_static_equilibrium(sim, num_articulatio articulation.write_joint_state_to_sim(default_q, default_qd) articulation.update(sim.cfg.dt) - # Default joint pose from FRANKA_PANDA_FLAT_CFG bends the elbow + # Default joint pose from FRANKA_PANDA_CFG bends the elbow # (joint2=-0.569, joint4=-2.81, joint6=3.04) so several links carry a # gravity load — τ_gc is non-trivial in this configuration. A natural- # hang pose (all zeros) would produce near-zero τ_gc and make this diff --git a/source/isaaclab_physx/test/sensors/test_frame_transformer.py b/source/isaaclab_physx/test/sensors/test_frame_transformer.py index 8775fa47d35f..8efc6b4de1f7 100644 --- a/source/isaaclab_physx/test/sensors/test_frame_transformer.py +++ b/source/isaaclab_physx/test/sensors/test_frame_transformer.py @@ -32,7 +32,7 @@ # Pre-defined configs ## from isaaclab_assets.robots.anymal import ANYMAL_C_CFG # isort:skip -from isaaclab_assets.robots.franka import FRANKA_PANDA_FLAT_CFG # isort:skip +from isaaclab_assets.robots.franka import FRANKA_PANDA_CFG # isort:skip def quat_from_euler_rpy(roll, pitch, yaw, degrees=False): @@ -726,7 +726,7 @@ def test_frame_transformer_invalidation_drops_cached_launch_state(monkeypatch): def test_frame_transformer_nested_rigid_bodies(sim): """Test that a matched rigid body does not include nested rigid-body descendants.""" scene_cfg = MySceneCfg(num_envs=2, env_spacing=5.0, lazy_sensor_update=False) - scene_cfg.robot = replace(FRANKA_PANDA_FLAT_CFG, prim_path="{ENV_REGEX_NS}/Robot") + scene_cfg.robot = replace(FRANKA_PANDA_CFG, prim_path="{ENV_REGEX_NS}/Robot") scene_cfg.frame_transformer = FrameTransformerCfg( prim_path="{ENV_REGEX_NS}/Robot/(Geometry/)?panda_link0", target_frames=[ 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..54250dde7ca9 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 @@ -28,7 +28,7 @@ from isaaclab_tasks.utils import PresetCfg 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_LEGACY_HIGH_PD_CFG BenchmarkMode = Literal["render", "physics_render"] """Animation mode used by the render benchmark. @@ -144,9 +144,9 @@ class RenderBenchmarkSceneCfg(InteractiveSceneCfg): init_state=RigidObjectCfg.InitialStateCfg(pos=(0.0, 0.0, -0.05)), ) robot: ArticulationCfg = replace( - FRANKA_PANDA_HIGH_PD_CFG, + FRANKA_PANDA_LEGACY_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_LEGACY_HIGH_PD_CFG.init_state, pos=(1.0, 0.0, 0.0), rot=(0.0, 0.0, 1.0, 0.0)), ) cabinet: ArticulationCfg = ArticulationCfg( prim_path="{ENV_REGEX_NS}/Cabinet", 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..76000c041c8d 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_LEGACY_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_LEGACY_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/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..e8da541c7b09 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_LEGACY_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_LEGACY_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/franka_pour/pour_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/contrib/franka_pour/pour_env_cfg.py index 6e521d15deb5..a01d17f061d9 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_FLAT_CFG +from isaaclab_assets.robots.franka import FRANKA_PANDA_CFG from . import mdp from .geometry import ( @@ -314,7 +314,7 @@ 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_FLAT_CFG, prim_path="{ENV_REGEX_NS}/Robot") + robot = replace(FRANKA_PANDA_CFG, prim_path="{ENV_REGEX_NS}/Robot") robot.spawn.usd_path = FRANKA_POUR_ROBOT_USD_PATH robot.spawn.variants = {"Physics": "mujoco", "Colliders": "convex_hulls"} robot.spawn.func = spawn_franka_with_arm_collisions 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..4c76b049a78c 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_LEGACY_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_LEGACY_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..141125da0b23 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_LEGACY_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_LEGACY_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..8a1dd9feebc8 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_LEGACY_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_LEGACY_CFG, prim_path="{ENV_REGEX_NS}/Robot") # Set actions for the specific robot type (franka) self.actions.arm_action = mdp.JointPositionActionCfg( 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..d93e3ee74cf4 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_LEGACY_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_LEGACY_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..a5795efc2bec 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_LEGACY_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_LEGACY_CFG, prim_path="{ENV_REGEX_NS}/Robot") self.scene.robot.spawn.semantic_tags = [("class", "robot")] # Add semantics to table 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..ab1c2b72ecc0 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_LEGACY_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_LEGACY_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..a379eb0b5aba 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_LEGACY_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_LEGACY_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..515e69b18e18 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_LEGACY_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_LEGACY_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..8861d9a3a5b8 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_LEGACY_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_LEGACY_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..3de75bb15a36 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_LEGACY_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_LEGACY_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_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/contrib/stack/config/franka/stack_ik_rel_visuomotor_env_cfg.py index 3d5572611523..ebd249665e19 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_LEGACY_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_LEGACY_HIGH_PD_CFG, prim_path="{ENV_REGEX_NS}/Robot", init_state=ArticulationCfg.InitialStateCfg(joint_pos=_FRANKA_STACK_IK_REL_INIT_JOINT_POS), ) 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..7f4517f4f8f3 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_LEGACY_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_LEGACY_CFG, prim_path="{ENV_REGEX_NS}/Robot", init_state=ArticulationCfg.InitialStateCfg(joint_pos=_FRANKA_STACK_IK_REL_INIT_JOINT_POS), ) 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..a48386cfd4c8 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_LEGACY_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_LEGACY_CFG, prim_path="{ENV_REGEX_NS}/Robot") # Set actions for the specific robot type (franka) self.actions.arm_action = mdp.JointPositionActionCfg( 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..f8b746bd4fef 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,7 @@ from isaaclab.utils import configclass, replace -from isaaclab_assets.robots.franka import FRANKA_PANDA_CFG +from isaaclab_assets.robots.franka import FRANKA_PANDA_LEGACY_CFG from ...cabinet_direct_env_cfg import CabinetDirectEnvCfg, CabinetDirectSceneCfg @@ -18,7 +18,7 @@ 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_LEGACY_CFG, prim_path="{ENV_REGEX_NS}/Robot") @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..6a15539219a4 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,7 @@ from isaaclab.sensors.frame_transformer import OffsetCfg from isaaclab.utils import configclass, replace -from isaaclab_assets.robots.franka import FRANKA_PANDA_CFG +from isaaclab_assets.robots.franka import FRANKA_PANDA_LEGACY_CFG from ... import mdp from ...cabinet_env_cfg import FRAME_MARKER_SMALL_CFG, CabinetEnvCfg, CabinetSceneCfg @@ -19,7 +19,7 @@ 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_LEGACY_CFG, prim_path="{ENV_REGEX_NS}/Robot") ee_frame = FrameTransformerCfg( prim_path="{ENV_REGEX_NS}/Robot/panda_link0", debug_vis=False, 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 2d136cd8c31d..3fd5a0d2b251 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 @@ -16,7 +16,7 @@ from isaaclab.utils import clone, configclass, replace from isaaclab.utils.assets import ISAACLAB_NUCLEUS_DIR -from isaaclab_assets.robots import FRANKA_PANDA_CFG +from isaaclab_assets.robots import FRANKA_PANDA_LEGACY_CFG from ... import lift_env_cfg as lift from ... import mdp @@ -27,7 +27,7 @@ # 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_CFG) +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"} 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..16fad7b84776 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,7 @@ from isaaclab_tasks.utils import PresetCfg, preset -from isaaclab_assets import FRANKA_PANDA_CFG, FRANKA_PANDA_MENAGERIE_CFG +from isaaclab_assets import FRANKA_PANDA_LEGACY_CFG, FRANKA_PANDA_MENAGERIE_CFG from ...reach_env_cfg import ReachEnvCfg @@ -100,9 +100,9 @@ def __post_init__(self): 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, + 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, ) # IK targets need backend-native gravity control to hold steady between commands. self.scene.robot.spawn.rigid_props = [ From 304c728d8225b7668f43d7175e599147e3f3ecd0 Mon Sep 17 00:00:00 2001 From: Mustafa Haiderbhai Date: Wed, 30 Sep 2026 18:13:11 -0700 Subject: [PATCH 12/14] Group Franka config variants and fix docstring spacing --- .../isaaclab_assets/robots/franka.py | 54 +++++++++---------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/source/isaaclab_assets/isaaclab_assets/robots/franka.py b/source/isaaclab_assets/isaaclab_assets/robots/franka.py index 084218cf228f..8084402b2eee 100644 --- a/source/isaaclab_assets/isaaclab_assets/robots/franka.py +++ b/source/isaaclab_assets/isaaclab_assets/robots/franka.py @@ -87,6 +87,14 @@ """Configuration of the legacy Franka Emika Panda robot asset.""" +FRANKA_PANDA_LEGACY_HIGH_PD_CFG = clone(FRANKA_PANDA_LEGACY_CFG) +FRANKA_PANDA_LEGACY_HIGH_PD_CFG.spawn.rigid_props.disable_gravity = True +for actuator in ("panda_shoulder", "panda_forearm"): + FRANKA_PANDA_LEGACY_HIGH_PD_CFG.actuators[actuator].stiffness = 400.0 + FRANKA_PANDA_LEGACY_HIGH_PD_CFG.actuators[actuator].damping = 80.0 +"""Configuration of the legacy Franka Emika Panda robot with stiffer PD control.""" + + FRANKA_PANDA_CFG = ArticulationCfg( spawn=sim_utils.UsdFileCfg( usd_path=f"{ISAACLAB_NUCLEUS_DIR}/Robots/FrankaEmika/franka_panda.usda", @@ -147,6 +155,24 @@ """ +FRANKA_PANDA_MENAGERIE_CFG = clone(FRANKA_PANDA_LEGACY_CFG) +FRANKA_PANDA_MENAGERIE_CFG.spawn.usd_path = f"{ISAACLAB_NUCLEUS_DIR}/Robots/FrankaEmika/franka_panda.usda" +FRANKA_PANDA_MENAGERIE_CFG.actuators = { + "panda_arm": ImplicitActuatorCfg( + joint_names_expr=["panda_joint[1-7]"], + joint_velocity_limit={"panda_joint[1-4]": 20.0, "panda_joint[5-7]": 25.0}, + stiffness=None, + damping=None, + ), + "panda_hand": ImplicitActuatorCfg( + joint_names_expr=["panda_finger_joint.*"], + stiffness=None, + damping=None, + ), +} +"""Configuration of the Franka Emika Panda robot with Menagerie actuator settings.""" + + FRANKA_ROBOTIQ_GRIPPER_CFG = clone(FRANKA_PANDA_LEGACY_CFG) FRANKA_ROBOTIQ_GRIPPER_CFG.spawn.usd_path = f"{ISAAC_NUCLEUS_DIR}/Robots/FrankaRobotics/FrankaPanda/franka.usd" FRANKA_ROBOTIQ_GRIPPER_CFG.spawn.variants = {"Gripper": "Robotiq_2F_85"} @@ -204,32 +230,4 @@ damping=0.0, ), } - - """Configuration of Franka Emika Panda robot with Robotiq_2f_85 gripper.""" - - -FRANKA_PANDA_LEGACY_HIGH_PD_CFG = clone(FRANKA_PANDA_LEGACY_CFG) -FRANKA_PANDA_LEGACY_HIGH_PD_CFG.spawn.rigid_props.disable_gravity = True -for actuator in ("panda_shoulder", "panda_forearm"): - FRANKA_PANDA_LEGACY_HIGH_PD_CFG.actuators[actuator].stiffness = 400.0 - FRANKA_PANDA_LEGACY_HIGH_PD_CFG.actuators[actuator].damping = 80.0 -"""Configuration of the legacy Franka Emika Panda robot with stiffer PD control.""" - - -FRANKA_PANDA_MENAGERIE_CFG = clone(FRANKA_PANDA_LEGACY_CFG) -FRANKA_PANDA_MENAGERIE_CFG.spawn.usd_path = f"{ISAACLAB_NUCLEUS_DIR}/Robots/FrankaEmika/franka_panda.usda" -FRANKA_PANDA_MENAGERIE_CFG.actuators = { - "panda_arm": ImplicitActuatorCfg( - joint_names_expr=["panda_joint[1-7]"], - joint_velocity_limit={"panda_joint[1-4]": 20.0, "panda_joint[5-7]": 25.0}, - stiffness=None, - damping=None, - ), - "panda_hand": ImplicitActuatorCfg( - joint_names_expr=["panda_finger_joint.*"], - stiffness=None, - damping=None, - ), -} -"""Configuration of the Franka Emika Panda robot with Menagerie actuator settings.""" From 6a36528c8188bd1af914a38f617cf2652a78ec28 Mon Sep 17 00:00:00 2001 From: Octi Zhang Date: Wed, 30 Sep 2026 19:44:49 -0700 Subject: [PATCH 13/14] Match frame bodies without implicit descendant discovery --- ...iliank-direct-body-prim-resolution.fixed.rst | 2 -- ...maximiliank-direct-body-prim-resolution.skip | 0 source/isaaclab/isaaclab/sim/utils/queries.py | 12 +++--------- source/isaaclab/test/sim/test_cloner.py | 16 ++++------------ .../frame_transformer/frame_transformer.py | 14 +++++--------- .../frame_transformer/frame_transformer.py | 17 +++++------------ 6 files changed, 17 insertions(+), 44 deletions(-) delete mode 100644 source/isaaclab/changelog.d/maximiliank-direct-body-prim-resolution.fixed.rst create mode 100644 source/isaaclab/changelog.d/maximiliank-direct-body-prim-resolution.skip diff --git a/source/isaaclab/changelog.d/maximiliank-direct-body-prim-resolution.fixed.rst b/source/isaaclab/changelog.d/maximiliank-direct-body-prim-resolution.fixed.rst deleted file mode 100644 index 57e1244eea39..000000000000 --- a/source/isaaclab/changelog.d/maximiliank-direct-body-prim-resolution.fixed.rst +++ /dev/null @@ -1,2 +0,0 @@ -* Fixed direct rigid-body path queries so nested rigid-body descendants are not selected when the requested body matches, - while preserving descendant matches below other requested non-rigid prims. diff --git a/source/isaaclab/changelog.d/maximiliank-direct-body-prim-resolution.skip b/source/isaaclab/changelog.d/maximiliank-direct-body-prim-resolution.skip new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/source/isaaclab/isaaclab/sim/utils/queries.py b/source/isaaclab/isaaclab/sim/utils/queries.py index 1c569dd6c130..0994b049c44c 100644 --- a/source/isaaclab/isaaclab/sim/utils/queries.py +++ b/source/isaaclab/isaaclab/sim/utils/queries.py @@ -387,7 +387,6 @@ def resolve_matching_prims_from_source( env_regex_ns: str = "/World/envs/env_[^/]+", raise_if_no_matches: bool = True, traverse_instance_prims: bool = True, - prefer_direct_matches: bool = False, ) -> list[tuple[Usd.Prim, str]]: """Resolve matching prims from a single(source) instance when multiple instances are present. @@ -403,8 +402,6 @@ def resolve_matching_prims_from_source( env_regex_ns: Namespace pattern that marks one instance root when no clone plan applies. raise_if_no_matches: Whether to raise if no prim matches ``path_expr``. Defaults to True. traverse_instance_prims: Whether to traverse instance prims when applying ``predicate``. - prefer_direct_matches: Prefer matching prims named by ``path_expr`` over their matching descendants. - For each matched prim, descendants remain a fallback if that prim does not satisfy ``predicate``. Returns: A list of ``(source_prim, destination_expr)`` pairs. Empty only when @@ -476,12 +473,9 @@ def resolve_matching_prims_from_source( unique_matches = {} for source, dest in results: source_path = source.GetPath().pathString - if prefer_direct_matches and predicate(source): - children = [source] - else: - children = get_all_matching_child_prims( - source_path, predicate, traverse_instance_prims=traverse_instance_prims - ) + children = get_all_matching_child_prims( + source_path, predicate, traverse_instance_prims=traverse_instance_prims + ) for child in children: child_path = child.GetPath().pathString unique_matches.setdefault(child_path, (child, dest + child_path[len(source_path) :])) diff --git a/source/isaaclab/test/sim/test_cloner.py b/source/isaaclab/test/sim/test_cloner.py index fdf88ccc1130..f8f92ad01c9e 100644 --- a/source/isaaclab/test/sim/test_cloner.py +++ b/source/isaaclab/test/sim/test_cloner.py @@ -286,16 +286,13 @@ def test_resolve_matching_prims_from_source(sim, with_clone_plan): "/World/envs/env_[^/]+/Robot/other/bar", ] - # A direct match must not hide another matched root's predicate-matching descendants. + # Path matching does not expand the matched prims into their subtrees. matches = queries.resolve_matching_prims_from_source( - r"/World/envs/env_[^/]+/Robot/(foo|other)", - predicate=lambda prim: prim.GetName() in {"foo", "bar"}, - expected_num_matches=2, - prefer_direct_matches=True, + r"/World/envs/env_[^/]+/Robot/(foo|other)", expected_num_matches=2 ) assert [(prim.GetPath().pathString, path) for prim, path in matches] == [ ("/World/envs/env_0/Robot/foo", "/World/envs/env_[^/]+/Robot/foo"), - ("/World/envs/env_0/Robot/other/bar", "/World/envs/env_[^/]+/Robot/other/bar"), + ("/World/envs/env_0/Robot/other", "/World/envs/env_[^/]+/Robot/other"), ] if with_clone_plan: @@ -305,12 +302,7 @@ def test_resolve_matching_prims_from_source(sim, with_clone_plan): ) sim.set_clone_plan(make_clone_plan((asset,), ((0,),), 2)) - matches = queries.resolve_matching_prims_from_source( - r"/World/envs/env_[^/]+/Robot/foo", - predicate=lambda prim: prim.GetName() in {"foo", "bar"}, - expected_num_matches=1, - prefer_direct_matches=True, - ) + matches = queries.resolve_matching_prims_from_source(r"/World/envs/env_[^/]+/Robot/foo", expected_num_matches=1) assert [(prim.GetPath().pathString, path) for prim, path in matches] == [ ("/World/template/Robot/foo", "/World/envs/env_[^/]+/Robot/foo") ] diff --git a/source/isaaclab_ov/isaaclab_ov/sensors/frame_transformer/frame_transformer.py b/source/isaaclab_ov/isaaclab_ov/sensors/frame_transformer/frame_transformer.py index f1bd9fdef7df..2c8f583ad5a9 100644 --- a/source/isaaclab_ov/isaaclab_ov/sensors/frame_transformer/frame_transformer.py +++ b/source/isaaclab_ov/isaaclab_ov/sensors/frame_transformer/frame_transformer.py @@ -172,15 +172,11 @@ def _initialize_impl(self) -> None: for frame, prim_path, offset, frame_type in zip(frames, frame_prim_paths, frame_offsets, frame_types): # Resolve source-side env prims and destination expressions. This keeps discovery plan-aware when # the active clone plan has physics clones without authored USD prims for every environment. - def has_rigid_body_api(prim) -> bool: - return bool(prim.HasAPI(UsdPhysics.RigidBodyAPI)) - - matches = resolve_matching_prims_from_source( - prim_path, - predicate=has_rigid_body_api, - raise_if_no_matches=False, - prefer_direct_matches=True, - ) + matches = [ + (prim, destination) + for prim, destination in resolve_matching_prims_from_source(prim_path, raise_if_no_matches=False) + if prim.HasAPI(UsdPhysics.RigidBodyAPI) + ] if not matches: raise ValueError( f"Failed to create frame transformer for frame '{frame}' with path '{prim_path}'." diff --git a/source/isaaclab_physx/isaaclab_physx/sensors/frame_transformer/frame_transformer.py b/source/isaaclab_physx/isaaclab_physx/sensors/frame_transformer/frame_transformer.py index cc8daf52ac63..fa72c6e63371 100644 --- a/source/isaaclab_physx/isaaclab_physx/sensors/frame_transformer/frame_transformer.py +++ b/source/isaaclab_physx/isaaclab_physx/sensors/frame_transformer/frame_transformer.py @@ -185,18 +185,11 @@ def _initialize_impl(self): frame_offsets = [None] + [target_frame.offset for target_frame in self.cfg.target_frames] frame_types = ["source"] + ["target"] * len(self.cfg.target_frames) for frame, prim_path, offset, frame_type in zip(frames, frame_prim_paths, frame_offsets, frame_types): - # Resolve the source-side env prims (filtered to rigid bodies) and their destination - # expressions. Plan-aware: with an active ``ClonePlan``, only env-0 representatives - # are walked and dest expressions are rebuilt against the plan's destination glob. - def has_rigid_body_api(prim) -> bool: - return bool(prim.HasAPI(UsdPhysics.RigidBodyAPI)) - - matches = resolve_matching_prims_from_source( - prim_path, - has_rigid_body_api, - raise_if_no_matches=False, - prefer_direct_matches=True, - ) + matches = [ + (prim, destination) + for prim, destination in resolve_matching_prims_from_source(prim_path, raise_if_no_matches=False) + if prim.HasAPI(UsdPhysics.RigidBodyAPI) + ] if not matches: raise ValueError( f"Failed to create frame transformer for frame '{frame}' with path '{prim_path}'." From d648b0a67909362b50d3a813045fd02f1b9b8d72 Mon Sep 17 00:00:00 2001 From: Octi Zhang Date: Wed, 30 Sep 2026 19:57:14 -0700 Subject: [PATCH 14/14] Trim Franka regression tests to backend behavior --- source/isaaclab/test/sim/test_cloner.py | 21 ------------------- .../test/assets/test_articulation.py | 1 - .../test/assets/test_articulation.py | 2 -- .../test/sensors/test_frame_transformer.py | 15 ++----------- .../test/sensors/test_frame_transformer.py | 15 ++----------- 5 files changed, 4 insertions(+), 50 deletions(-) diff --git a/source/isaaclab/test/sim/test_cloner.py b/source/isaaclab/test/sim/test_cloner.py index f8f92ad01c9e..51bfc38077f8 100644 --- a/source/isaaclab/test/sim/test_cloner.py +++ b/source/isaaclab/test/sim/test_cloner.py @@ -285,24 +285,3 @@ def test_resolve_matching_prims_from_source(sim, with_clone_plan): "/World/envs/env_[^/]+/Robot/foo/bar", "/World/envs/env_[^/]+/Robot/other/bar", ] - - # Path matching does not expand the matched prims into their subtrees. - matches = queries.resolve_matching_prims_from_source( - r"/World/envs/env_[^/]+/Robot/(foo|other)", expected_num_matches=2 - ) - assert [(prim.GetPath().pathString, path) for prim, path in matches] == [ - ("/World/envs/env_0/Robot/foo", "/World/envs/env_[^/]+/Robot/foo"), - ("/World/envs/env_0/Robot/other", "/World/envs/env_[^/]+/Robot/other"), - ] - - if with_clone_plan: - stage.DefinePrim("/World/template/Robot/foo/bar", "Xform") - asset = AssetBaseCfg( - prim_path="/World/envs/env_[^/]+/Robot", spawn=SpawnerCfg(spawn_path="/World/template/Robot") - ) - sim.set_clone_plan(make_clone_plan((asset,), ((0,),), 2)) - - matches = queries.resolve_matching_prims_from_source(r"/World/envs/env_[^/]+/Robot/foo", expected_num_matches=1) - assert [(prim.GetPath().pathString, path) for prim, path in matches] == [ - ("/World/template/Robot/foo", "/World/envs/env_[^/]+/Robot/foo") - ] diff --git a/source/isaaclab_newton/test/assets/test_articulation.py b/source/isaaclab_newton/test/assets/test_articulation.py index 1639b55450cb..511de3ef2426 100644 --- a/source/isaaclab_newton/test/assets/test_articulation.py +++ b/source/isaaclab_newton/test/assets/test_articulation.py @@ -2566,7 +2566,6 @@ def test_write_joint_viscous_friction_to_sim(sim, num_articulations, device, art ) expected_pd_damping = torch.full_like(expected_viscous_friction, 2.0) - assert not torch.allclose(expected_pd_damping, expected_viscous_friction) torch.testing.assert_close(articulation.data.joint_damping.torch[:, arm_joint_ids], expected_pd_damping) torch.testing.assert_close( wp.to_torch(articulation.root_view.get_attribute("joint_target_kd", SimulationManager.get_model()))[ diff --git a/source/isaaclab_ov/test/assets/test_articulation.py b/source/isaaclab_ov/test/assets/test_articulation.py index fcb7e1ec9d56..f116a632706e 100644 --- a/source/isaaclab_ov/test/assets/test_articulation.py +++ b/source/isaaclab_ov/test/assets/test_articulation.py @@ -2360,8 +2360,6 @@ def test_apply_joint_command(sim, num_articulations, device, add_ground_plane): leader_pos = articulation.data.joint_pos.torch[:, leader_id] follower_pos = articulation.data.joint_pos.torch[:, follower_id] - assert torch.isfinite(articulation.data.joint_pos.torch).all() - assert torch.isfinite(articulation.data.joint_vel.torch).all() assert torch.all(torch.abs(leader_pos - initial_leader_pos) > 0.005) torch.testing.assert_close(follower_pos, leader_pos, rtol=0.0, atol=5.0e-4) diff --git a/source/isaaclab_ov/test/sensors/test_frame_transformer.py b/source/isaaclab_ov/test/sensors/test_frame_transformer.py index 07f4f3c80f07..185fb16143ea 100644 --- a/source/isaaclab_ov/test/sensors/test_frame_transformer.py +++ b/source/isaaclab_ov/test/sensors/test_frame_transformer.py @@ -682,18 +682,7 @@ def test_frame_transformer_nested_rigid_bodies(device): scene_cfg.frame_transformer = FrameTransformerCfg( prim_path="{ENV_REGEX_NS}/Robot/(Geometry/)?panda_link0", target_frames=[ - FrameTransformerCfg.FrameCfg( - name="hand", - prim_path="{ENV_REGEX_NS}/Robot/(Geometry/.*/)?panda_hand", - ), - FrameTransformerCfg.FrameCfg( - name="left_finger", - prim_path="{ENV_REGEX_NS}/Robot/(Geometry/.*/)?panda_leftfinger", - ), - FrameTransformerCfg.FrameCfg( - name="right_finger", - prim_path="{ENV_REGEX_NS}/Robot/(Geometry/.*/)?panda_rightfinger", - ), + FrameTransformerCfg.FrameCfg(prim_path="{ENV_REGEX_NS}/Robot/(Geometry/.*/)?panda_(hand|.*finger)"), ], ) scene = InteractiveScene(scene_cfg) @@ -706,7 +695,7 @@ def test_frame_transformer_nested_rigid_bodies(device): target_ids = robot.find_bodies(["panda_hand", "panda_leftfinger", "panda_rightfinger"])[0] frame_data = scene.sensors["frame_transformer"].data - assert frame_data.target_frame_names == ["hand", "left_finger", "right_finger"] + assert frame_data.target_frame_names == ["panda_hand", "panda_leftfinger", "panda_rightfinger"] torch.testing.assert_close(frame_data.source_pos_w.torch, robot.data.body_pos_w.torch[:, source_id]) torch.testing.assert_close(frame_data.source_quat_w.torch, robot.data.body_quat_w.torch[:, source_id]) torch.testing.assert_close(frame_data.target_pos_w.torch, robot.data.body_pos_w.torch[:, target_ids]) diff --git a/source/isaaclab_physx/test/sensors/test_frame_transformer.py b/source/isaaclab_physx/test/sensors/test_frame_transformer.py index 8efc6b4de1f7..a61dc3804246 100644 --- a/source/isaaclab_physx/test/sensors/test_frame_transformer.py +++ b/source/isaaclab_physx/test/sensors/test_frame_transformer.py @@ -730,18 +730,7 @@ def test_frame_transformer_nested_rigid_bodies(sim): scene_cfg.frame_transformer = FrameTransformerCfg( prim_path="{ENV_REGEX_NS}/Robot/(Geometry/)?panda_link0", target_frames=[ - FrameTransformerCfg.FrameCfg( - name="hand", - prim_path="{ENV_REGEX_NS}/Robot/(Geometry/.*/)?panda_hand", - ), - FrameTransformerCfg.FrameCfg( - name="left_finger", - prim_path="{ENV_REGEX_NS}/Robot/(Geometry/.*/)?panda_leftfinger", - ), - FrameTransformerCfg.FrameCfg( - name="right_finger", - prim_path="{ENV_REGEX_NS}/Robot/(Geometry/.*/)?panda_rightfinger", - ), + FrameTransformerCfg.FrameCfg(prim_path="{ENV_REGEX_NS}/Robot/(Geometry/.*/)?panda_(hand|.*finger)"), ], ) scene = InteractiveScene(scene_cfg) @@ -754,7 +743,7 @@ def test_frame_transformer_nested_rigid_bodies(sim): target_ids = robot.find_bodies(["panda_hand", "panda_leftfinger", "panda_rightfinger"])[0] frame_data = scene.sensors["frame_transformer"].data - assert frame_data.target_frame_names == ["hand", "left_finger", "right_finger"] + assert frame_data.target_frame_names == ["panda_hand", "panda_leftfinger", "panda_rightfinger"] torch.testing.assert_close(frame_data.source_pos_w.torch, robot.data.body_pos_w.torch[:, source_id]) torch.testing.assert_close(frame_data.source_quat_w.torch, robot.data.body_quat_w.torch[:, source_id]) torch.testing.assert_close(frame_data.target_pos_w.torch, robot.data.body_pos_w.torch[:, target_ids])