Simbody
3.6
|
This is the abstract base class for impulse solvers, which solve an important subproblem of the contact and impact equations. More...
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 |
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).
|
inline |
|
inlinevirtual |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
pure virtual |
Solve.
Implemented in SimTK::PGSImpulseSolver, and SimTK::PLUSImpulseSolver.
|
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 |
|
static |
|
static |
|
static |
|
static |
|
static |
|
protected |
|
protected |
|
protected |
|
mutableprotected |
|
mutableprotected |
|
mutableprotected |
|
mutableprotected |
|
mutableprotected |
|
mutableprotected |