Skip to main content
The robot controllers are the friendliest way to drive a robot: call action methods to get Step descriptors, collect them in a list, and run(). Nothing executes until run().
import cadenza_lab as cadenza

go1 = cadenza.go1()            # Unitree Go1 quadruped
g1  = cadenza.g1()             # Unitree G1 humanoid

How it works

Each action method (go1.jump(), go1.walk_forward(), …) returns a lightweight Step, a name plus modifiers. run() normalizes the list, looks each name up in the action library, applies your speed/extension overrides, and executes it on the simulator. A nested list runs as one concurrent, merged gait.

The Step descriptor

Step(name, speed=1.0, extension=1.0, repeat=1, distance_m=0.0, rotation_rad=0.0)
FieldMeaning
speedFor gaits: command-speed multiplier. For phase actions: motion-speed multiplier.
extensionScales joint displacement from the stand pose (phase) or step height (gait).
repeatRun the action N times.
distance_mTarget travel distance for locomotion (0 = action default).
rotation_radTarget rotation for turns (0 = action default).
You rarely build Step directly. The action methods do it for you.

Go1 action methods

Each returns a Step. Pass speed, extension, distance_m, rotation_rad, or repeat where they apply.
GroupMethods
Posturestand · stand_up · sit · lie_down · crouch · deep_crouch · rear_up
Locomotionwalk_forward · walk_backward · trot_forward · crawl_forward · pace_forward · bound_forward
Turning / strafingturn_left · turn_right · side_step_left · side_step_right
Skillsjump · climb_step · shake_hand · rear_kick
Escape hatchaction(name, **kwargs) for any library action by name
go1 = cadenza.go1()
go1.walk_forward(speed=1.5, distance_m=2.0)   # -> Step("walk_forward", speed=1.5, distance_m=2.0)
go1.turn_left(rotation_rad=1.57)              # quarter turn
go1.action("trot_forward", speed=1.2, repeat=2)

G1 action methods

The G1 humanoid scripted runner currently executes stand, crouch, walk_forward, jump, and hold:
g1 = cadenza.g1()
g1.run([g1.stand(), g1.crouch(), g1.walk_forward(distance_m=1.0), g1.stand(), g1.jump()])
The full G1 action library has 20 actions (arms, turns, etc.). Reach the rest through Sim, GymAdapter, or the stack. The scripted g1.run([...]) path is the balance-stabilized subset.

run()

run(sequence=None, *, goal=None, scene=None, target=None, on=None,
    model=None, sense=None, max_iterations=250, headless=False,
    verbose=True, streaming=False)
Two shapes:
go1 = cadenza.go1()
go1.run([
    go1.stand(),
    go1.walk_forward(speed=1.5, distance_m=2.0),
    go1.jump(),
])
When goal= is given, run() forwards to cadenza.stack.run. Otherwise it executes the sequence in the viewer.

Concurrency

Nest a list inside the sequence to fuse those actions into a single gait. Their velocity / yaw / step-height commands are merged:
go1.run([
    go1.stand(),
    [go1.turn_left(), go1.walk_forward()],   # turn while walking (one arc)
    go1.sit(),
])

Inference at construction

Attach a VLA orchestration strategy so each step is run “think-and-act” instead of open-loop:
from cadenza.inference import Sequential

go1 = cadenza.go1(inference=Sequential())
go1.run([go1.walk_forward(distance_m=5.0)])

Bundled assets

cadenza.Go1.model()             # path to the bundled Go1 scene XML
cadenza.Go1.terrain("terrain")  # path to a bundled terrain XML (use as xml_path)
go1 = cadenza.go1(xml_path=cadenza.Go1.terrain("terrain"))

Demo: a full Go1 routine

"""demo_robot.py: open the viewer and run a short Go1 routine.
Needs a display (opens a MuJoCo window). Close the window to exit.
"""
import cadenza_lab as cadenza

go1 = cadenza.go1()
go1.run([
    go1.stand(),
    go1.walk_forward(speed=1.3, distance_m=1.5),
    [go1.turn_left(), go1.walk_forward()],   # arc left
    go1.shake_hand(),
    go1.jump(speed=1.8, extension=1.2),
    go1.sit(),
])
python demo_robot.py

Send it to a real robot

The same Step list deploys to a physical Go1 / G1 over DDS, SSH, or a bridge.