Add the BeiDou Open Service signals from the official BDS-SIS-ICDs
(http://en.beidou.gov.cn/SYSTEMS/ICD/):
* BeiDouB1I (B1, 1561.098 MHz, 2046-chip Gold code, BPSK(2))
* BeiDouB3I (B3, 1268.52 MHz, 10230-chip Gold code, BPSK(10))
* BeiDouB2bI (B2b, 1207.14 MHz, 10230-chip Gold code, BPSK(10))
* BeiDouB2aI/B2aQ (L5, 10230-chip Gold codes, BPSK(10), data+pilot)
* BeiDouB1C_D/B1C_P (L1, 10230-chip truncated-Weil codes, BOC(1,1),
data+pilot)
Also add the BDT (BeiDou Time) time system, the B1I/B3I/B2b RF bands, and
the AbstractBeiDouSignal supertype.
Every ranging code and secondary code is generated from the ICD LFSR/Weil
definitions and verified against the ICDs' own first/last-24-chip octal
values (B2a, B2b, B1C) and the B3I register-shift table; all codes were
additionally cross-checked chip-for-chip against PocketSDR (all signals)
and GNSS-SDR (B1I, B3I). B1I/B3I apply the NH20 secondary only on the
MEO/IGSO (D1) PRNs 6-58, with no overlay on the GEO (D2) PRNs, matching
the ICD satellite-type tables. The B1C pilot QMBOC(6,1,4/33) is modelled
as its standard BOC(1,1) tracking approximation.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Summary
Adds the BeiDou Open Service signals, generated from the official BeiDou
SIS‑ICDs (http://en.beidou.gov.cn/SYSTEMS/ICD/), following the existing
per‑constellation architecture (
AbstractGPSSignal/AbstractGalileoSignal).New signal types:
BeiDouB1IB1I(1561.098 MHz)BeiDouB3IB3I(1268.52 MHz)BeiDouB2bIB2b(1207.14 MHz)BeiDouB2aI/BeiDouB2aQL5(1176.45 MHz)BeiDouB1C_D/BeiDouB1C_PL1(1575.42 MHz)Also adds:
AbstractBeiDouSignalsupertype.BDT(BeiDou Time) time system — epoch2006‑01‑01T00:00:00,TAI − 33 s.B1I,B3I,B2b(B1C and B2a reuse the existingL1/L5carriers).docs/api.md, and README entries. Theget_signal_id/get_band_idaccessors work for the new types via theirnameofdefaults(
:BeiDouB1I,:B1I,:L1for B1C,:L5for B2a, …); tests pin these.Verification against the ICDs
Every ranging code and secondary code is generated directly from the ICD
LFSR/Weil definitions (no vendored code tables) and pinned in the test suite to
the ICDs' own published values:
code table are reproduced exactly for all PRNs (primary + secondary).
(the B3I ICD publishes no chip vectors).
structurally (maximal‑length G1/G2 m‑sequences, balanced 2046‑chip Gold codes).
Cross‑checks against other implementations
To close the gap for B1I/B3I (no ICD chip vectors), the generated codes were
additionally cross‑checked against two independent open‑source receivers:
python/sdr_code.py): full chip‑for‑chip match on allsignal components and every PRN (up to the global chip‑sign convention).
beidou_b1i/b3i_signal_replica.cc): B1I full‑code match, and theB1I phase‑select / B3I G2‑init parameter tables match 63/63.
The B3I G1 short‑cycle length (period 8190) follows the ICD's stated "period of
8190 chips", and is confirmed by the ICD's own B2a/B2b last‑24‑chip octal values,
which lie in the post‑8190 repeat region and match this implementation.
Modelling notes
NH20 overlay is applied only on the MEO/IGSO satellites (PRN 6‑58, D1 message);
the GEO satellites (PRN 1‑5, 59‑63, D2 message) carry no secondary. This is
exposed as a
PerPRNSecondaryCodewhose GEO columns are an all‑ones no‑op, so aGEO PRN's tiered code equals its primary code (matches PocketSDR's
sec_code_B1I).by the LUT, with a
_BOC11approximation variant), QMBOC is a quadraturemultiplex: its real in‑phase component simply is BOC(1,1). So
BeiDouB1C_Pgenerates a BOC(1,1) replica — the standard real tracking replica (same as
PocketSDR) — and there is no separate full/
_BOC11split. The B1C datacomponent is exactly BOC(1,1) per the ICD (no approximation).
Compatibility
Purely additive — no existing type, signature, or behaviour changes; every
GPS/Galileo signal produces identical output. Suggested release: minor bump to
3.4.0(the one caveat is the usual SemVer note that adding exports — here theshort band/time‑system names
B1I/B3I/B2b/BDT— can theoretically collidewith a downstream user's own bindings under
using GNSSSignals).Tests
New
test/beidou/suite (per‑signal files + shared ICD verification vectors)covering code lengths, chip rates, bands, time system, secondary codes, the
ICD‑octal pins above, the B3I shift table, and
gen_code!sampling.get_band_id/
get_signal_idtests extended with BeiDou coverage. Full suite green locally,including Aqua and the AVX‑512 SDE SIMD‑only path.
🤖 Generated with Claude Code