ARTICLE DETAIL

资讯详情

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

自抗扰控制ADRC在Buck变换器仿真中的建模与参数整定

自抗扰控制ADRC在Buck变换器仿真中的建模与参数整定 最近我在调一台Buck变换器的样机负载一突变输出电压就甩个尖峰PID参数来回试了好几组都没压下去。后来把自抗扰控制ADRC搬进Matlab/Simulink里先做仿真验证前前后后折腾了两周总算是把扰动抑制的问题理顺了。这篇东西不聊虚的就讲讲我在电力电子变换器仿真里用ADRC的具体做法为什么选ADRC、被控对象怎么建模、扩张状态观测器和过渡过程怎么搭、Simulink里怎么一步步实现最后再把我踩过的发散和振荡坑整理成排查清单。想用ADRC做电源、逆变器、PFC这类控制的工程师或者正在做相关课题的学生可以直接按这里的思路去搭一套能跑通的基础仿真。1. 自抗扰控制为什么在电力电子变换器里越来越常见1.1 先说说PID在电源控制里的痛点做电源控制的人对PID实在太熟了电压环、电流环、三环控制几乎都是PID的天下。PID确实简单、可靠、工业验证充分但用到开关变换器上会有几个绕不开的问题。第一个是积分饱和。负载突变时误差持续存在积分项一路累积等到误差反向时积分还没退出来输出就会过冲。我实测过Buck变换器从轻载切重载如果积分限幅没处理好输出电压超调能到百分之十几。第二个是扰动抑制能力受限。PID本质上是误差驱动意思是你得先看到输出偏离了才去纠正扰动到输出的那段动态它管不了只能靠环路增益硬扛。第三个是参数整定很依赖经验尤其当被控对象本身参数在变电感饱和、电容老化、输入电压波动时一组PID参数很难在全工况范围内都保持好性能。1.2 ADRC的核心思想不是消除扰动而是估计并补偿它自抗扰控制的想法很有意思与其费劲去分辨扰动到底是什么、来自哪里不如把所有不想要的动态都当成一个“总扰动”用一个扩张状态观测器ESO把它实时估出来然后在控制量里反向补偿掉。这样说可能有点抽象我拿生活场景类比一下。你开车上坡脚踩油门维持速度。PID的思路是发现速度掉了5km/h我就多踩一点油门至于这个坡有多陡、车重了多少它不管。ADRC的思路是我感觉到速度在掉同时我通过一些观测量能估计出“哦当前有个等效的阻力在拖累我”然后直接把这个等效阻力对应的油门补偿上去剩下的误差再交给比例和微分去修正。放到电力电子变换器里输入电压波动、负载变化、电感参数漂移、模型未建模动态在ADRC眼里统统都是总扰动的一部分。ESO只需要知道输出和输入就能把总扰动估计出来。这个思路对开关变换器特别友好因为变换器本身就是强非线性、参数时变、扰动源多的对象。1.3 电力电子场景下ADRC的适配性我之所以推荐在电力电子变换器里用ADRC还有一层现实原因现在的数字控制器DSP、MCU算力足够跑ADRC这样简单的算法。ADRC本身并不复杂核心就是ESO加一个反馈律迭代公式都是简单的加减乘除。以Buck变换器为例控制频率设到50kHz甚至100kHz也就是20微秒甚至10微秒算一次完全来得及。而且电力电子变换器的采样条件相对好电压电流传感器精度足够ESO需要的高频采样在数字控制里本身就具备。开关频率越高ADRC的带宽优势越能体现出来。我自己的体会是只要你能稳定地把ESO带宽推到开关频率的十分之一左右ADRC对负载突变的抑制效果就会明显好于传统PID。2. 被控对象建模先搞清楚你要控的是什么2.1 以Buck变换器为例推导二阶模型在仿真里用ADRC第一步不是写控制器而是建立被控对象模型。选Buck变换器作为例子因为它结构简单但能代表一大类电压源型变换器。工作在连续导通模式CCM下Buck变换器的平均模型由两个方程描述。电感电流的微分方程L * (diL/dt) d * Vin - vo电容电压的状态方程C * (dvo/dt) iL - vo / R为了把系统整理成ADRC需要的二阶形式我们消去电感电流iL。由电容方程得到 iL C * (dvo/dt) vo / R代入电感方程并整理LC * (d²vo/dt²) (L/R) * (dvo/dt) d * Vin - vo再写成二阶标准形式d²vo/dt² (Vin / (LC)) * d - vo / (LC) - (1 / (RC)) * (dvo/dt)这个形式特别关键。ADRC的一般二阶模型是 y f b0 * u这里的输出y就是vo输入u就是占空比d。对比一下b0 Vin / (LC)而f -vo/(LC) - (1/(RC)) * vo这就是“总扰动”的一部分。注意f里包含了输出电压自身、电感、电容、负载电阻等一大堆信息ADRC要做的是把f当成一个整体去估计而不是逐项去测。2.2 平均模型和开关模型怎么选这是仿真里第一个选择。平均模型把开关管和二极管等效成一个受控电压源或电流源仿真速度快不含开关纹波适合验证ADRC算法本身。开关模型则用真实的MOSFET、二极管和PWM调制器能看出开关纹波和真实动态但仿真速度慢还容易遇到求解器不收敛的问题。我的建议是分两步走。第一步用平均模型把ADRC的参数调通确认ESO能准确估计总扰动、波形稳定不振荡。第二步再把模型换成开关模型用同样的ADRC参数去跑看实际表现。如果你一开始就用开关模型ESO的采样步长和PWM开关频率交互在一起很难分清问题是出在算法还是出在器件建模上。2.3 仿真参数怎么定一个能直接抄的示例我做仿真时用的一组典型参数如下参数数值说明输入电压 Vin24 V允许仿真中在20V到28V之间跳变输出电压参考 Vref12 V目标稳压值电感 L1 mH保证CCM纹波电流约200mA电容 C470 uF输出电压纹波约几十毫伏负载电阻 R10 Ω对应输出电流1.2A可切换至5Ω模拟负载突变开关频率 fsw100 kHz数字控制在100kHz量级控制频率 fs50 kHz也就是控制周期Ts2e-5 s根据上面的公式b0 Vin / (L*C) 24 / (1e-3 * 470e-6) ≈ 51064。这是一个比较大的数你后面在Simulink里搭建ESO时直接用这个值然后再微调。我建议在仿真里把b0定义成模型参数用标称值计算不要搞成实时变量因为ESO补偿能力足够处理一定的b0偏差。3. 核心算法拆解TD、ESO和反馈控制律3.1 安排过渡过程TD到底解决了什么问题自抗扰控制里有一个常常被忽略的环节就是跟踪微分器TD。它的作用是给参考信号安排一个平滑的过渡过程。比如参考电压从0突变到12V如果直接把这个阶跃信号送给控制器误差瞬间很大控制量一开始就饱和输出必然超调。TD的作用就是生成一条平滑的参考轨迹让输出慢慢逼近目标值。二阶TD的离散形式我习惯这样写v1[k1] v1[k] Ts * v2[k]v2[k1] v2[k] Ts * fhan(v1[k] - vref, v2[k], r0, h0)中间的fhan函数是韩京清教授提出的最速控制综合函数工程上可以直接用其近似形式。你也可以用更简单的线性形式把参考值通过一个一阶惯性环节再加微分效果在多数电源场景下也够用。不过我用下来还是觉得fhan的过渡更利落超调小上升时间也可控。参数r0决定了过渡过程的速度r0越大参考轨迹上升越快但太大就失去平滑意义h0一般取仿真步长的整数倍。我在Buck仿真里r0取的是输出电压参考幅度的10倍左右也就是120。这样参考电压从0到12V的过渡过程大约是0.1秒量级既能看清单突变到重载的过程又不至于太慢。3.2 扩张状态观测器ESOADRC的心脏ESO是整个ADRC的核心。它的思路是用一个扩张出来的状态变量去估计总扰动。对于二阶系统 y f b0*u扩张状态取z1估计输出电压z2估计输出电压变化率z3估计总扰动f。连续形式下的ESO写成这样dz1/dt z2 β1 * (y - z1)dz2/dt z3 β2 * (y - z1) b0 * udz3/dt β3 * (y - z1)这里β1、β2、β3是观测器增益工程上常按带宽法配置β1 3ωoβ2 3ωo²β3 ωo³。ωo就是观测器带宽它决定了ESO跟踪输出的速度和扰动估计的收敛速度。数字实现时我直接用前向欧拉法离散控制周期Ts2e-5s离散公式如下z1[k1] z1[k] Ts * (z2[k] 3ωo(y[k] - z1[k]))z2[k1] z2[k] Ts * (z3[k] 3ωo²(y[k] - z1[k]) b0*u[k])z3[k1] z3[k] Ts * (ωo³*(y[k] - z1[k]))欧拉法在控制频率远高于系统带宽时精度足够电力电子里采样频率高用欧拉法没问题。如果你控制频率只有几千Hz就要考虑更高精度的离散方法比如梯形法。3.3 控制器带宽和观测器带宽怎么配合ADRC的反馈控制律我推荐用线性形式够用又简单u0 kp * (v1 - z1) kd * (v2 - z2)其中kp ωc²kd 2ωcωc是控制器带宽。控制量u (u0 - z3) / b0注意这里减掉的是扰动估计值z3这就是前馈补偿的体现。参数整定的经验法则是先定b0再定ωc最后定ωo。ωc决定了闭环响应速度一般取期望穿越频率的2到3倍。我的Buck仿真里期望电压环穿越频率1kHz左右ωc取6000 rad/s。ωo要明显大于ωcESO才能在控制器正常工作前先把扰动估出来。我通常让ωo是ωc的5到10倍也就是3万到6万rad/s。但也不是越大越好ωo过大会把测量噪声放大。这里给一个我实测过的初始参数组合b051064ωc6000ωo30000r0120。在这个参数下Buck变换器从0启动到12V的输出波形几乎没有超调稳定时间大约15ms。负载从10Ω突变到5Ω时输出电压跌落只有0.3V左右恢复时间不到2ms。4. Matlab/Simulink仿真搭建从零开始跑通4.1 仿真环境与模块选择我用的是Matlab R2021b版本Simulink配合Simscape Electrical Toolbox。虽然也可以用传递函数直接搭被控对象但我建议有条件还是用Simscape里的电力电子器件这样后续做开关模型时不用换框架。仿真分两层主电路层负责搭建Buck变换器本身控制层负责实现ADRC算法。主电路我用Simscape Electrical里的MOSFET、Diode、Inductor、Capacitor、Resistor搭建PWM波通过Relay模块产生或者用比较器实现。控制层我用了MATLAB Function模块方便直接写ESO的离散迭代代码。如果你不想用Simscape也可以用传递函数直接搭平均模型被控对象就是个二阶传递函数分子是Vin/(LC)分母是s² 1/(RC)*s 1/(LC)。这样搭建速度快适合先验证算法逻辑但看不到开关纹波。4.2 MATLAB Function里写ADRC一段能直接跑的代码我在MATLAB Function里写的ADRC离散化代码如下这个结构既可以在仿真里用也可以后面移植到DSP的C代码里逻辑是完全对应的function u adrc_controller(vref, y, Ts) % 参数 b0 51064; % 控制增益依据Vin/(L*C)计算 wc 6000; % 控制器带宽 rad/s wo 30000; % 观测器带宽 rad/s r0 120; % 过渡过程速度 % 持久变量 persistent v1 v2 z1 z2 z3 if isempty(v1) v1 0; v2 0; z1 0; z2 0; z3 0; end % TD安排过渡过程简化线性形式 v1 v1 Ts * v2; v2 v2 Ts * r0 * (vref - v1); % ESO扩张状态观测器 e y - z1; z1 z1 Ts * (z2 3*wo * e); z2 z2 Ts * (z3 3*wo*wo * e b0 * u_prev); z3 z3 Ts * (wo*wo*wo * e); % 控制器 u0 wc*wc * (v1 - z1) 2*wc * (v2 - z2); u (u0 - z3) / b0; % 限幅 u max(0, min(1, u)); end这段代码里有个关键细节ESO的z2更新用到了上一次的控制量u_prev而这里没有显式定义。实际使用时你可以把u也设置成persistent变量在函数末尾保存u_prev u确保离散ESO使用的是上一时刻的控制量而不是当前时刻否则会引入代数环和一步超前的不真实效果。4.3 在Simulink里接线和配置在主电路侧用Simscape搭建Buck电路的方法我不展开细说了网上的教程很多。我重点说控制侧的几个配置点第一MATLAB Function模块的输入是vref和y输出是u。vref用Step模块给出12V阶跃y从输出电压传感器引出u输出到PWM比较器与三角载波比较产生MOSFET的驱动信号。第二求解器我建议选ode23tb最大步长设为2e-7秒也就是开关周期的一百分之一这样能捕捉到PWM边沿。如果用平均模型ode45就够了。第三PWM载波频率设为100kHz三角波幅值0到1这样占空比直接对应u。仿真时间我一般设置0.1秒足够看启动过程、稳态以及一组负载突变。To Workspace模块用来记录输出电压、电感电流、ESO的z3扰动估计值后面分析波形用得上。4.4 波形怎么看哪些现象说明ADRC在工作看仿真结果时我一般盯着三个点启动波形、负载突变响应、z3跟踪效果。启动时输出应该平滑上升不超调或只有很小超调。如果输出抖了一下然后上去多半是TD参数r0太大或者ωo不够。负载突变时我在t0.05s把负载电阻从10Ω切到5Ω好的响应是输出电压掉一小口然后快速恢复恢复过程没有振荡。z3波形最能反映问题稳态时z3应该近似等于实际总扰动负载突变时z3应该迅速变化并跟上新的扰动水平。如果z3跟得很慢说明ωo太小了如果z3有高频毛刺说明ωo太大。5. 仿真发散与不收敛问题排查实录5.1 我遇到过的典型发散场景做ADRC仿真最折磨人的就是发散。我第一次搭的时候仿真跑了两毫秒就直接崩掉了波形像过山车一样飞出去。查了半天原因是ESO离散化时用了当前时刻的控制量而不是上一时刻的控制量造成了一个虚拟的代数正反馈。把u改成persistent、用上一时刻的值更新z2之后仿真立刻就稳了。第二个典型的发散原因是ωo太大。把ωo从30000调到100000后z3开始高频抖动随后整个闭环振荡。原因很简单ESO带宽接近离散系统奈奎斯特频率导致数值不稳定。解决方法是把ωo限制在控制频率的十分之一以内。我控制频率50kHzωo最大也就50000 rad/s实际我用30000留足裕量。第三个场景是b0严重失配。我故意试了一次把b0设成标称值的两倍仿真虽然没发散但输出稳态误差很明显。这是因为ESO把b0的偏差也当成了扰动的一部分去估计理论上能补偿但如果偏差达到数倍ESO的收敛速度就跟不上了。5.2 常见问题速查表表现可能原因处理方式仿真直接发散、数值飞掉代数环、ESO用了当前步u、步长过大使用上一时刻u减小最大步长输出电压高频振荡ωo过大、控制周期过大降低ωo到控制频率的1/10以内启动过程超调大TD速度r0太小、kp/kd参数不合适增大r0检查ωc设置稳态有静差b0偏差过大、ESO收敛过慢校正b0或增大ωo负载突变响应慢ωc太小、ESO带宽不够增大ωc同时成比例增大ωoz3波形毛刺严重测量噪声被ESO放大降低ωo或在输出端加低通滤波模型不连续导致仿真中断开关模型的高频瞬态、求解器步长不配换ode23tb限最大步长5.3 提高ADRC仿真稳定性的几个实操习惯最后说几个我在实践中养成的习惯对避免仿真调参痛苦非常有用。第一永远先用平均模型验证ADRC核心逻辑再把被控对象换成开关模型。这能帮你把算法问题和模型数值问题分开排查。第二把ADRC所有参数定义成工作区变量用脚本一次性赋值不要在模块里写死。这样你可以在一个循环里自动扫参数比如从ωc2000跑到10000看哪个值范围内系统稳定。第三加一个控制量限幅再送给PWM保证u在0到1之间。很多发散是从控制量越界开始的。第四在Simulink里把离散求解器的固定步长设得足够小尤其是开关模型最大步长不要超过开关周期的1/100。步长太大时即使算法正确也会因为数值误差导致高频发散。我个人调ADRC时最深的体会是这个算法比PID多了一组参数但恰恰因为多了ESO它在面对不确定性时更从容。你不需要精确知道负载到底变了多少、输入电压到底波动了多少ESO会自己估出来并补偿掉。用常规PID时那种反复换参数还压不住负载突变的憋屈感换成ADRC之后会轻很多。如果你也是第一次搭ADRC仿真建议按这个顺序操作先按章节2的参数搭好Buck电路再复制章节4的ADRC代码到MATLAB Function里用章节3的参数组合跑一次然后试着把负载突变加上。等这一步跑通了再去调ωc、ωo感受一下各参数分别影响什么。这套流程走下来你对自抗扰控制的把握会比只看书深刻得多。
返回列表