Files
dmc/DMC_Architektur_und_Design.md
T

27 KiB
Raw Blame History

Drone Mission Control (DMC) — Architektur- und Design-Dokumentation

Zusammenfassung aller bisher in diesem Projekt getroffenen Architektur- und Design-Entscheidungen: vom HTML/JS-Demonstrator ("Drone Mission Command.html") bis zur geplanten Flutter-Zielarchitektur.


1. Projektüberblick

Ziel: Mobile App zur Missionsplanung und Flugsteuerung für einen Fixed-Wing-Drohnen-Aufbau (Heewing T1 Ranger, iNAV-Firmware), mit Fokus auf Wegpunkt-Missionen, Live-Fly-Modus und Point-and-Fly (PnF)-Einzelziel-Anflug.

Zwei Entwicklungsstränge:

  1. HTML/JS-Demonstrator (Drone Mission Command.html, vormals taf_mission_planner_osm_v13.html) — iteratives Rapid-Prototyping zur Validierung von Workflow und Feature-Umfang, lauffähig im Browser.
  2. Flutter-Zielarchitektur — die für die produktive App geplante Struktur, die den Demonstrator ablösen soll.

Sprachregelung: Konversation und Dokumentation auf Deutsch, Code und UI-Texte auf Englisch.


2. Systemarchitektur (Flutter-Zielarchitektur)

Fünf-Schichten-Architektur, gemeinsam festgelegt:

┌─────────────────────────────────────────────┐
│  UI Layer (Screens: Plan / Fly / Settings /  │
│  Library)                                    │
├─────────────────────────────────────────────┤
│  App-Mode State Machine                      │
│  (Plan → Connect → Upload → Fly)             │
├─────────────────────────────────────────────┤
│  Mission Domain Layer                        │
│  (Strategy Pattern: TrackMission,             │
│  SurveyAreaMission*, SearchAreaMission*)      │
├─────────────────────────────────────────────┤
│  Mission-Sync Service  │  Telemetry Service   │
├─────────────────────────────────────────────┤
│  Transport / Protokoll-Layer                 │
│  (FlightControllerLink-Abstraktion)          │
└─────────────────────────────────────────────┘

* geplant, noch nicht implementiert

2.1 Kernprinzip: Protokoll-Abstraktion

Ein einheitliches Interface FlightControllerLink kapselt die Kommunikation mit dem Flightcontroller, unabhängig davon, ob iNAV (via MSP) oder ArduPilot (via MAVLink) angesprochen wird. Die Mission-Domain-Schicht kennt nur eine protokollneutrale FlatWaypointList; die Divergenz zu MSP bzw. MAVLink findet ausschließlich im letzten Schritt (Encoder) statt.

2.2 App-Mode State Machine

Explizite Zustandsfolge: Plan → Connect → Upload → Fly, inkl. definiertem "Ready-to-Fly"-Gate:

Mission hochgeladen und verifiziert und Drohne noch disarmed.

Grund: iNAV (und MAVLink bei iNAV) akzeptiert MSP_SET_WP-Uploads grundsätzlich nur im unarmed-Zustand. Der Handover-Prozess (Connect → Verify → Upload → Ready-to-Fly) muss dieses Gate technisch erzwingen, nicht nur als UI-Konvention behandeln.


3. Komponenten

Zentrale Abstraktion für alle FC-Interaktionen.

Methoden/Properties:

  • connect(), disconnect()
  • capabilities → FcCapabilities-Struct (Feature-Flags: supportsMultiMission, supportsInFlightUpload, maxWaypoints, …)
  • uploadMission(FlatWaypointList)
  • setFlightMode(mode) — abstrakte Modus-Konstanten: MISSION_RUN, GUIDED_POINT, RETURN_HOME, HOLD
  • arm()
  • subscribeTelemetry()
  • readActiveWaypointIndex()

Implementierungen:

  • MspFlightControllerLink — für iNAV, eigenständiger MSP-Adapter (kein fertiges Dart-Paket verfügbar, komplett selbst implementiert)
  • MavlinkFlightControllerLink — für ArduPilot (perspektivisch, nicht MVP)
  • MockFlightControllerLink — synthetische Telemetrie für Tests ohne Hardware/SITL

3.2 Mission Domain Layer

Strategy-Pattern für erweiterbare Missionstypen:

  • TrackMission — aktuell implementiert (Wegpunkt-Strecke)
  • SurveyAreaMission — geplant (Flächenabflug)
  • SearchAreaMission — geplant (Suchmuster)

Gemeinsame Datenstruktur: FlatWaypointList (protokollunabhängig), am Ende protokollspezifisch codiert durch:

  • MspWaypointEncoder (iNAV)
  • MavlinkMissionEncoder (ArduPilot)

3.3 Mission-Sync Service

Orchestriert den Ablauf Connect → Verify → Upload → Ready-to-Fly. Erzwingt das Ready-to-Fly-Gate.

3.4 Telemetry Service

Abonniert Live-Telemetrie vom FC, liefert normalisierte TelemetryFrame-Objekte an die UI. Läuft in einem eigenen Isolate, um Kartenrendering nicht zu blockieren.

3.5 Drohnen-Profil (Settings)

Enthält u. a.:

  • FC-Typ — bewusst als explizites Setting im Drohnen-Profil verankert, nicht aus dem Transportkanal abgeleitet (siehe Abschnitt 4.3)
  • Flugleistungsdaten: min/max Speed, min. Kurvenradius, max. Steig-/Sinkrate, max. Reichweite, max. Flugdauer, Cruise Speed
  • Standardprofil: T1 Ranger (Heewing)
  • Liste mehrerer Profile, aufrufbar über Tap, Teil des Vollbild-Menüs (gemeinsam mit Missionsübersicht, per Tabs umschaltbar)

3.6 Waypoint-Liste (UI-Komponente)

  • Spalten: Execute (Dropdown: —/Loiter/Landing) und Action
  • Swipe-adjustierbare Wertechips für Alt/Speed/Catch-Radius (vertikal ±10, horizontal ±1, 14px/Step, Achsen-Lock bei 8px)
  • Zeilen-Edit-Modus bewusst entkoppelt vom Karten-Edit-Modus (siehe Abschnitt 4.4)
  • Zeile antippen → Karte zentriert auf diesen Wegpunkt, Liste schließt sich
  • Liste zeigt englische Spaltenüberschriften, ausreichend Randabstand zu den Drehrädern
  • Automatisches Beenden des Zeilen-Edit-Modus beim Schließen der Liste (Sicherung gegen inkonsistenten Zustand)

3.7 Flugpfad-Darstellung

  • Kein einfacher Spline durch alle Punkte, sondern physikalisch fundierte Geometrie: Geradenstücke + tangentiale Kreisbögen (Fillets) pro Kursänderung, abgeleitet aus Geschwindigkeit + max. Schräglage (25°)
  • Machbarkeitsprüfung kombiniert Tangentenlänge der Kurve mit dem Fangradius (60 m): überschreitet die Tangentenlänge den Fangradius, wird der Turn rot markiert
  • Höhenprofil-Anzeige in der unteren Leiste

3.8 Wind-System

  • buildCombinedWindLevels() — vereint Druckflächendaten und feste Nabenhöhen (10/80/120/180 m AGL, in ASL umgerechnet) als Stützpunkte für Interpolation
  • windUrlsFor() — baut zwei getrennte, fokussierte Open-Meteo-Requests
  • Alle drei Konsumenten (Header, Waypoints, Validierungspanel) nutzen denselben Mechanismus
  • Böen (wind_gusts_10m) nur im Validierungspanel, nicht in der Wegpunktanzeige

3.9 Terrain-System

  • Distanzbasierte Sampling-Strategie: alle 30 m (TERRAIN_SAMPLE_SPACING), min. 10 / max. 2000 Samples (TERRAIN_MAX_SAMPLES)
  • Einzelpunkt-Höhenabfrage (fetchElevationAt) für Point-and-Fly-Kollisionsprüfung
  • Datenquelle: AWS Terrarium Tiles

3.10 Point-and-Fly (PnF) Modus

  • Zentrales Fadenkreuz (amber) auf dem Bildschirm
  • Setzt transienten Einzel-Wegpunkt (Loiter-Aktion) mit aktuellen Radwerten für Alt/Speed
  • Terrain-Kollisionsprüfung: mind. 60 m Bodenabstand, referenziert gegen Home-Wegpunkt-Höhe
  • Zielpunkt übernimmt beim Setzen die zu diesem Zeitpunkt gültigen Radwerte dauerhaft (ändert sich nicht rückwirkend)
  • Zielpunkt verschwindet beim Moduswechsel oder Verlassen des Fly-Modus
  • Zentrale Sichtbarkeitslogik über ein gemeinsames Prädikat (Räder, Fadenkreuz, Readouts konsistent)

3.11 Fly-Modus allgemein

  • setFlightMode() zentralisiert
  • Eintritt in Fly-Modus setzt immer auf Standardmodus Waypoint zurück
  • Verlassen des Fly-Modus klappt Dropdown automatisch ein
  • Readouts: drei Zeilen (Titel, SET in Blau, LIVE in Grün)
  • M-/D-/C-Monogramm-Konstruktion (Drone Mission Command)
  • Finale Lösung: vertikal gespiegeltes "C" mit kurzem vertikalem Schließstrich statt verjüngtem "D" — mathematisch als Sonderfall derselben Tangentenkonstruktion bestätigt (Stammlänge 75,2 Einheiten, 92,4 % bilaterale Symmetrie)

4. Getroffene Design-Entscheidungen inkl. Begründung

# Entscheidung Begründung
4.1 MVP-Scope: nur Android, nur iNAV via MSP, nur WiFi/TCP Reduziert Komplexität für ersten Release; MAVLink, USB-Seriell und iOS werden bewusst zurückgestellt
4.2 MSP für iNAV, MAVLink für ArduPilot, beide hinter FlightControllerLink Jedes Protokoll spricht die native Sprache seines FC; einheitliche Domain-Schicht bleibt protokollunabhängig
4.3 FC-Typ als explizites Setting im Drohnen-Profil, nicht aus Transport abgeleitet Zukunftssicher: falls iNAV später testweise über MAVLink läuft, bleibt Zuordnung eindeutig steuerbar
4.4 Zeilen-Edit-Modus der Wegpunktliste von Karten-Edit-Modus entkoppelt Nutzer-Feedback: gekoppeltes Verhalten war unerwartet/unerwünscht — Bearbeiten in der Liste soll nicht automatisch den Karten-Modus verändern
4.5 "Ready-to-Fly"-Gate = Upload + Verifiziert + Disarmed iNAV/MAVLink erlauben grundsätzlich keinen Missions-Upload im armed-Zustand; das Gate muss dies technisch erzwingen
4.6 Physikalisch fundierter Flugpfad (Geraden + Kreisbögen) statt Spline Ehrlichere Darstellung dessen, was ein realer Autopilot (ArduPlane/iNAV) tatsächlich fliegt; verhindert falsches Sicherheitsgefühl bei engen Kurven
4.7 Tangentenkonstruktion statt frei gezogener Linien beim Logo Vermeidet sichtbaren Knick zwischen Gerade und Bogen; mathematisch konsistent mit der ursprünglichen D-Form
4.8 Gespiegeltes C statt verjüngtem D als Logo-Grundform Wirkt symmetrischer, ist aber dieselbe Konstruktion nur gespiegelt und geschlossen
4.9 Böen nur im Validierungspanel, nicht in der Wegpunktanzeige 10-m-Böendaten sind auf Flughöhe nicht aussagekräftig
4.10 Zwei getrennte Open-Meteo-Requests statt einem kombinierten Ein kombinierter 35-Variablen-Request verursachte Modellauswahl-Fehler; auch ein einzelner Request für die Validierung schlug fehl — zwei fokussierte Requests bestätigt als robustes Muster
4.11 typeof x === 'number'-Guards überall im Wind-Code Open-Meteo liefert bei fehlenden Werten null, nicht undefined — ungeschützter Code führte zu drei aufeinanderfolgenden Rendering-Fehlern
4.12 Distanzbasiertes statt festes Terrain-Sampling (30 m Spacing) Gleichmäßigere Auflösung unabhängig von der Missionslänge, mit sinnvollen Ober-/Untergrenzen (10–2000 Samples)
4.13 Fester Dateiname "Drone Mission Command.html" Bewusst beibehalten, um localStorage-Daten über Updates hinweg zu erhalten
4.14 Klettersteigungsprüfung nutzt geradlinige statt Bogen-Distanz Bewusste Vereinfachung; als vernachlässigbar bewertet, aber offen dokumentiert (siehe Abschnitt 6)
4.15 Drift statt Hive für Missions-Persistenz (Flutter-Ziel) Indexierte Abfragen nötig (Suche nach Name, Ort, Datum); zudem kompatibel mit künftigem local-first Server-Sync-Muster (Dirty-Flags, Server-IDs)
4.16 Bloc/Riverpod-Kombination für State-Management (Flutter-Ziel) Bloc passt zur expliziten App-Mode-State-Machine (erzwungene Event→State-Struktur, Debug-Tooling); Riverpod ist ergonomischer für viele kleine reaktive Zustände wie Telemetriewerte
4.17 flutter_map statt google_maps_flutter (Flutter-Ziel) Freies OSM-Tile-Modell entspricht dem Leaflet-Demonstrator; anderes Lizenz-/API-Modell bei Google Maps unerwünscht; ermöglicht direkte Portierung der Tangenten-Bogen-Geometrie
4.18 flutter_map_tile_caching (FMTC) für Offline-Kacheln (Flutter-Ziel) Automatisches Caching pro Mission, gekeyt über die Bounding-Box der Mission
4.19 Eigener MSP-Encoder/Decoder in Dart (Flutter-Ziel) Kein fertiges Dart-Paket verfügbar; Struktur bereits aus MSP-Recherche bekannt
4.20 Foreground Service (Android) für Telemetrie im Hintergrund (Flutter-Ziel) Ohne Foreground Service + Wake Lock würde Android die Verbindung bei App-Wechsel/Display-Sperre kappen
4.21 Protokoll-Parsing in eigenem Isolate (Flutter-Ziel) Verhindert UI-Ruckeln bei hoher Telemetrie-Rate; Isolates kommunizieren nur über Message-Passing, kein Shared Memory
4.22 Mission-Domain-Layer + Protokoll-Adapter als eigenständiges reines Dart-Package (Flutter-Ziel) Isoliert unit-testbar ohne Emulator; wiederverwendbar für z. B. CLI-Tools oder Backend-Simulatoren
4.23 go_router für Navigation (Flutter-Ziel) Typisierte Übergänge, passend zum expliziten Mode-Wechsel-Trigger der State-Machine
4.24 SSID-Anzeige in den Settings aufgegeben, Verbindungspille zeigt nur generisches "Connected" Auf echter Hardware (Pixel-Gerät, Android 16) liefert NetworkCapabilities.getTransportInfo() konsequent ein redigiertes WifiInfo (SSID <unknown ssid>, BSSID maskiert) — bestätigt per natives Log.d in MlrsNetworkPlugin.onAvailable()/onCapabilitiesChanged(), gegengeprüft mit adb shell dumpsys wifi (Shell-Kontext kennt und ordnet die echte SSID korrekt der App zu, das App-API liefert sie aber nicht). Die im Code angenommene "Ausnahme für selbst angefragte WifiNetworkSpecifier-Netze ohne ACCESS_FINE_LOCATION" gilt offenbar nur für WifiManager.getConnectionInfo(), nicht für diesen NetworkCapabilities-Weg über ConnectivityManager.NetworkCallback. Statt ACCESS_FINE_LOCATION (inkl. Laufzeit-Prompt) nur für diese kosmetische Anzeige hinzuzufügen, hat der Nutzer sich bewusst dagegen entschieden — die zugrundeliegende SSID-Merk-Logik (UdpTransport.connectedSsid/_rememberSsid, preferredSsid für stilles Reconnect) bleibt bestehen, liefert im Regelfall aber null/keinen Effekt
4.25 Homepoint-Abfrage (MSP_WP/0x76, WP#0) gezielt statt kontinuierlich, nur bei Connect/GPS-Fix/Armen getWaypoint() in navigation.c liefert für WP#0 den Homepoint (GPS_home.lat/lon/alt), aber (0,0,0) statt eines Fehlers, solange STATE(GPS_FIX_HOME) nicht gesetzt ist — als "kein Homepoint" behandelt (parseMspHomePoint). Der FC selbst friert den Homepoint nicht beim ersten GPS-Fix ein, sondern lässt ihn der Drohne folgen, solange sie disarmed ist und noch nie armed war (updateHomePosition()), und sperrt ihn erst beim ersten Armen (iNAV-Default reset_home_type = FIRST_ARM, settings.yaml) — kontinuierliches Polling wäre also die meiste Zeit sinnlos; home_point_provider.dart fragt stattdessen gezielt bei genau diesen drei Momenten neu ab

5. Verworfene Alternativen

Verworfene Option Warum nicht gewählt
Spline/Glättungskurve durch alle Wegpunkte Suggeriert unrealistische Kurvenradien; ersetzt durch Geraden+Kreisbögen-Modell (4.6)
Freie Linienführung beim Logo (statt Tangentenkonstruktion) Hätte sichtbaren Knick zwischen Gerade und Bogen erzeugt
Verjüngtes "D" als finale Logoform Wirkte weniger symmetrisch als gespiegeltes/geschlossenes "C" (Farbschwerpunkt-Analyse: −27,2 → −22,7 Einheiten Verbesserung)
Kombinierter 35-Variablen-Wetter-Request Verursachte Modellauswahl-Fehler bei Open-Meteo
Einzelner Request für das Wind-Validierungspanel Ebenfalls fehlgeschlagen; bestätigte die Notwendigkeit des Zwei-Request-Musters
Gekoppelter Zeilen-/Karten-Edit-Modus Erste Implementierung koppelte beide Modi; nach Nutzer-Feedback explizit wieder entkoppelt
Böen-Anzeige auch in der Wegpunktliste Als nicht aussagekräftig auf Flughöhe verworfen, in Validierungspanel belassen
dart_mavlink-Community-Paket unkritisch übernehmen Nicht offiziell gelistet, wirkt wenig gepflegt — Alternative (eigener Generator aus MAVLink-XML) als Option offengehalten, aber noch nicht entschieden
Feste Anzahl Terrain-Samples (z. B. 50) Ungleichmäßige Auflösung je nach Missionslänge; durch distanzbasiertes Sampling ersetzt
USB-Seriell als Transportkanal (aktuell) Auf iOS ohne MFi-Zertifizierung praktisch nicht machbar; für aktuellen WiFi-Bridge-Plan nicht kritisch, aber als Plattformrisiko vermerkt, falls später gewünscht
Auto-Erkennung des FC-Typs aus der Transportverbindung Weniger robust/eindeutig als explizites Profil-Setting (4.3)
Hive für Missions-Persistenz (ursprünglich vorgeschlagen) Ausreichend für aktuellen Funktionsumfang, aber keine indexierten Abfragen — zugunsten von Drift verworfen, sobald Suche/Sync-Anforderungen klar wurden

6. Offene Fragen / TODOs

  • Klettersteigungsprüfung gegen tatsächliche Bogenlänge statt Geradenverbindung berechnen — aktuell bewusste Vereinfachung, könnte bei engen Kombinationen aus Höhenänderung und scharfer Kurve leicht zu optimistisch sein.
  • iNAV-10-Änderungen an Mission-/Wegpunktsystem — zum Recherchezeitpunkt keine bestätigten grundlegenden Änderungen gegenüber v9 gefunden; Release-Termin (evtl. Ende 2026) und Feature-Freeze noch offen, vor App-Release erneut prüfen.
  • Experimenteller iNAV-Community-Branch für Wegpunkt-Upload im Flug (bei nicht aktivem NAV-WP-Modus) — Status unklar, ob in einen stabilen Release gewandert; vor Release gegen aktuelle 9.x-Firmware verifizieren, nicht darauf verlassen.
  • MSP2_INAV_WIND (0x2231) für geschätzte Windstärke/-richtung im Drone Status — vom iNAV-Windschätzer (flight/wind_estimator.c, GPS-basiert, kein Pitot nötig) berechnet, aber bis 9.1.0 nur ins OSD gerendert, nicht per MSP abrufbar. Command wurde erst kürzlich auf dem Branch release/9.1 hinzugefügt (Commit "feat(msp): add MSP2_INAV_WIND (0x2231) to expose wind estimator", Bugfix in PR iNavFlight/inav#11762, gemerged 2026-08-03) — bislang in keinem getaggten Release (weder 9.1.0 noch master) enthalten, T1 Ranger müsste also erst auf eine Firmware ab diesem Commit geflasht werden. Response-Payload laut fc_msp.c: u16 windSpeed (cm/s, horizontal), u16 windAngle (Grad, 0–359, Earth-Frame), u8 windFlags (1 = Schätzung gültig). Vor Umsetzung erneut prüfen, ob der Command in einem stabilen Release gelandet ist.
  • MSP2_INAV_GEOZONE/_SET_GEOZONE + _GEOZONE_VERTEX/_SET_GEOZONE_VERTEX (0x2210–0x2213) für Geofencing — bisher ungenutzt, aber vermutlich das interessanteste noch nicht angebundene MSP-Feature für DMC. Indexbasiert abgefragt (mspFcGeozoneOutCommand/mspFcGeozoneVerteciesOutCommand in fc_msp.c): pro Zone (Request-Byte = Zonenindex) u8 type (Inclusion/Exclusion), u8 shape (Kreis/Polygon), u32 minAltitude, u32 maxAltitude, u8 isSealevelRef, u8 fenceAction (NONE/AVOID/POS_HOLD/RTH, siehe settings.yaml Table fence_action), u8 vertexCount; Vertices einzeln per (zoneId, vertexId) nachladbar (u32 lat, u32 lon, bei Kreisform zusätzlich ein Radius-Vertex). Könnte analog zur bestehenden Flugpfad-Machbarkeitsprüfung (domain/mission/mission_warnings.dart) als Warnung genutzt werden, wenn eine geplante Route eine auf der Drohne konfigurierte No-Fly-Zone kreuzt.
  • MSP2_INAV_SAFEHOME/_SET_SAFEHOME (0x2038/0x2039) für alternative RTH-Landepunkte — bisher ungenutzt. Indexbasiert (ein Request pro Slot, bis MAX_SAFE_HOMES): u8 enabled, u32 lat, u32 lon. Könnte eine "Backup-Landepunkte verwalten"-Ansicht ermöglichen, eigener UI-Scope (Liste/Editor), nicht MVP-kritisch.
  • MSP2_INAV_BATTERY_CONFIG (0x2005, alternativ als Teilmenge von MSPV2_INAV_MISC/0x2003) für die auf dem FC hinterlegte Batteriekonfiguration — bisher ungenutzt. Liefert u8 cells sowie u16 cellDetect/cellMin/cellMax/cellWarning (je 0.01V/Zelle, fc_msp.c case MSP2_INAV_BATTERY_CONFIG, Felder verifiziert gegen settings.yaml: vbat_cell_detect_voltage/vbat_max_cell_voltage/vbat_min_cell_voltage/vbat_warning_cell_voltage). Könnte künftig DroneProfile.batteryCellCount/die Pro-Zelle-Schwellwerte mit der tatsächlichen FC-Konfiguration abgleichen oder daraus vorbefüllen, statt sie nur manuell im Profil-Editor zu pflegen.
  • MSPV2_INAV_AIR_SPEED (0x2009) für echte Fahrt durch die Luft (Pitot) — liefert u32 getAirspeedEstimate(), ohne USE_PITOT-Sensor konstant 0. Für den T1 Ranger aktuell nicht relevant (kein Pitot-Rohr vorgesehen); bei künftigem Pitot-Ausbau erneut prüfen.
  • MSP2_INAV_TEMPERATURES (0x201E) für Temperatursensor-Werte — Array von bis zu MAX_TEMP_SENSORS i16-Werten (-1000 = ungültig), braucht konfigurierte Temp-Sensoren (USE_TEMPERATURE_SENSOR). Im aktuellen T1-Ranger-Aufbau keine physischen Temp-Sensoren vorgesehen, daher niedrige Priorität.
  • Bit-Layout von sensorStatus/armingFlags/boxModeFlags (Teil der bereits genutzten MSP2_INAV_STATUS, 0x2000) — vollständig dokumentiert direkt im Code, siehe Doc-Kommentare zu MspCommands.inavStatus und MspArmingFlags in msp_commands.dart, um Drift zwischen Architektur-Doku und Code zu vermeiden. Insbesondere boxModeFlags ist dort ausführlich erklärt: die Bit-Position ist NICHT fest, sondern muss einmalig über MSP_BOXIDS (ID 119) mit der jeweiligen Firmware-Konfiguration korreliert werden.
  • dart_mavlink-Paket vs. eigener Generator aus MAVLink-XML-Dialektdateien — Entscheidung für die MAVLink-Anbindung (nicht MVP-kritisch, aber für spätere ArduPilot-Unterstützung relevant) noch offen.
  • XR1-Empfänger-Kompatibilität mit mLRS — XR4 ist vom mLRS-Team offiziell validiert, XR1 nur wahrscheinlich kompatibel (über generisches Firmware-Target), nicht bestätigt.
  • iOS-Hintergrundverbindung — Konzept (Background Modes / "voip"/"location"-Capability) benannt, aber nicht MVP-relevant (MVP ist Android-only) und nicht im Detail ausgearbeitet.
  • USB-Seriell als späterer Fallback-Transportkanal — Plattformrisiko (iOS ohne MFi quasi unmöglich) früh klären, falls dies später doch gewünscht wird.
  • Melos-Monorepo vs. Einzelpaket-Struktur — konkreter Ordner-/Package-Vorschlag für das Flutter-Projekt wurde als nächster Schritt vorgeschlagen, aber noch nicht ausgearbeitet.
  • SurveyAreaMission und SearchAreaMission — als Missionstypen im Strategy-Pattern vorgesehen, aber inhaltlich noch nicht spezifiziert oder implementiert.
  • Winkelannahmen der Flugpfad-Machbarkeitsprüfung (25° Schräglage, 20° Steigwinkel) — zur Diskussion gestellt, ob diese Werte angepasst werden sollen; keine endgültige Entscheidung dokumentiert.
  • Migration vom HTML-Demonstrator zur Flutter-App — Reihenfolge/Umfang der Portierung (z. B. wann welches Feature 1:1 übernommen wird) ist nicht Schritt-für-Schritt festgelegt.

7. Umfangreiche Feature-Liste

7.1 Missionsplanung

  • Wegpunkt-Missionen (Track-Missionen) auf OSM-Kartenbasis (Leaflet.js im Demonstrator)
  • Wegpunkt hinzufügen/verschieben/löschen direkt auf der Karte
  • Wegpunktliste mit swipe-adjustierbaren Werten für Höhe, Geschwindigkeit, Fangradius (Catch-Radius)
  • Execute-Aktion pro Wegpunkt: —, Loiter, Landing
  • Zeilen-Edit-Modus unabhängig vom Karten-Edit-Modus
  • Tippen auf Listenzeile zentriert Karte auf diesen Wegpunkt
  • Automatisches Schließen des Edit-Modus beim Schließen der Liste
  • Höhenprofil-Anzeige der gesamten Wegpunktliste in der unteren Leiste
  • Physikalisch realistische Flugpfad-Darstellung (Geraden + Kreisbögen statt Spline)
  • Farbliche Markierung nicht machbarer Kurven (Tangentenlänge > Fangradius)
  • Klettersteigungs-/Sinkraten-Prüfung pro Streckenabschnitt
  • JUMP-Wegpunkt-Unterstützung für Patrouillen-/Loop-Missionen (iNAV Action-Code 6, mit Wiederholzähler inkl. Endlos-Option)
  • Mehrfach-Missionsverwaltung (bis zu 9 Missionen im FC speicherbar, iNAV-seitig)
  • Aktiven Wegpunkt live aus FC auslesen und in der Liste hervorheben (MSP_NAV_STATUS/wp_number)
  • Adressensuche/Geocoding (Nominatim)
  • Terrainprofil entlang der Mission (AWS Terrarium Tiles, distanzbasiertes Sampling)

7.2 Flugbetrieb (Fly-Modus)

  • Umschaltbare Flugmodi: Waypoint, Point-and-Fly, weitere abstrahiert über MISSION_RUN/GUIDED_POINT/RETURN_HOME/HOLD
  • Standard-Rückstellung auf Waypoint-Modus beim Eintritt in Fly-Modus
  • Live-Telemetrie-Anzeige (SET- vs. LIVE-Werte für Höhe/Geschwindigkeit)
  • Drehräder (Wheels) zur Live-Anpassung von Soll-Höhe/-Geschwindigkeit
  • Point-and-Fly: zentrales Fadenkreuz, Einzelziel setzen ohne bestehende Mission zu verändern
  • Terrain-Kollisionsprüfung bei PnF (Mindestabstand 60 m über Grund)
  • Persistente Zielpunkt-Beschriftung mit zum Setzzeitpunkt gültigen Werten
  • Wind-Anzeige nach Höhe interpoliert (10/80/120/180 m AGL + Druckflächendaten)
  • Wind-Validierungspanel mit Böen-Anzeige
  • Home-Button (zentriert an der oberen Bildschirmkante)
  • Maximieren-Button mit Mindestabstand zu den Drehrädern

7.3 Drohnen-Profile

  • Mehrere Drohnenprofile verwaltbar, Standardprofil T1 Ranger
  • Profilliste als Tab im Vollbild-Menü (gemeinsam mit Missionsübersicht)
  • Profildaten: min/max Speed, min. Kurvenradius, max. Steig-/Sinkrate, max. Reichweite, max. Flugdauer, Cruise Speed
  • FC-Typ als explizites Profil-Setting (MSP/MAVLink)

7.4 Konnektivität (geplant/MVP)

  • WiFi/TCP-Verbindung zum Flightcontroller (DroneBridge, mLRS-WiFi-Bridge)
  • MSP-Protokoll nativ für iNAV
  • MAVLink-Protokoll für ArduPilot (Post-MVP)
  • Feature-Capability-Abfrage je FC (FcCapabilities: Multi-Mission, In-Flight-Upload, max. Wegpunkte)
  • Ready-to-Fly-Gate mit Upload-/Verifikations-/Arm-Status

7.5 Persistenz & Datenhaltung

  • Lokale Speicherung von Missionen, Profilen, Einstellungen
  • Autosave/Mission-Drafts
  • Suche nach Missionen nach Name, Ort, Datum (Flutter-Ziel, Drift)
  • Vorbereitung für lokal-first Server-Sync (Dirty-Flags, Server-IDs)

7.6 Branding/Visuelles Design

  • Eigenes Monogramm-Logo (M/D/C-Konstruktion, gespiegeltes C mit Schließstrich)
  • Konsistentes Farbschema für SET/LIVE-Anzeigen (Blau/Grün)
  • Einheitliche Chip-Optik für swipe-adjustierbare Werte und Execute-Dropdown

7.7 Nicht-funktionale Eigenschaften

  • Android-Landscape-Ausrichtung (MVP)
  • Offline-Kartenkachel-Caching pro Mission (Flutter-Ziel)
  • Hintergrund-Telemetrie ohne Verbindungsabbruch bei App-Wechsel (Flutter-Ziel)
  • Testbarkeit ohne physische Hardware via Mock-FC-Link
  • Reine, UI-unabhängige Testbarkeit der Mission-Domain-Logik (separates Dart-Package, Flutter-Ziel)

8. Technologie-Stack im Überblick

Bereich Demonstrator (HTML/JS) Flutter-Ziel
Karten Leaflet.js + OSM-Tiles flutter_map + flutter_map_tile_caching
Wind Open-Meteo API Open-Meteo API
Geocoding Nominatim Nominatim
Terrain AWS Terrarium Tiles AWS Terrarium Tiles
Persistenz localStorage Drift (SQLite)
State-Management (imperativ, Vanilla JS) Bloc + Riverpod (kombiniert)
MSP-Protokoll eigene JS-Implementierung eigene Dart-Implementierung
MAVLink — (nicht MVP) dart_mavlink (Risiko prüfen) oder eigener Generator
Hintergrundbetrieb — flutter_foreground_task (Android)
Navigation — go_router
Nebenläufigkeit — Dart Isolates für Protokoll-Parsing

Dieses Dokument fasst den Stand der bisherigen Projektkonversationen zusammen. Es wird empfohlen, es bei künftigen Architekturentscheidungen fortzuschreiben.