Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: Build
run: |
sudo apt-get update
DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC sudo apt-get -y install git make wget gcc libevent-dev libcsfml-dev file g++ cpio unzip rsync bc bzip2 libcairo-dev
DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC sudo apt-get -y install git make wget gcc libevent-dev libcsfml-dev file g++ cpio unzip rsync bc bzip2 libcairo-dev libsqlite3-dev
./build.sh goke
./build.sh hisi
./build.sh star6b0
Expand Down
46 changes: 46 additions & 0 deletions .github/workflows/preflight-pack.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: preflight-pack

# Build the standalone preflight map app (gs/mapserver.py + web/) into a single
# self-contained binary for Linux, macOS and Windows. Run manually or by pushing
# a `preflight-v*` tag; grab the binaries from the run's Artifacts.

on:
workflow_dispatch:
push:
tags:
- "preflight-v*"

jobs:
build:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
artifact: msposd-preflight-linux
- os: macos-latest
artifact: msposd-preflight-macos
- os: windows-latest
artifact: msposd-preflight-windows
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Install PyInstaller
run: python -m pip install --upgrade pyinstaller

- name: Build
run: python -m PyInstaller --clean --noconfirm gs/pack/mapserver.spec

- name: Upload binary
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact }}
path: |
dist/msposd-preflight
dist/msposd-preflight.exe
if-no-files-found: error
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,15 @@ msposd_star6b0
msposd_star6e
msposd_star6c
msposd
msposd_x
msposd_rockchip
version.h
serial_monitor.c
*.ini
# PyInstaller output (gs/pack standalone build)
/build/
/dist/
*.spec.bak


.claude/
6 changes: 4 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"program": "${workspaceFolder}/msposd",
"args": [
"--master",
"127.0.0.1:14550",
"127.0.0.1:14560",
"--baudrate",
"115200",
"--osd",
Expand Down Expand Up @@ -54,7 +54,9 @@
"args": [
"-m",
"/tmp/inav_pty",
"-d",
"-d",
"--out",
"127.0.0.1:14560",
"-r",
"1030",
"--ahi",
Expand Down
64 changes: 64 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Project Instructions

This file is the single source of truth for all AI coding agents (Claude Code,
OpenAI Codex, or any tool that reads AGENTS.md / CLAUDE.md).

## Project Overview

A program that draws flight controller's OSD(On-Screen Display) information via MSP DisplayPort protocil directly onto the video stream coming from an OpenIPC camera.

## Development Workflow: spec - draft - simplify - verify

Every non-trivial task MUST follow this four-phase pipeline.
Each phase is a gate: do not advance until the current phase passes.

### Phase 1: Spec (Plan)

Before writing any code, produce a plan:

1. Read relevant documentation in `documentation/`.
2. Read the source files you intend to modify.
3. Write a concise plan covering: what changes, which files, why.
4. Document key design decisions and their rationale in the plan. This
prevents oscillating between approaches mid-implementation.
5. Get human approval on the plan before proceeding.

Do NOT skip planning. A good plan lets you one-shot the implementation.

### Phase 2: Draft (Implement)

Execute the plan:

- Follow the coding conventions below.
- Make minimal, focused changes. Do not refactor unrelated code.
- Do not add features beyond what the spec calls for.

### Phase 3: Simplify (Review)

After implementation, review your own work:

- Can any function be shorter or clearer?
- Are there unnecessary abstractions, error paths, or comments?
- Does the architecture stay clean? No dead code, no orphan headers.
- Remove anything that is not strictly needed.

### Phase 4: Verify (Build + Test)

Run verification before declaring done:



## Documentation in code Rules:

Every function/method MUST include a documentation comment.

Requirements:
- Use standard language conventions.
- Include:
- Short function description (MAX 50 words)
- Description of every parameter
- Return value description if applicable
- Keep descriptions concise and technical.
- Do NOT exceed 50 words for the function summary.


27 changes: 23 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ CFLAGS ?=
CFLAGS += -Wno-address-of-packed-member -DVERSION_STRING="\"$(VERSION_STRING)\""

SRCS := compat.c msposd.c bmp/bitmap.c bmp/region.c bmp/lib/schrift.c bmp/text.c osd/net/network.c osd/msp/msp.c osd/msp/msp_displayport.c libpng/lodepng.c osd/util/interface.c osd/util/settings.c osd/util/ini_parser.c osd/msp/vtxmenu.c osd/util/subtitle.c osd/util/simple_ini.c
GS_SRCS := osd/util/terrain_elevation.c osd/util/terrain_agl.c
OUTPUT ?= $(PWD)
BUILD = $(CC) $(SRCS) -I $(SDK)/include -I$(TOOLCHAIN)/usr/include -I$(PWD) -L$(DRV) $(CFLAGS) $(LIB) -levent_core -Os -s $(CFLAGS) -o $(OUTPUT)

Expand Down Expand Up @@ -60,13 +61,31 @@ star6e: version.h
native: version.h
$(eval SDK = ./sdk/gk7205v300)
$(eval CFLAGS += -D_x86)
$(eval LIB = -lcsfml-graphics -lcsfml-window -lcsfml-system `pkg-config --libs cairo x11 xext` -lXext -lm)
$(eval BUILD = $(CC) $(SRCS) -I $(SDK)/include -L $(DRV) $(CFLAGS) $(LIB) -levent_core -O0 -g -o $(OUTPUT))
$(eval LIB = -lcsfml-graphics -lcsfml-window -lcsfml-system `pkg-config --libs cairo x11 xext` -lXext -lm -lsqlite3)
$(eval BUILD = $(CC) $(SRCS) $(GS_SRCS) -I $(SDK)/include -L $(DRV) $(CFLAGS) $(LIB) -levent_core -O0 -g -o $(OUTPUT))
$(BUILD)

rockchip: version.h
$(eval SDK = ./sdk/gk7205v300)
$(eval CFLAGS += -D__ROCKCHIP__)
$(eval LIB = `pkg-config --libs cairo x11 xext` -lXext -lm -lrt)
$(eval BUILD = $(CC) $(SRCS) -I $(SDK)/include -L $(DRV) $(CFLAGS) $(LIB) -levent_core -O0 -g -o $(OUTPUT))
$(eval LIB = `pkg-config --libs cairo x11 xext` -lXext -lm -lrt -lsqlite3)
$(eval BUILD = $(CC) $(SRCS) $(GS_SRCS) -I $(SDK)/include -L $(DRV) $(CFLAGS) $(LIB) -levent_core -O0 -g -o $(OUTPUT))
$(BUILD)

test-terrain-elevation:
$(CC) tests/terrain_elevation_test.c osd/util/terrain_elevation.c -I$(PWD) \
-DTERRAIN_ELEVATION_DB_PATH='"/tmp/msposd-terrain-elevation-test.db"' \
-Wall -Wextra -Werror -O1 -g -fsanitize=address,undefined -fno-omit-frame-pointer -no-pie \
-o /tmp/msposd-terrain-elevation-test -lsqlite3 -lm
ASAN_OPTIONS=detect_leaks=0:abort_on_error=1:handle_segv=0 \
/tmp/msposd-terrain-elevation-test

test-terrain-agl:
$(CC) tests/terrain_agl_test.c osd/util/terrain_agl.c osd/util/terrain_elevation.c \
-I$(PWD) -DTERRAIN_ELEVATION_DB_PATH='"/tmp/msposd-terrain-agl-test.db"' \
-Wall -Wextra -Werror -O1 -g -fsanitize=address,undefined -fno-omit-frame-pointer -no-pie \
-o /tmp/msposd-terrain-agl-test -lsqlite3 -lm
ASAN_OPTIONS=detect_leaks=0:abort_on_error=1:handle_segv=0 \
/tmp/msposd-terrain-agl-test

test-terrain: test-terrain-elevation test-terrain-agl
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ This keywords can be added using the PilotName/CraftName fields(INAV/BF/Ardu), o
- ```!TMP!``` Camera board temp
- ```!TMW!``` WiFi module temperature (only 8812EU2/8733BU chipsets supported)
- ```!RC!``` Sticks Position widget (Ground Side only)
- ```!AGL!``` GPS-calibrated height above terrain in metres (Ground Side only);
displays ```----m``` while unavailable

### Usage Example:

Expand Down
2 changes: 1 addition & 1 deletion build_rockchip.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ if [ ! -f $output/tmp/prepare_chroot.done ]; then
echo 'deb [signed-by=/usr/share/keyrings/radxa-archive-keyring.gpg] https://radxa-repo.github.io/bullseye rockchip-bullseye main' > /etc/apt/sources.list.d/80-rockchip.list

apt-get update
apt-get install -y git gcc make pkg-config libspdlog-dev libevent-dev libcairo-dev
apt-get install -y git gcc make pkg-config libspdlog-dev libevent-dev libcairo-dev libsqlite3-dev
apt clean
touch /tmp/prepare_chroot.done
EOL
Expand Down
84 changes: 84 additions & 0 deletions documentation/build-preflight-release.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Build a release package — preflight map

How to package the preflight map (`map.sh preflight` / `gs/mapserver.py`) into a **single
self-contained binary per OS** that end users run without installing Python. It starts a
local server and opens the map in the user's **default browser** (no Python/WebKit to
install). Writable `config.ini`, `state.ini` and `maps/` are created next to the
executable on first run. Map tiles, shared landmarks and shared elevation data live
inside `maps/`.

## Prerequisites
- Python **3.9+** and `pip` on the build machine (`pyinstaller` is installed automatically).
- Build **on each target OS** — a Windows `.exe` needs Windows, a macOS build needs a Mac.

PyInstaller bundles a bootloader for the host OS; it does not cross-compile. Running
`build.sh` on Linux or WSL produces a Linux ELF executable. Copying or renaming that
file to `.exe` will produce Windows' “not a valid app” error. Use native Windows with
`build.bat`, or use the Windows artifact from CI.

## Build (current OS)
```bash
./gs/pack/build.sh # Linux / macOS
gs\pack\build.bat # Windows
```
Output: **`dist/msposd-preflight`** (`.exe` on Windows) — one file.

On Linux, verify the artifact type before publishing it:

```bash
file dist/msposd-preflight
# ... ELF 64-bit ...
```

## Build all three OSes at once (CI)
The `.github/workflows/preflight-pack.yml` matrix builds Linux/macOS/Windows. Trigger it:
- **Manually:** GitHub → Actions → *preflight-pack* → *Run workflow*, or
- **By tag:** push a tag matching `preflight-v*`, e.g.
```bash
git tag preflight-v1.0 && git push origin preflight-v1.0
```
Download the three binaries from the run's **Artifacts**.

## Run / verify
```bash
./dist/msposd-preflight # starts server, opens the browser
./dist/msposd-preflight --port 9000 # custom port
./dist/msposd-preflight --no-browser # server only
```
Ctrl+C (or closing the console) stops it.

## Install elsewhere on Linux

No installation step is required. The binary can be copied to another writable folder
on the same Linux system:

```bash
mkdir -p ~/Apps/msposd-preflight
cp dist/msposd-preflight ~/Apps/msposd-preflight/
chmod +x ~/Apps/msposd-preflight/msposd-preflight
~/Apps/msposd-preflight/msposd-preflight
```

Its new containing directory becomes the writable application directory. Copy the old
`config.ini`, `state.ini` and `maps/` into that directory to preserve settings, map
packs, landmarks and elevation data. Otherwise it starts with defaults and creates data
as needed. Only one server can own the default HTTP port; stop the old copy or start the
new one with `--port 9000`.

## Ship it
Give users the single binary. On first run it creates its data folder alongside itself;
each area download creates a new `maps/<pack>.mbtiles` without modifying older packs.
Select the desired entry under **Downloaded maps**, then use **Export selected map…** to
create a zip containing that pack plus `landmarks.db` and `elevation.db` for the
OSD/flight station.

## Notes
- **Unsigned binaries** trip macOS Gatekeeper / Windows SmartScreen — code-sign (and
notarize on macOS) for public release; fine as-is for internal use.
- Some Windows AV engines false-positive on PyInstaller one-file builds.
- For distribution across different Linux releases, build on an appropriately old
compatible Linux baseline; copying within the build machine itself is safe.
- The dev launcher opens preflight in the system browser by default. Use
`./map.sh preflight --GTK` for the compatibility WebKit `mapwin` window.

See [`../gs/pack/README.md`](../gs/pack/README.md) for how the packaging works internally.
Loading
Loading