ARTICLE DETAIL

资讯详情

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

基于Simulink的滑模控制仿真建模与S-Function实现

基于Simulink的滑模控制仿真建模与S-Function实现 先说明一下这篇是我基于“基于Simulink的滑模控制算法仿真建模示例”这个标题结合实际做控制仿真的一线经验整理出来的内容。不整那些虚的直接聊怎么做以及踩过哪些坑。搞控制的人应该都听过滑模控制Sliding Mode Control, SMC这个名字。鲁棒性好、响应快、对参数摄动和外部扰动不敏感这些都是它的招牌优点。但很多人第一次接触它是在论文里真正想在 Simulink 里把一个能跑的滑模控制模型搭出来却往往会卡在几个点上滑模面怎么取、趋近律怎么设计、符号函数带来的抖振怎么处理、S-Function 怎么写才不报错。这篇文章就是围绕“基于Simulink的滑模控制算法仿真建模示例”这一个需求带你走一遍从控制律推导到 Simulink 模型跑通的完整过程。我把被控对象、控制器设计、模型搭建、参数调试还有常见的坑全部拆开讲清楚。适合控制方向的学生、刚入门做算法验证的工程师以及想快速搭一个 SMC 仿真模板的人参考。1. 这个示例到底解决什么问题1.1 为什么拿滑模控制当例子滑模控制是变结构控制里最有代表性的一种。它的核心思想特别直白设计一个滑模面让系统状态先被“吸”到这个面上然后沿着这个面滑向平衡点。一旦系统进入滑模运动对外界的扰动和模型的不确定性就“不敏感”了——这是在设计阶段就写进控制律里的性质不需要精确知道扰动是多少。这个特性在仿真里非常直观。你可以在被控对象端加上一个时变扰动然后对比一下无扰动和有扰动两种情况下的跟踪效果。你会发现只要扰动有界且控制器参数满足设计条件跟踪误差几乎不受影响。这种“看得见的鲁棒性”是做仿真教学和算法验证的最佳素材。放到 Simulink 这个环境里滑模控制又非常适合用来演示几个关键的建模技巧非线性环节符号函数的建模、基于 S-Function 的自定义控制律、变步长和固定步长对仿真结果的影响。所以说滑模控制不只是一个控制算法它本身也是一个串联起 Simulink 各项核心功能的好载体。1.2 适合谁看看完能得到什么这篇文章主要面向三类人第一类是正在做课程设计或者毕业设计的学生。需要快速理解滑模控制原理并且在 Simulink 里搭出一个能跑、能出图、能放到论文里的模型。这篇文章会给出可以直接复现的建模步骤和参数。第二类是做算法验证的工程师。可能你实际控制对象是电机、机械臂或者无人车现在想先把滑模控制器的性能在仿真环境里验证一下再决定要不要移植到实车上。这里讲的 S-Function 写法、参数调试方法能帮你省掉很多试错时间。第三类是对 Simulink 建模有兴趣想从“拖模块”进阶到“写程序”的人。滑模控制器如果用纯模块拖拽会非常乱用 S-Function 就清爽得多。这个过程能帮你理解 Simulink 仿真的底层机制状态、导数、输出是怎么循环调用的。看完之后你应该能独立搭出一个完整的二阶系统滑模控制仿真模型知道滑模面参数、趋近律参数怎么调节遇到抖动过大、仿真发散、代数环报警这些问题也知道去哪里排查。如果你后面想扩展还可以在这个基础上改造成自适应滑模、模糊滑模或者连接 Carsim、Amesim 做联合仿真底子是通用的。2. 滑模控制设计思路拆解2.1 从控制目标到滑模面的映射先说被控对象我选了一个最常见的二阶系统作为示例[ \ddot{x} a\dot{x} b u d(t) ]其中x是位置u是控制输入d(t)是外部扰动。实际物理系统里很多对象都可以简化成这个形式比如一个质量块在力作用下的运动或者一个直流电机驱动下的位置系统。控制目标很简单让状态x跟踪上期望轨迹x_d。定义跟踪误差为[ e x_d - x ]滑模控制的第一步是设计滑模面。最常用的线性滑模面为[ s \dot{e} c e ]其中c 0它决定了滑模面上误差收敛的速度。这句话值得停下来想一想当系统进入滑模运动后也就是s 0那么\dot{e} -c e这是一阶线性微分方程解出来e(t) e(0)e^{-ct}。也就是说误差会以指数速度衰减衰减快慢完全由c决定。c越大收敛越快但代价是控制量更大、更容易激发未建模动态。这个映射关系是整个设计的灵魂。滑模面其实不是一个“面”它就是误差空间里的一条路径。控制器的任务只有一个把系统状态强行推到这条路径上然后按住不放。2.2 等效控制加切换控制滑模控制律的经典结构分为两部分[ u u_{eq} u_{sw} ]u_eq叫等效控制它的作用是当系统已经位于滑模面上时用这个控制量维持系统在滑模面上运动。u_sw叫切换控制它的作用是在系统偏离滑模面时施加一个强力的“纠正”作用把状态拉回滑模面。设计u_eq的方法是令\dot{s} 0。对s \dot{e} c e求导得到[ \dot{s} \ddot{e} c\dot{e} (\ddot{x}_d - \ddot{x}) c\dot{e} ]代入系统方程\ddot{x} a\dot{x} bu d忽略扰动d并且令\dot{s} 0可以解出[ u_{eq} \frac{1}{b}(\ddot{x}_d - a\dot{x} - c\dot{e}) ]注意u_eq里面没有包含切换项它本身是连续函数可以看作是对系统模型的“前馈补偿”。切换控制u_sw的最简单形式是[ u_{sw} \eta \cdot \text{sgn}(s) ]其中\eta 0sgn是符号函数。这样总的控制律为[ u \frac{1}{b}(\ddot{x}_d - a\dot{x} - c\dot{e}) \eta \cdot \text{sgn}(s) ]这个控制律的物理意义很清楚如果s 0说明误差在增大或收敛不够快就施加一个负方向的切换力如果s 0则施加一个正方向的切换力。通过不停地切换把系统状态束缚在滑模面附近。2.3 稳定性证明与参数取值范围如果你是做学术研究稳定性证明是必须写进论文里的。这里给一个标准推导后面建模仿真也用得上。定义李雅普诺夫函数[ V \frac{1}{2}s^2 ]对时间求导[ \dot{V} s\dot{s} s(\ddot{e} c\dot{e}) ]把前面的推导代入并且计入扰动d可以得到[ \dot{V} s(d - b\eta \cdot \text{sgn}(s)) ds - b\eta |s| ]如果扰动有界即|d| \le D那么只要选择\eta满足[ b\eta D ]就有[ \dot{V} \le D|s| - b\eta |s| -(b\eta - D)|s| 0 ]这就证明了系统能够在有限时间内到达滑模面并保持在滑模面上。\eta的下限由扰动上界D决定这是参数选择最重要的依据。实际调试中\eta如果选得只比D/b大一点点系统虽然稳定但到达滑模面的速度很慢如果选得太大抖振会非常明显仿真步长稍大甚至会发散。所以\eta不是一个随便拍脑袋定的值它是需要根据扰动幅度实测来反复试的。3. Simulink 建模全过程实录3.1 建模方式选型纯模块拖拽还是 S-Function在 Simulink 里实现滑模控制器有两条路线可以选择。第一条是纯模块拖拽从 Simulink 库里面拉 Sum、Gain、Sign、Saturation、Integrator 这些模块拼出控制器。这种方式的优点是完全图形化看起来直观缺点是模型一旦复杂起来线多、模块多整个画面乱成一团。而且模块拖拽这种方式控制器参数写死在 Gain 模块里想批量调节很麻烦得一个模块一个模块去改。第二条是用 S-Function 或者 MATLAB Function Block 写控制律。这种方式把整个控制器封装成一个自定义模块内部逻辑用 MATLAB 或者 C 语言实现外部只暴露必要的输入输出端口。这样模型又干净又标准参数可以集中管理。对于一个滑模控制器来说控制律其实就几行数学表达式用 S-Function 写再合适不过。我个人的建议是如果你的目标是做学术验证或者后续要改控制律做对比实验强烈建议直接用 S-Function。如果你只是临时搭一个演示模型想快速看效果可以用纯模块拖拽。但两种方式都值得会因为你后面读别人源码的时候两种风格的模型都会遇到。下面我会以 S-Function 为主线因为它的复用性更强也更接近工程中的代码实现。3.2 被控对象模型搭建先搭被控对象这是最简单也最标准的部分。打开 Simulink新建一个空白模型命名为smc_demo.slx。被控对象是二阶系统\ddot{x} a\dot{x} b u d(t)用积分器链来搭。具体步骤是拖入两个 Integrator一个输出\dot{x}一个输出x。在第二个积分器也就是x后面加一个 Gain增益设为a输出作为反馈接到\dot{x}的导数项。控制量u经过 Gain增益为b。扰动d(t)用一个 Signal Builder 或者 Sine Wave 模块生成叠加到控制通道上。把这三路信号加总连接第一个 Integrator 的输入端。这样被控对象就搭好了。有一个细节a和b这两个参数不要直接填数字建议在模型初始化回调里用a -2; b 3;定义或者在 MATLAB 工作区里先运行一遍赋值脚本。这样后面调参数不用打开模型改直接改脚本重新跑即可非常方便。初始状态也要设置一下。双击两个 Integrator在 Initial condition 里分别设成x(0) 0、\dot{x}(0) 0。如果你想让仿真一开始就能看到误差的收敛过程可以考虑设置初始位置不为零比如x(0) 1这样一开始就有大的跟踪误差控制器需要花一段时间把误差压下去这个过程的曲线放在论文里更“好看”。3.3 控制器子系统的搭建被控对象搭好后控制器我建议用一个 S-Function 实现。整个控制器需要哪些输入期望位置x_d、期望速度\dot{x}_d、期望加速度\ddot{x}_d以及实际位置x和实际速度\dot{x}。这五个信号合在一起用一个 Mux 打包成输入向量传给 S-Function。这里很容易踩一个坑很多初学者会把期望加速度\ddot{x}_d忽略掉直接在控制器里用微分模块对x_d求导得到。但 Simulink 的 Derivative 模块数值求导会放大噪声仿真步长一变结果就飘这是经典的坑。我的建议是期望轨迹直接在外部生成位置、速度、加速度三路信号都用数学表达式计算好。如果你期望轨迹是正弦函数那就分别对正弦求导得到余弦和负正弦直接作为信号源输给控制器。这样既干净又稳定。S-Function 的 MATLAB 版代码如下你可以直接复制保存为smc_sfun.mfunction [sys,x0,str,ts] smc_sfun(t,x,u,flag) % 基于二阶系统的滑模控制器S-Function % 输入u [xd; xd_dot; xd_ddot; x; x_dot] switch flag case 0 [sys,x0,str,ts] mdlInitializeSizes; case 3 sys mdlOutputs(t,x,u); case {1,2,4,9} sys []; otherwise error([Unhandled flag ,num2str(flag)]); end function [sys,x0,str,ts] mdlInitializeSizes sizes simsizes; sizes.NumContStates 0; sizes.NumDiscStates 0; sizes.NumOutputs 1; sizes.NumInputs 5; sizes.DirFeedthrough 1; % 关键输出直接依赖输入 sizes.NumSampleTimes 1; sys simsizes(sizes); x0 []; str []; ts [0 0]; function sys mdlOutputs(t,x,u) % 解析输入 xd u(1); xd_dot u(2); xd_ddot u(3); x u(4); x_dot u(5); % 系统参数与工作区保持一致 a -2; b 3; % 误差 e xd - x; e_dot xd_dot - x_dot; % 滑模面: s edot c*e c 5; s e_dot c * e; % 等效控制 u_eq (xd_ddot - a*x_dot - c*e_dot) / b; % 切换控制 eta 0.5; u_sw eta * sign(s); sys u_eq u_sw;这段代码里有几个关键信息需要强调。DirFeedthrough是 S-Function 里最容易被忽略的一个属性。它表示输出是否直接依赖输入。由于我们的控制律公式里有x_dot、e_dot这些输入直接参与运算所以DirFeedthrough必须设为1。如果设置成0Simulink 会认为输出不依赖输入在排序求解阶段就可能出现代数环或者直接报错。ts [0 0]表示连续采样。滑模控制本质是连续时间系统必须用连续采样时间否则策略的实时性会受影响仿真结果也会产生额外的离散误差。为什么用 Level-2 M-File S-Function 更推荐上面的 Level-1 写法在旧版本 MATLAB 里还能用但 R2017b 之后官方推荐用 Level-2。Level-2 的接口更清晰支持直接定义输入输出端口名称还支持代码生成。如果你的 MATLAB 版本比较新建议直接改用matlab.System类或者 Level-2 S-Function 模板。但不管哪种写法核心的控制律数学是一样的。3.4 整体模型连接与仿真参数配置控制器和被控对象都准备好了接下来就是连线组成闭环。闭环结构如下期望轨迹生成模块输出三路信号x_d、\dot{x}_d、\ddot{x}_d与实际位置x和实际速度\dot{x}一起五个信号进入 S-Function。S-Function 输出u送入被控对象的u输入端。在模型里你需要加几个 Scope 或 To Workspace 模块把e、u、s这几路信号记录下来。观察误差、控制量和滑模面是调试时最重要的三个信号。滑模面收敛到零的过程能直观地说明到达阶段的情况误差曲线说明跟踪性能控制量曲线能看出抖振有多严重。仿真参数设置方面有几个点一定要处理求解器选择ode45或者ode4如果你的 MATLAB 版本默认是变步长建议改为固定步长仿真步长设定为0.001秒。仿真时间设为10秒足够让系统进入稳态并展示抗扰性能。这里多说一句为什么建议固定步长。滑模控制里面有符号函数sign(s)这是不连续的非线性环节。变步长求解器在检测到这种不连续时会自动缩小步长直到满足误差容限。结果就是仿真速度变得极慢而且在不同步长下结果漂移很大用起来很痛苦。固定步长虽然精度略低但仿真速度快结果稳定可复现对于算法验证来说完全够用。等你后面做代码生成实时部署的时候固定步长也是必然的选择。3.5 期望轨迹与扰动设计期望轨迹我这里给两个典型配置覆盖两种常见场景。第一个是阶跃跟踪。期望位置x_d用 Step 模块初始值为 0终值为 1跳变时间设在 0 秒或者 0.1 秒。这个场景用来验证系统的跟踪能力和稳态精度。由于滑模控制在阶跃响应下会有很明显的到达阶段和滑模阶段放在论文里特别直观。第二个是正弦跟踪。期望轨迹为x_d sin(t)位置信号用一个 Sine Wave 模块频率设为1 rad/s幅度设为 1速度信号为cos(t)在另一个 Sine Wave 模块里设置相位为pi/2即可加速度为-sin(t)相位设为pi。这样三路信号都是标准正弦波方便对比跟踪相位延迟。扰动d(t)我也建议叠加一个正弦扰动幅度取 0.5频率取 2 rad/s。这样在仿真中段可以看到滑模控制器把扰动抑制掉的效果。为了让对比更明显可以设置成 3 秒后扰动才出现用 Step 模块和 Sine Wave 相乘实现简单又直观。4. 参数调试与抖振抑制4.1 调参顺序和判断标准模型搭好之后第一次仿真跑出来大概率不是理想效果。别急着调参数先明确调参的逻辑。滑模控制器参数主要有三个滑模面系数c、切换增益eta、以及如果用了边界层方案还有一个边界层厚度phi。我的调试顺序是先定c再调eta最后处理抖振。c决定了误差收敛速度也决定了滑模面附近系统的等效带宽。c太小误差收敛慢跟踪大信号时相位滞后严重c太大控制量峰值很高同时高频噪声会被放大。从实际经验看c设置在系统开环穿越频率的 3 到 5 倍比较合适。对于一个开环带宽在 1 rad/s 左右的二阶对象c取 5 到 10 是一个合理区间。eta决定了切换控制的强度它的下限由扰动上界决定。如果仿真中扰动幅度为 0.5b3那eta至少要大于 0.17否则系统无法克服扰动稳态误差不为零。实际调试中我会先把eta调到 0.5看效果如果到达阶段太慢再往上加。判断调试是否成功的标准有两个第一误差曲线能否收敛到接近零的稳态值第二滑模面s是否快速收敛到零并在零附近维持。如果s长期不归零说明控制器设计有误或者输入输出连线错误这时候先不要调参数回头查模型。4.2 抖振产生的机理和三种抑制方案抖振是滑模控制最出名也最头疼的问题。它的原理其实很清楚理想滑模控制要求控制量在滑模面两侧无限频繁地切换但在实际数字仿真中切换频率受仿真步长限制不可能无限高。于是系统状态不会严格停留在滑模面上而是在滑模面附近来回穿越表现为高频小幅振荡。这个振荡会通过控制量传播到执行机构在仿真里看就是控制量剧烈跳动。解决抖振的思路是把不连续的切换变成连续的饱和逼近。最常用、最简单、实测效果也最稳定的一种方案是用sat函数替代sign函数[ u_{sw} \eta \cdot \text{sat}(s/\phi) ]其中\phi 0是边界层厚度。当|s| \phi时饱和函数输出s/\phi这时候控制量是连续线性变化的当|s| \ge \phi时输出为\pm 1等价于原切换控制。你可以在 Simulink 里直接用 Saturation 模块或者直接在 S-Function 里写phi 0.05; u_sw eta * min(max(s/phi, -1), 1);这个方案的好处是只改一行代码抖振立刻消失。代价是当系统状态在边界层内运动时控制不再是理想滑模稳态误差会略增大。phi越小越接近理想切换抖振越大phi越大越平滑但是跟踪精度损失越大。实测下来phi取 0.01 到 0.1 之间比较合理具体要看你的误差允许范围。第二种方案是改用指数趋近律。它的思路是让滑模面的导数满足更精细的方程在远离滑模面时快速趋近接近滑模面时平滑过渡[ \dot{s} -\varepsilon \cdot \text{sign}(s) - k s ]其中\varepsilon 0k 0。相比直接切换这一项-ks起到比例趋近的作用作用是在接近滑模面时让切换力度线性衰减从而减弱抖振。这种方案在理论上有更好的趋近品质但实现时仍然包含sign项因此不会完全消除抖振。第三种方案是使用高阶滑模结构或者更进一步的超螺旋滑模Super-Twisting。超螺旋算法的好处是控制量是连续的理论上可以完全消除一阶抖振但代价是实现复杂、参数更多调参难度高适合有一定基础之后再去尝试。第一次做滑模仿真先用sat边界层方案把流程跑通才是性价比最高的路径。4.3 仿真步长与求解器设置前面提过一次固定步长和变步长的问题这里再往深里说一下因为这是仿真结果能不能复现的关键。滑模控制器包含符号函数它是严格不连续的。如果用变步长求解器比如默认的ode45求解器会在符号函数翻转的时刻自动缩小积分步长把每次翻转都精确捕捉。这会导致两个后果一是仿真耗时成倍增加二是仿真结果对误差容限设置非常敏感容限小和容限大得到的结果可能完全不同。这给参数调试带来了极大的困扰因为你不确定看到的抖振是算法固有的还是数值计算产生的。改用固定步长求解器之后符号函数的翻转时刻不一定落在采样点上也就是“错过”一部分极高频切换但这在工程上是完全可以接受的。实际数字控制系统就是固定步长运行仿真越接近实际的离散化行为对后续部署越有参考价值。求解器我推荐用ode4四阶龙格库塔法这是固定步长求解器里精度和稳定性兼顾最好的选择。步长选1e-3秒起步如果发现抖振或者不稳定先把步长细化到5e-4或1e-4看是否改善。如果细化步长后结果变化很大说明当前步长下的仿真不可靠需要以更小步长为准。一旦找到了一个能稳定复现结果的步长后续所有参数对比实验都固定在那个步长下进行。5. 常见问题排查与避坑5.1 S-Function 相关报错我在带学生做这个示例的过程中遇到最多的问题就是 S-Function 相关的报错。这里整理几个高频问题做成一个速查表方便直接对应排查。现象可能原因解决办法编译报错Undefined function or variableS-Function 文件名与函数名不一致确保文件名和函数名完全一致且文件在 MATLAB 搜索路径中报错Invalid MEX-file使用了不支持的 S-Function 格式旧版 Level-1 S-Function 在新版本里可能报错改用 Level-2 格式仿真结果全为 0DirFeedthrough设置错误确保设成 1否则输出没有正确关联输入仿真非常慢使用了变步长求解器且包含符号函数改固定步长求解器步长设为 1e-3 或更小报代数环错误输入直接依赖输出且中间没有状态量在反馈回路中加 Memory 或 Unit Delay 模块不推荐或者改用 S-Function 正确设置DirFeedthroughS-Function 报错有一个通用的排查思路先单独测试 S-Function。在 MATLAB 命令行里手动构造一个输入向量直接调用该函数看输出是否与手算一致。这一步可以排除大部分纯程序问题之后再回到 Simulink 环境排查连线问题。5.2 被控对象模块连接中的常见问题被控对象模块连接中最常见的坑有三个。第一个是积分器的初始条件设置死板导致仿真初始时刻有巨大的跳变。比如期望位置从 0 跳到 1而实际位置初值为 0误差初始值为 1滑模面初始值s(0) e_dot(0) c*e(0) c。如果c 5那么初始滑模面就是 5符号函数一开始就会输出最大切换量控制量瞬间冲到很大的值看起来像“爆炸”。这其实是正常的滑模控制就是靠这种强切换把状态拉回滑模面。如果你觉得初始控制量太大可以把期望位置加一个斜坡过渡或者把实际初始位置设置成与期望一致然后外加扰动来观察抗扰性能。第二个是反馈信号取错位置。很多人搭建被控对象时把反馈点接在了扰动之前而不是被控对象输出端。比如扰动加在求和模块之后、积分器之前那反馈就应该取积分器的输出而不是取求和模块的输出。这个错误会导致控制器无法感知真实状态闭环失效。第三个问题是模型里面用了代数环。Simulink 里如果输入一个模块的信号直接又依赖该模块自己的输出而没有经过任何状态量Integrator、Delay 等就会形成代数环。代数环会导致仿真时每个步长内要解一个隐式方程速度极慢甚至不收敛。滑模控制器里常见的情况是控制器输出直接连接被控对象而被控对象的输出又直接反馈给控制器中间如果没有状态量就可能报警。因为被控对象本身就是积分器链通常有状态量在中间不会形成代数环。但如果被控对象是纯增益或纯微分就会有问题。5.3 仿真结果不合理时的排查思路仿真的结果不合理先别急着调模型。按照下面的顺序过一遍大多数问题都能定位。第一步检查稳态误差。如果误差不为零先检查eta是否大于扰动上界。如果eta不够大系统在扰动存在时会有稳态偏差。解决办法是把eta调大。第二步检查控制量曲线。如果控制量振荡剧烈、幅度很大先看是不是抖振也就是周期性高频振荡。如果是用sat替代sign或者减小eta。如果控制量整体饱和在限幅值上说明控制器增益过高或者期望轨迹切换太剧烈需要降低期望轨迹的变化率。第三步检查滑模面曲线。如果滑模面长时间不为零或者上下震荡说明系统没有真正进入滑模运动。可能的原因有c和eta参数匹配不当、被控对象参数与控制器内部假设不一致、扰动过大超出设计范围。注意如果你的被控对象参数a和b与 S-Function 里写死的数值不一致滑模控制仍然能工作因为切换项可以补偿模型误差但前提是eta大于补偿所需的极限值。这个特性也是滑模控制被称为“强鲁棒”的原因之一。6. 从仿真到工程应用的扩展思路6.1 仿真模型的走向代码生成与半实物仿真很多人在 Simulink 里完成了滑模控制器的仿真验证之后下一步就是想把它部署到实际的控制器上。这个环节有一些不同于纯仿真的问题需要提前考虑。如果你用的是具有嵌入式代码生成能力的工具链比如 Simulink Coder、Embedded Coder那么 S-Function 写出来的控制器可以自动生成 C 代码烧录到 DSP、MCU 或者工控机里。但有几个前置条件第一所有的控制律代码必须封装在 Simulink 的标准模块里外部 MATLAB 脚本依赖要清除干净第二仿真必须基于固定步长且步长与实际控制周期一致第三实际执行机构有饱和限幅、死区、延迟等非线性特性这些在仿真里最好也建模进去。从纯仿真的角度最快的下一步是做联合仿真。滑模控制器留在 Simulink 里把被控对象替换成高保真车辆模型比如 Carsim 或者 Amesim。这时候 Simulink 只负责运行控制算法车辆动力学由更专业的软件计算通过接口实时交互。我见过很多做车辆控制的人这么干车道保持、防抱死、能量管理等算法都用类似的方式验证。滑模控制的强鲁棒性在这种高保真模型上反而更能体现价值因为高保真模型里充满了各种未建模动态和参数不确定性。6.2 我个人推荐的三个扩展方向如果你已经成功跑通了上面的示例想继续深入我按性价比从高到低推荐三个方向。第一个方向是改造成自适应滑模控制。把固定增益eta改成可在线调整的增益根据误差大小动态变化。这样做的好处是兼顾快速性和抖振抑制误差大的时候用大增益快速收敛误差小的时候用小增益减少抖动。实现上只需要在 S-Function 里加一个自适应律的微分方程模型结构几乎不用动但论文可写的分析内容会多很多。第二个方向是做滑模观测器。很多工程场景里系统不可直接测量或测量成本高控制器无法获得全部状态量。这种情况下可以给系统设计一个滑模观测器利用输出估计全部状态再把估计值送进滑模控制器。这个方向能学到状态观测、非线性系统分析等一整套方法论而且 Simulink 里做观测器仿真非常直观。第三个方向是尝试反步滑模控制或者动态滑模控制。这些方法的共同点是在控制器里引入积分作用或虚拟控制量使得控制器输出本身是连续的从根源上消除抖振。它们的推导过程更复杂但控制性能更好适合用来冲击高水平的期刊或会议论文。我的建议是先别贪多把当前这个基本示例彻底吃透能手推控制律、能独立搭模型、能自己解释每个参数变化引起的现象。这个基础打好了往任意方向扩展都不会太吃力。最后再分享一个小技巧。仿真过程中可以把滑模面s和跟踪误差e画在同一张图上画成相轨迹图也就是以e为横轴、e_dot为纵轴。你会很清楚地看到系统状态从初始位置开始先冲向滑模面然后贴着滑模面滑向原点——这个过程非常优雅也是滑模控制名字的真正由来。做控制的人第一次看到自己搭的模型画出这个轨迹时大多会有点小激动。这个图放在报告或者论文里也比单纯的误差曲线有说服力得多。动手搭一个吧Simulink 里画相轨迹很简单e和e_dot从模型里引出来用 XY Graph 模块一接就行。
返回列表