event_client.cpp
Go to the documentation of this file.
1 
13 
14 namespace rostate_machine
15 {
16  EventClient::EventClient(ros::NodeHandle nh,ros::NodeHandle pnh,std::string client_namespace) : client_namespace(client_namespace)
17  {
18  nh_ = nh;
19  pnh_ = pnh;
20  state_buf_ = boost::circular_buffer<rostate_machine::State>(2);
21  nh_.param<std::string>(client_namespace+"/description", description_, "");
22  }
23 
25  {
26  loadXml();
27  trigger_event_pub_ = nh_.advertise<rostate_machine::Event>(client_namespace+"/trigger_event",1);
28  current_state_sub_ = nh_.subscribe(client_namespace+"/current_state",1,&EventClient::stateCallback,this);
29  return;
30  }
31 
33  {
34 
35  }
36 
38  {
40  return duration;
41  }
42 
43  void EventClient::publishEvent(rostate_machine::Event event)
44  {
45  ROS_ASSERT(eventKeyFound(event));
47  }
48 
49  boost::optional<rostate_machine::State> EventClient::getPreviousState()
50  {
51  if(state_buf_.size() == 2)
52  {
53  return state_buf_[0];
54  }
55  else
56  {
57  return boost::none;
58  }
59  }
60 
61  boost::optional<rostate_machine::State> EventClient::getCurrentState()
62  {
63  if(state_buf_.size() == 2)
64  {
65  return state_buf_[1];
66  }
67  else if(state_buf_.size() == 1)
68  {
69  return state_buf_[0];
70  }
71  else
72  {
73  return boost::none;
74  }
75  }
76 
77  void EventClient::stateCallback(const rostate_machine::State::ConstPtr msg)
78  {
79  state_buf_.push_back(*msg);
80  std::vector<std::string> active_tags;
81  if(state_buf_.size() == 1)
82  {
83  state_changed_timestamp_ = msg->header.stamp;
84  for(auto tag_itr = tag_info_.begin(); tag_itr != tag_info_.end(); tag_itr++)
85  {
86  for(auto state_itr = tag_itr->states.begin(); state_itr != tag_itr->states.end(); state_itr++)
87  {
88  if(tag_itr->when == always && *state_itr == state_buf_[0].current_state)
89  {
90  active_tags.push_back(tag_itr->tag);
91  }
92  }
93  }
94  }
95  if(state_buf_.size() == 2)
96  {
97  for(auto tag_itr = tag_info_.begin(); tag_itr != tag_info_.end(); tag_itr++)
98  {
99  for(auto state_itr = tag_itr->states.begin(); state_itr != tag_itr->states.end(); state_itr++)
100  {
101  if(tag_itr->when == always && *state_itr == state_buf_[1].current_state)
102  {
103  active_tags.push_back(tag_itr->tag);
104  }
105  }
106  }
107  if(state_buf_[0].current_state != state_buf_[1].current_state)
108  {
109  state_changed_timestamp_ = msg->header.stamp;
110  for(auto tag_itr = tag_info_.begin(); tag_itr != tag_info_.end(); tag_itr++)
111  {
112  for(auto state_itr = tag_itr->states.begin(); state_itr != tag_itr->states.end(); state_itr++)
113  {
114  if(tag_itr->when == on_entry && *state_itr == state_buf_[1].current_state)
115  {
116  active_tags.push_back(tag_itr->tag);
117  }
118  if(tag_itr->when == on_exit && *state_itr == state_buf_[0].current_state)
119  {
120  active_tags.push_back(tag_itr->tag);
121  }
122  }
123  }
124  }
125  }
126  for(auto tag_itr = active_tags.begin(); tag_itr != active_tags.end(); tag_itr++)
127  {
128  std::vector<std::function<boost::optional<rostate_machine::Event>(void)> > execute_funcs = tagged_functions_[*tag_itr];
129  for(auto func_itr = execute_funcs.begin(); func_itr != execute_funcs.end(); func_itr++)
130  {
131  std::function<boost::optional<rostate_machine::Event>(void)> func = *func_itr;
132  boost::optional<rostate_machine::Event> ret = func();
133  if(ret)
134  {
135  ROS_ASSERT(eventKeyFound(*ret));
137  }
138  }
139  }
140  return;
141  }
142 
144  {
145  using namespace boost::property_tree;
146  ptree pt;
147  std::stringstream ss;
148  ss << description_;
149  xml_parser::read_xml(ss, pt);
150  for (const ptree::value_type& state_itr : pt.get_child("state_machine"))
151  {
152  if(state_itr.first == "callback")
153  {
154  std::string tag = state_itr.second.get<std::string>("<xmlattr>.tag");
155  std::string when = state_itr.second.get<std::string>("<xmlattr>.when");
156  std::vector<std::string> states = split(state_itr.second.get<std::string>("<xmlattr>.states"),',');
157  bool is_matched = false;
158  if(when == "always")
159  {
160  TagInfo info = TagInfo(tag,always,states);
161  tag_info_.push_back(info);
162  is_matched = true;
163  }
164  if(when == "on_entry")
165  {
166  TagInfo info = TagInfo(tag,on_entry,states);
167  tag_info_.push_back(info);
168  is_matched = true;
169  }
170  if(when == "on_exit")
171  {
172  TagInfo info = TagInfo(tag,on_exit,states);
173  tag_info_.push_back(info);
174  is_matched = true;
175  }
176  if(is_matched == false)
177  {
178  ROS_WARN_STREAM("unspoorted when attribute!");
179  }
180  }
181  if(state_itr.first == "transition")
182  {
183  std::string trigger_event_name = state_itr.second.get<std::string>("<xmlattr>.name");
184  available_events_.push_back(trigger_event_name);
185  }
186  }
187  return;
188  }
189 
190  bool EventClient::eventKeyFound(rostate_machine::Event event)
191  {
192  bool found = false;
193  for(auto itr = available_events_.begin(); itr != available_events_.end(); itr++)
194  {
195  if(*itr == event.trigger_event_name)
196  {
197  found = true;
198  }
199  }
200  return found;
201  }
202 
203  void EventClient::registerCallback(std::function<boost::optional<rostate_machine::Event>(void)> func,std::string tag)
204  {
205  tagged_functions_[tag].push_back(func);
206  return;
207  }
208 
209  std::vector<std::string> EventClient::onTransition()
210  {
211  std::vector<std::string> tags;
212  return tags;
213  }
214 
215 
216  std::vector<std::string> EventClient::split(const std::string &s, char delim)
217  {
218  std::vector<std::string> elems;
219  std::stringstream ss(s);
220  std::string item;
221  while (getline(ss, item, delim))
222  {
223  if (!item.empty())
224  {
225  elems.push_back(item);
226  }
227  }
228  return elems;
229  }
230 }
void publishEvent(rostate_machine::Event event)
ros::Subscriber current_state_sub_
Definition: event_client.h:72
void registerCallback(std::function< boost::optional< rostate_machine::Event >(void)> func, std::string tag)
void publish(const boost::shared_ptr< M > &message) const
Event Client for Rostate Machine.
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
void stateCallback(const rostate_machine::State::ConstPtr msg)
boost::optional< rostate_machine::State > getPreviousState()
ros::Publisher trigger_event_pub_
Definition: event_client.h:71
std::vector< std::string > available_events_
Definition: event_client.h:81
boost::optional< rostate_machine::State > getCurrentState()
const std::string client_namespace
Definition: event_client.h:59
constexpr int on_exit
Definition: event_client.h:40
EventClient(ros::NodeHandle nh, ros::NodeHandle pnh, std::string client_namespace)
constexpr int on_entry
Definition: event_client.h:39
constexpr int always
Definition: event_client.h:38
bool param(const std::string &param_name, T &param_val, const T &default_val) const
ros::Duration getCurrentStateDuration()
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
#define ROS_WARN_STREAM(args)
std::vector< TagInfo > tag_info_
Definition: event_client.h:80
static Time now()
std::vector< std::string > onTransition()
boost::circular_buffer< rostate_machine::State > state_buf_
Definition: event_client.h:74
#define ROS_ASSERT(cond)
std::vector< std::string > split(const std::string &s, char delim)
bool eventKeyFound(rostate_machine::Event event)
std::map< std::string, std::vector< std::function< boost::optional< rostate_machine::Event >void)> > > tagged_functions_
Definition: event_client.h:79


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