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 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 from __future__ import with_statement
00038 
00039 import roslib; roslib.load_manifest('pr2_plugs_actions')
00040 import rospy
00041 import threading
00042 import copy
00043 from std_msgs.msg import Bool
00044 from pr2_msgs.msg import PowerState
00045 from collections import deque
00046 
00047 
00048 class Battery:
00049     def __init__(self, low_cb=None, high_cb=None, name='battery_monitor'):
00050         self.lock = threading.Lock()  
00051         self.state = None
00052         self.low_trigger = 0
00053         self.high_trigger = 100
00054         self.low_cb = low_cb
00055         self.high_cb = high_cb
00056         self.buffer_size = rospy.get_param("~%s/buffer_size"%name, 5)
00057         self.msgs = deque()
00058         self.power_sub = rospy.Subscriber('power_state', PowerState, self._power_cb)
00059         rospy.loginfo("Start monitoring battery")
00060 
00061     def set_thresholds(self, low=None, high=None):
00062         with self.lock:
00063             if low:
00064                 self.low_trigger = low
00065             if high:
00066                 self.high_trigger = high
00067             self.state = None
00068             rospy.loginfo("Set battery thresholds to %f and %f"%(self.low_trigger, self.high_trigger))
00069 
00070 
00071     def get_state(self):
00072         while not rospy.is_shutdown():
00073             rospy.sleep(0.1)
00074             with self.lock:
00075                 if self.state:
00076                     return copy.deepcopy(self.state)
00077 
00078 
00079 
00080     def _power_cb(self, msg):
00081         with self.lock:
00082             self.msgs.append(msg)
00083 
00084             
00085             while len(self.msgs) > self.buffer_size:
00086                 self.msgs.popleft()
00087 
00088             
00089             if not len(self.msgs) >= self.buffer_size:
00090                 return 
00091 
00092             
00093             state = 0
00094             for msg in self.msgs:
00095                 if msg.relative_capacity <= self.low_trigger:
00096                     state -= 1
00097                 elif msg.relative_capacity >= self.high_trigger:
00098                     state += 1
00099 
00100             
00101             if self.high_cb and state == self.buffer_size and self.msgs[-1].AC_present == 1:
00102                 self.msgs = deque()  
00103                 if self.state != 'high':
00104                     rospy.loginfo('Calling high battery callback')
00105                     self.high_cb()
00106                 self.state = 'high'
00107 
00108             
00109             elif self.low_cb and state == -self.buffer_size and self.msgs[-1].AC_present != 1:
00110                 self.msgs = deque()  
00111                 if self.state != 'low':
00112                     rospy.loginfo('Calling low battery callback')
00113                     self.low_cb()
00114                 self.state = 'low'
00115 
00116             elif self.msgs[-1].AC_present == 1:
00117                 self.state = 'charging'
00118 
00119             elif self.msgs[-1].AC_present != 1:
00120                 self.state = 'discharging'
00121 
00122 
00123