state_machine.cpp
Go to the documentation of this file.
1 
13 
14 #include <ros/ros.h>
15 
21 StateMachine::StateMachine(std::string xml_string)
22 {
23  using namespace boost::property_tree;
24  ptree pt;
25  std::stringstream ss;
26  ss << xml_string;
27  read_xml(ss, pt);
28  std::string init_state_name;
29  for (const ptree::value_type& state_itr : pt.get_child("state_machine"))
30  {
31  if(state_itr.first == "init_state")
32  {
33  init_state_name = state_itr.second.get<std::string>("<xmlattr>.name");
34  }
35  if(state_itr.first == "state_machine_name")
36  {
37  name_ = state_itr.second.get<std::string>("<xmlattr>.name");
38  }
39  }
40  for (const ptree::value_type& state_itr : pt.get_child("state_machine"))
41  {
42  if(state_itr.first == "transition")
43  {
44  std::string from_state_name = state_itr.second.get<std::string>("<xmlattr>.from");
45  std::string to_state_name = state_itr.second.get<std::string>("<xmlattr>.to");
46  std::string trigger_event_name = state_itr.second.get<std::string>("<xmlattr>.name");
47  addTransition(from_state_name, to_state_name, trigger_event_name);
48  }
49  }
50  setCurrentState(init_state_name);
51 }
52 
58 {
59 }
60 
66 std::string StateMachine::getName()
67 {
68  return name_;
69 }
70 
78 bool StateMachine::setCurrentState(std::string current_state)
79 {
80  std::lock_guard<std::mutex> lock(mtx_);
81  auto vertex_range = boost::vertices(state_graph_);
82  for (auto first = vertex_range.first, last = vertex_range.second; first != last; ++first)
83  {
84  vertex_t v = *first;
85  if(state_graph_[v].name == current_state)
86  {
87  current_state_ = v;
88  return true;
89  }
90  }
91  return false;
92 }
93 
101 void StateMachine::addTransition(std::string from_state_name, std::string to_state_name, std::string trigger_event_name)
102 {
103  std::lock_guard<std::mutex> lock(mtx_);
104  vertex_t from_state;
105  vertex_t to_state;
106  edge_t transition;
107  auto vertex_range = boost::vertices(state_graph_);
108  if(from_state_name != to_state_name)
109  {
110  bool from_state_found = false;
111  bool to_state_found = false;
112  for (auto first = vertex_range.first, last = vertex_range.second; first != last; ++first)
113  {
114  vertex_t v = *first;
115  if(state_graph_[v].name == from_state_name)
116  {
117  from_state_found = true;
118  from_state = v;
119  }
120  if(state_graph_[v].name == to_state_name)
121  {
122  to_state_found = true;
123  to_state = v;
124  }
125  }
126  if(!from_state_found)
127  {
128  vertex_t v = boost::add_vertex(state_graph_);
129  state_graph_[v].name = from_state_name;
130  from_state = v;
131  }
132  if(!to_state_found)
133  {
134  vertex_t v = boost::add_vertex(state_graph_);
135  state_graph_[v].name = to_state_name;
136  to_state = v;
137  }
138  bool inserted = false;
139  boost::tie(transition, inserted) = boost::add_edge(from_state, to_state, state_graph_);
140  state_graph_[transition].trigger_event = trigger_event_name;
141  state_graph_[transition].from_state = from_state_name;
142  state_graph_[transition].to_state = to_state_name;
143  }
144  else
145  {
146  bool state_found = false;
147  for (auto first = vertex_range.first, last = vertex_range.second; first != last; ++first)
148  {
149  vertex_t v = *first;
150  if(state_graph_[v].name == from_state_name)
151  {
152  state_found = true;
153  from_state = v;
154  to_state = v;
155  }
156  }
157  if(!state_found)
158  {
159  vertex_t v = boost::add_vertex(state_graph_);
160  state_graph_[v].name = from_state_name;
161  from_state = v;
162  to_state = v;
163  }
164  bool inserted = false;
165  boost::tie(transition, inserted) = boost::add_edge(from_state, to_state, state_graph_);
166  state_graph_[transition].trigger_event = trigger_event_name;
167  state_graph_[transition].from_state = from_state_name;
168  state_graph_[transition].to_state = to_state_name;
169  }
170  return;
171 }
172 
179 {
180  std::lock_guard<std::mutex> lock(mtx_);
181  std::vector<std::string> ret;
183  adjacency_iterator_t vi_end;
184  for (boost::tie(vi, vi_end) = adjacent_vertices(current_state_, state_graph_); vi != vi_end; ++vi)
185  {
186  ret.push_back(state_graph_[*vi].name);
187  }
188  return ret;
189 }
190 
196 std::vector<std::string> StateMachine::getPossibeTransitions()
197 {
198  std::lock_guard<std::mutex> lock(mtx_);
199  std::vector<std::string> ret;
201  out_edge_iterator_t ei_end;
202  for (boost::tie(ei, ei_end) = out_edges(current_state_, state_graph_); ei != ei_end; ++ei)
203  {
204  ret.push_back(state_graph_[*ei].trigger_event);
205  }
206  return ret;
207 }
208 
216 bool StateMachine::tryTransition(std::string trigger_event_name)
217 {
218  std::lock_guard<std::mutex> lock(mtx_);
220  out_edge_iterator_t ei_end;
221  for (boost::tie(ei, ei_end) = out_edges(current_state_, state_graph_); ei != ei_end; ++ei)
222  {
223  if(trigger_event_name == state_graph_[*ei].trigger_event)
224  {
225  auto vertex_range = boost::vertices(state_graph_);
226  for (auto first = vertex_range.first, last = vertex_range.second; first != last; ++first)
227  {
228  vertex_t v = *first;
229  if(state_graph_[v].name == state_graph_[*ei].to_state)
230  {
231  current_state_ = v;
232  return true;
233  }
234  }
235  return false;
236  }
237  }
238  return false;
239 }
240 
247 {
248  std::lock_guard<std::mutex> lock(mtx_);
249  std::string current_state = state_graph_[current_state_].name;
250  std::vector<std::string> possible_transitions;
252  out_edge_iterator_t ei_end;
253  for (boost::tie(ei, ei_end) = out_edges(current_state_, state_graph_); ei != ei_end; ++ei)
254  {
255  possible_transitions.push_back(state_graph_[*ei].trigger_event);
256  }
257  std::vector<std::string> possible_transition_states;
259  adjacency_iterator_t vi_end;
260  for (boost::tie(vi, vi_end) = adjacent_vertices(current_state_, state_graph_); vi != vi_end; ++vi)
261  {
262  possible_transition_states.push_back(state_graph_[*vi].name);
263  }
264  StateInfo ret(current_state, possible_transition_states, possible_transitions);
265  return ret;
266 }
267 
274 {
275  return state_graph_[current_state_].name;
276 }
277 
284 {
285  std::lock_guard<std::mutex> lock(mtx_);
286  std::stringstream sstream;
287  boost::write_graphviz(sstream,state_graph_,node_writer_(state_graph_,getCurrentState()),
289  return sstream.str();
290 }
291 
297 void StateMachine::drawStateMachine(std::string dot_filename)
298 {
299  std::lock_guard<std::mutex> lock(mtx_);
300  std::ofstream f(dot_filename.c_str());
301  boost::write_graphviz(f,state_graph_,node_writer_(state_graph_,getCurrentState()),
303  return;
304 }
bool setCurrentState(std::string current_state)
Function for setting Current State Infomation.
std::vector< std::string > getPossibeTransitions()
Function for getting possible transition trigger event.
f
EdgeWriter< Map > edge_writer_(Map &map)
void addTransition(std::string from_state_name, std::string to_state_name, std::string trigger_event_name)
add Transition function for the State Machine
boost::graph_traits< graph_t >::out_edge_iterator out_edge_iterator_t
Definition: state_machine.h:66
StateInfo getStateInfo()
Function getting current state info.
bool tryTransition(std::string trigger_event_name)
Try transition from trigger event.
std::string name_
vertex_t current_state_
std::string getName()
get name of the state machine
std::string getCurrentState()
Function getting current state name.
graph_t state_graph_
std::mutex mtx_
std::string getDotString()
Function getting dot string which describe state machine in std::string format.
NodeWriter< Map > node_writer_(Map &map, std::string current_state)
GraphWriter graph_writer_
~StateMachine()
Destroy the State Machine:: State Machine object.
Struct for State Infomation.
Definition: state_machine.h:72
State Machine Library using Boost::Graph.
graph_t::vertex_descriptor vertex_t
vertex type for State Machine Class (State)
Definition: state_machine.h:59
std::vector< std::string > getPossibeTransitionStates()
Function for getting possible transition states.
graph_t::edge_descriptor edge_t
edge type for State Machine Class (State Transition)
Definition: state_machine.h:64
void drawStateMachine(std::string dot_filename)
Function saving state machine in .dot format.
StateMachine(std::string xml_string)
Construct a new State Machine:: State Machine object.
boost::graph_traits< graph_t >::adjacency_iterator adjacency_iterator_t
Definition: state_machine.h:65


rostate_machine
Author(s):
autogenerated on Wed Sep 4 2019 05:19:52