Avoiding Jitter

Please don't post Bullet support questions here, use the above forums instead.
Steinmetz
Posts: 26
Joined: Sat Dec 15, 2007 12:03 am

Avoiding Jitter

Post by Steinmetz »

I know this has been discussed before, but I didn't understand most of it. Also the discussion were mostly about implementations with Verlet etc. ...
I have implemented, that each frame for a few iterations every Object is tested against each other, and if they penetrate, they get pushed away from each other. Now I can stack a few boxes over each other, and thats a advancement, but still it's not perfect.
As you could extract out of the topic name, the objects jitter.
I read these slides : http://www.gphysics.com/files/GDC2006_ErinCatto.zip
Do I have to implement sequential impulses to get rid of the jitter? And can somebody explain in short to me, where the sense in applying a impulse a few times in one frame, is? Does the jitter end if I do this?

I'm sorry but I didn't really understand it...

I appreciate all help.
Steinmetz
Posts: 26
Joined: Sat Dec 15, 2007 12:03 am

Re: Avoiding Jitter

Post by Steinmetz »

If that question isn't that easy to answer, I'll point another one, a bit more specific ...
If I have the following situation :
Image
Think the red box immovable.
I'd calculate two impulses, one at p1 and one at p2.
The one at p1 would be bigger, than the one at p2, because the distance from p1 to the COM is much bigger than the distance of p2 to the COM. (COM of the black body)
This would lead to the black body rotating clockwise, until only p2 is a real contact point, and then rotating counterclockwise...
I think this could be the jittering? Also it could be the reason why I can't really stack boxes for a long time, they always slide off each other.

I've uploaded the actual version of my engine, so you can see what I want to say ;)
http://www.file-upload.net/download-726 ... e.rar.html
Thanks.
Dirk Gregorius
Posts: 861
Joined: Sun Jul 03, 2005 4:06 pm
Location: Kirkland, WA

Re: Avoiding Jitter

Post by Dirk Gregorius »

Did you implement the sequential impulse as described in the paper as above? If yes there will be no jitter. There are several measures that remove the jitter (in order of importance):

1) Clamp against the accumulated impulse
2) Allow some penetration (to avoid contact breaking)
3) Warmstarting (amortized iterations)
4) Position correction (NGS) instead of Baumgarte

If implemented correctly you should be able to stack 5 boxes in 3D (of size 1x1x1 and mass 1) dropped onto each other at 2-4 iterations and the system should quickly become stable. At 8 iterations you shouldn't notice any artifacts...


HTH,
-Dirk
Steinmetz
Posts: 26
Joined: Sat Dec 15, 2007 12:03 am

Re: Avoiding Jitter

Post by Steinmetz »

Ok, I read the paper through again, and now I'll have to ask a few questions:
1) Clamp against the accumulated impulse
I didn't find anything about, what exactly clamping is, maybe it is because I am german, but the translation also didn't help me :(
3) Warmstarting (amortized iterations)
The same as above, I found out very little about that, what is it exactly?

I'll try to explain what I think I have to do:
For a few iterations:
for each contact:
for each contact point:
calculate impulse and add it to the accumulated impulse
apply the accumulated impulse ( on which point? )
translate the objects by the MTD ( and allow a bit of slop )
integrate position

And another question, what exactly is the bias velocity / impulse, I didn't understand that too.
Dirk Gregorius
Posts: 861
Joined: Sun Jul 03, 2005 4:06 pm
Location: Kirkland, WA

Re: Avoiding Jitter

Post by Dirk Gregorius »

I suggest to look at the source code in Box2D_Lite - not Box2D. There you see how to implement the approach. Note that there are also newer versions of the paper from 2007 and 2008. Try to understand this and ask specific questions about it here. This is easier to answer...



BTW - The clamping works like this:

float dP = ComputeIncrementalImpulse();

float P = c->mAccumulatedImpulse;
c->mAccumulatedImpulse = Max( P + dP, 0 );
dP = c->mAccumulatedImpulse - P;

// Apply incremental impulse dP


Also note that there is no translation!
Steinmetz
Posts: 26
Joined: Sat Dec 15, 2007 12:03 am

Re: Avoiding Jitter

Post by Steinmetz »

Ok, I've implemented it today (first, thanks, it looks much better now :) ), but there are still a few problems.
These are best described with the engine itself:
http://www.file-upload.net/download-731 ... e.rar.html
Try stacking a few boxes ( Press 3 and draw them ), and you will see, that is nearly impossible, because they always slide off each other
I think I'm doing something important wrong, but I don't know what it is.
There are only two contact points to which I apply impulses, is that correct?
As I said before, I can't imagine why a box should rest on an other if I apply one impulse near the center and one more far away.

And I've got another question, I've implemented constraints by position correction, and as you can see, it doesn't work together with the new contact handling, (press 8 and draw a chain and then pull one of the spheres around :D).
Do I have to implement the impulse based constraints, or is it possible to use the old ones with the position?

Thanks.
Dirk Gregorius
Posts: 861
Joined: Sun Jul 03, 2005 4:06 pm
Location: Kirkland, WA

Re: Avoiding Jitter

Post by Dirk Gregorius »

There are many factors:

1) How many iterations do you use?
2) What timestep do you use?
3) What gravity do you use?

The sliding indicates that there are problems in your friction. So how do you implement this? Can you skecth you approach?


BTW:
If you looked at Box2D you can compare you engine against it. If the demos behave different there is a mistake in your implementation. Personally I would use impulses also for joints. Friction is a non-holonome constraint, so it will be quite difficult to integrate this correctly into a solver on the position level. Actually if you read everything thoroughly you will notice that NGS actually has a position level solver as well. Basically the algorithm works like this:

1) Update velocities
2) Correct velocities // Impulses
3) Update positions
4) Correct positions // "Pseudo impulses" which correct positions (similar to the Jacobsen approach)

The best way is to sketch this for a simple pendulum. Imagine the bob at some angle. You update the velocity (add gravity). So the bob would simply fall down. Next you correct the velocity to be tangential to the arc. Now you update position using the corrected velocity. Still you will not end up on the arc. So finally you correct position, projecting the bob back onto the arc.


Cheers,
-Dirk
Steinmetz
Posts: 26
Joined: Sat Dec 15, 2007 12:03 am

Re: Avoiding Jitter

Post by Steinmetz »

The problem with the jittering/sliding is gone now, I forgot to implement multiple contact points for the infinite planes, now it works great, thanks!
But I have problems with the constraints.
First I tried to implement the revolute joint from the box2d lite code by nearly copying everything.
I don't really understand what the "effecitve Mass" is, so I didn't get it implemented correctly.

Then I tried to implement a simple distance constraint by myself and it works for now, if the anchor points are in the center of mass, but now comes the same problem as above, because I think, I need the effecitve mass again.

Reading the Wikipedia article didn't really help me..
Can anyone explain me what exactly that is?
Dirk Gregorius
Posts: 861
Joined: Sun Jul 03, 2005 4:06 pm
Location: Kirkland, WA

Re: Avoiding Jitter

Post by Dirk Gregorius »

The general algorithm goes like this:

1) Define some geometric constraint, e.g. your distance constraint for two particles C( p1, p2 ) = |p2 - p1| - L0 = 0
2) Build the time derivative of the constraint and find the Jacobian by inspection dC/dt = (p2 -p1) / |p2 - p1| * (v2 - v1) = n * (v2 - v1) where n = (p2 -p1) / |p2 - p1| and the Jacobian is J = ( -nT | nT ) (nT should indicated that n is stored as row vector)
3) We seek impulses such that the velocities after applying the impulse satisfy the velocity constraint. If you solve this (seek this forum or GameDev.net - I have posted this several times now) you get:

J*W*JT * lambda = -0.1f * C / dt - J*v

We call J*W*JT the effective mass. You can think of this as the mass the impulse feels when it is applied.


HTH,
-Dirk