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.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 scheduled at device samples.

The device holds each word until the next one lands, milliseconds after the record that motivated it ended, so a record need not have run on the word the loop last computed, and a correction computed against the wrong word restates an error the device is about to remove. The timeline lets the estimator attribute each record to the word that ran (mean_nco_word) and size its correction for when it lands (NCOReferencedPLLAndDLL).

Scheduled words live in a fixed vector of capacity entries, so nothing allocates; with more 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 device samples [a, b): the replica frequencies a record over that span was correlated with. For b <= a, the word in effect at a.

words is an NCOTimeline (hardware channel) or a FixedNCOWord (software receiver, one word per 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. Anything queued at or past sample is superseded (a device keeps the newest command per sample, and a later command never targets an earlier sample).

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.

As in mean_nco_word, a record ending at b covers [b - integrated_samples, b) and a word landing at s is in effect from s on, so back-to-back records (lo == hi) differ when a word lands at their boundary.

source