Implement Galileo E1B I/NAV navigation decoding
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import numpy as np
|
||||
|
||||
from galileo_rx.navigation.e1b_prompt_stream import E1BPromptEpoch
|
||||
from galileo_rx.navigation.e1b_symbol_sync import E1BSymbolSynchronizer
|
||||
|
||||
|
||||
def _epoch(index: int, sign: int, *, slip: bool = False) -> E1BPromptEpoch:
|
||||
start = index * 16
|
||||
prompt = sign * np.exp(1j * 0.37)
|
||||
return E1BPromptEpoch(
|
||||
1, start, start + 16, float(prompt.real), float(prompt.imag), 0.0, 1000.0, 0.0,
|
||||
50.0, True, True, slip, False, True,
|
||||
)
|
||||
|
||||
|
||||
def test_symbol_sync_preserves_global_polarity_ambiguity() -> None:
|
||||
truth = np.asarray([1, -1] * 12, dtype=np.int8)
|
||||
synchronizer = E1BSymbolSynchronizer(minimum_axis_epochs=4, minimum_confidence=0.9)
|
||||
symbols = synchronizer.process_many([_epoch(i, int(-value)) for i, value in enumerate(truth)])
|
||||
hard = np.asarray([item.hard_value for item in symbols[4:]], dtype=np.int8)
|
||||
# Either polarity is valid here; page synchronization resolves it later.
|
||||
expected_bits = (truth[4:] > 0).astype(np.int8)
|
||||
assert np.array_equal(hard, expected_bits) or np.array_equal(hard, 1 - expected_bits)
|
||||
assert all(not item.inverted for item in symbols)
|
||||
|
||||
|
||||
def test_cycle_slip_invalidates_and_restarts_axis_lock() -> None:
|
||||
sync = E1BSymbolSynchronizer(minimum_axis_epochs=3, minimum_confidence=0.1)
|
||||
symbols = [sync.process(_epoch(i, 1, slip=i == 5)) for i in range(10)]
|
||||
assert symbols[5].valid is False
|
||||
assert symbols[6].valid is False
|
||||
assert symbols[7].valid is True
|
||||
assert sync.loss_count == 1
|
||||
Reference in New Issue
Block a user