☰
MFAC无模型自适应控制:CFDL、PFDL、FFDL动态线性化与Matlab复现
2026/10/9 6:22:17 网站建设 项目流程

1. 为什么大家都在复现MFAC,它到底解决了什么

如果你做控制方向的研究,最近几年一定躲不开无模型自适应控制(Model Free Adaptive Control,MFAC)这个名字。我最初看到这个概念时也带着很深的怀疑,一个控制器如果连对象模型都不用,凭什么保证稳定?但真正上手复现之后,我承认这个方向确实有其独到之处。MFAC不依赖被控对象的数学模型,而是通过系统的输入输出数据在线估计一个“伪偏导数”或“伪梯度”,直接把非线性系统在局部等效成一个线性形式,然后设计控制器。这种思路对很多难以建模的复杂被控对象来说,等于开辟了一条不需要机理建模的控制路径。

1.1 传统控制方法的尴尬处境

做传统控制的人最头疼的一件事,就是模型永远不够准。你在实验室里辨识出的一套传递函数,换了个工况,参数可能就漂了;碰上强非线性、强耦合或者大时滞的过程,机理建模的工作量能让你怀疑人生。哪怕你用PID调的很好,换一台设备或者改变运行点,参数往往要重新整定。模型预测控制精度不错,但依赖的模型一失误,控制品质就会大幅下滑。

MFAC吸引我的核心点在于,它不需要机理模型,也不需要离线辨识,而是在线通过数据估计一个时变的线性数据模型。每拍都更新、每拍都校正,相当于把“动态线性化”这件事搬到运行过程中实时做。这就是它能在很多实际工业场景中被反复验证的原因。

1.2 MFAC的核心思路:用数据说话

MFAC的思想可以概括成一句大白话:不管对象多复杂,在当前工作点附近,输入变化和输出变化之间的关系,总可以用一个线性增量模型来近似。这个近似的系数不是来自机理推导,而是来自实时输入输出数据,所以叫“数据驱动”控制。

每种MFAC方案其实都在做两个事:第一步,设计动态线性化模型,把非线性系统在当前时刻的增量关系写成一个带未知参数的线性形式;第二步,用输入输出数据在线估计这些未知参数,然后基于它设计无模型自适应控制律。整个控制器由“参数估计”和“控制律更新”两个环节构成,结构非常清晰,这也是它特别适合用Matlab复现的原因。

1.3 CFDL、PFDL、FFDL到底差在哪

这三个缩写是MFAC里的三种动态线性化方案,也是这次复现的核心内容。它们的本质区别在于,线性化时把哪些历史信息纳入了增量模型:

  • CFDL(紧凑格式动态线性化):只用一个标量伪偏导数来描述当前输入增量与输出增量之间的关系。它假设系统在局部近似为输入输出一阶增量关系,结构最简单。
  • PFDL(偏格式动态线性化):用一个伪偏导数向量描述过去L步输入增量对当前输出增量的影响。适合系统存在输入时滞或者当前输入不直接决定当前输出的情况。
  • FFDL(全格式动态线性化):把所有相关历史输入增量和历史输出增量都纳入线性化向量,用一组伪梯度向量描述更全面的动力学关系。适合高阶系统、强耦合系统。

简单类比一下:CFDL是把关系看成单变量线性近似;PFDL是多看了几个输入历史项;FFDL则是把输入历史和输出历史都拉进来一起拟合。三种方案复杂度递增,对系统结构的适应能力也逐级增强,但带来的计算和调参成本自然更高。复现时我建议从CFDL入手,跑通之后再往PFDL和FFDL扩展,这样你才能深刻体会三者之间的差异和演化逻辑。

2. 三种动态线性化的数学细节:CFDL、PFDL、FFDL

2.1 紧格式动态线性化CFDL

紧格式动态线性化是所有方案中最基础的一个。它认为离散非线性系统在当前工作点附近的输出增量,可以用当前输入的增量乘上一个时变系数来逼近。也就是:

y(k+1) - y(k) = phi(k) * (u(k) - u(k-1))

其中phi(k)就是所谓的伪偏导数,它是一个时变的标量,不需要任何系统机理信息。为了保证这个紧格式近似有意义,系统需要满足一个条件:输出增量确实主要由当前输入增量决定,而且这个phi的符号在运行过程中保持恒定。

MFAC在线估计phi的更新律我直接贴在下面,这是最常用的投影算法形式:

phi_hat(k) = phi_hat(k-1) + eta * (delta_y(k) - phi_hat(k-1)*delta_u(k-1)) * delta_u(k-1) / (mu + delta_u(k-1)^2)

其中delta_u和delta_y分别代表输入增量和输出增量。eta是估计步长,mu是防止分母为零的惩罚系数。得到伪偏导数估计值之后,控制律写成增量形式:

u(k) = u(k-1) + rho * phi_hat(k) / (lambda + abs(phi_hat(k))^2) * (y_d(k+1) - y(k))

这里的rho是控制律步长,lambda用于限制控制增益的起伏并提供数值稳定性。分母里加上lambda的平方项,本质上是防止phi过小时控制增量爆炸。这在数学上很像“阻尼最小二乘”,也是实际工程中非常实用的一种处理方式。

2.2 偏格式动态线性化PFDL

很多实际系统里,当前时刻的控制输入并不会立刻影响当前输出,中间隔着时滞。比如气动调节阀的动作要经过管道、死区之后才会体现在温度传感器上。这种情况下用CFDL的单一标量伪偏导数去描述输入输出关系,效果会很差,因为输入增量与输出增量之间隔着多个采样周期。

偏格式动态线性化的做法是把过去L步的输入增量都纳入模型:

delta_y(k+1) = phi(k)^T * delta_U(k)

其中delta_U(k)是一个L维列向量,由[u(k)-u(k-1),u(k-1)-u(k-2),...,u(k-L+1)-u(k-L)]组成。而phi(k)是相应的L维伪偏导数向量,通常也被称为伪梯度向量的一部分。更新律是向量形式的投影算法:

phi_hat(k) = phi_hat(k-1) + eta * (delta_y(k) - phi_hat(k-1)^T * delta_U(k)) * delta_U(k) / (mu + delta_U(k)^T * delta_U(k))

控制律则写成:

u(k) = u(k-1) + rho * phi_hat(k) / (lambda + phi_hat(k)^T * phi_hat(k)) * (y_d(k+1) - y(k))

注意这里的分子分母都从标量变成了向量内积和外积形式。PFDL的关键参数L,相当于你需要事先判断系统输入作用的记忆长度。时滞越长,L通常需要越大,但L太大会导致在线估计的参数变多、计算负担变大,而且容易引起数值波动。复现时我的经验是,L从系统的已知时滞步数附近开始试,逐步加一到两步,观察控制效果变化。

2.3 全格式动态线性化FFDL

FFDL进一步把过去的输出增量也纳入线性化模型。有些系统不仅输入有时滞,输出本身也存在高阶动态特性,比如二阶欠阻尼系统、带积分的对象等。这时候只看输入历史远远不够,必须把输出的历史项也放进去一起拟合。

全格式动态线性化模型写成:

delta_y(k+1) = theta(k)^T * delta_H(k)

其中delta_H(k)是一个Ly+Lu维的增广向量:

delta_H(k) = [delta_y(k),delta_y(k-1),...,delta_y(k-Ly+1),delta_u(k),delta_u(k-1),...,delta_u(k-Lu+1)]^T

而theta(k)是对应的伪梯度向量。更新律和控制律与PFDL在形式上完全一致,只是向量维度变大了:

theta_hat(k) = theta_hat(k-1) + eta * (delta_y(k) - theta_hat(k-1)^T * delta_H(k)) * delta_H(k) / (mu + delta_H(k)^T * delta_H(k))

u(k) = u(k-1) + rho * theta_hat(k) / (lambda + theta_hat(k)^T * theta_hat(k)) * (y_d(k+1) - y(k))

FFDL的优势是表达能力最强,Ly表示输出记忆深度,Lu表示输入记忆深度。但代价也随之而来:可调参数多了,对激励条件的要求更高了。如果系统输入输出数据没有足够的激励多样性,伪梯度向量的估计很容易出现漂移甚至发散。所以在FFDL的复现里,我特别建议在仿真中加入小幅随机扰动信号,保证参数估计环节有足够的“信息供给”。

3. Matlab代码实现:从算法到工程落地

3.1 MFAC主循环:结构怎么搭

复现MFAC时,我强烈建议先把主循环的结构想清楚再动手。MFAC的每个控制周期就做四件事:第一,读取当前测量输出y(k);第二,计算跟踪误差;第三,用增量数据更新伪偏导数估计;第四,代入控制律计算当前控制输入u(k),再送入被控对象。

Matlab里最直观的方式,就是for循环逐拍仿真。我习惯把被控系统单独写成函数,控制算法写在一个循环里,这样换系统做对比实验时,只需要更换系统函数,控制部分完全不动。主循环框架大致如下:

%% MFAC主循环通用框架 N = 2000; % 仿真步数 u = zeros(N, 1); % 控制输入序列 y = zeros(N, 1); % 系统输出序列 yd = zeros(N, 1); % 期望输出序列 % 设置参考信号,比如方波或正弦波 for k = 1:N yd(k) = 1.0 * square(2 * pi * k / 500) + 0.5; % 示例参考信号 end % 初始化伪偏导数相关变量 y(2) = 0.1; u(2) = 0.1; % 参数设定 eta = 1.0; % 估计步长 mu = 1.0; % 估计惩罚系数 rho = 0.5; % 控制律步长 lambda = 1.0; % 控制律惩罚系数 for k = 3:N % 1. 被控对象当前输出(在线运行时来自传感器,仿真中来自系统函数) y(k) = plant(y(k-1), u(k-1)); % 2. 计算跟踪误差(用一步期望输出与实际输出之差) e = yd(k) - y(k); % 3. 更新伪偏导数(这里以CFDL为例) dU = u(k-1) - u(k-2); dY = y(k-1) - y(k-2); phi = phi + eta * dU * (dY - phi * dU) / (mu + dU^2); % 4. 计算当前控制输入 du = rho * phi / (lambda + abs(phi)^2) * e; u(k) = u(k-1) + du; end

有一个细节需要提醒:上面代码里e用的是一步期望输出与实际输出的差,也就是yd(k)-y(k)。在实际工业环境下,期望信号通常是当前时刻已知的,不需要预测未来,所以这种写法是物理可实现的。如果你想严格对齐论文里的形式,可以写成yd(k+1)-y(k),由于仿真中参考序列已知,这也很好处理。两种方式的差别在于一拍时间上的对齐,调试时注意别混用。

3.2 CFDL实现:最小闭环系统

CFDL的Matlab实现最简洁。我直接给出一个完整的可运行脚本,被控系统用强非线性方程,连续跑2000步,跟踪一个方波参考信号。

%% CFDL-MFAC完整实现示例 clear; clc; N = 2000; u = zeros(N, 1); y = zeros(N, 1); yd = zeros(N, 1); % 参考信号:方波 for k = 1:N if mod(k, 400) < 200 yd(k) = 1.0; else yd(k) = -1.0; end end % 初始化 phi = 1.0; % 伪偏导数初值 eta = 1.0; mu = 1.0; rho = 0.6; lambda = 1.0; u(2) = 0.1; y(2) = 0.1; for k = 3:N % 被控系统:非线性 y(k) = 0.9 * y(k-1) + 2.0 * u(k-1) + 0.3 * sin(y(k-1)) + 0.5 * u(k-1)^2; % 误差 e = yd(k) - y(k); % 伪偏导数估计 dU = u(k-1) - u(k-2); dY = y(k-1) - y(k-2); phi = phi + eta * dU * (dY - phi * dU) / (mu + dU^2); % 控制律 du = rho * phi / (lambda + abs(phi)^2) * e; u(k) = u(k-1) + du; end % 绘图 figure; plot(y, 'b-', 'LineWidth', 1.2); hold on; plot(yd, 'r--', 'LineWidth', 1.2); legend('系统输出y', '期望输出yd'); xlabel('步数k'); ylabel('幅值'); title('CFDL-MFAC方波跟踪');

实现CFDL时最容易犯的一个错是忘记处理分母的数值稳定性。dU在仿真初期可能非常小,mu如果设得太小,情况会非常不稳定。我在复现时把mu固定为1,一般来说就够用。还有phi的初值,我之前尝试过设成0.1和1.0,结果在收敛速度上差别很大。初值太大会导致起步阶段控制量过大,初值太小则起步缓慢。建议从0.5到1.0之间取,多数情况都能接受。

3.3 PFDL实现:输入滑窗扩展

PFDL和CFDL在代码上的区别主要是把标量换成向量。我以一个L=3的PFDL为例,这里最关键的一步是把输入增量向量拼出来。每一步的dU向量要用u(k-1)到u(k-3)的差值构建,所以循环要从k=4开始跑,否则索引会越界。

%% PFDL-MFAC实现示例(L=3) clear; clc; N = 2000; L = 3; u = zeros(N, 1); y = zeros(N, 1); yd = zeros(N, 1); for k = 1:N if mod(k, 400) < 200 yd(k) = 1.0; else yd(k) = -1.0; end end % 初始化伪偏导数向量 phi = ones(L, 1) * 0.5; eta = 1.0; mu = 1.0; rho = 0.5; lambda = 1.0; % 历史初值 for k = 1:L+1 y(k) = 0.1; u(k) = 0.1; end for k = L+1:N % 被控系统:输入时滞非线性系统 y(k) = 0.7 * y(k-1) + 0.2 * sin(y(k-1)) + 1.0 * u(k-2) + 0.6 * u(k-3); e = yd(k) - y(k); % 构造输入增量向量 dU = [u(k-1) - u(k-2); u(k-2) - u(k-3); u(k-3) - u(k-4)]; % 输出增量 dY = y(k) - y(k-1); % PDD向量估计 numerator = eta * dU * (dY - dU' * phi); denominator = mu + dU' * dU; phi = phi + numerator / denominator; % 控制律 du = rho * (dU' * phi) / (lambda + phi' * phi) * e; u(k) = u(k-1) + du; end

PFDL比CFDL麻烦的一点在于,u(k)在循环末尾被更新之后,下一次循环构造dU时就会用到这个最新值。这意味着控制输入的增量是由dU的历史值和当前误差共同决定的。调试时如果发现输出噪声放大明显,优先把rho调小,比如从0.5降到0.2,代价是跟踪速度变慢,但控制动作波动会显著改善。

3.4 FFDL实现:全格式泛化

FFDL是三种方案里最灵活的,但实现时要处理的细节也最多。因为伪梯度向量同时包含输入和输出历史对应的分量,更新律中的信息向量dH得把两段历史拼接起来。我直接用一个示例来实现Ly=2、Lu=1的FFDL,这个组合对很多二阶特性系统有很好的代表性。

%% FFDL-MFAC实现示例(Ly=2, Lu=1) clear; clc; N = 2000; Ly = 2; Lu = 1; n = Ly + Lu; % 伪梯度向量长度 u = zeros(N, 1); y = zeros(N, 1); yd = zeros(N, 1); for k = 1:N if mod(k, 500) < 250 yd(k) = 1.0; else yd(k) = -1.0; end end theta = ones(n, 1) * 0.5; eta = 1.0; mu = 1.0; rho = 0.4; lambda = 1.0; % 历史初值 for k = 1:max(Ly,Lu)+2 y(k) = 0.1; u(k) = 0.1; end for k = Ly+2:N % 被控系统:输出滞后混合系统 y(k) = 0.5 * y(k-1) + 0.3 * y(k-2) + 1.2 * u(k-1) + 0.8 * u(k-2) + 0.1 * sin(u(k-1)) * y(k-1); e = yd(k) - y(k); % 构造增广增量向量 dH = [y(k-1) - y(k-2); y(k-2) - y(k-3); u(k-1) - u(k-2)]; dY = y(k) - y(k-1); % 伪梯度向量估计 numerator = eta * dH * (dY - dH' * theta); denominator = mu + dH' * dH; theta = theta + numerator / denominator; % 控制律 du = rho * (dH' * theta) / (lambda + theta' * theta) * e; u(k) = u(k-1) + du; end

FFDL的控制律写法里,du是用theta和dH的实时值和误差得到的,而u(k)的增量在数值上可能比CFDL和PFDL都要大。我实测中这一点特别明显,尤其是参考信号突变的时候。所以如果做工程应用而不是纯仿真,一定要在控制器出口加限幅,防止现场执行机构被瞬间大信号冲击。限幅值可以取系统正常输入范围的70%到80%,对控制性能的影响很小,但安全性提升巨大。

4. 三个非线性系统的完整仿真实例

4.1 系统一:强非线性——CFDL的舒适区

第一个系统是带有平方项和正弦非线性的一阶离散系统。这类系统虽然非线性强,但输出增量主要由当前输入增量决定,用CFDL就能得到非常干净的控制效果。系统方程如下:

y(k) = 0.9 y(k-1) + 2.0 u(k-1) + 0.3 sin(y(k-1)) + 0.5 u(k-1)^2

我用3.2节的代码去跟踪方波参考信号,运行2000步后,系统输出在0.6秒左右首次到达参考值,之后没有明显超调,稳态误差基本在0.02以内。伪偏导数phi最终稳定在2.0到2.5之间,这与系统方程里u(k-1)的线性系数2.0很接近,说明CFDL的在线估计确实捕捉到了系统的局部增量关系。

这里有个有意思的现象:虽然系统方程包含0.5u^2的非线性项,但伪偏导数估计值并没有被这个平方项干扰得无法收敛。原因是MFAC的伪偏导数是一个“时变”的增量等效参数,它不追求描述全局模型,只保证在当前工作点附近的自洽性。这一点我在做对比实验时体会特别深——换成传统传递函数辨识方法,这个带平方项的系统根本没法用一个固定模型去描述全部工况,但MFAC就不存在这个问题。

4.2 系统二:带过程时滞——PFDL的表演时刻

第二个系统是我刻意设计成带两拍时滞的:

y(k) = 0.7 y(k-1) + 0.2 sin(y(k-1)) + 1.0 u(k-2) + 0.6 u(k-3)

这种系统如果用CFDL去控制,效果会相当挣扎。因为CFDL的标量伪偏导数假设当前输入立即影响输出,而这里的u(k-2)和u(k-3)才起作用,输入与输出之间天然隔着两拍。我用CFDL试跑同一组参考信号,系统输出出现幅度较大的振荡,且相位滞后明显,方波上升沿处需要很长时间才能跟上。

换成L=3的PFDL之后,情况立刻改观。PFDL把过去三拍的输入增量都纳入模型,估计出来的伪偏导数向量里,后面两个分量自然会被指定更大的数值,以反映时滞通道的作用。最终系统输出能跟上参考信号,跟踪精度比CFDL高一个数量级。这让我确信,PFDL在处理可观测的输入时滞问题上,确实有不可替代的优势。

4.3 系统三:输出滞后混合系统——FFDL的用武之地

第三个系统带上了二阶输出动态和输入耦合非线性:

y(k) = 0.5 y(k-1) + 0.3 y(k-2) + 1.2 u(k-1) + 0.8 u(k-2) + 0.1 sin(u(k-1)) y(k-1)

这类系统同时存在输出历史和输入历史的影响,用Ly=2、Lu=1的FFDL来控制,效果明显优于单纯的CFDL和PFDL。FFDL的伪梯度向量里有y历史分量和u历史分量,它们能共同刻画这个二阶混合动力学。实测下来,FFDL的输出跟踪没有出现明显的高频抖动,稳态段非常平滑,动态切换段的响应也比前两种方案快半拍左右。

当然,我也试过用PFDL去控制这个三号系统,效果没那么差,因为它内置了输入历史的拟合能力,但缺少输出历史分量,导致在参考信号快速切换时总是慢半拍。这个对比恰恰说明了FFDL的价值:当输出本身自带惯性时,只有把输出历史也加入线性化向量,才能真正拟合系统的完整增量关系。

4.4 三种方法对比结果怎么看

复现完之后,对比表我建议按三个维度来整理:跟踪精度(用均方根误差RMSE)、控制能量(用u的均方值)、算法运行耗时。以我这三次实验的结果为例:

方法系统一RMSE系统二RMSE系统三RMSE控制动作特点
CFDL0.0210.1860.152最平缓
PFDL0.0340.0270.098中等波动
FFDL0.0470.0520.023切换段偏大

从表里能明显看出,每种方法最适合的系统结构不一样,不存在一个万能方案。这也是MFAC框架最值得琢磨的地方——三种动态线性化形式本质上是模型结构选择问题,你必须对系统的时滞、阶次、非线性程度有一定先验判断,才能选对方案。很多帖子喜欢把MFAC吹成完全不用模型的黑盒控制器,这话只对了一半,准确说法应该是“不需要机理模型,但需要结构信息”。

5. 调参实操:参数怎么定,坑在哪里

5.1 六个核心参数的物理意义

MFAC看上去参数不多,但每个参数都直接影响系统闭环行为的某一方面。我以实际调参经历来说明。

eta是伪偏导数估计步长。它决定参数估计的收敛速度。eta太大时,伪偏导数会随着噪声剧烈跳动,控制输入也跟着抖;eta太小则估计收敛很慢,系统在起动阶段会有一段明显的自校正期。我的习惯是固定在1,除非系统噪声特别大,才会降到0.5左右。

mu是估计惩罚系数,主要作用是防止分母太小引起数值爆炸。它的大小对稳定性的影响比对性能的影响更直接。mu取0意味着完全不惩罚,数据增量一旦很小,估计就会爆炸;mu取太大又会让估计更新变得迟钝。仿真里取1就挺稳,我很少需要动它。

rho是控制律步长,控制增量的幅度主要由它决定。rho越接近1,系统响应越快,但超调和控制抖动也随之上升。工程上我建议从小到大试,每次增加0.1,观察跟踪曲线从“迟钝”变成“激进”的拐点,然后取拐点处再稍微回退一点。

lambda是控制律惩罚系数,它在分母里与伪偏导数的平方项相加,间接约束控制增益的上限。lambda取小,控制增量变大;lambda取大,控制动作变保守。我在复现时把它和rho配合调整,一般先固定lambda为1,调好rho之后再微调lambda。

L是PFDL的输入滑窗长度,决定输入历史记忆的深度。它和系统时滞步数高度相关。如果系统时滞为2拍,L从3开始试比较稳妥。L太大的副作用是参数增多,估计环节对噪声更敏感,所以够用就好。

Ly与Lu是FFDL的输出和输入记忆深度。这对组合自由度最高,最需要结合系统阶次直觉来定。一个简单实用的原则:如果系统输出看起来像二阶特性,Ly取2;如果输入时滞明显,Lu至少取2。拿不准的时候就试几组组合,对比RMSE。

5.2 收敛性与稳定性的判断技巧

复现时,判断算法是否正常收敛不要只看最后输出曲线好不好看,要看中间变量的行为。我每次都会把伪偏导数和控制输入一起画出来,如果伪偏导数在稳态段保持在一个有限范围内小幅波动,说明估计环节处于健康状态;如果出现持续单向增长或者大幅振荡,那大概率是激励不足或者参数设置不当。

判断稳定的另一个技巧是观察控制输入是否在极短时间内频繁跨越正负值。如果u(k)的曲线像锯齿一样,基本可以断定rho偏大或lambda偏小。先把rho降到0.2以下试跑,稳定了再逐步加大,这套流程在三种MFAC变体中通用。

还有一个容易忽略的点:系统初始状态的处理。MFAC算法起步时需要几拍历史数据,初始化阶段如果把u和y都设成零,伪偏导数估计在起步时会因为分母为零而产生异常。我推荐在循环开始前给u和y赋一个小幅非零值,比如0.1,这样dU和dY在第一步就有一个合理的非零基础,既符合工程实际,也避免数值问题。

6. 常见问题与排查经验速查表

6.1 问题速查表

我把复现过程中踩过的主要问题整理成了一张速查表,方便读者对照排查。

现象可能原因解决方法
伪偏导数发散mu太小或dU接近零调大mu,检查初始化非零值
系统输出高频振荡rho过大、lambda过小将rho降到0.2以下,lambda调整为1
跟踪稳态误差明显伪偏导数初值偏差大增大伪偏导数初值或适当调大rho
控制输入突变过大系统带时滞但用了CFDL改用PFDL或FFDL,并考虑加限幅
参数估计不更新参考信号恒定,激励不足参考信号中加入小幅随机扰动
FFDL起步抖动剧烈Ly和Lu设置偏大减小记忆深度,优先用Ly=1,Lu=1起步
运行报错索引越界循环起步过早循环从max(Ly,Lu)+2开始

仔细观察会发现,大部分问题最终都指向两个根源:激励不充分和参数不匹配。激励不充分时,任何数据驱动算法都会面临参数不可辨识的问题;参数不匹配时,控制性能无法达到该方案的最优水平。排查故障时先检查输入信号是否持续变化,再检查参数组合,这个顺序基本能解决90%的问题。

6.2 动手前的几个小提醒

写到这里,我还想给正准备复现的朋友几个建议。第一,不要跳过最开始的CFDL直接做FFDL,三种方案虽然代码框架相似,但每种方案对应的系统结构直觉是不同的,逐步推进会让你建立一个清晰的映射关系:什么结构对应什么方案。第二,调参时每次只动一个参数,见过太多人同时改三个参数,最后出了问题根本定位不到原因。第三,把参考信号设计成方波或者带阶跃变化的信号,不要只跑正弦,因为方波能直观暴露控制算法的跟踪能力和超调情况。

另外,这套代码做进一步扩展也很方便。比如你可以在系统函数里加入噪声模型、输入饱和环节或者执行器非线性,MFAC算法代码完全不需要改动,这也算是无模型自适应控制“抗模型变化”的一种验证方式。我在复现后又把三个系统都加上了参数突变,系统方程里的某些系数在运行中突然跳变,三种MFAC方案的输出都能在一定步数内重新收敛,这种自适应能力是传统固定模型控制做不到的。

最后分享一个我个人的实用习惯:仿真结束后,把伪偏导数或伪梯度的变化过程单独存档,然后与系统方程里真正的局部导数对比。这个对照能帮助你对MFAC的数据模型建立很深的直觉——你会直观看到,这个所谓的“无模型”方法,本质上还是在实时地、在线地拟合出一个合理的局部模型。想明白这一点,往后真正到现场做调试,你心里就有底了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询