In this lab we will simulate the behavior of a simple pendulum (i.e. with no forces other than gravity and the pendulum arm's tension acting on it). The differential equation describing the motion of a pendulum shown below can be easily derived from Newton's Laws, but has no closed form solution. Therefore a simplifying assumption is often made that the displacement angle of the pendulum (how wide it swings up from vertical) is very small which allows a reasonable approximation to be made by simplifying the equation. With this simplifying assumption the equation becomes that of a simple harmonic oscillator and is easily solvable with a cosine function as the solution.
d2θ/dt2 -(g/L)sin(θ) = 0
Where g is acceleration due to gravity, L is the length of the pendulum's arm and θ is the angular displacement from vertical.
But real pendulums have much more interesting behavior. With a computer program it becomes possible to explore this behavior by numerically solving the of the equation with Euler's method and simulating the result.
A pendulum can be started by displacing it and either dropping it or giving it a push to make it go higher. If it is pushed hard enough, it can actually loop around in a complete circle. If it has a stiff rod for an arm, and if it is pushed pushed just the right amount, it could theoretically be made to balance exactly straight over its pivot point. Our ultimate goal in this lab is to find within 3 decimal places what starting velocity we need to release our simulated pendulum to get it to balance on top. Chances are you will not be able to find an exact value for that critical velocity, but you can find two numbers, one a little too fast and one a little to slow, that only differ in the fourth decimal place.
You only need to turn in a listing of your final program or as much as you were able to get working. Please turn something in even if you got stuck so we can help you get unstuck. The more you can write about what you were having trouble with or what lame Python error message you couldn't get past the better
This version starts out with a binary search to find the closest possible approximation to the critical initial ω to balance the pendulum at the top. Once it has computed this, it runs a simulation showing the pendulum and a graph of θ versus time. The simulation runs long enough to see that the approximation still is not exact and the pendulum eventually goes over the top. Not that because of this sensitivity, chosing different dt will result in slightly different answers for the critical ω.
from visual.graph import * graphics=False # turn graphing code on or off armlength=2 g = 9.8 # acceleration due to gravity t=0 #draw the pendulum graphics def make_pendulum(): global pendulum top=vector(0,20,0) basesize=vector(.2,.1,.2) base = box(size=basesize, pos=top+vector(0,basesize.y/2.0,0)) pendulum = frame(pos=top,axis=(0,-1,0)) arm = cylinder(frame=pendulum, length=armlength, radius=0.01) bob = sphere(frame=pendulum, pos=(armlength,0,0), color=color.red, radius=.1) scene.center = (0,top.y-armlength/2.0,0) scene.range = armlength #this function causes the graphics windows to appear def enable_graphics(): global graphics, thetagraph, frame_rate graphics=True thetagraph=gdisplay(title="Theta") make_pendulum() frame_rate=24 #theta is angle relative to straight down def setPendulumAngle(pendulum,theta): x=armlength*sin(theta) y=-armlength*cos(theta) pendulum.axis=(x,y,0) #Run a complete simulation and return the final theta def simulate(theta,w,time_limit=4,dt=1.0/128): t=0 theta_max=0 # maximum value of theta reached so far if graphics: thetacurve=gcurve(gdisplay=thetagraph) while t<=time_limit: #Euler's method a = (-g/armlength)*sin(theta) w += a*dt theta += w*dt t += dt if theta>theta_max: theta_max=theta if graphics: if t % (1.0/frame_rate) < dt: setPendulumAngle(pendulum,theta) thetacurve.plot(pos=(t,theta)) rate(frame_rate) return theta_max dt=1.0/256 upper=5 lower = w_estimate = 3 # starting guess count=0 last_estimate=0 while last_estimate != w_estimate: last_estimate = w_estimate theta_max = simulate(0,w_estimate,time_limit=30,dt=dt) #do a binary search looking to see if pendulum went over the top # or swung back if theta_max > 2*pi: upper = w_estimate print "Overshot" else: lower = w_estimate print "Undershot" w_estimate = (upper+lower)/2.0 count += 1 print "trial:",count,"estimated w:", w_estimate enable_graphics() simulate(0,w_estimate,time_limit=30,dt=dt) import sys sys.exit(0)