human_driver_monitor.h
Go to the documentation of this file.
1 /**************************************************************************************************
2  Software License Agreement (BSD License)
3 
4  Copyright (c) 2011-2013, LAR toolkit developers - University of Aveiro - http://lars.mec.ua.pt
5  All rights reserved.
6 
7  Redistribution and use in source and binary forms, with or without modification, are permitted
8  provided that the following conditions are met:
9 
10  *Redistributions of source code must retain the above copyright notice, this list of
11  conditions and the following disclaimer.
12  *Redistributions in binary form must reproduce the above copyright notice, this list of
13  conditions and the following disclaimer in the documentation and/or other materials provided
14  with the distribution.
15  *Neither the name of the University of Aveiro nor the names of its contributors may be used to
16  endorse or promote products derived from this software without specific prior written permission.
17 
18  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
19  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
21  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
24  IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 ***************************************************************************************************/
27 #ifndef _HUMAN_DRIVER_MONITOR_H_
28 #define _HUMAN_DRIVER_MONITOR_H_
29 
35 #include <ros/ros.h>
36 #include <iostream>
37 
38 #include <human_driver_monitor/HumanDriverMonitorStatus.h>
39 
40 #include <diagnostic_updater/diagnostic_updater.h>
41 #include <diagnostic_updater/publisher.h>
42 #include <boost/thread/thread.hpp>
43 
44 #include <tcp_client/AsyncClient.h>
45 #include <boost/format.hpp>
46 #include <boost/thread/thread.hpp>
47 #include <boost/spirit/include/qi.hpp>
48 #include <boost/spirit/include/phoenix_core.hpp>
49 #include <boost/spirit/include/phoenix_operator.hpp>
50 
51 using namespace std;
52 
53 namespace human_driver_monitor
54 {
55 
63 {
64  public:
83  HumanDriverMonitor(const ros::NodeHandle& nh,std::string ip,std::string port):
84  server_ip_(ip),
85  server_port_(port),
86  nh_(nh),
87  status_freq_("HumanDriverMonitor",updater_,diagnostic_updater::FrequencyStatusParam(&status_max_frequency_,&status_min_frequency_, 0.1, 10)),//The last two parameters correspond to the tolerance and window size
88  status_max_frequency_(50.0),//The frequency values appear in hz
89  status_min_frequency_(70.0),
90  comm_(io_service_,server_ip_,server_port_)
91  {}
92 
97  {}
98 
107  void init()
108  {
109  //Set diagnostics
110  updater_.setHardwareID("human driver monitor");
111  updater_.add("HumanDriverMonitor",this,&human_driver_monitor::HumanDriverMonitor::diagnostics);
112 
113  //Setup the new data handler
114  comm_.readHandler.connect(boost::bind(&HumanDriverMonitor::newData,this,_1));
115 
116  //Setup the on successful connection handler
117  comm_.connectHandler.connect(boost::bind(&HumanDriverMonitor::connectHandler,this));
118  }
119 
128  {
129  status_pub_ = nh_.advertise<human_driver_monitor::HumanDriverMonitorStatus>("status", 1);
130  }
131 
141  void loop()
142  {
143  //Run io service on a different tread
144  boost::thread thread(boost::bind(&boost::asio::io_service::run, &io_service_));
145 
146  ros::Rate r(50);//Hz
147 
148  do
149  {
150  //Update the diagnostics tool
151  updater_.update();
152  //Spin ros and sleep the desired amount
153  ros::spinOnce();
154  r.sleep();
155  }while(ros::ok());
156 
157  //Stop the io service running in a separate thread
158  io_service_.stop();
159  //Join the thread
160  thread.join();
161  }
162 
167  protected:
168 
174  void connectHandler(void)
175  {
176  try
177  {
178  comm_.write("start");
179  }catch(std::exception& e)
180  {
181  std::cout << "Exception: " << e.what() << "\n";
182  }
183  }
184 
191  void newData(string data)
192  {
193  //Erase the first 02 and the last 03 (stx and enx)
194  data.erase(0,1);
195  data.erase(data.end()-2,data.end());
196 
197  //Get info from message
198 
199  if(data[1]=='1')
200  status_.lights_high=1;
201  else
202  status_.lights_high=0;
203 
204  if(data[5]=='1')
205  status_.lights_medium=1;
206  else
207  status_.lights_medium=0;
208 
209  if(data[2]=='1')
210  status_.ignition=1;
211  else
212  status_.ignition=0;
213 
214  if(data[6]=='1')
215  status_.horn=1;
216  else
217  status_.horn=0;
218 
219  if(data[3]=='1')
220  status_.lights_left=1;
221  else
222  status_.lights_left=0;
223 
224  if(data[4]=='1')
225  status_.lights_right=1;
226  else
227  status_.lights_right=0;
228 
229  if(status_.lights_left && status_.lights_right)
230  status_.lights_danger=1;
231  else
232  status_.lights_danger=0;
233 
234  data.erase(0,7);
235 
236  //use boost spirit qi to parse the rest of the message
237  namespace qi = boost::spirit::qi;
238  using qi::omit;
239  using qi::int_;
240  using qi::char_;
241  using qi::ascii::space;
242  using qi::_1;
243  using boost::phoenix::ref;
244 
245  qi::phrase_parse(data.begin(),data.end(),
246  omit[char_] >> int_[ref(status_.throttle_pressure) = _1] >>
247  omit[char_] >> int_[ref(status_.brake_pressure) = _1] >>
248  omit[char_] >> int_[ref(status_.clutch_pressure) = _1]
249  ,space);
250 
251  status_.header.stamp = ros::Time::now();
252  status_.header.frame_id = "";
253  status_pub_.publish(status_);
254  status_freq_.tick();
255  }
256 
263  void diagnostics(diagnostic_updater::DiagnosticStatusWrapper& stat)
264  {
265  if(!comm_.isConnected())
266  {
267  stat.summary(diagnostic_msgs::DiagnosticStatus::ERROR, "No connection to hardware.");
268  stat.add("Status",comm_.error_.message());
269  stat.add("Connecting to",server_ip_);
270  stat.add("Port number",server_port_);
271  }else
272  {
273  stat.summary(diagnostic_msgs::DiagnosticStatus::OK, "No problems.");
274  stat.add("Connected with",server_ip_);
275  stat.add("Port number",server_port_);
276 
277  boost::format fmt("%.2f");
278  fmt % (ros::Time::now()-status_.header.stamp).toSec();
279 
280  stat.add("Last message sent", fmt.str()+" seconds ago" );
281  }
282  }
283 
285  std::string server_ip_;
287  std::string server_port_;
288 
290  ros::NodeHandle nh_;
291 
293  ros::Publisher status_pub_;
294 
296  human_driver_monitor::HumanDriverMonitorStatus status_;
297 
299  diagnostic_updater::Updater updater_;
301  diagnostic_updater::HeaderlessTopicDiagnostic status_freq_;
307  boost::asio::io_service io_service_;
309  AsyncClient comm_;
310 };
311 
312 }
313 
314 #endif
ros::NodeHandle nh_
Ros node handler.
double status_max_frequency_
Maximum admissible frequency.
AsyncClient comm_
Asynchronous tcp/ip communication object.
void diagnostics(diagnostic_updater::DiagnosticStatusWrapper &stat)
Diagnostics function handler.
diagnostic_updater::Updater updater_
Diagnostics class.
void connectHandler(void)
This function will be called (asynchronously) on a successful connection.
HumanDriverMonitor(const ros::NodeHandle &nh, std::string ip, std::string port)
Class constructor.
void newData(string data)
This function will be called (asynchronously) upon arrival of new data.
void loop()
Start main control loop.
boost::asio::io_service io_service_
Input/Output communication service.
human_driver_monitor::HumanDriverMonitorStatus status_
Status message.
std::string server_port_
Port of the Arduino server.
ros::Publisher status_pub_
Ros status publisher.
void setupMessaging()
Start ros message subscribing and advertising.
std::string server_ip_
Ip of the Arduino server.
double status_min_frequency_
Minimum admissible frequency.
diagnostic_updater::HeaderlessTopicDiagnostic status_freq_
Frequency diagnostics tool.


human_driver_monitor
Author(s): Jorge Almeida
autogenerated on Mon Mar 2 2015 01:31:41