[ODE] Mismatching results / non-deterministic behaviour
Jan Tinkhof
boost at tinkhof.de
Wed Sep 13 12:26:24 MST 2006
Hi,
I'm currently trying to implement a scheme to save and restore ODEs
world state. The results are very promising so far, but I have come
across a problem that is unconnected to any serialization I'm attempting.
I have noticed that I get different results each time I setup and run a
simple simulation using ODEs public interface. This test uses ODE 0.7
ONLY, no other library or 3D graphics are involved.
This is the code I use:
#include "ode/ode.h"
#include <iostream>
void runtest()
{
dWorldID myworld = dWorldCreate();
dBodyID mybody1 = dBodyCreate(myworld);
dBodyID mybody2 = dBodyCreate(myworld);
dBodySetPosition(mybody1, 0.f, 1.f, 2.f);
dBodySetPosition(mybody2, 1.f, 2.f, 3.f);
dGeomID mygeom1 = dCreateBox(NULL, 1.0f, 1.0f, 1.0f); // NO
collision points are calculated
dGeomID mygeom2 = dCreateSphere(NULL, 1.0f); // NO collision points
are calculated
dGeomSetPosition(mygeom1, 0.f, 1.f, 2.f);
dGeomSetPosition(mygeom2, 1.f, 2.f, 3.f);
dGeomSetBody(mygeom1, mybody1);
dGeomSetBody(mygeom2, mybody2);
dJointID myjoint = dJointCreateHinge(myworld,0);
dJointAttach(myjoint, mybody1, mybody2);
dJointSetHingeAnchor(myjoint, 1.f, 1.f, 1.f);
dJointSetHingeAxis(myjoint, 1.f, 0.f, 0.f);
dBodyAddForce(mybody1, 0.1f, 0.1f, 0.1f);
for (int s = 0; s < 10000; ++s)
{
dWorldQuickStep(myworld, 0.01f);
dBodyAddForce(mybody1, 0.1f, 0.1f, 0.1f);
}
const float* pos1 = dBodyGetPosition(mybody1);
const float* pos2 = dBodyGetPosition(mybody2);
std::cout.precision(12);
std::cout << "runtest:" << std::endl;
std::cout << "Body1 x: " << pos1[0] << " y: " << pos1[1] << " z: "
<< pos1[2] << std::endl;
std::cout << "Body2 x: " << pos2[0] << " y: " << pos2[1] << " z: "
<< pos2[2] << std::endl;
std::cout << std::endl;
dWorldDestroy(myworld);
}
int main( int argc, char* argv[], char* envp[] )
{
runtest();
runtest();
runtest();
runtest();
runtest();
}
... and these are the results I get:
runtest:
Body1 x: 250.228286743 y: 252.350143433 z: 252.396209717
Body2 x: 250.816452026 y: 250.691482544 z: 252.647384644
runtest:
Body1 x: 250.22694397 y: 252.35005188 z: 252.395523071
Body2 x: 250.817779541 y: 250.691711426 z: 252.647949219
runtest:
Body1 x: 250.226898193 y: 252.350341797 z: 252.395523071
Body2 x: 250.817581177 y: 250.691757202 z: 252.647979736
runtest:
Body1 x: 250.229873657 y: 252.350143433 z: 252.39680481
Body2 x: 250.815002441 y: 250.691375732 z: 252.646453857
runtest:
Body1 x: 250.22706604 y: 252.34967041 z: 252.395294189
Body2 x: 250.817337036 y: 250.692123413 z: 252.648086548
I get the same set of results when I restart the program, but I would
also expect the same result for every iteration of the test.
Obviously, there is some hidden variable/influence that doesn't get
reset between iterations, only termination and a restart of the app
seems to clear it. I figured it might have to do something with the
floating point processor, so tried to reset it with an __asm {finit}
between calls to runtest, but that made no difference.
I am using VC 8.0, single precision, and have tried both the precise and
strict floating point model.
I'm currently at my wits end, there has to be something I'm overlooking,
but I just can't see it.
I'd appreciate any help offered.
Jan
More information about the ODE
mailing list