基于LPV-MPC的四旋翼双闭环8字形轨迹跟踪仿真
1. 项目全景为什么会想做一个基于LPV-MPC的8字形轨迹控制仿真四旋翼轨迹跟踪这类问题看起来不算新鲜市面上调PID飞个8字形的demo满天飞但真要涉及大幅度机动、姿态角变化、内环外环耦合这些工况常规思路立刻捉襟见肘。这个项目选用MPC模型预测控制作为核心控制框架把模型按LPV线性参数变化方式处理再配上“位置姿态”双闭环结构最终在Matlab环境下完成了8字形轨迹的闭环仿真与代码验证。先说清楚它适合谁。如果你正在学无人机控制尤其是想从“调一组PID让飞机飞得差不多”升级到“明白预测、约束、滚动优化如何在无人机上落地”或者你手头有明确需求要跑一套带约束的轨迹跟踪控制器做课程设计或者算法对照再或者你只是好奇双闭环MPC和单层MPC在性能上到底差多少——这个项目的内容都对你有参考价值。8字形轨迹选择得很有讲究。相比直线、圆形这类简单轨迹8字形包含曲率连续反向、速度方向频繁切换、以及两个方向上的耦合运动控制器需要同时处理横向和纵向的协调。而且由于路径存在自交叉跟踪误差的积累很容易在交叉点附近暴露出来。换句话说8字形轨迹是对“控制器对期望轨迹的预测能力约束满足能力”的一个非常综合的压测。项目里选择这个轨迹不是随便挑一个好看的形状而是刻意用一个能挑毛病的工况去验证MPC的鲁棒性。再往下一层说项目名字里的三个关键词——双闭环、LPV、MPC——其实代表了三个不同层面的设计决策。双闭环是信息架构LPV是建模策略MPC是控制算法。三者不是并列关系而是三层叠起来的一套完整方案拆开看任何一层单独拿出来都不是新东西但合在一起恰好能解决8字形跟踪里最麻烦的“模型失配状态约束轨迹非线速变化”三座大山。下面分段把这些设计逻辑讲透。2. 控制方案选型MPC为什么值得LPV为什么必要双闭环为什么合理2.1 为什么选MPC而不是PID或LQR在8字形轨迹跟踪里最直观的痛点是约束。一个实际无人机系统电机推力有上下限姿态角有物理极限超过某个角度升力矢量就补偿不过来角速度受限于执行机构带宽。PID和LQR在设计阶段往往只能把这些约束“隐式处理”——通过限制增益来避免超限代价就是牺牲了动态响应速度。MPC的思路不同它直接在优化问题里把约束写进去预测未来N步算出在当前时刻最优的控制序列只执行第一步下一时刻重新滚动一遍。滚动优化带来一个额外优势它天然带有前瞻性。8字形轨迹在交叉点以后方向突变传统反馈控制往往要等到误差已经出现才开始动作MPC则能根据未来参考轨迹提前修正把误差消灭在发生之前。这个特性在跟踪高速、大曲率轨迹时非常鲜明实测下来同一组参数下MPC在交叉点附近的跟踪滞后比LQR要小一个数量级在我的仿真里大概从0.3s降到了0.05s以内。当然MPC不是没有代价。每步都要解一个二次规划QP问题计算量比PID大不少。但8字形这种低频轨迹我这里轨迹周期约31s位置环采样周期取0.1s姿态环更快一些常规笔记本电脑完全跑得动没必要为实时性发愁。如果换成更高频的轨迹则需要考虑快速MPC算法或嵌入式求解器这是后话。2.2 LPV线性参数变化到底解决了什么四旋翼真实动力学是强非线性的姿态方程里有角速度耦合项位置方程里升力矢量是通过旋转矩阵映射到世界系的角度一大线性化误差就很明显。如果只用单一工作点的线性模型做MPC会遇到一个尴尬情况在悬停点线性化得到的模型在8字轨迹某些大姿态角段会产生明显的模型失配控制效果随轨迹位置浮动。解决思路有几个一是用非线性MPC直接在每个采样时刻数值求解非线性优化问题精度高但计算量不可接受二是把系统看成一族线性系统在不同工作点使用对应的线性模型这就是LPV思想。具体到这个项目我把四旋翼模型按调度变量scheduling variable组织起来。位置环的调度变量选的是飞行速度或者说水平方向速度分量姿态环的调度变量选的是俯仰角和滚转角。每个采样时刻控制器根据当前调度变量的实测值选择或插值出对应的线性预测模型再在这个模型上执行标准MPC优化。这样模型始终是跟着工况走的比单纯固定模型鲁棒得多但又没有非线性优化那么大的计算包袱。提示LPV实现有一个前提调度变量本身必须是可测的、变化较为平滑的。四旋翼系统里速度和姿态角都是现成可测状态且物理上连续变化满足这个条件。调度变量跳变剧烈时反而会引入模型切换的瞬态响应这点等会在问题排查部分单独展开。2.3 位置姿态双闭环结构是怎么回事理论上可以把位置、姿态、角速度全部塞进一个MPC用一个全状态优化问题同时输出电机指令。但工程上很少这么干主要原因是数值病态和尺度差异。位置环的状态量以米、米/秒为单位姿态环以弧度、弧度/秒为单位量级差两三个数量级放在同一个代价函数里权重调配会变得极敏感。而级联结构天然把量纲差异隔离开来。我采用的结构是位置环MPC作为外环采样周期0.1s跟踪8字形参考轨迹输出期望加速度进而换算成期望滚转角、俯仰角、总推力姿态环MPC作为内环采样周期0.01s跟踪期望姿态角输出三轴力矩指令最终由混控矩阵映射到四个电机的转速。内外环采样周期拉开10倍不仅可以降低位置环的计算频次更重要的是避免了内外环之间因带宽重叠产生的耦合振荡。经典的串级控制经验是把内环带宽做得比外环高5~10倍这样内环能快速追踪外环指令外环看到的对象近似是一条快速稳定的内环响应设计起来各自独立、互不纠缠。对Matlab实现来说使用模型预测控制工具箱就很方便两种MPC对象分别构建位置环的输出变量作为姿态环的参考信号传入整体代码结构清晰后期换模型或调参都不用动框架。3. Matlab仿真实现从动力学模型到代码逐行拆解3.1 四旋翼动力学建模的关键取舍仿真第一步是定义被控对象。我用的模型包含12个状态位置(px,py,pz)、线速度(vx,vy,vz)、姿态角(φ,θ,ψ)、角速度(p,q,r)。控制输入是总推力T和三个力矩τφ, τθ, τψ。位置动力学惯性系下关键方程m*ẍ (cosφ·sinθ·cosψ sinφ·sinψ)·T m*ÿ (cosφ·sinθ·sinψ - sinφ·cosψ)·T m*z̈ (cosφ·cosθ)·T - m·g姿态动力学机体坐标系下通常用刚体欧拉方程J·ω̇ -ω × (J·ω) τ其中J为转动惯量矩阵简化模型下取对角阵diag(Ixx, Iyy, Izz)耦合项−ω×(J·ω)在高速角速度时不可忽略LPV调度变量选取时正好能体现它的影响。参数我沿用了一组典型小型无人机数据参数数值说明m1.2 kg机体质量Ixx0.0211 kg·m²滚转惯量Iyy0.0211 kg·m²俯仰惯量Izz0.0367 kg·m²偏航惯量g9.81 m/s²重力加速度角度幅值限制±30°滚转/俯仰推力上限25 N约2g过载模型细节不需要太复杂前提是MPC的预测模型要与此保持一致性——如果被控对象里用了完整非线性模型预测模型却在某一工作点静态线性化模型失配带来的残差会直接反映到跟踪误差上。这就是为什么我把被控对象做成非线性六自由度模型而预测模型用LPV方式的局部线性化两者之间的失配程度反而能验证控制器对模型不确定性的容忍度。3.2 位置环LPV-MPC预测模型与控制器配置位置环的预测模型我设计为以“期望加速度”为输入的三通道积分器模型。状态取[px, vx, py, vy, pz, vz]控制输入为[ax, ay, az]。在LPV层面模型状态矩阵A中考虑了当前飞行速度与调度变量相关的修正项体现高速飞行时的气动阻尼效应B矩阵保持单位阵。调度变量这里取水平速度vh sqrt(vx^2 vy^2)每个采样时刻重新计算调度变量vh更新预测模型矩阵然后交给MPC求解。权重配置上位置跟踪误差权重略大于速度误差让位置优先准确控制增量权重用来抑制过猛的加速度指令避免把姿态参考推得太陡。% 位置环MPC构建示例 posPlant ss(A_pos, B_pos, C_pos, D_pos); % A_pos由调度变量实时更新 Ts_pos 0.1; Np_pos 15; Nc_pos 4; posMpc mpc(posPlant, Ts_pos, Np_pos, Nc_pos); posMpc.Weights.OutputVariables [2 2 5]; % [x误差 y误差 z误差] posMpc.Weights.ManipulatedVariables [0 0 0.1]; % 推力增量权重 posMpc.OutputVariables.Min [-inf -inf 0.1]; posMpc.OutputVariables.Max [ inf inf 2.0]; posMpc.ManipulatedVariables.Min [-0.5 -0.5 -10]; posMpc.ManipulatedVariables.Max [ 0.5 0.5 10];位置环MPC输出的是期望加速度ax_des, ay_des, az_des。az_des加上g后换算成推力ax_des、ay_des通过“反解姿态”公式换算成期望的滚转角φ_des和俯仰角θ_desφ_des (ax_des·sinψ - ay_des·cosψ) / g θ_des (ax_des·cosψ ay_des·sinψ) / g这两个角度参考传给姿态内环跟踪。这里有个小坑位置环输出加速度受限于可用的姿态角范围如果位置环给的加速度过大换算出的姿态角会超出物理极限导致内环达不到指令。因此位置环的约束里要留有裕量。% 调度变量平滑滤波避免模型矩阵跳变 smoothed_vh 0.3 * vh_current 0.7 * vh_prev; A_pos updatePosModel(smoothed_vh);3.3 姿态环LPV-MPC快回路的设计要点姿态环预测模型主要是3个角速度通道和3个姿态角通道。由于角速度耦合项ω×(J·ω)是非线性的我在LPV实现中把当前角速度作为调度变量之一实时更新预测模型捕获大机动时的惯性耦合。姿态环的状态取[φ, θ, ψ, p, q, r]控制输入为[τφ, τθ, τψ]。关键设计参数% 姿态环MPC构建示例 Ts_att 0.01; Np_att 10; Nc_att 3; attMpc mpc(attPlant, Ts_att, Np_att, Nc_att); attMpc.Weights.OutputVariables [3 3 0.5 0 0 0 0 0 0]; % 前三个是φ,θ,ψ attMpc.Weights.ManipulatedVariablesRate [0.5 0.5 0.5]; attMpc.OutputVariables.Min -deg2rad(30)*ones(1,3); attMpc.OutputVariables.Max deg2rad(30)*ones(1,3);姿态环的控制输入是三轴力矩τ[τφ, τθ, τψ]实际电机转速通过归一化混控矩阵映射U MixMat * [T; τφ; τθ; τψ] ω_i sqrt(U_i / kt_i)姿态环约束重点是角速度上限与力矩上限约束太紧会导致QP问题无解或剧烈抖动这个在调试时消耗了我最多时间。还有个细节姿态环MPC的预测模型里如果包含偏航ψ通道而8字形轨迹飞行中偏航通常锁定或者慢变那ψ通道的权重可以给得小一点避免MPC把控制能量浪费在不必要的偏航修正上。3.4 8字形轨迹生成与仿真循环8字形轨迹我采用利萨如曲线形式x_ref(t) Ax * sin(ω * t) y_ref(t) Ay * sin(2 * ω * t π/2) z_ref(t) 1.0 % 定高1米参数取ω0.2 rad/sAx4mAy3m。这样x方向周期31.4sy方向周期15.7s两个方向的频率比1:2合成的图形就是标准8字。轨迹生成后我还加了对参考位置的导数作为速度前馈项MPC可以只做跟踪误差调节但加上参考速度前馈后跟踪滞后会明显减小。仿真循环结构伪代码for k 1 : T_total/Ts_pos % 1. 获取当前状态 % 2. 更新位置环调度变量更新预测模型 % 3. 位置MPC在线求解得到期望加速度 % 4. 反算期望姿态角 - 期望角速度用差分估计 % 5. 内环以更小步长推进姿态环MPC求解 % 6. 记录数据、绘制轨迹 end实际工程实现时位置环和姿态环如果完全用嵌套for循环姿态环每周期执行MPC求解次数会很多。我的做法是位置环每一次更新姿态环执行若干次MPC求解并推进姿态步长然后由六自由度推进方程更新系统状态。这样外环每0.1s内环实际跑了10步姿态闭环既保证内环快速性又控制计算总量。如果在Simulink中实现更干净的做法是两个子系统各自用触发采样时间位置环采样0.1s姿态环采样0.01s通过模型参考把姿态环作为被控对象的内嵌回路。但这里为了Matlab纯代码仿真的可读性我选择将所有模块写成函数和脚本运行逻辑一目了然也方便后续扩展到硬件在环。3.5 代码结构的组织建议整个Matlab工程按脚本和函数拆分main_8shape_LPV_MPC.m % 主脚本参数、轨迹、循环 quadParams.m % 四旋翼参数结构体 lissajousTrajectory.m % 8字形轨迹生成函数 dynamicsStep.m % 被控对象离散推进 updatePosModel.m % 位置环LPV模型更新 updateAttModel.m % 姿态环LPV模型更新 plotResults.m % 绘图与误差分析这种划分的好处是任何一层改了模型不会波及另一层实验时只需要在main脚本里改参数无需动求解器代码。另外强烈建议在模型更新函数里加一个调度变量渐变滤波器避免调度变量抖动导致模型矩阵在相邻时刻跳变。我用的是一阶惯性滤波alpha取0.3左右效果稳定。4. 参数调优实战从跑不动到平稳跟踪的调整路径4.1 预测时域究竟要设多大先看被控对象的开环时间常数预测时域Np的意义是“看多远来决策”。设小了MPC变成近视眼设大了优化问题的规模增大而且远期约束已经变得不太相关求解器容易在数值上发懵。对位置环对象的时间常数取决于8字形轨迹的周期约31s所以预测至少要覆盖轨迹周期的1/10~1/5Np15、Ts0.1s即1.5s的预测窗口在这个任务里已经能提前感知大曲率段的几何变化。姿态环对象快得多时间常数约0.2sNp10、Ts0.01s即0.1s窗口也就足够了。控制时域Nc则影响决策自由度。Nc增大让MPC在每个周期内能改变输入更多次但也会让输入变化过于灵活表现为控制信号高频抖动、求解时间上升。常见的经验范围是Nc≈Np/3到Np/2我取Nc4和Nc3调出来效果平稳。4.2 权重矩阵的物理意义与调节次序MPC代价函数J Σ(y−y_ref) Q (y−y_ref) ΣΔu R Δu Σu S u三个权重对应三件事输出跟踪Q、控制增量抑制R、绝对控制量抑制S。调参次序我建议从外向里先调位置环Q让跟踪误差收敛再调R抑制加速度指令抖动最后调姿态环的Q和R。调的时候要盯着时域曲线看不要只看最终RMSE。比如位置环R给太小期望加速度会噼里啪啦跳映射到期望姿态角上就是一顿乱晃姿态内环根本追不上姿态环Q给太大又会让角速度指令过猛电机容易饱和。我的初始值可以作为参考但不同无人机参数下最优值可能差好几倍配置项初始推荐值调节方向位置环Q[2 2 5]跟踪滞后明显时适当增大位置环R[0.1 0.1 1]姿态指令抖动时增大姿态环Q[3 3 0.5]姿态超调时增大角度通道姿态环R[0.5 0.5 0.5]电机力矩抖动时增大实际调参中我给出一组快速收敛的现场经验先拿LQR参数摆一个数量级正确的初值Q对角线取误差平方正比R对角线取控制量反比然后整体乘以缩放系数扫描观察RMSE变化曲线在RMSE出现平台期之前取参数往往就是接近最优的位置。进一步精细调整再通过灵敏度分析进行但没必要一上来就做。4.3 双闭环交互外环参考指令别太滑头双闭环系统最大的坑在于外环输出期望姿态角变化速率如果不加限制内环会一直处于追赶状态永远到不了稳态。解决思路有二一是在位置环MPC里限制控制增量的变化率通过控制变量上下限来实现二是在外环输出到内环参考之间加一个速率限制器斜率限制在±15°/s以内这样内环有时间跟踪。两种方法可以叠加使用。另外一点位置环MPC在交叉点附近会产生较大的横向加速度需求如果直接丢给姿态环姿态角瞬间冲得很极端。我的做法是加一个低通滤波器时间常数0.2s把期望姿态角的跳变抹平实测交叉点附近的角速度冲击降低了一半以上。4.4 LPV调度平滑调度变量不能生硬切换虽然LPV模型在整个包线内看起来都是线性的但相邻时刻模型矩阵如果相差太远MPC在每个周期重置预测模型时会产生模型切换瞬态对应到控制量上就是毛刺。我用了两步处理第一步对调度变量重点是姿态环的当前角速度、位置环的水平速度做一阶低通滤波让调度信号平滑第二步如果飞行包线跨度大可以构建有限数量的工作点模型然后用插值方式合成预测模型而不是硬切换。插值系数直接由调度变量在相邻工作点之间的相对位置决定。Matlab工具箱里支持这种调度插值模型各版本之间接口略不同我用的是标准MPC对象加自定义模型更新完全可控。5. 仿真中的常见问题与排查技巧实录5.1 8字形跟踪在交叉点附近明显滞后甚至偏离排查顺序先看位置环输出加速度曲线是否在交叉点附近过大或过小。若过大说明MPC预测不够或者权重太软增大Np或Q。若过小则可能是速度前馈缺失位置环在等误差产生后才响应建议在控制序列中补充参考速度项。再看期望姿态角转换曲线若滚转角参考超过±30°就把位置环输出加速度限幅压下来。5.2 MPC求解器报No feasible solution或QP无解常见原因是约束太紧。比如姿态环把角度上限设在±30°而外环给的参考角度在滤波前瞬时超过这个值那么优化问题在初始时刻就不满足约束直接判无解。解决放宽宽容度MPC对象里设ExactFeasibilityCheckfalse或者给MPC加软约束SoftConstraints更优的做法是确保参考信号经过限幅滤波后再进MPC让参考落在可行域内部。5.3 姿态环出现高频振荡大概率是Nc偏大或R偏小导致MPC过度使用控制自由度。先把Nc降到3以内R增大到5倍观察如果还振荡检查角速度测量是否被仿真推进里的数值噪声污染LPV调度变量对噪声敏感时会传递到模型矩阵。5.4 LPV模型切换带来的控制量毛刺调度变量滤波是第一个手段。第二个手段是把调度变量变化率本身也当作约束放进优化问题。不过更简单的做法是给调度变量更新加一个更新死区只有当调度变量变化超过设定阈值时才更新预测模型这样模型不会因为微小抖动反复切换。我实测把阈值设在±0.5°/s角速度调度基本能兼顾准确性和稳定性。5.5 仿真耗时过长或数据爆炸位置环Np15, Nc4在标准MPC里不是问题但如果姿态环每个外环步都跑完整MPC总体计算量会膨胀。建议内环只取Np10, Nc2并且把MPC求解的公差放宽SolverOptions.Tolerance。另外一定要先跑一个短时段的仿真比如前20%时段验证不会发散再跑全程避免浪费算力。6. 一点自己的经验与体会这个项目调下来最深的体会是“嵌套闭环的调试顺序比算法选择还重要”。先让被控对象在开环下稳定再调内环内环稳定了再调外环一步不到位就全面开花。另一个值得记录的经验是MPC的权重和约束本质上是一对矛盾你在调Q让跟踪更紧时一定要同步检查控制量是否撞约束一旦控制量长时间贴在约束边界上说明系统已经在极限工作加大权重无法换来更好的跟踪只会让求解器更紧。最后再分享一个小技巧仿真做完后可以打印每个MPC求解的平均耗时和最优值曲线。如果最优值曲线在正常跟踪时出现明显波动往往是约束激活或调度模型异常的兆头提前看到这些小信号能省掉大量排查时间。这套基于LPV-MPC的双闭环仿真框架后续如果要扩展到更复杂的轨迹比如三维螺旋、避障路径只需要替换轨迹生成函数和适当调整权重整体架构不用大改。