Promptable humanoid control

One policy.
New goals. New behaviors.

Chen Tessler*,1Yifeng Jiang*,1Alec Otto2Yi Shi†,1Umar Iqbal1Gal Chechik1Xue Bin Peng1

1 NVIDIA2 Dollhouse Robotics* Equal contribution† Work done while interning at NVIDIA

Metatron turns motion goals into coordinated whole-body action. Coding agents can write and refine those goals to build new skills—without retraining the policy.

Goals specify what to do.

Metatron coordinates how to move.

01 / An interface for skill code

Set the goals.
Let the body respond.

A coding agent can work with positions, orientations, velocities, and arrival times. Metatron turns those goals into coordinated whole-body motion.

What & where

Specify the task.

Give approximate targets for a hand, foot, torso, or travel velocity and heading. Refine them when the task needs more precision.

When

Give it timing.

Arrival times can be approximate too. Skill code can sequence goals and update their timing as the task progresses.

What stays free

Leave room to move.

Constrain only what matters. Metatron generates the remaining motion instead of requiring a complete pose at every instant.

The overlays show the supplied goals. Metatron generates the whole-body motion in response.

G1 / MuJoCo simulation

Change the goals, not the policy.

Velocity, heading, and timed foot targets guide locomotion. During recovery, the skill switches to upright-pose goals.

SOMA / IsaacLab simulation · separate policy

Run, slide, climb. Change the goals.

Velocity and heading goals build speed. For the slide, a low pelvis target and a forward foot target guide the body down with one leg extended ahead. For the climb, a pelvis-position target above the ledge and a heading goal guide the body upward, leaving hand and foot placement to the policy.

02 / Agent-assisted skill development

Refine the goals.
Not the policy.

Describe a task. A coding agent writes goal-setting code, tests it in simulation, and refines it from the results. Metatron stays frozen.

HumanSpecify the task
Coding agent + motion examplesWrite and refine skill code
Simulation + frozen MetatronEvaluate and diagnose

The LLM develops the skill offline. At runtime, ordinary skill code supplies goals—not an LLM in the robot’s control loop. A human decides whether to deploy it.

Hardware example / Agent-assisted steering

A better gait,
through better goals.

Velocity goals alone can produce hesitant foot motion. We used Claude Code to fit a compact foot-trajectory rule from motion-capture clips. Its timed foot targets guide more decisive stepping, with the policy unchanged.

Velocity + heading+ timed foot targets

The demonstrated improvement in hardware gait quality and stability is assessed qualitatively.

What does a skill look like?

Two feet.
Half a cycle apart.

Speed sets the step frequency and swing amplitude. Each foot follows a cosine swing and lifts during half the cycle. The skill evaluates this rule at future arrival times and adds the resulting foot goals to the velocity and heading prompt.

The stance widens for sideways travel, and the swing axis follows the travel direction with reduced lateral motion. Metatron supplies the whole-body response.

Moving-gait pseudocode based on the C++ deployment. Standing holds and turning corrections are omitted.

View simplified skill code
# speed in m/s; frequency in Hz; distances in m
frequency = min(2.0, 0.83 + 0.93 * speed)
amplitude = 0.13 + 0.065 * speed
phase += 2 * pi * frequency * dt

for time in future_times:
    for foot, shift in [(right, 0), (left, pi)]:
        angle = phase + 2 * pi * frequency * time + shift
        offset = stance_offset(foot, travel_angle)
        offset.xy += amplitude * cos(angle) * swing_axis
        offset.z += 0.08 * max(0, -sin(angle))
        goals.add(foot, to_world(offset, time), time)

# Foot goals + velocity + heading → frozen Metatron
03 / Agent-authored skills · G1 in MuJoCo

New tasks.
Same frozen policy.

For these simulated tasks, GPT-6 Astra refined goal-setting code, timing, and motion references under human direction. No task-specific policy training.

Running → jump goals → running

Four hurdles. One continuous run.

Switch from running goals to a reference jump before each bar, then resume running as both feet clear it. Repeat without resetting the robot or policy.

4 × 20 cm hurdles · 5 m apart · zero bar contacts in this run

Goals supplied Concept + pseudocode

Forward velocity, heading, and torso XY goals guide the run. At 2.6 m from a known bar, replace velocity conditioning with timed position and rotation goals for the torso, hands, and feet, sampled from a reference jump aligned over the bar. Once both feet clear, return to running goals.

# Conceptual pseudocode — not a runnable API
for bar in course:  # four bars, 5 m apart
    run(speed=3.3, heading=forward, lane=center)
    when distance_to(bar) <= 2.6:
        track_jump_goals(aligned_over=bar)
    when both_feet_clear(bar, margin=0.12):
        resume_running(ramp_seconds=0.32)

Approaches average 3.07–3.17 m/s; the robot slows during each jump. The bar locations are supplied by task code, not perceived by the policy. Illustrative names; control details abbreviated.

Running → recovery → running

Fall. Get up. Carry on.

The robot runs into a 40 cm bar, falls, gets up, and resumes running.

3.83 m/s before impact · running again 3.28 s after the fall

Goals supplied Concept + pseudocode

Velocity and torso goals guide the run; hands and feet are free. A low torso held for 120 ms triggers upright five-body goals. Once upright, resume running. No obstacle-avoidance goal, reset, or teleport is used.

# Conceptual pseudocode — not a runnable API
# Height is measured above the lowest body.
height = torso_height / upright_height
if not recovering:
    recovering = below_for(height, 0.65, seconds=0.12)
elif height >= 0.90:
    recovering = False
if recovering:
    goals = timed_upright_pose(torso, hands, feet)
else:
    goals = track_running_goals(velocity, torso_path, heading)
policy.track(goals)

Illustrative names; control details abbreviated.

Motion reference + timed release

Send the ball down the lane.

A bowling reference guides the swing. After release, gravity and physical collisions determine the ball and pin motion.

9 of 10 pins knocked down

Goals supplied Concept + pseudocode

A bowling reference supplies torso, hand, and foot poses in global and local frames. Scene code releases the simulated grasp at a set time; physics moves the ball.

# Conceptual pseudocode — not a runnable API
horizons = [0.1, 0.2, 0.4, 0.6, 0.8]
poses = bowling_reference.sample(future_motion_times)
goals = body_pose_goals(poses, torso + hands + feet,
                        horizons, frames="global + local")
policy.track(goals)
if time >= 2.3:
    scene.release_ball_grasp()  # Physics takes over.

Illustrative names; control details abbreviated.

Motion reference + physical racket

Meet the ball.

A forehand reference drives a racket into a dropped ball, sending it over the net to the opposite side of the court.

5.37 m/s outgoing ball speed

Goals supplied Concept + pseudocode

A forehand reference supplies five-body poses. Hand targets guide the attached racket. Scene code drops the ball at a set time: a timed drill, not visual ball tracking.

# Conceptual pseudocode — not a runnable API
horizons = [0.1, 0.2, 0.4, 0.6, 0.8]
poses = forehand_reference.sample(future_motion_times)
policy.track(body_pose_goals(
    poses, torso + hands + feet, horizons,
    frames="global + local"))
if time >= 1.2:
    scene.drop_ball()  # Racket contact sets its flight.

Illustrative names; control details abbreviated.

Foot targets + contact physics

Follow through on the kick.

Timed goals guide the kicking foot into a passive football. The ball moves through contact—not a scripted trajectory.

2 m approach · 4.82 m/s peak ball speed

Goals supplied Concept + pseudocode

Approach with velocity and torso goals. Near the ball, switch to timed foot targets: draw back, strike, and follow through. Keep the support foot planted; leave the hands free.

# Conceptual pseudocode — not a runnable API
if distance_to_ball > 0.7:
    goals = approach_goals(speed=1.5, heading=toward_ball)
else:
    goals = timed_kick(
        support_foot=planted, torso=balanced_stance,
        kicking_foot=[(0.08, backswing), (0.18, strike),
                      (0.36, forward_and_up), (0.98, settle)])
policy.track(goals)  # No force or velocity is applied to the ball.

Illustrative names; control details abbreviated.

04 / The training recipe

Learn from complete motion.
Act on partial goals.

Dense reference motions teach coordination. Masked on-policy distillation makes that capability available through a flexible goal interface.

01

Train the tracker

Full reference motions supervise dense whole-body tracking.

Reinforcement learning
02

Distill Metatron

The frozen tracker supervises a generative policy with masked goals.

On-policy distillation
03

Deploy the policy.
Supply goals in code.

On-device · C++ skill codeskill(state) → goals
Frozen Metatronactions
No task-specific policy training

After stage 2, Metatron’s weights are frozen. Stage 3 adds skills through goal-setting code, without further policy training. On the robot, C++ skill code updates goals from the current state; Metatron turns them into joint targets.

05 / Try it yourself · MuJoCo

Interactive
Web Demo

Steer the G1, change its motion style, or give it a destination. The actual policy and physics simulation run in your browser.

Launch interactive demo

Desktop recommended
First load downloads and prepares the model. Later visits can reuse cached weights.

NVIDIA Metatron browser demo showing G1 getting up from the floor
06 / More G1 demonstrations

More ways to move.

From everyday interaction to dynamic motion, explore the goals behind each G1 example.

G1 / Real robot

Direct the motion,
not every joint.

An Xbox controller specifies travel velocity and heading. Timed foot-placement goals guide the gait; the same policy coordinates the rest of the body.

Goals supplied
VelocityHeadingFoot targets
Policy weights unchanged

The skill generates goals, not joint actions.

These behavior clips play at real-time 1× speed. These modes share one G1 policy and deployment stack; switching modes changes the goals and their masks, not the policy weights. The scene-geometry simulation grid illustrates prompting with a separate sitting policy.

Metatron · Full narrated film

Inside the goal interface

Specify what matters.

Combine any subset of these goals in one prompt. Metatron generates the remaining motion.

Where is the target defined?

From motion data to skill code

Train the controller. Then build skills.

Two stages learn the policy. The third develops skills with its weights frozen.