LeRobot 入门教程(九)使用 Android、iOS 手机控制机械臂

系列文章目录


目录

系列文章目录

前言

一、开始使用

[1.1 支持平台](#1.1 支持平台)

[1.2 手机方向与控制方式](#1.2 手机方向与控制方式)

[1.3 选择平台](#1.3 选择平台)

[1.4 连接与校准](#1.4 连接与校准)

[1.5 运行示例脚本](#1.5 运行示例脚本)

[1.6 重要管道步骤与选项](#1.6 重要管道步骤与选项)

[1.7 不同的反向运动学初始猜测](#1.7 不同的反向运动学初始猜测)

[1.8 管道步骤说明](#1.8 管道步骤说明)

[1.9 故障排除](#1.9 故障排除)

[二、Teleop 入门教程](#二、Teleop 入门教程)

[2.1 安装](#2.1 安装)

[2.2 用法](#2.2 用法)

[2.2.1 基本接口](#2.2.1 基本接口)

[2.2.2 xArm](#2.2.2 xArm)

[2.2.3 ROS 2 接口](#2.2.3 ROS 2 接口)

发布主题:

订阅主题:

[2.2.4 ROS 2 与反向运动学接口](#2.2.4 ROS 2 与反向运动学接口)

[2.2.5 自定义接口](#2.2.5 自定义接口)

[2.3 示例](#2.3 示例)

[2.4 实用工具](#2.4 实用工具)

[2.4.1 JacobiRobot](#2.4.1 JacobiRobot)

[2.4.2 JacobiRobotROS](#2.4.2 JacobiRobotROS)

关键特性:


前言

在本指南中您将学习:

  • 如何连接iOS/Android手机
  • 手机姿态如何映射至机器人末端执行器(EE)目标
  • 如何调整安全限制、抓取器控制及逆向运动学设置

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

bash 复制代码
pip install lerobot[phone]

一、开始使用

1.1 支持平台

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

链接:

1.2 手机方向与控制方式

  • 方向:将手机屏幕朝上握持,顶部边缘与机器人抓手方向一致。此举确保校准时手机坐标系与机器人坐标系对齐,使动作更自然,详见下图示意。
  • 启用/禁用:
    • iOS:长按B1键启用遥控操作,松开即停止。首次按下将捕获基准姿态。
    • Android:长按移动按钮,松开停止。首次按下将捕获参考姿势。
  • 抓手控制:
    • iOS:模拟输入A3作为速度输入控制抓手。
    • Android:按钮A和B分别作为增量/减量控制(A打开,B关闭)。可在"GripperVelocityToJoint"步骤中调整速度。

1.3 选择平台

修改示例代码,在 PhoneConfig 中使用 PhoneOS.IOS 或 PhoneOS.ANDROID。API 在不同平台上完全相同,仅输入源存在差异。所有示例均位于 examples/ 目录下,并包含 phone_so100_*.py 变体文件。

远程操作示例:

python 复制代码
from lerobot.teleoperators.phone.config_phone import PhoneConfig, PhoneOS

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

1.4 连接与校准

当创建 Phone(teleop_config) 并调用 connect() 时,系统将自动提示校准。请按上述方向握持手机,然后:

  • iOS:长按B1键捕捉基准姿态。
  • Android:在WebXR页面点击移动按钮捕捉基准姿态。

为何需要校准?我们捕捉当前姿态以便后续姿态在机器人对齐坐标系中呈现。当您再次点击按钮启用控制时,系统会重新捕捉位置,避免手机在禁用状态下移动导致的漂移偏差。

1.5 运行示例脚本

运行其中一个示例脚本,以实现遥操作、记录数据集、回放数据集或评估策略.

所有脚本均假设您已完成机器人配置(例如 SO-100 跟随机器人)并设置正确的串口。

此外需将机器人的 urdf 文件复制到示例文件夹。对于本教程示例(使用 SO100/SO101),强烈建议使用 SO-ARM100 仓库中的 urdf 文件。

  • 运行此示例进行遥操作:
python 复制代码
python examples/phone_to_so100/teleoperate.py

运行示例后:

  • Android:启动脚本后,在手机上打开打印的本地网址,点击"开始",然后长按"移动"。
  • iOS:先打开HEBI Mobile I/O;B1控制运动,A3控制夹爪。

此外,您可通过编辑示例中的处理器步骤自定义映射或安全限值。您还可通过修改输入和运动学步骤来重新映射输入(例如使用不同模拟输入),或将管道适配至其他机器人(如LeKiwi)。更多详情请参阅《机器人与遥控操作器处理器指南》。

  • 运行此示例可记录数据集,该数据集保存末端执行器的绝对位置观测值与动作:

    bash 复制代码
    python examples/phone_to_so100/record.py
  • 运行此示例以重放录制的剧集:

    bash 复制代码
    python examples/phone_to_so100/replay.py
  • 运行此示例以评估预训练策略:

    bash 复制代码
    python examples/phone_to_so100/evaluate.py

1.6 重要管道步骤与选项

  • 运动学在多个步骤中使用。我们采用Placo(作为Pinocchio的封装库)来处理运动学计算。通过传递机器人的URDF文件和目标坐标系来构造运动学对象。我们将target_frame_name设置为夹爪坐标系。

    python 复制代码
    kinematics_solver = RobotKinematics(
      urdf_path="./SO101/so101_new_calib.urdf",
      target_frame_name="gripper_frame_link",
      joint_names=list(robot.bus.motors.keys()),
    )
  • MapPhoneActionToRobotAction步骤将校准后的手机姿态和输入转换为目标位移量和夹爪指令,下文展示该步骤的输出结果。

    python 复制代码
    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参数定义末端执行器姿态的步进尺寸,可通过修改该参数调整运动速度。

    python 复制代码
    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和max_ee_twist_step_rad分别是末端执行器姿态的位移极限值和扭转极限值,修改这些参数可调整安全边界。

    python 复制代码
    EEBoundsAndSafety(
        end_effector_bounds={"min": [-1.0, -1.0, -1.0], "max": [1.0, 1.0, 1.0]},
        max_ee_step_m=0.10,
        max_ee_twist_step_rad=0.50,
    )
  • 夹持器速度到关节步骤将速度类型的夹持器输入转换为绝对夹持器位置,使用当前测量的状态。速度因子是乘以速度的系数。

    python 复制代码
    GripperVelocityToJoint(speed_factor=20.0)

1.7 不同的反向运动学初始猜测

我们在运动学步骤中采用不同的反向运动学初始猜测。初始猜测值可选当前测量关节或前帧反向运动学解。

  • 闭环模式(用于记录/评估):设置 initial_guess_current_joints=True,使反向运动学每帧从测量关节开始计算。

    python 复制代码
    InverseKinematicsEEToJoints(
        kinematics=kinematics_solver,
        motor_names=list(robot.bus.motors.keys()),
        initial_guess_current_joints=True,  # closed loop
    )
  • 开环(用于回放):将initial_guess_current_joints设为False,使逆向运动学从前一次的逆向运动学解继续,而非基于测量状态。这在无反馈回放时能保持动作稳定性。

    python 复制代码
    InverseKinematicsEEToJoints(
        kinematics=kinematics_solver,
        motor_names=list(robot.bus.motors.keys()),
        initial_guess_current_joints=False,  # open loop
    )

1.8 管道步骤说明

  • MapPhoneActionToRobotAction:将校准后的手机姿态和输入转换为目标位移量和夹爪指令。运动由使能信号控制(iOS系统为B1,安卓系统为Move)。
  • EEReferenceAndDelta:在使能时锁存参考EE姿态,并与目标位移量结合以生成每帧的绝对期望EE姿态。禁用时持续发送上次指令姿态。
  • EEBoundsAndSafety:将EE姿态限制在工作空间内,并限速跳跃以确保安全。同时声明action.ee.*特征。
  • InverseKinematicsEEToJoints:通过逆运动学将EE姿态转换为关节位置。闭环控制推荐设置initial_guess_current_joints=True;开环回放为稳定性需设为False。
  • GripperVelocityToJoint:将速度型抓取器输入与当前测量状态融合,转换为绝对抓取器位置。
  • ForwardKinematicsJointsToEE:根据观测关节计算 observation.state.ee.*,用于 EE 状态日志记录与训练。

1.9 故障排除

  • iOS 未被发现:确保 HEBI Mobile I/O 处于开启状态,且笔记本电脑/手机处于同一网络。
  • Android URL无法访问:检查是否使用https而非http协议,使用脚本打印的精确IP地址,允许浏览器进入并忽略证书问题。
  • 运动感觉反转:调整MapPhoneActionToRobotAction中的符号翻转,或交换轴向以匹配您的设置。

二、Teleop 入门教程

只需三个简单步骤,即可将您的手机变身为机械臂远程操控设备:

  1. 在电脑上安装并启动服务器。
  2. 在手机上打开提供的网址。
  3. 点击开始,然后长按移动按钮即可操控机械臂。

重要提示

您的手机必须支持 WebXR API。遗憾的是,iPhone 不支持 WebXR API。

该网络应用程序利用WebXR API,整合手机传感器以检测其在三维空间中的方位与位置。服务器接收这些数据后,将其发送至机械臂控制器。

|----------------------------------------------------------------------------|----------------------------------------------------------------------------|
| | |
| Teleoperation of a physical Lite6 robot | Teleoperation of a simulated UR5e robot in Webots |

2.1 安装

该软件包可在PyPI上获取。您可使用pip进行安装:

bash 复制代码
pip install teleop

2.2 用法

我们提供了一些现成的机械臂接口,但您也可以通过将 teleop.Teleop 类集成到项目中来创建自己的接口。

2.2.1 基本接口

一个简单的接口,用于打印遥控响应。您可以将其作为参考来构建自己的接口。

bash 复制代码
python -m teleop.basic

2.2.2 xArm

用于远程操控uFactory Lite 6机器人的接口。支持其他xArm机器人可能需要进行微调。

bash 复制代码
python -m teleop.xarm

请注意该接口设计极为简洁,未实现任何过滤功能。因此,您可能需要通过高帧率设备进行远程操控。智能手机通常为30帧/秒,而VR操纵杆可达90帧/秒,后者在无过滤的远程操控场景中显然更具优势。

2.2.3 ROS 2 接口

ROS 2 接口主要设计用于与 cartesian_controllers 包配合使用,但也可适配 MoveIt Servo 或其他包。

发布主题:
  • target_frame (geometry_msgs/PoseStamped):机器人机械臂末端执行器在机器人基座坐标系中的目标姿态。
  • tf (tf2_msgs/TFMessage):用于可视化的机器人基座坐标系与目标坐标系之间的变换。
订阅主题:
  • current_pose (geometry_msgs/PoseStamped):机器人末端执行器在机器人基座坐标系中的当前姿态。用于更新参考姿态。

您可通过标准ROS 2参数覆盖默认主题名称:

bash 复制代码
python -m teleop.ros2 --ros-args -r target_frame:=/some_other_topic_name

2.2.4 ROS 2 与反向运动学接口

不支持伺服控制?没问题。teleop 通过 JacobiRobotROS 实用类提供伺服控制支持。

熊猫机械臂使用示例:

bash 复制代码
python -m teleop.ros2_ik \
  --joint-names panda_joint1 panda_joint2 panda_joint3 panda_joint4 panda_joint5 panda_joint6 panda_joint7 \
  --ee-link panda_hand \
  --ros-args -r /joint_trajectory:=/panda_arm_controller/joint_trajectory

xArm 使用示例:

bash 复制代码
python -m teleop.ros2_ik \
  --joint-names joint1 joint2 joint3 joint4 joint5 joint6 \
  --ee-link link6 \
  --ros-args -r /joint_trajectory:=/joint_trajectory_controller/joint_trajectory

2.2.5 自定义接口

对于大多数应用程序,您需要创建自定义接口来与机械臂交互。以下是一个示例:

python 复制代码
import numpy as np
from teleop import Teleop


def callback(pose: np.ndarray, message: dict) -> None:
    """
    Callback function triggered when pose updates are received.
    Arguments:
        - np.ndarray: A 4x4 transformation matrix representing the end-effector target pose.
        - dict: A dictionary containing additional information.
    """
    print(f'Pose: {pose}')
    print(f'Message: {message}')

teleop = Teleop()
teleop.subscribe(callback)
teleop.run()

2.3 示例

探索示例以了解如何在各种场景中使用该软件包:

  • examples/webots:在Webots仿真中使用ikpy实现UR5e机械臂的远程操作。

2.4 实用工具

该软件包包含若干实用工具类,用于简化机械臂集成:

注意

使用实用工具类时,请安装软件包及其附加依赖项:

bash 复制代码
pip install teleop[utils]

2.4.1 JacobiRobot

基于Pinocchio的机械臂伺服控制与运动学解决方案。

核心特性:

  • 基于Pinocchio的前向/逆向运动学计算
  • 带速度/加速度限制的姿态伺服控制
  • 实时3D可视化
  • 关节级控制与监测

应用场景:

python 复制代码
from teleop.utils.jacobi_robot import JacobiRobot

robot = JacobiRobot("robot.urdf", ee_link="end_effector")
target_pose = np.eye(4)  # 4x4 transformation matrix
reached = robot.servo_to_pose(target_pose, dt=0.01)

2.4.2 JacobiRobotROS

用于JacobiRobot的ROS 2封装器,可与标准ROS 2主题和消息集成。

关键特性:
  • 从/robot_description主题自动加载URDF
  • 关节状态订阅与轨迹发布
  • 兼容joint_trajectory_controller
  • 与现有ROS 2控制堆栈无缝集成

用法:

python 复制代码
from teleop.utils.jacobi_robot_ros import JacobiRobotROS
import rclpy

rclpy.init()
node = rclpy.create_node("robot_control")

robot = JacobiRobotROS(
    node=node,
    ee_link="end_effector",
    joint_names=["joint1", "joint2", "joint3"]
)

robot.reset_joint_states()  # Wait for initial joint states
reached = robot.servo_to_pose(target_pose, dt=0.03)
相关推荐
Phoenixtree_DongZhao2 小时前
《Nature》封面:DeepSeek-R1通过强化学习激发大语言模型的推理能力
人工智能·强化学习·混合专家
喜葵2 小时前
从x.ai到VSCode:一个AI编程助手的意外之旅
人工智能·vscode·ai编程
蒙帕智能运维2 小时前
FunASR:面向产业落地的端到端语音识别系统
人工智能·机器人·语音识别
机器之心2 小时前
大模型七连发,外国人馋透了!阿里云栖大会全栈升级够狠
人工智能·openai
listhi5202 小时前
自适应全变分模型的图像平滑去噪与边缘保留算法
图像处理·算法·计算机视觉
zskj_zhyl2 小时前
七彩喜智慧养老:科技向善,让晚年生活绽放“喜”悦之光
人工智能·科技·物联网·机器人
清风徐来QCQ2 小时前
关于maven编译没把resources资源包含进target目录
java·开发语言·maven
肖永威3 小时前
python开发环境VSCode中隐藏“__pycache__”目录实践
开发语言·vscode·python
IT_陈寒3 小时前
Vite 5大性能优化技巧:构建速度提升300%的实战分享!
前端·人工智能·后端