I was shocked to see that my super simple simulation is NOT deterministic. I thought ODE ran on a fixed timestep? And all im doing is dropping some spheres onto a little trimesh I built.
I saw in the ode source there seems to be some randomness going on with regards to joints, but im not using any joints..
So, can anyone tell me what I have to do to make ODE 100% deterministic?
Thanks
Don't think it is possible.
Tabarn@kdeca.lis
03-05-2007 19:18:49
Could it be why even if I set the maximum linear velocity using this code :
// Set maximum linear velocity
Vector3 vect3Tmp = poodeBody->getLinearVelocity();
if(vect3Tmp.x > MAX_LINEAR_XVEL)
vect3Tmp.x = MAX_LINEAR_XVEL;
if(vect3Tmp.x < -MAX_LINEAR_XVEL)
vect3Tmp.x = -MAX_LINEAR_XVEL;
if(vect3Tmp.y > MAX_LINEAR_YVEL)
vect3Tmp.y = MAX_LINEAR_YVEL;
if(vect3Tmp.y < -MAX_LINEAR_YVEL)
vect3Tmp.y = -MAX_LINEAR_YVEL;
poodeBody->setLinearVelocity(vect3Tmp);
Sometimes, the simulation occur faster than the limits?
All is going smooth, but sometimes the simulation speed up by two or three times for a few seconds. It does not seem to be related to the framerate.
GAH how is it not possible?
Doesnt ODE run on a fixed timestep? If thats the case why should you not be able to get determinstic results if you reset everything to the exact same starting positions? Thats the very definition of a fixed timestep...
GAH how is it not possible?
Doesnt ODE run on a fixed timestep? If thats the case why should you not be able to get determinstic results if you reset everything to the exact same starting positions? Thats the very definition of a fixed timestep...
That is a possibility, instead of updating given the passed time, fix the step size ( or update multiple times ).
I am running a fixed timestep though. I use opal which is a abstract layer ontop of ode.
I heard ODE has some random defines that can be removed, and that doing so will remove the 'randomness'. Gonna try that, along with a fixed timestep.. should be deterministic at that point dag nabit
rewb0rn
08-05-2007 07:10:48
if you do so, please submit a cvs patch to tuan kuranes or post your code here, so we all can use it. I use fixed timesteps too and know your problem. fortunately it is not that obvious in my game.
Will do, but im not using 'OgreODE', but rather opal. And im having trouble building it from source (the sdk works fine, but all my custom builds give erratic behavior).
Once I can get opal to build from source, I will try removing some of the 'random' defines that are part of the ode source. That SHOULD make things deterministic (given a fixed time step).
Hmm, I just checked the ODE wiki and don't see any answers there, it might be worth asking on their mailing list though.
Tabarn@kdeca.lis
29-05-2007 17:27:16
In reply to my previous post in this thread, I must say that since I'm using smaller values in the forces applied, I haven't seen that problem. I was applying 100-500 forces, but scaling them to 5-30 reduce the stability problems.
I must admit many parameters have changed since then, but I think that was the problem as I red somewhere that using smaller forces is better.
rewb0rn
29-05-2007 21:26:00
How did u scale them? Just scaling forces (even gravity) would just make everything move slower, wouldnt it? Did you change weights too? Weird is I use a mass of 140 for each capsule and sphere for my player, which I think is a value of good precision, but I need a force of ~8000000 to apply to my player once to jump to a realistic level, with a grav of something like -900.
Tabarn@kdeca.lis
31-05-2007 20:08:08
I'm currently using gravity of 10, movement forces of 15, jump of 30 for a short period of time, with a capsule mass of 200, 0.5 as height and 0.25 as radius, it's density is 10.
Please post your world and contact settings here :
http://www.ogre3d.org/phpBB2addons/viewtopic.php?t=4417
rewb0rn
31-05-2007 21:43:39
since my values are not final it doesnt make sense to me to post them.
syedhs
01-06-2007 18:20:53
Yes there were discussions on non-deterministic behavior of ODE physcs. I searched my emails and here are the related excerpts:
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
And there was one reply to which I had tested it myself to be true: add 'dRandSetSeed(0)' prior to each test and the values will come out exactly the same (deterministic). Btw, I didn't really test it in any real application, but it should give some pointers (or it could be the actual solutions).