pendulum_ode.py 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. """Double pendulum from ODE integration"""
  2. # Copyright (c) 2018, N. Rougier, https://github.com/rougier/pendulum
  3. # http://www.physics.usyd.edu.au/~wheat/dpend_html/solve_dpend.c
  4. # Adapted for vedo by M. Musy, 2021
  5. from scipy import integrate
  6. from vedo import *
  7. G = 9.81 # acceleration due to gravity, in m/s^2
  8. L1 = 1.0 # length of pendulum 1 in m
  9. L2 = 1.0 # length of pendulum 2 in m
  10. M1 = 1.0 # mass of pendulum 1 in kg
  11. M2 = 1.0 # mass of pendulum 2 in kg
  12. th1= 120 # initial angles (degrees)
  13. th2= -20
  14. w1 = 0 # initial angular velocities (degrees per second)
  15. w2 = 0
  16. dt = 0.015
  17. def derivs(state, t):
  18. dydx = np.zeros_like(state)
  19. dydx[0] = state[1]
  20. a = state[2] - state[0]
  21. sina, cosa = sin(a), cos(a)
  22. den1 = (M1 + M2)*L1 - M2*L1*cosa*cosa
  23. dydx[1] = (M2*L1*state[1]*state[1]*sina*cosa +
  24. M2*G*sin(state[2])*cosa +
  25. M2*L2*state[3]*state[3]*sina -
  26. (M1+M2)*G*sin(state[0]) )/den1
  27. dydx[2] = state[3]
  28. den2 = (L2/L1)*den1
  29. dydx[3] = (-M2*L2*state[3]*state[3]*sina*cosa +
  30. (M1+M2)*G*sin(state[0])*cosa -
  31. (M1+M2)*L1*state[1]*state[1]*sina -
  32. (M1+M2)*G*sin(state[2]) )/den2
  33. return dydx
  34. t = np.arange(0.0, 10.0, dt)
  35. state = np.radians([th1, w1, th2, w2])
  36. y = integrate.odeint(derivs, state, t)
  37. P1 = np.dstack([L1*sin(y[:,0]), -L1*cos(y[:,0])]).squeeze()
  38. P2 = P1 + np.dstack([L2*sin(y[:,2]), -L2*cos(y[:,2])]).squeeze()
  39. plt = Plotter(interactive=False, size=(900,700),)
  40. ax = Axes(xrange=(-2,2), yrange=(-2,1), htitle=__doc__)
  41. for i in progressbar(len(t)):
  42. j = max(i- 5,0)
  43. k = max(i-10,0)
  44. l1 = Line([[0,0], P1[i], P2[i]]).lw(7).c("blue2", 1.0)
  45. l2 = Line([[0,0], P1[j], P2[j]]).lw(6).c("blue2", 0.4)
  46. l3 = Line([[0,0], P1[k], P2[k]]).lw(5).c("blue2", 0.2)
  47. plt.clear().show(l1, l2, l3, ax, zoom=1.4)
  48. plt.interactive().close()