battery_profile_frame.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 #
3 # License: BSD
4 # https://raw.github.com/yujinrobot/kobuki_desktop/master/kobuki_qtestsuite/LICENSE
5 #
6 ##############################################################################
7 # Imports
8 ##############################################################################
9 
10 import os
11 from python_qt_binding.QtCore import Signal, Slot, pyqtSlot
12 try: # indigo
13  from python_qt_binding.QtGui import QFrame, QVBoxLayout
14 except ImportError: # kinetic+ (pyqt5)
15  from python_qt_binding.QtWidgets import QFrame, QVBoxLayout
16 import math
17 
18 import rospy
19 from qt_gui_py_common.worker_thread import WorkerThread
20 from rqt_plot.plot_widget import PlotWidget
21 from kobuki_testsuite import Rotate
22 from kobuki_msgs.msg import RobotStateEvent
23 
24 # Local resource imports
25 import detail.common_rc
26 import detail.text_rc
27 from detail.battery_profile_frame_ui import Ui_battery_profile_frame
28 from full_size_data_plot import FullSizeDataPlot
29 from rqt_plot.data_plot import DataPlot
30 
31 ##############################################################################
32 # Classes
33 ##############################################################################
34 
35 class BatteryProfileFrame(QFrame):
36  def __init__(self, parent=None):
37  super(BatteryProfileFrame, self).__init__(parent)
38  self._cmd_vel_topic_name = '/mobile_base/commands/velocity'
39  self._battery_topic_name = "/mobile_base/sensors/core/battery"
40  self._ui = Ui_battery_profile_frame()
41  self._motion = None
43  self._motion_thread = None
44  self._plot_widget = None
45 
46  def setupUi(self, cmd_vel_topic_name):
47  self._ui.setupUi(self)
48  self._cmd_vel_topic_name = cmd_vel_topic_name
49  self._plot_layout = QVBoxLayout(self._ui.battery_profile_group_box)
50  self._ui.start_button.setEnabled(True)
51  self._ui.stop_button.setEnabled(False)
52  self.restore()
53 
54  def shutdown(self):
55  '''
56  Used to terminate the plugin
57  '''
58  rospy.loginfo("Kobuki TestSuite: battery test shutdown")
59  self._stop()
60 
61  ##########################################################################
62  # Widget Management
63  ##########################################################################
64 
65  def hibernate(self):
66  '''
67  This gets called when the frame goes out of focus (tab switch).
68  Disable everything to avoid running N tabs in parallel when in
69  reality we are only running one.
70  '''
71  self._stop()
72  self._plot_layout.removeWidget(self._plot_widget)
73  self._plot_widget = None
74 
75  def restore(self):
76  '''
77  Restore the frame after a hibernate.
78  '''
79  self._plot_widget = PlotWidget()
80  self._plot_widget.setWindowTitle("Battery Profile")
81  self._plot_widget.topic_edit.setText(self._battery_topic_name)
82  self._plot_layout.addWidget(self._plot_widget)
83 
85  self._data_plot.set_autoscale(y=False)
86  self._data_plot.set_ylim([0, 180])
87  self._plot_widget.switch_data_plot_widget(self._data_plot)
88 
89 
90  ##########################################################################
91  # Motion Callbacks
92  ##########################################################################
93 
94  def _run_finished(self):
95  self._ui.start_button.setEnabled(True)
96  self._ui.stop_button.setEnabled(False)
97 
98  ##########################################################################
99  # Qt Callbacks
100  ##########################################################################
101  @Slot()
103  self._ui.start_button.setEnabled(False)
104  self._ui.stop_button.setEnabled(True)
105  if not self._motion:
106  self._motion = Rotate(self._cmd_vel_topic_name)
107  self._motion.init(self._ui.angular_speed_spinbox.value())
108  if not self.robot_state_subscriber:
109  self.robot_state_subscriber = rospy.Subscriber("/mobile_base/events/robot_state", RobotStateEvent, self.robot_state_callback)
110  rospy.sleep(0.5)
111  self._plot_widget._start_time = rospy.get_time()
112  self._plot_widget.enable_timer(True)
113  try:
114  self._plot_widget.remove_topic(self._battery_topic_name)
115  except KeyError:
116  pass
117  self._plot_widget.add_topic(self._battery_topic_name)
118  self._motion_thread = WorkerThread(self._motion.execute, self._run_finished)
119  self._motion_thread.start()
120 
121  @Slot()
123  '''
124  Hardcore stoppage - straight to zero.
125  '''
126  self._stop()
127 
128  def _stop(self):
129  if self._plot_widget:
130  self._plot_widget.enable_timer(False) # pause plot rendering
131  if self._motion_thread:
132  self._motion.stop()
133  self._motion_thread.wait()
134  self._motion_thread = None
135  if self._motion:
136  self._motion.shutdown()
137  self._motion = None
138  if self.robot_state_subscriber:
139  self.robot_state_subscriber.unregister()
140  self.robot_state_subscriber = None
141  self._ui.start_button.setEnabled(True)
142  self._ui.stop_button.setEnabled(False)
143 
144  @pyqtSlot(float)
146  if self._motion:
147  self._motion.init(self._ui.angular_speed_spinbox.value())
148 
149  ##########################################################################
150  # External Slot Callbacks
151  ##########################################################################
152  @Slot(str)
154  '''
155  To be connected to the configuration dock combo box (via the main testsuite frame)
156  '''
157  self._cmd_vel_topic_name = topic_name
158  print("DudetteBattery %s" % topic_name)
159 
160  ##########################################################################
161  # Ros Callbacks
162  ##########################################################################
163 
164  def robot_state_callback(self, data):
165  if data.state == RobotStateEvent.OFFLINE:
166  self.stop()
def on_cmd_vel_topic_combo_box_currentIndexChanged(self, topic_name)
External Slot Callbacks.


kobuki_qtestsuite
Author(s): Daniel Stonier
autogenerated on Mon Jun 10 2019 13:53:02