Simbody  3.4 (development)
System.h
Go to the documentation of this file.
00001 #ifndef SimTK_SimTKCOMMON_SYSTEM_H_
00002 #define SimTK_SimTKCOMMON_SYSTEM_H_
00003 
00004 /* -------------------------------------------------------------------------- *
00005  *                       Simbody(tm): SimTKcommon                             *
00006  * -------------------------------------------------------------------------- *
00007  * This is part of the SimTK biosimulation toolkit originating from           *
00008  * Simbios, the NIH National Center for Physics-Based Simulation of           *
00009  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
00010  * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody.  *
00011  *                                                                            *
00012  * Portions copyright (c) 2006-13 Stanford University and the Authors.        *
00013  * Authors: Michael Sherman                                                   *
00014  * Contributors: Peter Eastman                                                *
00015  *                                                                            *
00016  * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
00017  * not use this file except in compliance with the License. You may obtain a  *
00018  * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
00019  *                                                                            *
00020  * Unless required by applicable law or agreed to in writing, software        *
00021  * distributed under the License is distributed on an "AS IS" BASIS,          *
00022  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
00023  * See the License for the specific language governing permissions and        *
00024  * limitations under the License.                                             *
00025  * -------------------------------------------------------------------------- */
00026 
00027 #include "SimTKcommon/basics.h"
00028 #include "SimTKcommon/Simmatrix.h"
00029 #include "SimTKcommon/internal/State.h"
00030 #include "SimTKcommon/internal/Subsystem.h"
00031 
00032 #include <cassert>
00033 
00034 namespace SimTK {
00035 
00036 class DecorativeGeometry;
00037 class DefaultSystemSubsystem;
00038 class ScheduledEventHandler;
00039 class ScheduledEventReporter;
00040 class TriggeredEventHandler;
00041 class TriggeredEventReporter;
00042 class RealizeOptions;
00043 class RealizeResults;
00044 class ProjectOptions;
00045 class ProjectResults;
00046 
00047 //==============================================================================
00048 //                                 SYSTEM
00049 //==============================================================================
00096 class SimTK_SimTKCOMMON_EXPORT System {
00097 public:
00098 class Guts; // local; name is System::Guts
00099 
00100 
00101 //------------------------------------------------------------------------------
00124 System& setUpDirection(const CoordinateDirection& up);
00125 
00133 System& setUseUniformBackground(bool useUniformBackground);
00134 
00148 System& setDefaultTimeScale(Real tc);
00149 
00157 System& setDefaultLengthScale(Real lc);
00158 
00164 void setHasTimeAdvancedEvents(bool); // default=false
00165 
00167 CoordinateDirection getUpDirection() const;
00170 bool getUseUniformBackground() const;
00173 Real getDefaultTimeScale() const;
00176 Real getDefaultLengthScale() const;
00179 bool hasTimeAdvancedEvents() const;
00183 //------------------------------------------------------------------------------
00192 inline void addEventHandler(ScheduledEventHandler* handler);
00195 inline void addEventHandler(TriggeredEventHandler* handler);
00198 inline void addEventReporter(ScheduledEventReporter* handler) const;
00201 inline void addEventReporter(TriggeredEventReporter* handler) const;
00205 //------------------------------------------------------------------------------
00234 const State& realizeTopology() const;
00235 
00250 const State& getDefaultState() const;
00253 State&       updDefaultState();
00254 
00273 void realizeModel(State& state) const;
00274 
00282 void realize(const State& state, Stage stage = Stage::HighestRuntime) const;
00286 //------------------------------------------------------------------------------
00367 void project(State& state, Real accuracy=-1) const;
00368 
00384 void projectQ(State& state, Real accuracy=-1) const;
00385 
00403 void projectU(State& state, Real accuracy=-1) const;
00404 
00440 void projectQ(State& state, Vector& qErrEst, 
00441              const ProjectOptions& options, ProjectResults& results) const;
00442 
00466 void projectU(State& state, Vector& uErrEst, 
00467              const ProjectOptions& options, ProjectResults& results) const;
00468 
00469 
00487 void prescribe(State& state) const {
00488     realize(state, Stage::Time);
00489     prescribeQ(state);
00490     realize(state, Stage::Position);
00491     prescribeU(state);
00492 }
00493 
00512 bool prescribeQ(State& state) const;
00513 
00529 bool prescribeU(State& state) const;
00533 //------------------------------------------------------------------------------
00572 void handleEvents(State&                        state, 
00573                   Event::Cause                  cause, 
00574                   const Array_<EventId>&        eventIds,
00575                   const HandleEventsOptions&    options,
00576                   HandleEventsResults&          results) const;
00577     
00581 void reportEvents(const State&                  state, 
00582                   Event::Cause                  cause, 
00583                   const Array_<EventId>&        eventIds) const;
00584 
00593 void calcEventTriggerInfo(const State&              state,
00594                           Array_<EventTriggerInfo>& triggerInfo) const;
00595 
00601 void calcTimeOfNextScheduledEvent(const State&      state, 
00602                                   Real&             tNextEvent, 
00603                                   Array_<EventId>&  eventIds, 
00604                                   bool              includeCurrentTime) const;
00605 
00609 void calcTimeOfNextScheduledReport(const State&     state, 
00610                                    Real&            tNextEvent, 
00611                                    Array_<EventId>& eventIds, 
00612                                    bool             includeCurrentTime) const;
00616 //------------------------------------------------------------------------------
00645 void relax(State& state, Stage stage, Real accuracy=-1) const;
00649 //------------------------------------------------------------------------------
00670 void multiplyByN(const State& state, const Vector& u, 
00671                  Vector& dq) const;
00673 void multiplyByNTranspose(const State& state, const Vector& fq, 
00674                           Vector& fu) const;
00676 void multiplyByNPInv(const State& state, const Vector& dq, 
00677                      Vector& u) const;
00679 void multiplyByNPInvTranspose(const State& state, const Vector& fu, 
00680                               Vector& fq) const;
00684 //------------------------------------------------------------------------------
00694 void resetAllCountersToZero();
00695 
00696     // Realization
00697 
00701 int getNumRealizationsOfThisStage(Stage) const;
00702 
00706 int getNumRealizeCalls() const;
00707 
00708     // Prescribed motion
00709 
00711 int getNumPrescribeQCalls() const;
00713 int getNumPrescribeUCalls() const;
00714 
00715     // Projection
00716 
00719 int getNumProjectQCalls() const;
00721 int getNumFailedProjectQCalls() const;
00724 int getNumQProjections() const;
00727 int getNumQErrorEstimateProjections() const;
00728 
00731 int getNumProjectUCalls() const;
00733 int getNumFailedProjectUCalls() const;
00736 int getNumUProjections() const;
00739 int getNumUErrorEstimateProjections() const;
00740 
00741     // Event handling and reporting
00742 
00746 int getNumHandlerCallsThatChangedStage(Stage) const;
00747 
00750 int getNumHandleEventCalls() const;
00751 
00754 int getNumReportEventCalls() const;
00758 //------------------------------------------------------------------------------
00765 System() : guts(0) { }
00767 System(const System&);
00769 System& operator=(const System&);
00772 ~System();
00773 
00775 const String& getName()    const;
00777 const String& getVersion() const;
00778 
00781 SubsystemIndex adoptSubsystem(Subsystem& child);
00782 
00784 int getNumSubsystems() const;
00786 const Subsystem& getSubsystem(SubsystemIndex)   const;
00788 Subsystem& updSubsystem(SubsystemIndex);
00791 const DefaultSystemSubsystem& getDefaultSubsystem() const;
00794 DefaultSystemSubsystem& updDefaultSubsystem();
00795 
00799 inline operator const Subsystem&() const; // implemented below
00803 inline operator Subsystem&();
00804 
00809 bool systemTopologyHasBeenRealized() const;
00810 
00818 StageVersion getSystemTopologyCacheVersion() const;
00819 
00825 void setSystemTopologyCacheVersion(StageVersion topoVersion) const;
00826 
00836 void invalidateSystemTopologyCache() const;
00837 
00845 void calcDecorativeGeometryAndAppend(const State&, Stage, 
00846                                      Array_<DecorativeGeometry>&) const;
00847 
00848 
00851 bool isSameSystem(const System& otherSystem) const;
00852 
00853 
00857 const Guts& getSystemGuts() const {assert(guts); return *guts;}
00861 Guts&       updSystemGuts()       {assert(guts); return *guts;}
00862 
00866 void adoptSystemGuts(System::Guts* g);
00867 
00869 explicit System(System::Guts* g) : guts(g) { }
00871 bool hasGuts() const {return guts!=0;}
00872 
00874 bool isOwnerHandle() const;
00876 bool isEmptyHandle() const;
00879 private:
00880 friend class Guts;
00881 // This is the only data member in this class. Also, any class derived from
00882 // System must have *NO* data members at all (data goes in the Guts class).
00883 Guts*   guts;
00884 };
00885 
00886 
00895 class SimTK_SimTKCOMMON_EXPORT DefaultSystemSubsystem : public Subsystem {
00896 public:
00897     explicit DefaultSystemSubsystem(System& sys);
00898     void addEventHandler(ScheduledEventHandler* handler);
00899     void addEventHandler(TriggeredEventHandler* handler);
00900     void addEventReporter(ScheduledEventReporter* handler) const;
00901     void addEventReporter(TriggeredEventReporter* handler) const;
00902     EventId createEventId(SubsystemIndex subsys, const State& state) const;
00903     void findSubsystemEventIds
00904        (SubsystemIndex subsys, const State& state, 
00905         const Array_<EventId>& allEvents, 
00906         Array_<EventId>& eventsForSubsystem) const;
00907   // don't let doxygen see this private class
00909     class Guts;
00911 private:
00912     const Guts& getGuts() const;
00913     Guts& updGuts();
00914 };
00915 
00916 inline void System::addEventHandler(ScheduledEventHandler* handler)
00917 {   updDefaultSubsystem().addEventHandler(handler); }
00918 inline void System::addEventHandler(TriggeredEventHandler* handler)
00919 {   updDefaultSubsystem().addEventHandler(handler); }
00920 inline void System::addEventReporter(ScheduledEventReporter* handler) const
00921 {   getDefaultSubsystem().addEventReporter(handler); }
00922 inline void System::addEventReporter(TriggeredEventReporter* handler) const
00923 {   getDefaultSubsystem().addEventReporter(handler); }
00924 
00925 inline System::operator const Subsystem&() const {return getDefaultSubsystem();}
00926 inline System::operator Subsystem&() {return updDefaultSubsystem();}
00927 
00928 
00929 //==============================================================================
00930 //                     PROJECT OPTIONS and PROJECT RESULTS
00931 //==============================================================================
00935 class ProjectOptions {
00936 public:
00937     enum Option {
00939         None            = 0x0000,
00944         LocalOnly       = 0x0001,
00948         DontThrow       = 0x0002,
00951         UseInfinityNorm = 0x0004,
00955         ForceProjection = 0x0008,
00959         ForceFullNewton = 0x0010
00960     };
00961 
00963     ProjectOptions() {clear();}
00967     explicit ProjectOptions(Real accuracy) 
00968     {   clear(); setRequiredAccuracy(accuracy); }
00971     explicit ProjectOptions(Option opt)
00972     {   clear(); setOption(opt); }
00973 
00977     ProjectOptions& clear() 
00978     {   optionSet=0; setAccuracyDefaults(); return *this; }
00979 
00984     ProjectOptions& setRequiredAccuracy(Real accuracy) {
00985         requiredAccuracy = accuracy > 0 ? accuracy 
00986                                         : getDefaultRequiredAccuracy();
00987         return *this;
00988     }
00989 
00992     ProjectOptions& setOvershootFactor(Real overshoot) {
00993         assert(0 < overshoot && overshoot <= 1);
00994         desiredOvershoot = overshoot;
00995         return *this;
00996     }
00997 
01000     ProjectOptions& setProjectionLimit(Real limit) {
01001         assert(limit > 0);
01002         projectionLimit = limit;
01003         return *this;
01004     }
01005 
01008     ProjectOptions& clearOption(Option opt) 
01009     {   optionSet &= ~(unsigned)opt; return *this; }
01011     ProjectOptions& setOption  (Option opt) 
01012     {   optionSet |= (unsigned)opt; return *this; }
01013 
01015     Real getRequiredAccuracy()       const {return requiredAccuracy;}
01018     Real getOvershootFactor() const {return desiredOvershoot;}
01020     Real getProjectionLimit() const {return projectionLimit;}
01021 
01022     bool isOptionSet(Option opt) const {return (optionSet&(unsigned)opt) != 0;}
01023 
01024     static Real getDefaultRequiredAccuracy() {return Real(1e-4);}
01025     static Real getDefaultOvershootFactor()  {return Real(0.1);} //i.e., 1e-5
01026 
01027     // Set operators: not, or, and, set difference
01028     ProjectOptions& operator|=(const ProjectOptions& opts) 
01029     {   optionSet |= opts.optionSet; return *this; }
01030     ProjectOptions& operator&=(const ProjectOptions& opts) 
01031     {   optionSet &= opts.optionSet; return *this; }
01032     ProjectOptions& operator-=(const ProjectOptions& opts) 
01033     {   optionSet &= ~opts.optionSet; return *this; }
01034 
01035     ProjectOptions& operator|=(Option opt) {setOption(opt); return *this;}
01036     ProjectOptions& operator-=(Option opt) {clearOption(opt); return *this;}
01037 
01038 private:
01039     Real     requiredAccuracy;
01040     Real     desiredOvershoot; // try for accuracy*overshoot
01041     Real     projectionLimit;  // abort if initial norm is worse than this
01042     unsigned optionSet;
01043 
01044     void setAccuracyDefaults() {
01045         requiredAccuracy = getDefaultRequiredAccuracy();
01046         desiredOvershoot = getDefaultOvershootFactor(); 
01047         projectionLimit  = Infinity; // we'll try from however far away
01048     }
01049 };
01050 
01052 class ProjectResults {
01053 public:
01054     ProjectResults() {clear();}
01055 
01056     enum Status {
01058         Invalid                 = -1,
01061         Succeeded               = 0,
01064         FailedToAchieveAccuracy = 1,
01069         FailedToConverge        = 2    
01070     };
01071 
01074     ProjectResults& clear() {
01075         m_exitStatus = Invalid;
01076         m_anyChangeMade = m_projectionLimitExceeded = false;
01077         m_numIterations = 0;
01078         m_worstError = -1;
01079         m_normOnEntrance = m_normOnExit = NaN;
01080         return *this;
01081     }
01082     bool    isValid()        const {return m_exitStatus != Invalid;}
01083     Status  getExitStatus()  const {return m_exitStatus;}
01084 
01085     bool getAnyChangeMade()  const {assert(isValid());return m_anyChangeMade;}
01086     int  getNumIterations()  const {assert(isValid());return m_numIterations;}
01087     Real getNormOnEntrance() const {assert(isValid());return m_normOnEntrance;}
01088     Real getNormOnExit()     const {assert(isValid());return m_normOnExit;}
01089     int  getWorstErrorOnEntrance()    const 
01090     {   assert(isValid());return m_worstError; }
01091     bool getProjectionLimitExceeded() const 
01092     {   assert(isValid());return m_projectionLimitExceeded; }
01093 
01094     ProjectResults& setExitStatus(Status status) 
01095     {   m_exitStatus=status; return *this; }
01096     ProjectResults& setAnyChangeMade(bool changeMade) 
01097     {   m_anyChangeMade=changeMade; return *this; }
01098     ProjectResults& setProjectionLimitExceeded(bool limitExceeded) 
01099     {   m_projectionLimitExceeded=limitExceeded; return *this; }
01100     ProjectResults& setNumIterations(int numIterations) 
01101     {   m_numIterations=numIterations; return *this; }
01102     ProjectResults& setNormOnEntrance(Real norm, int worstError) 
01103     {   m_normOnEntrance=norm; m_worstError=worstError; return *this; }
01104     ProjectResults& setNormOnExit(Real norm) 
01105     {   m_normOnExit=norm; return *this; }
01106 private:
01107     Status  m_exitStatus;
01108     bool    m_anyChangeMade;
01109     bool    m_projectionLimitExceeded;
01110     int     m_numIterations;
01111     int     m_worstError;       // index of worst error on entrance
01112     Real    m_normOnEntrance;   // in selected rms or infinity norm
01113     Real    m_normOnExit;
01114 };
01115 
01116 
01117 
01118 //==============================================================================
01119 //                    REALIZE OPTIONS and REALIZE RESULTS 
01120 //==============================================================================
01122 class RealizeOptions {
01123     unsigned int optionSet;
01124     explicit RealizeOptions(unsigned o) : optionSet(o) { }
01125 public:
01126 
01127     enum Option {
01128         None      = 0x00,
01129         DontThrow = 0x01
01130     };
01131 
01132 
01133     RealizeOptions() : optionSet(0) { }
01134 
01135     // This is an implicit conversion
01136     RealizeOptions(Option opt) : optionSet((unsigned)opt) { }
01137 
01138     // Implicit conversion to bool when needed
01139     operator bool() const {return optionSet != 0;}
01140     bool isEmpty() const {return optionSet==0;}
01141 
01142     bool isOptionSet(Option opt) const {return (optionSet&(unsigned)opt) != 0;}
01143     void clear() {optionSet=0;}
01144     void clearOption(Option opt) {optionSet &= ~(unsigned)opt;}
01145     void setOption  (Option opt) {optionSet |= (unsigned)opt;}
01146 
01147     // Set operators: or, and
01148     RealizeOptions& operator|=(RealizeOptions opts) {optionSet |= opts.optionSet; return *this;}
01149     RealizeOptions& operator&=(RealizeOptions opts) {optionSet &= opts.optionSet; return *this;}
01150 
01151     RealizeOptions& operator|=(Option opt) {setOption(opt); return *this;}
01152     RealizeOptions& operator-=(Option opt) {clearOption(opt); return *this;}
01153 };
01154 
01156 class RealizeResults {
01157 };
01158 
01159 
01160 
01161 
01162 } // namespace SimTK
01163 
01164 #endif // SimTK_SimTKCOMMON_SYSTEM_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines