Stage 1: Prepare the humanoid USD#
A locomotion policy learns the dynamics represented by the training asset. Incorrect mass, inertia, collision, joint, or actuator properties therefore become part of the behavior the policy learns. Prepare and validate the USD before you encode the same robot in AGILE. Longer training cannot correct these errors; the policy instead adapts to the incorrect model.
This stage assumes nothing about what your robot’s manufacturer publishes. Where H2 has published actuator values, they are shown as a worked example, but every procedure here also works when the only information you have is the asset itself.
Choose your starting point#
Three assets can stand in for the humanoid in this stage, and which one you have changes only where you begin, not what you validate:
Asset |
When to use it |
|---|---|
Shipped reference H2 |
|
Your own humanoid URDF |
The path most readers will follow for real work. Start at Import a custom humanoid from URDF. |
Robot Menagerie H2 |
The asset the reference AGILE task trains on, retrieved by |
All three converge on the inspection, pose, gain, and validation sections that follow, which are the point of this stage.
What Stage 2 actually trains on#
The reference H2 task does not train with the USD that you open in Stage 1. Stage 2 calls fetch_h2_usd()
to retrieve H2 from the AGILE Robot Menagerie, so edits to the shipped Isaac Sim asset do not affect
the reference run.
Use Stage 1 to learn the validation process on an asset that you can inspect. For your own humanoid, point the Stage 2 robot configuration at the USD you validate here. That USD then becomes the training asset, and all the Stage 1 checks apply directly to it.
Keep these differences between the two H2 assets in mind:
The Menagerie asset provides
collision_profileandhandsvariant sets. Stage 2 selectsfeet_onlyandnonerespectively. The shipped asset provides only aPhysicsvariant set. If your own robot uses variants, define their names and selections in its Stage 2 spawn configuration.The collider audit later in this stage teaches you how to verify collision coverage. The reference task uses the Menagerie asset’s selected colliders; your custom task uses the collision geometry in your own USD, so audit it before training.
See also
Simulating a dexterous hand in Isaac Sim walks through the same inspect, collider, and gain-tuning workflow on a smaller asset.
Gain Tuner is the reference for the tuning workflow and for the Sinusoidal and dt Sweep test modes that this stage does not use.
Rigging a Legged Robot for a Locomotion Policy covers the general legged-robot case outside the humanoid context. Note that its temporary anchor is attached to the torso for pose capture; for gain testing, anchor the articulation root instead.
Start from the reference H2 asset#
Open Isaac/Robots/Unitree/H2/H2.usda from the Content Browser. The asset was generated from Unitree’s
h2_description package by the URDF importer, so it already has the structure this workflow expects:
The default prim is
H2, and the articulation root is/H2/Geometry/pelvis.A
Physicsvariant set carriesphysics,physx,mujoco, andnonepayloads. Check which variant is selected in the Property panel under Variants before you edit anything, and author physics edits into the payload layer backing that variant so that a later geometry update does not discard them.The robot is floating base. It contains no world fixed joint, which is what locomotion training requires.
It has 31 revolute joints: six per leg (
hip_pitch,hip_roll,hip_yaw,knee,ankle_roll,ankle_pitch), three waist joints, two head joints, and seven per arm.
Several properties still need your attention before training, and they are easy to miss because the asset opens and simulates without complaint:
Property |
State in the shipped asset |
Action |
|---|---|---|
Drive stiffness and damping |
Uniform |
Replace with per-group values. A single stiffness shared by a leg and a wrist is a placeholder rather
than a tuned plant. A fresh URDF import authors |
Maximum joint velocity |
The drive performance envelope is |
Verify rather than add. Read the resolved limits back with the joint-properties snippet in
Deploying policies in Isaac Sim and confirm they match your hardware, instead of
assuming the |
Effort limits |
Authored per joint and mostly consistent with Unitree’s published values. |
Spot-check against H2 actuator gains. Waist roll and pitch carry |
Armature and joint friction |
Not authored; both resolve to zero. |
Unitree publishes |
Sensor and hand frames |
Absent. The asset was built with fixed-joint merging enabled, so |
The reference observation terms do not read an IMU prim, so this costs you nothing on the H2 path. If your own observation terms or deployment interface reference those frames by name, re-import from URDF with merging disabled rather than trying to recover them from this asset. |
Note
The head joints (head_pitch_joint and head_yaw_joint) carry drives in the asset but do not appear
in Unitree’s published actuator groups. Decide deliberately whether the policy commands them, holds them,
or leaves them to a randomized action, and record that decision for Stage 2.
Import a custom humanoid from URDF#
Follow Importing a URDF and save the result as a USD asset. Three importer settings determine whether the asset is usable for locomotion training.
Set Base Type to Mobile. The default is Source, which defers to the source URDF; because H2 declares its floating base only in a commented-out block, importing H2 on the default authors a
/H2/Physics/root_jointfixed joint between the root prim and the pelvis, which produces an articulation that cannot translate. A locomotion policy trained against a world-fixed root learns a plant that does not exist. Setting Mobile removes that joint and leaves only the fixed joints the URDF itself declares.Enable Allow Self-Collision if your robot’s arms can reach its torso or legs. Without it, training can discover poses that pass limbs through the body.
Set Robot Type to Humanoid so the importer tags the asset for the robot schema that the robotics tools read.
Note
Fixed-joint merging is what separates the two starting points, and you do not have to do anything to get
it right from the GUI. The import dialog does not expose the option and the importer does not merge by
default, so a GUI import preserves the sensor and inertial frames the URDF declares. For H2 that means a
fresh import keeps imu_in_pelvis and imu_in_torso as plain Xform frames, and keeps
left_hand_link and right_hand_link as rigid bodies, while the shipped asset was built with merging
enabled and contains none of them. The reference H2 observation terms do not read an IMU prim, so preserve
these frames only if your own observation terms or your deployment interface reference them by name. If
you script the import instead, leave merge_fixed_joints at its default of False while you
validate.
H2.urdf selected with Allow Self-Collision enabled, Robot Type set to Humanoid, and
Base Type set to Mobile.#
The importer writes USD Asset Structure 3.0: a thin root layer over payloads/base.usda for geometry and
a Physics variant set over the physics payloads. Author gains and limits into the physics payload so that
geometry updates from your CAD or URDF source do not discard your tuning.
A fresh import is structurally sound but not yet trainable. Importing H2 with the settings above gives 31
revolute joints, 34 rigid bodies, 23 colliders, and a single articulation root on pelvis, which matches
what Stage 2 expects. What it does not give you is the actuator model:
After a fresh import |
What you get |
What to do before Stage 2 |
|---|---|---|
World fixed joint |
|
Confirm no world fixed joint survives. The hand fixed joints the URDF declares are fine. |
Drive stiffness and damping |
|
Author per-group gains. An undriven articulation collapses the moment you press Play. |
Max force |
Taken from the URDF |
Reconcile against the manufacturer’s published spec. H2’s URDF and Unitree’s published groups disagree
on the arms: |
Armature, joint friction, and drive velocity |
Unauthored |
Decide whether they live in the USD or in the Stage 2 actuator configuration, and set them in one place only. |
Sensor and hand frames |
Preserved when fixed-joint merging is disabled |
Keep them if Stage 2 observations or your deployment interface reference them by name. |
Inspect the articulation#
Inspect the imported or library asset before you touch drives. Each of these catches a class of failure that is expensive to diagnose after training starts.
Enable collider visualization with Eye > Show by Type > Physics > Colliders > All and confirm every contact surface has geometry. Rigid-body colliders draw green and static colliders draw magenta, so magenta on a robot you expect to be dynamic means the physics has not resolved and you are looking at the wrong thing.
Enable joint visualization with Eye > Show by Type > Physics > Joints and confirm each axis points where you expect. A reversed axis trains a policy that drives the joint the wrong way, and the symptom appears only at deployment.
Open Window > Robot Inspector and confirm every moving link has plausible mass, center of mass, and inertia. Zero or default inertia on a limb is a common URDF export defect. The Tree hierarchy mode is easier to scan than the stage when payloads spread prims across layers.
Confirm the asset uses meters, kilograms, seconds, radians, and newtons in its source data.
Confirm the joint axes, position limits, velocity limits, and effort limits match the robot.
Confirm exactly one articulation root exists, on the root link. On H2 that is
/H2/Geometry/pelvis. Do not attach the humanoid to the world with a fixed joint for locomotion training.Confirm joint and link names are stable and unique. You reference these names in the AGILE robot and task configurations, and renaming them later invalidates a trained policy.
Collider visualization on the imported H2. Convex hulls cover the torso, thighs, and feet, while the shin is represented only by the thin rod at the knee.#
Do not read “has colliders” as “has the right colliders.” The imported H2 puts collision on 23 of its 34
rigid-body links, and the shipped asset on 21 of 32; the two extra links in the imported asset are
left_hand_link and right_hand_link, which merging removes. That sounds complete until you look at
what the shapes are. Most
links carry a convex hull of their visual mesh, but the URDF also ships two crude primitive stand-ins per leg:
Link |
Collider |
What to check |
|---|---|---|
|
Convex hull mesh |
This is the foot, and it is the contact surface that matters most for locomotion. The ankle roll link carries no collider, so do not look for the foot there. |
|
Cylinder, |
A 5 cm-diameter rod is a placeholder for the shin, not a representation of it. If your task rewards or terminations depend on shin contact, replace it. |
|
Sphere, |
A 10 cm ball at the hip. Adequate for self-collision rejection, poor for anything that contacts the thigh. |
Eleven links carry no collider at all in both assets: .*_hip_pitch_link, .*_ankle_roll_link,
.*_wrist_pitch_link, .*_wrist_roll_link, waist_yaw_link, waist_roll_link, and
head_pitch_link. None of them is at the end of a chain, so the robot has no uncovered extremity, but the
gaps are not all the same size: the hip pitch, ankle roll, and head pitch are single uncovered links between
two covered ones, while the waist and each wrist have two uncovered links in a row. Walk your own robot’s
chains the same way and confirm where the gaps fall rather than assuming the count is enough.
Note
If you audit the asset with a script rather than the viewport, traverse instance proxies. Both H2 assets
store their geometry as USD instances, so a plain Usd.Stage.Traverse() walks past the prototypes and
reports 4 colliders instead of 23. Use
Usd.PrimRange.Stage(stage, Usd.TraverseInstanceProxies()) and confirm the count matches what collider
visualization draws before you conclude that geometry is missing.
Warning
Do not transform the asset’s root prim directly. Both H2 assets carry a Physics variant set on that
prim, and authoring over it can clear the variant selection, which silently removes every joint and
articulation root from the stage while the robot still looks correct in the viewport. Parent the asset
under your own Xform and move that instead. If the physics disappears, check the variant selection in the
Property panel under Variants before anything else.
Validate the drives#
Once a group tracks acceptably, use the remaining test modes to catch authoring mistakes rather than to search for better gains. A unit conversion that is off by the factor of 57.3 between radians and degrees, a missing max force, or reversed joint bodies all surface here as failures across nearly every joint at once.
Keep the anchor and the removed ground plane from Anchor the robot before you test anything in place for these tests, for the same reason.
Run Snap to Limits across the actuated joints. It commands each joint to its lower limit, holds, then commands the upper limit, so it verifies that gains, limits, and collision geometry agree.
Snap to Limits results per joint, with the settling time and the mean and maximum error at each limit.#
Run Stress last. It drives joints with extreme random commands and exposes solver instabilities of the kind that aggressive reinforcement learning exploration produces.
Delete the temporary fixed joint, and restore the ground plane if you removed one.
Read the per-joint verdicts precisely:
Result |
Meaning |
|---|---|
|
Both limits were reached within tolerance. |
|
The limit was not reached and the joint was still moving. This points at gains or dynamics. |
|
The limit was not reached and the joint stalled, typically against self-collision or another physical constraint. |
Note
Expect a mixed result on H2 and read it correctly. Snap to Limits with Unitree’s published gains passes
13 of 31 joints; the rest report BLOCKED or FAIL. That is not an authoring error, for the same
reason the Step Function errors above are large.
To separate contact blocking from insufficient torque, run the test again with Disable Self-Collisions During Test. On H2 the two runs differ by a single joint, which says the limiting factor is torque rather than contact. Disable Velocity Limits During Test isolates the velocity ceiling the same way. What should worry you instead is a joint that fails while its mirror twin passes, or one whole side of the robot failing at once.
Tip
If joints go unstable near their limits rather than simply failing to reach them, select PhysicsScene
in the Stage panel and raise Time Steps Per Second to 120 before you change any gains.
Validate the physical model#
The sections above cover the static properties and the drives in isolation. Confirm the dynamic behavior of the whole robot before you configure the training task:
Restore the ground plane, place the robot above it, press Play, and confirm that it falls and settles without exploding, tunneling through the ground, or developing persistent contact jitter.
Exercise each joint through a conservative range in Tools > Robotics > Joint Inspector and confirm that its direction, limit, and reported state are correct.
Confirm the robot is floating base with no world fixed joint remaining, and that exactly one articulation root exists on the root link.
Read the position, velocity, and effort limits back at runtime rather than trusting the authored attributes. On H2 the drive performance envelope reports an infinite velocity while the joints resolve finite limits, so the authored value and the effective value disagree.
Confirm the drive stiffness and damping are the per-group values you authored rather than a uniform value repeated across every joint.
The H2 articulation loaded and holding its standing pose on a ground plane in Isaac Sim.#
Record the Stage 2 inputs#
The USD is only one part of the training model. Record the following values while their meaning is visible in Isaac Sim. In Stage 2, you encode them in the AGILE robot configuration; in Stage 3, you reference the same names and frames from MDP terms. The H2 values are given as a worked example; substitute your own robot’s names throughout.
Record |
H2 reference value |
|---|---|
USD path and articulation root prim |
|
Root link, foot links, and fall-termination links |
Root |
Ordered joint names and the controlled subset |
31 revolute joints; the reference task controls 14 (12 leg joints plus |
Default standing root pose, joint positions, and joint velocities |
Base at |
Position, velocity, and effort limits |
All three resolve at runtime; record the resolved values, not the authored attributes |
Actuator stiffness, damping, armature, friction, saturation, and expected control delay |
Published groups in Author the actuator gains; |
IMU and other sensor frames used to produce policy observations |
|
Do not infer these values from the H2 example for another robot. The names determine which simulated bodies and joints an MDP term resolves, while the physical values determine the dynamics the policy experiences.
Troubleshooting by layer#
Symptom |
Likely layer |
Check |
|---|---|---|
The robot explodes or develops persistent jitter. |
Scale, inertia, or collision geometry. |
Check units, small or invalid inertias, initial interpenetration, self-collision, and solver settings. |
The robot falls through or floats above the ground. |
Collision geometry. |
Confirm that the feet and ground have enabled colliders and compatible collision groups. |
A joint moves in the wrong direction or beyond the expected range. |
Joint definition. |
Check the joint bodies, axis, local frames, limits, and unit conversion. |
The robot cannot fall freely. |
Articulation structure. |
Remove world-fixed joints and confirm that one articulation root represents the floating base. |
A later AGILE term cannot find a link or joint. |
Naming contract. |
Record the resolved articulation names, not display labels or URDF names that changed during import. |
The robot looks correct but has no joints or articulation root. |
Variant selection. |
Confirm the |
Colliders draw magenta instead of green. |
Physics resolution. |
Magenta means static. The links are not resolving as rigid bodies, so check the variant selection and the payload before you trust any collider or mass reading. |
A script reports far fewer colliders than collider visualization draws. |
Traversal. |
Traverse instance proxies with |
The robot springs into its pose when simulation starts. |
Joint state. |
Drive targets alone are not a start state. Author |
Nearly every joint fails Snap to Limits at once. |
Gain authoring. |
Check the radian-to-degree conversion and confirm Max Force is set on every drive. |
Completion checklist#
The USD contains one validated floating-base articulation.
Mass, inertia, collision, joint-axis, and joint-limit values are physically credible.
Contact surfaces that your task depends on carry collision geometry that represents them, not a placeholder primitive.
The robot falls and settles without unstable contacts.
Every joint moves in the expected direction and respects its limits.
Joint and link names are stable and unique.
The standing pose is authored as joint state, not only as drive targets.
Drive stiffness, damping, and max force are authored per joint group rather than uniformly.
The temporary fixed joint used for gain testing is deleted.
The Stage 2 input list records the asset, pose, actuator, joint, link, and sensor values.
Continue with Stage 2: Create a custom humanoid task in AGILE.