原理
微分跟踪器(Tracking-Differentiator)的功能:输入一个信号 v ( t ) v(t) v(t),输出两个信号 z 1 ( t ) , z 2 ( t ) z_1(t), z_2(t) z1(t),z2(t),其中 z 1 ( t ) z_1(t) z1(t)跟踪信号 v ( t ) v(t) v(t),而 z 2 ( t ) = z 1 ˙ ( t ) z_2(t) = \dot{z_1}(t) z2(t)=z1˙(t),因而 z 2 ( t ) z_2(t) z2(t) 可以看做 v ( t ) v(t) v(t)的近似导数。
如何设计微分跟踪器主要依据以下定理:
意思就是如果一个形如(1)式的二阶微分方程组,具有全局渐进稳定的零点,就可以用来构造如(2)所示的微分跟踪器。
仿真
四阶龙格库塔数值积分法
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
def dxdt(x,y,t,h=2e-2):
K1, L1 = f1(x, y, t), f2(x, y, t)
dx, dy = h*K1/2, h*L1/2
K2, L2 = f1(x+dx, y+dy, t), f2(x+dx, y+dy, t)
dx, dy = h*K2/2, h*L2/2
K3, L3 = f1(x+dx, y+dy, t), f2(x+dx, y+dy, t)
dx, dy = h*K3, h*L3
K4, L4 = f1(x+dx, y+dy, t), f2(x+dx, y+dy, t)
dx = (K1 + 2*K2 + 2*K3 + K4)*h/6
dy = (L1 + 2*L2 + 2*L3 + L4)*h/6
return dx, dy
def trajectory(initial_point = [0, 0], num_points=1e4, h=2e-2):
x0, y0 = initial_point[0], initial_point[1]
n = int(num_points)
x = np.zeros([n,2])
x[0,:] = [x0,y0]
for k in range(1,n):
dx,dy = dxdt(x[k-1,0],x[k-1,1],h*k,h)
x[k,0] = x[k-1,0] + dx
x[k,1] = x[k-1,1] + dy
return x.T
测试以下:
def f1(x, y, t):
return y - 0.1*x
def f2(x, y, t):
return -x
N = 10000
x = trajectory((0.5,0.5),N)
fig = plt.figure()
plt.plot(*(0.5,0.5),'o',label='start')
plt.plot(*x, color='red',label='trajectory')
plt.legend(loc='lower right')
plt.show()
在画一个看看,据论文说这是一个由二阶最速开关系统:
def sat(x, delta):
return x/delta if np.abs(x)<delta else np.sign(x)
def f1(x, y, t):
return y
def f2(x, y, t):
return -R*sat(x + np.abs(y)*y/(2*R), delta)
N = 1000
R = 10
x = trajectory((0.5,0.5),N)
fig = plt.figure()
plt.plot(*(0.5,0.5),'o',label='start')
plt.plot(*x, color='red',label='trajectory')
plt.plot(*x[:,-1],'o', color='green',label='end')
plt.legend(loc='lower right')
plt.show()
说明上面的数值积分算法还行吧
跟踪带噪声的正弦信号
def f1(x, y, t):
return y
def f2(x, y, t):
return -R*sat(x - v(t) + np.abs(y)*y/(2*R), delta)
def sat(x, delta):
return x/delta if np.abs(x)<delta else np.sign(x)
def v(t):
return np.sin(t) + np.random.randn()*0.01
R = 8
delta = 0.01
N = 1000
x = trajectory((0.5,0.5),N)
fig = plt.figure()
plt.plot(x[0], color='red', label='track')
plt.plot(x[1], color='blue', label='diff')
plt.legend()
plt.show()
红线是对正弦信号的跟踪,蓝线是对输入信号导数的估计。
跟踪阶跃信号
def f1(x, y, t):
return y
def f2(x, y, t):
return -R*sat(x - v(t) + np.abs(y)*y/(2*R), delta)
def sat(x, delta):
return x/delta if np.abs(x)<delta else np.sign(x)
def v(t):
return 1 if int(t)%2==0 else 0
R = 90
delta = 0.001
h = 1e-2
N = 600
x = trajectory((0.5,0.5),N,h)
fig = plt.figure()
plt.plot(x[0], color='red', label='track')
plt.show()
plt.plot(x[1], color='blue', label='diff')
# plt.plot((x[0][1:]-x[0][:-1])/h, color='green', label='diff')
plt.legend()
plt.show()
有一定的超调,微分信号有震颤
参考文献
韩京清, 王伟. 非线性跟踪─微分器[J]. 系统科学与数学, 1994(02):177-183.