使用odeint()在Python中进行摆锤模拟不能完全起到摆锤的作用 [英] Pendulum simulation in Python using odeint() not quite working as a pendulum

查看:139
本文介绍了使用odeint()在Python中进行摆锤模拟不能完全起到摆锤的作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用四阶Runge-Kutta微分建立了摆锤仿真,其中所有步骤都是逐步完成的:

I have built a pendulum simulation using fourth order Runge-Kutta differentiation where everything is done step by step:

from scipy import *
from matplotlib.pyplot import *
##A pendulum simulation using fourth order 
##Runge-Kutta differentiation

ts=.05 #time step size
td=20 #trial duration
te=int(td/ts) #no of timesteps

mu=0.1 #friction factor
m=1 #mass
g=9.81 #grav. acceleration
l=1 #length

th=[((rand()*2)-1)*pi] #initial angle
om=[0] #initial angular velocity
u=0 #torque

for j in range(te):
    #Euler approximation
    th.append(th[j] + ts*om[j])
    f1 = (-mu*om[j] + m*g*l*sin(th[j]) + u)/(m*(l^2))
    om.append(om[j] + ts*f1)

    #approximation 1 at mid-interval
    th2 = th[j+1] + (ts/2)*om[j+1]
    f2 = (-mu*om[j+1] + m*g*l*sin(th[j+1]) + u)/(m*(l^2))
    om2 = om[j+1] + (ts/2)*f2

    #approximation 2 at mid-interval
    th3 = th2 + (ts/2)*om2
    f3 = (-mu*om2 + m*g*l*sin(th2) + u)/( m*(l^2))
    om3 = om2 + (ts/2)*f3

    #approximation at next time step
    th4 = th3 + (ts)*om3
    f4 = (-mu*om3 + m*g*l*sin(th3) + u)/( m*(l^2))
    om4 = om3 + (ts)*f4

    dth=(om[j] + 2*om[j+1] + 2*om2 + om3)/6
    dom=(f1 + 2*f2 + 2*f3 + f4)/6
    th[j+1] = th[j] + ts*dth
    om[j+1] = om[j] + ts*dom

subplot(211),plot(th),xlabel('Angle'),ylabel('')
subplot(212),plot(om,'r'),xlabel('Angular velocity'),ylabel('')
show()

这很好用,但我觉得不太优雅,这就是为什么我决定使用odeint()函数重写它的原因:

This works wonderfully but I don't find elegant which is why I decided to rewrite it using the odeint() function:

from scipy import integrate
from scipy import *
from matplotlib.pyplot import *
##A pendulum simulation

th=((rand()*2)-1)*pi #initial angle
om=0 #initial angular velocity
u=0 #torque

y0 = [om, th] #initial values
t = linspace(0, 20, 400) #

def f(y, t):
    mu=0.1 #friction factor
    m=1 #mass
    g=9.81 #grav. acceleration
    l=1 #length

    return (y[0],
        (-mu*y[0] + m*g*l*sin(y[1]) + u)/(m*(l^2)))


r = integrate.odeint(f, y0, t)

subplot(211),plot(t,r[:,1]),xlabel('Angle'),ylabel('')
subplot(212),plot(t,r[:,0],'r'),xlabel('Angular velocity'),ylabel('')
show()

这个新版本看起来不像钟摆.谁能告诉我我在做什么错?

And this new version looks nothing like a pendulum. Can anyone tell me what I'm doing wrong?

推荐答案

您的派生函数在摆锤运动中存在错误.

You've got mistakes in your derivative function for the motion for the pendulum.

在python中,^是异或运算符,而不是幂运算符(**).因此,您将使用l ** 2.同样,AFAICT,状态向量的第一个元素实际上应该是y [1].从过去的类似工作中可以得出结论(假设m = 1,l = 1).

In python ^ is exclusive-or operator, rather than the power operator, which is **. So you'll to use l**2. Also, AFAICT, the first element of the state vector should actually be y[1]. From similar work in the past this worked (assumed m = 1 and l = 1).

def simple_pendulum_deriv(x, t, g = 9.81, mu = 0.5): 
    nx = np.zeros(2)
    nx[0] = x[1]
    nx[1] = -(g * np.sin(x[0])) - mu*x[1]
    return nx

这篇关于使用odeint()在Python中进行摆锤模拟不能完全起到摆锤的作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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