The new flight screen (lib/ui/fly/fly_screen.dart) is built from layers. Each readout listens to its own telemetry sub-model, so a 10 Hz tick only repaints what changed. It adds a status bar with a status chip and tip marquee, a smart battery bar with land/RTH markers, a camera info strip, an attitude ball, an H/D/VS/HS/VPS strip, and a minimap that swaps places with the video when tapped. The HUD is laid out in design pixels and scaled to phone or tablet inside the safe area. What the HUD shows depends on the product: dual or multi battery bars, SSD status, a thermal spot reading, a master/slave RC badge, and Wi-Fi bars in place of RC/HD. The bridges now report the data for these: the camera's ssd/thermal groups and the RC's master/slave mode. The old FlightControlPage can still be opened from Settings > About > Classic flight screen until the P3 safety flows land. The same tab also gets a toggle for the performance overlay. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
48 lines
1.4 KiB
Dart
48 lines
1.4 KiB
Dart
import 'package:flutter/foundation.dart';
|
|
import 'package:latlong2/latlong.dart';
|
|
|
|
import 'hud_geometry.dart';
|
|
import 'state/aircraft_state.dart';
|
|
|
|
/// The path the aircraft has flown this session, for the minimap. Follows an
|
|
/// [AircraftState] and keeps a point every [minSpacing] metres, so a 10 Hz
|
|
/// hover does not grow the list.
|
|
class FlightTrail extends ChangeNotifier {
|
|
FlightTrail(this.aircraft, {this.minSpacing = 2, this.maxPoints = 5000}) {
|
|
aircraft.addListener(_onAircraft);
|
|
_onAircraft();
|
|
}
|
|
|
|
final AircraftState aircraft;
|
|
final double minSpacing; // m
|
|
final int maxPoints;
|
|
|
|
final List<LatLng> _points = <LatLng>[];
|
|
|
|
List<LatLng> get points => List<LatLng>.unmodifiable(_points);
|
|
|
|
void _onAircraft() {
|
|
final double? lat = aircraft.latitude, lon = aircraft.longitude;
|
|
if (lat == null || lon == null || (lat == 0 && lon == 0)) return;
|
|
if (_points.isNotEmpty) {
|
|
final LatLng last = _points.last;
|
|
if (HudGeometry.distance(last.latitude, last.longitude, lat, lon) < minSpacing) return;
|
|
}
|
|
_points.add(LatLng(lat, lon));
|
|
if (_points.length > maxPoints) _points.removeRange(0, _points.length - maxPoints);
|
|
notifyListeners();
|
|
}
|
|
|
|
void clear() {
|
|
if (_points.isEmpty) return;
|
|
_points.clear();
|
|
notifyListeners();
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
aircraft.removeListener(_onAircraft);
|
|
super.dispose();
|
|
}
|
|
}
|