import '../domain/waypoint/flat_waypoint_list.dart'; /// Abstrakte Flugmodi, protokollunabhaengig (Architektur-Doku 3.1). enum FlightMode { missionRun, guidedPoint, returnHome, hold } /// Feature-Flags des angebundenen Flightcontrollers (Doku 3.1). class FcCapabilities { const FcCapabilities({ required this.supportsMultiMission, required this.supportsInFlightUpload, required this.maxWaypoints, }); final bool supportsMultiMission; final bool supportsInFlightUpload; final int maxWaypoints; } /// Normalisiertes Telemetrie-Frame, das an die UI weitergereicht wird (Doku 3.4). /// /// Der Strom wird bewusst NICHT auf einen gueltigen GPS-Fix gegated (frueher /// wurde ohne Fix gar kein Frame gesendet) - jeder Konsument entscheidet /// selbst anhand von [hasFix], ob/wie er [lat]/[lon] verwendet. Der /// Kartenmarker (FlyScreen) faellt bei fehlendem Fix weiterhin auf den /// ersten Wegpunkt zurueck, das Settings-Diagnosepanel zeigt Hoehe/ /// Geschwindigkeit/Armed-Status dagegen auch ohne Fix an. class TelemetryFrame { const TelemetryFrame({ required this.lat, required this.lon, required this.hasFix, required this.numSat, required this.altitudeM, required this.speedMs, required this.headingDeg, required this.armed, required this.batteryPercent, required this.linkQuality, required this.snrDb, required this.hdop, required this.navMode, required this.flightMode, this.activeWaypointIndex, }); /// Nur aussagekraeftig, wenn [hasFix] - ohne Fix meldet der FC oft (0,0) /// oder eine veraltete Position. final double lat; final double lon; final bool hasFix; final int numSat; /// Barometrisch/GPS-fusionierte Hoehe relativ zum Referenzpunkt der /// Positionsschaetzung (in der Praxis: Einschaltort, siehe /// MspNavMode-/estAlt-Doku in msp_telemetry_codec.dart) - keine absolute /// Hoehe ueber Meeresspiegel. final double altitudeM; final double speedMs; /// Kurs ueber Grund in Grad (0 = Norden, im Uhrzeigersinn) - dreht den /// Drohnen-Marker (Doku 3.10, [DroneMarkerIcon]). final double headingDeg; final bool armed; /// Akku-Ladestand in Prozent (0-100). final int batteryPercent; /// Empfaenger-Linkqualitaet in Prozent (0-100). final int linkQuality; /// Signal-Rausch-Verhaeltnis des Uplinks in dB (siehe /// parseMspLinkStatsSnr in msp_telemetry_codec.dart) - hoeher ist besser, /// negative Werte bedeuten das Rauschen ueberdeckt das Signal bereits /// teilweise trotz ggf. noch ordentlicher Linkqualitaet. final int snrDb; /// Horizontale Streuung der GPS-Positionsschaetzung (kleiner ist besser, /// siehe MspGpsReading.hdop in msp_telemetry_codec.dart). Ohne Fix ein /// sehr grosser Wert (iNAV meldet dann 99.99), nicht null. final double hdop; /// Roher `MW_GPS_MODE_*`-Wert aus `MSP_NAV_STATUS` (0=None, 1=Hold, /// 2=RTH, 3=Waypoint mission, 15=Emergency) - siehe MspNavMode.mode in /// msp_telemetry_codec.dart. Getrennt von [flightMode] (der bereits /// formatierten Kurzbeschreibung), weil computeDroneStatus in /// domain/telemetry/drone_status.dart den Rohwert fuer die /// Zustandsableitung braucht. final int navMode; /// Menschenlesbare Kurzbeschreibung des Navigationsmodus (z.B. "Waypoint /// mission (en route)", "Return to home (climbing)", "Idle") - siehe /// MspNavMode.formatted in msp_telemetry_codec.dart. final String flightMode; /// 0-basierter Index des gerade angeflogenen Wegpunkts in der /// App-eigenen Wegpunktliste (z.B. `currentMissionProvider`), oder null, /// wenn keine Mission aktiv ist. Bei MSP bereits aus dem 1-basierten /// `activeWpNumber` umgerechnet (siehe parseMspNavStatusActiveWaypoint in /// msp_telemetry_codec.dart). final int? activeWaypointIndex; } /// Zentrale Abstraktion fuer alle Flightcontroller-Interaktionen (Doku 3.1). /// Implementierungen: MspFlightControllerLink (iNAV), MavlinkFlightControllerLink /// (ArduPilot, Post-MVP), MockFlightControllerLink (Tests ohne Hardware). abstract class FlightControllerLink { FcCapabilities get capabilities; Future connect(); Future disconnect(); Future uploadMission(FlatWaypointList mission); Future setFlightMode(FlightMode mode); Future arm(); Stream subscribeTelemetry(); Future readActiveWaypointIndex(); }