LeRobot documentation

手机

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

and get access to the augmented documentation experience

to get started

手机

使用您的手机(iOS 或 Android)来控制您的机器人。

在本指南中,您将了解:

  • 如何连接 iOS/Android 手机
  • 手机姿态如何映射到机器人末端执行器(EE)目标
  • 如何调整安全限制、夹爪控制和 IK 设置

要通过手机控制您的机器人,请使用以下命令安装相关依赖项:

pip install 'lerobot[phone,kinematics,feetech,core_scripts]'

kinematics 提供了示例中使用的逆运动学,feetech 对应 SO-100/SO-101 电机,core_scripts 则是录制和可视化工具。

快速入门

支持的平台

  • iOS:使用 HEBI Mobile I/O 应用(ARKit 位姿 + 按钮)。请先下载该应用,打开后示例将在您的网络上发现它,并流式传输手机位姿和输入。
  • Android:使用 teleop 包(WebXR)。启动 Python 进程时,会打印一个本地 URL。在手机上打开该链接,点击 Start,然后使用 Move 来流式传输姿态。

链接:

手机方向与操作

  • 方向:手持手机,使屏幕朝上,且手机顶部边缘与机器人夹爪指向同一方向。这可以确保校准将手机坐标系与机器人坐标系对齐,从而使运动感觉自然,请参考下图。
  • 启用/禁用 — 这是一个 死人开关,在整个运动过程中必须持续按住:
    • iOS:按住 B1 可移动机器人,松开后机械臂将保持在当前位置。每次按下都会将手机重新锚定到机械臂当前的姿态,因此您可以松开、将手移回舒适的位置、再次按下并继续操作——机器人不会发生跳变。
    • Android:与 WebXR 页面上的 Move 按钮相同。
  • 夹爪控制(无论是否按住启用按钮均可使用):
    • iOS:模拟滑块 A3 作为速度输入控制夹爪——向上推以打开,向下拉以关闭,松开至中心位置以保持。
    • Android:按钮 A 和 B 分别执行递增/递减操作(A 打开,B 关闭)。您可以在 GripperVelocityToJoint 步骤中调整速度。
  • 握持方式:用双手握住手机,一只手的拇指放在启用按钮(B1)上,另一只手的拇指放在夹爪滑块(A3)上,这样可以在不改变握持姿势的同时同时控制机械臂和夹爪。操作时请保持手机平放——手机的姿态即为指令,因此在运动过程中重新握持会导致机器人移动。
  • 机器人初始位姿:teleoperate.py 在启动时(手机校准之前)会将机械臂移动到其归位位姿,并在按下 Ctrl+C 时将其移回脚本启动时所在的初始位置。归位操作会命令每个本体关节移动到 set_half_turn_homings() 在校准期间居中对齐的半转值——即校准示意图中保持的位姿——同时夹爪保持原位,以避免归位时夹爪闭合夹住物体。这一点很重要,因为目标位姿是通过逆运动学(IK)从你按下启用按钮时机械臂所处的位置求解的——如果机械臂处于折叠或完全伸展状态,其剩余活动空间很小,容易触及关节限位。其他示例脚本(record.py、evaluate.py、replay.py)不会执行机械臂归位,因此请在启动这些脚本前手动将其放置到该位姿。
Phone teleop orientation

步骤 1:选择平台

修改示例,在 PhoneConfig 中使用 PhoneOS.IOS 或 PhoneOS.ANDROID。各平台的 API 完全相同,仅输入源不同。所有示例均位于 examples/phone_to_so100/ 中:teleoperate.py、record.py、replay.py、evaluate.py 和 rollout.py。

遥操作示例:

from lerobot.teleoperators.phone import Phone, PhoneConfig
from lerobot.teleoperators.phone.config_phone import PhoneOS

teleop_config = PhoneConfig(phone_os=PhoneOS.IOS)  # or PhoneOS.ANDROID
teleop_device = Phone(teleop_config)

步骤 2:连接并校准

创建 Phone(teleop_config) 并调用 connect() 后,系统会自动提示进行校准。请将手机保持在上文所述的朝向,然后:

  • iOS:长按 B1 以捕获参考姿势。
  • Android:在 WebXR 页面上按Move按钮以捕获参考位姿。

为什么要进行校准?我们会捕获当前的位姿,以便后续的位姿都在与机器人对齐的坐标系中表示。当您再次按下按钮以启用控制时,系统会重新捕获位置,以避免手机在禁用期间被移动后产生漂移。

步骤 3:运行示例

运行其中一个示例脚本,以进行遥操作、录制数据集、回放数据集或评估策略。

所有脚本都假定您已配置并校准了您的机器人(例如 SO-100 follower)。

您必须提供机器人的 URDF。 每个示例都会求解逆运动学,这需要机械臂的运动学模型,而 LeRobot 并不附带 URDF。

对于本教程中使用的 SO-100/SO-101,请在 LeRobot 仓库中,将 SO-ARM100 仓库 中的 SO101 文件夹复制到 examples/phone_to_so100/,使文件位于 examples/phone_to_so100/SO101/so101_new_calib.urdf:

git clone --depth 1 https://github.com/TheRobotStudio/SO-ARM100.git /tmp/SO-ARM100
cp -r /tmp/SO-ARM100/Simulation/SO101 examples/phone_to_so100/SO101

如果将文件存储在其他位置,或者要控制另一条机械臂,请使用 --urdf 将脚本指向不同的文件。

  • 运行此示例以进行遥操作,并传入从动臂的串口(使用 lerobot-find-port 查找):

    cd examples/phone_to_so100
    python teleoperate.py --port /dev/tty.usbmodem5A460814411

    --id 用于选择要使用的已存储校准,--urdf 指向上述 URDF。

运行示例后:

  • Android:启动脚本后,在手机上打开打印出的本地 URL,点击 Start,然后长按 Move。
  • iOS:首先打开 HEBI Mobile I/O;按住 B1 以移动机器人。A3 控制夹爪。

此外,您可以通过编辑示例中显示的处理器步骤来自定义映射或安全限制。您还可以通过修改输入和运动学步骤来重新映射输入(例如,使用不同的模拟输入)或将流水线适配到其他机器人(例如,LeKiwi)。有关此内容的更多信息,请参阅机器人和遥操作器的处理器指南。

  • 运行此示例以记录数据集,该数据集会保存绝对末端执行器观测值和动作:

    cd examples/phone_to_so100
    python record.py
  • 运行此示例以重放记录的回合:

    cd examples/phone_to_so100
    python replay.py
  • 运行此示例以评估预训练策略:

    cd examples/phone_to_so100
    python evaluate.py

重要的流水线步骤和选项

  • 运动学在多个步骤中都会用到。我们使用 Placo,它是 Pinocchio 的一个封装,用于处理我们的运动学。我们通过传入机器人的 URDF 和目标坐标系来构建运动学对象。我们将 target_frame_name 设置为夹爪坐标系。

    kinematics_solver = RobotKinematics(
      urdf_path="./SO101/so101_new_calib.urdf",
      target_frame_name="gripper_frame_link",
      joint_names=list(robot.bus.motors.keys()),
    )
    
  • MapPhoneActionToRobotAction 步骤会将校准后的手机位姿和输入转换为目标增量和夹爪指令,下方展示了该步骤的输出。

    action["enabled"] = enabled
    action["target_x"] = pos[1] if enabled else 0.0
    action["target_y"] = -pos[0] if enabled else 0.0
    action["target_z"] = pos[2] if enabled else 0.0
    action["target_wx"] = rotvec[1] if enabled else 0.0
    action["target_wy"] = -rotvec[0] if enabled else 0.0
    action["target_wz"] = rotvec[2] if enabled else 0.0
    action["gripper_vel"] = gripper_vel  # Still send gripper action when disabled
  • EEReferenceAndDelta 步骤将目标增量转换为期望的绝对末端执行器位姿,并在启用时存储参考值。end_effector_step_sizes 是末端执行器位姿的步长,可以修改以改变运动速度。

    EEReferenceAndDelta(
        kinematics=kinematics_solver,
        end_effector_step_sizes={"x": 0.5, "y": 0.5, "z": 0.5},
        motor_names=list(robot.bus.motors.keys()),
        use_latched_reference=True,
    ),
  • EEBoundsAndSafety 步骤会将末端执行器的运动限制在工作空间内,并检查末端执行器是否存在较大的步长跳跃,以确保安全性。end_effector_bounds 是末端执行器位姿的边界,可以修改以更改工作空间。max_ee_step_m 是末端执行器位姿的步长限制,可以修改以更改安全限制。

    EEBoundsAndSafety(
        end_effector_bounds={"min": [-1.0, -1.0, -1.0], "max": [1.0, 1.0, 1.0]},
        max_ee_step_m=0.10,
    )
  • GripperVelocityToJoint 步骤利用当前测量状态,将类似速度的夹爪输入转换为夹爪的绝对位置。speed_factor 是用于乘以速度的系数。

    GripperVelocityToJoint(speed_factor=20.0)

不同的 IK 初始猜测

我们在运动学步骤中使用不同的 IK 初始猜测值。初始猜测值可以是当前测量的关节值,也可以是上一次的 IK 解。

  • 闭环(用于记录/评估):设置 initial_guess_current_joints=True,使 IK 从每帧测量的关节位置开始。

    InverseKinematicsEEToJoints(
        kinematics=kinematics_solver,
        motor_names=list(robot.bus.motors.keys()),
        initial_guess_current_joints=True,  # closed loop
    )
  • 开环(用于重放):将 initial_guess_current_joints=False,使 IK 从上一个 IK 解继续,而不是从测量状态开始。这确保了在无反馈重放时动作的稳定性。

    InverseKinematicsEEToJoints(
        kinematics=kinematics_solver,
        motor_names=list(robot.bus.motors.keys()),
        initial_guess_current_joints=False,  # open loop
    )

Pipeline 步骤详解

  • MapPhoneActionToRobotAction:将校准后的手机位姿和输入转换为目标增量和夹爪指令。运动由使能信号(iOS 上的 B1,Android 上的 Move)控制。
  • EEReferenceAndDelta:在启用时锁定参考末端执行器位姿,并将其与目标增量结合,以在每一帧生成绝对的目标末端执行器位姿。禁用时,它会持续发送最后一条指令位姿。
  • EEBoundsAndSafety:将 EE 位姿限制在工作空间内,并对跳跃进行速率限制以确保安全。同时声明了 action.ee.* 特征。
  • InverseKinematicsEEToJoints:通过 IK 将末端执行器位姿转换为关节位置。对于闭环控制,建议使用 initial_guess_current_joints=True;为确保稳定性,在开环重放时请设置为 False。
  • GripperVelocityToJoint:使用当前测量状态,将类似速度的夹爪输入积分到绝对夹爪位置。
  • ForwardKinematicsJointsToEE:根据观测到的关节计算 observation.state.ee.*,用于末端执行器状态的日志记录和训练。

故障排除

  • 未检测到 iOS:请确保 HEBI Mobile I/O 已打开,并且您的笔记本电脑/手机处于同一网络中。
  • 无法访问 Android URL:请检查您是否误用了 https 而非 http,请使用脚本打印出的确切 IP 地址,并允许浏览器进入且忽略证书问题。
  • 运动感觉是反的:请逐个轴进行检查,然后在 MapPhoneActionToRobotAction 中调整符号翻转,或交换轴以匹配您的设置。
  • 手臂几乎不动或无法突破其极限:请从中段起始姿态重新开始(参见上文)——IK 是从手臂的当前构型求解的。
Update on GitHub