LeRobot documentation

Bộ xử lý cho Robot và Người vận hành từ xa

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v0.6.1).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Bộ xử lý cho Robot và Người vận hành từ xa

Hướng dẫn này cho thấy cách xây dựng và chỉnh sửa các pipeline xử lý kết nối teleoperators (ví dụ: điện thoại) với robot và datasets. Các pipeline chuẩn hóa các phép chuyển đổi giữa các không gian hành động/quan sát khác nhau để bạn có thể thay thế teleops và robot mà không cần viết lại glue code.

Chúng tôi sử dụng các ví dụ Phone to SO‑100 follower để minh họa cụ thể, nhưng các mẫu này cũng áp dụng cho các robot khác.

Những gì bạn sẽ học

  • Kiểm soát EE tuyệt đối so với tương đối: Ý nghĩa của từng loại, các đánh đổi và cách lựa chọn cho tác vụ của bạn.
  • Mô hình ba đường ống: Cách ánh xạ hành động teleop → hành động tập dữ liệu → lệnh robot, và quan sát robot → quan sát tập dữ liệu.
  • Adapters (to_transition / to_output): Cách các adapter này chuyển đổi các dict thô sang EnvTransition và ngược lại để giảm bớt mã lặp lại.
  • Hợp đồng tính năng của Dataset: Cách các bước khai báo tính năng thông qua transform_features(...), và cách tổng hợp/gộp chúng để ghi lại.
  • Chọn biểu diễn: Khi nào nên lưu các khớp, tư thế tuyệt đối của EE, hoặc các delta tương đối của EE — và cách điều đó ảnh hưởng đến huấn luyện.
  • Hướng dẫn tùy chỉnh Pipeline: Cách thay thế robot/URDF một cách an toàn và điều chỉnh các giới hạn, kích thước bước, cũng như các tùy chọn như khởi tạo IK.

Kiểm soát EE tuyệt đối so với tương đối

Các ví dụ trong hướng dẫn này sử dụng tư thế tuyệt đối của đầu cuối (EE) vì chúng dễ suy luận. Trong thực tế, các delta tương đối của EE hoặc vị trí khớp thường được ưu tiên hơn như các đặc trưng học.

Với processors, bạn chọn các đặc trưng học tập muốn sử dụng cho chính sách của mình. Điều này có thể là vị trí/tốc độ của các khớp, EE tuyệt đối, hoặc vị trí EE tương đối. Bạn cũng có thể chọn lưu trữ các đặc trưng khác, chẳng hạn như mô-men xoắn khớp, dòng điện động cơ, v.v.

Ba pipeline

Chúng ta thường kết hợp ba pipeline. Tùy thuộc vào cấu hình của bạn, một số pipeline có thể trống nếu không gian hành động và quan sát đã khớp nhau. Mỗi pipeline trong số này xử lý các phép chuyển đổi khác nhau giữa các không gian hành động và quan sát khác nhau. Dưới đây là giải thích ngắn gọn về từng pipeline.

  1. Pipeline 1: Không gian hành động Teleop → không gian hành động của bộ dữ liệu (tư thế điện thoại → mục tiêu EE)
  2. Pipeline 2: Không gian hành động của tập dữ liệu → không gian lệnh của robot (mục tiêu EE → khớp)
  3. Pipeline 3: Không gian quan sát của robot → không gian quan sát của bộ dữ liệu (khớp → tư thế EE)

Dưới đây là một ví dụ về ba pipeline mà chúng tôi sử dụng trong các ví dụ follower từ điện thoại sang SO-100:

phone_to_robot_ee_pose_processor = RobotProcessorPipeline[tuple[RobotAction, RobotObservation], RobotAction]( # teleop -> dataset action
    steps=[
        MapPhoneActionToRobotAction(platform=teleop_config.phone_os),
        EEReferenceAndDelta(
            kinematics=kinematics_solver, end_effector_step_sizes={"x": 0.5, "y": 0.5, "z": 0.5}, motor_names=list(robot.bus.motors.keys()),
        ),
        EEBoundsAndSafety(
            end_effector_bounds={"min": [-1.0, -1.0, -1.0], "max": [1.0, 1.0, 1.0]}, max_ee_step_m=0.20,
        ),
        GripperVelocityToJoint(),
    ],
    to_transition=robot_action_observation_to_transition,
    to_output=transition_to_robot_action,
)

robot_ee_to_joints_processor = RobotProcessorPipeline[tuple[RobotAction, RobotObservation], RobotAction]( # dataset action -> robot
    steps=[
        InverseKinematicsEEToJoints(
            kinematics=kinematics_solver, motor_names=list(robot.bus.motors.keys()), initial_guess_current_joints=True,
        ),
    ],
    to_transition=robot_action_observation_to_transition,
    to_output=transition_to_robot_action,
)

robot_joints_to_ee_pose = RobotProcessorPipeline[RobotObservation, RobotObservation]( # robot obs -> dataset obs
    steps=[
        ForwardKinematicsJointsToEE(kinematics=kinematics_solver, motor_names=list(robot.bus.motors.keys()))
    ],
    to_transition=observation_to_transition,
    to_output=transition_to_observation,
)

Tại sao là to_transition / to_output

Để chuyển đổi từ robot/teleoperator sang pipeline và ngược lại, chúng ta sử dụng các adapter pipeline to_transition và to_output. Chúng chuẩn hóa các phép chuyển đổi để giảm mã boilerplate, và đóng vai trò cầu nối giữa các từ điển thô của robot và teleoperator với định dạng EnvTransition của pipeline. Trong các ví dụ về follower từ điện thoại sang SO-100, chúng ta sử dụng các adapter sau:

  • robot_action_observation_to_transition: chuyển đổi cặp (action, robot observation) thành một pipeline transition (các bước EE và IK cần vị trí khớp hiện tại của robot).
  • transition_to_robot_action: chuyển đổi transition của pipeline thành dict hành động robot.
  • observation_to_transition: chuyển đổi dict quan sát của robot sang một transition của pipeline.
  • transition_to_observation: chuyển đổi transition của pipeline thành dict observation.

Xem src/lerobot/processor/converters.py để biết thêm chi tiết.

Hợp đồng tính năng của bộ dữ liệu

Các đặc trưng của Dataset được xác định bởi các khóa được lưu trong dataset. Mỗi bước có thể khai báo các đặc trưng mà nó thay đổi trong một hợp đồng gọi là transform_features(...). Khi bạn xây dựng một processor, processor có thể tổng hợp tất cả các đặc trưng này bằng aggregate_pipeline_dataset_features() và gộp nhiều dict đặc trưng bằng combine_feature_dicts(...).

Dưới đây là một ví dụ về cách chúng ta khai báo các đặc trưng bằng phương thức transform_features trong các ví dụ follower từ điện thoại sang SO-100:

    def transform_features(
        self, features: dict[PipelineFeatureType, dict[str, PolicyFeature]]
    ) -> dict[PipelineFeatureType, dict[str, PolicyFeature]]:
        # We only use the ee pose in the dataset, so we don't need the joint positions
        for n in self.motor_names:
            features[PipelineFeatureType.ACTION].pop(f"{n}.pos", None)
        # We specify the dataset features of this step that we want to be stored in the dataset
        for k in ["x", "y", "z", "wx", "wy", "wz", "gripper_pos"]:
            features[PipelineFeatureType.ACTION][f"ee.{k}"] = PolicyFeature(
                type=FeatureType.STATE, shape=(1,)
            )
        return features

Ở đây, chúng ta khai báo các PolicyFeatures mà chúng ta sửa đổi trong bước này, để biết các đặc trưng nào có thể mong đợi khi chạy bộ xử lý. Các đặc trưng này sau đó có thể được tổng hợp và sử dụng để tạo ra các đặc trưng của bộ dữ liệu.

Dưới đây là một ví dụ về cách chúng tôi tổng hợp và gộp các đặc trưng trong ví dụ ghi âm từ điện thoại sang SO-100:

features=combine_feature_dicts(
        # Run the feature contract of the pipelines
        # This tells you how the features would look like after the pipeline steps
        aggregate_pipeline_dataset_features(
            pipeline=phone_to_robot_ee_pose_processor,
            initial_features=create_initial_features(action=phone.action_features), # <- Action features we can expect, these come from our teleop device (phone) and action processor
            use_videos=True,
        ),
        aggregate_pipeline_dataset_features(
            pipeline=robot_joints_to_ee_pose,
            initial_features=create_initial_features(observation=robot.observation_features), # <- Observation features we can expect, these come from our robot and observation processor
            use_videos=True,
            patterns=["observation.state.ee"], # <- Here you could optionally filter the features we want to store in the dataset, with a specific pattern

        ),
    ),

Cách hoạt động:

  • aggregate_pipeline_dataset_features(...): áp dụng transform_features trên toàn bộ pipeline và lọc theo các mẫu (bao gồm hình ảnh khi use_videos=True, và bao gồm các đặc trưng trạng thái khi patterns được chỉ định).
  • combine_feature_dicts(...): kết hợp nhiều feature dict.
  • Ghi âm bằng record_loop(...) sử dụng build_dataset_frame(...) để xây dựng các khung dữ liệu nhất quán với dataset.features trước khi gọi add_frame(...) để thêm khung vào tập dữ liệu.

Hướng dẫn khi tùy chỉnh các pipeline robot

Bạn có thể lưu trữ bất kỳ tính năng nào sau đây làm không gian hành động/quan sát của bạn:

  • Vị trí khớp
  • Tư thế EE tuyệt đối
  • Chênh lệch EE tương đối
  • Các tính năng khác: vận tốc khớp, mô-men xoắn, v.v.

Chọn không gian hành động và quan sát cho chính sách của bạn, sau đó cấu hình/sửa đổi các pipeline và bước tương ứng.

Các robot khác nhau

  • Bạn có thể dễ dàng tái sử dụng các pipeline, ví dụ như để sử dụng một robot khác với teleop qua điện thoại, bằng cách sửa đổi các ví dụ và thay thế RobotKinematics (URDF) cùng motor_names để sử dụng robot của bạn với Phone teleop. Ngoài ra, bạn nên đảm bảo rằng target_frame_name trỏ đến gripper/wrist của bạn.

An toàn là trên hết

  • Khi thay đổi các pipeline, hãy bắt đầu với các giới hạn chặt chẽ và triển khai các bước an toàn khi làm việc với robot thực.
  • Khuyến nghị nên bắt đầu với mô phỏng trước, sau đó mới chuyển sang các robot thực.

Đó là tất cả! Chúng tôi hy vọng hướng dẫn này giúp bạn bắt đầu tùy chỉnh các pipeline robot của mình. Nếu bạn gặp bất kỳ vấn đề nào, hãy tham gia cộng đồng Discord của chúng tôi để được hỗ trợ.

Update on GitHub