104 lines
4.3 KiB
Python
104 lines
4.3 KiB
Python
import numpy as np
|
|
|
|
from galileo_rx.acquisition.acquisition_manager import AcquisitionManager
|
|
from galileo_rx.config import AcquisitionConfig, TrackingConfig
|
|
from galileo_rx.signal_profiles import galileo_e1_profile
|
|
from galileo_rx.signals.code_provider import SyntheticCodeProvider
|
|
from galileo_rx.signals.signal_generator import ChannelModelConfig, SatelliteSignalConfig, SyntheticSignalGenerator
|
|
from galileo_rx.tracking.tracking_channel import TrackingChannel
|
|
from galileo_rx.tracking.tracking_manager import TrackingManager
|
|
from galileo_rx.types import AcquisitionResult, TrackingState
|
|
|
|
|
|
def test_acquisition_to_tracking_and_multichannel_manager() -> None:
|
|
fs = 4.092e6
|
|
profile = galileo_e1_profile()
|
|
provider = SyntheticCodeProvider()
|
|
satellites = [
|
|
SatelliteSignalConfig(2, "E1C", code_delay_chips=81.0, doppler_hz=1000.0, carrier_phase_rad=0.1, cn0_db_hz=52.0),
|
|
]
|
|
generator = SyntheticSignalGenerator(profile, provider, fs, satellites=satellites, channel=ChannelModelConfig(seed=9))
|
|
samples, _ = generator.generate(int(0.12 * fs))
|
|
acquisition_config = AcquisitionConfig(
|
|
doppler_min_hz=0,
|
|
doppler_max_hz=2000,
|
|
doppler_step_hz=250,
|
|
coherent_integration_ms=4,
|
|
noncoherent_accumulations=2,
|
|
detection_threshold=2.0,
|
|
zero_padding_mode="none",
|
|
parabolic_interpolation=False,
|
|
)
|
|
acquisition, _ = AcquisitionManager(profile, provider, fs, acquisition_config).acquire_one(samples, "E1C", 2)
|
|
assert acquisition.detected
|
|
tracking_config = TrackingConfig(
|
|
integration_ms=4.0,
|
|
use_fll_assist=True,
|
|
pull_in_duration_ms=20.0,
|
|
secondary_code_mode="wipeoff",
|
|
loss_of_lock_epochs=20,
|
|
)
|
|
manager = TrackingManager(profile, provider, fs, tracking_config)
|
|
channel = manager.add_channel(acquisition)
|
|
measurements = channel.process(samples[: 25 * channel.integration_samples])
|
|
assert len(measurements) == 25
|
|
assert not measurements[-1].reacquisition_requested
|
|
assert measurements[-1].state in {TrackingState.PLL_TRACK, TrackingState.WEAK_SIGNAL}
|
|
assert abs(measurements[-1].carrier_frequency_hz - 1000.0) < 100.0
|
|
assert np.median([abs(item.dll_error_chips) for item in measurements[-10:]]) < 0.1
|
|
|
|
|
|
def test_tracking_under_doppler_rate() -> None:
|
|
fs = 4.092e6
|
|
profile = galileo_e1_profile()
|
|
provider = SyntheticCodeProvider()
|
|
generator = SyntheticSignalGenerator(
|
|
profile,
|
|
provider,
|
|
fs,
|
|
satellites=[SatelliteSignalConfig(4, "E1B", code_delay_chips=11.0, doppler_hz=-500.0, doppler_rate_hz_s=100.0)],
|
|
channel=ChannelModelConfig(add_awgn=False),
|
|
)
|
|
samples, _ = generator.generate(int(0.08 * fs))
|
|
acquisition_config = AcquisitionConfig(
|
|
doppler_min_hz=-1000,
|
|
doppler_max_hz=0,
|
|
doppler_step_hz=250,
|
|
coherent_integration_ms=4,
|
|
noncoherent_accumulations=1,
|
|
detection_threshold=1.5,
|
|
zero_padding_mode="none",
|
|
)
|
|
acquisition, _ = AcquisitionManager(profile, provider, fs, acquisition_config).acquire_one(samples, "E1B", 4)
|
|
channel = TrackingChannel(profile, provider, fs, TrackingConfig(pull_in_duration_ms=40.0), acquisition)
|
|
measurements = channel.process(samples)
|
|
expected_hz = -500.0 + 100.0 * measurements[-1].time_s
|
|
assert abs(measurements[-1].carrier_frequency_hz - expected_hz) < 100.0
|
|
|
|
|
|
def test_code_aiding_uses_doppler_not_nonzero_if_center() -> None:
|
|
fs = 8.184e6
|
|
profile = galileo_e1_profile()
|
|
provider = SyntheticCodeProvider()
|
|
if_hz = 2.046e6
|
|
doppler_hz = 1800.0
|
|
acquisition = AcquisitionResult(
|
|
detected=True,
|
|
prn=1,
|
|
component="E1B",
|
|
code_phase_samples=0.0,
|
|
code_phase_chips=0.0,
|
|
doppler_hz=doppler_hz,
|
|
carrier_frequency_hz=if_hz + doppler_hz,
|
|
peak_power=1.0,
|
|
second_peak_power=0.1,
|
|
detection_metric=10.0,
|
|
estimated_cn0_db_hz=None,
|
|
coherent_integration_ms=4.0,
|
|
noncoherent_accumulations=1,
|
|
)
|
|
channel = TrackingChannel(profile, provider, fs, TrackingConfig(use_fll_assist=False), acquisition)
|
|
expected_hz = profile.code_rate_hz * (1.0 + doppler_hz / profile.carrier_frequency_hz)
|
|
assert abs(channel.code_nco.frequency_hz - expected_hz) < 1e-9
|
|
assert channel.carrier_center_hz == if_hz
|