예제 #1
0
    def create_button(self,
                      name,
                      callback=None,
                      image_path=None,
                      size=(128, 160),
                      always_enabled=False):
        """Create a push button which the mock input device can register.

        :param name:
            Name of the button
        :param callback:
            The callback to attach to the button when pressed
        :param image_path:
            The name of the image file
        :param size:
            Default size of the button
        :param always_enabled:
            Never disable the button if it's not in possible gaits

        :return:
            A QPushButton object which contains the passed arguments
        """
        if image_path is None:
            qt_button = QPushButton()

            text = check_string(name)
            qt_button.setText(text)
        else:
            qt_button = ImageButton(get_image_path(image_path))

        qt_button.setObjectName(name)

        if always_enabled:
            self._always_enabled_buttons.append(name)
            qt_button.setEnabled(True)

        qt_button.setMinimumSize(QSize(*size))
        qt_button.setMaximumSize(QSize(*size))

        if callback:
            qt_button.clicked.connect(callback)

        return qt_button
예제 #2
0
class ApplyGroup(BoxGroup):
    class ApplyUpdater(QObject):

        pending_updates = Signal(bool)

        def __init__(self, updater, loopback):
            super(ApplyGroup.ApplyUpdater, self).__init__()
            self.updater = updater
            self.loopback = loopback
            self._configs_pending = {}

        def update(self, config):
            for name, value in config.items():
                self._configs_pending[name] = value
            self.loopback(config)
            self.pending_updates.emit(bool(self._configs_pending))

        def apply_update(self):
            self.updater.update(self._configs_pending)
            self._configs_pending = {}
            self.pending_updates.emit(False)

    def __init__(self, updater, config, nodename):
        self.updater = ApplyGroup.ApplyUpdater(updater, self.update_group)
        super(ApplyGroup, self).__init__(self.updater, config, nodename)

        self.button = QPushButton('Apply %s' % self.param_name)
        self.button.clicked.connect(self.updater.apply_update)

        self.button.setEnabled(False)
        self.updater.pending_updates.connect(self._pending_cb)

        self.grid.addRow(self.button)

    def _pending_cb(self, pending_updates):
        if not pending_updates and self.button.hasFocus():
            # Explicitly clear focus to prevent focus from being
            # passed to the next in the chain automatically
            self.button.clearFocus()
        self.button.setEnabled(pending_updates)
예제 #3
0
class NodeSelection(QWidget):
    def __init__(self, parent):
        super(NodeSelection, self).__init__()
        self.parent_widget = parent
        self.selected_nodes = []
        self.setWindowTitle("Select the nodes you want to record")
        self.resize(500, 700)
        self.area = QScrollArea(self)
        self.main_widget = QWidget(self.area)
        self.ok_button = QPushButton("Done", self)
        self.ok_button.clicked.connect(self.onButtonClicked)
        self.ok_button.setEnabled(False)
        self.main_vlayout = QVBoxLayout(self)
        self.main_vlayout.addWidget(self.area)
        self.main_vlayout.addWidget(self.ok_button)
        self.setLayout(self.main_vlayout)

        self.selection_vlayout = QVBoxLayout(self)

        self.node_list = rosnode.get_node_names()
        self.node_list.sort()
        for node in self.node_list:
            self.addCheckBox(node)
        self.main_widget.setLayout(self.selection_vlayout)
        self.show()

    def addCheckBox(self, node):
        item = QCheckBox(node, self)
        item.stateChanged.connect(lambda x: self.updateNode(x, node))
        self.selection_vlayout.addWidget(item)

    def updateNode(self, state, node):
        if state == Qt.Checked:
            self.selected_nodes.append(node)
        else:
            self.selected_nodes.remove(node)
        if len(self.selected_nodes) > 0:
            self.ok_button.setEnabled(True)
        else:
            self.ok_button.setEnabled(False)

    def onButtonClicked(self):
        master = rosgraph.Master('rqt_bag_recorder')
        state = master.getSystemState()
        subs = [
            t for t, l in state[1] if len([
                node_name
                for node_name in self.selected_nodes if node_name in l
            ]) > 0
        ]
        # print subs
        # print len(subs)
        for topic in subs:
            self.parent_widget.changeTopicCheckState(topic, Qt.Checked)
            self.parent_widget.updateList(Qt.Checked, topic, topic)
        self.close()
예제 #4
0
class NodeSelection(QWidget):
    def __init__(self, parent):
        super(NodeSelection, self).__init__()
        self.parent_widget = parent
        self.selected_nodes = []
        self.setWindowTitle("Select the nodes you want to record")
        self.resize(500, 700)
        self.area = QScrollArea(self)
        self.main_widget = QWidget(self.area)
        self.ok_button = QPushButton("Done", self)
        self.ok_button.clicked.connect(self.onButtonClicked)
        self.ok_button.setEnabled(False)
        self.main_vlayout = QVBoxLayout(self)
        self.main_vlayout.addWidget(self.area)
        self.main_vlayout.addWidget(self.ok_button)
        self.setLayout(self.main_vlayout)

        self.selection_vlayout = QVBoxLayout(self)

        self.node_list = rosnode.get_node_names()
        self.node_list.sort()
        for node in self.node_list:
            self.addCheckBox(node)
        self.main_widget.setLayout(self.selection_vlayout)
        self.show()

    def addCheckBox(self, node):
        item = QCheckBox(node, self)
        item.stateChanged.connect(lambda x: self.updateNode(x, node))
        self.selection_vlayout.addWidget(item)

    def updateNode(self, state, node):
        if state == Qt.Checked:
            self.selected_nodes.append(node)
        else:
            self.selected_nodes.remove(node)
        if len(self.selected_nodes) > 0:
            self.ok_button.setEnabled(True)
        else:
            self.ok_button.setEnabled(False)

    def onButtonClicked(self):
        master = rosgraph.Master('rqt_bag_recorder')
        state = master.getSystemState()
        subs = [t for t, l in state[1]
                if len([node_name for node_name in self.selected_nodes if node_name in l]) > 0]
        for topic in subs:
            self.parent_widget.changeTopicCheckState(topic, Qt.Checked)
            self.parent_widget.updateList(Qt.Checked, topic)
        self.close()
예제 #5
0
class BagParser(QWidget):
    def __init__(self, bag_files, listtopics, duration):
        super(BagParser, self).__init__()

        # window title
        self.setWindowTitle("Making csv file")
        # size of window
        self.resize(960, 720)
        #self.showFullScreen()
        #self.setWindowState(Qt.WindowMaximized)

        # print listtopics
        # print E.get_general_features_options()
        # print E.get_specific_features_options()

        self.topics_items = dict()
        self.topics_items["0"] = listtopics
        self.topics_items["1"] = E.get_general_features_options()
        self.topics_items["2"] = E.get_specific_features_options()

        print self.topics_items

        #path to bag file
        self.bag_files = bag_files

        self.selected_bag_topics = []
        self.selected_specific_features = []
        self.selected_general_features = []

        self.items_list_topics = []

        self.area = QScrollArea(self)
        self.areagen = QScrollArea(self)
        self.areaspec = QScrollArea(self)
        self.main_widget = QWidget(self.area)
        self.main_widget1 = QWidget(self.areagen)
        self.main_widget2 = QWidget(self.areaspec)
        self.ok_button = QPushButton("Export To CSV", self)
        #self.ok_button.setFixedSize(150, 30)
        self.ok_button.clicked.connect(self.onButtonClicked)

        self.clear_button = QPushButton("Clear Selection", self)
        # self.clear_button.resize(self.clear_button.sizeHint())
        self.clear_button.clicked.connect(self.onClearClicked)

        self.choose_button = QPushButton("Get Last Export Choose", self)
        self.choose_button.clicked.connect(self.onButtonChooseCliked)
        self.ok_button.setEnabled(False)

        self.label1 = QLabel("Select topic from bag(s)", self)
        self.label1.setAlignment(Qt.AlignCenter)

        self.label2 = QLabel("Statistics Features", self)
        self.label2.setAlignment(Qt.AlignCenter)

        self.label3 = QLabel("Specific Features", self)
        self.label3.setAlignment(Qt.AlignCenter)

        self.duration = duration

        self.label5 = QLabel("Duration Time: " + str("%.1f" % duration), self)
        self.label5.setAlignment(Qt.AlignCenter)

        self.main_vlayout = QVBoxLayout(self)
        # self.main_vlayout = QGridLayout(self)
        self.main_vlayout.addWidget(self.label1)
        self.main_vlayout.addWidget(self.area)
        self.main_vlayout.addWidget(self.label2)
        self.main_vlayout.addWidget(self.areagen)
        self.main_vlayout.addWidget(self.label3)
        self.main_vlayout.addWidget(self.areaspec)

        self.label4 = QLabel("Window time", self)
        self.label4.setAlignment(Qt.AlignCenter)

        # self.main_vlayout.addWidget(self.label4)

        self.window = QLineEdit(self)
        # self.main_vlayout.addWidget(self.window)
        self.window.setText("1")

        self.windows_time_3 = QHBoxLayout(self)

        self.windows_time_3.addWidget(self.label4)

        self.windows_time_3.addWidget(self.window)

        self.windows_time_3.addWidget(self.label5)

        self.main_vlayout.addLayout(self.windows_time_3)

        # self.window = QLineEdit(self)
        # self.window.setText("1")

        # self.box = QVBoxLayout()
        # self.box.addStretch(1)
        # self.box.addWidget(self.clear_button)
        # self.box.addWidget(self.choose_button)
        # self.box.addWidget(self.label4)
        # self.box.addWidget(self.window)
        # self.box.addWidget(self.label5)
        # self.box.addWidget(self.ok_button)

        #self.main_vlayout.addWidget(self.from_nodes_button)

        # self.main_vlayout.addLayout(self.box)

        self.two_buttons = QHBoxLayout(self)

        self.two_buttons.addWidget(self.choose_button)

        self.two_buttons.addWidget(self.clear_button)

        self.main_vlayout.addLayout(self.two_buttons)

        self.main_vlayout.addWidget(self.ok_button)

        self.setLayout(self.main_vlayout)

        self.selection_vlayout = QVBoxLayout(self)
        self.item_all = MyQCheckBox("All", self, self.selection_vlayout, None)
        self.item_all.stateChanged.connect(
            lambda x: self.updateList(x, self.item_all, None))
        self.selection_vlayout.addWidget(self.item_all)
        topic_data_list = listtopics
        topic_data_list.sort()
        for topic in topic_data_list:
            self.addCheckBox(topic, self.selection_vlayout,
                             self.selected_bag_topics)

        self.selection_vlayout1 = QVBoxLayout(self)
        self.item_all1 = MyQCheckBox("All", self, self.selection_vlayout1,
                                     None)
        self.item_all1.stateChanged.connect(
            lambda x: self.updateList(x, self.item_all1, None))
        self.selection_vlayout1.addWidget(self.item_all1)
        topic_data_list1 = E.get_general_features_options()
        topic_data_list1.sort()
        for topic in topic_data_list1:
            self.addCheckBox(topic, self.selection_vlayout1,
                             self.selected_general_features)

        self.selection_vlayout2 = QVBoxLayout(self)
        self.item_all2 = MyQCheckBox("All", self, self.selection_vlayout2,
                                     None)
        self.item_all2.stateChanged.connect(
            lambda x: self.updateList(x, self.item_all2, None))
        self.selection_vlayout2.addWidget(self.item_all2)
        topic_data_list2 = E.get_specific_features_options()
        topic_data_list2.sort()
        for topic in topic_data_list2:
            self.addCheckBox(topic, self.selection_vlayout2,
                             self.selected_specific_features)

        self.main_widget.setLayout(self.selection_vlayout)
        self.main_widget1.setLayout(self.selection_vlayout1)
        self.main_widget2.setLayout(self.selection_vlayout2)

        self.area.setWidget(self.main_widget)
        self.areagen.setWidget(self.main_widget1)
        self.areaspec.setWidget(self.main_widget2)
        self.show()

    def onClearClicked(self):
        self.clearTopicCheckState()

    def clearTopicCheckState(self):
        for item in self.items_list_topics:
            item.setCheckState(False)
        self.item_all.setCheckState(False)
        self.item_all1.setCheckState(False)
        self.item_all2.setCheckState(False)

    def addCheckBox(self, topic, selection_vlayout, selected_list):
        item = MyQCheckBox(topic, self, selection_vlayout, selected_list)
        item.stateChanged.connect(lambda x: self.updateList(x, item, topic))
        self.items_list_topics.append(item)
        selection_vlayout.addWidget(item)

    def changeTopicCheckState(self, topic, state):
        for item in self.items_list_topics:
            if item.text() == topic:
                item.setCheckState(state)
                return

    def updateList(self,
                   state,
                   item_clicked,
                   topic=None,
                   force_update_state=False):
        if topic is None:  # The "All" checkbox was checked / unchecked
            # print "if topic is None"
            if state == Qt.Checked:
                self.item_all.setTristate(False)
                for item in self.items_list_topics:
                    if item.checkState() == Qt.Unchecked and \
                            item.selection_vlayout == item_clicked.selection_vlayout:
                        item.setCheckState(Qt.Checked)
            elif state == Qt.Unchecked:
                self.item_all.setTristate(False)
                for item in self.items_list_topics:
                    if item.checkState() == Qt.Checked and \
                            item.selection_vlayout == item_clicked.selection_vlayout:
                        item.setCheckState(Qt.Unchecked)
        else:
            # print "else:"
            if state == Qt.Checked:
                item_clicked.selected_list.append(topic)
                print item_clicked.selected_list
            else:
                item_clicked.selected_list.remove(topic)
                #if self.item_all.checkState() == Qt.Checked:
                #    self.item_all.setCheckState(Qt.PartiallyChecked)

        if self.selected_specific_features != []:
            if self.selected_general_features != [] and self.selected_bag_topics != []:
                self.ok_button.setEnabled(True)
            elif self.selected_general_features == [] and self.selected_bag_topics == []:
                self.ok_button.setEnabled(True)
            else:
                self.ok_button.setEnabled(False)
        else:
            if self.selected_general_features != [] and self.selected_bag_topics != []:
                self.ok_button.setEnabled(True)
            else:
                self.ok_button.setEnabled(False)

        # if self.selected_bag_topics != []:
        #     if self.selected_specific_features == [] and self.selected_general_features == []:
        #         self.ok_button.setEnabled(False)
        #     else:
        #         self.ok_button.setEnabled(True)
        #     # elif self.selected_specific_features != [] and self.selected_general_features == []:
        #     #     self.ok_button.setEnabled(True)
        #     # elif self.selected_specific_features == [] and self.selected_general_features != []:
        #     #     self.ok_button.setEnabled(True)
        # else:
        #     self.ok_button.setEnabled(False)

        # if self.selected_specific_features != []:
        #     if self.selected_bag_topics == [] and self.selected_general_features == []:
        #         self.ok_button.setEnabled(True)
        #     elif self.selected_bag_topics != [] and self.selected_general_features != []:
        #         self.ok_button.setEnabled(True)
        #     else:
        #         self.ok_button.setEnabled(False)
        # else:
        #     if self.selected_bag_topics == [] or self.selected_general_features == []:
        #         self.ok_button.setEnabled(False)
        #     else:
        #         self.ok_button.setEnabled(True)

    def onButtonChooseCliked(self):
        for checkbox in self.items_list_topics:
            checkbox.setCheckState(Qt.Unchecked)
        with open(get_path() + "logger.log", 'r') as f:
            topics = f.read().splitlines()
        for checkbox in self.items_list_topics:
            if checkbox.text() in topics:
                checkbox.setCheckState(Qt.Checked)

    def get_current_opened_directory(self, filepath):
        import os
        direc = "/"
        if os.path.isfile(filepath):
            with open(filepath, 'r') as f:
                direc = f.read()
        return direc

    def onButtonClicked(self):
        import inspect, os
        filepath = os.path.dirname(
            os.path.abspath(inspect.getfile(
                inspect.currentframe()))) + "/log/save_csv.log"
        current_directory = self.get_current_opened_directory(filepath)
        window = self.window.text()
        try:
            val = float(window)
        except ValueError:
            QMessageBox.about(self, "Error in Window Time",
                              "That's not a number!")
            return
        if val >= self.duration:
            QMessageBox.about(
                self, "Error in Window Time",
                "time need to be smaller than: " + str(self.duration))
            return
        # filename = QFileDialog.getSaveFileName(self, self.tr('csv File'), current_directory, self.tr('csv (*.csv)'))
        saved_dir = str(
            QFileDialog.getExistingDirectory(self, "Select Directory",
                                             current_directory))
        # if filename[0] != '':
        #     with open(filepath, "w") as f:
        #         f.write(filename[0])
        if saved_dir != '':
            with open(filepath, "w") as f:
                f.write(saved_dir)
            topics = self.selected_bag_topics
            specific_features_selection = self.selected_specific_features
            general_features_selection = self.selected_general_features
            with open(get_path() + 'logger.log', "w") as f:
                for topic in topics:
                    f.write(topic + "\n")
                for topic1 in specific_features_selection:
                    f.write(topic1 + "\n")
                for topic2 in general_features_selection:
                    f.write(topic2 + "\n")
            ef = E.ExtractFeatures(topics, float(window),
                                   specific_features_selection,
                                   general_features_selection)
            counter = 0
            for bag_file in self.bag_files:
                df = ef.generate_features(bag_file)
                if len(self.bag_files) == 1:
                    counter = -1
                # temp = filename + "/" +
                # temp = get_corrent_file_name(filename[0], ".csv", counter)
                csv_path = generate_csv_from_bag(saved_dir, bag_file)
                # temp = "%s_%s%s" % (filename[0],counter,".csv")
                E.write_to_csv(csv_path, df)
                counter = counter + 1
            QMessageBox.about(self, "csv export",
                              "csv was exported successfuly")
예제 #6
0
파일: qt.py 프로젝트: zaxrok/py_trees_ros
class Dashboard(QWidget):

    _scan_button_led = Signal(bool)
    _cancel_button_led = Signal(bool)

    def __init__(self):
        super(Dashboard, self).__init__()

        not_latched = False
        # latched = True
        self.publishers = py_trees_ros.utilities.Publishers([
            ('scan', "~scan", std_msgs.Empty, not_latched, 1),
            ('cancel', "~cancel", std_msgs.Empty, not_latched, 1),
        ])

        self.scan_push_button = QPushButton("Scan")
        self.scan_push_button.setStyleSheet("QPushButton { font-size: 30pt; }")
        self.scan_push_button.setSizePolicy(QSizePolicy.Expanding,
                                            QSizePolicy.Expanding)
        self.scan_push_button.pressed.connect(
            functools.partial(self.publish_button_message,
                              self.publishers.scan))

        self.cancel_push_button = QPushButton("Cancel")
        self.cancel_push_button.setStyleSheet(
            "QPushButton { font-size: 30pt; }")
        self.cancel_push_button.setSizePolicy(QSizePolicy.Expanding,
                                              QSizePolicy.Expanding)
        self.cancel_push_button.pressed.connect(
            functools.partial(self.publish_button_message,
                              self.publishers.cancel))

        self.led_strip_flashing = False
        self.led_strip_on_count = 1
        self.led_strip_colour = "grey"

        self.led_strip_lock = threading.Lock()
        self.led_strip_timer = QTimer()
        self.led_strip_timer.timeout.connect(self.led_strip_timer_callback)
        self.led_strip_label = QLabel("LED Strip")
        self.led_strip_label.setAlignment(Qt.AlignCenter)
        self.led_strip_label.setSizePolicy(QSizePolicy.Expanding,
                                           QSizePolicy.Expanding)
        self.led_strip_label.setStyleSheet(
            "background-color: %s; font-size: 30pt;" % self.led_strip_colour)

        self.hbox_layout = QGridLayout(self)
        self.hbox_layout.addWidget(self.scan_push_button)
        self.hbox_layout.addWidget(self.cancel_push_button)
        self.hbox_layout.addWidget(self.led_strip_label)

        self.subscribers = py_trees_ros.utilities.Subscribers([
            ("report", "/tree/report", std_msgs.String,
             self.reality_report_callback),
            ("led_strip", "/led_strip/display", std_msgs.String,
             self.led_strip_display_callback)
        ])
        self.led_strip_timer.start(500)  # ms

    def publish_button_message(self, publisher):
        publisher.publish(std_msgs.Empty())

    def reality_report_callback(self, msg):
        if msg.data == "cancelling":
            self.set_scanning_colour(False)
            self.set_cancelling_colour(True)
            self.cancel_push_button.setEnabled(True)
        elif msg.data == "scanning":
            self.set_scanning_colour(True)
            self.set_cancelling_colour(False)
            self.cancel_push_button.setEnabled(True)
        else:
            self.set_scanning_colour(False)
            self.set_cancelling_colour(False)
            self.cancel_push_button.setEnabled(False)

    def set_cancelling_colour(self, val):
        if val:
            self.cancel_push_button.setStyleSheet(
                "QPushButton { font-size: 30pt; background-color: red}")
        else:
            self.cancel_push_button.setStyleSheet(
                "QPushButton { font-size: 30pt; }")

    def set_scanning_colour(self, val):
        if val:
            self.scan_push_button.setStyleSheet(
                "QPushButton { font-size: 30pt; background-color: green}")
        else:
            self.scan_push_button.setStyleSheet(
                "QPushButton { font-size: 30pt; }")

    def led_strip_display_callback(self, msg):
        with self.led_strip_lock:
            if not msg.data:
                self.led_strip_colour = "grey"
                self.led_strip_flashing = False
            else:
                self.led_strip_flashing = True
                self.led_strip_colour = None
                for colour in ["blue", "red", "green"]:
                    if colour in msg.data:
                        self.led_strip_colour = colour
                        break
                if not self.led_strip_colour:
                    self.led_strip_colour = "pink"
                    rospy.loginfo(
                        "Dashboard: received unknown LED colour {0}, setting 'pink'"
                        .format(msg.data))

    @Slot()
    def led_strip_timer_callback(self):
        with self.led_strip_lock:
            if self.led_strip_flashing:
                if self.led_strip_on_count > 0:
                    self.led_strip_on_count = 0
                    self.led_strip_label.setStyleSheet(
                        "background-color: none; font-size: 30pt;")
                else:
                    self.led_strip_on_count += 1
                    self.led_strip_label.setStyleSheet(
                        "background-color: %s; font-size: 30pt;" %
                        self.led_strip_colour)
            else:  # solid
                self.led_strip_on_count = 1
                self.led_strip_label.setStyleSheet(
                    "background-color: %s; font-size: 30pt;" %
                    self.led_strip_colour)
예제 #7
0
class TopicSelection(QWidget):

    recordSettingsSelected = Signal(bool, list)

    def __init__(self):
        super(TopicSelection, self).__init__()
        master = rosgraph.Master('rqt_bag_recorder')
        self.setWindowTitle("Select the topics you want to record")
        self.resize(500, 700)

        self.topic_list = []
        self.selected_topics = []
        self.items_list = []

        self.area = QScrollArea(self)
        self.main_widget = QWidget(self.area)
        self.ok_button = QPushButton("Record", self)
        self.ok_button.clicked.connect(self.onButtonClicked)
        self.ok_button.setEnabled(False)

        self.from_nodes_button = QPushButton("From Nodes", self)
        self.from_nodes_button.clicked.connect(self.onFromNodesButtonClicked)

        self.main_vlayout = QVBoxLayout(self)
        self.main_vlayout.addWidget(self.area)
        self.main_vlayout.addWidget(self.ok_button)
        self.main_vlayout.addWidget(self.from_nodes_button)
        self.setLayout(self.main_vlayout)

        self.selection_vlayout = QVBoxLayout(self)
        self.item_all = QCheckBox("All", self)
        self.item_monitor = QCheckBox("Monitor", self)
        self.item_monAge = QCheckBox("Monitor + Agents", self)
        self.item_all.stateChanged.connect(self.updateList)
        self.item_monitor.stateChanged.connect(lambda x: self.updateList(x, "Monitor"))
        self.item_monAge.stateChanged.connect(lambda x: self.updateList(x, "Monitor+"))
        self.selection_vlayout.addWidget(self.item_all)
        self.selection_vlayout.addWidget(self.item_monitor)
        self.selection_vlayout.addWidget(self.item_monAge)
        topic_data_list = master.getPublishedTopics('')
        topic_data_list.sort()
        for topic, datatype in topic_data_list:
            self.addCheckBox(topic)

        self.main_widget.setLayout(self.selection_vlayout)

        self.area.setWidget(self.main_widget)
        self.show()

    def addCheckBox(self, topic):
        self.topic_list.append(topic)
        item = QCheckBox(topic, self)
        item.stateChanged.connect(lambda x: self.updateList(x, topic))
        self.items_list.append(item)
        self.selection_vlayout.addWidget(item)

    def changeTopicCheckState(self, topic, state):
        for item in self.items_list:
            if item.text() == topic:
                item.setCheckState(state)
                return

    def updateList(self, state, topic=None, force_update_state=False):
        if topic is None:  # The "All" checkbox was checked / unchecked
            if state == Qt.Checked:
                self.item_all.setTristate(False)
                for item in self.items_list:
                    if item.checkState() == Qt.Unchecked:
                        item.setCheckState(Qt.Checked)
            elif state == Qt.Unchecked:
                self.item_all.setTristate(False)
                for item in self.items_list:
                    if item.checkState() == Qt.Checked:
                        item.setCheckState(Qt.Unchecked)
        elif topic == "Monitor" or topic == "Monitor+":
            if state == Qt.Checked:
                self.item_monitor.setTristate(False)
                self.selected_topics.append("/world_model")
                self.selected_topics.append("/draws")
                self.selected_topics.append("/debugs")
                self.selected_topics.append("/referee")
                for item in self.items_list:
                    if item.text() == "/world_model" \
                            or item.text() == "/debugs" \
                            or item.text() == "/draws" \
                            or item.text() =="/referee":
                        item.setCheckState(Qt.Checked)
            elif state == Qt.Unchecked:
                self.item_all.setTristate(False)
                self.selected_topics.remove("/world_model")
                self.selected_topics.remove("/draws")
                self.selected_topics.remove("/debugs")
                self.selected_topics.remove("/referee")
                for item in self.items_list:
                    if item.text() == "/world_model" \
                            or item.text() =="/referee" \
                            or item.text() =="/debugs" \
                            or item.text()=="/draws":
                        item.setCheckState(Qt.Unchecked)

            if topic == "Monitor+":
                if state == Qt.Checked:
                    for item in self.items_list:
                        if item.text().find("agent") >-1:
                            self.selected_topics.append(item)
                            item.setCheckState(Qt.Checked)

                elif state == Qt.Unchecked:
                    for item in self.items_list:
                        if item.text().find("agent") >-1:
                            self.selected_topics.remove(item)
                            item.setCheckState(Qt.Unchecked)

        else:
            if state == Qt.Checked:
                self.selected_topics.append(topic)
            else:
                self.selected_topics.remove(topic)
                if self.item_all.checkState() == Qt.Checked:
                    self.item_all.setCheckState(Qt.PartiallyChecked)

        if self.selected_topics == []:
            self.ok_button.setEnabled(False)
        else:
            self.ok_button.setEnabled(True)

    def onButtonClicked(self):
        self.close()
        self.recordSettingsSelected.emit(
            self.item_all.checkState() == Qt.Checked, self.selected_topics)

    def onFromNodesButtonClicked(self):
        self.node_selection = NodeSelection(self)
예제 #8
0
class TopicSelection(QWidget):

    recordSettingsSelected = Signal(bool, list)

    def __init__(self):
        super(TopicSelection, self).__init__()
        master = rosgraph.Master('rqt_bag_recorder')
        self.setWindowTitle("Select the topics you want to record")
        self.resize(500, 700)

        self.topic_list = []
        self.selected_topics = []
        self.items_list = []

        self.area = QScrollArea(self)
        self.main_widget = QWidget(self.area)
        self.ok_button = QPushButton("Record", self)
        self.ok_button.clicked.connect(self.onButtonClicked)
        self.ok_button.setEnabled(False)

        self.main_vlayout = QVBoxLayout(self)
        self.main_vlayout.addWidget(self.area)
        self.main_vlayout.addWidget(self.ok_button)
        self.setLayout(self.main_vlayout)

        self.selection_vlayout = QVBoxLayout(self)
        self.item_all = QCheckBox("All", self)
        self.item_all.stateChanged.connect(self.updateList)
        self.selection_vlayout.addWidget(self.item_all)
        topic_data_list = master.getPublishedTopics('')
        topic_data_list.sort()
        for topic, datatype in topic_data_list:
            self.addCheckBox(topic)

        self.main_widget.setLayout(self.selection_vlayout)

        self.area.setWidget(self.main_widget)
        self.show()

    def addCheckBox(self, topic):
        self.topic_list.append(topic)
        item = QCheckBox(topic, self)
        item.stateChanged.connect(lambda x: self.updateList(x,topic))
        self.items_list.append(item)
        self.selection_vlayout.addWidget(item)


    def updateList(self, state, topic = None):
        if topic is None: # The "All" checkbox was checked / unchecked
            if state == Qt.Checked:
                self.item_all.setTristate(False)
                for item in self.items_list:
                    if item.checkState() == Qt.Unchecked:
                        item.setCheckState(Qt.Checked)
            elif state == Qt.Unchecked:
                self.item_all.setTristate(False)
                for item in self.items_list:
                    if item.checkState() == Qt.Checked:
                        item.setCheckState(Qt.Unchecked)
        else:
            if state == Qt.Checked:
                self.selected_topics.append(topic)
            else:
                self.selected_topics.remove(topic)
                if self.item_all.checkState()==Qt.Checked:
                    self.item_all.setCheckState(Qt.PartiallyChecked)

        if self.selected_topics == []:
            self.ok_button.setEnabled(False)
        else:
            self.ok_button.setEnabled(True)

    def onButtonClicked(self):
        self.close()
        self.recordSettingsSelected.emit((self.item_all.checkState() == Qt.Checked), self.selected_topics)
예제 #9
0
class TopicSelection(QWidget):

    recordSettingsSelected = Signal(bool, list)

    def __init__(self):
        super(TopicSelection, self).__init__()
        master = rosgraph.Master('rqt_bag_recorder')
        self.setWindowTitle("Select the topics you want to record")
        self.resize(500, 700)

        self.topic_list = []
        self.selected_topics = []
        self.items_list = []

        self.area = QScrollArea(self)
        self.main_widget = QWidget(self.area)
        self.ok_button = QPushButton("Record", self)
        self.ok_button.clicked.connect(self.onButtonClicked)
        self.ok_button.setEnabled(False)

        self.main_vlayout = QVBoxLayout(self)
        self.main_vlayout.addWidget(self.area)
        self.main_vlayout.addWidget(self.ok_button)
        self.setLayout(self.main_vlayout)

        self.selection_vlayout = QVBoxLayout(self)
        self.item_all = QCheckBox("All", self)
        self.item_all.stateChanged.connect(self.updateList)
        self.selection_vlayout.addWidget(self.item_all)
        topic_data_list = master.getPublishedTopics('')
        topic_data_list.sort()
        for topic, datatype in topic_data_list:
            self.addCheckBox(topic)

        self.main_widget.setLayout(self.selection_vlayout)

        self.area.setWidget(self.main_widget)
        self.show()

    def addCheckBox(self, topic):
        self.topic_list.append(topic)
        item = QCheckBox(topic, self)
        item.stateChanged.connect(lambda x: self.updateList(x, topic))
        self.items_list.append(item)
        self.selection_vlayout.addWidget(item)

    def updateList(self, state, topic=None):
        if topic is None:  # The "All" checkbox was checked / unchecked
            if state == Qt.Checked:
                self.item_all.setTristate(False)
                for item in self.items_list:
                    if item.checkState() == Qt.Unchecked:
                        item.setCheckState(Qt.Checked)
            elif state == Qt.Unchecked:
                self.item_all.setTristate(False)
                for item in self.items_list:
                    if item.checkState() == Qt.Checked:
                        item.setCheckState(Qt.Unchecked)
        else:
            if state == Qt.Checked:
                self.selected_topics.append(topic)
            else:
                self.selected_topics.remove(topic)
                if self.item_all.checkState() == Qt.Checked:
                    self.item_all.setCheckState(Qt.PartiallyChecked)

        if self.selected_topics == []:
            self.ok_button.setEnabled(False)
        else:
            self.ok_button.setEnabled(True)

    def onButtonClicked(self):
        self.close()
        self.recordSettingsSelected.emit(
            (self.item_all.checkState() == Qt.Checked), self.selected_topics)
예제 #10
0
class NodeSelection(QWidget):
    def __init__(self, parent):
        super(NodeSelection, self).__init__()
        self.parent_widget = parent
        self.selected_nodes = []
        self.setWindowTitle("Select the nodes you want to record")
        self.resize(300, 300)
        self.area = QScrollArea(self)
        self.main_widget = QWidget(self.area)
        self.ok_button = QPushButton("Done", self)
        self.ok_button.clicked.connect(self.onButtonClicked)
        self.ok_button.setEnabled(False)
        self.main_vlayout = QVBoxLayout(self)
        self.main_vlayout.addWidget(self.area)
        self.main_vlayout.addWidget(self.ok_button)
        self.setLayout(self.main_vlayout)

        self.selection_vlayout = QVBoxLayout(self)

        self.node_list = rosnode.get_node_names()
        self.node_list.sort()
        for node in self.node_list:
            # add planner node by choosing agent number
            if "planner" not in node:
                self.addCheckBox(node)

        self.main_widget.setLayout(self.selection_vlayout)
        self.area.setWidget(self.main_widget)

        self.show()

    def addCheckBox(self, node):
        item = QCheckBox(node, self)
        item.stateChanged.connect(lambda x: self.updateNode(x, node))
        self.selection_vlayout.addWidget(item)

    def updateNode(self, state, node):
        if state == Qt.Checked:
            self.selected_nodes.append(node)
            if "planner" + "_" + node.split("_")[1] in self.node_list:
                self.selected_nodes.append("planner" + "_" +
                                           node.split("_")[1])
        else:
            self.selected_nodes.remove(node)
            if "planner" + "_" + node.split("_")[1] in self.node_list:
                self.selected_nodes.remove("planner" + "_" +
                                           node.split("_")[1])

        if len(self.selected_nodes) > 0:
            self.ok_button.setEnabled(True)
        else:
            self.ok_button.setEnabled(False)

    def onButtonClicked(self):
        master = rosgraph.Master('rqt_bag_recorder')
        state = master.getSystemState()
        print state[1]
        subs = [
            t for t, l in state[1] if len([
                node_name
                for node_name in self.selected_nodes if node_name in l
            ]) > 0
        ]

        topic_data_list = master.getPublishedTopics('')
        topic_data_list.sort()
        for topic, datatype in topic_data_list:
            if ("/" + topic.split("/")[1] + "/task" in subs):
                subs.append(topic)
        for topic in subs:
            self.parent_widget.changeTopicCheckState(topic, Qt.Checked)
            self.parent_widget.updateList(Qt.Checked, topic)
        self.close()
예제 #11
0
class TopicSelection(QWidget):
    recordSettingsSelected = Signal(bool, list, dict)

    def __init__(self):
        super(TopicSelection, self).__init__()
        master = rosgraph.Master('rqt_bag_recorder')
        self.setWindowTitle("Record a Simulation")
        self.resize(650, 720)

        pre = TS.get_time_series_pre_feature_options()
        glob = TS.get_global_time_series_features_options()
        # print pre
        # print glob
        all_topics = S.get_topics_options()
        keys = all_topics.keys()
        # print all_topics.keys()[0]
        self.plp_filename = ""
        self.group_selected_items = dict()
        self.group_areas = dict()
        self.group_main_widget = dict()
        self.group_selection_vlayout = dict()
        self.group_item_all = dict()
        # self.main_vlayout = QVBoxLayout(self)
        self.main_vlayout = QVBoxLayout(self)

        self.group_label = dict()

        self.selected_topics = []
        self.items_list = []

        for group_name in all_topics:
            self.group_selected_items[group_name] = []
            self.group_areas[group_name] = QScrollArea(self)
            self.group_main_widget[group_name] = QWidget(
                self.group_areas[group_name])
            self.group_label[group_name] = QLabel(group_name, self)
            self.group_label[group_name].setAlignment(Qt.AlignCenter)
            self.main_vlayout.addWidget(self.group_label[group_name])
            self.main_vlayout.addWidget(self.group_areas[group_name])
            self.group_selection_vlayout[group_name] = QVBoxLayout(self)
            self.group_item_all[group_name] = MyQCheckBox(
                "All", self, self.group_selection_vlayout[group_name], None)
            self.MakeCheckBoxList(self.group_selection_vlayout[group_name],
                                  self.group_selected_items[group_name],
                                  all_topics[group_name],
                                  self.group_item_all[group_name])
            self.group_main_widget[group_name].setLayout(
                self.group_selection_vlayout[group_name])
            self.group_areas[group_name].setWidget(
                self.group_main_widget[group_name])

        self.label1 = QLabel("Scenarios", self)
        self.label1.setAlignment(Qt.AlignCenter)

        self.main_vlayout.addWidget(self.label1)

        scanarios = S.get_scenarios_options()
        self.scanarios_answer = scanarios
        self.map_answer = dict()
        # print scanarios
        keys1 = scanarios.keys()

        # print keys1[0]
        # print scanarios[keys1[0]]["name"]
        # print scanarios[keys1[0]]["params"]
        #
        # for item in scanarios[keys1[0]]["params"]:
        #     print item

        self.radio_items = dict()
        self.number_group = QButtonGroup(self)

        for id_radio in scanarios:
            self.radio_items[id_radio] = QRadioButton(
                scanarios[id_radio]["name"])
            self.number_group.addButton(self.radio_items[id_radio])
            self.main_vlayout.addWidget(self.radio_items[id_radio])
            self.radio_items[id_radio].setChecked(False)
            self.radio_items[id_radio].clicked.connect(
                partial(self.callConsult, scanarios[id_radio]["params"],
                        id_radio))

        self.select_path = QLineEdit()
        self.save_path = QLineEdit()

        self.select_path.setEnabled(False)
        self.save_path.setEnabled(False)

        self.plp_button = QPushButton("Select PLP Python File...", self)
        self.plp_button.clicked.connect(self.onPlpClicked)

        self.two_buttons1 = QHBoxLayout(self)

        self.two_buttons1.addWidget(self.plp_button)

        self.two_buttons1.addWidget(self.select_path)

        self.main_vlayout.addLayout(self.two_buttons1)

        # self.label = QLabel("live Topics", self)
        # self.label.setAlignment(Qt.AlignCenter)
        #
        # self.main_vlayout.addWidget(self.label)

        # self.area = QScrollArea(self)
        # self.main_widget = QWidget(self.area)

        self.ok_button = QPushButton("Record", self)
        self.ok_button.clicked.connect(self.onButtonClicked)
        self.ok_button.setEnabled(False)
        self.choose_button = QPushButton("Get Last Export Choose", self)
        self.choose_button.clicked.connect(self.onButtonChooseCliked)

        self.clear_button = QPushButton("Clear Selection", self)
        self.clear_button.clicked.connect(self.onClearClicked)

        self.choose_clear_buttons = QHBoxLayout(self)

        self.choose_clear_buttons.addWidget(self.choose_button)

        self.choose_clear_buttons.addWidget(self.clear_button)

        self.main_vlayout.addLayout(self.choose_clear_buttons)

        # self.main_vlayout.addRow(self.choose_button, self.clear_button)

        # self.from_nodes_button = QPushButton("From Nodes", self)
        # self.from_nodes_button.clicked.connect(self.onFromNodesButtonClicked)

        # self.main_vlayout.addWidget(self.area)
        # self.main_vlayout.addWidget(self.choose_button)
        self.main_vlayout.addWidget(self.ok_button)
        # self.main_vlayout.addWidget(self.from_nodes_button)
        self.setLayout(self.main_vlayout)

        self.selection_vlayout = QVBoxLayout(self)

        # self.item_all = MyQCheckBox("All", self, self.selection_vlayout, None)
        # self.item_all.stateChanged.connect(lambda x: self.updateList(x, self.item_all, None))
        # self.selection_vlayout.addWidget(self.item_all)
        # topic_data_list4 = map(lambda l: l[0], master.getPublishedTopics(''))
        # topic_data_list4.sort()
        # for topic in topic_data_list4:
        #     self.addCheckBox(topic, self.selection_vlayout, self.selected_topics)

        # self.main_widget.setLayout(self.selection_vlayout)

        # self.area.setWidget(self.main_widget)

        # print S.get_scenarios_options()

        self.show()

    def onClearClicked(self):
        self.clearTopicCheckState()

    def clearTopicCheckState(self):
        for item in self.items_list:
            item.setCheckState(False)
        for item in self.group_item_all.values():
            item.setCheckState(False)

    def onButtonChooseCliked(self):
        for checkbox in self.items_list:
            checkbox.setCheckState(Qt.Unchecked)
        with open(get_path() + "logger_topic.log", 'r') as f:
            topics = f.read().splitlines()
        for checkbox in self.items_list:
            if checkbox.text() in topics:
                checkbox.setCheckState(Qt.Checked)

    def callConsult(self, params, id_radio):
        self.input_dialog = inputDialog(params, id_radio)
        self.input_dialog.ParamsSelected.connect(self.params_answer)
        # item, ok = QInputDialog.getItem(self, "select parameter",
        #                                 "list of parameters", params, 0, False)
        # if ok and item:
        #     self.gettext(item)

    def params_answer(self, params, label_items, id_radio):
        if id_radio == 0:
            # print "------" + str(id_radio)
            self.number_group.setExclusive(False)
            # print self.radio_items
            for item in self.radio_items:
                # print self.radio_items[item]
                self.radio_items[item].setChecked(False)
            self.number_group.setExclusive(True)
            self.enable_record()
        else:
            # print id_radio
            # print params
            # print params.values()
            a = {}
            # print label_items
            for item, name in zip(params, label_items):
                # value = params[item].text()
                a[name] = item.text().encode("utf-8")
            # print a
            self.map_answer = {"id": id_radio, "params": a}
            self.enable_record()
            return self.map_answer

        # for item in params.values():
        #     print item.text()
        # pass

    # def gettext(self, item):
    #     text, ok = QInputDialog.getText(self, 'Text Input Dialog', item)
    #
    #     if ok:
    #        print self.multipleReplace(str(text), item)
    #
    #
    # def multipleReplace(self, text, item):
    #     for key in self.scanarios_answer:
    #         #
    #         print self.scanarios_answer[key]["params"]
    #         for id, par in enumerate(self.scanarios_answer[key]["params"]):
    #             if par == item:
    #                 self.scanarios_answer[key]["params"][id] = text
    #     for id_radio in self.radio_items.keys():
    #         if self.radio_items[id_radio].isChecked():
    #             self.map_answer = {"id" : id_radio, "params" : self.scanarios_answer[id_radio]["params"]}
    #     return self.map_answer

    def MakeCheckBoxList(self, selection_vlayout, selected, topics_Keys,
                         item_all):
        item_all.stateChanged.connect(
            lambda x: self.updateList(x, item_all, None))
        selection_vlayout.addWidget(item_all)
        topic_data_list = topics_Keys
        topic_data_list.sort()
        for topic in topic_data_list:
            self.addCheckBox(topic, selection_vlayout, selected)

    def get_item_by_name(self, item_name):
        for item in self.items_linputDialogist:
            if item.text() == item_name:
                return item
        return None

    def addCheckBox(self, topic, selection_vlayout, selected_list):
        item = MyQCheckBox(topic, self, selection_vlayout, selected_list)
        item.stateChanged.connect(lambda x: self.updateList(x, item, topic))
        self.items_list.append(item)
        selection_vlayout.addWidget(item)

    def changeTopicCheckState(self, topic, state):
        for item in self.items_list:
            if item.text() == topic:
                item.setCheckState(state)
                return

    # def updateList(self, state, topic=None, force_update_state=False):
    #     if topic is None:  # The "All" checkbox was checked / unchecked
    #         if state == Qt.Checked:
    #             self.item_all.setTristate(False)
    #             for item in self.items_list:
    #                 if item.checkState() == Qt.Unchecked:
    #                     item.setCheckState(Qt.Checked)
    #         elif state == Qt.Unchecked:
    #             self.item_all.setTristate(False)
    #             for item in self.items_list:
    #                 if item.checkState() == Qt.Checked:
    #                     item.setCheckState(Qt.Unchecked)
    #     else:
    #         if state == Qt.Checked:
    #             self.selected_topics.append(topic)
    #         else:
    #             self.selected_topics.remove(topic)
    #             if self.item_all.checkState() == Qt.Checked:
    #                 self.item_all.setCheckState(Qt.PartiallyChecked)
    #
    #     if self.selected_topics == []:
    #         self.ok_button.setEnabled(False)
    #     else:
    #         self.ok_button.setEnabled(True)

    def updateList(self,
                   state,
                   item_clicked,
                   topic=None,
                   force_update_state=False):
        if type(item_clicked) is str:
            item_clicked = self.get_item_by_name(item_clicked)
            if item_clicked is None:
                return
        if topic is None:  # The "All" checkbox was checked / unchecked
            #print "if topic is None"
            if state == Qt.Checked:
                # self.item_all.setTristate(False)
                for item in self.items_list:
                    if item.checkState() == Qt.Unchecked and \
                            item.selection_vlayout == item_clicked.selection_vlayout:
                        item.setCheckState(Qt.Checked)
            elif state == Qt.Unchecked:
                # self.item_all.setTristate(False)
                for item in self.items_list:
                    if item.checkState() == Qt.Checked and \
                            item.selection_vlayout == item_clicked.selection_vlayout:
                        item.setCheckState(Qt.Unchecked)
        else:
            if state == Qt.Checked:
                item_clicked.selected_list.append(topic)
                #print item_clicked.selected_list
            else:
                item_clicked.selected_list.remove(topic)
        #if self.item_all.checkState() == Qt.Checked:
        #    self.item_all.setCheckState(Qt.PartiallyChecked)

        self.enable_record()

    def enable_record(self):
        temp_selected_topics = []
        for item in self.group_selected_items.values():
            if item:
                for i in item:
                    temp_selected_topics.append(i)

        flag = False
        for item in self.radio_items:
            if self.radio_items[item].isChecked():
                flag = True
                break
            # print self.radio_items[item]

        # flag = reduce(lambda acc, curr: acc or , self.radio_items, False)
        # print "------+++++-" + str(flag)
        if len(temp_selected_topics) > 0 or len(self.selected_topics) > 0:
            self.ok_button.setEnabled(flag)
        else:
            self.ok_button.setEnabled(False)

    def onButtonClicked(self):
        # print self.group_selected_items
        for item in self.group_selected_items.values():
            if item:
                for i in item:
                    self.selected_topics.append(i)
        topics = self.selected_topics
        with open(get_path() + 'logger_topic.log', "w") as f:
            for topic in topics:
                f.write(topic + "\n")
        self.close()
        # TBD - runing plp on shell on itself
        # if self.plp_filename != "":
        #     from .plp import Plp
        #     Plp(self.plp_filename)
        self.recordSettingsSelected.emit(False, self.selected_topics,
                                         self.map_answer)

    def get_current_opened_directory(self, filepath):
        import os
        direc = "/"
        if os.path.isfile(filepath):
            with open(filepath, 'r') as f:
                pathes = f.read()
                direc = pathes.rsplit('/', 1)[0]
        return direc

    def onPlpClicked(self):
        import inspect, os
        filepath = os.path.dirname(
            os.path.abspath(inspect.getfile(
                inspect.currentframe()))) + "/log/save_plp.log"
        current_directory = self.get_current_opened_directory(filepath)
        fd = QFileDialog(self)
        wc = "Csv files {.py} (*.py)"
        # print current_directory
        filename, filter = fd.getOpenFileNamesAndFilter(
            filter=wc, initialFilter=('*.py'), directory=current_directory)
        if len(filename):
            self.plp_filename = filename[0]
            with open(filepath, "w") as f:
                f.write(self.plp_filename)
            self.select_path.setText(self.plp_filename)
            # print self.plp_filename[0]

    def onFromNodesButtonClicked(self):
        self.node_selection = NodeSelection(self)

    def getTopicsByName(self, name):
        arr = S.get_topics_options()
        return arr[name]
예제 #12
0
class MetricsRefboxWidget(QWidget):

    status_signal = pyqtSignal(object)
    timeout_signal = pyqtSignal(object)
    result_signal = pyqtSignal(object)
    bagfile_signal = pyqtSignal(object)

    def __init__(self):
        super(MetricsRefboxWidget, self).__init__()
        self.status_signal.connect(self.update_status)
        self.timeout_signal.connect(self._handle_timeout)
        self.result_signal.connect(self.update_result)
        self.bagfile_signal.connect(self._update_bagfile_name)
        self.timer = QElapsedTimer()
        self.timer_interrupt = QTimer(self)
        self.timer_interrupt.timeout.connect(self.update_timer)
        self.timer_interrupt.start(100)

        self.metrics_refbox = metrics_refbox.MetricsRefbox(
            self._status_cb, self._start_cb, self._result_cb)
        self.trial_configs = {}
        self.current_benchmark = None
        self.current_benchmark_enum = -1
        # once we receive confirmation from robot
        self.benchmark_running = False
        # once we send the start message to robot
        self.benchmark_started = False
        # set to True if we're not recording individual trials
        # but rather continuously recording all data (hence no timeouts)
        self.continuous_recording = False
        self.timeout = False
        self.stopped = False
        self.result_msg = None
        self.config_locked = True
        self.config = self.metrics_refbox.get_config()
        self.setup()
        self.show()

    def setup(self):
        layout = QGridLayout()

        # Sidebar
        self.benchmark_combo_box = QComboBox()
        for key in self.config['benchmarks'].keys():
            self.benchmark_combo_box.addItem(
                self.config['benchmarks'][key]['name'])
        self.benchmark_combo_box.currentIndexChanged.connect(
            self._handle_benchmark_selected)
        self.benchmark_combo_box.setMaximumWidth(SIDEBAR_WIDTH)
        self.set_current_benchmark()

        self.team_combo_box = QComboBox()
        for key in self.config['teams']:
            self.team_combo_box.addItem(key)
        self.team_combo_box.setMaximumWidth(SIDEBAR_WIDTH)
        self.test_communication_button = QPushButton('Test communication')
        self.test_communication_button.clicked.connect(self._handle_test_comm)

        self.trial_list_widget = QListWidget()
        self.trial_list_widget.currentItemChanged.connect(
            self._handle_trial_change)
        self.trial_list_widget.setMaximumWidth(SIDEBAR_WIDTH)

        sidebar_layout = QVBoxLayout()
        sidebar_layout.addWidget(QLabel("Team"))
        sidebar_layout.addWidget(self.team_combo_box)
        sidebar_layout.addWidget(self.test_communication_button)
        sidebar_layout.addWidget(QLabel("Benchmark"))
        sidebar_layout.addWidget(self.benchmark_combo_box)
        sidebar_layout.addWidget(QLabel("Trial"))
        sidebar_layout.addWidget(self.trial_list_widget)

        self.generate_button = QPushButton('Generate')
        self.generate_button.clicked.connect(self._handle_generate)

        self.delete_button = QPushButton('Delete')
        self.delete_button.clicked.connect(self._handle_delete)

        self.save_trials_button = QPushButton('Save')
        self.save_trials_button.clicked.connect(self._handle_save_trial_config)

        self.lock_button = QPushButton('Lock')
        if self.config_locked:
            self.lock_button.setText('Unlock')
        self.lock_button.clicked.connect(self._handle_lock)

        sidebar_button_layout = QGridLayout()
        sidebar_button_layout.addWidget(self.generate_button, 0, 0)
        sidebar_button_layout.addWidget(self.delete_button, 0, 1)
        sidebar_button_layout.addWidget(self.save_trials_button, 1, 0)
        sidebar_button_layout.addWidget(self.lock_button, 1, 1)
        sidebar_layout.addLayout(sidebar_button_layout)

        layout.addLayout(sidebar_layout, 0, 0)

        # Status box
        self.status = QPlainTextEdit()
        self.status.setReadOnly(True)
        self.status.setMaximumHeight(200)

        # row 1, col 0, rowspan 1, colspan 2
        layout.addWidget(self.status, 1, 0, 1, 2)

        # trial config and results
        trial_layout = QVBoxLayout()
        self.trial_config_layout = QHBoxLayout()
        self.trial_results_layout = QVBoxLayout()
        self.setup_trial_config()

        # benchmark trial controls
        benchmark_controls_group_box = QGroupBox('Controls')
        benchmark_controls_layout = QHBoxLayout()
        self.start_trial_button = QPushButton('Start')
        self.start_trial_button.clicked.connect(self._handle_start_trial)
        self.stop_trial_button = QPushButton('Stop')
        self.stop_trial_button.clicked.connect(self._handle_stop_trial)
        self.prev_trial_button = QPushButton('Previous')
        self.prev_trial_button.clicked.connect(self._handle_prev_trial)
        self.next_trial_button = QPushButton('Next')
        self.next_trial_button.clicked.connect(self._handle_next_trial)
        self.start_continuous_recording_button = QPushButton(
            'Start continuous recording')
        self.start_continuous_recording_button.clicked.connect(
            self._handle_continuous_recording)

        self.timer_field = QLabel()
        font = QFont("Arial", 20, QFont.Bold)
        self.timer_field.setFont(font)
        self.timer_field.setAutoFillBackground(True)
        benchmark_controls_layout.addWidget(self.start_trial_button)
        benchmark_controls_layout.addWidget(self.stop_trial_button)
        benchmark_controls_layout.addWidget(self.prev_trial_button)
        benchmark_controls_layout.addWidget(self.next_trial_button)
        benchmark_controls_layout.addWidget(
            self.start_continuous_recording_button)
        benchmark_controls_layout.addWidget(self.timer_field)
        benchmark_controls_group_box.setLayout(benchmark_controls_layout)

        trial_layout.addLayout(self.trial_config_layout)
        trial_layout.addWidget(benchmark_controls_group_box)
        trial_layout.addLayout(self.trial_results_layout)
        self.save_results_button = QPushButton('Save results')
        self.save_results_button.clicked.connect(self._handle_save_result)
        trial_layout.addWidget(self.save_results_button)

        layout.addLayout(trial_layout, 0, 1)

        self.setLayout(layout)
        self.show()

        self.show_env_var('ROS_MASTER_URI')
        self.show_env_var('ROS_IP')
        self.show_env_var('ROS_HOSTNAME')

    def show_env_var(self, var):
        env_str = os.getenv(var) if os.getenv(var) is not None else ''
        msg = var + ': ' + env_str + '\n'
        self.update_status(msg)

    def set_current_benchmark(self):
        '''
        Sets the current benchmark type based on user selection
        Load config file for selected benchmark and setup GUI to show config and results based on that
        '''
        benchmark_index = self.benchmark_combo_box.currentIndex()
        benchmark_name = list(
            self.config['benchmarks'].keys())[benchmark_index]
        benchmark_result_type = getattr(
            metrics_refbox_msgs.msg,
            self.config['benchmarks'][benchmark_name]['type'])
        config_file_name = benchmark_name + '.json'
        config_file = os.path.join(self.metrics_refbox.get_config_file_path(),
                                   config_file_name)
        stream = open(config_file, 'r')
        benchmark_config = json.load(stream)
        module = importlib.import_module(benchmark_config['module'])
        self.current_benchmark = getattr(module, benchmark_config['class'])(
            benchmark_config, self.metrics_refbox.get_config_file_path(),
            benchmark_name, benchmark_result_type)
        self.current_benchmark_enum = self.config['benchmarks'][
            benchmark_name]['enum']

    def setup_trial_config(self):
        '''
        set up the benchmark specific part of the GUI related to the configuration of
        the benchmark (for example, which objects will be used for object detection)

        the specific configuration is loaded based on the selected trial_index
        '''

        for i in reversed(range(self.trial_config_layout.count())):
            self.trial_config_layout.itemAt(i).widget().setParent(None)

        for i in reversed(range(self.trial_results_layout.count())):
            self.trial_results_layout.itemAt(i).widget().setParent(None)

        self.current_benchmark.setup(self.trial_config_layout,
                                     self.trial_results_layout,
                                     self.config_locked)

        self.trial_list_widget.clear()
        self.trial_configs.clear()

        path = os.path.join(self.metrics_refbox.get_config_file_path(),
                            'trials')
        trial_config_file = os.path.join(
            path, self.current_benchmark.config['trial_config'])
        if os.path.exists(trial_config_file):
            with open(trial_config_file, "r") as fp:
                trial_config = json.load(fp)
            for key in sorted(trial_config.keys()):
                trial_item = QListWidgetItem(key)
                trial_item.setFlags(trial_item.flags() | Qt.ItemIsEditable)
                self.trial_list_widget.addItem(trial_item)
                self.trial_configs[key] = trial_config[key]
            self.trial_list_widget.setCurrentRow(0)

    def _handle_test_comm(self):
        '''
        'Test communication' button
        '''
        self.metrics_refbox.test_communication()
        self.status_signal.emit('Sent test message to all clients\n')

    def _handle_benchmark_selected(self, idx):
        '''
        benchmark selection has changed
        '''
        self._handle_save_trial_config(None)
        self.set_current_benchmark()
        self.setup_trial_config()

    def _handle_trial_change(self, current_item, previous_item):
        '''
        Trial selection has changed
        '''
        if previous_item is not None:
            self.trial_configs[previous_item.text(
            )] = self.current_benchmark.get_current_selections()
            self.current_benchmark.clear_results()
        if current_item is not None and current_item.text(
        ) in self.trial_configs.keys() and self.trial_configs[
                current_item.text()] is not None:
            self.current_benchmark.apply_selections(
                self.trial_configs[current_item.text()])
        else:
            self.current_benchmark.clear_selections()

    def _handle_generate(self, button):
        '''
        generate a new trial config
        '''
        trial_config = self.current_benchmark.generate()
        names = []
        for key in self.trial_configs.keys():
            names.append(key)
        msg = 'Select a name for this trial configuration'
        text = ''
        while True:
            text, ok = QInputDialog.getText(self, 'Trial name', msg)
            if text not in names:
                break
            QMessageBox.critical(self, "Error", "Name exists already")
        if ok:
            trial_item = QListWidgetItem(text)
            trial_item.setFlags(trial_item.flags() | Qt.ItemIsEditable)
            self.trial_list_widget.addItem(trial_item)
            self.trial_configs[text] = trial_config
            self.trial_list_widget.setCurrentItem(trial_item)

    def _handle_delete(self, button):
        '''
        delete current trial config
        '''
        selected_items = self.trial_list_widget.selectedItems()
        for item in selected_items:
            self.trial_list_widget.takeItem(self.trial_list_widget.row(item))
            del self.trial_configs[item.text()]

    def _handle_save_trial_config(self, button):
        '''
        save trial config in case it has been edited
        '''
        if self.trial_list_widget.currentItem() is not None:
            self.trial_configs[self.trial_list_widget.currentItem().text(
            )] = self.current_benchmark.get_current_selections()
        path = os.path.join(self.metrics_refbox.get_config_file_path(),
                            'trials')
        trial_config_file = os.path.join(
            path, self.current_benchmark.config['trial_config'])
        with open(trial_config_file, "w") as fp:
            json.dump(self.trial_configs, fp)

    def _handle_lock(self, button):
        '''
        Lock trial config settings so they are not changed accidentally
        '''
        if self.config_locked:
            self.current_benchmark.unlock_config()
            self.config_locked = False
            self.lock_button.setText('Lock')
        else:
            self.current_benchmark.lock_config()
            self.config_locked = True
            self.lock_button.setText('Unlock')

    def _handle_start_trial(self, button):
        '''
        Trial start button; send command to refbox client via ROS node
        '''
        if self.benchmark_running or self.benchmark_started:
            self.update_status(
                "Benchmark has already started. Stop and start the benchmark if you want to restart it\n"
            )
        else:
            self.metrics_refbox.start(
                self.current_benchmark_enum,
                self.current_benchmark.get_task_info_for_robot())
            self.benchmark_started = True
            self.current_benchmark.clear_results()
            self.update_status("Sent start command\n")
            self.timer_field.setText('')
            self.disable_buttons()

    def _handle_stop_trial(self, button):
        '''
        Trial stop button
        '''
        self.metrics_refbox.stop()
        self.elapsed_time = self.timer.elapsed()
        self.stopped = True
        self.benchmark_running = False
        self.benchmark_started = False
        self.status_signal.emit("Sent stop command\n")
        self.result_signal.emit(None)
        self.enable_buttons()

    def _handle_next_trial(self, button):
        '''
        Select next trial
        '''
        row = self.trial_list_widget.currentRow()
        if (row + 1 < self.trial_list_widget.count()):
            self.trial_list_widget.setCurrentRow(row + 1)

    def _handle_prev_trial(self, button):
        '''
        Select previous trial
        '''
        row = self.trial_list_widget.currentRow()
        if (row - 1 >= 0):
            self.trial_list_widget.setCurrentRow(row - 1)

    def _handle_continuous_recording(self, button):
        '''
        Start recording button, not tied to any benchmark, and requires user to stop recording
        '''
        if self.benchmark_running or self.benchmark_started:
            self.metrics_refbox.stop()
            self.elapsed_time = self.timer.elapsed()
            self.stopped = True
            self.benchmark_running = False
            self.benchmark_started = False
            self.status_signal.emit("Sent stop command\n")
            self.start_continuous_recording_button.setText(
                'Start continuous recording')
            self.enable_buttons()
            self.stop_trial_button.setEnabled(True)
            self.continuous_recording = False
        else:
            self.metrics_refbox.start_recording()
            self.continuous_recording = True
            self.start_continuous_recording_button.setText('Stop recording')
            self.benchmark_started = True
            self.update_status("Sent start command\n")
            self.timer_field.setText('')
            self.disable_buttons()
            self.stop_trial_button.setEnabled(False)

    def _handle_save_result(self, button):
        '''
        Save results again in case notes were added
        '''
        self.result_signal.emit(self.result_msg)

    def _start_cb(self, msg):
        '''
        called when we get confirmation that the robot received the start message;
        official start of trial time
        '''
        if msg.data == True:
            self.elapsed_time = 0.0
            self.timer.start()
            self.benchmark_running = True
            self.timeout = False
            self.stopped = False
            self.result_msg = None
            if msg.rosbag_filename == '':
                self.status_signal.emit(
                    'Error: rosbag filename not specified although start message confirmed\n'
                )
                self._handle_stop_trial(None)
                return
            self.status_signal.emit('Started trial and recording to %s\n' %
                                    msg.rosbag_filename)
            self.bagfile_signal.emit(msg.rosbag_filename)
        else:
            self.status_signal.emit(
                'Error: Benchmark did not start, probably because the rosbag recorder is not running\n'
            )
            self._handle_stop_trial(None)

    def _result_cb(self, msg):
        '''
        called when we get a result from the robot
        official end of trial time
        '''
        if self.benchmark_running:
            self.elapsed_time = self.timer.elapsed()
            self.benchmark_running = False
            self.benchmark_started = False

            self.status_signal.emit("Trial completed in %.2f seconds\n" %
                                    (self.elapsed_time / 1000.0))
            self.result_msg = msg
            self.result_signal.emit(msg)
            self.enable_buttons()

    def _status_cb(self, msg):
        '''
        callback to send text to status box
        '''
        self.status_signal.emit(msg)

    def update_status(self, msg):
        '''
        signal handler for status box
        '''
        timestamp = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        m = '[' + timestamp + '] ' + msg
        self.status.insertPlainText(m)
        self.status.ensureCursorVisible()

    def _update_bagfile_name(self, name):
        self.current_benchmark.set_bagfile_name(name)

    def update_result(self, msg):
        '''
        signal handler for result message; process and save result
        '''
        self.current_benchmark.show_results(msg, self.timeout, self.stopped)
        current_trial_name = self.trial_list_widget.currentItem().text()
        current_team_name = self.team_combo_box.currentText()
        results_dict = self.current_benchmark.get_trial_result_dict(
            msg, current_trial_name, current_team_name, self.timeout,
            self.stopped, self.elapsed_time / 1000.0)

        filename = self.current_benchmark.get_bagfile_name(
        )[:-4] + '_' + self.current_benchmark.benchmark_name + '.json'
        path = os.path.join(self.metrics_refbox.get_results_file_path(),
                            filename)
        with open(path, "w") as fp:
            json.dump(results_dict, fp)

    def update_timer(self):
        '''
        Timer callback; update GUI, and also check if timeout has expired
        '''
        if not self.benchmark_running:
            return
        self.timer_field.setText("Time: %.1f s" %
                                 (self.timer.elapsed() / 1000.0))
        # if we're in continuous recording mode, no need to check timeout
        if self.continuous_recording:
            return
        if self.timer.hasExpired(self.current_benchmark.get_timeout() *
                                 1000.0):
            self.status_signal.emit(
                "Trial timeout of %.2f seconds has expired\n" %
                self.current_benchmark.get_timeout())
            self.timeout_signal.emit('timeout expired')

    def _handle_timeout(self, msg):
        '''
        timeout has expired, so stop the trial
        '''
        self.timeout = True
        self._handle_stop_trial(None)

    def closeEvent(self, event):
        '''
        make sure we save trial configs when window is closed
        '''
        self.metrics_refbox.stop()
        self._handle_save_trial_config(None)
        event.accept()

    def disable_buttons(self):
        '''
        disable buttons when trial is running
        '''
        self.team_combo_box.setEnabled(False)
        self.benchmark_combo_box.setEnabled(False)
        self.trial_list_widget.setEnabled(False)
        self.next_trial_button.setEnabled(False)
        self.prev_trial_button.setEnabled(False)
        self.delete_button.setEnabled(False)
        self.generate_button.setEnabled(False)
        self.save_trials_button.setEnabled(False)
        self.lock_button.setEnabled(False)
        self.start_trial_button.setEnabled(False)

    def enable_buttons(self):
        self.team_combo_box.setEnabled(True)
        self.benchmark_combo_box.setEnabled(True)
        self.trial_list_widget.setEnabled(True)
        self.next_trial_button.setEnabled(True)
        self.prev_trial_button.setEnabled(True)
        self.delete_button.setEnabled(True)
        self.generate_button.setEnabled(True)
        self.save_trials_button.setEnabled(True)
        self.lock_button.setEnabled(True)
        self.start_trial_button.setEnabled(True)