useTrajectoryRecorder directly, or raw qpos arrays.
Signature
Usage
Record and Replay
Record a trajectory withuseTrajectoryRecorder, then play it back directly — no format conversion needed:
Options
| Field | Type | Default | Description |
|---|---|---|---|
fps | number | 30 | Playback frame rate |
speed | number | 1.0 | Speed multiplier (0.5 = half speed, 2 = double) |
loop | boolean | false | Loop when reaching the end |
mode | "kinematic" | "physics" | "kinematic" | Playback mode (see below) |
onComplete | () => void | — | Called when playback reaches the end (non-looping) |
onStateChange | (state: PlaybackState) => void | — | Called on every state transition |
Return Value
| Field | Type | Description |
|---|---|---|
play | () => void | Start or resume playback |
pause | () => void | Pause playback |
seek | (frame: number) => void | Jump to a specific frame |
reset | () => void | Reset to frame 0, return to idle state |
setSpeed | (speed: number) => void | Change playback speed at runtime |
state | PlaybackState | Current state: "idle", "playing", "paused", or "completed" |
frame | number | Current frame index |
playing | boolean | Shorthand for state === "playing" |
totalFrames | number | Total number of frames in trajectory |
progress | number | Normalized progress from 0 to 1 |
State Machine
Playback Modes
Kinematic (default)
Pauses the simulation and writesqpos directly from the trajectory, calling mj_forward to update positions for rendering. No physics stepping occurs. The simulation resumes when playback completes or reset() is called.
Physics
Keeps the simulation running and appliesctrl values from the trajectory each physics step via useBeforePhysicsStep. Frame advancement is based on simulation time (data.time) rather than wall-clock time. Use this mode to replay recorded control inputs through the physics engine, which is useful for comparing recorded vs. simulated behavior.
Requires trajectory frames with ctrl data (use useTrajectoryRecorder with fields: ["qpos", "ctrl"]).
Notes
- In kinematic mode, the simulation’s previous pause state is restored on
reset()or completion - The trajectory input accepts both
TrajectoryFrame[]andnumber[][]— format is auto-detected - For a declarative component API, see
<TrajectoryPlayer>