Box resting after 1 iteration

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

Box resting after 1 iteration

Post by Steinmetz »

I implemented a version of Box2d Lite for my own engine, so the methods used are the same. But I have a problem:
If a simple circle lies on a infinite plane with slope 0, after 1 iteration it gets to rest immediately. (Velocity ^ 2 = 0)
But if I do the same with a Box (or Square), it only works if just one point is colliding with the plane.
In the main case, where a complete edge (-> 2 points) is lying on the plane, the box jitters and begins to sink into the plane (with no position correction)
With more than one iteration, e.g. 10, it still has a velocity, not that big, but it exists.
That's just for one Box, if I add more, the error gets bigger and bigger, and leads to real ugly results.

I could imagine, that the problem lies in applying the impulse on the first contact point and after that applying the second impulse, which is a bit smaller -> leads to jitter.
But in the box2dlite-Code I didn't find anything on that.
If I calculate the middle of the two contact points, and just apply one impulse, stacking would not work.
If I wait with applying the first impulse until I calculated the second one, the resulting angular velocity is wrong.
Can anyone explain what to do please?
Thank you, and pardon my English
Dirk Gregorius
Posts: 861
Joined: Sun Jul 03, 2005 4:06 pm
Location: Kirkland, WA

Re: Box resting after 1 iteration

Post by Dirk Gregorius »

A box on a plane should be fine between 2-4 iterations. Do you allow some penetration (called slop in Erin's paper) and are you carefull how much penetration you repair each frame? If the warmstarting works, that means if you identify all contacts correctly it could work with one iteration. I can stack 5 boxes with one iteration in 3D, but it is jittery in the beginning and it takes some time until it settles. Still I don't recommend this. I would use 4-16 iterations depending on the scene. For large stacks or pyramids it becomes even more.

I would check:

- Allow slop
- Only correct 10% of the penetration (Baumgarte)
- Check your warmstarting and if your contact IDs are valid


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

Re: Box resting after 1 iteration

Post by Steinmetz »

First, thank you alot for your reply!
I would check:

- Allow slop
I allow 1.5 pixels of slop, for circles 0.5 or something like that is enough, but for boxes I need alot more.
But in the case I described above, I haven't turned position correction on, so that can't be the problem.
- Only correct 10% of the penetration (Baumgarte)
Same as above, position correction is turned off, and I use split impulses instead of Baumgarte, so the penetration can't have any effect on the velocity.
- Check your warmstarting and if your contact IDs are valid
I haven't implemented warmstarting until now because I didn't know how to store the contacts of the last frame until the next the best. I didn't think of it being necessary, more an improvement...
I just store the contact points, and not the IDs of that points, but as far I see, these points are correct.

If I set the iterations to 1, after collision resolving, the velocity of the body at the contact points is not 0, and with time the body begins to shift in direction of the second(!) contact point.
Thanks for your Help.
Dirk Gregorius
Posts: 861
Joined: Sun Jul 03, 2005 4:06 pm
Location: Kirkland, WA

Re: Box resting after 1 iteration

Post by Dirk Gregorius »

Warmstarting has a huge effect. You basically do hundreds of iterations amortized over several frames. Without warmstarting you quickly need 10 to 100 iterations depending on the size of the stack. A quick test is to use say 256 iterations. The box should rest perfectly in this case. If it doesn't you have bugs in your implementation.

Maybe you add a post-condition (assert) after solving each contact constraint if you don't do it alreadt. Recompute the velocity in the direction of the contact normal at each contact point. It has to be zero for this point.
Steinmetz
Posts: 26
Joined: Sat Dec 15, 2007 12:03 am

Re: Box resting after 1 iteration

Post by Steinmetz »

Warmstarting has a huge effect. You basically do hundreds of iterations amortized over several frames. Without warmstarting you quickly need 10 to 100 iterations depending on the size of the stack.
It seems that I underrated this ... :) I'm going to implement it as soon as I can. How do you store the contacts or collisions or whatever they should be called between frames? Do you just save the list, and then, in the next frame, look through that list, and assign each contact of the new frame to an old contact? Or is there a more intelligent and simple method that I am missing?
A quick test is to use say 256 iterations. The box should rest perfectly in this case. If it doesn't you have bugs in your implementation.

Maybe you add a post-condition (assert) after solving each contact constraint if you don't do it alreadt. Recompute the velocity in the direction of the contact normal at each contact point. It has to be zero for this point.
If I just have one contact point, the normal velocity is exactly 0 but if I have more than one (two) contact points after 1 iteration it is still very big (5 or 10 px/s).
At ten iterations, it gets to between 10^-4 and 1 px/s
but even at 256 iterations, it is not 0 but something like 10^-16 ... I don't know, should it be really 0?

And again, thank you a lot for your help!
Dirk Gregorius
Posts: 861
Joined: Sun Jul 03, 2005 4:06 pm
Location: Kirkland, WA

Re: Box resting after 1 iteration

Post by Dirk Gregorius »

I have a reference to the manifold with each pair. So when I find a new pair I check if I already created a contact for it. If yes, I update it with the new contact information otherwise I just allocate a new one from a pre-allocated buffer.

Using a hash-table is fine as well...
Erin Catto
Posts: 316
Joined: Fri Jul 01, 2005 5:29 am
Location: Irvine

Re: Box resting after 1 iteration

Post by Erin Catto »

Are you accumulating the impulses? Are you clamping the accumulated impulse instead of the immediate impulse?
Steinmetz
Posts: 26
Joined: Sat Dec 15, 2007 12:03 am

Re: Box resting after 1 iteration

Post by Steinmetz »

Sorry for the late answer, and thanks for your replys
I have a reference to the manifold with each pair. So when I find a new pair I check if I already created a contact for it. If yes, I update it with the new contact information otherwise I just allocate a new one from a pre-allocated buffer.

Using a hash-table is fine as well...
I'll give the first one a try, thank you.
Are you accumulating the impulses? Are you clamping the accumulated impulse instead of the immediate impulse?
Yes. The problem is, in 99% of the time, the simulation looks very nice and realistic, but in a few cases, something really disturbing is happening... I'm going to try to construct such a situation, so I can show it to you. All I can say at the moment is, that a box always slides towards the second contact point(maybe the second impulse is too high).

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

Re: Box resting after 1 iteration

Post by Steinmetz »

Awesome!
Warmstarting is really impressive, the simulation looks so much nicer now, its incredible.
I think, this fixes nearly all my problems.
I just gave each body an unique Id, which is a prime.
Then, a contact of bodies b1 and b2 gets the identity b1.id * b2.id
Now i just store the contacts of the last frame, check for each old contact, if a new one has the same Id, and then synchronize the accumulated Impulses.
Well, I don't think I'm doing something wrong, because it really works fine.
Thank you all alot!