Skip to content

Record & controller·

start/stop LeRobot v3 episode recording and the PS4 controller teleop loop — every drive becomes training datatools/rover_record.py, 6 tools.

From the module docstring

🎬 LeRobot dataset recording + 🎮 PS4 controller — agent-facing @tool wrappers.

tool does
start_recording Start recording a new LeRobot dataset episode.
stop_recording Stop the current recording episode and save it to the dataset.
recording_status Get the current recording engine status (running, episode, frames).
controller_start Enable the PS4 controller teleop background thread.
controller_stop Disable the PS4 controller teleop and stop the rover.
controller_status Get the current PS4 controller status (connected, axis values).

start_recording·

start_recording(task: str = 'drive') -> Dict[str, Any]

Start recording a new LeRobot dataset episode.

Captures front (+ rear, if present) cameras, full telemetry state vector, last-commanded action, and microphone audio at the configured FPS (default 10) into a versioned LeRobot v3 dataset on disk.

Each call to start_recording → stop_recording produces ONE episode. The dataset is created on the first run and APPENDED on subsequent runs, so you can build it up over many sessions.

argument meaning
task Short natural-language label for what the rover is doing in this episode (e.g. "navigate to crosswalk", "follow sidewalk"). Stored as the LeRobot 'task' string and used for task-conditioned training later.

Returns

Dict with status and: episode_index, fps, dataset_root.

source: tools/rover_record.py:39

stop_recording·

stop_recording() -> Dict[str, Any]

Stop the current recording episode and save it to the dataset.

Encodes captured frames into MP4 video files, writes the parquet rows for state/action, and persists episode metadata. Audio (if captured) is written as a WAV sidecar at /audio/episode_NNNNNN.wav.

Returns

Dict with status and: frames captured, duration, dataset_root.

source: tools/rover_record.py:81

recording_status·

recording_status() -> Dict[str, Any]

Get the current recording engine status (running, episode, frames).

Returns

Dict with status and full engine state JSON (recording, total_episodes,
current_frames, current_duration_s, dataset_root, …).

source: tools/rover_record.py:114

controller_start·

controller_start() -> Dict[str, Any]

Enable the PS4 controller teleop background thread.

Starts polling a connected DualShock 4 (or compatible SDL2 joystick) and forwarding commands to the rover. Updates ACTION_STATE so any active recording captures the human action stream tagged source='controller'. The agent and the controller share the rover — whichever issues the most-recent /control wins.

Mapping: Left stick Y → linear (forward / reverse, scaled to ±0.7) Right stick X → angular (turn, scaled to ±0.9) L2 trigger → soft brake R2 trigger → boost (allows up to ±1.0) Square → toggle headlamp Circle → emergency stop (zero velocities) Triangle → start_recording('controller-teleop') Cross (X) → stop_recording

Tune limits with env vars: ROVER_CONTROLLER_LINEAR_MAX, ROVER_CONTROLLER_ANGULAR_MAX, ROVER_CONTROLLER_DEADZONE, ROVER_CONTROLLER_HZ.

Returns

Dict with status and connection state. If no joystick is found,
status='error' with a hint to plug one in.

source: tools/rover_record.py:155

controller_stop·

controller_stop() -> Dict[str, Any]

Disable the PS4 controller teleop and stop the rover.

Kills the background polling thread and sends a final zero-velocity /control to the rover so it doesn't keep moving on the last command.

Returns

Dict with status.

source: tools/rover_record.py:210

controller_status·

controller_status() -> Dict[str, Any]

Get the current PS4 controller status (connected, axis values).

Returns

Dict with status, device name, current axis values (linear/angular),
lamp state, and any error message.

source: tools/rover_record.py:229