我用 PPO 把 7 自由度机械臂练到 100% 成功率:3300 轮泛化测试全过
我在 PyBullet 里训练了一台 KUKA iiwa 7 自由度机械臂,任务是任意目标点到达。模型累计训练 500 万+ 步,之后做了两轮验证:一轮是 729 个目标点的网格化全测,一轮是 66 组物理扰动条件下的泛化测试,每组 50 回合,合计 3300 回合。两轮全部通过,成功率 100%,最坏情况下的末端定位误差 4.91 厘米。
整个 demo 可以一键跑起来,固定种子、固定目标序列,谁跑都是同一个结果。这篇文章记录我是怎么做的,以及中间踩的坑。
一、这个 demo 长什么样
输入很简单:一个三维空间里的目标点坐标。
输出也简单:7 个关节的控制指令。
效果:机械臂从初始位姿出发,自己规划着把末端执行器送到目标点附近并稳住。不需要摄像头,不用视觉,全程靠一个 13 维的数值观测向量------关节状态、末端位置、目标位置,拼起来就是模型看到的全部世界。
演示的时候屏幕上有个红色小球标记目标点,机械臂伸过去,稳住,判定成功,换下一个点。我把它做成了固定流程:50 个目标点按网格顺序跑完,终端里逐条打印每个回合的最小距离、步数、耗时,同时写进日志文件。
有一点我特意坚持了:演示必须确定性复现。种子固定、目标点序列固定、物理参数固定。我不希望演示的时候出现"这次运气好"的情况,演示翻车比没有演示更糟。
二、整体结构:四层,各管各的
系统分四层,一层只管一件事:
| 层 | 干什么 |
|---|---|
| 仿真环境层 | 自研到达任务环境,13 维观测、7 维动作,物理引擎做了抽象,PyBullet 之外还预留了 MuJoCo、Isaac Sim、ROS2/Gazebo 三个后端接口 |
| 训练层 | Stable-Baselines3 的 PPO,多环境并行采样,带早停 |
| 迁移适配层 | 仿真策略到真机的适配,13 维观测进、7 维关节指令出,观测维度和训练时严格对齐 |
| 部署验证层 | 部署就绪检查,9 大模块 86 项检查,结论只有两种:过,或者不过 |
为什么这么分?因为我吃过耦合的亏。最早仿真环境和训练脚本搅在一起,改一个物理参数要翻三个文件,后来训练、迁移、验证混在一块,模型换个版本根本说不清是哪层出的问题。拆成四层之后,每层的输入输出都是白纸黑字,出了问题定位快得多。
三、训练:500 万步是怎么跑下来的
训练用的是课程学习的思路,目标难度从近到远、从固定到随机,一步步加上去。具体怎么个加法、奖励怎么设计,这部分是我的核心实现,文章里不展开------我能给的是效果数据:课程难度最低档和最高档各做 50 回合回归测试,都是 50/50 通过。
工程上最值得说的一个数字是训练吞吐。一开始用的是串行向量化环境,吞吐 91 SPS(每秒步数),16 个环境跑起来 CPU 闲着大半。后来换成多进程向量化环境,再处理了一下线程绑定的问题,吞吐拉到 426 SPS,提速 4.7 倍。同样的训练预算,时间直接砍掉一大截。
另外我给了训练一个硬纪律:定期评估,达标就停。不追求"练满预算",只追求"指标到位"。训练这东西,练过头和练不够一样浪费算力。
四、验证:我最较真的部分
成功率 100% 这种话,自己说出来不值钱,得让测试说话。我做了两轮。
第一轮:729 点网格全测。 在工作空间里按 9×9×9 打网格,729 个目标点一个不落全测一遍。结果 729/729 通过,最坏的一个点,末端停在距离目标 4.91 厘米的位置。这个"最坏情况"我比平均成绩更看重------平均值会骗人,最坏值不会。
第二轮:泛化扰动测试。 这一轮是专门防"背题"的。模型在固定参数下练出来的,换个物理条件会不会原形毕露?我扰动了四类条件:
- 摩擦系数:7 档
- 阻尼:5 档
- 重力:3 档(90%、100%、110%)
- 初始关节角:3 组分布,包括一组训练时从没见过的宽分布
66 组条件,每组 50 回合,一共 3300 回合。结果:全部通过,一组没掉。
这里有个细节我想单独说。最早那版模型不是这个成绩。我本地留着一份早期的演示日志,前四个回合全是失败------目标就在眼前,末端差着一两厘米就是稳不住。那份日志我没删,至今还在仓库里。后来重新训练、重新验证,才有了现在这个版本。把失败的日志留着,是我给自己的提醒:100% 不是起点,是改出来的。
五、五层安全控制器:策略之外的一道闸
强化学习的策略输出我从来不直接发给关节。中间永远隔着一层安全控制器,一共五层:
- 输入合法性检查------维度不对、数据异常,直接打回
- 关节限位------任何指令先按物理限位裁剪,越界的量直接削掉
- 单步步长限制------一步只允许动这么多,防止策略抽风似的大幅跳变
- 工作空间监视------末端快出安全区域了就告警
- 碰撞监视------持续监测,异常熔断
设计原则就一条:策略负责"聪明",安全层负责"不出事"。仿真里翻车是日志,真机上翻车是事故。这套闸在仿真里就全程挂着,迁移到真机时原样带走,不是后补的。
六、部署就绪检查:86 项,全绿才放行
模型练好只是上半场,能不能部署是下半场。我做了一份部署就绪检查,9 大模块、86 项检查,覆盖模型加载、空间兼容性、推理性能、硬件安全、仿真到真实迁移、压力测试这些维度。
规则很简单:86 项全过才放行,结论二值化,没有"基本可以""问题不大"这种中间状态。实际跑下来 86/86 全部通过,零失败零警告。
部署还分了三级:测试级、预发级、生产级,每级有各自的必过项清单,低级不过不许进高级。这套分级是从后端工程里搬过来的习惯------我做过后端服务,上线流程那套门禁思维,用在机器人部署上一样成立。
七、自己踩过的坑,三个重点
坑一:观测向量对不上。 训练时是 13 维,推理时手一抖拼成了别的顺序,模型照样输出动作,只是动作全是错的,看起来像"练废了"。其实模型没废,是喂错了输入。后来我把观测拼装做成唯一入口,训练和推理共用一份代码,这类问题从此绝迹。
坑二:把"训练收敛"当成"可以交付"。 训练曲线漂亮不等于泛化好,更不等于能部署。我是被现实教育之后才把验证层独立出来的------现在模型想"毕业",得先过 729 点网格、再过扰动测试、最后过 86 项检查,一关都少不了。
坑三:演示环境不固定。 早期演示没固定种子,同一台机器跑两次结果都不一样,给人看的时候非常被动。现在一切确定性拉满:固定种子、固定目标序列、固定物理参数,跑一百次一个样。
八、如何跑起来
环境要求不高:Python 3.10+,依赖装好就行。
bash
git clone https://github.com/Hxdmou/-embodied-intelligence-demo
pip install -r requirements.txt
python demo_trained_agent.py
Windows 下还有一键启动菜单,仿真演示、GUI 控制、部署健康检查几个入口都在里面,不用记命令。
跑起来之后你会看到机械臂一个点一个点地够过去,终端里实时刷每个回合的数据。键盘可以干预:H 回初始位,空格换目标,ESC 退出。
九、总结
这个项目让我最深的一个体会是:强化学习demo 的难点从来不在"让它动起来",而在"让它每次都行"。从能动到稳定,中间隔着的是验证体系------网格测试、扰动测试、安全闸、部署门禁,一层都不能省。
仿真只是起点,真机才是终点。中间那条路,我还在继续走。
作者方向:AI 智能体应用开发,长期做具身智能仿真与部署工程化。
- GitHub:github.com/Hxdmou/-emb...
- 邮箱:979718240@qq.com(仅文字沟通)