自抗扰控制(ADRC)仿真系统(matlab/simulink)的搭建

2022-08-26 14:43:15 浏览数 (1)

大家好,又见面了,我是你们的朋友全栈君。

一、现在关于自抗扰控制技术方面的研究已经比较成熟了,基本上熟悉结构以后都可以找到例子实现,今天以一个简单的例子来介绍自抗扰控制的仿真系统搭建,不必畏惧,熟悉皆可达。 1.首先自抗扰控制分为TD(跟踪微分器),非线性组合,ESO扩张状态观测器。而每部分的公式推导均可在《自抗扰控制技术-估计补偿不确定因素的控制技术》这本书中找到,很推荐,如果有些不了解的地方也可以搜索韩老师的论文看看。

2.按照一般论文流程,先介绍整体结构,框图如下:

其实结构也挺少,使用习惯以后,其实很好理解。 3.接下来按照每个部分简单做一个介绍。 (1)先介绍一下TD(跟踪微分器)部分。 首先我们需要知道为什么需要TD部分,我个人有些自己粗浅的理解。首先想想我们常见的输入信号,是不是个阶跃,一般如下图所示:

这里是输入为1的阶跃信号,其实这种信号很常见,数值大小我们暂时不看。例如智能车的位置信息,锅炉系统的设置温度,水流控制的流量大小。这种信号最大的缺点就是,系统开始工作的时候我们希望加快系统的响应速度,因此给一个较大的放大环节(可以想成传统PID的P控制器系数),而这个时候的输入减输出(e=r-y)就很大,在乘以P环节的比例系数会更大,在到达设定值之前也就是y<r之前这个偏差一直是朝着一边变化的,因此很容易出现超调。这就是超调和快速性之间的矛盾出现了。 因此你想不想让输入变成下图这样:

其中红色曲线为输入,绿色曲线为红色的微分信号。完成这个功能的过程就是TD部分的设计。公式如下:

上面有个fhan函数有点懵,别急下面马上有。fhan 是最速控制综合函数,当

时,有以下表达式:

不用担心,这上面这么多公式你只需要注意两个变量,r,h。其中r为速度因子,h表示步长(采样间隔,一般单片机是0.1s)。r一般在10-500之前选取,具体看你系统的情况,调试不难,调试的时候看TD的输出曲线就行。 (2)非线性组合 这部分有个很简单的方法,你可以直接在TD的两个输出的(TD后输入信号,TD后输入信号的微分)做差后面分别加一个KP就ok了,一个取名KP,一个取名KD。这就等于两个比例环节,说明白了就是对信号的组合方式,如何利用误差和误差的微分。当然也可以采用非线性组合,例如以下:

非线性组合方式有很多,前面介绍的那本书上也有很多介绍,百度也能很多,自己设置几个非线性函数也可以,这里就不介绍了。 (3)ESO_扩张状态观测器 大家应该对状态观测器还有一点印象吧。没印象也没关系,就是设置另一个系统出来观测原系统的状态变量。公式如下:

看着复杂,其实自己推导确实很复杂。简单介绍一下。这个z1就是对输出的估计,毕竟叫扩张状态观测器。这个z3是对系统总扰动的估计。到这里有个简单的了解就行了。对于上面扩张状态观测器有很多变量,看的可能有点晕。fal函数仅仅是对误差e进行了一些变化。这里我们可以直接使用误差,有兴趣的这里可以继续研究。这样的话ESO就会变成如下形式:

这里再推荐高志强的一篇线性化设计ADRC的论文,也可以参考上面给出的书本自抗扰控制技术第209页,将带宽的概念引入自抗扰控制。参考论文《 Scaling and bandwidth-parameterization based controller tuning》。引入后ESO中的三个变量将变成这样:

这样的话ADRC的ESO部分将变得非常清爽。

4.仿真框图

仿真结果: 输出显示:绿色为安排过渡过程后的输入信号,红线为输出信号。

TD输出:红色为TD后的输入,绿色为微分信号。

ESO输出:红色为z1、绿色 z2、蓝色z3

代码部分: %TD部分

代码语言:javascript复制
function [v1,v2] = fcn(u)
persistent v1_1 v2_1
h=0.1;
delta=10;
if isempty(v1_1)
    v1_1=0;
end

if isempty(v2_1)
    v2_1=0;
end



%hfst计算内容
d=delta*h;
d0=h*d;
y=v1_1-u h*v2_1;
a0=sqrt(d*d 8*delta*abs(y));
a=0;
out1=0;
if abs(y)>d0
    a=v2_1 (a0-d)/2*sign(y);
end

if abs(y)<=d0
    a=v2_1 y/h;
end

if abs(a)>d
    out1=-delta*sign(a);
end

if abs(a)<=d
    out1=-delta*a/d;
end
out=out1;
%结束

v1=v1_1 h*v2_1;
v2=v2_1 h*out;

v1_1=v1;
v2_1=v2;

v1=v1;
v2=v2;

end

ESO部分:此部分我是用Simulink搭建的,和公式写都一样,有兴趣的可以用s-function写一个。

到此结束!

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/144200.html原文链接:https://javaforall.cn

0 人点赞