diagnostic_updater.h
Go to the documentation of this file.
1 #include "sick_scan/sick_scan_base.h" /* Base definitions included in all header files, added by add_sick_scan_base_header.py. Do not edit this line. */
2 /*********************************************************************
3  * Software License Agreement (BSD License)
4  *
5  * Copyright (c) 2008, Willow Garage, Inc.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above
15  * copyright notice, this list of conditions and the following
16  * disclaimer in the documentation and/or other materials provided
17  * with the distribution.
18  * * Neither the name of the Willow Garage nor the names of its
19  * contributors may be used to endorse or promote products derived
20  * from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  *********************************************************************/
35 
36 #ifndef DIAGNOSTICUPDATER_HH
37 #define DIAGNOSTICUPDATER_HH
38 
39 #include <stdexcept>
40 #include <vector>
41 #include <string>
42 
43 #include "ros/node_handle.h"
44 #include "ros/this_node.h"
45 
47 #include "diagnostic_updater/DiagnosticStatusWrapper.h"
48 
49 #include <thread>
50 
51 namespace diagnostic_updater
52 {
53 
54  typedef std::function<void(DiagnosticStatusWrapper&)> TaskFunction;
55  typedef std::function<void(diagnostic_msgs::DiagnosticStatus&)> UnwrappedTaskFunction;
56 
66  class DiagnosticTask
67  {
68  public:
72  DiagnosticTask(const std::string name) : name_(name)
73  {}
74 
78  const std::string &getName()
79  {
80  return name_;
81  }
82 
86  virtual void run(diagnostic_updater::DiagnosticStatusWrapper &stat) = 0;
87 
91  virtual ~DiagnosticTask()
92  {}
93 
94  private:
95  const std::string name_;
96  };
97 
107  template <class T>
108  class GenericFunctionDiagnosticTask : public DiagnosticTask
109  {
110  public:
119  GenericFunctionDiagnosticTask(const std::string &name, std::function<void(T&)> fn) :
120  DiagnosticTask(name), fn_(fn)
121  {}
122 
123  virtual void run(DiagnosticStatusWrapper &stat)
124  {
125  fn_(stat);
126  }
127 
128  private:
129  const std::string name_;
130  const TaskFunction fn_;
131  };
132 
133  typedef GenericFunctionDiagnosticTask<diagnostic_msgs::DiagnosticStatus> UnwrappedFunctionDiagnosticTask;
134  typedef GenericFunctionDiagnosticTask<DiagnosticStatusWrapper> FunctionDiagnosticTask;
135 
147  class CompositeDiagnosticTask : public DiagnosticTask
148  {
149  public:
153  CompositeDiagnosticTask(const std::string name) : DiagnosticTask(name)
154  {}
155 
159  virtual void run(DiagnosticStatusWrapper &stat)
160  {
161  DiagnosticStatusWrapper combined_summary;
162  DiagnosticStatusWrapper original_summary;
163 
164  original_summary.summary(stat);
165 
166  for (std::vector<DiagnosticTask *>::iterator i = tasks_.begin();
167  i != tasks_.end(); i++)
168  {
169  // Put the summary that was passed in.
170  stat.summary(original_summary);
171  // Let the next task add entries and put its summary.
172  (*i)->run(stat);
173  // Merge the new summary into the combined summary.
174  combined_summary.mergeSummary(stat);
175  }
176 
177  // Copy the combined summary into the output.
178  stat.summary(combined_summary);
179  }
180 
187  void addTask(DiagnosticTask *t)
188  {
189  tasks_.push_back(t);
190  }
191 
192  private:
193  std::vector<DiagnosticTask *> tasks_;
194  };
195 
204  class DiagnosticTaskVector
205  {
206  protected:
211  class DiagnosticTaskInternal
212  {
213  public:
214  DiagnosticTaskInternal(const std::string name, TaskFunction f) :
215  name_(name), fn_(f)
216  {}
217 
219  {
220  stat.name = name_;
221  fn_(stat);
222  }
223 
224  const std::string &getName() const
225  {
226  return name_;
227  }
228 
229  private:
230  std::string name_;
232  };
233 
234  std::mutex lock_;
235 
239  const std::vector<DiagnosticTaskInternal> &getTasks()
240  {
241  return tasks_;
242  }
243 
244  public:
257  void add(const std::string &name, TaskFunction f)
258  {
259  DiagnosticTaskInternal int_task(name, f);
260  addInternal(int_task);
261  }
262 
271  void add(DiagnosticTask &task)
272  {
273  TaskFunction f = std::bind(&DiagnosticTask::run, &task, std::placeholders::_1);
274  add(task.getName(), f);
275  }
276 
290  template <class T>
291  void add(const std::string name, T *c, void (T::*f)(diagnostic_updater::DiagnosticStatusWrapper&))
292  {
293  DiagnosticTaskInternal int_task(name, std::bind(f, c, std::placeholders::_1));
294  addInternal(int_task);
295  }
296 
297 
309  bool removeByName(const std::string name)
310  {
311  std::lock_guard<std::mutex> lock(lock_);
312  for (std::vector<DiagnosticTaskInternal>::iterator iter = tasks_.begin();
313  iter != tasks_.end(); iter++)
314  {
315  if (iter->getName() == name)
316  {
317  tasks_.erase(iter);
318  return true;
319  }
320 
322  }
323  return false;
324  }
325 
326  private:
332  virtual void addedTaskCallback(DiagnosticTaskInternal &)
333  {}
334  std::vector<DiagnosticTaskInternal> tasks_;
335 
336  protected:
340  void addInternal(DiagnosticTaskInternal &task)
341  {
342  std::lock_guard<std::mutex> lock(lock_);
343  tasks_.push_back(task);
344  addedTaskCallback(task);
345  }
346  };
347 
363  class Updater : public DiagnosticTaskVector
364  {
365  public:
366  bool verbose_;
367 
374  Updater(ros::NodeHandle h = ros::NodeHandle(), ros::NodeHandle ph = ros::NodeHandle("~"), std::string node_name = ros::this_node::getName()) :
375  private_node_handle_(ph), node_handle_(h), node_name_(node_name), hwid_("none")
376  {
377  setup();
378  }
379 
384  void update()
385  {
386  ros::Time now_time = ros::Time::now();
387  if (now_time < next_time_) {
388  // @todo put this back in after fix of #2157 update_diagnostic_period(); // Will be checked in force_update otherwise.
389  return;
390  }
391 
392  force_update();
393  }
394 
401  void force_update()
402  {
404 
406 
407  if (node_handle_.ok())
408  {
409  bool warn_nohwid = hwid_.empty();
410 
411  std::vector<diagnostic_msgs::DiagnosticStatus> status_vec;
412 
413  std::lock_guard<std::mutex> lock(lock_); // Make sure no adds happen while we are processing here.
414  const std::vector<DiagnosticTaskInternal> &tasks = getTasks();
415  for (std::vector<DiagnosticTaskInternal>::const_iterator iter = tasks.begin();
416  iter != tasks.end(); iter++)
417  {
419 
420  status.name = iter->getName();
421  status.level = 2;
422  status.message = "No message was set";
423  status.hardware_id = hwid_;
424 
425  iter->run(status);
426 
427  status_vec.push_back(status);
428 
429  if (status.level)
430  warn_nohwid = false;
431 
432  if (verbose_ && status.level)
433  ROS_WARN("Non-zero diagnostic status. Name: '%s', status %i: '%s'", status.name.c_str(), status.level, status.message.c_str());
434  }
435 
436  if (warn_nohwid && !warn_nohwid_done_)
437  {
438  ROS_WARN("diagnostic_updater: No HW_ID was set. This is probably a bug. Please report it. For devices that do not have a HW_ID, set this value to 'none'. This warning only occurs once all diagnostics are OK so it is okay to wait until the device is open before calling setHardwareID.");
439  warn_nohwid_done_ = true;
440  }
441 
442  publish(status_vec);
443  }
444  }
445 
450  double getPeriod()
451  {
452  return period_;
453  }
454 
455  // Destructor has trouble because the node is already shut down.
456  /*~Updater()
457  {
458  // Create a new node handle and publisher because the existing one is
459  // probably shut down at this stage.
460 
461  ros::NodeHandle newnh;
462  node_handle_ = newnh;
463  publisher_ = node_handle_.advertise<diagnostic_msgs::DiagnosticArray>("/diagnostics", 1);
464  broadcast(2, "Node shut down");
465  }*/
466 
478  void broadcast(int lvl, const std::string msg)
479  {
480  std::vector<diagnostic_msgs::DiagnosticStatus> status_vec;
481 
482  const std::vector<DiagnosticTaskInternal> &tasks = getTasks();
483  for (std::vector<DiagnosticTaskInternal>::const_iterator iter = tasks.begin();
484  iter != tasks.end(); iter++)
485  {
487 
488  status.name = iter->getName();
489  status.summary(lvl, msg);
490 
491  status_vec.push_back(status);
492  }
493 
494  publish(status_vec);
495  }
496 
497  void setHardwareIDf(const char *format, ...)
498  {
499  va_list va;
500  char buff[1000]; // @todo This could be done more elegantly.
501  va_start(va, format);
502  if (vsnprintf(buff, 1000, format, va) >= 1000)
503  ROS_DEBUG("Really long string in diagnostic_updater::setHardwareIDf.");
504  hwid_ = std::string(buff);
505  va_end(va);
506  }
507 
508  void setHardwareID(const std::string &hwid)
509  {
510  hwid_ = hwid;
511  }
512 
513  private:
519  {
520  double old_period = period_;
521  private_node_handle_.getParamCached("diagnostic_period", period_);
522  next_time_ += ros::Duration(period_ - old_period); // Update next_time_
523  }
524 
529  {
530  std::vector<diagnostic_msgs::DiagnosticStatus> status_vec;
531  status_vec.push_back(stat);
532  publish(status_vec);
533  }
534 
538  void publish(std::vector<diagnostic_msgs::DiagnosticStatus> &status_vec)
539  {
540  for (std::vector<diagnostic_msgs::DiagnosticStatus>::iterator
541  iter = status_vec.begin(); iter != status_vec.end(); iter++)
542  {
543  iter->name =
544  node_name_.substr(1) + std::string(": ") + iter->name;
545  }
547  msg.status = status_vec;
548  msg.header.stamp = ros::Time::now(); // Add timestamp for ROS 0.10
549 #ifndef _MSC_VER
551 #endif
552  }
553 
557  void setup()
558  {
560 
561  period_ = 1.0;
564 
565  verbose_ = false;
566  warn_nohwid_done_ = false;
567  }
568 
573  virtual void addedTaskCallback(DiagnosticTaskInternal &task)
574  {
575  DiagnosticStatusWrapper stat;
576  stat.name = task.getName();
577  stat.summary(0, "Node starting up");
578  publish(stat);
579  }
580 
584 
586 
587  double period_;
588  std::string hwid_;
589  std::string node_name_;
590  bool warn_nohwid_done_;
591  };
592 
593 };
594 
595 #endif
diagnostic_updater::CompositeDiagnosticTask::addTask
void addTask(DiagnosticTask *t)
diagnostic_updater::Updater::addedTaskCallback
virtual void addedTaskCallback(DiagnosticTaskInternal &task)
diagnostic_msgs::DiagnosticArray_
Definition: DiagnosticArray.h:25
diagnostic_updater::DiagnosticTask::name_
const std::string name_
Definition: eloquent/include/diagnostic_updater/diagnostic_updater.hpp:98
diagnostic_updater::CompositeDiagnosticTask::tasks_
std::vector< DiagnosticTask * > tasks_
Definition: eloquent/include/diagnostic_updater/diagnostic_updater.hpp:196
diagnostic_updater::DiagnosticTaskVector::DiagnosticTaskInternal::name_
std::string name_
Definition: eloquent/include/diagnostic_updater/diagnostic_updater.hpp:229
msg
msg
ros::Publisher
diagnostic_updater::DiagnosticTaskVector::lock_
boost::mutex lock_
Definition: foxy/include/diagnostic_updater/diagnostic_updater.hpp:233
diagnostic_updater::Updater::setHardwareIDf
void setHardwareIDf(const char *format,...)
diagnostic_updater::Updater::force_update
void force_update()
diagnostic_updater::DiagnosticTask::DiagnosticTask
DiagnosticTask(const std::string name)
diagnostic_updater::UnwrappedTaskFunction
boost::function< void(diagnostic_msgs::DiagnosticStatus &)> UnwrappedTaskFunction
Definition: foxy/include/diagnostic_updater/diagnostic_updater.hpp:62
diagnostic_updater::Updater::node_handle_
ros::NodeHandle node_handle_
Definition: diagnostic_updater.h:582
diagnostic_updater::DiagnosticTaskVector::DiagnosticTaskInternal::getName
const std::string & getName() const
ROS_WARN
#define ROS_WARN(...)
Definition: sick_scan_logging.h:122
diagnostic_updater::Updater::node_name_
std::string node_name_
Definition: eloquent/include/diagnostic_updater/diagnostic_updater.hpp:612
diagnostic_updater::GenericFunctionDiagnosticTask::fn_
const TaskFunction fn_
Definition: eloquent/include/diagnostic_updater/diagnostic_updater.hpp:133
diagnostic_updater::DiagnosticTask::~DiagnosticTask
virtual ~DiagnosticTask()
ros::Publisher::publish
void publish(const boost::shared_ptr< M > &message) const
diagnostic_updater::Updater::broadcast
void broadcast(int lvl, const std::string msg)
ros::NodeHandle::advertise
Publisher advertise(AdvertiseOptions &ops)
Definition: rossimu.cpp:350
DiagnosticArray.h
diagnostic_updater::Updater::private_node_handle_
ros::NodeHandle private_node_handle_
Definition: diagnostic_updater.h:581
f
f
diagnostic_updater::GenericFunctionDiagnosticTask::GenericFunctionDiagnosticTask
GenericFunctionDiagnosticTask(const std::string &name, boost::function< void(T &)> fn)
std_msgs::Duration
::std_msgs::Duration_< std::allocator< void > > Duration
Definition: Duration.h:48
diagnostic_updater::Updater::verbose_
bool verbose_
Definition: eloquent/include/diagnostic_updater/diagnostic_updater.hpp:356
diagnostic_updater::UnwrappedFunctionDiagnosticTask
GenericFunctionDiagnosticTask< diagnostic_msgs::DiagnosticStatus > UnwrappedFunctionDiagnosticTask
Definition: foxy/include/diagnostic_updater/diagnostic_updater.hpp:137
api.setup.name
name
Definition: python/api/setup.py:12
diagnostic_updater::DiagnosticTask::run
virtual void run(diagnostic_updater::DiagnosticStatusWrapper &stat)=0
diagnostic_updater::Updater::Updater
Updater(ros::NodeHandle h=ros::NodeHandle(), ros::NodeHandle ph=ros::NodeHandle("~"), std::string node_name=ros::this_node::getName())
diagnostic_updater
Author: Blaise Gassend.
diagnostic_updater::Updater::publisher_
ros::Publisher publisher_
Definition: diagnostic_updater.h:583
diagnostic_updater::Updater::period_
double period_
Definition: diagnostic_updater.h:587
diagnostic_updater::Updater::hwid_
std::string hwid_
Definition: eloquent/include/diagnostic_updater/diagnostic_updater.hpp:611
diagnostic_updater::DiagnosticTaskVector::DiagnosticTaskInternal::fn_
TaskFunction fn_
Definition: eloquent/include/diagnostic_updater/diagnostic_updater.hpp:230
diagnostic_updater::TaskFunction
boost::function< void(DiagnosticStatusWrapper &)> TaskFunction
Definition: foxy/include/diagnostic_updater/diagnostic_updater.hpp:60
diagnostic_updater::Updater::setHardwareID
void setHardwareID(const std::string &hwid)
diagnostic_updater::Updater::update_diagnostic_period
void update_diagnostic_period()
diagnostic_updater::Updater::next_time_
ros::Time next_time_
Definition: diagnostic_updater.h:585
diagnostic_updater::DiagnosticTaskVector::addedTaskCallback
virtual void addedTaskCallback(DiagnosticTaskInternal &)
diagnostic_updater::DiagnosticTaskVector::DiagnosticTaskInternal::DiagnosticTaskInternal
DiagnosticTaskInternal(const std::string name, TaskFunction f)
ros::this_node::getName
const ROSCPP_DECL std::string & getName()
Returns the name of the current node.
Definition: rossimu.cpp:343
diagnostic_updater::Updater::update
void update()
ros::NodeHandle::ok
bool ok() const
Definition: rossimu.cpp:338
ros::NodeHandle::getParamCached
bool getParamCached(const std::string &key, bool &b) const
ros::Time
diagnostic_updater::FunctionDiagnosticTask
GenericFunctionDiagnosticTask< DiagnosticStatusWrapper > FunctionDiagnosticTask
Definition: foxy/include/diagnostic_updater/diagnostic_updater.hpp:139
diagnostic_updater::Updater::warn_nohwid_done_
bool warn_nohwid_done_
Definition: eloquent/include/diagnostic_updater/diagnostic_updater.hpp:613
sick_scan_xd_api_test.c
c
Definition: sick_scan_xd_api_test.py:445
diagnostic_updater::DiagnosticTaskVector::DiagnosticTaskInternal::run
void run(diagnostic_updater::DiagnosticStatusWrapper &stat) const
diagnostic_updater::DiagnosticTask::getName
const std::string & getName()
diagnostic_updater::Updater::publish
void publish(diagnostic_msgs::DiagnosticStatus &stat)
diagnostic_updater::GenericFunctionDiagnosticTask::name_
const std::string name_
Definition: eloquent/include/diagnostic_updater/diagnostic_updater.hpp:132
diagnostic_updater::CompositeDiagnosticTask::CompositeDiagnosticTask
CompositeDiagnosticTask(const std::string name)
sick_scan_base.h
diagnostic_updater::DiagnosticStatusWrapper
Wrapper for the diagnostic_msgs::msg::DiagnosticStatus message that makes it easier to update.
Definition: eloquent/include/diagnostic_updater/diagnostic_status_wrapper.hpp:68
ROS_DEBUG
#define ROS_DEBUG(...)
Definition: sick_scan_logging.h:112
diagnostic_updater::DiagnosticTaskVector::removeByName
bool removeByName(const std::string name)
diagnostic_updater::DiagnosticTaskVector::addInternal
void addInternal(DiagnosticTaskInternal &task)
diagnostic_updater::DiagnosticTaskVector::tasks_
std::vector< DiagnosticTaskInternal > tasks_
Definition: eloquent/include/diagnostic_updater/diagnostic_updater.hpp:328
diagnostic_msgs::DiagnosticStatus_::name
_name_type name
Definition: DiagnosticStatus.h:50
diagnostic_updater::GenericFunctionDiagnosticTask::run
virtual void run(DiagnosticStatusWrapper &stat)
diagnostic_updater::CompositeDiagnosticTask::run
virtual void run(DiagnosticStatusWrapper &stat)
diagnostic_updater::DiagnosticTaskVector::getTasks
const std::vector< DiagnosticTaskInternal > & getTasks()
diagnostic_updater::Updater::getPeriod
double getPeriod()
diagnostic_updater::DiagnosticTaskVector::add
void add(const std::string &name, TaskFunction f)
diagnostic_msgs::DiagnosticStatus_
Definition: DiagnosticStatus.h:24
diagnostic_updater::Updater::setup
void setup()
sick_scan_xd_simu.status
def status
Definition: sick_scan_xd_simu.py:139
t
geometry_msgs::TransformStamped t
ros::NodeHandle
ros::Time::now
static Time now()


sick_scan_xd
Author(s): Michael Lehning , Jochen Sprickerhof , Martin Günther
autogenerated on Fri Oct 25 2024 02:47:08