00001
00002
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
00036
00037
00038
00039 #ifndef HIERARCHICAL_STATE_MACHINE_HPP
00040 #define HIERARCHICAL_STATE_MACHINE_HPP
00041
00042 #include "StateInterface.hpp"
00043 #include "ConditionInterface.hpp"
00044 #include "CommandInterface.hpp"
00045 #include "DataSourceBase.hpp"
00046 #include "Handle.hpp"
00047 #include "EventProcessor.hpp"
00048
00049 #include <map>
00050 #include <vector>
00051 #include <string>
00052 #include <utility>
00053 #include <boost/tuple/tuple.hpp>
00054 #include <boost/weak_ptr.hpp>
00055 #include <boost/shared_ptr.hpp>
00056
00057 namespace RTT
00058 {
00059
00060
00061
00062 class TaskContext;
00063 class EventService;
00064 class StateMachineProcessor;
00065
00066 class StateMachine;
00067 typedef boost::shared_ptr<StateMachine> StateMachinePtr;
00068 typedef boost::weak_ptr<StateMachine> StateMachineWPtr;
00069
00078 class RTT_API StateMachine
00079 {
00080 enum PrivateStatus { nill, gostop, goreset, pausing } smpStatus;
00081
00082 static std::string emptyString;
00083 public:
00087 struct RTT_API Status {
00088 enum StateMachineStatus {inactive, activating, active, requesting, running, stopping, stopped, resetting, deactivating, paused, error, unloaded };
00089 };
00090 protected:
00095 typedef std::vector< boost::tuple<ConditionInterface*, StateInterface*, int, int, boost::shared_ptr<ProgramInterface> > > TransList;
00096 typedef std::map< StateInterface*, TransList > TransitionMap;
00097 typedef std::multimap< StateInterface*, std::pair<ConditionInterface*, int> > PreConditionMap;
00098 typedef std::vector< boost::tuple<EventService*,
00099 std::string, std::vector<DataSourceBase::shared_ptr>,
00100 StateInterface*,
00101 ConditionInterface*, boost::shared_ptr<ProgramInterface>,
00102 Handle,
00103 StateInterface*, boost::shared_ptr<ProgramInterface> > > EventList;
00104 typedef std::map< StateInterface*, EventList > EventMap;
00105 std::vector<StateMachinePtr> _children;
00106 typedef boost::weak_ptr<StateMachine> StateMachineParentPtr;
00107 StateMachineParentPtr _parent;
00108
00109 std::string _name;
00110 EventProcessor* eproc;
00111 Status::StateMachineStatus smStatus;
00112 StateMachineProcessor* smp;
00113
00114
00115 virtual void handleUnload();
00116 public:
00117
00118 typedef std::vector<StateMachinePtr> ChildList;
00119
00124 virtual ~StateMachine();
00125
00131 StateMachine(StateMachinePtr parent, const std::string& name="Default");
00132
00139 StateMachine(StateMachinePtr parent, EventProcessor* ep, const std::string& name="Default");
00140
00141 void setStateMachineProcessor(StateMachineProcessor* smproc) {
00142 smp = smproc;
00143 if (smp)
00144 smStatus = Status::inactive;
00145 else {
00146 smStatus = Status::unloaded;
00147 this->handleUnload();
00148 }
00149 }
00150
00151 void setEventProcessor(EventProcessor* smproc) {
00152 eproc = smproc;
00153 }
00154
00158 bool requestState(const std::string& statename) {
00159 StateInterface* tmp = this->getState(statename);
00160 if (tmp) {
00161 return this->requestStateChange( tmp );
00162 }
00163 return false;
00164 }
00165
00169 bool inState(const std::string& state) const {
00170 StateInterface* copy = this->currentState();
00171 if (copy == 0)
00172 return false;
00173 return copy->getName() == state;
00174 }
00175
00180 bool inStrictState(const std::string& state) const {
00181 StateInterface* copy = this->currentState();
00182 if (copy == 0)
00183 return false;
00184 return copy->getName() == state && !this->inTransition();
00185 }
00186
00190 const std::string& getCurrentStateName() const {
00191 StateInterface* copy = this->currentState();
00192 if (copy == 0)
00193 return emptyString;
00194 return copy->getName();
00195 }
00196
00200 inline bool isStrictlyActive() const {
00201 return this->isActive() && !this->inTransition();
00202 }
00203
00207 inline bool inInitialState() const {
00208 return initstate == current;
00209 }
00210
00214 inline bool inFinalState() const {
00215 return finistate == current;
00216 }
00217
00222 bool stepDone() const {
00223 if ( isPaused() )
00224 return !mstep;
00225 return isStrictlyActive();
00226 }
00227
00231 inline bool isActive() const { return current != 0; }
00232
00237 inline bool isStopped() const { return smStatus == Status::stopped; }
00238
00242 inline bool inError() const { return smStatus == Status::error; }
00243
00247 inline bool isReactive() const { return current != 0 && smStatus != Status::running; }
00248
00253 inline bool isAutomatic() const { return smStatus == Status::running; }
00254
00258 inline bool isPaused() const { return smStatus == Status::paused; }
00259
00263 bool activate();
00264
00268 bool pause();
00269
00274 bool step();
00275
00279 bool automatic();
00280
00284 bool start();
00285
00290 bool stop();
00291
00296 bool reset();
00297
00301 bool reactive();
00302
00306 bool deactivate();
00307
00312 bool execute();
00313
00329 StateInterface* requestNextState(bool stepping = false);
00330
00335 StateInterface* requestNextStateStep();
00336
00341 bool requestFinalState();
00342
00353 bool requestInitialState();
00354
00363 StateInterface* nextState();
00364
00368 std::vector<std::string> getStateList() const;
00369
00373 StateInterface* getState( const std::string & name ) const;
00374
00378 Status::StateMachineStatus getStatus() const;
00379
00383 void addState( StateInterface* s );
00384
00397 bool requestStateChange( StateInterface * s_n );
00398
00412 bool executePending( bool stepping = false );
00413
00431 void preconditionSet( StateInterface* state, ConditionInterface* cnd, int line);
00432
00452 void transitionSet( StateInterface* from, StateInterface* to, ConditionInterface* cnd, int priority, int line);
00453
00476 void transitionSet( StateInterface* from, StateInterface* to,
00477 ConditionInterface* cnd, boost::shared_ptr<ProgramInterface> transprog,
00478 int priority, int line);
00479
00499 bool createEventTransition( EventService* es,
00500 const std::string& ename, std::vector<DataSourceBase::shared_ptr> args,
00501 StateInterface* from, StateInterface* to,
00502 ConditionInterface* guard, boost::shared_ptr<ProgramInterface> transprog,
00503 StateInterface* elseto = 0, boost::shared_ptr<ProgramInterface> elseprog =
00504 boost::shared_ptr<ProgramInterface>() );
00505
00509 void setInitialState( StateInterface* s );
00510
00514 void setFinalState( StateInterface* s );
00515
00520 StateInterface* currentState() const;
00521
00526 ProgramInterface* currentProgram() const;
00527
00531 StateInterface* getInitialState() const {
00532 return initstate;
00533 }
00534
00538 StateInterface* getFinalState() const {
00539 return finistate;
00540 }
00541
00549 void setInitCommand( CommandInterface* c)
00550 {
00551 initc = c;
00552 }
00553
00554 CommandInterface* getInitCommand() const
00555 {
00556 return initc;
00557 }
00558
00562 StateMachinePtr getParent() const
00563 {
00564 return _parent.lock();
00565 }
00566
00567 void setParent(StateMachinePtr parent)
00568 {
00569 _parent = parent;
00570 }
00571
00575 const ChildList& getChildren() const
00576 {
00577 return _children;
00578 }
00579
00580 void addChild( StateMachinePtr child ) {
00581 _children.push_back( child );
00582 }
00583
00588 const std::string& getName() const {
00589 return _name;
00590 }
00591
00596 int getLineNumber() const;
00597
00601 virtual std::string getText() const;
00602
00609 bool inTransition() const;
00610
00616 bool interruptible() const;
00617
00618 protected:
00624 TransitionMap stateMap;
00625
00630 PreConditionMap precondMap;
00631
00636 EventMap eventMap;
00637
00638
00639 void changeState( StateInterface* s, ProgramInterface* tprog, bool stepping = false );
00640
00641 void leaveState( StateInterface* s );
00642
00643 void enterState( StateInterface* s );
00644
00645 void runState( StateInterface* s );
00646
00647 void handleState( StateInterface* s );
00648
00649 bool executeProgram(ProgramInterface*& cp, bool stepping);
00650
00651 int checkConditions( StateInterface* state, bool stepping = false );
00652
00653 void enableEvents( StateInterface* s );
00654 void disableEvents( StateInterface* s );
00655 private:
00656
00661 void eventTransition( StateInterface* from, ConditionInterface* c,
00662 ProgramInterface* p, StateInterface* to,
00663 ProgramInterface* elsep, StateInterface* elseto );
00664
00668 StateInterface* initstate;
00669
00673 StateInterface* finistate;
00674
00679 StateInterface* current;
00680
00684 StateInterface* next;
00685
00686 CommandInterface* initc;
00687
00688 ProgramInterface* currentProg;
00689 ProgramInterface* currentExit;
00690 ProgramInterface* currentHandle;
00691 ProgramInterface* currentEntry;
00692 ProgramInterface* currentRun;
00693 ProgramInterface* currentTrans;
00694
00695 TransList::iterator reqstep;
00696 TransList::iterator reqend;
00697
00698 std::pair<PreConditionMap::const_iterator,PreConditionMap::const_iterator> prec_it;
00699 bool checking_precond;
00700 bool mstep;
00701
00702 int evaluating;
00703 };
00704 }
00705
00706 #endif