diagnostics.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2016 SoftBank Robotics Europe
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16 */
17 
18 #include <diagnostic_msgs/DiagnosticArray.h>
19 
22 
23 Diagnostics::Diagnostics(const qi::SessionPtr& session,
24  ros::Publisher *pub,
25  const std::vector<std::string> &joints_all_names,
26  const std::string &robot):
27  pub_(pub),
28  joints_all_names_(joints_all_names),
29  temperature_warn_level_(68.0f),
30  temperature_error_level_(73.0f)
31 {
32  //resize the joint current vector
33  joints_current_.reserve(joints_all_names_.size());
34  joints_current_.resize(joints_all_names_.size());
35 
36  //set the default status
37  status_.name = std::string("naoqi_dcm_driver:Status");
38  status_.hardware_id = "robot";
39  status_.level = diagnostic_msgs::DiagnosticStatus::OK;
40  status_.message = "OK";
41 
42  //connect to Memmory proxy
43  try
44  {
45  memory_proxy_ = session->service("ALMemory");
46  }
47  catch (const std::exception& e)
48  {
49  ROS_ERROR("DIAGNOSTICS: Failed to connect to Memory Proxy!\n\tTrace: %s", e.what());
50  }
51 
52  //set the keys to check
53  keys_tocheck_.push_back("Device/SubDeviceList/Battery/Charge/Sensor/Value");
54 
55  std::vector<std::string>::const_iterator it = joints_all_names_.begin();
56  for(; it != joints_all_names_.end(); ++it) {
57  keys_tocheck_.push_back("Device/SubDeviceList/" + *it + "/Temperature/Sensor/Value");
58  keys_tocheck_.push_back("Device/SubDeviceList/" + *it + "/Hardness/Actuator/Value");
59  keys_tocheck_.push_back("Device/SubDeviceList/" + *it + "/ElectricCurrent/Sensor/Value");
60  }
61 
62  std::vector<std::string>::const_iterator it_cntrl = joints_all_names_.begin();
63  for(; it_cntrl != joints_all_names_.end(); ++it_cntrl)
64  keys_tocheck_.push_back("Device/SubDeviceList/" + *it_cntrl + "/ElectricCurrent/Sensor/Value");
65 
66  //allow the temperature reporting (for CPU)
67  try
68  {
69  if ((robot == "pepper") || (robot == "juliette") || (robot == "nao")) {
70  qi::AnyObject body_temperature_ = session->service("ALBodyTemperature");
71  body_temperature_.call<void>("setEnableNotifications", true);
72  }
73  }
74  catch (const std::exception& e)
75  {
76  ROS_WARN("DIAGNOSTICS: Failed to connect to ALBodyTemperature!\n\tTrace: %s", e.what());
77  }
78 }
79 
81 {
82  if (status.level == diagnostic_msgs::DiagnosticStatus::OK) {
83  status.message = "OK";
84  } else if (status.level == diagnostic_msgs::DiagnosticStatus::WARN) {
85  status.message = "WARN";
86  } else {
87  status.message = "ERROR";
88  }
89  }
90 
92 {
93  if(status.level > status_.level) {
94  status_.level = status.level;
95  status_.message = status.message;
96  }
97 }
98 
100 {
101  diagnostic_msgs::DiagnosticArray msg;
102  msg.header.stamp = ros::Time::now();
103 
104  //set the default status
105  status_.level = diagnostic_msgs::DiagnosticStatus::OK;
106  status_.message = "OK";
107 
108  // Fill the temperature / stiffness message for the joints
109  float maxTemperature = 0.0f;
110  float maxStiffness = 0.0f;
111  float minStiffness = 1.0f;
112  float minStiffnessWoHands = 1.0f;
113  float maxCurrent = 0.0f;
114  float minCurrent = 10.0f;
115  std::stringstream hotJointsSS;
116  diagnostic_msgs::DiagnosticStatus::_level_type max_level = diagnostic_msgs::DiagnosticStatus::OK;
117 
118  std::vector<float> values;
119  try
120  {
121  qi::AnyValue keys_tocheck_qi = memory_proxy_.call<qi::AnyValue>("getListData", keys_tocheck_);
122  values = fromAnyValueToFloatVector(keys_tocheck_qi);
123  }
124  catch(const std::exception& e)
125  {
126  ROS_ERROR("DIAGNOSTICS: Could not get joint data from the robot \n\tTrace: %s", e.what());
127  return false;
128  }
129 
130  //check the battery charge level
131  size_t val = 0;
132  float batteryCharge = static_cast<float>(values[val++]);
133 
135  status_battery.name = std::string("naoqi_dcm_driver:Battery");
136  status_battery.hardware_id = "battery";
137  status_battery.add("BatteryCharge", batteryCharge);
138 
139  //TODO check if it is charging
140  if (batteryCharge > 5.0f)
141  {
142  status_battery.level = diagnostic_msgs::DiagnosticStatus::OK;
143  status_battery.message = "OK";
144  }
145  else
146  {
147  status_battery.level = diagnostic_msgs::DiagnosticStatus::ERROR;
148  status_battery.message = "LOW Battery Charge";
149  }
150  msg.status.push_back(status_battery);
151 
152  std::vector<std::string>::iterator it_name = joints_all_names_.begin();
153  std::vector<float>::iterator it_current = joints_current_.begin();
154  for(; it_name != joints_all_names_.end(); ++it_name, ++it_current)
155  {
157  status.name = std::string("naoqi_dcm_driver:") + *it_name;
158 
159  float temperature = static_cast<float>(values[val++]);
160  float stiffness = static_cast<float>(values[val++]);
161  *it_current = static_cast<float>(values[val++]);
162 
163  // Fill the status data
164  status.hardware_id = *it_name;
165  status.add("Temperature", temperature);
166  status.add("Stiffness", stiffness);
167  status.add("ElectricCurrent", *it_current);
168 
169  // Define the level
170  if (temperature < temperature_warn_level_)
171  {
172  status.level = diagnostic_msgs::DiagnosticStatus::OK;
173  status.message = "OK";
174  }
175  else if (temperature < temperature_error_level_)
176  {
177  status.level = diagnostic_msgs::DiagnosticStatus::WARN;
178  status.message = "Hot";
179  }
180  else
181  {
182  status.level = diagnostic_msgs::DiagnosticStatus::ERROR;
183  status.message = "HIGH JOINT TEMPERATURE : " + *it_name;
184  }
185 
186  msg.status.push_back(status);
187  setAggregatedMessage(status);
188 
189  // Fill the joint data for later processing
190  max_level = std::max(max_level, status.level);
191  maxTemperature = std::max(maxTemperature, temperature);
192  maxStiffness = std::max(maxStiffness, stiffness);
193  minStiffness = std::min(minStiffness, stiffness);
194  if((*it_name).find("Hand") == std::string::npos)
195  minStiffnessWoHands = std::min(minStiffnessWoHands, stiffness);
196  maxCurrent = std::max(maxCurrent, *it_current);
197  minCurrent = std::min(minCurrent, *it_current);
198  if(status.level >= (int) diagnostic_msgs::DiagnosticStatus::WARN) {
199  hotJointsSS << std::endl << *it_name << ": " << temperature << "°C";
200  }
201  }
202 
203  // Get the aggregated joints status
205  status.name = std::string("naoqi_dcm_driver:Status");
206  status.hardware_id = "joints";
207  status.level = max_level;
208  setMessageFromStatus(status);
209 
210  status.add("Highest Temperature", maxTemperature);
211  status.add("Highest Stiffness", maxStiffness);
212  status.add("Lowest Stiffness", minStiffness);
213  status.add("Lowest Stiffness without Hands", minStiffnessWoHands);
214  status.add("Highest Electric Current", maxCurrent);
215  status.add("Lowest Electric current", minCurrent);
216  status.add("Hot Joints", hotJointsSS.str());
217 
218  msg.status.push_back(status);
219 
220  pub_->publish(msg);
221 
222  if(status_.level >= (int) diagnostic_msgs::DiagnosticStatus::ERROR)
223  {
224  ROS_ERROR_STREAM("DIAGNOSTICS: ERROR DETECTED: " << getStatusMsg());
225  return false;
226  }
227  else
228  return true;
229 }
230 
232 {
233  return status_.message;
234 }
msg
Diagnostics(const qi::SessionPtr &session, ros::Publisher *pub, const std::vector< std::string > &joints_all_names, const std::string &robot)
Constructor.
Definition: diagnostics.cpp:23
void setMessageFromStatus(diagnostic_updater::DiagnosticStatusWrapper &status)
set the message based on level
Definition: diagnostics.cpp:80
void publish(const boost::shared_ptr< M > &message) const
void setAggregatedMessage(diagnostic_updater::DiagnosticStatusWrapper &status)
set the aggregated message
Definition: diagnostics.cpp:91
f
std::vector< double > values
std::vector< std::string > joints_all_names_
Definition: diagnostics.hpp:68
std::string getStatusMsg()
return the status message
#define ROS_WARN(...)
qi::AnyObject memory_proxy_
Definition: diagnostics.hpp:65
std::vector< float > joints_current_
Definition: diagnostics.hpp:71
std::vector< std::string > keys_tocheck_
Definition: diagnostics.hpp:75
bool publish()
publish the newly received data
Definition: diagnostics.cpp:99
float temperature_error_level_
Definition: diagnostics.hpp:81
diagnostic_updater::DiagnosticStatusWrapper status_
Definition: diagnostics.hpp:84
ros::Publisher * pub_
Definition: diagnostics.hpp:62
static Time now()
std::vector< float > fromAnyValueToFloatVector(qi::AnyValue &value)
Definition: tools.cpp:70
void add(const std::string &key, const T &val)
#define ROS_ERROR_STREAM(args)
float temperature_warn_level_
Definition: diagnostics.hpp:78
#define ROS_ERROR(...)


naoqi_dcm_driver
Author(s): Konstantinos Chatzilygeroudis , Mikael Arguedas , Karsten Knese , Natalia Lyubova
autogenerated on Thu Jul 25 2019 03:49:27