LeRobot documentation

Biểu diễn Hành động

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Biểu diễn Hành động

Hướng dẫn này giải thích các cách khác nhau để biểu diễn hành động của robot trong LeRobot, mối quan hệ giữa chúng và khi nào nên sử dụng từng cách.

Không gian khớp so với không gian đầu cuối

Trước khi thảo luận về các biểu diễn hành động, việc hiểu hai không gian tọa độ mà hành động có thể tồn tại sẽ rất hữu ích.

Không gian liên hợp

Hành động trong không gian khớp chỉ định trực tiếp vị trí đích cho mỗi động cơ. Đối với cánh tay 6-DOF có kẹp, một hành động trong không gian khớp có thể có dạng:

action = [shoulder_pan: 45.0, shoulder_lift: -20.0, elbow: -30.0, wrist_pitch: 10.0, wrist_roll: 0.0, wrist_yaw: 5.0, gripper: 0.8]

Không gian khớp là mặc định trong LeRobot. Nó đơn giản, không yêu cầu mô hình động học và ánh xạ trực tiếp sang lệnh động cơ. Hầu hết các cấu hình cho người mới bắt đầu (SO-100, Koch) sử dụng hành động trong không gian khớp.

Không gian Đầu cuối (EE)

Hành động trong không gian đầu cuối (end-effector) xác định vị trí và hướng mong muốn của đầu công cụ (gripper) của robot trong hệ tọa độ Descartes:

action = [x: 0.25, y: -0.10, z: 0.15, wx: 0.0, wy: 0.0, wz: 0.1, gripper: 0.8]

Không gian EE trực quan hơn cho các tác vụ như pick-and-place vì nó mô tả trực tiếp vị trí mà gripper cần đến, nhưng nó yêu cầu một mô hình động học (URDF) để chuyển đổi giữa các tư thế EE và các góc khớp.

Chuyển đổi Giữa Các Không Gian

LeRobot cung cấp các bước xử lý để chuyển đổi giữa không gian khớp và không gian EE bằng động học thuận và động học nghịch. Các bước này được xây dựng dựa trên RobotKinematics, thành phần nạp mô hình URDF của robot của bạn.

from lerobot.model.kinematics import RobotKinematics
from lerobot.robots.so_follower.robot_kinematic_processor import (
    ForwardKinematicsJointsToEE,
    InverseKinematicsEEToJoints,
)

kinematics = RobotKinematics(
    urdf_path="./SO101/so101_new_calib.urdf",
    target_frame_name="gripper_frame_link",
    joint_names=["shoulder", "elbow", "wrist_pitch", "wrist_roll", "wrist_yaw"],
)

# Joints → EE (for observations: "where is my gripper?")
fk_step = ForwardKinematicsJointsToEE(kinematics=kinematics, motor_names=[...])

# EE → Joints (for actions: "move my gripper here")
ik_step = InverseKinematicsEEToJoints(kinematics=kinematics, motor_names=[...])

Xem examples/so100_to_so100_EE/ để có một ví dụ hoàn chỉnh về việc ghi, phát lại và đánh giá với các hành động trong không gian EE trên cánh tay SO-100.

Hành động tuyệt đối, tương đối và delta

Dù bạn làm việc trong không gian khớp hay không gian EE, giá trị hành động có thể được biểu diễn theo ba cách khác nhau. Thuật ngữ tuân theo UMI (Chi et al., 2024).

Hành động tuyệt đối (mặc định của LeRobot)

Mỗi hành động chỉ định trực tiếp vị trí đích.

Ví dụ (không gian liên hợp, khối 4):

current_state = [45.0, -30.0, 10.0]

action_chunk = [
    [46.0, -29.0, 11.0],   # go to 46, -29, 11
    [47.5, -27.0, 12.0],   # go to 47.5, -27, 12
    [49.0, -25.0, 13.5],   # go to 49, -25, 13.5
    [50.0, -24.0, 15.0],   # go to 50, -24, 15
]

Mỗi giá trị là một vị trí đích trong hệ tọa độ của robot. Đơn giản và trực tiếp, nhưng đòi hỏi một hệ tọa độ toàn cục nhất quán. Đây là mặc định trong LeRobot.

Hành động tương đối (được sử dụng bởi OpenPI / pi0)

Mỗi hành động trong chunk là một độ lệch so với trạng thái hiện tại tại thời điểm dự đoán. Tất cả các hành động trong chunk cùng chia sẻ một điểm tham chiếu:

current_state = [45.0, -30.0, 10.0]

relative_chunk = [
    [1.0,  1.0, 1.0],   # +1 from current → target 46, -29, 11
    [2.5,  3.0, 2.0],   # +2.5 from current → target 47.5, -27, 12
    [4.0,  5.0, 3.5],   # +4 from current → target 49, -25, 13.5
    [5.0,  6.0, 5.0],   # +5 from current → target 50, -24, 15
]

Việc chuyển đổi rất đơn giản: relative = absolute - current_state. Để khôi phục absolute: absolute = relative + current_state.

Tại sao sử dụng hành động tương đối? Mô hình học cách dự đoán các độ dịch chuyển có tâm quanh số 0, điều này dễ chuẩn hóa hơn và dẫn đến quá trình huấn luyện ổn định hơn. Vì mỗi khối tham chiếu cùng một trạng thái hiện tại, nên không có sự tích lũy sai số giữa các khối.

Delta Actions (các khác biệt tuần tự)

Mỗi hành động là một độ lệch so với hành động trước đó (hoặc so với trạng thái hiện tại ở bước đầu tiên):

current_state = [45.0, -30.0, 10.0]

delta_chunk = [
    [1.0,  1.0, 1.0],   # current → 46, -29, 11
    [1.5,  2.0, 1.0],   # previous action → 47.5, -27, 12
    [1.5,  2.0, 1.5],   # previous action → 49, -25, 13.5
    [1.0,  1.0, 1.5],   # previous action → 50, -24, 15
]

Ở đây, mỗi bước là tương đối so với bước trước đó. Để khôi phục các vị trí tuyệt đối, bạn phải cộng tất cả các delta trước đó, điều này có nghĩa là lỗi sẽ tích lũy theo thời gian. UMI lập luận rõ ràng chống lại cách biểu diễn này vì lý do đó.

So sánh trực quan

Hình dưới đây (dựa trên hình từ UMI, Chi et al., 2024) minh họa sự khác biệt chính. Với relative trajectory, mọi hành động trong chunk đều trỏ về cùng một điểm gốc (trạng thái hiện tại), do đó một bước suy luận mới sẽ đặt lại tham chiếu một cách sạch sẽ. Với delta, mỗi hành động phụ thuộc vào hành động trước đó, nên sai số sẽ tích lũy. Hành động Absolute đòi hỏi một hệ tọa độ toàn cục nhất quán.

Relative Trajectory as Action Representation (UMI, Chi et al., 2024)

Sử dụng Hành động Tương đối trong LeRobot

LeRobot cung cấp RelativeActionsProcessorStep để chuyển đổi giữa các hành động tuyệt đối và tương đối bên trong pipeline xử lý. Đây là cách pi0, pi0.5 và pi0_fast hỗ trợ các hành động tương đối.

Lưu ý: Tất cả các mô hình pi (pi0, pi0.5, pi0fast) áp dụng chuyển đổi tương đối _trước khi chuẩn hóa (relative → normalize), do đó bộ chuẩn hóa luôn nhận các giá trị delta (tương đối). Điều này có nghĩa là thống kê hành động tương đối là bắt buộc cho tất cả chúng khi huấn luyện với use_relative_actions=true. Trong pi0_fast, RelativeActionsProcessorStep chỉ sửa đổi hành động — quan sát trạng thái không thay đổi — nên NormalizerProcessorStep vẫn chạy trước bộ mã hóa trạng thái và bộ mã hóa tiếp tục nhận trạng thái đã chuẩn hóa như dự kiến.

Cách hoạt động

Trong quá trình huấn luyện (tiền xử lý), các hành động được chuyển đổi từ tuyệt đối sang tương đối trước khi mô hình nhìn thấy chúng:

raw absolute action → RelativeActionsProcessorStep → normalize → model

Trong quá trình inference (xử lý hậu kỳ), các dự đoán của mô hình được chuyển đổi lại về giá trị tuyệt đối trước khi được gửi đến robot:

model output → unnormalize → AbsoluteActionsProcessorStep → robot

AbsoluteActionsProcessorStep đọc trạng thái hiện tại được lưu trong bộ nhớ đệm từ RelativeActionsProcessorStep được ghép cặp với nó, do đó hai bước này phải được kết nối với nhau (được xử lý tự động bởi policy factory).

Bật hành động tương đối cho nhóm pi (pi0, pi0.5, pi0_fast)

Bước 1: Tiền xử lý thống kê hành động tương đối cho bộ dữ liệu của bạn:

lerobot-edit-dataset \
    --repo_id your_dataset \
    --new_repo_id your_dataset \
    --operation.type recompute_stats \
    --operation.overwrite true \
    --operation.relative_action true \
    --operation.chunk_size 50 \
    --operation.relative_exclude_joints "['gripper']"

Bước 2: Huấn luyện với hành động tương đối được bật:

lerobot-train \
    --dataset.repo_id=your_dataset \
    --policy.type=pi0 \
    --policy.use_relative_actions=true \
    --policy.relative_exclude_joints='["gripper"]'

Tham số relative_exclude_joints chỉ định các khớp cần được giữ trong không gian tuyệt đối. Ví dụ, các lệnh kẹp (gripper) thường là nhị phân (mở/đóng) và không được hưởng lợi từ mã hóa tương đối.

Đối với các cấu hình chính sách định nghĩa action_feature_names, make_policy sẽ điền danh sách này từ metadata names của đặc trưng hành động trong bộ dữ liệu. Các tên có thể là một chuỗi phẳng hoặc một từ điển mà các giá trị của nó đều là danh sách hoặc bộ (tuple). Ví dụ, {"arm": ["shoulder", "elbow"], "hand": ["gripper"]} sẽ trở thành ["shoulder", "elbow", "gripper"], chứ không phải là các khóa nhóm. Thứ tự chèn nhóm và thứ tự trong nhóm được giữ nguyên, do đó hãy khai báo các tên theo cùng thứ tự với vector hành động. Các ánh xạ tên-sang-chỉ số cũ vẫn giữ nguyên hành vi theo thứ tự khóa.

Kết hợp các hành động tương đối với RTC

RTC chạy suy luận chính sách với tần số cao và gửi các hành động đến robot ngay khi chúng được dự đoán, thay vì chờ một khối hoàn chỉnh. Hành động tương đối và RTC hoàn toàn tương thích: vì mỗi khối trong chế độ tương đối đều tham chiếu đến cùng trạng thái hiện tại (được ghi nhận tại thời điểm bắt đầu suy luận), mỗi hành động được dự đoán trong khối vẫn là một độ dịch hợp lệ ngay cả khi robot đã di chuyển. Không cần xử lý đặc biệt — RelativeActionsProcessorStep lưu trạng thái vào bộ nhớ đệm một lần cho mỗi lần gọi suy luận và AbsoluteActionsProcessorStep áp dụng nó cho mọi hành động trong đầu ra được phát trực tiếp.

Kết hợp các hành động tương đối với không gian EE

Hành động tương đối hoạt động trong cả không gian khớp và không gian EE. Ví dụ, nếu bộ dữ liệu của bạn lưu trữ các hành động EE, mã hóa tương đối sẽ chuyển đổi chúng thành các độ lệch so với tư thế EE hiện tại:

current_ee_state = [x: 0.25, y: -0.10, z: 0.15, gripper: 0.8]

absolute_ee_chunk = [
    [0.26, -0.09, 0.16, 0.8],
    [0.28, -0.07, 0.18, 0.8],
]

relative_ee_chunk = [
    [0.01,  0.01, 0.01, 0.0],   # offset from current EE pose
    [0.03,  0.03, 0.03, 0.0],   # offset from current EE pose
]

Tóm tắt Pipeline Xử lý

Dưới đây là cách các bộ xử lý khác nhau được kết hợp. Mỗi mũi tên là một bước xử lý, và chúng có thể được nối tiếp trong một RobotProcessorPipeline hoặc PolicyProcessorPipeline:

                    ┌─────────────────────────────────────────┐
   Action Space     │   Joint Space  ←──IK──→  EE Space      │
                    │   ForwardKinematicsJointsToEE           │
                    │   InverseKinematicsEEToJoints           │
                    └─────────────────────────────────────────┘

                    ┌─────────────────────────────────────────┐
   Representation   │   Absolute  ←────→  Relative            │
                    │   RelativeActionsProcessorStep (pre)    │
                    │   AbsoluteActionsProcessorStep (post)   │
                    └─────────────────────────────────────────┘

                    ┌─────────────────────────────────────────┐
   Normalization    │   Raw  ←────→  Normalized               │
                    │   NormalizerProcessorStep (pre)         │
                    │   UnnormalizerProcessorStep (post)      │
                    └─────────────────────────────────────────┘

Một preprocessor huấn luyện điển hình có thể nối chuỗi: raw absolute joint actions → relative → normalize. Một postprocessor suy luận điển hình: unnormalize → absolute → (optionally IK to joints).

Tham khảo

Update on GitHub