Skip to content

Configuration

Judah Paul edited this page Jul 15, 2026 · 11 revisions

Configuration

The app reads its configuration from environment variables. A single template at the repo root, .env.example, holds both these application variables and the Docker Compose host-port and service variables; the app reads its half from the root .env through the compose env_file.

Variable Default Purpose
DATABASE_PATH ./src/data.db Path to the SQLite database file. The schema is created on first boot, so the path only needs to be writable. In the production image this is /app/src/data.db.
OPENAIP_API_KEY unset OpenAIP key for worldwide airspace overlays and no-fly-zone safety checks. Server-side only. When unset, /api/airspace falls back to the FAA's keyless public layers (US coverage); see Mission Planning.
VITE_ALTITUDE_ANGEL_API_KEY unset Key for the Altitude Angel airspace endpoint.
AI_API_KEY unset Key for the AI PID tuning assistant. Also settable in Integrations.
AI_BASE_URL https://api.openai.com/v1 Base URL of the OpenAI-compatible endpoint the AI assistant calls (a LiteLLM proxy or a local Ollama works).
AI_MODEL gpt-4o-mini Model the AI assistant requests.
MAVLINK_SIGNING_KEY unset Passphrase for MAVLink 2 signing. Also settable in Integrations. When set, the link signs outbound and verifies inbound messages.
NODE_ENV set by compose production uses the serial link at /dev/ttyACM0; development uses the SITL TCP link.

Airspace data

The server route /api/airspace supplies both the map overlay and the pre-flight airspace checks. It reads two providers:

  • OpenAIP (worldwide) when OPENAIP_API_KEY is set. Create a free account at openaip.net, generate an API key, and set the variable. The key is read only on the server, so it never reaches the browser.
  • FAA public airspace layers (US) as a keyless fallback when the key is unset or OpenAIP returns nothing. No account or key is required.

See Mission Planning for how the zones drive the overlay and the pre-flight checks.

Map tiles

The 2D map picks its basemap per view from settings resolved by /api/map-config. A MapTiler API key (Integrations, or MAPTILER_KEY) selects MapTiler's rich dark basemap and a labeled hybrid satellite; without a key the map falls back to OpenStreetMap, CARTO Dark Matter, and Google hybrid. Each mode (light, dark, satellite) accepts a custom XYZ tile URL override, chosen from a preset dropdown of free sources or typed in. The map swaps between the light and dark basemap when the theme toggles, and satellite is the default view.

MAVLink signing

MAVLink 2 signing authenticates the vehicle link with a shared passphrase, set in Integrations (or MAVLINK_SIGNING_KEY). The passphrase is hashed to a 32-byte key with SHA-256, the same derivation QGroundControl and Mission Planner use, so the identical passphrase configured on the autopilot authenticates the link. Every outbound message is signed with a strictly increasing timestamp, and inbound signed messages are verified: one that fails is dropped and never counts as link traffic, so a wrong key surfaces as a down link. Strict mode (a toggle in Integrations) additionally drops unsigned inbound messages, which enforces signing once the autopilot is configured for it.

Signing is authentication and integrity, not encryption. Telemetry still travels in cleartext, so pair it with a transport tunnel (VPN or TLS) for confidentiality. Set the same passphrase on the autopilot through its own MAVLink signing setup. This matters most when the link is reachable over the public internet, as it is on a public-IP cellular SIM (see Build).

AI PID tuning assistant

The vehicle parameters page can ask an OpenAI-compatible chat endpoint to review the PID gains. Configure the endpoint in Integrations (or AI_API_KEY, AI_BASE_URL, AI_MODEL): OpenAI, a LiteLLM proxy, or a local Ollama all speak the same wire format. The AI PID Tune button sends the current rate and attitude gains plus the latest vibration and attitude telemetry to /api/ai/pid-tune, which returns gain suggestions that apply one at a time or all at once. Without a key the endpoint returns a clear message and makes no request.

Clone this wiki locally