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
00049 SimTK_DEFINE_UNIQUE_INDEX_TYPE(EventId)
00050
00051
00098 class SimTK_SimTKCOMMON_EXPORT System {
00099 public:
00100 class Guts;
00101 friend class Guts;
00102 private:
00103
00104
00105 Guts* guts;
00106 public:
00107 System() : guts(0) { }
00108 System(const System&);
00109 System& operator=(const System&);
00110 ~System();
00111
00112 const String& getName() const;
00113 const String& getVersion() const;
00114
00115
00116 class ProjectOptions {
00117 unsigned long optionSet;
00118 explicit ProjectOptions(unsigned int o) : optionSet(o) { }
00119 public:
00120
00121 enum Option {
00122 None = 0x00,
00123
00124 Q = 0x01,
00125 U = 0x02,
00126 QError = 0x04,
00127 UError = 0x08,
00128
00129 PositionOnly = (Q|QError),
00130 VelocityOnly = (U|UError),
00131 All = (PositionOnly|VelocityOnly)
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 long getNumRealizationsOfThisStage(Stage) const;
00177
00181 long getNumRealizeCalls() const;
00182
00183
00184
00187 long getNumQProjections() const;
00188 long getNumUProjections() const;
00189 long getNumQErrorEstimateProjections() const;
00190 long getNumUErrorEstimateProjections() const;
00191
00194 long getNumProjectCalls() const;
00195
00196
00197
00201 long getNumHandlerCallsThatChangedStage(Stage) const;
00202
00205 long getNumHandleEventCalls() const;
00206
00209 long getNumReportEventCalls() const;
00210
00211
00213
00215
00229 const State& realizeTopology() const;
00230
00231
00244 const State& getDefaultState() const;
00245 State& updDefaultState();
00246
00262 void realizeModel(State&) const;
00263
00271 void realize(const State& s, Stage g = Stage::HighestValid) const;
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281 void calcDecorativeGeometryAndAppend(const State&, Stage, std::vector<DecorativeGeometry>&) const;
00282
00284
00286
00287
00288
00296 Real calcTimescale(const State&) const;
00297
00313 void calcYUnitWeights(const State&, Vector& weights) const;
00314
00315
00316
00332 void project(State&, Real consAccuracy, const Vector& yweights,
00333 const Vector& ootols, Vector& yerrest, ProjectOptions=ProjectOptions::All) const;
00334
00343 void calcYErrUnitTolerances(const State&, Vector& tolerances) const;
00344
00345
00347
00349
00350 class EventTriggerInfo;
00351
00357 void setHasTimeAdvancedEvents(bool);
00358 bool hasTimeAdvancedEvents() const;
00359
00387
00388 enum EventCause {
00389 TriggeredEvents =1,
00390 ScheduledEvents =2,
00391 TimeAdvancedEvent =3,
00392 TerminationEvent =4,
00393
00394 InvalidEventCause = -1
00395 };
00396 static const char* getEventCauseName(EventCause);
00397
00398
00415
00416 void handleEvents
00417 (State&, EventCause, const std::vector<EventId>& eventIds,
00418 Real accuracy, const Vector& yWeights, const Vector& ooConstraintTols,
00419 Stage& lowestModified, bool& shouldTerminate) const;
00420
00423
00424 void reportEvents(const State& s, EventCause cause, const std::vector<EventId>& eventIds) const;
00425
00435 void calcEventTriggerInfo(const State&, std::vector<EventTriggerInfo>&) const;
00436
00442 void calcTimeOfNextScheduledEvent(const State&, Real& tNextEvent, std::vector<EventId>& eventIds, bool includeCurrentTime) const;
00443
00447 void calcTimeOfNextScheduledReport(const State&, Real& tNextEvent, std::vector<EventId>& eventIds, bool includeCurrentTime) const;
00448
00449
00450
00451
00452 static Real calcWeightedRMSNorm(const Vector& values, const Vector& weights) {
00453 assert(weights.size() == values.size());
00454 if (values.size()==0) return 0;
00455 Real sumsq = 0;
00456 for (int i=0; i<values.size(); ++i) {
00457 const Real wv = weights[i]*values[i];
00458 sumsq += wv*wv;
00459 }
00460 return std::sqrt(sumsq/weights.size());
00461 }
00462
00463 static Real calcWeightedInfinityNorm(const Vector& values, const Vector& weights) {
00464 assert(weights.size() == values.size());
00465 if (values.size()==0) return 0;
00466 Real maxval = 0;
00467 for (int i=0; i<values.size(); ++i) {
00468 const Real wv = std::abs(weights[i]*values[i]);
00469 if (wv > maxval) maxval=wv;
00470 }
00471 return maxval;
00472 }
00473
00476 SubsystemIndex adoptSubsystem(Subsystem& child);
00477
00479 int getNSubsystems() const;
00481 const Subsystem& getSubsystem(SubsystemIndex) const;
00483 Subsystem& updSubsystem(SubsystemIndex);
00485 const DefaultSystemSubsystem& getDefaultSubsystem() const;
00487 DefaultSystemSubsystem& updDefaultSubsystem();
00488
00489
00490 bool isOwnerHandle() const;
00491 bool isEmptyHandle() const;
00492
00493
00494 bool isSameSystem(const System& otherSystem) const;
00495
00500 bool systemTopologyHasBeenRealized() const;
00501
00502
00503
00504 const System::Guts& getSystemGuts() const {assert(guts); return *guts;}
00505 System::Guts& updSystemGuts() {assert(guts); return *guts;}
00506
00507
00508
00509
00510 void adoptSystemGuts(System::Guts* g);
00511
00512 explicit System(System::Guts* g) : guts(g) { }
00513 bool hasGuts() const {return guts!=0;}
00514
00515 private:
00516 class EventTriggerInfoRep;
00517 };
00518
00519 inline static System::ProjectOptions operator|(System::ProjectOptions::Option o1, System::ProjectOptions::Option o2) {return System::ProjectOptions(o1) |= o2;}
00520 inline static System::ProjectOptions operator|(System::ProjectOptions opts, System::ProjectOptions::Option o) {return opts |= o;}
00521 inline static System::ProjectOptions operator|(System::ProjectOptions::Option o, System::ProjectOptions opts) {return opts |= o;}
00522 inline static System::ProjectOptions operator&(System::ProjectOptions::Option o1, System::ProjectOptions::Option o2) {return System::ProjectOptions(o1) &= o2;}
00523 inline static System::ProjectOptions operator&(System::ProjectOptions opts, System::ProjectOptions::Option o) {return opts &= o;}
00524 inline static System::ProjectOptions operator&(System::ProjectOptions::Option o, System::ProjectOptions opts) {return opts &= o;}
00525 inline static System::ProjectOptions operator~(System::ProjectOptions::Option o) {return ~System::ProjectOptions(o);}
00526 inline static System::ProjectOptions operator-(System::ProjectOptions opts, System::ProjectOptions::Option o) {return opts -= o;}
00527 inline static System::ProjectOptions operator-(System::ProjectOptions opts1, System::ProjectOptions opts2) {return opts1 -= opts2;}
00528
00529
00530
00541 class SimTK_SimTKCOMMON_EXPORT System::EventTriggerInfo {
00542 public:
00543 EventTriggerInfo();
00544 explicit EventTriggerInfo(EventId eventId);
00545 ~EventTriggerInfo();
00546 EventTriggerInfo(const EventTriggerInfo&);
00547 EventTriggerInfo& operator=(const EventTriggerInfo&);
00548
00549 EventId getEventId() const;
00550 bool shouldTriggerOnRisingSignTransition() const;
00551 bool shouldTriggerOnFallingSignTransition() const;
00552 Real getRequiredLocalizationTimeWindow() const;
00553
00554
00555 EventTriggerInfo& setEventId(EventId);
00556 EventTriggerInfo& setTriggerOnRisingSignTransition(bool);
00557 EventTriggerInfo& setTriggerOnFallingSignTransition(bool);
00558 EventTriggerInfo& setRequiredLocalizationTimeWindow(Real);
00559
00560
00561 EventStatus::EventTrigger calcTransitionMask() const {
00562 unsigned mask = 0;
00563 if (shouldTriggerOnRisingSignTransition()) {
00564 mask |= EventStatus::NegativeToPositive;
00565 }
00566 if (shouldTriggerOnFallingSignTransition()) {
00567 mask |= EventStatus::PositiveToNegative;
00568 }
00569 return EventStatus::EventTrigger(mask);
00570 }
00571
00572 EventStatus::EventTrigger calcTransitionToReport
00573 (EventStatus::EventTrigger transitionSeen) const
00574 {
00575
00576 if (transitionSeen & EventStatus::Rising)
00577 return EventStatus::NegativeToPositive;
00578 if (transitionSeen & EventStatus::Falling)
00579 return EventStatus::PositiveToNegative;
00580 assert(!"impossible event transition situation");
00581 return EventStatus::NoEventTrigger;
00582 }
00583
00584 private:
00585
00586 System::EventTriggerInfoRep* rep;
00587
00588 const System::EventTriggerInfoRep& getRep() const {assert(rep); return *rep;}
00589 System::EventTriggerInfoRep& updRep() {assert(rep); return *rep;}
00590 };
00591
00592 }
00593
00594 #endif // SimTK_SimTKCOMMON_SYSTEM_H_