124 lines
4.6 KiB
ReStructuredText
124 lines
4.6 KiB
ReStructuredText
.. _commands:
|
|||
|
|
|
||
|
|
Commands
|
||
|
|
========
|
||
|
|
|
||
|
|
Commands specify what the policy should achieve at each moment: a target
|
||
|
|
velocity, a reference trajectory, a goal position. The command manager
|
||
|
|
generates these signals, resamples them at configurable intervals, and
|
||
|
|
passes them to the policy through the observation system.
|
||
|
|
|
||
|
|
|
||
|
|
Registration
|
||
|
|
------------
|
||
|
|
|
||
|
|
Commands are registered in ``ManagerBasedRlEnvCfg`` as a dictionary
|
||
|
|
mapping string names to ``CommandTermCfg`` instances. Unlike the
|
||
|
|
function-based terms used by other managers, every command term is a
|
||
|
|
class that inherits from ``CommandTerm``.
|
||
|
|
|
||
|
|
The ``resampling_time_range`` field controls how often the command
|
||
|
|
changes. After each resample the term draws a new timer value uniformly
|
||
|
|
from the given ``(min, max)`` range in seconds. Commands are also
|
||
|
|
resampled unconditionally on every episode reset.
|
||
|
|
|
||
|
|
.. code-block:: python
|
||
|
|
|
||
|
|
commands = {
|
||
|
|
"twist": UniformVelocityCommandCfg(
|
||
|
|
entity_name="robot",
|
||
|
|
resampling_time_range=(3.0, 8.0),
|
||
|
|
ranges=UniformVelocityCommandCfg.Ranges(
|
||
|
|
lin_vel_x=(-1.0, 1.0),
|
||
|
|
lin_vel_y=(-1.0, 1.0),
|
||
|
|
ang_vel_z=(-0.5, 0.5),
|
||
|
|
),
|
||
|
|
),
|
||
|
|
}
|
||
|
|
|
||
|
|
The ``generated_commands`` observation function reads the current
|
||
|
|
command tensor by name and passes it to the policy:
|
||
|
|
|
||
|
|
.. code-block:: python
|
||
|
|
|
||
|
|
ObservationTermCfg(
|
||
|
|
func=mdp.generated_commands,
|
||
|
|
params={"command_name": "twist"},
|
||
|
|
)
|
||
|
|
|
||
|
|
If the environment has no commands, the manager no-ops all operations
|
||
|
|
and returns empty tensors. There is no special handling required.
|
||
|
|
|
||
|
|
|
||
|
|
Included command terms
|
||
|
|
----------------------
|
||
|
|
|
||
|
|
Each task ships with its own command terms tailored to its objective.
|
||
|
|
|
||
|
|
.. list-table::
|
||
|
|
:header-rows: 1
|
||
|
|
:widths: 28 72
|
||
|
|
|
||
|
|
* - Term
|
||
|
|
- Description
|
||
|
|
* - ``UniformVelocityCommand``
|
||
|
|
- Generates planar velocity commands ``[v_x, v_y, omega_z]``
|
||
|
|
sampled uniformly from configurable ranges. Supports a standing
|
||
|
|
mode (fraction of environments receive zero velocity) and a
|
||
|
|
heading mode (yaw rate replaced by a proportional controller
|
||
|
|
tracking a sampled heading angle). Used by the velocity task.
|
||
|
|
* - ``LiftingCommand``
|
||
|
|
- Generates a 3D target position for a manipulated object.
|
||
|
|
Supports fixed and dynamic difficulty modes. Tracks metrics
|
||
|
|
including position error and episode success rate. Used by the
|
||
|
|
manipulation task.
|
||
|
|
* - ``MotionCommand``
|
||
|
|
- Streams reference joint positions, velocities, and body poses
|
||
|
|
from a pre-recorded ``.npz`` motion clip. Supports three
|
||
|
|
start-frame sampling modes: ``"start"`` (always frame 0),
|
||
|
|
``"uniform"`` (random), and ``"adaptive"`` (biased toward
|
||
|
|
difficult regions). At reset the robot is initialized from the
|
||
|
|
sampled frame with optional perturbations. Used by the tracking
|
||
|
|
task.
|
||
|
|
|
||
|
|
Each term can render debug visualizations in the interactive viewer
|
||
|
|
when ``debug_vis=True`` is set in the configuration. The image below
|
||
|
|
shows the ghost visualization from ``MotionCommand``, which renders a
|
||
|
|
translucent copy of the robot at the reference pose alongside the
|
||
|
|
actual robot.
|
||
|
|
|
||
|
|
.. figure:: _static/ghost_visualization.png
|
||
|
|
:align: center
|
||
|
|
:width: 100%
|
||
|
|
|
||
|
|
Viser visualization of the commanded reference motion for the G1 tracking task.
|
||
|
|
|
||
|
|
|
||
|
|
Writing custom command terms
|
||
|
|
-----------------------------
|
||
|
|
|
||
|
|
A custom command term is a class inheriting from ``CommandTerm`` paired
|
||
|
|
with a configuration dataclass inheriting from ``CommandTermCfg``. The
|
||
|
|
term must implement four methods: ``_resample_command(env_ids)`` to
|
||
|
|
sample new goals, ``_update_command(env_ids)`` for per-step updates,
|
||
|
|
``_update_metrics()`` for logging, and a ``command`` property returning
|
||
|
|
the current goal tensor. The base class manages the resampling timer
|
||
|
|
and reset logic automatically.
|
||
|
|
|
||
|
|
``_update_command`` is called in two situations. On every environment
|
||
|
|
step it receives ``env_ids=None``, meaning update all environments.
|
||
|
|
After a reset it is called again with the ids of the environments that
|
||
|
|
were just reset, so their command state is brought up to date before
|
||
|
|
observations are computed.
|
||
|
|
|
||
|
|
The distinction matters when your update advances state, such as
|
||
|
|
incrementing a frame index into a reference motion. Apply such advances
|
||
|
|
only to ``env_ids`` (all environments when ``None``); otherwise
|
||
|
|
resetting a few environments would also advance every other one. Updates
|
||
|
|
that simply recompute values from the current simulation state, like a
|
||
|
|
heading error, give the same result no matter how often they run and can
|
||
|
|
safely ignore ``env_ids``.
|
||
|
|
|
||
|
|
The configuration must implement a ``build(env)`` method that
|
||
|
|
constructs the paired term instance.
|