mirror of
https://github.com/azaion/gps-denied-onboard.git
synced 2026-06-22 21:41:13 +00:00
[AZ-420] Batch 81: FT-P-12 + FT-P-13 GCS scenarios
FT-P-12: parse mavproxy-listener tlog over a 60 s Derkachi replay and assert SUT->GCS GLOBAL_POSITION_INT cadence lands in [1, 2] Hz (AC-6.1). FT-P-13: inject `RELOC:<lat>,<lon>,<radius_m>` STATUSTEXT while the SUT is in dead_reckoned; verify FDR `c8.gcs.operator_command` ack <=2s, `anchor_search_region` centre shifts toward the hint, and no BAD_SIGNATURE / UNAUTHORIZED / REJECTED STATUSTEXT lands in the post-inject window (AC-6.2). Adds runner.helpers.gcs_telemetry_evaluator (rate, hint-ack correlation, haversine search-region shift, rejection scan) and sitl_observer.capture_gcs_tlog (parity surface to capture_ap_tlog). Pure-logic coverage: 39 new unit tests; full e2e/_unit_tests/ suite 746 passing (was 700). Scenarios skip locally on missing SITL replay fixture; production hooks (inbound STATUSTEXT parser, anchor_search_region FDR emitter) tracked outside this task. See _docs/03_implementation/batch_81_report.md + reviews/batch_81_review.md. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -29,6 +29,8 @@ Fixture file naming (under `${E2E_SITL_REPLAY_DIR}/`):
|
||||
{messages: [{image_id?, lat_deg, lon_deg} | null, ...]}
|
||||
* `ap_parameters_<host>.json` — {<param_name>: <value>, ...}
|
||||
* `ap_tlog_<host>.tlog` — raw mavproxy tlog (any binary content)
|
||||
* `gcs_tlog_<host>.tlog` — raw mavproxy-listener tlog from the GCS link
|
||||
(SUT→GCS summary stream + GCS→SUT operator commands; FT-P-12, FT-P-13)
|
||||
* `inav_handshake_<host>.json` — {established_within_s: float | None}
|
||||
* `inav_msp_frames_<host>.json` — {frames: [...], expected_num_sat: int}
|
||||
* `inav_gps_state_<host>.json` — {fix_type, num_sat, provider}
|
||||
@@ -418,6 +420,35 @@ def capture_ap_tlog(host: str, duration_s: float) -> Path:
|
||||
return path
|
||||
|
||||
|
||||
def capture_gcs_tlog(host: str, duration_s: float) -> Path:
|
||||
"""Return the path to the GCS-side mavproxy-listener tlog for ``host``.
|
||||
|
||||
Fixture: ``${E2E_SITL_REPLAY_DIR}/gcs_tlog_<host>.tlog``. The tlog
|
||||
captures both directions over the QGC GCS link — SUT→GCS summary
|
||||
bursts (``GLOBAL_POSITION_INT`` + ``NAMED_VALUE_FLOAT``) and
|
||||
GCS→SUT operator commands (``STATUSTEXT`` reloc-hints,
|
||||
``COMMAND_LONG`` parameter reads, etc.).
|
||||
|
||||
``duration_s`` is recorded for future live-mode use but ignored here
|
||||
— under FDR-replay the fixture file IS the captured stream.
|
||||
|
||||
Raises ``RuntimeError`` if env var unset or fixture missing.
|
||||
"""
|
||||
if duration_s <= 0:
|
||||
raise RuntimeError(f"capture_gcs_tlog: duration_s must be positive; got {duration_s}")
|
||||
root = replay_dir()
|
||||
if root is None:
|
||||
raise RuntimeError(
|
||||
f"capture_gcs_tlog: {_ENV_VAR} env var not set"
|
||||
)
|
||||
path = root / f"gcs_tlog_{host}.tlog"
|
||||
if not path.exists():
|
||||
raise RuntimeError(
|
||||
f"capture_gcs_tlog: fixture not found at {path}"
|
||||
)
|
||||
return path
|
||||
|
||||
|
||||
# read_ap_parameter — reads from param-dump JSON
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user