mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2026-10-12 10:41:50 +00:00
188 lines
6.0 KiB
Python
188 lines
6.0 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Generate Beidou_B1C_codes.h/.cc from ICD Weil parameters in Beidou_B1C_prn.h.
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
|
GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
|
This file is part of GNSS-SDR.
|
|
|
|
Copyright (C) 2010-2026 (see AUTHORS file for a list of contributors)
|
|
SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
Author: Wenhao Ou, 2026. ouwh(at)mail2.sysu.edu.cn
|
|
|
|
-----------------------------------------------------------------------------
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import re
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
PRN_HEADER = ROOT / "src/core/system_parameters/Beidou_B1C_prn.h"
|
|
OUT_HEADER = ROOT / "src/core/system_parameters/Beidou_B1C_codes.h"
|
|
OUT_SOURCE = ROOT / "src/core/system_parameters/Beidou_B1C_codes.cc"
|
|
|
|
|
|
def extract(name: str, text: str) -> list[int]:
|
|
match = re.search(rf"{name}\[63\]\s*=\s*\{{([^}}]+)\}}", text, re.S)
|
|
if not match:
|
|
raise RuntimeError(f"Could not parse {name}")
|
|
return [int(x.strip()) for x in match.group(1).split(",") if x.strip()]
|
|
|
|
|
|
def legendre(n: int) -> list[int]:
|
|
seq = [0] * n
|
|
for x in range(1, n):
|
|
seq[(x * x) % n] = 1
|
|
return seq
|
|
|
|
|
|
def weil_code(L: list[int], weil_len: int, w: int, p: int, out_len: int) -> list[int]:
|
|
W = [L[k] ^ L[(k + w) % weil_len] for k in range(weil_len)]
|
|
return [W[(n + p - 1) % weil_len] for n in range(out_len)]
|
|
|
|
|
|
def chips_to_hex(chips: list[int]) -> str:
|
|
out = ""
|
|
for i in range(0, len(chips), 4):
|
|
chunk = chips[i : i + 4]
|
|
value = 0
|
|
for bit in chunk:
|
|
value = (value << 1) | bit
|
|
while len(chunk) < 4:
|
|
value <<= 1
|
|
chunk.append(0)
|
|
out += format(value, "X")
|
|
return out
|
|
|
|
|
|
def chips_to_binstr(chips: list[int]) -> str:
|
|
return "".join(str(c) for c in chips)
|
|
|
|
|
|
# Keep generated source under the CI long-line limit (512 chars).
|
|
# Match the historical 76-char fragment width used in Beidou_B1C_codes.h.
|
|
_CODE_LINE_WIDTH = 76
|
|
|
|
|
|
def emit_array_decl(name: str, rows: list[str]) -> str:
|
|
return f"extern const char {name}[63][{len(rows[0]) + 1}];"
|
|
|
|
|
|
def emit_wrapped_string(row: str) -> list[str]:
|
|
"""Emit one array element as adjacent string literals, one chunk per line."""
|
|
chunks = [row[i : i + _CODE_LINE_WIDTH] for i in range(0, len(row), _CODE_LINE_WIDTH)]
|
|
if not chunks:
|
|
chunks = [""]
|
|
out: list[str] = []
|
|
for idx, chunk in enumerate(chunks):
|
|
suffix = "," if idx == len(chunks) - 1 else ""
|
|
out.append(f' "{chunk}"{suffix}')
|
|
return out
|
|
|
|
|
|
def emit_array_def(name: str, rows: list[str]) -> str:
|
|
lines = [f"const char {name}[63][{len(rows[0]) + 1}] = {{"]
|
|
for row in rows:
|
|
lines.extend(emit_wrapped_string(row))
|
|
lines.append("};")
|
|
return "\n".join(lines)
|
|
|
|
|
|
def main() -> None:
|
|
text = PRN_HEADER.read_text(encoding="utf-8")
|
|
data_w = extract("BEIDOU_B1C_DATA_PRN_W", text)
|
|
data_p = extract("BEIDOU_B1C_DATA_PRN_P", text)
|
|
pilot_w = extract("BEIDOU_B1C_PILOT_PRN_W", text)
|
|
pilot_p = extract("BEIDOU_B1C_PILOT_PRN_P", text)
|
|
sec_w = extract("BEIDOU_B1C_PILOT_SECONDARY_W", text)
|
|
sec_p = extract("BEIDOU_B1C_PILOT_SECONDARY_P", text)
|
|
|
|
L10243 = legendre(10243)
|
|
L3607 = legendre(3607)
|
|
|
|
data_hex = [
|
|
chips_to_hex(weil_code(L10243, 10243, data_w[i], data_p[i], 10230)) for i in range(63)
|
|
]
|
|
pilot_hex = [
|
|
chips_to_hex(weil_code(L10243, 10243, pilot_w[i], pilot_p[i], 10230)) for i in range(63)
|
|
]
|
|
sec_bin = [chips_to_binstr(weil_code(L3607, 3607, sec_w[i], sec_p[i], 1800)) for i in range(63)]
|
|
|
|
expected = "101011111111011001001110"
|
|
assert "".join(str(b) for b in weil_code(L10243, 10243, data_w[0], data_p[0], 10230)[:24]) == expected
|
|
|
|
script_name = Path(__file__).name
|
|
header = f"""/*!
|
|
* \\file Beidou_B1C_codes.h
|
|
* \\brief Precomputed BeiDou B1C primary and secondary codes (declarations)
|
|
* \\author Wenhao Ou, 2026. ouwh(at)mail2.sysu.edu.cn
|
|
*
|
|
* Auto-generated by {script_name}. Do not edit manually.
|
|
* Definitions live in Beidou_B1C_codes.cc.
|
|
*
|
|
* -----------------------------------------------------------------------------
|
|
*
|
|
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
|
* This file is part of GNSS-SDR.
|
|
*
|
|
* Copyright (C) 2010-2026 (see AUTHORS file for a list of contributors)
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
*
|
|
* -----------------------------------------------------------------------------
|
|
*/
|
|
#ifndef GNSS_SDR_BEIDOU_B1C_CODES_H
|
|
#define GNSS_SDR_BEIDOU_B1C_CODES_H
|
|
|
|
#include <cstddef>
|
|
|
|
constexpr size_t BEIDOU_B1C_PRIMARY_CODE_STR_LENGTH = 2558;
|
|
constexpr size_t BEIDOU_B1C_PILOT_SECONDARY_CODE_STR_LENGTH = 1800;
|
|
|
|
{emit_array_decl("BEIDOU_B1C_DATA_PRIMARY_CODE", data_hex)}
|
|
|
|
{emit_array_decl("BEIDOU_B1C_PILOT_PRIMARY_CODE", pilot_hex)}
|
|
|
|
{emit_array_decl("BEIDOU_B1C_PILOT_SECONDARY_CODE", sec_bin)}
|
|
|
|
#endif
|
|
"""
|
|
|
|
source = f"""/*!
|
|
* \\file Beidou_B1C_codes.cc
|
|
* \\brief Precomputed BeiDou B1C primary and secondary codes
|
|
* \\author Wenhao Ou, 2026. ouwh(at)mail2.sysu.edu.cn
|
|
*
|
|
* Auto-generated by {script_name}. Do not edit manually.
|
|
*
|
|
* -----------------------------------------------------------------------------
|
|
*
|
|
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
|
* This file is part of GNSS-SDR.
|
|
*
|
|
* Copyright (C) 2010-2026 (see AUTHORS file for a list of contributors)
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
*
|
|
* -----------------------------------------------------------------------------
|
|
*/
|
|
#include "Beidou_B1C_codes.h"
|
|
|
|
{emit_array_def("BEIDOU_B1C_DATA_PRIMARY_CODE", data_hex)}
|
|
|
|
{emit_array_def("BEIDOU_B1C_PILOT_PRIMARY_CODE", pilot_hex)}
|
|
|
|
{emit_array_def("BEIDOU_B1C_PILOT_SECONDARY_CODE", sec_bin)}
|
|
"""
|
|
|
|
OUT_HEADER.write_text(header, encoding="utf-8")
|
|
OUT_SOURCE.write_text(source, encoding="utf-8")
|
|
print(f"Wrote {OUT_HEADER} ({len(header)} bytes)")
|
|
print(f"Wrote {OUT_SOURCE} ({len(source)} bytes)")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|