Every robot has a fixed library of named base actions. These are the building
blocks for ActionCall, Sim.run, CLI group actions, and policy
outputs.
How an action becomes motion
An ActionSpec is either gait-based (a continuous locomotion command run by
the gait engine) or phase-based (a timed sequence of joint targets with
per-joint PD gains and motor schedules). The simulator dispatches on
spec.is_gait / spec.is_phase.
Look up actions
import cadenza_lab as cadenza
cadenza.list_actions("go1") # -> list[str] of action names
spec = cadenza.get_action("go1", "walk_forward") # -> ActionSpec
lib = cadenza.get_library("go1") # -> ActionLibrary
list_actions(robot) -> list[str]
get_action(robot, name) -> ActionSpec
get_library(robot) -> ActionLibrary
ActionLibrary
lib = cadenza.get_library("g1")
lib.robot # "g1"
lib.list_actions() # action names
lib.get("walk_forward") # -> ActionSpec
lib.describe() # human-readable summary of the library
ActionSpec
The full description of one action. Key fields:
| Field | Description |
|---|
name, description, robot | Identity. |
phases | Tuple of ActionPhase for phase-based actions. |
gait | A GaitAction for gait-based actions (else None). |
distance_m, rotation_rad, duration_s, speed_ms | Action defaults. |
max_pitch_rad, max_roll_rad | Abort thresholds. Exceed them and the action fails. |
hip_range, thigh_range, knee_range | Joint limits used by clamp_joints. |
spec = cadenza.get_action("go1", "walk_forward")
spec.is_gait # True
spec.is_phase # False
spec.total_duration() # seconds
jump = cadenza.get_action("go1", "jump")
jump.is_phase # True
[p.name for p in jump.phases] # ['crouch', 'hold_crouch', 'launch', ...]
Supporting dataclasses: GaitAction (gait command), ActionPhase (one timed
phase), JointTarget (12/16-DOF targets + kp/kd), and MotorSchedule
(per-joint velocity/torque caps and delays).
Action catalog
go1 (quadruped, 21)
g1 (humanoid, 20)
stand stand_up sit lie_down
jump walk_forward walk_backward trot_forward
crawl_forward turn_left turn_right precision_turn_left
precision_turn_right climb_step side_step_left
side_step_right pace_forward bound_forward rear_up
shake_hand rear_kick
stand stand_up sit lie_down
crouch deep_crouch lift_left_hand lift_right_hand
walk_forward walk_backward trot_forward crawl_forward
turn_left turn_right side_step_left side_step_right
jump shake_hand rear_kick rear_up
Action availability is per-robot, so always confirm with
cadenza.list_actions(robot) rather than assuming a name exists on both robots.
Parameterize with ActionCall
Wrap an action name with parameters to execute it (see
Gym adapter):
from cadenza_lab import ActionCall
ActionCall("walk_forward", distance_m=1.0)
ActionCall("turn_left", rotation_rad=1.57)
ActionCall("trot_forward", distance_m=2.0, speed=1.2)
Natural-language parsing
CommandParser turns a natural-language command into a list[ActionCall], the
same parser the one-liner cadenza.run(...) and the CLI’s scripted driver use.
The parser lives at cadenza.parser (the real module), not cadenza_lab.parser.
Import it as shown below.
from cadenza.parser import CommandParser
calls = CommandParser("go1").parse("walk forward 2 meters then turn left")
# [ActionCall(walk_forward, 2.0m), ActionCall(turn_left)]
Demo: explore the library
"""demo_actions.py: inspect the action library (headless, no viewer)."""
import cadenza_lab as cadenza
from cadenza.parser import CommandParser
for robot in ("go1", "g1"):
names = cadenza.list_actions(robot)
print(f"\n{robot}: {len(names)} actions")
for name in names:
spec = cadenza.get_action(robot, name)
kind = "gait " if spec.is_gait else "phase"
print(f" {kind} {name:<22} {spec.description}")
# Natural language → actions
calls = CommandParser("go1").parse("trot forward 3 meters then turn right then sit")
print("\nparsed:", [c.action_name for c in calls])