mirror of
https://github.com/azaion/gps-denied-onboard.git
synced 2026-06-22 20:41:12 +00:00
[AZ-698] Tlog trim + mid-flight alignment for replay
Adds find_aligned_window cross-correlation (NCC, per-window unit norm)
between IMU energy and video optical-flow magnitude. Returns
AlignedWindow{tlog_start_ns, tlog_end_ns, offset_ms, confidence,
used_fallback}, with fallback to head-takeoff on low confidence to
preserve AZ-405 behavior. TlogReplayFcAdapter honors tlog_start_ns and
skips pre-window messages. New --auto-trim CLI flag, mutex with
--time-offset-ms. AC-1..AC-4 covered by unit tests; AC-5 skipped (no
real flight_derkachi.mp4 in repo). 106 tests pass in regression slice.
Zero new mypy --strict errors.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,118 +0,0 @@
|
||||
# Tlog trim + mid-flight alignment for replay
|
||||
|
||||
**Task**: AZ-698_tlog_trim_midflight_alignment
|
||||
**Name**: Trim tlog to video window + align mid-flight slices via cross-correlation
|
||||
**Description**: Extend `replay_input/auto_sync.py` and `TlogReplayFcAdapter` to handle the case where the video is a mid-flight slice of a longer tlog (not the takeoff). Adds `find_aligned_window` (cross-correlation of IMU energy vs video optical-flow magnitude) and a `--auto-trim` CLI flag.
|
||||
**Complexity**: 5 points
|
||||
**Dependencies**: AZ-697
|
||||
**Component**: replay_input + c8_fc_adapter
|
||||
**Tracker**: AZ-698
|
||||
**Epic**: AZ-696
|
||||
|
||||
## Problem
|
||||
|
||||
`replay_input/auto_sync.py::detect_tlog_takeoff` walks the tlog HEAD for
|
||||
the takeoff event (sustained vertical accel + attitude rate). When the
|
||||
uploaded video covers a **mid-flight slice** (e.g., 20–25 min into a
|
||||
30 min flight), takeoff detection lands at t=0 and the resulting offset
|
||||
is garbage. The replay coordinator then streams the entire tlog
|
||||
start-to-end, wasting I/O on the leading minutes and computing
|
||||
estimates against stale tlog samples.
|
||||
|
||||
The user's pipeline framing: "tlog is usually bigger than video, and
|
||||
usually the last chunk in tlog is relevant" — the system must locate
|
||||
the video's window within the tlog and trim accordingly.
|
||||
|
||||
## Outcome
|
||||
|
||||
- A new `find_aligned_window(tlog_path, video_path, config) -> AlignedWindow`
|
||||
returns `(tlog_start_ns, tlog_end_ns, offset_ms, confidence)`.
|
||||
- `TlogReplayFcAdapter.open()` honors `tlog_start_ns` — seeks past
|
||||
pre-window messages so downstream only sees the relevant slice.
|
||||
- `gps-denied-replay --auto-trim` is the default for uploads that don't
|
||||
pass `--time-offset-ms` or `--skip-auto-sync`.
|
||||
- Existing takeoff-aligned Derkachi clip continues to pass AC-9 (no
|
||||
regression on AZ-405).
|
||||
|
||||
## Scope
|
||||
|
||||
### Included
|
||||
- New `find_aligned_window` algorithm — cross-correlation of:
|
||||
- IMU energy stream (10 Hz subsampled `|a| − 1g` from `RAW_IMU`/`SCALED_IMU2`)
|
||||
- Video optical-flow magnitude (existing `_compute_flow_magnitudes`)
|
||||
- New `AlignedWindow` DTO under `replay_input/interface.py`.
|
||||
- `TlogReplayFcAdapter._timestamp_filter(tlog_start_ns)` seek logic.
|
||||
- `gps-denied-replay --auto-trim` CLI flag wiring.
|
||||
- Tests: takeoff-aligned regression + synthetic mid-flight scenario.
|
||||
|
||||
### Excluded
|
||||
- Real-flight validation runner — AZ-699 (T3).
|
||||
- Map visualization — AZ-700 (T4).
|
||||
- HTTP API — AZ-701 (T5).
|
||||
- Camera calibration — AZ-702 (T6).
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
**AC-1: Backward-compat on takeoff-aligned clip**
|
||||
Given the existing Derkachi 60 s clip with synthesized tlog
|
||||
When `find_aligned_window` runs
|
||||
Then it returns `offset_ms` within ± 50 ms of the current `auto_sync.compute_offset` result
|
||||
|
||||
**AC-2: Mid-flight alignment**
|
||||
Given a synthetic scenario: tlog covering 0–300 s, video covering 100–110 s with motion onset at tlog t=105 s
|
||||
When `find_aligned_window` runs
|
||||
Then `tlog_start_ns ≈ 100 s`, `tlog_end_ns ≈ 110 s`, `offset_ms` places video t=0 at tlog t=100 s
|
||||
|
||||
**AC-3: Tlog trim honored by replay adapter**
|
||||
Given `TlogReplayFcAdapter` opened with `tlog_start_ns = 100 s`
|
||||
When messages flow
|
||||
Then only messages with `_timestamp ≥ 100 s` reach subscribers
|
||||
|
||||
**AC-4: AC-9 frame-window validator passes for both scenarios**
|
||||
Given the resolved offset from AC-1 or AC-2
|
||||
When the AC-9 validator runs on the aligned window
|
||||
Then it returns 0 (≥ 95 % match)
|
||||
|
||||
**AC-5: End-to-end CLI smoke**
|
||||
Given `gps-denied-replay --auto-trim --video derkachi.mp4 --tlog derkachi.tlog`
|
||||
When the run completes
|
||||
Then exit code is 0 and the output JSONL is non-empty
|
||||
|
||||
## Non-Functional Requirements
|
||||
|
||||
**Performance**
|
||||
- Alignment over a 30-min tlog completes in < 30 s on Tier-1 hardware (10 Hz subsampled IMU stream).
|
||||
|
||||
**Reliability**
|
||||
- Low confidence (< `low_confidence_threshold`) falls back to head-takeoff detection (existing behavior).
|
||||
|
||||
## Unit Tests
|
||||
|
||||
| AC Ref | What to Test | Required Outcome |
|
||||
|--------|-------------|-----------------|
|
||||
| AC-1 | Takeoff-aligned offset match | Within ± 50 ms of compute_offset |
|
||||
| AC-2 | Mid-flight window discovery | Correct (start_ns, end_ns) |
|
||||
| AC-3 | Adapter seek skips pre-window | First emitted ts ≥ tlog_start_ns |
|
||||
| AC-4 | Validator on aligned scenarios | Returns 0 |
|
||||
|
||||
## Blackbox Tests
|
||||
|
||||
| AC Ref | Initial Data/Conditions | What to Test | Expected Behavior | NFR References |
|
||||
|--------|------------------------|-------------|-------------------|----------------|
|
||||
| AC-5 | Real derkachi inputs + --auto-trim | Full replay CLI run | Clean exit 0 + non-empty JSONL | — |
|
||||
|
||||
## Constraints
|
||||
|
||||
- Reuse the existing `_find_sustained_event` window-scan utility — no new generic algorithms.
|
||||
- IMU subsampling MUST be deterministic (AC-10 across the rest of the replay path).
|
||||
- `tlog_start_ns` seek MUST not break the existing AZ-611 `--skip-auto-sync` path.
|
||||
|
||||
## Risks & Mitigation
|
||||
|
||||
**Risk 1: False maxima during steady cruise**
|
||||
- *Risk*: Cross-correlation of steady-state cruise IMU + uniform video flow can have multiple equal-height peaks.
|
||||
- *Mitigation*: Report `combined_confidence`; below threshold falls back to head-takeoff or explicit offset.
|
||||
|
||||
**Risk 2: Performance on long tlogs**
|
||||
- *Risk*: Multi-hour tlogs would slow naive correlation.
|
||||
- *Mitigation*: Subsample both streams to 10 Hz before FFT-based correlation.
|
||||
Reference in New Issue
Block a user