Пример #1
0
    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._rospack = rospkg.RosPack()

        self._model = MessageDataModel()
        self._proxy_model = MessageProxyModel()
        self._proxy_model.setSourceModel(self._model)

        self._widget = ConsoleWidget(self._proxy_model, self._rospack)
        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_agg'
        self._subscribe(self._topic)
Пример #2
0
    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._datamodel = MessageDataModel()
        self._proxymodel = MessageProxyModel()
        self._proxymodel.setSourceModel(self._datamodel)

        self._mainwindow = ConsoleWidget(self._proxymodel)
        if context.serial_number() > 1:
            self._mainwindow.setWindowTitle(self._mainwindow.windowTitle() +
                                            (' (%d)' %
                                             context.serial_number()))
        context.add_widget(self._mainwindow)

        self._consolesubscriber = ConsoleSubscriber(self.message_callback)

        # Timer and Mutex for flushing recieved messages to datamodel.
        # Required since QSortProxyModel can not handle a high insert rate
        self._mutex = QMutex()
        self._timer = QTimer()
        self._timer.timeout.connect(self.insert_messages)
        self._timer.start(100)
Пример #3
0
    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)
Пример #4
0
    def __init__(self):
        """
        :param context: plugin context hook to enable adding widgets
                        as a ROS_GUI pane, ''PluginContext''
        """

        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)

        # 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)
Пример #5
0
    def __init__(self, context, icon_paths=None, minimal=True):
        ok_icon = ['bg-green.svg', 'ic-console.svg']
        warn_icon = ['bg-yellow.svg', 'ic-console.svg', 'ol-warn-badge.svg']
        err_icon = ['bg-red.svg', 'ic-console.svg', 'ol-err-badge.svg']
        stale_icon = ['bg-grey.svg', 'ic-console.svg', 'ol-stale-badge.svg']

        icons = [ok_icon, warn_icon, err_icon, stale_icon]

        super(ConsoleDashWidget, self).__init__('Console Widget', icons, icon_paths=icon_paths)

        self.minimal = minimal
        self.setFixedSize(self._icons[0].actualSize(QSize(50, 30)))

        self._datamodel = MessageDataModel()
        self._proxymodel = MessageProxyModel()
        self._proxymodel.setSourceModel(self._datamodel)

        self._mutex = QMutex()
        self._subscriber = ConsoleSubscriber(self._message_cb)

        self._console = None
        self.context = context
        self.clicked.connect(self._show_console)

        self.update_state(0)
        self._timer = QTimer()
        self._timer.timeout.connect(self._insert_messages)
        self._timer.start(100)

        if self._console is None:
            self._console = ConsoleWidget(self._proxymodel, self.minimal)
            self._console.destroyed.connect(self._console_destroyed)
        self._console_shown = False
        self.setToolTip("Rosout")
Пример #6
0
    def __init__(self, context, icon_paths=[]):
        self._graveyard = []
        ok_icon = ['bg-green.svg', 'ic-diagnostics.svg']
        warn_icon = [
            'bg-yellow.svg', 'ic-diagnostics.svg', 'ol-warn-badge.svg'
        ]
        err_icon = ['bg-red.svg', 'ic-diagnostics.svg', 'ol-err-badge.svg']
        stale_icon = [
            'bg-grey.svg', 'ic-diagnostics.svg', 'ol-stale-badge.svg'
        ]

        icons = [ok_icon, warn_icon, err_icon, stale_icon]

        super(MonitorDashWidget, self).__init__('MonitorWidget',
                                                icons,
                                                icon_paths=icon_paths)

        self.setFixedSize(self._icons[0].actualSize(QSize(50, 30)))

        self._monitor = None
        self._close_mutex = QMutex()
        self._show_mutex = QMutex()

        self._last_update = rospy.Time.now()

        self.context = context
        self.clicked.connect(self._show_monitor)

        self._monitor_shown = False
        self.setToolTip('Diagnostics')

        self._diagnostics_toplevel_state_sub = rospy.Subscriber(
            'diagnostics_toplevel_state', DiagnosticStatus,
            self.toplevel_state_callback)
        self._top_level_state = -1
        self._stall_timer = QTimer()
        self._stall_timer.timeout.connect(self._stalled)
        self._stalled()
        self._plugin_settings = None
        self._instance_settings = None
Пример #7
0
    def __init__(self, context, camera_topic='/image_raw', name='camera'):
        self._icons = [['bg-grey.svg', 'ol-play-badge.svg']]
        super(CameraViewDashWidget, self).__init__("View" + name,
                                                   icons=self._icons,
                                                   icon_paths=None)
        self.context = context
        self.update_state(0)

        self._cam_view = CameraViewWidget(camera_topic, name)

        self._cam_view_shown = False
        self.clicked.connect(self._show_cam_view)
        self._show_mutex = QMutex()
Пример #8
0
    def __init__(self, context, name='NavView', icon_paths=None):
        self._icons = [['bg-grey.svg', 'ic-navigation.svg']]
        super(NavViewDashWidget, self).__init__(name,
                                                icons=self._icons,
                                                suppress_overlays=True,
                                                icon_paths=icon_paths)
        self.context = context
        self.update_state(0)
        self.setFixedSize(self._icons[0].actualSize(QSize(50, 30)))

        self._navview = None
        self._navview_shown = False
        self.clicked.connect(self._show_navview)
        self._show_mutex = QMutex()
Пример #9
0
    def __init__(self, context):
        super(View, self).__init__(context)
        self.setObjectName('UCTFView')

        self._widget = Widget()
        if context.serial_number() > 1:
            self._widget.setWindowTitle(self._widget.windowTitle() +
                                        (' (%d)' % context.serial_number()))
        context.add_widget(self._widget)

        self._update_queue = []
        self._mutex = QMutex()

        self.subscribers = {}
        self._vehicle_types = {}
        self._received_msg_types = []
        self._subscribe('blue', GROUND_CONTROL_PORT_BLUE)
        self._subscribe('gold', GROUND_CONTROL_PORT_GOLD)

        self._timer = QTimer()
        self._timer.timeout.connect(self._update_model)
        self._timer.start(40)
Пример #10
0
    def __init__(self, qsettings):
        super(SettingsProxy, self).__init__()
        self.setObjectName('SettingsProxy')

        self._qsettings = qsettings
        self._mutex = QMutex(QMutex.Recursive)
Пример #11
0
    def __init__(self, context):
        super(QueryPlugin, self).__init__(context)

        self.learner_list = None
        self.finnish_help = None

        # Initialize subscriber for experiment starting
        self.experiment_subscriber = rospy.Subscriber('start_experiment',\
                                                      ExperimentTrigger,\
                                                      self._start_experiment)

        parameters_available = \
            rospy.has_param('/experiment_config') and\
            rospy.has_param('/experiment_intro') and\
            rospy.has_param('/training_intro') and\
            rospy.has_param('/teaching_intro') and\
            rospy.has_param('/teaching_continuation') and\
            rospy.has_param('/experiment_outro')

        if parameters_available:
            self.experiment_config = rospy.get_param('/experiment_config')
            self.experiment_intro = rospy.get_param('/experiment_intro')
            self.training_intro = rospy.get_param('/training_intro')
            self.teaching_intro = rospy.get_param('/teaching_intro')
            self.teaching_continuation = \
                rospy.get_param('/teaching_continuation')
            self.experiment_outro = rospy.get_param('/experiment_outro')
        else:
            rospy.logerr('Parameters needed are not available')
            exit(5)

        # Synchronization primitives for the Keyboard event
        self.keyboard_condition = QWaitCondition()
        self.keyboard_lock = QMutex()
        self.last_key_pressed = None

        # Synchronization primitives for the Phase event
        self.phase_condition = QWaitCondition()
        self.phase_lock = QMutex()
        self.sm = -1  # ID of the state in the State Machine
        self.training_counter = -1  # how many learners have been used

        # Initialize and start the LearnerThread
        self.learner_thread = LearnerThread(self)
        self.learner_thread.show_question.connect(self._set_question_text)
        self.learner_thread.flash_question.connect\
            (self._flash_question_background)
        self.learner_thread.flash_label.connect(self._flash_label)
        self.learner_thread.show_fixed.connect(self._set_fixed_text)
        self.learner_thread.show_tab.connect(self._set_tab)
        self.learner_thread.show_score.connect(self._set_score)
        self.learner_thread.show_score_outro.connect(self._set_score_outro)
        self.learner_thread.start()

        # Give QObjects reasonable names
        self.setObjectName('Query plugin')

        # Create the Widget
        self._widget = ResponsiveWidget(self)
        self._widget.press_enter.connect(self._step_state_machine)

        # Get the UI file
        ui_file = os.path.join(rospkg.RosPack().get_path('learner'), \
            'resources', 'learner.ui')
        loadUi(ui_file, self._widget)

        # Get the pictures for the instruction label
        picture_paths = list()
        neutral_picture_path = os.path.join(rospkg.RosPack().get_path('learner'), \
            'resources', 'drawing.png')

        picture_paths.append(os.path.join(rospkg.RosPack().get_path('learner'), \
            'resources', 'drawing_dunno.png'))
        picture_paths.append(os.path.join(rospkg.RosPack().get_path('learner'), \
            'resources', 'drawing_no.png'))
        picture_paths.append(os.path.join(rospkg.RosPack().get_path('learner'), \
            'resources', 'drawing_yes.png'))

        self.pictures = list()
        self.neutral_picture = QPixmap(neutral_picture_path)

        for p in picture_paths:
            self.pictures.append(QPixmap(p))

        # Give QObjects reasonable names
        self._widget.setObjectName('Query widget')

        # Add widget to the user interface
        context.add_widget(self._widget)

        # Create the response buttons
        button_size_policy = QSizePolicy(QSizePolicy.Expanding,
                                         QSizePolicy.Expanding)

        # Set up the labels
        self._widget.fixed_label.setWordWrap(True)
        self._widget.fixed_label.setFont(QFont("Sans Serif", 30))
        self._widget.question_label.setWordWrap(True)
        self._widget.question_label.setFont(QFont("Sans Serif", 30))
        self._widget.intro_label.setWordWrap(True)
        self._widget.intro_label.setFont(QFont("Sans Serif", 30))
        self._widget.score_intro_label.setWordWrap(True)
        self._widget.score_intro_label.setFont(QFont("Sans Serif", 20))
        self._widget.score_label.setWordWrap(True)
        self._widget.score_label.setFont(QFont("Sans Serif", 38))
        self._widget.score_outro_label.setWordWrap(True)
        self._widget.score_outro_label.setFont(QFont("Sans Serif", 24))

        # Clear the first page label
        self._widget.intro_label.setText("")

        # Activate starting tab
        self._widget.tab_manager.setCurrentIndex(1)

        # Activate keyboard grabber
        self._widget.grabKeyboard()
Пример #12
0
class QueryPlugin(Plugin):
    def __init__(self, context):
        super(QueryPlugin, self).__init__(context)

        self.learner_list = None
        self.finnish_help = None

        # Initialize subscriber for experiment starting
        self.experiment_subscriber = rospy.Subscriber('start_experiment',\
                                                      ExperimentTrigger,\
                                                      self._start_experiment)

        parameters_available = \
            rospy.has_param('/experiment_config') and\
            rospy.has_param('/experiment_intro') and\
            rospy.has_param('/training_intro') and\
            rospy.has_param('/teaching_intro') and\
            rospy.has_param('/teaching_continuation') and\
            rospy.has_param('/experiment_outro')

        if parameters_available:
            self.experiment_config = rospy.get_param('/experiment_config')
            self.experiment_intro = rospy.get_param('/experiment_intro')
            self.training_intro = rospy.get_param('/training_intro')
            self.teaching_intro = rospy.get_param('/teaching_intro')
            self.teaching_continuation = \
                rospy.get_param('/teaching_continuation')
            self.experiment_outro = rospy.get_param('/experiment_outro')
        else:
            rospy.logerr('Parameters needed are not available')
            exit(5)

        # Synchronization primitives for the Keyboard event
        self.keyboard_condition = QWaitCondition()
        self.keyboard_lock = QMutex()
        self.last_key_pressed = None

        # Synchronization primitives for the Phase event
        self.phase_condition = QWaitCondition()
        self.phase_lock = QMutex()
        self.sm = -1  # ID of the state in the State Machine
        self.training_counter = -1  # how many learners have been used

        # Initialize and start the LearnerThread
        self.learner_thread = LearnerThread(self)
        self.learner_thread.show_question.connect(self._set_question_text)
        self.learner_thread.flash_question.connect\
            (self._flash_question_background)
        self.learner_thread.flash_label.connect(self._flash_label)
        self.learner_thread.show_fixed.connect(self._set_fixed_text)
        self.learner_thread.show_tab.connect(self._set_tab)
        self.learner_thread.show_score.connect(self._set_score)
        self.learner_thread.show_score_outro.connect(self._set_score_outro)
        self.learner_thread.start()

        # Give QObjects reasonable names
        self.setObjectName('Query plugin')

        # Create the Widget
        self._widget = ResponsiveWidget(self)
        self._widget.press_enter.connect(self._step_state_machine)

        # Get the UI file
        ui_file = os.path.join(rospkg.RosPack().get_path('learner'), \
            'resources', 'learner.ui')
        loadUi(ui_file, self._widget)

        # Get the pictures for the instruction label
        picture_paths = list()
        neutral_picture_path = os.path.join(rospkg.RosPack().get_path('learner'), \
            'resources', 'drawing.png')

        picture_paths.append(os.path.join(rospkg.RosPack().get_path('learner'), \
            'resources', 'drawing_dunno.png'))
        picture_paths.append(os.path.join(rospkg.RosPack().get_path('learner'), \
            'resources', 'drawing_no.png'))
        picture_paths.append(os.path.join(rospkg.RosPack().get_path('learner'), \
            'resources', 'drawing_yes.png'))

        self.pictures = list()
        self.neutral_picture = QPixmap(neutral_picture_path)

        for p in picture_paths:
            self.pictures.append(QPixmap(p))

        # Give QObjects reasonable names
        self._widget.setObjectName('Query widget')

        # Add widget to the user interface
        context.add_widget(self._widget)

        # Create the response buttons
        button_size_policy = QSizePolicy(QSizePolicy.Expanding,
                                         QSizePolicy.Expanding)

        # Set up the labels
        self._widget.fixed_label.setWordWrap(True)
        self._widget.fixed_label.setFont(QFont("Sans Serif", 30))
        self._widget.question_label.setWordWrap(True)
        self._widget.question_label.setFont(QFont("Sans Serif", 30))
        self._widget.intro_label.setWordWrap(True)
        self._widget.intro_label.setFont(QFont("Sans Serif", 30))
        self._widget.score_intro_label.setWordWrap(True)
        self._widget.score_intro_label.setFont(QFont("Sans Serif", 20))
        self._widget.score_label.setWordWrap(True)
        self._widget.score_label.setFont(QFont("Sans Serif", 38))
        self._widget.score_outro_label.setWordWrap(True)
        self._widget.score_outro_label.setFont(QFont("Sans Serif", 24))

        # Clear the first page label
        self._widget.intro_label.setText("")

        # Activate starting tab
        self._widget.tab_manager.setCurrentIndex(1)

        # Activate keyboard grabber
        self._widget.grabKeyboard()

    def _set_question_text(self, string):
        self._widget.question_label.setText(string)

    def _flash_question_background(self, color_code):
        # 0 is yellow, 1 is red, 2 is green
        # -1 is the standard gray
        if color_code == 0:
            self._widget.question_label.setStyleSheet\
                ('background-color: rgb(254, 229, 0)')
        elif color_code == 1:
            self._widget.question_label.setStyleSheet\
                ('background-color: rgb(255, 120, 103)')
        elif color_code == 2:
            self._widget.question_label.setStyleSheet\
                ('background-color: rgb(145, 228, 141)')
        elif color_code == -1:
            self._widget.question_label.setStyleSheet\
                ('background-color: rgb(236, 236, 236)')

    def _flash_label(self, color_code):
        # 0 is not sure, 1 is no, 2 is yes
        # -1 is the standard label

        if color_code == -1:
            self._widget.instruction_label.setPixmap(self.neutral_picture)
        else:
            self._widget.instruction_label.setPixmap(self.pictures[color_code])
        if color_code == 0:

            self._widget.question_label.setStyleSheet\
                ('background-color: rgb(254, 229, 0)')
        elif color_code == 1:
            self._widget.question_label.setStyleSheet\
                ('background-color: rgb(255, 120, 103)')
        elif color_code == 2:
            self._widget.question_label.setStyleSheet\
                ('background-color: rgb(145, 228, 141)')
        elif color_code == -1:
            self._widget.question_label.setStyleSheet\
                ('background-color: rgb(236, 236, 236)')

    def _set_tab(self, int):
        self._widget.tab_manager.setCurrentIndex(int)

    def _set_fixed_text(self, string):
        self._widget.fixed_label.setText(string)

    def _set_score(self, string):
        self._widget.score_label.setText(string)

    def _set_score_outro(self, string):
        self._widget.score_outro_label.setText(string)

    def _set_intro_text(self, string):
        self._widget.intro_label.setText(string)

    def _start_experiment(self, msg):
        self.phase_lock.lock()
        self.learner_list = self.experiment_config[msg.type]
        self.finnish_help = msg.finnish
        self.learner_thread.learners = self.learner_list

        # Initialize service with NAO
        self.nao_talk = rospy.ServiceProxy('nao_speech', speech)

        # Need to skip some phases?
        if msg.skip == -1:
            self.sm = 0
            self.training_counter = 0
        elif msg.skip == 0:
            self.sm = 3
            self.training_counter = 0
        else:
            self.sm = 3
            self.training_counter = msg.skip

        self.experiment_name = msg.name

        rospy.logwarn("Start Interaction '{}': order {} with finnish: {}"\
            .format(self.experiment_name, msg.type, msg.finnish))

        self.nao_talk(self.experiment_intro, True, True)

        self._set_intro_text("Press ENTER to start the training.")
        self._set_question_text("")
        self._set_fixed_text("")
        self.phase_lock.unlock()

    def _step_state_machine(self):
        try:
            rospy.loginfo('State Machine function entered')
            self.phase_lock.lock()
            if self.sm == 0:
                # I am at the beginning of training and I received
                # Enter on keyboard --> Start training
                self._set_tab(0)
                rospy.logwarn("SM: 0 --> 1")
                self.sm = 1
                self.phase_lock.unlock()
                self.phase_condition.wakeAll()

                self.nao_talk(self.training_intro, True, True)
                return
            elif self.sm == 2:
                # The training is done and I received an Enter
                self._set_tab(1)
                rospy.logwarn("SM: 2 --> 3")
                self.sm = 3
                self.phase_lock.unlock()
                self.phase_condition.wakeAll()

                self._set_fixed_text("")
                self._set_question_text("")
                self._set_intro_text("Press Enter to start the experiment")

                if self.training_counter == 0:
                    self.nao_talk(self.teaching_intro, True, True)
                else:
                    self.nao_talk(self.teaching_continuation, True, True)

                return
            elif self.sm == 3:
                # I am in the intro page before exp and I receive an Enter
                # --> Start the experiment
                self._set_tab(0)
                rospy.logwarn("SM: 3 --> 4")
                self.sm = 4
                self.phase_lock.unlock()
                self.phase_condition.wakeAll()

                return
            elif self.sm == 5:
                if self.training_counter < 2:
                    # one phase of experiment is done, still more to go
                    self._set_tab(1)
                    rospy.logwarn("SM: 5 --> 3")
                    self.sm = 3
                    self.training_counter += 1
                    rospy.loginfo('training counter: {}'\
                        .format(self.training_counter))
                    self.phase_lock.unlock()
                    self.phase_condition.wakeAll()

                    if self.training_counter == 0:
                        self.nao_talk(self.teaching_intro, True, True)
                    else:
                        self.nao_talk(self.teaching_continuation, True, True)
                    return
                else:
                    # all phases of experiment are done
                    self._set_tab(1)
                    rospy.logwarn("SM: 5 --> 6")
                    self.sm = 6
                    self.phase_lock.unlock()
                    self.phase_condition.wakeAll()

                    self.nao_talk(self.experiment_outro, True, True)
                    self._set_intro_text("")
                    return
        finally:
            self.phase_lock.unlock()
Пример #13
0
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._datamodel = MessageDataModel()
        self._proxymodel = MessageProxyModel()
        self._proxymodel.setSourceModel(self._datamodel)

        self._mainwindow = ConsoleWidget(self._proxymodel)
        if context.serial_number() > 1:
            self._mainwindow.setWindowTitle(self._mainwindow.windowTitle() + (' (%d)' % context.serial_number()))
        context.add_widget(self._mainwindow)

        self._consolesubscriber = ConsoleSubscriber(self.message_callback)

        # Timer and Mutex for flushing recieved messages to datamodel.
        # Required since QSortProxyModel can not handle a high insert rate
        self._mutex = QMutex()
        self._timer = QTimer()
        self._timer.timeout.connect(self.insert_messages)
        self._timer.start(100)

    def insert_messages(self):
        """
        Callback for flushing incoming Log messages from the queue to the datamodel
        """
        self._mutex.lock()
        msgs = self._datamodel._insert_message_queue
        self._datamodel._insert_message_queue = []
        self._mutex.unlock()
        self._datamodel.insert_rows(msgs)
        self._mainwindow.update_status()

    def message_callback(self, msg):
        """
        Callback for adding an incomming message to the queue
        """
        if not self._datamodel._paused:
            self._mutex.lock()
            self._datamodel._insert_message_queue.append(msg)
            self._mutex.unlock()

    def shutdown_plugin(self):
        self._consolesubscriber.unsubscribe_topic()
        self._timer.stop()
        self._mainwindow.cleanup_browsers_on_close()

    def save_settings(self, plugin_settings, instance_settings):
        self._mainwindow.save_settings(plugin_settings, instance_settings)

    def restore_settings(self, plugin_settings, instance_settings):
        self._mainwindow.restore_settings(plugin_settings, instance_settings)

    def trigger_configuration(self):
        self._consolesubscriber.set_message_limit(self._datamodel._message_limit)
        ok = self._consolesubscriber.show_dialog()
        if ok:
            self._datamodel._message_limit = self._consolesubscriber.get_message_limit()