Simbody  3.5
SimTK::ImpulseSolver Class Referenceabstract

This is the abstract base class for impulse solvers, which solve an important subproblem of the contact and impact equations. More...

+ Inheritance diagram for SimTK::ImpulseSolver:

Classes

struct  BoundedRT
 
struct  ConstraintLtdFrictionRT
 
struct  StateLtdFrictionRT
 
struct  UncondRT
 
struct  UniContactRT
 
struct  UniSpeedRT
 

Public Types

enum  ContactType {
  TypeNA =-1,
  Observing =0,
  Known =1,
  Participating =2
}
 
enum  UniCond {
  UniNA =-1,
  UniOff =0,
  UniActive =1,
  UniKnown =2
}
 
enum  FricCond {
  FricNA =-1,
  FricOff =0,
  Sliding =1,
  Impending =2,
  Rolling =3
}
 
enum  BndCond {
  BndNA =-1,
  SlipLow =0,
  ImpendLow =1,
  Engaged =2,
  ImpendHigh =3,
  SlipHigh =4
}
 

Public Member Functions

 ImpulseSolver (Real roll2slipTransitionSpeed, Real convergenceTol, int maxIters)
 
virtual ~ImpulseSolver ()
 
void setMaxRollingSpeed (Real roll2slipTransitionSpeed)
 
Real getMaxRollingSpeed () const
 
void setConvergenceTol (Real tol)
 
Real getConvergenceTol () const
 
void setMaxIterations (int maxIts)
 
int getMaxIterations () const
 
void clearStats () const
 
void clearStats (int phase) const
 
virtual bool solve (int phase, const Array_< MultiplierIndex > &participating, const Matrix &A, const Vector &D, const Array_< MultiplierIndex > &expanding, Vector &piExpand, Vector &verrStart, Vector &verrApplied, Vector &pi, Array_< UncondRT > &unconditional, Array_< UniContactRT > &uniContact, Array_< UniSpeedRT > &uniSpeed, Array_< BoundedRT > &bounded, Array_< ConstraintLtdFrictionRT > &consLtdFriction, Array_< StateLtdFrictionRT > &stateLtdFriction) const =0
 Solve. More...
 
virtual bool solveBilateral (const Array_< MultiplierIndex > &participating, const Matrix &A, const Vector &D, const Vector &rhs, Vector &pi) const =0
 Solve a set of bilateral (unconditional) constraints for the impulse necessary to enforce them. More...
 

Static Public Member Functions

static const char * getContactTypeName (ContactType ct)
 
static const char * getUniCondName (UniCond uc)
 
static const char * getFricCondName (FricCond fc)
 
static const char * getBndCondName (BndCond bc)
 
static void dumpUniContacts (const String &msg, const Array_< UniContactRT > &uniContacts)
 

Static Public Attributes

static const int MaxNumPhases = 3
 

Protected Attributes

Real m_maxRollingTangVel
 
Real m_convergenceTol
 
int m_maxIters
 
long long m_nSolves [MaxNumPhases]
 
long long m_nIters [MaxNumPhases]
 
long long m_nFail [MaxNumPhases]
 
long long m_nBilateralSolves
 
long long m_nBilateralIters
 
long long m_nBilateralFail
 

Detailed Description

This is the abstract base class for impulse solvers, which solve an important subproblem of the contact and impact equations.

Impact problem:

    M  du    + ~G (pi+piE) = 0
    G (u+du) -  D (pi+piE) = b - verrNewton

where verrNewton is constraint space velocity error due to Newton restitution (not used for Poisson restitution). Moving knowns to the right:

    M  du    + ~G pi = -~G piE
    G  du    -  D pi = b - G u - verrNewton + D piE

Substituting 2nd eqn into first gives this impact subproblem:

    [A+D] pi = verr0 + verrNewton + verrExpand
    where verr0 = Gu-b, verrExpand = -[A+D]piE, and A=G M\ ~G.

Contact problem:

    M du + ~G pi  = h f
    G du -  D pi  = b - G u

Substituting gives this contact subproblem:

    [A+D] pi = verr0 + verrApplied
    where verrApplied = h G M\ f.

The form of the problems is the same, with different RHS and no expansion impulse given for contact. The impulse solver thus solves this system of equations and inequalities:

    [A+D] (piExpand + piUnknown) = verrStart + verrApplied
    where verrStart = verr0 + verrNewton

subject to several inequalities and replacement of friction rows by sliding or impending slip equations for the unknown impulse piUnknown. piExpand is the given Poisson expansion impulse, non-zero only for expanding unilateral normal contacts, with piExpand_z[k]<=0 for each unilateral contact k. A is an mXm symmetric positive semidefinite matrix, D a diagonal matrix with nonnegative elements, pi=piExpand+piUnknown and rhs are m-vectors. We write pi this way because friction limits depend on pi, not just piUnknown. We require piExpand_z<=0 for unilateral normal contacts z.

Similarly, we must separate verrStart and verrApplied, because verrStart contains the actual constraint-space velocities, especially sliding, which we need in order to determine sliding direction and contact status (rolling or sliding). verrApplied just represents what the applied forces would do if there were no constraints; the constraints will react to that so that the actual velocity changes will be much different.

For each "sliding step", we classify frictional contacts based on the current contents of verrStart, then solve:

    [A+D] piUnknown = verrStart + verrApplied - [A+D]*piExpand 
    with inequalities
    piUnknown_z <= 0
    sqrt(piUnknown_x^2+piUnknown_y^2) <= -mu*pi_z
    where pi=piUnknown+piExpand

We then choose a fraction s of this sliding step to accept, with 0<s<=1, then update

    verrStart   += s*(verrApplied - [A+D]*pi)
    piExpand    -= s*piExpand
    verrApplied -= s*verrApplied

If s < 1 then we are not done. In that case we have removed some of the verr and used up some of the expansion impulse. Return to do another sliding step until we take one where s==1.

We return piUnknown and the updated verrStart which would be zero if all contacts were active and rolling.

There are often multiple solutions for piUnknown; consult the documentation for particular ImpulseSolver implementations to determine which solution is returned. Possibilities include: any solution (PGS), and the least squares solution (PLUS).

Member Enumeration Documentation

Enumerator
TypeNA 
Observing 
Known 
Participating 
Enumerator
UniNA 
UniOff 
UniActive 
UniKnown 
Enumerator
FricNA 
FricOff 
Sliding 
Impending 
Rolling 
Enumerator
BndNA 
SlipLow 
ImpendLow 
Engaged 
ImpendHigh 
SlipHigh 

Constructor & Destructor Documentation

SimTK::ImpulseSolver::ImpulseSolver ( Real  roll2slipTransitionSpeed,
Real  convergenceTol,
int  maxIters 
)
inline
virtual SimTK::ImpulseSolver::~ImpulseSolver ( )
inlinevirtual

Member Function Documentation

void SimTK::ImpulseSolver::setMaxRollingSpeed ( Real  roll2slipTransitionSpeed)
inline
Real SimTK::ImpulseSolver::getMaxRollingSpeed ( ) const
inline
void SimTK::ImpulseSolver::setConvergenceTol ( Real  tol)
inline
Real SimTK::ImpulseSolver::getConvergenceTol ( ) const
inline
void SimTK::ImpulseSolver::setMaxIterations ( int  maxIts)
inline
int SimTK::ImpulseSolver::getMaxIterations ( ) const
inline
void SimTK::ImpulseSolver::clearStats ( ) const
inline
void SimTK::ImpulseSolver::clearStats ( int  phase) const
inline
virtual bool SimTK::ImpulseSolver::solve ( int  phase,
const Array_< MultiplierIndex > &  participating,
const Matrix A,
const Vector D,
const Array_< MultiplierIndex > &  expanding,
Vector piExpand,
Vector verrStart,
Vector verrApplied,
Vector pi,
Array_< UncondRT > &  unconditional,
Array_< UniContactRT > &  uniContact,
Array_< UniSpeedRT > &  uniSpeed,
Array_< BoundedRT > &  bounded,
Array_< ConstraintLtdFrictionRT > &  consLtdFriction,
Array_< StateLtdFrictionRT > &  stateLtdFriction 
) const
pure virtual
virtual bool SimTK::ImpulseSolver::solveBilateral ( const Array_< MultiplierIndex > &  participating,
const Matrix A,
const Vector D,
const Vector rhs,
Vector pi 
) const
pure virtual

Solve a set of bilateral (unconditional) constraints for the impulse necessary to enforce them.

This can be used for projecting a set of violated active constraints onto their manifold. This just solves the linear system

    P*(A+D)*~P P*pi = P*rhs 
            Pbar*pi = 0

where P is a pXm "participation" matrix such that P(i,j)=1 if constraint j is the i'th active constraint, zero otherwise, and Pbar is the "nonparticipation" matrix such that Pbar(i,j)=1 if constraint j is the i'th inactive constraint, zero otherwise. A is mXm symmetric, positive semidefinite, but may be rank deficient. D is an mXm diagonal matrix with only nonnegative elements. The returned solution pi (mX1) should ideally be the solution of minimum 2-norm ||pi|| if the system is underdetermined, or the solution that minimizes the 2-norm of the error ||(A+D)pi-rhs|| (participating part only) if the solution is overdetermined and inconsistent. However, concrete ImpulseSolvers are free to return a different solution provide their behavior is well documented. The method used should be qualitatively similar to that used by the solve() method for the same concrete ImpulseSolver. For example, if solve() uses an iterative method then this should also do so.

Implemented in SimTK::PGSImpulseSolver, and SimTK::PLUSImpulseSolver.

static const char* SimTK::ImpulseSolver::getContactTypeName ( ContactType  ct)
static
static const char* SimTK::ImpulseSolver::getUniCondName ( UniCond  uc)
static
static const char* SimTK::ImpulseSolver::getFricCondName ( FricCond  fc)
static
static const char* SimTK::ImpulseSolver::getBndCondName ( BndCond  bc)
static
static void SimTK::ImpulseSolver::dumpUniContacts ( const String msg,
const Array_< UniContactRT > &  uniContacts 
)
static

Member Data Documentation

const int SimTK::ImpulseSolver::MaxNumPhases = 3
static
Real SimTK::ImpulseSolver::m_maxRollingTangVel
protected
Real SimTK::ImpulseSolver::m_convergenceTol
protected
int SimTK::ImpulseSolver::m_maxIters
protected
long long SimTK::ImpulseSolver::m_nSolves[MaxNumPhases]
mutableprotected
long long SimTK::ImpulseSolver::m_nIters[MaxNumPhases]
mutableprotected
long long SimTK::ImpulseSolver::m_nFail[MaxNumPhases]
mutableprotected
long long SimTK::ImpulseSolver::m_nBilateralSolves
mutableprotected
long long SimTK::ImpulseSolver::m_nBilateralIters
mutableprotected
long long SimTK::ImpulseSolver::m_nBilateralFail
mutableprotected

The documentation for this class was generated from the following file: