zeroruntime.teleops.export reads a recorded session and
builds one row per observation. There is no ready-made LeRobot export script.
Write the rows into your dataset format yourself, because dataset layouts change
between LeRobot versions.
To check a session before you export it, print export.summarize(rows) for each
episode, as in Walking a session. It reports the row count,
the measured frame rate, and how many rows were joined by id rather than by time.
To drop the guessed rows, keep only rows whose correlation is explicit.
Walking a session
build_rows() is pure. It touches no filesystem beyond checking that the images
a row references exist, and it does not import LeRobot, so you can test a join
without a training stack installed.
Correlation quality
Each row records how its action was matched to its observation.explicit is what you want. temporal happens when the leader never stamped an
observation id, and those rows are labelled rather than mixed in silently, so you
can filter, weight or reject them.
Even an
explicit row is an upper bound rather than proof. The id a command
carries is the newest observation the leader had received, and video
reaches the operator’s screen by its own path with its own delay, so what they
were actually looking at may be slightly older.The follower records both ids for exactly this reason: observation_id is
what the leader claimed, observation_id_local is what was current on the
robot at that moment. The gap between them in applied.jsonl is the size of
the doubt, so you can measure it rather than assume it away.summarize() also gives you rows, fps_effective, fps_jitter_ms,
camera_skew_ms_max, camera_skew_ms_mean, obs_to_applied_ms_mean and
rows_limited.
fps_effective is measured from the joint read times rather than declared, so
a recording that ran at 27 Hz reports 27 rather than the 30 you asked for.
fps_jitter_ms is the spread around it.What a row holds
action is the operator’s target at the moment the frame was captured: what
a policy should predict from that frame. applied is what the arm was actually
told in response (after the safety limits), which arrives a fraction of a
second later, so training on it would teach a policy to lag. target is that
response before the limits, so the difference stays recoverable.
Per-camera capture times are kept rather than averaged away, so a wrist camera
running 60 ms behind the front camera is visible in the data.
Related
Recording format
The streams these functions read, and the drop counters to check first.
Recording
Turning recording on and bounding episodes.