diff --git a/.gitignore b/.gitignore index 5d230b15ec..b3913cdb43 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,9 @@ .cache.xml .directory +# python venv +pprzEnv/ + # Eclipse IDE project files *.cproject *.project diff --git a/conf/system/term_init.sh b/conf/system/term_init.sh new file mode 100644 index 0000000000..a3b2c8e43c --- /dev/null +++ b/conf/system/term_init.sh @@ -0,0 +1,19 @@ + +source ~/.profile + +if [ -d "$PAPARAZZI_HOME/pprzEnv" ]; then + source $PAPARAZZI_HOME/pprzEnv/bin/activate +fi + +shell=$(echo $SHELL | cut -d / -f 3) + +if [ "$shell" = "bash" ]; then + # enter bash specific commands here + echo $shell > /dev/null +elif [ "$shell" = "zsh" ]; then + # enter zsh specific commands here + echo $shell > /dev/null +else + # fallback commands + echo $shell > /dev/null +fi; diff --git a/install.sh b/install.sh index da99729856..729a5ff0c8 100755 --- a/install.sh +++ b/install.sh @@ -1,6 +1,60 @@ #!/bin/bash -sudo apt-get install -f -y python3 python3-pyqt5 +USE_VENV=true +BASHRC_SOURCE_VENV=false + +# exit on error +set -e + +for arg in "$@" +do + if [ "$arg" = "-h" ] || [ "$arg" = "--help" ] + then + echo "Usage: ./install.sh [-n|--no-venv] [-h|---help]" + echo " -n, --no-venv Do not use python virtual environment" + echo " -s, --source Add venv source in ~/.bashrc" + echo " -h, --help Print this help" + exit 0 + fi + + if [ "$arg" = "-n" ] || [ "$arg" = "--no-venv" ] + then + USE_VENV=false + echo "the venv will not be installed!" + fi + + if [ "$arg" = "-s" ] || [ "$arg" = "--source" ] + then + BASHRC_SOURCE_VENV=true + fi + +done + + +if [ $VIRTUAL_ENV ] +then + echo "Cannot create venv from itself! Run 'deactivate' first if you want to recreate the venv." + USE_VENV = false + BASHRC_SOURCE_VENV=false +fi + + +if [ "$USE_VENV" = true ] +then + sudo apt install -y python3 python3-venv + python3 setup.py + source pprzEnv/bin/activate + + if [ "$BASHRC_SOURCE_VENV" = true ] + then + echo "venv source will be added to ~/.bashrc" + echo "source $(pwd)/pprzEnv/bin/activate" >> ~/.bashrc + fi + +else + sudo apt-get install -f -y python3 python3-pyqt5 +fi + python3 ./sw/tools/install.py diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000..be1e52b730 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,11 @@ +lxml +numpy +scipy +ivy-python +pyserial +PyQt5 +PyQtWebEngine +pyqtgraph +unidecode +matplotlib +distro diff --git a/setup.py b/setup.py new file mode 100644 index 0000000000..8ec84f360e --- /dev/null +++ b/setup.py @@ -0,0 +1,49 @@ +import venv +import os +import sys +import subprocess +import argparse +import shutil + +ENV_NAME = 'pprzEnv' + + +def run(args): + if args.clean: + if os.path.exists(ENV_NAME): + print("Cleaning previous venv.") + shutil.rmtree(ENV_NAME) + else: + print("No previous venv to clean.") + + print("Creating a virtual environment for Paparazzi...") + venv.create(ENV_NAME, with_pip=True, system_site_packages=args.system) + + # installing requirements + cmd = [f'./{ENV_NAME}/bin/pip', 'install', '-r' , 'requirements.txt'] + result = subprocess.run(cmd, check=False) + if result.returncode: + print("Failed to create venv!") + else: + print("venv successfully created.") + + # installing pprzlink + print("Installing pprzlink...") + cmd = [f'./{ENV_NAME}/bin/pip', 'install', '-e' , 'sw/ext/pprzlink/lib/v2.0/python'] + result = subprocess.run(cmd, check=False) + if result.returncode: + print("Failed to install pprzlink!") + else: + print("pprzlink successfully installed.") + + if not os.path.exists(f'./{ENV_NAME}/bin/calibrate.py'): + os.symlink('../../sw/tools/calibration/calibrate.py', f'./{ENV_NAME}/bin/calibrate.py') + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="This script will setup the python environment for Paparazzi") + parser.add_argument('-s', '--system', action='store_true', help="Use system site packages.") + parser.add_argument('-c', '--clean', action='store_true', help="Delete the previous virtual environment before recreating it.") + args = parser.parse_args() + + run(args) diff --git a/sw/supervision/python/utils.py b/sw/supervision/python/utils.py index 8bfad9a6f7..41b311ae5b 100644 --- a/sw/supervision/python/utils.py +++ b/sw/supervision/python/utils.py @@ -5,6 +5,7 @@ import subprocess from PyQt5.QtWidgets import * from typing import NamedTuple from PyQt5.QtCore import QSettings +import subprocess class GConfEntry(NamedTuple): @@ -66,16 +67,17 @@ def get_build_version() -> str: version = f.readline().strip() return version +def get_shell(): + p = subprocess.run(['getent', 'passwd', os.getenv('LOGNAME')], capture_output=True) + shell = p.stdout.decode().strip().split(':')[6] + return shell -def open_terminal(wd, command=None): - cmd = "" - if command is not None: - cmd = " -- {}".format(command) +def open_terminal(wd): terminal_emulator = get_settings().value("terminal_emulator", "", str) if terminal_emulator == "": - terminal_emulator = "gnome-terminal" - os.system("{}".format(terminal_emulator)) - + terminal_emulator = "x-terminal-emulator" + shell = get_shell() + subprocess.Popen([terminal_emulator, '-e', shell, '--rcfile', 'conf/system/term_init.sh'], cwd=wd) def get_settings() -> QSettings: return QSettings(os.path.join(CONF_DIR, "pprz_center_settings.ini"), QSettings.IniFormat) diff --git a/sw/tools/install.py b/sw/tools/install.py index 8aacc0ebe7..6356087d4a 100755 --- a/sw/tools/install.py +++ b/sw/tools/install.py @@ -5,11 +5,11 @@ from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * -import lsb_release +import distro import subprocess import webbrowser -release = lsb_release.get_distro_information() +distro_version = float(distro.version()) docs = 'https://paparazzi-uav.readthedocs.io' @@ -47,12 +47,12 @@ class InstallWindow(QWidget): def cmd_dev(self): self.execute('sudo -E apt-get -f -y install paparazzi-dev') # Missing - if float(release['RELEASE']) <= 20.04: + if distro_version <= 20.04: self.execute('sudo -E apt-get install -y python3-lxml python3-numpy') def cmd_arm(self): self.execute('sudo -E apt-get -f -y install paparazzi-dev') - if float(release['RELEASE']) >= 20.04: + if distro_version >= 20.04: self.execute('sudo -E apt-get install -y python-is-python3 gcc-arm-none-eabi gdb-multiarch') # python3-serial? else: @@ -72,7 +72,7 @@ class InstallWindow(QWidget): self.execute('sudo -E cp conf/system/udev/rules/*.rules /etc/udev/rules.d/ && sudo -E udevadm control --reload-rules') def cmd_gazebo(self): - if float(release['RELEASE']) > 20.04: + if distro_version > 20.04: self.execute('sudo -E apt-get -f -y install gazebo libgazebo-dev') else: self.execute('sudo -E apt-get -f -y install gazebo9 libgazebo9-dev') @@ -106,8 +106,7 @@ class InstallWindow(QWidget): QWidget.__init__(self) mainlayout = QVBoxLayout() - os = QLabel() - os.setText("OS: " + release['ID'] + ' ' + release['RELEASE']) + os = QLabel(f"OS: {distro.name()} {distro.version()}") os.setFont(QFont("Times", 18, QFont.Bold)) mainlayout.addWidget(os) @@ -143,7 +142,7 @@ class InstallWindow(QWidget): btn_layout.addWidget(button4) button5 = QPushButton('5) Binary ground station') - if float(release['RELEASE']) < 20.04: + if distro_version < 20.04: button5.setDisabled(True) else: button5.clicked.connect(self.cmd_gcs) @@ -153,7 +152,7 @@ class InstallWindow(QWidget): button6.clicked.connect(self.cmd_mcu) btn_layout.addWidget(button6) - if float(release['RELEASE']) <= 20.04: + if distro_version <= 20.04: button7 = QPushButton('7) Gazebo9') else: button7 = QPushButton('7) Gazebo11') @@ -162,7 +161,7 @@ class InstallWindow(QWidget): button8 = QPushButton('8) Bebop Opencv') button8.clicked.connect(self.cmd_bebopcv) - if float(release['RELEASE']) > 20.04: + if distro_version > 20.04: button8.setDisabled(True) btn_layout.addWidget(button8)