pr2_breaker.py
Go to the documentation of this file.
1 # Software License Agreement (BSD License)
2 #
3 # Copyright (c) 2012, Willow Garage, Inc.
4 # All rights reserved.
5 #
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
8 # are met:
9 #
10 # * Redistributions of source code must retain the above copyright
11 # notice, this list of conditions and the following disclaimer.
12 # * Redistributions in binary form must reproduce the above
13 # copyright notice, this list of conditions and the following
14 # disclaimer in the documentation and/or other materials provided
15 # with the distribution.
16 # * Neither the name of Willow Garage, Inc. nor the names of its
17 # contributors may be used to endorse or promote products derived
18 # from this software without specific prior written permission.
19 #
20 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 # POSSIBILITY OF SUCH DAMAGE.
32 import rospy
33 
34 from python_qt_binding.QtCore import QSize
35 
36 from pr2_msgs.msg import PowerBoardState
37 from pr2_power_board.srv import PowerBoardCommand, PowerBoardCommandRequest
38 
39 from rqt_robot_dashboard.widgets import MenuDashWidget
40 
41 try:
42  from python_qt_binding.QtGui import QMessageBox
43 except:
44  from python_qt_binding.QtWidgets import QMessageBox
45 
46 
47 class PR2BreakerButton(MenuDashWidget):
48  """
49  Dashboard widget to display and interact with the PR2 Breaker state.
50  """
51  def __init__(self, breaker_name, breaker_index):
52  """
53  :param breaker_name: Name of the breaker
54  :type breaker_name: str
55  :param breaker_index: Index of the breaker
56  :type breaker_index: int
57  """
58 
59  if breaker_name == 'Left Arm':
60  breaker_icon = 'ic-larm.svg'
61  elif breaker_name == 'Base':
62  breaker_icon = 'ic-base.svg'
63  elif breaker_name == 'Right Arm':
64  breaker_icon = 'ic-rarm.svg'
65  else:
66  breaker_icon = 'ic-breaker.svg'
67 
68  ok_icon = ['bg-green.svg', breaker_icon]
69  warn_icon = ['bg-yellow.svg', breaker_icon, 'ol-warn-badge.svg']
70  err_icon = ['bg-red.svg', breaker_icon, 'ol-err-badge.svg']
71  stale_icon = ['bg-grey.svg', breaker_icon, 'ol-stale-badge.svg']
72 
73  icons = [ok_icon, warn_icon, err_icon, stale_icon]
74 
75  super(PR2BreakerButton, self).__init__('Breaker:' + breaker_name, icons=icons, icon_paths=[['rqt_pr2_dashboard', 'images']])
76  self.update_state(3)
77 
78  self.setFixedSize(self._icons[0].actualSize(QSize(50, 30)))
79 
80  self.add_action('Enable', self.on_enable)
81  self.add_action('Standby', self.on_standby)
82  self.add_action('Disable', self.on_disable)
83  self.add_separator()
84  self.add_action('Enable All Breakers', self.on_enable_all)
85  self.add_action('Standby All Breakers', self.on_standby_all)
86  self.add_action('Disable All Breakers', self.on_disable_all)
87 
88  self._power_control = rospy.ServiceProxy('power_board/control', PowerBoardCommand)
89  self._serial = 0
90  self._index = breaker_index
91  self._name = breaker_name
92  self._power_board_state = None
93  self._last_status_msg = None
94  self.setToolTip(breaker_name)
95 
96  def control(self, breaker, cmd):
97  """
98  Sends a PowerBoardCommand srv to the pr2
99 
100  :param breaker: breaker index to send command to
101  :type breaker: int
102  :param cmd: command to be sent to the pr2 breaker
103  :type cmd: str
104  """
105  if (not self._power_board_state):
106  QMessageBox.critical(self, "Error", self.tr("Cannot control breakers until we have received a power board state message"))
107  return False
108 
109  if (not self._power_board_state.run_stop or not self._power_board_state.wireless_stop):
110  if (cmd == "start"):
111  QMessageBox.critical(self, "Error", self.tr("Breakers will not enable because one of the runstops is pressed"))
112  return False
113 
114  try:
115  power_cmd = PowerBoardCommandRequest()
116  power_cmd.breaker_number = breaker
117  power_cmd.command = cmd
118  power_cmd.serial_number = self._serial
119  self._power_control(power_cmd)
120 
121  return True
122  except rospy.ServiceException, e:
123  QMessageBox.critical(self, "Error", "Service call failed with error: %s" % (e), "Error")
124  return False
125 
126  return False
127 
128  def control3(self, cmd):
129  if (not self.control(0, cmd)):
130  return False
131  if (not self.control(1, cmd)):
132  return False
133  if (not self.control(2, cmd)):
134  return False
135  return True
136 
137  def on_enable(self):
138  self.set_enable()
139 
140  def on_standby(self):
141  self.set_standby()
142 
143  def on_disable(self):
144  self.set_disable()
145 
146  def on_enable_all(self):
147  self.set_enable_all()
148 
149  def on_standby_all(self):
150  self.set_standby_all()
151 
152  def on_disable_all(self):
153  self.set_disable_all()
154 
155  def set_enable(self):
156  if (not self.control(self._index, "reset")):
157  return
158 
159  self.control(self._index, "start")
160 
161  def set_standby(self):
162  if (not self.control(self._index, "reset")):
163  return
164 
165  self.control(self._index, "stop")
166 
167  def set_disable(self):
168  self.control(self._index, "disable")
169 
170  def set_enable_all(self):
171  if (not self.control3("reset")):
172  return
173 
174  self.control3("start")
175 
176  def set_standby_all(self):
177  if (not self.control3("reset")):
178  return
179 
180  self.control3("stop")
181 
182  def set_disable_all(self):
183  self.control3("disable")
184 
186  """
187  Sets state of button based on msg
188 
189  :param msg: message containing the PR2 powerboard state
190  :type msg: pr2_msgs.msg.PowerBoardState
191  """
192  last_voltage = msg.circuit_voltage[self._index]
193 
194  self._power_board_state = msg
195  self._serial = msg.serial_num
196 
197  status_msg = "OK"
198 
199  if (msg.circuit_state[self._index] == PowerBoardState.STATE_DISABLED):
200  self.set_error()
201  status_msg = "Disabled"
202  elif (msg.circuit_state[self._index] == PowerBoardState.STATE_NOPOWER):
203  self.set_error()
204  status_msg = "No Power"
205  elif (msg.circuit_state[self._index] == PowerBoardState.STATE_STANDBY):
206  self.set_warn()
207  status_msg = "Standby"
208  else:
209  self.set_ok()
210 
211  if (status_msg != self._last_status_msg or abs(last_voltage - msg.circuit_voltage[self._index]) >= 0.1):
212  self.setToolTip("Breaker: %s \nVoltage: %.02f \nState: %s" % (self._name, msg.circuit_voltage[self._index], status_msg))
213  self._last_status_msg = status_msg
214 
215  def reset(self):
216  self.set_stale()
217  self.setToolTip("Breaker: %s (Stale)" % (self._name))
218 
219  def set_ok(self):
220  self.update_state(0)
221 
222  def set_warn(self):
223  self.update_state(1)
224 
225  def set_error(self):
226  self.update_state(2)
227 
228  def set_stale(self):
229  self.update_state(3)
def __init__(self, breaker_name, breaker_index)
Definition: pr2_breaker.py:51


rqt_pr2_dashboard
Author(s): Aaron Blasdel
autogenerated on Fri Dec 11 2020 03:39:03