From 9cca65019f5af06b167b68bdbc6f6d356ba07daa Mon Sep 17 00:00:00 2001 From: tajniak81 <13187254+tajniak81@users.noreply.github.com> Date: Thu, 22 Oct 2026 09:25:28 +0200 Subject: [PATCH] Retry a timed-out waypoint upload and wait for the route to be ready On the Mavic Pro in the simulator a waypoint mission failed with "Execution of this process has timed out". The bridge now resends a timed-out upload with retryUploadMission (up to 3 times) and only reports the upload done once the operator is READY_TO_EXECUTE, and the error now says whether the upload or the start failed. Co-Authored-By: Claude Opus 5.5 --- .../com/pilotvault/flyapp/MissionBridge.kt | 41 +++++++++++++++++-- .../fly/modes/waypoints/waypoint_start.dart | 5 ++- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/Fly App/android/app/src/main/kotlin/com/pilotvault/flyapp/MissionBridge.kt b/Fly App/android/app/src/main/kotlin/com/pilotvault/flyapp/MissionBridge.kt index f3183b1..8b03de3 100644 --- a/Fly App/android/app/src/main/kotlin/com/pilotvault/flyapp/MissionBridge.kt +++ b/Fly App/android/app/src/main/kotlin/com/pilotvault/flyapp/MissionBridge.kt @@ -20,6 +20,7 @@ import dji.common.mission.waypoint.WaypointMissionFlightPathMode import dji.common.mission.waypoint.WaypointMissionGotoWaypointMode import dji.common.mission.waypoint.WaypointMissionHeadingMode import dji.common.mission.waypoint.WaypointMissionInterruption +import dji.common.mission.waypoint.WaypointMissionState import dji.common.mission.waypoint.WaypointMissionUploadEvent import dji.common.mission.waypoint.WaypointTurnMode import dji.common.model.LocationCoordinate2D @@ -417,9 +418,36 @@ class MissionBridge(private val ctx: BridgeCtx) : SubBridge { ctx.fail(result, loadErr.description) return } - // Completes once every waypoint is on the aircraft; progress arrives - // through the listener meanwhile. - op.uploadMission(ctx.completion(result)) + // Completes once every waypoint is on the aircraft and the operator is + // ready to start; progress arrives through the listener meanwhile. + uploadWithRetry(op, result, retriesLeft = UPLOAD_RETRIES) + } + + /** + * A waypoint packet that times out fails the whole upload with + * COMMON_TIMEOUT (seen on a Mavic Pro in the simulator); MSDK's answer is + * `retryUploadMission`, which resends only what is missing. + */ + private fun uploadWithRetry(op: WaypointMissionOperator, result: MethodChannel.Result, retriesLeft: Int, retry: Boolean = false) { + val done = CommonCallbacks.CompletionCallback { error -> + ctx.mainHandler.post { + when { + error == null -> whenReady(op, result, READY_WAIT_MS) + error.errorCode == DJIError.COMMON_TIMEOUT.errorCode && retriesLeft > 0 -> uploadWithRetry(op, result, retriesLeft - 1, retry = true) + else -> result.error("DJI_ERROR", error.description, null) + } + } + } + if (retry) op.retryUploadMission(done) else op.uploadMission(done) + } + + /** The upload callback can land before the state says READY_TO_EXECUTE; a start then times out. */ + private fun whenReady(op: WaypointMissionOperator, result: MethodChannel.Result, waitMs: Long) { + when { + op.currentState == WaypointMissionState.READY_TO_EXECUTE -> result.success(null) + waitMs <= 0 -> result.error("DJI_ERROR", "The aircraft never reported the route ready (${op.currentState?.name})", null) + else -> ctx.mainHandler.postDelayed({ whenReady(op, result, waitMs - READY_POLL_MS) }, READY_POLL_MS) + } } private fun startActiveTrack(call: MethodCall, result: MethodChannel.Result) { @@ -474,3 +502,10 @@ class MissionBridge(private val ctx: BridgeCtx) : SubBridge { @Volatile private var v2Active = false private val v2 = WaypointV2(ctx) { v2Active = it } } + +/** How often a timed-out waypoint upload is resent before giving up. */ +private const val UPLOAD_RETRIES = 3 + +/** How long an uploaded route may take to reach READY_TO_EXECUTE, polled every [READY_POLL_MS]. */ +private const val READY_WAIT_MS = 5000L +private const val READY_POLL_MS = 200L diff --git a/Fly App/lib/ui/fly/modes/waypoints/waypoint_start.dart b/Fly App/lib/ui/fly/modes/waypoints/waypoint_start.dart index 299c99e..b9c918f 100644 --- a/Fly App/lib/ui/fly/modes/waypoints/waypoint_start.dart +++ b/Fly App/lib/ui/fly/modes/waypoints/waypoint_start.dart @@ -39,9 +39,10 @@ Future startWaypointFlow( ), ); if (r == null) return; + bool uploaded = false; try { - await gate.startWaypointMission(spec, limits: limits, rthHeight: r.number); + await gate.startWaypointMission(spec, limits: limits, rthHeight: r.number, onUploaded: () => uploaded = true); } catch (e) { - onError('Waypoint mission', e); + onError(uploaded ? 'Waypoint start' : 'Waypoint upload', e); } }