Log simulator starts, stops and diagnostics to a file on the tablet
The Mavic Pro simulator closes by itself every 3-11 minutes and logcat on the dev tablet rolls over before it can be read. SimLog appends the simulator's on/off changes (with the flight state at that moment), the app's own start and stop commands, and every diagnostics change to files/sim_log.txt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e3917e6f25
commit
727850bb0e
3 files changed
+51
-2
No files matched your search
@@ -33,6 +33,7 @@ class DiagnosticsBridge(private val ctx: BridgeCtx) : SubBridge {
|
||||
ctx.mainHandler.post {
|
||||
if (items == last) return@post
|
||||
last = items
|
||||
SimLog.write(ctx.appContext, "diagnostics: " + items.joinToString(" | ") { "${it["code"]} ${it["reason"]}" })
|
||||
ctx.emit(mapOf("type" to "diagnostics", "items" to items))
|
||||
}
|
||||
}
|
||||
|
||||
+18
-2
@@ -25,6 +25,9 @@ import kotlin.math.sqrt
|
||||
*/
|
||||
class FlightControllerBridge(private val ctx: BridgeCtx) : SubBridge {
|
||||
|
||||
/** The simulator state last seen, so [SimLog] records only its changes. */
|
||||
@Volatile private var lastSimulatorActive: Boolean? = null
|
||||
|
||||
private fun fc(): FlightController? = ctx.aircraft()?.flightController
|
||||
|
||||
override fun handle(call: MethodCall, result: MethodChannel.Result): Boolean {
|
||||
@@ -58,10 +61,12 @@ class FlightControllerBridge(private val ctx: BridgeCtx) : SubBridge {
|
||||
call.argument<Int>("updateFrequency") ?: 10,
|
||||
call.argument<Int>("satelliteCount") ?: 12,
|
||||
)
|
||||
SimLog.write(ctx.appContext, "app: startSimulator")
|
||||
sim.start(data, ctx.completion(result))
|
||||
}
|
||||
}
|
||||
"stopSimulator" -> guard(controller, result) {
|
||||
SimLog.write(ctx.appContext, "app: stopSimulator")
|
||||
val sim = it.simulator
|
||||
if (sim == null) ctx.fail(result, "Simulator unavailable on this aircraft")
|
||||
else sim.stop(ctx.completion(result))
|
||||
@@ -135,8 +140,19 @@ class FlightControllerBridge(private val ctx: BridgeCtx) : SubBridge {
|
||||
if (product !is Aircraft) return
|
||||
val controller = product.flightController ?: return
|
||||
controller.setStateCallback { state ->
|
||||
val values = telemetry(state) + compass(controller) +
|
||||
("simulatorActive" to (try { controller.simulator?.isSimulatorActive } catch (_: Throwable) { null }))
|
||||
val sim = try { controller.simulator?.isSimulatorActive } catch (_: Throwable) { null }
|
||||
if (sim != null && sim != lastSimulatorActive) {
|
||||
if (lastSimulatorActive != null || sim) {
|
||||
SimLog.write(
|
||||
ctx.appContext,
|
||||
"simulator ${if (sim) "ON" else "OFF"}: mode=${state.flightModeString} flying=${state.isFlying} " +
|
||||
"motors=${state.areMotorsOn()} alt=${state.aircraftLocation?.altitude} sats=${state.satelliteCount} " +
|
||||
"flightTime=${state.flightTimeInSeconds}s goHome=${state.goHomeExecutionState}",
|
||||
)
|
||||
}
|
||||
lastSimulatorActive = sim
|
||||
}
|
||||
val values = telemetry(state) + compass(controller) + ("simulatorActive" to sim)
|
||||
ctx.mainHandler.post { ctx.hub.putFast(values) }
|
||||
}
|
||||
// Magnetic interference per compass (P6b's interference meter): the
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.pilotvault.flyapp
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import java.io.File
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
|
||||
/**
|
||||
* A small file log for the simulator closing by itself (Mavic Pro, every
|
||||
* 3–11 min, cause unknown): simulator starts/stops with the flight state at
|
||||
* that moment, and every diagnostics change. logcat on the dev tablet rolls
|
||||
* over within minutes, so this lives in the app's files dir (`sim_log.txt`,
|
||||
* capped at [MAX_BYTES]) and is read with `run-as … cat files/sim_log.txt`.
|
||||
*/
|
||||
object SimLog {
|
||||
private const val FILE = "sim_log.txt"
|
||||
private const val MAX_BYTES = 512 * 1024
|
||||
private val time = SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.ROOT)
|
||||
|
||||
fun write(context: Context, line: String) {
|
||||
Log.w("PVSim", line)
|
||||
try {
|
||||
val f = File(context.filesDir, FILE)
|
||||
if (f.length() > MAX_BYTES) f.delete()
|
||||
synchronized(this) { f.appendText("${time.format(Date())} $line\n") }
|
||||
} catch (_: Throwable) {
|
||||
// Logging must never break a flight.
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user