Skip to main content
This is the full loop, on one page:
Each arrow is one command. By the end you will have taught a robot a task by showing it, not programming it.

1. Demonstrate

Two ways to produce demonstrations. Both record the same thing β€” camera frames, joint states, and episode markers β€” into a timestamped session database.

With a VR headset

Best when you have a Quest 3. You see what you are doing, and the arm tracks your hand.
Open https://<host-ip>:8443/teleop in the Quest browser, accept the certificate, tap Connect. Then: A take is: hold A, move into place, press B, do the task, press B again. The terminal confirms every save:
Save each good take with B before quitting β€” an episode still recording at shutdown is dropped.

By hand-teaching

Best for arms you can move by hand. The Galaxea A1Z runs gravity compensation while you guide it through the task:
SPACE starts an episode and saves it, g toggles the gripper, d discards β€” and pressing d between episodes undoes the last save. Real hardware only for now; there is no A1Z simulator yet. Replay any episode to check what you captured:

What you end up with

Either way, the recorder prints the path of a session database:
One file per run, never overwritten. It holds three streams: color_image, coordinator_joint_state, and the episode start/save/discard markers. Record enough successful episodes to cover the variation the policy will encounter, including camera pose, lighting, object pose, and motion timing.

2. Build a dataset

DataPrep reads the session database, aligns camera and joint streams onto one clock, splits at the episode markers, and writes a training dataset:
The config maps recorded streams to dataset features β€” which stream is the observation image, which is the state, what rate to resample at. Copy example_config.json and adjust; the A1Z ships its own at dataprep/galaxea_a1z_state_config.json. By default the action for each frame is the next frame’s measured joint state, which is what next-state behavioral cloning expects. Output is a LeRobot v3 dataset by default; pass -f hdf5 for HDF5. Check what you built:
You get features, shapes, dtypes, and episode counts β€” worth a look before spending GPU hours. Each dataset also carries a dimos_meta.json recording exactly how it was built.

3. Train

Training happens in LeRobot, pointed straight at your DataPrep output. No upload step, no format shuffling:
Use --policy.device=mps on Apple silicon or cpu for a slow smoke test. Policy quality depends on demonstration count, consistency, and coverage; a completed training run does not by itself mean the policy will generalize. The checkpoint you deploy lands at:

4. Run it on the robot

LeRobotPolicyModule wraps the checkpoint as a DimOS module: camera frames and joint states in, joint commands out, at the policy’s control rate. On the A1Z it is one command:
It will not surprise you: loading and hardware initialization ask for confirmation, and inference starts only once live camera and joint observations are flowing. For other arms, compose LeRobotPolicyModule into a blueprint next to a camera and the coordinator. The module never moves hardware at startup β€” its execute_learned_policy skill starts inference explicitly, and stop_learned_policy halts it with the robot holding position. For the complete A1Z dependency setup, exact dataset conversion command, camera selection, safety notes, and multi-policy agent blueprint, use the Galaxea A1Z hardware and learning guide.

When something looks wrong

Work backwards through the loop. A policy behaving strangely is usually a dataset problem; a dataset problem is usually a recording problem.
  • dimos dataprep inspect β€” do shapes, rates, and episode counts match what you expect?
  • dimos a1z replay β€” does the recorded motion look like what you demonstrated?
  • Recordings from before the coordinator_joint_state stream rename need a config pointing at the old name β€” or just re-record.