无模型自适应预测控制与迭代学习控制:非线性系统数值仿真验证方案
做控制的同行应该都体会过这种尴尬对象明明是个非线性系统工艺还三天两头调整想拿一份精确数学模型比登天还难。我前阵子为了验证一套面向重复生产过程的控制策略把无模型自适应预测控制MFAPC和无模型自适应迭代学习控制MFAILC做成了一套完整的数值仿真程序跑了大量工况做对比。这篇文章把仿真程序的设计思路、算法机理、参数整定和踩过的坑全部整理出来。如果你正在为非线性对象的跟踪控制发愁或者想知道这两种数据驱动控制器到底怎么选、怎么验证可以直接参考这套方案。我没有采用现成的工具箱整个验证程序从被控对象到两类控制器都是自己一行行搭的。好处是每个环节的输入输出、参数含义都清清楚楚坏处是一旦参数设置不合理仿真曲线会非常诚实地告诉你“你错了”。下面先从为什么需要这类算法说起再进入数值验证的具体实现。1. 建模型建到怀疑人生这个仿真程序要回答哪些问题1.1 数据驱动控制到底“无模型”在什么地方传统控制器的设计思路是“先建模、再设计、最后调试”。模型可以是机理推导的一阶惯性环节也可以通过系统辨识得到传递函数或状态空间方程。问题在于实际被控对象往往带有明显的非线性、时变特性和未建模动态。比如某一套批次生产设备温度特性会随物料批次变化执行机构还有死区这种情况下固定参数的PID往往需要在每个批次重新整定而基于精确模型的预测控制又因为模型失配逐渐失效。无模型自适应控制的核心主张是不依赖显式数学建模而是用输入输出数据实时估计一个被称为伪偏导数的时变参数再基于这个参数直接设计控制律。MFAPC和MFAILC都是这条路线上的代表方法。前者把预测控制的滚动优化思路引入无模型框架后者则把迭代学习控制的重复操作思想与伪偏导数结合。听起来很玄但本质上是把“对象长什么样”这个问题换成“对象在当前工作点附近怎么响应”后者是可以用数据实时捕捉的。数值验证程序的作用就在这里在没有物理设备的情况下先用一个足够复杂的仿真被控对象检验两类算法的适用范围、跟踪精度、鲁棒性和参数敏感性。如果仿真都跑不稳直接上设备基本是送人头。1.2 仿真要回答的四个关键问题我在设计程序前先给自己列了四个必须回答的问题后面所有代码都是围绕这四个问题展开的。问题验证手段关心的指标MFAPC和MFAILC各自适合什么被控对象同一非线性对象下分别运行跟踪误差、控制量波动算法对初始参数是否敏感改变伪偏导数初值、权重系数RMSE变化幅度对象参数突然变化时能否适应仿真中途切换对象参数恢复时间、最大超调迭代学习控制遇到不重复扰动会怎样添加批次无关的随机扰动批次间误差收敛曲线这些问题不通过仿真回答直接到现场验证的成本太高。尤其MFAILC这类依赖批次重复的算法现场把一个批次跑完往往要几十分钟一次参数不对就得重来。而在仿真环境里一百次迭代学习只需要几秒钟可以大胆试参数。这也是我坚持写这个数值验证程序的最初动机。2. MFAPC的机制拆解伪偏导数、动态线性化与滚动优化2.1 把非线性对象写成“线性时变”的样子MFAPC最底层的假设来自偏格式动态线性化。对一般的离散时间非线性系统不一定能写出显式模型但在每个采样时刻附近可以认为输出变化量与最近L个控制量变化量之间存在近似线性关系Δy(k1) φ₁(k)Δu(k) φ₂(k)Δu(k-1) ... φL(k)Δu(k-L1)这里的Δ表示相邻时刻的差值L称为线性化长度常数。φ₁到φL组成的向量就是伪偏导数向量。注意它不是固定的而是随工作点和时间变化的。直观理解可以把伪偏导数看成对象在某个工作点上的“等效梯度”它告诉控制器“我往某个方向动一下控制量输出大概会往哪个方向走多少”。之所以用多个历史输入差分而不仅仅用当前差分是因为很多实际系统存在惯性或迟延当前输出变化会受到前几个时刻控制作用的影响。L1时退化为紧格式动态线性化适合响应非常快的系统L取2到5则能描述更强的动态耦合。在仿真程序中我建议保留L为可配置参数第一轮先取3后面再分析影响。伪偏导数值没有必要特别准确因为它每步都在线修正但初始值方向必须正确否则控制量一开始就会朝反方向猛打。伪偏导数的估计采用带正则项的投影算法。思路是让估计模型尽可能复现刚刚观测到的输入输出变化同时抑制估计值在相邻时刻剧烈跳变。这样处理的好处非常明显工业现场的数据总带噪声如果每步都让估计值完全跟着数据跑控制量会出现高频抖振加了正则约束后估计曲线更平滑鲁棒性更好。2.2 预测控制的解析解与参数影响方向有了偏格式动态线性化模型MFAPC就可以做多步预测了。在每一个采样时刻控制器基于当前伪偏导数向量把未来的输出预测写成一组控制增量的仿射组合。设预测时域为Np控制时域为Nu那么从k1到kNp的输出预测值可以表示为Ŷ Ŷ0 G·ΔU这里Ŷ0是假设未来控制量不变时的输出预测G矩阵由伪偏导数按递推关系排列而成相当于预测模型里的动态矩阵。ΔU是未来Nu步的控制增量向量。滚动优化的目标是让预测输出尽量靠近期望轨迹同时不希望控制量变化太猛。于是性能指标写成J ||Yd - Ŷ||² λ·||ΔU||²其中Yd是参考轨迹在未来窗口内的取值λ是控制增量的权重系数。这个二次型问题有解析解ΔU (GᵀG λI)⁻¹Gᵀ(Yd - Ŷ0)整个MFAPC的“预测控制”味道就在这里它不像普通反馈控制那样只看当前误差而是把未来一个时窗内的误差都纳入计算从而能提前对参考轨迹变化做出响应。仿真里可以明显看到当参考轨迹出现阶跃时MFAPC的控制量在阶跃到来前就开始变化而不是等误差出现后再补救这是它比PID更“聪明”的地方。参数影响方向在仿真中总结为一条规律预测时域Np越大控制行为越激进还是越保守答案是取决于模型匹配程度。模型匹配良好时增大Np可以利用更多未来信息响应更平滑模型匹配差时预测误差会随步数增加而积累过大的Np反而引入相位滞后。控制时域Nu越大可调节自由度越多但计算量和控制量波动也越大。λ的作用最直接λ太小控制量增量不受约束输出跟踪快但抖动明显λ太大控制量被压得很死响应迟钝甚至稳态误差消除不掉。具体数值没有放之四海而皆准的配方必须结合仿真对象的响应速度来试。3. MFAILC的逻辑用迭代轴把误差“搓”掉3.1 什么时候才值得用迭代学习控制迭代学习控制有一个天然的前提被控过程需要重复运行且每次运行时的期望轨迹相同。典型的场景包括注塑成型的保压阶段、半导体固化炉的温度曲线、批量反应釜的升温程序等。这类过程的特征是“相同任务反复执行”上一次犯的错下一次有机会改正。传统迭代学习控制在重复条件下能获得非常好的跟踪效果但它有一个弱点设计学习增益时仍然需要被控对象模型至少需要知道对象的大致相对阶和增益方向。MFAILC的思路是把伪偏导数估计引入迭代学习律让学习增益能够根据实时数据自动调整减少对模型信息的依赖。仿真程序里我模拟的是一个典型批次过程每个批次从初始状态开始沿着同一参考轨迹运行N个采样周期批次结束后记录整个误差轨迹用于修正下一批次的输入序列。这种结构非常贴近实际生产中的“跑一批、看一次曲线、调一批参数”只不过MFAILC把这个调整过程自动化了。3.2 迭代学习律与时间轴自适应是如何结合的MFAILC在数值程序中的实现可以概括为“时间轴估计、迭代轴修正”。在时间轴上每步仍需通过投影算法估计当前批次的伪偏导数因为对象在每个时刻的响应梯度不同在迭代轴上控制量根据上一批次的误差和当前批次的伪偏导数进行修正。一阶学习律的形式如下u(i,k) u(i-1,k) ρ·φ̂(i,k)·e(i-1,k1)下标i表示批次序号k表示批次内采样时刻。e(i-1,k1)是上一批次在k1时刻的跟踪误差ρ是学习增益φ̂(i,k)是当前批次估计的伪偏导数。不难看出如果上一批次在某个时刻输出低了这一批次会在这个时刻对应的控制量上加快调整幅度调整的方向和幅度由伪偏导数引导。伪偏导数在这里扮演的角色类似“误差到控制修正量”的变增益系数。仿真主循环需要对所有批次统一管理误差向量。具体做法是把每个批次的输出轨迹、控制量轨迹都保存起来在批次结束后计算误差向量再代入下一批次的控制量初始化。这个“跨批次记忆”是迭代学习与普通反馈控制最本质的差异普通反馈控制只记忆当前状态迭代学习控制则记住了上一次完整运行的教训。3.3 收敛的前提和失效场景很多初次接触迭代学习的读者会以为它能对付一切重复过程这是误解。MFAILC能够收敛需要满足几个基本条件每次运行的初始状态要一致或偏差不大参考轨迹在批次间完全相同对象在一个批次内的非线性特征虽然可以变化但变化的规律不能过于剧烈系统相对阶信息要能由伪偏导数大致反映。仿真里我专门构造了一个“破坏性实验”在部分批次加入与批次序号相关的随机扰动并且让每个批次的初始状态在额定值附近随机波动。结果非常直观当初始状态波动时MFAILC仍能收敛到一个较小的残差范围但收敛速度和最终精度都明显下降当扰动完全不重复时迭代学习对这批扰动几乎无能为力因为学习律只能修正可重复的误差源随机扰动只能靠时间轴反馈压住。这说明在实际应用中如果上游工况本身不稳定不能指望MFAILC单枪匹马解决问题需要配合时间轴反馈或者前馈补偿。4. 仿真程序设计被控对象、场景注入与主循环结构4.1 被控对象选择一个非仿射、时变的递推模型数值验证程序里被控对象选择比控制算法本身更需要谨慎。太简单的对象体现不出算法优势太复杂的对象又难以定位问题。我最终选用了一个在控制文献中经常出现的非仿射非线性递推模型形式如下y(k1) [a(k)·y(k)·y(k-1)·u(k-1)·(y(k)-1) b(k)·u(k)] / [1 y(k)² y(k-1)²]这个式子没有对u(k)显式线性化u以非线性方式出现在分子中同时分母随输出变化系统的增益和动态特性都会随工作点大幅改变。a(k)和b(k)是时变参数可以在仿真中途直接切换用来模拟工艺调整或进料变化。初始条件我设为y(1)y(2)0控制量初始化为0。采样周期取Ts0.01s一个批次的仿真长度为10s即1000个采样点。这个对象看起来只是一个数学式子但它足够难为控制器了。原因是它的增益方向虽然总体为正但在某些输出区间内u前面的等效系数非常小输出变化对控制作用不敏感而在另一些区间很小的控制增量就能造成较大的输出变化。伪偏导数估计器必须实时跟踪这种增益变化稍有滞后输出就会出现明显的振荡。4.2 轨迹、扰动与参数突变场景设计参考轨迹设计成有典型工业代表性的形状先一段斜坡上升再进入平台保持然后阶跃到另一个平台最后再斜坡下降。这个轨迹同时考验控制器的动态跟踪和稳态保持能力。所有批次共用同一条参考轨迹便于MFAILC在批次间比较误差。扰动注入分为三类。第一类是传感器测量噪声加入幅值很小的白噪声第二类是对象输入端的方法性扰动只在某个时间窗口内加入固定值第三类是模型参数突变在仿真进行到一半时切换a(k)和b(k)。每一类扰动都对应一种实际工况分别验证算法的测量鲁棒性、抑制外部扰动的能力以及应对对象自身变化的自适应能力。4.3 控制主循环与评价指标整个程序模块化程度不高但主线非常清晰MFAPC直接进行单批次长仿真MFAILC则在外层增加批次循环。用一个简化的代码骨架表示% 公共部分初始化参数、参考轨迹、被控对象状态 % MFAPC: 单次循环 for k 2:N-1 phi_hat estimate_PPD(y, u, phi_hat_prev); % 伪偏导数估计 dU mfapc_calc(phi_hat, Yd(k1:kNp), Y0); % 滚动优化 u(k) u(k-1) dU(1); y(k1) nonlinear_plant(y, y_prev, u, k, a, b); end % MFAILC: 批次循环 for i 1:maxIter for k 2:N-1 phi_hat estimate_PPD(y_i, u_i, phi_hat_prev); u_i(k) u_prev(k) rho * phi_hat * e_prev(k1); y_i(k1) nonlinear_plant(y_i, y_i_prev, u_i, k, a, b); end e_prev Yd - y_i; u_prev u_i; end这段代码省去了大量边界处理和状态缓存但核心结构足够表达两类算法的差异。MFAPC的更新在每个采样时刻完成MFAILC的修正发生在批次结束后这是二者最大的节奏差异。评价指标主要用均方根误差RMSE、平均绝对误差MAE和最大绝对误差maxE三个指标其中maxE能敏锐地暴露阶跃时刻的超调问题RMSE则反映整体跟踪水平。5. 数值结果对比跟踪性能、鲁棒性与伪偏导数曲线5.1 固定对象下的跟踪精度差异在对象参数固定、测量噪声很小的基准工况下两种算法都能完成跟踪任务但表现差异明显。MFAPC从第一个批次开始就具备较强的跟踪能力RMSE在两个时间窗口后就能稳定在0.04左右MFAILC的第一个批次实际是“开环粗略反馈”的水平RMSE接近0.3需要经过十到二十次迭代学习才能逐步逼近参考轨迹。从第20个批次开始MFAILC的RMSE降到0.008左右最大绝对误差从0.25压到0.03以下明显优于MFAPC。这个结果符合直觉MFAPC是单次运行算法只能利用当前批次的实时数据MFAILC则把前二十次的误差信息全部压进了控制输入对固定对象来说学习效应是滚雪球式累积的。如果在生产现场遇到严格重复的批次任务MFAILC往往越跑越准这是它最大的实用价值。算法RMSEMAEmaxE控制量方差MFAPC0.0420.0330.1150.006MFAILC第1批次0.2860.2240.5210.018MFAILC第20批次0.0080.0060.0290.0025.2 参数突变与不重复扰动下的表现参数突变是两种算法的分水岭。在仿真到第500个采样点时我把a(k)从0.5切换到1.2b(k)从1.0切换到0.6相当于对象增益方向不变但大小明显变大。MFAPC的伪偏导数估计器在突变发生后的几个采样周期内快速更新输出经过一个短促的过渡波动后重新回到参考轨迹恢复时间大约0.3秒超调量在10%以内。这个表现完全体现了无模型自适应方法的优势它不需要知道模型怎么变只要数据在变估计器就会跟上。MFAILC面对参数突变的反应可以用“内伤”来形容。因为学习律是基于上一批次误差调整控制量当对象在第500个采样点突然改变特性后同一批次内MFAILC只能依靠伪偏导数的时间轴反馈勉强压住波动批次结束后的误差修正会把这个突变信息带入下一批次。经过三到五个批次的迭代MFAILC恢复到了与突变前相当的跟踪水平。这说明MFAILC对时变对象的适应不是即时的而是需要几个完整批次来消化变化。不重复扰动下的结果更有意思。我在每批次加入一个随机位置、随机幅值的外部干扰MFAILC经过多次迭代后RMSE收敛到一个平台大约0.03左右再也无法进一步下降。原因是随机扰动不可预测迭代学习把上一批次的随机误差当成可重复误差去修正反而引入部分错误的修正量。这个平台高度取决于随机扰动的强度如果扰动过大MFAILC甚至可能发生迭代发散学习律不但没有压过噪声还会把噪声放大到控制输入里。5.3 伪偏导数曲线告诉我们什么仿真程序中我额外记录了伪偏导数的实时曲线。MFAPC在正常工作段时φ̂的数值在1到3之间缓慢波动跟随工作点变化参数突变瞬间φ̂会短暂跳增随后回落到新的稳定范围。这说明估计器确实在用数据追踪对象的等效增益。如果φ̂曲线频繁出现正负交替或数值剧烈摆动基本可以断定估计参数里的μ设置过小或测量噪声过大控制器会很快表现出抖振。MFAILC的伪偏导数是按批次更新的曲线呈现“静-动-静”的节律。批次刚开始时由于初始状态和上一批次的边界条件不同φ̂会有明显波动进入批次中段后估计值逐渐稳定批次结束时由于学习律带来的控制量调整尚未完全作用完φ̂又可能小幅波动。这个现象在程序里非常容易观察到它提醒我们在实际应用中不要只看单步估计值而是要分析估计器在整个批次内的统计特性。6. 参数整定、常见坑和一套能移植的程序结构6.1 伪偏导数的初值、投影与重置伪偏导数初值是仿真中最容易埋雷的地方。初始值给得太小控制器起步阶段会非常迟钝给得太大前几步控制量可能冲过头。我的经验是把初值设置成与被控对象稳态增益同一量级如果完全没概念宁可给得稍微偏大一点因为投影算法会在几步内把它拉回来。仿真里我试验了从0.2到5的不同初值发现只要方向正确MFAPC都能在十个采样周期内回到正常跟踪状态但初值偏大时前几步控制量峰值明显更高。投影算法是保证伪偏导数估计稳定性的关键。具体做法是当估计值的绝对值小于某个下限时把它强制拉回到下限值当估计值的符号与预期增益方向相反时重置为初值。这个机制看起来很像手工补丁但它在工程上非常有效。没有投影机制的估计器在输出长时间不变时φ̂可能漂移到不合理区间等到参考轨迹变化时控制量会出现无法解释的猛冲。仿真程序里一定要加这个逻辑不要以为算法本身能自动规避。6.2 λ和Np/Nu的搭配经验MFAPC的参数整定顺序有讲究。我习惯先把预测时域Np固定为采样周期数的十分之一左右控制时域Nu取Np的三分之一到一半再调λ。λ的调整看控制量曲线最直观如果控制量像锯齿一样高频抖动就是λ太小逐步增大直到曲线平滑如果跟踪响应明显滞后就是λ太大逐步减小。这个顺序比同时调三个参数效率高得多因为Np和Nu对响应形态的影响方向和λ是互相牵连的。MFAILC的学习增益ρ也很敏感。ρ太小批次间收敛速度慢几十次迭代都看不到明显改善ρ太大第一个批次结束后的修正量就非常猛烈第二批次的输出可能直接振荡发散。安全做法是从0.3开始试观察误差最大值的下降曲线如果修正后的maxE比上一批次更小说明ρ方向正确、幅度适中如果maxE反而变大立即减半重试。6.3 几个仿真里经常翻车的细节最后说几个我实际调试中踩过的具体坑每一个都花了不少时间。第一数据缓存索引错位。MFAILC需要保存整条输出轨迹和控制轨迹索引变量一多很容易在“当前采样点”和“上一采样点”之间来回绕晕。建议所有轨迹数组从1开始存放初始值循环内下标统一对齐到k和k1不要混用。第二噪声强度对伪偏导数估计的影响被低估。我一开始加的测量噪声很小控制器完全正常把噪声幅值放大到0.05后MFAPC开始出现偶发尖峰。这不是算法坏了而是估计器把噪声当成了真实动态。解决办法是在估计器中增加历史差分信号的平滑滤波或者适当增大正则系数μ。第三MFAILC对初始状态变化的敏感度比想象中大得多。我故意让每个批次的初始状态在±0.05范围内波动结果是最终收敛残差从0.008变成0.02。这说明如果实际设备每批次的初始条件受人工操作影响较大必须先稳定初始状态或者把初始偏差也纳入迭代修正向量否则学习效果会被明显削弱。跑完这一轮仿真我最大的体会是数据驱动控制不是一个能让人完全甩开模型的魔法但它确实给了我们一条在模型信息极度匮乏时还能把控制做好走通的路。MFAPC适合在线实时调整场景MFAILC则适合批次重复且误差可复现的场合两者并不冲突甚至可以串级使用。后续我打算在这个仿真框架上再加入约束处理和执行器饱和逻辑让程序更接近实际工业控制器的现场形态。如果你也在验证类似算法参数整定阶段请务必保持耐心先让每条曲线都符合物理直觉再追求更漂亮的指标数字。