Simbody
3.6

This is an implementation of the fixedstep SemiExplicit Euler method, also known as SemiImplicit Euler or Symplectic Euler. More...
Public Member Functions  
SemiExplicitEulerIntegrator (const System &sys, Real stepSize)  
Create a SemiExplicitEulerIntegrator for integrating a System with fixed size steps. More...  
Public Member Functions inherited from SimTK::Integrator  
Integrator ()  
~Integrator ()  
const char *  getMethodName () const 
Get the name of this integration method. More...  
int  getMethodMinOrder () const 
Get the minimum order this Integrator may use. More...  
int  getMethodMaxOrder () const 
Get the maximum order this Integrator may use. More...  
bool  methodHasErrorControl () const 
Get whether this Integrator provides error control. More...  
void  initialize (const State &state) 
Supply the integrator with a starting state. More...  
void  reinitialize (Stage stage, bool shouldTerminate) 
After an event handler has made a discontinuous change to the Integrator's "advanced state", this method must be called to reinitialize the Integrator. More...  
const State &  getState () const 
Return a State corresponding to the "current" time at the end of the last call to stepTo() or stepBy(). More...  
Real  getTime () const 
Get the time of the current State. This is equivalent to calling getState().getTime(). More...  
bool  isStateInterpolated () const 
Get whether getState() will return an interpolated state or just the same thing as getAdvancedState() does. More...  
const State &  getAdvancedState () const 
Return the state representing the trajectory point to which the integrator has irreversibly advanced. More...  
Real  getAdvancedTime () const 
Get the time of the advanced State. This is equivalent to calling getAdvancedState().getTime(). More...  
State &  updAdvancedState () 
Get a nonconst reference to the advanced state. More...  
Real  getAccuracyInUse () const 
Get the accuracy which is being used for error control. More...  
Real  getConstraintToleranceInUse () const 
Get the constraint tolerance which is being used for error control. More...  
SuccessfulStepStatus  stepTo (Real reportTime, Real scheduledEventTime=Infinity) 
Integrate the System until something happens which requires outside processing, and return a status code describing what happened. More...  
SuccessfulStepStatus  stepBy (Real interval, Real scheduledEventTime=Infinity) 
Integrate the System until something happens which requires outside processing, and return a status code describing what happened. More...  
Vec2  getEventWindow () const 
Get the window (tLow, tHigh] within which one or more events have been localized. More...  
const Array_< EventId > &  getTriggeredEvents () const 
Get the IDs of all events which have been localized within the event window. More...  
const Array_< Real > &  getEstimatedEventTimes () const 
Get the estimated times of all events which have been localized within the event window. More...  
const Array_< Event::Trigger > &  getEventTransitionsSeen () const 
Get EventTriggers describing the events which have been localized within the event window. More...  
bool  isSimulationOver () const 
Get whether the simulation has terminated. More...  
TerminationReason  getTerminationReason () const 
Get the reason the simulation terminated. More...  
void  resetAllStatistics () 
Reset all statistics to zero. More...  
Real  getActualInitialStepSizeTaken () const 
Get the size of the first successful step after the last initialize() call. More...  
Real  getPreviousStepSizeTaken () const 
Get the size of the most recent successful step. More...  
Real  getPredictedNextStepSize () const 
Get the step size that will be attempted first on the next call to stepTo() or stepBy(). More...  
int  getNumStepsAttempted () const 
Get the total number of steps that have been attempted (successfully or unsuccessfully) since the last call to resetAllStatistics(). More...  
int  getNumStepsTaken () const 
Get the total number of steps that have been successfully taken since the last call to resetAllStatistics(). More...  
int  getNumRealizations () const 
Get the total number of state realizations that have been performed since the last call to resetAllStatistics(). More...  
int  getNumQProjections () const 
Get the total number of times a state positions Q have been projected since the last call to resetAllStatistics(). More...  
int  getNumUProjections () const 
Get the total number of times a state velocities U have been projected since the last call to resetAllStatistics(). More...  
int  getNumProjections () const 
Get the total number of times a state has been projected (counting both Q and U projections) since the last call to resetAllStatistics(). More...  
int  getNumErrorTestFailures () const 
Get the number of attempted steps that have failed due to the error being unacceptably high since the last call to resetAllStatistics(). More...  
int  getNumConvergenceTestFailures () const 
Get the number of attempted steps that failed due to nonconvergence of internal step iterations. More...  
int  getNumRealizationFailures () const 
Get the number of attempted steps that have failed due to an error when realizing the state since the last call to resetAllStatistics(). More...  
int  getNumQProjectionFailures () const 
Get the number of attempted steps that have failed due to an error when projecting the state positions (Q) since the last call to resetAllStatistics(). More...  
int  getNumUProjectionFailures () const 
Get the number of attempted steps that have failed due to an error when projecting the state velocities (U) since the last call to resetAllStatistics(). More...  
int  getNumProjectionFailures () const 
Get the number of attempted steps that have failed due to an error when projecting the state (either a Q or Uprojection) since the last call to resetAllStatistics(). More...  
int  getNumConvergentIterations () const 
For iterative methods, get the number of internal step iterations in steps that led to convergence (not necessarily successful steps). More...  
int  getNumDivergentIterations () const 
For iterative methods, get the number of internal step iterations in steps that did not lead to convergence. More...  
int  getNumIterations () const 
For iterative methods, this is the total number of internal step iterations taken regardless of whether those iterations led to convergence or to successful steps. More...  
void  setFinalTime (Real tFinal) 
Set the time at which the simulation should end. More...  
void  setInitialStepSize (Real hinit) 
Set the initial step size that should be attempted. More...  
void  setMinimumStepSize (Real hmin) 
Set the minimum step size that should ever be used. More...  
void  setMaximumStepSize (Real hmax) 
Set the maximum step size that should ever be used. More...  
void  setFixedStepSize (Real stepSize) 
Set the integrator to use a single fixed step size for all steps. More...  
void  setAccuracy (Real accuracy) 
Set the overall accuracy that should be used for integration. More...  
void  setConstraintTolerance (Real consTol) 
Set the tolerance within which constraints must be satisfied. More...  
void  setUseInfinityNorm (bool useInfinityNorm) 
(Advanced) Use infinity norm (maximum absolute value) instead of default RMS norm to evaluate whether accuracy has been achieved for states and for constraint tolerance. More...  
bool  isInfinityNormInUse () const 
(Advanced) Are we currently using the infinity norm? More...  
void  setInternalStepLimit (int nSteps) 
Set the maximum number of steps that may be taken within a single call to stepTo() or stepBy(). More...  
void  setReturnEveryInternalStep (bool shouldReturn) 
Set whether the Integrator should return from stepTo() or stepBy() after every internal step, even if no event has occurred and the report time has not been reached. More...  
void  setProjectEveryStep (bool forceProject) 
Set whether the system should be projected back to the constraint manifold after every step. More...  
void  setAllowInterpolation (bool shouldInterpolate) 
Set whether the Integrator is permitted to return interpolated states for reporting purposes which may be less accurate than the "real" states that form the trajectory. More...  
void  setProjectInterpolatedStates (bool shouldProject) 
Set whether interpolated states should be projected back to the constraint manifold after interpolation is performed. More...  
void  setForceFullNewton (bool forceFullNewton) 
(Advanced) Constraint projection may use an outofdate iteration matrix for efficiency. More...  
Additional Inherited Members  
Public Types inherited from SimTK::Integrator  
enum  SuccessfulStepStatus { ReachedReportTime =1, ReachedEventTrigger =2, ReachedScheduledEvent =3, TimeHasAdvanced =4, ReachedStepLimit =5, EndOfSimulation =6, StartOfContinuousInterval =7, InvalidSuccessfulStepStatus = 1 } 
When a step is successful, it will return an indication of what caused it to stop where it did. More...  
enum  TerminationReason { ReachedFinalTime = 1, AnUnrecoverableErrorOccurred = 2, EventHandlerRequestedTermination = 3, InvalidTerminationReason = 1 } 
Once the simulation has ended, getTerminationReason() may be called to find out what caused it to end. More...  
Static Public Member Functions inherited from SimTK::Integrator  
static String  getSuccessfulStepStatusString (SuccessfulStepStatus) 
Get a human readable description of the reason a step returned. More...  
static String  getTerminationReasonString (TerminationReason) 
Get a human readable description of the termination reason. More...  
static String  successfulStepStatusString (SuccessfulStepStatus stat) 
OBSOLETE: use getSuccessfulStepStatusString(). More...  
Protected Member Functions inherited from SimTK::Integrator  
const IntegratorRep &  getRep () const 
IntegratorRep &  updRep () 
Protected Attributes inherited from SimTK::Integrator  
IntegratorRep *  rep 
This is an implementation of the fixedstep SemiExplicit Euler method, also known as SemiImplicit Euler or Symplectic Euler.
This method is very popular for game engines such as ODE, because it is a first order method that is more stable than Explicit Euler. However, the implementation used in gaming is fully explicit, which is only correct if there are no velocitydependent force elements. Coriolis forces, damping, etc. would require an implicit solution which is generally too slow for real time simulation.
The correct implementation of this method is described in Geometric Numerical Integration, Hairer, Lubich & Wanner 2006, page 3. The method applies to a system of differential equations that can be partitioned like this:
udot = udot(q,u) qdot = qdot(q,u) = N(q)u in Simbody
SemiImplicit Euler treats one variable implicitly, and the other explicitly, producing two different possible forms:
Form 1: q1 = q0 + h qdot(q1,u0) < implicit in q u1 = u0 + h udot(q1,u0) Form 2: u1 = u0 + h udot(q0,u1) < implicit in u q1 = q0 + h qdot(q0,u1)
If udot were udot(q) only, Form 2 would be
u1 = u0 + h udot(q0) < if no velocity dependence q1 = q0 + h N(q0)u1
That would be a correct, yet fully explicit implementation of Symplectic Euler. Instead, the standard gaming implementation is
u1 = u0 + h udot(q0,u0) < wrong; should be implicit in u q1 = q0 + h N(q0)u1
This differs from a true Symplectic Euler by however much the velocity dependent forces change from u0 to u1. If they are very small, no great loss. That may be less likely in internal coordinates though. Making this implicit would be quite expensive since we don't have analytical partial derivatives of udot available.
Form 1 on the other hand could be implemented efficiently as a true semiimplicit method:
q1 = q0 + h N(q1)u0 < implicit in q u1 = u0 + h udot(q1,u0)
The directional partial derivatives D N(q)*u0 / D q are easily calculated for the block diagonal matrix N which in many cases is just an identity matrix. A disadvantage is that accelerations are unknown at (q0,u0) and (q1,u1); if those are needed (very common!) a second evaluation of the accelerations would be required. For that expense, a second order integration method could have been used instead. I also don't know whether this form would have the same stability properties in practice as the other one; it would be interesting to experiment. However, for now we use Form 2 in the gamer's fullyexplicit style. This will not work well in the presence of huge damping forces and probably not for very high rotation rates either!
SimTK::SemiExplicitEulerIntegrator::SemiExplicitEulerIntegrator  (  const System &  sys, 
Real  stepSize  
) 
Create a SemiExplicitEulerIntegrator for integrating a System with fixed size steps.