My first post on Stack Overflow, so bear with me. I have built a model of a chaotic double pendulum in python using the pymunk physics library, which in turn uses the chipmunk C library. The pendulum, being chaotic, displays extreme sensitivity to initial conditions. However, I have realized that even if I run the simulation with the exact same initial conditions (changing zero code whatsoever), the two simulations diverge fairly quickly.
There is something in my code that has the potential to yield different results each time it is run. Because the simulation is chaotic, any tiny error that isn't constant between my runs can result in large changes.
What could be causing this? I am not sure if this is a result of a small flaw in chipmunk, pymunk, or even python or my OS/PC.
EDIT:
Here is my code:
import pyglet
import pymunk
import pymunk.pyglet_util
def add_pendulum(space):
static_body = pymunk.Body()
static_body.position = 400, 400
mass = 10
inertia = pymunk.moment_for_box(mass, 5, 100)
body1 = pymunk.Body(mass, inertia)
body1.position = 350, 400
l1 = pymunk.Poly(body1, [(50, 0), (-50, 0), (-50, 5), (50, 5)])
l1.friction = 0.1
l1.collision_type = 2
pivot_joint = pymunk.PivotJoint(static_body, body1, (400, 400))
space.add(body1, l1, pivot_joint)
mass = 10
inertia = pymunk.moment_for_box(mass, 5, 100)
body2 = pymunk.Body(mass, inertia)
body2.position = 250, 400
l2 = pymunk.Poly(body2, [(50, 0), (-50, 0), (-50, 5), (50, 5)])
l2.friction = 0.1
l2.collision_type = 2
pivot_joint2 = pymunk.PivotJoint(body1, body2, (300, 402.5))
space.add(body2, l2, pivot_joint2)
# A hack to disable all collisions
nocollisions = lambda space, arbiter: False
space.add_collision_handler(2, 2, nocollisions, nocollisions, nocollisions, nocollisions)
window = pyglet.window.Window(800, 600)
space = pymunk.Space()
add_pendulum(space)
space.gravity = (0, -10)
test = [()] # A temporary hack to hide the tuple in a mutable object
def on_draw(dt): #For graphing the moving pendulum
points = test[0]
space.step(dt)
pyglet.gl.glClearColor(0, 0, 0, 1)
window.clear()
pymunk.pyglet_util.draw(space)
points += (int(tuple(space.shapes[1].get_vertices()[1])[0]), int(tuple(space.shapes[1].get_vertices()[1])[1]))
pyglet.gl.glClearColor(200, 200, 200, 1)
pyglet.graphics.draw(len(points)/2, pyglet.gl.GL_POINTS,
('v2i', points)
)
test[0] = points
pyglet.clock.schedule_interval(on_draw, 1/1000.0)
pyglet.app.run()