NASA Astrobee Robot Software  0.19.1
Flight software for the Astrobee robots operating inside the International Space Station.
ff_fsm.h
Go to the documentation of this file.
1 /* Copyright (c) 2017, United States Government, as represented by the
2  * Administrator of the National Aeronautics and Space Administration.
3  *
4  * All rights reserved.
5  *
6  * The Astrobee platform is licensed under the Apache License, Version 2.0
7  * (the "License"); you may not use this file except in compliance with the
8  * License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15  * License for the specific language governing permissions and limitations
16  * under the License.
17  */
18 
19 #ifndef FF_UTIL_FF_FSM_H_
20 #define FF_UTIL_FF_FSM_H_
21 
22 // C++ includes
23 #include <functional>
24 #include <utility>
25 #include <vector>
26 #include <map>
27 
28 namespace ff_util {
29 
30 class FSM {
31  public:
32  typedef int8_t State;
33  typedef uint32_t Event;
34  typedef std::function<State(Event const&)> TransitionCallback;
35  typedef std::function<State(State const&, Event const&)> CatchallCallback;
36  typedef std::function<void(State const&, Event const&)> UpdateCallback;
37 
38  // Initialize the FSM with a given initial state
39  FSM(State const& initial_state,
40  UpdateCallback callback = nullptr) :
41  state_(initial_state), callback_(callback) {}
42 
43  // 1-state transition
44  void Add(State const& s1,
45  Event const& mask,
46  TransitionCallback callback) {
47  for (size_t i = 0; i < 8 * sizeof(Event); i++) {
48  if (mask & (1 << i)) {
49  fsm_[std::make_pair(s1, 1 << i)] = callback;
50  }
51  }
52  }
53 
54  // 2-state transition
55  void Add(State const& s1, State const& s2,
56  Event const& mask,
57  TransitionCallback callback) {
58  for (size_t i = 0; i < 8 * sizeof(Event); i++) {
59  if (mask & (1 << i)) {
60  fsm_[std::make_pair(s1, 1 << i)] = callback;
61  fsm_[std::make_pair(s2, 1 << i)] = callback;
62  }
63  }
64  }
65 
66  // 3-state transition
67  void Add(State const& s1, State const& s2, State const& s3,
68  Event const& mask,
69  TransitionCallback callback) {
70  for (size_t i = 0; i < 8 * sizeof(Event); i++) {
71  if (mask & (1 << i)) {
72  fsm_[std::make_pair(s1, 1 << i)] = callback;
73  fsm_[std::make_pair(s2, 1 << i)] = callback;
74  fsm_[std::make_pair(s3, 1 << i)] = callback;
75  }
76  }
77  }
78 
79  // Catch-all for a single event. Takes priority.
80  void Add(Event const& mask, CatchallCallback callback) {
81  for (size_t i = 0; i < 8 * sizeof(Event); i++)
82  if (mask & (1 << i)) catchall_[1 << i] = callback;
83  }
84 
85  // Get the current state
87  return state_;
88  }
89 
90  // Set the current state
91  void SetState(State const& state) {
92  state_ = state;
93  }
94 
95  // Update the state machine - we only expect one event here
96  void Update(Event const& event) {
97  // Case 1 : A catch-all event occured
98  if (catchall_.find(event) != catchall_.end()) {
99  state_ = catchall_[event](state_, event);
100  if (callback_)
101  callback_(state_, event);
102  return;
103  }
104  // Case 2: Valid transition in the state machine
105  std::pair<State, Event> key = std::make_pair(state_, event);
106  if (fsm_.find(key) != fsm_.end()) {
107  state_ = fsm_[key](event); // Call the transition function
108  if (callback_) // Post-update callback
109  callback_(state_, event);
110  }
111  // Case 3: Quietly ignore
112  }
113 
114  private:
115  State state_;
116  std::map<std::pair<State, Event>, TransitionCallback> fsm_;
117  std::map<Event, CatchallCallback> catchall_;
118  UpdateCallback callback_;
119 };
120 
121 } // namespace ff_util
122 
123 #endif // FF_UTIL_FF_FSM_H_
ff_util::FSM::UpdateCallback
std::function< void(State const &, Event const &)> UpdateCallback
Definition: ff_fsm.h:36
ff_util::FSM::Add
void Add(State const &s1, State const &s2, Event const &mask, TransitionCallback callback)
Definition: ff_fsm.h:55
ff_util::FSM::FSM
FSM(State const &initial_state, UpdateCallback callback=nullptr)
Definition: ff_fsm.h:39
ff_util::FSM::Update
void Update(Event const &event)
Definition: ff_fsm.h:96
mask
uint8_t mask
Definition: signal_lights.h:72
ff_util::FSM::SetState
void SetState(State const &state)
Definition: ff_fsm.h:91
ff_util::FSM::Event
uint32_t Event
Definition: ff_fsm.h:33
ff_util::FSM::Add
void Add(Event const &mask, CatchallCallback callback)
Definition: ff_fsm.h:80
ff_util::FSM::TransitionCallback
std::function< State(Event const &)> TransitionCallback
Definition: ff_fsm.h:34
ff_util::FSM::GetState
State GetState()
Definition: ff_fsm.h:86
ff_util::FSM::State
int8_t State
Definition: ff_fsm.h:32
ff_util::FSM::Add
void Add(State const &s1, Event const &mask, TransitionCallback callback)
Definition: ff_fsm.h:44
ff_util::FSM::CatchallCallback
std::function< State(State const &, Event const &)> CatchallCallback
Definition: ff_fsm.h:35
ff_util
Definition: config_client.h:31
state
uint8_t state
Definition: signal_lights.h:90
ff_util::State
Definition: ff_flight.h:49
ff_util::FSM
Definition: ff_fsm.h:30
ff_util::FSM::Add
void Add(State const &s1, State const &s2, State const &s3, Event const &mask, TransitionCallback callback)
Definition: ff_fsm.h:67