Drake C++ Documentation

Constraints can be categorized as either bilateral ("two-sided" constraints, e.g., g(q) = 0) or unilateral ("one-sided" constraints, e.g., g(q) ≥ 0).

Although the former can be realized through the latter using a pair of inequality constraints, g(q) ≥ 0 and -g(q) ≥ 0; the constraint problem structure distinguishes the two types to maximize computational efficiency in the solution algorithms. It is assumed throughout this documentation that g(.) is a vector function. In general, the constraint functions do not maintain consistent units: the units of the iᵗʰ constraint function are not necessarily equivalent to the units of the jᵗʰ dimension of g(.).

Constraints may be posed at the position level:


at the velocity level:


or at the acceleration level:


Additionally, constraints posed at any level can impose constraints on the constraint forces, λ. For example, the position-level constraint:


could be used to enforce q ≥ 0, λ ≥ 0, and qλ = 0, a triplet of conditions useful for, e.g., ensuring that a joint range-of-motion limit is respected (q ≥ 0), guaranteeing that no constraint force is applied if the constraint is not active (q > 0 implies λ = 0), and guaranteeing that the constraint force can only push the connected links apart at the joint rather than act to "glue" them together (λ > 0).

Note the semicolon in all of the above definitions of g() separates general constraint dependencies (e.g., t,q,v in gₐ) from variables that must be determined using the constraints (e.g., v̇ in gₐ).

Constraints with velocity-level unknowns

This documentation distinguishes between equations that are posed at the position level but are differentiated once with respect to time (i.e., to reduce the Differential Algebraic Equation or Differential Complementarity Problem index [Ascher 1998]):

d/dt gₚ(t; q) = ġₚ(t, q; v)

vs. equations that must be posed at the velocity-level (i.e., nonholonomic constraints):

gᵥ(t, q; v).

Both cases yield a constraint with velocity-level unknowns, thereby allowing the constraint to be used in a velocity-level constraint formulation (e.g., an Index-2 DAE or Index-2 DCP). Only the former constraint may "drift" from zero over time, due to truncation and discretization errors, unless corrected. See Constraint stabilization for further information.

Constraints with force and acceleration-level unknowns

A bilateral constraint equation with force and acceleration-level unknowns will take the form:

g̈ₚ(t,q,v;v̇) = 0

if gₚ(.) has been differentiated twice with respect to time (for DAE/DCP index reduction), or

ġᵥ(t,q,v;v̇) = 0

if gᵥ(.) is nonholonomic and has been differentiated once with respect to time (again, for DAE/DCP index reduction). As noted elsewhere, constraints can also incorporate terms dependent on constraint forces, like:

g̈ₚ + λ = 0

Making the constraint type above more general by permitting unknowns over λ allows constraints to readily express, e.g., sliding Coulomb friction constraints (of the form fₜ = μ⋅fₙ).

Complementarity conditions

Each unilateral constraint comprises a triplet of equations. For example:

gₐ(t,q,v;v̇,λ) ≥ 0
λ ≥ 0
gₐ(t,q,v;v̇,λ)⋅λ = 0

which we will typically write in the common shorthand notation:

0 ≤ gₐ  ⊥  λ ≥ 0

Interpreting this triplet of constraint equations, two conditions become apparent: (1) when the constraint is inactive (gₐ > 0), the constraint force must be zero (λ = 0) and (2) the constraint force can only act in one direction (λ ≥ 0). This triplet is known as a complementarity constraint.