ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

四足机器人运动控制:强化学习与PD参数优化实战

四足机器人运动控制:强化学习与PD参数优化实战 四足机器人这个方向这几年被媒体说得热闹真正干过的人知道光是把一条腿的摆动相和支撑相交替跑顺就够折腾一阵子了。我最早入坑时实验室那台四足机器人用传统MPC方法调了一个多月走三步摔两步。后来切到强化学习路线在仿真环境里跑通了通用运动控制策略有人说这是用了多么高深的算法其实核心逻辑非常朴素让策略网络学会在什么状态输出什么目标角度而底层那套PD参数决定了策略学得快不快、实机平台稳不稳。这篇把我在四足机器人通用运动控制策略强化学习与PD参数优化这件事上的经验全部摊开包括状态动作空间怎么设计、奖励函数怎么避坑、PD增益怎么和强化学习配合、Sim-to-Real要处理哪些细节以及一次真实的步态抖动排查全过程。适合谁看如果你正要开始给四足机器人做运动控制或者已经在调PD/MPC但觉得每种地形调一遍参数实在太痛苦想试试用强化学习换一种思路这篇文章应该能让你少走几周弯路。1. 通用运动控制策略背后的痛点与范式转变1.1 固定参数控制器的天花板在哪里四足机器人这种系统本质上是一个高维、强非线性、变拓扑摆动相和支撑相切换、还带冲击的多体动力学系统。传统控制方案里最典型的是两条路线一条是纯PD/计算力矩控制优点是简单可靠缺点也很明显——它完全依赖你手工调出来的增益能覆盖所有运动状态。同一个Kp、Kd值在慢走时可能很稳一加速就开始振换个斜坡地形又跟不住。我见过不少组在实验室地板上走得很顺的机器人拿到户外草地上直接躺平根因就在这PD参数是线性增益而四足运动是高度非线性的过程。另一条是MPC模型预测控制加WBC全身控制通过优化求解每一时刻的足端力和关节力矩。这个方法在MIT Mini Cheetah、Unitree系列等很多开源平台上被验证过效果上限很高。但代价是——你需要一个足够准的动力学模型需要实机标定惯性参数、摩擦参数、电机力矩常数需要在每个控制周期内完成QP求解。一旦场地条件变化大草地、沙地、泥地、斜坡那个线性化后的预测模型很快就不准了。所以通用这个词对传统方法来说是个奢侈的要求。你会发现大量时间花在这个地形参数要重新辨识一下这个速度下MPC权重得改一下。这本质上是一种针对特定工况做数值拟合的工作模式不具备跨场景迁移能力。1.2 强化学习带来的范式转变强化学习的思路完全不同。它不试图手工推导一个精确的控制律而是通过状态输入-动作输出-奖励反馈的循环让一个策略网络在大量交互中自己学会从观测到动作的映射。对四足机器人来说这个映射学到的其实是**在当前状态下我该输出一组什么样的关节目标角度/力矩才能既前进、又稳、还省力**。这个范式最大的好处是整个过程不需要显式建模地面摩擦力、地形起伏、电机延迟这些复杂物理量。只要仿真环境里把这些物理效应渲染得足够丰富策略自然会把怎么应对不同地面状态内化到网络权重里。拿我自己的经历来说之前用MPC调了一个多月没跑起来后来参考开源项目把强化学习的完整链路搭好大概两周就在仿真里走稳定了。不是说MPC不行而是强化学习的搜索空间更通用——它不依赖一个精确模型它只需要一个足够逼真的交互环境。1.3 为什么是强化学习 PD参数而不是端到端这是新手最容易误解的地方。看到强化学习控制四足机器人很多人以为策略网络直接输出12个关节的力矩指令底层什么都不管纯端到端。实际工程里几乎没人这么做。原因很简单关节力矩直接由神经网络输出相当于让策略同时学习规划轨迹和稳定跟踪两件事搜索空间巨大训练效率极低实机也很容易因为一个输入扰动产生剧烈力矩抖动。底盘厂商、电机驱动器、减速器、阻抗特性各异端到端学出来的力矩控制策略跨硬件迁移极差。PD控制器虽然笨但它有一个非常宝贵的特性——对误差的即时反应是确定性的。你给它一个目标角度它立刻产生一个与误差成比例的纠正力矩这个反馈环节不依赖模型天然稳定。所以主流做法其实是分层结构上层强化学习策略网络以机器人状态和用户速度指令为输入输出各关节目标位置有时加前馈力矩。下层每个关节一个PD控制器按照Kp*(q_target - q_cur) Kd*(dq_target - dq_cur)计算力矩输出。强化学习负责聪明PD负责稳。策略不用管电流环怎么兑现这个指令PD也不用管下一步该迈哪条腿各干各的活。这也解释了为什么标题里把PD参数优化和强化学习并列——PD是整个闭环里最接近物理执行的那一环它的参数好坏直接决定了上层策略学出来的动作是否可执行。2. 策略网络内部设计状态空间、动作空间与相位变量的作用2.1 状态空间哪些观测必须进网络通用运动控制策略要处理的输入要覆盖机器人现在是什么姿态脚踩在什么地形用户想让它怎么走三类信息。我整理一份我在项目里使用的状态空间你可以作为起点状态类别具体内容维度为什么需要身体姿态翻滚角、俯仰角由IMU四元数换算2保持身体水平是运动控制的基本目标身体角速度三轴角速度3阻尼需要用角速度来判断姿态变化趋势关节状态12个关节的当前角度12策略必须知道每条腿当前构型才能规划下一步关节速度12个关节的当前角速度12判断当前运动趋势避免动作突变线速度基座系下的x/y向速度可观测或估计2判断实际前进速度也是奖励函数依据指令用户给出的前向速度、横向速度、转向角速度3策略要响应不同速度指令动作反馈上一时刻网络输出的动作值12让动作变化平滑避免每帧输出跳变相位变量一个0~1周期变量2告诉策略当前处于摆动相还是支撑相注意相位变量这一步很关键。四足行走本质上是四条腿按特定节律在摆动相和支撑相之间切换。如果没有任何相位概念策略可能学出一个四条腿同时抡的古怪步态——虽然在奖励数字上能前进但效率极低还伤关节。我通常给每条腿一个相位变量 phi定义为周期内从0走到1前半段是摆动相、后半段是支撑相再用 sin(2piphi) 和 cos(2piphi) 两个值进网络让策略能用连续信号感知步态周期。2.2 动作空间选型位置增量、绝对位置、力矩动作空间的选择对训练效果影响巨大这一点被很多新手忽略。常见三种绝对目标关节角度策略直接输出12个关节的目标角度。优点是实现最简单缺点是网络输出的绝对值稍有偏差PD就会跟踪到错误位置且不同机器人关节范围不同需要精细scale。位置增量相对动作策略输出的是目标角度的增量当前目标角度 上一时刻目标角度 增量。这个做法的关键优势是天然带平滑性——目标角度不会瞬间从一个值跳到另一个值。它还天然兼容不同的关节初始位置部署时不需要重新初始化目标值。我最终选的就是这种。目标角度 前馈力矩输出目标角度的同时额外给一个前馈力矩项。适合需要大力矩爆发的高速运动奔跑、跳跃但需要标定电机的力矩常数实机调试成本更高。从通用性角度位置增量是最稳妥的起点。它既给了PD明确的跟踪目标又通过增量限制把策略太激进导致实机抖动的风险从结构上压低了。2.3 策略网络与PD的分工边界这里我说一个经验性原则策略网络只负责规划不负责补偿突发干扰。突发干扰比如脚踩到一个小石子由PD的低层反馈快速处理策略网络因为推理频率受限根本来不及反应。所以策略输出的是一个期望的关节轨迹PD的任务是把当前状态拉向这个轨迹。两者一个管去哪一个管怎么稳过去。下次你看到某个机器人视频里脚踢到障碍物后依然稳住大步走别以为那是策略网络看到了障碍物多半是PD反馈在毫秒级别扛住了冲击策略只是顺势调整了一下目标。这个分工还带来一个额外好处调试的时候可以分层排查。机器人姿态发散先看PD是不是没跟踪住目标角度如果PD跟踪得很好但步态就是不对那问题在策略网络或者奖励函数。这个从下往上的排查顺序在后面第6章的抖动案例里还会用到。3. 奖励函数实践如何把走得稳翻译成数学模型3.1 把运动目标拆解成连续可微的奖励项奖励函数是强化学习的指挥棒。四足运动控制里通常不会用一个稀疏奖励比如走到终点才算成功因为那会让策略在百万步探索中拿不到任何梯度信号。我常用的做法是把运动目标拆成几个连续项速度跟踪项贴近指令速度。这部分是核心奖励直接决定策略愿不愿意往前走。形式一般是指数函数exp(-(v_cmd - v_actual)^2 / sigma)好处是范围在0~1之间不会因为速度偏差大导致奖励梯度过大、训练发散。姿态稳定项身体要大致水平。对roll和pitch角度做指数惩罚只要偏差不大就不会压掉速度项。动作平滑项相邻两个动作的差异要小。这是个轻量惩罚防止策略为了刷速度分而疯狂抖动关节。能量项力矩和关节速度的乘积要小。鼓励策略用更自然、更省力的步态而不是像抽筋一样乱蹬。这个设计思路的核心只有一条奖励数值不是目的行为导向才是目的。每个奖励项都要问自己一句它会诱导策略产生什么行为。3.2 我踩过的奖励设计坑步态坍塌与奖励膨胀坑一步态坍塌。早期我把速度跟踪权重调得极高结果策略学出了一个非常奇葩的动作——四条腿几乎同时蹬地靠一次次兔子跳往前窜。从奖励数值上看它得分最高但从运动质量上看这根本不是正常行走且关节冲击极大。解决办法是加约束项比如对支撑相和摆动相的相位错开进行奖励或者对足端冲击力做惩罚让策略必须用前后腿交替摆动的方式前进。更本质的解法是用相位变量在奖励里做引导让每条腿在相位周期的特定区间摆动周期之间偏移固定角度对角小跑是半个周期错开策略就很难再退化成兔子跳。坑二奖励膨胀。多个奖励项同时作用时如果某一项的范围远大于其他项训练前期梯度会被它主导。比如速度项权重是5姿态惩罚是0.1那策略初期会极度偏向刷速度姿态完全不管最后学出一个歪着身子猛冲的姿势。解决方式是所有奖励项尽量保持在同一个量级多用指数函数把偏差映射到0~1区间。调奖励函数和调PID参数其实很像——先整体跑通看哪一项主导了行为再微调权重而不是一开始就试图把所有项调到完美。3.3 一套可复用的奖励函数参考结构我提供一个验证过的参考结构包含典型权重幅度可按你的仿真框架调整r 1.0 * exp(-(v_cmd_x - v_x)^2 / 0.25) # 前向速度跟踪 0.8 * exp(-(v_cmd_y - v_y)^2 / 0.25) # 横向速度跟踪 - 0.5 * (roll^2 pitch^2) # 姿态偏差惩罚 - 0.1 * ||angular_velocity||^2 # 身体角速度惩罚 - 0.5 * ||q_dot||^2 # 关节速度惩罚平滑 - 0.0005 * ||torque||^2 # 能量消耗惩罚 - 0.2 * ||action_delta||^2 # 动作变化量惩罚 - 0.3 * foot_slip_penalty # 支撑相足端滑动惩罚其中foot_slip_penalty是支撑相时足端水平速度的L2范数。你可以先按这个结构跑通再精调不要一开始就自己发明一堆奇形怪状的数学表达式。3.4 训练阶段的奖励调整策略训练初期我强烈建议先把姿态稳定项和动作平滑项的权重从默认值加大30%-50%让策略先学会站得稳、动得缓速度跟踪跑得慢一点没关系。等策略学会了基础步态再把速度权重提上去让它在稳的基础上追求快。这个稳字诀其实和调PD一个逻辑——先保证不摔再追求性能。还有一个小技巧用看训练曲线的斜率变化来判断奖励设计是否合理。如果总奖励前期快速上升然后进入平台期说明基础步态已经学到了后续要提高上限得靠调整奖励项细节或扩展地形随机性而不是单纯等训练时长安。4. PD参数在强化学习框架里的真实角色4.1 先明白PD是策略训练的环境的一部分很多人以为PD参数只是实机部署最后那步要调的电机参数其实它在训练阶段就已经在影响整个学习过程了。在强化学习训练里策略输出的动作就是PD控制器的目标位置而环境返回的状态是PD控制器跟踪后的实际运动结果。也就是说PD增益直接决定了状态转移概率。Kp10和Kp50策略看到的同一动作指令对应的身体运动反应完全不同。如果PD太软策略发现目标角度设了但脚根本抬不动它会学出一套自我欺骗的策略——输出极端位置指令去补偿跟踪不足在仿真里看似有用实机上会变成剧烈抖动或电流过载。如果PD太硬一点误差就产生巨大纠正力矩容易激起关节振荡尤其在摆动相末期落地冲击时高频振动会让IMU数据大量污染。所以PD参数是策略的任务难度旋钮太软任务无法完成太硬任务难以收敛。4.2 一组可用的PD增益初始化范围不同机器人腿长、质量、减速比差异很大但我可以给一组基于常见中小型四足机器人单腿重量约0.5-2kg肩高20-40cm的参考范围关节Kp (位置增益)Kd (速度增益)髋关节外展20-400.5-1.0髋关节前摆30-500.8-1.5膝关节35-601.0-2.0膝关节比髋关节需要更大的Kp因为扭矩臂更长需要更多力矩来抵抗重力。Kd通常取Kp的1/20到1/30过高的Kd会放大速度噪声实机上尤其明显。实际的取值流程我推荐三步走在仿真里把机器人悬空把Kp设到一个基础值给关节一个目标角度观察能否快速收敛且无明显超调。接地后设一个很低的前进速度指令观察腿在支撑相时有没有明显下沉Kp不够或者有没有持续的高频抖动Kp/Kd偏高。找到跟踪得稳但不振的临界值区间再在这个区间内跑一轮强化学习对比选学习曲线收敛更快的那组。4.3 强弱PD对强化学习的实际影响对比我做过一组直接对比。同样一套奖励函数和网络结构Kp全调大2倍训练出来的策略在仿真里表现差别不大但部署到实机上非常明显高Kp那一版腿部振动大、关节温度高、落地冲击大低Kp那一版步态偏软容易在斜坡上打滑摔倒。背后机理是强化学习在仿真里学到的是一种基于仿真动力学模型的预期。仿真里电机、减速器、摩擦模型都很干净不存在真实物理中的齿槽效应、死区、线缆阻力。PD增益越高仿真和实测的差异越容易被放大PD增益适中时策略对模型误差的敏感度会低很多。所以我不建议为了追求跟踪精度把Kp调得过大——适度软一点反而对Sim-to-Real有好处。4.4 把PD参数也纳入领域随机化通常我们说的领域随机化包括地形、摩擦系数、质量分布。但别忘了PD参数本身也是要随机化的。实测中发现实机调试时电机温度升高会让绕组电阻略有变化电流环参数也会飘这相当于PD有效增益在变小。因此训练时给PD增益加±20%左右的随机扰动可以让策略学会在关节响应快一点/慢一点的情况下都能维持不错的表现。这一点投入产出比极高——几乎不增加训练成本但实机的鲁棒性提升非常明显。5. 从仿真到实物我还原一套完整的Sim-to-Real部署流程5.1 仿真环境的几个关键建模细节仿真环境是强化学习策略的训练场环境保真度直接决定了策略能否顺利迁移到实机。我这里特别注意几个容易被忽略的物理量电机力矩曲线很多仿真环境默认电机最大力矩恒定但真实无刷电机在高速区力矩会下降。如果不建模这个特性策略可能学出我要在高速时输出大扭矩的动作实机上电机根本给不到。关节速度限制策略可能会尝试让关节速度飙到仿真允许的极限之外在实机上加一个限幅器强行截断那个冲击瞬间就会破坏协调性。所以仿真里就要把每个关节的最大角速度写进约束。足端接触模型四足机器人是靠足端和地面的接触力完成支撑、蹬地、缓冲的。接触模型的刚度和阻尼设置不合理会导致策略学到假动作——仿真里能站稳实机上因为地面接触特性不同直接扑街。我在通用策略训练时会随机化接触刚度和摩擦系数让策略不能过度依赖某一种接触特性。5.2 领域随机化的实践清单这是Sim-to-Real最重要的一环。下面是我常用的一组参数范围来自多个开源项目和自己的实践随机化对象范围地面摩擦系数0.5 ~ 1.25PD增益Kp/Kd基准值 ±20%整机质量±10%电机最大力矩±10%身体重心偏移±2cm外部推力扰动随机方向幅值0~5N地面高度噪声每步仿真加一个随机小高程足端横向外力模拟碰撞灌木、侧踢等情况这些随机化不是一次性加进去建议分阶段打开。先开摩擦和PD增益让策略学会基本适应训练稳定后再开质量、推力扰动最后再开地形噪声。如果一开始把所有随机化全开策略会让策略收敛极慢而且无法判断是哪个环节出了问题。5.3 实机部署的物理世界细节仿真里一个控制周期是理想化的——状态获取、策略推理、指令下发一气呵成。实机不是IMU数据从总线上读到上位机有延迟神经网络推理要时间指令通过总线发给电机驱动还要时间。这个整链路延迟如果超过一个控制周期策略就会反应慢半拍表现怪异。我在实机上一般把部署架构固定为低频策略层50-100Hz 高频PD层500-1000Hz。策略不需要每毫秒都重新推理它输出的是目标角度轨迹PD层在高频下持续修正误差。这样既保证了策略的时效性又让底层控制足够平滑。有一个细节特别提醒低频策略输出的目标角度变化是离散的如果批次变化太大PD层会在两次更新之间产生阶跃跟踪。我用一个过渡滤波器把目标角度平滑化成每毫秒变化的小步长实机上能显著减少膝关节的突突抖动。5.4 实机调试顺序第一次上实机千万不要直接给高速跑跳指令。我推荐这个顺序悬空测试把机器人吊起来让四条腿悬空执行从仿真导出的动作序列。观察关节实际反馈角度和目标角度是否贴合有没有报错、异响、追不上目标的情况。原地小步幅速度指令设0只让策略输出站立和原地踏步动作。观察姿态是否平稳支撑相有没有明显漂移。低速前进0.2m/s平行地面走直线随时准备急停。逐步提高速度、加入转向、走上斜坡或草地。每次切换前保存一份完整日志关节角度误差、PD输出力矩、IMU姿态、策略输出动作。日志和仿真日志对齐是后面排障的核心工具。6. 一次真实的排障记录步态周期性抖动的完整排查链路6.1 现象描述实机上把速度从0.3m/s提到0.5m/s时出现了一个很典型的问题机器人总体能往前走但步态带着明显的周期性抖动尤其在摆动腿伸出、快要落地的那一段膝关节部位能听到电机高频咯咯响身体在前进方向上有规律的俯仰起伏。仿真里用同一套权重跑却没有这种现象。这类问题很难靠直接改参数一次性解决因为现象背后可能有多层原因。下面就是我完整排查的思路你可以当作一份问题排查模板来用。6.2 第一步仿真复现与对比日志我做的第一件事不是上实机改参数而是回到仿真环境里复现同一工况对比两边日志。仿真里没有抖动但把实机日志和仿真日志叠加对比后我发现一个关键差异实机状态里摆动相末期膝关节目标角度变化异常剧烈——策略在两次更新50Hz之间给膝关节下了一个幅度超过0.2弧度的跳变目标而PD层为了跟上这个阶跃目标产生了接近限幅的瞬时力矩随后又因为超调剧烈回拉一拉一冲之间就形成了高频抖动。这个现象在仿真里几乎不会出现因为仿真里的PD跟踪条件太理想了——没有通信延迟没有总线周期限制目标角度和实际角度几乎同步。而实机上策略推理频率低、指令到达延迟目标角度的跳变落到PD层时已经是突然出现。6.3 第二步定位根因——为什么策略会输出大跳变继续往深挖为什么策略会在摆动相末期输出这么剧烈的目标角度跳变我打开训练日志里的动作增量曲线发现大部分时间动作增量都控制在合理范围但在支撑相和摆动相交界处的相位切换点附近动作增量的方差明显变大。根因在奖励函数设计里摆动相末期策略为了给落地做准备需要把脚调整到一个合适的落地姿态。如果落地姿态和当前姿态差异大而策略又只学了位置到达目标没有在奖励里显式惩罚动作变化率它就会倾向于一次性把目标角度改到位而不是分几步平滑调整。这种为了结果不择手段的动作模式在仿真里因为PD跟踪过于理想而被掩盖了实机上一遇到延迟就被暴露出来。6.4 第三步见招拆招的三层修复原因定位清楚了修复方案就很明确我分了三层处理第一层策略层限速。在策略输出动作增量的地方加了一个限幅器把每个控制周期允许的最大增量从0.15弧度降到0.05弧度。这个动作等同告诉策略你可以快速规划但关节目标位置必须一步一步挪过去。第二层PD层平滑。在PD跟踪目标位置前加了一阶低通滤波时间常数约0.02秒。这样策略输出的目标角度跳到最终值后PD实际跟踪的是一个平滑上升的过渡曲线电流不会出现阶跃尖峰。第三层奖励函数补盲区。把动作变化惩罚项||action_delta||^2的权重从0.2提到0.4并且在摆动相末期额外加了一个落地平稳惩罚——让策略学会提前规划落地姿态而不是临到落地前才猛甩脚。改完后重新训练了约200万步导出策略上实机验证同样的0.5m/s速度指令膝关节的咯咯声消失身体俯仰起伏明显减小步态重新变得干净利索。6.5 从这个案例可复用的排障思路以后再遇到仿真正常实机异常类问题我强烈建议你按这个链路走先别改任何参数把实机日志和仿真日志的同一段状态并排对比找到差异最大的那个观测量。从差异向回追溯差异是出现在策略输出层面还是PD跟踪层面把这两个阶段分开评估。如果问题在策略输出看奖励函数有没有鼓励瞬变的盲区如果问题在PD跟踪看目标角度有没有阶跃、频率是否匹配、延迟是否可以容忍。修复顺序一定是从结构上降低问题发生概率而不是加大Kd硬压抖动。硬压Kd短期可能掩盖问题但会让策略和实机的物理特性脱节换一个工况就会复发。按这个思路我后来还排查过类似的现象策略输出频率从50Hz提升到100Hz后抖动消失本质就是降低了目标角度的步长还有一例是落地冲击引起机身共振最终靠把姿态惩罚项从roll/pitch的平方惩罚改成加一个带通滤波的冲击惩罚解决。这类问题共同的特点就是仿真给了你太多理想化信任实机用物理现实无情地把你的信任消费掉。只多踩几次你会自然形成条件反射大跳变必查频率、高增益必查噪声、周期性问题必查相位切换。最后一点实际体会做四足机器人运动控制这几年我最深的感触是强化学习和PD参数不是先进替代落后的关系而是一个负责聪明、一个负责可靠的搭档。在你把PD那层物理基础打牢之前学再多先进算法都像在沙地上盖楼。所以如果你也是刚开始干这行花点时间摸透你的电机、你的减速器、你的关节响应特性比花更多时间调网络结构划算得多。通用运动控制策略的通用两个字从来不是单一算法能撑起来的它是物理层、控制层、学习层层层叠加之后攒出来的结果。
返回列表