1. Record demonstrations
Two supported ways to demonstrate. Whichever you use, three data-quality rules apply:- Write a real task description (
--task/default_task_label). Language-conditioned policies train on this text; a placeholder bakes in uselessness. - Stay out of the camera frame. The policy trains on exactly what the camera sees; at deployment there is no human in the scene.
- Record the gripper. If the task grasps, the gripper channel must be in the observation and action.
Option A: teach mode (kinesthetic) - recommended
On arms that support it (currently the Galaxea A1Z), put the arm in gravity-compensated zero-force mode and drag it through the task:.db path. Full details, safety notes, and camera options: Galaxea A1Z.
Option B: Quest VR teleop
Run a collection blueprint. Add--simulation to drive MuJoCo; omit it for real hardware (a RealSense + the arm):
A take is: hold A to move the arm into place, press B to start, perform the task, press B to save (or Y to throw it away). The terminal prints one line per transition:
End each good take with B before quitting - an episode still recording at shutdown is dropped.(Keyboard teleop also exists, but do not collect training data with it. See choosing a teleop method.)
Where recordings go
.db file per session, nothing overwritten. Quest sessions record color_image, coordinator_joint_state, and status (episode start/save/discard markers); the exact path is printed when the recorder starts.
2. Build a dataset
DataPrep is an offline batch step that reads a session DB and writes a dataset. The observation/action stream mapping comes from a JSON config. For the A1Z, a ready-made config ships in the repo:dimos/learning/dataprep/example_config.json and edit to taste:
--source / --output / --format override the config, so one config serves many sessions. Inspect the result (features, shapes, dtypes, episode/frame counts):
dimos_meta.json sidecar recording exactly how it was built.
Config fields that matter
source- the session.db.observation/action- map a dataset feature name to a recorded{stream, field}. Action defaults to the next frame’s joint state (action_shift: 1), giving a next-state behavioral-cloning target.sync- resample everything onto one timeline:anchorstream,rate_hz, nearest-matchtolerance_ms.output-format(lerobot|hdf5),path, andmetadata(robot,default_task_label, …).
3. Train a policy
The LeRobot dataset is the handoff point. What it unlocks, roughly in order of effort:- ACT - the reliable baseline. On the order of 50-100 good episodes per task; trains in hours on a single consumer GPU with LeRobot’s standard training scripts.
- SmolVLA - a small language-conditioned VLA, fine-tunable on a consumer GPU.
- pi0 / pi0-FAST - fine-tunable in LeRobot, but wants datacenter-class GPUs.
- GR00T - NVIDIA’s fine-tuning pipeline consumes LeRobot datasets directly.
outputs/<job_name>_act/checkpoints/last/pretrained_model.
4. Run the policy on the robot
LeRobotPolicyModule wraps a checkpoint as a DimOS module: camera frames and joint states in, joint commands out, at the policy’s control rate. It never moves hardware at startup - its execute_learned_policy skill starts inference explicitly, and stop_learned_policy halts it with the robot holding position.
On the Galaxea A1Z it is one command:
LeRobotPolicyModule into a blueprint next to a camera and the coordinator.
Status: collection and dataset export work on every supported arm. Running a trained checkpoint back on hardware ships today on the A1Z; for other arms, compose
LeRobotPolicyModule yourself. Training runs in LeRobot outside of DimOS. The exported dataset remains the stable interface between the two halves.Notes
- Sim vs real camera - under
--simulationthe MuJoCo camera suppliescolor_image; on real hardware a RealSense does. The blueprint picks the right one automatically. - “action” is the measured next joint state, not a recorded command. For true commanded actions you would record
joint_commandand mapactionto it. - Old sessions - recordings made before the
coordinator_joint_staterename use the old stream name; point a matching config at them, or re-record.
