Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <diagnostic_msgs/DiagnosticArray.h>
00019
00020 #include "naoqi_dcm_driver/diagnostics.hpp"
00021 #include "naoqi_dcm_driver/tools.hpp"
00022
00023 Diagnostics::Diagnostics(const qi::SessionPtr& session,
00024 ros::Publisher *pub,
00025 const std::vector<std::string> &joints_all_names,
00026 const std::string &robot):
00027 pub_(pub),
00028 joints_all_names_(joints_all_names),
00029 temperature_warn_level_(68.0f),
00030 temperature_error_level_(73.0f)
00031 {
00032
00033 joints_current_.reserve(joints_all_names_.size());
00034 joints_current_.resize(joints_all_names_.size());
00035
00036
00037 status_.name = std::string("naoqi_dcm_driver:Status");
00038 status_.hardware_id = "robot";
00039 status_.level = diagnostic_msgs::DiagnosticStatus::OK;
00040 status_.message = "OK";
00041
00042
00043 try
00044 {
00045 memory_proxy_ = session->service("ALMemory");
00046 }
00047 catch (const std::exception& e)
00048 {
00049 ROS_ERROR("DIAGNOSTICS: Failed to connect to Memory Proxy!\n\tTrace: %s", e.what());
00050 }
00051
00052
00053 keys_tocheck_.push_back("Device/SubDeviceList/Battery/Charge/Sensor/Value");
00054
00055 std::vector<std::string>::const_iterator it = joints_all_names_.begin();
00056 for(; it != joints_all_names_.end(); ++it) {
00057 keys_tocheck_.push_back("Device/SubDeviceList/" + *it + "/Temperature/Sensor/Value");
00058 keys_tocheck_.push_back("Device/SubDeviceList/" + *it + "/Hardness/Actuator/Value");
00059 keys_tocheck_.push_back("Device/SubDeviceList/" + *it + "/ElectricCurrent/Sensor/Value");
00060 }
00061
00062 std::vector<std::string>::const_iterator it_cntrl = joints_all_names_.begin();
00063 for(; it_cntrl != joints_all_names_.end(); ++it_cntrl)
00064 keys_tocheck_.push_back("Device/SubDeviceList/" + *it_cntrl + "/ElectricCurrent/Sensor/Value");
00065
00066
00067 try
00068 {
00069 if ((robot == "pepper") || (robot == "juliette") || (robot == "nao")) {
00070 qi::AnyObject body_temperature_ = session->service("ALBodyTemperature");
00071 body_temperature_.call<void>("setEnableNotifications", true);
00072 }
00073 }
00074 catch (const std::exception& e)
00075 {
00076 ROS_WARN("DIAGNOSTICS: Failed to connect to ALBodyTemperature!\n\tTrace: %s", e.what());
00077 }
00078 }
00079
00080 void Diagnostics::setMessageFromStatus(diagnostic_updater::DiagnosticStatusWrapper &status)
00081 {
00082 if (status.level == diagnostic_msgs::DiagnosticStatus::OK) {
00083 status.message = "OK";
00084 } else if (status.level == diagnostic_msgs::DiagnosticStatus::WARN) {
00085 status.message = "WARN";
00086 } else {
00087 status.message = "ERROR";
00088 }
00089 }
00090
00091 void Diagnostics::setAggregatedMessage(diagnostic_updater::DiagnosticStatusWrapper &status)
00092 {
00093 if(status.level > status_.level) {
00094 status_.level = status.level;
00095 status_.message = status.message;
00096 }
00097 }
00098
00099 bool Diagnostics::publish()
00100 {
00101 diagnostic_msgs::DiagnosticArray msg;
00102 msg.header.stamp = ros::Time::now();
00103
00104
00105 status_.level = diagnostic_msgs::DiagnosticStatus::OK;
00106 status_.message = "OK";
00107
00108
00109 float maxTemperature = 0.0f;
00110 float maxStiffness = 0.0f;
00111 float minStiffness = 1.0f;
00112 float minStiffnessWoHands = 1.0f;
00113 float maxCurrent = 0.0f;
00114 float minCurrent = 10.0f;
00115 std::stringstream hotJointsSS;
00116 diagnostic_msgs::DiagnosticStatus::_level_type max_level = diagnostic_msgs::DiagnosticStatus::OK;
00117
00118 std::vector<float> values;
00119 try
00120 {
00121 qi::AnyValue keys_tocheck_qi = memory_proxy_.call<qi::AnyValue>("getListData", keys_tocheck_);
00122 values = fromAnyValueToFloatVector(keys_tocheck_qi);
00123 }
00124 catch(const std::exception& e)
00125 {
00126 ROS_ERROR("DIAGNOSTICS: Could not get joint data from the robot \n\tTrace: %s", e.what());
00127 return false;
00128 }
00129
00130
00131 size_t val = 0;
00132 float batteryCharge = static_cast<float>(values[val++]);
00133
00134 diagnostic_updater::DiagnosticStatusWrapper status_battery;
00135 status_battery.name = std::string("naoqi_dcm_driver:Battery");
00136 status_battery.hardware_id = "battery";
00137 status_battery.add("BatteryCharge", batteryCharge);
00138
00139
00140 if (batteryCharge > 5.0f)
00141 {
00142 status_battery.level = diagnostic_msgs::DiagnosticStatus::OK;
00143 status_battery.message = "OK";
00144 }
00145 else
00146 {
00147 status_battery.level = diagnostic_msgs::DiagnosticStatus::ERROR;
00148 status_battery.message = "LOW Battery Charge";
00149 }
00150 msg.status.push_back(status_battery);
00151
00152 std::vector<std::string>::iterator it_name = joints_all_names_.begin();
00153 std::vector<float>::iterator it_current = joints_current_.begin();
00154 for(; it_name != joints_all_names_.end(); ++it_name, ++it_current)
00155 {
00156 diagnostic_updater::DiagnosticStatusWrapper status;
00157 status.name = std::string("naoqi_dcm_driver:") + *it_name;
00158
00159 float temperature = static_cast<float>(values[val++]);
00160 float stiffness = static_cast<float>(values[val++]);
00161 *it_current = static_cast<float>(values[val++]);
00162
00163
00164 status.hardware_id = *it_name;
00165 status.add("Temperature", temperature);
00166 status.add("Stiffness", stiffness);
00167 status.add("ElectricCurrent", *it_current);
00168
00169
00170 if (temperature < temperature_warn_level_)
00171 {
00172 status.level = diagnostic_msgs::DiagnosticStatus::OK;
00173 status.message = "OK";
00174 }
00175 else if (temperature < temperature_error_level_)
00176 {
00177 status.level = diagnostic_msgs::DiagnosticStatus::WARN;
00178 status.message = "Hot";
00179 }
00180 else
00181 {
00182 status.level = diagnostic_msgs::DiagnosticStatus::ERROR;
00183 status.message = "HIGH JOINT TEMPERATURE : " + *it_name;
00184 }
00185
00186 msg.status.push_back(status);
00187 setAggregatedMessage(status);
00188
00189
00190 max_level = std::max(max_level, status.level);
00191 maxTemperature = std::max(maxTemperature, temperature);
00192 maxStiffness = std::max(maxStiffness, stiffness);
00193 minStiffness = std::min(minStiffness, stiffness);
00194 if((*it_name).find("Hand") == std::string::npos)
00195 minStiffnessWoHands = std::min(minStiffnessWoHands, stiffness);
00196 maxCurrent = std::max(maxCurrent, *it_current);
00197 minCurrent = std::min(minCurrent, *it_current);
00198 if(status.level >= (int) diagnostic_msgs::DiagnosticStatus::WARN) {
00199 hotJointsSS << std::endl << *it_name << ": " << temperature << "°C";
00200 }
00201 }
00202
00203
00204 diagnostic_updater::DiagnosticStatusWrapper status;
00205 status.name = std::string("naoqi_dcm_driver:Status");
00206 status.hardware_id = "joints";
00207 status.level = max_level;
00208 setMessageFromStatus(status);
00209
00210 status.add("Highest Temperature", maxTemperature);
00211 status.add("Highest Stiffness", maxStiffness);
00212 status.add("Lowest Stiffness", minStiffness);
00213 status.add("Lowest Stiffness without Hands", minStiffnessWoHands);
00214 status.add("Highest Electric Current", maxCurrent);
00215 status.add("Lowest Electric current", minCurrent);
00216 status.add("Hot Joints", hotJointsSS.str());
00217
00218 msg.status.push_back(status);
00219
00220 pub_->publish(msg);
00221
00222 if(status_.level >= (int) diagnostic_msgs::DiagnosticStatus::ERROR)
00223 {
00224 ROS_ERROR_STREAM("DIAGNOSTICS: ERROR DETECTED: " << getStatusMsg());
00225 return false;
00226 }
00227 else
00228 return true;
00229 }
00230
00231 std::string Diagnostics::getStatusMsg()
00232 {
00233 return status_.message;
00234 }