From e114bfd9b8ab1ea4e7082f4cc82460c380af575e Mon Sep 17 00:00:00 2001 From: Oleksandr Bezdieniezhnykh Date: Mon, 18 May 2026 08:24:37 +0300 Subject: [PATCH] [AZ-614] tlog synth: anchor at t=0 to align with video time-base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Derkachi auto-sync coordinator compares absolute tlog timestamps (from pymavlink's 8-byte record header) against absolute video timestamps (CAP_PROP_POS_MSEC, which starts at 0). Anchoring the synthetic tlog at 1_700_000_000_000_000 us (2023-11-14) produced a ~53-year offset (offset_ms=1699999995666) that always tripped the AC-9 frame-window match validator at 0% match. Setting the base to 0 puts the tlog on the same axis as the video (and matches the CSV's `Time` column, which is seconds since row 0 per `_docs/00_problem/input_data/flight_derkachi/README.md`: "the video and telemetry align at exactly three video frames per telemetry row"). Verified on Colima with GPS_DENIED_TIER=2: the offset reported by the auto-sync coordinator drops from 1699999995666 ms to -4334 ms. The remaining 4.3 s offset is NOT a synth issue — it's the tlog take-off detector (no signal in the steady-cruise CSV → defaults to samples.accel[0][0] == 0) vs the video motion-onset detector (which fires on a scenery-contrast false positive at ~4.3 s). The synth cannot fabricate a take-off spike at the right time without knowing the video motion-onset moment a priori, and the README confirms the fixture is mid-flight footage with no take-off in either signal. Resolving the remaining 4.3 s mismatch requires SUT-side work to honor the documented "manual offset bypasses auto-sync" contract — that's the scope of AZ-611. Filed as a known limitation in the commit message; AC-1..AC-6 still red until AZ-611 lands. Co-authored-by: Cursor --- tests/e2e/replay/_tlog_synth.py | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/tests/e2e/replay/_tlog_synth.py b/tests/e2e/replay/_tlog_synth.py index 0791181..ca7ad71 100644 --- a/tests/e2e/replay/_tlog_synth.py +++ b/tests/e2e/replay/_tlog_synth.py @@ -53,13 +53,21 @@ SOURCE_SYSTEM: Final[int] = 1 # vehicle id (any non-zero stable integer) SOURCE_COMPONENT: Final[int] = mavlink.MAV_COMP_ID_AUTOPILOT1 _HEARTBEAT_PERIOD_S: Final[float] = 1.0 # tlog timestamp epoch — pymavlink stores absolute microseconds. The -# Derkachi CSV's ``timestamp(ms)`` field is a flight-controller boot -# clock, not Unix epoch. We anchor the synthetic tlog at a fixed -# Unix-epoch base so the timestamps are monotonically increasing and -# greater than the MAVLink2-required minimum (2015 cutoff). The -# absolute value is irrelevant for replay-mode determinism; only the -# delta-between-rows matters. -_TLOG_BASE_TIMESTAMP_US: Final[int] = 1_700_000_000_000_000 # 2023-11-14 22:13:20 UTC +# synthetic tlog must use the SAME time-base as the Derkachi video +# (CAP_PROP_POS_MSEC, which starts at 0) because the AZ-405 auto-sync +# coordinator computes ``offset_ns = tlog_takeoff_ns - video_motion_onset_ns`` +# from absolute timestamps. Anchoring the tlog at a Unix epoch (the +# pre-AZ-614 default of 2023-11-14) produced a ~53-year offset that +# always tripped the AC-9 frame-window validator (frame-window match +# 0% < 95% threshold) and hard-failed AC-1 / AC-2 / AC-5 / AC-6. +# +# Anchoring at 0 places the tlog on the same axis as the video and +# also matches the CSV's ``Time`` column (column 2, seconds since +# row 0). pymavlink's binary record format accepts unsigned 64-bit +# microseconds and has no lower bound on the absolute value — the +# 2015-cutoff mentioned in the pre-AZ-614 comment was a misreading +# of the MAVLink protocol spec. +_TLOG_BASE_TIMESTAMP_US: Final[int] = 0 def synthesize_tlog(csv_path: Path, tlog_path: Path) -> int: