Implement Galileo E1B I/NAV navigation decoding

This commit is contained in:
2026-07-31 00:15:34 +03:00
parent 2a6ccfc23d
commit 814a788b36
104 changed files with 6351 additions and 10 deletions
+16 -3
View File
@@ -26,7 +26,14 @@ def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--signalsim-path", required=True, type=Path)
parser.add_argument("--executable", type=Path)
vector_names = ["high_cn0_single_prn", "nominal_cn0_single_prn", "negative_doppler", "multiple_prns"]
vector_names = [
"high_cn0_single_prn",
"nominal_cn0_single_prn",
"negative_doppler",
"multiple_prns",
"navigation_single_prn",
"navigation_multisat",
]
parser.add_argument("--vector", choices=[*vector_names, "all"], default="high_cn0_single_prn")
parser.add_argument("--project-root", type=Path, default=Path(__file__).resolve().parents[1])
args = parser.parse_args()
@@ -46,6 +53,8 @@ def main() -> int:
"nominal_cn0_single_prn": {"duration_s": 0.6, "cn0_db_hz": 50.0, "visible_prns": [1], "expected_doppler_hz": {1: 1828.0}},
"negative_doppler": {"duration_s": 2.2, "cn0_db_hz": 55.0, "visible_prns": [27], "expected_doppler_hz": {27: -2637.0}},
"multiple_prns": {"duration_s": 0.12, "cn0_db_hz": 55.0, "visible_prns": [1, 4, 19, 21, 27], "expected_doppler_hz": {1: 1828.0, 4: 2171.0, 19: -367.0, 21: -712.0, 27: -2637.0}},
"navigation_single_prn": {"duration_s": 4.2, "cn0_db_hz": 55.0, "visible_prns": [1], "expected_doppler_hz": {1: 1828.0}, "sample_frequency_mhz": 4.092, "center_frequency_mhz": 1574.397},
"navigation_multisat": {"duration_s": 32.2, "cn0_db_hz": 55.0, "visible_prns": [1, 4, 19, 21, 27], "expected_doppler_hz": {1: 1828.0, 4: 2171.0, 19: -367.0, 21: -712.0, 27: -2637.0}, "sample_frequency_mhz": 4.092, "center_frequency_mhz": 1574.397},
}
selected = vector_names if args.vector == "all" else [args.vector]
for vector_name in selected:
@@ -57,6 +66,8 @@ def main() -> int:
config["ephemeris"]["name"] = str(rinex)
config["trajectory"]["trajectoryList"][0]["time"] = parameters["duration_s"]
config["power"]["initPower"]["value"] = parameters["cn0_db_hz"]
config["output"]["sampleFreq"] = parameters.get("sample_frequency_mhz", 8.184)
config["output"]["centerFreq"] = parameters.get("center_frequency_mhz", 1573.374)
visible = set(parameters["visible_prns"])
config["output"]["config"]["maskOut"] = [{"system": "Galileo", "svid": [prn for prn in range(1, 37) if prn not in visible]}]
output_name = f"{vector_name}_iq8.bin"
@@ -76,8 +87,10 @@ def main() -> int:
"size_bytes": output.stat().st_size,
"sha256": sha256(output),
"complex_sample_count": output.stat().st_size // 2,
"sampling_frequency_hz": 8_184_000.0,
"intermediate_frequency_hz": 2_046_000.0,
"sampling_frequency_hz": round(float(config["output"]["sampleFreq"]) * 1e6, 6),
"intermediate_frequency_hz": round(
(1575.42 - float(config["output"]["centerFreq"])) * 1e6, 6
),
"sample_format": "IQ8_interleaved_signed_I_then_Q",
"duration_s": parameters["duration_s"],
"prns": parameters["visible_prns"],