Simbody  3.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
System.h
Go to the documentation of this file.
1 #ifndef SimTK_SimTKCOMMON_SYSTEM_H_
2 #define SimTK_SimTKCOMMON_SYSTEM_H_
3 
4 /* -------------------------------------------------------------------------- *
5  * Simbody(tm): SimTKcommon *
6  * -------------------------------------------------------------------------- *
7  * This is part of the SimTK biosimulation toolkit originating from *
8  * Simbios, the NIH National Center for Physics-Based Simulation of *
9  * Biological Structures at Stanford, funded under the NIH Roadmap for *
10  * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody. *
11  * *
12  * Portions copyright (c) 2006-13 Stanford University and the Authors. *
13  * Authors: Michael Sherman *
14  * Contributors: Peter Eastman *
15  * *
16  * Licensed under the Apache License, Version 2.0 (the "License"); you may *
17  * not use this file except in compliance with the License. You may obtain a *
18  * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. *
19  * *
20  * Unless required by applicable law or agreed to in writing, software *
21  * distributed under the License is distributed on an "AS IS" BASIS, *
22  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
23  * See the License for the specific language governing permissions and *
24  * limitations under the License. *
25  * -------------------------------------------------------------------------- */
26 
27 #include "SimTKcommon/basics.h"
28 #include "SimTKcommon/Simmatrix.h"
31 
32 #include <cassert>
33 
34 namespace SimTK {
35 
36 class DecorativeGeometry;
37 class DefaultSystemSubsystem;
38 class ScheduledEventHandler;
39 class ScheduledEventReporter;
40 class TriggeredEventHandler;
41 class TriggeredEventReporter;
42 class RealizeOptions;
43 class RealizeResults;
44 class ProjectOptions;
45 class ProjectResults;
46 
47 //==============================================================================
48 // SYSTEM
49 //==============================================================================
97 public:
98 class Guts; // local; name is System::Guts
99 
100 
101 //------------------------------------------------------------------------------
124 System& setUpDirection(const CoordinateDirection& up);
125 
133 System& setUseUniformBackground(bool useUniformBackground);
134 
148 System& setDefaultTimeScale(Real tc);
149 
157 System& setDefaultLengthScale(Real lc);
158 
164 void setHasTimeAdvancedEvents(bool); // default=false
165 
167 CoordinateDirection getUpDirection() const;
170 bool getUseUniformBackground() const;
173 Real getDefaultTimeScale() const;
176 Real getDefaultLengthScale() const;
179 bool hasTimeAdvancedEvents() const;
183 //------------------------------------------------------------------------------
192 inline void addEventHandler(ScheduledEventHandler* handler);
195 inline void addEventHandler(TriggeredEventHandler* handler);
198 inline void addEventReporter(ScheduledEventReporter* handler) const;
201 inline void addEventReporter(TriggeredEventReporter* handler) const;
205 //------------------------------------------------------------------------------
234 const State& realizeTopology() const;
235 
250 const State& getDefaultState() const;
253 State& updDefaultState();
254 
273 void realizeModel(State& state) const;
274 
282 void realize(const State& state, Stage stage = Stage::HighestRuntime) const;
286 //------------------------------------------------------------------------------
367 void project(State& state, Real accuracy=-1) const;
368 
384 void projectQ(State& state, Real accuracy=-1) const;
385 
403 void projectU(State& state, Real accuracy=-1) const;
404 
440 void projectQ(State& state, Vector& qErrEst,
441  const ProjectOptions& options, ProjectResults& results) const;
442 
466 void projectU(State& state, Vector& uErrEst,
467  const ProjectOptions& options, ProjectResults& results) const;
468 
469 
487 void prescribe(State& state) const {
488  realize(state, Stage::Time);
489  prescribeQ(state);
490  realize(state, Stage::Position);
491  prescribeU(state);
492 }
493 
512 bool prescribeQ(State& state) const;
513 
529 bool prescribeU(State& state) const;
530 
536 void getFreeQIndex(const State& state, Array_<SystemQIndex>& freeQs) const;
537 
543 void getFreeUIndex(const State& state, Array_<SystemUIndex>& freeUs) const;
547 //------------------------------------------------------------------------------
586 void handleEvents(State& state,
587  Event::Cause cause,
588  const Array_<EventId>& eventIds,
589  const HandleEventsOptions& options,
590  HandleEventsResults& results) const;
591 
595 void reportEvents(const State& state,
596  Event::Cause cause,
597  const Array_<EventId>& eventIds) const;
598 
607 void calcEventTriggerInfo(const State& state,
608  Array_<EventTriggerInfo>& triggerInfo) const;
609 
615 void calcTimeOfNextScheduledEvent(const State& state,
616  Real& tNextEvent,
617  Array_<EventId>& eventIds,
618  bool includeCurrentTime) const;
619 
623 void calcTimeOfNextScheduledReport(const State& state,
624  Real& tNextEvent,
625  Array_<EventId>& eventIds,
626  bool includeCurrentTime) const;
630 //------------------------------------------------------------------------------
659 void relax(State& state, Stage stage, Real accuracy=-1) const;
663 //------------------------------------------------------------------------------
684 void multiplyByN(const State& state, const Vector& u,
685  Vector& dq) const;
687 void multiplyByNTranspose(const State& state, const Vector& fq,
688  Vector& fu) const;
690 void multiplyByNPInv(const State& state, const Vector& dq,
691  Vector& u) const;
693 void multiplyByNPInvTranspose(const State& state, const Vector& fu,
694  Vector& fq) const;
698 //------------------------------------------------------------------------------
708 void resetAllCountersToZero();
709 
710  // Realization
711 
715 int getNumRealizationsOfThisStage(Stage) const;
716 
720 int getNumRealizeCalls() const;
721 
722  // Prescribed motion
723 
725 int getNumPrescribeQCalls() const;
727 int getNumPrescribeUCalls() const;
728 
729  // Projection
730 
733 int getNumProjectQCalls() const;
735 int getNumFailedProjectQCalls() const;
738 int getNumQProjections() const;
741 int getNumQErrorEstimateProjections() const;
742 
745 int getNumProjectUCalls() const;
747 int getNumFailedProjectUCalls() const;
750 int getNumUProjections() const;
753 int getNumUErrorEstimateProjections() const;
754 
755  // Event handling and reporting
756 
760 int getNumHandlerCallsThatChangedStage(Stage) const;
761 
764 int getNumHandleEventCalls() const;
765 
768 int getNumReportEventCalls() const;
772 //------------------------------------------------------------------------------
779 System() : guts(0) { }
781 System(const System&);
783 System& operator=(const System&);
786 ~System();
787 
789 const String& getName() const;
791 const String& getVersion() const;
792 
795 SubsystemIndex adoptSubsystem(Subsystem& child);
796 
798 int getNumSubsystems() const;
800 const Subsystem& getSubsystem(SubsystemIndex) const;
802 Subsystem& updSubsystem(SubsystemIndex);
805 const DefaultSystemSubsystem& getDefaultSubsystem() const;
808 DefaultSystemSubsystem& updDefaultSubsystem();
809 
813 inline operator const Subsystem&() const; // implemented below
817 inline operator Subsystem&();
818 
823 bool systemTopologyHasBeenRealized() const;
824 
832 StageVersion getSystemTopologyCacheVersion() const;
833 
839 void setSystemTopologyCacheVersion(StageVersion topoVersion) const;
840 
850 void invalidateSystemTopologyCache() const;
851 
859 void calcDecorativeGeometryAndAppend(const State&, Stage,
861 
862 
865 bool isSameSystem(const System& otherSystem) const;
866 
867 
871 const Guts& getSystemGuts() const {assert(guts); return *guts;}
875 Guts& updSystemGuts() {assert(guts); return *guts;}
876 
880 void adoptSystemGuts(System::Guts* g);
881 
883 explicit System(System::Guts* g) : guts(g) { }
885 bool hasGuts() const {return guts!=0;}
886 
888 bool isOwnerHandle() const;
890 bool isEmptyHandle() const;
893 private:
894 friend class Guts;
895 // This is the only data member in this class. Also, any class derived from
896 // System must have *NO* data members at all (data goes in the Guts class).
897 Guts* guts;
898 };
899 
900 
910 public:
911  explicit DefaultSystemSubsystem(System& sys);
912  void addEventHandler(ScheduledEventHandler* handler);
913  void addEventHandler(TriggeredEventHandler* handler);
914  void addEventReporter(ScheduledEventReporter* handler) const;
915  void addEventReporter(TriggeredEventReporter* handler) const;
916  EventId createEventId(SubsystemIndex subsys, const State& state) const;
917  void findSubsystemEventIds
918  (SubsystemIndex subsys, const State& state,
919  const Array_<EventId>& allEvents,
920  Array_<EventId>& eventsForSubsystem) const;
921  // don't let doxygen see this private class
923  class Guts;
925 private:
926  const Guts& getGuts() const;
927  Guts& updGuts();
928 };
929 
931 { updDefaultSubsystem().addEventHandler(handler); }
933 { updDefaultSubsystem().addEventHandler(handler); }
938 
939 inline System::operator const Subsystem&() const {return getDefaultSubsystem();}
940 inline System::operator Subsystem&() {return updDefaultSubsystem();}
941 
942 
943 //==============================================================================
944 // PROJECT OPTIONS and PROJECT RESULTS
945 //==============================================================================
950 public:
951  enum Option {
953  None = 0x0000,
958  LocalOnly = 0x0001,
962  DontThrow = 0x0002,
965  UseInfinityNorm = 0x0004,
969  ForceProjection = 0x0008,
974  };
975 
981  explicit ProjectOptions(Real accuracy)
982  { clear(); setRequiredAccuracy(accuracy); }
985  explicit ProjectOptions(Option opt)
986  { clear(); setOption(opt); }
987 
992  { optionSet=0; setAccuracyDefaults(); return *this; }
993 
999  requiredAccuracy = accuracy > 0 ? accuracy
1001  return *this;
1002  }
1003 
1007  assert(0 < overshoot && overshoot <= 1);
1008  desiredOvershoot = overshoot;
1009  return *this;
1010  }
1011 
1015  assert(limit > 0);
1016  projectionLimit = limit;
1017  return *this;
1018  }
1019 
1023  { optionSet &= ~(unsigned)opt; return *this; }
1026  { optionSet |= (unsigned)opt; return *this; }
1027 
1029  Real getRequiredAccuracy() const {return requiredAccuracy;}
1032  Real getOvershootFactor() const {return desiredOvershoot;}
1034  Real getProjectionLimit() const {return projectionLimit;}
1035 
1036  bool isOptionSet(Option opt) const {return (optionSet&(unsigned)opt) != 0;}
1037 
1038  static Real getDefaultRequiredAccuracy() {return Real(1e-4);}
1039  static Real getDefaultOvershootFactor() {return Real(0.1);} //i.e., 1e-5
1040 
1041  // Set operators: not, or, and, set difference
1043  { optionSet |= opts.optionSet; return *this; }
1045  { optionSet &= opts.optionSet; return *this; }
1047  { optionSet &= ~opts.optionSet; return *this; }
1048 
1049  ProjectOptions& operator|=(Option opt) {setOption(opt); return *this;}
1050  ProjectOptions& operator-=(Option opt) {clearOption(opt); return *this;}
1051 
1052 private:
1053  Real requiredAccuracy;
1054  Real desiredOvershoot; // try for accuracy*overshoot
1055  Real projectionLimit; // abort if initial norm is worse than this
1056  unsigned optionSet;
1057 
1058  void setAccuracyDefaults() {
1059  requiredAccuracy = getDefaultRequiredAccuracy();
1060  desiredOvershoot = getDefaultOvershootFactor();
1061  projectionLimit = Infinity; // we'll try from however far away
1062  }
1063 };
1064 
1067 public:
1069 
1070  enum Status {
1072  Invalid = -1,
1084  };
1085 
1089  m_exitStatus = Invalid;
1090  m_anyChangeMade = m_projectionLimitExceeded = false;
1091  m_numIterations = 0;
1092  m_worstError = -1;
1093  m_normOnEntrance = m_normOnExit = NaN;
1094  return *this;
1095  }
1096  bool isValid() const {return m_exitStatus != Invalid;}
1097  Status getExitStatus() const {return m_exitStatus;}
1098 
1099  bool getAnyChangeMade() const {assert(isValid());return m_anyChangeMade;}
1100  int getNumIterations() const {assert(isValid());return m_numIterations;}
1101  Real getNormOnEntrance() const {assert(isValid());return m_normOnEntrance;}
1102  Real getNormOnExit() const {assert(isValid());return m_normOnExit;}
1104  { assert(isValid());return m_worstError; }
1106  { assert(isValid());return m_projectionLimitExceeded; }
1107 
1109  { m_exitStatus=status; return *this; }
1111  { m_anyChangeMade=changeMade; return *this; }
1113  { m_projectionLimitExceeded=limitExceeded; return *this; }
1114  ProjectResults& setNumIterations(int numIterations)
1115  { m_numIterations=numIterations; return *this; }
1117  { m_normOnEntrance=norm; m_worstError=worstError; return *this; }
1119  { m_normOnExit=norm; return *this; }
1120 private:
1121  Status m_exitStatus;
1122  bool m_anyChangeMade;
1123  bool m_projectionLimitExceeded;
1124  int m_numIterations;
1125  int m_worstError; // index of worst error on entrance
1126  Real m_normOnEntrance; // in selected rms or infinity norm
1127  Real m_normOnExit;
1128 };
1129 
1130 
1131 
1132 //==============================================================================
1133 // REALIZE OPTIONS and REALIZE RESULTS
1134 //==============================================================================
1137  unsigned int optionSet;
1138  explicit RealizeOptions(unsigned o) : optionSet(o) { }
1139 public:
1140 
1141  enum Option {
1142  None = 0x00,
1143  DontThrow = 0x01
1144  };
1145 
1146 
1147  RealizeOptions() : optionSet(0) { }
1148 
1149  // This is an implicit conversion
1150  RealizeOptions(Option opt) : optionSet((unsigned)opt) { }
1151 
1152  // Implicit conversion to bool when needed
1153  operator bool() const {return optionSet != 0;}
1154  bool isEmpty() const {return optionSet==0;}
1155 
1156  bool isOptionSet(Option opt) const {return (optionSet&(unsigned)opt) != 0;}
1157  void clear() {optionSet=0;}
1158  void clearOption(Option opt) {optionSet &= ~(unsigned)opt;}
1159  void setOption (Option opt) {optionSet |= (unsigned)opt;}
1160 
1161  // Set operators: or, and
1162  RealizeOptions& operator|=(RealizeOptions opts) {optionSet |= opts.optionSet; return *this;}
1163  RealizeOptions& operator&=(RealizeOptions opts) {optionSet &= opts.optionSet; return *this;}
1164 
1165  RealizeOptions& operator|=(Option opt) {setOption(opt); return *this;}
1166  RealizeOptions& operator-=(Option opt) {clearOption(opt); return *this;}
1167 };
1168 
1171 };
1172 
1173 
1174 
1175 
1176 } // namespace SimTK
1177 
1178 #endif // SimTK_SimTKCOMMON_SYSTEM_H_