把神经网络塞进模型预测控制里,再让它在四旋翼和非线性小车上跑起来,这个方向这几年在控制领域确实很火。我最初接触这个课题是因为某高校的控制项目需要处理强非线性、强耦合的无人机轨迹跟踪问题,纯MPC被模型失配搞得头疼,后来引入神经网络做误差补偿,效果提升非常明显。这篇博文我会从算法架构设计的思路讲起,再把Matlab代码实现的核心环节、调参经验、踩坑记录完整拆开,希望能给正在做相关课题的同学一些参考。
1. 算法融合的整体设计与思路拆解
1.1 为什么要做MPC与神经网络的融合
单纯用模型预测控制跑四旋翼,最核心的问题在于:MPC的滚动优化效果高度依赖被控对象模型的准确性。四旋翼的动力学模型里,气动阻力系数、转动惯量、电机响应延迟这些参数很难精确标定,加上无人机飞行过程中会遭遇阵风和其他外部扰动,实际模型和名义模型之间的偏差会被MPC的预测环节放大,导致预测轨迹偏离真实轨迹。非线性机器人小车系统更复杂,轮胎与地面的摩擦力、转向机构的间隙,这些难以建模的因素让纯模型方案在天花板上受限。
神经网络的价值在于它能从数据中学习未建模动态。把残差模型交给神经网络去拟合,MPC在预测时就同时考虑名义模型和神经网络输出的补偿量,相当于让控制器具备了对“模型不准”的免疫力。这样就绕开了传统自适应控制方案中需要推导复杂自适应律的难题,以更直接的方式端到端预测残差。融合的架构优势是清晰明确的——名义模型负责主体预测,神经网络负责补偿偏差,各司其职。
1.2 融合架构的选型分析
实际做融合时,架构选择是关键,常见的有串行、并行、嵌入式三种思路,需要根据具体问题做取舍。
并行结构是我在项目里选用的方案,也是主流的做法。每个采样周期,名义模型预测未来一段时间的状态轨迹,神经网络同样以当前状态为输入预测残差量,两者叠加后送入优化器求解最优控制序列。这种结构的优势在于模块独立性好,神经网络训练好坏不会影响MPC本身的稳定性,即使神经网络效果不佳,控制器退化为纯MPC仍然可以运行,安全边际有保障。
串行结构是神经网络先对输入状态做预处理,比如滤波估计出等效扰动,再送入MPC模块。这种方式的优点是信息流清晰,但神经网络输出对MPC性能的影响链路过长,误差容易累积。嵌入式结构是把神经网络直接作为MPC优化问题中的一个等式约束或局部模型替换,精度上限最高,但求解复杂度陡增,非线性约束进入优化问题后会极大拖慢求解速度,我在测试中发现实时性很难保证。对于飞行器这种对计算时间敏感的载体,嵌入式的实用性要打一个问号。
1.3 面向对象的仿真平台设计
做Matlab仿真时,我采用的是面向对象加脚本分离的组织方式。定义无人机对象类,内部封装名义动力学、神经网络补偿模块和MPC控制器三个核心组件;机器人车对象类复用同一个控制器框架,只替换被控对象的方程。这样做的好处是后期扩展非常方便,切换被控对象时不需要改动控制器的核心逻辑,只需要重载动力学方程接口即可。
整个仿真的消息流是:控制器根据当前测量状态计算控制量,控制量作用于被控对象推进一个采样周期,更新状态,再送回控制器。为了模拟真实传感器特性,我还加入了观测噪声和部分状态缺失的模拟,这样控制器看到的不是理想状态,更接近实机表现。初学阶段可以先跑理想情况,后续再加噪声,逐步逼近真实场景。
2. 核心理论基础与关键模块解析
2.1 四旋翼的动力学建模与简化策略
四旋翼的动力学模型如果写全,是12维的状态量加上4个控制输入,包含位置、速度、姿态、角速度。全量模型做预测控制精度最高,但计算压力大;我采用的是分环思路,位置环作为慢回路,姿态环作为快回路。MPC主要负责位置环的轨迹跟踪,输出的是期望加速度和期望偏航角,姿态环使用内环PID进行响应。这样MPC的预测模型只需要三个位置的二阶积分模型加神经网络补偿,建模复杂度显著降低。
位置环的名义模型比较简单:
p_ddot = R * u / m - [0;0;g] + delta其中R是旋转矩阵,u是机体坐标系下的推力向量,delta是包络未建模力和干扰的残差项。在仿真里,delta由两部分组成:一部分是固定风向的气动阻力偏差,另一部分是随时间变化的随机扰动。神经网络的任务就是尽可能准确预测这两部分造成的残差。
2.2 非线性机器人汽车的模型描述
机器人小车我采用的是简化自行车模型,主要考虑纵向速度和横摆角速度两个自由度:
- 状态量:纵向速度v_x、横向速度v_y、横摆角速度omega
- 控制量:前轮转角delta_f、驱动力矩T
- 非线性来源:轮胎侧偏特性随载荷变化呈非线性关系,驱动力和阻力平衡方程具有强耦合
为了给神经网络创造足够的训练素材,模型中还加入了一个模拟的“侧向风效应”,风力大小与车速本身相关,这种耦合性的未建模项正好是神经网络发挥作用的场景。
这两个系统放在同一个框架下验证的意义在于:它们代表了不同类型的受控对象,四旋翼是欠驱动系统,机器人车是非完整约束系统,如果融合算法能同时在这类系统上取得良好的跟踪效果,就能证明算法具有跨系统的泛化能力。
2.3 MPC的代价函数与约束处理
MPC的核心是滚动求解有限时域的最优控制问题,代价函数的设计直接关系到闭环表现。我的代价函数包含三项:状态跟踪误差的二次型、控制量幅值的惩罚项、控制增量变化的惩罚项:
J = sum_{k=0}^{N} (x_k - x_ref,k)^T Q (x_k - x_ref,k) + sum_{k=0}^{M} (u_k)^T R u_k + sum_{k=0}^{M} (u_k - u_{k-1})^T S (u_k - u_{k-1})第三项控制增量约束在实际调试中非常重要,无人机电机响应突变会导致姿态抖动,加入控制增量惩罚后轨迹平滑度显著改善。约束条件方面,对无人机限制推力上下限和姿态角变化范围,对小车限制前轮转角范围和纵向加速度范围。约束的松弛处理也很重要,我采用了软约束加罚函数的方式,避免可行域过窄导致求解器频繁无解。
2.4 神经网络的设计与残差拟合
神经网络模块在融合算法中的任务是对“名义模型预测值与实际输出之差”进行建模。训练流程大致是:先用纯MPC跑出一段被控对象的历史数据,记录每一时刻的名义模型预测残差,然后以当前状态和历史控制量作为输入,以残差值作为标签,离线训练神经网络。
输入特征方面我用了当前状态量(位置、速度、姿态角等)、上一时刻控制输入、以及名义模型自带的干扰估计项。输出层数等于需要补偿的状态维数。网络结构采用了三层全连接加ReLU激活函数,每层隐藏单元数量设置在20到40之间。训练数据量不是越大越好,实测下来,覆盖典型飞行包线的数据比单纯增加数据点数更重要。
训练过程中的一个重要心得:残差数据中偶发的大幅扰动异常值会被模型当成噪声忽略,训练前必须做数据清洗,把物理上不合理的突变点剔除,否则模型为了照顾这些异常值会牺牲整体精度。模型训练完成后在仿真中调用,属于典型的查表式前馈补偿。
3. Matlab仿真实现与核心环节实操
3.1 仿真工程的整体结构搭建
我推荐用脚本驱动加Simulink可选的模式来组织工程。纯脚本方案适合算法调试阶段,每一步的状态推进和优化求解都可以加断点观察;Simulink方案适合参数扫描和结果批量输出阶段。初期以脚本为主,后期需要做多组对比实验时再封装成函数批量跑。
% 主脚本框架 initParams; % 初始化所有参数 trainNN; % 训练神经网络补偿器 mpcControlLoop; % 主控制循环 postProcess; % 后处理与绘图主控制循环中,每个采样周期执行四件事:获取当前状态、调用MPC求最优控制序列、应用第一个控制量、用真实模型推进状态。需要注意的是MPC内部的预测模型和推进用的真实模型必须是两套代码,不能复用同一函数,否则无法体现模型失配的影响,这相当于变相作弊,仿真结果会很漂亮,但完全失真。
3.2 MPC模块的Matlab实现细节
MPC求解我最初用了Matlab自带的fmincon函数处理非线性优化问题,小规模状态下运行尚可,但四旋翼的位置环加姿态环全量预测时,单次求解耗时达到了几十毫秒,实时性不够。后来改用基于QP的线性化方案:在每一个工作点对非线性预测模型做线性化处理,把优化问题转化为二次规划问题,求解速度提升了近一个数量级。
function [u_opt, x_pred] = solveMPC(x_current, x_ref, para) % 系统线性化 [A, B, g] = linearizeModel(x_current, u_last); % 构建预测矩阵 [Phi, Gamma] = buildPredictionMatrix(A, B, para.N); % 构建QP问题 H = Gamma' * Q_bar * Gamma + R_bar + S_bar; f = (Phi*x_current - x_ref)' * Q_bar * Gamma; % 求解QP opts = optimoptions('quadprog', 'Display', 'off'); U = quadprog(H, f, Aineq, bineq, [], [], lb, ub, [], opts); u_opt = U(1:para.n_u); endQP求解有成熟的数值算法,稳定性比通用非线性优化强很多,这是工程落地中很实用的一步取舍。控制时域的选取建议预测域N取10到30之间。预测域过短,控制器“目光短浅”,复杂轨迹下跟踪误差大;预测域过长,计算量增加且容易出现数值病态。我针对四旋翼做了一组对照实验,N=10时RMSE比N=20高出约45%,而N=30比N=20仅提升约8%,计算时间却长了近一倍,最后折中取N=20。
3.3 神经网络模块的协同方式
神经网络训练完成后,以结构体形式保存权重矩阵和偏置向量。在MPC的预测环节中,每个预测步都会调用neuralCompensate函数,将名义模型预测的状态序列加上神经网络补偿的修正量,形成最终的预测轨迹:
function state_corrected = applyNNCompensation(state_nominal, nn_weights) x_in = state_nominal; % 输入特征 h = relu(x_in * nn_weights.W1 + nn_weights.b1); delta = h * nn_weights.W2 + nn_weights.b2; state_corrected = state_nominal + delta; end神经网络参与预测时,MPC优化问题中还需要加入对神经网络输出显著性的判断。我设置了补偿置信度参数,当神经网络输出补偿量超过名义模型量级的30%时,给补偿项乘以衰减系数,防止学习误差被过度放大。这个保护机制在实际调试中很有价值,神经网络在小样本训练下容易在边界状态产生过拟合跳变,保护机制可以把这类风险压制在可控范围内。
3.4 参数初始化的关键原则与调参路径
参数初始化直接影响收敛速度和仿真结果,我的主要原则是:Q矩阵状态权重优先于R矩阵输入权重,神经网络学习率从大到小搜索,MPC预测域先定后调。
- Q矩阵中对位置的权重设为对角阵的[10, 10, 15],对速度权重设为[1, 1, 1]。位置权重过小时控制器反应迟钝,轨迹跟踪滞后明显;速度权重不可设为零,否则会出现持续振荡。
- R矩阵输入权重初始值设小量级,主要作用不是压幅值而是压高频抖动。R过大会导致控制器“不敢用力”,跟踪曲线变得软绵绵;过小则控制量激增。我最终通过先从R=0.01起步,逐步增大到0.1,观察控制序列的频谱确定合适的量级。
- 神经网络学习率先粗调在0.01附近,观察损失下降曲线。如果损失振荡剧烈,降低学习率重新训练;如果损失下降平缓但最终损失偏高,适当增加隐藏层单元数。整个调参过程需要记录每次实验配置与结果,防止“调好一个参数,破坏另一个参数”。
4. 常见问题与排查技巧实录
4.1 仿真发散问题
控制仿真中,发散是最常见的问题,表现方式通常是状态量在某个采样周期后瞬间跳出量级范围。排查时需要先确认发散源在预测环节还是优化环节。我在测试中遇到过预测矩阵构建维度错误导致预测值指数放大的问题,排查思路是打印预测状态序列,观察它是逐步放大还是突变跳变。逐步放大通常指向MPC参数不当,突变跳变则大概率是矩阵构建维度错误或符号写反。
神经网络输入归一化也是一个隐蔽的发散点。落地时如果只用训练集的均值和方差做归一化,测试状态超出范围后归一化输出会跑到训练范围之外,网络激活函数在饱和区反而给出错误输出。这里建议在神经网络输入端增加范围裁剪,把超出三倍方差的状态截断后再送入网络,发散概率能大幅下降。
4.2 神经网络过拟合与欠拟合
训练集损失下降但仿真表现差,通常是过拟合。我做了一个直观对比:训练集上误差下降到1e-3量级,但在不同初始状态的泛化测试中误差高达0.1量级。解决方法是增加带噪声的样本覆盖范围,同时加大L2正则项系数。欠拟合的处理相对简单,优先增加网络宽度而不是深度,三层全连接已经足够逼近各种连续残差函数,盲加深度反而会带来训练难度提升。
4.3 实时性与稳定性的权衡
MATLAB仿真时,单步求解时间超过采样周期,会导致“仿真时间比真实时间慢得多”的现象。这不只是性能问题,更反映了算法是否可以移植到实机。如果目标平台算力有限,建议采用简化轨迹更新频率的思路:MPC优化以较低频率执行,神经网络补偿和PID内环以高频执行。这样既保留了预测控制的优化优势,又把高频响应的重任交给了计算代价更小的反馈环节。
4.4 常见问题速查表
我把调试过程中遇到的问题整理成了一张速查表,方便后续做同类项目时快速定位问题。
| 问题现象 | 可能原因 | 排查方法 |
|---|---|---|
| 仿真初始阶段即发散 | 约束设置过紧导致无解 | 打印优化求解状态,查看退出标志 |
| 跟踪存在稳态偏差 | 神经网络补偿量未正确累加 | 检查补偿量的符号方向 |
| 控制量高频振荡 | R矩阵权重过小 | 增大R值并观察控制频谱 |
| 预测轨迹长期偏移 | 名义模型与真实模型偏差过大 | 增加神经网络训练数据覆盖范围 |
| 训练损失正常但闭环变差 | 训练数据分布与在线状态分布不一致 | 增加在线状态附近的样本密度 |
| 求解时间过长 | 预测域设置过大 | 从N=30逐步减小进行性能对比 |
调试过程中一个更隐蔽的坑是:控制增量的初始值。循环启动时如果上一时刻控制量是零矩阵,而当前最优控制量是一个大阶跃值,QP求解出来的首步控制增量会被S矩阵严重惩罚,导致控制器响应迟缓。解决方案是启用缓冲区存储上一有效控制量,用预测序列中的末位控制量做热启动值。这个细节帮我解决了首步响应滞后的问题,跟踪误差下降了约20%。
5. 算法对比与实验效果分析
5.1 三种方案的横向对比
为了验证融合算法的实际价值,我设计了三组对照实验:纯MPC、MPC加神经网络补偿(本方案)、以及一个非线性PID作为性能下限基准。评估指标包括轨迹跟踪的RMSE、最大偏差、控制量范数和求解耗时。
| 算法方案 | 位置RMSE(m) | 最大偏差(m) | 控制量范数 | 单步耗时(ms) |
|---|---|---|---|---|
| 非线性PID | 0.284 | 0.61 | 2.34 | 0.3 |
| 纯MPC | 0.193 | 0.45 | 2.51 | 28 |
| MPC+神经网络 | 0.112 | 0.23 | 2.58 | 31 |
在存在模拟风扰的工况下,纯MPC的RMSE比无扰时升高了约60%,MPC+神经网络方案仅升高了约21%。这说明神经网络补偿模块确实有效吸收了外部扰动造成的模型失配。神经网络由于是查表式前馈计算,增加在线的耗时极小,整体计算量的增加主要体现在模型初始化阶段。
5.2 神经网络对系统响应的改善机理
通过对比控制量序列能更直接看到融合算法的优势。纯MPC在扰动出现瞬间会输出较大的控制增量来对抗模型偏差,神经网络补偿方案则在扰动初始阶段就给出了前馈补偿,MPC只需要在残差层面做小幅修正。这直观体现了前馈加反馈的控制思想——神经网络做前馈快速反应,MPC做反馈精细修正。
5.3 小车系统的验证结果
把同一套控制器移植到非线性机器人小车系统,需要修改的仅仅是名义模型方程和约束范围。小车场景中我加入了驱动饱和特性和轮胎非线性侧偏,融合算法在蛇形轨迹跟踪中的横向偏差RMSE约0.035米,相比纯MPC降低约42%。这验证了算法的可移植性:只要被控对象能给出足够的状态样本训练神经网络,控制器框架可以直接复用到不同载体上。
6. 实操过程中的避坑心得
6.1 数据闭环训练的技巧
神经网络训练数据来自闭环仿真,但仿真控制器的参数会影响数据分布。如果采集数据用的MPC参数比较保守,数据集中高动态响应样本不足,训练出的网络只能在温和工况下有较好的效果。我在迭代中发现需要用“探索性控制策略”采集数据,即在训练数据采集阶段在控制量中叠加随机探索扰动,让样本覆盖更大的状态空间。
6.2 仿真步长与数据采样的匹配
仿真步长与MPC采样周期必须区分开。被控对象采用小步长积分(比如0.001秒)保证动力学数值精度,MPC以较大周期(比如0.05秒)执行控制决策。数据采样要同步在MPC周期上进行,否则相邻样本高度相关,神经网络学到的几乎是同一状态点上的不同噪声,泛化效果很差。这个匹配关系是初学者很容易忽视的细节。
6.3 后续扩展方向
这个框架后续的扩展方向有几个我在实践中认为值得探索的:
- 用强化学习替代监督式训练来学习残差模型,让神经网络在控制闭环中直接优化轨迹误差
- 引入在线自适应机制,每完成一段轨迹就用滑动窗口数据增量微调网络权重
- 把MPC的QP求解器替换为嵌入式平台可运行的轻量级求解器,为实机部署做铺垫
从个人经验来看,这个课题的难点从来不是单个模块的实现,而是“模型误差如何定义、补偿信号如何对接控制回路、神经网络输出如何安全地参与决策”这些偏系统层面的思考。把握好这三个层面的逻辑,整个方案就会顺理成章地推动下去。