39 #ifndef HIERARCHICAL_STATE_MACHINE_HPP 40 #define HIERARCHICAL_STATE_MACHINE_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" 55 #include <boost/tuple/tuple.hpp> 56 #include <boost/weak_ptr.hpp> 57 #include <boost/shared_ptr.hpp> 60 {
namespace scripting {
75 enum PrivateStatus { nill, gostop, goreset, pausing } smpStatus;
77 static std::string emptyString;
83 enum StateMachineStatus {inactive, activating, active, requesting, running, stopping, stopped, resetting, deactivating, paused, error, unloaded };
90 typedef std::vector< boost::tuple<ConditionInterface*, StateInterface*, int, int, boost::shared_ptr<ProgramInterface> > >
TransList;
92 typedef std::multimap< StateInterface*, std::pair<ConditionInterface*, int> >
PreConditionMap;
94 std::string, std::vector<base::DataSourceBase::shared_ptr>,
98 StateInterface*, boost::shared_ptr<ProgramInterface> > >
EventList;
99 typedef std::map< StateInterface*, EventList >
EventMap;
122 StateMachine(StateMachinePtr parent,
const std::string& name=
"Default");
127 void trace(
bool on_off);
133 StateInterface* tmp = this->getState(statename);
135 return this->requestStateChange( tmp );
143 bool inState(
const std::string& state)
const {
144 StateInterface* copy = this->currentState();
147 return copy->
getName() == state;
155 StateInterface* copy = this->currentState();
158 return copy->
getName() == state && !this->inTransition();
165 StateInterface* copy = this->currentState();
175 return this->isActive() && !this->inTransition();
182 return initstate == current;
189 return finistate == current;
199 return isStrictlyActive();
205 inline bool isActive()
const {
return current != 0; }
211 inline bool isStopped()
const {
return smStatus == Status::stopped; }
216 inline bool inError()
const {
return smStatus == Status::error; }
221 inline bool isReactive()
const {
return current != 0 && smStatus != Status::running; }
227 inline bool isAutomatic()
const {
return smStatus == Status::running; }
232 inline bool isPaused()
const {
return smStatus == Status::paused; }
307 StateInterface* requestNextState(
bool stepping =
false);
313 StateInterface* requestNextStateStep();
319 bool requestFinalState();
331 bool requestInitialState();
341 StateInterface* nextState();
346 std::vector<std::string> getStateList()
const;
351 StateInterface* getState(
const std::string & name )
const;
361 std::string getStatusStr()
const;
366 void addState( StateInterface* s );
380 bool requestStateChange( StateInterface * s_n );
395 bool executePending(
bool stepping =
false );
414 void preconditionSet( StateInterface* state, ConditionInterface* cnd,
int line);
435 void transitionSet( StateInterface* from, StateInterface* to, ConditionInterface* cnd,
int priority,
int line);
459 void transitionSet( StateInterface* from, StateInterface* to,
460 ConditionInterface* cnd, boost::shared_ptr<ProgramInterface> transprog,
461 int priority,
int line);
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 );
498 void setFinalState( StateInterface* s );
504 StateInterface* currentState()
const;
548 return _parent.lock();
565 _children.push_back( child );
580 int getLineNumber()
const;
585 virtual std::string getText()
const;
593 bool inTransition()
const;
600 bool interruptible()
const;
622 void changeState( StateInterface* s,
ProgramInterface* tprog,
bool stepping =
false );
624 void leaveState( StateInterface* s );
626 void enterState( StateInterface* s );
628 void runState( StateInterface* s );
630 void handleState( StateInterface* s );
634 int checkConditions( StateInterface* state,
bool stepping =
false );
636 void enableGlobalEvents();
637 void disableGlobalEvents();
638 void enableEvents( StateInterface* s );
639 void disableEvents( StateInterface* s );
646 bool eventTransition( StateInterface* from, ConditionInterface* c,
653 StateInterface* initstate;
658 StateInterface* finistate;
664 StateInterface* current;
669 StateInterface* next;
680 TransList::iterator reqstep;
681 TransList::iterator reqend;
683 std::pair<PreConditionMap::const_iterator,PreConditionMap::const_iterator> prec_it;
684 bool checking_precond;
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
Status::StateMachineStatus smStatus
Based on the software pattern 'command', 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.
An object oriented wrapper around a recursive mutex.
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...
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