Skip to content

LUT code-gen: support Galileo E1B (CBOC) via a multi-level Int8 baked table #75

Description

@zsoerenm

Summary

Proposal to extend the LUT code generators (CodeReplicaLUT / CodeGeneratorLUT / CodeGeneratorLUT4) to support Galileo E1B (CBOC) by baking a multi-level Int8 sub-chip table instead of the current ±1-only table. CBOC is the one remaining signal the LUT path rejects; the obstacle is not fundamental.

Background

_codelut_modulation currently throws for CBOC:

function _codelut_modulation(m::CBOC)
    error("CodeReplicaLUT does not support CBOC (Int8/±1 only); use gen_code!")
end

CBOC(6,1,1/11) (Galileo E1B, boc1_power = 10/11) has subcarrier
√(10/11)·BOC(1,1) ± √(1/11)·BOC(6,1), so each sub-chip takes one of four values rather than ±1:

  • ±1.25497 when the two BOC signs agree
  • ±0.65195 when they disagree

That 4-level structure (not the irrational amplitudes per se) is why it breaks the LUT's ±1 assumption (_sc_sign returns Int8(±1); primary/secondary multiplies are ±1; get_code_type(GalileoE1B()) === Float32).

Why this is feasible

CodeTable stores Int8 chips verbatim and the permute/run-fill kernels just shuffle bytes — multi-level values are mechanically fine. The only quantity that must be right is the level ratio A/B ≈ (a+b)/(a-b) = 1.924951 (overall scale cancels in correlation).

Quantization quality with small Int8 levels (relative RMS error of the quantized waveform vs the exact float CBOC, optimized over scale):

Int8 levels ratio rel. RMS waveform error
±2 / ±1 2.000 1.55 %
±25 / ±13 1.9231 0.040 %
±27 / ±14 1.9286 0.077 %
±77 / ±40 1.92500 0.0011 %

±77 / ±40 (both within Int8) matches the ratio to 0.0026% → ~0.001% RMS waveform error, i.e. negligible correlation loss, far below any receiver's quantization/noise floor.

Reproduction of the table:

a = sqrt(10/11); b = sqrt(1/11); hi = a + b; lo = a - b
r = hi/lo                       # 1.924950591148529
waveform_err(A, B) = begin
    tv = Float64[hi, lo, -lo, -hi]; qv = Float64[A, B, -B, -A]
    c = sum(tv .* qv) / sum(qv .^ 2)         # least-squares scale
    sqrt(sum((tv .- c .* qv) .^ 2) / sum(tv .^ 2))
end
waveform_err(77, 40)            # ≈ 1.05e-5

Proposed change

  • Add a CBOC arm to _codelut_modulation and a CodeLUT.CBOC modulation descriptor with subchip_factor = 2·m2 = 12 (BOC(6,1) sets the resolution).
  • A CBOC-specific _sc_sign-style baker producing the 4 levels per sub-chip:
    level(k, pos, P) = s1 · (s1 == s2 ? A : B), where s1 is the BOC(1,1) sub-chip sign and s2 the BOC(6,1) sub-chip sign, with A/B a chosen rational (default ±77/±40).
  • The primary chip (±1) and any secondary (±1) multiply the baked level as today — sign flips preserve the level structure, so it composes with the existing primary/secondary path unchanged.

Caveats / decisions to make

  • Output convention: the LUT would emit a scaled, multi-level Int8 replica (magnitudes {77, 40}), not ±1 and not the float path's scale. Correlation is scale-invariant, but callers mixing it with a carrier need wider accumulators (already true for Int8 chips, just larger magnitude). Worth documenting clearly, or exposing the chosen (A, B) on the plan.
  • Level choice: ±25/±13 (0.04 %) keeps magnitudes small (less accumulator growth) and is still excellent; ±77/±40 is essentially exact. Could be a parameter with a sensible default.
  • Not byte-identical to the existing Float32 gen_code!; a test should assert correlation/normalized-shape agreement within a tolerance rather than exact equality.
  • Orthogonal to LUT code-gen subcarrier misaligned vs canonical gen_code! for TMBOC (GPS L1C-P) at non-even samples/sub-chip #74 (TMBOC subcarrier rounding) and to the recently-added non-baked-secondary iterator support.

Cosine-phased BOCcos is a separate, easier case (it is ±1, just a quarter-chip phase offset) and could be folded in alongside if desired.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions