Contents
ODE Solvers
Please see the ODE's users manual for general ODE documentation.
In general, rigid body simulators solve
- Kinematics constraints
- Collision and contact constraints
Rigid body dynamics
ODE's constraint solver uses a full coordinate system approach and enforces joint and contact constraints as posed by the linear complementarity problem (LCP).
Basic Governing Equations of Constrained Dynamics
Before we discuss the solvers, here is a very brief note here on the governing dynamics equations. Simple Euler's discretization yields

Constraints are described by the constraint Jacobian
given
or
where
for fixed joints and
for contact joints.
If we rewrite in matrix form we have:
![$\Biggl[$
\begin{tabular}{c c}
$\overline{\overline{M}}$ & $-\overline{\overline{J}}^{t}$ \\
$\overline{\overline{J}}$ & $0$ \\
\end{tabular}$\Biggr]$
$\Biggl[$
\begin{tabular}{c}
$\dot{\overline{v}}$ \\
$\overline\lambda$
\end{tabular}$\Biggr]$
$= $
$\Biggl[$
\begin{tabular}{c}
$\overline{f}_{ext}$ \\
$-\overline{k}$
\end{tabular}
$\Biggr]$ $\Biggl[$
\begin{tabular}{c c}
$\overline{\overline{M}}$ & $-\overline{\overline{J}}^{t}$ \\
$\overline{\overline{J}}$ & $0$ \\
\end{tabular}$\Biggr]$
$\Biggl[$
\begin{tabular}{c}
$\dot{\overline{v}}$ \\
$\overline\lambda$
\end{tabular}$\Biggr]$
$= $
$\Biggl[$
\begin{tabular}{c}
$\overline{f}_{ext}$ \\
$-\overline{k}$
\end{tabular}
$\Biggr]$](/wiki/physics_ode/ODE?action=AttachFile&do=get&target=latex_f9da05dc7c2df04495cc486e01069888514d9605_p1.png)
Substitute
and rearrange to get:
ODE is semi-implicit in that the Jacobians
and external forces
from the previous time step are used throughout the iterations.
Solvers
ODE ships with two default solvers
Lemke's Agorithm dWorldStep()
- This algorithm will attempt to achieve a numerically exact solution. It is about one order of magnitude slower than SOR PGS LCP solver and its convergence behavior is less predictable in practice.
Successive Over-Relaxation (SOR) Projected Gauss-Seidel (PGS) LCP solver dWorldQuickStep()
- Essentially a Gauss-Seidel algorithm with solution vector projected into the allowable solution space at every update. The PR2 robot simulations default to this algorithm running at 1kHz (to match mechanism controller update rate of the real robot).
Lemke's Agorithm
Please refer to step.cpp for implementation details. Various references contain discussions on this algorithm, see 2.7.1 in Michael Cline, "Rigid Body Simulation with Contacts and Constraints" for example.
SOR PGS LCP
As implemented in ODE's quickstep.cpp, and reiterating the solution procedure from several popular literatures here.
We are essentially solving a system of linear equations where the solution space is non-negative in parts of the system.

where based on the derivations from governing equations in the previous section,
![$$ \overline{b} = \frac{\overline{c}}{h} - \overline{\overline{J}}[ \frac{\overline{v}^{n}}{h} + \overline{\overline{M}}^{-1}\overline{f}_{ext} ]$$ $$ \overline{b} = \frac{\overline{c}}{h} - \overline{\overline{J}}[ \frac{\overline{v}^{n}}{h} + \overline{\overline{M}}^{-1}\overline{f}_{ext} ]$$](/wiki/physics_ode/ODE?action=AttachFile&do=get&target=latex_e1c18962d36e1eb4efcea14e1a08fb0d7ab70e6f_p1.png)
and
![$$ \overline{\overline{A}} = [\overline{\overline{J}}\overline{\overline{M}}^{-1}\overline{\overline{J}}^{T}] $$ $$ \overline{\overline{A}} = [\overline{\overline{J}}\overline{\overline{M}}^{-1}\overline{\overline{J}}^{T}] $$](/wiki/physics_ode/ODE?action=AttachFile&do=get&target=latex_de977ea417248626368f7928dccc2f8bb7578c90_p1.png)
If we solve for
in delta-form using Gauss-Seidel, i.e.

then it follows that

for
Formulate the desired solution in the form of acceleration1 (inverse mass matrix times constraint forces), denoted by

then
update becomes

and

for
where each
is projected into its corresponding solution space depending on the type of constraint specified.
At every iteration, for each
update above, constraint accelerations
are updated in the following manner:

for
where

For more details please see the list of references.
to clarify, in quickstep.cpp, $$\bar{a}_c$$ is denoted by variable fc as of svn revision 1675 (1)






