自适应模糊滑模控制器设计与MATLAB仿真
2026/9/20 14:49:54 网站建设 项目流程

简介:面向自动控制与智能控制领域的 MATLAB 自适应模糊滑模控制器(AFSMC)设计代码包,适合研究非线性、参数不确定系统的鲁棒控制问题,也适用于相关课程设计与论文实验。压缩包内含 4 个文件,包括 3 个 m 源码与 1 个 mdl 仿真模型,整体仅 5KB;m 文件分别承担被控对象模型、滑模面切换函数和结果绘图等职责,mdl 文件用于在 Simulink 中搭建完整闭环系统,便于直接运行与观察控制效果。已有 773 人浏览学习。代码覆盖 AFSMC 设计的关键流程:模糊规则库定义、滑模面选取、自适应律在线调整以及控制器输出综合,能帮助读者理解 AFSMC 各设计环节的具体实现。资源体量小、结构精炼,适合作为自适应模糊滑模控制从理论到实现的入门范例,也可在此基础之上扩展自己的控制对象和模糊规则,完成更复杂场景下的控制器设计。

1. 自适应模糊滑模控制器解决的不止是抖振

滑模控制对匹配不确定性天然具有抗扰动能力,但抖振几乎和鲁棒性同时出现;为了压抖振,传统做法是引入边界层,可边界层厚度又依赖不确定性上界,这个上界往往比不确定性本身还难估计。自适应模糊滑模控制器的处理方式,是把“没建模的动态”交给模糊逻辑在线逼近,用自适应律持续修正模糊规则后件,滑模切换项只负责吸收残差。这样既保住了滑模面的抗扰动骨架,又不必依赖一个保守的静态上界。它适合机械臂轨迹跟踪、电机调速、飞行器姿态控制这类非线性强、参数会漂移的快速回路。配合 MATLAB/Simulink,从公式到仿真曲线能快速闭环。本文按该领域最常用的标准结构展开:二阶仿射系统 + 高斯模糊基函数 + Lyapunov 直接法导出的自适应更新律,读者改被控对象即可复用整个控制框架。

2. 滑模面的构建与抖振从哪里来

2.1 二阶仿射系统的滑模动态方程

机械臂、轮式移动机器人、电机驱动模型经过整理,通常能写成如下二阶仿射非线性系统:

ẍ = f(x, ẋ) + g(x, ẋ)·u + d(t)

其中 f 代表模型内部动态,g 是控制增益,轨迹跟踪要求 g 非奇异,d(t) 是外部扰动。后续为简化推导,按常见做法先取 g = 1;g = ĝ + Δg 的情形可以把偏差吸收进不确定性项里,处理方式不变。

定义跟踪误差 e = x − x_d,取滑模面:

s = ė + λe, λ > 0

当 s 收敛到 0,系统降阶为一阶动态 ė + λe = 0,跟踪误差按 exp(−λt) 指数衰减。控制目标从“让 x 跟上 x_d”转换为“把 s 驱赶到 0 并保持”。对 s 求导并代入系统方程:

ṡ = f(x, ẋ) + u + d(t) − ẍ_d + λė

暂不考虑扰动且 f 已知时,令 ṡ = 0 可解出等效控制:

u_eq = −f + ẍ_d − λė

实际中 f 不准确、扰动存在,工程上在 u_eq 后叠加鲁棒项,标准形式为:

u = u_eq − h·sign(s)

代入后得到 ṡ = d(t) − h·sign(s),只要切换增益 h > |d(t)|,立刻有 s·ṡ < 0,这是最基本的滑模到达条件。鲁棒性自此建立,但 sign(s) 的高频切换也把抖振问题带出来了。

2.2 sign、sat 与幂次趋近律——三种切换函数对比

抖振的本质是:控制量在滑模面两侧每个控制周期内发生极性翻转。解抖振的常见手段有三类:饱和函数 sat(s, φ)、幂次趋近律、以及高阶滑模。三者对比在下表列出。

切换形式典型表达式优点与代价适用范围
sign(s)sign(s)到达速度最快,但高频切换必然抖振理论分析、抖振边界验证
sat(s, φ)|s|<φ 时取 s/φ,否则 sign(s)消除抖振,却带来稳态跟踪误差工程中最常用的折衷方案
幂次趋近律k·|s|^α·sign(s),0<α<1接近滑模面时切换幅度变小,α 对收敛速度影响明显兼顾到达速度与抖振抑制

看不直观的,直接跑一段 MATLAB 对比脚本,调整 φ 和 α 观察曲线形态:

% 切换函数对比:sign / sat / 幂次趋近 s = -1:0.001:1; phi = 0.1; alpha = 0.6; y_sign = sign(s); y_sat = min(1, max(-1, s / phi)); y_pow = s .* abs(s).^(alpha - 1); figure; plot(s, y_sign, 'k-', s, y_sat, 'b--', s, y_pow, 'r-.', 'LineWidth', 2); grid on; axis([-1 1 -1.2 1.2]); legend('sign(s)', 'sat(s,\phi)', '|s|^\alpha sgn(s)');

说明:min(1, max(-1, s/phi))是 sat 的向量化写法,不需要 for 循环逐点判断;幂次趋近表达式本身含符号特性,0<α<1 时可保证有限时间到达,但 α 过小后,s 接近零时切换项斜率趋向无穷,与 sign 的差别变小。运行后能直观看到三类控制的过渡特性:sign 在零点形成竖直直线,sat 在 ±φ 内线性过渡,幂次趋近介于两者之间。

2.3 边界层的代价与切换增益的上界假设

把 sign 换成 sat(s, φ) 后,边界层内控制量为连续变量,执行器不再频繁换向,抖振明显下降,但代价必须算清楚。边界层 |s| ≤ φ 内,控制信号近似为 u = u_eq − h·s/φ,代入 ṡ 表达式,扰动上界为 d̄ 时,稳态边界约为 |s| ≤ φ·d̄/h。h 越大、φ 越小,稳态误差越小;可是 h 变大意味着边界层外的切换幅度变大,φ 留小了执行器又开始抖。

φ 本质上是“鲁棒性换平稳性”的折衷旋钮,它的合理取值依赖 d̄ 的上界。而实际工程里,机械臂负载变化、摩擦系数漂移、电机绕组温度导致增益变化,这些上界很难静态估计——这正是自适应模糊滑模控制器进入的切入点:让原先需要工程师拍脑门估计的未知动态由模糊系统在线学习,把切换增益 h 的职责缩小到吸收“逼近残差 + 扰动”。

3. 模糊规则库与自适应律的设计

3.1 模糊系统为什么能在线逼近模型不确定性

模糊逻辑系统被广泛用作万能逼近器,即对紧集上的连续函数 f(x, ẋ),理论上存在一组规则后件参数,使模糊输出 f̂ 以任意精度逼近 f。工程上更关心的是它和神经网络比有哪些实际优势:结构透明、参数只有规则后件权重、不确定性被限定在固定模糊集划分内,且基函数可直接计算、可导,非常适合插进 Lyapunov 分析里。

选用高斯隶属度函数有两个原因:可导,适应自适应律对参数连续更新的要求;局部性,某条规则只影响其附近区间,参数耦合弱。每个输入取三个模糊集 N/Z/P 是文献中最常见的折衷:五个或七个模糊集逼近精度更高,但规则参数成平方增长,在线更新更容易过拟合;3×3 = 9 条规则通常足以抓住主导非线性。

3.2 3×3 模糊规则库的搭建与基函数计算

基函数由高斯隶属度函数和归一化分母构成:

μᵢ(x) = exp(−(x − cᵢ)² / (2σ²)) ξₖ(x, ẋ) = μᵢ(x)·μⱼ(ẋ) / ΣₚΣᵣ μₚ(x)·μᵣ(ẋ)

其中 cᵢ 是高斯函数中心,σ 是宽度,归一化保证所有 ξₖ 之和为 1。模糊输出可写作:

f̂(x, ẋ) = θᵀ·ξ

把这个计算封装成函数,保存为 fuzzy_basis.m:

function xi = fuzzy_basis(x1, x2, c1, c2, sigma) % 计算归一化模糊基函数向量 % 输入: x1 = x, x2 = x_dot % c1, c2: 两个输入的高斯隶属函数中心, 长度均为3 % 输出: xi, 9x1 列向量 (3x3条规则的归一化基函数) mu1 = exp(-((x1 - c1).^2) ./ (2 * sigma^2)); mu2 = exp(-((x2 - c2).^2) ./ (2 * sigma^2)); prodMF = mu1.' * mu2; % 3x3, 每条规则的前件隶属度 den = sum(prodMF, 'all'); % 归一化分母 xi = prodMF(:) / (den + eps); % 加 eps 避免除零 end
  • mu1是 x 落在不同模糊集的隶属度,结果 1×3;
  • mu1.' * mu2得到 3×3 规则强度矩阵,第一行第二列对应“x 属于 N 且 ẋ 属于 Z”这条规则;
  • prodMF(:)把矩阵按列拉平成 9×1,归一化后就是基函数向量 ξ。

规则库本身的逻辑由下表描述,θ₁ 到 θ₉ 是自适应律要学习的后件参数。

规则编号x 的模糊集ẋ 的模糊集可调参数
1NNθ₁
2NZθ₂
3NPθ₃
4ZNθ₄
5ZZθ₅
6ZPθ₆
7PNθ₇
8PZθ₈
9PPθ₉

强调一点:这不是传统意义上一套写死的经验推理规则。θ 初始全部为 0,也就是说没有初始规则可用;自适应律用每个时刻的滑模面 s 和基函数 ξ 在线修改 θ,规则是“长”出来的。这与“给一套专家规则然后查表输出”的常见模糊控制有本质区别。

3.3 用 Lyapunov 直接法推出自适应律 θ̇ = η·s·ξ

把模糊逼近 F̂ = θ̂ᵀξ 代入控制律:

u = −f̂ + ẍ_d − λė − h·sat(s/φ)

代入 ṡ 的推导结果得到:

ṡ = (f − f̂) + d − h·sat(s/φ) = θ̃ᵀ·ξ + ε + d − h·sat(s/φ)

其中 θ̃ = θ∗ − θ̂ 为参数误差,ε 是模糊系统的最优逼近误差。取 Lyapunov 函数:

V = 0.5s² + θ̃ᵀθ̃ / (2η)

对时间求导,展开后:

V̇ = s·θ̃ᵀξ + s·ε + s·d − h·s·sat(s/φ) − θ̃ᵀθ̂̇ / η

此时取自适应律:

θ̂̇ = η·s·ξ

代入后 θ̃ 相关两项正负相消,得到:

V̇ = s·ε + s·d − h·s·sat(s/φ)

只要 h 大于 ε 的上界与扰动 d 上界之和,V̇ ≤ 0 就有保证,系统状态将进入滑模面邻域稳定。推导中最关键的一点是:为什么自适应律偏偏取 ηsξ?因为它能让含 θ̃ 的项在 V̇ 中完全消失。如果读者自己改成别的更新律,Lyapunov 导数里会出现无法处理的交叉项,参数收敛性就无法保证。

3.4 保留鲁棒项 h·sat 的原因

有人会问:模糊逼近都做出来了,滑模切换项能不能去掉?不能。模糊系统逼近的是 f,而 ε + d 始终未被建模;h·sat 吸收的正是这部分残差。去掉它,系统就退化成开环补偿器,滑模面的抗扰动能力荡然无存。这一结构和“模糊滑模控制”类文献里“用模糊规则直接输出控制量”的做法不同:本文的滑模面是骨架,模糊自适应只是把 f 的估计误差从鲁棒项里匀掉一部分,从而降低抖振时对 h 的依赖。

4. MATLAB 下自适应模糊滑模控制器的完整仿真

4.1 可复现的被控对象模型与参数表

为了能让读者直接对照,取一个带未知非线性、阻尼和外部扰动的二阶系统:

ẍ = −a·sin(x) − b·ẋ + u + d·sin(2t)

控制器侧只看到 x 和 ẋ,完全不知道 a、b、d 的具体数值。参考轨迹取 x_d = 0.5·sin(t),初始状态偏移到 0.2,目的是让控制器在初始时刻就要纠正误差,便于观察自适应过程。

参数符号取值控制器是否已知
非线性系数a9.8未知
阻尼系数b1.0未知
扰动幅值d0.5未知
滑模面系数λ3.0设计值
鲁棒增益h2.0设计值
边界层厚度φ0.02设计值
自适应学习率η0.6设计值
高斯函数宽度σ0.4设计值

h 初值取 2.0,一是要覆盖扰动上界 0.5,二是给模糊系统的逼近残差留余量。模糊系统两个输入的隶属函数中心均取 −0.8、0、0.8,覆盖工作区间 ±1。

4.2 完整仿真主程序

主程序存为 adaptive_fuzzy_smc.m,与 fuzzy_basis.m 放在同一目录:

% 自适应模糊滑模控制器仿真 % 被控对象: x'' = -a*sin(x) - b*x' + u + d*sin(2t) clear; clc; close all; % ------- 被控对象参数(控制器不可见)------- pa.a = 9.8; pa.b = 1.0; pa.d = 0.5; % ------- 控制器参数 ------- lambda = 3.0; % 滑模面斜率 h = 2.0; % 鲁棒切换增益 phi = 0.02; % 边界层厚度 eta = 0.6; % 自适应学习率 % ------- 模糊系统 ------- c1 = [-0.8 0 0.8]; % x 的高斯隶属函数中心 c2 = [-0.8 0 0.8]; % x_dot 的高斯隶属函数中心 sig = 0.4; theta = zeros(9, 1); % 9条规则后件权重 % ------- 仿真参数 ------- dt = 1e-3; t = 0:dt:10; x = [0.2; 0]; % 初始状态 [x; x_dot] u_rec = zeros(size(t)); e_rec = zeros(size(t)); s_rec = zeros(size(t)); theta_rec = zeros(9, length(t)); for k = 1:length(t) tk = t(k); % 参考轨迹及其导数 xd = 0.5*sin(tk); dxd = 0.5*cos(tk); ddxd = -0.5*sin(tk); % 误差与滑模面 e = x(1) - xd; de = x(2) - dxd; s = de + lambda*e; % 模糊基函数 xi = fuzzy_basis(x(1), x(2), c1, c2, sig); % 自适应律:theta_dot = eta * s * xi,用欧拉法离散 theta = theta + eta * s * xi * dt; % 控制量 f_hat = xi.' * theta; u = -f_hat + ddxd - lambda*de - h * sat(s, phi); % RK4 积分被控对象 k1 = plant_rhs(x, u, tk, pa); k2 = plant_rhs(x + 0.5*dt*k1, u, tk + 0.5*dt, pa); k3 = plant_rhs(x + 0.5*dt*k2, u, tk + 0.5*dt, pa); k4 = plant_rhs(x + dt*k3, u, tk + dt, pa); x = x + (dt/6) * (k1 + 2*k2 + 2*k3 + k4); % 记录数据 u_rec(k) = u; e_rec(k) = e; s_rec(k) = s; theta_rec(:,k) = theta; end % ------- 绘图 ------- figure(1); subplot(3,1,1); plot(t, e_rec, 'LineWidth', 1.2); ylabel('跟踪误差 e'); grid on; subplot(3,1,2); plot(t, s_rec, 'LineWidth', 1.2); ylabel('滑模面 s'); grid on; subplot(3,1,3); plot(t, u_rec, 'LineWidth', 1.2); ylabel('控制量 u'); xlabel('时间/s'); grid on; % ------- 稳态指标 ------- idx = t > 5; fprintf('RMS(e) = %.4g rad\n', sqrt(mean(e_rec(idx).^2))); fprintf('max|s| = %.4g\n', max(abs(s_rec(idx)))); fprintf('max|u| = %.4g\n', max(abs(u_rec(idx)))); fprintf('max(dtheta) = %.4g\n', max(abs(theta_rec(:,idx) - theta_rec(:,1)), [], 'all')); % ------- 局部函数 ------- function dxdt = plant_rhs(x, u, t, pa) dxdt = [x(2); -pa.a*sin(x(1)) - pa.b*x(2) + u + pa.d*sin(2*t)]; end function y = sat(s, phi) y = min(1, max(-1, s / phi)); end

代码说明:

  • 控制器在每个采样时刻先算滑模面 s,再调 fuzzy_basis 得基函数,随后按自适应律 θ = θ + η·s·ξ·dt 更新规则后件;
  • 控制量由三项组成:负模糊补偿 −f̂、参考前馈与滑模趋近项 −λė、鲁棒边界层项 −h·sat(s/φ)。其中 λė 项是等效控制的一部分,不能省;
  • 被控对象积分采用 RK4,比欧拉法在高频扰动 d·sin(2t) 下更稳,步长 1e-3 已经足够;
  • 脚本中satmin/max向量化实现,与符号函数相比在边界层内是连续过渡,这是去抖振的关键。

预期仿真结果:前 1~2 秒内跟踪误差因未知动态而较大,θ 从零开始积累后,f̂ 逐渐逼近真实 f;约 3 秒后误差进入稳态,滑模面 s 大致落在 ±0.02 的边界层带内,控制量曲线无高频振荡。典型数量级如下表,读者在本地运行会有微小差异,但量级应一致。

指标稳态典型值
RMS 跟踪误差10⁻³ ~ 10⁻² rad
滑模面 max|s|约 0.03 以内
控制量峰值< 8
控制量抖振幅值无明显 PWM 级振荡

4.3 Simulink 搭建时的模块划分

不用脚本也可以搭 Simulink 模型。模块布局按信号流划分为五块:

  1. 参考轨迹生成:用 Sin 模块加 Derivative 得到 xd、ẋd、ẍd;
  2. 滑模面构造:Sum 模块计算 e 和 ė,Gain 模块实现 λ,再相加;
  3. 模糊自适应部分:MATLAB Function 模块内嵌 fuzzy_basis 和 θ 更新逻辑,θ 用 Memory 模块做一步延迟反馈;
  4. 控制律计算:Sum 模块合成 u 的四个分量;
  5. 被控对象:用两个 Integrator 串联构造二阶系统,或直接写 S-Function。

仿真步长选固定步长 1e-3 s,求解器设 ode4(RK4),与脚本一致。模糊自适应部分不宜用变步长,否则 θ 更新时点不固定,自适应曲线不好对比。

5. 调参与看曲线——几个接近工程实践的技巧

5.1 参数改动不能按直觉从 φ 开始

很多初学者上来就调边界层 φ,结果误差变大就怀疑算法错了。合理顺序是:先定 λ,再定 h 和 φ 的初始值,然后调 η,最后才动隶属函数宽度。λ 决定滑模面主导的收敛速度,一般按期望误差收敛时间 τ ≈ 1/λ 选,λ 太大容易放大测量噪声;h 先取“扰动上界的 2 到 4 倍”做一个保守估计,φ 从 0.02 起步;η 从 0.2 到 1.0 之间试,观察 θ 是否振荡。隶属函数宽度 σ 影响很小,只有模糊逼近始终粗糙时才处理。

5.2 用三条曲线和一个指标判断收敛

仿真后不需要盯着误差曲线反复看,直接查三条曲线:e 是否进入稳态带、s 是否持续落在 ±φ 内、u 是否高频振荡。θ 曲线可以叠加 9 条权重一起画,判断自适应是否收敛更可靠。一段实用判断代码:

idx = t > 5; dtheta = max(abs(diff(theta_rec(:, idx), 1, 2)), [], 'all'); if dtheta < 1e-4 disp('theta 已进入慢变区,自适应基本收敛'); else disp('theta 仍持续快速变化,请检查激励或调小 eta'); end

如果 theta 持续震荡,优先减小 η,而不是加大 φ。η 过大时自适应律每个步长修正量太大,θ 会在真实值附近来回跳,模糊输出 f̂ 带上了高频噪声,最终仍反映成 u 的毛刺。

5.3 参考轨迹要有激励强度,否则 θ 不唯一

正弦参考 x_d = 0.5·sin(t) 基本能激励出系统动态,但若现场应用时参考是常值或缓慢斜坡,θ 就不会充分收敛——因为系统只在狭窄区间内运动,模糊基函数大部分区域无激励,那些区域的 θ 停在上次更新的随机位置。输出跟踪可能仍然不错,但切换一个工作点后误差会突然变大。对策是验证时叠加两个频率的正弦:

x_d = 0.5*sin(1.0*t) + 0.1*sin(3.5*t)

双频参考把速度变化和加速度变化都铺开,模糊逼近对 x 和 ẋ 两个输入都有覆盖,θ 更容易收敛到稳定的近似解。

改任何参数之后,第一步都去看 s 曲线是否始终落在 ±φ 之内——如果滑模面收敛不了,要么 h 不足,要么自适应更新方向或符号有误,其他曲线再漂亮也没有意义。

本文还有配套的精品资源,点击获取

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

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

立即咨询