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

问题描述

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

{ x ˙ 1 = f 1 + x 2 , x ˙ 2 = f 2 + x 3 , ⋮ x ˙ n − 1 = f n − 1 + x n , x ˙ n = f n + u , y = x 1 \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. x˙1x˙2x˙n1x˙ny=f1+x2,=f2+x3,=fn1+xn,=fn+u,=x1
可以转化成 n 个一阶控制器设计问题,如图
在这里插入图片描述
即首先用系统的输出 y = x 1 y=x_1 y=x1 去逼近目标信号 v ( t ) v(t) v(t),对变量 x 1 x_1 x1而言,需要的控制量为 u 1 u_1 u1

接下来递归地转化成子问题:用 x 2 x_2 x2去逼近 u 1 u_1 u1,求出 u 2 u_2 u2; 用 x 3 x_3 x3去逼近 u 2 u_2 u2,……,求出 u u u

仿真实验

考虑二阶被控对象:
{ x ˙ 1 = f 1 ( x 1 , t ) + x 2 , x ˙ 2 = f 2 ( x 2 , t ) + u , y = x 1 \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. x˙1x˙2y=f1(x1,t)+x2,=f2(x2,t)+u,=x1
其中 f 1 , f 2 f_1,f_2 f1,f2对控制器而言未知,仿真时使用如下函数:
f 1 ( x , t ) = x 2 + c o s ( t ) f 2 ( x , t ) = 0.5   sign ( sin ⁡ ( 2 ∗ x ) ) + 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} f1(x,t)=x2+cos(t)f2(x,t)=0.5sign(sin(2x))+sin(cos(t))

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)

在这里插入图片描述
非线性误差

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'])

结果如下
在这里插入图片描述
所需的控制量:
在这里插入图片描述
系统的内部总扰动 f 1 , f 2 f_1, f_2 f1,f2
在这里插入图片描述
调了一个小时的参数 🤦‍♀️

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值