Probably a Bug in NxOgre

M@gg!

23-08-2006 09:48:57

Hi Betajaen,

yesterday if been wasting 7 hours of my life to track down a bug. With no success.

It's still the AddForce bug.

We shot a projectile with a fixed force from a fixed position. Some of the projectiles fly farther as the other ones. The behavior seems not to be deterministic.

I have printed out all parameters I could reach and discovered, that somehow the parameters set from PhysX after the AddForce differ between the far and short flying ones. But the values of two short or long ones are equal.

My assumption is, that NxOgre has a problem with wrong time stepping, but it's just a guess.

The values where shot 4 frames after creation of the projectile.


10:18:14: Bullet10:
10:18:14: NxOgre AddLocalForce_vector: Name: Bullet10 Force: 14.6028 3.42921 0
10:18:14:
10:18:14:
10:18:14: Bullet10:
10:18:14: Bullet10 GetAngularDrehmoment 0 0 0
10:18:14: Bullet10 GetAngularVelocity 0 0 0
10:18:14: Bullet10 GetAngularDamping 0.05
10:18:14: Bullet10 CCDMotionThreshold 0
10:18:14: Bullet10 LinearDamping 0
10:18:14: Bullet10 LinearMomentum 0.730137 0.156715 -0.0011469
10:18:14: Bullet10 LinearVelocity 32.3723 6.94834 -0.0508504
10:18:14: Bullet10 Mass 0.0225543
10:18:14: Bullet10 MassSpaceInertiaTensor 9.47846e-005 9.47846e-005 9.47846e-005
10:18:14: Bullet10 MaxAngularVelocity 7



10:18:15: Bullet11:
10:18:15: NxOgre AddLocalForce_vector: Name: Bullet11 Force: 14.6028 3.42921 0
10:18:14:
10:18:14:
10:18:15: Bullet11:
10:18:15: Bullet11 GetAngularDrehmoment 0 0 0
10:18:15: Bullet11 GetAngularVelocity 0 0 0
10:18:15: Bullet11 GetAngularDamping 0.05
10:18:15: Bullet11 CCDMotionThreshold 0
10:18:15: Bullet11 LinearDamping 0
10:18:15: Bullet11 LinearMomentum 0.486758 0.0995616 -0.000764598
10:18:15: Bullet11 LinearVelocity 21.5816 4.4143 -0.0339003
10:18:15: Bullet11 Mass 0.0225543
10:18:15: Bullet11 MassSpaceInertiaTensor 9.47846e-005 9.47846e-005 9.47846e-005
10:18:15: Bullet11 MaxAngularVelocity 7

betajaen

23-08-2006 10:56:38

Ouch!

Okay, I'll work on it now. I'm pretty sure it's to do with the variable time stepper.

betajaen

23-08-2006 11:23:47

Alright, what I did is:

Made a normal Scene with:
- Gravity On
- Floor On
- One cube using cube.1m.mesh
- Cube size is 1.0f
- Weight is 10.0f
- Starting position is 0,4,0

Added a force of 3000,0,0 after the cube is created.

Then what I did is logged all of the positions of the cube to a log file, and pasted the last position into notepad.

I've repeated the test many times.

Normal

1.58333 3.48243 0
1.58333 3.48243 0
1.41667 3.58322 0
1.41667 3.58322 0
1.33333 3.62953 0


VSync On
5.40694 0.498011 0.0665542
5.40694 0.498011 0.0665542
5.40694 0.498011 0.0665542



Now then this is the most interesting part, and my conclusion to the matter.

I adjusted the simulation code in NxOgre itself, usually it tells the NxScene to "simulate" based on the amount of seconds since the last frame, basically Euler.

The PhysX integrator which calculates where the body should be at +time.

So I told it to simulate a fixed number of 0.01666, so every frame PhysX would simulate 0.01666 seconds of time.

These are the results:

5.40694 0.498011 0.0665542
5.40694 0.498011 0.0665542
5.40694 0.498011 0.0665542
5.40694 0.498011 0.0665542
5.40694 0.498011 0.0665542
5.40694 0.498011 0.0665542
5.40694 0.498011 0.0665542


In conclusion, it's not a bug. It's the PhysX integrator making a good guess where the cube should based on the time elapsed on the previous frame.

Now this happens in all real-time Physics engines, ODE, Newton, TrueAxis, Havok and PhysX the works. Fortunately PhysX seems to be the better of the lot at doing it. :D

betajaen

23-08-2006 11:32:14

I'm also puzzled why at normal the cube ends up ~1.5 but in the rest it's ~5.

I've been fiddling around with the NxForceModes which make a huge difference, but at this point I think Ageia would help you better than I can.

M@gg!

23-08-2006 11:43:27

Sorry, but activating VSYNC does not help.

Try using "addLocalForce" on a sphere Mesh:


mBdyBody = mNxSceneManager->createBody(mName, "sphere.mesh",new nxOgre::sphereShape(0.1), 5, _position);

mBdyBody->mNode->scale(Ogre::Vector3(0.0005,0.0005,0.0005));


Now add the force like this:

mBdyBody->addLocalForce(15,15,0);

And enjoy!!!

betajaen

23-08-2006 11:48:31

Oh you crafty monkey, I get the same sleeping position all the time. :D

M@gg!

23-08-2006 11:53:04

Slowly but shurely I'm getting crazy.

Perhaps this only happens when you are having a lot to calculate and this brings the time stepper out of ballance.

Do you have any idea why this could be happen in our simulation?

betajaen

23-08-2006 12:17:47

It might, but I've only tried it with one cube and that always went to the same exact position.

What happens if adjust in Scene::Simulation, mScene->simulate(1.0/60.0f) Is it better then?

M@gg!

23-08-2006 13:13:17

What happens if adjust in Scene::Simulation, mScene->simulate(1.0/60.0f) Is it better then?

This was my next target, but I didn't know where to find it.

And I was right, it is exactly as I said a time stepper problem.

Now it works! Thx a lot you saved me hours of unscrambling your code.


The hint for me was this small text in the PhysX Documentation:

Recommended Time Stepping Method

The recommended time stepping method for a typical application is to use fixed time steps where maxTimestep is an exact multiple of elapsedTime and elapsedTime is a constant. This way the number of sub steps which are taken is know to the user and does not vary.


The advantage of this is that the behavior when applying forces and moving kinematic actors is deterministic. If the user executes a variable number of sub steps on each call to simulate then the time period over which forces are applied and kinematic actors moved will vary (for example causing the velocity of kinematic actors to vary). When accounting for variable frame rates, the user can make multiple calls to simulate with new values supplied to moveGlobalPose() and addForce() etc.

betajaen

23-08-2006 17:31:40

Excellent.

But since the stepper is completely dependent on frame rate now.the faster the frame rate the faster the physics simulation is. As I was getting around a 1000FPS for the box demo, with it running at 1.0/60.0f, it was actually 16 times as fast than it should be.

So there are two options I can see:

- Decide on a targeted frame rate, either via VSync or renderOneFrame()
- Decide on a number of simulations to do in a second, any more called will be ignored.

Both will have it's advantages and disadvantages though, it's up to you.

M@gg!

23-08-2006 18:13:17

Both will have it's advantages and disadvantages though, it's up to you.

Yes, this would be a good feature! A simple way to chose it during creation of the scene in NxOgre.

In addition it will be a nice chapter in your book!

By the way, a chapter about Local and Globel force might be helpfully, too.


PS: I fear, that the timer in Ogre is not as accurate as it should be, but it's just an unpleasant feeling of mine. I've until now not tested it.

betajaen

23-08-2006 18:38:44

In theory it's already implemented via the blueprint<scene> class.