feat(bit-buffer)!: emit complex soft bits, drop the hard-bit buffer#200
Closed
giove-a wants to merge 1 commit into
Closed
feat(bit-buffer)!: emit complex soft bits, drop the hard-bit buffer#200giove-a wants to merge 1 commit into
giove-a wants to merge 1 commit into
Conversation
Store the coherently accumulated complex prompt of each completed
navigation bit in `soft_bits` (now `Vector{ComplexF32}` instead of
`Vector{Float32}`) as the buffer's sole decoded-bit output, so a
downstream receiver can decide whether the navigation data lives in the
real component, the imaginary component, or a combination of both.
This is what enables L5/E5a pilot+data tracking: a pilot-driven lock
leaves the data 90 degrees out of phase, so the data bits sit in the
quadrature component that a real-only accumulation discards.
BREAKING CHANGE: the legacy hard-bit concept is removed. `get_bits` and
the fixed-width `buffer::UInt128` / `length` fields (with their 128-bit
overflow guard) are gone. Consumers form their own hard decision from
`get_soft_bits` (e.g. `real.(soft) .> 0` for in-phase signals like GPS
L1 C/A and Galileo E1B). `get_num_bits` is retained, now backed by the
soft-bit count. The convenience `BitBuffer` constructor drops its
`buffer` / `length` arguments.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
giove-a
force-pushed
the
sc/complex-bit-buffer
branch
from
July 11, 2026 16:49
2ee4f5d to
105ee47
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #200 +/- ##
==========================================
- Coverage 97.63% 97.62% -0.01%
==========================================
Files 32 32
Lines 3296 3291 -5
==========================================
- Hits 3218 3213 -5
Misses 78 78 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Member
|
This PR points out a real problem, but the proposed solution does not resolve the bit sync problem which still relies on the real part only. |
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
Reworks the
BitBufferso the coherently accumulated complex prompt ofeach completed navigation bit is the buffer's sole decoded-bit output
(
get_soft_bits, nowVector{ComplexF32}). A downstream receiver decideswhether the navigation data lives in the real component, the imaginary
component, or a combination of both, and forms its own hard decision.
The legacy hard-bit concept —
get_bitsand the fixed-widthbuffer::UInt128/lengthfields — is removed.Motivation
Previously the buffer collapsed the accumulated prompt to
real(...)forboth the stored soft bit and the packed hard bits. That discards the
quadrature component, which is exactly where the data lands in L5/E5a
pilot+data tracking: the pilot drives the carrier lock, leaving the data
90° out of phase in the imaginary component. Retaining the full complex
accumulation lets a
GNSSReceiverrecover that data. (E1, already in-phase,is unaffected.)
Once soft bits carry the full complex value,
get_bitsis a strictly lossy,in-phase-only projection of them (
real(soft) > 0) — redundant for in-phasesignals and wrong for quadrature-data signals. Rather than carry a parallel,
misleading representation, this removes it.
What changed
soft_bits:Vector{Float32}→Vector{ComplexF32}; stores the fullpolarity-corrected complex accumulation. Polarity is applied to the whole
phasor (a 180° ambiguity =
×(-1), both quadratures), not just the real part.buffer::UInt128andlength::Intfields,get_bits(accessor, export, and all
TrackedSignal/TrackedSat/TrackStateforwards), the hard-bit packing, and the 128-bit overflow guard (a
growable
Vectorhas no fixed cap).get_num_bits, now backed by the soft-bit count(
length(soft_bits)).BitBufferconstructor drops itsbuffer/lengtharguments (7-arg → 5-arg).
the pre-sync window only ever stored the in-phase sign, and only in-phase
signals with no secondary code reach that path (GPS L1 C/A). Quadrature-data
signals route through the secondary-code sync path and decode fresh
post-sync, where the full complex path applies.
bit_sync.md,tracking_state.md) and the affectedjldoctestsupdated to
get_soft_bits.get_bitsis gone. Consumers form their own hard decision fromget_soft_bits:get_num_bitsis unchanged in meaning. The convenienceBitBuffer(...)constructor no longer takes
buffer/lengthpositional args.Testing
Pkg.test()passes in full (Flexiband integration test skipped as usual —1.6 GB download).
grows past 128 bits without error.
component.
🤖 Generated with Claude Code