Skip to content
47 changes: 35 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ dedicated circuit board, but generic development kits such as Raspberry Pi and A
high-level system running on a host computer, the software framework has the ability to adapt to any type of hardware
component if you are willing to write some codes.

This document will guide you through LEADS VeC. You will find a detailed
version [here](https://leads-docs.projectneura.org/en/latest/vec).
This document will guide you through LEADS VeC. You will find a detailed version
[here](https://leads-docs.projectneura.org/en/latest/vec).

LEADS VeC Demo

Expand Down Expand Up @@ -76,7 +76,8 @@ pip install Pillow PySDL2 customtkinter gpiozero lgpio pynmea2 pynput pysdl2-dll

`numpy` and `pandas` will be automatically installed with `leads`.

`Pillow`, `PySDL2`, `customtkinter`, `gpiozero`, `lgpio`, `pynmea2`, `pynput`, `pysdl2-dll`, and `pyserial` are optional.
`Pillow`, `PySDL2`, `customtkinter`, `gpiozero`, `lgpio`, `pynmea2`, `pynput`, `pysdl2-dll`, and `pyserial` are
optional.

If you only want the framework, run the following.

Expand Down Expand Up @@ -232,9 +233,6 @@ If not specified, all configurations will be default values.

To learn about the configuration file, read [Configurations](#configurations).

If you install Python using the scripts, you will not find `python ...`, `python3 ...`, `pip ...`, or `pip3 ...` working
because you have to specify the Python version such that `python3.12 ...` and `python3.12 -m pip ...`.

## Environment Setup

This section helps you set up the identical environment we have for the VeC project. A more detailed guide of
Expand All @@ -243,18 +241,43 @@ Ubuntu 22.04 LTS on a Raspberry Pi 4 Model B 8GB. After the OS is set up, just r
You may also choose to clone the repository or download the scripts from
[releases](https://github.com/ProjectNeura/LEADS/releases) (only stable releases provide scripts).

These scripts currently only support Ubuntu.
These scripts currently only support `apt` as the package manager.

If you install Python using the scripts, you will not find `python ...`, `python3 ...`, `pip ...`, or `pip3 ...` working
because you have to specify the Python environment such that `/usr/local/leads/venv/bin/python ...` and
`/usr/local/leads/venv/bin/pip ...`.

### Python and LEADS
### LEADS

You can simply run "[setup.sh](scripts/setup.sh)" and it will install everything including all the optional dependencies
of LEADS for you.
You can simply run "[setup.sh](scripts/setup.sh)" and it will install everything including Python 3.12 all the optional
dependencies of LEADS for you.

```shell
/bin/sh "setup.sh$(wget -O setup.sh https://raw.githubusercontent.com/ProjectNeura/LEADS/master/scripts/setup.sh)" && rm setup.sh || rm setup.sh
```

### Python Only
To save your time from typing `/usr/local/leads/venv/bin/python -m leads_vec -c /usr/local/leads/config.json run` a
thousand times, we provide a boot script "[leads.sh](scripts/leads.sh)".

Download it to wherever you feel convenient.

```shell
wget -O leads.sh https://raw.githubusercontent.com/ProjectNeura/LEADS/master/scripts/leads.sh
```

Run it like this.

```shell
/bin/sh leads.sh {arg1} {arg2} {arg3} ...
```

It specifies to use this configuration file: "usr/local/leads/config.json". If the file does not exist an error will be
raised. You must [create](#configurations) or [generate](#generate-a-configuration-file) a configuration file with the
exact same path.

You can always pass other optional arguments additionally to that.

### Python

[python-install.sh](scripts/python-install.sh) will only install Python 3.12 and Tcl/Tk.

Expand All @@ -280,7 +303,7 @@ To configure frp, use "[frp-config.sh](scripts/frp-config.sh)".
There are 4 arguments for this script, of which the first 2 are required.

```shell
/bin/sh "frp-config.sh$(...)" ${frp server IP} ${frp token} ${frp port} ${LEADS comm port} && rm frp-config.sh || rm frp-config.sh
/bin/sh "frp-config.sh$(...)" {frp_server_ip} {frp_token} {frp_port} {comm_port} && rm frp-config.sh || rm frp-config.sh
```

### OBS Studio
Expand Down
25 changes: 7 additions & 18 deletions leads_vec/__main__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
from argparse import ArgumentParser as _ArgumentParser, BooleanOptionalAction as _BooleanOptionalAction
from importlib.metadata import version as _package_version, PackageNotFoundError as _PackageNotFoundError
from importlib.util import spec_from_file_location as _spec_from_file_location, module_from_spec as _module_from_spec
from os import mkdir as _mkdir, chmod as _chmod
from os import getlogin as _get_login
from os.path import abspath as _abspath
from os.path import exists as _exists
from subprocess import run as _run
from sys import exit as _exit, version as _version
from warnings import filterwarnings as _filterwarnings

Expand All @@ -22,7 +21,7 @@

parser = _ArgumentParser(prog="LEADS VeC",
description="Lightweight Embedded Assisted Driving System VeC",
epilog="ProjectNeura: https://projectneura.org"
epilog="ProjectNeura: https://projectneura.org\n"
"GitHub: https://github.com/ProjectNeura/LEADS")
parser.add_argument("action", choices=("info", "replay", "run"))
parser.add_argument("-c", "--config", default=None, help="specify a configuration file")
Expand Down Expand Up @@ -51,26 +50,19 @@
_L.info(f"LEADS VeC",
f"System Kernel: {_get_system_kernel().upper()}",
f"Python Version: {_version}",
f"User: {_get_login()}",
f"`frpc` Available: {_frpc_exists()}",
f"Module Path: {_MODULE_PATH}",
f"LEADS Version: {leads_version}",
f"LEADS VeC Version: {__version__}",
sep="\n")
_exit()
if args.register == "systemd":
if _get_system_kernel() != "linux":
_exit("Error: Unsupported operating system")
if not _exists("/usr/local/leads/config.json"):
_L.info("Config file not found. Creating \"/usr/local/leads/config.json\"...")
_mkdir("/usr/local/leads")
with open("/usr/local/leads/config.json", "w") as f:
f.write(str(_Config({})))
_L.info("Using \"/usr/local/leads/config.json\"")
_chmod("/usr/local/leads/config.json", 777)
from ._bootloader import create_service as _create_service

_create_service()
_L.info("Service registered")
_L.info(f"Service script is located at \"{_MODULE_PATH}/_bootloader/leads_vec.service.sh\"")
elif args.register == "config":
if _exists("config.json"):
r = input("\"config.json\" already exists. Overwrite? (y/N) >>>").lower()
Expand All @@ -94,13 +86,10 @@
config.auto_magnify_font_sizes()
_register_config(config)
if args.xws:
if _get_system_kernel() != "linux":
_exit("Error: Unsupported operating system")
from os import getuid as _getuid
from pwd import getpwuid as _getpwuid
from ._bootloader import configure_xws as _configure_xws

_L.info("Configuring X Window System...")
_run(("/usr/bin/xhost", f"+SI:localuser:{_getpwuid(_getuid()).pw_name}"))
_configure_xws()
_L.info("X Window System configured")

from leads_vec.cli import main

Expand Down
1 change: 1 addition & 0 deletions leads_vec/_bootloader/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
from leads_vec._bootloader.frp import *
from leads_vec._bootloader.systemd import *
from leads_vec._bootloader.xws import *
5 changes: 4 additions & 1 deletion leads_vec/_bootloader/leads_vec.service.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,7 @@ then
echo "Error: Config file does not exist"
exit 1
fi
python3.12 -m leads_vec -c /usr/local/leads/config.json --xws run

# change the interpreter or adjust the arguments according to your needs
# but do not remove `--xws`
/usr/local/leads/venv/bin/python -m leads_vec -c /usr/local/leads/config.json --xws run
16 changes: 14 additions & 2 deletions leads_vec/_bootloader/systemd.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
from os import chmod as _chmod, getlogin as _get_login
from os.path import abspath as _abspath
from os import chmod as _chmod, getlogin as _get_login, mkdir as _mkdir
from os.path import abspath as _abspath, exists as _exists

from leads import L as _L
from leads_gui import Config as _Config
from leads_gui.system import get_system_kernel as _get_system_kernel


def create_service() -> None:
if _get_system_kernel() != "linux":
raise SystemError("Unsupported operating system")
if not _exists("/usr/local/leads/config.json"):
_L.debug("Config file not found. Creating \"/usr/local/leads/config.json\"...")
_mkdir("/usr/local/leads")
with open("/usr/local/leads/config.json", "w") as f:
f.write(str(_Config({})))
_chmod("/usr/local/leads/config.json", 777)
_chmod(f"{(script := _abspath(__file__)[:-10])}leads_vec.service.sh", 777)
with open("/etc/systemd/system/leads_vec.service", "w") as f:
f.write(
Expand Down
10 changes: 10 additions & 0 deletions leads_vec/_bootloader/xws.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from os import getlogin as _get_login
from subprocess import run as _run

from leads_gui.system import get_system_kernel as _get_system_kernel


def configure_xws() -> None:
if _get_system_kernel() != "linux":
raise SystemError("Unsupported operating system")
_run(("/usr/bin/xhost", f"+SI:localuser:{_get_login()}"))
2 changes: 1 addition & 1 deletion readthedocs
13 changes: 7 additions & 6 deletions scripts/frp-config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ abort() {
if [ "${EUID:-$(id -u)}" -ne 0 ];
then abort "Error: This script requires root permission"
fi
if ! test -d "/usr/local/frp";
then abort "Error: /usr/local/frp not found"
fi

execute() {
if ! "$@";
Expand All @@ -32,15 +35,13 @@ argument_exists_or() {
else echo "$2"
fi
}
if ! test -d "/usr/local/frp";
then abort "frp not found"
fi

echo "Configuring client..."
echo "serverAddr = \"$(require_argument "$1" "frp server IP")\"" > "/usr/local/frp/frpc.toml"
echo "serverAddr = \"$(require_argument "$1" "frp_server_ip")\"" > "/usr/local/frp/frpc.toml"
{
echo "serverPort = $(argument_exists_or "$3" "7000")"
echo "auth.method = \"token\""
echo "auth.token = \"$(require_argument "$2" "frp token")\""
echo "auth.token = \"$(require_argument "$2" "frp_token")\""
echo "[[proxies]]"
echo "name = \"leads-vec-comm\""
echo "type = \"tcp\""
Expand All @@ -52,7 +53,7 @@ echo "Configuring server..."
echo "bindPort = $(argument_exists_or "$3" "7000")" > "/usr/local/frp/frps.toml"
{
echo "auth.method = \"token\""
echo "auth.token = \"$(require_argument "$2" "frp token")\""
echo "auth.token = \"$(require_argument "$2" "frp_token")\""
echo "vhostHTTPPort = 80"
echo "vhostHTTPSPort = 443"
} >> "/usr/local/frp/frps.toml"
7 changes: 4 additions & 3 deletions scripts/frp-install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ if [ "${EUID:-$(id -u)}" -ne 0 ];
then abort "Error: This script requires root permission"
fi

if test -d "/usr/local/frp";
then abort "Error: /usr/local/frp already exists"
fi

execute() {
if ! "$@";
then abort "$(printf "Failed: %s" "$@")"
Expand All @@ -19,9 +23,6 @@ execute_root() {
execute "sudo" "$@"
}

if test -d "/usr/local/frp";
then abort "/usr/local/frp already exists"
fi
if ! command -v curl > /dev/null;
then
echo "cURL is not available, installing..."
Expand Down
14 changes: 14 additions & 0 deletions scripts/leads.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/sh

abort() {
printf "%s\n" "$@" >&2
exit 1
}

execute() {
if ! "$@";
then abort "$(printf "Failed: %s" "$@")"
fi
}

execute "/usr/local/leads/venv/bin/python" "-m" "leads_vec" "-c" "/usr/local/leads/config.json" "$@" "run"
9 changes: 3 additions & 6 deletions scripts/python-install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,7 @@ execute_root "add-apt-repository" "ppa:deadsnakes/ppa"
execute_root "apt" "update"
echo "Installing Python 3.12..."
execute_root "apt" "install" "-y" "gcc" "python3.12" "python3.12-dev"
echo "Fixing Pip..."
execute_root "wget" "-O" "get-pip.py" "https://bootstrap.pypa.io/get-pip.py"
execute_root "python3.12" "get-pip.py"
echo "Cleaning up..."
execute_root "rm" "get-pip.py"
echo "Installing Tcl/Tk..."
execute_root "apt" "install" "-y" "python3.12-tk"
execute_root "apt" "install" "-y" "python3.12-tk"
echo "Creating Virtual Environment..."
execute_root "python3.12" "-m" "venv" "/usr/local/leads/venv"
4 changes: 2 additions & 2 deletions scripts/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,5 @@ execute_root "/bin/sh" "python-install.sh"
echo "Cleaning up..."
execute_root "rm" "python-install.sh"
echo "Installing dependencies..."
execute "python3.12" "-m" "pip" "install" "Pillow" "PySDL2" "customtkinter" "gpiozero" "lgpio" "pynmea2" "pynput" "pysdl2-dll" "pyserial" "leads"
execute "python3.12" "-m" "leads_vec" "info"
execute "/usr/local/leads/venv/bin/pip" "install" "Pillow" "PySDL2" "customtkinter" "gpiozero" "lgpio" "pynmea2" "pynput" "pysdl2-dll" "pyserial" "leads"
execute "/usr/local/leads/venv/bin/python" "-m" "leads_vec" "info"