90 lines
3.4 KiB
Dart
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),
|
|
);
|
|
}
|