From 62d655fe8e31ecda9ac8473879dd2a868d7e2fc4 Mon Sep 17 00:00:00 2001 From: Constantin Leue <77660791+Consti3D@users.noreply.github.com> Date: Sun, 26 Jul 2026 21:04:38 +0200 Subject: [PATCH] prototype and icons --- .gitignore | 130 ++ DMC_Architektur_und_Design.md | 289 +++ Drone Mission Control.html | 2913 +++++++++++++++++++++++++++++++ design/B_paperplane.svg | 1 + design/DMC Logo gespiegelt.html | 87 + design/DMC logo sketches.odp | Bin 0 -> 15244 bytes design/Drone Marker v2.html | 104 ++ design/Y1_pink_purple.svg | 1 + design/Y1_pink_purple_sq.svg | 1 + design/Y2_pink_dark.svg | 1 + design/Y3_purple_turq.svg | 1 + design/Y3_purple_turq_sq.svg | 1 + design/Y4_purple_yellow.svg | 1 + design/Y5_turq_purple.svg | 1 + design/Y6_turq_dark.svg | 1 + 15 files changed, 3532 insertions(+) create mode 100644 .gitignore create mode 100644 DMC_Architektur_und_Design.md create mode 100644 Drone Mission Control.html create mode 100644 design/B_paperplane.svg create mode 100644 design/DMC Logo gespiegelt.html create mode 100644 design/DMC logo sketches.odp create mode 100644 design/Drone Marker v2.html create mode 100644 design/Y1_pink_purple.svg create mode 100644 design/Y1_pink_purple_sq.svg create mode 100644 design/Y2_pink_dark.svg create mode 100644 design/Y3_purple_turq.svg create mode 100644 design/Y3_purple_turq_sq.svg create mode 100644 design/Y4_purple_yellow.svg create mode 100644 design/Y5_turq_purple.svg create mode 100644 design/Y6_turq_dark.svg diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..72b10a9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,130 @@ +test/flutter_test_project/.gitignore +test/flutter_test_project/.metadata +test/flutter_test_project/analysis_options.yaml +test/flutter_test_project/pubspec.lock +test/flutter_test_project/pubspec.yaml +test/flutter_test_project/README.md +test/flutter_test_project/android/.gitignore +test/flutter_test_project/android/build.gradle.kts +test/flutter_test_project/android/gradle.properties +test/flutter_test_project/android/settings.gradle.kts +test/flutter_test_project/android/app/build.gradle.kts +test/flutter_test_project/android/app/src/debug/AndroidManifest.xml +test/flutter_test_project/android/app/src/main/AndroidManifest.xml +test/flutter_test_project/android/app/src/main/kotlin/com/example/flutter_test_project/MainActivity.kt +test/flutter_test_project/android/app/src/main/res/drawable/launch_background.xml +test/flutter_test_project/android/app/src/main/res/drawable-v21/launch_background.xml +test/flutter_test_project/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +test/flutter_test_project/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +test/flutter_test_project/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +test/flutter_test_project/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +test/flutter_test_project/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +test/flutter_test_project/android/app/src/main/res/values/styles.xml +test/flutter_test_project/android/app/src/main/res/values-night/styles.xml +test/flutter_test_project/android/app/src/profile/AndroidManifest.xml +test/flutter_test_project/android/gradle/wrapper/gradle-wrapper.properties +test/flutter_test_project/ios/.gitignore +test/flutter_test_project/ios/Flutter/AppFrameworkInfo.plist +test/flutter_test_project/ios/Flutter/Debug.xcconfig +test/flutter_test_project/ios/Flutter/Release.xcconfig +test/flutter_test_project/ios/Runner/AppDelegate.swift +test/flutter_test_project/ios/Runner/Info.plist +test/flutter_test_project/ios/Runner/Runner-Bridging-Header.h +test/flutter_test_project/ios/Runner/SceneDelegate.swift +test/flutter_test_project/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +test/flutter_test_project/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png +test/flutter_test_project/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png +test/flutter_test_project/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png +test/flutter_test_project/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png +test/flutter_test_project/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png +test/flutter_test_project/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png +test/flutter_test_project/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png +test/flutter_test_project/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png +test/flutter_test_project/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png +test/flutter_test_project/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png +test/flutter_test_project/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png +test/flutter_test_project/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png +test/flutter_test_project/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png +test/flutter_test_project/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png +test/flutter_test_project/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png +test/flutter_test_project/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json +test/flutter_test_project/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png +test/flutter_test_project/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png +test/flutter_test_project/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png +test/flutter_test_project/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md +test/flutter_test_project/ios/Runner/Base.lproj/LaunchScreen.storyboard +test/flutter_test_project/ios/Runner/Base.lproj/Main.storyboard +test/flutter_test_project/ios/Runner.xcodeproj/project.pbxproj +test/flutter_test_project/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +test/flutter_test_project/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +test/flutter_test_project/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +test/flutter_test_project/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +test/flutter_test_project/ios/Runner.xcworkspace/contents.xcworkspacedata +test/flutter_test_project/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +test/flutter_test_project/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +test/flutter_test_project/ios/RunnerTests/RunnerTests.swift +test/flutter_test_project/lib/main.dart +test/flutter_test_project/linux/.gitignore +test/flutter_test_project/linux/CMakeLists.txt +test/flutter_test_project/linux/flutter/CMakeLists.txt +test/flutter_test_project/linux/flutter/generated_plugin_registrant.cc +test/flutter_test_project/linux/flutter/generated_plugin_registrant.h +test/flutter_test_project/linux/flutter/generated_plugins.cmake +test/flutter_test_project/linux/runner/CMakeLists.txt +test/flutter_test_project/linux/runner/main.cc +test/flutter_test_project/linux/runner/my_application.cc +test/flutter_test_project/linux/runner/my_application.h +test/flutter_test_project/macos/.gitignore +test/flutter_test_project/macos/Flutter/Flutter-Debug.xcconfig +test/flutter_test_project/macos/Flutter/Flutter-Release.xcconfig +test/flutter_test_project/macos/Flutter/GeneratedPluginRegistrant.swift +test/flutter_test_project/macos/Runner/AppDelegate.swift +test/flutter_test_project/macos/Runner/DebugProfile.entitlements +test/flutter_test_project/macos/Runner/Info.plist +test/flutter_test_project/macos/Runner/MainFlutterWindow.swift +test/flutter_test_project/macos/Runner/Release.entitlements +test/flutter_test_project/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png +test/flutter_test_project/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png +test/flutter_test_project/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png +test/flutter_test_project/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png +test/flutter_test_project/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png +test/flutter_test_project/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png +test/flutter_test_project/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png +test/flutter_test_project/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +test/flutter_test_project/macos/Runner/Base.lproj/MainMenu.xib +test/flutter_test_project/macos/Runner/Configs/AppInfo.xcconfig +test/flutter_test_project/macos/Runner/Configs/Debug.xcconfig +test/flutter_test_project/macos/Runner/Configs/Release.xcconfig +test/flutter_test_project/macos/Runner/Configs/Warnings.xcconfig +test/flutter_test_project/macos/Runner.xcodeproj/project.pbxproj +test/flutter_test_project/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +test/flutter_test_project/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +test/flutter_test_project/macos/Runner.xcworkspace/contents.xcworkspacedata +test/flutter_test_project/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +test/flutter_test_project/macos/RunnerTests/RunnerTests.swift +test/flutter_test_project/test/widget_test.dart +test/flutter_test_project/web/favicon.png +test/flutter_test_project/web/index.html +test/flutter_test_project/web/manifest.json +test/flutter_test_project/web/icons/Icon-192.png +test/flutter_test_project/web/icons/Icon-512.png +test/flutter_test_project/web/icons/Icon-maskable-192.png +test/flutter_test_project/web/icons/Icon-maskable-512.png +test/flutter_test_project/windows/.gitignore +test/flutter_test_project/windows/CMakeLists.txt +test/flutter_test_project/windows/flutter/CMakeLists.txt +test/flutter_test_project/windows/flutter/generated_plugin_registrant.cc +test/flutter_test_project/windows/flutter/generated_plugin_registrant.h +test/flutter_test_project/windows/flutter/generated_plugins.cmake +test/flutter_test_project/windows/runner/CMakeLists.txt +test/flutter_test_project/windows/runner/flutter_window.cpp +test/flutter_test_project/windows/runner/flutter_window.h +test/flutter_test_project/windows/runner/main.cpp +test/flutter_test_project/windows/runner/resource.h +test/flutter_test_project/windows/runner/runner.exe.manifest +test/flutter_test_project/windows/runner/Runner.rc +test/flutter_test_project/windows/runner/utils.cpp +test/flutter_test_project/windows/runner/utils.h +test/flutter_test_project/windows/runner/win32_window.cpp +test/flutter_test_project/windows/runner/win32_window.h +test/flutter_test_project/windows/runner/resources/app_icon.ico diff --git a/DMC_Architektur_und_Design.md b/DMC_Architektur_und_Design.md new file mode 100644 index 0000000..7552530 --- /dev/null +++ b/DMC_Architektur_und_Design.md @@ -0,0 +1,289 @@ +# 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 + +### 3.1 `FlightControllerLink` (Interface) +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) + +### 3.12 Branding/Logo +- 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 | + +--- + +## 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. +- **`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.* diff --git a/Drone Mission Control.html b/Drone Mission Control.html new file mode 100644 index 0000000..34190f7 --- /dev/null +++ b/Drone Mission Control.html @@ -0,0 +1,2913 @@ + + + + + +Drone Mission Control + + + + + +
+ + +
Karte verschieben und pinchen, um zu zoomen
+ +
+
+ +
+
+ + — +
+
+ + +
+ + + +
+ +
+
+
+
Waypoint
+
Point and Fly
+
Return to Home
+
Manual
+
+ + +
+ + + + + + + + + +
+ + + +
+
+
Alt: 60 m
+ +
+
+
Speed: 15 m/s
+ +
+
+
+
+ + + +
+ + +
+
+
Route exceeds drone capabilities at highlighted point
+
+ +
+
+

Waypoints

+
+ + + +
+
+
+ + + +
+
+
+
+ # + Altitude + Speed + Execute + Catch radius + Wind + Action +
+
+
+
+
+
+
Drag a point up or down to adjust that waypoint's altitude. Brown area shows ground elevation sampled every 30 m along the route (loads automatically). Red bands mark less than 10m ground clearance.
+
+
+
+
Drag a point up or down to adjust that waypoint's speed. Diamonds show head-/tailwind along each leg; the faint dashed line shows achievable ground speed (needs wind data fetched).
+
+
+
+
+ +
+
+

Missions & Drones

+ +
+
+ + +
+
+
+
+ Name + Waypoints + Date + Action +
+
+
+ + + +
+
+
+
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+

Wind Validation

+ +
+
+
+
+
+ +
+
+

Warnings

+ +
+
+
+
+
+ +
+
+

Edit drone profile

+ +
+
+
+
+
+ + +
+
+
+ + + + + + diff --git a/design/B_paperplane.svg b/design/B_paperplane.svg new file mode 100644 index 0000000..4e0de3d --- /dev/null +++ b/design/B_paperplane.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/design/DMC Logo gespiegelt.html b/design/DMC Logo gespiegelt.html new file mode 100644 index 0000000..4ce3a7d --- /dev/null +++ b/design/DMC Logo gespiegelt.html @@ -0,0 +1,87 @@ + +DMC – gespiegeltes C +
+

Drone Mission Command

+

D als gespiegeltes C

+

Beide Buchstaben sind jetzt dieselbe Form: derselbe Radius, dieselbe Öffnung von +±40 Grad. Das D ist das gespiegelte C, dessen Öffnung von einer senkrechten Sehne +geschlossen wird.

+ +

Vorher / nachhergleiche Farben, nur das D unterscheidet sich

+
Verjüngtes D +

Verjüngtes D

Stamm 92 · Bogen r 66
Schwerpunkt −22,7

Gespiegeltes C +

Gespiegeltes C

Strich 75 · Bogen r 58,5
Schwerpunkt −21,2

+ +

Auf dem Homescreen

+
09:52●●●
+
Pinkes M auf ViolettDMC
Pinkes M auf SchwarzDMC
Violettes M auf TürkisDMC
Violettes M auf GelbDMC
Türkises M auf ViolettDMC
Türkises M auf SchwarzDMC
+ +

Alle sechs · echte Größen

+
Pinkes M auf Violett +

Pinkes M auf Violett

DC/M-Kontrast 3,5 : 1

+
112
72
48
32
24
Pinkes M auf Schwarz +

Pinkes M auf Schwarz

DC/M-Kontrast 3,5 : 1

+
112
72
48
32
24
Violettes M auf Türkis +

Violettes M auf Türkis

DC/M-Kontrast 6,6 : 1

+
112
72
48
32
24
Violettes M auf Gelb +

Violettes M auf Gelb

DC/M-Kontrast 6,6 : 1

+
112
72
48
32
24
Türkises M auf Violett +

Türkises M auf Violett

DC/M-Kontrast 1,8 : 1

+
112
72
48
32
24
Türkises M auf Schwarz +

Türkises M auf Schwarz

DC/M-Kontrast 1,8 : 1

+
112
72
48
32
24
+ + +
\ No newline at end of file diff --git a/design/DMC logo sketches.odp b/design/DMC logo sketches.odp new file mode 100644 index 0000000000000000000000000000000000000000..028b31b558e0e96aa09096debc38b74295afef23 GIT binary patch literal 15244 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 literal 0 HcmV?d00001 diff --git a/design/Drone Marker v2.html b/design/Drone Marker v2.html new file mode 100644 index 0000000..ea87e95 --- /dev/null +++ b/design/Drone Marker v2.html @@ -0,0 +1,104 @@ + +Drohnen-Marker +
+

Drone Mission Control

+

Drohnen-Marker

+

Ohne Mittelpunkt, Papierflieger jetzt zweifarbig in Pink. Dazu die Scheibe mit +Pfeilausschnitt und zwei Entwürfe, die anders herum denken.

+ +

Auf der Karte · Slipstream

+
+

Auf der Karte · Scheibe mit Ausschnitt

+
+ +

Alle sieben Entwürfe

+
+
Papierflieger +
Klassiker +

Papierflieger

Zwei Facetten, die dunkle jetzt in tieferem Pink statt Grau – die Form bleibt dadurch komplett in der Logo-Familie.

+
64px
44px
30px
22px
+
rotiert
+
+
Navigationspfeil +
Klassiker +

Navigationspfeil

Die FPV- und GPS-Konvention. Bei kleinster Größe am eindeutigsten, weil die Richtung nur aus Spitze und Heckkerbe besteht.

+
64px
44px
30px
22px
+
rotiert
+
+
Abgerundeter Dart +
Klassiker +

Abgerundeter Dart

Weichere Kanten, näher an modernen Karten-Apps. Ruhiger, etwas weniger technisch.

+
64px
44px
30px
22px
+
rotiert
+
+
Scheibe mit Ausschnitt +
Neu +

Scheibe mit Ausschnitt

Pfeil als echte Aussparung in einer vollen Scheibe – die Karte scheint hindurch. Kompakteste Silhouette, gute Trefferfläche für den Finger.

+
64px
44px
30px
22px
+
rotiert
+
+
Scheibe, Ausschnitt gerandet +
Neu +

Scheibe, Ausschnitt gerandet

Wie oben, aber die Aussparung bekommt einen weißen Rand – der Pfeil bleibt auch über unruhigem Satellitenbild ablesbar.

+
64px
44px
30px
22px
+
rotiert
+
+
Slipstream +
Überraschend +

Slipstream

Der Pfeil ist gar nicht gezeichnet. Zwei Flügelformen lassen einen Keil frei, und das Auge ergänzt die Spitze von selbst – dieselbe Negativraum-Idee wie das M, das durch die Buchstaben deines Logos scheint.

+
64px
44px
30px
22px
+
rotiert
+
+
Swift +
Überraschend +

Swift

Eine einzige geschwungene Silhouette statt gerader Kanten – die Kontur zieht sich wie ein Mauersegler nach hinten aus. Schlicht, aber deutlich weniger erwartbar als ein Dreieck.

+
64px
44px
30px
22px
+
rotiert
+
+ +

Zum Überraschungsmoment: Slipstream zeichnet den Pfeil nicht, sondern lässt ihn +frei – das Auge setzt die Spitze selbst zusammen. Das ist derselbe Kniff, der im Logo funktioniert, +wo das M durch die Innenflächen von D und C scheint. Marker und Logo folgen damit derselben +Gestaltungsidee, ohne sich zu wiederholen.

+Zum Drehpunkt: Wird der Marker später per Heading rotiert, sollte sich die Scheibe um ihren +Mittelpunkt drehen, die Pfeilformen dagegen um den Punkt, der die Position markiert – sonst wandert +die angezeigte Position beim Drehen leicht aus. Bei den Scheiben-Varianten ist das gratis, weil +Drehpunkt und Positionspunkt zusammenfallen.

+
\ No newline at end of file diff --git a/design/Y1_pink_purple.svg b/design/Y1_pink_purple.svg new file mode 100644 index 0000000..5781682 --- /dev/null +++ b/design/Y1_pink_purple.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/design/Y1_pink_purple_sq.svg b/design/Y1_pink_purple_sq.svg new file mode 100644 index 0000000..92b741e --- /dev/null +++ b/design/Y1_pink_purple_sq.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/design/Y2_pink_dark.svg b/design/Y2_pink_dark.svg new file mode 100644 index 0000000..195d1ff --- /dev/null +++ b/design/Y2_pink_dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/design/Y3_purple_turq.svg b/design/Y3_purple_turq.svg new file mode 100644 index 0000000..621d3e1 --- /dev/null +++ b/design/Y3_purple_turq.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/design/Y3_purple_turq_sq.svg b/design/Y3_purple_turq_sq.svg new file mode 100644 index 0000000..010a89b --- /dev/null +++ b/design/Y3_purple_turq_sq.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/design/Y4_purple_yellow.svg b/design/Y4_purple_yellow.svg new file mode 100644 index 0000000..9db7441 --- /dev/null +++ b/design/Y4_purple_yellow.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/design/Y5_turq_purple.svg b/design/Y5_turq_purple.svg new file mode 100644 index 0000000..684a59b --- /dev/null +++ b/design/Y5_turq_purple.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/design/Y6_turq_dark.svg b/design/Y6_turq_dark.svg new file mode 100644 index 0000000..25c16de --- /dev/null +++ b/design/Y6_turq_dark.svg @@ -0,0 +1 @@ + \ No newline at end of file