38 from diagnostic_msgs.msg
import DiagnosticArray, DiagnosticStatus
39 from python_qt_binding
import loadUi
40 from python_qt_binding.QtCore
import QTimer, Signal, Qt, Slot
41 from python_qt_binding.QtGui
import QPalette
42 from python_qt_binding.QtWidgets
import QWidget, QTreeWidgetItem
54 NOTE: RobotMonitorWidget.shutdown function needs to be called 55 when the instance of this class terminates. 57 RobotMonitorWidget itself doesn't store previous diagnostic states. 58 It instead delegates that function to Timeline class. 65 _message_updated = Signal(dict)
66 _queue_updated = Signal()
70 :param context: plugin context hook to enable adding widgets as a 71 ROS_GUI pane, 'PluginContext' 72 :param topic: Diagnostic topic to subscribe to 'str' 75 super(RobotMonitorWidget, self).
__init__()
77 ui_file = os.path.join(rp.get_path(
'rqt_robot_monitor'),
'resource',
78 'robotmonitor_mainwidget.ui')
81 obj_name =
'Robot Monitor' 82 self.setObjectName(obj_name)
83 self.setWindowTitle(obj_name)
93 self._timeline.message_updated.connect(
95 self._timeline.queue_updated.connect(
97 self._message_updated.connect(
99 self._queue_updated.connect(
104 self._timeline_pane.pause_changed.connect(self._timeline.set_paused)
105 self._timeline_pane.position_changed.connect(self._timeline.set_position)
106 self._timeline.pause_changed.connect(self._timeline_pane.set_paused)
107 self._timeline.position_changed.connect(self._timeline_pane.set_position)
110 self._timeline_pane.show()
117 self.tree_all_devices.itemDoubleClicked.connect(self.
_tree_clicked)
118 self.warn_flattree.itemDoubleClicked.connect(self.
_tree_clicked)
119 self.err_flattree.itemDoubleClicked.connect(self.
_tree_clicked)
126 self._timer.start(1000)
128 palette = self.tree_all_devices.palette()
139 This method just calls _signal_message_updated in 'best effort' manner. 140 This method should be called by signal with DirectConnection. 145 self._message_updated.emit(status)
149 """ DiagnosticArray message callback """ 152 for name, status
in status.items():
154 path = name.split(
'/')
157 tmp_tree = self.
_tree 159 tmp_tree = tmp_tree[p]
160 tmp_tree.update(status, util.get_resource_name(name))
163 if status.level == DiagnosticStatus.WARN:
167 if (status.level == DiagnosticStatus.ERROR
or 168 status.level == DiagnosticStatus.STALE):
169 self.
_err_tree[name].update(status, name)
173 self._warn_tree.prune()
174 self._err_tree.prune()
184 self.tree_all_devices.resizeColumnToContents(0)
185 self.warn_flattree.resizeColumnToContents(0)
186 self.err_flattree.resizeColumnToContents(0)
193 This method just calls _signal_queue_updated in 'best effort' manner. 194 This method should be called by signal with DirectConnection. 199 self._queue_updated.emit()
205 levels = [max([s.level
for s
in s.values()])
for s
in self.
_timeline]
206 self._timeline_pane.set_levels(levels)
207 self._timeline_pane.redraw.emit()
211 """Overridden from QWidget""" 212 rospy.logdebug(
'RobotMonitorWidget resizeEvent')
214 self._timeline_pane.redraw.emit()
218 """ Called when an inspector window is closed """ 222 @Slot(QTreeWidgetItem, int)
225 Slot to QTreeWidget.itemDoubleClicked 227 :type item: QTreeWidgetItem 230 rospy.logdebug(
'RobotMonitorWidget _tree_clicked col=%d', column)
241 """ Update the display if it's stale """ 243 if self._timeline.has_messages:
247 time_diff = int(self._timeline.data_age)
249 msg_template =
"Last message received %s %s ago" 251 msg = msg_template % (time_diff,
"second")
253 msg = msg_template % (time_diff,
"seconds")
254 self._timeline_pane._msg_label.setText(msg)
255 if previous_stale_state != self.
_is_stale:
259 self._timeline_pane._msg_label.setText(
"No messages received")
262 """ Update the background color based on staleness """ 263 p = self.tree_all_devices.palette()
265 p.setColor(QPalette.Base, Qt.darkGray)
266 p.setColor(QPalette.AlternateBase, Qt.lightGray)
270 self.tree_all_devices.setPalette(p)
271 self.warn_flattree.setPalette(p)
272 self.err_flattree.setPalette(p)
276 This needs to be called whenever this class terminates. 277 This closes all the instances on all trees. 278 Also unregisters ROS' subscriber, stops timer. 280 rospy.logdebug(
'RobotMonitorWidget in shutdown')
282 names = self._inspectors.keys()
287 self._timeline.shutdown()
293 instance_settings.set_value(
'splitter', self.splitter.saveState())
298 if instance_settings.contains(
'splitter'):
299 self.splitter.restoreState(instance_settings.value(
'splitter'))
301 self.splitter.setSizes([100, 100, 200])