Hydra Configuration System
Isaac Lab supports the Hydra configuration system to modify the task’s configuration using command line arguments, which can be useful to automate experiments and perform hyperparameter tuning.
Any parameter of the environment can be modified by adding one or multiple elements of the form env.a.b.param1=value
to the command line input, where a.b.param1 reflects the parameter’s hierarchy, for example env.actions.joint_effort.scale=10.0.
Similarly, the agent’s parameters can be modified by using the agent prefix, for example agent.seed=2024.
The way these command line arguments are set follow the exact structure of the configuration files. Since the different
RL frameworks use different conventions, there might be differences in the way the parameters are set. For example,
with rl_games the seed will be set with agent.params.seed, while with rsl_rl, skrl and sb3 it will be set with
agent.seed.
As a result, training with hydra arguments can be run with the following syntax:
rsl_rl
rl_games
skrl
sb3
uv (Recommended)
isaaclab.sh / isaaclab.bat
The above command will run training with the task Isaac-Cartpole without selecting a visualizer,
and set the env.actions.joint_effort.scale parameter to 10.0 and the agent.seed parameter to 2024.
To keep backwards compatibility, and to provide a more user-friendly experience, we have kept the old cli arguments
of the form --param, for example --num_envs, --seed, --max_iterations. These arguments have precedence
over the hydra arguments, and will overwrite the values set by the hydra arguments.
Modifying advanced parameters
Callables
It is possible to modify functions and classes in the configuration files by using the syntax module:attribute_name.
For example, in the Cartpole environment:
we could modify joint_pos_rel to compute absolute positions instead of relative positions with
env.observations.policy.joint_pos_rel.func=isaaclab.envs.mdp:joint_pos.
Setting parameters to None
To set parameters to None, use the null keyword, which is a special keyword in Hydra that is automatically converted to None.
In the above example, we could also disable the joint_pos_rel observation by setting it to None with
env.observations.policy.joint_pos_rel=null.
Dictionaries
Elements in dictionaries are handled as parameters in the hierarchy. For example, in the Cartpole environment:
the position_range parameter can be modified with env.events.reset_cart_position.params.position_range="[-2.0, 2.0]".
This example shows two noteworthy points:
- The value contains a space, so it must be enclosed in quotes for the shell.
- The parameter is a list while it is a tuple in the config. This is due to the fact that Hydra does not support tuples.
Modifying inter-dependent parameters
Particular care should be taken when modifying the parameters using command line arguments. Some of the configurations perform intermediate computations based on other parameters. These computations will not be updated when the parameters are modified.
For example, for the configuration of the Cartpole camera environment:
The configuration declares the single-frame channel count and a default spatial size.
At environment initialization, CartpoleCameraEnv rebuilds observation_space from
the resolved camera: the default frame_stack=2 expands channels, and height/width are
taken from scene.tiled_camera. So
env.scene.tiled_camera.width=128 env.scene.tiled_camera.height=128
alone yields an effective stacked shape of [6,128,128] without also overriding
env.observation_space. The channel entry in observation_space must still match the
camera data type (for example [1, ...] with presets=depth); presets already set this.
Class-body assignments are evaluated once at import time and do not track later Hydra overrides unless runtime code explicitly rebuilds the dependent value, as this camera environment does.
Similarly, the __post_init__ method is not updated with the command line inputs. In the LocomotionVelocityRoughEnvCfg, for example,
the post init update is as follows:
Here, when modifying env.decimation or env.sim.dt, the user needs to give the updated env.sim.render_interval,
env.scene.height_scanner.update_period, and env.scene.contact_forces.update_period as input as well.
Custom Configuration Validation
Configclass objects can define a validate_config() method to perform domain-specific
validation after all fields have been resolved. This hook is called automatically after preset
resolution and MISSING-field checks succeed, allowing you to catch invalid parameter
combinations early with clear error messages.
For example, the Franka reach configuration validates that its Newton IK action preset is paired with a Newton physics configuration:
When it runs:
- All
MISSINGfields are checked first — if any remain,TypeErroris raised. - Only then is
validate_config()called on the top-level config object. - The hook should raise
ValueErrorwith a clear message and migration guidance.
Common validation patterns:
- Compatibility between independently selectable controllers, physics configurations, and renderers
- Renderer, camera data type, and feature extractor compatibility
- Numeric relationships or limits that cannot be expressed by field types alone
Preset System
For a user-focused introduction to choosing physics, rendering, and task variants, start with /source/concepts/backends_and_presets. This section covers the complete preset definition and resolution behavior.
The preset system lets you swap out entire config sections — or individual scalar values — with a single command line argument. Instead of overriding individual fields, you select a named preset that completely replaces the config section (no field merging).
Presets are declared by subclassing ~isaaclab_tasks.utils.hydra.PresetCfg
or by using the ~isaaclab_tasks.utils.hydra.preset convenience factory. The
system recursively discovers all presets from nested configs automatically,
including presets inside dict-valued fields (e.g. actuators).
Override Order
The effective precedence, from lowest to highest, is:
- Defaults: Each unresolved
PresetCfgfalls back to itsdefaultfield. - Typed and domain selections:
physics=newton_mjwarpselects physics whilepresets=rgbbroadcasts a task-specific name to every matching config. - Path selections:
env.sim.physics=newton_kaminotargets one specificPresetCfgand takes precedence at that path. - Play-mode changes: When requested by a play command, the environment’s
play_mode()changes are applied to the resolved config. - Scalar overrides:
env.sim.dt=0.001has the final say for an individual field.
If multiple broadcast names select different alternatives at the same active path, resolution fails instead of silently choosing one.
Defining Presets with PresetCfg
Create a ~isaaclab_tasks.utils.hydra.PresetCfg subclass where each field
is a named alternative. The default field is the config used when no CLI
override is given:
Physics is owned by ~isaaclab.sim.SimulationCfg, so the preset’s config
path is env.sim.physics. For backend selection, prefer the typed selector:
Use the path form env.sim.physics=newton_mjwarp only when you intentionally
want to replace that one preset node without selecting other matching task presets.
The default field can be set to None to make an optional feature that is
disabled unless explicitly selected:
Here, env.scene.camera resolves to None by default. A registered task using
this config can activate the large camera with the path selector
env.scene.camera=large.
Backend and Solver Presets
Physics backend selection uses the same preset system. A task can define a
PresetCfg whose entries replace the complete physics config:
The Cartpole task’s definition is a maintained example:
The newton_mjwarp and newton_kamino entries both select the Newton physics backend because
both entries are ~isaaclab_newton.physics.NewtonCfg objects. The difference
is the solver configuration: newton_mjwarp uses
~isaaclab_newton.physics.MJWarpSolverCfg, while newton_kamino uses
~isaaclab_newton.physics.KaminoPADMMSolverCfg.
Kamino is therefore a solver preset, not a separate Isaac Lab backend. The same Newton assets, sensors, renderers, and visualizers are used after the preset is resolved. It is a Proximal Alternating Direction Method of Multipliers (P-ADMM) based solver for constrained rigid multi-body dynamics, and its Isaac Lab support is currently beta.
Kamino support is experimental and currently depends on the asset being
structured in a way that Kamino can consume. Assets that work with the
MuJoCo-Warp or PhysX presets may still require model-structure updates before
they work with physics=newton_kamino.
Backend support is task-specific and changes as tasks are validated. Use the task’s
--help output as the source of truth. Passing physics=newton_kamino to a
task that does not advertise it fails; it does not add a Kamino configuration to
that task.
Inline Presets with preset()
For simple values (scalars, lists) that don’t warrant a full subclass, use the
~isaaclab_tasks.utils.hydra.preset factory. It dynamically creates a
PresetCfg instance from keyword arguments:
This is equivalent to defining a PresetCfg subclass with the same float
fields, but without the ceremony. The default keyword is required.
preset() works for any value type — scalars, lists, or even config
instances:
Use preset() when the definition fits on a single line. Use a
PresetCfg subclass when the options are verbose enough to benefit from
type annotations and multiline formatting.
The preset system discovers preset() values anywhere in the config tree,
including inside dict-valued fields such as actuators:
The typed physics= selector uses broadcast resolution for the selected name,
so matching task-specific alternatives such as this armature value are updated too.
It additionally verifies that the name resolved a physics configuration; the free-form
presets= selector does not provide that type check.
Typed Preset Selectors
The preset CLI layer recognizes three key=value tokens (no leading dashes)
that can be appended to any training or play script command:
The typed selectors use the same broadcast resolution as presets=. This means
physics=newton_mjwarp can also update dependent task presets with the same name,
such as actuator or event settings. They are not interchangeable, however: a typed
selector must resolve at least one config of its declared type or it raises an error.
Use physics= and renderer= for backend choices, and reserve presets= for
task-specific modes.
Common physics preset names (only when advertised by the task):
Common renderer preset names (when provided by
~isaaclab_tasks.utils.presets.MultiBackendRendererCfg):
The implicit default field is task-specific and is intentionally omitted from
--help. Do not infer a task’s default backend from these conventional names;
inspect its help output or configuration. Automatic choices such as physics=physx
and renderer=rtx are opt-in, not universal defaults.
Domain presets (observation modes, camera configurations, etc.) are task-specific.
Pass --task=<task-name> --help to a training command to see all presets available
for that task, grouped by selector type.
For reinforcement-learning tasks, preset resolution composes the registered
environment and agent configurations as sibling roots. A library’s canonical
<library>_cfg_entry_point may therefore return a root-level PresetCfg with
the same alternative names as the environment. A broadcast such as
presets=resnet18 selects resnet18 in both roots in one resolution pass:
uv (Recommended)
isaaclab.sh / isaaclab.bat
This is the preferred way to keep an environment-coupled policy shape, such as a
feature extractor or action-space head, aligned with the selected environment. It
does not require a preset-specific registry entry or rewrite --agent.
Independent training recipes remain explicit agent choices. A task may select an alternate agent for symmetry, recurrence, distillation, or another algorithm without changing its environment preset.
Preset-specific agent entry points and registry-side preset-to-agent maps are not
part of this model. Use the canonical entry point and select its variant with
presets=. For older SKRL runs whose manifest or directory encoded a
configuration-key suffix instead of agent.class as the algorithm, pass the
checkpoint path explicitly instead of using automatic latest or best
discovery.
Legacy aliases newton → newton_mjwarp and kamino → newton_kamino
are still accepted but emit a FutureWarning. The renderer aliases
isaacsim_rtx_renderer → isaacsim_rtx and ovrtx_renderer → ovrtx
behave the same way. Prefer the canonical names.
Using Presets
Typed selectors — preferred form for physics and renderer backends:
Path presets — select a specific preset for one config path:
Domain presets — broadcast a task-specific name everywhere it exists:
Multiple domain presets — apply several non-conflicting task choices:
The KukaAllegro -Camera tasks default to a single camera and the matching
RSL-RL CNN actor. presets=duo_camera switches both the camera rig and actor
inputs; the critic continues to use state observations.
Combined — typed selectors, a domain preset, and a scalar override:
Global Preset Conflict Detection
If two global presets both match the same config path, an error is raised so the ambiguity is caught early:
Real-World Example
The ANYmal-C locomotion environment shows both PresetCfg and preset()
working together:
The base velocity configuration also defines newton_mjwarp alternatives for
physics and a center-of-mass randomization event that MJWarp disables. An explicit
physics=newton_mjwarp resolves the physics config and every active dependent
alternative with that name: the event is disabled and the ANYmal-C actuator
armature becomes 0.01. The typed selector also verifies that a physics preset
was actually selected.
Without a selector, each PresetCfg independently uses its own default;
the name of a default alternative is not broadcast to other preset nodes.