From 8fe61aace83fdf166e9eff5100046a21c830f89f Mon Sep 17 00:00:00 2001 From: Octi Zhang Date: Thu, 26 Feb 2026 01:29:15 -0800 Subject: [PATCH 1/2] clean up mimic and pink --- .../isaaclab/controllers/joint_impedance.py | 52 +------- .../controllers/joint_impedance_cfg.py | 61 +++++++++ .../controllers/pink_ik/local_frame_task.py | 118 ++--------------- .../pink_ik/null_space_posture_task.py | 13 +- .../isaaclab/controllers/pink_ik/pink_ik.py | 44 +++++-- .../controllers/pink_ik/pink_ik_cfg.py | 25 +++- .../controllers/pink_ik/pink_task_cfg.py | 67 ++++++++++ .../controllers/pink_ik/pink_tasks.py | 123 ++++++++++++++++++ source/isaaclab/isaaclab/controllers/utils.py | 12 +- .../mdp/actions/pink_task_space_actions.py | 2 +- .../test/controllers/test_local_frame_task.py | 2 +- .../isaaclab/test/controllers/test_pink_ik.py | 7 +- .../pick_place/configs/pink_controller_cfg.py | 14 +- .../fixed_base_upper_body_ik_g1_env_cfg.py | 44 +++---- .../pick_place/locomanipulation_g1_env_cfg.py | 9 +- .../pick_place/mdp/observations.py | 8 +- .../pick_place/mdp/terminations.py | 8 +- .../exhaustpipe_gr1t2_pink_ik_env_cfg.py | 53 +++----- .../nutpour_gr1t2_pink_ik_env_cfg.py | 53 +++----- .../pick_place/pickplace_gr1t2_env_cfg.py | 82 ++++++------ .../pickplace_gr1t2_waist_enabled_env_cfg.py | 46 +++---- ...ckplace_unitree_g1_inspire_hand_env_cfg.py | 58 +++------ 22 files changed, 486 insertions(+), 415 deletions(-) create mode 100644 source/isaaclab/isaaclab/controllers/joint_impedance_cfg.py create mode 100644 source/isaaclab/isaaclab/controllers/pink_ik/pink_task_cfg.py create mode 100644 source/isaaclab/isaaclab/controllers/pink_ik/pink_tasks.py diff --git a/source/isaaclab/isaaclab/controllers/joint_impedance.py b/source/isaaclab/isaaclab/controllers/joint_impedance.py index 5baca32385d..0dee9da4898 100644 --- a/source/isaaclab/isaaclab/controllers/joint_impedance.py +++ b/source/isaaclab/isaaclab/controllers/joint_impedance.py @@ -5,58 +5,12 @@ from __future__ import annotations -from collections.abc import Sequence -from dataclasses import MISSING +from typing import TYPE_CHECKING import torch -from isaaclab.utils import configclass - - -@configclass -class JointImpedanceControllerCfg: - """Configuration for joint impedance regulation controller.""" - - command_type: str = "p_abs" - """Type of command: p_abs (absolute) or p_rel (relative).""" - - dof_pos_offset: Sequence[float] | None = None - """Offset to DOF position command given to controller. (default: None). - - If None then position offsets are set to zero. - """ - - impedance_mode: str = MISSING - """Type of gains: "fixed", "variable", "variable_kp".""" - - inertial_compensation: bool = False - """Whether to perform inertial compensation (inverse dynamics).""" - - gravity_compensation: bool = False - """Whether to perform gravity compensation.""" - - stiffness: float | Sequence[float] = MISSING - """The positional gain for determining desired torques based on joint position error.""" - - damping_ratio: float | Sequence[float] | None = None - """The damping ratio is used in-conjunction with positional gain to compute desired torques - based on joint velocity error. - - The following math operation is performed for computing velocity gains: - :math:`d_gains = 2 * sqrt(p_gains) * damping_ratio`. - """ - - stiffness_limits: tuple[float, float] = (0, 300) - """Minimum and maximum values for positional gains. - - Note: Used only when :obj:`impedance_mode` is "variable" or "variable_kp". - """ - - damping_ratio_limits: tuple[float, float] = (0, 100) - """Minimum and maximum values for damping ratios used to compute velocity gains. - - Note: Used only when :obj:`impedance_mode` is "variable". - """ +if TYPE_CHECKING: + from .joint_impedance_cfg import JointImpedanceControllerCfg class JointImpedanceController: diff --git a/source/isaaclab/isaaclab/controllers/joint_impedance_cfg.py b/source/isaaclab/isaaclab/controllers/joint_impedance_cfg.py new file mode 100644 index 00000000000..36f157c6f63 --- /dev/null +++ b/source/isaaclab/isaaclab/controllers/joint_impedance_cfg.py @@ -0,0 +1,61 @@ +# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md). +# All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause + +from __future__ import annotations + +from collections.abc import Sequence +from dataclasses import MISSING + +from isaaclab.utils import configclass + + +@configclass +class JointImpedanceControllerCfg: + """Configuration for joint impedance regulation controller.""" + + class_type: type | str = "isaaclab.controllers.joint_impedance:JointImpedanceController" + """The associated controller class.""" + + command_type: str = "p_abs" + """Type of command: p_abs (absolute) or p_rel (relative).""" + + dof_pos_offset: Sequence[float] | None = None + """Offset to DOF position command given to controller. (default: None). + + If None then position offsets are set to zero. + """ + + impedance_mode: str = MISSING + """Type of gains: "fixed", "variable", "variable_kp".""" + + inertial_compensation: bool = False + """Whether to perform inertial compensation (inverse dynamics).""" + + gravity_compensation: bool = False + """Whether to perform gravity compensation.""" + + stiffness: float | Sequence[float] = MISSING + """The positional gain for determining desired torques based on joint position error.""" + + damping_ratio: float | Sequence[float] | None = None + """The damping ratio is used in-conjunction with positional gain to compute desired torques + based on joint velocity error. + + The following math operation is performed for computing velocity gains: + :math:`d_gains = 2 * sqrt(p_gains) * damping_ratio`. + """ + + stiffness_limits: tuple[float, float] = (0, 300) + """Minimum and maximum values for positional gains. + + Note: Used only when :obj:`impedance_mode` is "variable" or "variable_kp". + """ + + damping_ratio_limits: tuple[float, float] = (0, 100) + """Minimum and maximum values for damping ratios used to compute velocity gains. + + Note: Used only when :obj:`impedance_mode` is "variable". + """ + diff --git a/source/isaaclab/isaaclab/controllers/pink_ik/local_frame_task.py b/source/isaaclab/isaaclab/controllers/pink_ik/local_frame_task.py index ff8c6b9b03d..def3bcb12d2 100644 --- a/source/isaaclab/isaaclab/controllers/pink_ik/local_frame_task.py +++ b/source/isaaclab/isaaclab/controllers/pink_ik/local_frame_task.py @@ -3,114 +3,20 @@ # # SPDX-License-Identifier: BSD-3-Clause -from collections.abc import Sequence +"""Deprecated compatibility shim for Pink task imports. -import numpy as np -import pinocchio as pin -from pink.tasks.frame_task import FrameTask +Prefer importing from ``isaaclab.controllers.pink_ik.pink_tasks``. +""" -from .pink_kinematics_configuration import PinkKinematicsConfiguration +from __future__ import annotations +import warnings -class LocalFrameTask(FrameTask): - """ - A task that computes error in a local (custom) frame. - Inherits from FrameTask but overrides compute_error. - """ +warnings.warn( + "`isaaclab.controllers.pink_ik.local_frame_task` is deprecated; " + "import from `isaaclab.controllers.pink_ik.pink_tasks` instead.", + DeprecationWarning, + stacklevel=2, +) - def __init__( - self, - frame: str, - base_link_frame_name: str, - position_cost: float | Sequence[float], - orientation_cost: float | Sequence[float], - lm_damping: float = 0.0, - gain: float = 1.0, - ): - """ - Initialize the LocalFrameTask with configuration. - - This task computes pose errors in a local (custom) frame rather than the world frame, - allowing for more flexible control strategies where the reference frame can be - specified independently. - - Args: - frame: Name of the frame to control (end-effector or target frame). - base_link_frame_name: Name of the base link frame used as reference frame - for computing transforms and errors. - position_cost: Cost weight(s) for position error. Can be a single float - for uniform weighting or a sequence of 3 floats for per-axis weighting. - orientation_cost: Cost weight(s) for orientation error. Can be a single float - for uniform weighting or a sequence of 3 floats for per-axis weighting. - lm_damping: Levenberg-Marquardt damping factor for numerical stability. - Defaults to 0.0 (no damping). - gain: Task gain factor that scales the overall task contribution. - Defaults to 1.0. - """ - super().__init__(frame, position_cost, orientation_cost, lm_damping, gain) - self.base_link_frame_name = base_link_frame_name - self.transform_target_to_base = None - - def set_target(self, transform_target_to_base: pin.SE3) -> None: - """Set task target pose in the world frame. - - Args: - transform_target_to_world: Transform from the task target frame to - the world frame. - """ - self.transform_target_to_base = transform_target_to_base.copy() - - def set_target_from_configuration(self, configuration: PinkKinematicsConfiguration) -> None: - """Set task target pose from a robot configuration. - - Args: - configuration: Robot configuration. - """ - if not isinstance(configuration, PinkKinematicsConfiguration): - raise ValueError("configuration must be a PinkKinematicsConfiguration") - self.set_target(configuration.get_transform(self.frame, self.base_link_frame_name)) - - def compute_error(self, configuration: PinkKinematicsConfiguration) -> np.ndarray: - """ - Compute the error between current and target pose in a local frame. - """ - if not isinstance(configuration, PinkKinematicsConfiguration): - raise ValueError("configuration must be a PinkKinematicsConfiguration") - if self.transform_target_to_base is None: - raise ValueError(f"no target set for frame '{self.frame}'") - - transform_frame_to_base = configuration.get_transform(self.frame, self.base_link_frame_name) - transform_target_to_frame = transform_frame_to_base.actInv(self.transform_target_to_base) - - error_in_frame: np.ndarray = pin.log(transform_target_to_frame).vector - return error_in_frame - - def compute_jacobian(self, configuration: PinkKinematicsConfiguration) -> np.ndarray: - r"""Compute the frame task Jacobian. - - The task Jacobian :math:`J(q) \in \mathbb{R}^{6 \times n_v}` is the - derivative of the task error :math:`e(q) \in \mathbb{R}^6` with respect - to the configuration :math:`q`. The formula for the frame task is: - - .. math:: - - J(q) = -\text{Jlog}_6(T_{tb}) {}_b J_{0b}(q) - - The derivation of the formula for this Jacobian is detailed in - [Caron2023]_. See also - :func:`pink.tasks.task.Task.compute_jacobian` for more context on task - Jacobians. - - Args: - configuration: Robot configuration :math:`q`. - - Returns: - Jacobian matrix :math:`J`, expressed locally in the frame. - """ - if self.transform_target_to_base is None: - raise Exception(f"no target set for frame '{self.frame}'") - transform_frame_to_base = configuration.get_transform(self.frame, self.base_link_frame_name) - transform_frame_to_target = self.transform_target_to_base.actInv(transform_frame_to_base) - jacobian_in_frame = configuration.get_frame_jacobian(self.frame) - J = -pin.Jlog6(transform_frame_to_target) @ jacobian_in_frame - return J +from .pink_tasks import DampingTask, FrameTask, LocalFrameTask diff --git a/source/isaaclab/isaaclab/controllers/pink_ik/null_space_posture_task.py b/source/isaaclab/isaaclab/controllers/pink_ik/null_space_posture_task.py index fbd3b84199a..62d2263643b 100644 --- a/source/isaaclab/isaaclab/controllers/pink_ik/null_space_posture_task.py +++ b/source/isaaclab/isaaclab/controllers/pink_ik/null_space_posture_task.py @@ -5,6 +5,8 @@ from __future__ import annotations +from typing import Any + import numpy as np import pinocchio as pin import scipy.linalg.blas as blas @@ -87,7 +89,7 @@ class NullSpacePostureTask(Task): def __init__( self, - cost: float, + cost: float | Any, lm_damping: float = 0.0, gain: float = 1.0, controlled_frames: list[str] | None = None, @@ -111,6 +113,15 @@ def __init__( controlled_joints: Joint names to control in the posture task. If None or empty, all actuated joints are controlled. """ + # Support class_type(cfg) construction by accepting a config object as first argument. + if not isinstance(cost, (int, float)): + cfg = cost + cost = float(getattr(cfg, "cost")) + lm_damping = float(getattr(cfg, "lm_damping", lm_damping)) + gain = float(getattr(cfg, "gain", gain)) + controlled_frames = getattr(cfg, "controlled_frames", controlled_frames) + controlled_joints = getattr(cfg, "controlled_joints", controlled_joints) + super().__init__(cost=cost, gain=gain, lm_damping=lm_damping) self.target_q: np.ndarray | None = None self.controlled_frames: list[str] = controlled_frames or [] diff --git a/source/isaaclab/isaaclab/controllers/pink_ik/pink_ik.py b/source/isaaclab/isaaclab/controllers/pink_ik/pink_ik.py index 788a5da6705..c7d1022cf8a 100644 --- a/source/isaaclab/isaaclab/controllers/pink_ik/pink_ik.py +++ b/source/isaaclab/isaaclab/controllers/pink_ik/pink_ik.py @@ -14,16 +14,20 @@ from __future__ import annotations -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, cast import numpy as np import torch from pink import solve_ik +from pink.tasks import Task from isaaclab.assets import ArticulationCfg +from isaaclab.controllers import utils as controller_utils +from isaaclab.utils.assets import retrieve_file_path from isaaclab.utils.string import resolve_matching_names_values from .null_space_posture_task import NullSpacePostureTask +from .pink_task_cfg import PinkIKTaskCfg from .pink_kinematics_configuration import PinkKinematicsConfiguration if TYPE_CHECKING: @@ -74,10 +78,25 @@ def __init__( # Validate consistency between controlled_joint_indices and configuration self._validate_consistency(cfg, controlled_joint_indices) + # Resolve URDF/mesh paths at runtime. If only usd_path is provided, convert USD→URDF first. + if cfg.urdf_path is None and cfg.usd_path is not None: + import tempfile + + urdf_output_dir = cfg.urdf_output_dir or tempfile.gettempdir() + urdf_path, mesh_path = controller_utils.convert_usd_to_urdf( + cfg.usd_path, urdf_output_dir, force_conversion=True + ) + else: + urdf_path = retrieve_file_path(cfg.urdf_path) if cfg.urdf_path else cfg.urdf_path + mesh_path = retrieve_file_path(cfg.mesh_path) if cfg.mesh_path else cfg.mesh_path + + if urdf_path is None: + raise ValueError("Either urdf_path or usd_path must be provided in the controller configuration") + # Initialize the Kinematics model used by pink IK to control robot self.pink_configuration = PinkKinematicsConfiguration( - urdf_path=cfg.urdf_path, - mesh_path=cfg.mesh_path, + urdf_path=urdf_path, + mesh_path=mesh_path, controlled_joint_names=cfg.joint_names, ) @@ -93,16 +112,19 @@ def __init__( ) self.init_joint_positions = np.zeros(len(pink_joint_names)) self.init_joint_positions[indices] = np.array(values) + self._variable_input_tasks = [task_cfg.class_type(task_cfg) for task_cfg in cfg.variable_input_tasks] + self._fixed_input_tasks = [task_cfg.class_type(task_cfg) for task_cfg in cfg.fixed_input_tasks] + self.cfg.variable_input_tasks = cast(list[Task | PinkIKTaskCfg], self._variable_input_tasks) + self.cfg.fixed_input_tasks = cast(list[Task | PinkIKTaskCfg], self._fixed_input_tasks) - # Set the default targets for each task from the configuration - for task in cfg.variable_input_tasks: + for task in self._variable_input_tasks: # If task is a NullSpacePostureTask, set the target to the initial joint positions if isinstance(task, NullSpacePostureTask): task.set_target(self.init_joint_positions) continue - task.set_target_from_configuration(self.pink_configuration) - for task in cfg.fixed_input_tasks: - task.set_target_from_configuration(self.pink_configuration) + getattr(task, "set_target_from_configuration")(self.pink_configuration) + for task in self._fixed_input_tasks: + getattr(task, "set_target_from_configuration")(self.pink_configuration) # Create joint ordering mappings self._setup_joint_ordering_mappings() @@ -127,6 +149,8 @@ def _validate_consistency(self, cfg: PinkIKControllerCfg, controlled_joint_indic ) # Check: Joint name consistency - verify that the indices point to the expected joint names + if cfg.all_joint_names is None: + raise ValueError("cfg.all_joint_names cannot be None") actual_joint_names = [cfg.all_joint_names[idx] for idx in controlled_joint_indices] if actual_joint_names != cfg.joint_names: mismatches = [] @@ -184,7 +208,7 @@ def update_null_space_joint_targets(self, curr_joint_pos: np.ndarray): Args: curr_joint_pos: The current joint positions of shape (num_joints,). """ - for task in self.cfg.variable_input_tasks: + for task in self._variable_input_tasks: if isinstance(task, NullSpacePostureTask): task.set_target(curr_joint_pos) @@ -220,7 +244,7 @@ def compute( try: velocity = solve_ik( self.pink_configuration, - self.cfg.variable_input_tasks + self.cfg.fixed_input_tasks, + self._variable_input_tasks + self._fixed_input_tasks, dt, solver="daqp", safety_break=self.cfg.fail_on_joint_limit_violation, diff --git a/source/isaaclab/isaaclab/controllers/pink_ik/pink_ik_cfg.py b/source/isaaclab/isaaclab/controllers/pink_ik/pink_ik_cfg.py index 3eb9fa6c575..3d37c4d9512 100644 --- a/source/isaaclab/isaaclab/controllers/pink_ik/pink_ik_cfg.py +++ b/source/isaaclab/isaaclab/controllers/pink_ik/pink_ik_cfg.py @@ -7,11 +7,14 @@ from __future__ import annotations -from dataclasses import MISSING - -from pink.tasks import FrameTask +from dataclasses import field +from typing import TYPE_CHECKING from isaaclab.utils import configclass +from .pink_task_cfg import PinkIKTaskCfg + +if TYPE_CHECKING: + from pink.tasks import Task @configclass @@ -21,9 +24,19 @@ class PinkIKControllerCfg: The Pink IK controller can be found at: https://github.com/stephane-caron/pink """ + usd_path: str | None = None + """Path to the robot's USD file. When set and ``urdf_path`` is None, the controller will automatically + convert the USD to URDF at runtime using ``convert_usd_to_urdf``. Requires Isaac Sim at runtime. + """ + + urdf_output_dir: str | None = None + """Output directory for the USD-to-URDF conversion. Only used when ``usd_path`` is set and + ``urdf_path`` is None. Defaults to ``tempfile.gettempdir()`` if not provided. + """ + urdf_path: str | None = None """Path to the robot's URDF file. This file is used by Pinocchio's ``robot_wrapper.BuildFromURDF`` - to load the robot model. + to load the robot model. If not provided, the URDF is generated from ``usd_path`` at runtime. """ mesh_path: str | None = None @@ -38,7 +51,7 @@ class PinkIKControllerCfg: The last ``num_hand_joints`` values of the action are the hand joint angles. """ - variable_input_tasks: list[FrameTask] = MISSING + variable_input_tasks: list[Task | PinkIKTaskCfg] = field(default_factory=list) """A list of tasks for the Pink IK controller. These tasks are controllable by the environment action. @@ -47,7 +60,7 @@ class PinkIKControllerCfg: For more details, visit: https://github.com/stephane-caron/pink """ - fixed_input_tasks: list[FrameTask] = MISSING + fixed_input_tasks: list[Task | PinkIKTaskCfg] = field(default_factory=list) """ A list of tasks for the Pink IK controller. These tasks are fixed and not controllable by the env action. diff --git a/source/isaaclab/isaaclab/controllers/pink_ik/pink_task_cfg.py b/source/isaaclab/isaaclab/controllers/pink_ik/pink_task_cfg.py new file mode 100644 index 00000000000..efcf3a0e914 --- /dev/null +++ b/source/isaaclab/isaaclab/controllers/pink_ik/pink_task_cfg.py @@ -0,0 +1,67 @@ +# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md). +# All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause + +"""Task configuration objects for Pink IK.""" + +from __future__ import annotations + +from dataclasses import MISSING, field +from typing import Any + +from isaaclab.utils import configclass + + +@configclass +class PinkIKTaskCfg: + """Task specification for deferred runtime construction.""" + + class_type: str | type | None = None + """Task builder as ``"module.path:callable"`` or callable object.""" + + +@configclass +class FrameTaskCfg(PinkIKTaskCfg): + """Configuration wrapper for ``pink.tasks.FrameTask``.""" + + frame: Any = MISSING + position_cost: Any = MISSING + orientation_cost: Any = MISSING + lm_damping: float = 0.0 + gain: float = 1.0 + class_type: str | type | None = "isaaclab.controllers.pink_ik.pink_tasks:FrameTask" + + +@configclass +class DampingTaskCfg(PinkIKTaskCfg): + """Configuration wrapper for ``pink.tasks.DampingTask``.""" + + cost: Any = MISSING + class_type: str | type | None = "isaaclab.controllers.pink_ik.pink_tasks:DampingTask" + + +@configclass +class LocalFrameTaskCfg(PinkIKTaskCfg): + """Configuration wrapper for ``LocalFrameTask``.""" + + frame: Any = MISSING + base_link_frame_name: Any = MISSING + position_cost: Any = MISSING + orientation_cost: Any = MISSING + lm_damping: float = 0.0 + gain: float = 1.0 + class_type: str | type | None = "isaaclab.controllers.pink_ik.pink_tasks:LocalFrameTask" + + +@configclass +class NullSpacePostureTaskCfg(PinkIKTaskCfg): + """Configuration wrapper for ``NullSpacePostureTask``.""" + + cost: Any = MISSING + lm_damping: float = 0.0 + gain: float = 1.0 + controlled_frames: list[str] = field(default_factory=list) + controlled_joints: list[str] = field(default_factory=list) + class_type: str | type | None = "isaaclab.controllers.pink_ik.null_space_posture_task:NullSpacePostureTask" + diff --git a/source/isaaclab/isaaclab/controllers/pink_ik/pink_tasks.py b/source/isaaclab/isaaclab/controllers/pink_ik/pink_tasks.py new file mode 100644 index 00000000000..84bb60a3a8e --- /dev/null +++ b/source/isaaclab/isaaclab/controllers/pink_ik/pink_tasks.py @@ -0,0 +1,123 @@ +# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md). +# All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause + +from collections.abc import Sequence + +import numpy as np +import pinocchio as pin +from pink.tasks import DampingTask as PinkDampingTask +from pink.tasks.frame_task import FrameTask as PinkFrameTask + +from .pink_kinematics_configuration import PinkKinematicsConfiguration + + +class FrameTask(PinkFrameTask): + """Frame task that also supports ``class_type(cfg)`` construction.""" + + def __init__( + self, + cfg_or_frame, + position_cost: float | Sequence[float] | None = None, + orientation_cost: float | Sequence[float] | None = None, + lm_damping: float = 0.0, + gain: float = 1.0, + ): + if isinstance(cfg_or_frame, str): + frame = cfg_or_frame + else: + cfg = cfg_or_frame + frame = cfg.frame + position_cost = cfg.position_cost + orientation_cost = cfg.orientation_cost + lm_damping = cfg.lm_damping + gain = cfg.gain + + if position_cost is None or orientation_cost is None: + raise ValueError("position_cost and orientation_cost must be provided") + + super().__init__( + frame, + position_cost=position_cost, + orientation_cost=orientation_cost, + lm_damping=lm_damping, + gain=gain, + ) + + +class DampingTask(PinkDampingTask): + """Damping task accepting either cfg or direct cost argument.""" + + def __init__(self, cfg_or_cost, cost: float | None = None): + if isinstance(cfg_or_cost, (int, float)): + _cost = float(cfg_or_cost if cost is None else cost) + else: + _cost = cfg_or_cost.cost + super().__init__(cost=_cost) + + +class LocalFrameTask(FrameTask): + """ + A task that computes error in a local (custom) frame. + Inherits from FrameTask but overrides compute_error. + """ + + def __init__( + self, + frame, + base_link_frame_name: str | None = None, + position_cost: float | Sequence[float] | None = None, + orientation_cost: float | Sequence[float] | None = None, + lm_damping: float = 0.0, + gain: float = 1.0, + ): + if isinstance(frame, str): + resolved_frame = frame + if base_link_frame_name is None: + raise ValueError("base_link_frame_name must be provided") + else: + cfg = frame + resolved_frame = cfg.frame + base_link_frame_name = cfg.base_link_frame_name + position_cost = cfg.position_cost + orientation_cost = cfg.orientation_cost + lm_damping = cfg.lm_damping + gain = cfg.gain + + if position_cost is None or orientation_cost is None: + raise ValueError("position_cost and orientation_cost must be provided") + + super().__init__(resolved_frame, position_cost, orientation_cost, lm_damping, gain) + self.base_link_frame_name = base_link_frame_name + self.transform_target_to_base = None + + def set_target(self, transform_target_to_base: pin.SE3) -> None: + self.transform_target_to_base = transform_target_to_base.copy() + + def set_target_from_configuration(self, configuration: PinkKinematicsConfiguration) -> None: + if not isinstance(configuration, PinkKinematicsConfiguration): + raise ValueError("configuration must be a PinkKinematicsConfiguration") + self.set_target(configuration.get_transform(self.frame, self.base_link_frame_name)) + + def compute_error(self, configuration: PinkKinematicsConfiguration) -> np.ndarray: + if not isinstance(configuration, PinkKinematicsConfiguration): + raise ValueError("configuration must be a PinkKinematicsConfiguration") + if self.transform_target_to_base is None: + raise ValueError(f"no target set for frame '{self.frame}'") + + transform_frame_to_base = configuration.get_transform(self.frame, self.base_link_frame_name) + transform_target_to_frame = transform_frame_to_base.actInv(self.transform_target_to_base) + + error_in_frame: np.ndarray = pin.log(transform_target_to_frame).vector + return error_in_frame + + def compute_jacobian(self, configuration: PinkKinematicsConfiguration) -> np.ndarray: + if self.transform_target_to_base is None: + raise Exception(f"no target set for frame '{self.frame}'") + transform_frame_to_base = configuration.get_transform(self.frame, self.base_link_frame_name) + transform_frame_to_target = self.transform_target_to_base.actInv(transform_frame_to_base) + jacobian_in_frame = configuration.get_frame_jacobian(self.frame) + J = -pin.Jlog6(transform_frame_to_target) @ jacobian_in_frame + return J + diff --git a/source/isaaclab/isaaclab/controllers/utils.py b/source/isaaclab/isaaclab/controllers/utils.py index 7e72912fdfd..fc091d324af 100644 --- a/source/isaaclab/isaaclab/controllers/utils.py +++ b/source/isaaclab/isaaclab/controllers/utils.py @@ -12,12 +12,6 @@ import os import re -from isaacsim.core.utils.extensions import enable_extension - -enable_extension("isaacsim.asset.exporter.urdf") - -from nvidia.srl.from_usd.to_urdf import UsdToUrdf - # import logger logger = logging.getLogger(__name__) @@ -32,6 +26,12 @@ def convert_usd_to_urdf(usd_path: str, output_path: str, force_conversion: bool Returns: A tuple containing the paths to the URDF file and the mesh directory. """ + from isaacsim.core.utils.extensions import enable_extension + + enable_extension("isaacsim.asset.exporter.urdf") + + from nvidia.srl.from_usd.to_urdf import UsdToUrdf + usd_to_urdf_kwargs = { "node_names_to_remove": None, "edge_names_to_remove": None, diff --git a/source/isaaclab/isaaclab/envs/mdp/actions/pink_task_space_actions.py b/source/isaaclab/isaaclab/envs/mdp/actions/pink_task_space_actions.py index 7dad8020533..5d7e59418ee 100644 --- a/source/isaaclab/isaaclab/envs/mdp/actions/pink_task_space_actions.py +++ b/source/isaaclab/isaaclab/envs/mdp/actions/pink_task_space_actions.py @@ -15,7 +15,7 @@ import isaaclab.utils.math as math_utils from isaaclab.assets.articulation import Articulation from isaaclab.controllers.pink_ik import PinkIKController -from isaaclab.controllers.pink_ik.local_frame_task import LocalFrameTask +from isaaclab.controllers.pink_ik.pink_tasks import LocalFrameTask from isaaclab.managers.action_manager import ActionTerm if TYPE_CHECKING: diff --git a/source/isaaclab/test/controllers/test_local_frame_task.py b/source/isaaclab/test/controllers/test_local_frame_task.py index cf832f32a93..5e7304d9372 100644 --- a/source/isaaclab/test/controllers/test_local_frame_task.py +++ b/source/isaaclab/test/controllers/test_local_frame_task.py @@ -16,7 +16,7 @@ import pinocchio as pin import pytest -from isaaclab.controllers.pink_ik.local_frame_task import LocalFrameTask +from isaaclab.controllers.pink_ik.pink_tasks import LocalFrameTask from isaaclab.controllers.pink_ik.pink_kinematics_configuration import PinkKinematicsConfiguration # class TestLocalFrameTask: diff --git a/source/isaaclab/test/controllers/test_pink_ik.py b/source/isaaclab/test/controllers/test_pink_ik.py index 99a8603089b..c42b9b63f59 100644 --- a/source/isaaclab/test/controllers/test_pink_ik.py +++ b/source/isaaclab/test/controllers/test_pink_ik.py @@ -94,10 +94,9 @@ def env_and_cfg(request): env, env_cfg = create_test_env(env_name, num_envs=1) - # Get only the FrameTasks from variable_input_tasks - variable_input_tasks = [ - task for task in env_cfg.actions.upper_body_ik.controller.variable_input_tasks if isinstance(task, FrameTask) - ] + # Read instantiated task objects from the live action term/controller, not raw cfg wrappers. + action_term = env.action_manager.get_term(name="upper_body_ik") + variable_input_tasks = [task for task in action_term._ik_controllers[0].cfg.variable_input_tasks if isinstance(task, FrameTask)] assert len(variable_input_tasks) == 2, "Expected exactly two FrameTasks (left and right hand)." frames = [task.frame for task in variable_input_tasks] # Try to infer which is left and which is right diff --git a/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomanipulation/pick_place/configs/pink_controller_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomanipulation/pick_place/configs/pink_controller_cfg.py index 488d22c137b..51d69f92eed 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomanipulation/pick_place/configs/pink_controller_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomanipulation/pick_place/configs/pink_controller_cfg.py @@ -9,9 +9,7 @@ including both fixed base and mobile configurations for upper body manipulation. """ -from isaaclab.controllers.pink_ik.local_frame_task import LocalFrameTask -from isaaclab.controllers.pink_ik.null_space_posture_task import NullSpacePostureTask -from isaaclab.controllers.pink_ik.pink_ik_cfg import PinkIKControllerCfg +from isaaclab.controllers.pink_ik import LocalFrameTaskCfg, NullSpacePostureTaskCfg, PinkIKControllerCfg from isaaclab.envs.mdp.actions.pink_actions_cfg import PinkInverseKinematicsActionCfg ## @@ -25,23 +23,23 @@ show_ik_warnings=True, fail_on_joint_limit_violation=False, variable_input_tasks=[ - LocalFrameTask( - "g1_29dof_with_hand_rev_1_0_left_wrist_yaw_link", + LocalFrameTaskCfg( + frame="g1_29dof_with_hand_rev_1_0_left_wrist_yaw_link", base_link_frame_name="g1_29dof_with_hand_rev_1_0_pelvis", position_cost=8.0, # [cost] / [m] orientation_cost=2.0, # [cost] / [rad] lm_damping=10, # dampening for solver for step jumps gain=0.5, ), - LocalFrameTask( - "g1_29dof_with_hand_rev_1_0_right_wrist_yaw_link", + LocalFrameTaskCfg( + frame="g1_29dof_with_hand_rev_1_0_right_wrist_yaw_link", base_link_frame_name="g1_29dof_with_hand_rev_1_0_pelvis", position_cost=8.0, # [cost] / [m] orientation_cost=2.0, # [cost] / [rad] lm_damping=10, # dampening for solver for step jumps gain=0.5, ), - NullSpacePostureTask( + NullSpacePostureTaskCfg( cost=0.5, lm_damping=1, controlled_frames=[ diff --git a/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomanipulation/pick_place/fixed_base_upper_body_ik_g1_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomanipulation/pick_place/fixed_base_upper_body_ik_g1_env_cfg.py index e225660e8e8..c6c115ed679 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomanipulation/pick_place/fixed_base_upper_body_ik_g1_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomanipulation/pick_place/fixed_base_upper_body_ik_g1_env_cfg.py @@ -4,16 +4,8 @@ # SPDX-License-Identifier: BSD-3-Clause -import logging - -try: - import isaacteleop # noqa: F401 -- pipeline builders need isaacteleop at runtime - from isaaclab_teleop import IsaacTeleopCfg, XrCfg - - _TELEOP_AVAILABLE = True -except ImportError: - _TELEOP_AVAILABLE = False - logging.getLogger(__name__).warning("isaaclab_teleop is not installed. XR teleoperation features will be disabled.") +from isaaclab_teleop.isaac_teleop_cfg import IsaacTeleopCfg +from isaaclab_teleop.xr_cfg import XrCfg import isaaclab.envs.mdp as base_mdp import isaaclab.sim as sim_utils @@ -26,7 +18,7 @@ from isaaclab.scene import InteractiveSceneCfg from isaaclab.sim.spawners.from_files.from_files_cfg import GroundPlaneCfg, UsdFileCfg from isaaclab.utils import configclass -from isaaclab.utils.assets import ISAAC_NUCLEUS_DIR, ISAACLAB_NUCLEUS_DIR, retrieve_file_path +from isaaclab.utils.assets import ISAAC_NUCLEUS_DIR, ISAACLAB_NUCLEUS_DIR from isaaclab_tasks.manager_based.locomanipulation.pick_place import mdp as locomanip_mdp from isaaclab_tasks.manager_based.manipulation.pick_place import mdp as manip_mdp @@ -393,20 +385,16 @@ def __post_init__(self): # Set the URDF and mesh paths for the IK controller urdf_omniverse_path = f"{ISAACLAB_NUCLEUS_DIR}/Controllers/LocomanipulationAssets/unitree_g1_kinematics_asset/g1_29dof_with_hand_only_kinematics.urdf" # noqa: E501 - # Retrieve local paths for the URDF and mesh files. Will be cached for call after the first time. - self.actions.upper_body_ik.controller.urdf_path = retrieve_file_path(urdf_omniverse_path) - - # IsaacTeleop-based teleoperation pipeline - # Build the pipeline and extract SE3 retargeters for UI parameter tuning - if _TELEOP_AVAILABLE: - self.xr = XrCfg( - anchor_pos=(0.0, 0.0, -0.45), - anchor_rot=(0.0, 0.0, 0.0, 1.0), - ) - pipeline, se3_retargeters = _build_g1_upper_body_pipeline() - self.isaac_teleop = IsaacTeleopCfg( - pipeline_builder=lambda: pipeline, - # retargeters_to_tune=lambda: se3_retargeters, - sim_device=self.sim.device, - xr_cfg=self.xr, - ) + # Defer Nucleus path resolution to controller initialization at runtime. + self.actions.upper_body_ik.controller.urdf_path = urdf_omniverse_path + + # IsaacTeleop-based teleoperation pipeline (resolved lazily at runtime). + self.xr = XrCfg( + anchor_pos=(0.0, 0.0, -0.45), + anchor_rot=(0.0, 0.0, 0.0, 1.0), + ) + self.isaac_teleop = IsaacTeleopCfg( + pipeline_builder=_build_g1_upper_body_pipeline, + sim_device=self.sim.device, + xr_cfg=self.xr, + ) diff --git a/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomanipulation/pick_place/locomanipulation_g1_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomanipulation/pick_place/locomanipulation_g1_env_cfg.py index 552c4d7d942..b27264d8380 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomanipulation/pick_place/locomanipulation_g1_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomanipulation/pick_place/locomanipulation_g1_env_cfg.py @@ -25,7 +25,7 @@ from isaaclab.scene import InteractiveSceneCfg from isaaclab.sim.spawners.from_files.from_files_cfg import GroundPlaneCfg, UsdFileCfg from isaaclab.utils import configclass -from isaaclab.utils.assets import ISAAC_NUCLEUS_DIR, ISAACLAB_NUCLEUS_DIR, retrieve_file_path +from isaaclab.utils.assets import ISAAC_NUCLEUS_DIR, ISAACLAB_NUCLEUS_DIR from isaaclab_tasks.manager_based.locomanipulation.pick_place import mdp as locomanip_mdp from isaaclab_tasks.manager_based.locomanipulation.pick_place.configs.action_cfg import AgileBasedLowerBodyActionCfg @@ -438,11 +438,8 @@ def __post_init__(self): # scene settings self.scene.replicate_physics = False - # Set the URDF and mesh paths for the IK controller - urdf_omniverse_path = f"{ISAACLAB_NUCLEUS_DIR}/Controllers/LocomanipulationAssets/unitree_g1_kinematics_asset/g1_29dof_with_hand_only_kinematics.urdf" # noqa: E501 - - # Retrieve local paths for the URDF and mesh files. Will be cached for call after the first time. - self.actions.upper_body_ik.controller.urdf_path = retrieve_file_path(urdf_omniverse_path) + # Set the URDF path for the IK controller. Path resolution (Nucleus → local) happens at runtime. + self.actions.upper_body_ik.controller.urdf_path = f"{ISAACLAB_NUCLEUS_DIR}/Controllers/LocomanipulationAssets/unitree_g1_kinematics_asset/g1_29dof_with_hand_only_kinematics.urdf" # noqa: E501 if _TELEOP_AVAILABLE: self.xr = XrCfg( diff --git a/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomanipulation/pick_place/mdp/observations.py b/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomanipulation/pick_place/mdp/observations.py index 376f196cba8..5e39567efa5 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomanipulation/pick_place/mdp/observations.py +++ b/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomanipulation/pick_place/mdp/observations.py @@ -3,10 +3,16 @@ # # SPDX-License-Identifier: BSD-3-Clause +from __future__ import annotations + +from typing import TYPE_CHECKING + import torch import warp as wp -from isaaclab.envs import ManagerBasedRLEnv +if TYPE_CHECKING: + from isaaclab.envs import ManagerBasedRLEnv + from isaaclab.managers import SceneEntityCfg diff --git a/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomanipulation/pick_place/mdp/terminations.py b/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomanipulation/pick_place/mdp/terminations.py index c2f3fd0f8b0..ebdf0c25f61 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomanipulation/pick_place/mdp/terminations.py +++ b/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomanipulation/pick_place/mdp/terminations.py @@ -14,7 +14,6 @@ from isaaclab.assets import RigidObject from isaaclab.managers import SceneEntityCfg -from isaaclab.sim.views import XformPrimView from isaaclab.utils.math import quat_apply_inverse if TYPE_CHECKING: @@ -70,8 +69,11 @@ def task_done_pick_place_table_frame( object: RigidObject = env.scene[object_cfg.name] table = env.scene[table_cfg.name] - if not isinstance(table, XformPrimView): - raise TypeError(f"Expected table '{table_cfg.name}' to be an XformPrimView, got {type(table)}") + # Avoid importing sim views at module-load time for pure cfg loading. + if not hasattr(table, "get_world_poses"): + raise TypeError( + f"Expected table '{table_cfg.name}' to expose get_world_poses(), got {type(table)}" + ) # Get table world pose table_pos_w, table_quat_w = table.get_world_poses() diff --git a/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/exhaustpipe_gr1t2_pink_ik_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/exhaustpipe_gr1t2_pink_ik_env_cfg.py index 4d22c35e1f4..163da35de93 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/exhaustpipe_gr1t2_pink_ik_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/exhaustpipe_gr1t2_pink_ik_env_cfg.py @@ -3,22 +3,10 @@ # # SPDX-License-Identifier: BSD-3-Clause -import logging - -from pink.tasks import DampingTask, FrameTask - -try: - from isaaclab_teleop import IsaacTeleopCfg - - _TELEOP_AVAILABLE = True -except ImportError: - _TELEOP_AVAILABLE = False - logging.getLogger(__name__).warning("isaaclab_teleop is not installed. XR teleoperation features will be disabled.") - -import isaaclab.controllers.utils as ControllerUtils -from isaaclab.controllers.pink_ik import NullSpacePostureTask, PinkIKControllerCfg +from isaaclab.controllers.pink_ik import DampingTaskCfg, FrameTaskCfg, NullSpacePostureTaskCfg, PinkIKControllerCfg from isaaclab.envs.mdp.actions.pink_actions_cfg import PinkInverseKinematicsActionCfg from isaaclab.utils import configclass +from isaaclab_teleop.isaac_teleop_cfg import IsaacTeleopCfg from isaaclab_tasks.manager_based.manipulation.pick_place.exhaustpipe_gr1t2_base_env_cfg import ( ExhaustPipeGR1T2BaseEnvCfg, @@ -92,24 +80,24 @@ def __post_init__(self): # Determines whether Pink IK solver will fail due to a joint limit violation fail_on_joint_limit_violation=False, variable_input_tasks=[ - FrameTask( - "GR1T2_fourier_hand_6dof_left_hand_pitch_link", + FrameTaskCfg( + frame="GR1T2_fourier_hand_6dof_left_hand_pitch_link", position_cost=8.0, # [cost] / [m] orientation_cost=1.0, # [cost] / [rad] lm_damping=10, # dampening for solver for step jumps gain=0.5, ), - FrameTask( - "GR1T2_fourier_hand_6dof_right_hand_pitch_link", + FrameTaskCfg( + frame="GR1T2_fourier_hand_6dof_right_hand_pitch_link", position_cost=8.0, # [cost] / [m] orientation_cost=1.0, # [cost] / [rad] lm_damping=10, # dampening for solver for step jumps gain=0.5, ), - DampingTask( + DampingTaskCfg( cost=0.5, # [cost] * [s] / [rad] ), - NullSpacePostureTask( + NullSpacePostureTaskCfg( cost=0.2, lm_damping=1, controlled_frames=[ @@ -134,20 +122,13 @@ def __post_init__(self): fixed_input_tasks=[], ), ) - # Convert USD to URDF and change revolute joints to fixed - temp_urdf_output_path, temp_urdf_meshes_output_path = ControllerUtils.convert_usd_to_urdf( - self.scene.robot.spawn.usd_path, self.temp_urdf_dir, force_conversion=True - ) - - # Set the URDF and mesh paths for the IK controller - self.actions.gr1_action.controller.urdf_path = temp_urdf_output_path - self.actions.gr1_action.controller.mesh_path = temp_urdf_meshes_output_path + # Defer USD→URDF conversion to controller initialization (requires Isaac Sim at runtime). + self.actions.gr1_action.controller.usd_path = self.scene.robot.spawn.usd_path + self.actions.gr1_action.controller.urdf_output_dir = self.temp_urdf_dir - # IsaacTeleop-based teleoperation pipeline - if _TELEOP_AVAILABLE: - pipeline = _build_gr1t2_pickplace_pipeline() - self.isaac_teleop = IsaacTeleopCfg( - pipeline_builder=lambda: pipeline, - sim_device=self.sim.device, - xr_cfg=self.xr, - ) + # IsaacTeleop-based teleoperation pipeline. + self.isaac_teleop = IsaacTeleopCfg( + pipeline_builder=lambda: _build_gr1t2_pickplace_pipeline()[0], + sim_device=self.sim.device, + xr_cfg=self.xr, + ) diff --git a/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/nutpour_gr1t2_pink_ik_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/nutpour_gr1t2_pink_ik_env_cfg.py index 1e05d8b8589..98d7ce2d936 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/nutpour_gr1t2_pink_ik_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/nutpour_gr1t2_pink_ik_env_cfg.py @@ -3,22 +3,10 @@ # # SPDX-License-Identifier: BSD-3-Clause -import logging - -from pink.tasks import DampingTask, FrameTask - -try: - from isaaclab_teleop import IsaacTeleopCfg - - _TELEOP_AVAILABLE = True -except ImportError: - _TELEOP_AVAILABLE = False - logging.getLogger(__name__).warning("isaaclab_teleop is not installed. XR teleoperation features will be disabled.") - -import isaaclab.controllers.utils as ControllerUtils -from isaaclab.controllers.pink_ik import NullSpacePostureTask, PinkIKControllerCfg +from isaaclab.controllers.pink_ik import DampingTaskCfg, FrameTaskCfg, NullSpacePostureTaskCfg, PinkIKControllerCfg from isaaclab.envs.mdp.actions.pink_actions_cfg import PinkInverseKinematicsActionCfg from isaaclab.utils import configclass +from isaaclab_teleop.isaac_teleop_cfg import IsaacTeleopCfg from isaaclab_tasks.manager_based.manipulation.pick_place.nutpour_gr1t2_base_env_cfg import NutPourGR1T2BaseEnvCfg from isaaclab_tasks.manager_based.manipulation.pick_place.pickplace_gr1t2_env_cfg import ( @@ -90,24 +78,24 @@ def __post_init__(self): # Determines whether Pink IK solver will fail due to a joint limit violation fail_on_joint_limit_violation=False, variable_input_tasks=[ - FrameTask( - "GR1T2_fourier_hand_6dof_left_hand_pitch_link", + FrameTaskCfg( + frame="GR1T2_fourier_hand_6dof_left_hand_pitch_link", position_cost=8.0, # [cost] / [m] orientation_cost=1.0, # [cost] / [rad] lm_damping=10, # dampening for solver for step jumps gain=0.5, ), - FrameTask( - "GR1T2_fourier_hand_6dof_right_hand_pitch_link", + FrameTaskCfg( + frame="GR1T2_fourier_hand_6dof_right_hand_pitch_link", position_cost=8.0, # [cost] / [m] orientation_cost=1.0, # [cost] / [rad] lm_damping=10, # dampening for solver for step jumps gain=0.5, ), - DampingTask( + DampingTaskCfg( cost=0.5, # [cost] * [s] / [rad] ), - NullSpacePostureTask( + NullSpacePostureTaskCfg( cost=0.2, lm_damping=1, controlled_frames=[ @@ -132,20 +120,13 @@ def __post_init__(self): fixed_input_tasks=[], ), ) - # Convert USD to URDF and change revolute joints to fixed - temp_urdf_output_path, temp_urdf_meshes_output_path = ControllerUtils.convert_usd_to_urdf( - self.scene.robot.spawn.usd_path, self.temp_urdf_dir, force_conversion=True - ) - - # Set the URDF and mesh paths for the IK controller - self.actions.gr1_action.controller.urdf_path = temp_urdf_output_path - self.actions.gr1_action.controller.mesh_path = temp_urdf_meshes_output_path + # Defer USD→URDF conversion to controller initialization (requires Isaac Sim at runtime). + self.actions.gr1_action.controller.usd_path = self.scene.robot.spawn.usd_path + self.actions.gr1_action.controller.urdf_output_dir = self.temp_urdf_dir - # IsaacTeleop-based teleoperation pipeline - if _TELEOP_AVAILABLE: - pipeline = _build_gr1t2_pickplace_pipeline() - self.isaac_teleop = IsaacTeleopCfg( - pipeline_builder=lambda: pipeline, - sim_device=self.sim.device, - xr_cfg=self.xr, - ) + # IsaacTeleop-based teleoperation pipeline. + self.isaac_teleop = IsaacTeleopCfg( + pipeline_builder=lambda: _build_gr1t2_pickplace_pipeline()[0], + sim_device=self.sim.device, + xr_cfg=self.xr, + ) diff --git a/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/pickplace_gr1t2_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/pickplace_gr1t2_env_cfg.py index dd1edbf7d8b..76739b4b8ae 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/pickplace_gr1t2_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/pickplace_gr1t2_env_cfg.py @@ -3,27 +3,15 @@ # # SPDX-License-Identifier: BSD-3-Clause -import logging import os import tempfile import torch -from pink.tasks import DampingTask, FrameTask -try: - import isaacteleop # noqa: F401 -- pipeline builders need isaacteleop at runtime - from isaaclab_teleop import IsaacTeleopCfg, XrCfg - - _TELEOP_AVAILABLE = True -except ImportError: - _TELEOP_AVAILABLE = False - logging.getLogger(__name__).warning("isaaclab_teleop is not installed. XR teleoperation features will be disabled.") - -import isaaclab.controllers.utils as ControllerUtils import isaaclab.envs.mdp as base_mdp import isaaclab.sim as sim_utils from isaaclab.assets import ArticulationCfg, AssetBaseCfg, RigidObjectCfg -from isaaclab.controllers.pink_ik import NullSpacePostureTask, PinkIKControllerCfg +from isaaclab.controllers.pink_ik import DampingTaskCfg, FrameTaskCfg, NullSpacePostureTaskCfg, PinkIKControllerCfg from isaaclab.envs import ManagerBasedRLEnvCfg from isaaclab.envs.mdp.actions.pink_actions_cfg import PinkInverseKinematicsActionCfg from isaaclab.managers import EventTermCfg as EventTerm @@ -39,6 +27,8 @@ from . import mdp from isaaclab_assets.robots.fourier import GR1T2_HIGH_PD_CFG # isort: skip +from isaaclab_teleop.isaac_teleop_cfg import IsaacTeleopCfg # isort: skip +from isaaclab_teleop.xr_cfg import XrCfg # isort: skip def _build_gr1t2_pickplace_pipeline(): @@ -115,9 +105,21 @@ def _build_gr1t2_pickplace_pipeline(): # DexHand Retargeters (left and right hands) # ------------------------------------------------------------------------- # Resolve dex-retargeting YAML config paths from IsaacLab's retargeter data directory - import isaaclab.devices.openxr.retargeters.humanoid.fourier.gr1_t2_dex_retargeting_utils as _dex_utils - - _data_dir = os.path.abspath(os.path.join(os.path.dirname(_dex_utils.__file__), "data")) + import isaaclab_teleop.isaac_teleop_cfg as _teleop_cfg_mod + + _teleop_cfg_file = _teleop_cfg_mod.__file__ + if _teleop_cfg_file is None: + raise RuntimeError("Could not resolve isaaclab_teleop package path for dex-retargeting configs.") + _teleop_pkg_dir = os.path.dirname(_teleop_cfg_file) + _data_dir = os.path.join( + _teleop_pkg_dir, + "deprecated", + "openxr", + "retargeters", + "humanoid", + "fourier", + "data", + ) _config_dir = os.path.join(_data_dir, "configs", "dex-retargeting") left_yaml_path = os.path.join(_config_dir, "fourier_hand_left_dexpilot.yml") right_yaml_path = os.path.join(_config_dir, "fourier_hand_right_dexpilot.yml") @@ -401,24 +403,24 @@ class ActionsCfg: # Determines whether Pink IK solver will fail due to a joint limit violation fail_on_joint_limit_violation=False, variable_input_tasks=[ - FrameTask( - "GR1T2_fourier_hand_6dof_left_hand_pitch_link", + FrameTaskCfg( + frame="GR1T2_fourier_hand_6dof_left_hand_pitch_link", position_cost=8.0, # [cost] / [m] orientation_cost=1.0, # [cost] / [rad] lm_damping=12, # dampening for solver for step jumps gain=0.5, ), - FrameTask( - "GR1T2_fourier_hand_6dof_right_hand_pitch_link", + FrameTaskCfg( + frame="GR1T2_fourier_hand_6dof_right_hand_pitch_link", position_cost=8.0, # [cost] / [m] orientation_cost=1.0, # [cost] / [rad] lm_damping=12, # dampening for solver for step jumps gain=0.5, ), - DampingTask( + DampingTaskCfg( cost=0.5, # [cost] * [s] / [rad] ), - NullSpacePostureTask( + NullSpacePostureTaskCfg( cost=0.5, lm_damping=1, controlled_frames=[ @@ -597,27 +599,17 @@ def __post_init__(self): # scene settings self.scene.replicate_physics = False - # Convert USD to URDF and change revolute joints to fixed - temp_urdf_output_path, temp_urdf_meshes_output_path = ControllerUtils.convert_usd_to_urdf( - self.scene.robot.spawn.usd_path, self.temp_urdf_dir, force_conversion=True - ) + # Defer USD→URDF conversion to controller initialization (requires Isaac Sim at runtime). + self.actions.upper_body_ik.controller.usd_path = self.scene.robot.spawn.usd_path + self.actions.upper_body_ik.controller.urdf_output_dir = self.temp_urdf_dir - # Set the URDF and mesh paths for the IK controller - self.actions.upper_body_ik.controller.urdf_path = temp_urdf_output_path - self.actions.upper_body_ik.controller.mesh_path = temp_urdf_meshes_output_path - - # IsaacTeleop-based teleoperation pipeline - # Both are wrapped in lambdas so they survive @configclass deepcopy - # (retargeters contain non-picklable SWIG handles). - if _TELEOP_AVAILABLE: - self.xr = XrCfg( - anchor_pos=(0.0, 0.0, 0.0), - anchor_rot=(0.0, 0.0, 0.0, 1.0), - ) - pipeline, retargeters = _build_gr1t2_pickplace_pipeline() - self.isaac_teleop = IsaacTeleopCfg( - pipeline_builder=lambda: pipeline, - # retargeters_to_tune=lambda: retargeters, - sim_device=self.sim.device, - xr_cfg=self.xr, - ) + # IsaacTeleop-based teleoperation pipeline. + self.xr = XrCfg( + anchor_pos=(0.0, 0.0, 0.0), + anchor_rot=(0.0, 0.0, 0.0, 1.0), + ) + self.isaac_teleop = IsaacTeleopCfg( + pipeline_builder=lambda: _build_gr1t2_pickplace_pipeline()[0], + sim_device=self.sim.device, + xr_cfg=self.xr, + ) diff --git a/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/pickplace_gr1t2_waist_enabled_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/pickplace_gr1t2_waist_enabled_env_cfg.py index ba27679831f..8d247289525 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/pickplace_gr1t2_waist_enabled_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/pickplace_gr1t2_waist_enabled_env_cfg.py @@ -3,20 +3,12 @@ # # SPDX-License-Identifier: BSD-3-Clause -import logging import tempfile -try: - from isaaclab_teleop import IsaacTeleopCfg, XrCfg - - _TELEOP_AVAILABLE = True -except ImportError: - _TELEOP_AVAILABLE = False - logging.getLogger(__name__).warning("isaaclab_teleop is not installed. XR teleoperation features will be disabled.") - -import isaaclab.controllers.utils as ControllerUtils from isaaclab.envs import ManagerBasedRLEnvCfg from isaaclab.utils import configclass +from isaaclab_teleop.isaac_teleop_cfg import IsaacTeleopCfg +from isaaclab_teleop.xr_cfg import XrCfg from .pickplace_gr1t2_env_cfg import ( ActionsCfg, @@ -63,25 +55,17 @@ def __post_init__(self): for joint_name in waist_joint_names: self.actions.upper_body_ik.pink_controlled_joint_names.append(joint_name) - # Convert USD to URDF and change revolute joints to fixed - temp_urdf_output_path, temp_urdf_meshes_output_path = ControllerUtils.convert_usd_to_urdf( - self.scene.robot.spawn.usd_path, self.temp_urdf_dir, force_conversion=True - ) - - # Set the URDF and mesh paths for the IK controller - self.actions.upper_body_ik.controller.urdf_path = temp_urdf_output_path - self.actions.upper_body_ik.controller.mesh_path = temp_urdf_meshes_output_path + # Defer USD→URDF conversion to controller initialization (requires Isaac Sim at runtime). + self.actions.upper_body_ik.controller.usd_path = self.scene.robot.spawn.usd_path + self.actions.upper_body_ik.controller.urdf_output_dir = self.temp_urdf_dir - # IsaacTeleop-based teleoperation pipeline - if _TELEOP_AVAILABLE: - self.xr = XrCfg( - anchor_pos=(0.0, 0.0, 0.0), - anchor_rot=(0.0, 0.0, 0.0, 1.0), - ) - pipeline, retargeters = _build_gr1t2_pickplace_pipeline() - self.isaac_teleop = IsaacTeleopCfg( - pipeline_builder=lambda: pipeline, - # retargeters_to_tune=lambda: retargeters, - sim_device=self.sim.device, - xr_cfg=self.xr, - ) + # IsaacTeleop-based teleoperation pipeline. + self.xr = XrCfg( + anchor_pos=(0.0, 0.0, 0.0), + anchor_rot=(0.0, 0.0, 0.0, 1.0), + ) + self.isaac_teleop = IsaacTeleopCfg( + pipeline_builder=lambda: _build_gr1t2_pickplace_pipeline()[0], + sim_device=self.sim.device, + xr_cfg=self.xr, + ) diff --git a/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/pickplace_unitree_g1_inspire_hand_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/pickplace_unitree_g1_inspire_hand_env_cfg.py index 9f7fb2289fe..4527465d17f 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/pickplace_unitree_g1_inspire_hand_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/pickplace_unitree_g1_inspire_hand_env_cfg.py @@ -2,27 +2,18 @@ # All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause -import logging import os import tempfile import torch -from pink.tasks import FrameTask -try: - import isaacteleop # noqa: F401 -- pipeline builders need isaacteleop at runtime - from isaaclab_teleop import IsaacTeleopCfg, XrCfg +from isaaclab_teleop.isaac_teleop_cfg import IsaacTeleopCfg +from isaaclab_teleop.xr_cfg import XrCfg - _TELEOP_AVAILABLE = True -except ImportError: - _TELEOP_AVAILABLE = False - logging.getLogger(__name__).warning("isaaclab_teleop is not installed. XR teleoperation features will be disabled.") - -import isaaclab.controllers.utils as ControllerUtils import isaaclab.envs.mdp as base_mdp import isaaclab.sim as sim_utils from isaaclab.assets import ArticulationCfg, AssetBaseCfg, RigidObjectCfg -from isaaclab.controllers.pink_ik import NullSpacePostureTask, PinkIKControllerCfg +from isaaclab.controllers.pink_ik import FrameTaskCfg, NullSpacePostureTaskCfg, PinkIKControllerCfg from isaaclab.envs import ManagerBasedRLEnvCfg from isaaclab.envs.mdp.actions.pink_actions_cfg import PinkInverseKinematicsActionCfg from isaaclab.managers import EventTermCfg as EventTerm @@ -406,21 +397,21 @@ class ActionsCfg: show_ik_warnings=False, fail_on_joint_limit_violation=False, variable_input_tasks=[ - FrameTask( - "g1_29dof_rev_1_0_left_wrist_yaw_link", + FrameTaskCfg( + frame="g1_29dof_rev_1_0_left_wrist_yaw_link", position_cost=8.0, # [cost] / [m] orientation_cost=2.0, # [cost] / [rad] lm_damping=10, # dampening for solver for step jumps gain=0.5, ), - FrameTask( - "g1_29dof_rev_1_0_right_wrist_yaw_link", + FrameTaskCfg( + frame="g1_29dof_rev_1_0_right_wrist_yaw_link", position_cost=8.0, # [cost] / [m] orientation_cost=2.0, # [cost] / [rad] lm_damping=10, # dampening for solver for step jumps gain=0.5, ), - NullSpacePostureTask( + NullSpacePostureTaskCfg( cost=0.5, lm_damping=1, controlled_frames=[ @@ -596,24 +587,17 @@ def __post_init__(self): self.sim.dt = 1 / 120 # 120Hz self.sim.render_interval = 2 - # Convert USD to URDF and change revolute joints to fixed - temp_urdf_output_path, temp_urdf_meshes_output_path = ControllerUtils.convert_usd_to_urdf( - self.scene.robot.spawn.usd_path, self.temp_urdf_dir, force_conversion=True - ) + # Defer USD→URDF conversion to controller initialization (requires Isaac Sim at runtime). + self.actions.pink_ik_cfg.controller.usd_path = self.scene.robot.spawn.usd_path + self.actions.pink_ik_cfg.controller.urdf_output_dir = self.temp_urdf_dir - # Set the URDF and mesh paths for the IK controller - self.actions.pink_ik_cfg.controller.urdf_path = temp_urdf_output_path - self.actions.pink_ik_cfg.controller.mesh_path = temp_urdf_meshes_output_path - - # IsaacTeleop-based teleoperation pipeline - if _TELEOP_AVAILABLE: - self.xr = XrCfg( - anchor_pos=(0.0, 0.0, 0.0), - anchor_rot=(0.0, 0.0, 0.0, 1.0), - ) - pipeline = _build_g1_inspire_pickplace_pipeline() - self.isaac_teleop = IsaacTeleopCfg( - pipeline_builder=lambda: pipeline, - sim_device=self.sim.device, - xr_cfg=self.xr, - ) + # IsaacTeleop-based teleoperation pipeline (resolved lazily at runtime). + self.xr = XrCfg( + anchor_pos=(0.0, 0.0, 0.0), + anchor_rot=(0.0, 0.0, 0.0, 1.0), + ) + self.isaac_teleop = IsaacTeleopCfg( + pipeline_builder=_build_g1_inspire_pickplace_pipeline, + sim_device=self.sim.device, + xr_cfg=self.xr, + ) From 0a8e16dd077926ff39fdab83d818cd121be893ae Mon Sep 17 00:00:00 2001 From: Octi Zhang Date: Thu, 26 Feb 2026 01:39:55 -0800 Subject: [PATCH 2/2] pass precommit --- source/isaaclab/isaaclab/controllers/joint_impedance_cfg.py | 1 - .../isaaclab/controllers/pink_ik/local_frame_task.py | 2 -- source/isaaclab/isaaclab/controllers/pink_ik/pink_ik.py | 2 +- source/isaaclab/isaaclab/controllers/pink_ik/pink_ik_cfg.py | 1 + .../isaaclab/isaaclab/controllers/pink_ik/pink_task_cfg.py | 1 - source/isaaclab/isaaclab/controllers/pink_ik/pink_tasks.py | 1 - source/isaaclab/test/controllers/test_local_frame_task.py | 2 +- source/isaaclab/test/controllers/test_pink_ik.py | 4 +++- .../locomanipulation/pick_place/mdp/terminations.py | 4 +--- .../pick_place/exhaustpipe_gr1t2_pink_ik_env_cfg.py | 3 ++- .../manipulation/pick_place/nutpour_gr1t2_pink_ik_env_cfg.py | 3 ++- .../pick_place/pickplace_gr1t2_waist_enabled_env_cfg.py | 5 +++-- .../pick_place/pickplace_unitree_g1_inspire_hand_env_cfg.py | 1 - 13 files changed, 14 insertions(+), 16 deletions(-) diff --git a/source/isaaclab/isaaclab/controllers/joint_impedance_cfg.py b/source/isaaclab/isaaclab/controllers/joint_impedance_cfg.py index 36f157c6f63..8245b0e50ab 100644 --- a/source/isaaclab/isaaclab/controllers/joint_impedance_cfg.py +++ b/source/isaaclab/isaaclab/controllers/joint_impedance_cfg.py @@ -58,4 +58,3 @@ class JointImpedanceControllerCfg: Note: Used only when :obj:`impedance_mode` is "variable". """ - diff --git a/source/isaaclab/isaaclab/controllers/pink_ik/local_frame_task.py b/source/isaaclab/isaaclab/controllers/pink_ik/local_frame_task.py index def3bcb12d2..69413e5dbfd 100644 --- a/source/isaaclab/isaaclab/controllers/pink_ik/local_frame_task.py +++ b/source/isaaclab/isaaclab/controllers/pink_ik/local_frame_task.py @@ -18,5 +18,3 @@ DeprecationWarning, stacklevel=2, ) - -from .pink_tasks import DampingTask, FrameTask, LocalFrameTask diff --git a/source/isaaclab/isaaclab/controllers/pink_ik/pink_ik.py b/source/isaaclab/isaaclab/controllers/pink_ik/pink_ik.py index c7d1022cf8a..c4ef2deaeec 100644 --- a/source/isaaclab/isaaclab/controllers/pink_ik/pink_ik.py +++ b/source/isaaclab/isaaclab/controllers/pink_ik/pink_ik.py @@ -27,8 +27,8 @@ from isaaclab.utils.string import resolve_matching_names_values from .null_space_posture_task import NullSpacePostureTask -from .pink_task_cfg import PinkIKTaskCfg from .pink_kinematics_configuration import PinkKinematicsConfiguration +from .pink_task_cfg import PinkIKTaskCfg if TYPE_CHECKING: from .pink_ik_cfg import PinkIKControllerCfg diff --git a/source/isaaclab/isaaclab/controllers/pink_ik/pink_ik_cfg.py b/source/isaaclab/isaaclab/controllers/pink_ik/pink_ik_cfg.py index 3d37c4d9512..bb0839fcf1b 100644 --- a/source/isaaclab/isaaclab/controllers/pink_ik/pink_ik_cfg.py +++ b/source/isaaclab/isaaclab/controllers/pink_ik/pink_ik_cfg.py @@ -11,6 +11,7 @@ from typing import TYPE_CHECKING from isaaclab.utils import configclass + from .pink_task_cfg import PinkIKTaskCfg if TYPE_CHECKING: diff --git a/source/isaaclab/isaaclab/controllers/pink_ik/pink_task_cfg.py b/source/isaaclab/isaaclab/controllers/pink_ik/pink_task_cfg.py index efcf3a0e914..0955fba6782 100644 --- a/source/isaaclab/isaaclab/controllers/pink_ik/pink_task_cfg.py +++ b/source/isaaclab/isaaclab/controllers/pink_ik/pink_task_cfg.py @@ -64,4 +64,3 @@ class NullSpacePostureTaskCfg(PinkIKTaskCfg): controlled_frames: list[str] = field(default_factory=list) controlled_joints: list[str] = field(default_factory=list) class_type: str | type | None = "isaaclab.controllers.pink_ik.null_space_posture_task:NullSpacePostureTask" - diff --git a/source/isaaclab/isaaclab/controllers/pink_ik/pink_tasks.py b/source/isaaclab/isaaclab/controllers/pink_ik/pink_tasks.py index 84bb60a3a8e..bd653d606d6 100644 --- a/source/isaaclab/isaaclab/controllers/pink_ik/pink_tasks.py +++ b/source/isaaclab/isaaclab/controllers/pink_ik/pink_tasks.py @@ -120,4 +120,3 @@ def compute_jacobian(self, configuration: PinkKinematicsConfiguration) -> np.nda jacobian_in_frame = configuration.get_frame_jacobian(self.frame) J = -pin.Jlog6(transform_frame_to_target) @ jacobian_in_frame return J - diff --git a/source/isaaclab/test/controllers/test_local_frame_task.py b/source/isaaclab/test/controllers/test_local_frame_task.py index 5e7304d9372..e3ebec56c27 100644 --- a/source/isaaclab/test/controllers/test_local_frame_task.py +++ b/source/isaaclab/test/controllers/test_local_frame_task.py @@ -16,8 +16,8 @@ import pinocchio as pin import pytest -from isaaclab.controllers.pink_ik.pink_tasks import LocalFrameTask from isaaclab.controllers.pink_ik.pink_kinematics_configuration import PinkKinematicsConfiguration +from isaaclab.controllers.pink_ik.pink_tasks import LocalFrameTask # class TestLocalFrameTask: # """Test suite for LocalFrameTask class.""" diff --git a/source/isaaclab/test/controllers/test_pink_ik.py b/source/isaaclab/test/controllers/test_pink_ik.py index c42b9b63f59..9913c76f7dc 100644 --- a/source/isaaclab/test/controllers/test_pink_ik.py +++ b/source/isaaclab/test/controllers/test_pink_ik.py @@ -96,7 +96,9 @@ def env_and_cfg(request): # Read instantiated task objects from the live action term/controller, not raw cfg wrappers. action_term = env.action_manager.get_term(name="upper_body_ik") - variable_input_tasks = [task for task in action_term._ik_controllers[0].cfg.variable_input_tasks if isinstance(task, FrameTask)] + variable_input_tasks = [ + task for task in action_term._ik_controllers[0].cfg.variable_input_tasks if isinstance(task, FrameTask) + ] assert len(variable_input_tasks) == 2, "Expected exactly two FrameTasks (left and right hand)." frames = [task.frame for task in variable_input_tasks] # Try to infer which is left and which is right diff --git a/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomanipulation/pick_place/mdp/terminations.py b/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomanipulation/pick_place/mdp/terminations.py index ebdf0c25f61..ec42385377c 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomanipulation/pick_place/mdp/terminations.py +++ b/source/isaaclab_tasks/isaaclab_tasks/manager_based/locomanipulation/pick_place/mdp/terminations.py @@ -71,9 +71,7 @@ def task_done_pick_place_table_frame( table = env.scene[table_cfg.name] # Avoid importing sim views at module-load time for pure cfg loading. if not hasattr(table, "get_world_poses"): - raise TypeError( - f"Expected table '{table_cfg.name}' to expose get_world_poses(), got {type(table)}" - ) + raise TypeError(f"Expected table '{table_cfg.name}' to expose get_world_poses(), got {type(table)}") # Get table world pose table_pos_w, table_quat_w = table.get_world_poses() diff --git a/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/exhaustpipe_gr1t2_pink_ik_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/exhaustpipe_gr1t2_pink_ik_env_cfg.py index 163da35de93..3dd523de27f 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/exhaustpipe_gr1t2_pink_ik_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/exhaustpipe_gr1t2_pink_ik_env_cfg.py @@ -3,10 +3,11 @@ # # SPDX-License-Identifier: BSD-3-Clause +from isaaclab_teleop.isaac_teleop_cfg import IsaacTeleopCfg + from isaaclab.controllers.pink_ik import DampingTaskCfg, FrameTaskCfg, NullSpacePostureTaskCfg, PinkIKControllerCfg from isaaclab.envs.mdp.actions.pink_actions_cfg import PinkInverseKinematicsActionCfg from isaaclab.utils import configclass -from isaaclab_teleop.isaac_teleop_cfg import IsaacTeleopCfg from isaaclab_tasks.manager_based.manipulation.pick_place.exhaustpipe_gr1t2_base_env_cfg import ( ExhaustPipeGR1T2BaseEnvCfg, diff --git a/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/nutpour_gr1t2_pink_ik_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/nutpour_gr1t2_pink_ik_env_cfg.py index 98d7ce2d936..db242eee50a 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/nutpour_gr1t2_pink_ik_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/nutpour_gr1t2_pink_ik_env_cfg.py @@ -3,10 +3,11 @@ # # SPDX-License-Identifier: BSD-3-Clause +from isaaclab_teleop.isaac_teleop_cfg import IsaacTeleopCfg + from isaaclab.controllers.pink_ik import DampingTaskCfg, FrameTaskCfg, NullSpacePostureTaskCfg, PinkIKControllerCfg from isaaclab.envs.mdp.actions.pink_actions_cfg import PinkInverseKinematicsActionCfg from isaaclab.utils import configclass -from isaaclab_teleop.isaac_teleop_cfg import IsaacTeleopCfg from isaaclab_tasks.manager_based.manipulation.pick_place.nutpour_gr1t2_base_env_cfg import NutPourGR1T2BaseEnvCfg from isaaclab_tasks.manager_based.manipulation.pick_place.pickplace_gr1t2_env_cfg import ( diff --git a/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/pickplace_gr1t2_waist_enabled_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/pickplace_gr1t2_waist_enabled_env_cfg.py index 8d247289525..1c9f19bb302 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/pickplace_gr1t2_waist_enabled_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/pickplace_gr1t2_waist_enabled_env_cfg.py @@ -5,11 +5,12 @@ import tempfile -from isaaclab.envs import ManagerBasedRLEnvCfg -from isaaclab.utils import configclass from isaaclab_teleop.isaac_teleop_cfg import IsaacTeleopCfg from isaaclab_teleop.xr_cfg import XrCfg +from isaaclab.envs import ManagerBasedRLEnvCfg +from isaaclab.utils import configclass + from .pickplace_gr1t2_env_cfg import ( ActionsCfg, EventCfg, diff --git a/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/pickplace_unitree_g1_inspire_hand_env_cfg.py b/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/pickplace_unitree_g1_inspire_hand_env_cfg.py index 4527465d17f..6622f8c21c3 100644 --- a/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/pickplace_unitree_g1_inspire_hand_env_cfg.py +++ b/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/pickplace_unitree_g1_inspire_hand_env_cfg.py @@ -6,7 +6,6 @@ import tempfile import torch - from isaaclab_teleop.isaac_teleop_cfg import IsaacTeleopCfg from isaaclab_teleop.xr_cfg import XrCfg