ridgeback_diagnostic_updater.cpp
Go to the documentation of this file.
00001 
00034 #include <string>
00035 #include <sys/types.h>
00036 #include <ifaddrs.h>
00037 #include <unistd.h>
00038 
00039 #include "boost/algorithm/string/predicate.hpp"
00040 #include "diagnostic_updater/update_functions.h"
00041 #include "ridgeback_base/ridgeback_diagnostic_updater.h"
00042 
00043 namespace ridgeback_base
00044 {
00045 
00046 RidgebackDiagnosticUpdater::RidgebackDiagnosticUpdater()
00047 {
00048   setHardwareID("unknown");
00049   gethostname(hostname_, 1024);
00050 
00051   add("General", this, &RidgebackDiagnosticUpdater::generalDiagnostics);
00052   add("Battery", this, &RidgebackDiagnosticUpdater::batteryDiagnostics);
00053   add("User voltage supplies", this, &RidgebackDiagnosticUpdater::voltageDiagnostics);
00054   add("Current consumption", this, &RidgebackDiagnosticUpdater::currentDiagnostics);
00055   add("Power consumption", this, &RidgebackDiagnosticUpdater::powerDiagnostics);
00056   add("Temperature", this, &RidgebackDiagnosticUpdater::temperatureDiagnostics);
00057 
00058   // The arrival of this message runs the update() method and triggers the above callbacks.
00059   status_sub_ = nh_.subscribe("mcu/status", 5, &RidgebackDiagnosticUpdater::statusCallback, this);
00060 
00061   // These message frequencies are reported on separately.
00062   ros::param::param("~expected_imu_frequency", expected_imu_frequency_, 50.0);
00063   imu_diagnostic_ = new diagnostic_updater::TopicDiagnostic("/imu/data_raw", *this,
00064       diagnostic_updater::FrequencyStatusParam(&expected_imu_frequency_, &expected_imu_frequency_, 0.15),
00065       diagnostic_updater::TimeStampStatusParam(-1, 1.0));
00066   imu_sub_ = nh_.subscribe("/imu/data_raw", 5, &RidgebackDiagnosticUpdater::imuCallback, this);
00067 
00068   // Publish whether the wireless interface has an IP address every second.
00069   ros::param::param<std::string>("~wireless_interface", wireless_interface_, "wlan0");
00070   ROS_INFO_STREAM("Checking for wireless connectivity on interface: " << wireless_interface_);
00071   wifi_connected_pub_ = nh_.advertise<std_msgs::Bool>("wifi_connected", 1);
00072   wireless_monitor_timer_ =
00073     nh_.createTimer(ros::Duration(1.0), &RidgebackDiagnosticUpdater::wirelessMonitorCallback, this);
00074 }
00075 
00076 void RidgebackDiagnosticUpdater::generalDiagnostics(diagnostic_updater::DiagnosticStatusWrapper &stat)
00077 {
00078   stat.addf("MCU uptime", "%d seconds", last_status_->mcu_uptime.toSec());
00079   stat.add("External stop status", last_status_->external_stop_present ? "present" : "absent");
00080   stat.add("Run/stop status", last_status_->external_stop_present ? "running" : "stopped");
00081 
00082   if (!last_status_->drivers_active)
00083   {
00084     stat.summary(diagnostic_msgs::DiagnosticStatus::ERROR, "Stop loop open, platform immobilized.");
00085   }
00086   else
00087   {
00088     stat.summary(diagnostic_msgs::DiagnosticStatus::OK, "System OK.");
00089   }
00090 }
00091 
00092 void RidgebackDiagnosticUpdater::batteryDiagnostics(diagnostic_updater::DiagnosticStatusWrapper &stat)
00093 {
00094   stat.add("Battery Voltage (V)", last_status_->measured_battery);
00095 
00096   if (last_status_->measured_battery > 30.0)
00097   {
00098     stat.summary(diagnostic_msgs::DiagnosticStatus::ERROR, "Battery overvoltage.");
00099   }
00100   else if (last_status_->measured_battery < 1.0)
00101   {
00102     stat.summary(diagnostic_msgs::DiagnosticStatus::ERROR, "Battery voltage not detected, check BATT fuse.");
00103   }
00104   else if (last_status_->measured_battery < 20.0)
00105   {
00106     stat.summary(diagnostic_msgs::DiagnosticStatus::ERROR, "Battery critically under voltage.");
00107   }
00108   else if (last_status_->measured_battery < 24.0)
00109   {
00110     stat.summary(diagnostic_msgs::DiagnosticStatus::WARN, "Battery low voltage.");
00111   }
00112   else
00113   {
00114     stat.summary(diagnostic_msgs::DiagnosticStatus::OK, "Battery OK.");
00115   }
00116 }
00117 
00118 void RidgebackDiagnosticUpdater::voltageDiagnostics(diagnostic_updater::DiagnosticStatusWrapper &stat)
00119 {
00120   stat.add("12V Supply (V)", last_status_->measured_12v);
00121   stat.add("5V Supply (V)", last_status_->measured_5v);
00122 
00123   if (last_status_->measured_12v > 12.5 || last_status_->measured_5v > 5.5)
00124   {
00125     stat.summary(diagnostic_msgs::DiagnosticStatus::ERROR,
00126         "User supply overvoltage. Accessories may be damaged.");
00127   }
00128   else if (last_status_->measured_12v < 1.0 || last_status_->measured_5v < 1.0)
00129   {
00130     stat.summary(diagnostic_msgs::DiagnosticStatus::ERROR, "User supplies absent. Check tray fuses.");
00131   }
00132   else if (last_status_->measured_12v < 11.0 || last_status_->measured_5v < 4.0)
00133   {
00134     stat.summary(diagnostic_msgs::DiagnosticStatus::WARN, "Voltage supplies undervoltage. Check loading levels.");
00135   }
00136   else
00137   {
00138     stat.summary(diagnostic_msgs::DiagnosticStatus::OK, "User supplies OK.");
00139   }
00140 }
00141 
00142 void RidgebackDiagnosticUpdater::currentDiagnostics(diagnostic_updater::DiagnosticStatusWrapper &stat)
00143 {
00144   stat.add("Total current (A)", last_status_->total_current);
00145 
00146   if (last_status_->total_current > 32.0)
00147   {
00148     stat.summary(diagnostic_msgs::DiagnosticStatus::ERROR, "Current draw critical.");
00149   }
00150   else if (last_status_->total_current > 20.0)
00151   {
00152     stat.summary(diagnostic_msgs::DiagnosticStatus::WARN, "Current draw warning.");
00153   }
00154   else if (last_status_->total_current > 10.0)
00155   {
00156     stat.summary(diagnostic_msgs::DiagnosticStatus::OK, "Current draw requires monitoring.");
00157   }
00158   else
00159   {
00160     stat.summary(diagnostic_msgs::DiagnosticStatus::OK, "Current draw nominal.");
00161   }
00162 }
00163 
00164 void RidgebackDiagnosticUpdater::powerDiagnostics(diagnostic_updater::DiagnosticStatusWrapper &stat)
00165 {
00166   stat.add("Total power consumption (Wh)", last_status_->total_power_consumed);
00167   stat.add("AC power connnected", last_status_->charger_connected);
00168 
00169   if (last_status_->total_power_consumed > 260.0)
00170   {
00171     stat.summary(diagnostic_msgs::DiagnosticStatus::WARN, "Power consumed exceeds capacity of standard battery.");
00172   }
00173   else if (last_status_->total_power_consumed > 220.0)
00174   {
00175     stat.summary(diagnostic_msgs::DiagnosticStatus::WARN, "Power consumed approaches capacity of standard battery.");
00176   }
00177   else
00178   {
00179     stat.summary(diagnostic_msgs::DiagnosticStatus::OK, "Battery OK.");
00180   }
00181 }
00182 
00183 void RidgebackDiagnosticUpdater::temperatureDiagnostics(diagnostic_updater::DiagnosticStatusWrapper &stat)
00184 {
00185   stat.add("PCB temperature (C)", last_status_->pcb_temperature);
00186   stat.add("MCU temperature (C)", last_status_->mcu_temperature);
00187 
00188   if (last_status_->pcb_temperature > 100.0)
00189   {
00190     stat.summary(diagnostic_msgs::DiagnosticStatus::ERROR, "PCB temperature too HOT.");
00191   }
00192   else if (last_status_->pcb_temperature > 60.0)
00193   {
00194     stat.summary(diagnostic_msgs::DiagnosticStatus::WARN, "PCB temperature getting warm.");
00195   }
00196   else
00197   {
00198     stat.summary(diagnostic_msgs::DiagnosticStatus::OK, "PCB temperature OK.");
00199   }
00200 
00201   if (last_status_->mcu_temperature > 100.0)
00202   {
00203     stat.summary(diagnostic_msgs::DiagnosticStatus::ERROR, "MCU temperature too HOT.");
00204   }
00205   else if (last_status_->mcu_temperature > 60.0)
00206   {
00207     stat.summary(diagnostic_msgs::DiagnosticStatus::WARN, "MCU temperature getting warm.");
00208   }
00209   else
00210   {
00211     stat.summary(diagnostic_msgs::DiagnosticStatus::OK, "MCU temperature OK.");
00212   }
00213 }
00214 
00215 void RidgebackDiagnosticUpdater::statusCallback(const ridgeback_msgs::Status::ConstPtr& status)
00216 {
00217   // Fresh data from the MCU, publish a diagnostic update.
00218   last_status_ = status;
00219   setHardwareID(hostname_ + '-' + last_status_->hardware_id);
00220   update();
00221 }
00222 
00223 void RidgebackDiagnosticUpdater::imuCallback(const sensor_msgs::Imu::ConstPtr& msg)
00224 {
00225   imu_diagnostic_->tick(msg->header.stamp);
00226 }
00227 
00228 void RidgebackDiagnosticUpdater::wirelessMonitorCallback(const ros::TimerEvent& te)
00229 {
00230   std_msgs::Bool wifi_connected_msg;
00231   wifi_connected_msg.data = false;
00232 
00233   // Get system structure of interface IP addresses.
00234   struct ifaddrs* ifa_head;
00235   if (getifaddrs(&ifa_head) != 0)
00236   {
00237     ROS_WARN("System call getifaddrs returned error code. Unable to detect network interfaces.");
00238     return;
00239   }
00240 
00241   // Iterate structure looking for the wireless interface.
00242   struct ifaddrs* ifa_current = ifa_head;
00243   while (ifa_current != NULL)
00244   {
00245     if (strcmp(ifa_current->ifa_name, wireless_interface_.c_str()) == 0)
00246     {
00247       int family = ifa_current->ifa_addr->sa_family;
00248       if (family == AF_INET || family == AF_INET6)
00249       {
00250         wifi_connected_msg.data = true;
00251         break;
00252       }
00253     }
00254 
00255     ifa_current = ifa_current->ifa_next;
00256   }
00257 
00258   // Free structure, publish result message.
00259   freeifaddrs(ifa_head);
00260   wifi_connected_pub_.publish(wifi_connected_msg);
00261 }
00262 
00263 }  // namespace ridgeback_base


ridgeback_base
Author(s): Mike Purvis , Tony Baltovski
autogenerated on Sun Mar 24 2019 03:01:13