轮式并联五连杆下肢机器人强化学习运动控制建模与仿真
“轮式并联五连杆下肢机器人运动控制”这个标题一出来懂行的朋友应该已经嗅到了两条技术线的交汇一条是支撑移动与步态的机械本体设计另一条是从运动学、动力学到强化学习仿真训练的算法通路。我今年花了大量时间在这个项目上整体跑下来的感受是——真正难的往往不是某一个RL算法模块而是“建模—仿真—训练”这条链路的每一环都在互相影响任何一个环节粗糙一点后面强化学习再怎么调参都像给漏水的桶拧盖子。这个项目要解决什么问题呢简单说就是让一台带有轮式移动底座的下肢机器人学会在室内连续地形上平稳前进、转弯同时通过并联五连杆腿部机构带动下肢完成类人步态的运动。它适合谁做康复机器人、外骨骼、轮足机器人或下肢助力设备的工程师和研究生尤其是那些刚好卡在机械建模和RL训练之间、既不想只会手推公式、也不想只会调库的人。下面我从项目整体思路开始把这条我从零跑通的链路拆开来讲。1. 项目整体拆解为什么是轮式并联五连杆1.1 结构选型轮式底座与并联腿的联姻传统下肢外骨骼大多走串联链路髋、膝、踝几个关节电机直接安装在关节上。表面看结构直观、控制简单但实际用起来问题不少腿部末端惯量大驱动器跟着腿跑能耗高支撑相时连杆刚度有限力控制带宽低更重要的是整机重心偏高一旦负载变化或者用户发力不均衡很容易出现侧向失稳。并联五连杆机构则是另一条路线。它由五根杆件、两个主动驱动关节和两个被动关节组成一个闭环驱动器可以全部安置在靠近骨盆或车架的固定基座上腿部本身只剩轻量化连杆。这么做的好处非常直接末端刚度高、承载力强、驱动动能低而且控制器可以“隔着腿”感受到地面对脚掌的作用力。加上轮式底座之后设计方案就更务实了。轮子负责大部分水平方向移动和平衡问题腿部专注做步态支撑和姿态调整相当于把双足机器人最头疼的静不稳定问题“外包”给了四个轮子。整套系统重心低、续航友好、移动速度快对康复训练场景来说接受度也高。代价则是轮子在室内台阶、坡道、地毯或瓷砖接缝上的打滑问题这个不能只靠机械结构解决必须靠底层控制策略补偿。1.2 运动控制的三个层次与各自痛点这台机器人的运动控制如果从控制栈由上到下拆大致是三个层次。底层是轮式平台的速度控制。差速轮、舵轮或者四轮独立驱动无论哪种构型都要解决给定线速度和角速度后轮子实际转速怎么跟上的问题。这一层传统控制就够用PID、纯跟踪、简单MPC都能胜任难点只在摩擦补偿和轮径标定。中层是五连杆腿的关节轨迹控制。给定一个末端期望轨迹先通过逆运动学解出两个主动关节角再用PD或计算力矩法跟踪。这里的问题在于并联机构的工作空间窄、奇异位形多轨迹稍微规划得不够平滑关节角速度就容易爆表。上层是步态规划与协调控制。怎么决定腿何时摆动、何时支撑怎么根据平台速度调整步幅和相位如何在不平整地面上保持身体姿态不做大幅前倾这些是传统控制最难啃的部分。因为步态本质上是一套受地面交互约束的离散切换逻辑手工写规则也能跑但泛化能力很差换个负载或者换个摩擦系数就要重调。所以我的思路是底层和中层仍然用传统控制器保证安全上层步态协调交给强化学习。这样RL学到的不是“每个关节怎么转”而是“在这种状态下应该给腿部协同策略一个什么样的目标”整个系统的可解释性和安全性都会好很多。1.3 为什么非要用强化学习仿真训练有人可能会问直接上MPC或者模仿专家轨迹不也行吗我一开始也这么想过。但真实下肢机器人的模型参数经常变用户体重、地面坡度、轮胎磨损都会让精确动力学模型瞬间失真。MPC需要频繁在线辨识算力要求高而且遇到接触突变容易保守到不敢动。仿真训练解决的是另一个维度的问题。真机试错成本太高一台下肢机器人动辄好几万一个失稳动作可能就是维修费仿真里可以同时开几十个环境加速时间还可以随机注入扰动、增加负载、改变摩擦系数逼着算法学出真正的鲁棒策略。当然强化学习不是魔术。它的上限取决于仿真环境对现实世界的还原程度。你给机器的模型不对奖励函数设得再精巧学出来的策略在原场景也只是一套“仿真里的神操作”。这也是为什么我会把建模放到和算法几乎同等重要的位置不把仿真环境调到一个可信水平后面一切免谈。2. 建模从几何参数到动力学方程2.1 五连杆机构运动学建模步骤从闭环约束到逆解五连杆机构听起来复杂拆开看其实就是一个由两个RRR分支共享同一个末端点形成的闭环。在连杆编号和关节角定义都没做好之前直接上公式一定会乱。所以建模第一步不是列方程而是画一张运动学简图把每根杆件的长度、每个关节的旋转正方向、驱动关节和被动关节的位置全部标清楚。定义主动关节角为 θ1、θ2被动关节角为 θ3、θ4。以左分支为例末端位置可以用两个夹角表示末端 x 坐标等于第一杆投影加第二杆投影y 坐标同理。右分支也能写出同一末端位置的表达式两个表达式必须相等这就构成了一组闭环约束方程。正运动学是已知 θ1、θ2求末端位置。因为没有额外自由度直接联立圆弧方程就能解出被动角再算出末端坐标。逆运动学是反过来给定末端目标位置后需要从两个圆交点中挑出满足装配模式的解。这一点特别提醒并联机构通常有两组装配模式一组对应“肘外翻”一组对应“肘内翻”如果程序里选错末端轨迹就是镜像的而且很可能直接撞上奇异位形。逆解出来后关节速度之间的关系可以用雅可比矩阵来描述。雅可比矩阵在这个项目里不只是用来求速度的更重要的是检查奇异性。当矩阵接近奇异时关节角速度会非常夸张哪怕末端只移动几毫米电机也可能瞬间输出巨大转速。我建议在仿真里加一项“当前关节角离奇异位形的距离”到观察空间中让强化学习策略自己学会避开这些危险区域效果比事后限幅好得多。2.2 轮式平台与腿部耦合浮动基座系统的数学描述把轮式平台和腿放进同一个坐标系里实际上这就是一个浮动基座机器人系统。平台本身在空中是一个自由漂浮的刚体有六个自由度轮子和地面的接触会产生约束腿部末端则在支撑相被地面固定住在摆动相自由运动。整个系统的完整状态包括平台的三维位置和姿态加上所有关节角。写成状态变量就是 x, y, z, roll, pitch, yaw再加上主动和被动关节角。需要始终记住轮式平台不是固定在世界系里的它的位姿必须作为状态估计的一部分不能假设成一个“地上不动的小车”。轮腿耦合的核心难点在支撑相。当一只腿支撑时腿部末端与地面之间的摩擦锥约束必须被满足否则脚掌会滑动。另一个容易忽略的协调约束是轮子向前滚动的速度和支撑腿推动平台前进的速度必须一致。如果不一致轮子会在原地“磨地”腿部机构会被憋住关节力矩瞬间飙升。所以我处理这种耦合问题时没有硬着头皮去手推全套解析动力学而是用物理引擎的接触模型来承担这部分复杂性。物理引擎里的轮地接触、腿部末端与地面的点接触都能从几何和摩擦参数里自动算出约束力。但这不代表可以完全甩手不管我仍然需要自己定义哪些身体部位允许碰撞、哪些应该忽略以及接触刚度、阻尼、摩擦系数的合理初值。建模做到这份上才算给后面的RL铺好路。2.3 从解析建模到仿真引擎哪个环节最容易失控解析建模和仿真引擎之间并不存在“二选一”的关系而是相互校验的关系。我在项目里保留了完整的解析运动学模型用来做轨迹规划层、调试动作末端坐标同时把物理引擎当作动力学求解器用来算关节力矩和接触响应。在仿真引擎里搭模型时我会做这几件事先用CAD数据或者游标卡尺量出连杆长度、质量、质心位置然后填惯性参数给每个关节加阻尼接着给轮子设置摩擦系数和半径给腿末端加上接触面摩擦特性最后用一个正弦波关节轨迹做动力学校验看仿真输出的关节力矩和解析牛顿欧拉方程算出来的力矩误差是否小于10%。这一步是仿真训练的“体检”。如果不做体检后面RL学到的策略很可能是建在一个动力系统跑偏的仿真世界里的。最典型的失控场景是模型里把腿部连杆质量设得太小仿真里机器人双腿轻飘飘学出来的策略一到真机就腿软或者把摩擦系数设得过于理想机器人能持续打滑而不倒真机上一跑就转向。很多人觉得建模是“脏活累活”不如直接写算法有意思。但我个人认为建模才是这个项目里性价比最高的一环建得越细后面所有环节的坑越少。3. 强化学习仿真训练把机器人变成可学习的环境3.1 状态空间、动作空间与奖励函数怎么设计才不会翻车设计状态空间的第一原则是给算法所有它需要知道的信息但不要塞一堆噪声让它自己筛。我最终用的状态包括平台线速度和角速度、平台姿态角和角速度、两个主动关节的角度和角速度、两个被动关节的角度和角速度以及上一步的动作向量和当前任务目标比如目标线速度和目标角速度。任务目标必须显式放进去。很多新手会让RL自己去“记住”当前任务是什么但网络不是这样运作的它只会模仿训练分布里的经验。如果你希望策略在不同目标速度下都表现好那状态里必须有目标速度信息。动作空间方面我强烈推荐用“目标关节速度/位置 底层PD”而不是直接输出关节力矩。原因有三第一直接输出力矩会让仿真出现高频抖动训练不容易稳定第二底层PD相当于给RL加了一层“保护罩”限制了执行器的响应带宽让策略更容易学会平滑控制第三仿真策略向真机迁移时底层PD可以原封不动保留策略网络只负责给PD发参考信号。奖励函数是这门学科里最像“炼丹”的部分。我给一个简化的参考结构你可以直接套用r w1 * velocity_error w2 * energy_penalty w3 * smoothness_penalty w4 * orientation_penalty w5 * fall_penalty其中 velocity_error 是目标速度与实际速度的代数差通常用负平方绝对值energy_penalty 是关节力矩平方和smoothness_penalty 是当前动作与上一步动作差值的平方orientation_penalty 惩罚躯干偏离水平fall_penalty 在检测到跌倒时给一个大负数。权重分配要谨慎。我最初的版本把 velocity_error 权重调得太高结果是机器人学会了用腿部猛蹬地面来加速轮子反而没怎么参与后来把 smoothness_penalty 和 orientation_penalty 都加上并且给能耗项放到和跟踪误差同一量级动作才稳定下来。3.2 PPO调参心得从收敛到稳定复现强化学习算法我最后选的是PPO不是因为它是所有问题的最优解而是因为它对奖励尺度不那么敏感、实现门槛低、社区踩坑经验多适合这种连续控制任务。先给一套我个人实测效果不错的初始超参数学习率 0.0003GAE lambda 0.95clip 范围 0.2值函数系数 0.5熵系数 0.01并行环境 32 个迷你批量大小 4096 条经验训练步数 500 万左右。网络结构我用了两层全连接每层256个神经元激活函数用ReLU。状态输入会做z-score归一化动作输出是高斯策略每条动作的log std初始给-0.5。这套配置在大多数下肢机器人模型上都能在20到30万步后看到奖励明显上升后面就是慢慢调权重了。训练过程里我最看重四个指标平均奖励、episode长度、策略熵、KL散度。平均奖励上升伴随episode长度上升说明策略在学会“活得更久”熵如果掉得太快策略会过早锁死这时候可以把熵系数从0.01调到0.05KL散度超过设定阈值通常意味着学习率太大策略一次更新走得太远。一个非常常见的翻车点是学习率过高导致策略在某次更新后reward变成NaN或者策略输出方差突然加大。如果发现这种情况别急着降学习率先看是否状态里有NaN通常是因为仿真中关节角速度出现极大值最后把输入归一化炸掉了。3.3 课程学习、域随机化与模型导出直接把机器人扔进全难度的环境中训练很容易陷入“所有技能都学不好”的局面。我的做法是课程学习先让机器人在平整地面学习匀速前进目标速度固定为 0.3 m/s只奖励速度跟踪等到能稳定走半小时不出事再改成随机目标速度区间 0.1~0.6 m/s然后加上转向任务目标角速度随机最后加入地面摩擦变化、随机负载、甚至小坡道。域随机化要穿插在课程后面。比如把轮子摩擦系数从 0.5 到 1.2 随机采样把腿部连杆质量在名义值 ±15% 浮动把重心位置在几个厘米范围内偏移给传感器观测值加高斯噪声。目的很简单就是不要让策略只会处理一个超级干净的仿真世界。模型导出这一步也别忽略。训练好的策略网络我一般会导出成轻量模型格式部署到机载控制板。底层PD在真机上作为独立模块运行策略网络负责参考信号输出二者通过一个工作频率低于底层控制的高层循环同步。策略输出的控制频率不需要太高20Hz到50Hz足够底层PD跑到500Hz以上。这里有个小经验导出前先用评估环境做一次确定性测试关闭探索噪声记录平均reward和任务成功率。仿真里能稳定复现的确定性策略才值得往真机迁如果确定性测试都过不了大概率是训练过程过拟合了噪声策略。4. 常见问题与排查技巧实录4.1 仿真里机器人疯狂原地打转怎么查这个现象我见过不止一次而且大多出现在刚开始训练的头几千步。首先检查轮子差速模型的方向定义——很多新手把左轮和右轮的转速符号搞反导致给目标线速度时左右轮对着转机器人原地打转。排除符号问题后再看腿部摆动带来的反力矩。当腿部摆动相结束时如果脚掌猛烈落回地面会产生一个大的冲击力矩在没有姿态反馈补偿时平台会因此偏转。可以在观察空间中加入平台角速度和角加速度并且提高 orientation_penalty 的权重。还有一个容易被忽略的原因仿真求解器时间步长太大。如果步长超过接触动力学稳定极限轮子的接触力会震荡导致机器人看起来像在“抖着转圈”。我一般把物理步长设在 1/500 秒以下训练环境步长用 1/100 秒中间做两次物理子步跑大部分模型都没问题。排查这类问题最有效的方式是可视化别只盯着曲线看。打开仿真画面暂停在高危时刻检查左轮的转速、右轮的转速、机器人躯干朝向以及腿部末端位置基本一眼就能定位是哪一环出了问题。4.2 奖励函数被“钻空子”那些让人哭笑不得的局部最优强化学习特别喜欢钻空子这是我和它交手这么久最深的体会。第一个常见空子为了速度跟踪机器人把躯干前倾到极限靠重力“自由落体式”前进同时轮子当刹车用。表面看上速度跟踪误差很小但实际姿态已经危险到下一秒就要栽倒。这主要是 orientation_penalty 权重太低甚至没有加。加上之后策略就不会再走这个极端。第二个空子动作输出高频抖动。机器人通过高频小幅振动关节让传感器测出“平均”状态接近目标但真实物理上关节磨损大、功耗高。这个空子靠 smoothness_penalty 来堵但注意权重也不能过大否则策略会为了“少动”而消极怠工速度跟踪误差飙高。第三个空子比较隐蔽机器人学会了卸力。比如让它在跑步机上以目标速度前进它学会把脚撑在地面上让跑步机带着腿走看起来机器人没动但轮子转速很高。这个只能靠奖励函数中加入“平台必须在空间中有位移”这个事实条件来堵或者用更接近真实任务的环境不能只在理想跑步机上训练。4.3 sim-to-real gap的根源和缓解办法从仿真到真机差距主要来自三个层面物理引擎的接触模型过于理想、电机执行延迟和力矩响应带宽、连杆柔性带来的高频震荡。这些差距不是单靠RL算法能解决的而是要从建模和训练策略两端一起堵。我建议所有人在做仿真训练前先对真机做一次简单的系统辨识给轮子发出一个阶跃速度指令记录实际速度响应曲线辨识出执行器延迟和摩擦系数再给腿部关节一个正弦轨迹记录力矩响应和仿真对一下。辨识完把参数填回仿真模型再跑RLsim-to-real差距能小很多。域随机化也要加入这个辨识结果作为先验。比如真实摩擦系数在0.6附近那仿真里采样范围设为 0.45~0.75 而不是 0.1~1.0真实连杆质量偏差大约在 ±5%那采样范围设为 ±10% 就够了别过度随机化否则策略会因为任务“太不一致”而学不到东西。部署时我还有一个土办法先在仿真里把低层PD的鲁棒性调到能在±20%模型偏差下仍能跟踪目标轨迹再训练高层策略。这样即使底层参数有偏差策略层的决策输入也不会因为执行误差而完全失真。4.4 训练不收敛的排障清单下面这张表是我在这个项目里反复用到的排障清单基本覆盖了我遇到过的绝大多数训练问题。症状排查方向解决手段reward长期不增长熵系数过高导致探索过剩或学习率过低检查熵曲线降到0.005~0.01学习率提到3e-4reward偶尔NaN状态/动作出现NaN或奖励权重过大检查仿真数据做状态归一化限制奖励数值范围episode长度缩短提前终止条件过于严苛或机器人频繁跌倒放宽终止条件检查跌倒判据调整权重重心策略锁定单一动作熵系数太低经验多样性不足提高熵系数增大并行环境数增加初始动作噪声训练稳定但验证失败过拟合训练环境缺少域随机化加入摩擦/质量扰动真实场景测试学习率太高导致策略崩塌KL散度超过0.15~0.2降低学习率或减少迷你批量大小还有一个容易被忽略的点是初始状态分布。如果每次训练都是从同一姿态、同一速度开始策略只会学会“从同一个坑里爬出来”而不是学会“面对各种状态都能做出动作”。我建议每次reset时随机化初始姿态角在 ±10 度范围内初始速度在目标速度附近 ±0.1 m/s 抖动。这样训练出来的策略泛化能力会明显好很多。关于训练时长我的建议是不要一味追求跑满几百万步。如果并行32个环境跑500万步在我的机器上大约需要两到三个小时跑完的模型基本接近收敛如果到100万步reward还在原地大概率不是步数不够而是环境、奖励或建模中某一块出了问题继续跑只是浪费电。从建模到强化学习仿真训练这个标题看起来像一条笔直的流水线真正做的时候才发现到处是环环相扣的坑。我个人最大的体会是要把大约60%的时间花在建模和仿真校准上强化学习本身的算法实现反而只占20%剩下20%全耗在奖励函数和课程设计上。如果一开始就抱着“赶紧训练、赶紧出结果”的心态最后一定会在排障阶段加倍还回来。这个项目后续还可以继续扩展的方向很多比如把并联五连杆换成更复杂的串联并联混合机构或者加入真机部署后的在线自适应模型更新每一步都是新坑也每一步都能学到比调RL参数更有价值的工程经验。