我正在尝试解决这个问题:



你在哪里



这里:

s=c*e(t)+e_dot(t)




e(t)=theta(t)-thetad(t)




e_dot(t)=theta_dot(t)-thetad_dot(t)


其中thetad(所需的theta)= sin(t)-即要跟踪的信号!
和thetad_dot = cos(t),J = 10,c = 0.5,eta = 0.5

我先用odeint尝试-在t = 0.4之后给出了误差,即theta(上述微分方程的解)平稳降至0,然后保持不变。但是,当我尝试将mxstep增加到5000000时,直到t = 4.3s时,我才能得到一些正确的图形。

我想得到一个纯正弦图。那就是我想要theta(上面微分方程的解)跟踪thetad即sin(t)。但是它无法在t = 4.3秒后准确跟踪thetad。在这段时间之后,theta(上述微分方程的解)简单地下降到0并停留在那里。

这是我的代码-

from scipy.integrate import odeint
import numpy as np
import matplotlib.pyplot as plt

c=0.5
eta=0.5
def f(Y,t):
    x=Y[0]
    y=Y[1]
    e=x-np.sin(t)
    de=y-np.cos(t)
    s=c*e+de
    return [y,-c*(de)-np.sin(t)-eta*np.sign(s)]

t=np.linspace(0,10,1000)
y0=[0.5,1.0]
sol=odeint(f,y0,t,mxstep=5000000)
#sol=odeint(f,y0,t)
print(sol)
angle=sol[:,0]
omega=sol[:,1]
error=angle-np.sin(t)
derror=omega-np.cos(t)
plt.subplot(4,2,1)
plt.plot(t,angle)
plt.plot(t,error,'r--')
plt.grid()
plt.subplot(4,2,2)
plt.plot(t,omega)
plt.plot(t,derror,'g--')
plt.grid()
plt.subplot(4,2,3)
plt.plot(angle,omega)
plt.grid()
plt.subplot(4,2,4)
plt.plot(error,derror,'b--')
plt.savefig('signum_graph.eps')
plt.show()

最佳答案

odeint所使用的积分器(可能还有您发现已实现的所有积分器)均基于以下假设:在每个步骤中,导数(f)是连续的(并具有连续的导数)。信号函数显然违反了这一要求。无论步长有多小,这都会导致误差估计值非常高,进而导致步长过小以及您遇到的问题。

有两种常规解决方案:


选择步长大小,以使符号翻转恰好落在台阶上。 (这可能非常乏味。)
用非常陡峭的sigmoid替换信号函数,对于大多数应用程序来说,这应该很好并且更现实。在您的代码中,您可以使用

sign = lambda x: np.tanh(100*x)


而不是np.sign。此处的系数100控制S型曲线的陡度。选择足够高以反映您实际需要的行为。如果选择的值过高,这可能会对运行时间产生负面影响,因为积分器会将步长调整得不必要地小。


在您的情况下,设置一个小的绝对公差似乎也可行,但是我不会依赖于此:

sol = odeint(f,y0,t,mxstep=50000,atol=1e-5)

09-28 10:30