gyro_drift_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 import numpy
12 import operator
13 from python_qt_binding.QtCore import Signal, Slot, pyqtSlot
14 try: # indigo
15  from python_qt_binding.QtGui import QFrame, QVBoxLayout
16 except ImportError: # kinetic+ (pyqt5)
17  from python_qt_binding.QtWidgets import QFrame, QVBoxLayout
18 import math
19 
20 import roslib
21 roslib.load_manifest('kobuki_qtestsuite')
22 import rospy
23 from qt_gui_py_common.worker_thread import WorkerThread
24 from kobuki_testsuite import ScanToAngle, DriftEstimation
25 from rqt_plot.plot_widget import PlotWidget
26 
27 # Local resource imports
28 import detail.common_rc
29 import detail.text_rc
30 from detail.gyro_drift_frame_ui import Ui_gyro_drift_frame
31 from rqt_plot.data_plot import DataPlot
32 
33 ##############################################################################
34 # Classes
35 ##############################################################################
36 
37 class GyroDriftFrame(QFrame):
38  def __init__(self, parent=None):
39  super(GyroDriftFrame, self).__init__(parent)
40  self._ui = Ui_gyro_drift_frame()
41  self._laser_scan_angle_topic_name = '/laser_scan_angle'
42  self._gyro_scan_angle_topic_name = '/gyro_scan_angle'
43  self._error_scan_angle_topic_name = '/error_scan_angle'
44  self._cmd_vel_topic_name = '/mobile_base/commands/velocity'
45  self._gyro_topic_name = '/mobile_base/sensors/imu_data'
46  self._motion = None
47  self._scan_to_angle = None
48  self._motion_thread = None
49  self._plot_widget = None
50  self._plot_widget_live = None
51 
52  def setupUi(self):
53  self._ui.setupUi(self)
54  self._plot_layout = QVBoxLayout(self._ui.scan_angle_group_box)
55  self._ui.start_button.setEnabled(True)
56  self._ui.stop_button.setEnabled(False)
57 
58  def shutdown(self):
59  '''
60  Used to terminate the plugin
61  '''
62  rospy.loginfo("Kobuki TestSuite: gyro drift shutdown")
63  self._stop()
64 
65  ##########################################################################
66  # Widget Management
67  ##########################################################################
68 
69  def _pause_plots(self):
70  '''
71  Pause plots, more importantly, pause greedy plot rendering
72  '''
73  if self._plot_widget:
74  self._plot_widget.enable_timer(False)
75  if self._plot_widget_live:
76  self._plot_widget_live.enable_timer(False)
77 
78  def hibernate(self):
79  '''
80  This gets called when the frame goes out of focus (tab switch).
81  Disable everything to avoid running N tabs in parallel when in
82  reality we are only running one.
83  '''
84  self._stop()
85  self._plot_layout.removeWidget(self._plot_widget)
86  self._plot_layout.removeWidget(self._plot_widget_live)
87  self._plot_widget = None
88  self._plot_widget_live = None
89 
90  def restore(self):
91  '''
92  Restore the frame after a hibernate.
93  '''
94  self._plot_widget = PlotWidget()
95  self._plot_widget.setWindowTitle("Error")
96  self._plot_layout.addWidget(self._plot_widget)
97  self._plot_widget.switch_data_plot_widget(DataPlot(self._plot_widget))
98  self._plot_widget.data_plot.dynamic_range = True
100  self._plot_widget_live.setWindowTitle("Live Graphs")
101  self._plot_widget_live.switch_data_plot_widget(DataPlot(self._plot_widget_live))
102  self._plot_layout.addWidget(self._plot_widget_live)
103 
104  ##########################################################################
105  # Qt Callbacks
106  ##########################################################################
107  @Slot()
109  self._ui.start_button.setEnabled(False)
110  self._ui.stop_button.setEnabled(True)
111  if not self._scan_to_angle:
112  self._scan_to_angle = ScanToAngle('/scan',self._laser_scan_angle_topic_name)
113  if not self._motion:
115  self._motion.init(self._ui.angular_speed_spinbox.value())
116  rospy.sleep(0.5)
117  self._plot_widget._start_time = rospy.get_time()
118  self._plot_widget.enable_timer(True)
119  try:
120  self._plot_widget.remove_topic(self._error_scan_angle_topic_name+'/scan_angle')
121  self._plot_widget_live.remove_topic(self._laser_scan_angle_topic_name+'/scan_angle')
122  self._plot_widget_live.remove_topic(self._gyro_scan_angle_topic_name+'/scan_angle')
123  self._plot_widget_live.remove_topic(self._cmd_vel_topic_name+'/angular/z')
124  except KeyError:
125  pass
126  self._plot_widget_live.add_topic(self._cmd_vel_topic_name+'/angular/z')
127  self._plot_widget_live.add_topic(self._laser_scan_angle_topic_name+'/scan_angle')
128  self._plot_widget_live.add_topic(self._gyro_scan_angle_topic_name+'/scan_angle')
129  self._plot_widget.add_topic(self._error_scan_angle_topic_name+'/scan_angle')
130  self._motion_thread = WorkerThread(self._motion.execute, None)
131  self._motion_thread.start()
132 
133  @Slot()
135  self._stop()
136 
137  def _stop(self):
138  self._pause_plots()
139  if self._scan_to_angle:
140  self._scan_to_angle.shutdown()
141  self._scan_to_angle = None
142  if self._motion:
143  self._motion.stop()
144  if self._motion_thread:
145  self._motion_thread.wait()
146  self._motion_thread = None
147  if self._motion:
148  self._motion.shutdown()
149  self._motion = None
150  self._ui.start_button.setEnabled(True)
151  self._ui.stop_button.setEnabled(False)
152 
153  @pyqtSlot(float)
155  if self._motion:
156  self._motion.init(self._ui.angular_speed_spinbox.value())
157 


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