From 07d47f99a4468c09a541a5e93a724e7192e4471b Mon Sep 17 00:00:00 2001 From: Jay Date: Mon, 17 Aug 2026 10:25:29 -0400 Subject: [PATCH] report sensor freshness in captures --- docs/axis-validation-2026-08-16.md | 6 ++++-- tools/capture_serial.py | 34 ++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/docs/axis-validation-2026-08-16.md b/docs/axis-validation-2026-08-16.md index bf06155..f514715 100644 --- a/docs/axis-validation-2026-08-16.md +++ b/docs/axis-validation-2026-08-16.md @@ -54,5 +54,7 @@ in firmware. - Earlier side-to-side orientation changes were Y-dominant, confirming the remaining gyro axis. -The mounted sensor axes and the firmware's enclosure-frame mapping are -consistent. +The mounted sensor axes and the firmware's enclosure-frame axis assignments are +consistent. These tests established the dominant gyro axis but did not establish +gyro polarity; directed positive and negative rotations remain part of the +calibration pass. diff --git a/tools/capture_serial.py b/tools/capture_serial.py index b9152af..21e20f9 100644 --- a/tools/capture_serial.py +++ b/tools/capture_serial.py @@ -30,6 +30,15 @@ EXPECTED_COLUMNS = [ "loop_overrun_count", ] +ACCEL_STATUS_INDEX = EXPECTED_COLUMNS.index("accel_int_source") +GYRO_STATUS_INDEX = EXPECTED_COLUMNS.index("gyro_status") +LOOP_OVERRUN_INDEX = EXPECTED_COLUMNS.index("loop_overrun_count") + +ACCEL_DATA_READY_MASK = 0x80 +ACCEL_OVERRUN_MASK = 0x01 +GYRO_DATA_READY_MASK = 0x08 +GYRO_OVERRUN_MASK = 0x80 + def parse_args() -> argparse.Namespace: parser = argparse.ArgumentParser() @@ -85,6 +94,11 @@ def main() -> int: timing_anomaly_count = 0 ignored_line_count = 0 rejected_record_count = 0 + accel_stale_count = 0 + accel_overrun_count = 0 + gyro_stale_count = 0 + gyro_overrun_count = 0 + final_loop_overrun_count = 0 previous_sequence = None previous_timestamp_us = None print(f"Recording {port} to {output}; press Ctrl-C to stop", flush=True) @@ -123,6 +137,19 @@ def main() -> int: sequence = values[0] timestamp_us = values[1] + accel_status = values[ACCEL_STATUS_INDEX] + gyro_status = values[GYRO_STATUS_INDEX] + final_loop_overrun_count = values[LOOP_OVERRUN_INDEX] + + if not accel_status & ACCEL_DATA_READY_MASK: + accel_stale_count += 1 + if accel_status & ACCEL_OVERRUN_MASK: + accel_overrun_count += 1 + if not gyro_status & GYRO_DATA_READY_MASK: + gyro_stale_count += 1 + if gyro_status & GYRO_OVERRUN_MASK: + gyro_overrun_count += 1 + if previous_sequence is not None: expected_sequence = (previous_sequence + 1) & 0xFFFFFFFF if sequence != expected_sequence: @@ -159,6 +186,13 @@ def main() -> int: f"saved {output}", flush=True, ) + print( + f"Status totals: accel_stale={accel_stale_count}, " + f"accel_overrun={accel_overrun_count}, gyro_stale={gyro_stale_count}, " + f"gyro_overrun={gyro_overrun_count}, " + f"acquisition_loop_overruns={final_loop_overrun_count}", + flush=True, + ) return 0