自抗扰控制(ADRC)—— 多级串联型系统
程序员文章站
2024-01-09 23:48:04
...
问题描述
对如下的多级串联型系统的控制问题
可以转化成 n 个一阶控制器设计问题,如图
即首先用系统的输出 去逼近目标信号 ,对变量而言,需要的控制量为
接下来递归地转化成子问题:用去逼近,求出; 用去逼近,……,求出
仿真实验
考虑二阶被控对象:
其中对控制器而言未知,仿真时使用如下函数:
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'])
结果如下
所需的控制量:
系统的内部总扰动
调了一个小时的参数 ????♀️
上一篇: 改用sublime编辑器
下一篇: 冯诺依曼体系计算机体系结构和指令执行过程