feat(gps): add timer-based assisted reacquisition
Remove the fixed pseudorange start offset, preserve per-PRN navigation assistance across RF loss and power cycles, and seed coherent navigation measurement phase on reacquisition. Add full LNAV almanac visibility scheduling, power-safe QSPI journaling, RF-domain reset isolation, and PPS Gray CDC hardening with Linux, sanitizer, RTL, and end-to-end coverage.
This commit is contained in:
@@ -22,7 +22,6 @@ try:
|
||||
DEFAULT_IONO,
|
||||
POSTPONE_TOW_S,
|
||||
RF_HZ,
|
||||
START_OFFSET_S,
|
||||
TRACKING_HZ,
|
||||
ReceiverEpochSimulator,
|
||||
build_clock_trajectory,
|
||||
@@ -41,7 +40,6 @@ except ImportError: # allow: python3 pps_python/simulate_pps.py
|
||||
DEFAULT_IONO,
|
||||
POSTPONE_TOW_S,
|
||||
RF_HZ,
|
||||
START_OFFSET_S,
|
||||
TRACKING_HZ,
|
||||
ReceiverEpochSimulator,
|
||||
build_clock_trajectory,
|
||||
@@ -321,7 +319,7 @@ def simulate_startup_tow(
|
||||
"first_flight_s": first_flight,
|
||||
# Parsed HOW labels transmit subframe time, not receive-now.
|
||||
"how_as_receive_error_s": -(POSTPONE_TOW_S + first_flight),
|
||||
"how_plus_pipeline_startoffset_error_s": START_OFFSET_S - first_flight,
|
||||
"how_plus_pipeline_without_wls_error_s": -first_flight,
|
||||
"wls_aligned_error_s": wls_error,
|
||||
# Old receive reference written as if it were valid at APB-now.
|
||||
"apb_now_error_s": wls_error - sampled_latency,
|
||||
@@ -349,13 +347,13 @@ def plot_startup_tow(output_dir: Path, startup: dict[str, np.ndarray]) -> None:
|
||||
axes[0, 1].grid(True, alpha=0.3)
|
||||
|
||||
axes[1, 0].hist(
|
||||
startup["how_plus_pipeline_startoffset_error_s"] * 1.0e3,
|
||||
startup["how_plus_pipeline_without_wls_error_s"] * 1.0e3,
|
||||
bins=35,
|
||||
color="tab:orange",
|
||||
alpha=0.8,
|
||||
)
|
||||
axes[1, 0].set_xlabel("Phase error [ms]")
|
||||
axes[1, 0].set_title("Provisional: HOW + 180 ms + 68.802 ms")
|
||||
axes[1, 0].set_title("Still wrong: HOW + 180 ms without WLS flight time")
|
||||
axes[1, 0].grid(True, alpha=0.3)
|
||||
|
||||
axes[1, 1].hist(
|
||||
@@ -398,7 +396,7 @@ def build_summary(
|
||||
f"derived GPS reference RMS error: {finite_rms(timing_error)*1e9:.3f} ns",
|
||||
f"capture-to-commit delay mean/p99: {np.mean(latency)*1e3:.3f} / {np.percentile(latency, 99)*1e3:.3f} ms",
|
||||
f"first HOW used as receive-now, median phase error: {np.median(startup['how_as_receive_error_s'])*1e3:.3f} ms",
|
||||
f"first HOW + 180 ms + 68.802 ms, median phase error: {np.median(startup['how_plus_pipeline_startoffset_error_s'])*1e3:.3f} ms",
|
||||
f"first HOW + 180 ms without WLS, median phase error: {np.median(startup['how_plus_pipeline_without_wls_error_s'])*1e3:.3f} ms",
|
||||
]
|
||||
for start, stop, label in [
|
||||
(0.0, 20.0, "4 satellites"),
|
||||
@@ -426,8 +424,8 @@ def build_summary(
|
||||
[
|
||||
"",
|
||||
"Interpretation:",
|
||||
"- bias/c is millisecond-scale because it contains the 68.802 ms synthetic datum and the minimum satellite path.",
|
||||
"- epoch-aligned TOW (first delivery: HOW + 180 ms) + STARTOFFSET - bias/c reconstructs GPS time at the paired timestamp.",
|
||||
"- bias/c is millisecond-scale because the timer-difference datum contains the negative reference-satellite path.",
|
||||
"- epoch-aligned TOW (first delivery: HOW + 180 ms) - bias/c reconstructs GPS time at the paired timestamp.",
|
||||
"- treating that old reference as valid at APB arrival converts software latency into PPS phase error.",
|
||||
"- timestamping removes that phase misassociation; control application delay remains only as loop delay.",
|
||||
"- baremetal applies the fixed 180 ms readout correction once; the PPS peripheral must not add it again.",
|
||||
|
||||
Reference in New Issue
Block a user