diagnostics.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 import roslib; roslib.load_manifest('husky_bringup')
00003 import rospy
00004 
00005 from clearpath_base.msg import SystemStatus, SafetyStatus, PowerStatus
00006 from diagnostic_msgs.msg import DiagnosticArray, DiagnosticStatus, KeyValue
00007 
00008 # Constants
00009 UNDERVOLT_ERROR = 18
00010 UNDERVOLT_WARN = 19
00011 OVERVOLT_ERROR = 30
00012 OVERVOLT_WARN = 29
00013 DRIVER_OVERTEMP_ERROR = 50
00014 DRIVER_OVERTEMP_WARN = 30
00015 MOTOR_OVERTEMP_ERROR = 80
00016 MOTOR_OVERTEMP_WARN = 70
00017 LOWPOWER_ERROR = 0.2
00018 LOWPOWER_WARN = 0.3
00019 SAFETY_TIMEOUT = 0x1
00020 SAFETY_LOCKOUT = 0x2
00021 SAFETY_ESTOP = 0x8
00022 SAFETY_CCI = 0x10
00023 SAFETY_PSU= 0x20
00024 SAFETY_CURRENT = 0x40
00025 SAFETY_WARN = (SAFETY_TIMEOUT | SAFETY_CCI | SAFETY_PSU)
00026 SAFETY_ERROR = (SAFETY_LOCKOUT | SAFETY_ESTOP | SAFETY_CURRENT)
00027 
00028 class HuskyDiagnostics():
00029     def __init__(self):
00030         rospy.init_node('husky_diagnostics')
00031         self.diag_pub = rospy.Publisher('/diagnostics', DiagnosticArray)
00032         self.last_diagnostics_time = rospy.get_rostime()        
00033         rospy.Subscriber('husky/data/system_status', SystemStatus, self.HandleSystemStatus)
00034         rospy.Subscriber('husky/data/safety_status', SafetyStatus, self.HandleSafetyStatus)
00035         rospy.Subscriber('husky/data/power_status', PowerStatus, self.HandlePowerStatus)
00036 
00037         self.stat_estop = [] 
00038         self.stat_power = []
00039         self.stat_voltage = []
00040         self.stat_temp = []
00041         self.stat_uptime = []
00042 
00043         # Should publish: Estop, charge, voltage, current, temperatures
00044 
00045     def _publish(self, time):
00046         """ Publishes diagnostic data"""
00047         # Limit to 1 Hz
00048         if (time - self.last_diagnostics_time).to_sec() < 1.0:
00049             return
00050         self.last_diagnostics_time = time
00051         diag = DiagnosticArray()
00052         diag.header.stamp = time
00053 
00054         # E-Stop
00055         if self.stat_estop:
00056             diag.status.append(self.stat_estop)
00057         # Power
00058         if self.stat_power:
00059             diag.status.append(self.stat_power)
00060         # Voltage
00061         if self.stat_voltage:
00062             diag.status.append(self.stat_voltage)
00063         # Temperature
00064         if self.stat_temp:
00065             diag.status.append(self.stat_temp)
00066         # Uptime
00067         if self.stat_uptime:
00068             diag.status.append(self.stat_uptime)
00069 
00070         # Publish
00071         print diag
00072         self.diag_pub.publish(diag)
00073 
00074     def HandleSystemStatus(self,data):
00075         # Uptime
00076         self.stat_uptime = DiagnosticStatus(name="Uptime",level=DiagnosticStatus.OK, message="Robot Online")
00077         uptime = data.uptime
00078         self.stat_uptime.values = [KeyValue("Uptime (ms)",str(uptime))]
00079     
00080         # Bus voltage
00081         bus_volt = data.voltages[0]
00082         self.stat_voltage = DiagnosticStatus(name="Voltage",level=DiagnosticStatus.OK, message="Voltage OK")
00083         if bus_volt > OVERVOLT_ERROR:
00084             self.stat_voltage.level = DiagnosticStatus.ERROR
00085             self.stat_voltage.message = "Main bus voltage too high"
00086         elif bus_volt > OVERVOLT_WARN:
00087             self.stat_voltage.level = DiagnosticStatus.WARN
00088             self.stat_voltage.message = "Main bus voltage too high"
00089         elif bus_volt < UNDERVOLT_ERROR:
00090             self.stat_voltage.level = DiagnosticStatus.ERROR
00091             self.stat_voltage.message = "Main bus voltage too low"
00092         elif bus_volt < UNDERVOLT_WARN:
00093             self.stat_voltage.level = DiagnosticStatus.WARN
00094             self.stat_voltage.message = "Main bus voltage too low"
00095 
00096         self.stat_voltage.values = [KeyValue("Bus voltage (V)",str(bus_volt))]
00097 
00098         # Temperature
00099         self.stat_temp = DiagnosticStatus(name="Temperature",level=DiagnosticStatus.OK, message="OK")
00100         left_drv = data.temperatures[0]
00101         right_drv = data.temperatures[1]
00102         left_mot = data.temperatures[2]
00103         right_mot = data.temperatures[3]
00104         if max(left_drv,right_drv) > DRIVER_OVERTEMP_ERROR:
00105             self.stat_temp.level = DiagnosticStatus.ERROR
00106             self.stat_temp.message = "Motor drivers too hot"
00107         elif max(left_drv,right_drv) > DRIVER_OVERTEMP_WARN:
00108             self.stat_temp.level = DiagnosticStatus.WARN
00109             self.stat_temp.message = "Motor drivers too hot"
00110         if max(left_mot,right_mot) > MOTOR_OVERTEMP_ERROR:
00111             self.stat_temp.level = DiagnosticStatus.ERROR
00112             self.stat_temp.message = "Motors too hot"
00113         elif max(left_mot,right_mot) > MOTOR_OVERTEMP_WARN:
00114             self.stat_temp.level = DiagnosticStatus.WARN
00115             self.stat_temp.message = "Motors too hot"
00116 
00117         self.stat_temp.values = [KeyValue("Left motor driver (C)",str(left_drv)),
00118                                  KeyValue("Right motor driver (C)",str(right_drv)),
00119                                  KeyValue("Left motor (C)",str(left_mot)),
00120                                  KeyValue("Right motor (C)",str(right_mot))]
00121 
00122         # Publish
00123         self._publish(data.header.stamp)
00124 
00125     def HandleSafetyStatus(self,data):
00126         # Safety
00127         self.stat_estop = DiagnosticStatus(name="Safety System",level=DiagnosticStatus.OK,
00128                                            message="OK")
00129         flags = data.flags        
00130 
00131         if flags & SAFETY_ERROR:
00132             self.stat_estop.level = DiagnosticStatus.ERROR
00133             self.stat_estop.message = "Error"
00134         elif flags & SAFETY_WARN:
00135             self.stat_estop.level = DiagnosticStatus.WARN
00136             self.stat_estop.message = "Warning"
00137 
00138         self.stat_estop.values = [KeyValue("Timeout",str(flags & SAFETY_TIMEOUT > 0)),
00139                                  KeyValue("Lockout",str(flags & SAFETY_LOCKOUT > 0)), 
00140                                  KeyValue("Emergency Stop",str(flags & SAFETY_ESTOP > 0)), 
00141                                  KeyValue("ROS Pause",str(flags & SAFETY_CCI > 0)), 
00142                                  KeyValue("No battery",str(flags & SAFETY_PSU > 0)), 
00143                                  KeyValue("Current limit",str(flags & SAFETY_CURRENT > 0))]
00144         
00145         # Publish
00146         self._publish(data.header.stamp)
00147 
00148     def HandlePowerStatus(self,data):
00149         # Charge
00150         self.stat_power = DiagnosticStatus(name="Power System",level=DiagnosticStatus.OK, message="OK")
00151         charge = data.sources[0].charge
00152         capacity = data.sources[0].capacity
00153         present = data.sources[0].present
00154         bat_type = data.sources[0].description
00155         if charge < LOWPOWER_WARN:
00156             self.stat_power.level = DiagnosticStatus.WARN
00157             self.stat_power.message = "Low power"
00158         if charge < LOWPOWER_ERROR:
00159             self.stat_power.level = DiagnosticStatus.ERROR 
00160         self.stat_power.values = [KeyValue("Charge (%)",str(charge)),
00161                                  KeyValue("Battery Capacity (Wh)",str(capacity))]
00162 
00163         # Publish
00164         self._publish(data.header.stamp)
00165 
00166 if __name__ == "__main__":
00167     obj = HuskyDiagnostics()
00168     try:
00169         rospy.spin()
00170     except rospy.ROSInterruptException:
00171         pass


husky_bringup
Author(s): Mike Purvis, Ryan Gariepy
autogenerated on Sun Oct 5 2014 22:53:15