Conversation
GPS L2C broadcasts the same 300-bit CNAV message as GPS L5I (IS-GPS-200N
§30 ≡ IS-GPS-705J §20.3.3): identical preamble, rate-1/2 K=7 continuous
FEC, CRC-24Q, per-message-type layouts, π, and TOW×6. The 25 bps→50 sps /
12-second framing is time-domain only and leaves the symbol-domain decoder
unchanged (600-symbol message, 616-symbol sync window). Cross-checked
against gnss-sdr and pocketsdr, which both reuse one CNAV decoder for the
two signals.
Extract the shared CNAV core (FEC, window-Viterbi sync, CRC gate, all
parse_mt*, and the data container) into src/gps/cnav.jl; l5.jl and the new
l2c.jl are thin signal layers. The only decode difference is that
is_sat_healthy reports the L2 health bit (MT10 bit 53) for L2C vs the L5 bit
(54), dispatched on the constants type — one parametric GPSCNAVConstants{S}
aliased as GPSL5IConstants / GPSL2CMConstants.
The shared CNAV data container and its records are named signal-neutrally
(GPSCNAVData, GPSCNAVReducedAlmanac, GPSCNAVMidiAlmanac, GPSCNAVClock/
EphemerisDifferentialCorrection, GPSCNAVIntegritySupportMessage); the former
GPSL5I* names remain as exported deprecated aliases, to be removed at the
next major version. Internal helpers likewise use neutral gps_cnav_* /
GPSCNAV* / CNAV_* names.
Relocate the signal-agnostic GPS primitives UInt320 (packed-word type) and
_merge_keyed (dictionary helper) out of gps/l1ca.jl and gps/l1c_d.jl into the
shared gnss.jl, so the CNAV core depends only on shared utilities and not on
sibling signal files.
The L2 signal types (GPSL2CM/GPSL2CL) come from GNSSSignals v2.6.0, so
[compat] requires GNSSSignals 2.6.
Tests: add a synthetic round-trip suite plus a Spirent-derived golden
fixture (test/data/gps_l2c_prn25_nav_bits.bin, PRN 25, one full 24-message
broadcast cycle) whose decoded parameters match Spirent's own reference
decode across every message type. Factor the shared CNAV transmit-chain test
helpers into test/cnav_test_utils.jl, reused by the L5I and L2C tests.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #65 +/- ##
=======================================
Coverage 98.13% 98.13%
=======================================
Files 12 14 +2
Lines 1499 1505 +6
=======================================
+ Hits 1471 1477 +6
Misses 28 28 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a GPS L2C civil-navigation (CNAV) decoder per IS-GPS-200N §30, on the
v2 soft-symbol API. GPS L2C broadcasts the same 300-bit CNAV message as GPS
L5I (IS-GPS-200N §30 ≡ IS-GPS-705J §20.3.3) — identical preamble, rate-1/2 K=7
continuous FEC (G1=0o171, G2=0o133), CRC-24Q, per-message-type layouts, π, and
TOW × 6. The 25 bps → 50 sps / 12-second framing is time-domain only, so thesymbol-domain decoder is unchanged (600-symbol message, 616-symbol sync window).
Cross-checked against gnss-sdr and pocketsdr, both of which drive L2C and L5
through one CNAV decoder.
What's included
src/gps/cnav.jl(FEC, window-Viterbisync, CRC gate, all
parse_mt*, and the data container).src/gps/l5.jlandthe new
src/gps/l2c.jlare thin signal layers.GPSL2CMDecoderState(prn)+GNSSDecoderState(::GPSL2CM, prn)dispatch.The only decode difference from L5I is
is_sat_healthy, which reports theL2 health bit (MT10 bit 53) vs L5's bit 54 — dispatched on a parametric
GPSCNAVConstants{S}(aliasedGPSL5IConstants/GPSL2CMConstants).GPSCNAVData,GPSCNAVReducedAlmanac,GPSCNAVMidiAlmanac,GPSCNAV{Clock,Ephemeris}DifferentialCorrection,GPSCNAVIntegritySupportMessage.The former
GPSL5I*names remain as exported deprecated aliases(
Base.@deprecate_binding), to be removed at the next major version — so thisis non-breaking for downstream users.
UInt320(packed-word type) and_merge_keyedmoved fromgps/l1ca.jl/gps/l1c_d.jlintosrc/gnss.jl, sothe CNAV core no longer depends on sibling signal files.
Dependency
Requires GNSSSignals ≥ 2.6.0 (adds the
GPSL2CMsignal type);[compat] GNSSSignals = "2.6".Tests
test/cnav_test_utils.jl, reused by the L5I and L2C tests).test/data/gps_l2c_prn25_nav_bits.bin,PRN 25, one full 24-message broadcast cycle) whose decoded parameters match
Spirent's own reference decode across every message type (MT10/11, 30–37,
12/13/14/31/34/37, 15/36).
Notes for merge
Please merge squash or rebase (not a merge commit) to keep history linear
for release CI; semantic-release will minor-bump 3.1.0 → 3.2.0 from the
feat(gpsl2c)commit.