【问题标题】:output of function doesn't store correctly函数的输出没有正确存储
【发布时间】:2019-06-12 22:55:01
【问题描述】:

我有一个求解微分方程系统的函数。我想在系统解决后绘制其中一个结果变量(theta_i)。这个变量来自等式:

np.arctan2(g1,g2)

所以它的值假设在 -pi 和 pi 之间。如果我在计算后立即打印 theta_i(到函数中),结果看起来正确(值在 -0.2 和 0.5 之间)。但是,当我将 theta_i 保存在向量 u 中后打印时,结果完全错误(它继续上升)。奇怪的是,我以相同的方式(作为 u 中的数组)保存了来自函数的所有其他变量,但是当我绘制它们时它们的值看起来是正确的。我该如何解决这个问题?我是 python 新手。我使用 Python 2.7.12。提前谢谢你。

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

added_mass_x = 0.03 # kg 
added_mass_y = 0.04 
mb = 0.3 # kg 
m1 = mb-added_mass_x 
m2 = mb-added_mass_y 
l1 = 0.07 # m 
l2 = 0.05 # m 
J = 0.00050797 # kgm^2 
Sa = 0.0110 # m^2 
Cd = 2.44 
Cl = 3.41 
Kd = 0.000655 # kgm^2 
r = 1000 # kg/m^3

c1 = 0.5*r*Sa*Cd 
c2 = 0.5*r*Sa*Cl 
c3 = 0.5*mb*(l1**2) 
c4 = Kd/J 
c5 = (1/(2*J))*(l1**2)*mb*l2 
c6 = (1/(3*J))*(l1**3)*mb

theta_0 = 10*(np.pi/180) # rad 
theta_A = 20*(np.pi/180) # rad 
f = 2 # Hz

t = np.linspace(0,100,8000) # s

def direct(u,t):
    vcx = u[0]
    vcy = u[1]
    wz = u[2]
    psi = u[3]
    x = u[4]
    y = u[5]
    vcx_i = u[6]
    vcy_i = u[7]
    psi_i = u[8]
    wz_i = u[9]
    theta_i = u[10]
    theta_deg_i = u[11]

    # Subsystem 1
    omega = 2*np.pi*f # rad/s
    theta = theta_0 + theta_A*np.sin(omega*t) # rad
    theta_deg = (theta*180)/np.pi # deg
    thetadotdot = -(omega**2)*theta_A*np.sin(omega*t) # rad/s^2

    # Subsystem 2
    vcxdot = (m2/m1)*vcy*wz-(c1/m1)*vcx*np.sqrt((vcx**2)+(vcy**2))+(c2/m1)*vcy*np.sqrt((vcx**2)+(vcy**2))*np.arctan2(vcy,vcx)-(c3/m1)*thetadotdot*np.sin(theta)
    vcydot = -(m1/m2)*vcx*wz-(c1/m2)*vcy*np.sqrt((vcx**2)+(vcy**2))-(c2/m2)*vcx*np.sqrt((vcx**2)+(vcy**2))*np.arctan2(vcy,vcx)+(c3/m2)*thetadotdot*np.cos(theta)
    wzdot = ((m1-m2)/J)*vcx*vcy-c4*wz*wz*np.sign(wz)-c5*thetadotdot*np.cos(theta)-c6*thetadotdot
    psidot = wz

    # Subsystem 3
    xdotdot = vcxdot*np.cos(psi)-vcx*np.sin(psi)*wz+vcydot*np.sin(psi)+vcy*np.cos(psi)*wz # m/s^2
    ydotdot = -vcxdot*np.sin(psi)-vcx*np.cos(psi)*wz+vcydot*np.cos(psi)-vcy*np.sin(psi)*wz # m/s^2
    xdot = vcx*np.cos(psi)+vcy*np.sin(psi) # m/s
    ydot = -vcx*np.sin(psi)+vcy*np.cos(psi) # m/s

    # Subsystem 4
    vcx_i = xdot*np.cos(psi_i)-ydot*np.sin(psi_i)
    vcy_i = ydot*np.cos(psi_i)+xdot*np.sin(psi_i)
    psidot_i = wz_i
    vcxdot_i = xdotdot*np.cos(psi_i)-xdot*np.sin(psi_i)*psidot_i-ydotdot*np.sin(psi_i)-ydot*np.cos(psi_i)*psidot_i
    vcydot_i = ydotdot*np.cos(psi_i)-ydot*np.sin(psi_i)*psidot_i+xdotdot*np.sin(psi_i)+xdot*np.cos(psi_i)*psidot_i

    g1 = -(m1/c3)*vcxdot_i+(m2/c3)*vcy_i*wz_i-(c1/c3)*vcx_i*np.sqrt((vcx_i**2)+(vcy_i**2))+(c2/c3)*vcy_i*np.sqrt((vcx_i**2)+(vcy_i**2))*np.arctan2(vcy_i,vcx_i)
    g2 = (m2/c3)*vcydot_i+(m1/c3)*vcx_i*wz_i+(c1/c3)*vcy_i*np.sqrt((vcx_i**2)+(vcy_i**2))+(c2/c3)*vcx_i*np.sqrt((vcx_i**2)+(vcy_i**2))*np.arctan2(vcy_i,vcx_i)

    A = 12*np.sin(2*np.pi*f*t+np.pi) # eksiswsi tail_frequency apo simulink
    if A>=0.1:
        wzdot_i = ((m1-m2)/J)*vcx_i*vcy_i-c4*wz_i**2*np.sign(wz_i)-c5*g2-c6*np.sqrt((g1**2)+(g2**2))
    elif A<-0.1:
        wzdot_i = ((m1-m2)/J)*vcx_i*vcy_i-c4*wz_i**2*np.sign(wz_i)-c5*g2+c6*np.sqrt((g1**2)+(g2**2))
    else:
        wzdot_i = ((m1-m2)/J)*vcx_i*vcy_i-c4*wz_i**2*np.sign(wz)-c5*g2


    if g2>0:
        theta_i = np.arctan2(g1,g2)
    elif g2<0 and g1>=0:
        theta_i = np.arctan2(g1,g2)-np.pi
    elif g2<0 and g1<0:
        theta_i = np.arctan2(g1,g2)+np.pi
    elif g2==0 and g1>0:
        theta_i = -np.pi/2
    elif g2==0 and g1<0:
        theta_i = np.pi/2
    elif g1==0 and g2==0:
        theta_i = 0
    theta_deg_i = (theta_i*180)/np.pi
    #print theta_deg_i


    return [vcxdot, vcydot, wzdot, psidot, xdot, ydot, vcxdot_i, vcydot_i, psidot_i, wzdot_i, theta_i, theta_deg_i]

# arxikes synthikes 
vcx_0 = 0.1257 
vcy_0 = 0 
wz_0 = 0 
psi_0 = 0 
x_0 = 0 
y_0 = 0 
vcx_i_0 = 0.1257 
vcy_i_0 = 0 
psi_i_0 = 0 
wz_i_0 = 0 
theta_i_0 = 0.1745 
theta_deg_i_0 = 9.866 
u0 = [vcx_0, vcy_0, wz_0, psi_0, x_0, y_0, vcx_i_0, vcy_i_0, psi_i_0, wz_i_0, theta_i_0, theta_deg_i_0]

u = odeint(direct, u0, t, tfirst=False)

vcx = u[:,0] 
vcy = u[:,1] 
wz = u[:,2] 
psi = u[:,3] 
x = u[:,4] 
y = u[:,5] 
vcx_i = u[:,6] 
vcy_i = u[:,7] 
psi_i = u[:,8] 
wz_i = u[:,9] 
theta_i = u[:,10] 
theta_deg_i = u[:,11] 
print theta_i

plt.figure(17) 
plt.plot(t,theta_i,'r-',linewidth=1,label='theta_i') 
plt.xlabel('t [s]') 
plt.title('theta_i [rad] (Main body CF)') 
plt.legend() 
plt.show()

【问题讨论】:

  • “标量”只是一个数字(与向量相反)。 np.arctan2 是一个接受两个标量并产生另一个标量的函数;但是,您可以将其应用于 NumPy 中的向量,并且“广播”规则将自动使其工作。 np.arctan2 实际上不太可能给出错误的答案,因此您的错误可能在其他地方,您想发布该代码。
  • 如果您提供minimal, complete and verifiable example,别人会更容易帮助您。 arctan2 返回介于 -pi 和 pi 之间的值,因此问题可能出在代码中的其他地方。
  • 您确认arctan2 给出了正确的结果:np.arctan2(-8.209,51.76) = -0.1572。问题出在其他地方。你的代码有theta = np.arctan2(g1,g2)吗?如果是这样,请检查该计算中的所有内容,直到绘制它为止。检查您的输入,也许您没有为计算提取正确的 (g1,g2) 对。如果没问题,跟踪从输出到绘图创建的 theta 值。如果您使用的是数组,请确保所有索引都正确。
  • @kcw78 我在函数外跟踪 theta_i 的值,直到绘制它的线。似乎 theta_i 的绘图值(函数外部,介于 -0.2 和 0.5 之间))与函数内部的绘图值完全不同(它继续上升),但我不明白为什么。 (检查更新的问题)
  • @macroeconomist 你是对的。问题不在于 np.arctan2() 函数。我更新了我的问题以匹配我发现的内容。

标签: arrays python-2.7 numpy odeint atan2


【解决方案1】:

结果对我来说似乎没问题,只要确保你得到正确的差异顺序(dY,dx)。点相对于原点的角度示例。

b= np.array([[10,0], [10, 5], [10,10], [5, 10], [0,10]])
a = np.array([0,0])
ba = b - a
ang = np.degrees(np.arctan2(ba[:, 1], ba[:, 0]))
ang
  array([ 0.        , 26.56505118, 45.        , 63.43494882, 90.        ])

【讨论】:

  • 我发现问题不在我要找的地方,所以我更新了我的问题。
猜你喜欢
  • 2013-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-22
  • 2021-04-28
  • 1970-01-01
  • 2021-02-28
  • 2013-10-23
相关资源
最近更新 更多