ValueError错误并使用odepack.error integrate.odeint() [英] ValueError and odepack.error using integrate.odeint()

查看:826
本文介绍了ValueError错误并使用odepack.error integrate.odeint()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图写一个方程模型,然后画出一个完整的控制系统(特别是关于巡航控制)。但是我收到两个错误,每当我运行它:

I'm trying to write an equation to model and then plot an integral control system (specifically regarding cruise control). However I'm receiving two errors whenever I run it:

ValueError错误:对象太深所需的阵列
odepack.error:从函数调用结果不是浮点数的正确阵列

ValueError: object too deep for desired array odepack.error: Result from function call is not a proper array of floats.

我读过这些问题:

  • scipy curve_fit error: Result from function call is not a proper array of floats
  • How to solve this differential equation using scipy odeint?
  • Object Too Deep for Desired Array - scipy.integrate.odeint

这似乎像他们应该是有帮助的,但是我不能确定如何应用这些我的问题。我是相当新的蟒蛇所以请原谅如果我错过了一些明显或做了一些非常愚蠢的。我有密谋它没有问题,所以一旦我弄清楚如何真正得到这个工作,我想我设置的。

Which seem like they should be helpful, however I'm unsure how to apply those to my problem. I'm fairly new to python so please bear with me if I've missed something obvious or done something exceptionally silly. I have no problems with plotting it, so once I figure out how to actually get this working I think I'm set.

import numpy as np
import scipy.integrate as integrate

##Parameters

kp=.5 #proportional gain
ki=.1 #integral gain
vr=30 #desired velocity in m/s
Tm=190 #Max Torque in Nm
wm=420 #engine speed
B=0.4 #Beta
an=12 #at gear 4
p=1.3 #air density
Cd=0.32 #Drag coefficient
Cr=.01 #Coefficient of rolling friction
A=2.4 #frontal area

##Variables

m=18000 #weight
v=20 #starting velocity
time=np.linspace(0,10,50) #time
theta=np.radians(4) #Theta

def vderivs(state,t):
    v = state
    vel=[]
    ti=0

    while ti < t:
        v1 = an*controller(ti,vr,v)*torque(v)
        v2 = m*Cr*np.sign(v)
        v3 = 0.5*p*Cd*A*v**2
        v4 = m*np.sin(theta)

        if t < 10:
            vtot = v1+v2+v3
            vfin = np.divide(vtot,m)
        else:
            vtot = v1+v2+v3+v4
            vfin = np.divide(vtot,m)

        vel.append(vfin)
        ti+=1

    trueVel = np.array(vel, float)
    return trueVel

def uderivs(state,t):
    v = state
    deltax = vr - v
    return deltax    

def controller(time,desired,currentV):
    z = integrate.odeint(uderivs, currentV, time)
    u = kp*(vr-currentV)+ki*z
    return u.flatten()

def torque(v):    
    return Tm*(1-B*(np.divide(an*v,wm)-1)**2)   

def velocity(mass,desired,theta,t):
    v = integrate.odeint(vderivs, desired, t)
    return v.flatten()

test = velocity(m,vr,theta,time)
print(test)

请让我知道是否有其他任何你需要我!

Please let me know if there is anything else you need from me!

推荐答案

发布此作为独立的,因为我得到了你的code工作。好了,运行并产生输出:P

Posting this as separate, because I got your code to work. Well, to run and produce output :P

其实一个很大的问题是一些隐形广播,我没有注意到,但我一路上改变了很多其他的东西。

Actually one big problem is some stealth broadcasting that I didn't notice, but I changed a lot of other things along the way.

首先隐身广播是,如果你有一个参数集成1D功能, odeint 返回一个列向量,然后当你做的东西与结果是行向量,那么你得到一个二维数组(矩阵)。例如:

First the stealth broadcasting is that if you integrate a 1d function with one parameter, odeint returns a column vector, and then when you do stuff with that result that is a row vector, then you get a 2d array (matrix). For example:

In [704]: a
Out[704]: array([0, 1, 2, 3, 4])

In [705]: b
Out[705]: 
array([[0],
       [1],
       [2]])

In [706]: a+b
Out[706]: 
array([[0, 1, 2, 3, 4],
       [1, 2, 3, 4, 5],
       [2, 3, 4, 5, 6]])

您都拿到了输出速度,这是像的列向量b 并将其添加到时间的一些其他的功能,并得到一个矩阵。

You were getting output for velocity that was a column vector like b and adding it to some other function of time, and getting a matrix.

至于递归,我想我sovled这个问题。这两个衍生功能应采取一个标 T 在这一点上,他们计算出衍生物。要做到这一点, vderivs 需要做的整体,它应该做在所有时间可达 T 。于是我重新定义它们的方式:

With regards to the recursion, I think I sovled that issue. The two derivative functions should take a single scalar t at which point they calculate the derivative. To do that, vderivs needs to do the integral, which it should do over all time up to t. So I redefined them as such:

dt = .1   # another global constant parameter

def vderivs(v, t):
    ts = np.arange(0, t, dt)
    v1 = an * controller(v, ts) * torque(v)
    v2 = m*Cr*np.sign(v)
    v3 = 0.5*p*Cd*A*v**2 
    v4 = m*np.sin(theta)
    vtot = v1+v2+v3+v4*(ts>=10) # a vector of times includes incline only after ts = 10
    return vtot/m

当然, uderivs 是罚款,不过可以更简单地写:

And of course uderivs is fine as is but can be written more simply:

def uderivs(v, t):
    return vr - v

然后,确保速度控制器传递正确值(使用 V0 而不是v 的起始速度):

Then, make sure that velocity and controller pass the right values (using v0 instead of v for the starting velocity):

def controller(currentV, time):
    z = integrate.odeint(uderivs, currentV, time)
    return kp*(vr-currentV) + ki*z.squeeze()

def velocity(desired, theta, time):
    return integrate.odeint(vderivs, desired, time)

谁知道物理是正确的,但是这给:

Who knows if the physics is correct, but this gives:

请注意,它没有达到所希望的速度,所以增加了在其上是要解决的时间

Note that it hasn't reached the desired velocity, so I increased the time over which it was to be solved

time = np.linspace(0,50,50) #time

下面是所有code,我跑了:

Here is all the code that I ran:

import matplotlib.pylab as plt
import numpy as np
import scipy.integrate as integrate

##Parameters
kp = .5 #proportional gain
ki = .1 #integral gain
vr = 30 #desired velocity in m/s
Tm = 190 #Max Torque in Nm
wm = 420 #engine speed
B = 0.4 #Beta
an = 12 #at gear 4
p = 1.3 #air density
Cd = 0.32 #Drag coefficient
Cr = .01 #Coefficient of rolling friction
A = 2.4 #frontal area

##Variables
m = 18000.0 #weight
v0 = 20. #starting velocity
t = np.linspace(0, 20, 50) #time
dt = .1
theta = np.radians(4) #Theta

def torque(v):    
    return Tm * (1 - B*(an*v/wm - 1)**2)  

def vderivs(v, t):
    ts = np.arange(0, t, dt)
    v1 = an * controller(v, ts) * torque(v)
    v2 = m*Cr*np.sign(v)
    v3 = 0.5*p*Cd*A*v**2
    v4 = m*np.sin(theta)
    vtot = v1+v2+v3+v4*(ts>=10)
    return vtot/m

def uderivs(v, t):
    return vr - v

def controller(currentV, time):
    z = integrate.odeint(uderivs, currentV, time)
    return kp*(vr-currentV) + ki*z.squeeze()

def velocity(desired, theta, time):
    return integrate.odeint(vderivs, desired, time)

plt.plot(t, velocity(v0, theta, t), 'k-', lw=2, label='velocity')
plt.plot(t, controller(v0, t), 'r', lw=2, label='controller')
plt.legend()
plt.show()

这篇关于ValueError错误并使用odepack.error integrate.odeint()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆