Files
PilotVault/Fly App/lib/ui/fly/modes/waypoints/waypoint_start.dart
T
tajniak81andClaude Opus 5.5 43a66df8df Give the Fly App GO 4-style intelligent modes and a Waypoints editor
P7a of the GO 4-parity plan. The rail's GRID button becomes MODES, which
opens a picker of the product's intelligent flight modes with first-use
terms; Waypoints is the first one built.

Waypoints opens on the big map: tap to add waypoints or POIs, long-press
to drag, "+" to insert on a leg, and a point editor for altitude, speed,
heading (route / custom / POI), gimbal (set or aim at POI), camera action
and hover, and turn radius, with a swipe-to-adjust readout. Route settings,
a local mission library and undo sit in a tool column. Start runs the
SafetyGate's pre-start check in the slide-to-confirm dialog, then uploads
and starts; a run panel shows upload and flight progress with Pause,
Resume and Stop.

MissionBridge now listens to the waypoint operator and builds the full V1
mission (per-waypoint headings, turn direction, gimbal pitch, actions).
Not yet run on a simulator or aircraft.

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

48 lines
2.1 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 'dart:math' as math;
import 'package:flutter/material.dart';
import '../../../../fly/hud_geometry.dart';
import '../../../../fly/modes/waypoint_mission.dart';
import '../../../../fly/safety_gate.dart';
import '../../dialogs/slide_to_confirm.dart';
/// Starts a waypoint mission the GO 4 way (plan P7): the pre-start check —
/// the [SafetyGate]'s mission checks against the aircraft's limits, the RTH
/// altitude, the route summary — then slide to start. The gate re-checks,
/// uploads (the run panel shows the progress) and starts.
Future<void> startWaypointFlow(
BuildContext context, {
required SafetyGate gate,
required WaypointMissionSpec spec,
required void Function(String label, Object error) onError,
}) async {
final MissionLimits limits = await gate.missionLimits();
if (!context.mounted) return;
final List<GateCheck> checks = gate.checkWaypointStart(spec, limits);
final double top = spec.points.fold(0.0, (double h, WaypointSpec p) => math.max(h, p.altitude));
final int rth = (gate.model.aircraft.goHomeHeight ?? 60).round().clamp(SafetyGate.minRthHeight, SafetyGate.maxRthHeight);
final String length = spec.length >= 1000 ? '${(spec.length / 1000).toStringAsFixed(2)} km' : '${spec.length.round()} m';
final SlideResult? r = await showSlideToConfirm(
context,
SlideConfirmSpec(
icon: 'route',
title: 'Start "${spec.name}"',
description: '${spec.points.length} waypoints · $length · about ${formatDuration(spec.estimatedSeconds)}'
'${spec.repeatTimes > 1 ? ' · ${spec.repeatTimes}×' : ''}. '
'Highest waypoint ${top.round()} m. When finished: ${spec.finishAction.label.toLowerCase()}. '
'Pause or Stop at any time, or press the remote\'s pause button.',
sliderLabel: 'Slide to start',
checks: checks,
number: SlideNumber(label: 'RTH altitude', initial: rth, min: SafetyGate.minRthHeight, max: SafetyGate.maxRthHeight),
),
);
if (r == null) return;
try {
await gate.startWaypointMission(spec, limits: limits, rthHeight: r.number);
} catch (e) {
onError('Waypoint mission', e);
}
}