$search
00001 # Software License Agreement (BSD License) 00002 # 00003 # Copyright (c) 2008, Willow Garage, Inc. 00004 # All rights reserved. 00005 # 00006 # Redistribution and use in source and binary forms, with or without 00007 # modification, are permitted provided that the following conditions 00008 # are met: 00009 # 00010 # * Redistributions of source code must retain the above copyright 00011 # notice, this list of conditions and the following disclaimer. 00012 # * Redistributions in binary form must reproduce the above 00013 # copyright notice, this list of conditions and the following 00014 # disclaimer in the documentation and/or other materials provided 00015 # with the distribution. 00016 # * Neither the name of the Willow Garage nor the names of its 00017 # contributors may be used to endorse or promote products derived 00018 # from this software without specific prior written permission. 00019 # 00020 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00021 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00022 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00023 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00024 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00025 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00026 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00027 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00028 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00029 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00030 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00031 # POSSIBILITY OF SUCH DAMAGE. 00032 00033 import rospy 00034 00035 import wx 00036 00037 from pr2_msgs.msg import PowerState, PowerBoardState 00038 from pr2_power_board.srv import PowerBoardCommand, PowerBoardCommandRequest 00039 00040 from os import path 00041 00042 class PowerStateControl(wx.Window): 00043 def __init__(self, parent, id, icons_path): 00044 wx.Window.__init__(self, parent, id, wx.DefaultPosition, wx.Size(60, 32)) 00045 00046 self._power_consumption = 0.0 00047 self._pct = 0 00048 self._time_remaining = rospy.rostime.Duration(0) 00049 self._ac_present = 0 00050 00051 self._left_bitmap = wx.Bitmap(path.join(icons_path, "battery-minus.png"), wx.BITMAP_TYPE_PNG) 00052 self._right_bitmap = wx.Bitmap(path.join(icons_path, "battery-plus.png"), wx.BITMAP_TYPE_PNG) 00053 self._plug_bitmap = wx.Bitmap(path.join(icons_path, "battery-charging.png"), wx.BITMAP_TYPE_PNG) 00054 self._background_bitmap = wx.Bitmap(path.join(icons_path, "battery-background.png"), wx.BITMAP_TYPE_PNG) 00055 self._green = wx.Bitmap(path.join(icons_path, "battery-green-bar.png"), wx.BITMAP_TYPE_PNG) 00056 self._yellow = wx.Bitmap(path.join(icons_path, "battery-yellow-bar.png"), wx.BITMAP_TYPE_PNG) 00057 self._red = wx.Bitmap(path.join(icons_path, "battery-red-bar.png"), wx.BITMAP_TYPE_PNG) 00058 00059 self.SetSize(wx.Size(self._left_bitmap.GetWidth() + self._right_bitmap.GetWidth() + self._background_bitmap.GetWidth(), 32)) 00060 00061 self._start_x = self._left_bitmap.GetWidth() 00062 self._end_x = self.GetSize().x - self._right_bitmap.GetWidth() 00063 self._width = self._end_x - self._start_x 00064 00065 self._plugged_in = False 00066 00067 self.Bind(wx.EVT_PAINT, self.on_paint) 00068 00069 def on_paint(self, evt): 00070 dc = wx.BufferedPaintDC(self) 00071 00072 dc.SetBackground(wx.Brush(self.GetBackgroundColour())) 00073 dc.Clear() 00074 00075 w = self.GetSize().GetWidth() 00076 h = self._left_bitmap.GetHeight() 00077 00078 color_bitmap = None 00079 if (self._pct > 0.5): 00080 color_bitmap = self._green 00081 elif (self._pct > 0.3): 00082 color_bitmap = self._yellow 00083 else: 00084 color_bitmap = self._red 00085 00086 dc.DrawBitmap(self._background_bitmap, self._start_x, 0, True) 00087 00088 color_image = color_bitmap.ConvertToImage() 00089 scaled_color_image = color_image.Rescale(round(self._width * self._pct), color_bitmap.GetHeight()) 00090 color_bitmap = wx.BitmapFromImage(scaled_color_image) 00091 dc.DrawBitmap(color_bitmap, self._start_x, 0, True) 00092 dc.DrawBitmap(self._left_bitmap, 0, 0, True) 00093 dc.DrawBitmap(self._right_bitmap, self._end_x, 0, True) 00094 00095 if (self._plugged_in): 00096 dc.DrawBitmap(self._plug_bitmap, 00097 (self._start_x + self._width) / 2.0 - (self._plug_bitmap.GetWidth() / 2.0), 00098 self.GetSize().GetHeight() / 2.0 - (self._plug_bitmap.GetHeight() / 2.0)) 00099 00100 00101 def set_power_state(self, msg): 00102 last_pct = self._pct 00103 last_plugged_in = self._plugged_in 00104 last_time_remaining = self._time_remaining 00105 00106 self._power_consumption = msg.power_consumption 00107 self._time_remaining = msg.time_remaining 00108 self._pct = msg.relative_capacity / 100.0 00109 self._plugged_in = msg.AC_present 00110 00111 if (last_pct != self._pct or last_plugged_in != self._plugged_in or last_time_remaining != self._time_remaining): 00112 drain_str = "remaining" 00113 if (self._plugged_in): 00114 drain_str = "to full charge" 00115 self.SetToolTip(wx.ToolTip("Battery: %.2f%% (%d minutes %s)"%(self._pct * 100.0, self._time_remaining.to_sec()/60.0, drain_str))) 00116 self.Refresh() 00117 00118 def set_stale(self): 00119 self._plugged_in = 0 00120 self._pct = 0 00121 self._time_remaining = rospy.rostime.Duration(0) 00122 self._power_consumption = 0 00123 self.SetToolTip(wx.ToolTip("Battery: Stale")) 00124 00125 self.Refresh()