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
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)
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()
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()
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")
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)
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)
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)
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)
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()
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]
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)