GNSS-SDR  0.0.13
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  * Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors)
30  *
31  * GNSS-SDR is a software defined Global Navigation
32  * Satellite Systems receiver
33  *
34  * This file is part of GNSS-SDR.
35  *
36  * SPDX-License-Identifier: GPL-3.0-or-later
37  *
38  * -----------------------------------------------------------------------------
39  */
40 
41 #ifndef GNSS_SDR_PCPS_ACQUISITION_H
42 #define GNSS_SDR_PCPS_ACQUISITION_H
43 
44 #if ARMA_NO_BOUND_CHECKING
45 #define ARMA_NO_DEBUG 1
46 #endif
47 
48 #include "acq_conf.h"
49 #include "channel_fsm.h"
50 #include <armadillo>
51 #include <glog/logging.h>
52 #include <gnuradio/block.h>
53 #include <gnuradio/fft/fft.h>
54 #include <gnuradio/gr_complex.h> // for gr_complex
55 #include <gnuradio/thread/thread.h> // for scoped_lock
56 #include <gnuradio/types.h> // for gr_vector_const_void_star
57 #include <volk/volk_complex.h> // for lv_16sc_t
58 #include <volk_gnsssdr/volk_gnsssdr_alloc.h> // for volk_gnsssdr::vector
59 #include <complex>
60 #include <cstdint>
61 #include <memory>
62 #include <string>
63 #include <utility>
64 
65 #if HAS_STD_SPAN
66 #include <span>
67 namespace own = std;
68 #else
69 #include <gsl/gsl>
70 namespace own = gsl;
71 #endif
72 
73 #if GNURADIO_USES_STD_POINTERS
74 #else
75 #include <boost/shared_ptr.hpp>
76 #endif
77 
78 class Gnss_Synchro;
79 class pcps_acquisition;
80 
81 #if GNURADIO_USES_STD_POINTERS
82 using pcps_acquisition_sptr = std::shared_ptr<pcps_acquisition>;
83 #else
84 using pcps_acquisition_sptr = boost::shared_ptr<pcps_acquisition>;
85 #endif
86 
87 pcps_acquisition_sptr pcps_make_acquisition(const Acq_Conf& conf_);
88 
89 /*!
90  * \brief This class implements a Parallel Code Phase Search Acquisition.
91  *
92  * Check \ref Navitec2012 "An Open Source Galileo E1 Software Receiver",
93  * Algorithm 1, for a pseudocode description of this implementation.
94  */
95 class pcps_acquisition : public gr::block
96 {
97 public:
98  ~pcps_acquisition() = default;
99 
100  /*!
101  * \brief Initializes acquisition algorithm and reserves memory.
102  */
103  void init();
104 
105  /*!
106  * \brief Set acquisition/tracking common Gnss_Synchro object pointer
107  * to exchange synchronization data between acquisition and tracking blocks.
108  * \param p_gnss_synchro Satellite information shared by the processing blocks.
109  */
110  inline void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro)
111  {
112  gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler
113  d_gnss_synchro = p_gnss_synchro;
114  }
115 
116  /*!
117  * \brief Sets local code for PCPS acquisition algorithm.
118  * \param code - Pointer to the PRN code.
119  */
120  void set_local_code(std::complex<float>* code);
121 
122  /*!
123  * \brief If set to 1, ensures that acquisition starts at the
124  * first available sample.
125  * \param state - int=1 forces start of acquisition
126  */
127  void set_state(int32_t state);
128 
129  void set_resampler_latency(uint32_t latency_samples);
130 
131  /*!
132  * \brief Returns the maximum peak of grid search.
133  */
134  inline uint32_t mag() const
135  {
136  return d_mag;
137  }
138 
139  /*!
140  * \brief Starts acquisition algorithm, turning from standby mode to
141  * active mode
142  * \param active - bool that activates/deactivates the block.
143  */
144  inline void set_active(bool active)
145  {
146  gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler
147  d_active = active;
148  }
149 
150  /*!
151  * \brief Set acquisition channel unique ID
152  * \param channel - receiver channel.
153  */
154  inline void set_channel(uint32_t channel)
155  {
156  d_channel = channel;
157  }
158 
159  /*!
160  * \brief Set channel fsm associated to this acquisition instance
161  */
162  inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm)
163  {
164  d_channel_fsm = std::move(channel_fsm);
165  }
166 
167  /*!
168  * \brief Set statistics threshold of PCPS algorithm.
169  * \param threshold - Threshold for signal detection (check \ref Navitec2012,
170  * Algorithm 1, for a definition of this threshold).
171  */
172  inline void set_threshold(float threshold)
173  {
174  gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler
175  d_threshold = threshold;
176  }
177 
178  /*!
179  * \brief Set maximum Doppler grid search
180  * \param doppler_max - Maximum Doppler shift considered in the grid search [Hz].
181  */
182  inline void set_doppler_max(uint32_t doppler_max)
183  {
184  gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler
185  d_acq_parameters.doppler_max = doppler_max;
186  }
187 
188  /*!
189  * \brief Set Doppler steps for the grid search
190  * \param doppler_step - Frequency bin of the search grid [Hz].
191  */
192  inline void set_doppler_step(uint32_t doppler_step)
193  {
194  gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler
195  d_doppler_step = doppler_step;
196  }
197 
198  /*!
199  * \brief Set Doppler center frequency for the grid search. It will refresh the Doppler grid.
200  * \param doppler_center - Frequency center of the search grid [Hz].
201  */
202  inline void set_doppler_center(int32_t doppler_center)
203  {
204  gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler
205  if (doppler_center != d_doppler_center)
206  {
207  DLOG(INFO) << " Doppler assistance for Channel: " << d_channel << " => Doppler: " << doppler_center << "[Hz]";
208  d_doppler_center = doppler_center;
209  update_grid_doppler_wipeoffs();
210  }
211  }
212 
213  /*!
214  * \brief Parallel Code Phase Search Acquisition signal processing.
215  */
216  int general_work(int noutput_items, gr_vector_int& ninput_items,
217  gr_vector_const_void_star& input_items,
218  gr_vector_void_star& output_items);
219 
220 private:
221  friend pcps_acquisition_sptr pcps_make_acquisition(const Acq_Conf& conf_);
222  explicit pcps_acquisition(const Acq_Conf& conf_);
223 
224  void update_local_carrier(own::span<gr_complex> carrier_vector, float freq);
225  void update_grid_doppler_wipeoffs();
226  void update_grid_doppler_wipeoffs_step2();
227  void acquisition_core(uint64_t samp_count);
228  void send_negative_acquisition();
229  void send_positive_acquisition();
230  void dump_results(int32_t effective_fft_size);
231  bool is_fdma();
232  bool start();
233  void calculate_threshold(void);
234  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);
235  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);
236 
237  volk_gnsssdr::vector<volk_gnsssdr::vector<float>> d_magnitude_grid;
238  volk_gnsssdr::vector<float> d_tmp_buffer;
239  volk_gnsssdr::vector<std::complex<float>> d_input_signal;
240  volk_gnsssdr::vector<volk_gnsssdr::vector<std::complex<float>>> d_grid_doppler_wipeoffs;
241  volk_gnsssdr::vector<volk_gnsssdr::vector<std::complex<float>>> d_grid_doppler_wipeoffs_step_two;
242  volk_gnsssdr::vector<std::complex<float>> d_fft_codes;
243  volk_gnsssdr::vector<std::complex<float>> d_data_buffer;
244  volk_gnsssdr::vector<lv_16sc_t> d_data_buffer_sc;
245 
246  std::unique_ptr<gr::fft::fft_complex> d_fft_if;
247  std::unique_ptr<gr::fft::fft_complex> d_ifft;
248  std::weak_ptr<ChannelFsm> d_channel_fsm;
249 
250  Acq_Conf d_acq_parameters;
251  Gnss_Synchro* d_gnss_synchro;
252  arma::fmat d_grid;
253  arma::fmat d_narrow_grid;
254 
255  std::string d_dump_filename;
256 
257  int64_t d_dump_number;
258  uint64_t d_sample_counter;
259 
260  float d_threshold;
261  float d_mag;
262  float d_input_power;
263  float d_test_statistics;
264  float d_doppler_center_step_two;
265 
266  int32_t d_state;
267  int32_t d_positive_acq;
268  int32_t d_doppler_center;
269  int32_t d_doppler_bias;
270  uint32_t d_channel;
271  uint32_t d_samplesPerChip;
272  uint32_t d_doppler_step;
273  uint32_t d_num_noncoherent_integrations_counter;
274  uint32_t d_fft_size;
275  uint32_t d_consumed_samples;
276  uint32_t d_num_doppler_bins;
277  uint32_t d_num_doppler_bins_step2;
278  uint32_t d_dump_channel;
279  uint32_t d_buffer_count;
280 
281  bool d_active;
282  bool d_worker_active;
283  bool d_cshort;
284  bool d_step_two;
285  bool d_use_CFAR_algorithm_flag;
286  bool d_dump;
287 };
288 
289 #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:33
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.