Sign in to follow this  
NickGravelyn

Trouble Beginning With ODE

Recommended Posts

NickGravelyn    855
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);
        }
    }
}

Share this post


Link to post
Share on other sites
NoahAdler    290
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.

Share this post


Link to post
Share on other sites
grhodes_at_work    1385
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.

Share this post


Link to post
Share on other sites
grhodes_at_work    1385
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.

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