Example #1
0
    def device_discovery(self, devs):
        group = QActionGroup(self._menu_devices, exclusive=True)

        for d in devs:
            node = QAction(d["name"], self._menu_devices, checkable=True)
            node.toggled.connect(self._inputdevice_selected)
            group.addAction(node)
            self._menu_devices.addAction(node)
            if (d["name"] == GuiConfig().get("input_device")):
                self._active_device = d["name"]
        if (len(self._active_device) == 0):
            self._active_device = self._menu_devices.actions()[0].text()

        device_config_mapping = GuiConfig().get("device_config_mapping")
        if (device_config_mapping):
            if (self._active_device in device_config_mapping.keys()):
                self._current_input_config = device_config_mapping[str(
                    self._active_device)]
            else:
                self._current_input_config = self._menu_mappings.actions(
                )[0].text()
        else:
            self._current_input_config = self._menu_mappings.actions()[0].text(
            )

        # Now we know what device to use and what mapping, trigger the events
        # to change the menus and start the input
        for c in self._menu_mappings.actions():
            c.setEnabled(True)
            if (c.text() == self._current_input_config):
                c.setChecked(True)

        for c in self._menu_devices.actions():
            if (c.text() == self._active_device):
                c.setChecked(True)
Example #2
0
 def minMaxThrustChanged(self):
     self.helper.inputDeviceReader.set_thrust_limits(
         self.percentageToThrust(self.minThrust.value()),
         self.percentageToThrust(self.maxThrust.value()))
     if (self.isInCrazyFlightmode == True):
         GuiConfig().set("min_thrust", self.minThrust.value())
         GuiConfig().set("max_thrust", self.maxThrust.value())
Example #3
0
    def toggleVisibility(self, checked):
        """Show or hide the tab."""
        if checked:
            self.tabWidget.addTab(self, self.getTabName())
            s = ""
            try:
                s = GuiConfig().get("open_tabs")
                if (len(s) > 0):
                    s += ","
            except Exception as e:
                logger.warning("Exception while adding tab to config and "
                               "reading tab config")
            # Check this since tabs in config are opened when app is started
            if (self.tabName not in s):
                s += "%s" % self.tabName
                GuiConfig().set("open_tabs", s)

        if not checked:
            self.tabWidget.removeTab(self.tabWidget.indexOf(self))
            try:
                parts = GuiConfig().get("open_tabs").split(",")
            except Exception as e:
                logger.warning("Exception while removing tab from config and "
                               "reading tab config")
                parts = []
            s = ""
            for p in parts:
                if (self.tabName != p):
                    s += "%s," % p
            s = s[0:len(s) - 1]  # Remove last comma
            GuiConfig().set("open_tabs", s)
    def connected(self, linkURI):
        # IMU & THRUST
        lg = LogConfig("Stabalizer", GuiConfig().get("ui_update_period"))
        lg.add_variable("stabilizer.roll", "float")
        lg.add_variable("stabilizer.pitch", "float")
        lg.add_variable("stabilizer.yaw", "float")
        lg.add_variable("stabilizer.thrust", "uint16_t")

        self.helper.cf.log.add_config(lg)
        if (lg.valid):
            lg.data_received_cb.add_callback(self._imu_data_signal.emit)
            lg.error_cb.add_callback(self._log_error_signal.emit)
            lg.start()
        else:
            logger.warning("Could not setup logconfiguration after "
                           "connection!")

        # MOTOR
        lg = LogConfig("Motors", GuiConfig().get("ui_update_period"))
        lg.add_variable("motor.m1")
        lg.add_variable("motor.m2")
        lg.add_variable("motor.m3")
        lg.add_variable("motor.m4")

        self.helper.cf.log.add_config(lg)
        if lg.valid:
            lg.data_received_cb.add_callback(self._motor_data_signal.emit)
            lg.error_cb.add_callback(self._log_error_signal.emit)
            lg.start()
        else:
            logger.warning("Could not setup logconfiguration after "
                           "connection!")
Example #5
0
    def _update_input(self, device="", config=""):
        self.joystickReader.stop_input()
        self._active_config = str(config)
        self._active_device = str(device)

        GuiConfig().set("input_device", self._active_device)
        GuiConfig().get("device_config_mapping")[
            self._active_device] = self._active_config
        self.joystickReader.start_input(self._active_device,
                                        self._active_config)

        # update the checked state of the menu items
        for c in self._menu_mappings.actions():
            c.setEnabled(True)
            if c.text() == self._active_config:
                c.setChecked(True)
        for c in self._menu_devices.actions():
            c.setEnabled(True)
            if c.text() == self._active_device:
                c.setChecked(True)

        # update label
        if device == "" and config == "":
            self._statusbar_label.setText("No input device selected")
        elif config == "":
            self._statusbar_label.setText("Using [%s] - "
                                          "No input config selected" %
                                          (self._active_device))
        else:
            self._statusbar_label.setText(
                "Using [%s] with config [%s]" %
                (self._active_device, self._active_config))
    def device_discovery(self, devs):
        group = QActionGroup(self._menu_devices, exclusive=True)

        for d in devs:
            node = QAction(d["name"], self._menu_devices, checkable=True)
            node.toggled.connect(self._inputdevice_selected)
            group.addAction(node)
            self._menu_devices.addAction(node)
            if (d["name"] == GuiConfig().get("input_device")):
                self._active_device = d["name"]
        if (len(self._active_device) == 0):
            self._active_device = self._menu_devices.actions()[0].text()

        device_config_mapping = GuiConfig().get("device_config_mapping")
        if (device_config_mapping):
            if (self._active_device in device_config_mapping.keys()):
                self._current_input_config = device_config_mapping[
                    str(self._active_device)]
            else:
                self._current_input_config = self._menu_mappings.actions()[0].text()
        else:
            self._current_input_config = self._menu_mappings.actions()[0].text()

        # Now we know what device to use and what mapping, trigger the events
        # to change the menus and start the input
        for c in self._menu_mappings.actions():
            c.setEnabled(True)
            if (c.text() == self._current_input_config):
                c.setChecked(True)

        for c in self._menu_devices.actions():
            if (c.text() == self._active_device):
                c.setChecked(True)
Example #7
0
    def _inputdevice_selected(self, checked):
        if (not checked):
            return
        self.joystickReader.stop_input()
        sender = self.sender()
        self._active_device = sender.text()
        device_config_mapping = GuiConfig().get("device_config_mapping")
        if (self._active_device in device_config_mapping.keys()):
            self._current_input_config = device_config_mapping[str(
                self._active_device)]
        else:
            self._current_input_config = self._menu_mappings.actions()[0].text(
            )
        GuiConfig().set("input_device", str(self._active_device))

        for c in self._menu_mappings.actions():
            if (c.text() == self._current_input_config):
                c.setChecked(True)

        self.joystickReader.start_input(str(sender.text()),
                                        self._current_input_config)
        self._statusbar_label.setText(
            "Using [%s] with config [%s]" %
            (self._active_device, self._current_input_config))
        self.joystickReader.stop_input()
Example #8
0
 def thrustLoweringSlewRateLimitChanged(self):
     self.helper.inputDeviceReader.set_thrust_slew_limiting(
                         self.thrustLoweringSlewRateLimit.value(),
                         self.slewEnableLimit.value())
     if (self.isInCrazyFlightmode == True):
         GuiConfig().set("slew_limit", self.slewEnableLimit.value())
         GuiConfig().set("slew_rate", self.thrustLoweringSlewRateLimit.value())
 def setUIState(self, newState, linkURI=""):
     self.uiState = newState
     if (newState == UIState.DISCONNECTED):
         self.setWindowTitle("Not connected")
         self.menuItemConnect.setText("Connect to Crazyflie")
         self.connectButton.setText("Connect")
         self.menuItemQuickConnect.setEnabled(True)
         self.batteryBar.setValue(3000)
         self._menu_cf2_config.setEnabled(False)
         self._menu_cf1_config.setEnabled(True)
         self.linkQualityBar.setValue(0)
         self.menuItemBootloader.setEnabled(True)
         self.logConfigAction.setEnabled(False)
         if (len(GuiConfig().get("link_uri")) > 0):
             self.quickConnectButton.setEnabled(True)
     if (newState == UIState.CONNECTED):
         s = "Connected on %s" % linkURI
         self.setWindowTitle(s)
         self.menuItemConnect.setText("Disconnect")
         self.connectButton.setText("Disconnect")
         self.logConfigAction.setEnabled(True)
         # Find out if there's an I2C EEPROM, otherwise don't show the
         # dialog.
         if len(self.cf.mem.get_mems(MemoryElement.TYPE_I2C)) > 0:
             self._menu_cf2_config.setEnabled(True)
         self._menu_cf1_config.setEnabled(False)
     if (newState == UIState.CONNECTING):
         s = "Connecting to %s ..." % linkURI
         self.setWindowTitle(s)
         self.menuItemConnect.setText("Cancel")
         self.connectButton.setText("Cancel")
         self.quickConnectButton.setEnabled(False)
         self.menuItemBootloader.setEnabled(False)
         self.menuItemQuickConnect.setEnabled(False)
Example #10
0
 def setUIState(self, newState, linkURI=""):
     self.uiState = newState
     if (newState == UIState.DISCONNECTED):
         self.setWindowTitle("Not connected")
         self.menuItemConnect.setText("Connect to Crazyflie")
         self.connectButton.setText("Connect")
         self.menuItemQuickConnect.setEnabled(True)
         self.batteryBar.setValue(3000)
         self.linkQualityBar.setValue(0)
         self.menuItemBootloader.setEnabled(True)
         self.logConfigAction.setEnabled(False)
         if (len(GuiConfig().get("link_uri")) > 0):
             self.quickConnectButton.setEnabled(True)
     if (newState == UIState.CONNECTED):
         s = "Connected on %s" % linkURI
         self.setWindowTitle(s)
         self.menuItemConnect.setText("Disconnect")
         self.connectButton.setText("Disconnect")
         self.logConfigAction.setEnabled(True)
     if (newState == UIState.CONNECTING):
         s = "Connecting to %s ..." % linkURI
         self.setWindowTitle(s)
         self.menuItemConnect.setText("Cancel")
         self.connectButton.setText("Cancel")
         self.quickConnectButton.setEnabled(False)
         self.menuItemBootloader.setEnabled(False)
         self.menuItemQuickConnect.setEnabled(False)
Example #11
0
 def uiSetupReady(self):
     flightComboIndex = self.flightModeCombo.findText(
                          GuiConfig().get("flightmode"), Qt.MatchFixedString)
     if (flightComboIndex < 0):
         self.flightModeCombo.setCurrentIndex(0)
         self.flightModeCombo.currentIndexChanged.emit(0)
     else:
         self.flightModeCombo.setCurrentIndex(flightComboIndex)
         self.flightModeCombo.currentIndexChanged.emit(flightComboIndex)
Example #12
0
 def readConfigAction(self):
     self.statusChanged.emit("Reading config block...", 0)
     data = self.loader.read_flash(self.loader.start_page +
                                   self._config_page)
     if (data is not None):
         self.statusChanged.emit("Reading config block...done!", 100)
         if data[0:4] == "0xBC":
             # Skip 0xBC and version at the beginning
             [channel, speed, pitchTrim,
              rollTrim] = struct.unpack("<BBff", data[5:15])
         else:
             channel = GuiConfig().get("default_cf_channel")
             speed = GuiConfig().get("default_cf_speed")
             pitchTrim = GuiConfig().get("default_cf_trim")
             rollTrim = GuiConfig().get("default_cf_trim")
         self.updateConfigSignal.emit(channel, speed, rollTrim, pitchTrim)
     else:
         self.statusChanged.emit("Reading config block failed!", 0)
Example #13
0
    def _inputdevice_selected(self, checked):
        if not checked:
            return
        self.joystickReader.stop_input()
        sender = self.sender()
        self._active_device = sender.text()
        device_config_mapping = GuiConfig().get("device_config_mapping")
        if self._active_device in device_config_mapping.keys():
            self._current_input_config = device_config_mapping[str(self._active_device)]
        else:
            self._current_input_config = self._menu_mappings.actions()[0].text()
        GuiConfig().set("input_device", str(self._active_device))

        for c in self._menu_mappings.actions():
            if c.text() == self._current_input_config:
                c.setChecked(True)

        self.joystickReader.start_input(str(sender.text()), self._current_input_config)
        self._statusbar_label.setText("Using [%s] with config [%s]" % (self._active_device, self._current_input_config))
Example #14
0
    def connectionDone(self, linkURI):
        self.setUIState(UIState.CONNECTED, linkURI)

        GuiConfig().set("link_uri", linkURI)

        lg = LogConfig("Battery", 1000)
        lg.add_variable("pm.vbat", "float")
        self.cf.log.add_config(lg)
        if lg.valid:
            lg.data_received_cb.add_callback(self.batteryUpdatedSignal.emit)
            lg.error_cb.add_callback(self._log_error_signal.emit)
            lg.start()
        else:
            logger.warning("Could not setup loggingblock!")
Example #15
0
    def connectionDone(self, linkURI):
        self.setUIState(UIState.CONNECTED, linkURI)

        GuiConfig().set("link_uri", linkURI)

        lg = LogConfig("Battery", 1000)
        lg.addVariable(LogVariable("pm.vbat", "float"))
        self.log = self.cf.log.create_log_packet(lg)
        if (self.log != None):
            self.log.dataReceived.add_callback(self.batteryUpdatedSignal.emit)
            self.log.error.add_callback(self.loggingError)
            self.log.start()
        else:
            logger.warning("Could not setup loggingblock!")
Example #16
0
 def _auto_reconnect_changed(self, checked):
     self._auto_reconnect_enabled = checked
     GuiConfig().set("auto_reconnect", checked)
     logger.info("Auto reconnect enabled: %s", checked)
    def connected(self, linkURI):
        # IMU & THRUST
        lg = LogConfig("Stabalizer", GuiConfig().get("ui_update_period"))
        lg.add_variable("stabilizer.roll", "float")
        lg.add_variable("stabilizer.pitch", "float")
        lg.add_variable("stabilizer.yaw", "float")
        lg.add_variable("stabilizer.thrust", "uint16_t")
        lg.add_variable("acc.x", "float")
        lg.add_variable("acc.y", "float")
        lg.add_variable("acc.z", "float")

        self.helper.cf.log.add_config(lg)
        if (lg.valid):
            lg.data_received_cb.add_callback(self._imu_data_signal.emit)
            lg.error_cb.add_callback(self._log_error_signal.emit)
            lg.start()
        else:
            logger.warning("Could not setup logconfiguration after "
                           "connection!")

        # MOTOR
        lg = LogConfig("Motors", GuiConfig().get("ui_update_period"))
        lg.add_variable("motor.m1")
        lg.add_variable("motor.m2")
        lg.add_variable("motor.m3")
        lg.add_variable("motor.m4")

        self.helper.cf.log.add_config(lg)
        if lg.valid:
            lg.data_received_cb.add_callback(self._motor_data_signal.emit)
            lg.error_cb.add_callback(self._log_error_signal.emit)
            lg.start()
        else:
            logger.warning("Could not setup logconfiguration after "
                           "connection!")

        # Acc for freefall
        lg = LogConfig(
            "Acc", 10)  # Yes we need this at 100hz for freefall detection!!
        lg.add_variable("acc.zw", "float")

        self.helper.cf.log.add_config(lg)
        if lg.valid:
            lg.data_received_cb.add_callback(self._acc_data_signal.emit)
            lg.error_cb.add_callback(self._log_error_signal.emit)
            lg.start()
        else:
            logger.warning(
                "Could not setup logconfiguration after connection [ACC]!")

        lg = LogConfig("Magnetometer", 100)
        lg.add_variable("mag.x", "int16_t")
        lg.add_variable("mag.y", "int16_t")
        lg.add_variable("mag.z", "int16_t")

        self.helper.cf.log.add_config(lg)
        if lg.valid:
            lg.data_received_cb.add_callback(self._mag_data_signal.emit)
            lg.error_cb.add_callback(self._log_error_signal.emit)
            lg.start()
        else:
            logger.warning(
                "Could not setup logconfiguration after connection!")
Example #18
0
    def __init__(self, tabWidget, helper, *args):
        global D
        D.thrust = 0
        D.pitch = 0
        D.yawrate = 0
        D.roll = 0
        rospy.init_node("cf_flightTab")
        self.motor_pub = rospy.Publisher("cf_motorData", MotorData)
        self.stab_pub = rospy.Publisher("cf_stabData", StabData)
        self.acc_pub = rospy.Publisher("cf_accData", AccelData)
        self.gyro_pub = rospy.Publisher("cf_gyroData", GyroData)
        rospy.Subscriber("cf_textcmd", String, self._cmdCB)
        
        
        super(FlightTab, self).__init__(*args)
        self.setupUi(self)

        self.tabName = "Flight Control"
        self.menuName = "Flight Control"

        self.tabWidget = tabWidget
        self.helper = helper

        self.disconnectedSignal.connect(self.disconnected)
        self.connectionFinishedSignal.connect(self.connected)
        # Incomming signals
        self.helper.cf.connected.add_callback(
            self.connectionFinishedSignal.emit)
        self.helper.cf.disconnected.add_callback(self.disconnectedSignal.emit)

        self._input_updated_signal.connect(self.updateInputControl)
        self.helper.inputDeviceReader.input_updated.add_callback(
                                     self._input_updated_signal.emit)
        self._rp_trim_updated_signal.connect(self.calUpdateFromInput)
        self.helper.inputDeviceReader.rp_trim_updated.add_callback(
                                     self._rp_trim_updated_signal.emit)
        self._emergency_stop_updated_signal.connect(self.updateEmergencyStop)
        self.helper.inputDeviceReader.emergency_stop_updated.add_callback(
                                     self._emergency_stop_updated_signal.emit)
        
        self.helper.inputDeviceReader.althold_updated.add_callback(
                    lambda enabled: self.helper.cf.param.set_value("flightmode.althold", enabled))
        self._gyro_data_signal.connect(self._gyro_data_received)
        self._accel_data_signal.connect(self._accel_data_received)
        self._imu_data_signal.connect(self._imu_data_received)
        self._baro_data_signal.connect(self._baro_data_received)
        self._althold_data_signal.connect(self._althold_data_received)
        self._motor_data_signal.connect(self._motor_data_received)

        self._log_error_signal.connect(self._logging_error)

        # Connect UI signals that are in this tab
        self.flightModeCombo.currentIndexChanged.connect(self.flightmodeChange)
        self.minThrust.valueChanged.connect(self.minMaxThrustChanged)
        self.maxThrust.valueChanged.connect(self.minMaxThrustChanged)
        self.thrustLoweringSlewRateLimit.valueChanged.connect(
                                      self.thrustLoweringSlewRateLimitChanged)
        self.slewEnableLimit.valueChanged.connect(
                                      self.thrustLoweringSlewRateLimitChanged)
        self.targetCalRoll.valueChanged.connect(self._trim_roll_changed)
        self.targetCalPitch.valueChanged.connect(self._trim_pitch_changed)
        self.maxAngle.valueChanged.connect(self.maxAngleChanged)
        self.maxYawRate.valueChanged.connect(self.maxYawRateChanged)
        self.uiSetupReadySignal.connect(self.uiSetupReady)
        self.clientXModeCheckbox.toggled.connect(self.changeXmode)
        self.isInCrazyFlightmode = False
        self.uiSetupReady()

        self.clientXModeCheckbox.setChecked(GuiConfig().get("client_side_xmode"))

        self.crazyflieXModeCheckbox.clicked.connect(
                             lambda enabled:
                             self.helper.cf.param.set_value("flightmode.x",
                                                            str(enabled)))
        self.helper.cf.param.add_update_callback(
                        group="flightmode", name="xmode",
                        cb=( lambda name, checked:
                        self.crazyflieXModeCheckbox.setChecked(eval(checked))))
        self.ratePidRadioButton.clicked.connect(
                    lambda enabled:
                    self.helper.cf.param.set_value("flightmode.ratepid",
                                                   str(enabled)))
        self.angularPidRadioButton.clicked.connect(
                    lambda enabled:
                    self.helper.cf.param.set_value("flightmode.ratepid",
                                                   str(not enabled)))
        self.helper.cf.param.add_update_callback(
                    group="flightmode", name="ratepid",
                    cb=(lambda name, checked:
                    self.ratePidRadioButton.setChecked(eval(checked))))
        
        self.helper.cf.param.add_update_callback(
                    group="flightmode", name="althold",
                    cb=(lambda name, enabled:
                    self.helper.inputDeviceReader.setAltHold(eval(enabled))))

        self.helper.cf.param.add_update_callback(
                        group="imu_sensors",
                        cb=self._set_available_sensors)
                
        self.logBaro = None
        self.logAltHold = None

        self.ai = AttitudeIndicator()
        self.verticalLayout_4.addWidget(self.ai)
        self.splitter.setSizes([1000,1])

        self.targetCalPitch.setValue(GuiConfig().get("trim_pitch"))
        self.targetCalRoll.setValue(GuiConfig().get("trim_roll"))
Example #19
0
 def changeXmode(self, checked):
     self.helper.cf.commander.set_client_xmode(checked)
     GuiConfig().set("client_side_xmode", checked)
     logger.info("Clientside X-mode enabled: %s", checked)
Example #20
0
    def flightmodeChange(self, item):
        GuiConfig().set("flightmode", self.flightModeCombo.itemText(item))
        logger.info("Changed flightmode to %s",
                    self.flightModeCombo.itemText(item))
        self.isInCrazyFlightmode = False
        if (item == 0):  # Normal
            self.maxAngle.setValue(GuiConfig().get("normal_max_rp"))
            self.maxThrust.setValue(GuiConfig().get("normal_max_thrust"))
            self.minThrust.setValue(GuiConfig().get("normal_min_thrust"))
            self.slewEnableLimit.setValue(GuiConfig().get("normal_slew_limit"))
            self.thrustLoweringSlewRateLimit.setValue(
                                              GuiConfig().get("normal_slew_rate"))
            self.maxYawRate.setValue(GuiConfig().get("normal_max_yaw"))
        if (item == 1):  # Advanced
            self.maxAngle.setValue(GuiConfig().get("max_rp"))
            self.maxThrust.setValue(GuiConfig().get("max_thrust"))
            self.minThrust.setValue(GuiConfig().get("min_thrust"))
            self.slewEnableLimit.setValue(GuiConfig().get("slew_limit"))
            self.thrustLoweringSlewRateLimit.setValue(
                                                  GuiConfig().get("slew_rate"))
            self.maxYawRate.setValue(GuiConfig().get("max_yaw"))
            self.isInCrazyFlightmode = True

        if (item == 0):
            newState = False
        else:
            newState = True
        self.maxThrust.setEnabled(newState)
        self.maxAngle.setEnabled(newState)
        self.minThrust.setEnabled(newState)
        self.thrustLoweringSlewRateLimit.setEnabled(newState)
        self.slewEnableLimit.setEnabled(newState)
        self.maxYawRate.setEnabled(newState)
Example #21
0
 def _trim_roll_changed(self, value):
     logger.debug("Roll trim updated to [%f]" % value)
     self.helper.inputDeviceReader.set_trim_roll(value)
     GuiConfig().set("trim_roll", value)
Example #22
0
 def _trim_pitch_changed(self, value):
     logger.debug("Pitch trim updated to [%f]" % value)
     self.helper.inputDeviceReader.set_trim_pitch(value)
     GuiConfig().set("trim_pitch", value)
 def changeHoldmode(self, checked):
     self.clientHoldModeCheckbox.setChecked(checked)
     self.helper.cf.param.set_value("flightmode.althold", str(checked))
     # self.helper.cf.commander.set_client_holdmode(checked)
     GuiConfig().set("client_side_holdmode", checked)
     logger.info("Hold-mode enabled: %s", checked)
    def __init__(self, tabWidget, helper, *args):
        super(FlightTab, self).__init__(*args)
        self.setupUi(self)

        self.setStyleSheet(
            "QToolTip { color: #ffffff; background-color: #2d2d2d; border: 1px solid #f0f0f0; border-radius: 3px; }"
        )

        self.apitch = 0
        self.aroll = 0
        self.motor_power = 0
        self.tabName = "Flight Control"
        self.menuName = "Flight Control"

        self.ai = AttitudeIndicator()
        self.compass = CompassWidget()

        self.tabWidget = tabWidget
        self.helper = helper

        ########## Freefall related stuff
        self.ffd = FFD(parent=self)  # detection class
        self.ffr = FFR(parent=self)  # recovery class

        # Connect the crash/free fall detections
        self.ffd.sigFreeFall.connect(self.freefallDetected)
        self.ffd.sigCrashed.connect(self.crashDetected)
        self.ffr.sigRecoveryTimedOut.connect(self.recoveryAborted)

        # continuously send acc, mean, var to AI
        self.ffd.sigAccMeanVar.connect(self.ai.setFFAccMeanVar)
        # Only set recovery on if both fall and crash detection are on as well as recovery
        self.checkBox_ffd.stateChanged.connect(
            lambda on: self.ffGuiSync(0, on))  # detect freefall on/off
        self.checkBox_crash.stateChanged.connect(
            lambda on: self.ffGuiSync(1, on))  # detect crashing on/off
        self.checkBox_ffr.stateChanged.connect(
            lambda on: self.ffGuiSync(2, on))  # recovery crashing on/off

        # Use barometer for recovery (only clickedable if the checkbox activates in reaction to detecting a 10DOF flie
        self.checkBox_ffbaro.clicked.connect(self.ffr.setUseBaro)

        # intercept control commands
        self.helper.inputDeviceReader.auto_input_updated.add_callback(
            self.ffr.step)
        self.ffr.auto_input_updated.add_callback(
            self.helper.cf.commander.send_setpoint)
        self.ffr.auto_input_updated.add_callback(
            self._input_updated_signal.emit)
        self.ffr.althold_updated.add_callback(
            lambda param, arg: self.helper.cf.param.set_value(param, str(arg)))

        # Emergency Stop
        self._emergency_stop_updated_signal.connect(self.ffr.setKillSwitch)
        #self._emergency_stop_updated_signal.connect(self.ai.setKillSwitch)

        # Debugging Freefall
        self.pushButton_ff.clicked.connect(self.ffd.sendFakeEmit)
        self.pushButton_crash.clicked.connect(self.ffd.sendFakeLandingEmit)
        self.doubleSpinBox_ff_falloff.valueChanged.connect(
            self.ffr.falloff.setWidth)
        self.doubleSpinBox_ff_max.valueChanged.connect(
            self.ffr.falloff.setMaxThrust)
        self.doubleSpinBox_ff_min.valueChanged.connect(
            self.ffr.falloff.setMinThrust)
        self.doubleSpinBox_ff_time.valueChanged.connect(
            self.ffr.falloff.setTime)
        self.pushButton_plot.clicked.connect(self.ffr.falloff.plot)

        self.checkBox_debug.stateChanged.connect(self.toggleFFDebug)
        self.checkBox_ffbaro.clicked.connect(self.toggleFFDebug)

        # Slow down drawing to GUi items by keeping track of last received data time
        self.lastImuTime = 0

        self.disconnectedSignal.connect(self.disconnected)
        self.connectionFinishedSignal.connect(self.connected)
        # Incomming signals
        self.helper.cf.connected.add_callback(
            self.connectionFinishedSignal.emit)
        self.helper.cf.disconnected.add_callback(self.disconnectedSignal.emit)

        self._input_updated_signal.connect(self.updateInputControl)
        self.helper.inputDeviceReader.input_updated.add_callback(
            self._input_updated_signal.emit)
        self._rp_trim_updated_signal.connect(self.calUpdateFromInput)
        self.helper.inputDeviceReader.rp_trim_updated.add_callback(
            self._rp_trim_updated_signal.emit)
        self._emergency_stop_updated_signal.connect(self.updateEmergencyStop)
        self.helper.inputDeviceReader.emergency_stop_updated.add_callback(
            self._emergency_stop_updated_signal.emit)

        self._switch_mode_updated_signal.connect(self.switchMode)
        self.helper.inputDeviceReader.switch_mode_updated.add_callback(
            self._switch_mode_updated_signal.emit)

        self.helper.inputDeviceReader.althold_updated.add_callback(
            self.changeHoldmode)

        self._imu_data_signal.connect(self._imu_data_received)
        self._baro_data_signal.connect(self._baro_data_received)
        self._althold_data_signal.connect(self._althold_data_received)
        self._motor_data_signal.connect(self._motor_data_received)
        self._acc_data_signal.connect(self._acc_data_received)
        self._mag_data_signal.connect(self._mag_data_received)

        self._log_error_signal.connect(self._logging_error)

        # Connect UI signals that are in this tab
        self.flightModeCombo.currentIndexChanged.connect(self.flightmodeChange)
        self.minThrust.valueChanged.connect(self.minMaxThrustChanged)
        self.maxThrust.valueChanged.connect(self.minMaxThrustChanged)
        self.maxAltitude.valueChanged.connect(self.maxAltitudeChanged)
        self.thrustLoweringSlewRateLimit.valueChanged.connect(
            self.thrustLoweringSlewRateLimitChanged)
        self.slewEnableLimit.valueChanged.connect(
            self.thrustLoweringSlewRateLimitChanged)
        self.targetCalRoll.valueChanged.connect(self._trim_roll_changed)
        self.targetCalPitch.valueChanged.connect(self._trim_pitch_changed)
        self.maxAngle.valueChanged.connect(self.maxAngleChanged)
        self.maxYawRate.valueChanged.connect(self.maxYawRateChanged)
        self.uiSetupReadySignal.connect(self.uiSetupReady)
        self.clientHoldModeCheckbox.toggled.connect(self.changeHoldmode)
        self.isInCrazyFlightmode = False
        self.uiSetupReady()

        self.viscousModeSlider.valueChanged.connect(self.setViscousThrust)
        self.clientHoldModeCheckbox.setChecked(
            GuiConfig().get("client_side_holdmode"))

        # self.crazyflieXModeCheckbox.clicked.connect(
        #                     lambda enabled:
        #                     self.helper.cf.param.set_value("flightmode.x", str(enabled)))
        # self.helper.cf.param.add_update_callback(
        #                group="flightmode", name="xmode",
        #                cb=( lambda name, checked:
        #                self.crazyflieXModeCheckbox.setChecked(eval(checked))))
        self.ratePidRadioButton.clicked.connect(
            lambda enabled: self.helper.cf.param.set_value(
                "flightmode.ratepid", str(enabled)))
        self.angularPidRadioButton.clicked.connect(
            lambda enabled: self.helper.cf.param.set_value(
                "flightmode.ratepid", str(not enabled)))
        self.helper.cf.param.add_update_callback(
            group="flightmode",
            name="ratepid",
            cb=(lambda name, checked: self.ratePidRadioButton.setChecked(
                eval(checked))))

        self.helper.cf.param.add_update_callback(
            group="flightmode",
            name="althold",
            cb=(lambda name, enabled: self.helper.inputDeviceReader.setAltHold(
                eval(enabled))))

        self.helper.cf.param.add_update_callback(
            group="imu_sensors", cb=self._set_available_sensors)

        self.logBaro = None
        self.logAltHold = None

        self.horizontalLayout_5.addWidget(self.ai)
        self.horizontalLayout_5.addWidget(self.compass)
        # self.verticalLayout_4.addWidget(self.ai)
        self.splitter.setSizes([1000, 1])

        self.targetCalPitch.setValue(GuiConfig().get("trim_pitch"))
        self.targetCalRoll.setValue(GuiConfig().get("trim_roll"))
Example #25
0
 def closeEvent(self, event):
     self.hide()
     self.cf.close_link()
     GuiConfig().save_file()
Example #26
0
 def quickConnect(self):
     try:
         self.cf.open_link(GuiConfig().get("link_uri"))
     except KeyError:
         self.cf.open_link("")
Example #27
0
 def maxYawRateChanged(self):
     logger.debug("MaxYawrate changed to %d", self.maxYawRate.value())
     self.helper.inputDeviceReader.set_yaw_limit(self.maxYawRate.value())
     if (self.isInCrazyFlightmode == True):
         GuiConfig().set("max_yaw", self.maxYawRate.value())
Example #28
0
    def __init__(self, tabWidget, helper, *args):
        super(FlightTab, self).__init__(*args)
        self.setupUi(self)

        self.tabName = "Flight Control"
        self.menuName = "Flight Control"

        self.tabWidget = tabWidget
        self.helper = helper

        self.disconnectedSignal.connect(self.disconnected)
        self.connectionFinishedSignal.connect(self.connected)
        # Incomming signals
        self.helper.cf.connectSetupFinished.add_callback(
            self.connectionFinishedSignal.emit)
        self.helper.cf.disconnected.add_callback(self.disconnectedSignal.emit)

        self._input_updated_signal.connect(self.updateInputControl)
        self.helper.inputDeviceReader.input_updated.add_callback(
            self._input_updated_signal.emit)
        self._rp_trim_updated_signal.connect(self.calUpdateFromInput)
        self.helper.inputDeviceReader.rp_trim_updated.add_callback(
            self._rp_trim_updated_signal)
        self._emergency_stop_updated_signal.connect(self.updateEmergencyStop)
        self.helper.inputDeviceReader.emergency_stop_updated.add_callback(
            self._emergency_stop_updated_signal.emit)

        self._imu_data_signal.connect(self._imu_data_received)
        self._motor_data_signal.connect(self._motor_data_received)

        # Connect UI signals that are in this tab
        self.flightModeCombo.currentIndexChanged.connect(self.flightmodeChange)
        self.minThrust.valueChanged.connect(self.minMaxThrustChanged)
        self.maxThrust.valueChanged.connect(self.minMaxThrustChanged)
        self.thrustLoweringSlewRateLimit.valueChanged.connect(
            self.thrustLoweringSlewRateLimitChanged)
        self.slewEnableLimit.valueChanged.connect(
            self.thrustLoweringSlewRateLimitChanged)
        self.targetCalRoll.valueChanged.connect(self._trim_roll_changed)
        self.targetCalPitch.valueChanged.connect(self._trim_pitch_changed)
        self.maxAngle.valueChanged.connect(self.maxAngleChanged)
        self.maxYawRate.valueChanged.connect(self.maxYawRateChanged)
        self.uiSetupReadySignal.connect(self.uiSetupReady)
        self.clientXModeCheckbox.toggled.connect(self.changeXmode)
        self.isInCrazyFlightmode = False
        self.uiSetupReady()

        self.clientXModeCheckbox.setChecked(
            GuiConfig().get("client_side_xmode"))

        self.crazyflieXModeCheckbox.clicked.connect(
            lambda enabled: self.helper.cf.param.set_value(
                "flightctrl.xmode", str(enabled)))
        self.helper.cf.param.add_update_callback(
            "flightctrl.xmode",
            lambda name, checked: self.crazyflieXModeCheckbox.setChecked(
                eval(checked)))
        self.ratePidRadioButton.clicked.connect(
            lambda enabled: self.helper.cf.param.set_value(
                "flightctrl.ratepid", str(enabled)))
        self.angularPidRadioButton.clicked.connect(
            lambda enabled: self.helper.cf.param.set_value(
                "flightctrl.ratepid", str(not enabled)))
        self.helper.cf.param.add_update_callback(
            "flightctrl.ratepid",
            lambda name, checked: self.ratePidRadioButton.setChecked(
                eval(checked)))

        self.ai = AttitudeIndicator()
        self.gridLayout.addWidget(self.ai, 0, 1)

        self.targetCalPitch.setValue(GuiConfig().get("trim_pitch"))
        self.targetCalRoll.setValue(GuiConfig().get("trim_roll"))
Example #29
0
    def __init__(self, *args):
        super(MainUI, self).__init__(*args)
        self.setupUi(self)

        self.cf = Crazyflie(ro_cache=sys.path[0] + "/cflib/cache",
                            rw_cache=sys.path[1] + "/cache")

        cflib.crtp.init_drivers(
            enable_debug_driver=GuiConfig().get("enable_debug_driver"))

        # Create the connection dialogue
        self.connectDialogue = ConnectDialogue()

        # Create and start the Input Reader
        self._statusbar_label = QLabel("Loading device and configuration.")
        self.statusBar().addWidget(self._statusbar_label)

        self.joystickReader = JoystickReader(cf=self.cf)
        self._active_device = ""
        self.configGroup = QActionGroup(self._menu_mappings, exclusive=True)
        self._load_input_data()
        self._update_input
        ConfigManager().conf_needs_reload.add_callback(self._reload_configs)

        # Connections for the Connect Dialogue
        self.connectDialogue.requestConnectionSignal.connect(self.cf.open_link)

        self.connectionDoneSignal.connect(self.connectionDone)
        self.cf.connection_failed.add_callback(
            self.connectionFailedSignal.emit)
        self.connectionFailedSignal.connect(self.connectionFailed)

        self._input_device_error_signal.connect(self.inputDeviceError)
        self.joystickReader.device_error.add_callback(
            self._input_device_error_signal.emit)
        self._input_discovery_signal.connect(self.device_discovery)
        self.joystickReader.device_discovery.add_callback(
            self._input_discovery_signal.emit)

        # Connect UI signals
        self.menuItemConnect.triggered.connect(self.connectButtonClicked)
        self.logConfigAction.triggered.connect(self.doLogConfigDialogue)
        self.connectButton.clicked.connect(self.connectButtonClicked)
        self.quickConnectButton.clicked.connect(self.quickConnect)
        self.menuItemQuickConnect.triggered.connect(self.quickConnect)
        self.menuItemConfInputDevice.triggered.connect(self.configInputDevice)
        self.menuItemExit.triggered.connect(self.closeAppRequest)
        self.batteryUpdatedSignal.connect(self.updateBatteryVoltage)
        self._menuitem_rescandevices.triggered.connect(self._rescan_devices)
        self._menuItem_openconfigfolder.triggered.connect(
            self._open_config_folder)

        self._auto_reconnect_enabled = GuiConfig().get("auto_reconnect")
        self.autoReconnectCheckBox.toggled.connect(
            self._auto_reconnect_changed)
        self.autoReconnectCheckBox.setChecked(
            GuiConfig().get("auto_reconnect"))

        # Do not queue data from the controller output to the Crazyflie wrapper
        # to avoid latency
        #self.joystickReader.sendControlSetpointSignal.connect(
        #                                      self.cf.commander.send_setpoint,
        #                                      Qt.DirectConnection)
        self.joystickReader.input_updated.add_callback(
            self.cf.commander.send_setpoint)

        # Connection callbacks and signal wrappers for UI protection
        self.cf.connected.add_callback(self.connectionDoneSignal.emit)
        self.connectionDoneSignal.connect(self.connectionDone)
        self.cf.disconnected.add_callback(self.disconnectedSignal.emit)
        self.disconnectedSignal.connect(
            lambda linkURI: self.setUIState(UIState.DISCONNECTED, linkURI))
        self.cf.connection_lost.add_callback(self.connectionLostSignal.emit)
        self.connectionLostSignal.connect(self.connectionLost)
        self.cf.connection_requested.add_callback(
            self.connectionInitiatedSignal.emit)
        self.connectionInitiatedSignal.connect(
            lambda linkURI: self.setUIState(UIState.CONNECTING, linkURI))
        self._log_error_signal.connect(self._logging_error)

        # Connect link quality feedback
        self.cf.link_quality_updated.add_callback(self.linkQualitySignal.emit)
        self.linkQualitySignal.connect(
            lambda percentage: self.linkQualityBar.setValue(percentage))

        # Set UI state in disconnected buy default
        self.setUIState(UIState.DISCONNECTED)

        # Parse the log configuration files
        self.logConfigReader = LogConfigReader(self.cf)

        # Add things to helper so tabs can access it
        cfclient.ui.pluginhelper.cf = self.cf
        cfclient.ui.pluginhelper.inputDeviceReader = self.joystickReader
        cfclient.ui.pluginhelper.logConfigReader = self.logConfigReader

        self.logConfigDialogue = LogConfigDialogue(cfclient.ui.pluginhelper)
        self._bootloader_dialog = BootloaderDialog(cfclient.ui.pluginhelper)
        self.menuItemBootloader.triggered.connect(self._bootloader_dialog.show)
        self._about_dialog = AboutDialog(cfclient.ui.pluginhelper)
        self.menuItemAbout.triggered.connect(self._about_dialog.show)
        # Loading toolboxes (A bit of magic for a lot of automatic)
        self.toolboxes = []
        self.toolboxesMenuItem.setMenu(QtGui.QMenu())
        for t_class in cfclient.ui.toolboxes.toolboxes:
            toolbox = t_class(cfclient.ui.pluginhelper)
            dockToolbox = MyDockWidget(toolbox.getName())
            dockToolbox.setWidget(toolbox)
            self.toolboxes += [
                dockToolbox,
            ]

            # Add menu item for the toolbox
            item = QtGui.QAction(toolbox.getName(), self)
            item.setCheckable(True)
            item.triggered.connect(self.toggleToolbox)
            self.toolboxesMenuItem.menu().addAction(item)

            dockToolbox.closed.connect(lambda: self.toggleToolbox(False))

            # Setup some introspection
            item.dockToolbox = dockToolbox
            item.menuItem = item
            dockToolbox.dockToolbox = dockToolbox
            dockToolbox.menuItem = item

        # Load and connect tabs
        self.tabsMenuItem.setMenu(QtGui.QMenu())
        tabItems = {}
        self.loadedTabs = []
        for tabClass in cfclient.ui.tabs.available:
            tab = tabClass(self.tabs, cfclient.ui.pluginhelper)
            item = QtGui.QAction(tab.getMenuName(), self)
            item.setCheckable(True)
            item.toggled.connect(tab.toggleVisibility)
            self.tabsMenuItem.menu().addAction(item)
            tabItems[tab.getTabName()] = item
            self.loadedTabs.append(tab)
            if not tab.enabled:
                item.setEnabled(False)

        # First instantiate all tabs and then open them in the correct order
        try:
            for tName in GuiConfig().get("open_tabs").split(","):
                t = tabItems[tName]
                if (t != None and t.isEnabled()):
                    # Toggle though menu so it's also marked as open there
                    t.toggle()
        except Exception as e:
            logger.warning("Exception while opening tabs [%s]", e)
Example #30
0
 def maxAngleChanged(self):
     logger.debug("MaxAngle changed to %d", self.maxAngle.value())
     self.helper.inputDeviceReader.set_rp_limit(self.maxAngle.value())
     if (self.isInCrazyFlightmode == True):
         GuiConfig().set("max_rp", self.maxAngle.value())