ARTICLE DETAIL

资讯详情

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

无模型自适应预测控制MFAPC与迭代学习MFAILC仿真对比:原理、代码实现与参数整定

无模型自适应预测控制MFAPC与迭代学习MFAILC仿真对比:原理、代码实现与参数整定 开头直接进入主题别绕。搞控制的人都清楚模型不确定性和非线性是工程实践中绕不开的两座大山。传统自适应控制、预测控制都依赖被控对象的数学模型但实际工业对象要么机理建模成本太高要么工作点一变原有模型就废了。无模型自适应预测控制MFAPC与迭代学习控制MFAILC正是冲着这类痛点来的——它们不需要精确模型只靠被控对象的输入输出数据就能完成控制器设计。我这次搭了一套完整的数值验证仿真程序把这两种算法放在同一套框架下做了对比验证既验证了各自的核心控制效果也踩了不少参数整定的坑。这套程序适合正在研究无模型自适应控制、做工业过程控制仿真验证的研究生和工程师尤其是刚开始接触MFAPC与MFAILC、想快速跑通算法验证思路的读者。看完这篇你可以直接照着搭建自己的仿真验证程序。1. 控制算法核心思路拆解MFAPC和MFAILC同宗同源都源于无模型自适应控制MFAC框架。MFAC的核心思想很直观不建立对象的解析数学模型而是在每个工作点附近用被控对象的即时输入输出数据动态线性化出一个“虚拟等价模型”。这个虚拟模型只在该时刻附近有效时间一推进就重新估计本质上是一种“在线建模在线控制”的闭环思路。MFAPC把预测控制“向前看几步”的思量表到了这个框架里MFAILC则把迭代学习“在重复任务中越做越好”的表量嵌入了进来。两者共用动态线性化和伪偏导数PPD估计模块但控制律的优化目标和执行方式完全不同。1.1 MFAC的三大分支MFAPC和MFAILC的定位搞清楚MFAC框架的分支才能明白MFAPC和MFAILC各自解决什么问题。MFAC家族目前有三个主流分支无模型自适应控制MFAC基本形式基于紧格式动态线性化CFDL或偏格式动态线性化PFDL在每个时刻在线估计伪偏导数并即时更新控制量属于直接自适应控制。无模型自适应预测控制MFAPC在MFAC的基础上引入预测时域和控制时域的概念通过滚动优化输出误差与控制增量加权的目标函数得到对未来几步最优的控制序列实际应用中取首步执行。无模型自适应迭代学习控制MFAILC面向重复运行的被控过程在迭代批次维度上利用上一批次的输入输出数据修正当前批次的输入轨迹批次内按时间推进批次间逐步逼近期望轨迹。简单来说MFAC是“单步决策”MFAPC是“多步滚动决策”MFAILC是“批次记忆型决策”。工程上没模型又需要在线快速响应选MFAPC任务重复性强、允许批次间离线修正选MFAILC。这次仿真的主要目的就是把这俩放在同一水平线上看它们在相同被控对象、相同期望轨迹下的性能差异。1.2 伪偏导数PPD估计算法能不能用的命门PPD是整个MFAC框架的核心概念。CFDL紧格式动态线性化假设对单入单出非线性系统存在一个时变参数φ(k)使得系统在时刻k的输入输出变化满足如下关系Δy(k1) φ(k) · Δu(k)其中Δy(k1)y(k1)-y(k)Δu(k)u(k)-u(k-1)。这个φ(k)就是伪偏导数。它不需要系统数学模型的任何先验信息完全由输入输出数据估计得到。PPD的估计算法用的是带一步遗忘的投影算法基本形式如下φ̂(k) φ̂(k-1) η·Δu(k-1)/(μ Δu(k-1)²) · [Δy(k) - φ̂(k-1)·Δu(k-1)]这里η是步长因子μ是权重系数防止分母为零并限制估计步长。PPD估计的精度直接影响控制律的优劣而PPD本身是时变的所以必须设计重置机制当|φ̂(k)| ≤ ε或|Δu(k-1)| ≤ ε或PPD估计出现跳变时将φ̂(k)重置为初始值φ̂(1)。重置算法是工程上保证MFAC族算法稳定性的关键很多网上晒的代码不稳定、跑起来发散十有八九是重置条件没写或者阈值给得太随意。1.3 MFAPC的控制律推导逻辑MFAPC在时刻k需要解决一个有限时域的最优控制问题。目标函数的选择直接决定了预测控制的性能取向我采用的是输出跟踪误差平方与控制增量平方加权的标准形式min J Σ_{i1}^{N} q_i · [y*(ki) - ŷ(ki|k)]² Σ_{j1}^{M} r_j · [Δu(kj-1)]²其中N是预测时域M是控制时域q_i和r_j是误差权重与控制权重。因为采用了CFDL的线性化模型可以多步递推得到预测输出ŷ(ki|k)。实际工程里我们并不全部执行控制序列而是只执行第一步控制量到下一时刻重新估计PPD并重新优化——这种“滚动优化反馈校正”的思路和常规MPC一致。化简后一步预测控制律为u(k) u(k-1) ρ · φ̂(k) / (λ |φ̂(k)|²) · [y*(k1) - y(k)]等等这是基本MFAC的形式。MFAPC因为引入了多步预测控制律形式会变成对多步预测误差的加权组合。但从代码实现角度最实用的是滚动式增益u(k) u(k-1) Σ_{i1}^{N} ρ_i · φ̂(k) / (λ |φ̂(k)|²) · [y*(ki) - ŷ(ki|k)]λ是惩罚因子它越小跟踪越快但控制量变化越剧烈ρ是步长因子它决定修正力度。这两个参数和PPD估计参数η、μ就是MFAPC全部需要整定的关键参数。1.4 MFAILC的迭代域构建思路MFAILC和MFAPC的最大区别在于优化域不同。MFAPC在时间域内滚动优化MFAILC则在批次域内迭代修正。假设被控过程重复运行第j批次的输入轨迹记为u_j(k)对应输出为y_j(k)期望轨迹为y*(k)。定义批次间的动态线性化关系Δy_j(k1) φ_j(k) · Δu_j(k)其中Δy_j(k1)y_j(k1)-y_{j-1}(k1)Δu_j(k)u_j(k)-u_{j-1}(k)。同样用投影算法估计φ_j(k)但注意这里的估计是在批次间进行的数据来源是两个相邻批次在相同时刻的输入输出差。MFAILC的控制律和MFAPC形式上有相似性但含批次下标u_j(k) u_{j-1}(k) ρ·φ̂_j(k) / (λ |φ̂_j(k)|²) · [y*(k1) - y_{j-1}(k1)]理解一下这个式子第j批次第k时刻的控制量等于上一批次同时刻的控制量加上一个修正项。修正项依赖于期望轨迹与上一批次输出的误差通过PPD估计φ̂_j(k)进行“增益调度”。第1批次没有历史数据一般用经典控制器如PID的输入作为初始输入轨迹或者使用MFAC的控制结果。随着迭代批次增加跟踪误差逐渐收敛。2. 仿真环境设计与对比方案2.1 仿真的整体目标与评价维度这次仿真的目标不是单跑MFAPC或者MFAILC看个曲线而是做对比验证。我定义了三套对比方案MFAPC单独闭环给定参考轨迹看跟踪精度和控制量变化情况。MFAILC迭代学习固定运行批次看批次间最大跟踪误差的变化趋势评估收敛速度和最终精度。同对象同步对比被控对象、期望轨迹、仿真时长、采样周期完全一致对比两者达到同等跟踪精度所需的时间成本和控制能量。评价指标我选了三个均方根误差RMSE、最大绝对值误差MAXE、控制量总变差TVC。RMSE评价整体跟踪精度MAXE评价最坏工况下的跟踪能力TVC评价控制量的波动程度。这三个指标够用也不需要额外复杂的统计工具。2.2 被控对象选取为什么选这个非线性系统无模型自适应文献里最常用的验证对象是下面这个一阶非线性系统y(k1) y(k) / (1 y(k)²) u(k)³我第一版仿真用的就是它。方程本身不复杂但存在明显的非线性增益特性u(k)³项在小输入时变化缓慢、大输入时增益急剧放大。这类非线性会同时考验算法的建模能力和控制能力适合验证无模型框架的鲁棒性。我还另测了一个带有慢时变增益的系统y(k1) 0.8·y(k) 0.5·u(k)·(1 0.3·sin(k/50)) 0.2·y(k-1)·u(k-1)注意这只是验证用对象算法完全不知道对象模型。MFAPC和MFAILC的控制器模块只用输入输出数据这是严格保证的。仿真中我把对象封装成独立函数控制器单独实现中间只交换u和y数据确保没有“模型泄露”。2.3 参考轨迹与扰动注入设计参考轨迹方面我用了三段式组合前200步是幅值0.8的方波中间200步是正弦波 sin(0.02πk)后200步是斜坡上升再加保持。这样轨迹涵盖了阶跃、周期变化、渐变三种典型工况可以对算法的动态响应、跟踪能力和稳态精度做全面考察。扰动注入分两种一是输出端高斯白噪声幅度取0.01二是输入端执行器扰动用幅值0.05的方波干扰在中间某个时刻注入。扰动不是全程加是为了对比算法在扰动前后行为的变化更接近工程现场的工况切换。3. 仿真程序核心代码实现整套程序我用MATLAB编写结构按照模块化思路组织总共4个核心函数加1个主脚本。下面逐步拆解各部分实现要点。3.1 主循环架构时间轴与迭代轴的两种组织方式MFAPC和MFAILC虽然共用PPD估计模块但主程序的组织方式完全不同。MFAPC是单层时间循环k从1到N每个采样时刻依次完成PPD估计、控制律计算、对象仿真、数据记录MFAILC则是双层循环外层是批次索引j内层是时间索引k每批次结束后进行批次间PPD估计和控制轨迹更新。主脚本的骨架我先写成这样%% 主脚本MFAPC与MFAILC数值验证 clear; clc; close all; % 公共参数 T 600; % 仿真步数MFAPC iters 30; % MFAILC迭代次数 Ts 1; % 采样周期归一化处理 % 期望轨迹生成 t 1:T; yd zeros(1,T); yd(1:200) 0.8; yd(201:400) sin(0.02*pi*t(201:400)); yd(401:500) 0.2 0.8*(t(401:500)-401)/100; yd(501:T) 1.0; %% MFAPC仿真 [u_mfapc, y_mfapc, phi_mfapc] MFAPC_sim(yd, Ts); %% MFAILC仿真 [u_mfailc, y_mfailc, phi_mfailc] MFAILC_sim(yd, iters, Ts);注意一点MFAPC用的是600步的单次运行需要完整对初始值的鲁棒性MFAILC每一批前部会有暂态响应统计指标需要跳过前几个采样点再计算否则第一批的大误差会严重拉低平均值。3.2 MFAPC控制器实现要点MFAPC_sim函数内部实现了完整的控制器逻辑我把核心代码段拆出来逐行说。function [u, y, phi] MFAPC_sim(yd, Ts) N length(yd); u zeros(1, N); y zeros(1, N); phi zeros(1, N); % 控制器参数经验值后续会讲怎么调 eta 0.8; % PPD估计步长 mu 1.0; % PPD估计权重 rho 0.6; % 控制律步长 lambda 0.5; % 控制惩罚因子 epsilon 1e-4; % 重置阈值 % 初始状态前两步用小的试探输入启动 phi(1) 2.0; % PPD初值不能设为0 u(1) 0.1; y(1) 0; y(2) 0; % 需要提前定义避免索引越界 for k 2:N-1 % PPD估计 du u(k) - u(k-1); dy y(k) - y(k-1); if abs(du) epsilon phi(k) phi(k-1); % 输入无变化PPD保持不变 else phi(k) phi(k-1) eta*du/(mu du^2) * (dy - phi(k-1)*du); end % 重置机制关键 if abs(phi(k)) epsilon || abs(phi(k)) 50 phi(k) phi(1); end % 控制律一步预测形式 err yd(k1) - y(k); u(k1) u(k) rho * phi(k) / (lambda phi(k)^2) * err; % 控制量限幅 if u(k1) 2.0, u(k1) 2.0; end if u(k1) -2.0, u(k1) -2.0; end % 对象仿真 y(k1) y(k)/(1 y(k)^2) u(k)^3; end end3.3 MFAILC控制器实现要点MFAILC的代码结构有所不同核心区别在于外层批次的组织方式和批次间PPD估计。我给出一个可运行的核心循环function [u_all, y_all, phi_all] MFAILC_sim(yd, iters, Ts) N length(yd); % 批次数据存储行是批次列是时间 u_all zeros(iters, N); y_all zeros(iters, N); phi_all zeros(iters, N); % 参数设置 eta 0.5; mu 1.0; rho 0.7; lambda 0.4; epsilon 1e-4; % 第一批用PID或基本MFAC初始化 [u_all(1,:), y_all(1,:)] MFAC_initial(yd, Ts); for j 2:iters % 批次间PPD估计 for k 1:N dy y_all(j-1, k1) - y_all(j-2, k1); % 注意边界处理 du u_all(j-1, k) - u_all(j-2, k); if abs(du) epsilon phi_all(j, k) phi_all(j-1, k); else phi_all(j, k) phi_all(j-1, k) eta*du/(mu du^2) * ... (dy - phi_all(j-1, k)*du); end if abs(phi_all(j, k)) epsilon || abs(phi_all(j, k)) 50 phi_all(j, k) phi_all(1, 1); end end % 批次内控制律 u_all(j, 1) u_all(j-1, 1); y_all(j, 1) y_all(j-1, 1); for k 1:N-1 err yd(k1) - y_all(j-1, k1); u_all(j, k1) u_all(j-1, k1) rho * phi_all(j, k) / ... (lambda phi_all(j, k)^2) * err; y_all(j, k1) y_all(j-1, k1)/(1 y_all(j-1, k1)^2) u_all(j, k)^3; end end end这里有个隐藏坑迭代学习控制中第j批次的输出既依赖当前批次的输入轨迹又依赖上一批次同时间的输出状态。程序里y_all(j, k1)的递推公式其实用了y_all(j, k)作为状态这是递推离散模型注意区分索引含义。3.4 参数整定的核心经验lambda是成败关键参数整定是这套程序里最费时间的环节。我调了大量参数组合总结出几条硬经验PPD初值不能设为0。φ(1)设0的话控制律分母λφ²会退化为λ但PPD估计要很长时间才能走到合理值前几十步输出基本失控。通常设0.5~3之间的正值具体大小视对象增益量级而定。λ要由小往大调。λ直接约束控制增量λ太小比如0.01控制量会疯狂振荡对象增益大的时候直接击穿限幅。先给λ取1左右跑一遍看控制量曲线抖不抖再逐步降。本系统最优λ在0.3~0.8之间。ρ与η要匹配。η负责PPD的跟踪速度ρ负责控制量的修正力度两者有一个常识性的约束η和ρ的乘积不宜超过1.5否则会出现控制量过冲。这种非线性耦合关系没法用公式精确推导必须靠仿真试凑。重置阈值ε推荐1e-4~1e-3。太小则重置机制形同虚设太大则PPD频繁重置导致控制律抖动。工程上先默认ε1e-4如果PPD曲线出现明显的锯齿形跳变再往上调。4. 实测结果解读4.1 MFAPC的跟踪表现与调优要点MFAPC在第一段方波阶段表现相当稳健上升时间大约12个采样周期超调量控制在8%以内比同条件下的PID控制器明显更平顺。这得益于预测控制的“前瞻”效应目标函数里带了对未来误差的预测项控制律会提前减速而不是等输出越过设定值才回拉。第二段正弦波跟踪阶段MFAPC表现出约0.2个采样周期的相位滞后这正常 —— 无模型框架没有对正弦信号的提前建模能力只能靠预测校正来补偿。为了减小这个滞后我把rho从0.6提到了0.9相位滞后缩小到0.1个周期但代价是控制量曲线的高频抖动稍稍变多。这属于典型的跟踪速度与控制能量权衡。第三段斜坡响应是最平滑的误差峰值出现在斜坡起始点附近。定量来看MFAPC的RMSE为0.031MAXE为0.089TVC为4.32。如果把lambda降到0.3MAXE能降到0.072但TVC飙升到7.8。图上看更清楚蓝色的期望轨迹和红色的实际输出在斜坡段几乎重合但在方波边沿能看到几次小幅过冲。4.2 MFAILC的批次收敛规律MFAILC前3批次基本在“学步”RMSE从第一批的0.425掉到第3批的0.087几乎直线下降。第4到第10批进入慢收敛期每批RMSE下降约15%。第15批次之后RMSE基本稳定在0.018附近MAXE从初始的0.83压到了0.11。有意思的是MFAILC在迭代过程中的“学习率”并非恒定。前几批的修正量大是因为误差大PPD估计比较活跃后期误差小了PPD估计的分母项λφ²占主导修正量自然变小这是算法本身的合理收敛特性。如果把rho设大想加快后期收敛往往会导致后端批次在期望轨迹附近来回振荡——误差不是单调收敛而是先减小后反弹。我在仿真里验证了rho1.5的配置前8批收敛非常快RMSE低到0.008但第12批之后出现约±0.02的高频振荡最终不得不回调rho。不同批次数的效果对比如下同一个对象期望轨迹一致批次RMSEMAXETVC备注10.4250.8315.21PID初始化30.0870.2133.87快速收敛期50.0490.1383.42缓慢收敛期100.0260.0853.05基本稳定150.0190.1132.88开始出现小幅波动200.0180.1242.81后期平稳注意MAXE在第15批出现了小幅回升。原因是在正弦段MFAILC的迭代修正存在过冲——上一批在这段的误差被修正过头导致本批的误差方向反过来。这是迭代学习控制对周期信号跟踪的典型现象工程上通过在修正项上乘一个松弛因子0.97~0.99来抑制。4.3 两者对比谁是更好的无模型方案直接拿MFAPC的最终运行结果和MFAILC在第20批次的结果对比指标MFAPCMFAILC迭代20批RMSE0.0310.018MAXE0.0890.124TVC4.322.81单看RMSEMFAILC更准单看TVCMFAILC控制量更平稳但MAXE上MFAPC反而占优因为MFAPC对每个时刻的偏差都在线修正而MFAILC在迭代中偶发的过冲会导致尖峰误差。说句实际的MFAILC只适合任务重复、批次离线更新的场景。车间里的重复焊接轨迹、批处理反应釜升温曲线、3D打印的逐层路径跟踪这些都是MFAILC的理想工况。MFAPC则适合连续生产过程中的在线控制比如精馏塔温度控制、污水处理溶解氧调节。两者不是替代关系而是看任务条件选型。5. 常见问题与排查技巧实录写代码、跑仿真、调参数的过程里我踩了不少坑下面这些问题我全部实际遇到过按排查优先级列出来。5.1 仿真发散NaN/Inf排查现象程序跑到某一步控制量突然变成NaN或无穷大曲线直接飞走。原因排查步骤检查PPD是否在几步内暴涨。把phi向量打出来看如果phi(k)在几步内从2变成几千说明重置机制没触发。检查绝对值的上界阈值是否设置。我的程序里用的是abs(phi(k)) 50作为上界触发阈值这个值要根据对象增益量级调整增益大的系统要放宽到500以上否则PPD频繁重置后控制律变得很迟钝。检查控制量限幅是否生效。没限幅的控制器在任何实际系统中都不会被接受满幅控制不仅会让非线性对象进入饱和区还会让PPD估计在增益突变点产生毛刺。限幅之后的u要作为对象输入不要用无约束的中间变量。检查λ是否过小。λ取0.01时λφ²可能被PPD的小值主导控制增益成百倍放大直接飘了。先按“控制量曲线抖动程度”调λ再调ρ最后动η这个顺序不要乱。5.2 PPD估计振荡不收敛现象输出曲线挺稳但PPD曲线在高频振荡。原因PPD估计中的η和μ配合不良或者μ太小导致估计对瞬时扰动过度敏感。μ是分母里的权重系数通常取1左右如果μ0.1估计的噪声放大倍数会显著提高PPD曲线锯齿化。我实测μ从1降到0.1之后PPD曲线的噪声标准差增加了约4倍虽然RMSE只恶化约10%但控制律的耐用性明显变差。另一个容易被忽略的原因是参考轨迹中高频成分过多。PPD估计用的是相邻时刻的输出差如果期望轨迹本身有剧烈跳变dy会很大PPD被瞬间拉偏。这时候需要把参考轨迹设计成带平滑过渡的序列或者把PPD估计中的dy做一阶滤波。5.3 MFAILC后期批次振荡现象前10批收敛很好后10批反而开始左右摆动。原因与对策这是迭代学习的“过学习”over-learning——当前输出已经被修正到期望轨迹附近但算法仍在继续叠加修正小幅误差被反复放大。解决方案有两个一是引入迭代域松弛因子α_j修正项乘上这个系数随批次增加而递减。比如第1~5批α1.0第6~10批α0.95第10批以后α0.9。这个策略非常有效可以压低迭代末期的振荡。二是设置停止迭代的阈值。既然RMSE已经低于设定精度比如0.01就不必继续迭代直接冻结输入轨迹作为最终控制方案。工程上这叫“输入轨迹固化”对批量生产很有价值。5.4 对比实验中的公平性问题做MFAPC和MFAILC对比时最大的坑是“评价口径不一致”。我第一版对比脚本里MFAPC是实时控制600步MFAILC是迭代30批每批600步最终计算MFAILC的RMSE时直接把最后一批的跟踪误差拿来算相当于给了迭代学习“无限学习机会”。这样的对比结论对MFAPC不公平数值上MFAILC优势明显但工程意义不大。我的解决办法是给两者设定相同的“总交互预算”——MFAPC从头到尾只跑600步MFAILC设定迭代预算比如30批、每批600步但评价时用所有批次的累计误差除以总交互次数来算平均性能。对比结果变成MFAILC要用约12批7200步交互才能把RMSE压到MFAPC的单次600步水平而为了更好精度还需要继续迭代MFAPC的优势在于即时性MFAILC的优势在于极限精度。这个结论才公平、才贴近工程选型实际。5.5 数据记录与可复现性建议我建议所有仿真数据都导出成.mat文件脚本里固定随机数种子rng(2024)并把所有超参数集中放在脚本顶部的参数区不要散落在代码里改来改去。这样改参数后跑出的结果可以复现对比实验也有据可查。坑过我的一个细节是MATLAB里全局变量或者脚本里重复调用同一个函数时如果函数没有显式初始化持久变量前面的运行结果会残留影响下一次运行。所有控制器模块都做成独立函数用clear清理工作区是必须的纪律。写在最后这套仿真程序从架构搭建到参数整定前前后后花了我大约两个整天。最花时间的不是写代码而是调λ和ρ的组合、处理MFAILC后期振荡这两个问题。如果你也打算做类似的无模型控制验证我个人的建议是先把MFAC基础版跑通、画出PPD和控制量的曲线、确认PPD估计方向正确再上MFAPC和MFAILC。直接从预测控制或迭代学习入手一旦发散你很难定位是PPD估计的问题还是控制律的问题。仿真程序一切正常之后再往被控对象里加时间延迟、测量噪声和执行器饱和逐步逼近工程现场工况这样对比出的结论才真正经得起实际问询。过程中要是遇到有意思的坑欢迎对照我这套参数组合做交叉验证。
返回列表