Files
galileo/src/galileo_rx/signal_profiles.py
T

59 lines
1.7 KiB
Python

"""Signal definitions consumed by generic acquisition and tracking engines."""
from __future__ import annotations
from dataclasses import dataclass
from typing import Literal
@dataclass(frozen=True, slots=True)
class ComponentProfile:
name: str
channel_type: Literal["data", "pilot"]
primary_code_length_chips: int
primary_code_period_s: float
secondary_code_length: int | None
navigation_symbol_period_s: float | None
@dataclass(frozen=True, slots=True)
class SignalProfile:
name: str
carrier_frequency_hz: float
code_rate_hz: float
modulation: str
boc_subcarrier_rate_hz: float
components: dict[str, ComponentProfile]
def component(self, name: str) -> ComponentProfile:
try:
return self.components[name]
except KeyError as exc:
raise ValueError(f"component {name!r} is not supported by profile {self.name}") from exc
def galileo_e1_profile() -> SignalProfile:
"""Galileo E1 parameters; code chips themselves come from a code provider."""
return SignalProfile(
name="GALILEO_E1",
carrier_frequency_hz=1_575_420_000.0,
code_rate_hz=1_023_000.0,
modulation="BOC(1,1)",
boc_subcarrier_rate_hz=1_023_000.0,
components={
"E1B": ComponentProfile("E1B", "data", 4092, 0.004, None, 0.004),
"E1C": ComponentProfile("E1C", "pilot", 4092, 0.004, 25, None),
},
)
PROFILES = {"GALILEO_E1": galileo_e1_profile}
def get_signal_profile(name: str) -> SignalProfile:
try:
return PROFILES[name]()
except KeyError as exc:
raise ValueError(f"unknown signal profile {name!r}; available: {sorted(PROFILES)}") from exc