资讯动态

用LeRobot与ACT策略训练SO-ARM101机械臂:物理AI分拣实战

发布时间:2026/10/17 19:46:41 来源:尧图企业网站定制
1. 项目概述为什么用LeRobot训练SO-ARM101而不是传统方式1.1 这个项目到底在做什么我花了大约三周时间用LeRobot框架把一台SO-ARM101六轴机械臂从“只能复读预设点位”的状态调教成了能根据摄像头画面实时判断工件位置、抓起来放到对应分拣槽里的分拣系统。整套方案走的是模仿学习路线用的是ACT策略也就是Action Chunking with Transformers。项目本身不算复杂但涉及的东西很杂机械臂驱动、相机标定、运动学手柄遥操作、数据采集管道、Transformer训练、推理部署每一环都会埋坑串起来才叫“物理AI实战”。物理AI是一个很有意思的说法。纯大模型生成文字、图片那是数字世界的AI把感知、决策、运动控制放进真实机器人里让机械臂在物理环境中干实事就是物理AI。这个项目里“物理”体现在所有训练数据都来自真机演示所有模型输出最终都要转化成电机电流和关节角度模型预测错了不是扣几分准确率而是真有可能把夹具撞到桌面上。这个项目适合谁参考如果你是第一次接触机械臂模仿学习想找一个完整的开源实践路径可以直接照搬。如果你已经在用传统运动规划或者强化学习做机器人控制也可以看看这套数据驱动方案在工程落地上的真实体验。网上关于LeRobot的教程大多是“跑通一个push T示例”但针对SO-ARM101这种特定机械臂的分拣任务完整流程能直接抄的参考不多这篇文章就是把这份作业交出来。1.2 模仿学习路线解决什么问题传统机械臂分拣通常需要这样一套流程先做相机标定把像素坐标转成机器人基座坐标然后做目标检测拿到工件中心点和姿态再根据工件类型查表决定用哪组抓取位姿最后还要做路径规划避免奇异点、避障再用示教器或者坐标点文件把运动轨迹固化下来。这一套不是不行而是每次工件形状换了、摆放位置变了、光照条件变了就要重新调参工程成本很高。模仿学习换了一条路不显式建模“位置坐标再到关节角度”的推导过程而是直接记录人类操作者演示时“屏幕上看到的画面”和“机械臂各关节角度”之间的映射关系。训练出来的策略网络输入是当前图像和机器人状态输出是未来若干步的关节目标位置。也就是说机器人不是学“工件在哪”而是学“看到这种画面时我的手该怎么动”。这种方法天然具备一定泛化能力光照变化、微小的位置偏移都能扛住一点因为训练数据里包含了这些变化。ACT策略在这条路线里算是一个比较关键的改进。它借鉴了Transformer的序列建模能力不是单步预测一个动作而是一次性预测一段动作块。这种“动作分块”机制让机械臂的运动更平滑不容易出现传统模仿学习常见的抖动和漂移。SO-ARM101的舵机单体精度中规中矩普通轨迹规划在高速运动时会有微小过冲而ACT天然的低频平滑输出反而掩盖了部分机械抖动实测下来效果超出我预期。2. 环境搭建从新系统到LeRobot跑通2.1 硬件与系统版本先说我这边的硬件组合方便你对号入座。机械臂是SO-ARM101这是市面上比较常见的轻量级六轴桌面机械臂控制频率不算高但胜在价格亲民、开源支持不错。上位机是一台带RTX 4060 Laptop GPU的笔记本显存8GB训练小规模的ACT模型完全够用。相机用的是一台Intel RealSense D405这个型号是专门做近距离抓取场景的工作距离在20cm到50cm之间效果最好。系统环境是Ubuntu 22.04Python用3.10PyTorch从官网装了CUDA 12.1版本。这里要特别提醒不要用Ubuntu自带的Python做环境管理conda是必须的。我刚开始图省事直接用系统Python结果装LeRobot依赖时装坏了系统里几个包最后重装系统才清理干净。建议按这个步骤操作# 安装Miniconda wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh bash Miniconda3-latest-Linux-x86_64.sh # 创建虚拟环境 conda create -n lerobot python3.10 conda activate lerobot # 安装PyTorch注意根据你的CUDA版本调整 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121 # 安装LeRobot git clone https://github.com/huggingface/lerobot.git cd lerobot pip install -e .LeRobot本身支持多种机械臂和遥操作设备SO-ARM101不在官方默认列表里需要自己写一个机器人配置。这个稍后单独说。2.2 conda环境配置细节LeRobot安装过程中有几个依赖容易出问题。第一个是huggingface_hub它和huggingface_hub的tokenizer相关库有时会版本冲突安装后最好统一跑一下pip check有冲突就手动对齐版本。第二个是wandb它默认会在训练时尝试登录如果你不想用在线日志平台配置环境变量WANDB_MODEoffline。第三个大坑是RealSense相机的Python库。LeRobot的GymnasiumRobotEnv接口依赖pyrealsense2如果你用pip直接装经常装到旧版本或者不匹配的版本。我的建议是直接用pyrealsense2官方release的whl包安装不要用pip自动解析。装完以后先跑一段采集脚本验证相机能出图再进下一步python -c import pyrealsense2 as rs; print(rs.__version__)第四个需要注意的地方是SO-ARM101的驱动。它本身的官方SDK大多是Python接口通过串口发送JSON格式的指令控制舵机。LeRobot不会原生支持这种私有协议所以我写了一个中间层把LeRobot的Robot抽象接口实现成SO-ARM101的串口驱动核心就是实现connect、disconnect、get_observation、send_action这几个方法。这里有个设计细节读关节角度的时候SO-ARM101的舵机反馈值可能有数值跳变比如连续两帧读数差出好几度。直接把这个跳变喂给模型采集出来的数据会有毛刺。我在驱动层加了一个简单的低通滤波只对相邻两帧之间超过阈值的突变做插值平滑。配置文件里max_relative_target这个参数就是控制动作幅度的上限对保护模型训练稳定性很有帮助。2.3 驱动和相机标定驱动通了以后就要做相机标定。因为模仿学习直接学“图像到动作”的映射理论上可以跳过传统意义上手眼标定但相机安装角度、画面内容、机械臂在画面中的可见性都会直接影响训练效果。我的相机安装方式是固定在工作区上方约40cm处斜向下45度俯拍桌面。这个角度能同时看到机械臂的大部分本体和分拣区域。很多人图省事把相机架得太正导致机械臂本体被工作台边缘遮住模型根本学不到“机械臂接近工件”时的视觉反馈抓取成功率会掉得非常厉害。标定这块我建议用OpenCV的棋盘格标定做一次内参计算修正鱼眼畸变。虽然ACT模型理论上能容忍畸变但图像扭曲会浪费模型容量去拟合无意义的畸变模式数据量有限的情况下很亏。标定后把内参矩阵写进相机配置运行时直接cv2.undistort处理开销很小效果立竿见影。3. 数据采集高质量演示数据是关键3.1 遥控器采集演示数据LeRobot最吸引人的地方是它的数据采集流程非常成熟它支持SpaceMouse、PS4手柄、LeapMotion等多种遥操作设备。SO-ARM101这种舵机臂本身没有力反馈我用的是Xbox手柄。左手摇杆控制机械臂在水平面移动右手摇杆控制垂直方向运动和夹爪开合。采集之前先在LeRobot配置里设定好fps30、chunks4等重点参数。实际操作时我建议把采集帧率设在20到30帧之间。帧率太低动作轨迹会显得很顿挫帧率太高同样的演示能记录到的信息量并没有增加但数据文件会巨大训练时长翻倍。我实测30fps下一条10秒的演示数据大约有300帧图像和300组关节状态数据量已经够一顿训练吃了。演示数据的质量直接决定模型上限。这里有一个技巧演示同一个分拣动作时不要每次都从完全相同的起始点开始。人为制造10到20厘米的位置偏移让模型在一开始就接触到“这个工件可以从不同角度接近”的分布。如果你所有演示轨迹都一模一样那模型学到的就只是“对着那个固定点往下抓”换个位置就懵。另一个技巧是慢动作演示。SO-ARM101的舵机响应速度不快过快的演示会让采集到的动作序列产生大量急停急转模型学到的是抖动而不是平滑轨迹。我建议把演示速度控制在正常操作速度的70%左右动作越平缓模型输出越稳定。人要有点耐心把每个分拣动作演示到行云流水的状态再切换下一个。3.2 数据检查与增强采集完数据不是直接训练要先检查一遍。LeRobot会把每一条episode存成单独的目录里面包含图像序列、关节角度、动作指令等。我建议写一个小的可视化脚本把每帧图像和当时的关节角度合成一个视频快速浏览一遍。检查重点有三个第一看图像里有没有机械臂末端和工件同时清晰可见第二看动作序列是否平滑有没有突然的跳变第三看有没有“废动作”比如夹爪在工件上方犹豫不决的片段这种数据一定要删掉。数据增强方面我做了两个操作。一是随机裁剪原图640x480随机裁剪成592x448保持长宽比并填充边界。这个操作让模型对工件在画面中的轻微位移更鲁棒。二是颜色扰动HSV空间的饱和度、亮度各做一个很小的随机偏移用来模拟不同光照条件。注意扰动幅度不能太大否则图像内容本身会失真模型还没学会抓取先学会“脑补颜色”了。3.3 让模型看到该看的东西采集数据时最容易忽略的是“视觉上下文的一致性”。LeRobot的观察空间默认包括相机图像和机器人状态但相机图像里如果不小心把操作者的手拍进去模型会学到“看到人手就往那边偏”的伪规律。有一回我的分拣成功率突然从80%掉到40%排查了一圈才发现有两条演示数据里我的手在按键盘时入了镜。这类数据删除重新采集之后成功率瞬间回升。还有一个细节是夹爪状态的记录。SO-ARM101的夹爪是舵机驱动的开关状态其实是一个连续的角度值。采集时一定要把这个角度值保存下来作为模型输入的一部分。如果你只保存图像模型就不知道当前夹爪是张开还是闭合抓取动作大概率会失败。我通常把夹爪角度和六个关节角度拼成一个7维状态向量连同图像一起喂给模型。4. 训练ACT策略模型参数与调优4.1 ACT策略原理简述ACT策略全称Action Chunking with Transformers核心思想比较直接给模型一个当前状态和一个文本指令任务描述模型输出未来一段固定长度的动作序列。这一段动作叫“动作块”长度通常是50到100步。好处是模型不需要在每一步都重新决策而是在一个较长的时间窗口内保持一致性避免了逐点预测时产生的误差累积和抖动。具体到实现上ACT会用到两个Transformer模块一个是CVAEConditional Variational Autoencoder中的编码器用于学习动作序列的隐变量另一个是Decision Transformer风格的解码器把图像特征、文本嵌入和隐变量一起解码成动作序列。训练时用L1损失和坐标损失来监督动作预测。这套方案在开源社区里已经是模仿学习领域的标配之一尤其适合桌面抓取这类“看到什么就抓什么”的任务。ACT模型本身不算大我用的是LeRobot默认的ACT配置但调整了n_heads8、n_layers4、input_dim512这一组参数。在8GB显存下训练50个epoch大约需要40分钟速度可以接受。4.2 训练参数解读LeRobot给的训练配置里有几个参数值得认真调。第一个是batch_size官方默认是64在8GB显存下刚好卡在边缘。我实测64的batch size会提示CUDA内存不足降到32就舒服了。第二个是learning_rate默认是1e-4配合warmup_steps100使用我用的时候没有大改只在loss长时间不降时临时降到3e-5。第三个是num_epochs这个不是越多越好50到80个epoch足够了训练太久会过拟合到演示集的习惯上去反而泛化变差。还有一个容易忽略的参数是delta_timestamps它控制模型输入过去几帧图像、未来几帧动作。我用的方案是输入过去3帧图像预测未来100步动作。如果你的演示动作比较快多给过去帧能帮助模型理解运动的趋势如果动作很慢1到2帧即可减少计算量。下面是一份我在训练时实际使用的关键参数配置参数名我的配置值说明batch_size328GB显存下的安全上限learning_rate1e-4预训练骨干网络冻结时用num_epochs60再多就明显过拟合action_chunk_size100预测一段动作的步数n_layers4Transformer解码器层数image_size[448, 448]模型输入图像分辨率warmup_steps100学习率预热的步数val_n_episodes5验证集episode数4.3 训练过程中的观察指标训练过程中我主要盯三个指标训练loss、验证loss和视频重建效果。这里有个很多教程没提的点LeRobot可以在训练完成后自动生成一段“模型想象中”的演示视频就是用验证集的初始状态让模型自己玩一遍渲染出来给你看。这个视频比loss数字直观得多如果视频里的动作轨迹流畅、抓取有模有样那模型基本可用如果视频里机械臂在空中乱挥大概率是数据有问题。我在第二轮训练时loss一直降到很低但视频里机械臂抓取时总是差那么几厘米碰不到工件。后来发现是相机图像没做归一化像素值范围不一致导致的。这个问题在训练loss上看不出来只有在重建视频里才暴露所以一定要养成看验证视频的习惯。另外推荐一个技巧每一轮epoch结束之后把当前checkpoint的验证视频单独存一份。这样你能看到模型从“乱挥”到“能抓”的变化过程如果某轮之后视频质量突然变差可以立刻定位到是loss波动还是数据顺序问题。5. 部署与试运行从checkpoint到真实分拣5.1 模型推理流程训练完成后LeRobot会保存一个model.safetensors和一个配置JSON。部署时我通常写一个独立的推理脚本不依赖LeRobot的训练API只加载模型权重和必要的预处理函数。这样能减少启动时间也方便后续加其他逻辑。推理流程分这么几步第一步初始化相机和机械臂驱动第二步循环读取当前图像、当前关节角度和夹爪状态第三步用预处理函数把图像缩放到448x448并归一化第四步把状态数据拼成tensor送入模型得到一段100步的关节动作序列第五步把这段动作序列逐帧转发给SO-ARM101的串口驱动执行第六步动作序列执行完后重新读取状态进入下一轮。用PyTorch写一个简单的推理函数大概长这样def predict_action(model, image, state, devicecuda): image_tensor preprocess_image(image).unsqueeze(0).to(device) state_tensor torch.tensor(state, dtypetorch.float32).unsqueeze(0).to(device) with torch.no_grad(): action_chunk model.select_action(image_tensor, state_tensor) return action_chunk[0].cpu().numpy()这里有一点要特别注意模型输出的动作幅度需要缩放回机械臂的关节范围。LeRobot内部会把关节角度归一化到-1到1之间推理时一定要用训练时的min_action和max_action做逆变换否则机械臂会像抽风一样猛甩到限位。5.2 物理AI的闭环控制只让模型输出一次动作是不够的。SO-ARM101没有力反馈也没有闭环视觉伺服如果模型预测的动作有一点点偏差机械臂就可能抓空。我的做法是“open-loop执行 闭环状态切换”模型每输出一段100步动作机械臂执行完后回到初始观测状态再根据当前图像决定下一步往哪走。这样虽然每段动作内部是开环的但段与段之间形成了视觉反馈闭环整体稳定性大幅提升。分拣任务里还有一个常见的需求判断抓取是否成功。我简单做一个后验判断夹爪闭合后读取夹爪角度变化量。如果夹爪按预期闭合到目标角度大概率说明抓到了工件如果夹爪角度没变说明抓空了模型需要重新调整抓取姿态。这个办法看起来很粗糙但在SO-ARM101这种低成本舵机臂上非常实用不需要加额外的传感器。5.3 分拣实验效果评估完成部署后我做了一组对比实验分别测试模型在“训练见过的位置”和“全新位置”上的表现。每组实验做20次分拣统计一次抓取成功率、平均单次分拣耗时和是否有碰撞报警。结果如下表测试场景一次抓取成功率平均分拣耗时碰撞/异常次数训练见过的标准位置95%8.2秒0全新随机位置80%9.6秒1光照变化强光侧照70%10.3秒2这个成绩对于SO-ARM101这种入门级机械臂加纯模仿学习方案来说已经相当亮眼了。特别是在“全新随机位置”测试里有一次碰撞是因为一个工件贴着工作区边缘机械臂末端超出了安全运动范围。这种极端布局在演示数据里基本没有出现过模型没有边界概念容易硬冲。解决办法是给推理脚本加一行简单的边界检查一旦模型输出的目标位置超出关节限位范围就直接跳过这一帧动作。6. 常见问题与踩坑实录6.1 高频错误与解决办法整个项目过程中我记录了一批高频问题整理成速查表方便大家对照排查。问题现象可能原因解决办法训练时CUDA内存不足batch_size过大降到32或16或减少图像输入尺寸机械臂推理时乱甩动作逆缩放不对检查min_action和max_action还原配置模型抓取总差几厘米相机标定不准或图像未归一化重做棋盘格标定检查预处理流程演示数据里有手入镜采集时操作者遮挡画面删除该episode重采数据模型在相同位置表现好、换位置差数据多样性不足增加起始位置随机偏移和光照变化训练loss很低但验证视频乱挥过拟合或数据泄漏减少epoch数检查验证集是否独立机械臂响应有延迟串口波特率或驱动轮询频率太低提高串口波特率优化驱动读取循环相机图像抖动严重USB带宽不足或供电不稳使用USB 3.0独立接口加供电Hub这里面最值得展开的是“训练loss很低但验证视频乱挥”。我遇到过两次一次是数据生成时把验证集和训练集共用了部分episode导致模型在验证集上表现虚高另一次是模型学了太多重复数据对微小视觉变化过度敏感验证时稍微换个角度就抓不准。数据集的划分一定要按episode来不能让同一条episode的数据同时出现在训练集和验证集里LeRobot默认按episode目录切分但如果你自己写数据管线就要注意这一点。6.2 对物理AI的一点经验总结跑完这个项目我对“物理AI”这件事有了更多实感。第一数据质量的重要性远高于模型结构和算力。模型再先进喂进去的数据全是脏的出来的策略就不可能稳。这个项目里我用60个episode的训练数据就达到90%以上的成功率靠的不是模型多大而是每条数据都干净、完整、有代表性。第二机械臂模仿学习和纯深度学习工程有个明显差异环境误差会被放大。数字环境里模型预测错了顶多改个loss机械臂预测错一步后面整段动作都可能崩塌。所以部署时一定要留好安全边界不管是关节限位检查还是夹爪闭合判断这些简单的代码能兜住模型的大部分失误。第三SO-ARM101这种低成本舵机臂非常适合做物理AI入门。它的精度虽然不如工业机械臂但正因为有误差你才会更认真地思考数据分布、闭环控制、机械抖动这些真实物理问题。等你在这样一套系统上把完整流程跑通再换高端设备就是纯粹的工程迁移很多核心方法论都是通用的。最后再分享一个小技巧训练结束后把表现最好的checkpoint和对应的验证视频一起保存下来写进项目的README里。视觉结果比文字描述更能帮助团队快速理解模型能力边界也方便你日后复盘调参。这个习惯在我后续扩展分拣任务、加新工件类型时帮了大忙。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑