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 ()

Reply via email to