Unverified Commit fe976d76 authored by Özhan Özen's avatar Özhan Özen Committed by GitHub

Adds `OperationSpaceController` to docs and tests and implement corresponding...

Adds `OperationSpaceController` to docs and tests and implement corresponding action/action_cfg classes (#913)

# Description

This PR adds the `OperationalSpaceController` to the docs and provides
some tests for its parametric features. Moreover, it implements the
corresponding `OperationalSpaceControllerAction` and
`OperationalSpaceControllerActionCfg` classes so they can be used with
manager-based environments.

Fixes #873 

## Type of change

- Bug fix (non-breaking change which fixes an issue)
- New feature (non-breaking change which adds functionality)
- This change requires a documentation update

## Checklist

- [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with
`./isaaclab.sh --format`
- [x] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] I have updated the changelog and the corresponding version in the
extension's `config/extension.toml` file
- [x] I have added my name to the `CONTRIBUTORS.md` or my name already
exists there
``

---------
Signed-off-by: 's avatarÖzhan Özen <41010165+ozhanozen@users.noreply.github.com>
Co-authored-by: 's avatarJames Tigue <jtigue@theaiinstitute.com>
Co-authored-by: 's avatarjtigue-bdai <166445701+jtigue-bdai@users.noreply.github.com>
Co-authored-by: 's avatarKelly Guo <kellyguo123@hotmail.com>
parent b6a77298
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
DifferentialIKController DifferentialIKController
DifferentialIKControllerCfg DifferentialIKControllerCfg
OperationalSpaceController
OperationalSpaceControllerCfg
Differential Inverse Kinematics Differential Inverse Kinematics
------------------------------- -------------------------------
...@@ -23,3 +25,17 @@ Differential Inverse Kinematics ...@@ -23,3 +25,17 @@ Differential Inverse Kinematics
:inherited-members: :inherited-members:
:show-inheritance: :show-inheritance:
:exclude-members: __init__, class_type :exclude-members: __init__, class_type
Operational Space controllers
-----------------------------
.. autoclass:: OperationalSpaceController
:members:
:inherited-members:
:show-inheritance:
.. autoclass:: OperationalSpaceControllerCfg
:members:
:inherited-members:
:show-inheritance:
:exclude-members: __init__, class_type
...@@ -91,7 +91,7 @@ Manipulation ...@@ -91,7 +91,7 @@ Manipulation
Environments based on fixed-arm manipulation tasks. Environments based on fixed-arm manipulation tasks.
For many of these tasks, we include configurations with different arm action spaces. For example, For many of these tasks, we include configurations with different arm action spaces. For example,
for the reach environment: for the lift-cube environment:
* |lift-cube-link|: Franka arm with joint position control * |lift-cube-link|: Franka arm with joint position control
* |lift-cube-ik-abs-link|: Franka arm with absolute IK control * |lift-cube-ik-abs-link|: Franka arm with absolute IK control
...@@ -421,6 +421,10 @@ Comprehensive List of Environments ...@@ -421,6 +421,10 @@ Comprehensive List of Environments
- -
- Manager Based - Manager Based
- -
* - Isaac-Reach-Franka-OSC-v0
- Isaac-Reach-Franka-OSC-Play-v0
- Manager Based
- **rsl_rl** (PPO)
* - Isaac-Reach-Franka-v0 * - Isaac-Reach-Franka-v0
- Isaac-Reach-Franka-Play-v0 - Isaac-Reach-Franka-Play-v0
- Manager Based - Manager Based
......
This diff is collapsed.
...@@ -101,3 +101,4 @@ tutorials show you how to use motion generators to control the robots at the tas ...@@ -101,3 +101,4 @@ tutorials show you how to use motion generators to control the robots at the tas
:titlesonly: :titlesonly:
05_controllers/run_diff_ik 05_controllers/run_diff_ik
05_controllers/run_osc
[package] [package]
# Note: Semantic Versioning is used: https://semver.org/ # Note: Semantic Versioning is used: https://semver.org/
version = "0.29.1" version = "0.29.2"
# Description # Description
title = "Isaac Lab framework for Robot Learning" title = "Isaac Lab framework for Robot Learning"
......
Changelog Changelog
--------- ---------
0.29.2 (2024-12-16)
~~~~~~~~~~~~~~~~~~~
Fixed
^^^^^
* Fixed errors within the calculations of :class:`omni.isaac.lab.controllers.OperationalSpaceController`.
Added
^^^^^
* Added :class:`omni.isaac.lab.controllers.OperationalSpaceController` to API documentation.
* Added test cases for :class:`omni.isaac.lab.controllers.OperationalSpaceController`.
* Added a tutorial for :class:`omni.isaac.lab.controllers.OperationalSpaceController`.
* Added the implementation of :class:`omni.isaac.lab.envs.mdp.actions.OperationalSpaceControllerAction` class.
0.29.1 (2024-12-15) 0.29.1 (2024-12-15)
~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~
......
...@@ -13,3 +13,5 @@ commands to be sent to the robot. ...@@ -13,3 +13,5 @@ commands to be sent to the robot.
from .differential_ik import DifferentialIKController from .differential_ik import DifferentialIKController
from .differential_ik_cfg import DifferentialIKControllerCfg from .differential_ik_cfg import DifferentialIKControllerCfg
from .operational_space import OperationalSpaceController
from .operational_space_cfg import OperationalSpaceControllerCfg
# Copyright (c) 2022-2024, The Isaac Lab Project Developers.
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
from collections.abc import Sequence
from dataclasses import MISSING
from omni.isaac.lab.utils import configclass
from .operational_space import OperationalSpaceController
@configclass
class OperationalSpaceControllerCfg:
"""Configuration for operational-space controller."""
class_type: type = OperationalSpaceController
"""The associated controller class."""
target_types: Sequence[str] = MISSING
"""Type of task-space targets.
It has two sub-strings joined by underscore:
- type of task-space target: ``"pose"``, ``"wrench"``
- reference for the task-space targets: ``"abs"`` (absolute), ``"rel"`` (relative, only for pose)
"""
motion_control_axes_task: Sequence[int] = (1, 1, 1, 1, 1, 1)
"""Motion direction to control in task reference frame. Mark as ``0/1`` for each axis."""
contact_wrench_control_axes_task: Sequence[int] = (0, 0, 0, 0, 0, 0)
"""Contact wrench direction to control in task reference frame. Mark as 0/1 for each axis."""
inertial_dynamics_decoupling: bool = False
"""Whether to perform inertial dynamics decoupling for motion control (inverse dynamics)."""
partial_inertial_dynamics_decoupling: bool = False
"""Whether to ignore the inertial coupling between the translational & rotational motions."""
gravity_compensation: bool = False
"""Whether to perform gravity compensation."""
impedance_mode: str = "fixed"
"""Type of gains for motion control: ``"fixed"``, ``"variable"``, ``"variable_kp"``."""
motion_stiffness_task: float | Sequence[float] = (100.0, 100.0, 100.0, 100.0, 100.0, 100.0)
"""The positional gain for determining operational space command forces based on task-space pose error."""
motion_damping_ratio_task: float | Sequence[float] = (1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
"""The damping ratio is used in-conjunction with positional gain to compute operational space command forces
based on task-space velocity error.
The following math operation is performed for computing velocity gains:
:math:`d_gains = 2 * sqrt(p_gains) * damping_ratio`.
"""
motion_stiffness_limits_task: tuple[float, float] = (0, 1000)
"""Minimum and maximum values for positional gains.
Note: Used only when :obj:`impedance_mode` is ``"variable"`` or ``"variable_kp"``.
"""
motion_damping_ratio_limits_task: 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"``.
"""
contact_wrench_stiffness_task: float | Sequence[float] | None = None
"""The proportional gain for determining operational space command forces for closed-loop contact force control.
If ``None``, then open-loop control of desired contact wrench is performed.
Note: since only the linear forces could be measured at the moment,
only the first three elements are used for the feedback loop.
"""
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
from dataclasses import MISSING from dataclasses import MISSING
from omni.isaac.lab.controllers import DifferentialIKControllerCfg from omni.isaac.lab.controllers import DifferentialIKControllerCfg, OperationalSpaceControllerCfg
from omni.isaac.lab.managers.action_manager import ActionTerm, ActionTermCfg from omni.isaac.lab.managers.action_manager import ActionTerm, ActionTermCfg
from omni.isaac.lab.utils import configclass from omni.isaac.lab.utils import configclass
...@@ -248,3 +248,58 @@ class DifferentialInverseKinematicsActionCfg(ActionTermCfg): ...@@ -248,3 +248,58 @@ class DifferentialInverseKinematicsActionCfg(ActionTermCfg):
"""Scale factor for the action. Defaults to 1.0.""" """Scale factor for the action. Defaults to 1.0."""
controller: DifferentialIKControllerCfg = MISSING controller: DifferentialIKControllerCfg = MISSING
"""The configuration for the differential IK controller.""" """The configuration for the differential IK controller."""
@configclass
class OperationalSpaceControllerActionCfg(ActionTermCfg):
"""Configuration for operational space controller action term.
See :class:`OperationalSpaceControllerAction` for more details.
"""
@configclass
class OffsetCfg:
"""The offset pose from parent frame to child frame.
On many robots, end-effector frames are fictitious frames that do not have a corresponding
rigid body. In such cases, it is easier to define this transform w.r.t. their parent rigid body.
For instance, for the Franka Emika arm, the end-effector is defined at an offset to the the
"panda_hand" frame.
"""
pos: tuple[float, float, float] = (0.0, 0.0, 0.0)
"""Translation w.r.t. the parent frame. Defaults to (0.0, 0.0, 0.0)."""
rot: tuple[float, float, float, float] = (1.0, 0.0, 0.0, 0.0)
"""Quaternion rotation ``(w, x, y, z)`` w.r.t. the parent frame. Defaults to (1.0, 0.0, 0.0, 0.0)."""
class_type: type[ActionTerm] = task_space_actions.OperationalSpaceControllerAction
joint_names: list[str] = MISSING
"""List of joint names or regex expressions that the action will be mapped to."""
body_name: str = MISSING
"""Name of the body or frame for which motion/force control is performed."""
body_offset: OffsetCfg | None = None
"""Offset of target frame w.r.t. to the body frame. Defaults to None, in which case no offset is applied."""
task_frame_rel_path: str = None
"""The path of a ``RigidObject``, relative to the sub-environment, representing task frame. Defaults to None."""
controller_cfg: OperationalSpaceControllerCfg = MISSING
"""The configuration for the operational space controller."""
position_scale: float = 1.0
"""Scale factor for the position targets. Defaults to 1.0."""
orientation_scale: float = 1.0
"""Scale factor for the orientation (quad for ``pose_abs`` or axis-angle for ``pose_rel``). Defaults to 1.0."""
wrench_scale: float = 1.0
"""Scale factor for the wrench targets. Defaults to 1.0."""
stiffness_scale: float = 1.0
"""Scale factor for the stiffness commands. Defaults to 1.0."""
damping_ratio_scale: float = 1.0
"""Scale factor for the damping ratio commands. Defaults to 1.0."""
[package] [package]
# Note: Semantic Versioning is used: https://semver.org/ # Note: Semantic Versioning is used: https://semver.org/
version = "0.10.14" version = "0.10.15"
# Description # Description
title = "Isaac Lab Environments" title = "Isaac Lab Environments"
......
Changelog Changelog
--------- ---------
0.10.15 (2024-12-16)
~~~~~~~~~~~~~~~~~~~~
Added
^^^^^
* Added ``Isaac-Reach-Franka-OSC-v0`` and ``Isaac-Reach-Franka-OSC-Play-v0``
variations of the manager based reach environment that uses
:class:`omni.isaac.lab.envs.mdp.actions.OperationalSpaceControllerAction`.
0.10.14 (2024-12-03) 0.10.14 (2024-12-03)
~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~
......
...@@ -65,3 +65,27 @@ gym.register( ...@@ -65,3 +65,27 @@ gym.register(
}, },
disable_env_checker=True, disable_env_checker=True,
) )
##
# Operational Space Control
##
gym.register(
id="Isaac-Reach-Franka-OSC-v0",
entry_point="omni.isaac.lab.envs:ManagerBasedRLEnv",
disable_env_checker=True,
kwargs={
"env_cfg_entry_point": f"{__name__}.osc_env_cfg:FrankaReachEnvCfg",
"rsl_rl_cfg_entry_point": f"{agents.__name__}.rsl_rl_ppo_cfg:FrankaReachPPORunnerCfg",
},
)
gym.register(
id="Isaac-Reach-Franka-OSC-Play-v0",
entry_point="omni.isaac.lab.envs:ManagerBasedRLEnv",
disable_env_checker=True,
kwargs={
"env_cfg_entry_point": f"{__name__}.osc_env_cfg:FrankaReachEnvCfg_PLAY",
"rsl_rl_cfg_entry_point": f"{agents.__name__}.rsl_rl_ppo_cfg:FrankaReachPPORunnerCfg",
},
)
# Copyright (c) 2022-2024, The Isaac Lab Project Developers.
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
from omni.isaac.lab.controllers.operational_space_cfg import OperationalSpaceControllerCfg
from omni.isaac.lab.envs.mdp.actions.actions_cfg import OperationalSpaceControllerActionCfg
from omni.isaac.lab.utils import configclass
from . import joint_pos_env_cfg
##
# Pre-defined configs
##
from omni.isaac.lab_assets.franka import FRANKA_PANDA_CFG # isort: skip
@configclass
class FrankaReachEnvCfg(joint_pos_env_cfg.FrankaReachEnvCfg):
def __post_init__(self):
# post init of parent
super().__post_init__()
# Set Franka as robot
# We remove stiffness and damping for the shoulder and forearm joints for effort control
self.scene.robot = FRANKA_PANDA_CFG.replace(prim_path="{ENV_REGEX_NS}/Robot")
self.scene.robot.actuators["panda_shoulder"].stiffness = 0.0
self.scene.robot.actuators["panda_shoulder"].damping = 0.0
self.scene.robot.actuators["panda_forearm"].stiffness = 0.0
self.scene.robot.actuators["panda_forearm"].damping = 0.0
self.scene.robot.spawn.rigid_props.disable_gravity = True
# If closed-loop contact force control is desired, contact sensors should be enabled for the robot
# self.scene.robot.spawn.activate_contact_sensors = True
self.actions.arm_action = OperationalSpaceControllerActionCfg(
asset_name="robot",
joint_names=["panda_joint.*"],
body_name="panda_hand",
# If a task frame different from articulation root/base is desired, a RigidObject, e.g., "task_frame",
# can be added to the scene and its relative path could provided as task_frame_rel_path
# task_frame_rel_path="task_frame",
controller_cfg=OperationalSpaceControllerCfg(
target_types=["pose_abs"],
impedance_mode="variable_kp",
inertial_dynamics_decoupling=True,
partial_inertial_dynamics_decoupling=False,
gravity_compensation=False,
motion_stiffness_task=100.0,
motion_damping_ratio_task=1.0,
motion_stiffness_limits_task=(50.0, 200.0),
),
position_scale=1.0,
orientation_scale=1.0,
stiffness_scale=100.0,
)
# Removing these observations as they are not needed for OSC and we want keep the observation space small
self.observations.policy.joint_pos = None
self.observations.policy.joint_vel = None
@configclass
class FrankaReachEnvCfg_PLAY(FrankaReachEnvCfg):
def __post_init__(self):
# post init of parent
super().__post_init__()
# make a smaller scene for play
self.scene.num_envs = 16
self.scene.env_spacing = 2.5
# disable randomization for play
self.observations.policy.enable_corruption = False
This diff is collapsed.
...@@ -18,4 +18,5 @@ PER_TEST_TIMEOUTS = { ...@@ -18,4 +18,5 @@ PER_TEST_TIMEOUTS = {
"test_rsl_rl_wrapper.py": 200, "test_rsl_rl_wrapper.py": 200,
"test_sb3_wrapper.py": 200, "test_sb3_wrapper.py": 200,
"test_skrl_wrapper.py": 200, "test_skrl_wrapper.py": 200,
"test_operational_space.py": 200,
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment