Drone Status Menue: Sensor-Status, Arming, Temperaturen und Steig-/Sinkrate hinzugefuegt
Neue Zeile ganz oben mit farblich kodierten Sensor-Badges (ACC/BARO/MAG/ GPS/RNG/OF/PITOT/TEMP, aus dem sensorStatus-Bitfeld von MSP2_INAV_STATUS, zuvor schon dokumentiert aber ungenutzt), darunter ein Zeilenpaar fuer Arming-Status und die ersten 3 Temperatursensoren (neu: MSP2_INAV_ TEMPERATURES, 0x201E). Ans Ende der Liste die Steig-/Sinkrate (vario aus MSP_ALTITUDE, bislang nur die Hoehe selbst wurde daraus gelesen). - msp_commands.dart: inavTemperatures-Konstante ergaenzt; die Sensor- Status-Bits (bisher nur als Doc-Kommentar bei MSP2_INAV_STATUS notiert) zu echten Konstanten (MspSensorStatusBits) promoviert, da jetzt tatsaechlich gebraucht. - msp_telemetry_codec.dart: parseMspAltitudeVerticalSpeedMs, parseMspInavStatusSensorStatus, parseMspInavTemperaturesC ergaenzt + Unit-Tests. - TelemetryFrame: sensorStatusBits (Bitmaske, protokollneutral durchgereicht wie navMode), temperaturesC (erste 3 Sensoren, null je nicht konfiguriertem Slot), verticalSpeedMs. - msp_telemetry_poller.dart: vario kommt aus derselben MSP_ALTITUDE- Antwort wie die Hoehe (keine zusaetzliche Anfrage), sensorStatus aus derselben MSP2_INAV_STATUS-Antwort wie ARMED; MSP2_INAV_TEMPERATURES neu im 2-Hz-Statuszyklus abgefragt. - MockFlightControllerLink: synthetische Sensor-/Temperatur-/Vario-Werte (kein Pitot/Rangefinder/Opflow am T1 Ranger vorgesehen), leicht schwankend, damit die neuen Felder auch ohne Hardware sichtbar auf Werteaenderungen reagieren. - drone_status_messages_panel.dart: eigene Sensor-Status-Zeile (lokale Bit-Konstanten statt MSP-Import, analog zum bestehenden navMode-Muster in domain/telemetry/drone_status.dart, damit die UI protokollneutral bleibt), Arming+Temperaturen-Zeilenpaar, Vertical-speed-Zeile am Ende. Auf dem Pixel_10a-Emulator verifiziert: Sensor-Badges gruen/grau je nach Bitmaske, Arming/Temperaturen-Paar, Vertical speed am Listenende. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
08791cac0c
commit
9cece7dbb6
@@ -26,6 +26,9 @@ TelemetryFrame _frame({
|
||||
hdop: 1.0,
|
||||
navMode: navMode,
|
||||
flightMode: 'Idle',
|
||||
sensorStatusBits: 0,
|
||||
temperaturesC: const [null, null, null],
|
||||
verticalSpeedMs: 0,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'dart:typed_data';
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'package:dmc_app/transport/msp/msp_commands.dart';
|
||||
import 'package:dmc_app/transport/msp/msp_telemetry_codec.dart';
|
||||
|
||||
void main() {
|
||||
@@ -62,6 +63,78 @@ void main() {
|
||||
});
|
||||
});
|
||||
|
||||
group('parseMspAltitudeVerticalSpeedMs', () {
|
||||
test('vario in cm/s wird zu m/s, positiv = Steigen', () {
|
||||
final data = ByteData(10);
|
||||
data.setInt16(4, 250, Endian.little); // 2.5 m/s Steigen
|
||||
expect(
|
||||
parseMspAltitudeVerticalSpeedMs(data.buffer.asUint8List()),
|
||||
closeTo(2.5, 1e-9),
|
||||
);
|
||||
});
|
||||
|
||||
test('negativer vario-Wert bedeutet Sinken', () {
|
||||
final data = ByteData(10);
|
||||
data.setInt16(4, -180, Endian.little); // -1.8 m/s Sinken
|
||||
expect(
|
||||
parseMspAltitudeVerticalSpeedMs(data.buffer.asUint8List()),
|
||||
closeTo(-1.8, 1e-9),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
group('parseMspInavStatusSensorStatus', () {
|
||||
Uint8List statusPayload(int sensorStatus) {
|
||||
final data = ByteData(22);
|
||||
data.setUint16(4, sensorStatus, Endian.little);
|
||||
return data.buffer.asUint8List();
|
||||
}
|
||||
|
||||
test('liest das rohe sensorStatus-Bitfeld an Offset 4', () {
|
||||
expect(
|
||||
parseMspInavStatusSensorStatus(
|
||||
statusPayload(MspSensorStatusBits.acc | MspSensorStatusBits.gps),
|
||||
),
|
||||
MspSensorStatusBits.acc | MspSensorStatusBits.gps,
|
||||
);
|
||||
});
|
||||
|
||||
test('Hardware-Defekt-Bit (1<<15) wird mit uebertragen', () {
|
||||
final bits = parseMspInavStatusSensorStatus(
|
||||
statusPayload(MspSensorStatusBits.hardwareFailure),
|
||||
);
|
||||
expect(bits & MspSensorStatusBits.hardwareFailure, isNot(0));
|
||||
});
|
||||
|
||||
test('keine Sensoren gemeldet', () {
|
||||
expect(parseMspInavStatusSensorStatus(statusPayload(0)), 0);
|
||||
});
|
||||
});
|
||||
|
||||
group('parseMspInavTemperaturesC', () {
|
||||
test('liest die ersten 3 von bis zu 8 Slots in 0.1°C-Schritten', () {
|
||||
final data = ByteData(16); // 8 x i16
|
||||
data.setInt16(0, 285, Endian.little); // 28.5°C
|
||||
data.setInt16(2, 320, Endian.little); // 32.0°C
|
||||
data.setInt16(4, -1000, Endian.little); // ungueltig
|
||||
data.setInt16(6, 999, Endian.little); // 4. Slot wird ignoriert
|
||||
|
||||
final temps = parseMspInavTemperaturesC(data.buffer.asUint8List());
|
||||
|
||||
expect(temps, hasLength(3));
|
||||
expect(temps[0], closeTo(28.5, 1e-9));
|
||||
expect(temps[1], closeTo(32.0, 1e-9));
|
||||
expect(temps[2], isNull);
|
||||
});
|
||||
|
||||
test('Werte unterhalb des Sentinels gelten ebenfalls als ungueltig', () {
|
||||
final data = ByteData(16);
|
||||
data.setInt16(0, -1250, Endian.little);
|
||||
final temps = parseMspInavTemperaturesC(data.buffer.asUint8List());
|
||||
expect(temps[0], isNull);
|
||||
});
|
||||
});
|
||||
|
||||
group('parseMspInavStatusArmed', () {
|
||||
Uint8List statusPayload(int armingFlags) {
|
||||
final data = ByteData(22);
|
||||
|
||||
@@ -27,6 +27,9 @@ TelemetryFrame _frame({bool hasFix = true, int numSat = 10}) => TelemetryFrame(
|
||||
hdop: 1.0,
|
||||
navMode: 0,
|
||||
flightMode: 'Idle',
|
||||
sensorStatusBits: 0,
|
||||
temperaturesC: const [null, null, null],
|
||||
verticalSpeedMs: 0,
|
||||
);
|
||||
|
||||
typedef _ConnectionSettings = ({
|
||||
|
||||
Reference in New Issue
Block a user