欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

自抗扰控制(ADRC)—— 多级串联型系统

程序员文章站 2024-01-09 23:48:04
...

问题描述

对如下的多级串联型系统的控制问题

{x˙1=f1+x2,x˙2=f2+x3,x˙n1=fn1+xn,x˙n=fn+u,y=x1 \left\{ \begin{array}{ll} \dot{x}_1 &=f_1 + x_2, \\ \dot{x}_2 &= f_2 + x_3, \\ &\vdots \\ \dot{x}_{n-1} &= f_{n-1} + x_n, \\ \dot{x}_n &= f_n + u, \\ y &= x_1 \end{array} \right.
可以转化成 n 个一阶控制器设计问题,如图
自抗扰控制(ADRC)—— 多级串联型系统
即首先用系统的输出 y=x1y=x_1 去逼近目标信号 v(t)v(t),对变量x1x_1而言,需要的控制量为 u1u_1

接下来递归地转化成子问题:用x2x_2去逼近u1u_1,求出u2u_2; 用x3x_3去逼近u2u_2,……,求出 uu

仿真实验

考虑二阶被控对象:
{x˙1=f1(x1,t)+x2,x˙2=f2(x2,t)+u,y=x1 \left\{ \begin{array}{rl} \dot{x}_1 &=f_1(x_1, t) + x_2, \\ \dot{x}_2 &= f_2(x_2, t) + u, \\ y &= x_1 \end{array} \right.
其中f1,f2f_1,f_2对控制器而言未知,仿真时使用如下函数:
f1(x,t)=x2+cos(t)f2(x,t)=0.5sign(sin(2x))+sin(cos(t)) \begin{array}{l} f_1(x,t) = x^2 + cos(t) \\ f_2(x,t) = 0.5\,\text{sign}(\sin(2*x)) + \sin(\cos(t)) \end{array}

def f1(x,t):
    return x**2 + np.cos(t)

def f2(x,t):
    return 0.5*np.sign(np.sin(2*x)) + np.sin(np.cos(t))

有点复杂吧 ????‍♀️

没关系,ADRC 不怕非线性!

目标信号:

def target(t):
    if t < 10:
        return np.sign(np.sin(0.8*t))  
    elif t < 20:
        return 2*(0.5*t-int(0.5*t)-0.5)
    else:
        return np.sin(0.8*t)

自抗扰控制(ADRC)—— 多级串联型系统
非线性误差

def fal(x, alpha=0.5, delta=0.1):
    return  x/np.power(delta,1-alpha) if np.abs(x)<delta else np.power(np.abs(x), alpha)*np.sign(x)

记录时间序列的类,方便画图

class Logger:
    def __init__(self):
        self.data = {}
    
    def add(self, key, value):
        if key not in self.data:
            self.data[key] = []
        self.data[key].append(value)
      
    def plot(self, keys=None):
        plt.figure(figsize=(20,10))
        if keys is None:
            for k in self.data:
                plt.plot(self.data[k], label=k)     
        else:
            for k in keys:
                plt.plot(self.data[k], label=k)
        plt.legend()
        plt.show()     
logger = Logger()
h = 0.01
T = 30
N = int(T/h)

# 可调参数
r0 = 5
alpha1, alpha2 = 0.5, 0.9
beta1, beta2 = 10, 50

# 初值
v1 = 0
z11,z12,z21,z22 = 0,0,0,0
x1,x2 = 0,0
y = x1
u1,u = 0,0
for i in range(N):
    t = i*h
    
    # 目标信号
    v = target(t)

    # 过渡过程 v1 -> v, v1的过渡比v更加平缓
    v1 += h*r0*fal(v-v1, 0.5, h) 
    
    # ADRC1
    e = y - z11
    fe = fal(e, 0.5, h)
    z11 += h*(z12 + 100*e + u1)
    z12 += h*(100*fe)
    u1 = beta1*fal(v1 - z11, alpha1, 0.1) - z12
    
    # ADRC2
    e = x2 - z21
    fe = fal(e, 0.5, h)
    z21 += h*(z22 + 100*e + u)
    z22 += h*(100*fe)
    u = beta2*fal(u1 - z21, alpha2, 0.1) - z22
	
	# 系统状态更新
    x1 += h*(f1(x1,t) + x2)
    x2 += h*(f2(x2,t) + u)
    y = x1


    logger.add('v1',v1)
    logger.add('y',y)
    logger.add('v',v)
    logger.add('u1',u1)
    logger.add('u',u)
    logger.add('f1',z12)
    logger.add('f2',z22)

logger.plot(['v','v1','y'])
logger.plot(['u','u1'])
logger.plot(['f1','f2'])

结果如下
自抗扰控制(ADRC)—— 多级串联型系统
所需的控制量:
自抗扰控制(ADRC)—— 多级串联型系统
系统的内部总扰动 f1,f2f_1, f_2
自抗扰控制(ADRC)—— 多级串联型系统
调了一个小时的参数 ????‍♀️