00001 #ifndef SimTK_SimTKCOMMON_EVENT_H_ 00002 #define SimTK_SimTKCOMMON_EVENT_H_ 00003 00004 /* -------------------------------------------------------------------------- * 00005 * SimTK Core: SimTKcommon * 00006 * -------------------------------------------------------------------------- * 00007 * This is part of the SimTK Core 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. * 00011 * * 00012 * Portions copyright (c) 2008-9 Stanford University and the Authors. * 00013 * Authors: Michael Sherman * 00014 * Contributors: * 00015 * * 00016 * Permission is hereby granted, free of charge, to any person obtaining a * 00017 * copy of this software and associated documentation files (the "Software"), * 00018 * to deal in the Software without restriction, including without limitation * 00019 * the rights to use, copy, modify, merge, publish, distribute, sublicense, * 00020 * and/or sell copies of the Software, and to permit persons to whom the * 00021 * Software is furnished to do so, subject to the following conditions: * 00022 * * 00023 * The above copyright notice and this permission notice shall be included in * 00024 * all copies or substantial portions of the Software. * 00025 * * 00026 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * 00027 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * 00028 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * 00029 * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 00030 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 00031 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * 00032 * USE OR OTHER DEALINGS IN THE SOFTWARE. * 00033 * -------------------------------------------------------------------------- */ 00034 00040 #include "SimTKcommon/basics.h" 00041 00042 namespace SimTK { 00043 00048 SimTK_DEFINE_UNIQUE_INDEX_TYPE(SystemEventIndex); 00051 SimTK_DEFINE_UNIQUE_INDEX_TYPE(EventIndex); 00052 00058 SimTK_DEFINE_UNIQUE_INDEX_TYPE(SystemEventTriggerIndex); 00061 SimTK_DEFINE_UNIQUE_INDEX_TYPE(EventTriggerIndex); 00062 00069 SimTK_DEFINE_UNIQUE_INDEX_TYPE(SystemEventTriggerByStageIndex); 00072 SimTK_DEFINE_UNIQUE_INDEX_TYPE(EventTriggerByStageIndex); 00073 00089 class Event { 00090 public: 00091 00137 class Cause { 00138 public: 00139 enum Num { 00140 Initialization = 1, 00141 Triggered = 2, 00142 Scheduled = 3, 00143 TimeAdvanced = 4, 00144 Signaled = 5, 00145 Termination = 6, 00146 Invalid = -1 00147 }; 00148 00149 Cause() : value(Invalid) {} 00150 Cause(Num n) : value(n) {} // implicit conversion 00151 operator Num() const {return value;} // implicit conversion 00152 Cause& operator=(Num n) {value=n; return *this;} 00153 00154 bool isValid() const {Initialization<=value && value<=Termination;} 00155 00156 private: 00157 Num value; 00158 }; 00159 00162 SimTK_SimTKCOMMON_EXPORT static const char* getCauseName(Cause); 00163 00164 00171 enum Trigger { 00172 NoEventTrigger =0x0000, // must be 0 00173 00174 PositiveToNegative =0x0001, // 1 00175 NegativeToPositive =0x0002, // 2 00176 00177 Falling =(PositiveToNegative), // 1 00178 Rising =(NegativeToPositive), // 2 00179 AnySignChange =(PositiveToNegative|NegativeToPositive) // 3 00180 }; 00181 00184 SimTK_SimTKCOMMON_EXPORT static std::string eventTriggerString(Trigger); 00185 00186 00192 static Trigger classifyTransition(int before, int after) { 00193 if (before==after) 00194 return NoEventTrigger; 00195 if (before==0) 00196 return NoEventTrigger; // Do not report transitions away from zero. 00197 if (before==1) 00198 return PositiveToNegative; 00199 // before==-1 00200 return NegativeToPositive; 00201 } 00202 00208 static Trigger maskTransition(Trigger transition, Trigger mask) { 00209 return Trigger(transition & mask); // we're depending on NoEventTrigger==0 00210 } 00211 00212 private: 00213 }; 00214 00215 /* 00216 class EventStatus { 00217 public: 00218 EventStatus() { initialize(); } 00219 // default destructor, copy constructor, copy assignment 00220 00221 // Event trigger (which zero crossings cause triggering). Can be 00222 // OR'ed together to make a mask. 00223 enum EventTrigger { 00224 NoEventTrigger =0x0000, // must be 0 00225 00226 PositiveToNegative =0x0001, // 1 00227 NegativeToPositive =0x0002, // 2 00228 00229 Falling =(PositiveToNegative), // 1 00230 Rising =(NegativeToPositive), // 2 00231 AnySignChange =(PositiveToNegative|NegativeToPositive) // 3 00232 }; 00233 00234 bool isEventPending() const {return transitionSeen != NoEventTrigger;} 00235 EventTrigger getEventTrigger() const {return transitionSeen;} 00236 Real getLastTriggerTime() const {return lastTriggerTime;} 00237 Real getLastTriggerTimeBestGuess() const {return lastTriggerTimeBestGuess;} 00238 Real getBeforeValue() const {return beforeValue;} 00239 Real getAfterValue() const {return afterValue;} 00240 Real getLocalizationWindow() const {return localizationWindow;} 00241 00242 void setEventTriggered(EventTrigger transition, Real triggerTime, 00243 Real actualTimeEst, Real window, 00244 Real before, Real after) 00245 { 00246 assert(transition != NoEventTrigger); 00247 assert(triggerTime >= 0 && actualTimeEst >= 0 00248 && triggerTime >= actualTimeEst); 00249 00250 transitionSeen = transition; 00251 lastTriggerTime = triggerTime; 00252 lastTriggerTimeBestGuess = actualTimeEst; 00253 localizationWindow = window; 00254 beforeValue = before; 00255 afterValue = after; 00256 } 00257 00258 void clearEventTrigger() { 00259 transitionSeen = NoEventTrigger; 00260 } 00261 00262 // Classify a before/after sign transition. 00263 static EventTrigger classifyTransition(int before, int after) { 00264 if (before==after) 00265 return NoEventTrigger; 00266 if (before==0) 00267 return NoEventTrigger; // Do not report transitions away from zero. 00268 if (before==1) 00269 return PositiveToNegative; 00270 // before==-1 00271 return NegativeToPositive; 00272 } 00273 00274 static EventTrigger maskTransition(EventTrigger transition, EventTrigger mask) { 00275 return EventTrigger(transition & mask); // we're depending on NoEventTrigger==0 00276 } 00277 00278 SimTK_SimTKCOMMON_EXPORT static String eventTriggerString(EventTrigger e); 00279 private: 00280 void initialize() { 00281 transitionSeen = NoEventTrigger; 00282 lastTriggerTime = lastTriggerTimeBestGuess = localizationWindow 00283 = beforeValue = afterValue = NaN; 00284 } 00285 00286 EventTrigger transitionSeen; 00287 Real lastTriggerTime; // digital 00288 Real lastTriggerTimeBestGuess; // analog, <=lastTriggerTime 00289 Real localizationWindow; 00290 Real beforeValue, afterValue; 00291 }; 00292 */ 00293 00294 } // namespace SimTK 00295 00296 #endif // SimTK_SimTKCOMMON_EVENT_H_