MSP protocol implementation and settings menu

This commit is contained in:
Constantin Leue
2026-07-30 21:18:48 +02:00
parent 5994aee7ad
commit 078d58dbc0
16 changed files with 1132 additions and 29 deletions
@@ -0,0 +1,60 @@
import 'dart:typed_data';
import 'msp_commands.dart';
/// GPS-Rohwerte aus `MSP_RAW_GPS` (Doku Kommunikationsschicht Abschnitt 4).
class MspGpsReading {
const MspGpsReading({
required this.fixType,
required this.numSat,
required this.lat,
required this.lon,
required this.speedMs,
});
/// 0 = kein Fix (`fc_msp.c`: `gpsSol.fixType`).
final int fixType;
final int numSat;
final double lat;
final double lon;
final double speedMs;
bool get hasFix => fixType != 0;
}
/// Parst die `MSP_RAW_GPS`-Antwort (Byte-Layout siehe [MspCommands.rawGps]).
MspGpsReading parseMspRawGps(Uint8List payload) {
final data = ByteData.sublistView(payload);
return MspGpsReading(
fixType: data.getUint8(0),
numSat: data.getUint8(1),
lat: data.getInt32(2, Endian.little) / 1e7,
lon: data.getInt32(6, Endian.little) / 1e7,
speedMs: data.getUint16(12, Endian.little) / 100.0,
);
}
/// Parst die `MSP_ALTITUDE`-Antwort und liefert die geschaetzte Hoehe in
/// Metern (siehe [MspCommands.altitude]).
double parseMspAltitudeMeters(Uint8List payload) {
final data = ByteData.sublistView(payload);
return data.getInt32(0, Endian.little) / 100.0;
}
/// Parst die `MSP2_INAV_STATUS`-Antwort und liefert, ob der ARMED-Bit in
/// `armingFlags` gesetzt ist (siehe [MspCommands.inavStatus]).
bool parseMspInavStatusArmed(Uint8List payload) {
final data = ByteData.sublistView(payload);
// Offset 9 = cycleTime(2) + i2cErrors(2) + sensorStatus(2) + avgLoad(2)
// + Profil-Byte(1), siehe fc_msp.c/MSP2_INAV_STATUS.
final armingFlags = data.getUint32(9, Endian.little);
return (armingFlags & MspArmingFlags.armed) != 0;
}
/// Parst die `MSP_NAV_STATUS`-Antwort und liefert den aktiven
/// Wegpunktindex, oder null, wenn keine Mission aktiv ist (`activeWpNumber
/// == 0`, siehe [MspCommands.navStatus]).
int? parseMspNavStatusActiveWaypoint(Uint8List payload) {
final activeWpNumber = payload[3];
return activeWpNumber == 0 ? null : activeWpNumber;
}