def gen_signal(ephems, traj, t0, t_run, t_skip=0, t_step=0.002, fs=16.368e6, fi=4.092e6, snr=1, jitter=0, prns=range(1), scale=16, repair_unsmooth=True): step_t, step_tow, step_pv, step_samps = \ interp_traj(traj, t0, t_run, t_skip, t_step, fs, smoothify=repair_unsmooth) step_prn_snrs = [{p: snr for p in prns} for t in step_t] np.random.seed(222) nav_msg_tow0 = int(step_tow[0] / (5*6)) * 5*6 # Round to beginning of 30-second nav msg cycle nav_msgs = {prn: gen_nav_msg(ephems[prn], nav_msg_tow0) for prn in prns} cacodes = {prn: np.array(gencode.generateCAcode(prn)) for prn in prns} # nav_msgs = {prn: None for prn in prns} # cacodes = {prn: np.ones(1023) for prn in prns} chunk_len = 10 def gen_chunk(i, n): ss = [] for ix in range(i, i + n): def gen_signal_step_sat(prn): x, v = sat_los(step_tow[ix], step_pv[ix], ephems[prn]) return gen_signal_sat_los(step_tow[ix], x, v, step_samps, fs, fi, cacodes[prn], nav_msgs[prn], nav_msg_tow0, jitter) * step_prn_snrs[ix][prn] sp = map(lambda prn: gen_signal_step_sat(prn), step_prn_snrs[ix].keys()) s = np.sum(sp,0)# + np.random.normal(size=step_samps) s = np.int8(s * scale) ss.append(s) return np.concatenate(ss) sss = pp.parmap(lambda i: gen_chunk(i, min(chunk_len, len(step_t)-i)), range(0, len(step_t), chunk_len)) return np.concatenate(sss)
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
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