Robot data model — real episodes & source protocol

Three real robot classes. Pick a robot + tick: the two cards below show the concrete messages the SDK sends — the control-plane declaration (once) and the data-plane sample (this tick). Descriptor colour = provenance.

▸ Current transfer protocol — control plane vs data plane
CONTROL PLANE — once, on SourceDeclared (bidi Connect stream)
  • SDK sends one SourceDeclared{RobotSourceDescriptor} as the first event; Loop accepts it with a runtime source_id.
  • RobotSourceDescriptor carries source metadata and per-channel metadata (key·label·role·unit·rotation_type·range).
  • Descriptor channels are display/normalization metadata; per-tick robot values travel with their own keys in RobotPayload.state.
  • Changes are rare/structural → a new declaration, never per tick.
DATA PLANE — every tick (client-streaming StreamSamples)
  • Per source per tick: one SampleBatch{ source_id, samples: [Sample{ timestamp_us, sequence, RobotPayload{ state } }] }.
  • RobotPayload.state is a map from the robot signal key to a typed RobotValue; the data plane is self-describing.
  • Measured, commanded, and auxiliary robot signals can share one state map without runtime routing by source key.
  • Multi-rate (G1 control 50 / planner 10 Hz): each source streams at its own control_hz; slower signals are held or sent as their own source.

Why grouped (not a flat joint list)

  • Humanoid ≠ arm+gripper — G1 is legs+waist+arms+hands+floating base (43-DOF). rotation_type is first-class (quat/6D/euler). teleop_input is a third role. names count must == shape (G1 eef_state ships 4 names for 14 dims). Action is heterogeneous (joint targets + latent token).
source — from the dataset's own metadata (real)
inferred — our heuristic, NOT in the source
none — source provides nothing
▸ full source metadata (real)

① Control plane — SourceDeclared

sent once at declaration

    

② Data plane — Sample


    
Full channel table ▸ every channel with per-attribute provenance (source / inferred / none)
REAL · source data CHANNEL DESCRIPTOR · colour = provenance
source fieldidxvalue @ tickrole channel namegrouprotationunitrange

Real episodes at product/recorder_data_samples/ (Franka, Vega = recorder parquet; G1 = LeRobot/GR00T). Extracted by extract_real_examples.py. Messages are illustrative of the v2 proposal in docs/spec_discrepancies.md §A — values are real; descriptor colour = source/inferred/none.