Esempio n. 1
0
    def show_pop_up(self):
        msg = QMessageBox()
        msg.setWindowTitle('Alternative flight plan received')
        msg.setText('Accept alternative flight plan?')
        msg.setIcon(QMessageBox.Question)
        msg.setStandardButtons(QMessageBox.Yes|QMessageBox.No)
        msg.setDefaultButton(QMessageBox.No)
        # msg.setInformativeText('Accept new plan?')
        msg.setDetailedText('{}'.format(self.alternative_flight_plan))
        # msg.buttonClicked.connect(self.handle_message_box)  # TODO: do handling here?
        pop_up_response = msg.exec_()
        ros_response = RPSFlightPlanAccept()
        ros_response.icao = self.alternative_flight_plan.icao
        ros_response.flight_plan_id = self.alternative_flight_plan.flight_plan_id

        if pop_up_response == QMessageBox.Yes:
            ros_response.accept = True
            # Try to call light_sim service to change flight plan
            try:
                light_sim_change_flight_plan = rospy.ServiceProxy('/gauss_light_sim/change_flight_plan', ChangeFlightPlan)
                light_sim_change_flight_plan(ChangeFlightPlanRequest(alternative=copy.deepcopy(self.alternative_flight_plan)))
            except rospy.ServiceException as e:
                print("[RQt] Service call failed: %s"%e)

        if pop_up_response == QMessageBox.No:
            ros_response.accept = False
        self.acceptance_pub.publish(ros_response)
        self.alternative_flight_plan = None
Esempio n. 2
0
    def _import(self):
        print "import"
        array = pd.read_excel(self.gui.file_path,
                              index_col=[0]).values.tolist()

        if len(self.data_replay) > 0:
            msg = QMessageBox()
            msg.setIcon(QMessageBox.Warning)
            msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
            msg.setText("Data is not empty!\n Force clear")
            retval = msg.exec_()
            if retval == QMessageBox.Cancel:
                return
            else:
                self.data_replay = []
                self.gui.listVeiw.clear()

        if isinstance(array, list):
            self.data_replay = array
            for i in range(0, len(self.data_replay)):
                self.gui.listView_add_item(i)

        pass
class ChecklistWindow(QWidget):
    def __init__(self, aircraft_id):
        super(ChecklistWindow, self).__init__()
        # Set properties of the window
        self.setWindowTitle("BTO and BPO Checklist")
        self.resize(500, 700)
        self.move(200,100)
        self.checklist_state = 0

        # Relative path for the default BPO and BTO checklist
        BPO_checklist_file = os.path.join(rospkg.RosPack().get_path('yonah_rqt'), 'src/yonah_rqt', 'BPO_checklist.csv')
        BTO_checklist_file = os.path.join(rospkg.RosPack().get_path('yonah_rqt'), 'src/yonah_rqt', 'BTO_checklist.csv')
        
        # Check whether checklist is present, if not print a error message to terminal
        try:
            # If checklist is present, parse it and pass it to its respective variable
            self.BPO_checklist = self.excel_parser(BPO_checklist_file)
            self.BTO_checklist = self.excel_parser(BTO_checklist_file)
        except:
            rospy.logerr("Checklist files are missing or named wrongly. Please follow the original directory and naming")
            exit()
    
        # Create the layout
        self.main_layout = QVBoxLayout()
        self.buttons_layout = QHBoxLayout()
        self.tree_widget_layout = QHBoxLayout()
        
        # Create the widgets
        self.create_widget()
        self.has_message_opened = 0

        # Add the widgets into the layouts
        self.main_layout.addLayout(self.tree_widget_layout)
        self.main_layout.addLayout(self.buttons_layout)
        self.setLayout(self.main_layout)

    # Create the main layout of widget
    def create_widget(self):
        # Create tree structure
        self.create_tree()

        # Declare buttons and connect each of them to a function
        self.load_button = QPushButton('Load')
        self.ok_button = QPushButton('OK')
        self.cancel_button = QPushButton('Cancel')
        self.load_button.pressed.connect(self.load_clicked)
        self.ok_button.pressed.connect(self.ok_clicked)
        self.cancel_button.pressed.connect(self.cancel_clicked)
        
        # Add buttons into the layout
        self.buttons_layout.addWidget(self.load_button)
        self.buttons_layout.addWidget(self.cancel_button)
        self.buttons_layout.addWidget(self.ok_button)
        self.tree_widget_layout.addWidget(self.tree_widget)

    # Create the tree layout of widget inside of the main layout
    def create_tree(self):
        # Set up the main tree widget
        self.tree_widget = QTreeWidget()
        self.tree_widget.setColumnCount(2)
        self.tree_widget.setColumnWidth(0, 250)
        self.tree_widget.setHeaderLabels(['Parts', 'Status'])
        self.item = QTreeWidgetItem()
        
        # Create the BPO section
        self.BPO_header = QTreeWidgetItem(self.tree_widget)
        self.BPO_header.setFlags(self.BPO_header.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
        self.BPO_header.setText(0, 'BPO Checklist')
        self.BPO_header.setExpanded(True)
        self.create_item(self.BPO_header, self.BPO_checklist) # Adds the list of items into the section

        # Create the BTO section
        self.BTO_header = QTreeWidgetItem(self.tree_widget)
        self.BTO_header.setFlags(self.BTO_header.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
        self.BTO_header.setText(0, 'BTO Checklist')
        self.BTO_header.setExpanded(True)
        self.create_item(self.BTO_header, self.BTO_checklist) # Adds the list of items into the section

    # Populate the tree layout with items
    def create_item(self, parent, list):
        section_header = [] # List of the section headers
        for i in range (len(list)):
            if (list[i][1] == '' and list[i][0] != ''):
                section_header.append(list[i][0])
        k = 0

        # Iterate through the different sections
        for j in range (len(section_header)):
            # Child refers to the sections (mechanical, avionics, etc)
            child = QTreeWidgetItem(parent)
            child.setFlags(child.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
            child.setText(0, section_header[j])

            while k < len(list):
                if list[k][0] in section_header:
                    # When the while loop encounters the first title, continue the loop
                    if (list[k][0] == section_header[0]):
                        k += 1
                        continue
                    # When the while loop encounters the next titles, break the loop so that the value of j increases
                    k += 1 
                    break
                # when the list contains empty cells, skip the cell and continue
                elif list[k][0] == '':
                    k += 1
                    continue
                # Add the list items to the treewidgetitem
                # Grandchild refers to the items under each section (wing nuts, tail nuts, etc)
                grandchild = QTreeWidgetItem(child)
                grandchild.setText(0, list[k][0])
                grandchild.setText(1, list[k][1])
                grandchild.setCheckState(0, Qt.Unchecked) # Set all checkbox to its unchecked state
                k += 1

    # Read the excel sheet and parse it as an array
    def excel_parser(self, file_name):
        with open(file_name, 'r') as file:
            checklist = []
            reader = csv.reader(file)
            for row in reader:
                checklist.append(row)
            return checklist            
    
    # Determines what happens when load button is clicked
    def load_clicked(self):
        # Use QFileDialog to open the system's file browser
        filenames = QFileDialog.getOpenFileNames(
            self, self.tr('Load from Files'), '.', self.tr('csv files {.csv} (*.csv)'))
        # Iterate through the file names selected
        for filename in filenames[0]:
            # If the file names has the word BPO or BTO in it, remove current widget, add the loaded one
            if (filename.find('BPO') != -1):
                self.BPO_checklist = self.excel_parser(filename)
                self.remove_widget()
                self.create_widget()
            elif (filename.find('BTO') != -1):
                self.BTO_checklist = self.excel_parser(filename)
                self.remove_widget()
                self.create_widget()
            else:
                rospy.logerr('rqt: Checklist name must contain BPO or BTO')
                self.close()
    
    # Close all the main_layout
    def remove_widget(self):
        self.main_layout.removeWidget(self.tree_widget)
        self.tree_widget.deleteLater()
        self.buttons_layout.removeWidget(self.ok_button)
        self.buttons_layout.removeWidget(self.cancel_button)
        self.buttons_layout.removeWidget(self.load_button)
        self.ok_button.deleteLater()
        self.cancel_button.deleteLater()
        self.load_button.deleteLater()
    
     # Declare what will happen when ok button is clicked
    def ok_clicked(self):
        if self.BPO_header.checkState(0) != 2 or self.BTO_header.checkState(0) != 2: # User clicks ok without checking all
            self.dialog_window("Some items in the checklist are still unchecked", "Do you still want to continue?", True)
        else:
            self.checklist_state = 1
            self.close()

    # Declare what will happen when cancel button is clicked
    def cancel_clicked(self):
        if self.BPO_header.checkState(0) != 0 or self.BTO_header.checkState(0) != 0: # User clicks cancel with some boxes checked
            self.dialog_window('Some of your items are checked. Cancelling will uncheck all your items', 'Do you still want to continue?', False)
        else:
            self.BTO_header.setCheckState(0, Qt.Unchecked)
            self.BPO_header.setCheckState(0, Qt.Unchecked)
            self.close()
    
    # Create a pop up window when user pre-emptively cancelled or clicked ok without completing the checklist
    def dialog_window(self, message, detail, check):
        self.message = QMessageBox()
        self.has_message_opened = 1
        self.message.setIcon(QMessageBox.Warning)
        self.message.setText(message)
        self.message.setInformativeText(detail)
        self.message.setWindowTitle("Items are unchecked")
        self.message.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
        self.message.show()
        if check == True: # Check == True means it is from ok_clicked
            self.message.buttonClicked.connect(self.message_action)
        else:
            self.message.buttonClicked.connect(self.message_action_uncheck)
    
    # Determines what happens after dialog_window pops up from ok_button
    def message_action(self, i):
        if i.text() == '&Yes':
            self.checklist_state = 1
            self.close()
        else:
            self.message.close()

    # Determines what happens after dialog_window pops up from cancel_button
    def message_action_uncheck(self, i):
        self.response = i.text()
        if self.response == '&Yes':
            self.checklist_state = 1
            self.BTO_header.setCheckState(0, Qt.Unchecked)
            self.BPO_header.setCheckState(0, Qt.Unchecked)
            self.close()
        else:
            self.message.close()

    # Shutdown function
    def shutdown(self):
        self.close()
        if self.has_message_opened == 1:
            self.message.close()
class AnnotatorWidget(QWidget):
    """
    Annotator tool viewer
    """
    #name = 'Annotator'
    set_status_text = Signal(str)

    def __init__(self, context, bag_widget, publish_clock):
        super(AnnotatorWidget, self).__init__()
        rp = rospkg.RosPack()
        ui_file = os.path.join(rp.get_path('rqt_bag_meri_annotator'),
                               'resource', 'MeriPlugin.ui')
        loadUi(ui_file, self, {'AnnotatorGraphicsView': AnnotatorGraphicsView})
        self.setObjectName('AnnotatorWidget')
        self.setMouseTracking(True)
        self.annotation_data = list()
        self.interaction_time = 120.0

        self.bag_widget = bag_widget
        self.bagtimeline = self.bag_widget._timeline
        self._child_index = 0
        self.settings = QSettings("UFES", "MERI Annotator Widget")
        #self.settings.setValue("Last_child_index",self._child_index)

        self.instance = vlc.Instance()
        self.mediaplayer = self.instance.media_player_new()
        self.isPaused = False
        self.msgBox = QMessageBox()
        self.msgBox.setIcon(QMessageBox.Information)
        self.msgBox.setWindowTitle('Annotator Interface Information')
        self.msgBox.setStandardButtons(QMessageBox.Ok)

        self.BtnSaveJson.clicked.connect(self.BtnSaveJsonClicked)
        self.BtnLoadJson.clicked.connect(self.BtnLoadJsonClicked)
        self.BtnNext.clicked.connect(self.BtnNextClicked)
        self.BtnSetupBag.clicked.connect(self.BtnSetupBagClicked)
        self.BtnPrevious.clicked.connect(self.BtnPreviousClicked)
        self.BtnZero.clicked.connect(self.BtnZeroClicked)
        self.BtnOne.clicked.connect(self.BtnOneClicked)
        self.BtnTwo.clicked.connect(self.BtnTwoClicked)
        self.BtnAimLess.clicked.connect(self.BtnAimLessClicked)
        self.BtnGoalOriented.clicked.connect(self.BtnGoalOrientedClicked)
        self.BtnRobotStarted.clicked.connect(self.BtnRobotStartedClicked)
        self.BtnPointing.clicked.connect(self.BtnPointingClicked)
        self.BtnFollowLor.clicked.connect(self.BtnFollowLorClicked)
        self.BtnAdultSeek.clicked.connect(self.BtnAdultSeekClicked)
        self.BtnECTwC.clicked.connect(self.BtnECTwCClicked)
        self.BtnECTwR.clicked.connect(self.BtnECTwRClicked)
        self.BtnECTwT.clicked.connect(self.BtnECTwTClicked)
        self.BtnPlay.clicked.connect(self.BtnPlayClicked)
        self.BtnPause.clicked.connect(self.BtnPauseClicked)
        self.BtnStop.clicked.connect(self.BtnStopClicked)

        self.BtnPlay.setIcon(QIcon.fromTheme('media-playback-start'))
        self.BtnPause.setIcon(QIcon.fromTheme('media-playback-pause'))
        self.BtnLoadJson.setIcon(QIcon.fromTheme('document-open'))
        self.BtnSaveJson.setIcon(QIcon.fromTheme('document-save'))
        self.BtnStop.setIcon(QIcon.fromTheme('media-playback-stop'))
        self.BtnNext.setIcon(QIcon.fromTheme('go-next'))
        self.BtnSetupBag.setIcon(QIcon.fromTheme('document-properties'))
        self.BtnPrevious.setIcon(QIcon.fromTheme('go-previous'))

    def BtnSaveJsonClicked(self):
        if self.SpecialistName.text() == "":
            self.msgBox.setText(
                'Please register your name in the <html><b> Specialist_Name </b></html> box'
            )
            retval = self.msgBox.exec_()
        else:
            if len(self.annotation_data) == 0:
                self.msgBox.setText('No annotation has been recorded')
                retval = self.msgBox.exec_()
            else:
                annotationfile = [
                    self.SpecialistName.text() + "_annotation_" +
                    self._child_data[self._child_index]['ID'] + ".json"
                ]
                annotationfile_path = os.path.join(os.path.expanduser('~'),
                                                   'Documents',
                                                   'Annotation_files',
                                                   annotationfile[0])
                if os.path.exists(annotationfile_path):
                    self.msgBox.setText(
                        '<html><b>' + self.SpecialistName.text() +
                        '</b></html> already recorder annotations for child: <html><b>'
                        + self._child_data[self._child_index]['ID'] +
                        '</b></html>')
                    retval = self.msgBox.exec_()
                else:
                    with open(annotationfile_path, "w") as write_file:
                        json.dump(self.annotation_data, write_file)
                    self.msgBox.setText('Annotation File:  <html><b>' +
                                        annotationfile[0] +
                                        '</b></html> Saved!')
                    retval = self.msgBox.exec_()

    def BtnLoadJsonClicked(self):
        self._child_data = None
        json_path = self.settings.value("Last_path")
        if json_path == "":
            json_path = os.path.join(os.path.expanduser('~'), 'Documents')
        json_file = QFileDialog.getOpenFileName(self, "Open JSON File",
                                                json_path)
        self.settings.setValue("Last_path", json_file[0])
        with open(json_file[0]) as f:
            self._child_data = json.load(f)
        if self.settings.value("Last_child_index") is not None:
            self._child_index = int(self.settings.value("Last_child_index"))
        if self._child_index > len(self._child_data) - 1:
            self._child_index = 0
        self.LineChildId.setText(self._child_data[self._child_index]['ID'])
        self.msgBox.setText('Json Data of <html><b>' +
                            str(len(self._child_data)) +
                            '</b></html> Children were loaded')
        retval = self.msgBox.exec_()

    def BtnNextClicked(self):
        if self._child_index < len(self._child_data) - 1:
            self._child_index = self._child_index + 1
            self.LineChildId.setText(self._child_data[self._child_index]['ID'])
            self.settings.setValue("Last_child_index", self._child_index)

    def BtnPreviousClicked(self):
        if self._child_index > 0:
            self._child_index = self._child_index - 1
            self.LineChildId.setText(self._child_data[self._child_index]['ID'])
            self.settings.setValue("Last_child_index", self._child_index)

    def BtnSetupBagClicked(self):
        kinect2_a_bag_name = 'image_kinect2_a_' + self._child_data[
            self._child_index]['Kinect_a']
        kinect2_b_bag_name = 'image_kinect2_b_' + self._child_data[
            self._child_index]['Kinect_b']
        focus_bag_name = 'focus_data_' + self._child_data[
            self._child_index]['Focus']

        k2a_bag_file = os.path.join(os.path.expanduser('~'), "Documents",
                                    "hg_rosbag", "test_files",
                                    kinect2_a_bag_name)
        k2b_bag_file = os.path.join(os.path.expanduser('~'), "Documents",
                                    "hg_rosbag", "test_files",
                                    kinect2_b_bag_name)
        focus_bag_file = os.path.join(os.path.expanduser('~'), "Documents",
                                      "hg_rosbag", "test_files",
                                      focus_bag_name)

        self.bag_widget.load_bag(k2a_bag_file)
        self.bag_widget.load_bag(k2b_bag_file)
        #self.bag_widget.load_bag(focus_bag_file)

        audio_file_name = self._child_data[
            self._child_index]['Picture(jpg)/Audio(mp3)'] + '.mp3'
        audio_media_file = os.path.join(os.path.expanduser('~'), "Documents",
                                        "hg_rosbag", "audios", audio_file_name)
        self.OpenAudioMedia(audio_media_file)

        if self.checkCutBag.isChecked() == True:
            last_path = self.settings.value("Last_path")
            acronym_file = last_path[len(last_path) - 9:len(last_path) - 5]
            if acronym_file[0] == "s":
                config_name = ["cwa" + acronym_file + "_rs.json"]
            elif acronym_file[0] == "o":
                config_name = ["cw" + acronym_file + "_rs.json"]
            config_path = os.path.join(os.path.expanduser('~'), 'Documents',
                                       config_name[0])
            with open(config_path) as f:
                bag_config = json.load(f)

            if float(bag_config[self._child_index]
                     ['Sec']) > self.interaction_time:
                self.bagtimeline._timeline_frame._start_stamp = self.bagtimeline._timeline_frame._start_stamp + rospy.Duration.from_sec(
                    float(bag_config[self._child_index]['Sec']) -
                    self.interaction_time)
                self.annotation_data.append({
                    'key': 'Robot Started',
                    'time_stamp': 0,
                    'Sec': self.interaction_time
                })
            else:
                self.annotation_data.append({
                    'key':
                    'Robot Started',
                    'time_stamp':
                    0,
                    'Sec':
                    float(bag_config[self._child_index]['Sec'])
                })
            if (self.bagtimeline._timeline_frame._end_stamp -
                    self.bagtimeline._timeline_frame._start_stamp
                ) > rospy.Duration.from_sec(self.interaction_time * 2):
                self.bagtimeline._timeline_frame._end_stamp = self.bagtimeline._timeline_frame._start_stamp + rospy.Duration.from_sec(
                    self.interaction_time * 2)

    def BtnZeroClicked(self):
        task = self.ComBoxTask.currentText() + " 0 pts"
        self.AnnotationYamlCreator(task)

    def BtnOneClicked(self):
        task = self.ComBoxTask.currentText() + " 1 pts"
        self.AnnotationYamlCreator(task)

    def BtnTwoClicked(self):
        task = self.ComBoxTask.currentText() + " 2 pts"
        self.AnnotationYamlCreator(task)

    def BtnAimLessClicked(self):
        self.AnnotationYamlCreator('AimLess')

    def BtnGoalOrientedClicked(self):
        self.AnnotationYamlCreator('Goal Oriented')

    def BtnRobotStartedClicked(self):
        self.AnnotationYamlCreator('Robot Started')

    def BtnPointingClicked(self):
        self.AnnotationYamlCreator('Pointing')

    def BtnFollowLorClicked(self):
        self.AnnotationYamlCreator('Following LoR')

    def BtnAdultSeekClicked(self):
        self.AnnotationYamlCreator('AdultSeek')

    def BtnECTwCClicked(self):
        self.AnnotationYamlCreator('Eye Contact TwC')

    def BtnECTwRClicked(self):
        self.AnnotationYamlCreator('Eye Contact TwR')

    def BtnECTwTClicked(self):
        self.AnnotationYamlCreator('Eye Contact TwT')

    def BtnPlayClicked(self):
        self.bag_widget.play_button.setChecked(True)
        self.bag_widget.play_button.setIcon(self.bag_widget.pause_icon)
        self.bagtimeline.navigate_play()
        self.mediaplayer.play()

    def BtnPauseClicked(self):
        self.bag_widget.play_button.setChecked(False)
        self.bag_widget.play_button.setIcon(self.bag_widget.play_icon)
        self.bagtimeline.navigate_stop()
        self.mediaplayer.pause()

    def BtnStopClicked(self):
        self.bag_widget.play_button.setChecked(False)
        self.bag_widget.play_button.setIcon(self.bag_widget.play_icon)
        self.bagtimeline.navigate_stop()
        self.bagtimeline.navigate_start()
        self.mediaplayer.stop()

    def AnnotationYamlCreator(self, Annotation):
        playhead_time = self.bagtimeline._timeline_frame.playhead
        self.annotation_data.append({
            'key':
            Annotation,
            'time_stamp':
            playhead_time.to_nsec(),
            'Sec': (playhead_time -
                    self.bagtimeline._timeline_frame.start_stamp).to_sec()
        })

    def OpenAudioMedia(self, filename=None):
        """Open a media file in a MediaPlayer
          """
        self.media = self.instance.media_new(filename)
        # put the media in the media player
        self.mediaplayer.set_media(self.media)

    def shutdown_all(self):
        self.bagtimeline.handle_close()
        self.mediaplayer.stop()
        pass