Uploaded by Ebitu Ukiwe

E-L Equation of Motion for Double Pendulum Python Code

advertisement
import matplotlib
matplotlib.use('TkAgg') # 'tkAgg' if Qt not present
import matplotlib.pyplot as plt
import scipy as sp
import matplotlib.animation as animation
class Pendulum:
def __init__(self, theta1, theta2, dt):
self.theta1 = theta1
self.theta2 = theta2
self.p1 = 0.0
self.p2 = 0.0
self.dt = dt
self.g = 9.81
self.length = 1.0
self.trajectory = [self.polar_to_cartesian()]
def polar_to_cartesian(self):
x1 = self.length * sp.sin(self.theta1)
y1 = -self.length * sp.cos(self.theta1)
x2 = x1 + self.length * sp.sin(self.theta2)
y2 = y1 - self.length * sp.cos(self.theta2)
print(self.theta1, self.theta2)
return sp.array([[0.0, 0.0], [x1, y1], [x2, y2]])
def evolve(self):
theta1 = self.theta1
theta2 = self.theta2
p1 = self.p1
p2 = self.p2
g = self.g
l = self.length
expr1 = sp.cos(theta1 - theta2)
expr2 = sp.sin(theta1 - theta2)
expr3 = (1 + expr2**2)
expr4 = p1 * p2 * expr2 / expr3
expr5 = (p1**2 + 2 * p2**2 - p1 * p2 * expr1) \
* sp.sin(2 * (theta1 - theta2)) / 2 / expr3**2
expr6 = expr4 - expr5
self.theta1 += self.dt * (p1 - p2 * expr1) / expr3
self.theta2 += self.dt * (2 * p2 - p1 * expr1) / expr3
self.p1 += self.dt * (-2 * g * l * sp.sin(theta1) - expr6)
self.p2 += self.dt * (
-g * l * sp.sin(theta2) + expr6)
new_position = self.polar_to_cartesian()
self.trajectory.append(new_position)
print(new_position)
return new_position
class Animator:
def __init__(self, pendulum, draw_trace=False):
self.pendulum = pendulum
self.draw_trace = draw_trace
self.time = 0.0
# set up the figure
self.fig, self.ax = plt.subplots()
self.ax.set_ylim(-2.5, 2.5)
self.ax.set_xlim(-2.5, 2.5)
# prepare a text window for the timer
self.time_text = self.ax.text(0.05, 0.95, '',
horizontalalignment='left',
verticalalignment='top',
transform=self.ax.transAxes)
# initialize by plotting the last position of the trajectory
self.line, = self.ax.plot(
self.pendulum.trajectory[-1][:, 0],
self.pendulum.trajectory[-1][:, 1],
marker='o')
# trace the whole trajectory of the second pendulum mass
if self.draw_trace:
self.trace, = self.ax.plot(
[a[2, 0] for a in self.pendulum.trajectory],
[a[2, 1] for a in self.pendulum.trajectory])
def advance_time_step(self):
while True:
self.time += self.pendulum.dt
yield self.pendulum.evolve()
def update(self, data):
self.time_text.set_text('Elapsed time: {:6.2f} s'.format(self.time))
self.line.set_ydata(data[:, 1])
self.line.set_xdata(data[:, 0])
if self.draw_trace:
self.trace.set_xdata([a[2, 0] for a in self.pendulum.trajectory])
self.trace.set_ydata([a[2, 1] for a in self.pendulum.trajectory])
return self.line,
def animate(self):
self.animation = animation.FuncAnimation(self.fig, self.update,
self.advance_time_step, interval=25, blit=False)
pendulum = Pendulum(theta1=sp.pi, theta2=sp.pi - 0.01, dt=0.01)
animator = Animator(pendulum=pendulum, draw_trace=True)
animator.animate()
plt.show()
Download