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