Go to the documentation of this file.00001 #include "ros/ros.h"
00002 #include "ros/time.h"
00003 #include <vector>
00004 #include "std_msgs/Header.h"
00005 #include "std_msgs/Float32.h"
00006 #include "diagnostic_msgs/DiagnosticStatus.h"
00007 #include "diagnostic_msgs/DiagnosticArray.h"
00008 #include "diagnostic_msgs/KeyValue.h"
00009 #include "smart_battery_msgs/SmartBatteryStatus.h"
00010 #include <stdio.h>
00011 #include <stdlib.h>
00012 #include <unistd.h>
00013 #include <boost/thread.hpp>
00014 #include <boost/lexical_cast.hpp>
00015
00016 float voltage;
00017 bool sentMail = false;
00018 void voltageCallback(const smart_battery_msgs::SmartBatteryStatus::ConstPtr& msg){
00019 voltage = (msg->voltage);
00020
00021 }
00022
00023 int sendMail(std::string outboundList, std::string sender){
00024 char msg[] = "Hello,\nJust so you know, there is a robot whose battery is low. Please seek this robot and bring it to the lab for charging.\nBest,\nBuilding Wide Intelligence\n\nPS: Please don't email me!";
00025 int retval = -1;
00026 FILE *mailpipe = popen("/usr/lib/sendmail -t", "w");
00027 if(mailpipe != NULL){
00028 std::string to = "To: " + outboundList + "\n";
00029 std::string from = "From: " + sender + "\n";
00030 fputs(to.c_str(), mailpipe);
00031 fputs(from.c_str(), mailpipe);
00032 fputs("Subject: Segbot Low Battery Alert\n", mailpipe);
00033 fwrite(msg, 1, strlen(msg), mailpipe);
00034 fwrite(".\n", 1, 2, mailpipe);
00035 pclose(mailpipe);
00036 retval = 0;
00037 }else {
00038 perror("Failed to invoke sendmail");
00039 }
00040 return retval;
00041 }
00042
00043 int main(int argc, char **argv){
00044 ros::init(argc, argv, "battery_estimator");
00045 ros::NodeHandle n;
00046 ros::Publisher battery_life_pub = n.advertise<diagnostic_msgs::DiagnosticArray>("diagnostics", 10);
00047 ros::Subscriber voltage_sub = n.subscribe("/battery0", 10, voltageCallback);
00048 ros::Rate loop_rate(1);
00049 diagnostic_msgs::DiagnosticStatus voltages;
00050 diagnostic_msgs::DiagnosticStatus status;
00051 diagnostic_msgs::DiagnosticArray diagAr;
00052 diagnostic_msgs::KeyValue status_val;
00053 diagnostic_msgs::KeyValue voltages_val;
00054 voltages.hardware_id = "005";
00055 voltages.name = "voltage";
00056 voltages_val.value = voltage;
00057 voltages_val.key = "Current voltage: ";
00058 status.hardware_id = "005";
00059 status.name = "battery_estimator";
00060 status_val.key = "battery_value";
00061 status_val.value = "183.0";
00062 std::ostringstream ss;
00063
00064 while (ros::ok()){
00065 voltages_val.value = boost::lexical_cast<std::string>(voltage);
00066 diagAr.header.stamp = ros::Time::now();
00067 diagAr.header.frame_id = 1;
00068
00069 if(voltage > 11.0){
00070 status.message = "Battery in good health";
00071 status.level = 0;
00072 voltages.level = 0;
00073 voltages.message = "Voltage level OK";
00074 }else if(voltage > 10 && voltage < 11){
00075 status.message = "Battery low, return to lab.";
00076 status.level = 1;
00077 voltages.level = 1;
00078 voltages.message = "Voltage dropping";
00079 if(!sentMail){
00080
00081 bool paramSuccess;
00082 std::string outbound;
00083 paramSuccess = n.getParam("email_alert_outbound", outbound);
00084 std::string send;
00085 paramSuccess &= n.getParam("email_alert_sender", send);
00086 if(!paramSuccess){
00087 std::cout << "Error reading send mail parameters. Check launchfile. Emails not sent." << std::endl;
00088 }else{
00089 boost::thread mailThread(sendMail, outbound, send);
00090 }
00091 }
00092 sentMail = true;
00093 }else if(!voltage){
00094 voltages.message = "No voltage data";
00095 voltages.level = 2;
00096 status.message = "Cannot extrapolate battery charge. No voltage data.";
00097 status.level = 2;
00098 }else{
00099 status.message = "Battery CRITICALLY low, or voltmeter data is inaccurate (or missing). Ensure the volt sensor is connected properly and its publisher relaying data.";
00100 status.level = 2;
00101 voltages.level = 2;
00102 voltages.message = "ERROR: Ensure accurate volt readings!";
00103 }
00104
00105 status.values.clear();
00106 status.values.push_back(status_val);
00107 voltages.values.clear();
00108 voltages.values.push_back(voltages_val);
00109 diagAr.status.clear();
00110 diagAr.status.push_back(status);
00111 diagAr.status.push_back(voltages);
00112 battery_life_pub.publish(diagAr);
00113 ros::spinOnce();
00114 loop_rate.sleep();
00115 }
00116 return 0;
00117 }