GNSS-SDR  0.0.14
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 <armadillo>
48 #include <glog/logging.h>
49 #include <gnuradio/block.h>
50 #include <gnuradio/fft/fft.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>
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() = 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);
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();
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 #if GNURADIO_FFT_USES_TEMPLATES
244  std::unique_ptr<gr::fft::fft_complex_fwd> d_fft_if;
245  std::unique_ptr<gr::fft::fft_complex_rev> d_ifft;
246 #else
247  std::unique_ptr<gr::fft::fft_complex> d_fft_if;
248  std::unique_ptr<gr::fft::fft_complex> d_ifft;
249 #endif
250 
251  std::weak_ptr<ChannelFsm> d_channel_fsm;
252 
253  Acq_Conf d_acq_parameters;
254  Gnss_Synchro* d_gnss_synchro;
255  arma::fmat d_grid;
256  arma::fmat d_narrow_grid;
257 
258  std::queue<Gnss_Synchro> d_monitor_queue;
259  std::string d_dump_filename;
260 
261  int64_t d_dump_number;
262  uint64_t d_sample_counter;
263 
264  float d_threshold;
265  float d_mag;
266  float d_input_power;
267  float d_test_statistics;
268  float d_doppler_center_step_two;
269 
270  int32_t d_state;
271  int32_t d_positive_acq;
272  int32_t d_doppler_center;
273  int32_t d_doppler_bias;
274  uint32_t d_channel;
275  uint32_t d_samplesPerChip;
276  uint32_t d_doppler_step;
277  uint32_t d_num_noncoherent_integrations_counter;
278  uint32_t d_fft_size;
279  uint32_t d_consumed_samples;
280  uint32_t d_num_doppler_bins;
281  uint32_t d_num_doppler_bins_step2;
282  uint32_t d_dump_channel;
283  uint32_t d_buffer_count;
284 
285  bool d_active;
286  bool d_worker_active;
287  bool d_cshort;
288  bool d_step_two;
289  bool d_use_CFAR_algorithm_flag;
290  bool d_dump;
291 };
292 
293 
294 /** \} */
295 /** \} */
296 #endif // GNSS_SDR_PCPS_ACQUISITION_H
void set_doppler_step(uint32_t doppler_step)
Set Doppler steps for the grid search.
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)
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.