[ODE] Pushing through collisions

Alen Ladavac alenl-ml at croteam.com
Thu Apr 29 08:55:47 MST 2004


Hi guys,

Phew, you people managed to write a lot of things before I even noticed the
thread. :) We've been examining some of the problems you mention, and I
believe I have most of the answers, but not all of the solutions.

Here we go...

1) Why do objects interpenetrate? Contact forces can be generated only if
there is interpenetration, so if they manage to separate completely, the
contact force vanishes, and pushing force will push them back into
interpenetration again. So, it is better to have contact joints that will
never correct completely, otherwise you get the bounciness, similar to what
Colin described. Okey, I guess this one is more or less obvious.

1a) Side note, for Colin... don't set velocities directly. I'm sure you've
been told so before. :) But I guess you weren't told how to give constant
velocity to your avatar in a simple way using forces. Just create a simple
motor joint with two constraints in J, one along desired axis of motion,
another orthogonal to it. Put desired velocity in the right side of first
row and zero in the right side of second row, and finaly set hi/lo limits to
+/- desired force (F=M/a).

2) More important - how much do they penetrate? This has to do with ERP and
CFM. Actually, more CFM. CFM defines part of constraint force that is _not_
applied. So, if CFM is 0.01, then 1% of needed force is lost, i.e. only 99%
of force needed to keep the two objects apart is applied. On the other hand
ERP defines part of error that is corrected in one step, effectively adding
more force to the contact. These two counteract. If there was no CFM, ERP
would cause the joint error to converge towards 0 in a geometrical sequence
of error*ERP^n. If there was no ERP, CFM would allow constant increase of
the error with velocity of about F/m*stepsize each step.

This is usually easily observed as amount of sinking into floor that objects
get - heavier objects get more sinking, and larger stepsizes make all
objects sink more. There are formulae in "How to make new joints in ODE",
describing relations between CFM/ERP and spring/damper constants - those two
pairs are similar.

So, Jon, you can either: a) put lower limit on maximum movement force, b)
increase ERP, c) reduce CFM, or d) use smaller timesteps. Once you reach the
point when avatar can't penetrate as deep as its radius, you should be safe.

3) One interesting observation here would also be that CFM is here basically
as a shield against singularity in A matrix. (That's as far as I can see -
correct me if I'm wrong. Please do.) So if LCP solver was based on some
method that is immune to singularities, then it would not be needed
(biconjugate gradient anyone? ;) ). Maybe this is just a long shot, but
perhaps a simple Gauss-Seidel iterative solver will be able to work
correctly with CFM=0. We're experimenting with this at this very moment.
Note that in that case, we would want to modify the right hand side
calculation so that there is always some penetration left, otherwise we get
bouncing (see #1), but it could be a constant amount, not depending on the
contact force, what would make contacts look much stiffer.

4) Position displacement. This would be interesting to try. Mendoza et al
(in a recently mentioned paper) describe how they solve 3 LCPs - one for
positions, velocities and accelerations. Something like that might be good
to try. Currently, ODE puts all those into the same equation - and it is not
so bad - except for this dependency of penetration depth on external forces.
So perhaps only adding one more LCP for positions would help a lot.

5) The cylinder-sphere combination in our collider. Nguyen, I belive that we
have found a case where contact normal is NAN if sphere center is on the
cylinder axis. I'll send you a fix when we have time to do it.

Hope at least some of this helps,
Alen



More information about the ODE mailing list