Isaac Lab’s H1 Rough Play configuration starts by applying the H1 Rough training configuration, then overrides selected fields. It changes the scene size, terrain setup, command ranges, observation corruption and an external-force event. Several other settings—including disabled random pushing—already come from the H1 parent.
That inheritance explains why a policy can encounter a different command and observation distribution when moved from a training task to its Play counterpart. The checkpoint can remain fixed while the environment asks it to do different things. Reading only the bottom of the configuration file misses both the inherited behavior and the changes that actually distinguish Play.
The available-environments documentation pairs Isaac-Velocity-Rough-H1-v0 with the inference task Isaac-Velocity-Rough-H1-Play-v0. The details below follow the H1 rough-environment configuration on the current main branch, checked on October 16, 2026. No training or rollout was run for this article.
Follow both parent calls before reading the overrides
H1RoughEnvCfg inherits from LocomotionVelocityRoughEnvCfg. Its __post_init__ calls the parent implementation before applying H1-specific settings. These include the H1 robot asset, selected rewards, reset parameters, command ranges and the body used for base-contact termination.
H1RoughEnvCfg_PLAY then inherits from H1RoughEnvCfg and calls super().__post_init__() again. For a Play instance, the H1 configuration has therefore already been applied when the Play-specific assignments begin.
This makes an assignment’s location important. A field changed in the H1 parent affects both configurations unless Play overrides it. A field written again with the same value in Play is not a newly introduced behavior. Fields left untouched continue through the inheritance chain.
The velocity-command range changes the task request
The H1 parent sets the forward linear-velocity command range to (0.0, 1.0). Play narrows it to (1.0, 1.0). The lateral range remains (0.0, 0.0), and the yaw-rate range remains (-1.0, 1.0) in both classes. Play additionally sets the heading range to (0.0, 0.0).
| Command field | H1 parent assignment | Play assignment |
|---|---|---|
lin_vel_x |
(0.0, 1.0) |
(1.0, 1.0) |
lin_vel_y |
(0.0, 0.0) |
(0.0, 0.0) |
ang_vel_z |
(-1.0, 1.0) |
(-1.0, 1.0) |
heading |
No H1-specific assignment in this file | (0.0, 0.0) |
These are desired-motion parameters, not measured robot velocities. The narrowed forward range selects a single forward command value where the parent permits a range. Whether the robot tracks that request is the policy’s behavior during the rollout.
As a hypothetical comparison, imagine evaluating one fixed checkpoint first with a forward request of 0.3 and then with a request of 1.0. A different tracking response would be a response to a changed input, even though the network weights were identical. The actual Play assignment makes the forward-command range a concrete part of that comparison.
The yaw-rate range and heading field also remain distinct configuration entries. Setting the heading range to zero is not a statement that the measured robot yaw or every angular command is zero. Their use belongs to the inherited command generator; the H1 file shows which ranges Play supplies to it.
Play configures terrain placement and scene size
The Play subclass sets scene.num_envs to 50, scene.env_spacing to 2.5 and episode_length_s to 40.0. These are explicit Play assignments. Their training-side numeric defaults are inherited from another file, so they should not be inferred from the H1 source alone.
For terrain, Play sets max_init_terrain_level to None. The accompanying source comment describes spawning randomly across the grid instead of according to the robots’ terrain levels. If a terrain generator is present, Play sets its row and column counts to 5 and turns its curriculum flag off.
The condition around those assignments matters: the grid and generator-curriculum changes occur only when terrain_generator is not None. The code does not replace the rough-terrain task with flat terrain. It changes how that task’s terrain generator and initial terrain selection are configured.
This is why Play should be understood as an environment configuration, not a graphics switch. The number of simulated instances, episode duration and terrain sampling can change what is encountered during a rollout, independently of whether a viewer is open.
Random pushing was already disabled in the H1 parent
The Play class ends with a comment about removing random pushing and sets two event fields to None: base_external_force_torque and push_robot. Reading that block alone could suggest that both events distinguish Play from training.
The H1 parent already sets push_robot = None. Play repeats that value, so random pushing is disabled at the H1-parent level for both configurations. The parent also disables add_base_mass and base_com events.
The external-force event follows a different path. The H1 parent directs base_external_force_torque toward the torso body; Play removes the event by assigning None. That is a genuine Play-specific override in the inspected inheritance chain.
Play also sets observations.policy.enable_corruption = False. This assignment disables corruption for the policy observation group. The nearby broad comment about disabling randomization should be interpreted through these concrete assignments, because other variation remains in the inherited configuration.
For example, the H1 parent supplies reset pose ranges of (-0.5, 0.5) for x and y and (-3.14, 3.14) for yaw. Play does not override those reset parameters in this file. Its terrain placement is also explicitly randomized across the grid. These settings explain why disabling observation corruption and selected disturbance events does not make every initial condition fixed.
Compare the resolved environment around the same checkpoint
The inheritance chain provides a precise way to explain a training-versus-Play difference. First identify the field that affects the behavior: forward command, observation corruption, terrain assignment or a force event. Then locate its final assignment after both parent initializers have run.
For H1 Rough, that approach separates three cases: a new Play value such as the fixed forward-command range, an inherited value such as the reset pose range, and a repeated value such as push_robot = None. Each has a different interpretation when examining a rollout.
The Isaac Lab Arena policy-regression article develops the broader comparison contract for checkpoints and environments. The H1 example supplies a concrete reason for that contract: a task name ending in Play can resolve to different commands, observations and terrain settings, while retaining substantial behavior from the training configuration.