trouble with 3D split impulses

Please don't post Bullet support questions here, use the above forums instead.
User avatar
John McCutchan
Posts: 133
Joined: Wed Jul 27, 2005 1:05 pm
Location: Berkeley, CA

trouble with 3D split impulses

Post by John McCutchan »

I have a working 3D version of sequential impulses. I can have 10 cubes stacked directly on top of each
other be stable with only 10 iterations. This is with a erp = 0.2 * fps (fps = 60). I have started
to experiment with splitting the penetration depth correction impulses and I'm not getting good results.
The simulation becomes very jittery with the cubes tilting back and forth and settling into each other.
The instability seems to be coming from the angular movement. Has anyone experienced these kinds of
problems with 3D split impulses. Bullet doesn't use split impulses, is this just not implemented or
was it found to be problematic? I'm going to post my pseudo code below if anyone notices a problem.


PreImpulse:

Code: Select all

bias_normal_lambda = 0.0;
B = depth - DEPTH_SLOP;
B = B < 0.0 ? 0.0 : B;
P = J * accumulated_normal_lambda
apply P
Impulse:

Code: Select all

V = non-bias-velocity of both bodies
lambda = K^-1 * (-( J * v))
old_lambda = accumulated_normal_lambda
accumulated_normal_lambda += lambda
accumulated_normal_lambda = accumulated_normal_lambda < 0.0 ? 0.0 : accumulated_normal_lambda
lambda = accumulated_normal_lambda - old_lambda

P = J * lambda
apply P to non-bias velocity

V = bias-velocity of both bodies
bias_lambda = K^-1 * (-(J * V) + erp * B)

old_bias_lambda = bias_normal_lambda
bias_normal_lambda += bias_lambda
bias_normal_lambda = bias_normal_lambda < 0.0 ? 0.0 : bias_normal_lambda
bias_lambda = bias_normal_lambda - old_bias_lambda

P = J * bias_lambda
apply P to bias velocity
Position Integration code:

Code: Select all

lv = linear_velocity + bias_linear_velocity
av = angular_velocity + bias_angular_velocity
...
bias_linear_velocity = 0.0
bias_angular_velocity = 0.0
Dirk Gregorius
Posts: 861
Joined: Sun Jul 03, 2005 4:06 pm
Location: Kirkland, WA

Post by Dirk Gregorius »

When you split the impulse you basically have

Velocity impulse:
P = -invK * (J * v)

Position impulse:
P = -invK * 0.1 * C / dt

When you use Baumgarte stabilization you combine the relative velocity at the joint (J * v) with the position error at the joint ( C ). This effects the momentum. What you want is that the stabilization doesn't effect the momentum so you cirvcumvent this by splitting up the impulse into a velocity correcting and (pseudo) position correcting impulse. Note that from experience the splitted impulse seems only to work nice with contacts, but not with joints.

Another thing to understand is that the position constraint is non-linear ( e.g. C = u1 * v2 ) so when you add the bias tem 0.1 * C / dt you linearize the position constraint what opens the door to inaccurecies.

Hmm, from skimming over your code I can't see the error, maybe only a sign. Did you try -erp * B?


Cheers,
-Dirk
Erin Catto
Posts: 316
Joined: Fri Jul 01, 2005 5:29 am
Location: Irvine

Post by Erin Catto »

Be sure to initialize the bias impulses and velocities to zero before each time step. Test the solver with a sphere on a plane and look at the values in the debugger.
User avatar
John McCutchan
Posts: 133
Joined: Wed Jul 27, 2005 1:05 pm
Location: Berkeley, CA

Post by John McCutchan »

Re Dirk:
I don't think it's a sign issue because I'm using the same signs as I do when I'm not using splitting.

Re Erin:
I am setting the bias impulse to zero in PreImpulse and I'm setting
the velocities to zero in Position Integration.

Any other suggestions guys? I'm really baffled.
Dirk Gregorius
Posts: 861
Joined: Sun Jul 03, 2005 4:06 pm
Location: Kirkland, WA

Post by Dirk Gregorius »

Conceptually it looks correct what you do, so the only thing I can think of is that you forget to clear the velocities or impulses. Maybe a typo somewhere or you mix accidently the bias impulse with the normal impulse. I would say that it is something trivial that you maybe overlook at the moment...
User avatar
John McCutchan
Posts: 133
Joined: Wed Jul 27, 2005 1:05 pm
Location: Berkeley, CA

Post by John McCutchan »

I found the problem, and it had nothing to do with my code. My body space inverse inertia tensor was wrong. I used the closed form solution for the diagonal inertia tensor for a cube, but I forgot to scale by the mass before inverting it. So the angular impulses weren't being scaled properly.


Also, I found upping the depth slop from 0.01 to 0.1 had a huge impact.