Go to the documentation of this file.00001 from distutils.version import LooseVersion
00002 import math
00003 import os
00004 import sys
00005 from threading import Lock
00006
00007 import python_qt_binding
00008 import python_qt_binding.QtCore as QtCore
00009 from python_qt_binding.QtCore import QEvent
00010 from python_qt_binding.QtCore import QSize
00011 from python_qt_binding.QtCore import Qt
00012 from python_qt_binding.QtCore import QTimer
00013 from python_qt_binding.QtCore import qWarning
00014 from python_qt_binding.QtCore import Slot
00015 import python_qt_binding.QtGui as QtGui
00016 from python_qt_binding.QtGui import QBrush
00017 from python_qt_binding.QtGui import QColor
00018 from python_qt_binding.QtGui import QFont
00019 from python_qt_binding.QtGui import QIcon
00020 from python_qt_binding.QtGui import QPainter
00021 from python_qt_binding.QtGui import QPen
00022 import yaml
00023
00024 from resource_retriever import get_filename
00025 import rospy
00026 from rqt_gui_py.plugin import Plugin
00027 from std_msgs.msg import Bool
00028 from std_msgs.msg import Time
00029 from std_msgs.msg import UInt8
00030
00031 from image_view2_wrapper import ComboBoxDialog
00032
00033 if LooseVersion(python_qt_binding.QT_BINDING_VERSION).version[0] >= 5:
00034 from python_qt_binding.QtWidgets import QAction
00035 from python_qt_binding.QtWidgets import QComboBox
00036 from python_qt_binding.QtWidgets import QLabel
00037 from python_qt_binding.QtWidgets import QMenu
00038 from python_qt_binding.QtWidgets import QMessageBox
00039 from python_qt_binding.QtWidgets import QSizePolicy
00040 from python_qt_binding.QtWidgets import QWidget
00041
00042 else:
00043 from python_qt_binding.QtGui import QAction
00044 from python_qt_binding.QtGui import QComboBox
00045 from python_qt_binding.QtGui import QLabel
00046 from python_qt_binding.QtGui import QMenu
00047 from python_qt_binding.QtGui import QMessageBox
00048 from python_qt_binding.QtGui import QSizePolicy
00049 from python_qt_binding.QtGui import QWidget
00050
00051
00052 class StatusLight(Plugin):
00053 """
00054 rqt plugin to show light like ultra-man's light.
00055 It subscribes std_msgs/UInt8 topic and the value means:
00056 0 == Unknown (gray)
00057 1 == Success (green)
00058 2 == Warn (yellow)
00059 """
00060 def __init__(self, context):
00061 super(StatusLight, self).__init__(context)
00062 self.setObjectName("StatusLight")
00063 self._widget = StatusLightWidget()
00064 context.add_widget(self._widget)
00065
00066 def save_settings(self, plugin_settings, instance_settings):
00067 self._widget.save_settings(plugin_settings, instance_settings)
00068
00069 def restore_settings(self, plugin_settings, instance_settings):
00070 self._widget.restore_settings(plugin_settings, instance_settings)
00071
00072 def trigger_configuration(self):
00073 self._widget.trigger_configuration()
00074
00075
00076 class StatusLightWidget(QWidget):
00077 _UNKNOWN_COLOR = QColor("#dddddd")
00078 _SUCCESS_COLOR = QColor("#18FFFF")
00079 _WARN_COLOR = QColor("#FFCA00")
00080 _ERROR_COLOR = QColor("#F44336")
00081
00082 def __init__(self):
00083 super(StatusLightWidget, self).__init__()
00084 self.lock = Lock()
00085 self.status_sub = None
00086 self.status = 0
00087 self._status_topics = []
00088 self._update_topic_timer = QTimer(self)
00089 self._update_topic_timer.timeout.connect(self.updateTopics)
00090 self._update_topic_timer.start(1000)
00091 self._active_topic = None
00092 self._dialog = ComboBoxDialog()
00093 self._update_plot_timer = QTimer(self)
00094 self._update_plot_timer.timeout.connect(self.redraw)
00095 self._update_plot_timer.start(1000 / 15)
00096
00097 def redraw(self):
00098 self.update()
00099
00100 def paintEvent(self, event):
00101 with self.lock:
00102 if self.status == 1:
00103 color = self._SUCCESS_COLOR
00104 elif self.status == 2:
00105 color = self._WARN_COLOR
00106 else:
00107 color = self._UNKNOWN_COLOR
00108 rect = event.rect()
00109 qp = QPainter()
00110 qp.begin(self)
00111 radius = min(rect.width(), rect.height()) - 100
00112 qp.setFont(QFont('Helvetica', 100))
00113 qp.setPen(QPen(QBrush(color), 50))
00114 qp.setBrush(color)
00115 qp.drawEllipse(
00116 (rect.width() - radius) / 2, (rect.height() - radius) / 2,
00117 radius, radius)
00118 qp.end()
00119 return
00120
00121 def trigger_configuration(self):
00122 self._dialog.exec_()
00123 self.setupSubscriber(self._status_topics[self._dialog.number])
00124
00125 def updateTopics(self):
00126 need_to_update = False
00127 for (topic, topic_type) in rospy.get_published_topics():
00128 if topic_type == "std_msgs/UInt8":
00129 if not topic in self._status_topics:
00130 self._status_topics.append(topic)
00131 need_to_update = True
00132 if need_to_update:
00133 self._status_topics = sorted(self._status_topics)
00134 self._dialog.combo_box.clear()
00135 for topic in self._status_topics:
00136 self._dialog.combo_box.addItem(topic)
00137 if self._active_topic:
00138 if self._active_topic not in self._status_topics:
00139 self._status_topics.append(self._active_topic)
00140 self._dialog.combo_box.addItem(self._active_topic)
00141 self._dialog.combo_box.setCurrentIndex(
00142 self._status_topics.index(self._active_topic))
00143
00144 def setupSubscriber(self, topic):
00145 if self.status_sub:
00146 self.status_sub.unregister()
00147 self.status_sub = rospy.Subscriber(topic, UInt8,
00148 self.statusCallback)
00149 self._active_topic = topic
00150
00151 def onActivated(self, number):
00152 self.setupSubscriber(self._status_topics[number])
00153
00154 def statusCallback(self, msg):
00155 self.status = msg.data
00156
00157 def save_settings(self, plugin_settings, instance_settings):
00158 if self._active_topic:
00159 instance_settings.set_value("active_topic", self._active_topic)
00160
00161 def restore_settings(self, plugin_settings, instance_settings):
00162 if instance_settings.value("active_topic"):
00163 topic = instance_settings.value("active_topic")
00164 self._dialog.combo_box.addItem(topic)
00165 self.setupSubscriber(topic)