Saturday, March 20, 2010

AP Physics: Physical Pendula in Visual Python


I spent some time today creating a simple physical pendulum in Visual Python. The pendulum swings back and forth for 10 seconds, and generates a sinusoidal position graph as a result. See screenshot above. Code follows:

from __future__ import division # makes sure is decimal and not integer
from visual import *
from visual.graph import * # graphing capability

pendulum = frame()
bob = sphere(frame = pendulum, pos = (0,-1,0), radius = 0.15, color = color.red)
rod = cylinder(frame = pendulum, pos = (0,0,0), axis = (0,-1,0), length = 0.1, radius = 0.02, color = color.blue)

#starting position
startAngle = 30
theta = math.radians(startAngle)
pendulum.rotate(angle = theta, axis = (0,0,1), origin = (0,0,0))
angVel = 0
angAcc = 0

# masses
bob.mass = 0.100
rod.mass = 0.050

# moments
bob.momentArm = rod.length + bob.radius
cmLength = ( (bob.momentArm * bob.mass) + ( (rod.length / 2.0) * rod.mass) ) / (bob.mass + rod.mass)
rotInertia = (rod.mass*rod.length*rod.length/3.0) + (bob.mass*bob.momentArm*bob.momentArm)

# set up angle graph
graph1 = gdisplay(x=150, y=600, width=400, height=300,
title='Angle vs. Time', xtitle='time (s)', ytitle='angle (rad)',
xmax=10., xmin=0., ymax=1.1*theta, ymin=-1.1*theta,
foreground=color.black, background=color.white)
acurve = gcurve(gdisplay = graph1, color = color.black)

# time
time = 0
dt = 0.01

while time <>
rate(100)
time += dt
gravTorque = -1 * cmLength * (bob.mass + rod.mass) * 9.8 * sin(theta)
angAcc = gravTorque / rotInertia
angVel += angAcc * dt
theta += angVel * dt
pendulum.rotate(angle = angVel * dt, axis = (0,0,1), origin = (0,0,0))
acurve.plot(pos = (time, theta))


1 comment:

  1. Very informative post indeed.. being enrolled in: http://www.wiziq.com/course/6911-advanced-placement-ap-physics
    I was looking for such articles online to assist me and also your post helped me a lot.:)

    ReplyDelete