【LADRC】对自抗扰算法的理解及公式推导(附代码)

前言

        在学习和研究自抗扰控制(LADRC)算法的过程中,我积累了一些自己的理解和心得。为了更好地整理这些知识,同时也希望与有共同兴趣的朋友们进行交流和探讨,故撰写此文章。文章中的内容基于我的个人学习经验,难免会存在理解上的偏差或错误。第一次撰写博客,非常欢迎大家批评指正,共同进步!

1、从PID控制器开始

        对于串联积分型,我们可以很容易的使用P和PD控制器完成无稳态误差、无超调量到控制。

一阶系统:G_{(s)}=\frac{k_{p}}{s+k_{p}}

二阶系统:G_{(s)}=\frac{k_{p}}{s^{2}+k_{d}s+k_{p}}

        当系统不再是积分串联型的时候,如对于一个系统为:

\ddot{y}=-\alpha \dot{y}+\beta y+b u+d

式中d为未知的外部扰动。

        对于传统的PID控制,则引入一个积分器“I”

\ddot{y}=-\alpha \dot{y}+\beta y+b (k_{p}(y_{r}-y)+k_{d}\dot{y}+k_{i}\int (y_{r}-y)dt)+d

        传递函数G_{(s)}=\frac{b k_{p}s+b k_{i}}{s^{3}+(b k_{d}+\alpha )s^{2}+(b k_{p}+\beta )s+b k_{i}}。PID的参数可由极点配置法进行参数整定,当\alpha\betab发生改变后,系统的特性也会发生改变,导致在含扰动的非积分串联型系统中PID控制器的鲁棒性下降。

2、 线性自抗扰控制(LADRC)

        LADRC优势在于其不依赖于系统的精确数学模型,其思想为通过线性扩张状态观测器(LESO)来实时估计和补偿系统中的扰动和不确定性,将系统转变为一个串联积分型后进行控制,而LADRC相比于ADRC,引入了带宽的概念,减少了要调整的参数数量和调整难度。

同样针对上述系统:

\left\{\begin{matrix} \ddot{y}=-\alpha \dot{y}+\beta y+bu+d \\x_{1}=y \\x_{2}=\dot{y} \end{matrix}\right.

其状态空间为:

\begin{bmatrix} \dot{x_{1}} \\\dot{x_{2}} \end{bmatrix}=\begin{bmatrix} 0 & 1\\ \beta & -\alpha \end{bmatrix}\begin{bmatrix} x_{1}\\ x_{2} \end{bmatrix}+ \begin{bmatrix} 0\\b \end{bmatrix}u+ \begin{bmatrix} 0\\1 \end{bmatrix}d

y=\begin{bmatrix} 1 & 0 \end{bmatrix}\begin{bmatrix} x_{1}\\ x_{2} \end{bmatrix}

控制器设计为:

u=-\begin{bmatrix} K_{1} & K_{2} \end{bmatrix}\begin{bmatrix} x_{1}\\ x_{2} \end{bmatrix}+F_{r}

Fr为前馈项。当x1,x2不可测的时候,我们使用状态观测器来估计x1,x2的状态,则控制器变为:

u=-\begin{bmatrix} K_{1} & K_{2} \end{bmatrix}\begin{bmatrix} \widehat{x_{1}}\\ \widehat{x_{2}} \end{bmatrix}+F_{r}

引入的闭环观测器--Luenberger观测器公式如下:

\dot{\widehat{x}}=A\widehat{x}+Bu+\begin{bmatrix} L_{1}\\ L_{2} \end{bmatrix}(y-\widehat{y})

2.1无对象模型的线性扩张状态观测器(LESO)的设计

        有了以上准备,我们把LADRC的扩张状态观测器(LESO)写作:

\left\{\begin{matrix} \ddot{y}=-\alpha \dot{y}+\beta y+b_o u+d \\x_{1}=y \\x_{2}=\dot{y} \\\ x_{3}=f\end{matrix}\right.

LESO中的x3即为“扩张”出来的状态。

        式子中的f为总扰动,这个总扰动不仅包括了系统受到的外部扰动,还有系统数学模型不准确所带来的内部扰动。所以在上述式子中的\dot{x_{2}}=\ddot{y}=f+bu,我们可以将系统中除去输出的部分全部视作总扰动f=-\alpha \dot{y}+\beta y+d

则包含了扩张状态的状态空间方程为:

\begin{bmatrix} \dot{x_{1}}\\ \dot{x_{2}} \\ \dot{x_{3}} \end{bmatrix}=\begin{bmatrix} 0 & 1 &0 \\ 0& 0 & 1\\ 0&0 &0 \end{bmatrix}\begin{bmatrix} x_{1}\\ x_{2} \\ x_{3} \end{bmatrix}+\begin{bmatrix} 0\\b_o \\ 0 \end{bmatrix}u

y=\begin{bmatrix} 1 & 0 & 0 \end{bmatrix} \begin{bmatrix} x_{1}\\ x_{2} \\ x_{3} \end{bmatrix}

根据Luenberger观测器的形式:

\left\{\begin{matrix} \dot{\widehat{x}}=A\widehat{x}+Bu+L(y-\widehat{y})\\ \widehat{y}=C\widehat{x} \end{matrix}\right.

式中A=\begin{bmatrix} 0 & 1 &0 \\ 0& 0 & 1\\ 0&0 &0 \end{bmatrix}B=\begin{bmatrix} 0\\b_o \\ 0 \end{bmatrix}​​​​​​,​C=\begin{bmatrix} 1 &0 &0 \end{bmatrix}L=\begin{bmatrix} l_1\\ l_2 \\l_3 \end{bmatrix}推导得出:

\dot{\widehat{x}}=A\widehat{x}+Bu+L(y-\widehat{y})

        =(A-LC)\widehat{x}+Bu+Ly

                =\begin{bmatrix} l_{1} & 1 &0 \\ l_{2}& 0 &1 \\ l_{3}& 0&0 \end{bmatrix}\widehat{x}+\begin{bmatrix} 0 &l_{1} \\ b_o&l_{2} \\ 0& l_{3} \end{bmatrix}\begin{bmatrix} u\\y \end{bmatrix}

选择状态矩阵\overline{A}=\begin{bmatrix} l_{1} & 1 &0 \\ l_{2}& 0 &1 \\ l_{3}& 0&0 \end{bmatrix}进行特征根的计算,特征多项式:

SI-\overline{A}=\begin{bmatrix} s & 0 &0 \\ 0&s & 0\\ 0& 0&s \end{bmatrix}-\begin{bmatrix} l_{1} & 1 &0 \\ l_{2}& 0 &1 \\ l_{3}& 0&0 \end{bmatrix}

      =s^3+l_1s^2+l_2s+l_3

        选择观测器极点在左半平面内,为了方便调节,将极点选在-\omega _o上。-\omega _o称作观测器的带宽(特征根)。

s^3+l_1s^2+l_2s+l_3=[S-(-\omega _o)]^3

                                                         =s^3+3\omega _os^2+3\omega _o^2s+\omega _o^3

\therefore l_1=3\omega _o ,l_2=3\omega _o^2,l_3=\omega _o^3

        这样就可以做到只需要调整\omega _o就能够对观测器进行调节。

2.2状态误差反馈控制律的设计

        当设计的状态观测器能够较准确的估计出总扰动,即\widehat{x_3}=\widehat{f}\approx f。我们就令u=\frac{u_o-\widehat{f}}{b_o},则\ddot{y}=f+bu=f+b\frac{u_o-\widehat{f}}{b_o}=u_o,我们发现当把与输出u无关的参数全部包含到总扰动f中后,经过LESO的估计就能将其全部抵消。这样系统将转变为一个串联积分型,就可以采用最开始的PD控制器进行准确地控制。

u_o=K_p(r-\widehat{x_1})+K_d(\dot{r}-\widehat{x_2})+\ddot{r}

        式中r为目标值,\ddot{r}为前馈项,旨在提高系统对参考输入的跟踪性能。若不是阶跃输入信号(导数不为0),则PD控制器会产生稳态误差,加入前馈项就能减小稳态误差。绝大部分情况下可忽略此项。

        接下来对\ddot{y}=u_o=K_p(r-\widehat{x_1})+K_d(\dot{r}-\widehat{x_2})+\ddot{r}进行拉普拉斯变换得到:

        s^2Y=K_p\cdot E+K_d\cdot s\cdot E

        开环传递函数\frac{Y}{E}=\frac{K_p+Kd\cdot s}{s^{2}},则闭环传递函数为:

G_{(s)}=\frac{\frac{Y}{E}}{1+\frac{Y}{E}}=\frac{K_p+K_d\cdot s}{s^2+K_d\cdot s+K_p}

        对控制器进行极点配置,选取-\omega _c作为控制器带宽(极点):

s^2+K_d\cdot s+K_p=[s-(-\omega _o)]^2

                                     =s^2+2\omega _cs+\omega _c^2

\therefore K_p=\omega _c^2,K_d=2\omega _c

       这样就可以做到仅仅调整\omega _c,就能够对整个控制器进行调节。

         对于一个标准的二阶闭环传递函数G_{(s)}=\frac{\omega _n^2}{s^2+2\xi \omega _ns+\omega _n},上述的控制器闭环传函相当于\xi =1的情况(临界阻尼比),根据阻尼比与超调量之间的关系,此时控制器的超调量为0。这也就是LADRC算法没有超调量的原因。

2.3关于bo

        bo是输出补偿b的猜测值,我们可以根据所建立的关于系统的数学模型中输出u前的项来进行计算猜测,使其尽可能的解近实际的b。而猜测的bo与实际的b之间的偏差将会被加入到总扰动f中进行估计,所以更加准确的bo能够减小观测器的估计压力。

\ddot{y}=-\alpha \dot{y}+\beta y+\Delta u+d+b_o u

        式中f=-\alpha \dot{y}+\beta y+\Delta u+d\Delta u=bu-b_ou

2.4部分模型已知的线性扩张状态观测器(LESO)的设计

        对于一些系统来说,我们可以使用一些方法得到系统的部分模型,当我们把这些模型加入进LESO中后,能够有效的降低LESO的观测压力,在相同(甚至更低)的观测器带宽条件下获得更好的估计性能。若观测器的带宽过大,可能会导致观测器对实际的估计过于敏感,从而更易受到噪声影响。

        带入已知的模型,将上述式子写作

\ddot{y}=-a_1 \dot{y}-a_0 y+\Delta u+d+b_o u=-a_1 \dot{y}-a_0 y+{f}'+b_o u

其中,a0,a1已知,bo部分已知。{f}'=\Delta u+d为实际未知的扰动,仍然将总扰动记为f=a_1 \dot{y}+a_0 y+\Delta u+d

将含有扩张状态的状态空间方程写作:

\left\{\begin{matrix} \dot{x}=Ax+Bu+E{\dot{f}}'\\ y=Cx \end{matrix}\right.

此时,式子中各矩阵变为

A=\begin{bmatrix} 0 & 1 &0 \\ 0& 0 & 1\\ 0&-a_0 &-a_1 \end{bmatrix}B=\begin{bmatrix} 0\\b_o \\ -a_1b_o \end{bmatrix}​​​​​​,​​C=\begin{bmatrix} 1 &0 &0 \end{bmatrix}E=\begin{bmatrix} 0\\0 \\ 1 \end{bmatrix}

观测器为:

\left\{\begin{matrix} \dot{\widehat{x}}=(A-LC)\widehat{x}+Bu+Ly+E{\dot{f}}'\\ \widehat{y}=C\widehat{x}\end{matrix}\right.

使用与上面相同的方法进行特征根的计算,

SI-\overline{A} = \begin{bmatrix} S & 0 & 0 \\ 0 & S & 0 \\ 0 & 0 & S \end{bmatrix} - \begin{bmatrix} l_1 & 1 & 0 \\ l_2 & 0 & 1 \\ l_3 & -a_0 & -a_1 \end{bmatrix}

                                         =S^3 + l_1 S^2 - a_1 S^2 - a_1 l_1 S - a_0 S + l_2 S - a_0 l_1 - a_1 l_2 + l_3

将观测器极点选择在左半平面,为了方便调节,选择在-\omega _o

S^3 + l_1 S^2 - a_1 S^2 - a_1 l_1 S - a_0 S + l_2 S - a_0 l_1 - a_1 l_2 + l_3 = [S - (-\omega_o)]^3

=S^3 + (3\omega_o - a_1)S^2 + (3\omega_o^2 - a_1 \omega_o - a_0 + a_1^2)S + \omega_o^3 - 3a_1 \omega_o^2 + 3(a_1^2 - a_0) \omega_o + 2a_0 a_1 - a_1^3

可以得到:

l_1 = 3\omega_o - a_1 \\

l_2 = 3\omega_o^2 - a_1 \omega_o - a_0 + a_1^2

l_3 = \omega_o^3 - 3a_1 \omega_o^2 + 3(a_1^2 - a_0) \omega_o + 2a_0 a_1 - a_1^3

因为式子中除\omega _o为未知量,其余都为模型的已知参数,所以同样只需要调整\omega _o就能够对观测器进行调节。

3、LADRC参考代码

3.1无对象模型LADRC算法的Python实现

class LADRC:
    
    def __init__(self, ProcessOrder, Compensate, BandwidControlador, BandwidLESO, condicionInit,imprimirMat=1):

        self.u = 0
        self.h = 0.00001 
        self.nx = int(ProcessOrder)
        self.wc = BandwidControlador
        self.wo = BandwidLESO
        self.bo = Compensate
        self.zo = condicionInit
        self.Cg, self.Ac, self.Bc, self.Cc, self.Ee, self.zo, self.L,self.K,self.z = self.Parameter_Init(imprimirMat)


    def Parameter_Init(self, imprimirMat=1):
        
        n = self.nx + 1

        K = np.zeros([1, self.nx])
        for i in range(self.nx):
            K[0, i] = math.pow(self.wc, n - (i + 1)) * (
                    (math.factorial(self.nx)) / (math.factorial((i + 1) - 1) * math.factorial(n - (i + 1)))) #控制器带宽

        L = np.zeros([n, 1])
        for i in range(n):
            L[i] = math.pow(self.wo, i + 1) * (
                        (math.factorial(n)) / (math.factorial(i + 1) * math.factorial(n - (i + 1)))) #观测器带宽

        Cg = 1 / self.bo

        Ac = np.vstack((np.hstack((np.zeros([n - 1, 1]), np.identity(n - 1))), np.zeros([1, n])))
        Bc = np.vstack((np.zeros([self.nx - 1, 1]), self.bo, 0))
        Cc = np.hstack(([[1]], np.zeros([1, n - 1])))
        Ee = np.vstack((np.zeros((2, 1)), 1))
        zo = np.vstack(([[self.zo]], np.zeros([n - 1, 1])))
        z = np.zeros([n, 1])

        if imprimirMat == 1:
            print(f"K =\n {K}\n")
            print(f"L =\n {L}\n")
            print(f"Ac =\n {Ac}\n")
            print(f"Bc =\n {Bc}\n")
            print(f"Cc =\n {Cc}\n")
            print(f"Ee =\n {Ee}\n")
            print(f"z =\n {z}\n")
            print(f"zo =\n {zo}\n")

        return Cg, Ac, Bc, Cc, Ee, zo, L, K, z

    def LESO(self, u, y, z):
        
        return np.matmul(self.Ac, z) + self.Bc * u + self.L * (y - np.matmul(self.Cc, z))

    def Runkut4(self, F, z, h):
        
        k0 = h * F(z)
        k1 = h * F(z + 0.5 * k0)
        k2 = h * F(z + 0.5 * k1)
        k3 = h * F(z + k2)

        return z + (1 / 6) * (k0 + 2 * k1 + 2 * k2 + k3)

    def LADRC_Control(self, r, y):

        leso = partial(self.LESO, self.u, y) 
        self.z = self.Runkut4(leso, self.z, self.h) 

        u0 = self.K[0, 0] * (r - self.z[0, 0])  

        for i in range(self.nx - 1):
            u0 -= self.K[0, i + 1] * self.z[i + 1, 0] 

        self.u = (u0 - self.z[self.nx, 0]) * self.Cg

        return {'output':u0,'Z0':self.z[0,0],'Z1':self.z[1,0],'Z2':self.z[2,0]}

3.2部分模型已知LADRC算法的Python实现

class LADRC:

    def __init__(self, ProcessOrder, Compensate, BandwidControlador, BandwidLESO, condicionInit, ModelDisturbance, Disturbance0, Disturbance1,
                 imprimirMat=1):

        self.u = 0
        self.h = 0.00001 
        self.nx = int(ProcessOrder)
        self.wc = BandwidControlador
        self.wo = BandwidLESO
        self.bo = Compensate
        self.fh = ModelDisturbance
        self.zo = condicionInit
        self.a0 = Disturbance0
        self.a1 = Disturbance1
        self.Cg, self.Ac, self.Bc, self.Cc, self.Ee, self.zo, self.L, self.K, self.z = self.Parameter_Init(imprimirMat)

    def Parameter_Init(self, imprimirMat=1):
        
        n = self.nx + 1
        a0 = self.a0
        a1 = self.a1

        K = np.zeros([1, self.nx])
        for i in range(self.nx):
            K[0, i] = math.pow(self.wc, n - (i + 1)) * (
                    (math.factorial(self.nx)) / (math.factorial((i + 1) - 1) * math.factorial(n - (i + 1)))) #控制器带宽

        L = np.zeros([n, 1])
        for i in range(n):
            L[i] = math.pow(self.wo, i + 1) * (
                        (math.factorial(n)) / (math.factorial(i + 1) * math.factorial(n - (i + 1)))) #观测器带宽

        L[0] = L[0] - a1
        L[1] = L[1] - a1 * self.wo - a0 + a1 * a1
        L[2] = L[2] - 3 * a1 * self.wo * self.wo + 3  * self.wo * (a1 * a1 - a0) + 2 * a0 * a1 - math.pow(a1 , 3)  

        Cg = 1 / self.bo
        a0array = np.array([[a0]]) 
        a1array = np.array([[a1]]) 
        Ac = np.vstack((np.hstack((np.zeros([n - 1, 1]), np.identity(n - 1))), np.hstack((np.zeros((1, 1)), -a0array , -a1array))))
        Bc = np.vstack((np.zeros([self.nx - 1, 1]), self.bo, -a1array*self.bo))
        Cc = np.hstack(([[1]], np.zeros([1, n - 1])))
        Ee = np.vstack((np.zeros((2, 1)), 1 ))
        zo = np.vstack(([[self.zo]], np.zeros([n - 1, 1])))
        z = np.zeros([n, 1])

        if imprimirMat == 1:
            print(f"K =\n {K}\n")
            print(f"L =\n {L}\n")
            print(f"Ac =\n {Ac}\n")
            print(f"Bc =\n {Bc}\n")
            print(f"Cc =\n {Cc}\n")
            print(f"Ee =\n {Ee}\n")
            print(f"z =\n {z}\n")
            print(f"zo =\n {zo}\n")

        return Cg, Ac, Bc, Cc, Ee, zo, L, K, z

    def LESO(self, u, y, z):
        
        return np.matmul(self.Ac, z) + self.Bc * u + self.L * (y - np.matmul(self.Cc, z)) + self.Ee * self.fh

    def Runkut4(self, F, z, h):
        
        k0 = h * F(z)
        k1 = h * F(z + 0.5 * k0)
        k2 = h * F(z + 0.5 * k1)
        k3 = h * F(z + k2)

        return z + (1 / 6) * (k0 + 2 * k1 + 2 * k2 + k3)

    def LADRC_Control(self, r, y):

        leso = partial(self.LESO, self.u, y)  
        self.z = self.Runkut4(leso, self.z, self.h) 

        u0 = self.K[0, 0] * (r - self.z[0, 0])  

        for i in range(self.nx - 1):
            u0 -= self.K[0, i + 1] * self.z[i + 1, 0] 

        self.u = (u0 - self.z[self.nx, 0]) * self.Cg

        return {'output':u0,'Z0':self.z[0,0],'Z1':self.z[1,0],'Z2':self.z[2,0]}
  • 18
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一介线性自抗扰是一种控制器设计方法,它可以在系统存在外部扰动的情况下,实现快速、准确的动态响应。Simulink是一种功能强大的仿真工具,可以用于建立系统动力学模型并进行仿真分析。 在Simulink中进行yijie线性自抗扰的仿真,需要以下步骤: 1. 建立系统模型:使用Simulink的模块库,根据实际系统的特性以及线性自抗扰算法的设计原理,构建系统的数学模型。包括系统的输入输出关系、控制器结构、扰动模型等。 2. 设计自抗扰控制器:根据yijie线性自抗扰算法的原理,设计相应的控制器结构和参数。可以使用Simulink提供的工具,如PID控制器模块、状态空间模块等。 3. 进行仿真实验:在Simulink中将系统模型与设计的控制器相连,并加入外部扰动输入信号。设定合适的仿真时长和采样时间,运行仿真实验。 4. 仿真结果分析:根据仿真结果,分析系统的动态响应、稳定性以及抗扰性能。可以使用Simulink提供的数据分析工具和图表绘制工具进行结果分析。 5. 优化调整:根据仿真结果进行系统的优化调整,如调整控制器参数、改变控制结构等,以达到更好的响应性能和抗扰性能。 通过上述步骤,可以使用Simulink进行yijie线性自抗扰的仿真,帮助工程师和研究人员验证和优化yijie线性自抗扰算法的性能,并指导实际应用中的控制器设计。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值