mirror of
https://github.com/azaion/gps-denied-onboard.git
synced 2026-06-22 20:41:12 +00:00
[AZ-405] Replay — replay_input/ coordinator + IMU take-off auto-sync
Adds the Layer-4 cross-cutting `replay_input/` module per ADR-011: ReplayInputAdapter converges (video, tlog) into the standard FrameSource + FcAdapter + Clock surfaces the airborne composition root consumes. Owns time-alignment between video frames and tlog IMU/attitude ticks (manual via --time-offset-ms or auto via the AZ-405 IMU-take-off detector + Farneback motion-onset detector). Auto-sync algorithm (auto_sync.py): - Tlog take-off detector: sustained vertical-accel excess > 0.5 g for >= 0.5 s + sustained attitude-rate magnitude > 1 rad/s. - Video motion-onset detector: dense Farneback flow magnitude > 1.5 px sustained >= 0.5 s (deterministic per AC-10). - compute_offset combines the two; confidence = min(tlog, video). - validate_offset_or_fail implements the AC-9 95 % frame-window match validator with configurable threshold + window. ReplayInputAdapter.open() ordering (AC-13): 1. Load tlog samples + fail-fast on missing RAW_IMU/SCALED_IMU2 or ATTITUDE BEFORE any video read. 2. Resolve offset (auto-sync OR manual override; manual bypasses the detectors entirely per AC-8). 3. Run AC-9 validator on resolved offset; raise auto-sync hard-fail for AC-7 (CLI exit 2 mapping). 4. Build single Clock instance per pace (TlogDerived/ASAP, Wall/REAL). 5. Construct VideoFileFrameSource and TlogReplayFcAdapter with the resolved offset baked in (replay protocol Invariant 8). Structured log + FDR records on auto-sync detected / low-confidence / AC-8 hard-fail kinds. Idempotent close (AC-12). Tests: 25 unit tests across tests/unit/replay_input/ covering all 13 ACs (kernel-level synthetic fixtures for AC-1..AC-10; coordinator- level OpenCV synthetic videos + faked pymavlink for AC-6..AC-13). Contract update: replay_protocol.md v2.0.0 added fdr_client to the ReplayInputAdapter __init__ signature (was missing in the prose; the task spec already listed it in the allowed-imports section). Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
"""``replay_input/`` cross-cutting coordinator (AZ-405 / E-DEMO-REPLAY).
|
||||
|
||||
Layer-4 module per ``_docs/02_document/module-layout.md``. Converges
|
||||
``(video, tlog)`` inputs into the standard :class:`FrameSource`,
|
||||
:class:`FcAdapter`, and :class:`Clock` surfaces consumed by the
|
||||
airborne composition root. Owns the time-alignment concern between
|
||||
video frames and tlog IMU/attitude ticks (manual via
|
||||
``--time-offset-ms`` or automatic via the AZ-405 IMU-take-off
|
||||
detector).
|
||||
|
||||
New under ADR-011 (replay-as-configuration) — replaces the v1.0.0
|
||||
design where replay had its own composition root.
|
||||
|
||||
Public surface re-exports the coordinator class, the bundle DTO, the
|
||||
auto-sync decision DTO, the auto-sync config DTO, and the coordinator
|
||||
error class. The detector functions in :mod:`auto_sync` are NOT
|
||||
re-exported here so the public API stays focused on the composition
|
||||
root's wiring needs; tests import the detectors via their full module
|
||||
path.
|
||||
"""
|
||||
|
||||
from gps_denied_onboard.replay_input.errors import ReplayInputAdapterError
|
||||
from gps_denied_onboard.replay_input.interface import (
|
||||
AutoSyncConfig,
|
||||
AutoSyncDecision,
|
||||
ReplayInputBundle,
|
||||
)
|
||||
from gps_denied_onboard.replay_input.tlog_video_adapter import ReplayInputAdapter
|
||||
|
||||
__all__ = [
|
||||
"AutoSyncConfig",
|
||||
"AutoSyncDecision",
|
||||
"ReplayInputAdapter",
|
||||
"ReplayInputAdapterError",
|
||||
"ReplayInputBundle",
|
||||
]
|
||||
Reference in New Issue
Block a user