SciPy 投射物ODE积分

2 投票
1 回答
1365 浏览
提问于 2025-04-17 23:46

我正在做一个项目,涉及使用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)

而在你的代码中,你把ty的位置搞反了,定义成了:

def eq(x, t):

然后你的代码尝试访问t[0],这就引发了一个TypeError错误。

只需要把那一行改成:

def eq(t, x):

撰写回答