问题描述
对如下的多级串联型系统的控制问题
{
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˙n−1x˙ny=f1+x2,=f2+x3,⋮=fn−1+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(2∗x))+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
调了一个小时的参数 🤦♀️