hoytick
hoytick

Reputation: 5

Slowing down a physics defying spring

I am doing a tutorial for my physics class.

I made a program that should have a cart on a box that is moved by a spring and should slow down to a stop, however, when I run it, it appears the spring is accelerating the cart (no matter which things I negate.)

I have heard that it might be an issue with vPython rounding numbers resulting in the acceleration, if this is true, can I just make all the numbers 1000 times larger and would it fix it?

Thanks!

from visual import *
from visual.graph import *

length=1.0

track=box(pos=vector(0,-0.05,0),
          size=(length, 0.05, 0.10),
          material=materials.bricks,)

# creates the track which is "length"meters in the
# x direction, 0.05m tall, and 1m deep
start=-0.5*length+0.05

cart=box(pos=vector(start+0.01,0,0),
         size=(0.1,0.05,0.1),
         color=color.green)
k=-4
#spring constant

sprL=(start-0.05)-0.1

#sets position of left end of spring
spring=helix(pos=(sprL,0,0),
             axis=((cart.x-0.05)-sprL,0,0),
             radius=0.02,
             color=color.yellow)

cart.m=0.70
#mass of cart
cart.vel=vector(0,0,0)
#initial velocity of cart
cart.force = k*(cart.x)*vector(1,0,0) 
#force of the spring
cart.accel=cart.force/cart.m
#acceleration of the cart taking into account the fan
t=0
deltat=0.01
end=0.5*length-0.05
#defining the end of the track
gdisplay(x=100,
         y=500,
         xtitle='time (sec)',
         ytitle='X (cyan), Px (red)')

xcurve = gcurve(color=color.cyan)
pcurve= gcurve (color=color.red)

while cart.x<end+0.01 and (cart.x>(start-0.01)):
    #we include -0.01 so the cart does not fail immediately upon start...
    cart.pos = cart.pos + cart.vel*deltat+(0.5)*(cart.accel)*deltat**2
    #x equals x naught plus v times delta t plus one half a delta t squared
    #note that ** means "to the power of"
    xcurve.plot(pos=(t,cart.x))
    pcurve.plot(pos=(t,cart.vel.x))
    cart.vel=cart.vel+cart.accel*deltat
    #new velocity is old velocity plus acceleration times time
    cart.force=k*(cart.x)*vector(1,0,0)
    cart.accel=cart.force/cart.m
    spring.axis=((cart.x-0.05)-sprL,0,0)    
    t=t+deltat
    #increments time
    rate(100)
    #rate means no more than 100 loops per second

Upvotes: 0

Views: 455

Answers (1)

SirGuy
SirGuy

Reputation: 10780

You don't have a dissipative force in your system (one that leaks energy out of it). The equation F = -kx conserves energy (this is the equation that you have somewhat circuitously encoded and represents the force that a spring exerts on an object). Note that the equation there doesn't mean that the force is always negative, it simply points in the opposite direction of cart.pos. This is how you get the sinusoidal motion.

A dissipative force is needed for the object to actually slow down. The quintessential example of this would be represented by F = -kx -bv for some constant b and v is the velocity of your object. This represents your spring being slowed down by a fluid (air/water/whatever you like).

The minimal change to your code in this case would be inside your loop:

    cart.force=(k*(cart.x)-0.1*cart.vel.x)*vector(1,0,0)

This produces an underdamped system, to try out an overdamped system you can set the 0.1 to 10 instead.

Upvotes: 2

Related Questions