NCO timeline

A hardware correlator holds each NCO word until the next one lands, often several records after the record that motivated it. An NCOTimeline keeps track of the word in effect and the words scheduled at named device samples, so that a record can be attributed to the word it was really produced under (mean_nco_word) rather than the one that was last requested. Pass it as the words argument of step_loop. A software correlator, whose replica follows every command at once, passes a FixedNCOWord instead.

TrackingLoops.FixedNCOWord — Type
FixedNCOWord(carrier_doppler_hz, code_doppler_hz)

A replica that ran on one known word for every span asked about — what the software receiver's replicas do within a chunk. See mean_nco_word.

source
TrackingLoops.NCOTimeline — Type
NCOTimeline(; capacity = 64)

The carrier and code words one hardware channel's NCOs ran and will run: the word in effect now and the words already scheduled at named device samples.

A hardware loop is closed through a device that holds each word until the next one lands, milliseconds after the record that motivated it ended. The loop filter therefore cannot assume that the word it last computed is the one a record was integrated under, and a correction computed against the wrong word restates an error the device is already about to remove. The timeline is the record of what the NCO actually did, so the estimator can attribute every record to the word that really ran (mean_nco_word) and size its correction for the moment it will land (NCOReferencedPLLAndDLL).

The scheduled words live in a fixed-size vector of capacity entries with a count, so scheduling and promoting words never touch the allocator. Should more words than that ever be in flight, the oldest is taken as landed. Read them with scheduled_words.

source
TrackingLoops.mean_nco_word — Method
mean_nco_word(words, a, b) -> (carrier_doppler_hz, code_doppler_hz)

Time-weighted mean of the carrier and code words in effect over the device samples [a, b) — the replica frequencies a record integrated over that span was really correlated with. For b <= a the word in effect at a.

words is an NCOTimeline for a hardware channel, or a FixedNCOWord where the replica ran on one known word (the software receiver regenerates its replicas from the satellite's Doppler every chunk).

source
TrackingLoops.promote_words! — Method
promote_words!(timeline, sample)

Everything scheduled at or before sample has landed: fold it into the applied word. Only call this once no query will start before sample again.

source
TrackingLoops.reschedule_word! — Method
reschedule_word!(timeline, from_sample, to_sample)

The word scheduled at from_sample really landed at to_sample: move it. Anything scheduled at or past to_sample is superseded, as for schedule_word!. A no-op when nothing is scheduled at from_sample.

source
TrackingLoops.schedule_word! — Method
schedule_word!(timeline, sample, carrier_doppler_hz, code_doppler_hz)

Record a word the device has accepted for sample. A device keeps the newest command for a given sample, and a later command is never scheduled for an earlier sample, so anything queued at or past sample is superseded.

source
TrackingLoops.word_changes_within — Method
word_changes_within(timeline, lo, hi)

Whether a scheduled word takes effect in [lo, hi], i.e. whether a record ending at lo and one starting at hi ran on different words.

The convention is mean_nco_word's: a record ending at sample b covers [b - integrated_samples, b), and a word landing at s is in effect from s on. So a word landing exactly at a record's end belongs to the next record, and two back-to-back records (lo == hi) ran on different words when one lands at that shared boundary.

source