资讯详情

基于LeRobot的多臂协同控制:标定、训练与部署全流程解析

📅 2026/10/23 3:57:38 | 华诺云谱 👁 阅读
基于LeRobot的多臂协同控制:标定、训练与部署全流程解析
干了几年机器人控制最头疼的其实不是让一条臂精准走轨迹而是让两条臂待在同一张桌子上还能“心往一处想”。你单独测左臂走位漂亮得很单独测右臂重复精度也没话说。可一旦让它俩配合拧个瓶盖都能互相怼上或者一个往前一个往后直接打架。这就是我今天想聊的基于 LeRobot 的多臂协同控制怎么把两条机械臂从“各自为政”变成“一个整体”。LeRobot 是目前开源社区里比较完整的机器人学习框架核心思路是用模仿学习让机器人从示教数据里学动作而不是靠手写一大堆规则。多臂协同控制这件事恰恰是模仿学习最能发挥优势的领域——因为两条臂配合的动作比如双手端盘子、协同插线缆、装配零件用传统运动规划去写约束条件会写到怀疑人生但如果你让机器人“照着人怎么操作去学”问题就简单了一大截。这篇文章我会从硬件选型、坐标系标定、数据采集、模型训练、部署调试一路讲到常见坑位目标是让有基本机器人控制经验、但第一次碰双臂平台的开发者能照着这套流程把两条臂真正跑起来。适合的人包括做具身智能研究的同学、实验室里搭双臂平台做验证的工程师以及想从单臂控制往多臂协同进阶的机器人爱好者。1. 双臂协同比单臂难在哪先想清楚再动手1.1 三个绕不开的技术坎第一个坎是坐标系对齐。单臂的时候所有轨迹、位姿都以机械臂自己的基座坐标系为基准你不需要关心别的东西。但双臂一上桌问题立刻出现两条臂各自有各自的基座坐标系你让左臂末端走到坐标 (0.4, 0.1, 0.3)右臂末端也走到同样的坐标这个坐标的意义是完全不同的——因为两个基座可能差了0.5米、转了15度。所以第一步必须把两条臂的坐标系统一到一个公共坐标系下这个动作在机器人领域叫外参标定也就是求两条臂基座之间的变换关系。第二个坎是空间干涉。两条臂的工作空间天然重叠做协同动作的时候如果两边各跑各的轨迹很容易在中途发生碰撞。单臂控制里基本不用考虑自碰撞问题但双臂必须把“另一条臂在哪”实时纳入规划或决策里。实现方式有很多种传统路线是加碰撞检测算法在模仿学习路线里更实用的做法是在数据采集阶段就让人的操作天然避开干涉区让模型学到“双臂该在什么时候让开”的习惯。第三个坎是时间同步。协同动作对双边的时序一致性要求很高。比如双手捧着一个盒子往右平移如果左臂比右臂慢了0.2秒盒子就会被拧歪甚至掉落。单臂控制不需要和谁同步双臂协同则需要让左右臂的控制指令在同一个时间基准上发出这既涉及硬件通信层面的时钟同步也涉及算法层面输出的双路动作是否保持一致。1.2 模仿学习范式下双臂协同的数据更“重”单臂的模仿学习一条数据样本通常是这样一个状态比如当前关节角、末端位姿、相机图像对应一个动作比如下一时刻的关节角目标。这条链路在双臂上直接翻倍状态变成了双臂的联合状态动作变成了双臂的联合动作。假设每条臂6个关节、夹爪1个自由度那么单臂动作维度是7双臂就是14。数据维度翻倍带来两个直接影响一是需要更多数据量才能覆盖足够多的状态空间二是训练时模型要同时拟合两条臂的动作分布难度指数级上升。我在实际项目里体会最深的是数据采集阶段。单臂数据采集你可以慢慢来动着一条臂随时暂停、修正都行。双臂就完全不同了它需要左右手同步操作采集过程几乎不允许“一只手动一只手动”的录制方式——那样学出来的模型只会把两臂当成两个独立任务来处理学不到协同关系。LeRobot 在数据采集环节提供了一套标准的 episode回合机制每一条 episode 都是一个完整任务的左右臂同步记录这种按回合组织数据的方式天然适合双臂协同的学习。1.3 为什么直接选 LeRobot 而不自己造轮子我自己也写过控制程序深知从零搭一条模仿学习链路有多痛苦要写数据采集程序、要接相机同步、要设计模型结构、要写训练循环、要做评估……每个环节都有大量细节一个没接好整条链路就断掉。LeRobot 把这些封装成了标准模块你只需要把注意力放在硬件适配和任务设计上。更关键的是LeRobot 里默认支持了几类主流模仿学习算法比如基于 ACTAction Chunking with Transformers和扩散策略Diffusion Policy的实现。这类算法特别适合多关节高维度输出的场景正好匹配双臂14维动作的拟合需求。框架本身并不限定必须用哪类机械臂只要你把机器人的关节控制接口和相机数据接进来就能复用后面的采集、训练、评估流程。对多数团队来说这是目前把双臂协同最快跑通的一条路。2. 动手前的技术底牌硬件和环境的正确姿势2.1 硬件选型别在起点给自己挖坑先列出我建议的双臂协同最小硬件清单每一件后面都注明为什么不能省硬件数量建议与理由六轴协作机械臂带关节角度反馈2同型号最优关节控制接口统一标定和建模都省事夹爪2优先选带开合度反馈的电动夹爪数据里必须有“夹爪张合程度”这一维RGB-D 深度相机1-2放在能同时覆盖两条臂工作空间的位置别只盯着单臂控制主机1消费级带独显的机器即可LeRobot 训练对显存有一定要求工作台1固定安装位两条臂的基座一旦安装好就不许挪动关于机械臂型号我强烈建议两条臂用同一型号。如果条件所限必须用不同型号那么至少保证关节控制频率一致、控制接口统一否则后面数据采集时左右臂的响应延迟会有明显差异学出来的模型动作会非常别扭。某次我在一个模拟项目里用过两条不同品牌的臂结果训练出来的模型在回放时一条臂已经到位了另一条还在慢悠悠走整个协同动作完全对不上。2.2 软件环境搭建版本踩坑记录LeRobot 的安装流程不复杂但有几个版本坑一定要提前避conda create -n lerobot python3.10 -y conda activate lerobot pip install lerobot注意 Python 版本3.10 是我实测最稳的。装完以后验证一下依赖是否齐全import lerobot print(lerobot.__version__)如果没有报错基本框架就通了。接下来还需要安装 PyTorch推荐在安装 LeRobot 之前先把 PyTorch 装好避免依赖解析和你本机的 CUDA 版本错配。pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118这里的 cu118 对应 CUDA 11.8具体版本根据你显卡驱动来选。我在一台只有低端显卡的机器上试过纯 CPU 训练不是不能跑但效率低到让人失去耐心所以有 GPU 还是尽量用 GPU。2.3 机械臂的通信与控制接口LeRobot 本身不做底层运动控制它需要你提供一个“拿关节角度换动作执行”的接口。常见做法是走 ROS也可以直接走厂商提供的 SDK。我在实际项目里更推荐直接通过厂商 SDK 来控制省去 ROS 环境配置这一层复杂度。你需要在代码里实现的核心接口可以封装成一个机器人类里面至少包含读取关节状态和发送关节目标这两个方法class DualArmRobot: def __init__(self, left_sdk, right_sdk): self.left left_sdk self.right right_sdk def read_joint_states(self): # 返回 left_7d right_7d维度14 pass def send_joint_targets(self, target_14d): # 将14维目标拆成左右各7维分别下发 pass这里有个细节夹爪的开合度最好也作为独立维度和6个关节角一起拼成7维动作向量。LeRobot 内部对动作维度的理解很直接你给它多少维它就拟合多少维夹爪不参与协同配合的任务也可以加但那样模型就学不到“什么时候该抓什么时候该放”。2.4 数据量级预期几百回合起步很多人问我双臂协同到底要采多少数据才能训出一个能看的模型。我的经验是简单任务比如双手把一个立方体从A点搬到B点起步300到500回合中等复杂度任务比如双手协同插线缆要700到1000回合更复杂的精细化任务建议先别急着上真机去仿真环境里预训练再迁移到真机。不要觉得这个数据量吓人一个回合的任务时长通常只有5到15秒按50Hz采样频率也就是250到750帧数据。整个采集过程半天到一天是正常的。真正要花时间的是保证每回合的数据质量而不是盲目堆数量。3. 先让两条臂“说同一种语言”标定与协同环境搭建3.1 标定到底在标什么标定解决的是坐标统一问题。简单理解每台设备都有自己的“世界观”标定就是让两台设备对“什么是桌面上这一点”达成共识。双臂系统里通常要标定两件事一是两条臂基座坐标系之间的变换矩阵二是相机坐标系到某条臂基座坐标系的变换矩阵。变换矩阵这个东西本质是一个4x4的齐次矩阵里面包含旋转分量和平移分量。我一般用这样的方式表述假设你在左臂基座坐标系下有一个点坐标为 p_left那么它在右臂基座坐标系下的坐标 p_right 就等于p_right T_left_to_right * p_leftT_left_to_right 就是我们要求的标定矩阵。采集数据时每帧我们同时记录左右臂的关节角当模型输出动作时它学到的是“在这种联合状态下该输出什么联合动作”这里面的隐式前提就是双臂在同一空间框架下。标定错一点模型学到的协同映射就是错的后面再调参都补不回来。3.2 实操用 ArUco 标定板做双臂基座外参标定我用的标定方法算是经典里的经典把标定板固定在工作台上保证两条臂的相机都能看见它。先让左臂末端的相机读标定板求出左臂末端坐标系与标定板坐标系的变换 T_end_left_to_board再让右臂做同样的操作得到 T_end_right_to_board。因为标定板是同一个所以可以通过矩阵串联算出左臂基座到右臂基座的变换。实现时我直接借助 OpenCV 的 ArUco 模块import cv2 import numpy as np # 假设已经通过相机拍到标定板得到四个角点在图像上的坐标 # corners: (4, 2)实际板坐标按0.05m间距生成 board_points np.array([ [0, 0, 0], [0.05, 0, 0], [0, 0.05, 0], [0.05, 0.05, 0] ], dtypenp.float32) # 通过solvePnP求相机到标定板的位姿 _, rvec, tvec cv2.solvePnP(board_points, corners, camera_matrix, dist_coeffs) R, _ cv2.Rodrigues(rvec) T_cam_to_board np.eye(4) T_cam_to_board[:3, :3] R T_cam_to_board[:3, 3] tvec.flatten()拿到相机到标定板的变换后再通过机械臂的关节角正运动学求出末端到基座的变换 T_base_to_end一串联就成了T_cam_to_board T_cam_to_end * T_end_to_base * T_base_to_board实际工程里我会做至少5次不同视角的采样把每次算出来的矩阵做平均用来压低随机误差。标定做完之后必须验证让右臂末端去碰左臂末端附近的某个固定点把右臂坐标系下读到的位置换算到左臂坐标系再从左臂控制末端去同一个点看看实际误差能不能控制在几毫米内。能说明坐标系对齐了。3.3 安全空间与碰撞避让双臂协同跑起来之后最怕的是训练阶段还没什么问题一到模型的泛化场景两条臂在特定状态下忽然撞上。传统解法是实时做碰撞检测在每步控制前检查两臂的关键连杆距离是否小于安全阈值如果小于就停止运动或进入避让逻辑。我提供一个轻量级近似方案里很常用的做法把每节连杆简化成圆柱体或球体碰撞检测就退化成计算球心距def check_collision(spheres_left, spheres_right, threshold0.05): for sl in spheres_left: for sr in spheres_right: dist np.linalg.norm(sl.center - sr.center) if dist sl.radius sr.radius threshold: return True return False每根连杆包成1到2个球两条臂各6到12个球双循环的计算量也就上百次距离运算完全够实时跑。这个检测结果可以作为数据采集阶段的“安全刹车”也可以作为部署阶段的保护机制。注意这个方案只能拦截碰撞不能规划避让轨迹所以别指望它解决动态避障问题它是兜底不是主力。3.4 标定验证的小技巧标定完成后别急着采集数据花10分钟做个一致性检查。我的做法是让两条臂分别运动到工作空间内的5个不同位置每到一个位置同时记录左臂末端位姿和右臂末端位姿。然后利用标定矩阵把右臂末端位姿换算到左臂坐标系下和左臂直接测得的位姿做差。如果三个位置的平移误差都在5毫米以内、旋转误差在1度以内标定就算合格。这一步看着不起眼却是决定整个项目成败的关键。我曾经跳过验证直接开始采数据训出来的模型表现很奇怪左臂动作基本正常右臂动作完全乱套。后来排查才发现标定矩阵里的平移向量差了2厘米就是因为没做验证直接信任了单次标定结果。4. 数据采集与训练模型是怎么学会“配合”的4.1 采集方案主从遥操作是主流采集双臂示范数据的方式我试过三种示教器逐步编程、视觉动捕跟随、主从遥操作。示教器太慢一个5秒的动作可能要编20分钟动捕方案精度高但设备贵、环境要求苛刻。最适合实验室环境的还是主从遥操作——你用两只手分别控制两条“主臂”从臂实时跟随主臂的动作或者用一个双摇杆手柄控制两条从臂末端速度。LeRobot 社区里常见的方案是双臂同构遥操作两条主臂和两条从臂型号一致主臂的关节角度实时映射到从臂。映射时通常要加一个缩放系数因为人的手臂长度和机械臂的工作空间不一定一致joint_target_from joint_current_master * scale offsetscale 一般取 0.5 到 1.0 之间视工作空间匹配度而定。遥操作的手感和“人机匹配度”直接影响数据质量这一块建议多花时间调直到操作者能流畅、稳定地完成任务再正式开始采数据。4.2 数据集格式与采集节奏LeRobot 采集的数据集按回合组织在本地会生成一个目录里面包含观测数据、动作数据和状态元数据。我通常会以 50Hz 的频率采样也就是说每秒记录50帧。一帧数据里包括左臂7维关节状态6个关节角 夹爪开合度右臂7维关节状态同上相机图像可选用于视觉输入时间戳采集过程中最容易犯的错是“想一次录完”。我用过一段时间后总结出比较稳妥的节奏每采集20到30回合停下来回放其中5回合确认没有异常动作、没有目标物位置偏移过大再继续采。如果连续出现“右手总是没抓到盒子中心”这种问题多半是操作习惯的问题趁早纠正别等数据采完了才发现。目录结构大致是data/ task_name/ episodes/ episode_000001.parquet episode_000002.parquet meta/ info.jsonLeRobot 对这种结构可以直接读取不需要你额外写复杂的解析代码。4.3 训练配置从默认参数开始别乱动LeRobot 内置了多个算法实现我建议先从 ACT 默认配置跑起。ACT 在双臂协同这类高维连续动作控制任务上很稳训练收敛速度也相对快。一个典型的训练启动命令python lerobot/scripts/train.py \ --policy.typeact \ --dataset.repo_idlocal/custom_dataset \ --output_diroutputs/dual_arm_test \ --batch_size8 \ --num_epochs100 \ --lr1e-4这里几个参数值得解释一下batch_size 取 8 是因为双臂联合动作维度较高显存占用大小batch更容易稳定训练。强行上大batch容易OOM收益也有限。学习率 1e-4 是这类模型常见的起点别一上来就调大ACT 结构对这种学习率已经足够。num_epochs 建议先跑 100看 loss 曲线再决定是否继续。有时候 100 轮已经够用不需要盲目堆轮次。训练过程中盯着 loss 曲线。正常情况是前20轮快速下降后面进入缓慢下降平台期。如果 loss 从一开始就不降或者跌到某个值再也不动多半是数据问题不是超参问题先去检查数据回放。4.4 看一眼 loss 曲线和成功率训练结束后LeRobot 会产出 checkpoint。不要只看训练损失训练损失低只说明模型拟合了训练数据不代表泛化好。我把验证拆成两步先在仿真或回放环境里做一次 rollout看模型在“见过的状态附近”表现再上真机做50次评估记录成功率。一个比较可行的验收标准同一个任务模型在真机上连续执行50次成功率做到80%以上才算这个协同动作“学稳了”。如果成功率低先看是左臂的问题还是右臂的问题再具体分析。5. 部署运行与问题排查从“会配合”到“干得好”5.1 模型推理到控制指令的实时链路训练完的模型部署到真机链路是这样的读取相机图像和双臂关节状态 → 输入模型 → 输出一个动作块比如未来50步的双臂联合动作→ 控制器逐帧下发关节指令。LeRobot 的推理逻辑里有一个关键概念叫 action chunking模型一次预测多步动作而不是每帧都重新推理一次。这样做的好处是动作平滑、减少推理抖动。实际部署时要注意模型输出的动作块是关节角目标不是直接发给伺服电机的原始指令。如果你的机械臂SDK提供的是位置控制模式直接下发即可如果是速度控制模式还要先做差分换算。位置控制模式下需要注意下发频率必须和训练时保持一致。训练时用50Hz采集部署时如果只按10Hz下发动作会变得卡顿且生硬。5.2 高频踩坑实录双臂协同部署时我踩过不少坑挑几个最有代表性的说第一两条臂动作明显“一快一慢”。排查后往往不是模型问题而是通信延迟不一致。某型号机械臂的SDK走网络通信天线位置稍有遮挡命令下发的延迟就增大。解决办法很简单把两条臂都用有线连接或者改用同一个实时控制进程统一下发。第二夹爪开合动作错位。模型学得挺好但夹爪张合总是比预期慢半拍。原因通常是采集时夹爪开合度的数值变化是离散的开/闭两档而模型输出是连续的导致夹爪在中间位置卡顿。解法是在夹爪控制里加一个映射阈值把连续输出量化回开关量但如果任务需要精细夹持还是建议换带连续位置反馈的夹爪。第三模型表现的协同动作是对的但总是差一点点就碰到目标物。这个通常是图像输入和关节状态不同步导致的。LeRobot 采集时相机和关节数据会打时间戳同步时如果差值超过两帧模型学到的“视觉-动作”映射就是糊的。所以采集前一定要确认相机的时间戳对齐不要用默认值。5.3 排查速查表问题现象可能原因排查方向双臂动作不协调左右臂节奏不一致通信延迟差异或控制频率不统一检查SDK响应时间统一频率优先有线连接模型输出动作抖动、发飘动作块被逐帧累加误差积累使用LeRobot的chunk机制按块执行做滤波平滑夹爪总是夹偏图像与关节数据时间戳未对齐校准相机时间戳重新同步数据训练loss不下降数据回放有问题或动作维度不匹配先做episode回放确认数据正确性一到某个特定位置两条臂就撞碰撞检测阈值过松调整安全距离重建两臂连杆球体模型模型泛化差换目标位置就失败数据中目标物位置变化太少采集时人为改变目标物位置增加数据多样性5.4 数据质量是第一生产力训练之前先做数据回放检查也就是把采集的 episode 以动画形式播放出来肉眼确认“人的操作痕迹”是否自然、连续。这一步能过滤掉绝大多数的数据问题。我第一次做双臂协同项目时采集了400回合数据觉得肯定够用了结果模型一上真机就暴露问题左臂很稳右臂总是绕远路。回放数据才发现我采集时右手的操作习惯是“先抬高再平移”这个动作模式被模型原封不动学了过去。单看每回合都成功但绕远路这个习惯对效率影响很大。后面重新采集刻意让右手走“直接平移”的路线模型动作立刻变利索了。6. 我的几点经验心得与进阶方向6.1 三条能让项目少走弯路的经验第一条经验先分别把两条臂的单臂控制练到极致再上双臂协同。这里说的“练”不一定是算法层面而是底层接口的稳定性。左右臂各自的关节读取、目标下发、急停逻辑都验证过没问题之后再开始折腾协同和高层学习。很多双臂项目死在底层通信不稳定上这锅不该模型背。第二条经验数据一致性比数据量重要。500回合高质量、目标物位置分散、左右手动作模式一致的数据远胜1500回合随便采的杂乱数据。我在实际测试中把数据量砍掉一半但把每回合的动作质量提上来成功率反而涨了十几个百分点。第三条经验标定不能省也不能只做一次。整个项目过程中机械臂基座一旦被碰歪哪怕只偏了2毫米协同精度就全毁了。每次开机先跑一遍快速标定验证是一个值得养成的好习惯。6.2 后续可以怎么进阶跑通了双臂协同基础闭环之后有很多方向可以继续深入。我目前比较看好的是任务分层上层用一个独立模型负责把任务分解成“左臂负责夹持右臂负责插入”这类子任务下层再用模仿学习模型执行每一个子动作。LeRobot 现在的结构做这个分层改造很方便你只需要在推理链路里插入一个任务规划模块。另一个方向是引入语言指令。给双臂系统加一个语言接口让人说出“把盒子端到左边”模型就自动生成双臂协同动作。LeRobot 后续版本也在往多模态的方向走语言、视觉、动作的统一建模会让双臂协同的实用性再上一个台阶。最后再分享一个小技巧如果你有条件先在仿真环境里把任务跑通再迁移到真机。仿真里采集数据便宜、迭代快用仿真预训练一个基础模型再在真机上用小批量数据做微调能把整个项目周期从两三周压缩到三四天。LeRobot 对仿真环境有现成的支持这也是我为什么一直建议新项目从这套框架起步的原因——少造轮子多验证想法这才是做机器人学习该有的节奏。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑