# Performance Tests All performance tests honor the per-tier execution profile from `environment.md`. Latency and memory tests bound to Jetson Orin Nano Super hardware run on Tier-2 only; metrics that don't depend on hardware (e.g. inter-emit interval correctness, GCS rate) run on both tiers. ### NFT-PERF-01: End-to-end latency p95 budget **Summary**: Validates the AC-4.1 end-to-end latency budget (camera capture → GPS to FC) on the pinned hardware. **Traces to**: AC-4.1, D-CROSS-LATENCY-1 **Metric**: Wall-clock latency from frame-capture timestamp to outbound `GPS_INPUT` (AP) / `MSP2_SENSOR_GPS` (iNav) reception at the SITL container. **Preconditions**: - Tier-2 only — Jetson Orin Nano Super, JetPack 6.2, TensorRT 10.3 per D-C7-9. - `tile-cache-fixture` pre-loaded. - SUT cold-started THEN warmed up for 30 s of replay before measurement window starts. - Two configurations measured: (a) `K=3` baseline at +25 °C, (b) `K=2 + Jacobian-cov` hybrid auto-degrade at +50 °C ambient (NFT-9 in the solution draft). **Steps**: | Step | Consumer Action | Measurement | |------|----------------|-------------| | 1 | Run 30 s warm-up replay (excluded from measurement) | none | | 2 | Run 5 min Derkachi replay at 3 Hz target cadence | per-frame latency: `t_emit_at_sitl − t_capture` | | 3 | Record per-frame latency to CSV; compute p50, p95, p99 | distribution | | 4 | Repeat at +50 °C ambient (chamber if available, else flagged) | distribution under thermal-throttle hybrid | **Pass criteria**: - (a) `K=3` baseline: p95 ≤ 400 ms (AC-4.1 hard bound). - (b) `K=2 + Jacobian-cov` hybrid: p95 ≤ 400 ms still satisfied after auto-degrade (proves D-CROSS-LATENCY-1 effective). - ≤10% frame drops under sustained load (AC-4.1 allowance). - Per-stage latency partitioning (D-CROSS-LATENCY-1 table) recorded for all stages: C1 OKVIS2 / C2 UltraVPR / C2.5 / C3 / C3.5 / C4 / C4 cov / C5 / serialization / OS jitter — used in NFT-PERF-01 evidence bundle for budget-margin tracking. **Duration**: 2 × 5.5 min replays (warm-up + measurement) per configuration; ~25 min total per FC adapter. --- ### NFT-PERF-02: Frame-by-frame streaming (no batching) **Summary**: Validates AC-4.4 — estimates streamed frame-by-frame with no batching/delay. **Traces to**: AC-4.4 **Metric**: Inter-emit interval at SITL. **Preconditions**: - Tier-1 OR Tier-2. - SUT warmed up for 30 s. **Steps**: | Step | Consumer Action | Measurement | |------|----------------|-------------| | 1 | Replay Derkachi 5 min at 3 Hz | per-frame inter-emit interval at SITL | | 2 | Compute distribution | p95 of inter-emit interval | **Pass criteria**: p95 inter-emit interval ≤ inter-frame-interval × 1.05 (i.e. ≤ ~350 ms at 3 Hz target). No window of ≥3 missed-emit gaps. **Duration**: 6 min. --- ### NFT-PERF-03: Cold-start TTFF **Summary**: Validates AC-NEW-1 cold-start time-to-first-fix from companion boot. **Traces to**: AC-NEW-1 **Metric**: Wall-clock from SUT container-ready event (or `systemctl start` on Tier-2) to first valid outbound `GPS_INPUT` / `MSP2_SENSOR_GPS` arrival at SITL. **Preconditions**: - Tier-2 (Jetson) for the canonical run; Tier-1 acceptable for trend-tracking. - `cold-boot-fixture` provides the FC EKF snapshot (loaded into SITL before the SUT cold boot). - `tile-cache-fixture` already mounted (cache-load is part of the TTFF budget per AC-NEW-1 wording "from boot"). - 50 cold boots executed back-to-back to populate distribution. **Steps**: | Step | Consumer Action | Measurement | |------|----------------|-------------| | 1 | Stop SUT; clear in-memory state | container down | | 2 | Start SUT (record `t_start`) | timestamp | | 3 | First outbound message arrives at SITL (record `t_first_emit`) | TTFF = `t_first_emit − t_start` | | 4 | Repeat 50 times | distribution | **Pass criteria**: p95 TTFF < 30 s. **Duration**: ~30 min (50 × ~30 s + restart overhead). --- ### NFT-PERF-04: Spoofing-promotion latency **Summary**: Validates AC-NEW-2 — when FC signals GPS denial/spoof, promote onboard estimate to FC's primary position source within < 3 s p95. **Traces to**: AC-NEW-2 **Metric**: Latency from spoof-onset signal to FC-side EKF source-set switch (AP: `EK3_SRC1_POSXY` flips to companion-source value; iNav: GPS provider state reflects companion as primary). **Preconditions**: - Tier-1 acceptable (mostly software loops + SITL). - `derkachi-fixture` running with SUT in `satellite_anchored` steady state. - Spoof injector primed. **Steps**: | Step | Consumer Action | Measurement | |------|----------------|-------------| | 1 | Inject false GPS into FC SITL (record `t_spoof_onset`) | timestamp | | 2 | Observe FC EKF source-set state via parameter read polling at 100 Hz (record `t_promotion`) | promotion latency = `t_promotion − t_spoof_onset` | | 3 | Repeat 50 trials per FC (parameterized on `ardupilot` + `inav`) | distribution per FC | **Pass criteria**: p95 < 3 s on both FCs. **Duration**: ~25 min per FC (50 trials × ~30 s including pre-trial reset). --- ### Per-stage latency partition record (informational, not pass/fail) NFT-PERF-01 captures per-stage latencies matching the D-CROSS-LATENCY-1 partition table from `solution.md`. The recorded targets are tracked for budget-margin trend (regression detector), not as independent pass/fail thresholds — only AC-4.1 p95 ≤ 400 ms is the hard gate. | Stage | K=3 target p95 | K=2 hybrid target p95 | |-------|---------------|----------------------| | C1 OKVIS2 VIO | ≤ 60 ms | ≤ 60 ms | | C2 UltraVPR query | ≤ 15 ms | ≤ 15 ms | | C2.5 Top-N re-rank | ≤ 80 ms | ≤ 80 ms | | C3 DISK+LightGlue × N | ≤ 200 ms (steady) | ≤ 140 ms (thermal) | | C3.5 AdHoP (conditional, p99) | ≤ 100 ms when triggered | ≤ 60 ms when triggered | | C4 solvePnPRansac | ≤ 25 ms | ≤ 25 ms | | C4 covariance recovery | ≤ 100 ms (steady) | ≤ 25 ms (thermal) | | C5 iSAM2 update | ≤ 15 ms | ≤ 15 ms | | MAVLink/MSP2 + UART/USB | ≤ 30 ms | ≤ 30 ms | | OS scheduling jitter (p99) | ≤ 50 ms | ≤ 50 ms |