class NBSLibSwiftNav(NavBitSync): def __init__(self): NavBitSync.__init__(self) self.nav_msg = NavMsg() def update_bit_sync(self, corr, ms): self.nav_msg.update(corr, ms) self.bit_phase_ref = self.nav_msg.bit_phase_ref self.synced = self.bit_phase_ref >= 0
class TrackingChannelL1CA(TrackingChannel): """ L1CA tracking channel. """ def __init__(self, params): """ Initialize L1C/A tracking channel with L1C/A specific data. Parameters ---------- params : dictionary L1C/A tracking initialization parameters """ # Convert acquisition SNR to C/N0 cn0_0 = 10 * np.log10(params['acq'].snr) cn0_0 += 10 * np.log10(defaults.L1CA_CHANNEL_BANDWIDTH_HZ) params['cn0_0'] = cn0_0 params['coherent_ms'] = 1 params['IF'] = params['samples'][gps_constants.L1CA]['IF'] params['prn_code'] = caCodes[params['acq'].prn] params['code_freq_init'] = params['acq'].doppler * \ gps_constants.l1ca_chip_rate / gps_constants.l1 params['loop_filter_params'] = defaults.l1ca_stage1_loop_filter_params params['lock_detect_params'] = defaults.l1ca_lock_detect_params_opt params['chipping_rate'] = gps_constants.l1ca_chip_rate TrackingChannel.__init__(self, params) self.nav_msg = NavMsg() self.nav_bit_sync = NBSMatchBit() if self.prn < 32 else NBSSBAS() self.l2c_handover_acq = None self.l2c_handover_done = False def _run_preprocess(self): """ Run L1C/A tracking loop preprocessor operation. It runs before every coherent integration round. """ # For L1 C/A there are coherent and non-coherent tracking options. if self.stage1 and \ self.stage2_coherent_ms and \ self.nav_bit_sync.bit_phase == self.nav_bit_sync.bit_phase_ref: logger.info("[PRN: %d (%s)] switching to stage2, coherent_ms=%d" % (self.prn + 1, self.signal, self.stage2_coherent_ms)) self.stage1 = False self.coherent_ms = self.stage2_coherent_ms self.loop_filter.retune(**self.stage2_loop_filter_params) self.lock_detect.reinit( k1=self.lock_detect_params["k1"] * self.coherent_ms, k2=self.lock_detect_params["k2"], lp=self.lock_detect_params["lp"], lo=self.lock_detect_params["lo"]) self.cn0_est = CN0Estimator(bw=1e3 / self.stage2_coherent_ms, cn0_0=self.track_result.cn0[self.i - 1], cutoff_freq=10, loop_freq=1e3 / self.stage2_coherent_ms) self.coherent_iter = self.coherent_ms def _get_result(self): """ Get L1C/A tracking results. The possible outcome of L1C/A tracking operation is the L1C/A handover to L2C in the form of an AcquisitionResult object. Returns ------- out : AcquisitionResult L2C acquisition result or None """ if self.l2c_handover_acq and not self.l2c_handover_done: self.l2c_handover_done = True return self.l2c_handover_acq return None def _short_n_long_preprocess(self): if self.short_n_long and not self.stage1: # When simulating short and long cycles, short step resets EPL # registers, and long one adds up to them if self.short_step: self.E = self.P = self.L = 0.j self.coherent_iter = 1 else: self.coherent_iter = self.coherent_ms - 1 else: self.E = self.P = self.L = 0.j self.code_chips_to_integrate = gps_constants.chips_per_code return self.coherent_iter, self.code_chips_to_integrate def _short_n_long_postprocess(self): more_integration_needed = False if not self.stage1 and self.short_n_long: if self.short_step: # In case of short step - go to next integration period self.short_step = False self.alias_detect.first(self.P.real, self.P.imag) more_integration_needed = True else: # Next step is short cycle self.short_step = True return more_integration_needed def _run_postprocess(self): """ Run L1C/A coherent integration postprocessing. Runs navigation bit sync decoding operation and L1C/A to L2C handover. """ sync, bit = self.nav_bit_sync.update(np.real(self.P), self.coherent_ms) if sync: tow = self.nav_msg.update(bit) if tow >= 0: logger.info("[PRN: %d (%s)] ToW %d" % (self.prn + 1, self.signal, tow)) if self.nav_msg.subframe_ready(): data = GpsL1CADecodedData() sid = signal_from_code_index(0, self.prn) res = self.nav_msg.process_subframe(sid, data) if res < 0: logger.error("[PRN: %d (%s)] Subframe decoding error %d" % (self.prn + 1, self.signal, res)) elif res > 0: logger.info("[PRN: %d (%s)] Subframe decoded" % (self.prn + 1, self.signal)) else: # Subframe decoding is in progress pass else: tow = -1 self.track_result.tow[self.i] = tow if tow >= 0 else ( self.track_result.tow[self.i - 1] + self.coherent_ms) # Handover to L2C if possible if self.l2c_handover and not self.l2c_handover_acq and \ 'samples' in self.samples[gps_constants.L2C] and sync: chan_snr = self.track_result.cn0[self.i] chan_snr -= 10 * np.log10(defaults.L1CA_CHANNEL_BANDWIDTH_HZ) chan_snr = np.power(10, chan_snr / 10) l2c_doppler = self.loop_filter.to_dict( )['carr_freq'] * gps_constants.l2 / gps_constants.l1 self.l2c_handover_acq = \ AcquisitionResult(self.prn, self.samples[gps_constants.L2C][ 'IF'] + l2c_doppler, l2c_doppler, # carrier doppler self.track_result.code_phase[ self.i], chan_snr, 'A', gps_constants.L2C, self.track_result.absolute_sample[self.i])