Skip to content

Commit

Permalink
New python supervision (#2863)
Browse files Browse the repository at this point in the history
  • Loading branch information
Fabien-B committed Apr 20, 2022
1 parent 9f40bb4 commit e82db25
Show file tree
Hide file tree
Showing 97 changed files with 3,893 additions and 10,781 deletions.
2 changes: 1 addition & 1 deletion paparazzi
Expand Up @@ -11,7 +11,7 @@ env['PAPARAZZI_HOME'] = PAPARAZZI_HOME
env['PAPARAZZI_SRC'] = PAPARAZZI_SRC

if len(sys.argv) > 1 and sys.argv[1] == "-python":
path = os.path.normpath(os.path.join(dirname, 'sw', 'supervision', 'python', 'main.py'))
path = os.path.normpath(os.path.join(dirname, 'sw', 'supervision', 'python', 'paparazzicenter.py'))
os.execve(path, sys.argv, env)
else:
path = os.path.normpath(os.path.join(dirname, 'sw', 'supervision', 'paparazzicenter'))
Expand Down
44 changes: 0 additions & 44 deletions sw/supervision/python/.cache.dtd

This file was deleted.

18 changes: 18 additions & 0 deletions sw/supervision/python/Makefile
@@ -0,0 +1,18 @@
# Copyright (C) 2008-2022 The Paparazzi Team
# released under GNU GPLv2 or later. See COPYING file.
all:
mkdir -p generated
pyuic5 ui/conf_header.ui -o generated/ui_conf_header.py
pyuic5 ui/conf_item.ui -o generated/ui_conf_item.py
pyuic5 ui/build.ui -o generated/ui_build.py
pyuic5 ui/configuration_panel.ui -o generated/ui_configuration_panel.py
pyuic5 ui/new_ac_dialog.ui -o generated/ui_new_ac_dialog.py
pyuic5 ui/session.ui -o generated/ui_session.py
pyuic5 ui/program.ui -o generated/ui_program.py
pyuic5 ui/operation_panel.ui -o generated/ui_operation_panel.py
pyuic5 ui/console.ui -o generated/ui_console.py
pyuic5 ui/tools_list.ui -o generated/ui_tools_list.py
pyuic5 ui/app_settings.ui -o generated/ui_app_settings.py

clean:
rm -r generated
69 changes: 0 additions & 69 deletions sw/supervision/python/README.md

This file was deleted.

10 changes: 10 additions & 0 deletions sw/supervision/python/Readme.md
@@ -0,0 +1,10 @@
# Paparazzi Center

The Paparazzi Center is the home application for Paparazzi UAV.



Install the package `pyqt5-dev-tools` and run `make` to generate python ui files.

Install python dependencies:
`python3 -m pip install -r requirements.txt`
28 changes: 28 additions & 0 deletions sw/supervision/python/app_settings.py
@@ -0,0 +1,28 @@
# Copyright (C) 2008-2022 The Paparazzi Team
# released under GNU GPLv2 or later. See COPYING file.
from PyQt5.QtWidgets import *
from PyQt5 import QtCore, QtGui, QtWidgets
from generated.ui_app_settings import Ui_AppSettingsDialog
import utils


class AppSettings(QDialog, Ui_AppSettingsDialog):

def __init__(self, parent=None):
QWidget.__init__(self, parent=parent)
self.setupUi(self)
settings = utils.get_settings()
self.text_editor_edit.setText(settings.value("text_editor", "", str))
self.terminal_emulator_edit.setText(settings.value("terminal_emulator", "", str))
self.keep_changes_checkbox.setChecked(settings.value("always_keep_changes", False, bool))
self.finished.connect(self.handle_finished)

def handle_finished(self, result):
if result:
settings = utils.get_settings()
text_editor = self.text_editor_edit.text()
settings.setValue("text_editor", text_editor)
terminal_emulator = self.terminal_emulator_edit.text()
settings.setValue("terminal_emulator", terminal_emulator)
keep_changes = self.keep_changes_checkbox.isChecked()
settings.setValue("always_keep_changes", keep_changes)
119 changes: 119 additions & 0 deletions sw/supervision/python/build_widget.py
@@ -0,0 +1,119 @@
# Copyright (C) 2008-2022 The Paparazzi Team
# released under GNU GPLv2 or later. See COPYING file.
from PyQt5.QtWidgets import *
from PyQt5 import QtCore
from generated.ui_build import Ui_Build
import lxml.etree as ET
import os
import utils
from conf import Aircraft, Conf
from typing import List, Dict
from dataclasses import dataclass, field
import re


@dataclass
class FlashMode:
name: str
vars: Dict[str, str] = field(default_factory=dict)
boards: List[str] = field(default_factory=list)

def match(self, board):
for regex in self.boards:
if re.match(regex, board) is not None:
return True
return False


class BuildWidget(Ui_Build, QWidget):

spawn_program = QtCore.pyqtSignal(str, list, str)

def __init__(self, parent=None):
QWidget.__init__(self, parent=parent)
self.setupUi(self)
# uic.loadUi("ui/build.ui", self)
self.ac: Aircraft = None
self.conf: Conf = None # to save conf before building
self.flash_modes: List[FlashMode] = self.parse_flash_modes()
self.build_button.clicked.connect(self.build)
self.clean_button.clicked.connect(self.clean)
self.flash_button.clicked.connect(self.flash)
self.target_combo.currentTextChanged.connect(self.update_flash_mode)

def set_conf(self, conf: Conf):
self.conf = conf

@staticmethod
def parse_flash_modes() -> List[FlashMode]:
flash_xml = ET.parse(os.path.join(utils.CONF_DIR, "flash_modes.xml"))
modes = []
for xml_mode in flash_xml.getroot().findall("mode"):
mode_name = xml_mode.get("name")
vars = {}
for xml_var in xml_mode.findall("variable"):
var_name = xml_var.get("name")
var_value = xml_var.get("value")
vars[var_name] = var_value
mode = FlashMode(mode_name, vars)
for xml_board in xml_mode.find("boards").findall("board"):
board = xml_board.get("name")
mode.boards.append(board)
modes.append(mode)
return modes

def get_flash_modes(self, board):
modes = filter(lambda fm: fm.match(board), self.flash_modes)
mode_names = [mode.name for mode in modes]
return mode_names

def update_targets(self, ac: Aircraft):
self.ac = ac
self.target_combo.clear()

for target in ac.boards.keys():
self.target_combo.addItem(target)

def update_flash_mode(self, target):
self.device_combo.clear()
if target != "":
self.device_combo.addItem("Default")
board = self.ac.boards[target]
flash_modes = self.get_flash_modes(board)
self.device_combo.addItems(flash_modes)

def get_current_target(self) -> str:
return self.target_combo.currentText()

def build(self):
target = self.target_combo.currentText()
cmd = ["make", "-C", utils.PAPARAZZI_HOME, "-f", "Makefile.ac",
"AIRCRAFT={}".format(self.ac.name), "{}.compile".format(target)]
if self.print_config_checkbox.isChecked():
cmd.append("PRINT_CONFIG=1")
shortname = "Build {}".format(self.ac.name)
self.conf.save(False)
self.spawn_program.emit(shortname, cmd, None)

def clean(self):
cmd = ["make", "-C", utils.PAPARAZZI_HOME, "-f", "Makefile.ac",
"AIRCRAFT={}".format(self.ac.name), "clean_ac"]
shortname = "Clean {}".format(self.ac.name)
self.spawn_program.emit(shortname, cmd, None)

def flash(self):
target = self.target_combo.currentText()
vars = []
flash_mode = self.device_combo.currentText()
if flash_mode != "Default":
for mode in self.flash_modes:
if mode.name == flash_mode:
vars = ["{}={}".format(var_name, var_value) for (var_name, var_value) in mode.vars.items()]
break
else:
raise Exception("Flash mode {} not found!".format(flash_mode))
cmd = ["make", "-C", utils.PAPARAZZI_HOME, "-f", "Makefile.ac",
"AIRCRAFT={}".format(self.ac.name)] + vars + ["{}.upload".format(target)]
shortname = "Flash {}".format(self.ac.name)
self.spawn_program.emit(shortname, cmd, None)

0 comments on commit e82db25

Please sign in to comment.