Warning thresholds added in drone profile. traffic light indication in drone satus menue added. layout and content optimized

This commit is contained in:
Constantin Leue
2026-08-05 20:15:18 +02:00
parent f65dceb338
commit 4982341203
8 changed files with 1302 additions and 37 deletions
+72
View File
@@ -17,6 +17,18 @@ class DroneProfile {
required this.maxRangeM,
required this.maxEnduranceMin,
required this.maxAltitudeM,
this.gpsSatGreenMin = defaultGpsSatGreenMin,
this.gpsSatRedMin = defaultGpsSatRedMin,
this.hdopGreenMax = defaultHdopGreenMax,
this.hdopRedMax = defaultHdopRedMax,
this.currentGreenMaxA = defaultCurrentGreenMaxA,
this.currentRedMaxA = defaultCurrentRedMaxA,
this.batteryVoltageGreenMinV = defaultBatteryVoltageGreenMinV,
this.batteryVoltageRedMinV = defaultBatteryVoltageRedMinV,
this.rxQualityGreenMin = defaultRxQualityGreenMin,
this.rxQualityRedMin = defaultRxQualityRedMin,
this.rxSnrGreenMinDb = defaultRxSnrGreenMinDb,
this.rxSnrRedMinDb = defaultRxSnrRedMinDb,
});
/// Null fuer ein noch nicht gespeichertes (neu angelegtes) Profil.
@@ -34,6 +46,42 @@ class DroneProfile {
final double maxEnduranceMin;
final double maxAltitudeM;
/// Ampel-Schwellwerte fuer die farbcodierten Telemetriefelder im
/// Drohnen-Status-Menue (Doku: "Schwellwerte fuer die Ampel-Kodierung im
/// Drohnenprofil anlegen", siehe domain/telemetry/telemetry_field_status.dart)
/// - je Feld eine Gruen- und eine Rot-Schwelle, dazwischen gilt gelb.
/// *Max/*GreenMax bei Feldern, bei denen ein NIEDRIGER Wert gut ist (HDOP),
/// *Min/*GreenMin bei Feldern, bei denen ein HOHER Wert gut ist (alle
/// anderen). Default-Werte als statische Konstanten (statt nur inline im
/// Konstruktor), damit sie auch als Fallback beim Import aelterer, noch
/// ohne diese Felder exportierter Profile dienen koennen (siehe
/// drone_share_codec.dart).
final double gpsSatGreenMin;
final double gpsSatRedMin;
final double hdopGreenMax;
final double hdopRedMax;
final double currentGreenMaxA;
final double currentRedMaxA;
final double batteryVoltageGreenMinV;
final double batteryVoltageRedMinV;
final double rxQualityGreenMin;
final double rxQualityRedMin;
final double rxSnrGreenMinDb;
final double rxSnrRedMinDb;
static const defaultGpsSatGreenMin = 8.0;
static const defaultGpsSatRedMin = 6.0;
static const defaultHdopGreenMax = 2.0;
static const defaultHdopRedMax = 5.0;
static const defaultCurrentGreenMaxA = 20.0;
static const defaultCurrentRedMaxA = 30.0;
static const defaultBatteryVoltageGreenMinV = 20.4;
static const defaultBatteryVoltageRedMinV = 19.2;
static const defaultRxQualityGreenMin = 70.0;
static const defaultRxQualityRedMin = 50.0;
static const defaultRxSnrGreenMinDb = 0.0;
static const defaultRxSnrRedMinDb = -10.0;
/// T1 Ranger (Heewing) - Standardprofil (Doku 3.5), analog DEFAULT_DRONE
/// im HTML-Demonstrator.
static const _t1RangerName = 'T1 Ranger';
@@ -76,6 +124,18 @@ class DroneProfile {
double? maxRangeM,
double? maxEnduranceMin,
double? maxAltitudeM,
double? gpsSatGreenMin,
double? gpsSatRedMin,
double? hdopGreenMax,
double? hdopRedMax,
double? currentGreenMaxA,
double? currentRedMaxA,
double? batteryVoltageGreenMinV,
double? batteryVoltageRedMinV,
double? rxQualityGreenMin,
double? rxQualityRedMin,
double? rxSnrGreenMinDb,
double? rxSnrRedMinDb,
}) {
return DroneProfile(
id: id ?? this.id,
@@ -91,6 +151,18 @@ class DroneProfile {
maxRangeM: maxRangeM ?? this.maxRangeM,
maxEnduranceMin: maxEnduranceMin ?? this.maxEnduranceMin,
maxAltitudeM: maxAltitudeM ?? this.maxAltitudeM,
gpsSatGreenMin: gpsSatGreenMin ?? this.gpsSatGreenMin,
gpsSatRedMin: gpsSatRedMin ?? this.gpsSatRedMin,
hdopGreenMax: hdopGreenMax ?? this.hdopGreenMax,
hdopRedMax: hdopRedMax ?? this.hdopRedMax,
currentGreenMaxA: currentGreenMaxA ?? this.currentGreenMaxA,
currentRedMaxA: currentRedMaxA ?? this.currentRedMaxA,
batteryVoltageGreenMinV: batteryVoltageGreenMinV ?? this.batteryVoltageGreenMinV,
batteryVoltageRedMinV: batteryVoltageRedMinV ?? this.batteryVoltageRedMinV,
rxQualityGreenMin: rxQualityGreenMin ?? this.rxQualityGreenMin,
rxQualityRedMin: rxQualityRedMin ?? this.rxQualityRedMin,
rxSnrGreenMinDb: rxSnrGreenMinDb ?? this.rxSnrGreenMinDb,
rxSnrRedMinDb: rxSnrRedMinDb ?? this.rxSnrRedMinDb,
);
}
}
@@ -0,0 +1,89 @@
import '../mission/drone_profile.dart';
import 'drone_status.dart';
/// Ampel-Farbcodierung je einzelnem Telemetriefeld im Drohnen-Status-Menue
/// (Doku: "drone status felder im menue auch farblich kodieren") - anders
/// als [computeDroneStatus] (das Verbindungs-/Positionsqualitaet je zu einem
/// kombinierten Signal fuer die Fusszeilen-Pille zusammenfasst) bewertet
/// dies jedes Feld einzeln anhand der Schwellwerte im aktiven [DroneProfile].
class TelemetryFieldStatus {
const TelemetryFieldStatus({
required this.numSat,
required this.hdop,
required this.currentA,
required this.batteryVoltage,
required this.rxQuality,
required this.rxSnr,
});
final SignalLevel numSat;
final SignalLevel hdop;
final SignalLevel currentA;
final SignalLevel batteryVoltage;
final SignalLevel rxQuality;
final SignalLevel rxSnr;
}
/// Fuer Felder, bei denen ein HOHER Wert gut ist (Satelliten, RX-Qualitaet/
/// -SNR): rot unterhalb [redMin], gruen ab [greenMin], dazwischen gelb.
SignalLevel _levelHigherIsBetter(double value, double greenMin, double redMin) {
if (value < redMin) return SignalLevel.red;
if (value < greenMin) return SignalLevel.yellow;
return SignalLevel.green;
}
/// Fuer Felder, bei denen ein NIEDRIGER Wert gut ist (HDOP): rot oberhalb
/// [redMax], gruen bis [greenMax], dazwischen gelb.
SignalLevel _levelLowerIsBetter(double value, double greenMax, double redMax) {
if (value > redMax) return SignalLevel.red;
if (value > greenMax) return SignalLevel.yellow;
return SignalLevel.green;
}
/// Reine Ableitung aus normalisierten Telemetriewerten + den
/// Ampel-Schwellwerten des aktiven Drohnenprofils - kein MSP-/
/// Protokollwissen, siehe computeDroneStatus-Doku.
TelemetryFieldStatus computeTelemetryFieldStatus({
required int numSat,
required bool hasFix,
required double hdop,
required double currentA,
required double batteryVoltage,
required int linkQuality,
required int snrDb,
required DroneProfile profile,
}) {
return TelemetryFieldStatus(
numSat: _levelHigherIsBetter(
numSat.toDouble(),
profile.gpsSatGreenMin,
profile.gpsSatRedMin,
),
// Ohne Fix ist der HDOP-Wert bedeutungslos/veraltet (siehe Anzeige in
// drone_status_warnings_panel.dart, die dafuer bereits '—' zeigt) - dann
// unabhaengig vom Zahlenwert rot statt eines irrefuehrend guten Signals.
hdop: hasFix
? _levelLowerIsBetter(hdop, profile.hdopGreenMax, profile.hdopRedMax)
: SignalLevel.red,
currentA: _levelLowerIsBetter(
currentA,
profile.currentGreenMaxA,
profile.currentRedMaxA,
),
batteryVoltage: _levelHigherIsBetter(
batteryVoltage,
profile.batteryVoltageGreenMinV,
profile.batteryVoltageRedMinV,
),
rxQuality: _levelHigherIsBetter(
linkQuality.toDouble(),
profile.rxQualityGreenMin,
profile.rxQualityRedMin,
),
rxSnr: _levelHigherIsBetter(
snrDb.toDouble(),
profile.rxSnrGreenMinDb,
profile.rxSnrRedMinDb,
),
);
}