SciPy 投射物ODE积分
我正在做一个项目,涉及使用SciPy的积分器来模拟这个射击游戏中的抛射物运动。我之前从来没有用过Python编程,而且我的微积分有点生疏,不过经过几个小时的努力,我发现很难确定到底是什么导致了某些错误。在经过几小时的反复尝试后,我让它在积分方法中工作了(我觉得这是欧拉积分,但老实说我不太确定)。不过我还需要使用SciPy库中的两个积分器,但它们一直没有工作。两个积分器在同一个地方都抛出了相同的错误信息:
" File "**file extension**", line 17, in eq
projX = x[0];
TypeError: 'float' object has no attribute '__getitem__'"
看起来它期待的是不同类型的对象,但老实说我不知道该怎么理解。我不确定是我用错了积分器,还是在设置常微分方程(ODE)时犯了错误。我真的很困惑。任何帮助都会非常感激。以下是代码:
from numpy import *
from scipy.integrate import ode
from scipy import *
# setup wind (it will be replaced with the current value of the wind at every
# instant in time)
wd = array([0, 0])
# computes the ODE
def eq(x, t):
# setup gravitational acceleration
#this is Acceleration for Y
GRAVITY = 9.81
# get out the positions and velocities
projX = x[0];
projY = x[1];
projVX = x[2];
projVY = x[3];
# TODO: setup the acceleration
#acceleration is the derivitive of velocity (VX..VY acceleration is GRAVITY) in this case it's 0 (no wind)?
ACCELERATION = 0 #will be effected by wind
#TODO ground force
# TODO: return appropriate things
#needs to return: (x,y Time derivatives and x,y acceleration)
#acceleration is derivative of velocity. Velocity derivative of position.
#is essentially dx/dt
return array([x[2], x[3], ACCELERATION, -GRAVITY])
# integrates a projectile forward in time using simple Euler integration
# t: the current time of the system
# dt: the time to step the system forward
# x: the current state of the system ([x position, y position, x velocity, y
# velocity)
# returns the new state of the system
def integrate(t, dt, x):
#Euler Method
#x[0] = x[0] + x[2]*dt
#x[2] = x[2]
#x[1] = x[1]+x[3]*dt
#x[3] = x[3]-(9.81*dt)
#SciPy Dopri5 Integration
#vode Integrator
method = ode(eq).set_integrator('vode', method = 'bdf')
method.set_initial_value(x, t)
method.integrate(method.t+dt)
return x
#write one function that represents one step of the diff equation
它是从projectile.py中调用的。大部分代码只是为了绘图和设置PyGame,但与这部分相关的代码片段是:
# integrate the projectile forward in time
x = dynamics.integrate(fireT, dt, array([projX, projY, projVX, projVY]))
projX = x[0]
projY = x[1]
projVX = x[2]
projVY = x[3]
# update the time
fireT = fireT + dt
1 个回答
0
问题在于,eq
这个函数的参数顺序搞错了。根据ode
的文档,你传入的函数应该这样定义:
f : callable f(t, y, *f_args)
而在你的代码中,你把t
和y
的位置搞反了,定义成了:
def eq(x, t):
然后你的代码尝试访问t[0]
,这就引发了一个TypeError
错误。
只需要把那一行改成:
def eq(t, x):