Ejemplo n.º 1
0
    def __init__(self, parent=None, current_values=None):
        super(BlacklistDialog, self).__init__(parent)
        self.setWindowTitle("Blacklist")
        vbox = QVBoxLayout()
        self.setLayout(vbox)

        self._blacklist = Blacklist()
        if isinstance(current_values, list):
            for val in current_values:
                self._blacklist.append(val)
        vbox.addWidget(self._blacklist)

        controls_layout = QHBoxLayout()
        add_button = QPushButton(icon=QIcon.fromTheme('list-add'))
        rem_button = QPushButton(icon=QIcon.fromTheme('list-remove'))
        ok_button = QPushButton("Ok")
        cancel_button = QPushButton("Cancel")
        add_button.clicked.connect(self._add_item)
        rem_button.clicked.connect(self._remove_item)
        ok_button.clicked.connect(self.accept)
        cancel_button.clicked.connect(self.reject)

        controls_layout.addWidget(add_button)
        controls_layout.addWidget(rem_button)
        controls_layout.addStretch(0)
        controls_layout.addWidget(ok_button)
        controls_layout.addWidget(cancel_button)
        vbox.addLayout(controls_layout)
Ejemplo n.º 2
0
    def __init__(self, context):
        super(SpectrogramPlugin, self).__init__(context)
        self.setObjectName('Spectrogram')

        self._widget = QWidget()
        layout = QVBoxLayout()
        self._widget.setLayout(layout)

        layout_ = QHBoxLayout()
        self.line_edit = QLineEdit()
        layout_.addWidget(self.line_edit)
        self.apply_btn = QPushButton("Apply")
        self.apply_btn.clicked.connect(self.apply_clicked)
        layout_.addWidget(self.apply_btn)
        layout.addLayout(layout_)

        self.fig = Figure((5, 4), dpi=100)
        self.canvas = FigureCanvas(self.fig)
        self.axes = self.fig.add_subplot(111)
        self.fig.tight_layout()

        layout.addWidget(self.canvas)

        context.add_widget(self._widget)

        self.update_signal.connect(self.update_spectrogram)
        self.subscriber_signal.connect(self.update_subscriber)

        self.subscriber_signal.emit('spec')
    def setup_group_frame(self, group):
        layout = QVBoxLayout()

        # grid for buttons for named targets
        grid = QGridLayout()
        grid.setSpacing(1)

        self.button_group = QButtonGroup(self)

        row = 0
        column = 0
        named_targets = self.get_named_targets(group)
        for target in named_targets:
            button = QPushButton(target)
            self.button_group.addButton(button)
            grid.addWidget(button, row, column)
            column += 1
            if column >= self.MAX_COLUMNS:
                row += 1
                column = 0

        self.button_group.buttonClicked.connect(self._handle_button_clicked)

        # grid for show joint value and move arm buttons/text field
        joint_values_grid = QGridLayout()
        joint_values_grid.setSpacing(1)

        button_show_joint_values = QPushButton('Current Joint Values')
        button_show_joint_values.clicked[bool].connect(
            self._handle_show_joint_values_clicked)

        line_edit = QLineEdit()
        self.text_joint_values.append(line_edit)

        button_move_to = QPushButton('Move to')
        button_move_to.clicked[bool].connect(self._handle_move_to_clicked)

        joint_values_grid.addWidget(button_show_joint_values, 0, 1)
        joint_values_grid.addWidget(line_edit, 0, 2)
        joint_values_grid.addWidget(button_move_to, 0, 3)

        layout.addLayout(grid)
        line = QFrame()
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)
        layout.addWidget(line)
        layout.addLayout(joint_values_grid)

        frame = QFrame()
        frame.setLayout(layout)
        return frame
    def __init__(self, parent=None, subscribe=False):
        QWidget.__init__(self, parent)

        # start widget
        vbox = QVBoxLayout()
        vbox.setMargin(0)
        vbox.setContentsMargins(0, 0, 0, 0)

        # add error status text edit
        self.error_status_text_box = QErrorStatusTextBox()
        self.error_status_text_box_layout = QHBoxLayout()
        self.error_status_text_box_layout.addWidget(self.error_status_text_box)
        vbox.addLayout(self.error_status_text_box_layout)

        # add panel
        hbox = QHBoxLayout()

        # clear push button
        self.execute_command = QPushButton("Clear")
        self.execute_command.clicked.connect(self.error_status_text_box.clear)
        hbox.addWidget(self.execute_command)

        hbox.addStretch()

        # hide window checkbox
        hide_window_check_box = QCheckBox("Hide")
        hide_window_check_box.stateChanged.connect(self.state_changed)
        hbox.addWidget(hide_window_check_box)

        # end panel
        vbox.addLayout(hbox)

        # end widget
        self.setLayout(vbox)
        #self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)

        # subscriber
        if subscribe:
            self.error_status_sub = rospy.Subscriber("error_status", ErrorStatus, self.error_status_callback)
        self.subscribed = subscribe

        # connect signal slot internally to prevent crash by subscriber
        self.error_status_signal.connect(self.append_error_status)
    def __init__(self, parent=None, logger=Logger()):
        QWidgetWithLogger.__init__(self, parent, logger)

        # start widget
        vbox = QVBoxLayout()
        vbox.setMargin(0)
        vbox.setContentsMargins(0, 0, 0, 0)

        # add layout which is dynamically filled
        self.parameter_tree_widget = QParameterTreeWidget(logger=self.logger)
        vbox.addWidget(self.parameter_tree_widget)

        # button panel
        vbox_commands = QVBoxLayout()
        hbox = QHBoxLayout()

        # upload topic
        send_parameter_topic_widget = QTopicWidget(self, 'vigir_footstep_planning_msgs/SetParameterSetAction', True)
        send_parameter_topic_widget.topic_changed_signal.connect(self._init_upload_paramater_set_client)
        hbox.addWidget(send_parameter_topic_widget)

        # upload command
        self.upload_command = QPushButton("Upload")
        self.upload_command.clicked.connect(self.upload_parameters)
        hbox.addWidget(self.upload_command)
        vbox_commands.addLayout(hbox)

        # reload command
        self.reload_command = QPushButton("Reload")
        self.reload_command.clicked.connect(self.reload_parameters)
        vbox_commands.addWidget(self.reload_command)

        # add button panel
        vbox.addLayout(vbox_commands)

        # end widget
        self.setLayout(vbox)

        # init
        self.clear()
        send_parameter_topic_widget.emit_topic_name()
    def __init__(self, parent=None):
        super(VisualizerWidget, self).__init__(parent)
        self.setWindowTitle('Graph Profiler Visualizer')
        vbox = QVBoxLayout()
        self.setLayout(vbox)

        toolbar_layout = QHBoxLayout()
        refresh_button = QPushButton()
        refresh_button.setIcon(QIcon.fromTheme('view-refresh'))
        auto_refresh_checkbox = QCheckBox("Auto Refresh")
        hide_disconnected_topics = QCheckBox("Hide Disconnected Topics")
        topic_blacklist_button = QPushButton("Topic Blacklist")
        node_blacklist_button = QPushButton("Node Blacklist")

        refresh_button.clicked.connect(self._refresh)
        topic_blacklist_button.clicked.connect(self._edit_topic_blacklist)
        node_blacklist_button.clicked.connect(self._edit_node_blacklist)
        auto_refresh_checkbox.setCheckState(2)
        auto_refresh_checkbox.stateChanged.connect(self._autorefresh_changed)
        hide_disconnected_topics.setCheckState(2)
        hide_disconnected_topics.stateChanged.connect(self._hidedisconnectedtopics_changed)

        toolbar_layout.addWidget(refresh_button)
        toolbar_layout.addWidget(auto_refresh_checkbox)
        toolbar_layout.addStretch(0)
        toolbar_layout.addWidget(hide_disconnected_topics)
        toolbar_layout.addWidget(topic_blacklist_button)
        toolbar_layout.addWidget(node_blacklist_button)
        vbox.addLayout(toolbar_layout)

        # Initialize the Visualizer
        self._view = qt_view.QtView()
        self._adapter = rosprofiler_adapter.ROSProfileAdapter(self._view)
        self._adapter.set_topic_quiet_list(TOPIC_BLACKLIST)
        self._adapter.set_node_quiet_list(NODE_BLACKLIST)
        vbox.addWidget(self._view)
Ejemplo n.º 7
0
class LogicalMarkerPlugin(Plugin):
    def __init__(self, context):
        super(LogicalMarkerPlugin, self).__init__(context)

        # Create an image for the original map. This will never change.
        try:
            self.map_yaml_file_str = rospy.get_param("~map_file")
            self.data_directory = rospy.get_param("~data_directory")
        except KeyError:
            rospy.logfatal(
                "~map_file and ~data_directory need to be set to use the logical marker"
            )
            return

        map_image_location = getImageFileLocation(self.map_yaml_file_str)
        map = loadMapFromFile(self.map_yaml_file_str)
        locations_file = getLocationsFileLocationFromDataDirectory(
            self.data_directory)
        doors_file = getDoorsFileLocationFromDataDirectory(self.data_directory)
        objects_file = getObjectsFileLocationFromDataDirectory(
            self.data_directory)

        # Give QObjects reasonable names
        self.setObjectName('LogicalMarkerPlugin')

        # Create QWidget
        self.master_widget = QWidget()
        self.master_layout = QVBoxLayout(self.master_widget)

        # Main Functions - Doors, Locations, Objects
        self.function_layout = QHBoxLayout()
        self.master_layout.addLayout(self.function_layout)
        self.function_buttons = []
        self.current_function = None
        for button_text in ['Locations', 'Doors', 'Objects']:
            button = QPushButton(button_text, self.master_widget)
            button.clicked[bool].connect(self.handle_function_button)
            button.setCheckable(True)
            self.function_layout.addWidget(button)
            self.function_buttons.append(button)
        self.function_layout.addStretch(1)

        self.master_layout.addWidget(self.get_horizontal_line())

        # Subfunction toolbar
        self.subfunction_layout = QHBoxLayout()
        clearLayoutAndFixHeight(self.subfunction_layout)
        self.master_layout.addLayout(self.subfunction_layout)
        self.current_subfunction = None

        self.master_layout.addWidget(self.get_horizontal_line())

        self.image = MapImage(map_image_location, self.master_widget)
        self.master_layout.addWidget(self.image)

        self.master_layout.addWidget(self.get_horizontal_line())

        # Configuration toolbar
        self.configuration_layout = QHBoxLayout()
        clearLayoutAndFixHeight(self.configuration_layout)
        self.master_layout.addLayout(self.configuration_layout)

        # Add a stretch at the bottom.
        self.master_layout.addStretch(1)

        self.master_widget.setObjectName('LogicalMarkerPluginUI')
        if context.serial_number() > 1:
            self.master_widget.setWindowTitle(
                self.master_widget.windowTitle() +
                (' (%d)' % context.serial_number()))
        context.add_widget(self.master_widget)

        # Activate the functions
        self.functions = {}
        self.functions['Locations'] = LocationFunction(
            locations_file, map, self.master_widget, self.subfunction_layout,
            self.configuration_layout, self.image)
        self.functions['Doors'] = DoorFunction(
            doors_file, map, self.functions['Locations'], self.master_widget,
            self.subfunction_layout, self.configuration_layout, self.image)
        self.functions['Objects'] = ObjectFunction(
            objects_file, map, self.functions['Locations'], self.master_widget,
            self.subfunction_layout, self.configuration_layout, self.image)

    def construct_layout(self):
        pass

    def get_horizontal_line(self):
        """
        http://stackoverflow.com/questions/5671354/how-to-programmatically-make-a-horizontal-line-in-qt
        """
        hline = QFrame()
        hline.setFrameShape(QFrame.HLine)
        hline.setFrameShadow(QFrame.Sunken)
        return hline

    def handle_function_button(self):
        source = self.sender()

        if source.text() == self.current_function:
            source.setChecked(True)
            return

        # Depress all other buttons.
        for button in self.function_buttons:
            if button != source:
                button.setChecked(False)

        if self.current_function is not None:
            self.functions[self.current_function].deactivateFunction()
        self.current_function = source.text()

        # Clear all subfunction buttons.
        clearLayoutAndFixHeight(self.subfunction_layout)

        if self.current_function is not None:
            self.functions[self.current_function].activateFunction()

    def shutdown_plugin(self):
        modified = False
        for function in self.functions:
            if self.functions[function].isModified():
                modified = True
        if modified:
            ret = QMessageBox.warning(
                self.master_widget, "Save",
                "The logical map has been modified.\n"
                "Do you want to save your changes?",
                QMessageBox.Save | QMessageBox.Discard)
            if ret == QMessageBox.Save:
                for function in self.functions:
                    self.functions[function].saveConfiguration()

    def save_settings(self, plugin_settings, instance_settings):
        pass

    def restore_settings(self, plugin_settings, instance_settings):
        pass
Ejemplo n.º 8
0
class QuestionDialogPlugin(Plugin):

    def __init__(self, context):
        super(QuestionDialogPlugin, self).__init__(context)
        # Give QObjects reasonable names
        self.setObjectName('QuestionDialogPlugin')

        font_size = rospy.get_param("~font_size", 40)

        # Create QWidget
        self._widget = QWidget()
        self._widget.setFont(QFont("Times", font_size, QFont.Bold))
        self._layout = QVBoxLayout(self._widget)
        self._text_browser = QTextBrowser(self._widget)
        self._layout.addWidget(self._text_browser)
        self._button_layout = QHBoxLayout()
        self._layout.addLayout(self._button_layout)

        # layout = QVBoxLayout(self._widget)
        # layout.addWidget(self.button)
        self._widget.setObjectName('QuestionDialogPluginUI')
        if context.serial_number() > 1:
            self._widget.setWindowTitle(self._widget.windowTitle() +
                                        (' (%d)' % context.serial_number()))
        context.add_widget(self._widget)

        # Setup service provider
        self.service = rospy.Service('question_dialog', QuestionDialog,
                                     self.service_callback)
        self.response_ready = False
        self.response = None
        self.buttons = []
        self.text_label = None
        self.text_input = None

        self.connect(self._widget, SIGNAL("update"), self.update)
        self.connect(self._widget, SIGNAL("timeout"), self.timeout)

    def shutdown_plugin(self):
        self.service.shutdown()

    def service_callback(self, req):
        self.response_ready = False
        self.request = req
        self._widget.emit(SIGNAL("update"))
        # Start timer against wall clock here instead of the ros clock.
        start_time = time.time()
        while not self.response_ready:
            if self.request != req:
                # The request got preempted by a new request.
                return QuestionDialogResponse(QuestionDialogRequest.PREEMPTED, "")
            if req.timeout != QuestionDialogRequest.NO_TIMEOUT:
                current_time = time.time()
                if current_time - start_time > req.timeout:
                    self._widget.emit(SIGNAL("timeout"))
                    return QuestionDialogResponse(
                            QuestionDialogRequest.TIMED_OUT, "")
            time.sleep(0.2)
        return self.response

    def update(self):
        self.clean()
        req = self.request
        self._text_browser.setText(req.message)
        if req.type == QuestionDialogRequest.DISPLAY:
            # All done, nothing more too see here.
            self.response = QuestionDialogResponse(
                    QuestionDialogRequest.NO_RESPONSE, "")
            self.response_ready = True
        elif req.type == QuestionDialogRequest.CHOICE_QUESTION:
            for index, options in enumerate(req.options):
                button = QPushButton(options, self._widget)
                button.clicked.connect(partial(self.handle_button, index))
                self._button_layout.addWidget(button)
                self.buttons.append(button)
        elif req.type == QuestionDialogRequest.TEXT_QUESTION:
            self.text_label = QLabel("Enter here: ", self._widget)
            self._button_layout.addWidget(self.text_label)
            self.text_input = QLineEdit(self._widget)
            self.text_input.editingFinished.connect(self.handle_text)
            self._button_layout.addWidget(self.text_input)

    def timeout(self):
        self._text_browser.setText("Oh no! The request timed out.")
        self.clean()

    def clean(self):
        while self._button_layout.count():
            item = self._button_layout.takeAt(0)
            item.widget().deleteLater()
        self.buttons = []
        self.text_input = None
        self.text_label = None

    def handle_button(self, index):
        self.response = QuestionDialogResponse(index, "")
        self.clean()
        self.response_ready = True

    def handle_text(self):
        self.response = QuestionDialogResponse(
            QuestionDialogRequest.TEXT_RESPONSE,
            self.text_input.text())
        self.clean()
        self.response_ready = True

    def save_settings(self, plugin_settings, instance_settings):
        # TODO save intrinsic configuration, usually using:
        # instance_settings.set_value(k, v)
        pass

    def restore_settings(self, plugin_settings, instance_settings):
        # TODO restore intrinsic configuration, usually using:
        # v = instance_settings.value(k)
        pass
Ejemplo n.º 9
0
class MessageBox(QDialog):

    NoIcon = 0
    Information = 1
    Warning = 2
    Critical = 3
    Question = 4

    NoButton = 0
    Ok = 1  # An "OK" button defined with the AcceptRole .
    Open = 2  # A "Open" button defined with the AcceptRole .
    Save = 4  # A "Save" button defined with the AcceptRole .
    Cancel = 8  # A "Cancel" button defined with the RejectRole .
    Close = 16  # A "Close" button defined with the RejectRole .
    Discard = 32  # A "Discard" or "Don't Save" button, depending on the platform, defined with the DestructiveRole .
    Apply = 64  # An "Apply" button defined with the ApplyRole .
    Reset = 128  # A "Reset" button defined with the ResetRole .
    RestoreDefaults = 256  # A "Restore Defaults" button defined with the ResetRole .
    Help = 512  # A "Help" button defined with the HelpRole .
    SaveAll = 1024  # A "Save All" button defined with the AcceptRole .
    Yes = 2048  # A "Yes" button defined with the YesRole .
    YesToAll = 4096  # A "Yes to All" button defined with the YesRole .
    No = 8192  # A "No" button defined with the NoRole .
    NoToAll = 16384  # A "No to All" button defined with the NoRole .
    Abort = 32768  # An "Abort" button defined with the RejectRole .
    Retry = 65536  # A "Retry" button defined with the AcceptRole .
    Ignore = 131072  # An "Ignore" button defined with the AcceptRole .
    Avoid = 262144  # An "'Don't show again'" button defined with the HelpRole, returns a default AcceptButton .

    def __init__(self,
                 icon,
                 title,
                 text,
                 detailed_text="",
                 buttons=Cancel | Ok,
                 parent=None):
        QDialog.__init__(self, parent=parent)
        self.setWindowFlags(self.windowFlags() & ~Qt.WindowTitleHint)
        self.setWindowFlags(self.windowFlags()
                            & ~Qt.WindowContextHelpButtonHint
                            & ~Qt.WindowMinimizeButtonHint)
        self.setObjectName('MessageBox')
        self._use_checkbox = True
        self.text = text
        self.verticalLayout = QVBoxLayout(self)
        self.verticalLayout.setObjectName("verticalLayout")
        self.verticalLayout.setContentsMargins(1, 1, 1, 1)

        self.horizontalLayout = QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.horizontalLayout.setContentsMargins(1, 1, 1, 1)
        # create icon
        pixmap = None
        if icon == self.NoIcon:
            pass
        elif icon == self.Question:
            pixmap = QPixmap(
                QImage(":icons/question.png").scaled(56, 56,
                                                     Qt.IgnoreAspectRatio,
                                                     Qt.SmoothTransformation))
        elif icon == self.Information:
            pixmap = QPixmap(
                QImage(":icons/info.png").scaled(56, 56, Qt.IgnoreAspectRatio,
                                                 Qt.SmoothTransformation))
        elif icon == self.Warning:
            pixmap = QPixmap(
                QImage(":icons/warning.png").scaled(56, 56,
                                                    Qt.IgnoreAspectRatio,
                                                    Qt.SmoothTransformation))
        elif icon == self.Critical:
            pixmap = QPixmap(
                QImage(":icons/critical.png").scaled(56, 56,
                                                     Qt.IgnoreAspectRatio,
                                                     Qt.SmoothTransformation))
        spacerItem = QSpacerItem(10, 60, QSizePolicy.Minimum,
                                 QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem)
        self.icon_label = QLabel()
        if pixmap is not None:
            self.icon_label.setPixmap(pixmap)
        self.icon_label.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.horizontalLayout.addWidget(self.icon_label)
        spacerItem = QSpacerItem(10, 60, QSizePolicy.Minimum,
                                 QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem)
        # add message
        self.message_label = QLabel(text)
        self.message_label.setWordWrap(True)
        self.message_label.setScaledContents(True)
        self.message_label.setOpenExternalLinks(True)
        self.horizontalLayout.addWidget(self.message_label)
        self.verticalLayout.addLayout(self.horizontalLayout)

        # create buttons
        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setObjectName("buttonBox")
        self.buttonBox.setOrientation(Qt.Horizontal)

        self._accept_button = None
        self._reject_button = None
        self._buttons = buttons
        self._create_buttons(buttons)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)
        self.verticalLayout.addWidget(self.buttonBox)

        if detailed_text:
            self.btn_show_details = QPushButton(self.tr('Details...'))
            self.btn_show_details.setCheckable(True)
            self.btn_show_details.setChecked(True)
            self.btn_show_details.toggled.connect(self.on_toggled_details)
            self.buttonBox.addButton(self.btn_show_details,
                                     QDialogButtonBox.ActionRole)
            # create area for detailed text
            self.textEdit = textEdit = QTextEdit(self)
            textEdit.setObjectName("textEdit")
            textEdit.setReadOnly(True)
            textEdit.setText(detailed_text)
            # textEdit.setVisible(False)
            self.verticalLayout.addWidget(self.textEdit)
        self.resize(480, self.verticalLayout.totalSizeHint().height())
        buttons_in_box = self.buttonBox.buttons()
        if buttons_in_box:
            self.buttonBox.buttons()[0].setFocus()

    def setAcceptButton(self, button):
        '''
        Sets the button with given ID to accept button if more then one button with AcceptRole was added to this dialog.
        Adds the buttton to the box if is not already in.
        :param int button: button id
        '''
        if not button & self._buttons:
            self._create_buttons(button)
        self._accept_button = button

    def setRejectButton(self, button):
        '''
        Sets the button with given ID to reject button if more then one button with RejectRole was added to this dialog.
        Adds the buttton to the box if is not already in.
        :param int button: button id
        '''
        if not button & self._buttons:
            self._create_buttons(button)
        self._reject_button = button

    def on_toggled_details(self, checked):
        if checked:
            self.verticalLayout.addWidget(self.textEdit)
        else:
            self.verticalLayout.removeWidget(self.textEdit)
        self.textEdit.setVisible(checked)
        if not self.isMaximized():
            self.setMinimumSize(self.verticalLayout.totalMinimumSize())
            self.resize(self._current_size.width(),
                        self.verticalLayout.totalSizeHint().height())

    @staticmethod
    def about(parent, title, text, detailed_text='', buttons=Close):
        box = MessageBox(MessageBox.Information,
                         title,
                         text,
                         detailed_text=detailed_text,
                         buttons=buttons,
                         parent=parent)
        if MessageBox.Yes & buttons:
            box.setAcceptButton(MessageBox.Yes)
        if MessageBox.Cancel & buttons:
            box.setRejectButton(MessageBox.Cancel)
        elif MessageBox.No & buttons:
            box.setRejectButton(MessageBox.No)
        return box.exec_()

    @staticmethod
    def information(parent, title, text, detailed_text='', buttons=Close):
        box = MessageBox(MessageBox.Information,
                         title,
                         text,
                         detailed_text=detailed_text,
                         buttons=buttons,
                         parent=parent)
        if MessageBox.Yes & buttons:
            box.setAcceptButton(MessageBox.Yes)
        if MessageBox.Cancel & buttons:
            box.setRejectButton(MessageBox.Cancel)
        elif MessageBox.No & buttons:
            box.setRejectButton(MessageBox.No)
        return box.exec_()

    @staticmethod
    def question(parent,
                 title,
                 text,
                 detailed_text='',
                 buttons=Yes | No | Cancel):
        box = MessageBox(MessageBox.Question,
                         title,
                         text,
                         detailed_text=detailed_text,
                         buttons=buttons,
                         parent=parent)
        if MessageBox.Yes & buttons:
            box.setAcceptButton(MessageBox.Yes)
        if MessageBox.Cancel & buttons:
            box.setRejectButton(MessageBox.Cancel)
        elif MessageBox.No & buttons:
            box.setRejectButton(MessageBox.No)
        return box.exec_()

    @staticmethod
    def warning(parent, title, text, detailed_text='', buttons=Ok):
        box = MessageBox(MessageBox.Warning,
                         title,
                         text,
                         detailed_text=detailed_text,
                         buttons=buttons,
                         parent=parent)
        if MessageBox.Yes & buttons:
            box.setAcceptButton(MessageBox.Yes)
        if MessageBox.Cancel & buttons:
            box.setRejectButton(MessageBox.Cancel)
        elif MessageBox.No & buttons:
            box.setRejectButton(MessageBox.No)
        return box.exec_()

    @staticmethod
    def critical(parent, title, text, detailed_text='', buttons=Ok):
        box = MessageBox(MessageBox.Critical,
                         title,
                         text,
                         detailed_text=detailed_text,
                         buttons=buttons,
                         parent=parent)
        if MessageBox.Yes & buttons:
            box.setAcceptButton(MessageBox.Yes)
        if MessageBox.Cancel & buttons:
            box.setRejectButton(MessageBox.Cancel)
        elif MessageBox.No & buttons:
            box.setRejectButton(MessageBox.No)
        return box.exec_()

    def resizeEvent(self, event):
        if not self.isMaximized():
            self._current_size = event.size()

# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# %%%%%%%%%%%%%%%%%% close handling                        %%%%%%%%%%%%%%%%%%%%%
# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    def exec_(self):
        if self.text in IGNORED_ERRORS:
            self.accept()
            return self.result()
        return QDialog.exec_(self)

    def accept(self):
        if self.result() == 0:
            if self._accept_button is not None:
                self.setResult(self._accept_button)
            else:
                self.setResult(1)
        self.accepted.emit()
        if self.isModal():
            self.hide()

    def reject(self):
        if self.result() == 0:
            if self._reject_button is not None:
                self.setResult(self._reject_button)
        self.rejected.emit()
        self.hide()

    def hideEvent(self, event):
        # event.ignore()
        self.close()

    def closeEvent(self, event):
        self.setAttribute(Qt.WA_DeleteOnClose, True)
        QDialog.closeEvent(self, event)

# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# %%%%%%%%%%%%%%%%%% create buttons                        %%%%%%%%%%%%%%%%%%%%%
# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    def _create_buttons(self, buttons):
        if MessageBox.Ok & buttons:
            self._accept_button = MessageBox.Ok
            bt = QPushButton(self.tr("&ok"))
            bt.clicked.connect(self._on_ok_clicked)
            self.buttonBox.addButton(bt, QDialogButtonBox.AcceptRole)
        if MessageBox.Open & buttons:
            self._accept_button = MessageBox.Open
            bt = QPushButton(self.tr("&Open"))
            bt.clicked.connect(self._on_open_clicked)
            self.buttonBox.addButton(bt, QDialogButtonBox.AcceptRole)
        if MessageBox.Save & buttons:
            self._accept_button = MessageBox.Save
            bt = QPushButton(self.tr("&Save"))
            bt.clicked.connect(self._on_save_clicked)
            self.buttonBox.addButton(bt, QDialogButtonBox.AcceptRole)
        if MessageBox.Cancel & buttons:
            self._reject_button = MessageBox.Cancel
            bt = QPushButton(self.tr("&Cancel"))
            bt.clicked.connect(self._on_cancel_clicked)
            self.buttonBox.addButton(bt, QDialogButtonBox.RejectRole)
        if MessageBox.Close & buttons:
            self._reject_button = MessageBox.Close
            bt = QPushButton(self.tr("&Close"))
            bt.clicked.connect(self._on_close_clicked)
            self.buttonBox.addButton(bt, QDialogButtonBox.RejectRole)
        if MessageBox.Discard & buttons:
            bt = QPushButton(self.tr("&Discard"))
            bt.clicked.connect(self._on_discard_clicked)
            self.buttonBox.addButton(bt, QDialogButtonBox.DestructiveRole)
        if MessageBox.Apply & buttons:
            bt = QPushButton(self.tr("&Apply"))
            bt.clicked.connect(self._on_apply_clicked)
            self.buttonBox.addButton(bt, QDialogButtonBox.ApplyRole)
        if MessageBox.Reset & buttons:
            bt = QPushButton(self.tr("&Reset"))
            bt.clicked.connect(self._on_reset_clicked)
            self.buttonBox.addButton(bt, QDialogButtonBox.ResetRole)
        if MessageBox.RestoreDefaults & buttons:
            bt = QPushButton(self.tr("&RestoreDefaults"))
            bt.clicked.connect(self._on_restore_defaults_clicked)
            self.buttonBox.addButton(bt, QDialogButtonBox.ResetRole)
        if MessageBox.Help & buttons:
            bt = QPushButton(self.tr("&Help"))
            bt.clicked.connect(self._on_help_clicked)
            self.buttonBox.addButton(bt, QDialogButtonBox.HelpRole)
        if MessageBox.SaveAll & buttons:
            self._accept_button = MessageBox.SaveAll
            bt = QPushButton(self.tr("&SaveAll"))
            bt.clicked.connect(self._on_saveall_clicked)
            self.buttonBox.addButton(bt, QDialogButtonBox.AcceptRole)
        if MessageBox.Yes & buttons:
            bt = QPushButton(self.tr("&Yes"))
            bt.clicked.connect(self._on_yes_clicked)
            self.buttonBox.addButton(bt, QDialogButtonBox.YesRole)
        if MessageBox.YesToAll & buttons:
            bt = QPushButton(self.tr("&YesToAll"))
            bt.clicked.connect(self._on_yestoall_clicked)
            self.buttonBox.addButton(bt, QDialogButtonBox.YesRole)
        if MessageBox.No & buttons:
            bt = QPushButton(self.tr("&No"))
            bt.clicked.connect(self._on_no_clicked)
            self.buttonBox.addButton(bt, QDialogButtonBox.NoRole)
        if MessageBox.NoToAll & buttons:
            bt = QPushButton(self.tr("&NoToAll"))
            bt.clicked.connect(self._on_notoall_clicked)
            self.buttonBox.addButton(bt, QDialogButtonBox.NoRole)
        if MessageBox.Abort & buttons:
            self._reject_button = MessageBox.Abort
            bt = QPushButton(self.tr("&Abort"))
            bt.clicked.connect(self._on_abort_clicked)
            self.buttonBox.addButton(bt, QDialogButtonBox.RejectRole)
        if MessageBox.Retry & buttons:
            self._accept_button = MessageBox.Retry
            bt = QPushButton(self.tr("&Retry"))
            bt.clicked.connect(self._on_retry_clicked)
            self.buttonBox.addButton(bt, QDialogButtonBox.AcceptRole)
        if MessageBox.Ignore & buttons:
            self._accept_button = MessageBox.Ignore
            bt = QPushButton(self.tr("&Ignore"))
            bt.clicked.connect(self._on_ignore_clicked)
            self.buttonBox.addButton(bt, QDialogButtonBox.AcceptRole)
        if MessageBox.Avoid & buttons:
            if self._use_checkbox:
                checkbox = QCheckBox("&Don't show again", self)
                checkbox.stateChanged.connect(self._check_ignore)
                self.buttonBox.addButton(checkbox, QDialogButtonBox.HelpRole)
            else:
                bt = QPushButton(self.tr("&Don't show again"))
                bt.setMaximumHeight(24)
                bt.clicked.connect(self._add_to_ignore)
                self.buttonBox.addButton(bt, QDialogButtonBox.HelpRole)

    def _on_ok_clicked(self):
        self.done(MessageBox.Ok)

    def _on_open_clicked(self):
        self.done(MessageBox.Open)

    def _on_save_clicked(self):
        self.done(MessageBox.Save)

    def _on_cancel_clicked(self):
        self.done(MessageBox.Cancel)

    def _on_close_clicked(self):
        self.done(MessageBox.Close)

    def _on_discard_clicked(self):
        self.done(MessageBox.Discard)

    def _on_apply_clicked(self):
        self.done(MessageBox.Apply)

    def _on_reset_clicked(self):
        self.done(MessageBox.Reset)

    def _on_restore_defaults_clicked(self):
        self.done(MessageBox.RestoreDefaults)

    def _on_help_clicked(self):
        self.done(MessageBox.Help)

    def _on_saveall_clicked(self):
        self.done(MessageBox.SaveAll)

    def _on_yes_clicked(self):
        self.done(MessageBox.Yes)

    def _on_yestoall_clicked(self):
        self.done(MessageBox.YesToAll)

    def _on_no_clicked(self):
        self.done(MessageBox.No)

    def _on_notoall_clicked(self):
        self.done(MessageBox.NoToAll)

    def _on_abort_clicked(self):
        self.done(MessageBox.Abort)

    def _on_retry_clicked(self):
        self.done(MessageBox.Retry)

    def _on_ignore_clicked(self):
        self.done(MessageBox.Ignore)

    def _add_to_ignore(self):
        IGNORED_ERRORS.append(self.text)
        self.accept()

    def _check_ignore(self, state):
        if state:
            IGNORED_ERRORS.append(self.text)
        else:
            try:
                IGNORED_ERRORS.remove(self.text)
            except Exception:
                pass
Ejemplo n.º 10
0
    def __init__(self, context):
        super(PatternGeneratorWidget, self).__init__()

        # publisher
        self.pattern_generator_params_pub = rospy.Publisher(
            'pattern_generator/set_params',
            PatternGeneratorParameters,
            queue_size=1)

        # start widget
        widget = context

        # start upper part
        hbox = QHBoxLayout()

        # start left column
        left_vbox = QVBoxLayout()

        # start button
        start_command = QPushButton("Start")
        left_vbox.addWidget(start_command)

        # simulation checkbox
        self.simulation_mode_checkbox = QCheckBox()
        self.simulation_mode_checkbox.setText("Simulation Mode")
        self.simulation_mode_checkbox.setChecked(False)
        left_vbox.addWidget(self.simulation_mode_checkbox)

        # realtime checkbox
        self.realtime_mode_checkbox = QCheckBox()
        self.realtime_mode_checkbox.setText("Realtime Mode")
        self.realtime_mode_checkbox.setChecked(False)
        left_vbox.addWidget(self.realtime_mode_checkbox)

        # joystick checkbox
        self.joystick_mode_checkbox = QCheckBox()
        self.joystick_mode_checkbox.setText("Joystick Mode")
        self.joystick_mode_checkbox.setChecked(False)
        left_vbox.addWidget(self.joystick_mode_checkbox)

        # ignore invalid steps checkbox
        self.ignore_invalid_steps_checkbox = QCheckBox()
        self.ignore_invalid_steps_checkbox.setText("Ignore Invalid Steps")
        self.ignore_invalid_steps_checkbox.setChecked(False)
        left_vbox.addWidget(self.ignore_invalid_steps_checkbox)

        # foot seperation
        self.foot_seperation = generate_q_double_spin_box(
            0.2, 0.15, 0.3, 2, 0.01)
        self.foot_seperation.valueChanged.connect(self.callback_spin_box)
        add_widget_with_frame(left_vbox, self.foot_seperation,
                              "Foot Seperation (m):")

        # delta x
        self.delta_x = generate_q_double_spin_box(0.0, -0.4, 0.4, 2, 0.01)
        self.delta_x.valueChanged.connect(self.callback_spin_box)
        add_widget_with_frame(left_vbox, self.delta_x, "dX (m):")

        # delta y
        self.delta_y = generate_q_double_spin_box(0.0, -2.2, 2.2, 2, 0.01)
        self.delta_y.valueChanged.connect(self.callback_spin_box)
        add_widget_with_frame(left_vbox, self.delta_y, "dY (m):")

        # delta yaw
        self.delta_yaw = generate_q_double_spin_box(0.0, -30.0, 30.0, 0, 1.0)
        self.delta_yaw.valueChanged.connect(self.callback_spin_box)
        add_widget_with_frame(left_vbox, self.delta_yaw, "dYaw (deg):")

        # roll
        self.roll = generate_q_double_spin_box(0.0, -30.0, 30.0, 0, 1.0)
        self.roll.valueChanged.connect(self.callback_spin_box)
        add_widget_with_frame(left_vbox, self.roll, "Roll (deg):")

        # pitch
        self.pitch = generate_q_double_spin_box(0.0, -30.0, 30.0, 0, 1.0)
        self.pitch.valueChanged.connect(self.callback_spin_box)
        add_widget_with_frame(left_vbox, self.pitch, "Pitch (deg):")

        # end left column
        left_vbox.addStretch()
        hbox.addLayout(left_vbox, 1)

        # start right column
        right_vbox = QVBoxLayout()

        # stop button
        stop_command = QPushButton("Stop")
        right_vbox.addWidget(stop_command)

        # ignore collision
        self.collision_checkbox = QCheckBox()
        self.collision_checkbox.setText("Ignore Collision")
        self.collision_checkbox.setChecked(True)
        right_vbox.addWidget(self.collision_checkbox)

        # override 3D
        self.override_checkbox = QCheckBox()
        self.override_checkbox.setText("Override 3D")
        self.override_checkbox.setChecked(False)
        right_vbox.addWidget(self.override_checkbox)

        # end right coloumn
        right_vbox.addStretch()
        hbox.addLayout(right_vbox, 1)

        # add upper part
        hbox.setMargin(0)
        vbox = QVBoxLayout()
        vbox.addLayout(hbox)

        # parameter set selection
        self.parameter_set_widget = QParameterSetWidget()
        add_widget_with_frame(vbox, self.parameter_set_widget,
                              "Parameter Set:")

        # end widget
        widget.setLayout(vbox)
        #context.add_widget(widget)

        # signal connections
        start_command.clicked.connect(self.start_command_callback)
        stop_command.clicked.connect(self.stop_command_callback)
        self.joystick_mode_checkbox.clicked.connect(
            self.joystick_mode_check_callback)
        self.ignore_invalid_steps_checkbox.clicked.connect(
            self._publish_parameters)
class CalibrationMovementsGUI(QWidget):
    NOT_INITED_YET = 0
    BAD_PLAN = 1
    GOOD_PLAN = 2
    MOVED_TO_POSE = 3
    BAD_STARTING_POSITION = 4
    GOOD_STARTING_POSITION = 5

    def __init__(self):
        super(CalibrationMovementsGUI, self).__init__()
        move_group_name = rospy.get_param('~move_group', 'manipulator')
        self.angle_delta = math.radians(
            rospy.get_param('~rotation_delta_degrees', 25))
        self.translation_delta = rospy.get_param('~translation_delta_meters',
                                                 0.1)
        max_velocity_scaling = rospy.get_param('~max_velocity_scaling', 0.5)
        max_acceleration_scaling = rospy.get_param('~max_acceleration_scaling',
                                                   0.5)
        self.local_mover = CalibrationMovements(move_group_name,
                                                max_velocity_scaling,
                                                max_acceleration_scaling)
        self.current_pose = -1
        self.current_plan = None
        self.initUI()
        self.state = CalibrationMovementsGUI.NOT_INITED_YET

    def initUI(self):
        self.layout = QVBoxLayout()
        self.labels_layout = QHBoxLayout()
        self.buttons_layout = QHBoxLayout()

        self.progress_bar = QProgressBar()
        self.pose_number_lbl = QLabel('0/8')
        self.bad_plan_lbl = QLabel('No plan yet')
        self.guide_lbl = QLabel('Hello')

        self.check_start_pose_btn = QPushButton('Check starting pose')
        self.check_start_pose_btn.clicked.connect(
            self.handle_check_current_state)

        self.next_pose_btn = QPushButton('Next Pose')
        self.next_pose_btn.clicked.connect(self.handle_next_pose)

        self.plan_btn = QPushButton('Plan')
        self.plan_btn.clicked.connect(self.handle_plan)

        self.execute_btn = QPushButton('Execute')
        self.execute_btn.clicked.connect(self.handle_execute)

        self.labels_layout.addWidget(self.pose_number_lbl)
        self.labels_layout.addWidget(self.bad_plan_lbl)

        self.buttons_layout.addWidget(self.check_start_pose_btn)
        self.buttons_layout.addWidget(self.next_pose_btn)
        self.buttons_layout.addWidget(self.plan_btn)
        self.buttons_layout.addWidget(self.execute_btn)

        self.layout.addWidget(self.progress_bar)
        self.layout.addLayout(self.labels_layout)
        self.layout.addWidget(self.guide_lbl)
        self.layout.addLayout(self.buttons_layout)

        self.setLayout(self.layout)

        self.plan_btn.setEnabled(False)
        self.execute_btn.setEnabled(False)

        self.setWindowTitle('Local Mover')
        self.show()

    def updateUI(self):
        self.progress_bar.setMaximum(len(self.local_mover.poses))
        self.progress_bar.setValue(self.current_pose + 1)
        self.pose_number_lbl.setText('{}/{}'.format(
            self.current_pose + 1, len(self.local_mover.poses)))

        if self.state == CalibrationMovementsGUI.BAD_PLAN:
            self.bad_plan_lbl.setText('BAD plan!! Don\'t do it!!!!')
            self.bad_plan_lbl.setStyleSheet('QLabel { background-color : red}')
        elif self.state == CalibrationMovementsGUI.GOOD_PLAN:
            self.bad_plan_lbl.setText('Good plan')
            self.bad_plan_lbl.setStyleSheet(
                'QLabel { background-color : green}')
        else:
            self.bad_plan_lbl.setText('No plan yet')
            self.bad_plan_lbl.setStyleSheet('')

        if self.state == CalibrationMovementsGUI.NOT_INITED_YET:
            self.guide_lbl.setText(
                'Bring the robot to a plausible position and check if it is a suitable starting pose'
            )
        elif self.state == CalibrationMovementsGUI.BAD_STARTING_POSITION:
            self.guide_lbl.setText('Cannot calibrate from current position')
        elif self.state == CalibrationMovementsGUI.GOOD_STARTING_POSITION:
            self.guide_lbl.setText('Ready to start: click on next pose')
        elif self.state == CalibrationMovementsGUI.GOOD_PLAN:
            self.guide_lbl.setText(
                'The plan seems good: press execute to move the robot')
        elif self.state == CalibrationMovementsGUI.BAD_PLAN:
            self.guide_lbl.setText('Planning failed: try again')
        elif self.state == CalibrationMovementsGUI.MOVED_TO_POSE:
            self.guide_lbl.setText(
                'Pose reached: take a sample and go on to next pose')

        can_plan = self.state == CalibrationMovementsGUI.GOOD_STARTING_POSITION
        self.plan_btn.setEnabled(can_plan)
        can_move = self.state == CalibrationMovementsGUI.GOOD_PLAN
        self.execute_btn.setEnabled(can_move)

    def handle_check_current_state(self):
        self.local_mover.compute_poses_around_current_state(
            self.angle_delta, self.translation_delta)

        joint_limits = [math.radians(90)] * 5 + [math.radians(180)] + [
            math.radians(350)
        ]  # TODO: make param
        if self.local_mover.check_poses(joint_limits):
            self.state = CalibrationMovementsGUI.GOOD_STARTING_POSITION
        else:
            self.state = CalibrationMovementsGUI.BAD_STARTING_POSITION
        self.current_pose = -1

        self.updateUI()

    def handle_next_pose(self):
        self.guide_lbl.setText('Going to center position')
        if self.current_pose != -1:
            plan = self.local_mover.plan_to_start_pose()
            if plan is None:
                self.guide_lbl.setText(
                    'Failed planning to center position: try again')
            else:
                self.local_mover.execute_plan(plan)
        if self.current_pose < len(self.local_mover.poses) - 1:
            self.current_pose += 1
        self.state = CalibrationMovementsGUI.GOOD_STARTING_POSITION
        self.updateUI()

    def handle_plan(self):
        self.guide_lbl.setText(
            'Planning to the next position. Click on execute when a good one was found'
        )
        if self.current_pose >= 0:
            self.current_plan = self.local_mover.plan_to_pose(
                self.local_mover.poses[self.current_pose])
            if CalibrationMovements.is_crazy_plan(
                    self.current_plan, self.local_mover.fallback_joint_limits
            ):  #TODO: sort out this limits story
                self.state = CalibrationMovementsGUI.BAD_PLAN
            else:
                self.state = CalibrationMovementsGUI.GOOD_PLAN
        self.updateUI()

    def handle_execute(self):
        if self.current_plan is not None:
            self.guide_lbl.setText('Going to the selected pose')
            self.local_mover.execute_plan(self.current_plan)
            self.state = CalibrationMovementsGUI.MOVED_TO_POSE
            self.updateUI()
Ejemplo n.º 12
0
class RoomDialogPlugin(Plugin):
    def __init__(self, context):
        super(RoomDialogPlugin, self).__init__(context)
        # Give QObjects reasonable names
        self.setObjectName('RoomDialogPlugin')

        font_size = rospy.get_param("~font_size", 30)

        # Create QWidget
        self._widget = QWidget()
        self._widget.setFont(QFont("Times", font_size, QFont.Bold))
        self._layout = QVBoxLayout(self._widget)
        self._text_browser = QTextBrowser(self._widget)
        self._layout.addWidget(self._text_browser)
        self._button_layout = QGridLayout()
        self._layout.addLayout(self._button_layout)
        #        rospy.loginfo("Hello world")

        # Add combobox
        self._cb_layout = QHBoxLayout()
        self._cb = QComboBox()
        self._layout.addLayout(self._cb_layout)

        #layout = QVBoxLayout(self._widget)
        #layout.addWidget(self._button)
        self._widget.setObjectName('RoomDialogPluginUI')
        if context.serial_number() > 1:
            self._widget.setWindowTitle(self._widget.windowTitle() +
                                        (' (%d)' % context.serial_number()))
        context.add_widget(self._widget)

        # Setup service provider
        self.service = rospy.Service('room_dialog', RoomDialog,
                                     self.service_callback)
        self.response_ready = False
        self.response = None
        self.buttons = []
        self.text_label = None
        self.text_input = None

        # Add combo options

        self.connect(self._widget, SIGNAL("update"), self.update)
        self.connect(self._widget, SIGNAL("timeout"), self.timeout)

    def shutdown_plugin(self):
        self.service.shutdown()

    def service_callback(self, req):
        self.response_ready = False
        self.request = req
        self._widget.emit(SIGNAL("update"))
        # Start timer against wall clock here instead of the ros clock.
        start_time = time.time()
        while not self.response_ready:
            if self.request != req:
                # The request got preempted by a new request.
                return RoomDialogResponse(RoomDialogRequest.PREEMPTED, "")
            if req.timeout != RoomDialogRequest.NO_TIMEOUT:
                current_time = time.time()
                if current_time - start_time > req.timeout:
                    self._widget.emit(SIGNAL("timeout"))
                    return RoomDialogResponse(RoomDialogRequest.TIMED_OUT, "")
            time.sleep(0.2)
        return self.response

    def update(self):
        self.clean()
        req = self.request
        self._text_browser.setText(req.message)
        if req.type == RoomDialogRequest.DISPLAY:
            # All done, nothing more too see here.
            self.response = RoomDialogResponse(RoomDialogRequest.NO_RESPONSE,
                                               "")
            self.response_ready = True
        elif req.type == RoomDialogRequest.CHOICE_QUESTION:
            for index, options in enumerate(req.options):
                button = QPushButton(options, self._widget)
                button.clicked.connect(partial(self.handle_button, index))
                row = index / 3
                col = index % 3
                self._button_layout.addWidget(button, row, col)
                self.buttons.append(button)
        elif req.type == RoomDialogRequest.TEXT_QUESTION:
            self.text_label = QLabel("Enter here: ", self._widget)
            self._button_layout.addWidget(self.text_label, 0, 0)
            self.text_input = QLineEdit(self._widget)
            self.text_input.editingFinished.connect(self.handle_text)
            self._button_layout.addWidget(self.text_input, 0, 1)

        # add handling of combobox
        elif req.type == RoomDialogRequest.COMBOBOX_QUESTION:
            #  self.clean()
            rospy.loginfo("Combobox selected")

            #self._cb.duplicatesEnabled = False
            if self._cb.count() == 0:
                for index, options in enumerate(req.options):
                    self._cb.addItem(options)
                    rospy.loginfo(options)
                #self.buttons.append(options)
            # NOTE COULD INTRODUCE BUG
            self._cb.currentIndexChanged.connect(self.handle_cb)
            self._cb_layout.addWidget(self._cb)

    def timeout(self):
        self._text_browser.setText("Oh no! The request timed out.")
        self.clean()

    def clean(self):
        while self._button_layout.count():
            item = self._button_layout.takeAt(0)
            item.widget().deleteLater()

    # while self._cb_layout.count():
    #     item = self._cb_layout.takeAt(0)
    #     item.widget().deleteLater()

        self.buttons = []
        self.text_input = None
        self.text_label = None

    def handle_button(self, index):
        self.response = RoomDialogResponse(index, "")
        self.clean()
        self.response_ready = True

    def handle_text(self):
        self.response = RoomDialogResponse(RoomDialogRequest.TEXT_RESPONSE,
                                           self.text_input.text())
        self.clean()
        self.response_ready = True

    def handle_cb(self, index):
        # This will be the sign format seen around building ex: 3.404
        rospy.loginfo("handling cb")
        roomHuman = self._cb.currentText()
        # modify string into robot format ex: d3_404
        splitHuman = roomHuman.split('.', 1)
        roomRobot = 'd' + splitHuman[0] + '_' + splitHuman[1]
        roomRobot = str(roomRobot)
        self.response = RoomDialogResponse(RoomDialogRequest.CB_RESPONSE,
                                           roomRobot)
        self.clean()
        self.response_ready = True

    def save_settings(self, plugin_settings, instance_settings):
        # TODO save intrinsic configuration, usually using:
        # instance_settings.set_value(k, v)
        pass

    def restore_settings(self, plugin_settings, instance_settings):
        # TODO restore intrinsic configuration, usually using:
        # v = instance_settings.value(k)
        pass
Ejemplo n.º 13
0
class CalibrationMovementsGUI(QWidget):
    NOT_INITED_YET = 0
    BAD_PLAN = 1
    GOOD_PLAN = 2
    MOVED_TO_POSE = 3
    BAD_STARTING_POSITION = 4
    GOOD_STARTING_POSITION = 5
    CHECKING_STARTING_POSITION = 6
    MOVEMENT_FAILED = 7

    def __init__(self):
        super(CalibrationMovementsGUI, self).__init__()
        self.handeye_client = HandeyeClient()
        self.current_target_pose = -1  # -1 is home
        self.target_poses = None
        self.plan_was_successful = None
        self.state = CalibrationMovementsGUI.NOT_INITED_YET

        self.layout = QVBoxLayout()
        self.labels_layout = QHBoxLayout()
        self.buttons_layout = QHBoxLayout()

        self.progress_bar = QProgressBar()
        self.pose_number_lbl = QLabel('0/0')
        self.bad_plan_lbl = QLabel('No plan yet')
        self.bad_plan_lbl.setAlignment(Qt.AlignCenter)
        self.guide_lbl = QLabel('Hello')
        self.guide_lbl.setWordWrap(True)

        self.check_start_pose_btn = QPushButton('Check starting pose')
        self.check_start_pose_btn.clicked.connect(
            self.handle_check_current_state)

        self.next_pose_btn = QPushButton('Next Pose')
        self.next_pose_btn.clicked.connect(self.handle_next_pose)

        self.plan_btn = QPushButton('Plan')
        self.plan_btn.clicked.connect(self.handle_plan)

        self.execute_btn = QPushButton('Execute')
        self.execute_btn.clicked.connect(self.handle_execute)

        self.labels_layout.addWidget(self.pose_number_lbl)
        self.labels_layout.addWidget(self.bad_plan_lbl)

        self.buttons_layout.addWidget(self.check_start_pose_btn)
        self.buttons_layout.addWidget(self.next_pose_btn)
        self.buttons_layout.addWidget(self.plan_btn)
        self.buttons_layout.addWidget(self.execute_btn)

        self.layout.addWidget(self.progress_bar)
        self.layout.addLayout(self.labels_layout)
        self.layout.addWidget(self.guide_lbl)
        self.layout.addLayout(self.buttons_layout)

        self.setLayout(self.layout)

        self.plan_btn.setEnabled(False)
        self.execute_btn.setEnabled(False)

        self.setWindowTitle('Local Mover')
        self.show()

    def update_ui(self):
        if self.target_poses:
            count_target_poses = len(self.target_poses)
        else:
            count_target_poses = 1
        self.progress_bar.setMaximum(count_target_poses)
        self.progress_bar.setValue(self.current_target_pose + 1)
        self.pose_number_lbl.setText('{}/{}'.format(
            self.current_target_pose + 1, count_target_poses))

        if self.state == CalibrationMovementsGUI.BAD_PLAN:
            self.bad_plan_lbl.setText('BAD plan!! Don\'t do it!!!!')
            self.bad_plan_lbl.setStyleSheet('QLabel { background-color : red}')
        elif self.state == CalibrationMovementsGUI.GOOD_PLAN:
            self.bad_plan_lbl.setText('Good plan')
            self.bad_plan_lbl.setStyleSheet(
                'QLabel { background-color : green}')
        else:
            self.bad_plan_lbl.setText('No plan yet')
            self.bad_plan_lbl.setStyleSheet('')

        if self.state == CalibrationMovementsGUI.NOT_INITED_YET:
            self.guide_lbl.setText(
                'Bring the robot to a plausible position and check if it is a suitable starting pose'
            )
        elif self.state == CalibrationMovementsGUI.CHECKING_STARTING_POSITION:
            self.guide_lbl.setText(
                'Checking if the robot can translate and rotate in all directions from the current pose'
            )
        elif self.state == CalibrationMovementsGUI.BAD_STARTING_POSITION:
            self.guide_lbl.setText('Cannot calibrate from current position')
        elif self.state == CalibrationMovementsGUI.GOOD_STARTING_POSITION:
            self.guide_lbl.setText('Ready to start: click on next pose')
        elif self.state == CalibrationMovementsGUI.GOOD_PLAN:
            self.guide_lbl.setText(
                'The plan seems good: press execute to move the robot')
        elif self.state == CalibrationMovementsGUI.BAD_PLAN:
            self.guide_lbl.setText('Planning failed: try again')
        elif self.state == CalibrationMovementsGUI.MOVED_TO_POSE:
            self.guide_lbl.setText(
                'Pose reached: take a sample and go on to next pose')

        can_plan = self.state == CalibrationMovementsGUI.GOOD_STARTING_POSITION
        self.plan_btn.setEnabled(can_plan)
        can_move = self.state == CalibrationMovementsGUI.GOOD_PLAN
        self.execute_btn.setEnabled(can_move)
        QCoreApplication.processEvents()

    def handle_check_current_state(self):
        self.state = CalibrationMovementsGUI.CHECKING_STARTING_POSITION
        self.update_ui()
        res = self.handeye_client.check_starting_pose()
        if res.can_calibrate:
            self.state = CalibrationMovementsGUI.GOOD_STARTING_POSITION
        else:
            self.state = CalibrationMovementsGUI.BAD_STARTING_POSITION
        self.current_target_pose = res.target_poses.current_target_pose_index
        self.target_poses = res.target_poses.target_poses
        self.plan_was_successful = None

        self.update_ui()

    def handle_next_pose(self):
        res = self.handeye_client.select_target_pose(self.current_target_pose +
                                                     1)
        self.current_target_pose = res.target_poses.current_target_pose_index
        self.target_poses = res.target_poses.target_poses
        self.plan_was_successful = None

        self.state = CalibrationMovementsGUI.GOOD_STARTING_POSITION
        self.update_ui()

    def handle_plan(self):
        self.guide_lbl.setText(
            'Planning to the next position. Click on execute when a good one was found'
        )
        res = self.handeye_client.plan_to_selected_target_pose()
        self.plan_was_successful = res.success
        if self.plan_was_successful:
            self.state = CalibrationMovementsGUI.GOOD_PLAN
        else:
            self.state = CalibrationMovementsGUI.BAD_PLAN
        self.update_ui()

    def handle_execute(self):
        if self.plan_was_successful:
            self.guide_lbl.setText('Going to the selected pose')
            res = self.handeye_client.execute_plan()
            if res.success:
                self.state = CalibrationMovementsGUI.MOVED_TO_POSE
            else:
                self.state = CalibrationMovementsGUI.MOVEMENT_FAILED
            self.update_ui()
Ejemplo n.º 14
0
class NavViewWidget(QWidget):

    def __init__(self, map_topic='/map',
                 paths=['/move_base/NavFn/plan', '/move_base/TrajectoryPlannerROS/local_plan'],
                 polygons=['/move_base/local_costmap/robot_footprint']):
        super(NavViewWidget, self).__init__()
        self._layout = QVBoxLayout()
        self._button_layout = QHBoxLayout()

        self.setAcceptDrops(True)
        self.setWindowTitle('Navigation Viewer')

        self.paths = paths
        self.polygons = polygons
        self.map = map_topic
        self._tf = tf.TransformListener()

        self._nav_view = NavView(map_topic, paths, polygons, tf = self._tf, parent = self)

        self._set_pose = QPushButton('Set Pose')
        self._set_pose.clicked.connect(self._nav_view.pose_mode)
        self._set_goal = QPushButton('Set Goal')
        self._set_goal.clicked.connect(self._nav_view.goal_mode)

        self._button_layout.addWidget(self._set_pose)
        self._button_layout.addWidget(self._set_goal)

        self._layout.addLayout(self._button_layout)

        self._layout.addWidget(self._nav_view)

        self.setLayout(self._layout)

    def dragEnterEvent(self, e):
        if not e.mimeData().hasText():
            if not hasattr(e.source(), 'selectedItems') or len(e.source().selectedItems()) == 0:
                qWarning('NavView.dragEnterEvent(): not hasattr(event.source(), selectedItems) or len(event.source().selectedItems()) == 0')
                return
            item = e.source().selectedItems()[0]
            topic_name = item.data(0, Qt.UserRole)
            if topic_name == None:
                qWarning('NavView.dragEnterEvent(): not hasattr(item, ros_topic_name_)')
                return

        else:
            topic_name = str(e.mimeData().text())

        if accepted_topic(topic_name):
            e.accept()
            e.acceptProposedAction()

    def dropEvent(self, e):
        if e.mimeData().hasText():
            topic_name = str(e.mimeData().text())
        else:
            droped_item = e.source().selectedItems()[0]
            topic_name = str(droped_item.data(0, Qt.UserRole))

        topic_type, array = get_field_type(topic_name)
        if not array:
            if topic_type is OccupancyGrid:
                self.map = topic_name

                # Swap out the nav view for one with the new topics
                self._nav_view.close()
                self._nav_view = NavView(self.map, self.paths, self.polygons, self._tf, self)
                self._layout.addWidget(self._nav_view)
            elif topic_type is Path:
                self.paths.append(topic_name)
                self._nav_view.add_path(topic_name)
            elif topic_type is PolygonStamped:
                self.polygons.append(topic_name)
                self._nav_view.add_polygon(topic_name)

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

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