37 from python_qt_binding
import loadUi
38 from python_qt_binding.QtWidgets
import QWidget, QGraphicsScene, QLabel, QGraphicsEllipseItem, QGraphicsLineItem, QGraphicsTextItem
39 from python_qt_binding.QtCore
import Qt, Signal, QTimer, QDateTime, QDate, QTime, QPoint
40 from python_qt_binding.QtGui
import QPixmap, QFont, QPen, QColor, QBrush, QImage
45 from mobility_base_core_msgs.msg
import Mode, JoystickRaw
46 from rospy.rostime
import Time
47 from geometry_msgs.msg
import Twist
49 from mobility_base_core_msgs.msg
import BumperState
50 from mobility_base_core_msgs.msg
import BatteryState
51 from sensor_msgs.msg
import Imu
54 from mobility_base_core_msgs.srv
import GetMaxSpeed, SetMaxSpeed
55 from numpy
import isfinite
56 from mobility_base_core_msgs.srv
import SetMaxSpeedRequest
97 last_suppress_time = Time()
98 last_twist_time = Time()
99 gui_update_timer = QTimer()
103 joystick_table_vals = []
104 joystick_channel_text = [
'CHAN_ENABLE: ',
'CHAN_ROTATE: ',
'CHAN_FORWARD: ',
'CHAN_LATERAL: ',
'CHAN_MODE: ',
'CHAN_EXTRA: ']
105 joystick_bind_status =
False 106 joystick_bind_dot_counter = 0
112 JOYSTICK_SUPPRESS_PERIOD = 0.2
113 CMD_VEL_TIMEOUT_PERIOD = 0.2
114 joystick_suppressed =
False 115 command_received =
False 116 current_cmd = Twist()
122 good_icon = QPixmap()
123 none_icon = QPixmap()
131 checklist_status = []
146 bumper_front_left = 0
147 bumper_front_right = 0
149 bumper_rear_right = 0
152 gyro_cal_status =
False 157 cal_time = rospy.Time(0)
160 max_speed_known =
False 161 max_speed_dirty =
True 162 max_linear_actual = 0.0
163 max_angular_actual = 0.0
164 max_linear_setting = 0.0
165 max_angular_setting = 0.0
168 current_wake_time = rospy.Time(0)
175 is_currently_tab =
False 181 base_connected =
False 182 last_joystick_time = rospy.Time(0)
189 stick_ind_range_pix = 88.0
190 stick_ind_range_max = JoystickRaw.MAX
191 stick_ind_range_min = JoystickRaw.MIN
192 stick_ind_range_mid = JoystickRaw.CENTER
193 stick_ind_range_factor = stick_ind_range_pix / (stick_ind_range_max - stick_ind_range_min)
212 joystick_table_left_edge = 440
213 joystick_table_top_edge = 525
214 twist_table_left_edge = 700
215 twist_table_top_edge = 580
216 battery_table_left_edge = 700
217 battery_table_top_edge = 730
219 _deferred_fit_in_view = Signal()
222 super(DiagnosticGui, self).
__init__(context)
234 if gui_type ==
'full':
250 datetime_now = QDateTime(QDate.currentDate(), QTime.currentTime())
251 self._widget.absolute_wake_time_obj.setDateTime(datetime_now)
252 temp_time = self._widget.absolute_wake_time_obj.time()
253 temp_time = QTime(temp_time.hour(), temp_time.minute())
254 self._widget.absolute_wake_time_obj.setTime(temp_time)
258 self._widget.disconnected_lbl.setVisible(
False)
260 self._widget.disconnected_lbl.setVisible(
True)
261 self._widget.disconnected_lbl.setText(
'<font color=#FF0000>NOT CONNECTED</font>')
277 self.bad_icon.load(os.path.join(rospkg.RosPack().get_path(
'mobility_base_tools'),
'images',
'bad.png'))
278 self.good_icon.load(os.path.join(rospkg.RosPack().get_path(
'mobility_base_tools'),
'images',
'good.png'))
279 self.none_icon.load(os.path.join(rospkg.RosPack().get_path(
'mobility_base_tools'),
'images',
'none.png'))
305 self.joystick_table_heading.setText(
'Raw Joystick Data')
306 self.joystick_table_heading.setFont(QFont(
'Ubuntu', 11, QFont.Bold))
307 self.joystick_table_heading.move(left, top)
318 self.twist_table_heading.setText(
'Current Twist Command')
319 self.twist_table_heading.setFont(QFont(
'Ubuntu', 11, QFont.Bold))
320 self.twist_table_heading.move(left + 260, top)
335 self.battery_heading.setText(
'Current Battery State')
336 self.battery_heading.setFont(QFont(
'Ubuntu', 11, QFont.Bold))
337 self.battery_heading.move(left + 260, top + 150)
339 self.battery_label.move(left + 260, top + 150 +30)
340 self.battery_label.setText(
'000 %')
342 self.battery_voltage_label.move(left + 260, top + 150 +60)
343 self.battery_voltage_label.setText(
'00.00 V')
344 self.battery_voltage_label.setFixedWidth(200)
348 self.mode_heading.setFont(QFont(
'Ubuntu', 11, QFont.Bold))
349 self.mode_heading.move(left, top + 225)
350 self.mode_heading.setText(
'Current Mode')
352 self.mode_label.move(left + 120, top + 225)
353 self.mode_label.setText(
'XXXXXXXXXXXXXXXXXXXXXX')
356 self._widget.start_bind_btn.clicked.connect(self.
start_bind)
357 self._widget.stop_bind_btn.clicked.connect(self.
stop_bind)
359 self._widget.gyro_cal_btn.clicked.connect(self.
cal_gyro)
360 self._widget.clear_cal_btn.clicked.connect(self.
clear_cal)
364 self._widget.set_speed_btn.clicked.connect(self.
set_max_speed)
382 self.pub_start_bind.publish(std_msgs.msg.Empty())
385 self.pub_stop_bind.publish(std_msgs.msg.Empty())
388 gyro_cal_srv = rospy.ServiceProxy(
'/mobility_base/imu/calibrate', std_srvs.srv.Empty)
397 clear_cal_srv = rospy.ServiceProxy(
'/mobility_base/imu/clear_cal', std_srvs.srv.Empty)
405 float_val = float(self._widget.max_linear_txt.text())
416 float_val = float(self._widget.max_angular_txt.text())
426 set_max_speed_srv = rospy.ServiceProxy(
'/mobility_base/set_max_speed', SetMaxSpeed)
427 req = SetMaxSpeedRequest()
431 set_max_speed_srv(req)
437 set_max_speed_srv = rospy.ServiceProxy(
'/mobility_base/set_max_speed', SetMaxSpeed)
438 req = SetMaxSpeedRequest()
439 req.linear = float(
'nan')
440 req.angular = float(
'nan')
442 set_max_speed_srv(req)
451 self._widget.wake_time_days_txt.setText(str(self.
rel_wake_days))
457 self._widget.wake_time_hours_txt.setText(str(self.
rel_wake_hours))
469 self._widget.wake_time_secs_txt.setText(str(self.
rel_wake_secs))
472 new_wake_time = std_msgs.msg.Time()
474 new_wake_time.data = rospy.Time.now() + rospy.Duration(rel_wake_time)
475 self.pub_set_wake_time.publish(new_wake_time)
478 self.pub_set_wake_time.publish(rospy.Time(self._widget.absolute_wake_time_obj.dateTime().toTime_t()))
481 self.pub_set_wake_time.publish(rospy.Time(0))
491 if self._widget.height() > 830
and self._widget.width() > 1205:
493 self.context_.remove_widget(self.
_widget)
496 if self._widget.height() < 810
or self._widget.width() < 1185:
498 self.context_.remove_widget(self.
_widget)
504 self._widget.disconnected_lbl.setText(
'<font color=#FF0000>NOT CONNECTED</font>')
505 self._widget.disconnected_lbl.setVisible(
True)
510 self._widget.disconnected_lbl.setVisible(
False)
517 if (rospy.Time.now() - self.
cal_time).to_sec() > 5.0:
518 self._widget.gyro_cal_btn.setEnabled(
True)
519 self._widget.gyro_cal_btn.setText(
'Calibrate')
522 self._widget.gyro_cal_btn.setEnabled(
False)
523 self._widget.gyro_cal_btn.setText(str(5 - 0.1*floor(10*(rospy.Time.now() - self.
cal_time).to_sec())))
530 self._widget.joystick_bind_lbl.setText(
'')
539 self._widget.joystick_bind_lbl.setText(
'Joystick bound')
547 self._widget.modeLabel.setText(
"0 (Computer)")
550 self._widget.modeLabel.setText(
"1 (Manual)")
558 self.
twist_table_vals[0].setText(str(0.01 * floor(100 * self.current_cmd.linear.x)))
559 self.
twist_table_vals[1].setText(str(0.01 * floor(100 * self.current_cmd.linear.y)))
560 self.
twist_table_vals[2].setText(str(0.01 * floor(100 * self.current_cmd.angular.z)))
568 self.battery_voltage_label.setText(str(0.01 * floor(100 * self.
battery_voltage)) +
' V')
586 self._widget.gyro_cal_lbl.setText(
'Gyro calibrated')
589 self._widget.gyro_cal_lbl.setText(
'Gyro NOT calibrated')
591 self._widget.gyro_x_lbl.setText(
'x: ' + str(1e-5*floor(1e5*self.
gyro_x)))
592 self._widget.gyro_y_lbl.setText(
'y: ' + str(1e-5*floor(1e5*self.
gyro_y)))
593 self._widget.gyro_z_lbl.setText(
'z: ' + str(1e-5*floor(1e5*self.
gyro_z)))
597 service_name =
'/mobility_base/get_max_speed' 598 get_max_speed_srv = rospy.ServiceProxy(service_name, GetMaxSpeed)
601 resp = get_max_speed_srv()
607 self._widget.max_linear_lbl.setText(
'Unlimited')
612 self._widget.max_angular_lbl.setText(
'Unlimited')
627 self._widget.wake_time_lbl.setText(
'Not Set')
629 self._widget.wake_time_lbl.setText(time.strftime(
'%m/%d/%Y, %H:%M:%S', time.localtime(self.current_wake_time.to_sec())))
635 if mode_num == Mode.MODE_ESTOP:
637 elif mode_num == Mode.MODE_DISABLED:
638 return 'MODE_DISABLED' 639 elif mode_num == Mode.MODE_BATTERY_LIMP_HOME:
640 return 'MODE_BATTERY_LIMP_HOME' 641 elif mode_num == Mode.MODE_BATTERY_CRITICAL:
642 return 'MODE_BATTERY_CRITICAL' 643 elif mode_num == Mode.MODE_WIRELESS:
644 return 'MODE_WIRELESS' 645 elif mode_num == Mode.MODE_TIMEOUT:
646 return 'MODE_TIMEOUT' 647 elif mode_num == Mode.MODE_VELOCITY:
648 return 'MODE_VELOCITY' 649 elif mode_num == Mode.MODE_VELOCITY_RAW:
650 return 'MODE_VELOCITY_RAW' 747 if icon_type == self.
GOOD:
749 elif icon_type == self.
BAD:
789 self._widget.joystick_bind_lbl.setText(
'Binding.')
791 self._widget.joystick_bind_lbl.setText(
'Binding..')
793 self._widget.joystick_bind_lbl.setText(
'Binding...')
809 sub_joystick = rospy.Subscriber(
'/mobility_base/joystick_raw', JoystickRaw, self.
recv_joystick)
810 sub_suppress = rospy.Subscriber(
'/mobility_base/suppress_wireless', std_msgs.msg.Empty, self.
recv_suppress)
811 sub_twist = rospy.Subscriber(
'/mobility_base/cmd_vel', Twist, self.
recv_twist)
812 sub_mode = rospy.Subscriber(
'/mobility_base/mode', Mode, self.
recv_mode)
813 sub_bumpers = rospy.Subscriber(
'/mobility_base/bumper_states', BumperState, self.
recv_bumpers)
814 sub_battery = rospy.Subscriber(
'/mobility_base/battery', BatteryState, self.
recv_battery)
815 sub_bind = rospy.Subscriber(
'/mobility_base/bind_status', std_msgs.msg.Bool, self.
recv_bind_status)
816 sub_gyro_calibrated = rospy.Subscriber(
'/mobility_base/imu/is_calibrated', std_msgs.msg.Bool, self.
recv_gyro_calibrated)
817 sub_imu = rospy.Subscriber(
'/mobility_base/imu/data_raw', Imu, self.
recv_imu)
818 sub_wake_time = rospy.Subscriber(
'/mobility_base/wake_time', std_msgs.msg.Time, self.
recv_wake_time)
821 self.
pub_start_bind = rospy.Publisher(
'/mobility_base/bind_start', std_msgs.msg.Empty, queue_size=1)
822 self.
pub_stop_bind = rospy.Publisher(
'/mobility_base/bind_stop', std_msgs.msg.Empty, queue_size=1)
823 self.
pub_set_wake_time = rospy.Publisher(
'/mobility_base/set_wake_time', std_msgs.msg.Time, queue_size=1)
830 self.cyan_pen.setWidth(3)
831 self.magenta_pen.setWidth(3)
832 self.red_pen.setWidth(3)
843 self.stick_ind_l.setBrush(QBrush(QColor(255, 0, 0)))
844 self.stick_ind_l.setPen(QPen(QColor(0, 0, 0)))
850 self.stick_ind_r.setBrush(QBrush(QColor(255, 0, 0)))
851 self.stick_ind_r.setPen(QPen(QColor(0, 0, 0)))
854 line_pen = QPen(QColor(255,0,0))
857 self.stick_line_l.setPen(line_pen)
861 self.stick_line_r.setPen(line_pen)
875 graphics_scene = QGraphicsScene()
880 graphics_scene.addItem(self.
mode_ind)
883 graphics_scene.addItem(l)
884 graphics_scene.setSceneRect(0, 0, self._widget.joystickGraphicsView.width() - 4, self._widget.joystickGraphicsView.height() - 4)
885 self._widget.joystickGraphicsView.setScene(graphics_scene)
886 self._widget.joystickGraphicsView.setBackgroundBrush(QBrush(QImage(os.path.join(rospkg.RosPack().get_path(
'mobility_base_tools'),
'images',
'dx6ilabels.jpg'))))
887 self._widget.joystickGraphicsView.show()
893 self.blue_pen.setWidth(10)
926 graphics_scene = QGraphicsScene()
928 graphics_scene.addItem(bumper)
930 graphics_scene.addItem(label)
931 graphics_scene.setSceneRect(0, 0, self._widget.bumperGraphicsView.width() - 4, self._widget.bumperGraphicsView.height() - 4)
932 self._widget.bumperGraphicsView.setScene(graphics_scene)
933 self._widget.bumperGraphicsView.setBackgroundBrush(QBrush(QImage(os.path.join(rospkg.RosPack().get_path(
'mobility_base_tools'),
'images',
'mb_top.png'))))
934 self._widget.bumperGraphicsView.show()
937 new_line = QGraphicsLineItem()
939 new_line.setLine(x, y, x+40, y)
941 new_line.setLine(x, y, x, y+40)
943 new_line.setVisible(
False)
944 self.bumper_lines.append(new_line)
947 if bumper_state & BumperState.BUMPER_FRONT:
951 if bumper_state & BumperState.BUMPER_LEFT:
955 if bumper_state & BumperState.BUMPER_RIGHT:
959 if bumper_state & BumperState.BUMPER_REAR:
966 self.gui_update_timer.setInterval(100)
967 self.gui_update_timer.setSingleShot(
False)
968 self.gui_update_timer.timeout.connect(
lambda: self.
update_gui_cb())
969 self.gui_update_timer.start()
974 self.setObjectName(
'DiagnosticGui')
980 ui_file = os.path.join(rospkg.RosPack().get_path(
'mobility_base_tools'),
'resource',
'DiagnosticGui.ui')
984 self._widget.setObjectName(
'DiagnosticGui' + str(self.
widget_count))
987 self.context_.add_widget(self.
_widget)
992 self.setObjectName(
'DiagnosticGui')
998 ui_file = os.path.join(rospkg.RosPack().get_path(
'mobility_base_tools'),
'resource',
'DiagnosticGuiTabs.ui')
1002 self._widget.setObjectName(
'DiagnosticGui' + str(self.
widget_count))
1005 self.context_.add_widget(self.
_widget)
1010 r = sqrt(horiz_val * horiz_val + vert_val * vert_val)
1013 ang = atan2(vert_val, horiz_val)
1016 self.stick_ind_r.setPos(QPoint(px, py))
1022 r = sqrt(horiz_val * horiz_val + vert_val * vert_val)
1025 ang = atan2(vert_val, horiz_val)
1028 self.stick_ind_l.setPos(QPoint(px, py))