做控制这么多年,我最怕听到的前一句话是“这个被控对象没法拿模型描述”,后一句话往往是“那你先按经验调PID吧”。MFAC(无模型自适应控制)这个名字第一次出现在我面前时,我下意识觉得又是学术圈包装出来的概念,直到自己把CFDL、PFDL、FFDL三条动态线性化路线用Matlab完整复现了一遍,才发现这套思路确实是控制工程里很值得装进工具箱的东西。这篇博客我就把自己复现MFAC的心路历程、三种动态线性化方法的差异、关键代码实现细节以及调参踩坑经验整理出来,期望给正在啃论文、准备在非线性系统上跑通CFDL、PFDL、FFDL的读者提供一份可以直接参考的实战笔记。
1. “无模型”背后的真正逻辑:不是不建模,而是不建全局模型
1.1 从一次真实的被控对象改造说起
去年我接过一个小型温控改造项目,现场工艺对象是一台带强烈非线性的换热设备,冷水流量和出口温度之间的静态增益会随着负荷变化出现接近三倍的波动。按照传统思路,我应该先做阶跃响应试验、再用ARX或传递函数辨识建模,然后基于模型设计控制器。但现场只给了两天的调试窗口,负荷又不允许大幅激励,辨识出来的模型几乎不具备外推能力。正是这个背景下,我重新翻开了MFAC相关资料。
MFAC的全称是Model Free Adaptive Control,中文通常叫无模型自适应控制。从字面上看“无模型”好像是什么模型都不需要,这其实是个巨大的误解。MFAC真正做的事情,不是放弃模型,而是放弃“全局精确模型”,改用一种在线的、局部等价的线性模型来描述系统当下时刻的动态行为。怎么说呢,就像你开车时并不知道发动机内部成千上万个物理状态变量,你只需要把握“当前踩油门踏板深度变化一点,车速大概会怎么变化”这个在线灵敏度,就可以把车开得很好。MFAC的伪偏导数(Pseudo Partial Derivative,PPD)干的就是这件事——估计这个在线灵敏度。
1.2 动态线性化到底在“线性化”什么
MFAC的适用范围通常是离散时间非线性系统,这类系统可以描述成一个一般形式:
y(k+1) = f(y(k), y(k-1), ..., u(k), u(k-1), ...)
这里f是未知的非线性函数。如果在每个采样时刻,我们不考虑f的全局表达,而只关心输出增量Δy(k+1)=y(k+1)-y(k)与输入增量Δu(k)=u(k)-u(k-1)以及有限历史数据之间的关系,那么在一定前提条件下,可以把f在“当前工作点附近”等价成一个时变的线性增量方程。这就是动态线性化的核心思想。
很多人第一次看论文会头晕,因为侯忠生教授那套理论里的前提条件写得很严谨:系统输出对输入的偏导要存在、系统要满足某种Lipschitz条件等等。落到工程上,这些条件可以粗略翻译成一句人话:输入变化别太剧烈,系统在局部不要出现严重不连续。只要满足这一点,我们就能用一个带时变系数φ(k)的式子近似系统动态。最基础的紧格式动态线性化CFDL形式如下:
Δy(k+1) = φc(k)Δu(k)
这个式子朴素得让人惊讶:它没有去拟合非线性系统的整体行为,而是把当前输入增量到未来输出增量的映射直接用一个“时变增益”φc(k)代替了。φc(k)就是伪偏导数。它在不同工作点会不断变化,把所有模型误差、非线性特征、甚至部分未建模动态都吸收进去。
我复现时最大的感受是:MFAC的学习和自适应不在于去调一个固定模型的参数,而在于让这个在线等价的φ(k)随工作点实时滚动更新。所以它本质上是一种数据驱动的局部建模+局部控制方案,而不是无约束的乱猜控制。
1.3 MFAC和PID有什么区别
控制工程师一定会问:既然PID也不需要被控对象模型,也靠误差反馈在线修正,那MFAC多个啥?这个问题值得单独说。
PID的调节律完全基于当前误差e(k)及其积分、微分,它确实不需要对象模型,但PID的参数本质上是一种固定增益结构,面对强非线性、时变增益对象时,需要靠较大的积分或较保守的增益来兜底。MFAC则不同,它在每个采样周期都做了一件事:先用输入输出数据估计φ(k),再用这个φ(k)去计算控制量。也就是说,控制器在每个时刻都重新估计对象的“局部增益”,可以理解为一种自带在线增益调度功能的自适应PID,只不过这个增益来自实时数据而非人工整定。
用更通俗的比方来说:PID像是一位固定力道的厨师,火候靠经验手动调;MFAC像是一位每道菜下锅前都要快速试一下油温再决定用多大火的厨师。显然,在对象特性变化大、模型又拿不到的场景下,后者的适应能力上限更高。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. CFDL、PFDL、FFDL三套等价窗口:到底在窗口里装了哪些历史信息
2.1 紧格式CFDL:一个伪偏导数单挑全局
CFDL全称Compact Form Dynamic Linearization,中文叫紧格式动态线性化。说它“紧”,是因为它只用了当前这个采样周期的输入增量Δu(k)来描述输出增量Δy(k+1),历史输入、历史输出一概不管。
Δy(k+1) = φc(k)Δu(k)
这个模型的优势太明显了:需要在线估计的参数只有一个φc(k),辨识负担小,占用内存少,编程实现最简单,实时性最高。实际在DSP或单片机上跑起来,一个采样周期内做完估计算子和控制律计算只需要几条浮点指令。
但它的不足也很明显。如果被控对象本身带有较大的纯滞后或高阶惯性,当前输出增量不仅与当前输入增量有关,还与过去几个周期的输入增量密切相关。此时CFDL强迫把所有历史影响都“塞”进单一的φc(k)里,φc(k)就会被迫高频变化,从而出现两个后果:一是控制量抖振,二是伪偏导数估计值波动剧烈,控制器看起来每个时刻都在重新学习系统,效果反而不稳定。
我复现后给CFDL的评价是:适合响应快、滞后小、主要动态能近似为一阶的系统。对于明显存在大滞后或高阶动态的对象,CFDL只能算是一种简化版基线方案。
2.2 偏格式PFDL:把输入历史也纳入窗口
PFDL全称Partial Form Dynamic Linearization,偏格式动态线性化。它把动态线性化的窗口从“只含当前输入增量”扩展到“含最近L个周期的输入增量”。定义:
ΔU_L(k) = [Δu(k), Δu(k-1), ..., Δu(k-L+1)]^T
对应的伪偏导数是长度为L的向量:
φp,L(k) = [φ1(k), φ2(k), ..., φL(k)]^T
那么模型变成:
Δy(k+1) =
