GNSS-SDR  0.0.19
An Open Source GNSS Software Defined Receiver
pcps_acquisition.h
Go to the documentation of this file.
1 /*!
2  * \file pcps_acquisition.h
3  * \brief This class implements a Parallel Code Phase Search Acquisition
4  *
5  * Acquisition strategy (Kay Borre book + CFAR threshold).
6  * <ol>
7  * <li> Compute the input signal power estimation
8  * <li> Doppler serial search loop
9  * <li> Perform the FFT-based circular convolution (parallel time search)
10  * <li> Record the maximum peak and the associated synchronization parameters
11  * <li> Compute the test statistics and compare to the threshold
12  * <li> Declare positive or negative acquisition using a message queue
13  * </ol>
14  *
15  * Kay Borre book: K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen,
16  * "A Software-Defined GPS and Galileo Receiver. A Single-Frequency
17  * Approach", Birkhauser, 2007. pp 81-84
18  *
19  * \authors <ul>
20  * <li> Javier Arribas, 2011. jarribas(at)cttc.es
21  * <li> Luis Esteve, 2012. luis(at)epsilon-formacion.com
22  * <li> Marc Molina, 2013. marc.molina.pena@gmail.com
23  * <li> Cillian O'Driscoll, 2017. cillian(at)ieee.org
24  * <li> Antonio Ramos, 2017. antonio.ramos@cttc.es
25  * </ul>
26  *
27  * -----------------------------------------------------------------------------
28  *
29  * GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
30  * This file is part of GNSS-SDR.
31  *
32  * Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors)
33  * SPDX-License-Identifier: GPL-3.0-or-later
34  *
35  * -----------------------------------------------------------------------------
36  */
37 
38 #ifndef GNSS_SDR_PCPS_ACQUISITION_H
39 #define GNSS_SDR_PCPS_ACQUISITION_H
40 
41 #if ARMA_NO_BOUND_CHECKING
42 #define ARMA_NO_DEBUG 1
43 #endif
44 
45 #include "acq_conf.h"
46 #include "channel_fsm.h"
47 #include "gnss_sdr_fft.h"
48 #include <armadillo>
49 #include <glog/logging.h>
50 #include <gnuradio/block.h>
51 #include <gnuradio/gr_complex.h> // for gr_complex
52 #include <gnuradio/thread/thread.h> // for scoped_lock
53 #include <gnuradio/types.h> // for gr_vector_const_void_star
54 #include <volk/volk_complex.h> // for lv_16sc_t
55 #include <volk_gnsssdr/volk_gnsssdr_alloc.h> // for volk_gnsssdr::vector
56 #include <complex>
57 #include <cstdint>
58 #include <memory>
59 #include <queue>
60 #include <string>
61 #include <utility>
62 
63 #if HAS_STD_SPAN
64 #include <span>
65 namespace own = std;
66 #else
67 #include <gsl/gsl-lite.hpp>
68 namespace own = gsl;
69 #endif
70 
71 /** \addtogroup Acquisition
72  * Classes for GNSS signal acquisition
73  * \{ */
74 /** \addtogroup Acq_gnuradio_blocks acquisition_gr_blocks
75  * GNU Radio processing blocks for GNSS signal acquisition
76  * \{ */
77 
78 
79 class Gnss_Synchro;
80 class pcps_acquisition;
81 
82 using pcps_acquisition_sptr = gnss_shared_ptr<pcps_acquisition>;
83 
84 pcps_acquisition_sptr pcps_make_acquisition(const Acq_Conf& conf_);
85 
86 /*!
87  * \brief This class implements a Parallel Code Phase Search Acquisition.
88  *
89  * Check \ref Navitec2012 "An Open Source Galileo E1 Software Receiver",
90  * Algorithm 1, for a pseudocode description of this implementation.
91  */
92 class pcps_acquisition : public gr::block
93 {
94 public:
95  ~pcps_acquisition() override = default;
96 
97  /*!
98  * \brief Initializes acquisition algorithm and reserves memory.
99  */
100  void init();
101 
102  /*!
103  * \brief Set acquisition/tracking common Gnss_Synchro object pointer
104  * to exchange synchronization data between acquisition and tracking blocks.
105  * \param p_gnss_synchro Satellite information shared by the processing blocks.
106  */
107  inline void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro)
108  {
109  gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler
110  d_gnss_synchro = p_gnss_synchro;
111  }
112 
113  /*!
114  * \brief Sets local code for PCPS acquisition algorithm.
115  * \param code - Pointer to the PRN code.
116  */
117  void set_local_code(std::complex<float>* code);
118 
119  /*!
120  * \brief If set to 1, ensures that acquisition starts at the
121  * first available sample.
122  * \param state - int=1 forces start of acquisition
123  */
124  void set_state(int32_t state);
125 
126  void set_resampler_latency(uint32_t latency_samples);
127 
128  /*!
129  * \brief Returns the maximum peak of grid search.
130  */
131  inline uint32_t mag() const
132  {
133  return d_mag;
134  }
135 
136  /*!
137  * \brief Starts acquisition algorithm, turning from standby mode to
138  * active mode
139  * \param active - bool that activates/deactivates the block.
140  */
141  inline void set_active(bool active)
142  {
143  gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler
144  d_active = active;
145  }
146 
147  /*!
148  * \brief Set acquisition channel unique ID
149  * \param channel - receiver channel.
150  */
151  inline void set_channel(uint32_t channel)
152  {
153  d_channel = channel;
154  }
155 
156  /*!
157  * \brief Set channel fsm associated to this acquisition instance
158  */
159  inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm)
160  {
161  d_channel_fsm = std::move(channel_fsm);
162  }
163 
164  /*!
165  * \brief Set statistics threshold of PCPS algorithm.
166  * \param threshold - Threshold for signal detection (check \ref Navitec2012,
167  * Algorithm 1, for a definition of this threshold).
168  */
169  inline void set_threshold(float threshold)
170  {
171  gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler
172  d_threshold = threshold;
173  }
174 
175  /*!
176  * \brief Set maximum Doppler grid search
177  * \param doppler_max - Maximum Doppler shift considered in the grid search [Hz].
178  */
179  inline void set_doppler_max(uint32_t doppler_max)
180  {
181  gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler
182  d_acq_parameters.doppler_max = doppler_max;
183  }
184 
185  /*!
186  * \brief Set Doppler steps for the grid search
187  * \param doppler_step - Frequency bin of the search grid [Hz].
188  */
189  inline void set_doppler_step(uint32_t doppler_step)
190  {
191  gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler
192  d_doppler_step = doppler_step;
193  }
194 
195  /*!
196  * \brief Set Doppler center frequency for the grid search. It will refresh the Doppler grid.
197  * \param doppler_center - Frequency center of the search grid [Hz].
198  */
199  inline void set_doppler_center(int32_t doppler_center)
200  {
201  gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler
202  if (doppler_center != d_doppler_center)
203  {
204  DLOG(INFO) << " Doppler assistance for Channel: " << d_channel << " => Doppler: " << doppler_center << "[Hz]";
205  d_doppler_center = doppler_center;
206  update_grid_doppler_wipeoffs();
207  }
208  }
209 
210  /*!
211  * \brief Parallel Code Phase Search Acquisition signal processing.
212  */
213  int general_work(int noutput_items, gr_vector_int& ninput_items,
214  gr_vector_const_void_star& input_items,
215  gr_vector_void_star& output_items) override;
216 
217 private:
218  friend pcps_acquisition_sptr pcps_make_acquisition(const Acq_Conf& conf_);
219  explicit pcps_acquisition(const Acq_Conf& conf_);
220 
221  void update_local_carrier(own::span<gr_complex> carrier_vector, float freq) const;
222  void update_grid_doppler_wipeoffs();
223  void update_grid_doppler_wipeoffs_step2();
224  void acquisition_core(uint64_t samp_count);
225  void send_negative_acquisition();
226  void send_positive_acquisition();
227  void dump_results(int32_t effective_fft_size);
228  bool is_fdma();
229  bool start() override;
230  void calculate_threshold(void);
231  float first_vs_second_peak_statistic(uint32_t& indext, int32_t& doppler, uint32_t num_doppler_bins, int32_t doppler_max, int32_t doppler_step);
232  float max_to_input_power_statistic(uint32_t& indext, int32_t& doppler, uint32_t num_doppler_bins, int32_t doppler_max, int32_t doppler_step);
233 
234  volk_gnsssdr::vector<volk_gnsssdr::vector<float>> d_magnitude_grid;
235  volk_gnsssdr::vector<float> d_tmp_buffer;
236  volk_gnsssdr::vector<std::complex<float>> d_input_signal;
237  volk_gnsssdr::vector<volk_gnsssdr::vector<std::complex<float>>> d_grid_doppler_wipeoffs;
238  volk_gnsssdr::vector<volk_gnsssdr::vector<std::complex<float>>> d_grid_doppler_wipeoffs_step_two;
239  volk_gnsssdr::vector<std::complex<float>> d_fft_codes;
240  volk_gnsssdr::vector<std::complex<float>> d_data_buffer;
241  volk_gnsssdr::vector<lv_16sc_t> d_data_buffer_sc;
242 
243  std::unique_ptr<gnss_fft_complex_fwd> d_fft_if;
244  std::unique_ptr<gnss_fft_complex_rev> d_ifft;
245  std::weak_ptr<ChannelFsm> d_channel_fsm;
246 
247  Acq_Conf d_acq_parameters;
248  Gnss_Synchro* d_gnss_synchro;
249  arma::fmat d_grid;
250  arma::fmat d_narrow_grid;
251 
252  std::queue<Gnss_Synchro> d_monitor_queue;
253  std::string d_dump_filename;
254 
255  int64_t d_dump_number;
256  uint64_t d_sample_counter;
257 
258  float d_threshold;
259  float d_mag;
260  float d_input_power;
261  float d_test_statistics;
262  float d_doppler_center_step_two;
263 
264  int32_t d_state;
265  int32_t d_positive_acq;
266  int32_t d_doppler_center;
267  int32_t d_doppler_bias;
268  uint32_t d_channel;
269  uint32_t d_samplesPerChip;
270  uint32_t d_doppler_step;
271  uint32_t d_num_noncoherent_integrations_counter;
272  uint32_t d_fft_size;
273  uint32_t d_consumed_samples;
274  uint32_t d_num_doppler_bins;
275  uint32_t d_num_doppler_bins_step2;
276  uint32_t d_dump_channel;
277  uint32_t d_buffer_count;
278 
279  bool d_active;
280  bool d_worker_active;
281  bool d_cshort;
282  bool d_step_two;
283  bool d_use_CFAR_algorithm_flag;
284  bool d_dump;
285 };
286 
287 
288 /** \} */
289 /** \} */
290 #endif // GNSS_SDR_PCPS_ACQUISITION_H
void set_doppler_step(uint32_t doppler_step)
Set Doppler steps for the grid search.
Helper file for FFT interface.
This class implements a Parallel Code Phase Search Acquisition.
void set_state(int32_t state)
If set to 1, ensures that acquisition starts at the first available sample.
STL namespace.
void set_active(bool active)
Starts acquisition algorithm, turning from standby mode to active mode.
void set_doppler_max(uint32_t doppler_max)
Set maximum Doppler grid search.
Class that contains all the configuration parameters for generic acquisition block based on the PCPS ...
Interface of the State Machine for channel.
void set_local_code(std::complex< float > *code)
Sets local code for PCPS acquisition algorithm.
This is the class that contains the information that is shared by the processing blocks.
Definition: gnss_synchro.h:38
void set_doppler_center(int32_t doppler_center)
Set Doppler center frequency for the grid search. It will refresh the Doppler grid.
void set_channel(uint32_t channel)
Set acquisition channel unique ID.
void set_channel_fsm(std::weak_ptr< ChannelFsm > channel_fsm)
Set channel fsm associated to this acquisition instance.
uint32_t mag() const
Returns the maximum peak of grid search.
void set_gnss_synchro(Gnss_Synchro *p_gnss_synchro)
Set acquisition/tracking common Gnss_Synchro object pointer to exchange synchronization data between ...
int general_work(int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) override
Parallel Code Phase Search Acquisition signal processing.
void init()
Initializes acquisition algorithm and reserves memory.
void set_threshold(float threshold)
Set statistics threshold of PCPS algorithm.