双 Franka 使用 PICO 采集与 DAgger#
双 Franka 真实世界任务中,PICO 可用于双手遥操作采集和在线 HG-DAgger 接管。#
本指南介绍如何在双 Franka TCP-rot6d 环境中使用 PICO 进行示教数据采集,并以 PICO 人工接管运行在线 Human-Gated DAgger。双臂硬件、实时内核和相机检查请先参考 使用双 Franka;PICO / XRoboToolkit 数据发布链路请先参考 Franka 真机使用 VR 遥操作设备; HG-DAgger 的单臂流程可参考 在 Franka 上使用 HG-DAgger。
概览#
用 PICO 左右手柄分别控制双臂 Franka,先采集 tcp_rot6d 格式 LeRobot 数据, 再参考 使用双 Franka 准备 OpenPI π₀.₅ student checkpoint,最后在真机上启动在线 HG-DAgger。
OpenPI π₀.₅
SFT · HG-DAgger
Dual-arm manipulation
2× Franka · PICO · 3 cameras
任务#
任务 |
配置 / 入口 |
说明 |
|---|---|---|
PICO stream |
|
从 PICO / XRoboToolkit 发布左右手柄和按键数据。 |
Collection |
|
用 PICO 双手遥操作采集 tcp_rot6d LeRobot 数据。 |
HG-DAgger |
|
策略自主执行,PICO 接管帧作为专家数据进入 replay buffer。 |
观测与动作#
字段 |
说明 |
|---|---|
Observation |
左腕、右腕、全局相机,加双臂 TCP / 夹爪状态。 |
Action |
双臂 tcp_rot6d: |
Reward |
脚踏人工标记的成功 / 失败信号。 |
Prompt |
|
安装与节点布局#
软件环境#
机器人节点#
在每台直接与 Franka 通信的机器人节点上分别执行机器人节点安装。根据 Franka 官方
compatibility matrix
选择 LIBFRANKA_VERSION;避免使用 libfranka 0.18.0。
git clone https://github.com/RLinf/RLinf.git
cd RLinf
export LIBFRANKA_VERSION=0.15.0 # 替换为与固件兼容的版本
bash requirements/install.sh embodied --env franka-franky --use-mirror
source .venv/bin/activate
franka-franky 环境会安装 franka extra,其中包含 PICO consumer 侧所需的
pyzmq。PICO 头显、XRoboToolkit PC Service 和 vr_data_publisher 的安装与验证
流程见 Franka 真机使用 VR 遥操作设备。
推理节点#
运行在线 DAgger actor / rollout 的 GPU 推理节点使用 OpenPI 环境:
git clone https://github.com/RLinf/RLinf.git
cd RLinf
bash requirements/install.sh embodied --model openpi --env maniskill_libero
source .venv/bin/activate
Ray 节点布局#
采集配置使用两个 Franka 节点:
Rank |
角色 |
注意事项 |
|---|---|---|
|
左臂控制、env worker、三路相机、PICO consumer |
需要脚踏设备和 PICO ZeroMQ 地址可达。 |
|
右臂控制 |
只需要右臂 Franka / Robotiq 控制链路。 |
在线 DAgger 配置使用三个节点:
Rank |
角色 |
注意事项 |
|---|---|---|
|
inference / rollout / actor |
通常为 GPU 节点,运行 OpenPI。 |
|
左臂控制、env worker、三路相机、PICO consumer |
需要脚踏设备和 PICO ZeroMQ 地址可达。 |
|
右臂控制 |
只需要右臂 Franka / Robotiq 控制链路。 |
警告
Ray 会在 ray start 时捕获 Python 解释器和环境变量。请在启动 Ray 前完成
source .venv/bin/activate、PYTHONPATH、RLINF_NODE_RANK、
RLINF_KEYBOARD_DEVICE 和 ROS / Franka 相关环境变量配置。
集群设置#
在正式开始实验之前,需要先正确地搭建 ray 集群。
警告
这一步非常关键,请谨慎操作!任何细微的配置错误,都可能导致依赖缺失或无法正确控制机器人。
RLinf 使用 ray 来管理分布式环境,这意味着:
当你在某个节点上执行 ray start 时,ray 会记录当时的 Python 解释器路径和相关环境变量;
之后在该节点上由 ray 启动的所有进程都会继承同一套 Python 环境与环境变量。
我们提供了脚本 ray_utils/realworld/setup_before_ray.sh,
用于在每个节点启动 ray 之前帮助你统一设置环境。你可以根据自己的环境修改该脚本,并在每个节点上 source 它。
该脚本主要负责以下内容:
在使用自定义环境安装方式时,source 正确的虚拟环境;
在 Franka 控制节点上,加载 Franka / Robotiq / 相机所需的运行环境;
在所有节点上设置 RLinf 相关环境变量:
export PYTHONPATH=<path_to_your_RLinf_repo>:$PYTHONPATH
export RLINF_NODE_RANK=<node_rank_of_this_node>
export RLINF_COMM_NET_DEVICES=<network_device_for_communication> # 如果只有一个网卡可以省略
其中 RLINF_NODE_RANK 应在集群的 N 个节点之间设置为 0 ~ N-1,
用来在配置文件中唯一标识每个节点。PICO consumer / env worker 所在节点还需要在
ray start 前导出脚踏设备:
export RLINF_KEYBOARD_DEVICE=/dev/input/eventXX
采集配置中 N=2,rank 0 为左臂 / env / PICO consumer,rank 1 为右臂。
DAgger 配置中 N=3,rank 0 为 OpenPI inference / actor,rank 1 为左臂 /
env / PICO consumer,rank 2 为右臂。
在完成上述环境设置后,可以按如下方式在各节点上启动 ray:
其中 <head_node_ip_address> 为 head 节点的 IP 地址,必须 能被集群中其他节点访问。
# 在 head 节点(节点 rank 0)上
ray start --head --port=6379 --node-ip-address=<head_node_ip_address>
# 在 worker 节点(节点 rank 1 ~ N-1)上
ray start --address='<head_node_ip_address>:6379'
可以通过执行 ray status 来检查集群是否已正确启动。
配置#
主要配置文件#
配置 |
用途 |
|---|---|
|
PICO 双臂 tcp_rot6d 数据采集。 |
|
PICO 人工接管的在线 HG-DAgger。 |
|
双臂 TCP-rot6d 真机环境默认配置。 |
硬件占位符#
在采集和 DAgger 配置中替换以下字段:
LEFT_ROBOT_IP/RIGHT_ROBOT_IP:左右臂 FCI IP。BASE_CAMERA_SERIAL、LEFT_CAMERA_SERIAL、RIGHT_CAMERA_SERIAL: RealSense / Lumos 相机 serial 或稳定/dev/v4l/by-id路径。base_camera_type、left_camera_type、right_camera_type:相机类型, 通常为realsense、lumos、lumos。left_gripper_type/right_gripper_type:夹爪类型,Robotiq 夹爪填robotiq。LEFT_GRIPPER_CONNECTION/RIGHT_GRIPPER_CONNECTION:Robotiq 串口路径。left_controller_node_rank/right_controller_node_rank:左右臂控制节点 rank。采集配置通常为0/1;DAgger 三节点配置通常为1/2。node_rank:DualFranka 硬件配置所在的 env / PICO consumer 节点 rank。采集配置 通常为0;DAgger 三节点配置通常为1。TASK_DESCRIPTION:采集和 DAgger 使用的任务文本,应与 checkpoint 训练时一致。joint_reset_qpos:根据采集数据首帧关节均值或安全 home pose 设置。target_ee_pose和ee_pose_limit_min/max:按工作空间重新确认。
PICO 配置#
采集配置中 PICO consumer 地址位于 env.eval.pico.zmq_addr;DAgger 配置中位于
env.train.pico.zmq_addr。该地址必须与 publisher 绑定地址匹配:
ZMQ 数据流由 env worker / PICO intervention 所在节点订阅;在本文配置中,采集时为
rank 0 的左臂控制节点,DAgger 时为 rank 1 的左臂控制节点。
使用双臂 PICO 遥操作时,必须将 pico.hand 设置为 "dual",这样左 / 右
PICO 手柄才会分别绑定到左 / 右机械臂。
env:
train:
use_pico: True
pico:
zmq_addr: "tcp://<vr_publisher_ip>:<port>"
hand: "dual"
control_trigger: "grip"
calibration:
button: "trigger"
如果 publisher 和 env worker 在同一台机器,可以使用 ipc:///tmp/vr_data.ipc。
如果跨机器运行,publisher 侧绑定 tcp://0.0.0.0:<port>,RLinf consumer
侧填写 tcp://<vr_publisher_ip>:<port>,不要把 0.0.0.0 写到 consumer 配置里。
默认手柄语义:
左手 grip -> 接管左臂
右手 grip -> 接管右臂
左手 X/Y -> 关 / 开左夹爪
右手 A/B -> 关 / 开右夹爪
trigger -> 以当前头显朝向重新标定 operator base
采集和 DAgger 的 hold_current_when_inactive 语义不同:
采集配置为
True:未按grip的手臂保持当前 TCP,适合纯遥操作数据采集。DAgger 配置为
False:未按grip时保留策略动作,只把接管帧标为专家数据。
启动 PICO 数据流#
先在 PICO publisher 机器启动 XRoboToolkit PC Service,再启动 VR 数据发布进程。 示例命令如下,具体安装路径见 Franka 真机使用 VR 遥操作设备:
cd /opt/apps/roboticsservice
bash runService.sh
cd /path/to/pico_software/XRoboToolkit-Teleop-Sample-Python
source .venv/bin/activate
cd /path/to/pico_software
python -m vr_data_publisher --config configs/vr_bridge.yaml
在运行 env worker 的节点上验证 PICO 数据可达:
cd /path/to/RLinf
source .venv/bin/activate
export PYTHONPATH=$PWD:${PYTHONPATH:-}
python toolkits/realworld_check/test_pico_data.py \
--zmq-addr tcp://<vr_publisher_ip>:<port>
输出持续刷新,并且按下 grip、trigger、A/B、X/Y 时数值变化,
才继续启动真机采集或 DAgger。
采集 PICO 示教数据#
执行采集#
确认左右 Franka、Robotiq、相机、脚踏、PICO 数据流和采集 Ray 集群都正常后,在 head 节点执行:
bash examples/embodiment/collect_data.sh realworld_dual_franka_collect_data_pico
脚踏按键:
a:开始录制;录制过程中再次按下将中止录制并丢弃当前 buffer。b:递增segment_id,用于标记子任务边界。c:标记成功,写入 LeRobot shard,并结束当前 episode。
PICO 操作:
戴好头显并面向工作台正前方。
扣下
trigger完成 PICO base 标定。按住左 / 右手
grip分别接管左 / 右臂。用
X/Y控制左夹爪,用A/B控制右夹爪。松开某只手的
grip后,对应手臂保持当前 TCP。
采集脚本会在 logs/<timestamp>/ 下写出:
replay-buffer 轨迹:
demos/LeRobot 数据:
collected_data/rank_0/id_0/,后续 shard 为id_1、id_2
PICO 双臂采集已经使用 realworld_dual_franka_tcp_rot6d 环境,数据动作就是
tcp_rot6d;因此不需要执行 GELLO 流程中的 backfill_tcp_rot6d.py。
备注
配置中 data_collection.resume: True 只会在相同 save_dir 下续写。
collect_data.sh 默认每次创建新的 logs/<timestamp>,若要多次追加到同一数据集,
请把 data_collection.save_dir 改为固定路径。
准备 checkpoint#
在线 DAgger 需要一个可部署的 OpenPI checkpoint。数据整理、norm stats、SFT 和 checkpoint 目录准备请直接参考 使用双 Franka 中的 SFT 与部署 checkpoint 流程。
使用本页 PICO 采集的数据时,数据已经来自 realworld_dual_franka_tcp_rot6d 环境,
不需要再执行 GELLO 关节数据流程中的 backfill_tcp_rot6d.py。
完成 checkpoint 准备后,在
examples/embodiment/config/realworld_dual_franka_dagger_openpi.yaml 中设置:
rollout:
model:
model_path: /path/to/deploy/global_step_<N>
actor:
model:
openpi_data:
repo_id: <repo_id>/tcp_rot6d_v1
运行在线 HG-DAgger#
检查 DAgger 关键配置#
启动前确认以下字段:
algorithm:
dagger:
only_save_expert: True
env:
train:
use_pico: True
keyboard_reward_wrapper: eval_control
pico:
zmq_addr: "tcp://<vr_publisher_ip>:<port>"
hand: "dual"
hold_current_when_inactive: False
eval:
use_pico: False
only_save_expert: True 表示 replay buffer 只保存 PICO 接管产生的专家帧。
env.eval.use_pico: False 表示评测阶段只看策略本身,不混入人工接管。
执行 DAgger#
确认 DAgger Ray 集群已经启动后,在 head 节点启动在线训练:
bash examples/embodiment/run_realworld_async.sh realworld_dual_franka_dagger_openpi
运行中的操作方式:
a:从 idle 状态启动一次策略 rollout。左 / 右手
grip:接管对应机械臂;未接管的手臂继续执行策略动作。b:标记失败并结束当前 rollout。c:标记成功并结束当前 rollout。
每次 episode 结束后,env 会 reset 并再次等待 a。策略执行中只在需要纠正时按住
grip,松开后让策略继续运行;这些接管片段会通过 info["intervene_action"]
进入 HG-DAgger 的 replay buffer。
监控#
启动 TensorBoard:
tensorboard --logdir ./logs
推荐关注:
train/dagger/actor_loss:基于接管数据的监督损失。train/replay_buffer/num_trajectories:已保存轨迹数量。train/replay_buffer/total_samples:可训练样本数。train/actor/lr和train/actor/grad_norm:训练稳定性。
采集阶段可以直接查看 logs/<timestamp>/run_embodiment.log,确认成功 episode
计数和 LeRobot 写出路径。
故障排查#
- DAgger 等待时间过长未启动
这是
keyboard_reward_wrapper: eval_control的预期行为。若 DAgger 运行后长时间 等待未开始,可踩一下映射到键盘a的脚踏启动 rollout。