YARP
Yet Another Robot Platform
fsm.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2020 Istituto Italiano di Tecnologia (IIT)
3  * All rights reserved.
4  *
5  * This software may be modified and distributed under the terms of the
6  * BSD-3-Clause license. See the accompanying LICENSE file for details.
7  */
8 
9 #ifndef YARP_MANAGER_FSM
10 #define YARP_MANAGER_FSM
11 
12 #include <iostream>
13 #include <string>
14 #include <typeinfo>
15 #include <exception>
16 #include <map>
17 
18 #include <yarp/os/Semaphore.h>
19 
20 namespace FSM {
21  class Event;
22  class IEventSink;
23  class StateBase;
24  class StateMachineBase;
25 }
26 
32 {
33 public:
34  Event(const char* szName) {
35  if(szName) { strName = szName; }
36  timeStamp = 0;
37  }
38  virtual ~Event() = default;
39 
40  void setTimeStamp(double t) { timeStamp = t; }
41  double getTimeStamp() { return timeStamp; }
42  const char* getName() { return strName.c_str(); }
43 
44  inline bool operator==(const Event& alt) const {
45  return ((strName == alt.strName)); }
46 
47 private:
48  std::string strName;
49  double timeStamp;
50 };
51 
52 
53 
59 {
60 public:
61 
62  IEventSink() = default;
63  virtual ~IEventSink() = default;
64 
68  virtual void castEvent (Event* event) = 0;
69 
70 private:
71 
72 
73 };
74 
75 
80 {
81 public:
82  StateBase(IEventSink* pEventSink, const char* szName = nullptr) {
83  eventSink = pEventSink;
84  if(szName) { strName = szName; }
85  }
86 
87  virtual ~StateBase() = default;
88 
89  const char* getName() {
90  return strName.c_str(); }
91 
92 protected:
93  void castEvent(Event* event) {
94  eventSink->castEvent(event);
95  }
96 
97 private:
98  IEventSink* eventSink;
99  std::string strName;
100 };
101 
102 typedef std::map<FSM::StateBase*, std::map<FSM::Event*, FSM::StateBase*> > MyStateMap;
103 typedef std::map<FSM::StateBase*, std::map<FSM::Event*, FSM::StateBase*> >::iterator MyStateItr;
104 
105 
110 {
111 public:
113  state = nullptr;
114  currentTimeStamp = 0.0;
115  }
116  ~StateMachineBase() override = default;
117 
119  try
120  {
121  // typeid(*state);
122  return state;
123  }
124  catch (std::exception& )
125  {
126  std::cerr<<"Exception in currentState(): Initial state is not set!"<<std::endl;
127  std::terminate();
128  }
129  }
130 
131  void setInitState(StateBase* pState) {
132  if(!state) { state = pState; }
133  }
134 
135  void addTransition(StateBase* source, Event* event, StateBase* target) {
136  try
137  {
138 // typeid(*target);
139  transitions[source][event] = target;
140  }
141  catch (std::exception& typevar)
142  {
143  std::cerr<<"Exception in addTransition(): "<<typevar.what()<<std::endl;
144  std::terminate();
145  }
146  }
147 
148 protected:
149 
153  virtual void onTransition(StateBase* previous, Event* event, StateBase* current) {}
154  virtual void onEventMissed(StateBase* state, Event* event) {}
155 
156 public: // implementing IEventSink::castEvent()
157 
158  void castEvent(Event* event) override
159  {
160  semEvent.wait();
161  if(!state)
162  {
163  std::cerr<<"Initial state is not set!"<<std::endl;
164  semEvent.post();
165  return;
166  }
167 
168  if(event->getTimeStamp() < currentTimeStamp )
169  {
170  onEventMissed(state, event);
171  semEvent.post();
172  return;
173  }
174 
175  currentTimeStamp = event->getTimeStamp();
176 
177  MyStateItr it;
178  it = transitions.find(state);
179  if(it==transitions.end())
180  {
181  std::cerr<<"No transition is registered from state "<<state->getName()<<std::endl;
182  semEvent.post();
183  return;
184  }
185 
186  std::map<Event*, StateBase*> row = transitions[state];
187  std::map<Event*, StateBase*>::iterator itr2 = row.find(event);
188  if(itr2 == row.end())
189  {
190  std::cerr<<"No transition is registered for event ";
191  std::cerr<<event->getName()<<" ("<<event->getTimeStamp()<<")";
192  std::cerr<<" from state "<<state->getName()<<std::endl;
193  semEvent.post();
194  return;
195  }
196 
197  StateBase* previous = state;
198  state = row[event];
199 
200  // calling callback
201  onTransition(previous, event, state);
202  semEvent.post();
203  }
204 
205 private:
206  StateBase* state;
207  MyStateMap transitions;
208  yarp::os::Semaphore semEvent;
209  double currentTimeStamp;
210 
211 };
212 
213 
214 #endif // __YARP_MANAGER_FSM__
FSM::StateMachineBase::currentState
StateBase * currentState()
Definition: fsm.h:118
FSM::IEventSink::IEventSink
IEventSink()=default
yarp::os::Semaphore
A class for thread synchronization and mutual exclusion.
Definition: Semaphore.h:29
t
float t
Definition: FfmpegWriter.cpp:74
FSM::StateMachineBase::castEvent
void castEvent(Event *event) override
Definition: fsm.h:158
FSM::Event
class IEventSink
Definition: fsm.h:32
FSM::Event::getName
const char * getName()
Definition: fsm.h:42
yarp::os::Semaphore::wait
void wait()
Decrement the counter, even if we must wait to do that.
Definition: Semaphore.cpp:99
FSM::StateMachineBase::setInitState
void setInitState(StateBase *pState)
Definition: fsm.h:131
MyStateItr
std::map< FSM::StateBase *, std::map< FSM::Event *, FSM::StateBase * > >::iterator MyStateItr
Definition: fsm.h:103
FSM::Event::getTimeStamp
double getTimeStamp()
Definition: fsm.h:41
yarp::os::Semaphore::post
void post()
Increment the counter.
Definition: Semaphore.cpp:114
FSM::StateMachineBase::onTransition
virtual void onTransition(StateBase *previous, Event *event, StateBase *current)
Callback onTransition represents the change in the states.
Definition: fsm.h:153
FSM::Event::Event
Event(const char *szName)
Definition: fsm.h:34
FSM::StateMachineBase::~StateMachineBase
~StateMachineBase() override=default
FSM::IEventSink::~IEventSink
virtual ~IEventSink()=default
FSM::StateBase
Class StateBase.
Definition: fsm.h:80
FSM::StateMachineBase
Class StateMachineBase.
Definition: fsm.h:110
MyStateMap
std::map< FSM::StateBase *, std::map< FSM::Event *, FSM::StateBase * > > MyStateMap
Definition: fsm.h:102
Semaphore.h
FSM::StateMachineBase::StateMachineBase
StateMachineBase()
Definition: fsm.h:112
FSM::Event::~Event
virtual ~Event()=default
FSM::Event::setTimeStamp
void setTimeStamp(double t)
Definition: fsm.h:40
FSM::StateBase::~StateBase
virtual ~StateBase()=default
FSM::StateMachineBase::addTransition
void addTransition(StateBase *source, Event *event, StateBase *target)
Definition: fsm.h:135
FSM::IEventSink
class IEventSink
Definition: fsm.h:59
FSM::StateBase::getName
const char * getName()
Definition: fsm.h:89
FSM
Definition: fsm.h:20
FSM::StateBase::castEvent
void castEvent(Event *event)
Definition: fsm.h:93
FSM::StateMachineBase::onEventMissed
virtual void onEventMissed(StateBase *state, Event *event)
Definition: fsm.h:154
FSM::StateBase::StateBase
StateBase(IEventSink *pEventSink, const char *szName=nullptr)
Definition: fsm.h:82
FSM::Event::operator==
bool operator==(const Event &alt) const
Definition: fsm.h:44
FSM::IEventSink::castEvent
virtual void castEvent(Event *event)=0