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))
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))
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())
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
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()
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)
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)
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)
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()
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)
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)
def closeEvent(self, event): self.hide() self.cf.close_link() Config().save_file()
def _auto_reconnect_changed(self, checked): self._auto_reconnect_enabled = checked Config().set("auto_reconnect", checked) logger.info("Auto reconnect enabled: {}".format(checked))
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
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()
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)
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())
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)
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())
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()
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)
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)
def resizeEvent(self, event): Config().set("window_size", [event.size().width(), event.size().height()])
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)
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())
# 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):
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)