Trouble Beginning With ODE

Started by
4 comments, last by grhodes_at_work 18 years, 1 month ago
I'm trying to learn ODE but I'm having a bit of trouble. In my simulation, I have a box which is supposed to just fall down and collide with my ground. It all works fairly well, but the box never comes to rest, instead it just sits there shaking violently and occasionally jumping up. I can't figure it out for the life of me. Here's the code I'm using:

	dynamicsWorld = dWorldCreate();
	dWorldSetGravity(dynamicsWorld, 0, -9.81, 0);
	dWorldSetContactSurfaceLayer(dynamicsWorld, 0.001);	
	
	boxBody = dBodyCreate(dynamicsWorld);
	dMass *boxmass = new dMass;
	dMassSetBoxTotal(boxmass, 20, .5, .5, .5);
	dBodySetMass(boxBody, boxmass);
	dBodySetPosition(boxBody, 0, 10, 0);
	dBodyAddTorque(boxBody, 200, 0, 200);
	
	dynamicsSpace = dHashSpaceCreate(0);	
	boxGeom = dCreateBox(dynamicsSpace, .5, .5, .5);
	dGeomSetBody(boxGeom, boxBody);
	
	groundGeom = dCreateBox(dynamicsSpace, 10, .2, 10);
	
	contactGroup = dJointGroupCreate(0);


	dSpaceCollide(dynamicsSpace, 0, &nearCallback);
	dWorldStep(dynamicsWorld, frameInterval);
	dJointGroupEmpty(contactGroup);


void nearCallback (void *data, dGeomID o1, dGeomID o2) {
    if (dGeomIsSpace (o1) || dGeomIsSpace (o2)) {
		// colliding a space with something
		
		dSpaceCollide2 (o1,o2,data,&nearCallback);
		// collide all geoms internal to the space(s)
		
		if (dGeomIsSpace (o1))
            dSpaceCollide ((dSpaceID)o1,data,&nearCallback);
		if (dGeomIsSpace (o2))
            dSpaceCollide ((dSpaceID)o2,data,&nearCallback);
    }
    else {
        dBodyID b1 = dGeomGetBody(o1);
        dBodyID b2 = dGeomGetBody(o2);
		
        // Don't do anything if the two bodies are connected
		
        if (b2 && b2 && dAreConnected (b1,b2)) return;
		
        // Assuming only one contact here...
		
        dContact contact;
        contact.surface.mode = dContactBounce;
        contact.surface.bounce = 0.5;
        contact.surface.mu = 0.4;
        // etc...
		
		
        // colliding two non-space geoms, so generate contact
		
        // points between o1 and o2
		
        if(dCollide (o1,o2,0,&contact.geom,sizeof(dContactGeom))) {
            dJointID joint;
			
            // add these contact points to the simulation
			
            joint = dJointCreateContact(dynamicsWorld, contactGroup, &contact);
            dJointAttach(joint,b1,b2);
        }
    }
}

Advertisement
Might want to check out my web site...

www.pepperboy.net

Look at the sample code from ODE.NET2.
It's crucial for stability that a fixed integration time step is used. If frameTime's value varies, this could be a big part of the problem. Try to use a constant time step instead, and apply it multiple times if you need to advance the simulation further between some frames than others.
-bodisiw
You're using a "real world" value for gravity. If you look at the shipping ODE samples, you will notice that none of them use -9.81. They all use -0.5 for gravity. But....you ought to be able to use a real world value. And, in our own engine, a pluggable system that supports different physics middleware including ODE, we too use -9.81. What we found is that you need to play with the max correcting velocity, too, using dWorldSetContactMaxCorrectingVel(). The value we use (currently) is 100.0f for the max correcting velocity. Also, in your near callback, your bounce value is really quite large I think. We use 0.1f for bounce and bounce_vel for default collisions, and things are more reasonable. But...we also do not include the dContactBounce flag in our dContact structs.
Graham Rhodes Moderator, Math & Physics forum @ gamedev.net
I'll also second what Noah said about using a fixed time step, with multiple physics steps per frame if necessary to have the physics keep up with frame rate, instead of using the frame time as the physics step size.

But, I will say that this can get you into trouble unless you also set an upper limit to the number of physics steps that will be performed in any given frame. It is possible, for example, that at some point it takes longer for the physics to catch up with the frames than the current frame time. If physics is done in the same thread as frame drawing, then during the next frame you'll have to do even more physics steps to catch up, which will take even longer, etc., leading to frame times that just grow larger and larger----effectively hanging your game pretty soon. This can be an issue with ODE if there are lots of collisions and especially if using dWorldStep and also especially if you have not partitioned your world properly to avoid extraneous object-pair intersection tests.
Graham Rhodes Moderator, Math & Physics forum @ gamedev.net
Moving to the math & physics forum.
Graham Rhodes Moderator, Math & Physics forum @ gamedev.net

This topic is closed to new replies.

Advertisement