Summary
Add multi-root support to LeRobotDatasource and read_lerobot. Accept a single root or a list of roots; output looks like one large dataset with a dataset_index column identifying which root each row came from. episode_index and index retain per-root local values.
Key changes
root parameter widens to str | Path | list[str | Path]
- One
LeRobotDatasourceMetadata per root; validate that video_keys, fps, and feature names match across roots
_slice tags each range with a root_index; slicers themselves are unchanged
LeRobotReadTask takes segments: list[(root_idx, start, end)] + metas list
_read_fn loops over segments; each segment runs the existing pipeline independently
_build_batch appends dataset_index: int32
- Single-root API is fully backward-compatible (
dataset_index is always present, 0 for single-root)
Out of scope
No stats merging, no episode/row offset remapping, no new classes.
Acceptance criteria
Summary
Add multi-root support to
LeRobotDatasourceandread_lerobot. Accept a single root or a list of roots; output looks like one large dataset with adataset_indexcolumn identifying which root each row came from.episode_indexandindexretain per-root local values.Key changes
rootparameter widens tostr | Path | list[str | Path]LeRobotDatasourceMetadataper root; validate thatvideo_keys,fps, and feature names match across roots_slicetags each range with aroot_index; slicers themselves are unchangedLeRobotReadTasktakessegments: list[(root_idx, start, end)]+metaslist_read_fnloops over segments; each segment runs the existing pipeline independently_build_batchappendsdataset_index: int32dataset_indexis always present,0for single-root)Out of scope
No stats merging, no episode/row offset remapping, no new classes.
Acceptance criteria
read_lerobot(["/data/ds1", "/data/ds2"])returns a singleray.data.Datasetdataset_index(int32) column