Exemple #1
0
    def connected(self, linkURI):
        # IMU & THRUST
        lg = LogConfig("Stabilizer", Config().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")

        try:
            self.helper.cf.log.add_config(lg)
            lg.data_received_cb.add_callback(self._imu_data_signal.emit)
            lg.error_cb.add_callback(self._log_error_signal.emit)
            lg.start()
        except KeyError as e:
            logger.warning(str(e))
        except AttributeError as e:
            logger.warning(str(e))

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

        try:
            self.helper.cf.log.add_config(lg)
            lg.data_received_cb.add_callback(self._motor_data_signal.emit)
            lg.error_cb.add_callback(self._log_error_signal.emit)
            lg.start()
        except KeyError as e:
            logger.warning(str(e))
        except AttributeError as e:
            logger.warning(str(e))
Exemple #2
0
    def toggleVisibility(self, checked):
        """Show or hide the tab."""
        if checked:
            self.tabWidget.addTab(self, self.getTabName())
            s = ""
            try:
                s = Config().get("open_tabs")
                if (len(s) > 0):
                    s += ","
            except Exception:
                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
                Config().set("open_tabs", str(s))

        if not checked:
            self.tabWidget.removeTab(self.tabWidget.indexOf(self))
            try:
                parts = Config().get("open_tabs").split(",")
            except Exception:
                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
            Config().set("open_tabs", str(s))
Exemple #3
0
 def thrustLoweringSlewRateLimitChanged(self):
     self.helper.inputDeviceReader.thrust_slew_rate = (
         self.thrustLoweringSlewRateLimit.value())
     self.helper.inputDeviceReader.thrust_slew_limit = (
         self.slewEnableLimit.value())
     if (self.isInCrazyFlightmode is True):
         Config().set("slew_limit", self.slewEnableLimit.value())
         Config().set("slew_rate", self.thrustLoweringSlewRateLimit.value())
Exemple #4
0
    def get_saved_device_mapping(self, device_name):
        """Return the saved mapping for a given device"""
        config = None
        device_config_mapping = Config().get("device_config_mapping")
        if device_name in list(device_config_mapping.keys()):
            config = device_config_mapping[device_name]

        logging.debug("For [{}] we recommend [{}]".format(device_name, config))
        return config
Exemple #5
0
    def _inputdevice_selected(self, checked):
        """Called when a new input device has been selected from the menu. The
        data in the menu object is the associated map menu (directly under the
        item in the menu) and the raw device"""
        (map_menu, device, mux_menu) = self.sender().data()
        if not checked:
            if map_menu:
                map_menu.setEnabled(False)
                # Do not close the device, since we don't know exactly
                # how many devices the mux can have open. When selecting a
                # new mux the old one will take care of this.
        else:
            if map_menu:
                map_menu.setEnabled(True)

            (mux, sub_nodes) = mux_menu.data()
            for role_node in sub_nodes:
                for dev_node in role_node.children():
                    if type(dev_node) is QAction and dev_node.isChecked():
                        if device.id == dev_node.data()[1].id \
                                and dev_node is not self.sender():
                            dev_node.setChecked(False)

            role_in_mux = str(self.sender().parent().title()).strip()
            logger.info("Role of {} is {}".format(device.name,
                                                  role_in_mux))

            Config().set("input_device", str(device.name))

            self._mapping_support = self.joystickReader.start_input(
                device.name,
                role_in_mux)
        self._update_input_device_footer()
Exemple #6
0
 def uiSetupReady(self):
     flightComboIndex = self.flightModeCombo.findText(
         Config().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)
Exemple #7
0
 def readConfigAction(self):
     self.statusChanged.emit("Reading config block...", 0)
     data = self._bl.read_cf1_config()
     if (data is not None):
         if data[0:4] == bytearray("0xBC".encode('ISO-8859-1')):
             # Skip 0xBC and version at the beginning
             [channel, speed, pitchTrim,
              rollTrim] = struct.unpack("<BBff", data[5:15])
             self.statusChanged.emit("Reading config block...done!", 100)
         else:
             channel = Config().get("default_cf_channel")
             speed = Config().get("default_cf_speed")
             pitchTrim = Config().get("default_cf_trim")
             rollTrim = Config().get("default_cf_trim")
             self.statusChanged.emit(
                 "Could not find config block, showing defaults", 100)
         self.updateConfigSignal.emit(channel, speed, rollTrim, pitchTrim)
     else:
         self.statusChanged.emit("Reading config block failed!", 0)
Exemple #8
0
    def set_input_map(self, device_name, input_map_name):
        """Load and set an input device map with the given name"""
        dev = self._get_device_from_name(device_name)
        settings = ConfigManager().get_settings(input_map_name)

        if settings:
            self.springy_throttle = settings["springythrottle"]
            self._rp_dead_band = settings["rp_dead_band"]
            self._input_map = ConfigManager().get_config(input_map_name)
        dev.input_map = self._input_map
        dev.input_map_name = input_map_name
        Config().get("device_config_mapping")[device_name] = input_map_name
        dev.set_dead_band(self._rp_dead_band)
Exemple #9
0
    def foundInterfaces(self, interfaces):
        selected_interface = self._selected_interface

        self.interfaceCombo.clear()

        if interfaces:        
            for interface in interfaces:
                self.interfaceCombo.addItems(interface)
        else:
            self.interfaceCombo.addItem(INTERFACE_PROMPT_TEXT)
        
        if self._initial_scan:
            self._initial_scan = False

            try:
                if len(Config().get("link_uri")) > 0:
                    interfaces.index(Config().get("link_uri"))
                    selected_interface = Config().get("link_uri")
            except KeyError:
                #  The configuration for link_uri was not found
                pass
            except ValueError:
                #  The saved URI was not found while scanning
                pass

        if len(interfaces) == 1 and selected_interface is None:
            selected_interface = interfaces[0][0]

        newIndex = 0
        if selected_interface is not None:
            try:
                newIndex = interfaces.index(selected_interface) + 1
            except ValueError:
                pass

        self.interfaceCombo.setCurrentIndex(newIndex)

        self.uiState = UIState.DISCONNECTED
        self._update_ui_state()
Exemple #10
0
    def _assist_mode_changed(self, item):
        mode = None

        if (item == 0):  # Altitude hold
            mode = JoystickReader.ASSISTED_CONTROL_ALTHOLD
        if (item == 1):  # Position hold
            mode = JoystickReader.ASSISTED_CONTROL_POSHOLD
        if (item == 2):  # Position hold
            mode = JoystickReader.ASSISTED_CONTROL_HEIGHTHOLD
        if (item == 3):  # Position hold
            mode = JoystickReader.ASSISTED_CONTROL_HOVER

        self.helper.inputDeviceReader.set_assisted_control(mode)
        Config().set("assistedControl", mode)
Exemple #11
0
    def _connected(self):
        self.uiState = UIState.CONNECTED
        self._update_ui_state()

        Config().set("link_uri", str(self._selected_interface))

        lg = LogConfig("Battery", 1000)
        lg.add_variable("pm.vbat", "float")
        lg.add_variable("pm.state", "int8_t")
        try:
            self.cf.log.add_config(lg)
            lg.data_received_cb.add_callback(self.batteryUpdatedSignal.emit)
            lg.error_cb.add_callback(self._log_error_signal.emit)
            lg.start()
        except KeyError as e:
            logger.warning(str(e))

        mems = self.cf.mem.get_mems(MemoryElement.TYPE_DRIVER_LED)
        if len(mems) > 0:
            mems[0].write_data(self._led_write_done)
Exemple #12
0
 def closeEvent(self, event):
     self.hide()
     self.cf.close_link()
     Config().save_file()
Exemple #13
0
 def _auto_reconnect_changed(self, checked):
     self._auto_reconnect_enabled = checked
     Config().set("auto_reconnect", checked)
     logger.info("Auto reconnect enabled: {}".format(checked))
Exemple #14
0
    def __init__(self, *args):
        super(MainUI, self).__init__(*args)
        self.setupUi(self)

        # Restore window size if present in the config file
        try:
            size = Config().get("window_size")
            self.resize(size[0], size[1])
        except KeyError:
            pass

        ######################################################
        # By lxrocks
        # 'Skinny Progress Bar' tweak for Yosemite
        # Tweak progress bar - artistic I am not - so pick your own colors !!!
        # Only apply to Yosemite
        ######################################################
        import platform

        if platform.system() == 'Darwin':

            (Version, junk, machine) = platform.mac_ver()
            logger.info("This is a MAC - checking if we can apply Progress "
                        "Bar Stylesheet for Yosemite Skinny Bars ")
            yosemite = (10, 10, 0)
            tVersion = tuple(map(int, (Version.split("."))))

            if tVersion >= yosemite:
                logger.info("Found Yosemite - applying stylesheet")

                tcss = """
                    QProgressBar {
                        border: 1px solid grey;
                        border-radius: 5px;
                        text-align: center;
                    }
                    QProgressBar::chunk {
                        background-color: """ + COLOR_BLUE + """;
                    }
                 """
                self.setStyleSheet(tcss)

            else:
                logger.info("Pre-Yosemite - skinny bar stylesheet not applied")

        ######################################################

        self.cf = Espdrone(ro_cache=None,
                            rw_cache=edclient.config_path + "/cache")

        edlib.crtp.init_drivers(enable_debug_driver=Config()
                                .get("enable_debug_driver"))

        zmq_params = ZMQParamAccess(self.cf)
        zmq_params.start()

        zmq_leds = ZMQLEDDriver(self.cf)
        zmq_leds.start()

        self.scanner = ScannerThread()
        self.scanner.interfaceFoundSignal.connect(self.foundInterfaces)
        self.scanner.start()

        # Create and start the Input Reader
        self._statusbar_label = QLabel("No input-device found, insert one to"
                                       " fly.")
        self.statusBar().addWidget(self._statusbar_label)

        self.joystickReader = JoystickReader()
        self._active_device = ""
        # self.configGroup = QActionGroup(self._menu_mappings, exclusive=True)

        self._mux_group = QActionGroup(self._menu_inputdevice, exclusive=True)

        # TODO: Need to reload configs
        # ConfigManager().conf_needs_reload.add_callback(self._reload_configs)

        self.connect_input = QShortcut("Ctrl+I", self.connectButton,
                                       self._connect)
        self.cf.connection_failed.add_callback(
            self.connectionFailedSignal.emit)
        self.connectionFailedSignal.connect(self._connection_failed)

        self._input_device_error_signal.connect(
            self._display_input_device_error)
        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)

        # Hide the 'File' menu on OS X, since its only item, 'Exit', gets
        # merged into the application menu.
        if sys.platform == 'darwin':
            self.menuFile.menuAction().setVisible(False)

        # Connect UI signals
        self.logConfigAction.triggered.connect(self._show_connect_dialog)
        self.interfaceCombo.currentIndexChanged['QString'].connect(
            self.interfaceChanged)
        self.connectButton.clicked.connect(self._connect)
        self.scanButton.clicked.connect(self._scan)
        self.menuItemConnect.triggered.connect(self._connect)
        self.menuItemConfInputDevice.triggered.connect(
            self._show_input_device_config_dialog)
        self.menuItemExit.triggered.connect(self.closeAppRequest)
        self.batteryUpdatedSignal.connect(self._update_battery)
        self._menuitem_rescandevices.triggered.connect(self._rescan_devices)
        self._menuItem_openconfigfolder.triggered.connect(
            self._open_config_folder)


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

        self._disable_input = False

        self.joystickReader.input_updated.add_callback(
            lambda *args: self._disable_input or
            self.cf.commander.send_setpoint(*args))

        self.joystickReader.assisted_input_updated.add_callback(
            lambda *args: self._disable_input or
            self.cf.commander.send_velocity_world_setpoint(*args))

        self.joystickReader.heighthold_input_updated.add_callback(
            lambda *args: self._disable_input or
            self.cf.commander.send_zdistance_setpoint(*args))

        self.joystickReader.hover_input_updated.add_callback(
            self.cf.commander.send_hover_setpoint)

        # Connection callbacks and signal wrappers for UI protection
        self.cf.connected.add_callback(self.connectionDoneSignal.emit)
        self.connectionDoneSignal.connect(self._connected)
        self.cf.disconnected.add_callback(self.disconnectedSignal.emit)
        self.disconnectedSignal.connect(self._disconnected)
        self.cf.connection_lost.add_callback(self.connectionLostSignal.emit)
        self.connectionLostSignal.connect(self._connection_lost)
        self.cf.connection_requested.add_callback(
            self.connectionInitiatedSignal.emit)
        self.connectionInitiatedSignal.connect(self._connection_initiated)
        self._log_error_signal.connect(self._logging_error)

        self.batteryBar.setTextVisible(False)
        self.batteryBar.setStyleSheet(progressbar_stylesheet(COLOR_BLUE))

        self.linkQualityBar.setTextVisible(False)
        self.linkQualityBar.setStyleSheet(progressbar_stylesheet(COLOR_BLUE))

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

        self._selected_interface = None
        self._initial_scan = True
        self._scan()

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

        self._current_input_config = None
        self._active_config = None
        self._active_config = None

        self.inputConfig = None

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

        self.logConfigDialogue = LogConfigDialogue(edclient.ui.pluginhelper)
        self._bootloader_dialog = BootloaderDialog(edclient.ui.pluginhelper)
        self._cf2config_dialog = Cf2ConfigDialog(edclient.ui.pluginhelper)
        self._cf1config_dialog = Cf1ConfigDialog(edclient.ui.pluginhelper)
        self.menuItemBootloader.triggered.connect(self._bootloader_dialog.show)
        self._about_dialog = AboutDialog(edclient.ui.pluginhelper)
        self.menuItemAbout.triggered.connect(self._about_dialog.show)
        self._menu_cf2_config.triggered.connect(self._cf2config_dialog.show)
        self._menu_cf1_config.triggered.connect(self._cf1config_dialog.show)

        # Load and connect tabs
        self.tabsMenuItem = QMenu("Tabs", self.menuView, enabled=True)
        self.menuView.addMenu(self.tabsMenuItem)

        # self.tabsMenuItem.setMenu(QtWidgets.QMenu())
        tabItems = {}
        self.loadedTabs = []
        for tabClass in edclient.ui.tabs.available:
            tab = tabClass(self.tabs, edclient.ui.pluginhelper)
            item = QtWidgets.QAction(tab.getMenuName(), self, checkable=True)
            item.toggled.connect(tab.toggleVisibility)
            self.tabsMenuItem.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 Config().get("open_tabs").split(","):
                t = tabItems[tName]
                if (t is not 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 [{}]".format(e))

        # Loading toolboxes (A bit of magic for a lot of automatic)
        self.toolboxesMenuItem = QMenu("Toolboxes", self.menuView,
                                       enabled=True)
        self.menuView.addMenu(self.toolboxesMenuItem)

        self.toolboxes = []
        for t_class in edclient.ui.toolboxes.toolboxes:
            toolbox = t_class(edclient.ui.pluginhelper)
            dockToolbox = MyDockWidget(toolbox.getName())
            dockToolbox.setWidget(toolbox)
            self.toolboxes += [dockToolbox, ]

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

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

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

        # References to all the device sub-menus in the "Input device" menu
        self._all_role_menus = ()
        # Used to filter what new devices to add default mapping to
        self._available_devices = ()
        # Keep track of mux nodes so we can enable according to how many
        # devices we have
        self._all_mux_nodes = ()

        # Check which Input muxes are available
        self._mux_group = QActionGroup(self._menu_inputdevice, exclusive=True)
        for m in self.joystickReader.available_mux():
            node = QAction(m.name,
                           self._menu_inputdevice,
                           checkable=True,
                           enabled=False)
            node.toggled.connect(self._mux_selected)
            self._mux_group.addAction(node)
            self._menu_inputdevice.addAction(node)
            self._all_mux_nodes += (node,)
            mux_subnodes = ()
            for name in m.supported_roles():
                sub_node = QMenu("    {}".format(name),
                                 self._menu_inputdevice,
                                 enabled=False)
                self._menu_inputdevice.addMenu(sub_node)
                mux_subnodes += (sub_node,)
                self._all_role_menus += ({"muxmenu": node,
                                          "rolemenu": sub_node},)
            node.setData((m, mux_subnodes))

        self._mapping_support = True
Exemple #15
0
    def __init__(self, do_device_discovery=True):
        self._input_device = None

        self._mux = [
            NoMux(self),
            TakeOverSelectiveMux(self),
            TakeOverMux(self)
        ]
        # Set NoMux as default
        self._selected_mux = self._mux[0]

        self.min_thrust = 0
        self.max_thrust = 0
        self._thrust_slew_rate = 0
        self.thrust_slew_enabled = False
        self.thrust_slew_limit = 0
        self.has_pressure_sensor = False
        self._hover_max_height = MAX_TARGET_HEIGHT

        self.max_rp_angle = 0
        self.max_yaw_rate = 0
        try:
            self.set_assisted_control(Config().get("assistedControl"))
        except KeyError:
            self.set_assisted_control(JoystickReader.ASSISTED_CONTROL_ALTHOLD)

        self._old_thrust = 0
        self._old_raw_thrust = 0
        self.springy_throttle = True
        self._target_height = INITAL_TAGET_HEIGHT

        self.trim_roll = Config().get("trim_roll")
        self.trim_pitch = Config().get("trim_pitch")
        self._rp_dead_band = 0.1

        self._input_map = None

        if Config().get("flightmode") is "Normal":
            self.max_yaw_rate = Config().get("normal_max_yaw")
            self.max_rp_angle = Config().get("normal_max_rp")
            # Values are stored at %, so use the functions to set the values
            self.min_thrust = Config().get("normal_min_thrust")
            self.max_thrust = Config().get("normal_max_thrust")
            self.thrust_slew_limit = Config().get("normal_slew_limit")
            self.thrust_slew_rate = Config().get("normal_slew_rate")
        else:
            self.max_yaw_rate = Config().get("max_yaw")
            self.max_rp_angle = Config().get("max_rp")
            # Values are stored at %, so use the functions to set the values
            self.min_thrust = Config().get("min_thrust")
            self.max_thrust = Config().get("max_thrust")
            self.thrust_slew_limit = Config().get("slew_limit")
            self.thrust_slew_rate = Config().get("slew_rate")

        self._dev_blacklist = None
        if len(Config().get("input_device_blacklist")) > 0:
            self._dev_blacklist = re.compile(
                Config().get("input_device_blacklist"))
        logger.info("Using device blacklist [{}]".format(
            Config().get("input_device_blacklist")))

        self._available_devices = {}

        # TODO: The polling interval should be set from config file
        self._read_timer = PeriodicTimer(INPUT_READ_PERIOD, self.read_input)

        if do_device_discovery:
            self._discovery_timer = PeriodicTimer(1.0,
                                                  self._do_device_discovery)
            self._discovery_timer.start()

        # Check if user config exists, otherwise copy files
        if not os.path.exists(ConfigManager().configs_dir):
            logger.info("No user config found, copying dist files")
            os.makedirs(ConfigManager().configs_dir)

        for f in glob.glob(edclient.module_path +
                           "/configs/input/[A-Za-z]*.json"):
            dest = os.path.join(ConfigManager().configs_dir,
                                os.path.basename(f))
            if not os.path.isfile(dest):
                logger.debug("Copying %s", f)
                shutil.copy2(f, ConfigManager().configs_dir)

        ConfigManager().get_list_of_configs()

        self.input_updated = Caller()
        self.assisted_input_updated = Caller()
        self.heighthold_input_updated = Caller()
        self.hover_input_updated = Caller()
        self.rp_trim_updated = Caller()
        self.emergency_stop_updated = Caller()
        self.device_discovery = Caller()
        self.device_error = Caller()
        self.assisted_control_updated = Caller()
        self.alt1_updated = Caller()
        self.alt2_updated = Caller()

        # Call with 3 bools (rp_limiting, yaw_limiting, thrust_limiting)
        self.limiting_updated = Caller()
Exemple #16
0
 def _trim_pitch_changed(self, value):
     logger.debug("Pitch trim updated to [%f]" % value)
     self.helper.inputDeviceReader.trim_pitch = value
     Config().set("trim_pitch", value)
Exemple #17
0
 def minMaxThrustChanged(self):
     self.helper.inputDeviceReader.min_thrust = self.minThrust.value()
     self.helper.inputDeviceReader.max_thrust = self.maxThrust.value()
     if (self.isInCrazyFlightmode is True):
         Config().set("min_thrust", self.minThrust.value())
         Config().set("max_thrust", self.maxThrust.value())
Exemple #18
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.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.heighthold_input_updated.add_callback(
            self._heighthold_input_updated_signal.emit)
        self._heighthold_input_updated_signal.connect(
            self._heighthold_input_updated)
        self.helper.inputDeviceReader.hover_input_updated.add_callback(
            self._hover_input_updated_signal.emit)
        self._hover_input_updated_signal.connect(self._hover_input_updated)

        self.helper.inputDeviceReader.assisted_control_updated.add_callback(
            self._assisted_control_updated_signal.emit)

        self._assisted_control_updated_signal.connect(
            self._assisted_control_updated)

        self._imu_data_signal.connect(self._imu_data_received)
        self._baro_data_signal.connect(self._baro_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(Config().get("client_side_xmode"))

        self.espdroneXModeCheckbox.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.espdroneXModeCheckbox.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._led_ring_headlight.clicked.connect(
            lambda enabled: self.helper.cf.param.set_value(
                "ring.headlightEnable", str(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="cpu", name="flash", cb=self._set_enable_client_xmode)

        self.helper.cf.param.add_update_callback(
            group="ring",
            name="headlightEnable",
            cb=(lambda name, checked: self._led_ring_headlight.setChecked(
                eval(checked))))

        self._ledring_nbr_effects = 0

        self.helper.cf.param.add_update_callback(group="ring",
                                                 name="effect",
                                                 cb=self._ring_effect_updated)

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

        self.helper.cf.param.all_updated.add_callback(self._all_params_updated)

        self.logBaro = None
        self.logAltHold = None

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

        self.targetCalPitch.setValue(Config().get("trim_pitch"))
        self.targetCalRoll.setValue(Config().get("trim_roll"))

        self.helper.inputDeviceReader.alt1_updated.add_callback(
            self.alt1_updated)
        self.helper.inputDeviceReader.alt2_updated.add_callback(
            self.alt2_updated)
        self._tf_state = 0
        self._ring_effect = 0

        # Connect callbacks for input device limiting of rpöö/pitch/yaw/thust
        self.helper.inputDeviceReader.limiting_updated.add_callback(
            self._limiting_updated.emit)
        self._limiting_updated.connect(self._set_limiting_enabled)
Exemple #19
0
 def maxYawRateChanged(self):
     logger.debug("MaxYawrate changed to %d", self.maxYawRate.value())
     self.helper.inputDeviceReader.max_yaw_rate = self.maxYawRate.value()
     if (self.isInCrazyFlightmode is True):
         Config().set("max_yaw", self.maxYawRate.value())
Exemple #20
0
    def device_discovery(self, devs):
        """Called when new devices have been added"""
        for menu in self._all_role_menus:
            role_menu = menu["rolemenu"]
            mux_menu = menu["muxmenu"]
            dev_group = QActionGroup(role_menu, exclusive=True)
            for d in devs:
                dev_node = QAction(d.name, role_menu, checkable=True,
                                   enabled=True)
                role_menu.addAction(dev_node)
                dev_group.addAction(dev_node)
                dev_node.toggled.connect(self._inputdevice_selected)

                map_node = None
                if d.supports_mapping:
                    map_node = QMenu("    Input map", role_menu, enabled=False)
                    map_group = QActionGroup(role_menu, exclusive=True)
                    # Connect device node to map node for easy
                    # enabling/disabling when selection changes and device
                    # to easily enable it
                    dev_node.setData((map_node, d))
                    for c in ConfigManager().get_list_of_configs():
                        node = QAction(c, map_node, checkable=True,
                                       enabled=True)
                        node.toggled.connect(self._inputconfig_selected)
                        map_node.addAction(node)
                        # Connect all the map nodes back to the device
                        # action node where we can access the raw device
                        node.setData(dev_node)
                        map_group.addAction(node)
                        # If this device hasn't been found before, then
                        # select the default mapping for it.
                        if d not in self._available_devices:
                            last_map = Config().get("device_config_mapping")
                            if d.name in last_map and last_map[d.name] == c:
                                node.setChecked(True)
                    role_menu.addMenu(map_node)
                dev_node.setData((map_node, d, mux_menu))

        # Update the list of what devices we found
        # to avoid selecting default mapping for all devices when
        # a new one is inserted
        self._available_devices = ()
        for d in devs:
            self._available_devices += (d,)

        # Only enable MUX nodes if we have enough devies to cover
        # the roles
        for mux_node in self._all_mux_nodes:
            (mux, sub_nodes) = mux_node.data()
            if len(mux.supported_roles()) <= len(self._available_devices):
                mux_node.setEnabled(True)

        # TODO: Currently only supports selecting default mux
        if self._all_mux_nodes[0].isEnabled():
            self._all_mux_nodes[0].setChecked(True)

        # If the previous length of the available devies was 0, then select
        # the default on. If that's not available then select the first
        # on in the list.
        # TODO: This will only work for the "Normal" mux so this will be
        #       selected by default
        if Config().get("input_device") in [d.name for d in devs]:
            for dev_menu in self._all_role_menus[0]["rolemenu"].actions():
                if dev_menu.text() == Config().get("input_device"):
                    dev_menu.setChecked(True)
        else:
            # Select the first device in the first mux (will always be "Normal"
            # mux)
            self._all_role_menus[0]["rolemenu"].actions()[0].setChecked(True)
            logger.info("Select first device")

        self._update_input_device_footer()
Exemple #21
0
    def flightmodeChange(self, item):
        Config().set("flightmode", str(self.flightModeCombo.itemText(item)))
        logger.debug("Changed flightmode to %s",
                     self.flightModeCombo.itemText(item))
        self.isInCrazyFlightmode = False
        if (item == 0):  # Normal
            self.maxAngle.setValue(Config().get("normal_max_rp"))
            self.maxThrust.setValue(Config().get("normal_max_thrust"))
            self.minThrust.setValue(Config().get("normal_min_thrust"))
            self.slewEnableLimit.setValue(Config().get("normal_slew_limit"))
            self.thrustLoweringSlewRateLimit.setValue(
                Config().get("normal_slew_rate"))
            self.maxYawRate.setValue(Config().get("normal_max_yaw"))
        if (item == 1):  # Advanced
            self.maxAngle.setValue(Config().get("max_rp"))
            self.maxThrust.setValue(Config().get("max_thrust"))
            self.minThrust.setValue(Config().get("min_thrust"))
            self.slewEnableLimit.setValue(Config().get("slew_limit"))
            self.thrustLoweringSlewRateLimit.setValue(
                Config().get("slew_rate"))
            self.maxYawRate.setValue(Config().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)
Exemple #22
0
 def _trim_roll_changed(self, value):
     logger.debug("Roll trim updated to [%f]" % value)
     self.helper.inputDeviceReader.trim_roll = value
     Config().set("trim_roll", value)
Exemple #23
0
 def resizeEvent(self, event):
     Config().set("window_size", [event.size().width(),
                                  event.size().height()])
Exemple #24
0
 def changeXmode(self, checked):
     self.helper.cf.commander.set_client_xmode(checked)
     Config().set("client_side_xmode", checked)
     logger.info("Clientside X-mode enabled: %s", checked)
Exemple #25
0
 def maxAngleChanged(self):
     logger.debug("MaxAngle changed to %d", self.maxAngle.value())
     self.helper.inputDeviceReader.max_rp_angle = self.maxAngle.value()
     if (self.isInCrazyFlightmode is True):
         Config().set("max_rp", self.maxAngle.value())
Exemple #26
0
#  USA.
"""
Input interface that supports receiving commands via ZMQ.
"""

import logging
from threading import Thread

from edclient.utils.config import Config

try:
    import zmq
except Exception as e:
    raise Exception("ZMQ library probably not installed ({})".format(e))

if not Config().get("enable_zmq_input"):
    raise Exception("ZMQ input disabled in config file")

__author__ = 'Bitcraze AB'
__all__ = ['ZMQReader']

ZMQ_PULL_PORT = 1024 + 188

logger = logging.getLogger(__name__)

MODULE_MAIN = "ZMQReader"
MODULE_NAME = "ZMQ"


class _PullReader(Thread):
    def __init__(self, receiver, callback, *args):
Exemple #27
0
    def _populate_assisted_mode_dropdown(self):
        self._assist_mode_combo.addItem("Altitude hold", 0)
        self._assist_mode_combo.addItem("Position hold", 1)
        self._assist_mode_combo.addItem("Height hold", 2)
        self._assist_mode_combo.addItem("Hover", 3)
        heightHoldPossible = False
        hoverPossible = False

        # if int(self.helper.cf.param.values["deck"]["bcZRanger"]) == 1:
        #     heightHoldPossible = True
        #     self.helper.inputDeviceReader.set_hover_max_height(1.0)

        if int(self.helper.cf.param.values["deck"]["bcZRanger2"]) == 1:
            heightHoldPossible = True
            self.helper.inputDeviceReader.set_hover_max_height(2.0)

        # if int(self.helper.cf.param.values["deck"]["bcFlow"]) == 1:
        #     heightHoldPossible = True
        #     hoverPossible = True
        #     self.helper.inputDeviceReader.set_hover_max_height(1.0)

        # if int(self.helper.cf.param.values["deck"]["bcFlow2"]) == 1:
        #     heightHoldPossible = True
        #     hoverPossible = True
        #     self.helper.inputDeviceReader.set_hover_max_height(2.0)

        if not heightHoldPossible:
            self._assist_mode_combo.model().item(2).setEnabled(False)
        else:
            self._assist_mode_combo.model().item(0).setEnabled(False)

        if not hoverPossible:
            self._assist_mode_combo.model().item(3).setEnabled(False)
        else:
            self._assist_mode_combo.model().item(0).setEnabled(False)

        self._assist_mode_combo.currentIndexChanged.connect(
            self._assist_mode_changed)
        self._assist_mode_combo.setEnabled(True)

        try:
            assistmodeComboIndex = Config().get("assistedControl")
            if assistmodeComboIndex == 3 and not hoverPossible:
                self._assist_mode_combo.setCurrentIndex(0)
                self._assist_mode_combo.currentIndexChanged.emit(0)
            elif assistmodeComboIndex == 0 and hoverPossible:
                self._assist_mode_combo.setCurrentIndex(3)
                self._assist_mode_combo.currentIndexChanged.emit(3)
            elif assistmodeComboIndex == 2 and not heightHoldPossible:
                self._assist_mode_combo.setCurrentIndex(0)
                self._assist_mode_combo.currentIndexChanged.emit(0)
            elif assistmodeComboIndex == 0 and heightHoldPossible:
                self._assist_mode_combo.setCurrentIndex(2)
                self._assist_mode_combo.currentIndexChanged.emit(2)
            else:
                self._assist_mode_combo.setCurrentIndex(assistmodeComboIndex)
                self._assist_mode_combo.currentIndexChanged.emit(
                    assistmodeComboIndex)
        except KeyError:
            defaultOption = 0
            if hoverPossible:
                defaultOption = 3
            elif heightHoldPossible:
                defaultOption = 2
            self._assist_mode_combo.setCurrentIndex(defaultOption)
            self._assist_mode_combo.currentIndexChanged.emit(defaultOption)