Hi all!
I've been making a physics-engine for many months, and now I'm at the stage when I'm converting everything to PGS.
I used Lemke LCP solver, and I managed to create quite a good implementation, that is almost as fast as PGS (including Mixed LCP -> Common LCP transform) when several objects are in the simulation. Unfortunately, Lemke's speed decreases dramatically with the increase of the system's dimention (I guess O(4)). So, my only choice was to convert to PGS.
But with PGS I've first seen such an effect as unstable stacking. 3 objects placed on top of each other show some tangental velocity and the stack collapses. When I used Lemke, nothing of the kind was observed. Stacks of any size used to be absolutely stable.
My question might sound naive: what's the nature of this behavior? Why does the tangental velocity appear? And, of course, waht to do?
Why is stacking unstable?
-
- Posts: 316
- Joined: Fri Jul 01, 2005 5:29 am
- Location: Irvine
I recommend caching contact points and warm starting the PGS. But before you do that, make sure this case works:
1) 2 boxes vertically stacked (1m x 1m x 1m).
2) 20 PGS iterations
3) Gravity = 10
4) 1/60 second time step
That should be fairly stable.
If you want to look into contact caching and warm starting, you can look at
http://www.gphysics.com/files/GDC2006_ErinCatto.zip
The Box2D demo has warm starting enabled by default. To see the behavior without warm starting, comment out lines 69 and 70 in Arbiter.cpp:
c->accumulatedNormalImpulse = cOld->accumulatedNormalImpulse;
c->accumulatedTangentImpulse = cOld->accumulatedTangentImpulse;
1) 2 boxes vertically stacked (1m x 1m x 1m).
2) 20 PGS iterations
3) Gravity = 10
4) 1/60 second time step
That should be fairly stable.
If you want to look into contact caching and warm starting, you can look at
http://www.gphysics.com/files/GDC2006_ErinCatto.zip
The Box2D demo has warm starting enabled by default. To see the behavior without warm starting, comment out lines 69 and 70 in Arbiter.cpp:
c->accumulatedNormalImpulse = cOld->accumulatedNormalImpulse;
c->accumulatedTangentImpulse = cOld->accumulatedTangentImpulse;
-
- Posts: 23
- Joined: Wed Nov 30, 2005 11:07 am
- Location: China
-
- Posts: 26
- Joined: Thu May 18, 2006 9:25 pm
jiangwei, I do use compensation, and there's no interpenetration. It collapses due to some velocity tangental to contact normal ditrection, that drives the bodies off each other.
Erin, I'm going to play with the warm starting after I solve the shit with the stacking. Thank you for the link, but it's not the case. The non-penetration constraint is satisfied to any reasonable precision, but there appears an odd tangental velocity, which doesn't appear in case of Lemke LCP solver. Isn't such a behavior common?
Erin, I'm going to play with the warm starting after I solve the shit with the stacking. Thank you for the link, but it's not the case. The non-penetration constraint is satisfied to any reasonable precision, but there appears an odd tangental velocity, which doesn't appear in case of Lemke LCP solver. Isn't such a behavior common?
-
- Posts: 40
- Joined: Fri Jul 22, 2005 8:00 pm
- Location: Santa Monica
The lemke solver is more forgiving with poor penetration depth calculations. You might be looking in the wrong place for your problem.
It is more likely that you have a typo, or numerical degeneracy, in your friction tangent generation - that's one place where I got this behaviour. Also, check that you are clamping correctly with the tangential components.
Both Erin's awesome presentation and Bullet have good example code.
It is more likely that you have a typo, or numerical degeneracy, in your friction tangent generation - that's one place where I got this behaviour. Also, check that you are clamping correctly with the tangential components.
Both Erin's awesome presentation and Bullet have good example code.
-
- Posts: 316
- Joined: Fri Jul 01, 2005 5:29 am
- Location: Irvine
It should be easy to eliminate the penetration depth as the problem. You should be able to run a stable (no jitter) simulation with the penetration bias set to zero.
In Box2D again, change line 109 from:
c->bias = -0.1f * inv_dt * Min(0.0f, c->separation + k_allowedPenetration);
to
c->bias = 0.0f;
Run it and press 3 to see stacking without penetration compensation. It actually works ok. And there is no jitter.
In Box2D again, change line 109 from:
c->bias = -0.1f * inv_dt * Min(0.0f, c->separation + k_allowedPenetration);
to
c->bias = 0.0f;
Run it and press 3 to see stacking without penetration compensation. It actually works ok. And there is no jitter.
-
- Posts: 23
- Joined: Wed Nov 30, 2005 11:07 am
- Location: China