Files
dmc/app/lib/domain/telemetry/drone_status.dart
T

90 lines
3.4 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)").
enum DroneState { idle, ready, armed, waypoint, 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) - Emergency (15) hat
/// Vorrang vor allem anderen, "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 armed,
required bool hasFix,
required int navMode,
}) {
const navModeEmergency = 15;
const navModeWaypointMission = 3;
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.
DroneStatus computeDroneStatus({
required bool armed,
required bool hasFix,
required int numSat,
required double hdop,
required int linkQuality,
required int snrDb,
required int navMode,
}) {
return DroneStatus(
connectionQuality: _connectionQuality(linkQuality: linkQuality, snrDb: snrDb),
positionQuality: _positionQuality(hasFix: hasFix, numSat: numSat, hdop: hdop),
state: _droneState(armed: armed, hasFix: hasFix, navMode: navMode),
);
}