Skip to content

Commit fe976d7

Browse files
ozhanozenjtigue-bdaikellyguo11
authored
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: Özhan Özen <41010165+ozhanozen@users.noreply.github.com> Co-authored-by: James Tigue <jtigue@theaiinstitute.com> Co-authored-by: jtigue-bdai <166445701+jtigue-bdai@users.noreply.github.com> Co-authored-by: Kelly Guo <kellyguo123@hotmail.com>
1 parent b6a7729 commit fe976d7

File tree

19 files changed

+2599
-253
lines changed

19 files changed

+2599
-253
lines changed
Loading

docs/source/api/lab/omni.isaac.lab.controllers.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
DifferentialIKController
1111
DifferentialIKControllerCfg
12+
OperationalSpaceController
13+
OperationalSpaceControllerCfg
1214

1315
Differential Inverse Kinematics
1416
-------------------------------
@@ -23,3 +25,17 @@ Differential Inverse Kinematics
2325
:inherited-members:
2426
:show-inheritance:
2527
:exclude-members: __init__, class_type
28+
29+
Operational Space controllers
30+
-----------------------------
31+
32+
.. autoclass:: OperationalSpaceController
33+
:members:
34+
:inherited-members:
35+
:show-inheritance:
36+
37+
.. autoclass:: OperationalSpaceControllerCfg
38+
:members:
39+
:inherited-members:
40+
:show-inheritance:
41+
:exclude-members: __init__, class_type

docs/source/overview/environments.rst

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ Manipulation
9191
Environments based on fixed-arm manipulation tasks.
9292

9393
For many of these tasks, we include configurations with different arm action spaces. For example,
94-
for the reach environment:
94+
for the lift-cube environment:
9595

9696
* |lift-cube-link|: Franka arm with joint position control
9797
* |lift-cube-ik-abs-link|: Franka arm with absolute IK control
@@ -421,6 +421,10 @@ Comprehensive List of Environments
421421
-
422422
- Manager Based
423423
-
424+
* - Isaac-Reach-Franka-OSC-v0
425+
- Isaac-Reach-Franka-OSC-Play-v0
426+
- Manager Based
427+
- **rsl_rl** (PPO)
424428
* - Isaac-Reach-Franka-v0
425429
- Isaac-Reach-Franka-Play-v0
426430
- Manager Based
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
Using an operational space controller
2+
=====================================
3+
4+
.. currentmodule:: omni.isaac.lab
5+
6+
Sometimes, controlling the end-effector pose of the robot using a differential IK controller is not sufficient.
7+
For example, we might want to enforce a very specific pose tracking error dynamics in the task space, actuate the robot
8+
with joint effort/torque commands, or apply a contact force at a specific direction while controlling the motion of
9+
the other directions (e.g., washing the surface of the table with a cloth). In such tasks, we can use an
10+
operational space controller (OSC).
11+
12+
.. rubric:: References for the operational space control:
13+
14+
1. O Khatib. A unified approach for motion and force control of robot manipulators:
15+
The operational space formulation. IEEE Journal of Robotics and Automation, 3(1):43–53, 1987. URL http://dx.doi.org/10.1109/JRA.1987.1087068.
16+
17+
2. Robot Dynamics Lecture Notes by Marco Hutter (ETH Zurich). URL https://ethz.ch/content/dam/ethz/special-interest/mavt/robotics-n-intelligent-systems/rsl-dam/documents/RobotDynamics2017/RD_HS2017script.pdf
18+
19+
In this tutorial, we will learn how to use an OSC to control the robot.
20+
We will use the :class:`controllers.OperationalSpaceController` class to apply a constant force perpendicular to a
21+
tilted wall surface while tracking a desired end-effector pose in all the other directions.
22+
23+
The Code
24+
~~~~~~~~
25+
26+
The tutorial corresponds to the ``run_osc.py`` script in the
27+
``source/standalone/tutorials/05_controllers`` directory.
28+
29+
30+
.. dropdown:: Code for run_osc.py
31+
:icon: code
32+
33+
.. literalinclude:: ../../../../source/standalone/tutorials/05_controllers/run_osc.py
34+
:language: python
35+
:linenos:
36+
37+
38+
Creating an Operational Space Controller
39+
----------------------------------------
40+
41+
The :class:`~controllers.OperationalSpaceController` class computes the joint
42+
efforts/torques for a robot to do simultaneous motion and force control in task space.
43+
44+
The reference frame of this task space could be an arbitrary coordinate frame in Euclidean space. By default,
45+
it is the robot's base frame. However, in certain cases, it could be easier to define target coordinates w.r.t. a
46+
different frame. In such cases, the pose of this task reference frame, w.r.t. to the robot's base frame, should be
47+
provided in the ``set_command`` method's ``current_task_frame_pose_b`` argument. For example, in this tutorial, it
48+
makes sense to define the target commands w.r.t. a frame that is parallel to the wall surface, as the force control
49+
direction would be then only nonzero in the z-axis of this frame. The target pose, which is set to have the same
50+
orientation as the wall surface, is such a candidate and is used as the task frame in this tutorial. Therefore, all
51+
the arguments to the :class:`~controllers.OperationalSpaceControllerCfg` should be set with this task reference frame
52+
in mind.
53+
54+
For the motion control, the task space targets could be given as absolute (i.e., defined w.r.t. the robot base,
55+
``target_types: "pose_abs"``) or relative the the end-effector's current pose (i.e., ``target_types: "pose_rel"``).
56+
For the force control, the task space targets could be given as absolute (i.e., defined w.r.t. the robot base,
57+
``target_types: "force_abs"``). If it is desired to apply pose and force control simultaneously, the ``target_types``
58+
should be a list such as ``["pose_abs", "wrench_abs"]`` or ``["pose_rel", "wrench_abs"]``.
59+
60+
The axes that the motion and force control will be applied can be specified using the ``motion_control_axes_task`` and
61+
``force_control_axes_task`` arguments, respectively. These lists should consist of 0/1 for all six axes (position and
62+
rotation) and be complementary to each other (e.g., for the x-axis, if the ``motion_control_axes_task`` is ``0``, the
63+
``force_control_axes_task`` should be ``1``).
64+
65+
For the motion control axes, desired stiffness, and damping ratio values can be specified using the
66+
``motion_control_stiffness`` and ``motion_damping_ratio_task`` arguments, which can be a scalar (same value for all
67+
axes) or a list of six scalars, one value corresponding to each axis. If desired, the stiffness and damping ratio
68+
values could be a command parameter (e.g., to learn the values using RL or change them on the go). For this,
69+
``impedance_mode`` should be either ``"variable_kp"`` to include the stiffness values within the command or
70+
``"variable"`` to include both the stiffness and damping ratio values. In these cases, ``motion_stiffness_limits_task``
71+
and ``motion_damping_limits_task`` should be set as well, which puts bounds on the stiffness and damping ratio values.
72+
73+
For contact force control, it is possible to apply an open-loop force control by not setting the
74+
``contact_wrench_stiffness_task``, or apply a closed-loop force control (with the feed-forward term) by setting
75+
the desired stiffness values using the ``contact_wrench_stiffness_task`` argument, which can be a scalar or a list
76+
of six scalars. Please note that, currently, only the linear part of the contact wrench (hence the first three
77+
elements of the ``contact_wrench_stiffness_task``) is considered in the closed-loop control, as the rotational part
78+
cannot be measured with the contact sensors.
79+
80+
For the motion control, ``inertial_dynamics_decoupling`` should be set to ``True`` to use the robot's inertia matrix
81+
to decouple the desired accelerations in the task space. This is important for the motion control to be accurate,
82+
especially for rapid movements. This inertial decoupling accounts for the coupling between all the six motion axes.
83+
If desired, the inertial coupling between the translational and rotational axes could be ignored by setting the
84+
``partial_inertial_dynamics_decoupling`` to ``True``.
85+
86+
If it is desired to include the gravity compensation in the operational space command, the ``gravity_compensation``
87+
should be set to ``True``.
88+
89+
The included OSC implementation performs the computation in a batched format and uses PyTorch operations.
90+
91+
In this tutorial, we will use ``"pose_abs"`` for controlling the motion in all axes except the z-axis and
92+
``"wrench_abs"`` for controlling the force in the z-axis. Moreover, we will include the full inertia decoupling in
93+
the motion control and not include the gravity compensation, as the gravity is disabled from the robot configuration.
94+
Finally, we set the impedance mode to ``"variable_kp"`` to dynamically change the stiffness values
95+
(``motion_damping_ratio_task`` is set to ``1``: the kd values adapt according to kp values to maintain a critically
96+
damped response).
97+
98+
.. literalinclude:: ../../../../source/standalone/tutorials/05_controllers/run_osc.py
99+
:language: python
100+
:start-at: # Create the OSC
101+
:end-at: osc = OperationalSpaceController(osc_cfg, num_envs=scene.num_envs, device=sim.device)
102+
103+
Updating the states of the robot
104+
--------------------------------------------
105+
106+
The OSC implementation is a computation-only class. Thus, it expects the user to provide the necessary information
107+
about the robot. This includes the robot's Jacobian matrix, mass/inertia matrix, end-effector pose, velocity, and
108+
contact force, all in the root frame. Moreover, the user should provide gravity compensation vector, if desired.
109+
110+
.. literalinclude:: ../../../../source/standalone/tutorials/05_controllers/run_osc.py
111+
:language: python
112+
:start-at: # Update robot states
113+
:end-before: return jacobian_b, mass_matrix, gravity, ee_pose_b, ee_vel_b, root_pose_w, ee_pose_w, ee_force_b
114+
115+
116+
Computing robot command
117+
-----------------------
118+
119+
The OSC separates the operation of setting the desired command and computing the desired joint positions.
120+
To set the desired command, the user should provide command vector, which includes the target commands
121+
(i.e., in the order they appear in the ``target_types`` argument of the OSC configuration),
122+
and the desired stiffness and damping ratio values if the impedance_mode is set to ``"variable_kp"`` or ``"variable"``.
123+
They should be all in the same coordinate frame as the task frame (e.g., indicated with ``_task`` subscript) and
124+
concatanated together.
125+
126+
In this tutorial, the desired wrench is already defined w.r.t. the task frame, and the desired pose is transformed
127+
to the task frame as the following:
128+
129+
.. literalinclude:: ../../../../source/standalone/tutorials/05_controllers/run_osc.py
130+
:language: python
131+
:start-at: # Convert the target commands to the task frame
132+
:end-at: return command, task_frame_pose_b
133+
134+
The OSC command is set with the command vector in the task frame, the end-effector pose in the base frame, and the
135+
task (reference) frame pose in the base frame as the following. This information is needed, as the internal
136+
computations are done in the base frame.
137+
138+
.. literalinclude:: ../../../../source/standalone/tutorials/05_controllers/run_osc.py
139+
:language: python
140+
:start-at: # set the osc command
141+
:end-at: osc.set_command(command=command, current_ee_pose_b=ee_pose_b, current_task_frame_pose_b=task_frame_pose_b)
142+
143+
The joint effort/torque values are computed using the provided robot states and the desired command as the following:
144+
145+
.. literalinclude:: ../../../../source/standalone/tutorials/05_controllers/run_osc.py
146+
:language: python
147+
:start-at: # compute the joint commands
148+
:end-at: )
149+
150+
151+
The computed joint effort/torque targets can then be applied on the robot.
152+
153+
.. literalinclude:: ../../../../source/standalone/tutorials/05_controllers/run_osc.py
154+
:language: python
155+
:start-at: # apply actions
156+
:end-at: robot.write_data_to_sim()
157+
158+
159+
The Code Execution
160+
~~~~~~~~~~~~~~~~~~
161+
162+
You can now run the script and see the result:
163+
164+
.. code-block:: bash
165+
166+
./isaaclab.sh -p source/standalone/tutorials/05_controllers/run_osc.py --num_envs 128
167+
168+
The script will start a simulation with 128 robots. The robots will be controlled using the OSC.
169+
The current and desired end-effector poses should be displayed using frame markers in addition to the red tilted wall.
170+
You should see that the robot reaches the desired pose while applying a constant force perpendicular to the wall
171+
surface.
172+
173+
.. figure:: ../../_static/tutorials/tutorial_operational_space_controller.jpg
174+
:align: center
175+
:figwidth: 100%
176+
:alt: result of run_osc.py
177+
178+
To stop the simulation, you can either close the window or press ``Ctrl+C`` in the terminal.

docs/source/tutorials/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,3 +101,4 @@ tutorials show you how to use motion generators to control the robots at the tas
101101
:titlesonly:
102102

103103
05_controllers/run_diff_ik
104+
05_controllers/run_osc

source/extensions/omni.isaac.lab/config/extension.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22

33
# Note: Semantic Versioning is used: https://semver.org/
4-
version = "0.29.1"
4+
version = "0.29.2"
55

66
# Description
77
title = "Isaac Lab framework for Robot Learning"

source/extensions/omni.isaac.lab/docs/CHANGELOG.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,23 @@
11
Changelog
22
---------
33

4+
0.29.2 (2024-12-16)
5+
~~~~~~~~~~~~~~~~~~~
6+
7+
Fixed
8+
^^^^^
9+
10+
* Fixed errors within the calculations of :class:`omni.isaac.lab.controllers.OperationalSpaceController`.
11+
12+
Added
13+
^^^^^
14+
15+
* Added :class:`omni.isaac.lab.controllers.OperationalSpaceController` to API documentation.
16+
* Added test cases for :class:`omni.isaac.lab.controllers.OperationalSpaceController`.
17+
* Added a tutorial for :class:`omni.isaac.lab.controllers.OperationalSpaceController`.
18+
* Added the implementation of :class:`omni.isaac.lab.envs.mdp.actions.OperationalSpaceControllerAction` class.
19+
20+
421
0.29.1 (2024-12-15)
522
~~~~~~~~~~~~~~~~~~~
623

source/extensions/omni.isaac.lab/omni/isaac/lab/controllers/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,5 @@
1313

1414
from .differential_ik import DifferentialIKController
1515
from .differential_ik_cfg import DifferentialIKControllerCfg
16+
from .operational_space import OperationalSpaceController
17+
from .operational_space_cfg import OperationalSpaceControllerCfg

0 commit comments

Comments
 (0)