Damping in cpDampedSpring

Official forum for the Chipmunk2D Physics Library.
Post Reply
davesa
Posts: 2
Joined: Tue Jun 30, 2009 9:52 am
Contact:

Damping in cpDampedSpring

Post by davesa »

Hi,

I've just started playing around with pygame and pymunk/chipmunk and have started hacking the pymunk example (http://code.google.com/p/pymunk/wiki/Sl ... ntsExample). I'm trying to make an circle object return to it original position after being disturbed by a force. Unfortunately no matter what I set the damped_spring arguments to the oscillation either continue indefinitely at the same amplitude or increases in amplitude. My question is what do I need to set the arguments to in order to make the spring critically damped or at least eventually damp out all motion.

I'm new to pygame and to physics engines in general so I could be using the libraries incorrectly. Any pointers would be greatly appreciated. I have listed my test program below.

Thanks,

David

Code: Select all

import sys, random
import pygame
from pygame.locals import *
from pygame.color import *
import pymunk as pm
import math

def add_planet(space, x, y):
    mass = 1
    radius = 14
    inertia = pm.moment_for_circle(mass, 0, radius, (0,0))
    body = pm.Body(mass, inertia)
    body.position = x, y
    shape = pm.Circle(body, radius, (0,0))
    space.add(body, shape)
    return shape, body

def add_centre(space, x, y):
    mass = pm.inf
    inertia = pm.inf
    body = pm.Body(mass, inertia)
    body.position = x, y
    shape = pm.Circle(body, 14, (0,0))
    space.add(body, shape)
    return shape, body

def draw_planet(screen, planet):
    p = int(planet.body.position.x), 600-int(planet.body.position.y)
    pygame.draw.circle(screen, THECOLORS["blue"], p, int(planet.radius), 2)

def main():
    pygame.init()
    screen = pygame.display.set_mode((600, 600))
    pygame.display.set_caption("objects in space")
    clock = pygame.time.Clock()
    running = True
    
    pm.init_pymunk()
    space = pm.Space()
    space.gravity = (0.0, 0.0)
    
    planets = []
    planets.append(add_planet(space, 100, 300))
    planets.append(add_planet(space, 500, 300))
    planets.append(add_centre(space, 300, 300))

    ticks_to_impulse = 25
    while running:
        for event in pygame.event.get():
            if event.type == QUIT:
                running = False
            elif event.type == KEYDOWN and event.key == K_ESCAPE:
                running = False
        
        ticks_to_impulse -= 1
        if ticks_to_impulse == 0:
            planets[0][1].apply_impulse((100,0))
        if ticks_to_impulse < 0:
            planets[0][1].apply_impulse((0,0))

        screen.fill(THECOLORS["black"])
        
        [draw_planet(screen, planet) for planet, body in planets]

        # apply spring
        rlen = 200.0
        k = 0.5
        dmp = 2.00
        planets[0][1].damped_spring(planets[2][1], (0,0), (0,0), rlen, k, dmp, 1/50.0)
        space.step(1/50.0)
        
        pygame.display.flip()
        clock.tick(50)
        
if __name__ == '__main__':
    sys.exit(main())
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Damping in cpDampedSpring

Post by slembcke »

I don't see where you are resetting the forces. Chipmunk does not reset forces when stepping. In this case, you need to reset the forces on the object before applying the spring force function again.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
davesa
Posts: 2
Joined: Tue Jun 30, 2009 9:52 am
Contact:

Re: Damping in cpDampedSpring

Post by davesa »

Hi Slembcke,

Thanks for the reply. I added the line "planets[0][1].reset_forces()" directly after the line "while running:". I think the pymunk example I used as a starting point had gravity as its only force so it didn't need to reset any forces. Thanks for your reply I can now continue on with my experimentation :)

David

Code: Select all

while running:
    planets[0][1].reset_forces()
    for event in pygame.event.get():
        if event.type == QUIT:
            running = False
        elif event.type == KEYDOWN and event.key == K_ESCAPE:
            running = False
Post Reply

Who is online

Users browsing this forum: No registered users and 8 guests