class PluginLogManager(Plugin): """ rqt_console plugin's main class. Handles communication with ros_gui and contains callbacks to handle incoming message """ def __init__(self, context): Plugin.__init__(self, context) def onCreate(self, param): layout = QGridLayout(self) layout.setContentsMargins(2, 2, 2, 2) self._rospack = rospkg.RosPack() self._model = MessageDataModel() self._proxy_model = MessageProxyModel() self._proxy_model.setSourceModel(self._model) self.__widget = ConsoleWidget(self._proxy_model, self._rospack) layout.addWidget(self.__widget, 0, 0, 0, 0) # queue to store incoming data which get flushed periodically to the model # required since QSortProxyModel can not handle a high insert rate self._message_queue = [] self._mutex = QMutex() self._timer = QTimer() self._timer.timeout.connect(self.insert_messages) self._timer.start(100) self._subscriber = None self._topic = '/rosout_agg' self._subscribe(self._topic) def queue_message(self, log_msg): """ Callback for adding an incomming message to the queue. """ if not self.__widget._paused: msg = PluginLogManager.convert_rosgraph_log_message(log_msg) with QMutexLocker(self._mutex): self._message_queue.append(msg) @staticmethod def convert_rosgraph_log_message(log_msg): msg = Message() msg.set_stamp_format('hh:mm:ss.ZZZ (yyyy-MM-dd)') msg.message = log_msg.msg msg.severity = log_msg.level msg.node = log_msg.name msg.stamp = (log_msg.header.stamp.secs, log_msg.header.stamp.nsecs) msg.topics = sorted(log_msg.topics) msg.location = log_msg.file + ':' + log_msg.function + ':' + str( log_msg.line) return msg def insert_messages(self): """ Callback for flushing incoming Log messages from the queue to the model. """ with QMutexLocker(self._mutex): msgs = self._message_queue self._message_queue = [] if msgs: self._model.insert_rows(msgs) def shutdown_plugin(self): self._subscriber.unregister() self._timer.stop() self.__widget.cleanup_browsers_on_close() def save_settings(self, plugin_settings, instance_settings): self.__widget.save_settings(plugin_settings, instance_settings) def restore_settings(self, plugin_settings, instance_settings): self.__widget.restore_settings(plugin_settings, instance_settings) def trigger_configuration(self): topics = [ t for t in rospy.get_published_topics() if t[1] == 'rosgraph_msgs/Log' ] topics.sort(key=lambda tup: tup[0]) dialog = ConsoleSettingsDialog(topics, self._rospack) (topic, message_limit) = dialog.query(self._topic, self._model.get_message_limit()) if topic != self._topic: self._subscribe(topic) if message_limit != self._model.get_message_limit(): self._model.set_message_limit(message_limit) def _subscribe(self, topic): if self._subscriber: self._subscriber.unregister() self._subscriber = rospy.Subscriber(topic, Log, self.queue_message) self._currenttopic = topic def onStart(self): pass def onPause(self): pass def onResume(self): pass def onControlModeChanged(self, mode): if mode == ControlMode.AUTOMATIC: self.setEnabled(False) else: self.setEnabled(True) def onUserChanged(self, user_info): pass def onTranslate(self, lng): pass def onEmergencyStop(self, state): pass def onDestroy(self): self.shutdown_plugin()
class Console(Plugin): """ rqt_console plugin's main class. Handles communication with ros_gui and contains callbacks to handle incoming message """ def __init__(self, context): """ :param context: plugin context hook to enable adding widgets as a ROS_GUI pane, ''PluginContext'' """ super(Console, self).__init__(context) self.setObjectName('Console') self._context = context self._model = MessageDataModel() self._proxy_model = MessageProxyModel() self._proxy_model.setSourceModel(self._model) self._widget = ConsoleWidget(self._proxy_model) if context.serial_number() > 1: self._widget.setWindowTitle( self._widget.windowTitle() + (' (%d)' % context.serial_number())) context.add_widget(self._widget) # queue to store incoming data which get flushed periodically to the model # required since QSortProxyModel can not handle a high insert rate self._message_queue = [] self._mutex = QMutex() self._timer = QTimer() self._timer.timeout.connect(self.insert_messages) self._timer.start(100) self._subscriber = None self._topic = '/rosout' self._subscribe(self._topic) def queue_message(self, log_msg): """ Callback for adding an incomming message to the queue. """ if not self._widget._paused: msg = Console.convert_rosgraph_log_message(log_msg) with QMutexLocker(self._mutex): self._message_queue.append(msg) @staticmethod def convert_rosgraph_log_message(log_msg): msg = Message() msg.set_stamp_format('hh:mm:ss.ZZZ (yyyy-MM-dd)') msg.stamp = (log_msg.stamp.sec, log_msg.stamp.nanosec) msg.message = log_msg.msg msg.severity = log_msg.level msg.node = log_msg.name msg.location = log_msg.file + ':' + log_msg.function + ':' + str(log_msg.line) return msg def insert_messages(self): """ Callback for flushing incoming Log messages from the queue to the model. """ with QMutexLocker(self._mutex): msgs = self._message_queue self._message_queue = [] if msgs: self._model.insert_rows(msgs) def shutdown_plugin(self): self._context.node.destroy_subscription(self._subscriber) self._timer.stop() self._widget.cleanup_browsers_on_close() def save_settings(self, plugin_settings, instance_settings): self._widget.save_settings(plugin_settings, instance_settings) def restore_settings(self, plugin_settings, instance_settings): self._widget.restore_settings(plugin_settings, instance_settings) def trigger_configuration(self): topics = sorted([ topic_name for topic_name, topic_types in self._context.node.get_topic_names_and_types() if 'rcl_interfaces/msg/Log' in topic_types ]) dialog = ConsoleSettingsDialog(topics) (topic, message_limit) = dialog.query(self._topic, self._model.get_message_limit()) if topic != self._topic: self._subscribe(topic) if message_limit != self._model.get_message_limit(): self._model.set_message_limit(message_limit) def _subscribe(self, topic): if self._subscriber: self._context.node.destroy_subscription(self._subscriber) self._subscriber = self._context.node.create_subscription( Log, topic, self.queue_message, qos_profile_system_default ) self._currenttopic = topic