コード例 #1
0
ファイル: acquisition.py プロジェクト: odrisci/peregrine
    def acquisition(self,
                    prns=range(32),
                    start_doppler=-7000,
                    stop_doppler=7000,
                    doppler_step=None,
                    threshold=DEFAULT_THRESHOLD,
                    show_progress=True):
        """
    Perform an acquisition for a given list of PRNs.

    Perform an acquisition for a given list of PRNs across a range of Doppler
    frequencies.

    This function returns :class:`AcquisitionResult` objects contatining the
    location of the acquisition peak for PRNs that have an acquisition
    Signal-to-Noise ratio (SNR) greater than `threshold`.

    This calls `acquire` to find the precise code phase and a carrier frequency
    estimate to within `doppler_step` Hz and then uses interpolation to refine
    the carrier frequency estimate.

    Parameters
    ----------
    prns : iterable
      List of PRNs to acquire.
    start_doppler : float, optional
      Start of Doppler frequency search range in Hz. This value is included in
      the search.
    stop_doppler : float, optional
      End of Doppler frequency search range in Hz. This value is not included
      in the search.
    doppler_step : float, optional
      Doppler frequency step to use when performing the coarse Doppler
      frequency search.
    threshold : float, optional
      Threshold SNR value for a satellite to be considered acquired.
    show_progress : bool, optional
      When `True` a progress bar will be printed showing acquisition status and
      estimated time remaining.

    Returns
    -------
    out : [AcquisitionResult]
      A list of :class:`AcquisitionResult` objects, one per PRN in `prns`.

    """
        logger.info("Acquisition starting")

        # If the Doppler step is not specified, compute it from the coarse
        # acquisition length.
        if doppler_step is None:
            # TODO: Work out the best frequency bin spacing.
            # This is slightly sub-optimal if power is split between two bins,
            # perhaps you could peak fit or look at pairs of bins to get true peak
            # magnitude.
            doppler_step = self.sampling_freq / self.n_coarse

        freqs = np.arange(start_doppler, stop_doppler, doppler_step) + self.IF

        # If progressbar is not available, disable show_progress.
        if show_progress and not _progressbar_available:
            show_progress = False
            logger.warning(
                "show_progress = True but progressbar module not found.")

        # Setup our progress bar if we need it
        if show_progress:
            widgets = [
                '  Acquisition ',
                progressbar.Attribute('prn', '(PRN: %02d)', '(PRN --)'), ' ',
                progressbar.Percentage(), ' ',
                progressbar.ETA(), ' ',
                progressbar.Bar()
            ]
            pbar = progressbar.ProgressBar(widgets=widgets,
                                           maxval=len(prns) * len(freqs))
            pbar.start()
        else:
            pbar = None

        acq_results = []
        for n, prn in enumerate(prns):
            if pbar:

                def progress_callback(freq_num, num_freqs):
                    pbar.update(n * len(freqs) + freq_num,
                                attr={'prn': prn + 1})
            else:
                progress_callback = None

            coarse_results = self.acquire(caCodes[prn],
                                          freqs,
                                          progress_callback=progress_callback)
            code_phase, carr_freq, snr = self.find_peak(freqs, coarse_results)

            # If the result is above the threshold, then we have acquired the
            # satellite.
            status = '-'
            if (snr > threshold):
                status = 'A'

            # Save properties of the detected satellite signal
            acq_result = AcquisitionResult(prn, carr_freq, carr_freq - self.IF,
                                           code_phase, snr, status)
            acq_results.append(acq_result)

            # If the acquisition was successful, log it
            if (snr > threshold):
                logger.debug("Acquired %s" % acq_result)

        # Acquisition is finished

        # Stop printing progress bar
        if pbar:
            pbar.finish()

        logger.info("Acquisition finished")
        acquired_prns = [ar.prn + 1 for ar in acq_results if ar.status == 'A']
        logger.info("Acquired %d satellites, PRNs: %s.", len(acquired_prns),
                    acquired_prns)

        return acq_results
コード例 #2
0
ファイル: tracking.py プロジェクト: odrisci/peregrine
def track(signal, channel, settings,
          show_progress=True,
          trk=swiftnav.correlate.track_correlate,
          loop_filter=default_loop_filter):
  logger.info("Tracking starting")
  logger.debug("Tracking %d channels, PRNs %s" % (len(channel), [chan.prn+1 for chan in channel]))

  # Create list of tracking channels results (correlations, freqs, etc)
  track_results = []

  # If progressbar is not available, disable show_progress.
  if show_progress and not _progressbar_available:
    show_progress = False
    logger.warning("show_progress = True but progressbar module not found.")

  # Setup our progress bar if we need it
  if show_progress:
    widgets = ['  Tracking ',
               progressbar.Attribute(['chan', 'nchan'],
                                     '(CH: %d/%d)',
                                     '(CH: -/-)'), ' ',
               progressbar.Percentage(), ' ',
               progressbar.ETA(), ' ',
               progressbar.Bar()]
    pbar = progressbar.ProgressBar(widgets=widgets,
                                   maxval=len(channel)*settings.msToProcess,
                                   attr={'nchan': len(channel)})
    pbar.start()
  else:
    pbar = None

  #Do tracking for each channel
  for channelNr in range(len(channel)):
    track_result = TrackResults(settings.msToProcess)
    track_result.PRN = channel[channelNr].prn

    # Convert acquisition SNR to C/N0
    cn0_0 = 10*np.log10(channel[channelNr].snr)
    cn0_0 += 10*np.log10(1000) # Channel bandwidth
    cn0_est = swiftnav.track.CN0Estimator(1e3, cn0_0, 10, 1e3)

    loop_filter.start(0, channel[channelNr].carr_freq-settings.IF)
    remCodePhase = 0.0
    remCarrPhase = 0.0

    # Get a vector with the C/A code sampled 1x/chip
    caCode = caCodes[channel[channelNr].prn]

    # Add wrapping to either end to be able to do early/late
    caCode = np.concatenate(([caCode[1022]],caCode,[caCode[0]]))

    blksize_ = int(settings.samplingFreq * 1e-3 + 10)
    #number of samples to seek ahead in file
    samplesPerCodeChip = int(round(settings.samplingFreq / settings.codeFreqBasis))
    numSamplesToSkip = settings.skipNumberOfBytes + channel[channelNr].code_phase*samplesPerCodeChip

    #Process the specified number of ms
    for loopCnt in range(settings.msToProcess):
      if pbar:
        pbar.update(loopCnt + channelNr*settings.msToProcess, attr={'chan': channelNr+1})

      rawSignal = signal[numSamplesToSkip:]#[:blksize_]

      I_E, Q_E, I_P, Q_P, I_L, Q_L, blksize, remCodePhase, remCarrPhase = trk(rawSignal, loop_filter.code_freq+settings.codeFreqBasis, remCodePhase, loop_filter.carr_freq+settings.IF, remCarrPhase, caCode, settings)
      numSamplesToSkip += blksize

      E = I_E + Q_E*1.j
      P = I_P + Q_P*1.j
      L = I_L + Q_L*1.j
      loop_filter.update(E, P, L)

      track_result.carrPhase[loopCnt] = remCarrPhase
      track_result.carrFreq[loopCnt] = loop_filter.carr_freq+settings.IF

      track_result.codePhase[loopCnt] = remCodePhase
      track_result.codeFreq[loopCnt] = loop_filter.code_freq+settings.codeFreqBasis

      #Record stuff for postprocessing
      track_result.absoluteSample[loopCnt] = numSamplesToSkip

      track_result.I_E[loopCnt] = I_E
      track_result.I_P[loopCnt] = I_P
      track_result.I_L[loopCnt] = I_L
      track_result.Q_E[loopCnt] = Q_E
      track_result.Q_P[loopCnt] = Q_P
      track_result.Q_L[loopCnt] = Q_L

      track_result.cn0[loopCnt] = cn0_est.update(I_P)

    #Possibility for lock-detection later
    track_result.status = 'T'
    track_results += [track_result]

  if pbar:
    pbar.finish()

  logger.info("Tracking finished")

  return track_results
コード例 #3
0
ファイル: tracking.py プロジェクト: psalmela/peregrine
  def __init__(self,
               samples,
               channels,
               ms_to_track,
               sampling_freq,
               check_l2c_mask=False,
               l2c_handover=True,
               progress_bar_output='none',
               loop_filter_class=AidedTrackingLoop,
               correlator=track_correlate,
               stage2_coherent_ms=None,
               stage2_loop_filter_params=None,
               multi=False,
               tracker_options=None,
               output_file=None):
    """
    Set up tracking environment.
    1. Check if multy CPU tracking is possible
    2. Set up progress bar
    3. Create tracking channels based on the provided acquistion results

    Parameters
    ----------
    samples : dictionary
      Samples data for all one or more data channels
    channels : list
      A list of acquisition results
    ms_to_track : float
      How many milliseconds to track [ms].
      If set to '-1', then use all samples.
    sampling_freq : float
      Data sampling frequency [Hz]
    l2c_handover : bool
      Instructs if L1C/A to L2C handover is to be done
    progress_bar_output : string
      Where the progress bar updates are forwarded.
    loop_filter_class : class
      The type of the loop filter class to be used by tracker channels
    correlator : class
      The correlator class to be used by tracker channels
    stage2_coherent_ms : dictionary
      Stage 2 coherent integration parameters set.
    stage2_loop_filter_params : dictionary
      Stage 2 loop filter parameters set.
    multi : bool
      Enable multi core CPU utilization
    tracker_options : dictionary
      Enable piplining or short/long cycles tracking to simulate HW
    output_file : string
      The name of the output file, where the tracking results are stored.
      The actual file name is a mangled version of this file name and
      reflects the signal name and PRN number for which the tracking results
      are generated.

    """

    self.samples = samples
    self.sampling_freq = sampling_freq
    self.ms_to_track = ms_to_track
    self.tracker_options = tracker_options
    self.output_file = output_file
    self.l2c_handover = l2c_handover
    self.check_l2c_mask = check_l2c_mask
    self.correlator = correlator
    self.stage2_coherent_ms = stage2_coherent_ms
    self.stage2_loop_filter_params = stage2_loop_filter_params

    if mp.cpu_count() > 1:
      self.multi = multi
    else:
      self.multi = False

    self.loop_filter_class = loop_filter_class

    if self.ms_to_track >= 0:
      self.samples_to_track = self.ms_to_track * sampling_freq / 1e3
      if samples['samples_total'] < self.samples_to_track:
        logger.warning(
          "Samples set too short for requested tracking length (%.4fs)"
          % (self.ms_to_track * 1e-3))
        self.samples_to_track = samples['samples_total']
    else:
      self.samples_to_track = samples['samples_total']

    if progress_bar_output == 'stdout':
      self.show_progress = True
      progress_fd = sys.stdout
    elif progress_bar_output == 'stderr':
      self.show_progress = True
      progress_fd = sys.stderr
    else:
      self.show_progress = False
      progress_fd = -1

    # If progressbar is not available, disable show_progress.
    if self.show_progress and not _progressbar_available:
      self.show_progress = False
      logger.warning("show_progress = True but progressbar module not found.")

    self.init_sample_index = samples['sample_index']
    # Setup our progress bar if we need it
    if self.show_progress:
      widgets = ['  Tracking ',
                 progressbar.Attribute(['sample', 'samples'],
                                       '(sample: %d/%d)',
                                       '(sample: -/-)'), ' ',
                 progressbar.Percentage(), ' ',
                 progressbar.ETA(), ' ',
                 progressbar.Bar()]
      self.pbar = progressbar.ProgressBar(
          widgets=widgets,
          maxval=samples['samples_total'],
          attr={'samples': self.samples['samples_total'],
                'sample': 0l},
          fd=progress_fd)
    else:
      self.pbar = None

    self.tracking_channels = map(self._create_channel, channels)
コード例 #4
0
    def acquisition(self,
                    prns=range(32),
                    doppler_priors=None,
                    doppler_search=7000,
                    doppler_step=None,
                    threshold=DEFAULT_THRESHOLD,
                    progress_bar_output='none',
                    multi=True):
        """
    Perform an acquisition for a given list of PRNs.

    Perform an acquisition for a given list of PRNs across a range of Doppler
    frequencies.

    This function returns :class:`AcquisitionResult` objects containing the
    location of the acquisition peak for PRNs that have an acquisition
    Signal-to-Noise ratio (SNR) greater than `threshold`.

    This calls `acquire` to find the precise code phase and a carrier frequency
    estimate to within `doppler_step` Hz and then uses interpolation to refine
    the carrier frequency estimate.

    Parameters
    ----------
    prns : iterable, optional
      List of PRNs to acquire. Default: 0..31 (0-indexed)
    doppler_prior: list of floats, optional
      List of expected Doppler frequencies in Hz (one per PRN).  Search will be
      centered about these.  If None, will search around 0 for all PRNs.
    doppler_search: float, optional
      Maximum frequency away from doppler_prior to search.  Default: 7000
    doppler_step : float, optional
      Doppler frequency step to use when performing the coarse Doppler
      frequency search.
    threshold : float, optional
      Threshold SNR value for a satellite to be considered acquired.
    show_progress : bool, optional
      When `True` a progress bar will be printed showing acquisition status and
      estimated time remaining.

    Returns
    -------
    out : [AcquisitionResult]
      A list of :class:`AcquisitionResult` objects, one per PRN in `prns`.

    """
        logger.info("Acquisition starting")
        from peregrine.parallel_processing import parmap

        # If the Doppler step is not specified, compute it from the coarse
        # acquisition length.
        if doppler_step is None:
            # TODO: Work out the best frequency bin spacing.
            # This is slightly sub-optimal if power is split between two bins,
            # perhaps you could peak fit or look at pairs of bins to get true peak
            # magnitude.
            doppler_step = self.sampling_freq / self.n_integrate

        if doppler_priors is None:
            doppler_priors = np.zeros_like(prns)

        if progress_bar_output == 'stdout':
            show_progress = True
            progress_fd = sys.stdout
        elif progress_bar_output == 'stderr':
            show_progress = True
            progress_fd = sys.stderr
        else:
            show_progress = False
            progress_fd = -1

        # If progressbar is not available, disable show_progress.
        if show_progress and not _progressbar_available:
            show_progress = False
            logger.warning(
                "show_progress = True but progressbar module not found.")

        # Setup our progress bar if we need it
        if show_progress and not multi:
            widgets = [
                '  Acquisition ',
                progressbar.Attribute('prn', '(PRN: %02d)', '(PRN --)'), ' ',
                progressbar.Percentage(), ' ',
                progressbar.ETA(), ' ',
                progressbar.Bar()
            ]
            pbar = progressbar.ProgressBar(
                widgets=widgets,
                maxval=int(
                    len(prns) * (2 * doppler_search / doppler_step + 1)),
                fd=progress_fd)
            pbar.start()
        else:
            pbar = None

        def do_acq(n):
            prn = prns[n]
            doppler_prior = doppler_priors[n]
            freqs = np.arange(doppler_prior - doppler_search, doppler_prior +
                              doppler_search, doppler_step) + self.IF
            if pbar:

                def progress_callback(freq_num, num_freqs):
                    pbar.update(n * len(freqs) + freq_num,
                                attr={'prn': prn + 1})
            else:
                progress_callback = None

            coarse_results = self.acquire(caCodes[prn],
                                          freqs,
                                          progress_callback=progress_callback)

            code_phase, carr_freq, snr = self.find_peak(
                freqs, coarse_results, interpolation='gaussian')

            # If the result is above the threshold, then we have acquired the
            # satellite.
            status = '-'
            if (snr > threshold):
                status = 'A'

            # Save properties of the detected satellite signal
            acq_result = AcquisitionResult(prn, carr_freq, carr_freq - self.IF,
                                           code_phase, snr, status,
                                           self.signal)

            # If the acquisition was successful, log it
            if (snr > threshold):
                logger.debug("Acquired %s" % acq_result)

            return acq_result

        if multi:
            acq_results = parmap(do_acq,
                                 range(len(prns)),
                                 show_progress=show_progress)
        else:
            acq_results = map(do_acq, range(len(prns)))

        # Acquisition is finished

        # Stop printing progress bar
        if pbar:
            pbar.finish()

        logger.info("Acquisition finished")
        acquired_prns = [ar.prn + 1 for ar in acq_results if ar.status == 'A']
        logger.info("Acquired %d satellites, PRNs: %s.", len(acquired_prns),
                    acquired_prns)

        return acq_results