00001 #ifndef SimTK_SimTKCOMMON_SYSTEM_H_
00002 #define SimTK_SimTKCOMMON_SYSTEM_H_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "SimTKcommon/basics.h"
00036 #include "SimTKcommon/Simmatrix.h"
00037 #include "SimTKcommon/internal/State.h"
00038
00039 namespace SimTK {
00040
00041 class Subsystem;
00042 class DecorativeGeometry;
00043 class DefaultSystemSubsystem;
00044
00048 SimTK_DEFINE_UNIQUE_INDEX_TYPE(EventId);
00049
00092 class SimTK_SimTKCOMMON_EXPORT System {
00093 public:
00094 class Guts;
00095 friend class Guts;
00096 private:
00097
00098
00099 Guts* guts;
00100 public:
00101 System() : guts(0) { }
00102 System(const System&);
00103 System& operator=(const System&);
00104 ~System();
00105
00106 const String& getName() const;
00107 const String& getVersion() const;
00108
00109
00110 class ProjectOptions {
00111 unsigned long optionSet;
00112 explicit ProjectOptions(unsigned int o) : optionSet(o) { }
00113 public:
00114
00115 enum Option {
00116 None = 0x00,
00117
00118 Q = 0x01,
00119 U = 0x02,
00120 QError = 0x04,
00121 UError = 0x08,
00122
00123 PositionOnly = (Q|QError),
00124 VelocityOnly = (U|UError),
00125 All = (PositionOnly|VelocityOnly),
00126
00127
00128
00129
00130
00131 LocalOnly = 0x1000
00132 };
00133
00134 ProjectOptions() : optionSet(0) { }
00135
00136
00137 ProjectOptions(Option opt) : optionSet((unsigned long)opt) { }
00138
00139
00140 operator bool() const {return optionSet != 0;}
00141 bool hasAnyPositionOptions() const {return (optionSet&(unsigned long)PositionOnly) != 0;}
00142 bool hasAnyVelocityOptions() const {return (optionSet&(unsigned long)VelocityOnly) != 0;}
00143 bool isEmpty() const {return optionSet==0;}
00144
00145 bool isOptionSet(Option opt) const {return (optionSet&(unsigned long)opt) != 0;}
00146 void clear() {optionSet=0;}
00147 void clearOption(Option opt) {optionSet &= ~(unsigned long)opt;}
00148 void setOption (Option opt) {optionSet |= (unsigned long)opt;}
00149
00150
00151 ProjectOptions operator~() const {return ProjectOptions( (~optionSet) & (unsigned long)All );}
00152 ProjectOptions& operator|=(ProjectOptions opts) {optionSet |= opts.optionSet; return *this;}
00153 ProjectOptions& operator&=(ProjectOptions opts) {optionSet &= opts.optionSet; return *this;}
00154 ProjectOptions& operator-=(ProjectOptions opts) {optionSet &= ~opts.optionSet; return *this;}
00155
00156 ProjectOptions& operator|=(Option opt) {setOption(opt); return *this;}
00157 ProjectOptions& operator-=(Option opt) {clearOption(opt); return *this;}
00158 };
00159
00161
00163
00169 void resetAllCountersToZero();
00170
00171
00172
00176 int getNumRealizationsOfThisStage(Stage) const;
00177
00181 int getNumRealizeCalls() const;
00182
00183
00184
00188 int getNumPrescribeCalls() const;
00189
00190
00191
00194 int getNumQProjections() const;
00195 int getNumUProjections() const;
00196 int getNumQErrorEstimateProjections() const;
00197 int getNumUErrorEstimateProjections() const;
00198
00201 int getNumProjectCalls() const;
00202
00203
00204
00208 int getNumHandlerCallsThatChangedStage(Stage) const;
00209
00212 int getNumHandleEventCalls() const;
00213
00216 int getNumReportEventCalls() const;
00217
00218
00220
00222
00235 const State& realizeTopology() const;
00236
00249 const State& getDefaultState() const;
00250 State& updDefaultState();
00251
00267 void realizeModel(State&) const;
00268
00276 void realize(const State& s, Stage g = Stage::HighestRuntime) const;
00277
00285 void calcDecorativeGeometryAndAppend(const State&, Stage,
00286 Array_<DecorativeGeometry>&) const;
00287
00289
00291
00292
00293
00301 Real calcTimescale(const State&) const;
00302
00318 void calcYUnitWeights(const State&, Vector& weights) const;
00319
00320
00321
00336 void prescribe(State&, Stage) const;
00337
00355 void project(State&, Real consAccuracy, const Vector& yWeights,
00356 const Vector& cWeights, Vector& yerrest,
00357 ProjectOptions=ProjectOptions::All) const;
00358
00367 void calcYErrUnitTolerances(const State&, Vector& tolerances) const;
00368
00369
00370
00391 void relax(State&, Stage, Real accuracy,
00392 const Vector& yWeights, const Vector& cWeights) const;
00393
00394
00396
00398
00399 class EventTriggerInfo;
00400
00406 void setHasTimeAdvancedEvents(bool);
00407 bool hasTimeAdvancedEvents() const;
00408
00427 void handleEvents
00428 (State&, Event::Cause, const Array_<EventId>& eventIds,
00429 Real accuracy, const Vector& yWeights, const Vector& cWeights,
00430 Stage& lowestModified, bool& shouldTerminate) const;
00431
00435 void reportEvents(const State& s, Event::Cause cause,
00436 const Array_<EventId>& eventIds) const;
00437
00447 void calcEventTriggerInfo(const State&, Array_<EventTriggerInfo>&) const;
00448
00454 void calcTimeOfNextScheduledEvent(const State&, Real& tNextEvent,
00455 Array_<EventId>& eventIds, bool includeCurrentTime) const;
00456
00460 void calcTimeOfNextScheduledReport(const State&, Real& tNextEvent,
00461 Array_<EventId>& eventIds, bool includeCurrentTime) const;
00462
00463
00464
00465
00466 static Real calcWeightedRMSNorm(const Vector& values, const Vector& weights) {
00467 assert(weights.size() == values.size());
00468 if (values.size()==0) return 0;
00469 Real sumsq = 0;
00470 for (int i=0; i<values.size(); ++i) {
00471 const Real wv = weights[i]*values[i];
00472 sumsq += wv*wv;
00473 }
00474 return std::sqrt(sumsq/weights.size());
00475 }
00476
00477 static Real calcWeightedInfinityNorm(const Vector& values, const Vector& weights) {
00478 assert(weights.size() == values.size());
00479 if (values.size()==0) return 0;
00480 Real maxval = 0;
00481 for (int i=0; i<values.size(); ++i) {
00482 const Real wv = std::abs(weights[i]*values[i]);
00483 if (wv > maxval) maxval=wv;
00484 }
00485 return maxval;
00486 }
00487
00490 SubsystemIndex adoptSubsystem(Subsystem& child);
00491
00493 int getNSubsystems() const;
00495 const Subsystem& getSubsystem(SubsystemIndex) const;
00497 Subsystem& updSubsystem(SubsystemIndex);
00499 const DefaultSystemSubsystem& getDefaultSubsystem() const;
00501 DefaultSystemSubsystem& updDefaultSubsystem();
00502
00503
00504 bool isOwnerHandle() const;
00505 bool isEmptyHandle() const;
00506
00507
00508 bool isSameSystem(const System& otherSystem) const;
00509
00514 bool systemTopologyHasBeenRealized() const;
00515
00516
00517
00518 const System::Guts& getSystemGuts() const {assert(guts); return *guts;}
00519 System::Guts& updSystemGuts() {assert(guts); return *guts;}
00520
00521
00522
00523
00524 void adoptSystemGuts(System::Guts* g);
00525
00526 explicit System(System::Guts* g) : guts(g) { }
00527 bool hasGuts() const {return guts!=0;}
00528
00529 private:
00530 class EventTriggerInfoRep;
00531 };
00532
00533 inline static System::ProjectOptions operator|(System::ProjectOptions::Option o1, System::ProjectOptions::Option o2) {return System::ProjectOptions(o1) |= o2;}
00534 inline static System::ProjectOptions operator|(System::ProjectOptions opts, System::ProjectOptions::Option o) {return opts |= o;}
00535 inline static System::ProjectOptions operator|(System::ProjectOptions::Option o, System::ProjectOptions opts) {return opts |= o;}
00536 inline static System::ProjectOptions operator&(System::ProjectOptions::Option o1, System::ProjectOptions::Option o2) {return System::ProjectOptions(o1) &= o2;}
00537 inline static System::ProjectOptions operator&(System::ProjectOptions opts, System::ProjectOptions::Option o) {return opts &= o;}
00538 inline static System::ProjectOptions operator&(System::ProjectOptions::Option o, System::ProjectOptions opts) {return opts &= o;}
00539 inline static System::ProjectOptions operator~(System::ProjectOptions::Option o) {return ~System::ProjectOptions(o);}
00540 inline static System::ProjectOptions operator-(System::ProjectOptions opts, System::ProjectOptions::Option o) {return opts -= o;}
00541 inline static System::ProjectOptions operator-(System::ProjectOptions opts1, System::ProjectOptions opts2) {return opts1 -= opts2;}
00542
00543
00544
00555 class SimTK_SimTKCOMMON_EXPORT System::EventTriggerInfo {
00556 public:
00557 EventTriggerInfo();
00558 explicit EventTriggerInfo(EventId eventId);
00559 ~EventTriggerInfo();
00560 EventTriggerInfo(const EventTriggerInfo&);
00561 EventTriggerInfo& operator=(const EventTriggerInfo&);
00562
00563 EventId getEventId() const;
00564 bool shouldTriggerOnRisingSignTransition() const;
00565 bool shouldTriggerOnFallingSignTransition() const;
00566 Real getRequiredLocalizationTimeWindow() const;
00567
00568
00569 EventTriggerInfo& setEventId(EventId);
00570 EventTriggerInfo& setTriggerOnRisingSignTransition(bool);
00571 EventTriggerInfo& setTriggerOnFallingSignTransition(bool);
00572 EventTriggerInfo& setRequiredLocalizationTimeWindow(Real);
00573
00574 Event::Trigger calcTransitionMask() const {
00575 unsigned mask = 0;
00576 if (shouldTriggerOnRisingSignTransition()) {
00577 mask |= Event::NegativeToPositive;
00578 }
00579 if (shouldTriggerOnFallingSignTransition()) {
00580 mask |= Event::PositiveToNegative;
00581 }
00582 return Event::Trigger(mask);
00583 }
00584
00585 Event::Trigger calcTransitionToReport
00586 (Event::Trigger transitionSeen) const
00587 {
00588
00589 if (transitionSeen & Event::Rising)
00590 return Event::NegativeToPositive;
00591 if (transitionSeen & Event::Falling)
00592 return Event::PositiveToNegative;
00593 assert(!"impossible event transition situation");
00594 return Event::NoEventTrigger;
00595 }
00596
00597 private:
00598
00599 System::EventTriggerInfoRep* rep;
00600
00601 const System::EventTriggerInfoRep& getRep() const {assert(rep); return *rep;}
00602 System::EventTriggerInfoRep& updRep() {assert(rep); return *rep;}
00603 };
00604
00605 }
00606
00607 #endif // SimTK_SimTKCOMMON_SYSTEM_H_