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 import os
00032 import rospy
00033 import rospkg
00034 import time
00035
00036 from qt_gui.plugin import Plugin
00037 from python_qt_binding import loadUi
00038 from python_qt_binding.QtWidgets import QWidget, QGraphicsScene, QLabel, QGraphicsEllipseItem, QGraphicsLineItem, QGraphicsTextItem
00039 from python_qt_binding.QtCore import Qt, Signal, QTimer, QDateTime, QDate, QTime, QPoint
00040 from python_qt_binding.QtGui import QPixmap, QFont, QPen, QColor, QBrush, QImage
00041
00042 from cmath import *
00043 from math import *
00044
00045 from mobility_base_core_msgs.msg import Mode, JoystickRaw
00046 from rospy.rostime import Time
00047 from geometry_msgs.msg import Twist
00048
00049 from mobility_base_core_msgs.msg import BumperState
00050 from mobility_base_core_msgs.msg import BatteryState
00051 from sensor_msgs.msg import Imu
00052 import std_msgs.msg
00053 import std_srvs.srv
00054 from mobility_base_core_msgs.srv import GetMaxSpeed, SetMaxSpeed
00055 from numpy import isfinite
00056 from mobility_base_core_msgs.srv import SetMaxSpeedRequest
00057
00058
00059 class BumperIndex:
00060 def __init__(self):
00061 pass
00062
00063 BUMPER_1F = 0
00064 BUMPER_1L = 1
00065 BUMPER_1R = 2
00066 BUMPER_1B = 3
00067
00068 BUMPER_2F = 4
00069 BUMPER_2L = 5
00070 BUMPER_2R = 6
00071 BUMPER_2B = 7
00072
00073 BUMPER_3F = 8
00074 BUMPER_3L = 9
00075 BUMPER_3R = 10
00076 BUMPER_3B = 11
00077
00078 BUMPER_4F = 12
00079 BUMPER_4L = 13
00080 BUMPER_4R = 14
00081 BUMPER_4B = 15
00082
00083
00084 class ChannelIndex:
00085 def __init__(self):
00086 pass
00087
00088 CHAN_ENABLE = 0
00089 CHAN_ROTATE = 1
00090 CHAN_FORWARD = 2
00091 CHAN_LATERAL = 3
00092 CHAN_MODE = 4
00093 CHAN_EXTRA = 5
00094
00095
00096 class DiagnosticGui(Plugin):
00097 last_suppress_time = Time()
00098 last_twist_time = Time()
00099 gui_update_timer = QTimer()
00100
00101
00102 joystick_data = []
00103 joystick_table_vals = []
00104 joystick_channel_text = ['CHAN_ENABLE: ', 'CHAN_ROTATE: ', 'CHAN_FORWARD: ', 'CHAN_LATERAL: ', 'CHAN_MODE: ', 'CHAN_EXTRA: ']
00105 joystick_bind_status = False
00106 joystick_bind_dot_counter = 0
00107
00108
00109 current_mode = -1
00110
00111
00112 JOYSTICK_SUPPRESS_PERIOD = 0.2
00113 CMD_VEL_TIMEOUT_PERIOD = 0.2
00114 joystick_suppressed = False
00115 command_received = False
00116 current_cmd = Twist()
00117 battery_percent = 0
00118 battery_voltage = 0
00119
00120
00121 bad_icon = QPixmap()
00122 good_icon = QPixmap()
00123 none_icon = QPixmap()
00124
00125
00126 GOOD = 0
00127 BAD = 1
00128 NONE = 2
00129
00130
00131 checklist_status = []
00132
00133 BATT_MAN = 0
00134 ESTOP_MAN = 1
00135 DISABLE_MAN = 2
00136 JOYSTICK_MAN = 3
00137 SUPPRESS_MAN = 4
00138 BATT_COMP = 5
00139 ESTOP_COMP = 6
00140 DISABLE_COMP = 7
00141 JOYSTICK_COMP = 8
00142 SUPPRESS_COMP = 9
00143 CMD_COMP = 10
00144
00145
00146 bumper_front_left = 0
00147 bumper_front_right = 0
00148 bumper_rear_left = 0
00149 bumper_rear_right = 0
00150
00151
00152 gyro_cal_status = False
00153 gyro_x = 0.0
00154 gyro_y = 0.0
00155 gyro_z = 0.0
00156 cal_enabled = True
00157 cal_time = rospy.Time(0)
00158
00159
00160 max_speed_known = False
00161 max_speed_dirty = True
00162 max_linear_actual = 0.0
00163 max_angular_actual = 0.0
00164 max_linear_setting = 0.0
00165 max_angular_setting = 0.0
00166
00167
00168 current_wake_time = rospy.Time(0)
00169 rel_wake_days = 0
00170 rel_wake_hours = 0
00171 rel_wake_minutes = 0
00172 rel_wake_secs = 0
00173
00174
00175 is_currently_tab = False
00176 widget_count = 0
00177 current_tab_idx = -1
00178 raw_data_tab_idx = 5
00179
00180
00181 base_connected = False
00182 last_joystick_time = rospy.Time(0)
00183
00184
00185 stick_ind_lox = 80
00186 stick_ind_loy = 136
00187 stick_ind_rox = 286
00188 stick_ind_roy = 135
00189 stick_ind_range_pix = 88.0
00190 stick_ind_range_max = JoystickRaw.MAX
00191 stick_ind_range_min = JoystickRaw.MIN
00192 stick_ind_range_mid = JoystickRaw.CENTER
00193 stick_ind_range_factor = stick_ind_range_pix / (stick_ind_range_max - stick_ind_range_min)
00194 stick_ind_radius = 7
00195 mode_ind_x1 = 52
00196 mode_ind_y1 = 37
00197 mode_ind_x2 = 44
00198 mode_ind_y2 = 13
00199 power_ind_x1 = 160
00200 power_ind_x2 = 206
00201 power_ind_y = 213
00202 bumper_fl_x = 70
00203 bumper_fl_y = 60
00204 bumper_fr_x = 293
00205 bumper_fr_y = 60
00206 bumper_rl_x = 70
00207 bumper_rl_y = 282
00208 bumper_rr_x = 293
00209 bumper_rr_y = 282
00210 bumper_dx = 62
00211 bumper_dy = 54
00212 joystick_table_left_edge = 440
00213 joystick_table_top_edge = 525
00214 twist_table_left_edge = 700
00215 twist_table_top_edge = 580
00216 battery_table_left_edge = 700
00217 battery_table_top_edge = 730
00218
00219 _deferred_fit_in_view = Signal()
00220
00221 def __init__(self, context):
00222 super(DiagnosticGui, self).__init__(context)
00223
00224
00225 self.context_ = context
00226 self.init_gui('full')
00227
00228
00229 self.topic_timeout_timer = rospy.Timer(rospy.Duration(0.02), self.topic_timeout_cb)
00230 self.subscribe_topics()
00231 self.advertise_topics()
00232
00233 def init_gui(self, gui_type):
00234 if gui_type == 'full':
00235 self.spawn_full_gui()
00236 self.init_tables(self._widget, self.joystick_table_left_edge, self.joystick_table_top_edge)
00237 else:
00238 self.spawn_tab_gui()
00239 self.init_tables(self._widget.gui_tabs.widget(self.raw_data_tab_idx), 20, 20)
00240 self._widget.gui_tabs.setCurrentIndex(self.current_tab_idx)
00241
00242 self.reset_gui_timer()
00243 self.init_joystick_graphics()
00244 self.init_bumper_graphics()
00245 self.init_checklists()
00246 self.bind_callbacks()
00247 self.refresh_max_speed()
00248
00249
00250 datetime_now = QDateTime(QDate.currentDate(), QTime.currentTime())
00251 self._widget.absolute_wake_time_obj.setDateTime(datetime_now)
00252 temp_time = self._widget.absolute_wake_time_obj.time()
00253 temp_time = QTime(temp_time.hour(), temp_time.minute())
00254 self._widget.absolute_wake_time_obj.setTime(temp_time)
00255
00256
00257 if self.base_connected:
00258 self._widget.disconnected_lbl.setVisible(False)
00259 else:
00260 self._widget.disconnected_lbl.setVisible(True)
00261 self._widget.disconnected_lbl.setText('<font color=#FF0000>NOT CONNECTED</font>')
00262
00263 def topic_timeout_cb(self, event):
00264
00265 if (event.current_real - self.last_suppress_time).to_sec() < self.JOYSTICK_SUPPRESS_PERIOD and self.suppress_dt.to_sec() <= 1.0/9.0:
00266 self.joystick_suppressed = True
00267 else:
00268 self.joystick_suppressed = False
00269
00270
00271 if (event.current_real - self.last_twist_time).to_sec() < self.CMD_VEL_TIMEOUT_PERIOD and self.twist_dt.to_sec() <= 1.0/6.0:
00272 self.command_received = True
00273 else:
00274 self.command_received = False
00275
00276 def init_checklists(self):
00277 self.bad_icon.load(os.path.join(rospkg.RosPack().get_path('mobility_base_tools'), 'images', 'bad.png'))
00278 self.good_icon.load(os.path.join(rospkg.RosPack().get_path('mobility_base_tools'), 'images', 'good.png'))
00279 self.none_icon.load(os.path.join(rospkg.RosPack().get_path('mobility_base_tools'), 'images', 'none.png'))
00280 self.checklist_status=[0 for i in range(self.CMD_COMP + 1)]
00281 self.checklist_status[self.BATT_MAN] = self.NONE
00282 self.checklist_status[self.ESTOP_MAN] = self.NONE
00283 self.checklist_status[self.DISABLE_MAN] = self.NONE
00284 self.checklist_status[self.JOYSTICK_MAN] = self.NONE
00285 self.checklist_status[self.SUPPRESS_MAN] = self.NONE
00286 self.checklist_status[self.BATT_COMP] = self.NONE
00287 self.checklist_status[self.ESTOP_COMP] = self.NONE
00288 self.checklist_status[self.DISABLE_COMP] = self.NONE
00289 self.checklist_status[self.JOYSTICK_COMP] = self.NONE
00290 self.checklist_status[self.SUPPRESS_COMP] = self.NONE
00291 self.checklist_status[self.CMD_COMP] = self.NONE
00292
00293 def init_tab_tables(self):
00294 self.joystick_table_vals = [QLabel(self._widget.gui_tabs.widget(self.raw_data_tab_idx)) for i in range(ChannelIndex.CHAN_EXTRA+1)]
00295 self.joystick_table_labels = [QLabel(self._widget.gui_tabs.widget(self.raw_data_tab_idx)) for i in range(ChannelIndex.CHAN_EXTRA+1)]
00296 self.joystick_table_heading = QLabel(self._widget.gui_tabs.widget(self.raw_data_tab_idx))
00297
00298 def init_tables(self, widget, left, top):
00299
00300 self.joystick_data = [0 for i in range(ChannelIndex.CHAN_EXTRA+1)]
00301 self.joystick_table_vals = [QLabel(widget) for i in range(ChannelIndex.CHAN_EXTRA+1)]
00302 self.joystick_table_labels = [QLabel(widget) for i in range(ChannelIndex.CHAN_EXTRA+1)]
00303 self.joystick_table_heading = QLabel(widget)
00304
00305 self.joystick_table_heading.setText('Raw Joystick Data')
00306 self.joystick_table_heading.setFont(QFont('Ubuntu', 11, QFont.Bold))
00307 self.joystick_table_heading.move(left, top)
00308 for i in range(len(self.joystick_table_vals)):
00309 self.joystick_table_vals[i].move(left + 150, top + 30 * (i+1))
00310 self.joystick_table_vals[i].setText('0000')
00311 self.joystick_table_vals[i].setFixedWidth(200)
00312
00313 self.joystick_table_labels[i].move(left, top + 30 * (i+1))
00314 self.joystick_table_labels[i].setText(self.joystick_channel_text[i])
00315
00316
00317 self.twist_table_heading = QLabel(widget)
00318 self.twist_table_heading.setText('Current Twist Command')
00319 self.twist_table_heading.setFont(QFont('Ubuntu', 11, QFont.Bold))
00320 self.twist_table_heading.move(left + 260, top)
00321 self.twist_table_labels = [QLabel(widget) for i in range(0, 3)]
00322 self.twist_table_vals = [QLabel(widget) for i in range(0, 3)]
00323 for i in range(len(self.twist_table_vals)):
00324 self.twist_table_vals[i].move(left + 260 + 150, top + 30 * (i+1))
00325 self.twist_table_vals[i].setText('Not Published')
00326 self.twist_table_vals[i].setFixedWidth(200)
00327 self.twist_table_labels[i].move(left + 260, top + 30 * (i+1))
00328
00329 self.twist_table_labels[0].setText('Forward (m/s):')
00330 self.twist_table_labels[1].setText('Lateral (m/s):')
00331 self.twist_table_labels[2].setText('Rotation (rad/s):')
00332
00333
00334 self.battery_heading = QLabel(widget)
00335 self.battery_heading.setText('Current Battery State')
00336 self.battery_heading.setFont(QFont('Ubuntu', 11, QFont.Bold))
00337 self.battery_heading.move(left + 260, top + 150)
00338 self.battery_label = QLabel(widget)
00339 self.battery_label.move(left + 260, top + 150 +30)
00340 self.battery_label.setText('000 %')
00341 self.battery_voltage_label = QLabel(widget)
00342 self.battery_voltage_label.move(left + 260, top + 150 +60)
00343 self.battery_voltage_label.setText('00.00 V')
00344 self.battery_voltage_label.setFixedWidth(200)
00345
00346
00347 self.mode_heading = QLabel(widget)
00348 self.mode_heading.setFont(QFont('Ubuntu', 11, QFont.Bold))
00349 self.mode_heading.move(left, top + 225)
00350 self.mode_heading.setText('Current Mode')
00351 self.mode_label = QLabel(widget)
00352 self.mode_label.move(left + 120, top + 225)
00353 self.mode_label.setText('XXXXXXXXXXXXXXXXXXXXXX')
00354
00355 def bind_callbacks(self):
00356 self._widget.start_bind_btn.clicked.connect(self.start_bind)
00357 self._widget.stop_bind_btn.clicked.connect(self.stop_bind)
00358
00359 self._widget.gyro_cal_btn.clicked.connect(self.cal_gyro)
00360 self._widget.clear_cal_btn.clicked.connect(self.clear_cal)
00361
00362 self._widget.max_linear_txt.editingFinished.connect(self.max_linear_changed)
00363 self._widget.max_angular_txt.editingFinished.connect(self.max_angular_changed)
00364 self._widget.set_speed_btn.clicked.connect(self.set_max_speed)
00365 self._widget.clear_speed_btn.clicked.connect(self.clear_max_speed)
00366
00367 self._widget.wake_time_days_txt.editingFinished.connect(self.wake_days_changed)
00368 self._widget.wake_time_hours_txt.editingFinished.connect(self.wake_hours_changed)
00369 self._widget.wake_time_minutes_txt.editingFinished.connect(self.wake_minutes_changed)
00370 self._widget.wake_time_secs_txt.editingFinished.connect(self.wake_secs_changed)
00371 self._widget.set_relative_wake_time_btn.clicked.connect(self.set_relative_wake_time)
00372 self._widget.set_absolute_wake_time_btn.clicked.connect(self.set_absolute_wake_time)
00373 self._widget.clear_wake_time_btn.clicked.connect(self.clear_wake_time)
00374
00375 if self.is_currently_tab:
00376 self._widget.gui_tabs.currentChanged.connect(self.set_current_tab)
00377
00378 def set_current_tab(self, idx):
00379 self.current_tab_idx = self._widget.gui_tabs.currentIndex()
00380
00381 def start_bind(self):
00382 self.pub_start_bind.publish(std_msgs.msg.Empty())
00383
00384 def stop_bind(self):
00385 self.pub_stop_bind.publish(std_msgs.msg.Empty())
00386
00387 def cal_gyro(self):
00388 gyro_cal_srv = rospy.ServiceProxy('/mobility_base/imu/calibrate', std_srvs.srv.Empty)
00389 try:
00390 gyro_cal_srv()
00391 self.cal_enabled = False
00392 self.cal_time = rospy.Time.now()
00393 except:
00394 pass
00395
00396 def clear_cal(self):
00397 clear_cal_srv = rospy.ServiceProxy('/mobility_base/imu/clear_cal', std_srvs.srv.Empty)
00398 try:
00399 clear_cal_srv()
00400 except:
00401 pass
00402
00403 def max_linear_changed(self):
00404 try:
00405 float_val = float(self._widget.max_linear_txt.text())
00406 self.max_linear_setting = float_val;
00407 except ValueError:
00408 if self.max_linear_actual <= 0 or not isfinite(self.max_linear_actual):
00409 self.max_linear_setting = 0.0
00410 else:
00411 self.max_linear_setting = self.max_linear_actual
00412 self.max_speed_dirty = True
00413
00414 def max_angular_changed(self):
00415 try:
00416 float_val = float(self._widget.max_angular_txt.text())
00417 self.max_angular_setting = float_val;
00418 except ValueError:
00419 if self.max_angular_actual <= 0 or not isfinite(self.max_angular_actual):
00420 self.max_angular_setting = 0.0
00421 else:
00422 self.max_angular_setting = self.max_angular_actual
00423 self.max_speed_dirty = True
00424
00425 def set_max_speed(self):
00426 set_max_speed_srv = rospy.ServiceProxy('/mobility_base/set_max_speed', SetMaxSpeed)
00427 req = SetMaxSpeedRequest()
00428 req.linear = self.max_linear_setting
00429 req.angular = self.max_angular_setting
00430 try:
00431 set_max_speed_srv(req)
00432 self.max_speed_known = False
00433 except:
00434 pass
00435
00436 def clear_max_speed(self):
00437 set_max_speed_srv = rospy.ServiceProxy('/mobility_base/set_max_speed', SetMaxSpeed)
00438 req = SetMaxSpeedRequest()
00439 req.linear = float('nan')
00440 req.angular = float('nan')
00441 try:
00442 set_max_speed_srv(req)
00443 self.max_speed_known = False
00444 except:
00445 pass
00446
00447 def wake_days_changed(self):
00448 try:
00449 self.rel_wake_days = float(self._widget.wake_time_days_txt.text())
00450 except:
00451 self._widget.wake_time_days_txt.setText(str(self.rel_wake_days))
00452
00453 def wake_hours_changed(self):
00454 try:
00455 self.rel_wake_hours = float(self._widget.wake_time_hours_txt.text())
00456 except:
00457 self._widget.wake_time_hours_txt.setText(str(self.rel_wake_hours))
00458
00459 def wake_minutes_changed(self):
00460 try:
00461 self.rel_wake_minutes = float(self._widget.wake_time_minutes_txt.text())
00462 except:
00463 self._widget.wake_time_minutes_txt.setText(str(self.rel_wake_minutes))
00464
00465 def wake_secs_changed(self):
00466 try:
00467 self.rel_wake_secs = float(self._widget.wake_time_secs_txt.text())
00468 except:
00469 self._widget.wake_time_secs_txt.setText(str(self.rel_wake_secs))
00470
00471 def set_relative_wake_time(self):
00472 new_wake_time = std_msgs.msg.Time()
00473 rel_wake_time = 86400 * self.rel_wake_days + 3600 * self.rel_wake_hours + 60 * self.rel_wake_minutes + self.rel_wake_secs
00474 new_wake_time.data = rospy.Time.now() + rospy.Duration(rel_wake_time)
00475 self.pub_set_wake_time.publish(new_wake_time)
00476
00477 def set_absolute_wake_time(self):
00478 self.pub_set_wake_time.publish(rospy.Time(self._widget.absolute_wake_time_obj.dateTime().toTime_t()))
00479
00480 def clear_wake_time(self):
00481 self.pub_set_wake_time.publish(rospy.Time(0))
00482
00483 def refresh_max_speed(self):
00484 self.max_speed_dirty = True
00485 self.max_speed_known = False
00486
00487 def update_gui_cb(self):
00488
00489
00490 if self.is_currently_tab:
00491 if self._widget.height() > 830 and self._widget.width() > 1205:
00492 self.is_currently_tab = False
00493 self.context_.remove_widget(self._widget)
00494 self.init_gui('full')
00495 else:
00496 if self._widget.height() < 810 or self._widget.width() < 1185:
00497 self.is_currently_tab = True
00498 self.context_.remove_widget(self._widget)
00499 self.init_gui('tab')
00500
00501
00502 if self.base_connected and (rospy.Time.now() - self.last_joystick_time).to_sec() > 1.0:
00503 self.base_connected = False
00504 self._widget.disconnected_lbl.setText('<font color=#FF0000>NOT CONNECTED</font>')
00505 self._widget.disconnected_lbl.setVisible(True)
00506
00507 if not self.base_connected and (rospy.Time.now() - self.last_joystick_time).to_sec() < 1.0:
00508 self.base_connected = True
00509
00510 self._widget.disconnected_lbl.setVisible(False)
00511
00512
00513 self.update_checklist();
00514
00515
00516 if not self.cal_enabled:
00517 if (rospy.Time.now() - self.cal_time).to_sec() > 5.0:
00518 self._widget.gyro_cal_btn.setEnabled(True)
00519 self._widget.gyro_cal_btn.setText('Calibrate')
00520 self.cal_enabled = True
00521 else:
00522 self._widget.gyro_cal_btn.setEnabled(False)
00523 self._widget.gyro_cal_btn.setText(str(5 - 0.1*floor(10*(rospy.Time.now() - self.cal_time).to_sec())))
00524
00525
00526 if not self.check_joystick_valid():
00527 self.update_check_status(self._widget.joystick_bind_chk, self.NONE)
00528
00529 if not self.joystick_bind_status:
00530 self._widget.joystick_bind_lbl.setText('')
00531
00532
00533 for l in self.joystick_power_ind:
00534 l.setVisible(True)
00535 self.update_right_stick_indicator(self.stick_ind_range_mid, self.stick_ind_range_mid)
00536 self.update_left_stick_indicator(self.stick_ind_range_mid, self.stick_ind_range_mid)
00537 else:
00538 self.update_check_status(self._widget.joystick_bind_chk, self.GOOD)
00539 self._widget.joystick_bind_lbl.setText('Joystick bound')
00540
00541 for l in self.joystick_power_ind:
00542 l.setVisible(False)
00543 self.update_right_stick_indicator(self.joystick_data[ChannelIndex.CHAN_LATERAL], self.joystick_data[ChannelIndex.CHAN_FORWARD])
00544 self.update_left_stick_indicator(self.joystick_data[ChannelIndex.CHAN_ROTATE], self.joystick_data[ChannelIndex.CHAN_ENABLE])
00545 if self.joystick_data[ChannelIndex.CHAN_MODE] < self.stick_ind_range_mid:
00546 self.mode_ind.setPen(self.cyan_pen)
00547 self._widget.modeLabel.setText("0 (Computer)")
00548 else:
00549 self.mode_ind.setPen(self.magenta_pen)
00550 self._widget.modeLabel.setText("1 (Manual)")
00551
00552
00553 for i in range(len(self.joystick_table_vals)):
00554 self.joystick_table_vals[i].setText(str(self.joystick_data[i]))
00555
00556
00557 if self.command_received:
00558 self.twist_table_vals[0].setText(str(0.01 * floor(100 * self.current_cmd.linear.x)))
00559 self.twist_table_vals[1].setText(str(0.01 * floor(100 * self.current_cmd.linear.y)))
00560 self.twist_table_vals[2].setText(str(0.01 * floor(100 * self.current_cmd.angular.z)))
00561 else:
00562 self.twist_table_vals[0].setText('Not Published')
00563 self.twist_table_vals[1].setText('Not Published')
00564 self.twist_table_vals[2].setText('Not Published')
00565
00566
00567 self.battery_label.setText(str(self.battery_percent) + ' %')
00568 self.battery_voltage_label.setText(str(0.01 * floor(100 * self.battery_voltage)) + ' V')
00569
00570
00571 self.mode_label.setText(self.get_mode_string(self.current_mode))
00572
00573
00574 self.bumper_visible_switch(BumperIndex.BUMPER_1F, self.bumper_front_left)
00575 self.bumper_visible_switch(BumperIndex.BUMPER_2F, self.bumper_front_right)
00576 self.bumper_visible_switch(BumperIndex.BUMPER_3F, self.bumper_rear_left)
00577 self.bumper_visible_switch(BumperIndex.BUMPER_4F, self.bumper_rear_right)
00578 self.bumper_state_labels[0].setPlainText(str(self.bumper_front_left))
00579 self.bumper_state_labels[1].setPlainText(str(self.bumper_front_right))
00580 self.bumper_state_labels[2].setPlainText(str(self.bumper_rear_left))
00581 self.bumper_state_labels[3].setPlainText(str(self.bumper_rear_right))
00582
00583
00584 if self.gyro_cal_status:
00585 self.update_check_status(self._widget.gyro_cal_chk, self.GOOD)
00586 self._widget.gyro_cal_lbl.setText('Gyro calibrated')
00587 else:
00588 self.update_check_status(self._widget.gyro_cal_chk, self.BAD)
00589 self._widget.gyro_cal_lbl.setText('Gyro NOT calibrated')
00590
00591 self._widget.gyro_x_lbl.setText('x: ' + str(1e-5*floor(1e5*self.gyro_x)))
00592 self._widget.gyro_y_lbl.setText('y: ' + str(1e-5*floor(1e5*self.gyro_y)))
00593 self._widget.gyro_z_lbl.setText('z: ' + str(1e-5*floor(1e5*self.gyro_z)))
00594
00595
00596 if not self.max_speed_known:
00597 service_name = '/mobility_base/get_max_speed'
00598 get_max_speed_srv = rospy.ServiceProxy(service_name, GetMaxSpeed)
00599
00600 try:
00601 resp = get_max_speed_srv()
00602 self.max_speed_known = True
00603 self.max_linear_actual = resp.linear
00604 self.max_angular_actual = resp.angular
00605
00606 if self.max_linear_actual <= 0 or not isfinite(self.max_linear_actual):
00607 self._widget.max_linear_lbl.setText('Unlimited')
00608 else:
00609 self._widget.max_linear_lbl.setText(str(1e-2*round(1e2*self.max_linear_actual)))
00610
00611 if self.max_angular_actual <= 0 or not isfinite(self.max_angular_actual):
00612 self._widget.max_angular_lbl.setText('Unlimited')
00613 else:
00614 self._widget.max_angular_lbl.setText(str(1e-2*round(1e2*self.max_angular_actual)))
00615
00616 except:
00617 pass
00618
00619
00620 if self.max_speed_dirty:
00621 self._widget.max_linear_txt.setText(str(self.max_linear_setting))
00622 self._widget.max_angular_txt.setText(str(self.max_angular_setting))
00623 self.max_speed_dirty = False
00624
00625
00626 if self.current_wake_time == rospy.Time(0):
00627 self._widget.wake_time_lbl.setText('Not Set')
00628 else:
00629 self._widget.wake_time_lbl.setText(time.strftime('%m/%d/%Y, %H:%M:%S', time.localtime(self.current_wake_time.to_sec())))
00630
00631 def check_joystick_valid(self):
00632 return self.joystick_data[ChannelIndex.CHAN_FORWARD] > 0 or self.joystick_data[ChannelIndex.CHAN_LATERAL] > 0 or self.joystick_data[ChannelIndex.CHAN_ROTATE] > 0 or self.joystick_data[ChannelIndex.CHAN_MODE] > 0
00633
00634 def get_mode_string(self, mode_num):
00635 if mode_num == Mode.MODE_ESTOP:
00636 return 'MODE_ESTOP'
00637 elif mode_num == Mode.MODE_DISABLED:
00638 return 'MODE_DISABLED'
00639 elif mode_num == Mode.MODE_BATTERY_LIMP_HOME:
00640 return 'MODE_BATTERY_LIMP_HOME'
00641 elif mode_num == Mode.MODE_BATTERY_CRITICAL:
00642 return 'MODE_BATTERY_CRITICAL'
00643 elif mode_num == Mode.MODE_WIRELESS:
00644 return 'MODE_WIRELESS'
00645 elif mode_num == Mode.MODE_TIMEOUT:
00646 return 'MODE_TIMEOUT'
00647 elif mode_num == Mode.MODE_VELOCITY:
00648 return 'MODE_VELOCITY'
00649 elif mode_num == Mode.MODE_VELOCITY_RAW:
00650 return 'MODE_VELOCITY_RAW'
00651 else:
00652 return ''
00653
00654 def update_checklist(self):
00655 if self.current_mode >= Mode.MODE_TIMEOUT:
00656 self.checklist_status[self.BATT_MAN] = self.GOOD
00657 self.checklist_status[self.ESTOP_MAN] = self.GOOD
00658 self.checklist_status[self.DISABLE_MAN] = self.GOOD
00659 self.checklist_status[self.JOYSTICK_MAN] = self.BAD
00660 self.checklist_status[self.BATT_COMP] = self.GOOD
00661 self.checklist_status[self.ESTOP_COMP] = self.GOOD
00662 self.checklist_status[self.DISABLE_COMP] = self.GOOD
00663 self.checklist_status[self.JOYSTICK_COMP] = self.GOOD
00664 elif self.current_mode == Mode.MODE_WIRELESS:
00665 self.checklist_status[self.BATT_MAN] = self.GOOD
00666 self.checklist_status[self.ESTOP_MAN] = self.GOOD
00667 self.checklist_status[self.DISABLE_MAN] = self.GOOD
00668 self.checklist_status[self.JOYSTICK_MAN] = self.GOOD
00669 self.checklist_status[self.BATT_COMP] = self.GOOD
00670 self.checklist_status[self.ESTOP_COMP] = self.GOOD
00671 self.checklist_status[self.DISABLE_COMP] = self.GOOD
00672 self.checklist_status[self.JOYSTICK_COMP] = self.BAD
00673 elif self.current_mode == Mode.MODE_DISABLED:
00674 self.checklist_status[self.BATT_MAN] = self.NONE
00675 self.checklist_status[self.ESTOP_MAN] = self.GOOD
00676 self.checklist_status[self.DISABLE_MAN] = self.BAD
00677 self.checklist_status[self.JOYSTICK_MAN] = self.NONE
00678 self.checklist_status[self.BATT_COMP] = self.NONE
00679 self.checklist_status[self.ESTOP_COMP] = self.GOOD
00680 self.checklist_status[self.DISABLE_COMP] = self.BAD
00681 self.checklist_status[self.JOYSTICK_COMP] = self.NONE
00682 elif self.current_mode == Mode.MODE_ESTOP:
00683 self.checklist_status[self.BATT_MAN] = self.NONE
00684 self.checklist_status[self.ESTOP_MAN] = self.BAD
00685 self.checklist_status[self.DISABLE_MAN] = self.NONE
00686 self.checklist_status[self.JOYSTICK_MAN] = self.NONE
00687 self.checklist_status[self.BATT_COMP] = self.NONE
00688 self.checklist_status[self.ESTOP_COMP] = self.BAD
00689 self.checklist_status[self.DISABLE_COMP] = self.NONE
00690 self.checklist_status[self.JOYSTICK_COMP] = self.NONE
00691 elif self.current_mode == Mode.MODE_BATTERY_CRITICAL:
00692 self.checklist_status[self.BATT_MAN] = self.BAD
00693 self.checklist_status[self.ESTOP_MAN] = self.GOOD
00694 self.checklist_status[self.DISABLE_MAN] = self.GOOD
00695 self.checklist_status[self.JOYSTICK_MAN] = self.NONE
00696 self.checklist_status[self.BATT_COMP] = self.BAD
00697 self.checklist_status[self.ESTOP_COMP] = self.GOOD
00698 self.checklist_status[self.DISABLE_COMP] = self.GOOD
00699 self.checklist_status[self.JOYSTICK_COMP] = self.NONE
00700 elif self.current_mode == Mode.MODE_BATTERY_LIMP_HOME:
00701 self.checklist_status[self.BATT_MAN] = self.GOOD
00702 self.checklist_status[self.ESTOP_MAN] = self.GOOD
00703 self.checklist_status[self.DISABLE_MAN] = self.GOOD
00704 self.checklist_status[self.JOYSTICK_MAN] = self.NONE
00705 self.checklist_status[self.BATT_COMP] = self.BAD
00706 self.checklist_status[self.ESTOP_COMP] = self.GOOD
00707 self.checklist_status[self.DISABLE_COMP] = self.GOOD
00708 self.checklist_status[self.JOYSTICK_COMP] = self.NONE
00709
00710
00711 if self.joystick_suppressed:
00712 self.checklist_status[self.SUPPRESS_COMP] = self.GOOD
00713 self.checklist_status[self.DISABLE_COMP] = self.NONE
00714 self.checklist_status[self.JOYSTICK_COMP] = self.NONE
00715 else:
00716 self.checklist_status[self.SUPPRESS_COMP] = self.NONE
00717 if (rospy.Time.now() - self.last_suppress_time).to_sec() > self.JOYSTICK_SUPPRESS_PERIOD:
00718 self.checklist_status[self.SUPPRESS_MAN] = self.GOOD
00719 else:
00720 self.checklist_status[self.SUPPRESS_MAN] = self.BAD
00721
00722
00723 if self.command_received:
00724 self.checklist_status[self.CMD_COMP] = self.GOOD
00725 else:
00726 self.checklist_status[self.CMD_COMP] = self.BAD
00727
00728
00729 if self.current_mode == Mode.MODE_TIMEOUT:
00730 self.checklist_status[self.CMD_COMP] = self.BAD
00731
00732
00733 self.update_check_status(self._widget.batt_man_chk, self.checklist_status[self.BATT_MAN])
00734 self.update_check_status(self._widget.estop_man_chk, self.checklist_status[self.ESTOP_MAN])
00735 self.update_check_status(self._widget.disable_man_chk, self.checklist_status[self.DISABLE_MAN])
00736 self.update_check_status(self._widget.joystick_man_chk, self.checklist_status[self.JOYSTICK_MAN])
00737 self.update_check_status(self._widget.suppress_man_chk, self.checklist_status[self.SUPPRESS_MAN])
00738 self.update_check_status(self._widget.batt_comp_chk, self.checklist_status[self.BATT_COMP])
00739 self.update_check_status(self._widget.estop_comp_chk, self.checklist_status[self.ESTOP_COMP])
00740 self.update_check_status(self._widget.disable_comp_chk, self.checklist_status[self.DISABLE_COMP])
00741 self.update_check_status(self._widget.joystick_comp_chk, self.checklist_status[self.JOYSTICK_COMP])
00742 self.update_check_status(self._widget.suppress_comp_chk, self.checklist_status[self.SUPPRESS_COMP])
00743 self.update_check_status(self._widget.cmd_comp_chk, self.checklist_status[self.CMD_COMP])
00744 self.update_check_status(self._widget.joystick_bind_chk, self.NONE)
00745
00746 def update_check_status(self, obj, icon_type):
00747 if icon_type == self.GOOD:
00748 obj.setPixmap(self.good_icon)
00749 elif icon_type == self.BAD:
00750 obj.setPixmap(self.bad_icon)
00751 else:
00752 obj.setPixmap(self.none_icon)
00753
00754 def update_table(self):
00755 for i in range(0, len(self.joystick_table_vals)):
00756 self.joystick_table_vals[i].setText(55)
00757
00758 def recv_mode(self, mode_msg):
00759 self.current_mode = mode_msg.mode
00760
00761 def recv_suppress(self, suppress_msg):
00762 self.suppress_dt = rospy.Time.now() - self.last_suppress_time
00763 self.last_suppress_time = rospy.Time.now()
00764
00765 def recv_twist(self, twist_msg):
00766 self.twist_dt = rospy.Time.now() - self.last_twist_time
00767 self.last_twist_time = rospy.Time.now()
00768 self.current_cmd = twist_msg
00769
00770 def recv_joystick(self, joystick_msg):
00771 self.joystick_data = joystick_msg.channels;
00772 self.last_joystick_time = rospy.Time.now()
00773
00774 def recv_bumpers(self, bumper_msg):
00775 self.bumper_front_left = bumper_msg.front_left
00776 self.bumper_front_right = bumper_msg.front_right
00777 self.bumper_rear_left = bumper_msg.rear_left
00778 self.bumper_rear_right = bumper_msg.rear_right
00779
00780 def recv_battery(self, battery_msg):
00781 self.battery_percent = battery_msg.percent
00782 self.battery_voltage = battery_msg.voltage
00783
00784 def recv_bind_status(self, bind_msg):
00785 self.joystick_bind_status = bind_msg.data
00786
00787 if bind_msg.data:
00788 if self.joystick_bind_dot_counter == 0:
00789 self._widget.joystick_bind_lbl.setText('Binding.')
00790 elif self.joystick_bind_dot_counter == 1:
00791 self._widget.joystick_bind_lbl.setText('Binding..')
00792 elif self.joystick_bind_dot_counter == 2:
00793 self._widget.joystick_bind_lbl.setText('Binding...')
00794
00795 self.joystick_bind_dot_counter = (self.joystick_bind_dot_counter + 1) % 3
00796
00797 def recv_gyro_calibrated(self, cal_msg):
00798 self.gyro_cal_status = cal_msg.data
00799
00800 def recv_imu(self, imu_msg):
00801 self.gyro_x = imu_msg.angular_velocity.x
00802 self.gyro_y = imu_msg.angular_velocity.y
00803 self.gyro_z = imu_msg.angular_velocity.z
00804
00805 def recv_wake_time(self, time_msg):
00806 self.current_wake_time = time_msg.data
00807
00808 def subscribe_topics(self):
00809 sub_joystick = rospy.Subscriber('/mobility_base/joystick_raw', JoystickRaw, self.recv_joystick)
00810 sub_suppress = rospy.Subscriber('/mobility_base/suppress_wireless', std_msgs.msg.Empty, self.recv_suppress)
00811 sub_twist = rospy.Subscriber('/mobility_base/cmd_vel', Twist, self.recv_twist)
00812 sub_mode = rospy.Subscriber('/mobility_base/mode', Mode, self.recv_mode)
00813 sub_bumpers = rospy.Subscriber('/mobility_base/bumper_states', BumperState, self.recv_bumpers)
00814 sub_battery = rospy.Subscriber('/mobility_base/battery', BatteryState, self.recv_battery)
00815 sub_bind = rospy.Subscriber('/mobility_base/bind_status', std_msgs.msg.Bool, self.recv_bind_status)
00816 sub_gyro_calibrated = rospy.Subscriber('/mobility_base/imu/is_calibrated', std_msgs.msg.Bool, self.recv_gyro_calibrated)
00817 sub_imu = rospy.Subscriber('/mobility_base/imu/data_raw', Imu, self.recv_imu)
00818 sub_wake_time = rospy.Subscriber('/mobility_base/wake_time', std_msgs.msg.Time, self.recv_wake_time)
00819
00820 def advertise_topics(self):
00821 self.pub_start_bind = rospy.Publisher('/mobility_base/bind_start', std_msgs.msg.Empty, queue_size=1)
00822 self.pub_stop_bind = rospy.Publisher('/mobility_base/bind_stop', std_msgs.msg.Empty, queue_size=1)
00823 self.pub_set_wake_time = rospy.Publisher('/mobility_base/set_wake_time', std_msgs.msg.Time, queue_size=1)
00824
00825 def init_joystick_graphics(self):
00826
00827 self.cyan_pen = QPen(QColor(0, 255, 255))
00828 self.magenta_pen = QPen(QColor(255, 0, 255))
00829 self.red_pen = QPen(QColor(255, 0, 0))
00830 self.cyan_pen.setWidth(3)
00831 self.magenta_pen.setWidth(3)
00832 self.red_pen.setWidth(3)
00833 self.stick_ind_l = QGraphicsEllipseItem()
00834 self.stick_ind_r = QGraphicsEllipseItem()
00835 self.stick_line_l = QGraphicsLineItem()
00836 self.stick_line_r = QGraphicsLineItem()
00837 self.mode_ind = QGraphicsLineItem()
00838
00839
00840 px_l = self.stick_ind_lox - self.stick_ind_radius
00841 py_l = self.stick_ind_loy - self.stick_ind_radius
00842 self.stick_ind_l.setRect(px_l, py_l, 2 * self.stick_ind_radius, 2 * self.stick_ind_radius)
00843 self.stick_ind_l.setBrush(QBrush(QColor(255, 0, 0)))
00844 self.stick_ind_l.setPen(QPen(QColor(0, 0, 0)))
00845
00846
00847 px_r = self.stick_ind_rox - self.stick_ind_radius
00848 py_r = self.stick_ind_roy - self.stick_ind_radius
00849 self.stick_ind_r.setRect(px_r, py_r, 2 * self.stick_ind_radius, 2 * self.stick_ind_radius)
00850 self.stick_ind_r.setBrush(QBrush(QColor(255, 0, 0)))
00851 self.stick_ind_r.setPen(QPen(QColor(0, 0, 0)))
00852
00853
00854 line_pen = QPen(QColor(255,0,0))
00855 line_pen.setWidth(4)
00856 self.stick_line_l.setLine(self.stick_ind_lox, self.stick_ind_loy, self.stick_ind_lox, self.stick_ind_loy)
00857 self.stick_line_l.setPen(line_pen)
00858
00859
00860 self.stick_line_r.setLine(self.stick_ind_rox, self.stick_ind_roy, self.stick_ind_rox, self.stick_ind_roy)
00861 self.stick_line_r.setPen(line_pen)
00862
00863
00864 self.mode_ind.setLine(self.mode_ind_x1, self.mode_ind_y1, self.mode_ind_x2, self.mode_ind_y2)
00865 self.mode_ind.setPen(self.cyan_pen)
00866
00867
00868 self.joystick_power_ind = []
00869 self.joystick_power_ind.append(QGraphicsLineItem(self.power_ind_x1, self.power_ind_y + 20, self.power_ind_x1, self.power_ind_y - 20))
00870 self.joystick_power_ind.append(QGraphicsLineItem(self.power_ind_x1, self.power_ind_y - 20, self.power_ind_x1 + 50, self.power_ind_y - 20))
00871 self.joystick_power_ind.append(QGraphicsLineItem(self.power_ind_x1+50, self.power_ind_y - 20, self.power_ind_x1+50, self.power_ind_y + 20))
00872 self.joystick_power_ind.append(QGraphicsLineItem(self.power_ind_x1+50, self.power_ind_y + 20, self.power_ind_x1, self.power_ind_y + 20))
00873
00874
00875 graphics_scene = QGraphicsScene()
00876 graphics_scene.addItem(self.stick_ind_l)
00877 graphics_scene.addItem(self.stick_ind_r)
00878 graphics_scene.addItem(self.stick_line_l)
00879 graphics_scene.addItem(self.stick_line_r)
00880 graphics_scene.addItem(self.mode_ind)
00881 for l in self.joystick_power_ind:
00882 l.setPen(self.red_pen)
00883 graphics_scene.addItem(l)
00884 graphics_scene.setSceneRect(0, 0, self._widget.joystickGraphicsView.width() - 4, self._widget.joystickGraphicsView.height() - 4)
00885 self._widget.joystickGraphicsView.setScene(graphics_scene)
00886 self._widget.joystickGraphicsView.setBackgroundBrush(QBrush(QImage(os.path.join(rospkg.RosPack().get_path('mobility_base_tools'), 'images', 'dx6ilabels.jpg'))))
00887 self._widget.joystickGraphicsView.show()
00888
00889 def init_bumper_graphics(self):
00890
00891
00892 self.blue_pen = QPen(QColor(0,0,255))
00893 self.blue_pen.setWidth(10)
00894
00895 self.bumper_lines = []
00896
00897
00898 self.bumper_state_labels = [QGraphicsTextItem() for i in range(0,4)]
00899 for i in range(len(self.bumper_state_labels)):
00900 self.bumper_state_labels[i].setFont(QFont('Ubuntu', 14, QFont.Bold))
00901 self.bumper_state_labels[i].setPlainText('00')
00902 self.bumper_state_labels[0].setPos(self.bumper_fl_x-10, self.bumper_fl_y + 55)
00903 self.bumper_state_labels[1].setPos(self.bumper_fr_x-10, self.bumper_fr_y + 55)
00904 self.bumper_state_labels[2].setPos(self.bumper_rl_x-10, self.bumper_rl_y - 80)
00905 self.bumper_state_labels[3].setPos(self.bumper_rr_x-10, self.bumper_rr_y - 80)
00906
00907
00908 self.bumper_line(self.bumper_fl_x - 20, self.bumper_fl_y - self.bumper_dy, True)
00909 self.bumper_line(self.bumper_fl_x - self.bumper_dx, self.bumper_fl_y - 20, False)
00910 self.bumper_line(self.bumper_fl_x + self.bumper_dx, self.bumper_fl_y - 20, False)
00911 self.bumper_line(self.bumper_fl_x - 20, self.bumper_fl_y + self.bumper_dy, True)
00912 self.bumper_line(self.bumper_fr_x - 20, self.bumper_fr_y - self.bumper_dy, True)
00913 self.bumper_line(self.bumper_fr_x - self.bumper_dx, self.bumper_fr_y - 20, False)
00914 self.bumper_line(self.bumper_fr_x + self.bumper_dx, self.bumper_fr_y - 20, False)
00915 self.bumper_line(self.bumper_fr_x - 20, self.bumper_fr_y + self.bumper_dy, True)
00916 self.bumper_line(self.bumper_rl_x - 20, self.bumper_rl_y - self.bumper_dy, True)
00917 self.bumper_line(self.bumper_rl_x - self.bumper_dx, self.bumper_rl_y - 20, False)
00918 self.bumper_line(self.bumper_rl_x + self.bumper_dx, self.bumper_rl_y - 20, False)
00919 self.bumper_line(self.bumper_rl_x - 20, self.bumper_rl_y + self.bumper_dy, True)
00920 self.bumper_line(self.bumper_rr_x - 20, self.bumper_rr_y - self.bumper_dy, True)
00921 self.bumper_line(self.bumper_rr_x - self.bumper_dx, self.bumper_rr_y - 20, False)
00922 self.bumper_line(self.bumper_rr_x + self.bumper_dx, self.bumper_rr_y - 20, False)
00923 self.bumper_line(self.bumper_rr_x - 20, self.bumper_rr_y + self.bumper_dy, True)
00924
00925
00926 graphics_scene = QGraphicsScene()
00927 for bumper in self.bumper_lines:
00928 graphics_scene.addItem(bumper)
00929 for label in self.bumper_state_labels:
00930 graphics_scene.addItem(label)
00931 graphics_scene.setSceneRect(0, 0, self._widget.bumperGraphicsView.width() - 4, self._widget.bumperGraphicsView.height() - 4)
00932 self._widget.bumperGraphicsView.setScene(graphics_scene)
00933 self._widget.bumperGraphicsView.setBackgroundBrush(QBrush(QImage(os.path.join(rospkg.RosPack().get_path('mobility_base_tools'), 'images', 'mb_top.png'))))
00934 self._widget.bumperGraphicsView.show()
00935
00936 def bumper_line(self, x, y, front):
00937 new_line = QGraphicsLineItem()
00938 if front:
00939 new_line.setLine(x, y, x+40, y)
00940 else:
00941 new_line.setLine(x, y, x, y+40)
00942 new_line.setPen(self.blue_pen)
00943 new_line.setVisible(False)
00944 self.bumper_lines.append(new_line)
00945
00946 def bumper_visible_switch(self, idx, bumper_state):
00947 if bumper_state & BumperState.BUMPER_FRONT:
00948 self.bumper_lines[idx].setVisible(True)
00949 else:
00950 self.bumper_lines[idx].setVisible(False)
00951 if bumper_state & BumperState.BUMPER_LEFT:
00952 self.bumper_lines[idx+1].setVisible(True)
00953 else:
00954 self.bumper_lines[idx+1].setVisible(False)
00955 if bumper_state & BumperState.BUMPER_RIGHT:
00956 self.bumper_lines[idx+2].setVisible(True)
00957 else:
00958 self.bumper_lines[idx+2].setVisible(False)
00959 if bumper_state & BumperState.BUMPER_REAR:
00960 self.bumper_lines[idx+3].setVisible(True)
00961 else:
00962 self.bumper_lines[idx+3].setVisible(False)
00963
00964 def reset_gui_timer(self):
00965 self.gui_update_timer = QTimer(self._widget)
00966 self.gui_update_timer.setInterval(100)
00967 self.gui_update_timer.setSingleShot(False)
00968 self.gui_update_timer.timeout.connect(lambda: self.update_gui_cb())
00969 self.gui_update_timer.start()
00970
00971 def spawn_full_gui(self):
00972 super(DiagnosticGui, self).__init__(self.context_)
00973
00974 self.setObjectName('DiagnosticGui')
00975
00976
00977 self._widget = QWidget()
00978
00979
00980 ui_file = os.path.join(rospkg.RosPack().get_path('mobility_base_tools'), 'resource', 'DiagnosticGui.ui')
00981
00982 loadUi(ui_file, self._widget)
00983
00984 self._widget.setObjectName('DiagnosticGui' + str(self.widget_count))
00985 self.widget_count += 1
00986
00987 self.context_.add_widget(self._widget)
00988
00989 def spawn_tab_gui(self):
00990 super(DiagnosticGui, self).__init__(self.context_)
00991
00992 self.setObjectName('DiagnosticGui')
00993
00994
00995 self._widget = QWidget()
00996
00997
00998 ui_file = os.path.join(rospkg.RosPack().get_path('mobility_base_tools'), 'resource', 'DiagnosticGuiTabs.ui')
00999
01000 loadUi(ui_file, self._widget)
01001
01002 self._widget.setObjectName('DiagnosticGui' + str(self.widget_count))
01003 self.widget_count += 1
01004
01005 self.context_.add_widget(self._widget)
01006
01007 def update_right_stick_indicator(self, lat_val, forward_val):
01008 horiz_val = -self.stick_ind_range_factor * (lat_val - self.stick_ind_range_mid)
01009 vert_val = -self.stick_ind_range_factor * (forward_val - self.stick_ind_range_mid)
01010 r = sqrt(horiz_val * horiz_val + vert_val * vert_val)
01011 if r > self.stick_ind_range_pix / 2:
01012 r = self.stick_ind_range_pix / 2
01013 ang = atan2(vert_val, horiz_val)
01014 px = r * cos(ang)
01015 py = r * sin(ang)
01016 self.stick_ind_r.setPos(QPoint(px, py))
01017 self.stick_line_r.setLine(self.stick_ind_rox, self.stick_ind_roy, self.stick_ind_rox + px, self.stick_ind_roy + py)
01018
01019 def update_left_stick_indicator(self, yaw_val, enable_val):
01020 horiz_val = -self.stick_ind_range_factor * (yaw_val - self.stick_ind_range_mid)
01021 vert_val = -self.stick_ind_range_factor * (enable_val - self.stick_ind_range_mid)
01022 r = sqrt(horiz_val * horiz_val + vert_val * vert_val)
01023 if r > self.stick_ind_range_pix / 2:
01024 r = self.stick_ind_range_pix / 2
01025 ang = atan2(vert_val, horiz_val)
01026 px = r * cos(ang)
01027 py = r * sin(ang)
01028 self.stick_ind_l.setPos(QPoint(px, py))
01029 self.stick_line_l.setLine(self.stick_ind_lox, self.stick_ind_loy, self.stick_ind_lox + px, self.stick_ind_loy + py)
01030
01031 def shutdown_plugin(self):
01032 pass