Hi,
For my Thesis, I had reason to perform a number of identical
experiments with simple variations: displacements in space or time.
One set of experiments was using ODE:
I did a simple rigid body physics experiment using pyode: dropped a
box near a stationary box onto a plane. I saved an image of the rest
position of the box. The experiment is repeatable: the box lands in
same place each time relative to the stationary one.
Then I moved the whole experiment by (10,10,10) and repeated it. The
box rest position was different.
I also repeated the first experiment with the only difference being
that I programmed it to wait 8000 seconds before dropping the box.
Again the rest position was difference.
What do the developers of ODE have to say as to the cause of the
sensitivity of ODE to changes in position or time?
Attached are images of the rest position in the first and second
experiments and the code used to produce each. Also image of the time
displaced version and its code.
The hardware I was using was a VAIO notebook: intel 770 CPU with
radeon x600 GPU. For python install I followed the steps from Miriam
English:
1. installed python 2.4
python-2.4.3.msi
http://www.python.org/ftp/python/2.4.3/
2. edited autoexec.bat to add:
SET PATH=%PATH%;C:\python
SET PYTHON=C:\PYTHON\
3. installed pyOpenGL
PyOpenGL-2.0.2.01.py2.4-numpy23.exe
http://pyopengl.sourceforge.net
4. Copied glut32.dll to the C:\python\Lib\site-packages\OpenGL
directory. (This is a *crucial* step.)
glut32.dll
http://www.xmission.com/%7Enate/glut.html
5. installed OpenGLContext
OpenGLContext-2.0.0c1.win32-py2.4.exe
http://pyopengl.sourceforge.net/context/
(downloaded from http://pyopengl.sourceforge.net/ )
6. installed PIL (python Image Library)
PIL-1.1.5.win32-py2.4.exe
http://www.pythonware.com/products/pil/
7. installed pyODE
PyODE-1.1.0.win32-py2.4.exe
http://pyode.sourceforge.net/
Now I can double-click on the tutorial3.py from
http://pyode.sourceforge.net/ and it simply runs!
thanks,
chris
# pyODE example 3: Collision detection
# origin
# Originally by Matthias Baas.
# Updated by Pierre Gay to work without pygame or cgkit.
import sys, os, random, time
from math import *
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
import ode
# geometric utility functions
def scalp (vec, scal):
vec[0] *= scal
vec[1] *= scal
vec[2] *= scal
def length (vec):
return sqrt (vec[0]**2 + vec[1]**2 + vec[2]**2)
# prepare_GL
def prepare_GL():
"""Prepare drawing.
"""
# Viewport
glViewport(0,0,640,480)
# Initialize
glClearColor(0.8,0.8,0.9,0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST)
glDisable(GL_LIGHTING)
glEnable(GL_LIGHTING)
glEnable(GL_NORMALIZE)
glShadeModel(GL_FLAT)
# Projection
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective (45,1.3333,0.2,20)
# Initialize ModelView matrix
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
# Light source
glLightfv(GL_LIGHT0,GL_POSITION,[0,0,1,0])
glLightfv(GL_LIGHT0,GL_DIFFUSE,[1,1,1,1])
glLightfv(GL_LIGHT0,GL_SPECULAR,[1,1,1,1])
glEnable(GL_LIGHT0)
# View transformation
gluLookAt (2.4, 3.6, 4.8, 0.5, 0.5, 0, 0, 1, 0)
# draw_body
def draw_body(body):
"""Draw an ODE body.
"""
x,y,z = body.getPosition()
R = body.getRotation()
#rot = [R[0], R[3], R[6], 0.,
# R[1], R[4], R[7], 0.,
# R[2], R[5], R[8], 0.,
# x, y, z, 1.0]
rot = [1, 0.0, 0.0, 0.0,
0.0, 1, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
x, y, z, 1.0]
glPushMatrix()
glMultMatrixd(rot)
if body.shape=="box":
sx,sy,sz = body.boxsize
glScale(sx, sy, sz)
glutSolidCube(1)
glPopMatrix()
# create_box
def create_box(world, space, density, lx, ly, lz):
"""Create a box body and its corresponding geom."""
# Create body
body = ode.Body(world)
M = ode.Mass()
M.setBox(density, lx, ly, lz)
body.setMass(M)
# Set parameters for drawing the body
body.shape = "box"
body.boxsize = (lx, ly, lz)
# Create a box geom for collision detection
geom = ode.GeomBox(space, lengths=body.boxsize)
geom.setBody(body)
return body
# create box object
def create_object(posx, posy, posz):
"""create one box at a given position."""
global bodies, counter, objcount
body = create_box(world, space, 1000, 1.0,1.0,1.0)
body.setPosition((posx, posy, posz))
bodies.append(body)
#counter=0
objcount+=1
# drop_object
def drop_object(posx, posy, posz):
"""Drop an object into the scene."""
global bodies, counter, objcount
body = create_box(world, space, 1000, 1.0,1.0,1.0)
body.setPosition((posx, posy, posz))
bodies.append(body)
#counter=0
objcount+=1
# Collision callback
def near_callback(args, geom1, geom2):
"""Callback function for the collide() method.
This function checks if the given geoms do collide and
creates contact joints if they do.
"""
# Check if the objects do collide
contacts = ode.collide(geom1, geom2)
# Create contact joints
world,contactgroup = args
for c in contacts:
c.setBounce(0.2)
c.setMu(5000)
j = ode.ContactJoint(world, contactgroup, c)
j.attach(geom1.getBody(), geom2.getBody())
######################################################################
# Initialize Glut
glutInit ([])
# Open a window
glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE)
x = 0
y = 0
width = 640
height = 480
glutInitWindowPosition (x, y);
glutInitWindowSize (width, height);
glutCreateWindow ("(0,0,0)")
# Create a world object
world = ode.World()
world.setGravity( (0,-9.81,0) )
world.setERP(0.8)
world.setCFM(1E-5)
# Create a space object
space = ode.Space()
# Create a plane geom which prevent the objects from falling forever
floor = ode.GeomPlane(space, (0,1,0), 0)
# A list with ODE bodies
bodies = []
# A joint group for the contact joints that are generated whenever
# two bodies collide
contactgroup = ode.JointGroup()
# Some variables used inside the simulation loop
fps = 50
dt = 1.0/fps
running = True
state = 0
counter = 0
objcount = 0
lasttime = time.time()
# keyboard callback
def _keyfunc (c, x, y):
sys.exit (0)
glutKeyboardFunc (_keyfunc)
# draw callback
def _drawfunc ():
# Draw the scene
prepare_GL()
for b in bodies:
draw_body(b)
glutSwapBuffers ()
glutDisplayFunc (_drawfunc)
# idle callback
def _idlefunc ():
global counter, state, lasttime
t = dt - (time.time() - lasttime)
if (t > 0):
time.sleep(t)
counter += 1
if state==0:
create_object(0.0,0.5,0.0)
state = 1
if state==1:
if counter==20:
drop_object(1.29,5.0,0.0)
state = 2
# if objcount==30:
# state=1
# counter=0
# State 1: Explosion and pulling back the objects
#elif state==1:
# if counter==100:
# explosion()
# if counter>300:
# pull()
# if counter==500:
# counter=20
glutPostRedisplay ()
# Simulate
n = 2
for i in range(n):
# Detect collisions and create contact joints
space.collide((world,contactgroup), near_callback)
# Simulation step
world.step(dt/n)
# Remove all contact joints
contactgroup.empty()
lasttime = time.time()
glutIdleFunc (_idlefunc)
glutMainLoop ()
# pyODE example 3: Collision detection
# 1000
# Originally by Matthias Baas.
# Updated by Pierre Gay to work without pygame or cgkit.
import sys, os, random, time
from math import *
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
import ode
# geometric utility functions
def scalp (vec, scal):
vec[0] *= scal
vec[1] *= scal
vec[2] *= scal
def length (vec):
return sqrt (vec[0]**2 + vec[1]**2 + vec[2]**2)
# prepare_GL
def prepare_GL():
"""Prepare drawing.
"""
# Viewport
glViewport(0,0,640,480)
# Initialize
glClearColor(0.8,0.8,0.9,0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST)
glDisable(GL_LIGHTING)
glEnable(GL_LIGHTING)
glEnable(GL_NORMALIZE)
glShadeModel(GL_FLAT)
# Projection
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective (45,1.3333,0.2,20)
# Initialize ModelView matrix
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
# Light source
glLightfv(GL_LIGHT0,GL_POSITION,[0,0,1,0])
glLightfv(GL_LIGHT0,GL_DIFFUSE,[1,1,1,1])
glLightfv(GL_LIGHT0,GL_SPECULAR,[1,1,1,1])
glEnable(GL_LIGHT0)
# View transformation
gluLookAt (12.4, 13.6, 14.8, 10.5, 10.5, 10, 0, 1, 0)
# draw_body
def draw_body(body):
"""Draw an ODE body.
"""
x,y,z = body.getPosition()
R = body.getRotation()
#rot = [R[0], R[3], R[6], 0.,
# R[1], R[4], R[7], 0.,
# R[2], R[5], R[8], 0.,
# x, y, z, 1.0]
rot = [1, 0.0, 0.0, 0.0,
0.0, 1, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
x, y, z, 1.0]
glPushMatrix()
glMultMatrixd(rot)
if body.shape=="box":
sx,sy,sz = body.boxsize
glScale(sx, sy, sz)
glutSolidCube(1)
glPopMatrix()
# create_box
def create_box(world, space, density, lx, ly, lz):
"""Create a box body and its corresponding geom."""
# Create body
body = ode.Body(world)
M = ode.Mass()
M.setBox(density, lx, ly, lz)
body.setMass(M)
# Set parameters for drawing the body
body.shape = "box"
body.boxsize = (lx, ly, lz)
# Create a box geom for collision detection
geom = ode.GeomBox(space, lengths=body.boxsize)
geom.setBody(body)
return body
# create box object
def create_object(posx, posy, posz):
"""create one box at a given position."""
global bodies, counter, objcount
body = create_box(world, space, 1000, 1.0,1.0,1.0)
body.setPosition((posx, posy, posz))
bodies.append(body)
#counter=0
objcount+=1
# drop_object
def drop_object(posx, posy, posz):
"""Drop an object into the scene."""
global bodies, counter, objcount
body = create_box(world, space, 1000, 1.0,1.0,1.0)
body.setPosition((posx, posy, posz))
bodies.append(body)
#counter=0
objcount+=1
# Collision callback
def near_callback(args, geom1, geom2):
"""Callback function for the collide() method.
This function checks if the given geoms do collide and
creates contact joints if they do.
"""
# Check if the objects do collide
contacts = ode.collide(geom1, geom2)
# Create contact joints
world,contactgroup = args
for c in contacts:
c.setBounce(0.2)
c.setMu(5000)
j = ode.ContactJoint(world, contactgroup, c)
j.attach(geom1.getBody(), geom2.getBody())
######################################################################
# Initialize Glut
glutInit ([])
# Open a window
glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE)
x = 0
y = 0
width = 640
height = 480
glutInitWindowPosition (x, y);
glutInitWindowSize (width, height);
glutCreateWindow ("(10,10,10)")
# Create a world object
world = ode.World()
world.setGravity( (0,-9.81,0) )
world.setERP(0.8)
world.setCFM(1E-5)
# Create a space object
space = ode.Space()
# Create a plane geom which prevent the objects from falling forever
floor = ode.GeomPlane(space, (0,1,0), 10)
# A list with ODE bodies
bodies = []
# A joint group for the contact joints that are generated whenever
# two bodies collide
contactgroup = ode.JointGroup()
# Some variables used inside the simulation loop
fps = 50
dt = 1.0/fps
running = True
state = 0
counter = 0
objcount = 0
lasttime = time.time()
# keyboard callback
def _keyfunc (c, x, y):
sys.exit (0)
glutKeyboardFunc (_keyfunc)
# draw callback
def _drawfunc ():
# Draw the scene
prepare_GL()
for b in bodies:
draw_body(b)
glutSwapBuffers ()
glutDisplayFunc (_drawfunc)
# idle callback
def _idlefunc ():
global counter, state, lasttime
t = dt - (time.time() - lasttime)
if (t > 0):
time.sleep(t)
counter += 1
if state==0:
create_object(10.0,10.5,10.0)
state = 1
if state==1:
if counter==20:
drop_object(11.29,15.0,10.0)
state = 2
# if objcount==30:
# state=1
# counter=0
# State 1: Explosion and pulling back the objects
#elif state==1:
# if counter==100:
# explosion()
# if counter>300:
# pull()
# if counter==500:
# counter=20
glutPostRedisplay ()
# Simulate
n = 2
for i in range(n):
# Detect collisions and create contact joints
space.collide((world,contactgroup), near_callback)
# Simulation step
world.step(dt/n)
# Remove all contact joints
contactgroup.empty()
lasttime = time.time()
glutIdleFunc (_idlefunc)
glutMainLoop ()
# pyODE example 3: Collision detection
# origin
# Originally by Matthias Baas.
# Updated by Pierre Gay to work without pygame or cgkit.
import sys, os, random, time
from math import *
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
import ode
# geometric utility functions
def scalp (vec, scal):
vec[0] *= scal
vec[1] *= scal
vec[2] *= scal
def length (vec):
return sqrt (vec[0]**2 + vec[1]**2 + vec[2]**2)
# prepare_GL
def prepare_GL():
"""Prepare drawing.
"""
# Viewport
glViewport(0,0,640,480)
# Initialize
glClearColor(0.8,0.8,0.9,0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST)
glDisable(GL_LIGHTING)
glEnable(GL_LIGHTING)
glEnable(GL_NORMALIZE)
glShadeModel(GL_FLAT)
# Projection
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective (45,1.3333,0.2,20)
# Initialize ModelView matrix
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
# Light source
glLightfv(GL_LIGHT0,GL_POSITION,[0,0,1,0])
glLightfv(GL_LIGHT0,GL_DIFFUSE,[1,1,1,1])
glLightfv(GL_LIGHT0,GL_SPECULAR,[1,1,1,1])
glEnable(GL_LIGHT0)
# View transformation
gluLookAt (2.4, 3.6, 4.8, 0.5, 0.5, 0, 0, 1, 0)
# draw_body
def draw_body(body):
"""Draw an ODE body.
"""
x,y,z = body.getPosition()
R = body.getRotation()
#rot = [R[0], R[3], R[6], 0.,
# R[1], R[4], R[7], 0.,
# R[2], R[5], R[8], 0.,
# x, y, z, 1.0]
rot = [1, 0.0, 0.0, 0.0,
0.0, 1, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
x, y, z, 1.0]
glPushMatrix()
glMultMatrixd(rot)
if body.shape=="box":
sx,sy,sz = body.boxsize
glScale(sx, sy, sz)
glutSolidCube(1)
glPopMatrix()
# create_box
def create_box(world, space, density, lx, ly, lz):
"""Create a box body and its corresponding geom."""
# Create body
body = ode.Body(world)
M = ode.Mass()
M.setBox(density, lx, ly, lz)
body.setMass(M)
# Set parameters for drawing the body
body.shape = "box"
body.boxsize = (lx, ly, lz)
# Create a box geom for collision detection
geom = ode.GeomBox(space, lengths=body.boxsize)
geom.setBody(body)
return body
# create box object
def create_object(posx, posy, posz):
"""create one box at a given position."""
global bodies, counter, objcount
body = create_box(world, space, 1000, 1.0,1.0,1.0)
body.setPosition((posx, posy, posz))
bodies.append(body)
#counter=0
objcount+=1
# drop_object
def drop_object(posx, posy, posz):
"""Drop an object into the scene."""
global bodies, counter, objcount
body = create_box(world, space, 1000, 1.0,1.0,1.0)
body.setPosition((posx, posy, posz))
bodies.append(body)
#counter=0
objcount+=1
# Collision callback
def near_callback(args, geom1, geom2):
"""Callback function for the collide() method.
This function checks if the given geoms do collide and
creates contact joints if they do.
"""
# Check if the objects do collide
contacts = ode.collide(geom1, geom2)
# Create contact joints
world,contactgroup = args
for c in contacts:
c.setBounce(0.2)
c.setMu(5000)
j = ode.ContactJoint(world, contactgroup, c)
j.attach(geom1.getBody(), geom2.getBody())
######################################################################
# Initialize Glut
glutInit ([])
# Open a window
glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE)
x = 0
y = 0
width = 640
height = 480
glutInitWindowPosition (x, y);
glutInitWindowSize (width, height);
glutCreateWindow ("(0,0,0), startTime=8000")
# Create a world object
world = ode.World()
world.setGravity( (0,-9.81,0) )
world.setERP(0.8)
world.setCFM(1E-5)
# Create a space object
space = ode.Space()
# Create a plane geom which prevent the objects from falling forever
floor = ode.GeomPlane(space, (0,1,0), 0)
# A list with ODE bodies
bodies = []
# A joint group for the contact joints that are generated whenever
# two bodies collide
contactgroup = ode.JointGroup()
# Some variables used inside the simulation loop
fps = 50
dt = 1.0/fps
running = True
state = 0
counter = 0
objcount = 0
lasttime = time.time()
# keyboard callback
def _keyfunc (c, x, y):
sys.exit (0)
glutKeyboardFunc (_keyfunc)
# draw callback
def _drawfunc ():
# Draw the scene
prepare_GL()
for b in bodies:
draw_body(b)
glutSwapBuffers ()
glutDisplayFunc (_drawfunc)
# idle callback
def _idlefunc ():
global counter, state, lasttime
t = dt - (time.time() - lasttime)
if (t > 0):
time.sleep(t)
counter += 1
if state==0:
create_object(0.0,0.5,0.0)
state = 1
if state==1:
#20000 is different
#10000 is different a little less
#7000 no diff from 0 time
#5000 no diff from 0 time
if counter==8000:
drop_object(1.29,5.0,0.0)
state = 2
# if objcount==30:
# state=1
# counter=0
# State 1: Explosion and pulling back the objects
#elif state==1:
# if counter==100:
# explosion()
# if counter>300:
# pull()
# if counter==500:
# counter=20
glutPostRedisplay ()
# Simulate
n = 2
for i in range(n):
# Detect collisions and create contact joints
space.collide((world,contactgroup), near_callback)
# Simulation step
world.step(dt/n)
# Remove all contact joints
contactgroup.empty()
lasttime = time.time()
glutIdleFunc (_idlefunc)
glutMainLoop ()