Back to Plotjuggler

Multimodal Robotics Dataset Format Comparison

docs/research/dataset_format_comparison.md

3.999.09.4 KB
Original Source

Multimodal Robotics Dataset Format Comparison

MCAP (ROS 2 / Foxglove) vs RLDS vs LeRobot vs Zarr

AspectMCAPRLDSLeRobot (v2/v3)Zarr
Primary purposeRecording & replay of live robot data streamsStoring RL/IL episodes for ML trainingStoring robot demonstrations for policy trainingStoring chunked N-dimensional arrays
Origin / ecosystemFoxglove / ROS 2 (default since Iron)Google Research / TensorFlow DatasetsHuggingFace / PyTorchZarr community (framework-agnostic)
Typical role in pipelineUpstream — raw recording format, converted to training formatsTraining format (OXE, OpenVLA, Octo, RT-X)Training format (SmolVLA, GR00T, π0, ACT)Training format (Diffusion Policy, UMI)

Data Model

AspectMCAPRLDSLeRobot (v2/v3)Zarr
Core abstractionChannels of timestamped messagesEpisodes → Steps (nested tf.data.Dataset)Episodes → Frames (Parquet rows + MP4 videos)Flat N-dimensional arrays with shared time axis
Data organizationMultiple named topics/channels in a single fileNested: Dataset of episodes, each containing a Dataset of stepsParquet files (tabular) + MP4 files (video) + JSON metadataHierarchical groups of arrays (/data/, /meta/)
Episode boundariesNo native concept — continuous recording; episodes defined by external metadata or topic flagsStructural: each episode is a separate nested Dataset with is_first/is_last/is_terminal flagsepisode_index column in Parquet; meta/episodes/ metadata filesmeta/episode_ends integer array storing end indices
SchemaEmbedded in file (ROS msg defs, Protobuf, JSON Schema, Flatbuffers)FeaturesDict defined in TFDS builder codeinfo.json with feature names, shapes, dtypesZarr array metadata (dtype, shape, chunks, compressor)

Timestamp & Synchronization

AspectMCAPRLDSLeRobot (v2/v3)Zarr
Timestamp modelEach message has log_time (nanoseconds) + optional publish_time; wall-clock timestampsNone per step — implicit from step ordering; some datasets add optional episode-level timestamptimestamp (float32, seconds) per Parquet row; VideoFrame = {path, timestamp} for imagesNone — pure integer index alignment
Timestamp resolutionNanosecond (uint64)N/AFloat32 seconds (~microsecond effective)N/A
Multi-modal syncBy timestamp join — each channel has independent timestamps; consumers must align by timeBy construction — all fields (image, state, action) are co-located in the same step recordBy timestamp seek — Parquet timestamp used to seek into MP4 video via PTSBy shared index — row N in all arrays corresponds to the same timestep
Misalignment riskPossible — channels can have different rates; requires interpolation or nearest-timestamp matchingZero — data is atomically recorded per stepNon-zero — depends on MP4 PTS alignment with Parquet timestamps; sub-frame drift can degrade policy performanceZero — if recording was truly synchronous; no mechanism to detect if it wasn't
Variable-rate supportNative — each channel can publish at its own rateNo — fixed step structurePartially — FPS declared in info.json, delta_timestamps for temporal queriesNo — all arrays must share the same time dimension
Temporal queriesIndex-based seeking by time range and channelIterate steps sequentially (or batch with RLDS transforms)delta_timestamps API (e.g., [-1.0, -0.5, 0] to get history)Native numpy/zarr slicing (array[start:end])

Image & Video Storage

AspectMCAPRLDSLeRobot (v2/v3)Zarr
Image storagePer-message: sensor_msgs/Image (raw) or sensor_msgs/CompressedImage (JPEG/PNG) as individual messagesPer-step: raw image tensor (H, W, 3) uint8 inline in TFRecordMP4 video files (H.264/H.265); one file per camera per episode (v2) or per chunk (v3)Per-frame in chunked array with configurable codec (JPEG-XL, Blosc, etc.)
Inter-frame compressionNo (each message is independent)No (each step is independent)Yes — full video codec with temporal compressionNo (each chunk/frame is independent)
Image access patternSeek to timestamp → decompress single messageRead Nth step record → decode image tensorSeek to PTS in MP4 → decode frame (via torchcodec or pyav)Read chunk at index N → decompress
Storage efficiency (images)Poor to moderate (per-frame JPEG/PNG)Poor (~70x larger than video)Best (inter-frame video compression)Moderate (per-frame JPEG-XL, ~10-20x better than raw, worse than video)
Video playbackNatural — sequential message replayRequires reconstruction from step imagesNatural — MP4 files are standard videoRequires reconstruction from array frames

File Format & I/O

AspectMCAPRLDSLeRobot (v2/v3)Zarr
Container formatSingle binary file (.mcap) with append-only row-oriented layoutTFRecord files (.tfrecord) partitioned by episode groupsParquet files + MP4 files + JSON/JSONL metadataDirectory tree of chunks + JSON metadata (or .zarr.zip)
Single file?Yes — all channels in one fileNo — multiple TFRecord shardsNo — separate Parquet, MP4, and metadata filesNo — directory of chunk files
CompressionChunk-level: LZ4 or ZstandardPer-record: PNG for images, TFRecord built-inVideo codec for images; Parquet compression for tabular dataPer-chunk: configurable (Blosc, JPEG-XL, LZ4, Zstd, none)
Write patternAppend-only streaming (crash-safe)Batch write via TFDS builder or EnvLoggerBatch write via LeRobotDataset.add_frame() + save_episode()Random or append; parallel chunk writes possible
Random readFast — built-in index by timestamp and channelRead Nth record in partitionParquet: memory-mapped; Video: seek to keyframe + decodeDirect chunk addressing by index
Cloud/streamingIndexed remote read via HTTP range requeststfds.load() with GCS/S3 supportHuggingFace Hub streaming (StreamingLeRobotDataset in v3)Native cloud support (S3, GCS) via chunk-per-object
Self-describingYes — schemas embedded in filePartially — schema in TFDS builder code, not in data fileYes — info.json with full feature schemaYes — metadata JSON alongside chunks

Ecosystem & Tooling

AspectMCAPRLDSLeRobot (v2/v3)Zarr
Language supportC++, Python, Go, Rust, Swift, TypeScriptPython (TensorFlow)Python (PyTorch)Python, Java, JavaScript, C++, Rust, Julia
ML frameworkNone (recording format)TensorFlowPyTorch / HuggingFaceFramework-agnostic
VisualizationFoxglove Studio, PlotJugglerTensorBoard (limited)Rerun.io via HF Visualize spaceCustom (no standard viewer)
Key consumersROS 2 ecosystem, Foxglove, PlotJugglerOXE, OpenVLA, Octo, RT-1-X, RT-2-XSmolVLA, GR00T (N1/N1.5/N1.6), π0, ACT, X-VLADiffusion Policy, UMI
CommunityROS Tooling WG + FoxgloveGoogle DeepMindHuggingFaceOpen Microscopy Environment, climate/geo, ML
Dataset sharingNo standard hub (files shared directly)TFDS catalog + GCSHuggingFace Hub (thousands of datasets)No standard hub

Strengths & Weaknesses Summary

AspectMCAPRLDSLeRobot (v2/v3)Zarr
Greatest strengthFaithful, lossless recording of heterogeneous live data with nanosecond timestamps; crash-safe streaming writesPerfect sync by construction; mature OXE ecosystem with 60+ unified datasetsBest storage efficiency (video compression); largest community dataset hub; PyTorch-nativeSimplest data model; numpy-like random access; framework-agnostic
Greatest weaknessNot a training format — must be converted; no episode/step structureTerrible storage efficiency (no video compression); TensorFlow-onlyTimestamp-based video sync introduces subtle alignment risksNo inter-frame compression; no timestamps; no standard sharing platform
Best suited forRobot data recording, logging, replay, debugging, fleet data collectionLarge-scale VLA pre-training in the Google/TF ecosystemGeneral-purpose robot learning with PyTorch; dataset sharing and collaborationSmall-to-medium manipulation datasets that fit in RAM; Diffusion Policy workflows
ScalabilityExcellent for recording (append-only); files can be terabytesGood for training (sharded TFRecords); poor for storage (8.9 TB for OXE uncompressed)Good (v3 scales to millions of episodes with chunked files)Moderate (excellent for cloud I/O; limited by per-frame compression for large video datasets)

Typical Pipeline Position

[Robot HW] → [MCAP recording] → [conversion] → [RLDS / LeRobot / Zarr] → [VLA/Policy training]
                 ↑                                        ↑
          live, lossless                          training-optimized
         multi-rate streams                    fixed-rate, synchronized
        nanosecond timestamps                  episode/step structure