问题描述
目前我正在考虑如何为我正在运行的模拟加速 odeint。实际上它只是一个带有摩擦项和不连续力的原始二阶颂歌。我用来描述动力学的模型是在一个单独的函数中定义的。尝试解决 ode 会导致错误或极高的计算时间(以天为单位)。
这是我的大部分硬编码代码:
import numpy as np
import pandas as pd
from scipy.integrate import odeint
import matplotlib.pyplot as plt
def create_ref(tspan):
if tspan>2 and tspan<8:
output = np.sin(tspan)
elif tspan>=20:
output = np.sin(tspan*10)
else:
output = 0.5
return output
def model(state,t):
def Fs(x):
pT = 0
pB = 150
p0 = 200
pA = 50
kein = 0.25
kaus = 0.25
if x<0:
pA = pT
Fsres = -kaus*x*pA-kein*x*(p0-pB)
else:
pB = pT
Fsres = -kaus*x*pB-kein*x*(p0-pA)
return Fsres
x,dx = state
refNow = np.interp(t,xref.index.values,xref.values.squeeze())
refprev = np.interp(t-dt,xref.values.squeeze())
drefNow = (refNow-refprev)/dt
x_meas = x
dx_meas = dx
errNow = refNow-x_meas
errprev = refprev-(x_meas-dx_meas*dt)
intrefNow = dt*(errNow-errprev)
kp = 10
kd = 0.1
ki = 100
sigma = kP*(refNow-x_meas)+kd*(drefNow-dx_meas)+ki*intrefNow
tr0 = 5
FricRed = (1.5-0.5*np.tanh(0.1*(t-tr0)))
kpu = 300
fr = 0.1
m = 0.01
d = 0.01
k = 10
u = float(kpu*np.sqrt(np.abs(sigma))*np.sign(sigma))
ddx = 1/m*(Fs(x)+FricRed*fr*np.sign(dx)-d*dx-k*x + u )
return [dx,ddx]
dt = 1e-3
tspan = np.arange(start=0,stop=50,step=dt)
steplim = tspan[-1]*0.1
reffunc = np.vectorize(create_ref)
xrefvals = reffunc(tspan)
xref = pd.DataFrame(data=xrefvals,index=tspan,columns=['xref'])
x0 = [-0.5,0]
simresult = odeint(model,x0,tspan)
plt.figure(num=1)
plt.plot(tspan,simresult[:,0],label='ispos')
plt.plot(tspan,xref['xref'].values,label='despos')
plt.legend()
plt.show()
我根据 Pranav Hosangadi 的评论更改了代码。感谢您的提示。我不知道这一点并学到了一些新东西,没想到字典对计算时间有如此大的影响。但现在速度要快得多。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)