1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556 |
- """Double pendulum from ODE integration"""
- # Copyright (c) 2018, N. Rougier, https://github.com/rougier/pendulum
- # http://www.physics.usyd.edu.au/~wheat/dpend_html/solve_dpend.c
- # Adapted for vedo by M. Musy, 2021
- from scipy import integrate
- from vedo import *
- G = 9.81 # acceleration due to gravity, in m/s^2
- L1 = 1.0 # length of pendulum 1 in m
- L2 = 1.0 # length of pendulum 2 in m
- M1 = 1.0 # mass of pendulum 1 in kg
- M2 = 1.0 # mass of pendulum 2 in kg
- th1= 120 # initial angles (degrees)
- th2= -20
- w1 = 0 # initial angular velocities (degrees per second)
- w2 = 0
- dt = 0.015
- def derivs(state, t):
- dydx = np.zeros_like(state)
- dydx[0] = state[1]
- a = state[2] - state[0]
- sina, cosa = sin(a), cos(a)
- den1 = (M1 + M2)*L1 - M2*L1*cosa*cosa
- dydx[1] = (M2*L1*state[1]*state[1]*sina*cosa +
- M2*G*sin(state[2])*cosa +
- M2*L2*state[3]*state[3]*sina -
- (M1+M2)*G*sin(state[0]) )/den1
- dydx[2] = state[3]
- den2 = (L2/L1)*den1
- dydx[3] = (-M2*L2*state[3]*state[3]*sina*cosa +
- (M1+M2)*G*sin(state[0])*cosa -
- (M1+M2)*L1*state[1]*state[1]*sina -
- (M1+M2)*G*sin(state[2]) )/den2
- return dydx
- t = np.arange(0.0, 10.0, dt)
- state = np.radians([th1, w1, th2, w2])
- y = integrate.odeint(derivs, state, t)
- P1 = np.dstack([L1*sin(y[:,0]), -L1*cos(y[:,0])]).squeeze()
- P2 = P1 + np.dstack([L2*sin(y[:,2]), -L2*cos(y[:,2])]).squeeze()
- plt = Plotter(interactive=False, size=(900,700),)
- ax = Axes(xrange=(-2,2), yrange=(-2,1), htitle=__doc__)
- for i in progressbar(len(t)):
- j = max(i- 5,0)
- k = max(i-10,0)
- l1 = Line([[0,0], P1[i], P2[i]]).lw(7).c("blue2", 1.0)
- l2 = Line([[0,0], P1[j], P2[j]]).lw(6).c("blue2", 0.4)
- l3 = Line([[0,0], P1[k], P2[k]]).lw(5).c("blue2", 0.2)
- plt.clear().show(l1, l2, l3, ax, zoom=1.4)
- plt.interactive().close()
|