基于 openpi 的 ALOHA 真实机器人部署实战指南
【免费下载链接】openpi项目地址: https://gitcode.com/GitHub_Trending/op/openpi
openpi 仓库的examples/aloha_real示例提供了在真实 ALOHA 双臂机器人平台上运行 pi0 视觉-语言-动作(VLA)模型推理的完整参考实现。本文将以 examples/aloha_real/README.md 为核心,结合仓库中的环境封装、Docker 编排、策略服务与数据转换源码,系统讲解从硬件准备、双模式部署(Docker / 非 Docker)、三种预训练 Checkpoint 的场景布置,到使用自定义 ALOHA 数据集微调训练的完整链路,帮助你在自己的真实机器人上复现「取吐司」「叠毛巾」「开保鲜盒」等任务。
一、背景:ALOHA 平台与 openpi 示例定位
ALOHA(A Low-cost Open-source Hardware System for Bimanual Teleoperation)是一套低成本开源双臂遥操作系统。openpi 仓库通过examples/aloha_real示例将 pi0 策略与 ALOHA 真实硬件打通,其要点包括:
- 仓库使用 ALOHA 仓库的一个fork 版本,与上游相比仅做了极少修改,核心改动是使用 Intel RealSense 相机替代原有相机方案;
- fork 代码位于仓库的 third_party/aloha 目录,随 Docker 构建一并编译进 ROS Noetic 工作空间;
- 推理链路采用「远程策略服务器 + 机器人端轻量客户端」的架构:策略(模型)运行在有 GPU 的机器上,机器人端通过 WebSocket 请求动作块(action chunk),详见 docs/remote_inference.md。
从源码结构看,该示例由以下几个相互协作的模块组成:
| 文件 | 职责 |
|---|---|
| examples/aloha_real/main.py | 机器人端运行时入口,组装环境、策略 Agent 与 ActionChunkBroker |
| examples/aloha_real/env.py | 将真实 ALOHA 环境适配为 openpi-client 的Environment接口 |
| examples/aloha_real/real_env.py | 底层真实硬件封装(机械臂、夹爪、关节状态、图像采集),主要复制自 ACT 项目 |
| examples/aloha_real/robot_utils.py | ROS 订阅/发布工具,包括四路相机的ImageRecorder与关节Recorder |
| examples/aloha_real/constants.py | ALOHA 关节与夹爪的标定常量、归一化/反归一化函数 |
| examples/aloha_real/compose.yml | 一键启动整套系统的 Docker Compose 编排 |
| examples/aloha_real/Dockerfile | 基于 ROS Noetic 的镜像构建(含 Python 3.10、Interbotix 驱动、ALOHA fork) |
二、前置条件与硬件准备
1. 硬件安装
按 ALOHA 仓库的 hardware installation instructions 完成硬件安装。ALOHA 双臂通常包含两组各 6 自由度机械臂(一组主臂用于遥操作采集、一组从臂用于执行),加上夹爪和相机。
2. 修改相机序列号
由于本仓库使用 RealSense 相机,需要修改 fork 中的发布脚本,将相机序列号替换为你自己的设备序列号:
third_party/aloha/aloha_scripts/realsense_publisher.py每个 RealSense 相机都有唯一的序列号,脚本会按序列号区分cam_high(高处全景)与cam_low(低处全景)等相机;而腕部相机cam_left_wrist、cam_right_wrist通常通过 USB 端口号识别。必须将序列号改为你实际设备的序列号,否则相机节点无法发布图像。
3. 环境依赖说明
非 Docker 方式运行需要 Python 3.10 虚拟环境,依赖由 examples/aloha_real/requirements.txt 锁定(由 requirements.in 通过uv pip compile生成),关键依赖包括:
pyrealsense2:RealSense 相机驱动;rospkg、pyyaml:ROS 工具链依赖;dm_control、mujoco:基于 MuJoCo 的仿真控制栈;modern_robotics、pyquaternion:机器人运动学与姿态计算;msgpack、websockets:与策略服务器通信的序列化与传输;tyro:命令行参数解析(main.py 与转换脚本均使用)。
三、部署方式一:Docker 一键启动
Docker 方式由 examples/aloha_real/compose.yml 编排四个服务,一条命令拉起整套系统:
export SERVER_ARGS="--env ALOHA --default_prompt='take the toast out of the toaster'" docker compose -f examples/aloha_real/compose.yml up --buildCompose 编排的四个服务
| 服务 | 镜像 | 职责 |
|---|---|---|
ros_master | ros:noetic-robot | 启动roscore,作为 ROS 主节点 |
aloha_ros_nodes | aloha_real(本地构建) | 执行roslaunch aloha ros_nodes.launch,启动机械臂与相机 ROS 节点 |
openpi_server | openpi_server(本地构建) | 由 scripts/docker/serve_policy.Dockerfile 构建,运行uv run scripts/serve_policy.py加载 pi0 模型并提供策略服务 |
runtime | aloha_real(本地构建) | 运行 examples/aloha_real/main.py,即机器人端运行时 |
需要重点理解的关键配置
SERVER_ARGS环境变量:通过environment字段透传给openpi_server服务,控制策略服务器加载哪个环境(--env ALOHA)以及默认任务提示词(--default_prompt)。修改default_prompt即可切换执行的任务(详见下文 Checkpoint 指南中的提示词)。OPENPI_DATA_HOME:默认挂载宿主机~/.cache/openpi到容器内/openpi_assets,策略 Checkpoint 与归一化统计资产(norm stats)从这里加载;可通过OPENPI_DATA_HOME环境变量覆盖宿主机侧缓存目录。network_mode: host+privileged: true:机器人 ROS 通信(roscore/话题)、WebSocket 策略请求以及 USB/串口硬件访问都需要宿主机网络与设备权限;/dev被挂载进aloha_ros_nodes服务,$PWD挂载到/app以便直接运行仓库代码。- GPU 资源预留:
openpi_server服务通过deploy.resources.reservations.devices声明需要 1 块 NVIDIA GPU;如果没有 GPU 则需注释掉这段 deploy 配置(模型推理将无法进行,但编译仍可完成)。 init: true+tty: true:以 PID 1 方式运行并分配 TTY,保证roslaunch与运行时进程能正确接收信号。
docker compose up会按依赖顺序启动:ros_master→aloha_ros_nodes/openpi_server→runtime,最终由runtime服务执行python3 /app/examples/aloha_real/main.py进入回合循环(见 examples/aloha_real/Dockerfile 的CMD)。
四、部署方式二:不使用 Docker(三个终端窗口)
不依赖 Docker 时,需要手动准备环境并分别启动 ROS 节点、策略服务器与机器人运行时。
终端窗口 1:创建虚拟环境并运行机器人
# 创建 Python 3.10 虚拟环境 uv venv --python 3.10 examples/aloha_real/.venv source examples/aloha_real/.venv/bin/activate # 安装锁定依赖与 openpi-client 客户端包 uv pip sync examples/aloha_real/requirements.txt uv pip install -e packages/openpi-client # 运行机器人端运行时(默认连接 localhost:8000 的策略服务器) python -m examples.aloha_real.main终端窗口 2:启动 ROS 节点
roslaunch aloha ros_nodes.launch该命令需要在已 source ALOHA fork 工作空间(third_party/aloha编译产物)的环境中执行,负责拉起机械臂驱动、RealSense 相机发布与夹爪控制等 ROS 节点。
终端窗口 3:启动策略服务器
uv run scripts/serve_policy.py --env ALOHA --default_prompt='take the toast out of the toaster'scripts/serve_policy.py会根据--env ALOHA自动选择pi0_baseCheckpoint(对应gs://openpi-assets/checkpoints/pi0_base)并加载对应环境的输入/输出变换(对 ALOHA 而言是 src/openpi/policies/aloha_policy.py 中的AlohaInputs/AlohaOutputs),在默认端口8000上提供 WebSocket 策略服务。--default_prompt指定当前回合使用的自然语言指令。
机器人端运行时的工作机制
对照 examples/aloha_real/main.py,运行时启动流程为:
- 创建
WebsocketClientPolicy,连接host(默认0.0.0.0)与port(默认8000)上的策略服务器,并打印服务器元数据(含reset_pose复位姿态); - 用服务器下发的
reset_pose构造AlohaRealEnvironment; - 将策略包装进
ActionChunkBroker(action_horizon=25,即每次推理预测 25 步动作块); - 组装
Runtime,以max_hz=50(50 Hz 控制频率)运行,支持num_episodes、max_episode_steps参数控制回合数与每回合最大步数。
其中ActionChunkBroker(位于 packages/openpi_client/src/openpi_client/action_chunk_broker.py)负责将策略预测的动作块按步序切分下发——模型并非每步都推理,而是每action_horizon步推理一次,中间各步开环执行预测的动作块。
观测与动作空间
从 examples/aloha_real/real_env.py 的类注释可以明确动作/观测的维度结构:
- 动作空间(14 维):
[左臂关节角 (6), 左夹爪归一化位置 (1), 右臂关节角 (6), 右夹爪归一化位置 (1)],夹爪 0 表示闭合、1 表示张开; - 观测空间:
qpos(14 维,关节角 + 夹爪)、qvel(14 维,角速度 + 夹爪速度)、effort(力矩)以及四路相机图像cam_high、cam_low、cam_left_wrist、cam_right_wrist(均为 480×640×3 的 uint8 图像)。
在 examples/aloha_real/env.py 的get_observation中,图像会先删除深度通道,再经image_tools.resize_with_pad缩放填充到224×224并转为 uint8,最后重排为[C, H, W]送入策略;动作则从策略输出中取出actions字段直接执行。reset()会通过real_env依次重启夹爪电机、复位关节到reset_pose、执行「先闭合再张开」的夹爪复位(该顺序与原始 ALOHA 相反,是为了匹配 pi 内部数据采集时的夹爪初始状态并减少电机故障)。
策略服务器与客户端的完整链路
服务端与客户端的协议细节可参考 docs/remote_inference.md:
- 服务端:
uv run scripts/serve_policy.py --env ALOHA等价于执行uv run scripts/serve_policy.py policy:checkpoint --policy.config=pi0_fast_aloha --policy.dir=gs://openpi-assets/checkpoints/pi0_base之类的底层命令——--env只是快捷方式,你也可以为自己训练的 Checkpoint 显式指定policy:checkpoint与config/dir参数来启动服务器; - 客户端:
openpi-client包提供websocket_client_policy.WebsocketClientPolicy(host, port),机器人端只需构造{"observation/image": ..., "observation/wrist_image": ..., "observation/state": ..., "prompt": ...}观测字典,调用client.infer(observation)["actions"]即可拿到形状为(action_horizon, action_dim)的动作块。proprioceptive 的state可以传未归一化的原始值,归一化在服务器端完成;图像建议在客户端先resize_with_pad到 224×224 并convert_to_uint8,以降低带宽与延迟。
五、ALOHA Checkpoint 使用指南
pi0_base模型可以在 ALOHA 平台上零样本完成简单任务;此外官方额外提供两个微调 Checkpoint,可完成更进阶的任务。需要强调的是:零样本运行仍是实验性功能,不保证在你的机器人上一定成功;官方推荐的使用方式是用目标机器人的数据微调pi0_base。
| Checkpoint | 任务 | Prompt | 路径 |
|---|---|---|---|
pi0_base | 简单任务零样本 | 视任务而定 | gs://openpi-assets/checkpoints/pi0_base |
pi0_aloha_towel | 把毛巾折成八折 | fold the towel | gs://openpi-assets/checkpoints/pi0_aloha_towel |
pi0_aloha_tupperware | 打开保鲜盒并把食物倒到盘子上 | open the tupperware and put the food on the plate | gs://openpi-assets/checkpoints/pi0_aloha_tupperware |
这些微调配置在 src/openpi/training/config.py 中均有对应定义(pi0_aloha_towel、pi0_aloha_tupperware),它们都基于pi0模型,数据侧使用LeRobotAlohaDataConfig并指定assets=AssetsConfig(asset_id="trossen")加载 Trossen 机器人的归一化统计,同时把default_prompt预设为任务指令、在policy_metadata中给出复位姿态[0, -1.5, 1.5, 0, 0, 0]。
以下为各任务的经验性场景布置建议——策略曾在多套 ALOHA 工位上、未见过的条件下工作,但这些建议是为了最大化成功概率而总结的。
1. 吐司任务(Toast Task)
机器人需要从烤面包机中取出两片吐司并放到盘子上。
- Checkpoint 路径:
gs://openpi-assets/checkpoints/pi0_base - Prompt:
take the toast out of the toaster - 所需物体:两片吐司、一个盘子、一台标准烤面包机
- 物体分布经验:
- 真吐司与橡胶仿真吐司均可;
- 兼容标准双槽烤面包机;
- 各种颜色的盘子均可。
场景布置建议:
- 烤面包机放在工作区左上象限;
- 两片吐司初始时位于烤面包机内,且至少 1 cm 的面包露出顶部(便于抓取);
- 盘子大致放在工作区中下方;
- 自然光与合成光均可,但不要让场景过暗(例如不要放在封闭空间或窗帘下)。
2. 毛巾任务(Towel Task)
机器人将一条小毛巾(约手巾大小)对折成八折。
- Checkpoint 路径:
gs://openpi-assets/checkpoints/pi0_aloha_towel - Prompt:
fold the towel - 物体分布经验:
- 各种纯色毛巾均可;
- 纹理复杂或条纹毛巾上表现较差。
场景布置建议:
- 毛巾摊平并大致放在桌面中央;
- 选择与桌面颜色反差明显的毛巾(避免融为一体)。
3. 保鲜盒任务(Tupperware Task)
机器人打开装有食物的保鲜盒并把内容物倒到盘子上。
- Checkpoint 路径:
gs://openpi-assets/checkpoints/pi0_aloha_tupperware - Prompt:
open the tupperware and put the food on the plate - 所需物体:保鲜盒、食物(或类食物物品)、盘子
- 物体分布经验:
- 各种仿真食物均可(如仿真鸡块、薯条、炸鸡);
- 兼容不同盒盖颜色与形状的保鲜盒,方形带角掀盖的保鲜盒表现最佳;
- 策略见过各种纯色盘子。
场景布置建议:
- 保鲜盒与盘子都大致放在工作区中央附近时表现最好;
- 相对位置:保鲜盒在左,盘子在其右方或下方;
- 保鲜盒的掀盖朝向盘子。
六、使用自定义 ALOHA 数据集微调训练
官方强烈推荐的方式是采集目标机器人的数据微调pi0_base。整个流程分两步:
第一步:将数据集转换为 LeRobot v2.0 格式
仓库提供转换脚本 examples/aloha_real/convert_aloha_data_to_lerobot.py,把 ALOHA 采集的 HDF5 数据转换为 LeRobot dataset v2.0 格式:
uv run examples/aloha_real/convert_aloha_data_to_lerobot.py \ --raw-dir /path/to/raw/data \ --repo-id <org>/<dataset-name>官方示例是将 BiPlay 仓库的aloha_pen_uncap_diverse_raw原始数据集转换后上传到 HuggingFace Hub,得到physical-intelligence/aloha_pen_uncap_diverse。
该脚本的关键行为(与源码对应):
- 读取原始 HDF5:遍历
episode_*.hdf5文件,从/observations/qpos、/action读取状态与动作;若存在/observations/qvel、/observations/effort则一并读取为速度/力矩特征(通过has_velocity/has_effort自动检测); - 图像处理:固定读取
cam_high、cam_low、cam_left_wrist、cam_right_wrist四路相机(自动忽略 depth 深度通道);对压缩存储的图像用 OpenCV 逐帧解码并转 RGB; - 特征结构:14 个电机(左右各 6 关节 + 夹爪)对应
observation.state与action,图像为(3, 480, 640),数据集以50 FPS、robot_type="aloha"(--is-mobile时用mobile_aloha)创建; - 模式选择:
--mode video|image决定图像以视频还是单帧存储,默认脚本入口为image; - 上传:默认
push_to_hub=True会把转换结果推送到 HuggingFace Hub;本地转换可传--push-to-hub false; - 其他参数:
--task(任务描述,默认DEBUG)、--episodes(选择部分 episode)、--raw-repo-id(当本地目录不存在时直接从 Hub 下载原始数据)。
第二步:定义使用自定义数据集的训练配置
参考 src/openpi/training/config.py 中的pi0_aloha_pen_uncap配置,即可定义使用自定义数据集的新训练配置。具体训练命令请参照仓库根目录 README.md 中关于如何用新配置运行训练的说明。
重要:归一化统计(norm stats)的匹配
基础 Checkpoint 中包含了多种常见机器人配置的归一化统计。当用自定义数据集微调基础 Checkpoint 时,如果该数据集来自这些配置之一,建议使用基础 Checkpoint 中自带的对应归一化统计,而不是重新计算。在示例配置中,这一做法通过AssetsConfig指定:
asset_id指定为对应机器人配置(如trossen);- 同时提供预训练 Checkpoint 的资产目录路径
assets_dir。
例如(来自 src/openpi/training/config.py 中AssetsConfig的文档示例):
AssetsConfig( assets_dir="gs://openpi-assets/checkpoints/pi0_base/assets", asset_id="trossen", )该机制在源码中的语义是:AssetsConfig决定数据管线使用的资产(如 norm stats)的加载位置,这些资产会被复制到 Checkpoint 的assets/<asset_id>目录下,从而在微调时复用与预训练一致的归一化范围,避免因统计不匹配导致的训练不稳定或效果退化。
七、故障排查与注意事项
- 策略无法连接:确认
openpi_server已就绪且端口 8000 未被占用;Docker 方式下runtime服务依赖openpi_server,但实际推理请求发生在运行时启动之后,模型加载可能需要较长时间(首次需下载gs://openpi-assets/checkpoints/pi0_base等 Checkpoint,请保证网络可达 GCS)。 - 相机无图像:检查
realsense_publisher.py中的序列号是否与rs-enumerate-devices输出一致;Docker 方式确认/dev已挂载且容器为 privileged 模式。 - ROS 通信失败:所有服务(或三个终端)必须共享同一 ROS master;Docker 方式已统一使用
network_mode: host。 - 复位姿态差异:
pi0_aloha系列配置在policy_metadata中定义reset_pose=[0, -1.5, 1.5, 0, 0, 0],与 examples/aloha_real/real_env.py 中的默认值DEFAULT_RESET_POSITION=[0, -0.96, 1.16, 0, -0.3, 0]不同——运行时以服务器下发的reset_pose为准,若更换 Checkpoint 请留意复位姿态的变化。 - 零样本不稳定:正如文档强调,零样本运行是实验性功能。若任务失败率偏高,优先按第五节中的场景布置建议调整物体位置、光照与初始状态,或采集数据走微调路线。
- GPU 缺失:非 Docker 方式确保运行
serve_policy.py的机器有可用 GPU;Docker 方式注释掉 compose 中的 GPUdeploy段仅用于完成构建,实际推理仍需 GPU。
八、总结
本文完整梳理了 openpi 在真实 ALOHA 平台上从零到一部署 pi0 策略的路径:硬件准备与相机序列号配置、Docker 与手动双模式启动、ActionChunkBroker+ WebSocket 策略服务器的推理架构、三个预训练 Checkpoint 的场景布置经验,以及用convert_aloha_data_to_lerobot.py转换自定义数据集并微调训练的完整流程。相关可深入阅读的仓库资源包括:
- 运行时入口与参数:examples/aloha_real/main.py
- 环境适配与真实硬件封装:examples/aloha_real/env.py、examples/aloha_real/real_env.py
- 关节/夹爪标定常量:examples/aloha_real/constants.py
- 远程策略服务器与客户端协议:docs/remote_inference.md
- ALOHA 策略输入输出变换:src/openpi/policies/aloha_policy.py
- 数据转换与训练配置:examples/aloha_real/convert_aloha_data_to_lerobot.py、src/openpi/training/config.py
- 整体训练说明:README.md
【免费下载链接】openpi项目地址: https://gitcode.com/GitHub_Trending/op/openpi
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考