Orocos Real-Time Toolkit  2.8.3
StateMachine.hpp
Go to the documentation of this file.
1 /***************************************************************************
2  tag: Peter Soetens Tue Dec 21 22:43:07 CET 2004 StateMachineTree.hpp
3 
4  StateMachineTree.hpp - description
5  -------------------
6  begin : Tue December 21 2004
7  copyright : (C) 2004 Peter Soetens
8  email : peter.soetens@mech.kuleuven.ac.be
9 
10  ***************************************************************************
11  * This library is free software; you can redistribute it and/or *
12  * modify it under the terms of the GNU General Public *
13  * License as published by the Free Software Foundation; *
14  * version 2 of the License. *
15  * *
16  * As a special exception, you may use this file as part of a free *
17  * software library without restriction. Specifically, if other files *
18  * instantiate templates or use macros or inline functions from this *
19  * file, or you compile this file and link it with other files to *
20  * produce an executable, this file does not by itself cause the *
21  * resulting executable to be covered by the GNU General Public *
22  * License. This exception does not however invalidate any other *
23  * reasons why the executable file might be covered by the GNU General *
24  * Public License. *
25  * *
26  * This library is distributed in the hope that it will be useful, *
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
29  * Lesser General Public License for more details. *
30  * *
31  * You should have received a copy of the GNU General Public *
32  * License along with this library; if not, write to the Free Software *
33  * Foundation, Inc., 59 Temple Place, *
34  * Suite 330, Boston, MA 02111-1307 USA *
35  * *
36  ***************************************************************************/
37 
38 
39 #ifndef HIERARCHICAL_STATE_MACHINE_HPP
40 #define HIERARCHICAL_STATE_MACHINE_HPP
41 
42 #include "rtt-scripting-config.h"
43 #include "StateInterface.hpp"
44 #include "ConditionInterface.hpp"
45 #include "../base/ActionInterface.hpp"
46 #include "../base/ExecutableInterface.hpp"
47 #include "../base/DataSourceBase.hpp"
48 #include "../Handle.hpp"
49 #include "../os/Mutex.hpp"
50 
51 #include <map>
52 #include <vector>
53 #include <string>
54 #include <utility>
55 #include <boost/tuple/tuple.hpp>
56 #include <boost/weak_ptr.hpp>
57 #include <boost/shared_ptr.hpp>
58 
59 namespace RTT
60 { namespace scripting {
61  typedef boost::shared_ptr<StateMachine> StateMachinePtr;
62  typedef boost::weak_ptr<StateMachine> StateMachineWPtr;
63 
74  {
75  enum PrivateStatus { nill, gostop, goreset, pausing } smpStatus;
76 
77  static std::string emptyString;
78  public:
83  enum StateMachineStatus {inactive, activating, active, requesting, running, stopping, stopped, resetting, deactivating, paused, error, unloaded };
84  };
85  protected:
90  typedef std::vector< boost::tuple<ConditionInterface*, StateInterface*, int, int, boost::shared_ptr<ProgramInterface> > > TransList;
91  typedef std::map< StateInterface*, TransList > TransitionMap;
92  typedef std::multimap< StateInterface*, std::pair<ConditionInterface*, int> > PreConditionMap;
93  typedef std::vector< boost::tuple<ServicePtr,
94  std::string, std::vector<base::DataSourceBase::shared_ptr>,
96  ConditionInterface*, boost::shared_ptr<ProgramInterface>,
97  Handle,
98  StateInterface*, boost::shared_ptr<ProgramInterface> > > EventList;
99  typedef std::map< StateInterface*, EventList > EventMap;
100  std::vector<StateMachinePtr> _children;
101  typedef boost::weak_ptr<StateMachine> StateMachineParentPtr;
102  StateMachineParentPtr _parent;
103 
104  std::string _name;
106 
107  public:
108 
109  typedef std::vector<StateMachinePtr> ChildList;
110 
115  virtual ~StateMachine();
116 
122  StateMachine(StateMachinePtr parent, const std::string& name="Default");
123 
127  void trace(bool on_off);
128 
132  bool requestState(const std::string& statename) {
133  StateInterface* tmp = this->getState(statename);
134  if (tmp) {
135  return this->requestStateChange( tmp );
136  }
137  return false;
138  }
139 
143  bool inState(const std::string& state) const {
144  StateInterface* copy = this->currentState();
145  if (copy == 0)
146  return false;
147  return copy->getName() == state;
148  }
149 
154  bool inStrictState(const std::string& state) const {
155  StateInterface* copy = this->currentState();
156  if (copy == 0)
157  return false;
158  return copy->getName() == state && !this->inTransition();
159  }
160 
164  const std::string& getCurrentStateName() const {
165  StateInterface* copy = this->currentState();
166  if (copy == 0)
167  return emptyString;
168  return copy->getName();
169  }
170 
174  inline bool isStrictlyActive() const {
175  return this->isActive() && !this->inTransition();
176  }
177 
181  inline bool inInitialState() const {
182  return initstate == current;// && !_sc->inTransition();
183  }
184 
188  inline bool inFinalState() const {
189  return finistate == current;// && !this->inTransition();
190  }
191 
196  bool stepDone() const {
197  if ( isPaused() )
198  return !mstep;
199  return isStrictlyActive();
200  }
201 
205  inline bool isActive() const { return current != 0; }
206 
211  inline bool isStopped() const { return smStatus == Status::stopped; }
212 
216  inline bool inError() const { return smStatus == Status::error; }
217 
221  inline bool isReactive() const { return current != 0 && smStatus != Status::running; }
222 
227  inline bool isAutomatic() const { return smStatus == Status::running; }
228 
232  inline bool isPaused() const { return smStatus == Status::paused; }
233 
237  bool activate();
238 
242  bool pause();
243 
248  bool step();
249 
253  bool automatic();
254 
258  bool start();
259 
264  bool stop();
265 
270  bool reset();
271 
275  bool reactive();
276 
280  bool deactivate();
281 
286  bool execute();
287 
288  void loading();
289 
290  void unloading();
291 
307  StateInterface* requestNextState(bool stepping = false);
308 
313  StateInterface* requestNextStateStep();
314 
319  bool requestFinalState();
320 
331  bool requestInitialState();
332 
341  StateInterface* nextState();
342 
346  std::vector<std::string> getStateList() const;
347 
351  StateInterface* getState( const std::string & name ) const;
352 
356  Status::StateMachineStatus getStatus() const;
357 
361  std::string getStatusStr() const;
362 
366  void addState( StateInterface* s );
367 
380  bool requestStateChange( StateInterface * s_n );
381 
395  bool executePending( bool stepping = false );
396 
414  void preconditionSet( StateInterface* state, ConditionInterface* cnd, int line);
415 
435  void transitionSet( StateInterface* from, StateInterface* to, ConditionInterface* cnd, int priority, int line);
436 
459  void transitionSet( StateInterface* from, StateInterface* to,
460  ConditionInterface* cnd, boost::shared_ptr<ProgramInterface> transprog,
461  int priority, int line);
462 
484  bool createEventTransition( ServicePtr sp, ExecutionEngine* target_engine,
485  const std::string& ename, std::vector<base::DataSourceBase::shared_ptr> args,
486  StateInterface* from, StateInterface* to,
487  ConditionInterface* guard, boost::shared_ptr<ProgramInterface> transprog,
488  StateInterface* elseto = 0, boost::shared_ptr<ProgramInterface> elseprog =
489  boost::shared_ptr<ProgramInterface>() );
493  void setInitialState( StateInterface* s );
494 
498  void setFinalState( StateInterface* s );
499 
504  StateInterface* currentState() const;
505 
510  ProgramInterface* currentProgram() const;
511 
515  StateInterface* getInitialState() const {
516  return initstate;
517  }
518 
522  StateInterface* getFinalState() const {
523  return finistate;
524  }
525 
534  {
535  initc = c;
536  }
537 
539  {
540  return initc;
541  }
542 
546  StateMachinePtr getParent() const
547  {
548  return _parent.lock();
549  }
550 
551  void setParent(StateMachinePtr parent)
552  {
553  _parent = parent;
554  }
555 
559  const ChildList& getChildren() const
560  {
561  return _children;
562  }
563 
564  void addChild( StateMachinePtr child ) {
565  _children.push_back( child );
566  }
567 
572  const std::string& getName() const {
573  return _name;
574  }
575 
580  int getLineNumber() const;
581 
585  virtual std::string getText() const;
586 
593  bool inTransition() const;
594 
600  bool interruptible() const;
601 
602  protected:
608  TransitionMap stateMap;
609 
614  PreConditionMap precondMap;
615 
620  EventMap eventMap;
621 
622  void changeState( StateInterface* s, ProgramInterface* tprog, bool stepping = false );
623 
624  void leaveState( StateInterface* s );
625 
626  void enterState( StateInterface* s );
627 
628  void runState( StateInterface* s );
629 
630  void handleState( StateInterface* s );
631 
632  bool executeProgram(ProgramInterface*& cp, bool stepping);
633 
634  int checkConditions( StateInterface* state, bool stepping = false );
635 
636  void enableGlobalEvents();
637  void disableGlobalEvents();
638  void enableEvents( StateInterface* s );
639  void disableEvents( StateInterface* s );
640  private:
641 
646  bool eventTransition( StateInterface* from, ConditionInterface* c,
647  ProgramInterface* p, StateInterface* to,
648  ProgramInterface* elsep, StateInterface* elseto );
649 
653  StateInterface* initstate;
654 
658  StateInterface* finistate;
659 
664  StateInterface* current;
665 
669  StateInterface* next;
670 
671  base::ActionInterface* initc;
672 
673  ProgramInterface* currentProg;
674  ProgramInterface* currentExit;
675  ProgramInterface* currentHandle;
676  ProgramInterface* currentEntry;
677  ProgramInterface* currentRun;
678  ProgramInterface* currentTrans;
679 
680  TransList::iterator reqstep;
681  TransList::iterator reqend;
682 
683  std::pair<PreConditionMap::const_iterator,PreConditionMap::const_iterator> prec_it;
684  bool checking_precond;
685  bool mstep, mtrace;
686 
687  int evaluating;
688 
689  os::MutexRecursive execlock;
690  };
691 }}
692 
693 #endif
bool isStrictlyActive() const
Strictly active, means active and not in a transition.
A hierarchical StateMachine which is loaded in the Program Processor.
void setInitCommand(base::ActionInterface *c)
This was added for extra (non-user visible) initialisation when the StateMachine is activated...
std::vector< boost::tuple< ConditionInterface *, StateInterface *, int, int, boost::shared_ptr< ProgramInterface > > > TransList
The key is the current state, the value is the transition condition to another state with a certain p...
bool isAutomatic() const
Query if the state machine is reacting to events and evaluating transition conditions.
bool inState(const std::string &state) const
Check if the state machine is in a given state.
bool isStopped() const
Returns true if the state machine is in the final state, after a stop() directive.
This interface represents the concept of a condition which can be evaluated and return true or false...
StateMachineParentPtr _parent
bool inStrictState(const std::string &state) const
Check if the state machine is in a given state and not in the entry or exit program.
const std::string & getName() const
This method must be overloaded to get a useful hierarchy.
#define RTT_SCRIPTING_API
virtual const std::string & getName() const =0
Get the name of this state.
An execution engine serialises (executes one after the other) the execution of all commands...
bool inInitialState() const
Inspect if we are in the initial state.
bool stepDone() const
When isPaused(), return true if no step is pending, when isReactive(), return isStrictlyActive() ...
std::multimap< StateInterface *, std::pair< ConditionInterface *, int > > PreConditionMap
const std::string & getCurrentStateName() const
Return name of current state, empty string if not active.
boost::weak_ptr< StateMachine > StateMachineParentPtr
bool inError() const
Get the error status of this StateMachine.
boost::shared_ptr< Service > ServicePtr
Definition: rtt-fwd.hpp:86
Status::StateMachineStatus smStatus
Based on the software pattern &#39;command&#39;, this interface allows execution of action objects...
bool requestState(const std::string &statename)
Request a transition to a given state.
boost::shared_ptr< StateMachine > StateMachinePtr
StateInterface * getInitialState() const
Retrieve the initial state of the state machine.
std::vector< StateMachinePtr > ChildList
boost::weak_ptr< StateMachine > StateMachineWPtr
Enumerates all possible state machine statuses.
PreConditionMap precondMap
A map keeping track of all preconditions of a state.
bool inFinalState() const
Inspect if we are in the final state.
void addChild(StateMachinePtr child)
StateMachinePtr getParent() const
Get the parent, returns zero if no parent.
std::vector< boost::tuple< ServicePtr, std::string, std::vector< base::DataSourceBase::shared_ptr >, StateInterface *, ConditionInterface *, boost::shared_ptr< ProgramInterface >, Handle, StateInterface *, boost::shared_ptr< ProgramInterface > > > EventList
bool isReactive() const
Query if the state machine is currently reacting only to events.
std::vector< StateMachinePtr > _children
Objects that implement this interface are to be executed in the ExecutionEngine.
std::map< StateInterface *, TransList > TransitionMap
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
Definition: Activity.cpp:51
An object oriented wrapper around a recursive mutex.
Definition: Mutex.hpp:208
TransitionMap stateMap
A map keeping track of all States and conditional transitions between two states. ...
A State contains an entry, run, handle and exit program.
A Program represents a collection of instructions that can be stepwise executed.
StateInterface * getFinalState() const
Retrieve the final state of the state machine.
bool isActive() const
Returns true if the state machine is activated.
The Handle holds the information, and allows manipulation, of a connection between a internal::Signal...
Definition: Handle.hpp:66
bool isPaused() const
Query if the state machine is paused.
EventMap eventMap
A map keeping track of all events of a state.
void setParent(StateMachinePtr parent)
base::ActionInterface * getInitCommand() const
const ChildList & getChildren() const
Get a list of all child state machines.
std::map< StateInterface *, EventList > EventMap