Sentinel

Collect data

Record teleoperation episodes and manage their outcomes.

Sentinel records teleoperation into episodes — one recording per attempt at a task. This page covers turning recording on, starting and ending episodes, and what happens to each outcome. The on-disk result is documented in Using your data.

Enable recording

Recording is controlled by the robot configuration:

system:
  enable_dataset_recording: true

dataset_recording:
  enabled: true
  output_dir: "/datasets"
  storage_format: "mcap"
  max_bag_size_bytes: 1073741824   # split MCAP files at 1 GiB
  min_free_disk_bytes: 5368709120  # stop recording below 5 GiB free
  fps: 30.0
  topics:
    - /sentinel/events
    - /sentinel/xr/input/xr_input
    # ... robot state, commands, and encoded camera topics

The topics list defines exactly what each episode contains. Include the measured state, command, and encoded camera topics for every system you want in the dataset — the configuration templates ship with a complete list for their hardware.

The launcher creates a datasets/ directory next to the Sentinel folder on the host and mounts it at /datasets, so recordings survive container restarts. It also sets ENABLE_RECORDING=true in the container environment.

Recording stops when free disk space falls below min_free_disk_bytes. Check available space before a long collection run.

Start and end episodes

During a session, the operator controls episodes from the headset. With the default controller mapping:

InputAction
X buttonProgress the episode: start one if none is active, advance to the next subtask, and on the last subtask complete it and finish the episode as successful
Y buttonFail the current subtask and the episode
Y button (long press)Delete the most recent episode

The same transitions are available over HTTP through the APIstart, finish, fail, and discard — so an external system can drive collection without operator input.

Select the active task before starting an episode and advance through its subtasks as you work. Sentinel snapshots the task, prompt, and operator context when the episode begins. See Tasks, subtasks, and labels.

Episode outcomes

OutcomeHow it happensWhat is kept
SuccessX button through the last subtask, or the API's finishThe finalized recording
FailureY button or the API's failDepends on the configured retention policy. The default retains the finalized recording.
DiscardedLong-press Y (most recent episode) or the API's discard (active episode)Nothing — the recorded files are deleted

Discarding permanently deletes the recording — the API's discard removes the active episode, and long-pressing Y removes the most recent one. Use a failure outcome for unsuccessful attempts you want to keep for labeling or training, and confirm the failed-episode retention policy before relying on that data.

Decide what counts as success before a collection run begins and apply it consistently across operators — outcome labels are much cheaper to record now than to reconstruct from video later.

Check the output

Episodes land in timestamped session directories under datasets/:

datasets/
└── session_20260718_143052/
    ├── episode_001.finalized/
    └── episode_002.finalized/

An active recording uses the .in_progress suffix and must not be treated as complete. See Using your data for the directory layout, recorded topics, message schemas, and episode metadata.

Next step

Structure the data with tasks and labels

Define tasks, subtasks, and outcome criteria before a collection run.