Point the fly-mode rubber band at home during Return-to-Home
iNAV freezes activeWaypointIndex at whatever mission waypoint was active when RTH engaged instead of updating it to reflect the new target - navigation.c derives NAV_Status.activeWpIndex unconditionally from posControl.activeWaypointIndex, and none of the RTH state-entry handlers touch that field. Drawing the guidance line to that stale index would point at a waypoint the aircraft may have already passed. Extracted the target selection into computeRubberBandTarget() (mission stats.dart) so the RTH special-case and the abort-back-to-waypoint-mode fallback are unit-tested rather than only living inline in the widget build method - since it re-evaluates navMode on every frame, aborting RTH switches the line back to the mission waypoint with no extra transition logic needed.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import 'package:dmc_app/domain/mission/mission_stats.dart';
|
||||
import 'package:dmc_app/domain/waypoint/flat_waypoint_list.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:latlong2/latlong.dart';
|
||||
|
||||
Waypoint _wp(double lat, double lon, {double speed = 15}) =>
|
||||
Waypoint(lat: lat, lon: lon, altitudeM: 60, speedMs: speed, catchRadiusM: 60);
|
||||
@@ -110,4 +111,80 @@ void main() {
|
||||
expect(status!.etaToActiveWaypointSec, isNull);
|
||||
});
|
||||
});
|
||||
|
||||
group('computeRubberBandTarget', () {
|
||||
final waypoints = [_wp(0, 0), _wp(0, 0.01), _wp(0, 0.02)];
|
||||
const home = LatLng(1, 1);
|
||||
|
||||
test('zeigt normalerweise auf den aktiven Missionswegpunkt', () {
|
||||
final target = computeRubberBandTarget(
|
||||
navMode: 3, // Waypoint mission
|
||||
activeWaypointIndex: 1,
|
||||
waypoints: waypoints,
|
||||
homePoint: home,
|
||||
);
|
||||
expect(target, const LatLng(0, 0.01));
|
||||
});
|
||||
|
||||
test('zeigt bei Return-to-Home (navMode 2) auf den Homepoint statt auf '
|
||||
'den (ggf. laengst passierten) eingefrorenen Missionswegpunkt', () {
|
||||
final target = computeRubberBandTarget(
|
||||
navMode: navModeReturnToHome,
|
||||
activeWaypointIndex: 1,
|
||||
waypoints: waypoints,
|
||||
homePoint: home,
|
||||
);
|
||||
expect(target, home);
|
||||
});
|
||||
|
||||
test('liefert null bei RTH ohne bekannten Homepoint statt eines '
|
||||
'erfundenen Ziels', () {
|
||||
final target = computeRubberBandTarget(
|
||||
navMode: navModeReturnToHome,
|
||||
activeWaypointIndex: 1,
|
||||
waypoints: waypoints,
|
||||
homePoint: null,
|
||||
);
|
||||
expect(target, isNull);
|
||||
});
|
||||
|
||||
test('schaltet nach Abbruch von RTH (navMode wieder 3) automatisch '
|
||||
'zurueck auf den Missionswegpunkt', () {
|
||||
const rth = 2;
|
||||
final duringRth = computeRubberBandTarget(
|
||||
navMode: rth,
|
||||
activeWaypointIndex: 1,
|
||||
waypoints: waypoints,
|
||||
homePoint: home,
|
||||
);
|
||||
final afterAbort = computeRubberBandTarget(
|
||||
navMode: 3,
|
||||
activeWaypointIndex: 1,
|
||||
waypoints: waypoints,
|
||||
homePoint: home,
|
||||
);
|
||||
expect(duringRth, home);
|
||||
expect(afterAbort, const LatLng(0, 0.01));
|
||||
});
|
||||
|
||||
test('activeWaypointIndex null oder ausserhalb der Liste ergibt null '
|
||||
'(ausserhalb RTH)', () {
|
||||
expect(
|
||||
computeRubberBandTarget(
|
||||
navMode: 3,
|
||||
activeWaypointIndex: null,
|
||||
waypoints: waypoints,
|
||||
),
|
||||
isNull,
|
||||
);
|
||||
expect(
|
||||
computeRubberBandTarget(
|
||||
navMode: 3,
|
||||
activeWaypointIndex: 3,
|
||||
waypoints: waypoints,
|
||||
),
|
||||
isNull,
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user