Implement Galileo E1B I/NAV navigation decoding
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.mark.signalsim
|
||||
def test_four_satellites_are_navigation_ready_without_truth_inputs() -> None:
|
||||
path = Path("reports/navigation_run/inav_collection_report.json")
|
||||
if not path.is_file():
|
||||
pytest.skip("SignalSim multi-satellite navigation collection report is unavailable")
|
||||
report = json.loads(path.read_text(encoding="utf-8"))
|
||||
assert report["decoder_truth_inputs"] == []
|
||||
ready = [
|
||||
item for item in report["satellites"].values()
|
||||
if item["complete_ephemeris"] and item["clock_parameters"] and item["health_valid"] and item["data_valid"]
|
||||
]
|
||||
assert len(ready) >= 4
|
||||
assert report["galileo_time"]["valid"] is True
|
||||
assert report["navigation_ready"] is True
|
||||
@@ -0,0 +1,20 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.mark.signalsim
|
||||
def test_signalsim_decoded_ephemerides_match_rinex_truth_within_quantization() -> None:
|
||||
path = Path("reports/inav_truth_comparison.json")
|
||||
if not path.is_file():
|
||||
pytest.skip("post-decode SignalSim truth-comparison report is unavailable")
|
||||
report = json.loads(path.read_text(encoding="utf-8"))
|
||||
assert report["truth_injected_into_decoder"] is False
|
||||
assert report["overall_pass"] is True
|
||||
assert len(report["satellites"]) >= 4
|
||||
assert all(item["pass"] for item in report["satellites"].values())
|
||||
assert report["galileo_time"]["pass"] is True
|
||||
assert report["galileo_time"]["time_of_week_absolute_error_s"] <= 1
|
||||
@@ -0,0 +1,19 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from galileo_rx.navigation.decoder_diagnostics import load_prompt_epochs
|
||||
from galileo_rx.navigation.inav_pipeline import InavNavigationPipeline
|
||||
|
||||
|
||||
@pytest.mark.signalsim
|
||||
def test_signalsim_prompts_produce_crc_valid_inav_pages() -> None:
|
||||
path = Path("verification/navigation/signalsim_navigation_multisat/prn_01/prompt_epochs.npz")
|
||||
if not path.is_file():
|
||||
pytest.skip("SignalSim navigation prompt artifact is unavailable; run collect-navigation first")
|
||||
decoded = InavNavigationPipeline(1).process(load_prompt_epochs(path, 1))
|
||||
assert len(decoded.pages) == 15
|
||||
assert all(page.sync_valid and page.fec_valid and page.crc_valid for page in decoded.pages)
|
||||
assert {word.word_type for word in decoded.words} == {1, 2, 3, 4, 5, 6}
|
||||
@@ -0,0 +1,23 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
from galileo_rx.navigation.decoder_diagnostics import load_prompt_epochs
|
||||
from galileo_rx.navigation.e1b_symbol_sync import E1BSymbolSynchronizer
|
||||
|
||||
|
||||
@pytest.mark.signalsim
|
||||
def test_signalsim_prompt_artifact_recovers_soft_and_hard_symbols() -> None:
|
||||
path = Path("verification/navigation/signalsim_navigation_multisat/prn_01/prompt_epochs.npz")
|
||||
if not path.is_file():
|
||||
pytest.skip("SignalSim navigation prompt artifact is unavailable; run collect-navigation first")
|
||||
prompts = load_prompt_epochs(path, 1)
|
||||
symbols = E1BSymbolSynchronizer(8, 0.1).process_many(prompts)
|
||||
soft = np.asarray([item.soft_value for item in symbols], dtype=np.float64)
|
||||
assert soft.dtype == np.float64
|
||||
assert len(symbols) == 8044
|
||||
assert np.count_nonzero([item.valid for item in symbols]) > 7500
|
||||
assert {item.hard_value for item in symbols} == {0, 1}
|
||||
Reference in New Issue
Block a user