[ODE] Angular motors and 'LCP internal error, s <= 0'

Heidelberger, Bruno brunoh at student.ethz.ch
Thu Jan 17 02:19:02 2002


I'm using ODE for a project that tries to simulate autonomous creatures
in a virtual environment. Up until now I was using direct forces and
torques on the different bodies to make the creature move. This worked
quite well.
 
I now decided to switch to the new angular motor approach for a better
control over the motion, and it looks very promising so far. The only
problem that showed up is that there are some extreme twitches in some
joints at random intervals, and the error 'ODE Message 3: LCP internal
error, s <= 0 (s=0.0000e+000)' appears in the console ouput.
 
The interesting thing is that the same error messages were printed out
while running the old version (using direct forces/torques), but there
were no visible artifacts in the rendered motion.
 
My knowledge about the internals of physics engines are very limited
(not to say nonexistent), but I came up with the following hack inside
ODE that made the twitches go away:
 
The above mentioned error messages are produced inside the
dSolveLCPBasic(...) and the dSolveLCP(...) functions that can be found
in the ode/src/lcp.cpp file (latest CVS version!):
 
 if (s <= 0) {
   dMessage (d_ERR_LCP, "(1) LCP internal error, s <= 0 (s=%.4e)",s);
   if (i < (n-1)) {
     dSetZero (x+i,n-i);
     dSetZero (w+i,n-i);
   }
   goto done;
}

My (unsophisticated) fix was to remove the content of the original
'if'-clause and replaced it with a statement that set the 's' variable
to a very little positive value, something like this:
 
 if (s <= 0) {
   dMessage (d_ERR_LCP, "(1) LCP internal error, s <= 0 (s=%.4e)",s);
   s = 0.0000001;
 }

I have absolutely no idea what the side-effects of this modifications
are, as I don't even know anything about LCP solving, but the result was
that I fixed my motions of the creature.
 
Does anybody (Russ?) happen to know if this is a good solution, or not?
Are there some new problems now, because of this fix? Or is it probably
a better handling of the 'internal error' event?