Initial Galileo receiver and SignalSim integration
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
import numpy as np
|
||||
|
||||
from galileo_rx.acquisition.acquisition_manager import AcquisitionManager
|
||||
from galileo_rx.config import AcquisitionConfig, TrackingConfig
|
||||
from galileo_rx.fixed_point.fixed_correlator import FixedCorrelator
|
||||
from galileo_rx.fixed_point.formats import FixedFormat
|
||||
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
|
||||
|
||||
|
||||
def test_complete_float_and_fixed_prompt_regression() -> None:
|
||||
fs = 4.092e6
|
||||
profile, provider = galileo_e1_profile(), SyntheticCodeProvider()
|
||||
generator = SyntheticSignalGenerator(
|
||||
profile,
|
||||
provider,
|
||||
fs,
|
||||
satellites=[SatelliteSignalConfig(11, "E1B", code_delay_chips=24.0, doppler_hz=-750.0, carrier_phase_rad=0.05, cn0_db_hz=50.0)],
|
||||
channel=ChannelModelConfig(seed=123),
|
||||
)
|
||||
samples, _ = generator.generate(int(0.06 * fs))
|
||||
acquisition_config = AcquisitionConfig(
|
||||
doppler_min_hz=-1500, doppler_max_hz=0, doppler_step_hz=250,
|
||||
noncoherent_accumulations=2, detection_threshold=2.0, zero_padding_mode="none", parabolic_interpolation=False,
|
||||
)
|
||||
acquisition, _ = AcquisitionManager(profile, provider, fs, acquisition_config).acquire_one(samples, "E1B", 11)
|
||||
assert acquisition.detected and acquisition.raw_doppler_hz == -750.0
|
||||
channel = TrackingChannel(profile, provider, fs, TrackingConfig(pull_in_duration_ms=12.0), acquisition)
|
||||
measurements = channel.process(samples)
|
||||
assert len(measurements) == 15 and not measurements[-1].reacquisition_requested
|
||||
|
||||
count = channel.integration_samples
|
||||
phases = (-acquisition.code_phase_chips + np.arange(count) * profile.code_rate_hz / fs)
|
||||
code = provider.primary_code(profile, "E1B", 11)
|
||||
replica = code[np.floor(phases).astype(np.int64) % code.size] * np.where(np.mod(phases, 1.0) < 0.5, 1, -1)
|
||||
# This vector is intentionally unnormalized AWGN, so use an input format
|
||||
# with integer headroom rather than the post-AGC Q1.7 default.
|
||||
fixed_prompt = FixedCorrelator(fs, acquisition.carrier_frequency_hz, sample_format=FixedFormat(12, 4)).correlate_prompt(samples[:count], replica)
|
||||
float_prompt = np.sum(samples[:count] * np.exp(-2j * np.pi * acquisition.carrier_frequency_hz * np.arange(count) / fs) * replica)
|
||||
assert abs(fixed_prompt.complex_value - float_prompt) / abs(float_prompt) < 0.03
|
||||
Reference in New Issue
Block a user