COLLECT
COLLECT records teleoperation episodes to a standard robot-learning dataset, with PASS/FAIL review in the same tab.
Overview
COLLECT is the third of the console's six tabs (DEBUG · MANUAL · COLLECT · REPLAY · EVAL · RESULT). It runs no policy: each episode records the arm's state alongside the operator's commanded action, so the dataset is replayable and trainable in one pass.
collection section (see below). No separate process.Prerequisites
evaon PATH (see Installation).- Robot powered, leader/follower rig running.
- Data source publishing — for ROS, drivers and camera nodes up (e.g.
roscoreplus arm/camera nodes). - A collection config for the robot (see below).
Use MANUAL first to confirm motion and camera streams.
Why COLLECT may be greyed out
- No collection config → COLLECT disabled (DEBUG, MANUAL, REPLAY still work).
- Collection config present → COLLECT enabled.
Relaunch with a collection config; see below.
Workflow
| # | Step | Action |
|---|---|---|
| 1 | TASK | Pick the task (list comes from collection.tasks). Saved with the episode; each task gets its own folder. |
| 2 | START | Recording begins. Status: COLLECTING; frame count climbs. |
| 3 | STOP | Episode is handed to the background saver. Status: SAVING until written. |
| 4 | QC | Replay and mark PASS/FAIL, with optional note. |
While recording
- START — recording begins immediately. Save and image encode run on a background worker; capture never blocks.
- Backlog — if the host can't keep up, the queue grows and a warning is logged; recording continues.
- Warm-up frames dropped — initial frames before the leader is tracking carry no action and are skipped.
- STOP — episode is validated, packed, and queued for save; you can start the next one immediately. Empty episodes (0 frames) are discarded.
- Cancel — discards everything captured so far.
Status line: COLLECTING, SAVING, QUEUE_FULL, or IDLE, plus frame count, queue depth, and ETA.
Success and common faults
| Symptom | Cause / action |
|---|---|
| Frame count stuck at 0 | No data arriving. Verify drivers and that config topic names match the publishers. |
| Camera black / missing | Stream down or camera name mismatch. Confirm via MANUAL. |
QUEUE_FULL | Saver behind. Wait for IDLE; if persistent, lower fps or raise save_queue_max. |
| Episode red on review | An auto-check fired — see Quality control. |
Quality control
On STOP, replay the episode and mark PASS/FAIL. In addition, every episode runs through automatic checks; any failure marks it red and persists the reasons alongside the data.
| Flag | Raised when | Action |
|---|---|---|
episode_too_short | Fewer frames than min_episode_frames. | Re-record longer, or lower the threshold. |
non_monotonic_timestamp | A frame's timestamp does not advance past the previous. | Re-record. If recurring, check the publisher clock. |
missing_camera · invalid_image_shape | Configured camera absent, or image not H×W×3. | Verify stream and config name match. |
missing_configured_column · invalid_vector_dim | Configured field missing or wrong length. | Verify topic publishing and arm count. |
non_finite_value | NaN/Inf in a recorded value. | Auto-zeroed; re-record if frequent. |
frame_count_mismatch | Camera video frame count differs from the data table. | Re-record; indicates dropped/stalled camera. |
For deeper review and adding instruction text per episode, use REPLAY.
Writing a collection config
A config becomes a collection config the moment it declares columns to record — that is what enables the tab. A collection config inherits a per-robot deploy file via _base_ and adds a collection section (see Configuration).
Settings
| Setting | Purpose |
|---|---|
storage.log_dir | Output root. Per-task subfolders. Empty → default folder named after the config. |
storage.fps | Target frame rate. |
storage.save_queue_max | Max episodes queued for save. Full → QUEUE_FULL. |
schema.robot_type | Robot id, e.g. agilex_AGILEX. |
schema.min_episode_frames | Threshold for episode_too_short. |
schema.arms | Arms to record, one entry each. |
schema.cameras | Cameras to record. At least one required. |
schema.columns | The four required dataset fields: qpos, eef, action_qpos, action_eef. |
transport.ros1.groups | Per-arm source topics for observed and commanded state. Use ros2 for ROS 2. |
tasks | Task strings offered in the TASK picker. |
Copy the shipped collection config for your robot (e.g. configs/02_collection/dual_agilex_AGILEX.py) and edit the marked values. Lines marked ← change… must match your robot.
_base_ = ['<path to your robot's deploy _base.py>'] # ← point at your robot's deploy config collection = dict( storage=dict( log_dir='', # ← where to save (empty = a default folder named after this config). fps=30, # sane default; change only if your robot runs at another rate. save_queue_max=15, # sane default. ), schema=dict( robot_type='<your robot type>', # ← e.g. 'agilex_AGILEX'. min_episode_frames=10, # sane default. arms=dict(left_arm='left', right_arm='right'), # ← one entry per arm. cameras=dict( cam_high='observation.images.cam_high', # ← list your cameras (name → dataset field). ), columns=dict( # keep these four keys; values are standard dataset field names. qpos='observations.state.qpos', eef='observations.state.eef', action_qpos='action.qpos', action_eef='action.eef', ), ), transport=dict( ros1=dict(groups=dict( left_arm=dict( qpos_topic='<arm joint topic>', # ← change to your robot's real topics. eef_topic='<arm gripper-pose topic>', action_qpos_topic='<commanded joint topic>', action_eef_topic='<commanded gripper-pose topic>', ), # ...repeat for each arm. )), ), tasks=['<your task instruction>'], # ← e.g. 'pick up the apple'. )
Save under configs/02_collection/ and launch. The loader enforces:
- All four
columnskeys present —qpos,eef,action_qpos,action_eef. cameraslists at least one camera.armslists at least one arm.
Launching
eva --config configs/02_collection/my_robot.py
Open the console at http://localhost:8080 (override via --web-port, see CLI reference). Episodes are replayable through the dataset transport and reviewable in REPLAY.