Waehrend eines Verbindungsverlusts frieren die TelemetryFrame-Werte
bewusst ein (telemetryProvider.value bleibt auf dem letzten Stand, siehe
vorherigen Commit) - die Fusszeilen-Pille im Fly-Modus hat daraus bislang
weiterhin den zuletzt bekannten (ggf. laengst veralteten) Zustand
abgeleitet, statt den Verbindungsverlust selbst widerzuspiegeln.
- domain/telemetry/drone_status.dart: neuer DroneState.disconnected,
computeDroneStatus() bekommt einen neuen Parameter `connected` - hat
Vorrang vor allem anderen (auch vor Emergency) und uebersteuert
connectionQuality auf rot. positionQuality bleibt bewusst unveraendert
(folgt weiterhin den eingefrorenen Werten) - laut Anfrage sollen nur
Drohnen-Icon und Verbindungsqualitaet, nicht die Positionsqualitaet, rot
erzwungen werden.
- fly_screen.dart: `connected: !telemetryAsync.hasError` statt der
bisherigen Ableitung aus einzelnen Telemetriewerten.
- bottom_stats_bar.dart: neues Label/Farbe ("disconnected", rot) fuer den
neuen Zustand in der Drohnen-Status-Pille.
Auf dem Pixel_10a-Emulator verifiziert: WiFi-Verbindungsart (noch nie
verbunden) zeigt bereits korrekt rotes Papierflieger-Icon, rote
Verbindungsqualitaet, rotes Satelliten-Icon und "disconnected" in rot;
Mock-Verbindung zeigt unveraendert normal gruen "ready".
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
110 lines
4.5 KiB
Dart
110 lines
4.5 KiB
Dart
/// Ampelfarbe fuer die Verbindungs- und Positionsqualitaets-Icons in der
|
|
/// Drohnen-Status-Pille (Doku: "icon mit Farbcodierung (gruen/gelb/rot)").
|
|
enum SignalLevel { green, yellow, red }
|
|
|
|
/// Zustand der Drohne fuer das Papierflieger-Icon in der Drohnen-Status-
|
|
/// Pille (Doku: "drone state: papierflieger icon mit farbcodierung ... mit
|
|
/// text wie (idle, ready, armed, waypoint, error)"). [disconnected] deckt
|
|
/// den Fall ab, dass der Telemetrie-Strom selbst gerade fehlerhaft ist
|
|
/// (Doku: "Statuspille ... muss eine rote Drohne, eine rote
|
|
/// Verbindungsqualität und den Status text in rot disconnected anzeigen"),
|
|
/// im Unterschied zu den anderen Zustaenden, die aus (ggf. eingefrorenen,
|
|
/// siehe computeDroneStatus) Telemetriewerten abgeleitet werden.
|
|
enum DroneState { idle, ready, armed, waypoint, disconnected, error }
|
|
|
|
/// Kombiniertes Ergebnis aus [computeDroneStatus] - die drei Elemente der
|
|
/// Fly-Modus-Drohnen-Pille (Doku: "connection quality", "position quality",
|
|
/// "drone state").
|
|
class DroneStatus {
|
|
const DroneStatus({
|
|
required this.connectionQuality,
|
|
required this.positionQuality,
|
|
required this.state,
|
|
});
|
|
|
|
final SignalLevel connectionQuality;
|
|
final SignalLevel positionQuality;
|
|
final DroneState state;
|
|
}
|
|
|
|
/// Verbindungsqualitaet aus Empfaenger-Linkqualitaet (LQ%) und
|
|
/// Signal-Rausch-Verhaeltnis (SNR, dB) - LQ ist der primaere Massstab (die
|
|
/// 70%-Schwelle entspricht iNAVs eigenem OSD-Alarm-Default
|
|
/// `osd_link_quality_alarm`, `fc/settings.yaml`), SNR stuft zusaetzlich von
|
|
/// gruen auf gelb herab, wenn das Rauschen trotz noch guter LQ bereits das
|
|
/// Signal ueberdeckt (SNR < 0 dB).
|
|
SignalLevel _connectionQuality({required int linkQuality, required int snrDb}) {
|
|
if (linkQuality < 50) return SignalLevel.red;
|
|
if (linkQuality < 70 || snrDb < 0) return SignalLevel.yellow;
|
|
return SignalLevel.green;
|
|
}
|
|
|
|
/// Positionsqualitaet aus Satellitenanzahl und HDOP - gaengige GNSS-
|
|
/// Faustregel (>=8 Sat. und HDOP <2.0 = gut, >=6 Sat. und HDOP <5.0 =
|
|
/// brauchbar, sonst schlecht/kein Fix).
|
|
SignalLevel _positionQuality({
|
|
required bool hasFix,
|
|
required int numSat,
|
|
required double hdop,
|
|
}) {
|
|
if (!hasFix) return SignalLevel.red;
|
|
if (numSat >= 8 && hdop < 2.0) return SignalLevel.green;
|
|
if (numSat >= 6 && hdop < 5.0) return SignalLevel.yellow;
|
|
return SignalLevel.red;
|
|
}
|
|
|
|
/// Zustand aus Armed-Status, GPS-Fix und dem rohen Navigationsmodus
|
|
/// (`MW_GPS_MODE_*`, siehe TelemetryFrame.navMode) - [connected] hat
|
|
/// Vorrang vor allem anderen (kein Telemetrie-Strom heisst, keiner der
|
|
/// anderen Werte ist aktuell), danach Emergency (15), "waypoint" nur
|
|
/// solange tatsaechlich armed und im Waypoint-Missionsmodus (3) navigiert
|
|
/// wird, "ready" markiert lediglich einen vorhandenen GPS-Fix im
|
|
/// disarmed-Zustand (kein zusaetzlicher Qualitaets-Gate durch
|
|
/// Positionsqualitaet - Nutzerentscheidung).
|
|
DroneState _droneState({
|
|
required bool connected,
|
|
required bool armed,
|
|
required bool hasFix,
|
|
required int navMode,
|
|
}) {
|
|
const navModeEmergency = 15;
|
|
const navModeWaypointMission = 3;
|
|
|
|
if (!connected) return DroneState.disconnected;
|
|
if (navMode == navModeEmergency) return DroneState.error;
|
|
if (armed && navMode == navModeWaypointMission) return DroneState.waypoint;
|
|
if (armed) return DroneState.armed;
|
|
if (hasFix) return DroneState.ready;
|
|
return DroneState.idle;
|
|
}
|
|
|
|
/// Reine Ableitung aus einem [TelemetryFrame] (siehe transport/
|
|
/// flight_controller_link.dart) - kein MSP-/Protokollwissen, nur die
|
|
/// bereits normalisierten Felder.
|
|
///
|
|
/// [connected] spiegelt, ob der Telemetrie-Strom gerade tatsaechlich Daten
|
|
/// liefert (z.B. `!telemetryProvider.hasError`, siehe fly_screen.dart) -
|
|
/// getrennt von den einzelnen Telemetriewerten, weil diese bei einem
|
|
/// Verbindungsverlust bewusst auf ihrem letzten Stand "einfrieren" (Doku:
|
|
/// "im Drone Detail Menü ist es okay, dass die Daten einfrieren"), die
|
|
/// Statuspille aber trotzdem ehrlich "disconnected" anzeigen soll statt
|
|
/// den zuletzt bekannten (ggf. laengst veralteten) Zustand fortzuschreiben.
|
|
DroneStatus computeDroneStatus({
|
|
required bool connected,
|
|
required bool armed,
|
|
required bool hasFix,
|
|
required int numSat,
|
|
required double hdop,
|
|
required int linkQuality,
|
|
required int snrDb,
|
|
required int navMode,
|
|
}) {
|
|
return DroneStatus(
|
|
connectionQuality: connected
|
|
? _connectionQuality(linkQuality: linkQuality, snrDb: snrDb)
|
|
: SignalLevel.red,
|
|
positionQuality: _positionQuality(hasFix: hasFix, numSat: numSat, hdop: hdop),
|
|
state: _droneState(connected: connected, armed: armed, hasFix: hasFix, navMode: navMode),
|
|
);
|
|
}
|