ARTICLE DETAIL

资讯详情

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

滑模控制算法Simulink仿真建模全流程:从原理到抖振抑制

滑模控制算法Simulink仿真建模全流程:从原理到抖振抑制 滑模控制算法仿真建模这件事门槛比想象中低但翻车点也比想象中多。很多人刚开始接触滑模控制时容易被那一串公式推导劝退觉得Matlab/Simulink里的模型也一定很复杂。实际上把滑模控制算法仿真建模拆开看核心模块就那么几个Gain、Sum、Sign、积分器再加几个信号源和示波器。真正让仿真结果没法看的往往不是控制律本身而是求解器步长没设对、sign模块用得太理想化、参数整定顺序搞反了这些看起来很小的细节。这篇文章我会完整记录一遍用Simulink从零搭建滑模控制算法仿真建模示例的过程包括原理怎么落到模型上、每个模块为什么这么搭、调参时先调哪个后调哪个、以及抖振问题到底怎么治。适合刚接触滑模控制、想在Simulink里快速跑通第一个仿真的人也适合已经能跑但发现波形抖得没法看、想找排查方向的读者。1. 为什么要把滑模控制搬进Simulink原理与适用场景1.1 滑模控制到底解决的是什么问题滑模控制Sliding Mode ControlSMC最吸引人的点就一个鲁棒性。它面对模型参数不准和外部扰动时表现出很强的不敏感特性这是PID、LQR这类依赖精确模型的控制器很难做到的。我打个比方普通反馈控制像你开车走一条固定路线路况好的时候没问题一旦轮胎打滑或者有人别车路线就会明显偏离滑模控制则像给车加了一条看不见的滑轨不管你在哪个位置、有没有外力干扰控制器会先把你狠狠拽到滑轨附近然后沿着滑轨把误差送到零。这种设计天然对扰动和参数偏差不敏感所以在电机驱动、四旋翼、机械臂、导弹制导、汽车ABS这些对鲁棒性要求高的场合滑模控制一直是被反复研究的对象。但需要说句公道话滑模控制不是万能的它最大的毛病就是抖振。理想情况下状态一旦到达滑模面就贴着面滑动实际上由于切换不连续和数字仿真的离散特性状态会在滑模面附近来回穿越形成高频振荡。这个问题我在后面第5节会仔细讲。1.2 三个核心要素滑模面、趋近律、控制律一个完整的滑模控制器设计绕不开三个东西。我把它们拆开说第一个是滑模面。滑模面是系统状态空间里的一条目标曲线设计的目标就是让系统的误差状态落在这条曲线上。最常用也最直观的是线性滑模面s c·e e其中 e 是跟踪误差e 是误差变化率c 是大于零的常数。这个式子其实很巧妙当系统状态满足 s 0 时误差动态就退化成一阶线性系统 e -c·e误差会按指数速度收敛到零。也就是说一旦状态上了滑模面闭环行为就被这个滑模面决定了和被控对象的参数关系不大了——这就是鲁棒性的来源。第二个是趋近律。滑模面只定义了最终要去的面但状态怎么走向这个面、走多快由趋近律决定。最经典的是指数趋近律s -ε·sign(s) - k·s这里 ε 和 k 都大于零。等号右边有两项-k·s 是指数项让状态在距离滑模面较远时快速逼近-ε·sign(s) 是切换项确保证状态能穿越到滑模面上并保持也是抖振的直接来源。第三个是控制律。把系统模型代入趋近律反解出控制量 u就是完整的控制律。以我后面仿真要用的二阶系统为例被控对象是J·θ B·θ uJ 是转动惯量B 是阻尼系数θ 是位置输出u 是控制力矩。通过推导可以得到控制律u B·θ - J·c·e J·θd - k1·s - k2·sign(s)这个式子看着长拆开看就四块第一项 B·θ 补偿被控对象的阻尼项第二项 -J·c·e 补偿滑模面定义中误差变化率的耦合第三项 J·θd 是期望轨迹的加速度前馈最后两项 -k1·s - k2·sign(s) 就是趋近律部分k1 对应指数趋近项k2 对应切换项。前两项加第三项本质上就是在做等效控制——让系统状态在理想情况下保持零动态后面两项负责切换控制把偏离滑模面的状态拉回来。一句话总结原理等效控制保证状态不离开滑模面切换控制保证状态被强制推到滑模面上。后面的Simulink建模其实就是把这条控制律一条一条挪到模块图上。2. 模型框架设计二阶机电系统与控制器结构2.1 被控对象和仿真工况怎么选仿真建模第一步不是急着搭Simulink模块而是先明确被控对象模型和期望的跟踪工况。我选的被控对象是一个二阶机电系统物理上可以理解成一台带阻尼的旋转电机或单轴机械臂J·θ B·θ u模型参数取 J 0.01 kg·m²B 0.1 N·m·s。为什么选这个系统因为它结构简单、物理意义清楚而且和电机驱动、机器人关节这些真实工程对象强相关。把滑模控制在这个系统上摸透了再换到四旋翼、车辆或机械臂模型上思路是一样的。期望跟踪指令我建议用正弦信号而不是只用阶跃信号。阶跃信号只能看出稳态误差和超调正弦信号能看出动态跟踪能力——比如跟踪相位滞后、幅值衰减这些问题。我用的是θd 0.5·sin(2·t)幅值0.5弧度频率2 rad/s大约0.3Hz对仿真系统来说比较温和方便观察参数变化带来的影响。2.2 整体信号流与模块划分思路在打开Simulink之前先在纸上画一遍信号流向。搭模型最忌讳的直接上手到处拖模块后面一通线根本没法查问题。我这个模型的信号流是这样的参考输入 θd 和实际输出 θ 做差得到误差 ee 通过增益 c 后与误差变化率 e 相加得到滑模面 ss 分别进入趋近律的两个分支一路乘 -k1一路经过 sign 后乘 -k2两个分支加起来再加上被控对象阻尼补偿项 B·θ、滑模面耦合补偿项 -J·c·e、期望加速度前馈项 J·θd合成的控制量 u 进入被控对象被控对象输出 θ 和 θ 反馈回去这样的结构也决定了模块划分思路误差模块、滑模面模块、趋近律模块、控制量合成模块、被控对象模块。每一块都是独立子系统或者至少是独立的区域方便单独调试。我给每个区域都用大括号的Annotation标注了名字比如SMC Controller和Plant。特别强调一下控制律里用到了 θ实际速度这个信号我设计成从被控对象的积分器中间引出而不是对 θ 求导这个细节第3节会细说。3. 分模块搭建从被控对象到控制律的完整过程3.1 被控对象建模积分器串联比传递函数好用在哪被控对象有两种常见搭法我用的是积分器串联的方式。第一种是用传递函数模块直接放一个 Transfer Fcn分子是 [1]分母是 [J, B, 0]G(s) 1 / (J·s² B·s)。优点是简洁、一眼看清传递函数缺点是不方便引出中间状态尤其是不方便直接拿到速度信号 θ。如果后面要把速度信号引到控制器里还得额外再搭一个 s/(J·s² B·s) 的传递函数这就重复了。第二种是积分器串联先算 θ通过增益 1/J 得到角加速度然后串联两个积分器第一个积分器输出 θ第二个输出 θ。整个被控对象只需要三个模块一个 Sum、一个 Gain、两个 Integrator。它的最大优势是中间状态速度可以直接引出而且物理意义非常清楚加速度积分成速度速度积分成位置。我把两种方式对比一下建模方式优点缺点适用场景传递函数 Transfer Fcn简洁与频域分析方法衔接好中间状态不好引出做状态反馈不便频率响应分析、只需关注输入输出积分器串联中间状态直接可用物理清晰模块多一些需要手动配置初值状态反馈控制、需要速度和位置信号这里要提醒一个细节积分器初值一定要设置。我习惯把位置积分器初值设为 0.2速度积分器初值设为 0模拟系统从偏离目标位置的状态开始运动。这样能直接看出滑模控制的趋近过程——状态一开始离滑模面很远控制器把它拽回来的过程就是滑模趋近段。如果初值都是零起始点恰好就在滑模面上反而观察不到趋近过程了。3.2 跟踪误差与滑模面模块尽量别用Derivative误差模块很简单用两个 Sum 实现一个 Sum 算位置误差 e θ - θd另一个 Sum 算速度误差 de/dt θ - θd。求 θ 和 θd 的方法是关键。θ 从被控对象积分器中间引出完全没问题。但 θd 是期望指令的导数很多教程会直接用 Derivative 模块对 θd 求导我强烈不建议在滑模控制里这么干原因是Derivative 模块放大噪声。仿真中不可避免有数值误差对带噪声的信号求导噪声会剧烈放大。滑模控制对切换项已经够敏感了再叠加数值噪声抖振会更吓人。Derivative 模块有直接馈通direct feedthrough特性容易引发代数环警告。解决办法很朴素用数学解析式给出导数。期望轨迹是 θd 0.5·sin(2t)那一阶导就是 θd 1.0·cos(2t)二阶导是 θd -2.0·sin(2t)。这三个信号可以直接用三个信号源分别生成或者用一个正弦信号源并联两个 Gain 模块变换出来。因为正弦的二次导数就是自身乘以 -ω²我把正弦输出取反乘 4 就得到了 θd效率高且没有噪声。如果期望轨迹不是解析可导的复杂信号我建议你把期望轨迹做成一个单独的状态空间模型把位置、速度、加速度都作为输出引出来而不是用 Derivative 硬求。滑模面模块就一组 Gain Sums c·e de/dt。我把 e 通过 Gain 模块增益设为变量 c再和 de/dt 相加。注意这里的信号类型要保持 doubleSimulink 在默认配置下不会自动处理数据类型不一致的问题后面接 sign 模块时如果类型不对会报错。3.3 趋近律与控制律模块一条公式拆成三个分支控制律这条公式搭的时候我建议按它的物理结构拆成三个分支最后用一个 Sum 合成这样出了问题好定位分支1模型补偿项由 B·θ、-J·c·e、J·θd 三个子项构成。把 J·c 合并算成一个 Gain 系数可以提高执行效率。分支2指数趋近项-k1·s一个 Gain 搞定。分支3切换项-k2·sign(s)需要一个 Sign 模块和 Gain 模块。把三个分支的输出接入一个 Sum得到最终控制量 u。在这个 Sum 后面我建议加一个 Saturation 模块做限幅把控制力矩限制在 ±10 N·m 以内。限幅有两个作用一是模拟真实执行机构饱和特性不让控制器输出不现实的巨大力矩二是防止极端参数下控制量发散把仿真数值冲爆。Sign 模块在 Simulink 的 Math Operations 库里输入大于零输出1小于零输出-1等于零输出0。这个模块是理想化的符号函数在后面抖振分析里它就是罪魁祸首。3.4 接线、示波器与数据记录的小习惯接线之前我建议给每个子系统的输入输出接口都起好有意义的名字比如 r_position、theta、velocity、s_sliding、smc_u 这种不要用默认的 In1、Out1。名字会直接显示在总线标签上模型复杂之后排查连线问题会省很多事。示波器我一般会分三个Scope1 看位置跟踪θd 和 θ 放在一起直接判断跟踪效果Scope2 看滑模面 s这是评价滑模控制是否进入滑动模态的核心指标s 应该快速收敛到0附近然后小幅振荡Scope3 看控制量 u观察控制信号是否有剧烈抖振数据记录建议打开模型的 Signal Logging在相关信号线上右键选择 Log Selected Signals然后用 MATLAB 脚本里的logsout sim(modelname)拿到数据方便后续画图、做误差分析。跑完仿真后我用plot(logsout.get(theta).Values)这类命令处理数据比在示波器里右键导数据好用得多。还有一个很实用的小技巧用模型初始化回调函数Model Properties → Callbacks → InitFcn定义参数。我把 J、B、c、k1、k2 都写成一个 initialization 脚本或 .m 文件里的变量这样在模型里所有 Gain、积分器参数都填变量名而不是硬编码数字。改参数的时候只需要改脚本里的值而且方便用 for 循环批量扫参数对比。4. 参数整定与调试求解器、步长和参数配合4.1 求解器选型为什么默认ode45会翻车这一步是我踩过最深的坑。Simulink 默认求解器是变步长 ode45在绝大多数连续系统仿真里很稳但在滑模控制里经常出问题。原因是滑模控制引入了 sign(s) 这个不连续的切换项。在切换瞬间系统方程从一个动态快速跳到另一个动态数值上表现为刚性stiff行为。ode45 是显式 Runge-Kutta 法处理刚性系统时会因为稳定性限制被迫把步长压得非常小结果表现为仿真进度极慢波形在切换点附近出现肉眼可见的锯齿甚至在切换点附近误差估算失败导致报错。我实测下来同样的模型和参数ode45 跑 10 秒仿真需要一两分钟且波形明显毛糙换 ode23t 之后仿真速度快了不止一倍波形平滑很多。具体建议变步长仿真时首选ode23t。它对中等刚性系统兼顾精度和速度适合滑模这类带非光滑项的系统。如果模型更复杂、刚性更强考虑ode15s它作为多步法效率更高但会引入一定数值阻尼对抖振形态有点掩盖作用。如果做固定步长仿真比如为了之后做代码生成步长上限要足够小。滑模面时间常数约 1/c也就是 50ms 量级但切换项的剧烈动态要求更高分辨率我建议固定步长从 1ms 起试必要时缩小到 0.1ms — 0.5ms。步长太大时仿真结果看起来会像高频噪声的混叠很多人在这里误以为控制器设计错了。4.2 滑模参数怎么选c、k1、k2的分工参数整定前先搞清楚每个参数管什么事参数作用增大影响减小影响经验初值c滑模面斜率决定滑动阶段的收敛速度误差收敛更快但放大噪声和高频动态可能引起更大抖振收敛变慢对模型不确定性的敏感度增加20k1指数趋近项增益状态更快趋近滑模面但过大可能引起趋近段超调趋近速度变慢5k2切换项增益抗扰能力更强系统更鲁棒但抖振幅度显著增大抗扰性变差外界扰动可能把状态推出滑模面0.5我推荐的整定顺序是先定 c。把 k1、k2 设成比较小的值观察误差收敛速度。c 相当于滑模面上的收敛带宽c 越大误差衰减越快但太大时控制器对高频噪声特别敏感实测中会出现本来平滑的输出变得毛糙。一般先用 c 5 到 50 之间试看阶跃响应的收敛速度。再调 k1。观察 s 从初始值快速下降到 0 附近的过程。k1 决定趋近段速度但过大的 k1 会让 s 在趋近过程中冲过头表现为误差先快速变小再反弹。最后调 k2。主要看抗扰动能力和抖振幅值。我习惯从 k2 0.1 开始逐步增大到刚好能看到扰动被明显压制的水平再退一点留余量。k2 是抖振的直接能量来源neng 小则不小。另外一个重要的验证手段注入扰动看鲁棒性。模型搭好后我在被控对象输入端加一个幅值 0.5、频率 3Hz 的正弦干扰力矩比较有扰动和无扰动的跟踪误差曲线。如果 k2 足够大两条曲线几乎重合如果 k2 太小轨迹会有明显偏差。这个对比是判断滑模控制是否生效的最直观证据。4.3 实测中比较典型的报错与排查把我在调试过程中遇到的几个典型问题列出来大家碰到时可以直接对照现象常见原因排查与解决仿真极慢波形锯齿状求解器不匹配刚性系统把求解器从 ode45 换到 ode23t / ode15s仿真发散报 NaN 或 Infk1/k2 取值过大或限幅没加、控制量爆炸减小 k1、k2加 Saturation 限幅代数环警告sign 等直接馈通模块形成闭合代数回路在反馈路径插入 Memory 或 Unit Delay 打断或改善信号流布局一波动就振荡不停c 太大放大高频噪声减小 c或改回 1s 限制稳态误差不为零c/k 太小或滑模控制被边界层削弱过多增大 c 或 k2检查边界层参数见第5节跟踪滞后明显期望加速度前馈项 J·θd 缺失或符号不对检查前馈信号是否接入增益是否为 J代数环警告需要单独说一句。滑模控制器天然容易触发这个警告因为控制律里同时包含了状态反馈和 sign 非线性sign 是直接馈通模块信号从输出到输入存在瞬时路径。Simulink 会尝试迭代求解这个代数环花费额外计算时间严重时模型跑不动。我在反馈路径上插入一个 Memory 模块之后警告消失仿真也流畅了。Memory 模块引入一拍延迟对低频跟踪影响很小完全可接受。5. 抖振抑制从理想仿真到工程可用的关键一步5.1 抖振的机理sign在数字仿真中的规矩先明确一个概念抖振分两种来源一种来自真实物理系统一种来自数字仿真本身。真实抖振的来源是 sign(s) 在 s 0 处发生理想的不连续切换。物理执行器电机、舵机、液压阀不可能瞬间完成这种无限带宽的切换必然产生有限频率的高频振动。数字仿真中的抖振则是额外的仿真步长有限控制器在每个仿真步长内最多切换一次状态在滑模面附近来回穿越就形成了和步长相关的锯齿状高频振荡。你可以把 sign(s) 想象成一个没有死区的继电器误差稍微为正就全力往一个方向推稍微为负就全力往反方向推。理想情况下这个继电器能以无限频率切换但仿真做不到物理世界也做不到于是状态就会像拧麻花一样在滑模面附近来回转。所以抖振不是调参偶尔会遇到的问题而是滑模控制从原理到实现必然面临的固有矛盾。好消息是工程界积累了很多成熟抑制手段。5.2 四种工程上实用的抑制方案我在实际中用过的、有效的方案有四种按实现难度从低到高排列方案1边界层法饱和函数替代符号函数。把 sign(s) 换成 sat(s/φ)其中 φ 是边界层厚度sat(s/φ) sign(s) 当 |s| φ sat(s/φ) s/φ 当 |s| ≤ φ在 Simulink 里实现非常容易把 s 经过一个增益 1/φ再接一个上下限为 ±1 的 Saturation 模块就得到了 sat(s/φ)。边界层内切换项变成连续线性函数抖振被大幅削弱代价是边界层内没有理想的滑模运动稳态精度会打折扣。这是我最推荐的入门方案。方案2连续化近似。用 s/(|s| δ) 代替 sign(s)δ 是个很小的正数。在 |s| 很小的时候函数值平滑过渡到0附近不会发生突然切换。Simulink 里可以直接用一个 Fcn 模块写表达式u/(abs(u)delta)很方便。这个方案本质上和边界层法类似但更平滑。方案3切换项低通滤波。在 sign 模块后面串一个一阶低通滤波器比如 1/(0.001s 1)把高频切换信号滤平后再参与控制量合成。这个方案和之前 Simulink 仿真中常用的一阶滤波模块思路完全一致。好处是做法简单保留理想切换的各项特性缺点是滤波器会引入相位滞后边界层或滤波器时间常数太大会显著削弱鲁棒性。我一般只在边界层法效果不理想时才用滤波器因为滤波器调参会多一点。方案4高阶级联滑模。比如超螺旋滑模Super-Twisting它把 sign 项放进积分器中从原理上消除抖振。这个方案性能最好但设计复杂度明显上升需要处理二阶滑模面的稳定性证明和参数选取适合对控制性能要求高的项目作为从仿真走向实际工程前可以考虑的进阶方向。四种方案放一起对比方案实现难度抖振抑制效果对鲁棒性影响适用场景边界层饱和函数很低好边界层内精度下降绝大多数工程场景首选连续化近似 s/(sδ)低好切换项低通滤波中较好相位滞后削弱鲁棒性不希望改动控制律结构时超螺旋滑模较高很好基本保持性能要求高的军事、高速运动控制5.3 边界层参数怎么选一组实测对比边界层法是最推荐优先试的所以我把 φ 的选取经验单独说。φ 越大抖振越小但控制精度越差φ 越小精度越好但抖振越明显。这是一对矛盾。我用自己的模型做了一组对比实验位置跟踪稳态误差和抖振幅值的大致趋势如下边界层厚度 φ稳态误差量级抖振幅值量级观察现象0.01约 0.001明显u 曲线高频毛糙精度很好控制量抖得厉害0.05约 0.005轻微毛糙精度仍然可接受抖振大幅减弱0.1约 0.01几乎消失精度下降一个量级波形很光滑从这个趋势能明显看到φ 从 0.01 到 0.1 之间存在一个工程上比较好的折中点。我的经验是从 φ 0.05 开始试大约等于 s 幅值的 0.5% — 1% 量级然后根据实际波形微调。如果输出曲线还抖就把 φ 调大如果误差超了就调小。还要提醒一点φ 的标定依赖 s 的实际幅值范围。在固定 c 的前提下s 的数量级可以看误差曲线估算。建议在 Scope2 里先看 s 的幅值再定 φ这样比盲目试数更有数。边界层法和滤波方案配合使用时先调边界层后调滤波器时间常数不要同时动两个参数否则会分不清是谁在起作用。我在做工程复现时还发现一个现象固定步长仿真下即使加了饱和函数如果步长太大s 在边界层内的抖动仍然会被数值误差放大。所以说到底抖振抑制是一个控制设计 数值实现的联合问题好的参数加上合适的求解器步长才能得到一条真正干净的输出曲线。从Simulink模型到后续扩展的一点体会这个模型跑通之后我最大的感受是滑模控制的理论推导和工程实现之间差的就是对细节的敏感度。控制律本身半小时能推导完但要把仿真调得又快又稳需要把求解器、步长、边界层、限幅这些工程细节全部统筹起来。我现在拿到一个滑模控制仿真任务优先确认的永远是三件事模型里有没有用 Derivative 模块、求解器是不是 ode45、sign 函数有没有做平滑处理。这三个点几乎是所有滑模仿真看起来不对的根源。另外这个模型本身有很强的复用价值。把被控对象从二阶线性系统换成机电系统、车辆模型甚至加进 Carsim 联合仿真框架控制器结构基本不用动把控制律写好并验证稳定之后可以走 Simulink Coder 生成 C 代码进入快速原型或硬件在环测试流程。四旋翼、导弹制导、VSG 这类热门方向的滑模控制本质上都是同一个框架在不同被控对象上的应用。最后分享一个调试技巧如果你把模型参数都写在初始化脚本里可以用一段 for 循环批量跑不同 k2 或 φ 的仿真自动把每组的跟踪误差积分ITAE算出来做对比。用数据代替肉眼判断选参数会客观得多。我第一次做扫参实验时发现 k2 0.4 和 k2 0.8 的误差积分差距并不大但抖振幅值差了三倍果断选了小 k2。这种够用就好、留有余量的整定思路在从仿真走向实际硬件时能帮你避开不少麻烦。
返回列表