MIRA
StateMachine.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) by
3  * MetraLabs GmbH (MLAB), GERMANY
4  * and
5  * Neuroinformatics and Cognitive Robotics Labs (NICR) at TU Ilmenau, GERMANY
6  * All rights reserved.
7  *
8  * Redistribution and modification of this code is strictly prohibited.
9  *
10  * IN NO EVENT SHALL "MLAB" OR "NICR" BE LIABLE TO ANY PARTY FOR DIRECT,
11  * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
12  * THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF "MLAB" OR
13  * "NICR" HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14  *
15  * "MLAB" AND "NICR" SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
16  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
17  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
18  * ON AN "AS IS" BASIS, AND "MLAB" AND "NICR" HAVE NO OBLIGATION TO
19  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR MODIFICATIONS.
20  */
21 
30 #ifndef _MIRA_STATEMACHINE_H_
31 #define _MIRA_STATEMACHINE_H_
32 
33 #include <set>
34 
35 #include <thread/Thread.h>
36 #include <utils/Path.h>
37 #include <xml/XMLDom.h>
38 
39 #include <fw/Framework.h>
40 
41 #include <sm/StateMachineExports.h>
42 #include <sm/Transition.h>
43 #include <sm/TransitionTarget.h>
45 
46 namespace mira { namespace sm {
47 
49 
50 template <typename T, typename Sequence = std::vector<T>, typename Compare = std::less<typename Sequence::value_type>>
51 class iterable_priority_queue : public std::priority_queue<T, Sequence, Compare>
52 {
53 public:
54  typedef typename Sequence::iterator iterator;
55  typedef typename Sequence::const_iterator const_iterator;
56 
57  iterator begin() { return this->c.begin(); }
58  iterator end() { return this->c.end(); }
59  const_iterator begin() const { return this->c.begin(); }
60  const_iterator end() const { return this->c.end(); }
61 
62 };
63 
65 
70 {
71 public:
72 
73  StateMachine(Authority* authority = NULL, const std::string& name = "");
74  ~StateMachine();
75 
76  template<typename Reflector>
77  void reflect(Reflector& r)
78  {
79  r.interface("IStateMachine");
80  r.method("sendEvent", &StateMachine::sendEvent, this, "Send an event",
81  "event", "Event");
82  r.method("sendEventByName",
83  (void(StateMachine::*)(const std::string&))(&StateMachine::sendEventByName),
84  this, "Send an event by name",
85  "event", "Event name", "MyEvent");
86  r.method("sendEventByName",
87  (void(StateMachine::*)(const std::string&, const std::string&))(&StateMachine::sendEventByName),
88  this, "Send an event by name",
89  "event", "Event name", "jsonData", "Event data (JSON notation)");
90  r.method("sendEventByName",
91  (void(StateMachine::*)(const std::string&, const std::string&, const uint64))(&StateMachine::sendEventByName),
92  this, "Send an event by name",
93  "event", "Event name", "jsonData", "Event data (JSON notation)", "delay", "Delay (in ms) before event is dispatched");
94  }
95 
99  void load(const Path& filename);
104  void run();
108  void interrupt() { mRunning = false; }
112  void sendEvent(const Event& event);
116  void sendEventByName(const std::string& event) { sendEventByName(event, ""); }
117  void sendEventByName(const std::string& event, const std::string& jsonData) { sendEventByName(event, jsonData, 0); }
118  void sendEventByName(const std::string& event, const std::string& jsonData, const uint64 delay);
123  void cancelEvent(const std::string& sendid);
128  bool inState(const std::string& state) const;
132  bool isRunning() const { return mRunning; }
136  void printStates();
137 
138  std::set<std::string> getConfiguration() const;
143  void addListener(StateMachineListener* listener);
148  std::string getNamespace() const;
153  std::string resolveName(const std::string& name) const;
158  std::string resolveServiceName(const std::string& name) const;
159 
160 protected:
161 
162  void onChannelData(ChannelRead<void> data);
163 
164  void executeContent(XMLDom::iterator executable);
165  void executePython(const std::string& script, bool ignoreErrors = false);
166  void executeTransitionContent(TransitionList& t);
167  void createDataModel(TransitionTargetPtr t);
168  void setDataModel(TransitionTargetPtr t);
169 
170  bool isInFinalState(TransitionTargetPtr s);
171  bool isType1(TransitionPtr t);
172  bool isType2(TransitionPtr t);
173  bool isType3(TransitionPtr t);
174  bool preemtsTransition(TransitionPtr t1, TransitionPtr t2);
175  TransitionList filterPreempted(TransitionList& enabledTransitions);
176  bool matchesCondition(const std::string& condition);
177 
178  TransitionList selectTransitions(const std::string& event);
179  TransitionList selectEventlessTransitions();
180  void enterStates(TransitionList& tlist);
181  void exitStates(TransitionList& tlist);
182  void addStatesToEnter(TransitionTargetPtr t, TransitionTargetSet& statesToEnter, TransitionTargetSet& statesForDefaultEntry);
183  TransitionTargetList getTargetStates(const std::string& target);
184 
185  void microstep(TransitionList& enabledTransitions);
186 
187  TransitionPtr parseTransition(XMLDom::iterator node, TransitionTargetPtr source);
188  void parseDataModel(XMLDom::iterator node, TransitionTargetPtr parent);
189  FinalStatePtr parseFinal(XMLDom::iterator node, TransitionTargetPtr parent);
190  HistoryStatePtr parseHistory(XMLDom::iterator node, TransitionTargetPtr parent);
192  TransitionTargetPtr parseParallel(XMLDom::iterator node, TransitionTargetPtr parent);
193  void parseScriptSrc(XMLDom::iterator node);
194  void parseExecutableContent(XMLDom::iterator node, const std::string& nodeInfo = "");
195 
196  void publishConfiguration();
197 
198 public:
199 
200  std::string mName;
204  std::string mBinding;
205  std::map<std::string, TransitionTargetPtr> mTargets;
206  std::map<std::string, TransitionTargetSet> mHistoryValue;
207 
208  mutable boost::mutex mRunMutex;
209  bool mRunning;
211  struct EventLessComp {
212  bool operator() (const Event& lhs, const Event&rhs) const {
213  if (rhs.delay == 0 && lhs.delay != 0)
214  return true;
215  if (lhs.delay == 0)
216  return false;
217  Time lhsTime = lhs.invocationTime;
218  Time rhsTime = rhs.invocationTime;
219  assert(lhsTime.isValid() && rhsTime.isValid());
220  return lhsTime > rhsTime;
221  }
222  };
226  std::set<std::string> mSubscribedChannels;
230 
231  std::vector<StateMachineListener*> mListener;
232 
233  boost::python::object mPythonContext;
234 
236  boost::shared_ptr<Authority> mAuthority;
237 };
238 
240 
241 }} // namespace
242 
243 #endif
uint64_t uint64
Definition: StateMachineListener.h:41
const_iterator begin() const
Definition: StateMachine.h:59
boost::shared_ptr< TransitionTarget > TransitionTargetPtr
Definition: TransitionTarget.h:54
TODO Add description.
boost::filesystem::path Path
bool isValid() const
boost::shared_ptr< Authority > mAuthority
Definition: StateMachine.h:236
std::map< std::string, TransitionTargetPtr > mTargets
Definition: StateMachine.h:205
uint32_t uint32
std::vector< StateMachineListener * > mListener
Definition: StateMachine.h:231
EventQueue mInternalEvents
Definition: StateMachine.h:224
Authority * mParentAuthority
Definition: StateMachine.h:235
void sendEventByName(const std::string &event, const std::string &jsonData)
Definition: StateMachine.h:117
void sendEvent(const Event &event)
Send an event to the state machine.
Definition: StateMachine.h:51
sibling_iterator iterator
std::string mName
Definition: StateMachine.h:200
iterable_priority_queue< Event, std::vector< Event >, EventLessComp > EventQueue
Definition: StateMachine.h:223
std::set< TransitionTargetPtr, SortEntryOrder > TransitionTargetSet
Definition: TransitionTarget.h:118
TransitionTargetPtr mSCXML
Definition: StateMachine.h:203
void interrupt()
Interrupt the interpreter.
Definition: StateMachine.h:108
Channel< std::set< std::string > > mStateChannel
Definition: StateMachine.h:227
std::string mBinding
Definition: StateMachine.h:204
iterator end()
Definition: StateMachine.h:58
Event mCurrentEvent
Definition: StateMachine.h:229
const_iterator end() const
Definition: StateMachine.h:60
std::list< TransitionPtr > TransitionList
Definition: TransitionTarget.h:58
void reflect(Reflector &r)
Definition: StateMachine.h:77
Channel< std::set< std::string > > mCompressedStateChannel
Definition: StateMachine.h:228
Time invocationTime
Definition: Event.h:113
uint64 delay
Definition: Event.h:112
bool mRunning
Definition: StateMachine.h:209
boost::shared_ptr< FinalState > FinalStatePtr
Definition: TransitionTarget.h:169
Definition: Event.h:49
#define MIRA_STATEMACHINE_EXPORT
Definition: StateMachineExports.h:41
Sequence::const_iterator const_iterator
Definition: StateMachine.h:55
void sendEventByName(const std::string &event)
Send an event by name to the state machine.
Definition: StateMachine.h:116
boost::shared_ptr< HistoryState > HistoryStatePtr
Definition: TransitionTarget.h:50
std::list< TransitionTargetPtr > TransitionTargetList
Definition: TransitionTarget.h:55
boost::shared_ptr< Transition > TransitionPtr
Definition: TransitionTarget.h:57
boost::mutex mRunMutex
Definition: StateMachine.h:208
TODO Add description.
SCXML based state machine interpreter.
Definition: StateMachine.h:69
uint32 mCurrentID
Definition: StateMachine.h:202
TODO Add description.
XMLDom mDocument
Definition: StateMachine.h:201
TransitionTargetSet mConfiguration
Definition: StateMachine.h:210
Auto-generated file for export macro definition.
EventQueue mExternalEvents
Definition: StateMachine.h:225
boost::python::object mPythonContext
Definition: StateMachine.h:233
std::map< std::string, TransitionTargetSet > mHistoryValue
Definition: StateMachine.h:206
bool isRunning() const
Returns if the interpreter is running.
Definition: StateMachine.h:132
iterator begin()
Definition: StateMachine.h:57
Definition: StateMachine.h:211
Sequence::iterator iterator
Definition: StateMachine.h:54
std::set< std::string > mSubscribedChannels
Definition: StateMachine.h:226