-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdouble_pendulum.py
76 lines (41 loc) · 1.97 KB
/
double_pendulum.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import numpy as np
from time import time
import scipy.integrate as integrate
from math import *
class Double_Pendulum:
def __init__(self, init_state=[120,1,-20,0], l1=1, l2 = 1, m1=1, m2 = 1, g= 10, origin=(0,0)):
self.init_state = np.asarray(init_state, dtype='float')
self.params = (l1,l2,m1,m2,g)
self.origin = origin
self.time_elapsed = 0
self.state = self.init_state*np.pi/180
def position(self):
(l1,l2,m1,m2,g) = self.params
x = np.cumsum([self.origin[0], l1*sin(self.state[0]), l2*sin(self.state[2])])
y = np.cumsum([self.origin[1], -l1*cos(self.state[0]), -l2*cos(self.state[2])])
return x,y
def energy(self):
(l1,l2,m1,m2,g) = self.params
x = np.cumsum( [l1*sin(self.state[0]), l2*sin(self.state[2]) ])
y = np.cumsum([-l1*cos(self.state[0]), -l2*cos(self.state[2])])
vx = np.cumsum([l1*self.state[1]*cos(self.state[0]), l2*self.state[3]*cos(self.state[2])])
vy = np.cumsum([l1*self.state[1]*sin(self.state[0]), l2*self.state[3]*sin(self.state[2])])
V = g * (m1*y[0] + m2*y[1])
T = 0.5*(m1*np.dot(vx,vx) + m2*np.dot(vy,vy))
E = T + K
return E
def accel(self,state,t):
(l1,l2,m1,m2,g) = self.params
acc= np.zeros_like(state)
acc[0] = state[1]
acc[2] = state[3]
cos12 = cos(state[2]- state[0])
sin12 = sin(state[2]- state[0])
den1 = (m1 + m2)*l1 - m2*l1*cos12*cos12
acc[1] = (m2 * l1 * state[1]*state[1]*sin12*cos12 + m2 * g * sin(state[2]) * cos12 + m2*l2*state[3]*state[3]*sin12 - (m1 + m2)*g*sin(state[0]))/den1
den2 = (l2/l1)*den1
acc[3] = (-m2*l2*state[3]*state[3]*sin12*cos12 + (m1 + m2)*g*sin(state[0])*cos12 - (m1 + m2)*l1*state[1]*state[1]*sin12 - (m1 + m2)*g*sin(state[2]))/den2
return acc
def step(self,dt):
self.state = integrate.odeint(self.accel, self.state, [0,dt])[1]
self.time_elapsed += dt