From 43827426815df8de41738d3f4e7b8a3e78fa3cd3 Mon Sep 17 00:00:00 2001 From: Pepijn <138571049+pkooij@users.noreply.github.com> Date: Mon, 15 Sep 2025 14:39:05 +0200 Subject: [PATCH] fix teleop, record and eval (#1940) --- examples/phone_to_so100/evaluate.py | 12 ++++++++++-- examples/phone_to_so100/teleoperate.py | 7 +++---- .../so100_follower/robot_kinematic_processor.py | 2 +- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/examples/phone_to_so100/evaluate.py b/examples/phone_to_so100/evaluate.py index 0d22295d0..a9a872f52 100644 --- a/examples/phone_to_so100/evaluate.py +++ b/examples/phone_to_so100/evaluate.py @@ -17,6 +17,7 @@ from typing import Any from lerobot.cameras.opencv.configuration_opencv import OpenCVCameraConfig +from lerobot.configs.types import FeatureType, PolicyFeature from lerobot.datasets.lerobot_dataset import LeRobotDataset from lerobot.datasets.pipeline_features import aggregate_pipeline_dataset_features, create_initial_features from lerobot.datasets.utils import combine_feature_dicts @@ -106,9 +107,16 @@ dataset = LeRobotDataset.create( initial_features=create_initial_features(observation=robot.observation_features), use_videos=True, ), + # User for now should be explicit on the feature keys that were used for record + # Alternatively, the user can pass the processor step that has the right features aggregate_pipeline_dataset_features( - pipeline=robot_ee_to_joints_processor, - initial_features=create_initial_features(action=robot.action_features), + pipeline=make_default_teleop_action_processor(), + initial_features=create_initial_features( + action={ + f"ee.{k}": PolicyFeature(type=FeatureType.ACTION, shape=(1,)) + for k in ["x", "y", "z", "wx", "wy", "wz", "gripper_pos"] + } + ), use_videos=True, ), ), diff --git a/examples/phone_to_so100/teleoperate.py b/examples/phone_to_so100/teleoperate.py index b0ba95dee..f9aceeaa3 100644 --- a/examples/phone_to_so100/teleoperate.py +++ b/examples/phone_to_so100/teleoperate.py @@ -63,14 +63,13 @@ phone_to_robot_joints_processor = RobotProcessorPipeline[RobotAction, RobotActio max_ee_step_m=0.10, max_ee_twist_step_rad=0.50, ), + GripperVelocityToJoint( + speed_factor=20.0, + ), InverseKinematicsEEToJoints( kinematics=kinematics_solver, motor_names=list(robot.bus.motors.keys()), ), - GripperVelocityToJoint( - motor_names=list(robot.bus.motors.keys()), - speed_factor=20.0, - ), ], to_transition=robot_action_to_transition, to_output=transition_to_robot_action, diff --git a/src/lerobot/robots/so100_follower/robot_kinematic_processor.py b/src/lerobot/robots/so100_follower/robot_kinematic_processor.py index bb81c72e2..523881151 100644 --- a/src/lerobot/robots/so100_follower/robot_kinematic_processor.py +++ b/src/lerobot/robots/so100_follower/robot_kinematic_processor.py @@ -272,7 +272,7 @@ class InverseKinematicsEEToJoints(ProcessorStep): def __call__(self, transition: EnvTransition) -> EnvTransition: new_transition = transition.copy() - act = new_transition.get(TransitionKey.ACTION) or {} + act = new_transition.get(TransitionKey.ACTION).copy() if not isinstance(act, dict): raise ValueError(f"Action should be a RobotAction type got {type(act)}")