[ODE] Disappearing boxes.

don don_reid at attbi.com
Mon Aug 26 20:51:02 2002


--liOOAslEiF7prFVr
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

> From: Nate W <coding@natew.com>
> 
> On Sun, 25 Aug 2002, don wrote:
> 
> > I have a small test program with two boxes (0.5 per side) connected
> > with a slider joint.  The boxes are placed on the ground plane, and
> > for several steps, sit there fine, then suddenly they vanish.  
> 
> I have seen stuff very much like what you describe, but unfortunately I
> don't recall what solved the problem.  So, I make no promises, but here's
> a couple things you could try...
> 
> Try setting ERP to 0.9 and/or set CFM to 0.1.  This will result in a very
> 'squishy' simulation, but that squishyness sometimes helps with 
> instability problems.  

This slows done the motion and makes then rotate if bouncing (see
below).

> Start the simulation with both boxes slightly above the ground plane, say
> 0.1 units up.

I tried that, but if I start even that small amount above the ground,
then the boxes bounce and go up for a very long time.

I have gravity set to -9.81, and a moderate density for the boxes.

Here is a copy stripped down to a single box.  I must be doing something
stupid, this has worked in other cases.  With these particular setings,
I get the "LCP internal error, s <= 0" error before it crashes.
With smaller CFM, I don't.

If the starting Z value is 0.35, then they bounce and fly upwards.

Don Reid

--liOOAslEiF7prFVr
Content-Type: text/x-c++src; charset=us-ascii
Content-Disposition: attachment; filename="test_box2.cpp"

#include <ode/ode.h>
#include <drawstuff/drawstuff.h>

// select correct drawing functions

#ifdef dDOUBLE
#define dsDrawBox dsDrawBoxD
#define dsDrawSphere dsDrawSphereD
#define dsDrawCylinder dsDrawCylinderD
#define dsDrawCappedCylinder dsDrawCappedCylinderD
#endif

#define CP_V3(v3) (*((dVector3 *) v3 ))
#define CP_M3(m3) (*((dMatrix3 *) m3 ))

static dWorldID world;
static dSpaceID space;
static dGeomID ground;

static const int numBoxes = 1;
static dBodyID boxBody[numBoxes];
static dGeomID boxGeom[numBoxes];

static dJointGroupID contactgroup;

// this is called by dSpaceCollide when two objects in space are
// potentially colliding.

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

	const int N = 100;
	dContact contact[N];
	n = dCollide(o1, o2, N, &contact[0].geom, sizeof(dContact));
	if (n > 0) {
		for (i=0; i<n; i++) {
			printf("Contact at (%g,%g,%g)->(%g,%g,%g)\n", 
			    contact[i].geom.pos[0],
			    contact[i].geom.pos[1],
			    contact[i].geom.pos[2],
			    contact[i].geom.normal[0],
			    contact[i].geom.normal[1],
			    contact[i].geom.normal[2]);
			dJointID c = dJointCreateContact(world, contactgroup, &contact[i]);
			dJointAttach(c,
			    dGeomGetBody(contact[i].geom.g1),
			    dGeomGetBody(contact[i].geom.g2));
			}
		}
	}

static void start() {
	static float xyz[3] = {0.5, -4.0, 1.5};
	static float hpr[3] = {90.0, -20.0, 0.0};
	dsSetViewpoint(xyz, hpr);
	}

static void command(int cmd) {;}

static void simLoop(int pause) {
	dVector3 pos[2];
	dMatrix3 rot;
	dVector3 sides;
	int i;

	if (!pause) {
		dSpaceCollide (space, 0, &nearCallback);
		dWorldStep(world, 0.05);
		}

	// Draw all boxes
	dsSetColor(0, 0, 1);	// blue
	for (i=0; i<numBoxes; i++) {
		pos[i] = CP_V3(dBodyGetPosition(boxBody[i]));
		if (!pause) printf("box[%d] at %4.2f, %4.2f, %4.2f\n",
					i, pos[i][0], pos[i][1], pos[i][2]);
		rot = CP_M3(dBodyGetRotation(boxBody[i]));
		dGeomBoxGetLengths(boxGeom[i], sides);
		dsDrawBox(pos[i], rot, sides);
		}
	}



int main(int argc, char **argv) {
	dMass m;
	dMatrix3 R;

	// setup pointers to drawstuff callback functions
	dsFunctions fn;

	fn.version = DS_VERSION;
	fn.start = &start;
	fn.step = &simLoop;
	fn.command = &command;
	fn.stop = 0;
	fn.path_to_textures = "drawstuff/textures";

	// create world

	world = dWorldCreate();
	space = dHashSpaceCreate();
	dWorldSetGravity(world, 0, 0, -9.81);
	dWorldSetCFM(world, 1e-2);

	ground = dCreatePlane(space, 0, 0, 1, 0);

	// box[0]
	dRSetIdentity(R);
	dMassSetBox(&m, 10, 0.5, 0.5, 0.5);
	boxBody[0] = dBodyCreate(world);
	dBodySetPosition(boxBody[0], 0, 0, 0.25);
	dBodySetRotation(boxBody[0], R);
	dBodySetMass(boxBody[0], &m);
	boxGeom[0] = dCreateBox(space, 0.5, 0.5, 0.5);
	dGeomSetBody(boxGeom[0], boxBody[0]);

	// run simulation
	dsSimulationLoop(argc,argv,640,480,&fn);

	dJointGroupDestroy(contactgroup);
	dSpaceDestroy(space);
	dWorldDestroy(world);

	return 0;
	}

/* vi:set ts=4: */

--liOOAslEiF7prFVr--