diagnostics.cpp
Go to the documentation of this file.
1 
32 
33 #include <memory>
34 #include <string>
35 #include <utility>
36 
38 {
39 DiagnosticsManager::DiagnosticsManager(const std::string name, const std::string serial,
40  std::shared_ptr<ros::Publisher> const& pub,
41  const ros::NodeHandle& nh)
42  : camera_name_(name), serial_number_(serial), diagnostics_pub_(pub), nh_(nh)
43 {
44 }
45 
47 {
48 }
49 
50 template <typename T>
51 void DiagnosticsManager::addDiagnostic(const Spinnaker::GenICam::gcstring name)
52 {
53  T first = 0;
54  T second = 0;
55  // Call the overloaded function (use the pair to determine which one)
56  addDiagnostic(name, false, std::make_pair(first, second));
57 }
58 
59 template void DiagnosticsManager::addDiagnostic<int>(const Spinnaker::GenICam::gcstring name);
60 
61 template void DiagnosticsManager::addDiagnostic<float>(const Spinnaker::GenICam::gcstring name);
62 
63 void DiagnosticsManager::addDiagnostic(const Spinnaker::GenICam::gcstring name, bool check_ranges,
64  std::pair<int, int> operational, int lower_bound, int upper_bound)
65 {
66  diagnostic_params<int> param{ name, check_ranges, operational, lower_bound, upper_bound };
67  integer_params_.push_back(param);
68 }
69 
70 void DiagnosticsManager::addDiagnostic(const Spinnaker::GenICam::gcstring name, bool check_ranges,
71  std::pair<float, float> operational, float lower_bound, float upper_bound)
72 {
73  diagnostic_params<float> param{ name, check_ranges, operational, lower_bound, upper_bound };
74  float_params_.push_back(param);
75 }
76 
78 {
79  // Get Namespace
80  std::string node_name = ros::this_node::getName().substr(1);
81  std::string node_namespace = ros::this_node::getNamespace();
82  std::string node_prefix = "";
83  std::string node_path;
84  std::string node_id = node_name;
85 
86  // Create "Fake" Namespace for Diagnostics
87  if (node_namespace == "/")
88  {
89  node_namespace = ros::this_node::getName();
90  node_prefix = ros::this_node::getName() + "/";
91  }
92 
93  // Sanitize Node ID
94  size_t pos = node_id.find("/");
95  while (pos != std::string::npos)
96  {
97  node_id.replace(pos, 1, "_");
98  pos = node_id.find("/");
99  }
100 
101  // Sanitize Node Path
102  node_path = node_id;
103  pos = node_path.find("_");
104  while (pos != std::string::npos)
105  {
106  node_path.replace(pos, 1, " ");
107  pos = node_path.find("_");
108  }
109 
110  // GroupAnalyzer Parameters
111  if (!ros::param::has(node_prefix + "analyzers/spinnaker/path"))
112  {
113  ros::param::set(node_prefix + "analyzers/spinnaker/path", "Spinnaker");
114  ros::param::set(node_prefix + "analyzers/spinnaker/type", "diagnostic_aggregator/AnalyzerGroup");
115  }
116 
117  // Analyzer Parameters
118  std::string analyzerPath = node_prefix + "analyzers/spinnaker/analyzers/" + node_id;
119  if (!ros::param::has(analyzerPath + "/path"))
120  {
121  ros::param::set(analyzerPath + "/path", node_path);
122  ros::param::set(analyzerPath + "/type", "diagnostic_aggregator/GenericAnalyzer");
123  ros::param::set(analyzerPath + "/startswith", node_name);
124  ros::param::set(analyzerPath + "/remove_prefix", node_name);
125  }
126 
127  // Bond to Diagnostics Aggregator
128  if (bond_ == nullptr)
129  {
130  bond_ = std::shared_ptr<bond::Bond>(new bond::Bond("/diagnostics_agg/bond" + node_namespace, node_namespace));
131  }
132  else if (!bond_->isBroken())
133  {
134  return;
135  }
136  bond_->setConnectTimeout(120);
137 
138  // Add Diagnostics
139  diagnostic_msgs::AddDiagnostics srv;
140  srv.request.load_namespace = node_namespace;
141  if (!ros::service::waitForService("/diagnostics_agg/add_diagnostics", 1000))
142  {
143  return;
144  }
145  bond_->start();
146  ros::service::call("/diagnostics_agg/add_diagnostics", srv);
147 }
148 
149 template <typename T>
150 diagnostic_msgs::DiagnosticStatus DiagnosticsManager::getDiagStatus(const diagnostic_params<T>& param, const T value)
151 {
152  std::string node_name = ros::this_node::getName().substr(1);
153  diagnostic_msgs::KeyValue kv;
154  kv.key = param.parameter_name;
155  kv.value = std::to_string(value);
156 
157  diagnostic_msgs::DiagnosticStatus diag_status;
158  diag_status.values.push_back(kv);
159  diag_status.name = node_name + ":" + std::string(param.parameter_name.c_str());
160  diag_status.hardware_id = serial_number_;
161 
162  // Determine status level
163  if (!param.check_ranges || (value > param.operational_range.first && value <= param.operational_range.second))
164  {
165  diag_status.level = 0;
166  diag_status.message = "OK: " + std::string(param.parameter_name)
167  + " performing in expected operational range.";
168  }
169  else if (value >= param.warn_range_lower && value <= param.warn_range_upper)
170  {
171  diag_status.level = 1;
172  diag_status.message = "WARNING: " + std::string(param.parameter_name.c_str())
173  + " is not in expected operational range.";
174  }
175  else
176  {
177  diag_status.level = 2;
178  diag_status.message = "ERROR: " + std::string(param.parameter_name.c_str())
179  + " is in critical operation range.";
180  }
181  // Warning Range
182  kv.key = "Warning Range";
183  kv.value = "[" + std::to_string(param.warn_range_lower) + ", "
184  + std::to_string(param.warn_range_upper) + "]";
185  diag_status.values.push_back(kv);
186 
187  // Operational Range
188  kv.key = "Operational Range";
189  kv.value = "[" + std::to_string(param.operational_range.first) + ", "
190  + std::to_string(param.operational_range.second) + "]";
191  diag_status.values.push_back(kv);
192 
193  return diag_status;
194 }
195 
197 {
198  std::string node_name = ros::this_node::getName().substr(1);
199  diagnostic_msgs::DiagnosticArray diag_array;
200 
201  // Manufacturer Info
202  diagnostic_msgs::DiagnosticStatus diag_manufacture_info;
203  diag_manufacture_info.name = node_name + ": Manufacture Info";
204  diag_manufacture_info.hardware_id = serial_number_;
205 
206  for (const std::string param : manufacturer_params_)
207  {
208  // Check if Readable
209  if (!spinnaker->readableProperty(Spinnaker::GenICam::gcstring(param.c_str())))
210  {
211  diagnostic_msgs::KeyValue kv;
212  kv.key = param;
213  kv.value = "Property not Available and Readable";
214  diag_manufacture_info.values.push_back(kv);
215  continue;
216  }
217 
218  // Write if Readable
219  Spinnaker::GenApi::CStringPtr string_ptr = static_cast<Spinnaker::GenApi::CStringPtr>(
220  spinnaker->readProperty(Spinnaker::GenICam::gcstring(param.c_str())));
221 
222  diagnostic_msgs::KeyValue kv;
223  kv.key = param;
224  kv.value = string_ptr->GetValue(true);
225  diag_manufacture_info.values.push_back(kv);
226  }
227 
228  diag_array.status.push_back(diag_manufacture_info);
229 
230  // Float based parameters
232  {
233  // Check if Readable
234  if (!spinnaker->readableProperty(Spinnaker::GenICam::gcstring(param.parameter_name)))
235  {
236  diagnostic_msgs::KeyValue kv;
237  kv.key = param.parameter_name;
238  kv.value = "Property not Available and Readable";
239  diag_manufacture_info.values.push_back(kv);
240  continue;
241  }
242 
243  Spinnaker::GenApi::CFloatPtr float_ptr =
244  static_cast<Spinnaker::GenApi::CFloatPtr>(spinnaker->readProperty(param.parameter_name));
245 
246  float float_value = float_ptr->GetValue(true);
247 
248  diagnostic_msgs::DiagnosticStatus diag_status = getDiagStatus(param, float_value);
249  diag_array.status.push_back(diag_status);
250  }
251 
252  // Int based parameters
254  {
255  // Check if Readable
256  if (!spinnaker->readableProperty(Spinnaker::GenICam::gcstring(param.parameter_name)))
257  {
258  diagnostic_msgs::KeyValue kv;
259  kv.key = param.parameter_name;
260  kv.value = "Property not Available and Readable";
261  diag_manufacture_info.values.push_back(kv);
262  continue;
263  }
264 
265  Spinnaker::GenApi::CIntegerPtr integer_ptr =
266  static_cast<Spinnaker::GenApi::CIntegerPtr>(spinnaker->readProperty(param.parameter_name));
267 
268  int int_value = integer_ptr->GetValue(true);
269  diagnostic_msgs::DiagnosticStatus diag_status = getDiagStatus(param, int_value);
270  diag_array.status.push_back(diag_status);
271  }
272 
273  diagnostics_pub_->publish(diag_array);
274 }
275 } // namespace spinnaker_camera_driver
spinnaker_camera_driver::DiagnosticsManager::diagnostics_pub_
std::shared_ptr< ros::Publisher > diagnostics_pub_
Definition: diagnostics.h:136
spinnaker_camera_driver::DiagnosticsManager::diagnostic_params
Definition: diagnostics.h:111
ros::this_node::getNamespace
const ROSCPP_DECL std::string & getNamespace()
ros::service::call
bool call(const std::string &service_name, MReq &req, MRes &res)
spinnaker_camera_driver::DiagnosticsManager::processDiagnostics
void processDiagnostics(SpinnakerCamera *spinnaker)
Read the property of given parameters and push to aggregator.
Definition: diagnostics.cpp:196
spinnaker_camera_driver::SpinnakerCamera
Definition: SpinnakerCamera.h:69
spinnaker_camera_driver::DiagnosticsManager::float_params_
std::vector< diagnostic_params< float > > float_params_
Definition: diagnostics.h:142
spinnaker_camera_driver::DiagnosticsManager::DiagnosticsManager
DiagnosticsManager(const std::string name, const std::string serial, std::shared_ptr< ros::Publisher > const &pub, const ros::NodeHandle &nh)
Definition: diagnostics.cpp:39
spinnaker_camera_driver::SpinnakerCamera::readableProperty
bool readableProperty(const Spinnaker::GenICam::gcstring property_name)
Definition: SpinnakerCamera.cpp:121
spinnaker_camera_driver::DiagnosticsManager::manufacturer_params_
const std::vector< std::string > manufacturer_params_
Definition: diagnostics.h:147
spinnaker_camera_driver::DiagnosticsManager::~DiagnosticsManager
~DiagnosticsManager()
Definition: diagnostics.cpp:46
spinnaker_camera_driver
Definition: camera.h:45
bond::Bond
spinnaker_camera_driver::DiagnosticsManager::getDiagStatus
diagnostic_msgs::DiagnosticStatus getDiagStatus(const diagnostic_params< T > &param, const T value)
Function to push the diagnostic to the publisher.
Definition: diagnostics.cpp:150
spinnaker_camera_driver::DiagnosticsManager::bond_
std::shared_ptr< bond::Bond > bond_
Definition: diagnostics.h:138
diagnostics.h
Class to support ROS Diagnostics Aggregator for Spinnaker Camera.
spinnaker_camera_driver::DiagnosticsManager::addAnalyzers
void addAnalyzers()
Definition: diagnostics.cpp:77
ros::param::set
ROSCPP_DECL void set(const std::string &key, bool b)
ros::this_node::getName
const ROSCPP_DECL std::string & getName()
spinnaker_camera_driver::DiagnosticsManager::integer_params_
std::vector< diagnostic_params< int > > integer_params_
Definition: diagnostics.h:141
spinnaker_camera_driver::DiagnosticsManager::serial_number_
std::string serial_number_
Definition: diagnostics.h:135
ros::service::waitForService
ROSCPP_DECL bool waitForService(const std::string &service_name, int32_t timeout)
param
T param(const std::string &param_name, const T &default_val)
ros::param::has
ROSCPP_DECL bool has(const std::string &key)
ros::NodeHandle
spinnaker_camera_driver::SpinnakerCamera::readProperty
Spinnaker::GenApi::CNodePtr readProperty(const Spinnaker::GenICam::gcstring property_name)
Definition: SpinnakerCamera.cpp:133
spinnaker_camera_driver::DiagnosticsManager::addDiagnostic
void addDiagnostic(const Spinnaker::GenICam::gcstring name)
Add a diagnostic with name only (no warning checks)
Definition: diagnostics.cpp:51


spinnaker_camera_driver
Author(s): Chad Rockey
autogenerated on Mon Sep 25 2023 02:56:14