In [1]:
from IPython.core.display import HTML
def css_styling():
    styles = open("styles/example.css", "r").read()
    return HTML(styles)
css_styling()


Out[1]:

In [2]:
from __future__ import division, print_function
from IPython.core import page
page.page = print

Double Pendulum

A double pendulum is a pendulum with another pendulum attached to its end, and is a simple dynamics system that exhibits rich chaotic behavior,i.e. being sensible strongly to initial conditions:

For simplicity, assume the lengths are equal, e.g. $L_1=L_2=l$, and the weights of the balls attached at the ends of rods are also equal, $m_1=m_2=m$. Also let $(x_1,y_1)$ and $(x_2,y_2)$ are the coordinates of the first and second ball. Then the dynamics system are as follows:

\begin{eqnarray} (x_1,y_1)&=&(l\sin(\theta_1),-l \cos(\theta_1))\\ (x_2,y_2)&=&(l\sin(\theta_1) + l \sin(\theta_2),-l\cos(\theta_1) - l\cos(\theta_2))\\ \frac{d \theta_1}{d t}&=&\dot\theta_1\\ \frac{d \theta_2}{d t}&=&\dot\theta_2\\ \frac{d \dot\theta_1}{d t}&=&\ddot\theta_1\\ \frac{d \dot\theta_2}{d t}&=&\ddot\theta_2\\ \vartriangle\theta&=&\theta_2-\theta_2 \\ \ddot\theta_1&=&\frac { m l (\dot\theta_1^2)*\sin(\vartriangle\theta)*\cos(\vartriangle\theta) + m g \sin(\theta_2)*\cos(\vartriangle\theta) + m l (\dot\theta_2^2)*\sin(\vartriangle\theta) -2 m g \sin(\theta_1)} { 2 m l - m l (\cos\vartriangle\theta)^2 }\\ \ddot\theta_2&=&\frac { m l (\dot\theta_2^2)*\sin(\vartriangle\theta)*\cos(\vartriangle\theta) +2 m g \sin(\theta_1)*\cos(\vartriangle\theta) + m l (\dot\theta_1^2)*\sin(\vartriangle\theta) - m g \sin(\theta_2)} { 2 m l - m l (\cos\vartriangle\theta)^2 } \end{eqnarray} By discretization the differential operation, we could make animation of the motion of double pendulum via VPython:


In [1]:
#from pylab import *
from ivisual import *
from numpy import pi,sin,cos

from IPython.html.widgets import interact, interactive, fixed
from IPython.html import widgets
from IPython.display import clear_output, display, HTML, display_html, Javascript
from __future__ import division



In [ ]:
scene = idisplay('Double Pendulum')

scene.autoscale = 0  # disable function of auto-zooming
scene.title = 'Double pendulum'
scene.range = (2.05,2.05,2.05)

scene.background=color.white

theta1 = pi/3.0   # angle of 1st pendulum to vertical (initial value)
theta2 = pi/12.0  # angle of 2nd pendulum to vertical (initial value)

theta1_dot = 0.0  # rate of change of theta1 - initial value
theta2_dot = 0.1

g = 9.8     # acceleration of gravity
l = 1.0     # pendulum arm length 
m = 0.3     # mass of pendulum ball

ball1 = sphere(pos=vector(l*sin(theta1),-l*cos(theta1),0), radius=0.12, color=color.blue)
ball2 = sphere(pos=vector(l*sin(theta1) + l*sin(theta2),-l*cos(theta1) - l*cos(theta2),0), radius=0.12, color=color.blue ,make_trail=True)#, interval=10, retain=50)
arm1 = cylinder(pos=(0,0,0), axis=(l*sin(theta1),-l*cos(theta1),0), radius=.03, color=color.cyan)
arm2 = cylinder(pos=ball1.pos, axis=ball2.pos-ball1.pos, radius=.03, color=color.blue)

nub = sphere(pos=vector(0,0,0), radius=0.05, color=color.white)		# little white nub

time=0.0
dt=0.0001
while True:
    rate(5000)# Set number of times loop is repeated per second
    dta= theta2 - theta1# dta (short for 'delta' - the difference between the two angles)
    theta1_dot_dot = ( m*l*(theta1_dot**2.0)*sin(dta)*cos(dta) + m*g*sin(theta2)*cos(dta) + \
                       m*l*(theta2_dot**2.0)*sin(dta) -2.0*m*g*sin(theta1) ) /  \
                       ( 2.0*m*l - m*l*(cos(dta))**2.0 )# equation of motion
    theta2_dot_dot = ( -m*l*(theta2_dot**2.0)*sin(dta)*cos(dta) + 2.0*m*(g*sin(theta1)*cos(dta) \
                     - l*(theta1_dot**2.0)*sin(dta) - g*sin(theta2)) ) /  \
                     ( 2.0*m*l - m*l*(cos(dta))**2.0 )# the other equation of motion
    theta1_dot = theta1_dot + theta1_dot_dot*dt# makes sense if you think about it
    theta2_dot = theta2_dot + theta2_dot_dot*dt
    theta1 = theta1 + theta1_dot*dt
    theta2 = theta2 + theta2_dot*dt

    ball1.pos=( l*sin(theta1),-l*cos(theta1),0)
    arm1.axis = (ball1.pos.x, ball1.pos.y, 0)

    ball2.pos=(l*sin(theta1) + l*sin(theta2) , -l*cos(theta1) - l*cos(theta2), 0)
    arm2.pos = ball1.pos#(l*sin(theta1), -l*cos(theta1), 0)
    arm2.axis = ball2.pos-ball1.pos
    
    time += dt



In [ ]:
import io
import base64
from IPython.display import HTML

video = io.open('data/movies/pendulum.webm', 'r+b').read()
encoded = base64.b64encode(video)
HTML(data='''<div align="center"><video alt="test" controls>
                <source src="data:video/webm;base64,{0}" type="video/webm" />
             </video></div>'''.format(encoded.decode('ascii')))

Questions:

The double pendulum undergoes chaotic motion; in other words, the tracjectory of ball shows a sensitive dependence on initial conditions.

  1. Guess what the difference of results is between with small and big angles starting initially.
  2. Also make the trajectory of movement of first ball and observe it with it of other.