Some checks failed
nightly / Test against latest dependencies (py3.10) (push) Has been cancelled
nightly / Test against latest dependencies (py3.13) (push) Has been cancelled
tests / tests (3.13, locked) (push) Has been cancelled
tests / tests (3.13, unlocked) (push) Has been cancelled
tests / pyright (3.10) (push) Has been cancelled
tests / lint-format (push) Has been cancelled
tests / tests (3.10, locked) (push) Has been cancelled
tests / tests (3.11, locked) (push) Has been cancelled
tests / tests (3.12, locked) (push) Has been cancelled
tests / pyright (3.11) (push) Has been cancelled
tests / pyright (3.12) (push) Has been cancelled
tests / pyright (3.13) (push) Has been cancelled
tests / ty-check (3.10) (push) Has been cancelled
tests / ty-check (3.11) (push) Has been cancelled
tests / ty-check (3.12) (push) Has been cancelled
tests / ty-check (3.13) (push) Has been cancelled
tests / stubs (push) Has been cancelled
tests / smoke-test (push) Has been cancelled
Docker / check_paths (push) Has been cancelled
docs / build (push) Has been cancelled
Docker / build (push) Has been cancelled
Upstream: https://github.com/michaelgillett/mjlab Upstream-Commit: c19f713c415a699a79d71cd96aa13c3104a05047 Upstream-Branch: main
213 lines
9.2 KiB
ReStructuredText
213 lines
9.2 KiB
ReStructuredText
.. _events:
|
|
|
|
Events
|
|
======
|
|
|
|
The event manager executes hooks at specific points in the environment
|
|
lifecycle. Any logic that should run at startup, on episode reset, or at
|
|
regular intervals during training is registered as an event term. Common
|
|
examples include resetting entities to an initial state, applying domain
|
|
randomization to model parameters, pushing the robot with random velocity
|
|
perturbations, and initializing robot state from a reference motion clip.
|
|
All of these are configured through the same ``EventTermCfg`` interface,
|
|
differing only in the ``mode`` field that controls when each term fires.
|
|
|
|
Domain randomization, one of the most common uses of events, has its own
|
|
dedicated reference page. See :ref:`domain_randomization` for the full
|
|
``dr`` module, available functions, and internals.
|
|
|
|
.. code-block:: python
|
|
|
|
from mjlab.envs.mdp import events as event_fns, dr
|
|
from mjlab.managers.event_manager import EventTermCfg
|
|
from mjlab.managers.scene_entity_config import SceneEntityCfg
|
|
|
|
events = {
|
|
# Reset all entities to their default state each episode.
|
|
"reset_scene": EventTermCfg(
|
|
func=event_fns.reset_scene_to_default,
|
|
mode="reset",
|
|
),
|
|
# Randomize foot friction once at startup.
|
|
"foot_friction": EventTermCfg(
|
|
func=dr.geom_friction,
|
|
mode="startup",
|
|
params={
|
|
"asset_cfg": SceneEntityCfg("robot", geom_names=[".*foot.*"]),
|
|
"ranges": (0.3, 1.2),
|
|
"operation": "abs",
|
|
},
|
|
),
|
|
# Push the robot at random intervals during the episode.
|
|
"push_robot": EventTermCfg(
|
|
func=event_fns.push_by_setting_velocity,
|
|
mode="interval",
|
|
interval_range_s=(1.0, 3.0),
|
|
params={
|
|
"velocity_range": {"x": (-0.5, 0.5), "y": (-0.5, 0.5)},
|
|
},
|
|
),
|
|
# Transient random impulses with duration and cooldown.
|
|
"impulse": EventTermCfg(
|
|
func=event_fns.apply_body_impulse,
|
|
mode="step",
|
|
params={
|
|
"force_range": (-50.0, 50.0),
|
|
"torque_range": (0.0, 0.0),
|
|
"duration_s": (0.1, 0.2),
|
|
"cooldown_s": (1.0, 3.0),
|
|
"asset_cfg": SceneEntityCfg("robot", body_names=("base",)),
|
|
},
|
|
),
|
|
}
|
|
|
|
|
|
Lifecycle modes
|
|
---------------
|
|
|
|
The ``mode`` field on ``EventTermCfg`` determines when the term fires. The
|
|
four modes correspond to the timescales of an RL training run: once at
|
|
process startup, once per episode, periodically within an episode, and on
|
|
every environment step.
|
|
|
|
``"startup"``
|
|
Fires once during environment initialization, after all managers are
|
|
constructed. Every environment receives the event simultaneously. This
|
|
mode is intended for parameters that should differ across environments
|
|
but remain fixed for the entire training run, such as link masses or
|
|
joint armatures randomized via the ``dr`` module.
|
|
|
|
``"reset"``
|
|
Fires on every episode reset, for each environment being reset. This is
|
|
the most common mode. State initialization (writing the robot back to
|
|
its default pose) and episode-level domain randomization both belong
|
|
here.
|
|
|
|
The optional ``min_step_count_between_reset`` field prevents the term
|
|
from firing too frequently when episodes are very short. The term is
|
|
skipped for any environment that has not taken at least that many steps
|
|
since its last trigger. The first invocation always fires regardless.
|
|
|
|
``"interval"``
|
|
Fires at regular time intervals during training, independent of episode
|
|
boundaries. The trigger frequency is controlled by ``interval_range_s``,
|
|
a ``(min, max)`` range in seconds. After each trigger the manager
|
|
samples a new wait time uniformly from that range. Each environment has
|
|
its own independent timer by default; setting ``is_global_time=True``
|
|
synchronizes all environments to a single shared timer. Interval events
|
|
are the natural home for mid-episode perturbations such as external
|
|
pushes or drifting model parameters.
|
|
|
|
``"step"``
|
|
Fires on every environment step, for all environments. This mode is
|
|
intended for continuous effects that must be evaluated each step, such
|
|
as ``apply_body_impulse`` which manages its own internal duration and
|
|
cooldown timers. Because step events run every step, they should be
|
|
lightweight or manage their own activation logic internally to avoid
|
|
unnecessary computation.
|
|
|
|
As with all manager terms, ``func`` points to the callable and ``params``
|
|
holds keyword arguments forwarded to it alongside ``env`` and ``env_ids``.
|
|
Any ``SceneEntityCfg`` values inside ``params`` are resolved once at
|
|
manager construction (regex patterns are matched to model indices at that
|
|
point, not on every call). Terms can be plain functions or classes; see
|
|
:ref:`env-config-term-pattern` for the general pattern.
|
|
|
|
|
|
Built-in event functions
|
|
------------------------
|
|
|
|
The functions below are available in ``mjlab.envs.mdp.events``.
|
|
|
|
.. list-table::
|
|
:header-rows: 1
|
|
:widths: 30 70
|
|
|
|
* - Function
|
|
- Description
|
|
* - ``reset_scene_to_default``
|
|
- Resets all entities to their default states: root pose and velocity
|
|
for floating-base entities, mocap pose for fixed-base entities, and
|
|
joint positions and velocities for articulated entities. Environment
|
|
origins are applied automatically. This is the default event on
|
|
``ManagerBasedRlEnvCfg``; most environments keep it and add
|
|
additional terms alongside it.
|
|
* - ``reset_root_state_uniform``
|
|
- Resets a single entity's root pose and velocity with uniform random
|
|
offsets from the default. Accepts ``pose_range`` and
|
|
``velocity_range`` dictionaries with keys ``"x"``, ``"y"``,
|
|
``"z"``, ``"roll"``, ``"pitch"``, ``"yaw"``. Orientation
|
|
perturbations compose with the default quaternion. For fixed-base
|
|
robots, this is the only way to position them at their environment
|
|
origins; without it they stack at the world origin.
|
|
* - ``reset_root_state_from_flat_patches``
|
|
- Places an entity on a randomly chosen flat terrain patch based on
|
|
the environment's assigned terrain level and type. Falls back to
|
|
``reset_root_state_uniform`` when no flat patches are available.
|
|
Useful for locomotion tasks where robots should spawn on level
|
|
ground within their assigned sub-terrain.
|
|
* - ``reset_joints_by_offset``
|
|
- Resets joint positions and velocities by adding a uniform random
|
|
offset to the entity's defaults, clamped to soft joint limits.
|
|
* - ``push_by_setting_velocity``
|
|
- Adds a random velocity increment to the entity's current root
|
|
velocity, simulating an external push. Typically used with
|
|
``mode="interval"`` to test disturbance rejection.
|
|
* - ``apply_external_force_torque``
|
|
- Applies random forces and torques to one or more bodies via the
|
|
MuJoCo external wrench mechanism.
|
|
* - ``apply_body_impulse``
|
|
- Applies transient external wrenches to bodies with configurable
|
|
duration and cooldown. Each environment independently samples a
|
|
random force direction and holds it for a sampled duration, then
|
|
waits through a cooldown before firing again. Supports an optional
|
|
``body_point_offset`` to shift the application point away from the
|
|
center of mass. Includes built in debug visualization that draws
|
|
force arrows in the viewer. Use with ``mode="step"``.
|
|
* - ``randomize_terrain``
|
|
- Assigns each environment to a random sub-terrain row and column,
|
|
ignoring the curriculum. Useful for evaluation or play mode.
|
|
|
|
|
|
Writing custom event terms
|
|
--------------------------
|
|
|
|
An event function takes ``env`` and ``env_ids`` as its first two arguments
|
|
and any additional parameters from ``EventTermCfg.params``. It modifies
|
|
simulation state in place and returns nothing. For terms that need
|
|
expensive one-time setup (such as loading data from disk), use a class
|
|
so that the setup runs once at construction rather than on every call.
|
|
For example, the following custom event term resets the robot to a
|
|
random pose sampled from a pre-recorded dataset:
|
|
|
|
.. code-block:: python
|
|
|
|
import torch
|
|
from mjlab.managers.manager_base import ManagerTermBase
|
|
from mjlab.managers.scene_entity_config import SceneEntityCfg
|
|
|
|
class ResetFromDataset(ManagerTermBase):
|
|
"""Reset the robot to a random pose from a dataset."""
|
|
|
|
def __init__(self, cfg, env):
|
|
super().__init__(env)
|
|
self._robot = env.scene["robot"]
|
|
self._poses = torch.load(
|
|
cfg.params["dataset_path"],
|
|
map_location=env.device,
|
|
)
|
|
|
|
def __call__(self, env, env_ids, **kwargs):
|
|
# Sample with replacement: each env gets an independent pose.
|
|
indices = torch.randint(
|
|
len(self._poses), (len(env_ids),), device=env.device,
|
|
)
|
|
self._robot.write_joint_position_to_sim(
|
|
self._poses[indices], env_ids=env_ids,
|
|
)
|
|
|
|
When a term needs to maintain state or perform expensive setup, implement
|
|
it as a class. See :ref:`env-config-term-pattern` for the general
|
|
pattern. For custom DR terms that write to model fields, see
|
|
:ref:`domain_randomization`.
|