make lerobot record easier

This commit is contained in:
Pepijn
2026-03-02 20:17:50 +01:00
parent a2246a650b
commit 7940bfad52
2 changed files with 15 additions and 21 deletions
+3 -12
View File
@@ -487,18 +487,9 @@ def record(cfg: RecordConfig) -> LeRobotDataset:
robot = make_robot_from_config(cfg.robot)
teleop = make_teleoperator_from_config(cfg.teleop) if cfg.teleop is not None else None
# Dataset features derived automatically from robot/teleop pipelines
if teleop is not None:
dataset_features = build_dataset_features(robot, teleop, use_videos=cfg.dataset.video)
else:
# Policy-only recording: use robot observation features only
from lerobot.datasets.pipeline_features import aggregate_pipeline_dataset_features, create_initial_features
dataset_features = aggregate_pipeline_dataset_features(
pipeline=robot.output_pipeline(),
initial_features=create_initial_features(observation=robot.raw_observation_features),
use_videos=cfg.dataset.video,
)
# Dataset features derived automatically from robot/teleop pipelines.
# When teleop is None (policy-only recording), only observation features are included.
dataset_features = build_dataset_features(robot, teleop, use_videos=cfg.dataset.video)
dataset = None
listener = None
+12 -9
View File
@@ -27,7 +27,7 @@ from lerobot.datasets.utils import combine_feature_dicts
def build_dataset_features(
robot,
teleop,
teleop=None,
*,
use_videos: bool = True,
) -> dict:
@@ -35,15 +35,16 @@ def build_dataset_features(
Derive dataset feature specifications from robot and teleoperator pipelines.
Uses the robot's ``output_pipeline`` and ``raw_observation_features`` to determine
what the dataset will store as observations, and the teleoperator's ``output_pipeline``
and ``raw_action_features`` to determine what will be stored as actions.
what the dataset will store as observations, and (when provided) the teleoperator's
``output_pipeline`` and ``raw_action_features`` to determine what will be stored as actions.
This replaces the old pattern of manually calling ``aggregate_pipeline_dataset_features``
with explicit processor objects.
Args:
robot: The robot instance (must have ``output_pipeline()`` and ``raw_observation_features``).
teleop: The teleoperator instance (must have ``output_pipeline()`` and ``raw_action_features``).
teleop: The teleoperator instance. When ``None`` (policy-only recording), only observation
features are returned.
use_videos: If True, image observations are included as video features.
Returns:
@@ -51,17 +52,19 @@ def build_dataset_features(
Example::
dataset = LeRobotDataset.create(
repo_id="...",
fps=30,
features=build_dataset_features(follower, leader, use_videos=True),
)
# Teleop recording
features = build_dataset_features(follower, leader, use_videos=True)
# Policy-only recording (no teleop)
features = build_dataset_features(robot, use_videos=True)
"""
obs_features = aggregate_pipeline_dataset_features(
pipeline=robot.output_pipeline(),
initial_features=create_initial_features(observation=robot.raw_observation_features),
use_videos=use_videos,
)
if teleop is None:
return obs_features
action_features = aggregate_pipeline_dataset_features(
pipeline=teleop.output_pipeline(),
initial_features=create_initial_features(action=teleop.raw_action_features),