Signal support matrix
Every concrete signal type GNSSSignals.jl defines is listed here, together with what Tracking.jl does with it. A signal type existing upstream does not by itself mean this package can track it, so the table is the single place that says so — and test/signal_coverage.jl checks it against the live type tree, so a GNSSSignals release that adds a signal fails the test suite here rather than at the first get_default_correlator MethodError in user code.
What "supported" means here
Correlation and tracking is not navigation decoding, and neither is PVT. The table separates them:
- Sync feature is what the tracker locks onto to leave its one-block pre-sync integration — a data-bit edge, a secondary/overlay code phase, or nothing at all where the primary code period already is the integration unit.
- Navigation data is what the signal carries. A pilot or acquisition aid carries none, and nothing in this package asks it for a bit: it yields code phase, carrier phase, Doppler and C/N₀ like any other signal, and
get_soft_bitsstays empty for it forever. Decoding the message of the signals that do carry one is GNSSDecoder.jl's job, and PVT is a further step again — a satellite can be tracked and ranged on without either.
Evidence level. Every row is verified in software, against clean synthetic replicas generated by GNSSSignals, in this repository's test suite: a per-signal file (test/<constellation>_<signal>.jl) pins its defaults and sync behaviour, and test/signal_coverage.jl runs each one through track. That is the only claim made here. Simulated-FPGA, hardware-replay and live-RF validation live with the receiver and are tracked in GNSSReceiver.jl#130.
The matrix
Blocks per integration is the coherent integration length in whole primary code blocks: the value a fresh TrackedSignal starts at (default_num_code_blocks_to_integrate), and in brackets the structural ceiling set_preferred_num_code_blocks_to_integrate! may raise it to (max_num_code_blocks_to_integrate) — one data bit, one overlay period, or one code cycle. The tracker always integrates a single block until the sync feature is found, whatever this says.
| Signal | Band | Primary code | Blocks per integration | Sync feature | Navigation data | PRNs |
|---|---|---|---|---|---|---|
GPSL1CA | L1 | 1023 chips, 1 ms | 1 (max 20) | soft CFAR bit-edge search | LNAV, 50 sym/s | 1-37 |
GPSL1C_D | L1 | 10230 chips, 10 ms | 1 (max 1) | none needed — 1 symbol per code period | CNAV-2, 100 sym/s | 1-63 |
GPSL1C_P | L1 | 10230 chips, 10 ms | 1 (max 1800) | hard rotation sweep, 1800-chip overlay | none (pilot) | 1-63 |
GPSL2CM | L2 | 10230 chips, 20 ms | 1 (max 1) | none needed — 1 symbol per code period | CNAV, 50 sym/s | 1-63 |
GPSL2CL | L2 | 767250 chips, 1.5 s | 1 (max 1) | none — the code period is the integration | none (pilot) | 1-63 |
GPSL5I | L5 | 10230 chips, 1 ms | 1 (max 10) | soft CFAR overlay search, NH10 | CNAV, 100 sym/s | 1-37 |
GPSL5Q | L5 | 10230 chips, 1 ms | 1 (max 20) | soft CFAR overlay search, NH20 | none (pilot) | 1-37 |
GalileoE1B | L1 | 4092 chips, 4 ms | 1 (max 1) | none needed — 1 symbol per code period | I/NAV, 250 sym/s | 1-50 |
GalileoE1B_BOC11 | L1 | 4092 chips, 4 ms | 1 (max 1) | none needed — 1 symbol per code period | I/NAV, 250 sym/s | 1-50 |
GalileoE1C | L1 | 4092 chips, 4 ms | 1 (max 25) | soft CFAR overlay search, CS25 | none (pilot) | 1-50 |
GalileoE1C_BOC11 | L1 | 4092 chips, 4 ms | 1 (max 25) | soft CFAR overlay search, CS25 | none (pilot) | 1-50 |
GalileoE5aI | L5 | 10230 chips, 1 ms | 1 (max 20) | soft CFAR overlay search, CS20 | F/NAV, 50 sym/s | 1-50 |
GalileoE5aQ | L5 | 10230 chips, 1 ms | 1 (max 100) | soft CFAR overlay search, per-PRN CS100 | none (pilot) | 1-50 |
GalileoE5aQP | L5 | 330 chips, 64.5 µs | 31 (max 31) | none — no data, no overlay | none (acquisition aid) | 1-40 |
GalileoE5bI | E5b | 10230 chips, 1 ms | 1 (max 4) | soft CFAR overlay search, CS4 | I/NAV, 250 sym/s | 1-50 |
GalileoE5bQ | E5b | 10230 chips, 1 ms | 1 (max 100) | soft CFAR overlay search, per-SVID CS100 | none (pilot) | 1-50 |
GalileoE6B | E6 | 5115 chips, 1 ms | 1 (max 1) | none needed — 1 symbol per code period | C/NAV, 1000 sym/s | 1-50 |
GalileoE6C | E6 | 5115 chips, 1 ms | 1 (max 100) | soft CFAR overlay search, per-PRN CS100 | none (pilot) | 1-50 |
BeiDouB1I | B1I | 2046 chips, 1 ms | 1 (max 20) | soft CFAR overlay search, NH20 | D1, 50 sym/s (see GEO note) | 1-63 |
BeiDouB3I | B3I | 10230 chips, 1 ms | 1 (max 20) | soft CFAR overlay search, NH20 | D1, 50 sym/s (see GEO note) | 1-63 |
BeiDouB1C_D | L1 | 10230 chips, 10 ms | 1 (max 1) | none needed — 1 symbol per code period | B-CNAV1, 100 sym/s | 1-63 |
BeiDouB1C_P | L1 | 10230 chips, 10 ms | 1 (max 1800) | hard rotation sweep, 1800-chip overlay | none (pilot) | 1-63 |
BeiDouB2aI | L5 | 10230 chips, 1 ms | 1 (max 5) | soft CFAR overlay search, 5-chip | B-CNAV2, 200 sym/s | 1-63 |
BeiDouB2aQ | L5 | 10230 chips, 1 ms | 1 (max 100) | soft CFAR overlay search, per-PRN 100-chip | none (pilot) | 1-63 |
BeiDouB2bI | E5b | 10230 chips, 1 ms | 1 (max 1) | none needed — 1 symbol per code period | B-CNAV3, 1000 sym/s (see below) | 6-58 |
The PRNs column is the range the upstream code table defines, not a range this package screens for: asking for a PRN outside it yields an all-zero or out-of-bounds code from GNSSSignals rather than an error here. BeiDou B2b-I is the case where the two differ — its table has 63 columns but the ICD defines ranging codes for PRN 6-58 only, so the rest are all-zero.
Signals sharing a band can be tracked in one BandMeasurement regardless of constellation: Galileo E5b and BeiDou B2b share the 1207.14 MHz carrier (E5b for both), BeiDou B2a shares L5 with GPS L5 and Galileo E5a, and BeiDou B1C shares L1 with GPS L1 C/A, GPS L1C and Galileo E1.
Galileo E5a-QP, the acquisition aid
E5a-QP (OS SIS ICD v2.2 §2.3.1.4) is the one signal whose role differs from the rest, so it is worth spelling out what "supported" buys.
It is a dataless BPSK(5) quasi-pilot at 5.115 Mcps whose primary code is only 330 chips — a 64.5 µs period, repeated 31 times within 2 ms, with no overlay — broadcast so that a receiver can find Galileo cheaply: a 330-chip search is 31× smaller than E5a-I's 10230-chip one.
- As an acquisition aid. The recovered carrier Doppler transfers directly to E5a-I / E5a-Q (same carrier). The code phase does not transfer as directly: it pins E5a-I only modulo the 64.5 µs primary period, leaving 31 residual hypotheses across the 2 ms in which the two code grids realign — still a 330× reduction over a full 10230-chip search. E5a-QP runs at half the E5a-I/Q chip rate, so it cannot share a satellite's
SignalGroupwith them (see #151); track it in its own group and hand over. - As a tracked signal. It is tracked like any other pilot and yields the same code-phase, carrier-phase, Doppler and C/N₀ observables. What it needs is an integration policy: one 64.5 µs primary block would run the loop at 15.5 kHz off a 279 Hz per-block reference bandwidth, so E5a-QP integrates a whole 31-block code cycle — 10230 chips, exactly 2 ms — by default. That puts the loop at 500 Hz and, through the estimator's automatic
1/Nbandwidth scaling, at a 9 Hz effective carrier bandwidth. - What it never provides is navigation data, on its own or for E5a: it is dataless, and the F/NAV message stays E5a-I's to carry.
Note that E5a-QP is transmitted by a subset of the constellation (the current list is published by the GSC) and that the ICD states it will eventually be discontinued.
Known limitations
These are properties of the signals or open work, not of a missing dispatch method. Each is honest about what does and does not work today.
- BeiDou GEO satellites (PRN 1-5, 59-63) never sync on B1I/B3I. Their ranging codes carry no NH20 overlay and their message is D2 at 500 sym/s rather than D1 at 50 sym/s, so the secondary-code detector has nothing to lock onto. Such a satellite tracks and can be ranged on, but stays pre-sync and its data is not decoded — a 2-block D2 bit-edge search would need a per-PRN data rate, while
get_data_frequencyis a per-signal-type accessor reporting the D1 rate for every PRN. Seesrc/beidou/b1i.jl. - BeiDou B2b-I correlates to an all-zero prompt on a clean replica, which takes the loop down through a NaN Doppler (#234). Its defaults and sync detector are in place and checked, but the end-to-end pass is not usable until that is fixed.
- Long-overlay pilots (
GPSL1C_P,BeiDouB1C_P) locate their 1800-chip overlay with the hard rotation sweep, which needs a full 18 s overlay period before it can report a lock (#215). - Secondary-code phase is re-searched at handoff even when the acquisition stage already recovered it (#120).
- One chip rate per
SignalGroup, which is what keeps E5a-QP out of an E5a group even though it shares the carrier (#151). - Dataless pilots use the two-quadrant Costas carrier discriminators they do not need, halving each loop's pull-in range (#230).