Sign in to follow this  
Eldritch

ODE Runtime errors I cannot figure out

Recommended Posts

Been doing a simple application utilizing the seemingly powerful ODE stuff for simulating physics. When I attempt to run this application, I get some really strange feedback from some ODE CPP-file I don't even have: Here is what I get: #1
dMassSetBox(&m, 0.5, sides[0], sides[1], sides[2]);

The above line generates what seems to be a warning: "ODE Message 2: mass must be > 0 (\radonlabs\code\ode-0.5\ode\src\mass.cpp:39)" "m" is my dMass variable, and the sides are all set to 2.0. #2
dBodySetMass(object.body, &m);

The above line generates another warning: "ODE Message 2: inertia must be positive definite (\radonlabs\code\ode-0.5\ode\src\ode.cpp:410)" #3
dWorldQuickStep(world, 0.05);

Next comes the line that I cannot get past as the program crashes, producing the following error in a messagebox: "ODE INTERNAL ERROR 2: stepsize must be > 0 (\radonlabs\code\ode-0.5\src\ode.cpp:1263)" And boom.. down she goes.. I cannot for the love of anything holy understand these errors. And the referenced CPP-files are something I cannot figure out either.. I don't have them..

Share this post


Link to post
Share on other sites
If you don't have the source files download them here.
You seem to be getting some runtime warnings in debug mode.
For example here is why you're geting the first error:

From ode\src\mass.cpp(34):
static int checkMass (dMass *m)
{
int i;

if (m->mass <= 0) {
dDEBUGMSG ("mass must be > 0");
return 0;
}
...
It has detected 'mass' was set to a value less or equal to zero. Double check your mass value and all other values indicated in the warnings. Depending on compiler, floating-point types may need an 'f' appended to the number(0.5 => 0.5f).

Good Luck.

Share this post


Link to post
Share on other sites
I was hoping that the dMassSetBox() method was setting the mass for me.. it does not matter if I set the mass before or after that call, I still get the same problem. The mass is a dReal type, and I tried typecasting the 0.5 to dReal, still the same thing.. though, that parameter is called "density".

These are very strange errors as all tutorials I have looked at have used the very same setup, and they claim it to work :(

Share this post


Link to post
Share on other sites
Here's the code for those interested (very ugly, tried to make it fast without any particular object-orientation as I am learning ODE).

I have marked the lines that causes warnings and errors.


#include <windows.h>
#include "gl/gl.h"
#include "glut.h"
#include "ode/ode.h"

// SimpleObject structure.
struct SimpleObject
{
dBodyID body;
dGeomID geom;
};

// Globals.
float GeomMatrix[12]; // Our geometry matrix.
SimpleObject object; // Our simple object.
dWorldID world; // Our world.
dSpaceID space; // Our space.
dJointGroupID contactgroup; // Our contact group.

// Prototypes.
void InitOde(void);
void CloseOde(void);
void SimLoop(void);
void nearCallback(void *data, dGeomID o1, dGeomID o2);
void DrawGeom(dGeomID g, const dReal *pos, const dReal *R, int show_aabb);
void DrawBox(dReal sides[3], const dReal *pos, const dReal *R);
void Display(void);

void main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100, 100);
glutInitWindowSize(320, 320);
glutCreateWindow("Open Dynamics Engine Test");

InitOde();
glPointSize(5.0f);

glutDisplayFunc(Display);
glutMainLoop();
}

void Display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
SimLoop();
glFlush();
}

void InitOde(void)
{
// World settings.

world = dWorldCreate(); // Create world.
space = dSimpleSpaceCreate(0); // Create space.
contactgroup = dJointGroupCreate(0); // Create contact joint group.
dCreatePlane(space, 0, 1, 0, 0); // Create a simple plane.
dWorldSetGravity(world, 0, -1, 0); // Setup gravity.
dWorldSetERP(world, 0.2); // Setup Error Reduction Parameter.
dWorldSetCFM(world, 1e-5); // Setup Constraint Force Mixing.
dWorldSetContactMaxCorrectingVel(world, 0.9); // Set max velocity for when joints are broken.
dWorldSetContactSurfaceLayer(world, 0.001); // Set depth of surface collision between objects.
dWorldSetAutoDisableFlag(world, 1); // Enable auto-disable of resting objects.

// Body settings.

// Create new body for object and attach to world.
object.body = dBodyCreate(world);

// Set position of body.
dBodySetPosition(object.body, 0, 10, -5);

// Set initial linear velocity of object.
dReal tempVect[3] = {0.0, 0.0, 0.0};
dBodySetLinearVel(object.body, tempVect[0], tempVect[1], tempVect[2]);

// Set a random rotation angle for the object.
dMatrix3 R;
dRFromAxisAndAngle(R, dRandReal() * 2.0 - 1.0,
dRandReal() * 2.0 - 1.0,
dRandReal() * 2.0 - 1.0,
dRandReal() * 10.0 - 5.0);

dBodySetRotation(object.body, R);

// Set user data to something insignificant.
size_t i = 0;
dBodySetData(object.body, (void*)i);

// Geometry settings.

dReal sides[3];
sides[0] = 2.0;
sides[1] = 2.0;
sides[2] = 2.0;

// Create a box geometry for the object.
object.geom = dCreateBox(space, sides[0], sides[1], sides[2]);

// Associate geometry with body.
dGeomSetBody(object.geom, object.body);

// Set the mass of the body.
dMass m;
dMassSetBox(&m, 0.5, sides[0], sides[1], sides[2]); // <-- CAUSES A WARNING: says Mass must be > 0.
dBodySetMass(object.body, &m); // <-- CAUSES A WARNING: says something about inertia.
}

void CloseOde(void)
{
// Destroy joint group.
dJointGroupDestroy(contactgroup);

// Destroy collision space.
dSpaceDestroy(space);

// Destroy world!!! MUAHAHAHAHHA!!
dWorldDestroy(world);
}

void SimLoop(void)
{
// Perform per-frame updates of the physics simulation and calculate collisions.

// Determine what geometries in the space may be potentially intersecting.
dSpaceCollide(space, 0, &nearCallback); // Pass this on to nearCallback().

// Advance the simulation with a faster, less accurate stepping function.
dWorldQuickStep(world, 0.05); // CAUSES AN ERROR AND CRASH: says stepsize must be > 0.

// Remove all temporary collision joints.
dJointGroupEmpty(contactgroup);

// Draw geometry.
DrawGeom(object.geom, 0, 0, 0);
}

#define MAX_CONTACTS 6

static void nearCallback(void *data, dGeomID o1, dGeomID o2)
{
int i;

// Get bodies for both objects.
dBodyID b1 = dGeomGetBody(o1);
dBodyID b2 = dGeomGetBody(o2);

// Create an array of contact joints.
dContact contact[MAX_CONTACTS];

// Go through all contact joints and set their properties.
for (i = 0; i < MAX_CONTACTS; i++)
{
contact[i].surface.mode = dContactBounce | dContactSoftCFM; // Set bounce and soft contraints (soft material).
contact[i].surface.mu = dInfinity; // Set friction.
contact[i].surface.mu2 = 0; // Set additional friction.
contact[i].surface.bounce = 0.01; // Set bounciness.
contact[i].surface.bounce_vel = 0.1; // Set bounce velocity.
contact[i].surface.soft_cfm = 0.01; // Set soft constraint value.
}

// Perform collision test.
if (int numcollisions = dCollide(o1, o2, MAX_CONTACTS, &contact[0].geom, sizeof(dContact)))
{
// Add each contact point.
for (i = 0; i < numcollisions; i++)
{
dJointID c = dJointCreateContact(world, contactgroup, contact + i);
dJointAttach(c, b1, b2); // Attach joints.
}
}
}

void DrawGeom(dGeomID g, const dReal *pos, const dReal *R, int show_aabb)
{
if (!g)
return;

if (!pos)
pos = dGeomGetPosition(g);

if (!R)
R = dGeomGetRotation(g);

int type = dGeomGetClass(g);

if (type == dBoxClass)
{
dReal sides[3];
dGeomBoxGetLengths(g, sides);
DrawBox(sides, pos, R);
}
}

void DrawBox(dReal sides[3], const dReal *pos, const dReal *R)
{
glPushMatrix();

glBegin(GL_POINTS);

glTranslatef(pos[0], pos[1], pos[2]);

glEnd();

glPopMatrix();
}


Share this post


Link to post
Share on other sites
There doesn't appear to be anything wrong with your ODE code. Try using the pre-built binaries. What compiler and platform are you using?

Take a look their mailing list, perhaps they can help.

Share this post


Link to post
Share on other sites
I just built and ran your sample code (I had to remove the GLUT stuff since I don't seem to have the headers installed) and I don't get any warnings from ODE.

Share this post


Link to post
Share on other sites
I am using Visual Studio 2005. Perhaps I am using the wrong SDK for ODE.. there's a bunch of them, and I don't really know which one is recommended (they should only offer one to avoid confusion).

Quote:
Original post by Jack Sotac
There doesn't appear to be anything wrong with your ODE code. Try using the pre-built binaries. What compiler and platform are you using?

Take a look their mailing list, perhaps they can help.


Share this post


Link to post
Share on other sites
Basically you have an option to download ODE source code and/or pre-compiled binaries.

On the source side, they offer :
1)Stable ODE 0.5 source which is several years old(May 29, 2004).
2)A CVS snapshot from 23-Feb-2006
3)Download directly from the CVS which contains the cutting edge most recent changes and updates.

On the binary side:

1)You are given a choice between microsoft and cygwin(gcc) compatible ODE libraries indicated by 'msvc' or 'cygwin' in the filename.

2)Then a choise between static libs or dynamic lib(dlls). Dll libs are indicated by 'dll' in the filename.

3)Choose if you want ODE to use floats or doubles indicated by 'single' or 'double' in the filename.

3)Next you choose between debug or release library indicated by 'debug' or 'release' in the filename. I would use the debug versions until my app is done.

4)Lastly you choose if you want trimesh collision/support compiled in the library(trimesh vs. notrimesh).

If you compile from source, I'm sure you use #defines to config the library to these options.

So if you download ode-bin-0.5-msvc-dll-SINGLE-release-trimesh.zip, that indicates :
1)you want Microsoft binaries
2)you want the DLLs ODE library
3)that ODE uses floats
4)that the library was built in release mode
5)trimesh collision is supported.

In conclusion I like choices they offer for the pre-built binaries. Admittedly they are confusing at first.

Share this post


Link to post
Share on other sites
It sounds as if you're linking against the "double" version of the ODE library, while actually passing it "float" type data, or vice versa. Because the library linkage is C-style, it is not type safe, and a mis-match with the headers or compile options on your part will cause these kinds of problems.

Share this post


Link to post
Share on other sites
I think hplus0603 is right.

The typedef for dReal is in ode/common.h, and the dSINGLE and dDOUBLE macros that select its type are defined in ode/config.h.

The latest source is in the Subversion repository. They added project files for Visual Studio 2005, so it's a straightforward build.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this