Grifter

Lagrangian double pendulum with T/U statistic plotting

May 11th, 2014
194
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.19 KB | None | 0 0
  1. from visual import *
  2. from math import sin,cos,pi
  3. from random import randint
  4. import matplotlib.pyplot as plt
  5.  
  6. class pendulum():
  7.     def __init__(self):
  8.         self.simlength = int(input('How many seconds should the simulation run for?: '))
  9.         self.disp = display(title='Double pendulum', x=0, y=0, width=1920, height=1080, background=(0,0,0))
  10.         self.c = sphere(pos = (0,0,0), radius = 0.3)
  11.         self.l1 = randint(3,7)
  12.         self.l2 = randint(3,7)
  13.         self.disp.range = 50
  14.         self.m1 = 1
  15.         self.m2 = 2
  16.         self.theta1 = (randint(0,100)/100)*2*pi
  17.         self.theta2 = (randint(0,100)/100)*2*pi
  18.         self.vtheta1 = randint(-3,3)
  19.         self.vtheta2 = randint(-3,3)
  20.         self.atheta1 = 0
  21.         self.atheta2 = 0
  22.         self.g = 9.81
  23.         self.dt = 1/30
  24.         self.mass1 = sphere(pos = (self.l1*sin(self.theta1),-self.l1*cos(self.theta1),0), radius = ((3*self.m1)/(4*pi))**(1/3), color = color.red, make_trail = True, retain = 500)
  25.         self.mass2 = sphere(pos = (self.l1*sin(self.theta1)+self.l2*(self.theta2),-self.l1*cos(self.theta1)-self.l2*cos(self.theta2),0), radius = ((3*self.m2)/(4*pi))**(1/3), color = color.blue, make_trail = True, retain = 500)
  26.         self.stick1 = cylinder(pos=(0,0,0), axis = self.mass1.pos, radius = 0.1)
  27.         self.stick2 = cylinder(pos=self.mass1.pos, axis = self.mass2.pos-self.mass1.pos, radius = 0.1)
  28.         self.stats = [[],[],[],[],[],[]]
  29.         self.t=0
  30.  
  31.     def acc1(self):
  32.         self.atheta1 = (-self.g*(2*self.m1+self.m2)*sin(self.theta1) -self.m2*sin(self.theta1-2*self.theta2)-2*sin(self.theta1-self.theta2)*self.m2*((self.vtheta2**2)*self.l2+(self.vtheta1**2)*self.l1*cos(self.theta1-self.theta2)))/(self.l1*(2*self.m1+self.m2-self.m2*cos(2*self.theta1+2*self.theta2)))
  33.  
  34.     def acc2(self):
  35.         self.atheta2 = (2*sin(self.theta1-self.theta2)*((self.vtheta1**2)*self.l1*(self.m1+self.m2)+self.g*(self.m1+self.m2)*cos(self.theta1)+(self.vtheta2**2)*self.l2*self.m2*cos(self.theta1-self.theta2))/(self.l2*(2*self.m1 +self.m2-self.m2*cos(2*self.theta1-2*self.theta2))))
  36.    
  37.     def move(self):
  38.         self.vtheta1 += self.atheta1*self.dt
  39.         self.vtheta2 += self.atheta2*self.dt
  40.         self.theta1 += self.vtheta1*self.dt
  41.         self.theta2 += self.vtheta2*self.dt
  42.  
  43.     def anglim(self):
  44.         if self.theta1 >= 2*pi:
  45.             self.theta1 -= 2*pi
  46.         if self.theta1 <0:
  47.             self.theta1 += 2*pi
  48.         if self.theta2 >= 2*pi:
  49.             self.theta2 -= 2*pi
  50.         if self.theta2 <0:
  51.             self.theta2 += 2*pi
  52.  
  53.     def convert(self):
  54.         self.mass1.pos = (self.l1*sin(self.theta1),-self.l1*cos(self.theta1),0)
  55.         self.mass2.pos = (self.l1*sin(self.theta1)+self.l2*sin(self.theta2),-self.l1*cos(self.theta1)-self.l2*cos(self.theta2),0)
  56.         self.stick1.axis = self.mass1.pos
  57.         self.stick2.pos = self.mass1.pos
  58.         self.stick2.axis = self.mass2.pos-self.mass1.pos
  59.  
  60.     def telemetry(self):
  61.         self.stats[0].append(self.t)
  62.         self.stats[1].append(0.5*self.m1*(self.l1**2)*(self.vtheta1**2))
  63.         self.stats[2].append(self.l1*self.m1*self.g*cos(self.theta1))
  64.         self.stats[3].append(0.5*self.m2*((self.l1**2)*(self.vtheta1**2)+(self.l2**2)*(self.vtheta2**2)+(2*self.l1*self.l2*self.vtheta1*self.vtheta2*cos(self.theta1-self.theta2))))
  65.         self.stats[4].append(-self.l1*self.m2*self.g*cos(self.theta1)-self.l2*self.m2*self.g*cos(self.theta2))
  66.  
  67.     def step(self):
  68.         self.acc1()
  69.         self.acc2()
  70.         self.move()
  71.         self.anglim()
  72.         self.convert()
  73.         if self.simlength > 0:
  74.             self.telemetry()
  75.         self.t += self.dt
  76. p = pendulum()
  77.  
  78. while True:
  79.     rate(1/p.dt)
  80.     p.step()
  81.     if p.t >= p.simlength and p.simlength != 0:
  82.         break
  83. plt.figure(1)
  84. #plt.xkcd()
  85.  
  86. plt.subplot(211)
  87. plt.xlabel('Time (s)')
  88. plt.ylabel('Energy (J)')
  89. plt.title('Mass 1')
  90. plt.grid(True)
  91. plt.plot(p.stats[0],p.stats[1],p.stats[0],p.stats[2])
  92. plt.legend(['Kinetic Energy','Potential Energy'])
  93.  
  94. plt.subplot(212)
  95. plt.xlabel('Time (s)')
  96. plt.ylabel('Energy (J)')
  97. plt.title('Mass 2')
  98. plt.grid(True)
  99. plt.plot(p.stats[0],p.stats[3],p.stats[0],p.stats[4])
  100. plt.legend(['Kinetic Energy','Potential Energy'])
  101.  
  102. plt.show()
Advertisement
Add Comment
Please, Sign In to add comment