Ejemplo n.º 1
0
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
Ejemplo n.º 2
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])