Files
PilotVault/Fly App/lib/ui/fly/bottom/telemetry_strip.dart
T
tajniak81andClaude Opus 5.5 636da1ac2c Give the Fly App every remaining GO 4 flight mode and the missing settings
Intelligent modes: Point of Interest (orbit on the map, live radius and
speed), Follow Me (follows the phone), QuickShots on a boxed subject,
Course Lock / Home Lock, Tripod and Cinematic, a Free hyperlapse, and
Waypoints 2.0 for V2-only aircraft. ActiveTrack gains Spotlight Pro and
Circle. Every mode has a first-use tutorial and stops from the rail.
Waypoints can resume an interrupted mission, change cruise speed in
flight and check terrain clearance (Open-Meteo, on tap).

Settings: units, C1/C2 actions, dual-operator master/slave, HDMI/SDI
output, a link spectrum chart, Wi-Fi name and password, aircraft name,
video cache, battery warning history and pairing, non-smart cell
voltages. Calibration: compass interference meter, per-IMU calibration,
lens infinity focus and a first-manual-focus prompt. Also an RTK chip,
gimbal movement presets and motor tuning, Precision Takeoff gated on the
flight controller, and the precise GEO database's server version.

Built and unit/widget-tested only; nothing has flown yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 23:06:16 +02:00

101 lines
3.4 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'package:flutter/material.dart';
import '../../../fly/fly_prefs.dart';
import '../../../fly/hud_features.dart';
import '../../../fly/state/aircraft_state.dart';
import '../../../fly/units.dart';
import '../hud_kit.dart';
/// The bottom telemetry strip (plan P2): H · D · VS (with arrow) · HS · VPS,
/// in metres or feet as Settings → General → Units says.
class TelemetryStrip extends StatelessWidget {
const TelemetryStrip({super.key, required this.aircraft});
final AircraftState aircraft;
@override
Widget build(BuildContext context) {
return ListenableBuilder(
listenable: Listenable.merge(<Listenable>[aircraft, FlyPrefs.units]),
builder: (BuildContext context, _) {
final AircraftState a = aircraft;
final UnitSystem u = FlyPrefs.units.value;
final double? vs = a.verticalSpeed;
// Under 0.1 m/s is hover noise; no arrow for it.
final int dir = vs == null || vs.abs() < 0.1 ? 0 : vs.sign.toInt();
double? len(double? m) => m == null ? null : Units.lengthValue(m, u);
double? spd(double? ms) => ms == null ? null : Units.speedValue(ms, u);
final String l = Units.lengthUnit(u), s = Units.speedUnit(u);
return GlassPill(
height: 40,
padding: const EdgeInsets.symmetric(horizontal: 12),
child: Row(mainAxisSize: MainAxisSize.min, children: <Widget>[
_Field('H', fmtNum(len(a.altitude)), l),
_Field('D', fmtNum(len(a.homeDistance), digits: 0), l),
_Field('VS', fmtNum(spd(vs?.abs())), s, arrow: dir),
_Field('HS', fmtNum(spd(a.horizontalSpeed)), s),
Requires(HudFeatures.vpsReadout, child: _Field('VPS', fmtNum(len(a.vpsHeight)), l)),
]),
);
},
);
}
}
class _Field extends StatelessWidget {
const _Field(this.label, this.value, this.unit, {this.arrow = 0});
final String label;
final String value;
final String unit;
/// 1 climbing, −1 descending, 0 no arrow. Painted: Space Mono has no ▲ / ▼.
final int arrow;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 6),
child: Column(mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[
Text(label, style: HudText.label),
const SizedBox(height: 2),
Row(mainAxisSize: MainAxisSize.min, children: <Widget>[
if (arrow != 0)
Padding(
padding: const EdgeInsets.only(right: 2),
child: CustomPaint(size: const Size(7, 6), painter: _ArrowPainter(up: arrow > 0)),
),
Text.rich(TextSpan(children: <TextSpan>[
TextSpan(text: value, style: HudText.value),
TextSpan(text: ' $unit', style: HudText.unit),
])),
]),
]),
);
}
}
class _ArrowPainter extends CustomPainter {
const _ArrowPainter({required this.up});
final bool up;
@override
void paint(Canvas canvas, Size size) {
final double w = size.width, h = size.height;
final Path p = up
? (Path()
..moveTo(w / 2, 0)
..lineTo(w, h)
..lineTo(0, h))
: (Path()
..moveTo(0, 0)
..lineTo(w, 0)
..lineTo(w / 2, h));
canvas.drawPath(p..close(), Paint()..color = HudColors.ready);
}
@override
bool shouldRepaint(_ArrowPainter old) => old.up != up;
}