From d76dab62485f6aa08a3a5526a2b6b4623225f787 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sun, 8 Jul 2018 13:26:30 +0200 Subject: [PATCH 01/11] Implement non-coherent acquisition --- .../gnuradio_blocks/pcps_acquisition.cc | 54 +++++++++++++------ .../gnuradio_blocks/pcps_acquisition.h | 6 ++- 2 files changed, 43 insertions(+), 17 deletions(-) diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc index a9d6f8c53..c77b48ef1 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc @@ -63,7 +63,7 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu d_positive_acq = 0; d_state = 0; d_old_freq = 0; - d_well_count = 0; + d_num_noncoherent_integrations_counter = 0; d_fft_size = acq_parameters.sampled_ms * acq_parameters.samples_per_ms; d_mag = 0; d_input_power = 0.0; @@ -82,6 +82,8 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu d_cshort = true; } + d_tmp_buffer = static_cast(volk_gnsssdr_malloc(d_fft_size * sizeof(float), volk_gnsssdr_get_alignment())); + // COD: // Experimenting with the overlap/save technique for handling bit trannsitions // The problem: Circular correlation is asynchronous with the received code. @@ -110,6 +112,7 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu d_gnss_synchro = 0; d_grid_doppler_wipeoffs = nullptr; d_grid_doppler_wipeoffs_step_two = nullptr; + d_magnitude_grid = nullptr; d_worker_active = false; d_data_buffer = static_cast(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment())); if (d_cshort) @@ -134,8 +137,10 @@ pcps_acquisition::~pcps_acquisition() for (unsigned int i = 0; i < d_num_doppler_bins; i++) { volk_gnsssdr_free(d_grid_doppler_wipeoffs[i]); + volk_gnsssdr_free(d_magnitude_grid[i]); } delete[] d_grid_doppler_wipeoffs; + delete[] d_magnitude_grid; } if (acq_parameters.make_2_steps) { @@ -147,6 +152,7 @@ pcps_acquisition::~pcps_acquisition() } volk_gnsssdr_free(d_fft_codes); volk_gnsssdr_free(d_magnitude); + volk_gnsssdr_free(d_tmp_buffer); delete d_ifft; delete d_fft_if; volk_gnsssdr_free(d_data_buffer); @@ -243,9 +249,12 @@ void pcps_acquisition::init() d_grid_doppler_wipeoffs_step_two[doppler_index] = static_cast(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment())); } } + + d_magnitude_grid = new float*[d_num_doppler_bins]; for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++) { d_grid_doppler_wipeoffs[doppler_index] = static_cast(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment())); + d_magnitude_grid[doppler_index] = static_cast(volk_gnsssdr_malloc(d_fft_size * sizeof(float), volk_gnsssdr_get_alignment())); int doppler = -static_cast(acq_parameters.doppler_max) + d_doppler_step * doppler_index; update_local_carrier(d_grid_doppler_wipeoffs[doppler_index], d_fft_size, d_old_freq + doppler); } @@ -268,6 +277,7 @@ void pcps_acquisition::update_grid_doppler_wipeoffs() } } + void pcps_acquisition::update_grid_doppler_wipeoffs_step2() { for (unsigned int doppler_index = 0; doppler_index < acq_parameters.num_doppler_bins_step2; doppler_index++) @@ -277,6 +287,7 @@ void pcps_acquisition::update_grid_doppler_wipeoffs_step2() } } + void pcps_acquisition::set_state(int state) { gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler @@ -286,7 +297,6 @@ void pcps_acquisition::set_state(int state) d_gnss_synchro->Acq_delay_samples = 0.0; d_gnss_synchro->Acq_doppler_hz = 0.0; d_gnss_synchro->Acq_samplestamp_samples = 0; - d_well_count = 0; d_mag = 0.0; d_input_power = 0.0; d_test_statistics = 0.0; @@ -434,7 +444,7 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) d_input_power = 0.0; d_mag = 0.0; - d_well_count++; + d_num_noncoherent_integrations_counter++; DLOG(INFO) << "Channel: " << d_channel << " , doing acquisition of satellite: " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN @@ -474,14 +484,22 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) // Search maximum size_t offset = (acq_parameters.bit_transition_flag ? effective_fft_size : 0); - volk_32fc_magnitude_squared_32f(d_magnitude, d_ifft->get_outbuf() + offset, effective_fft_size); - volk_gnsssdr_32f_index_max_32u(&indext, d_magnitude, effective_fft_size); - magt = d_magnitude[indext]; + if (d_num_noncoherent_integrations_counter == 1) + { + volk_32fc_magnitude_squared_32f(d_magnitude_grid[doppler_index], d_ifft->get_outbuf() + offset, effective_fft_size); + } + else + { + volk_32fc_magnitude_squared_32f(d_tmp_buffer, d_ifft->get_outbuf() + offset, effective_fft_size); + volk_32f_x2_add_32f(d_magnitude_grid[doppler_index], d_magnitude_grid[doppler_index], d_tmp_buffer, effective_fft_size); + } + volk_gnsssdr_32f_index_max_32u(&indext, d_magnitude_grid[doppler_index], effective_fft_size); + magt = d_magnitude_grid[doppler_index][indext]; if (acq_parameters.use_CFAR_algorithm_flag) { // Normalize the maximum value to correct the scale factor introduced by FFTW - magt = d_magnitude[indext] / (fft_normalization_factor * fft_normalization_factor); + magt = magt / (fft_normalization_factor * fft_normalization_factor); } // 4- record the maximum peak and the associated synchronization parameters if (d_mag < magt) @@ -491,7 +509,7 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) if (!acq_parameters.use_CFAR_algorithm_flag) { // Search grid noise floor approximation for this doppler line - volk_32f_accumulator_s32f(&d_input_power, d_magnitude, effective_fft_size); + volk_32f_accumulator_s32f(&d_input_power, d_magnitude_grid[doppler_index], effective_fft_size); d_input_power = (d_input_power - d_mag) / (effective_fft_size - 1); } @@ -517,7 +535,7 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) // Record results to file if required if (acq_parameters.dump and d_channel == d_dump_channel) { - memcpy(grid_.colptr(doppler_index), d_magnitude, sizeof(float) * effective_fft_size); + memcpy(grid_.colptr(doppler_index), d_magnitude_grid[doppler_index], sizeof(float) * effective_fft_size); } } } @@ -616,12 +634,13 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) d_state = 0; // Positive acquisition } } - else if (d_well_count == acq_parameters.max_dwells) + + if (d_num_noncoherent_integrations_counter == acq_parameters.max_dwells) { + if (d_state != 0) send_negative_acquisition(); d_state = 0; d_active = false; d_step_two = false; - send_negative_acquisition(); } } else @@ -657,10 +676,16 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) } } d_worker_active = false; - // Record results to file if required - if (acq_parameters.dump and d_channel == d_dump_channel) + + if ((d_num_noncoherent_integrations_counter == acq_parameters.max_dwells) or (d_positive_acq == 1)) { - pcps_acquisition::dump_results(effective_fft_size); + // Record results to file if required + if (acq_parameters.dump and d_channel == d_dump_channel) + { + pcps_acquisition::dump_results(effective_fft_size); + } + d_num_noncoherent_integrations_counter = 0; + d_positive_acq = 0; } } @@ -706,7 +731,6 @@ int pcps_acquisition::general_work(int noutput_items __attribute__((unused)), d_gnss_synchro->Acq_delay_samples = 0.0; d_gnss_synchro->Acq_doppler_hz = 0.0; d_gnss_synchro->Acq_samplestamp_samples = 0; - d_well_count = 0; d_mag = 0.0; d_input_power = 0.0; d_test_statistics = 0.0; diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h index 91bfaf112..d26c98d5e 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h @@ -106,12 +106,14 @@ private: float d_input_power; float d_test_statistics; float* d_magnitude; + float** d_magnitude_grid; + float* d_tmp_buffer; long d_old_freq; int d_state; unsigned int d_channel; unsigned int d_doppler_step; float d_doppler_center_step_two; - unsigned int d_well_count; + unsigned int d_num_noncoherent_integrations_counter; unsigned int d_fft_size; unsigned int d_num_doppler_bins; unsigned long int d_sample_counter; @@ -150,7 +152,7 @@ public: } /*! - * \brief Initializes acquisition algorithm. + * \brief Initializes acquisition algorithm and reserves memory. */ void init(); From 6b67037fed1738674e67a09b05c9c93674bb6555 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Mon, 9 Jul 2018 17:56:47 +0200 Subject: [PATCH 02/11] Add first-to-second peak statistic --- .../galileo_e1_pcps_ambiguous_acquisition.cc | 1 + .../adapters/galileo_e5a_pcps_acquisition.cc | 1 + .../glonass_l1_ca_pcps_acquisition.cc | 1 + .../glonass_l2_ca_pcps_acquisition.cc | 1 + .../adapters/gps_l1_ca_pcps_acquisition.cc | 1 + ...gps_l1_ca_pcps_acquisition_fine_doppler.cc | 1 + .../gps_l1_ca_pcps_acquisition_fpga.cc | 1 + .../adapters/gps_l2_m_pcps_acquisition.cc | 1 + .../adapters/gps_l5i_pcps_acquisition.cc | 1 + .../gnuradio_blocks/pcps_acquisition.cc | 115 +++++++++++------- .../gnuradio_blocks/pcps_acquisition.h | 3 + src/algorithms/acquisition/libs/acq_conf.cc | 1 + src/algorithms/acquisition/libs/acq_conf.h | 1 + 13 files changed, 85 insertions(+), 44 deletions(-) diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc index f377a72c8..a98207678 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc @@ -58,6 +58,7 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition( long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 4000000); fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); acq_parameters.fs_in = fs_in_; + acq_parameters.samples_per_chip = static_cast(ceil((1.0 / Galileo_E1_CODE_CHIP_RATE_HZ) * static_cast(acq_parameters.fs_in))); dump_ = configuration_->property(role + ".dump", false); acq_parameters.dump = dump_; acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0); diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.cc index 85aaee1d3..9ff35a922 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.cc @@ -57,6 +57,7 @@ GalileoE5aPcpsAcquisition::GalileoE5aPcpsAcquisition(ConfigurationInterface* con long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 32000000); fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); acq_parameters.fs_in = fs_in_; + acq_parameters.samples_per_chip = static_cast(ceil((1.0 / Galileo_E5a_CODE_CHIP_RATE_HZ) * static_cast(acq_parameters.fs_in))); acq_pilot_ = configuration_->property(role + ".acquire_pilot", false); acq_iq_ = configuration_->property(role + ".acquire_iq", false); if (acq_iq_) diff --git a/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc index b654881d7..43354e627 100644 --- a/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc @@ -59,6 +59,7 @@ GlonassL1CaPcpsAcquisition::GlonassL1CaPcpsAcquisition( long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); acq_parameters.fs_in = fs_in_; + acq_parameters.samples_per_chip = static_cast(ceil(GLONASS_L1_CA_CHIP_PERIOD * static_cast(acq_parameters.fs_in))); dump_ = configuration_->property(role + ".dump", false); acq_parameters.dump = dump_; acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0); diff --git a/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.cc index 1f5d251fb..374b69e35 100644 --- a/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.cc @@ -58,6 +58,7 @@ GlonassL2CaPcpsAcquisition::GlonassL2CaPcpsAcquisition( long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); acq_parameters.fs_in = fs_in_; + acq_parameters.samples_per_chip = static_cast(ceil(GLONASS_L2_CA_CHIP_PERIOD * static_cast(acq_parameters.fs_in))); dump_ = configuration_->property(role + ".dump", false); acq_parameters.dump = dump_; acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0); diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc index f5602b1b6..18c728412 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc @@ -60,6 +60,7 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition( long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); acq_parameters.fs_in = fs_in_; + acq_parameters.samples_per_chip = static_cast(ceil(GPS_L1_CA_CHIP_PERIOD * static_cast(acq_parameters.fs_in))); dump_ = configuration_->property(role + ".dump", false); acq_parameters.dump = dump_; acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0); diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fine_doppler.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fine_doppler.cc index 44dcfc0ee..68d67dac8 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fine_doppler.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fine_doppler.cc @@ -56,6 +56,7 @@ GpsL1CaPcpsAcquisitionFineDoppler::GpsL1CaPcpsAcquisitionFineDoppler( long fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 2048000); fs_in_ = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); acq_parameters.fs_in = fs_in_; + acq_parameters.samples_per_chip = static_cast(ceil(GPS_L1_CA_CHIP_PERIOD * static_cast(acq_parameters.fs_in))); dump_ = configuration->property(role + ".dump", false); acq_parameters.dump = dump_; dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc index 8480441f7..a8e2a3f17 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc @@ -60,6 +60,7 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga( long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); long fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); acq_parameters.fs_in = fs_in; + acq_parameters.samples_per_chip = static_cast(ceil(GPS_L1_CA_CHIP_PERIOD * static_cast(acq_parameters.fs_in))); doppler_max_ = configuration_->property(role + ".doppler_max", 5000); if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max; acq_parameters.doppler_max = doppler_max_; diff --git a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc index 2fbb72252..e68de5230 100644 --- a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc @@ -60,6 +60,7 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition( long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); acq_parameters.fs_in = fs_in_; + acq_parameters.samples_per_chip = static_cast(ceil((1.0 / GPS_L2_M_CODE_RATE_HZ) * static_cast(acq_parameters.fs_in))); dump_ = configuration_->property(role + ".dump", false); acq_parameters.dump = dump_; acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0); diff --git a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc index da30699fa..82d9d0720 100644 --- a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc @@ -59,6 +59,7 @@ GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition( long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); acq_parameters.fs_in = fs_in_; + acq_parameters.samples_per_chip = static_cast(ceil((1.0 / GPS_L5i_CODE_RATE_HZ) * static_cast(acq_parameters.fs_in))); dump_ = configuration_->property(role + ".dump", false); acq_parameters.dump = dump_; acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0); diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc index c77b48ef1..276a72db7 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc @@ -127,6 +127,7 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu d_step_two = false; d_dump_number = 0; d_dump_channel = acq_parameters.dump_channel; + samplesPerChip = acq_parameters.samples_per_chip; } @@ -426,14 +427,72 @@ void pcps_acquisition::dump_results(int effective_fft_size) } } +float pcps_acquisition::first_vs_second_peak_statistics(uint32_t& indext, int& doppler) +{ + float firstPeak = 0.0; + int index_doppler = 0; + uint32_t tmp_intex_t = 0; + uint32_t index_time = 0; + + // Look for correlation peaks in the results ============================== + // Find the highest peak and compare it to the second highest peak + // The second peak is chosen not closer than 1 chip to the highest peak + //--- Find the correlation peak and the carrier frequency -------------- + for (int i = 0; i < d_num_doppler_bins; i++) + { + volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_magnitude_grid[i], d_fft_size); + if (d_magnitude_grid[i][tmp_intex_t] > firstPeak) + { + firstPeak = d_magnitude_grid[i][tmp_intex_t]; + index_doppler = i; + index_time = tmp_intex_t; + } + } + indext = index_time; + doppler = -static_cast(acq_parameters.doppler_max) + d_doppler_step * index_doppler; + + // -- - Find 1 chip wide code phase exclude range around the peak + //uint32_t samplesPerChip = ceil(GPS_L1_CA_CHIP_PERIOD * static_cast(this->d_fs_in)); + int32_t excludeRangeIndex1 = index_time - samplesPerChip; + int32_t excludeRangeIndex2 = index_time + samplesPerChip; + + // -- - Correct code phase exclude range if the range includes array boundaries + if (excludeRangeIndex1 < 0) + { + excludeRangeIndex1 = d_fft_size + excludeRangeIndex1; + } + else if (excludeRangeIndex2 >= static_cast(d_fft_size)) + { + excludeRangeIndex2 = excludeRangeIndex2 - d_fft_size; + } + + int32_t idx = excludeRangeIndex1; + memcpy(d_tmp_buffer, d_magnitude_grid[index_doppler], d_fft_size); + do + { + d_tmp_buffer[idx] = 0.0; + idx++; + if (idx == static_cast(d_fft_size)) idx = 0; + } + while (idx != excludeRangeIndex2); + + //--- Find the second highest correlation peak in the same freq. bin --- + volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_tmp_buffer, d_fft_size); + float secondPeak = d_tmp_buffer[tmp_intex_t]; + + // 5- Compute the test statistics and compare to the threshold + return firstPeak / secondPeak; +} + void pcps_acquisition::acquisition_core(unsigned long int samp_count) { gr::thread::scoped_lock lk(d_setlock); // initialize acquisition algorithm - uint32_t indext = 0; float magt = 0.0; + int doppler = 0; + uint32_t indext = 0; const gr_complex* in = d_data_buffer; // Get the input samples pointer int effective_fft_size = (acq_parameters.bit_transition_flag ? d_fft_size / 2 : d_fft_size); if (d_cshort) @@ -466,9 +525,7 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) { for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++) { - // doppler search steps - int doppler = -static_cast(acq_parameters.doppler_max) + d_doppler_step * doppler_index; - + // Remove doppler volk_32fc_x2_multiply_32fc(d_fft_if->get_inbuf(), in, d_grid_doppler_wipeoffs[doppler_index], d_fft_size); // 3- Perform the FFT-based convolution (parallel time search) @@ -482,7 +539,7 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) // compute the inverse FFT d_ifft->execute(); - // Search maximum + // compute squared magnitude (and accumulate in case of non-coherent integration) size_t offset = (acq_parameters.bit_transition_flag ? effective_fft_size : 0); if (d_num_noncoherent_integrations_counter == 1) { @@ -493,51 +550,21 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) volk_32fc_magnitude_squared_32f(d_tmp_buffer, d_ifft->get_outbuf() + offset, effective_fft_size); volk_32f_x2_add_32f(d_magnitude_grid[doppler_index], d_magnitude_grid[doppler_index], d_tmp_buffer, effective_fft_size); } - volk_gnsssdr_32f_index_max_32u(&indext, d_magnitude_grid[doppler_index], effective_fft_size); - magt = d_magnitude_grid[doppler_index][indext]; - - if (acq_parameters.use_CFAR_algorithm_flag) - { - // Normalize the maximum value to correct the scale factor introduced by FFTW - magt = magt / (fft_normalization_factor * fft_normalization_factor); - } - // 4- record the maximum peak and the associated synchronization parameters - if (d_mag < magt) - { - d_mag = magt; - - if (!acq_parameters.use_CFAR_algorithm_flag) - { - // Search grid noise floor approximation for this doppler line - volk_32f_accumulator_s32f(&d_input_power, d_magnitude_grid[doppler_index], effective_fft_size); - d_input_power = (d_input_power - d_mag) / (effective_fft_size - 1); - } - - // In case that acq_parameters.bit_transition_flag = true, we compare the potentially - // new maximum test statistics (d_mag/d_input_power) with the value in - // d_test_statistics. When the second dwell is being processed, the value - // of d_mag/d_input_power could be lower than d_test_statistics (i.e, - // the maximum test statistics in the previous dwell is greater than - // current d_mag/d_input_power). Note that d_test_statistics is not - // restarted between consecutive dwells in multidwell operation. - - if (d_test_statistics < (d_mag / d_input_power) or !acq_parameters.bit_transition_flag) - { - d_gnss_synchro->Acq_delay_samples = static_cast(indext % acq_parameters.samples_per_code); - d_gnss_synchro->Acq_doppler_hz = static_cast(doppler); - d_gnss_synchro->Acq_samplestamp_samples = samp_count; - - // 5- Compute the test statistics and compare to the threshold - //d_test_statistics = 2 * d_fft_size * d_mag / d_input_power; - d_test_statistics = d_mag / d_input_power; - } - } // Record results to file if required if (acq_parameters.dump and d_channel == d_dump_channel) { memcpy(grid_.colptr(doppler_index), d_magnitude_grid[doppler_index], sizeof(float) * effective_fft_size); } } + // 5- Compute the test statistics and compare to the threshold + float computed_statistic = first_vs_second_peak_statistics(indext, doppler); + if (d_test_statistics < computed_statistic or !acq_parameters.bit_transition_flag) + { + d_gnss_synchro->Acq_delay_samples = static_cast(indext % acq_parameters.samples_per_code); + d_gnss_synchro->Acq_doppler_hz = static_cast(doppler); + d_gnss_synchro->Acq_samplestamp_samples = samp_count; + d_test_statistics = computed_statistic; + } } else { diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h index d26c98d5e..5d648ebf3 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h @@ -95,6 +95,8 @@ private: void dump_results(int effective_fft_size); + float first_vs_second_peak_statistics(uint32_t& indext, int& doppler); + Acq_Conf acq_parameters; bool d_active; bool d_worker_active; @@ -108,6 +110,7 @@ private: float* d_magnitude; float** d_magnitude_grid; float* d_tmp_buffer; + uint32_t samplesPerChip; long d_old_freq; int d_state; unsigned int d_channel; diff --git a/src/algorithms/acquisition/libs/acq_conf.cc b/src/algorithms/acquisition/libs/acq_conf.cc index ed79db2fa..c3439b9c0 100644 --- a/src/algorithms/acquisition/libs/acq_conf.cc +++ b/src/algorithms/acquisition/libs/acq_conf.cc @@ -36,6 +36,7 @@ Acq_Conf::Acq_Conf() /* PCPS acquisition configuration */ sampled_ms = 0; max_dwells = 0; + samples_per_chip = 0; doppler_max = 0; num_doppler_bins_step2 = 0; doppler_step2 = 0.0; diff --git a/src/algorithms/acquisition/libs/acq_conf.h b/src/algorithms/acquisition/libs/acq_conf.h index 4707aeba7..afd43b1fb 100644 --- a/src/algorithms/acquisition/libs/acq_conf.h +++ b/src/algorithms/acquisition/libs/acq_conf.h @@ -40,6 +40,7 @@ class Acq_Conf public: /* PCPS Acquisition configuration */ unsigned int sampled_ms; + unsigned int samples_per_chip; unsigned int max_dwells; unsigned int doppler_max; unsigned int num_doppler_bins_step2; From dad0ba32ad1d800c7d8280492b1d499e577043d0 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 10 Jul 2018 07:45:49 +0200 Subject: [PATCH 03/11] Add work on noncoherent acquisition --- .../gnuradio_blocks/pcps_acquisition.cc | 100 +++++++++++++----- .../gnuradio_blocks/pcps_acquisition.h | 4 +- 2 files changed, 76 insertions(+), 28 deletions(-) diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc index 276a72db7..d1e4375d1 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc @@ -97,7 +97,7 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu if (acq_parameters.bit_transition_flag) { d_fft_size *= 2; - acq_parameters.max_dwells = 1; //Activation of acq_parameters.bit_transition_flag invalidates the value of acq_parameters.max_dwells + acq_parameters.max_dwells = 1; // Activation of acq_parameters.bit_transition_flag invalidates the value of acq_parameters.max_dwells } d_fft_codes = static_cast(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment())); @@ -128,6 +128,15 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu d_dump_number = 0; d_dump_channel = acq_parameters.dump_channel; samplesPerChip = acq_parameters.samples_per_chip; + // todo: CFAR statistic not available for non-coherent integration + if (acq_parameters.max_dwells == 1) + { + d_use_CFAR_algorithm_flag = acq_parameters.use_CFAR_algorithm_flag; + } + else + { + d_use_CFAR_algorithm_flag = false; + } } @@ -427,17 +436,49 @@ void pcps_acquisition::dump_results(int effective_fft_size) } } -float pcps_acquisition::first_vs_second_peak_statistics(uint32_t& indext, int& doppler) + +float pcps_acquisition::max_to_input_power_statistic(uint32_t& indext, int& doppler, float input_power) { - float firstPeak = 0.0; + float grid_maximum = 0.0; int index_doppler = 0; uint32_t tmp_intex_t = 0; uint32_t index_time = 0; + float fft_normalization_factor = static_cast(d_fft_size) * static_cast(d_fft_size); // Look for correlation peaks in the results ============================== // Find the highest peak and compare it to the second highest peak // The second peak is chosen not closer than 1 chip to the highest peak //--- Find the correlation peak and the carrier frequency -------------- + for (int i = 0; i < d_num_doppler_bins; i++) + { + volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_magnitude_grid[i], d_fft_size); + if (d_magnitude_grid[i][tmp_intex_t] > grid_maximum) + { + grid_maximum = d_magnitude_grid[i][tmp_intex_t]; + index_doppler = i; + index_time = tmp_intex_t; + } + } + indext = index_time; + doppler = -static_cast(acq_parameters.doppler_max) + d_doppler_step * index_doppler; + + float magt = grid_maximum / (fft_normalization_factor * fft_normalization_factor); + return magt / input_power; +} + + +float pcps_acquisition::first_vs_second_peak_statistic(uint32_t& indext, int& doppler) +{ + // Look for correlation peaks in the results + // Find the highest peak and compare it to the second highest peak + // The second peak is chosen not closer than 1 chip to the highest peak + + float firstPeak = 0.0; + int index_doppler = 0; + uint32_t tmp_intex_t = 0; + uint32_t index_time = 0; + + // Find the correlation peak and the carrier frequency for (int i = 0; i < d_num_doppler_bins; i++) { volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_magnitude_grid[i], d_fft_size); @@ -451,12 +492,11 @@ float pcps_acquisition::first_vs_second_peak_statistics(uint32_t& indext, int& d indext = index_time; doppler = -static_cast(acq_parameters.doppler_max) + d_doppler_step * index_doppler; - // -- - Find 1 chip wide code phase exclude range around the peak - //uint32_t samplesPerChip = ceil(GPS_L1_CA_CHIP_PERIOD * static_cast(this->d_fs_in)); + // Find 1 chip wide code phase exclude range around the peak int32_t excludeRangeIndex1 = index_time - samplesPerChip; int32_t excludeRangeIndex2 = index_time + samplesPerChip; - // -- - Correct code phase exclude range if the range includes array boundaries + // Correct code phase exclude range if the range includes array boundaries if (excludeRangeIndex1 < 0) { excludeRangeIndex1 = d_fft_size + excludeRangeIndex1; @@ -476,11 +516,11 @@ float pcps_acquisition::first_vs_second_peak_statistics(uint32_t& indext, int& d } while (idx != excludeRangeIndex2); - //--- Find the second highest correlation peak in the same freq. bin --- + // Find the second highest correlation peak in the same freq. bin --- volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_tmp_buffer, d_fft_size); float secondPeak = d_tmp_buffer[tmp_intex_t]; - // 5- Compute the test statistics and compare to the threshold + // Compute the test statistics and compare to the threshold return firstPeak / secondPeak; } @@ -510,36 +550,37 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) << " ,sample stamp: " << samp_count << ", threshold: " << d_threshold << ", doppler_max: " << acq_parameters.doppler_max << ", doppler_step: " << d_doppler_step - << ", use_CFAR_algorithm_flag: " << (acq_parameters.use_CFAR_algorithm_flag ? "true" : "false"); + << ", use_CFAR_algorithm_flag: " << (d_use_CFAR_algorithm_flag ? "true" : "false"); lk.unlock(); - if (acq_parameters.use_CFAR_algorithm_flag) + + if (d_use_CFAR_algorithm_flag) { - // 1- (optional) Compute the input signal power estimation + // Compute the input signal power estimation volk_32fc_magnitude_squared_32f(d_magnitude, in, d_fft_size); volk_32f_accumulator_s32f(&d_input_power, d_magnitude, d_fft_size); d_input_power /= static_cast(d_fft_size); } - // 2- Doppler frequency search loop + + // Doppler frequency grid loop if (!d_step_two) { for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++) { - // Remove doppler + // Remove Doppler volk_32fc_x2_multiply_32fc(d_fft_if->get_inbuf(), in, d_grid_doppler_wipeoffs[doppler_index], d_fft_size); - // 3- Perform the FFT-based convolution (parallel time search) + // Perform the FFT-based convolution (parallel time search) // Compute the FFT of the carrier wiped--off incoming signal d_fft_if->execute(); - // Multiply carrier wiped--off, Fourier transformed incoming signal - // with the local FFT'd code reference using SIMD operations with VOLK library + // Multiply carrier wiped--off, Fourier transformed incoming signal with the local FFT'd code reference volk_32fc_x2_multiply_32fc(d_ifft->get_inbuf(), d_fft_if->get_outbuf(), d_fft_codes, d_fft_size); - // compute the inverse FFT + // Compute the inverse FFT d_ifft->execute(); - // compute squared magnitude (and accumulate in case of non-coherent integration) + // Compute squared magnitude (and accumulate in case of non-coherent integration) size_t offset = (acq_parameters.bit_transition_flag ? effective_fft_size : 0); if (d_num_noncoherent_integrations_counter == 1) { @@ -556,15 +597,19 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) memcpy(grid_.colptr(doppler_index), d_magnitude_grid[doppler_index], sizeof(float) * effective_fft_size); } } - // 5- Compute the test statistics and compare to the threshold - float computed_statistic = first_vs_second_peak_statistics(indext, doppler); - if (d_test_statistics < computed_statistic or !acq_parameters.bit_transition_flag) + + // Compute the test statistic + if (d_use_CFAR_algorithm_flag) { - d_gnss_synchro->Acq_delay_samples = static_cast(indext % acq_parameters.samples_per_code); - d_gnss_synchro->Acq_doppler_hz = static_cast(doppler); - d_gnss_synchro->Acq_samplestamp_samples = samp_count; - d_test_statistics = computed_statistic; + d_test_statistics = max_to_input_power_statistic(indext, doppler, d_input_power); } + else + { + d_test_statistics = first_vs_second_peak_statistic(indext, doppler); + } + d_gnss_synchro->Acq_delay_samples = static_cast(indext % acq_parameters.samples_per_code); + d_gnss_synchro->Acq_doppler_hz = static_cast(doppler); + d_gnss_synchro->Acq_samplestamp_samples = samp_count; } else { @@ -592,7 +637,7 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) volk_gnsssdr_32f_index_max_32u(&indext, d_magnitude, effective_fft_size); magt = d_magnitude[indext]; - if (acq_parameters.use_CFAR_algorithm_flag) + if (d_use_CFAR_algorithm_flag) { // Normalize the maximum value to correct the scale factor introduced by FFTW magt = d_magnitude[indext] / (fft_normalization_factor * fft_normalization_factor); @@ -602,7 +647,7 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) { d_mag = magt; - if (!acq_parameters.use_CFAR_algorithm_flag) + if (!d_use_CFAR_algorithm_flag) { // Search grid noise floor approximation for this doppler line volk_32f_accumulator_s32f(&d_input_power, d_magnitude, effective_fft_size); @@ -635,6 +680,7 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) } } } + lk.lock(); if (!acq_parameters.bit_transition_flag) { diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h index 5d648ebf3..4ca381ce0 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h @@ -95,13 +95,15 @@ private: void dump_results(int effective_fft_size); - float first_vs_second_peak_statistics(uint32_t& indext, int& doppler); + float first_vs_second_peak_statistic(uint32_t& indext, int& doppler); + float max_to_input_power_statistic(uint32_t& indext, int& doppler, float input_power); Acq_Conf acq_parameters; bool d_active; bool d_worker_active; bool d_cshort; bool d_step_two; + bool d_use_CFAR_algorithm_flag; int d_positive_acq; float d_threshold; float d_mag; From e1c26ec858395d60a88efe2dca0cbd1ada467e21 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 10 Jul 2018 07:48:08 +0200 Subject: [PATCH 04/11] Add work on noncoherent acquisition --- .../acquisition/gnuradio_blocks/pcps_acquisition.cc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc index d1e4375d1..b77fd5e44 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc @@ -445,10 +445,7 @@ float pcps_acquisition::max_to_input_power_statistic(uint32_t& indext, int& dopp uint32_t index_time = 0; float fft_normalization_factor = static_cast(d_fft_size) * static_cast(d_fft_size); - // Look for correlation peaks in the results ============================== - // Find the highest peak and compare it to the second highest peak - // The second peak is chosen not closer than 1 chip to the highest peak - //--- Find the correlation peak and the carrier frequency -------------- + // Find the correlation peak and the carrier frequency for (int i = 0; i < d_num_doppler_bins; i++) { volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_magnitude_grid[i], d_fft_size); From 394f6088aa2312e4def761707d50bdacba845120 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 10 Jul 2018 08:47:04 +0200 Subject: [PATCH 05/11] Add work on noncoherent acquisition --- .../acquisition/gnuradio_blocks/pcps_acquisition.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc index b77fd5e44..d8c19ef17 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc @@ -554,8 +554,8 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) if (d_use_CFAR_algorithm_flag) { // Compute the input signal power estimation - volk_32fc_magnitude_squared_32f(d_magnitude, in, d_fft_size); - volk_32f_accumulator_s32f(&d_input_power, d_magnitude, d_fft_size); + volk_32fc_magnitude_squared_32f(d_tmp_buffer, in, d_fft_size); + volk_32f_accumulator_s32f(&d_input_power, d_tmp_buffer, d_fft_size); d_input_power /= static_cast(d_fft_size); } From 85f70fe1a395bf3990984d0470f4d350531817c3 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 10 Jul 2018 16:25:16 +0200 Subject: [PATCH 06/11] Fix coherent acquisition --- .../gnuradio_blocks/pcps_acquisition.cc | 56 ++++++++++++++----- .../gnuradio_blocks/pcps_acquisition.h | 2 + .../gps_l1_acq_performance_test.cc | 2 +- 3 files changed, 44 insertions(+), 16 deletions(-) diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc index d8c19ef17..cc71eb59d 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc @@ -64,7 +64,16 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu d_state = 0; d_old_freq = 0; d_num_noncoherent_integrations_counter = 0; - d_fft_size = acq_parameters.sampled_ms * acq_parameters.samples_per_ms; + d_consumed_samples = acq_parameters.sampled_ms * acq_parameters.samples_per_ms * (acq_parameters.bit_transition_flag ? 2 : 1); + if (acq_parameters.sampled_ms == 1) + { + d_fft_size = d_consumed_samples; + } + else + { + d_fft_size = d_consumed_samples * 2; + } + //d_fft_size = next power of two? //// d_mag = 0; d_input_power = 0.0; d_num_doppler_bins = 0; @@ -82,8 +91,6 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu d_cshort = true; } - d_tmp_buffer = static_cast(volk_gnsssdr_malloc(d_fft_size * sizeof(float), volk_gnsssdr_get_alignment())); - // COD: // Experimenting with the overlap/save technique for handling bit trannsitions // The problem: Circular correlation is asynchronous with the received code. @@ -96,12 +103,14 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu // size of the input buffer and padding the code with zeros. if (acq_parameters.bit_transition_flag) { - d_fft_size *= 2; + d_fft_size = d_consumed_samples * 2; acq_parameters.max_dwells = 1; // Activation of acq_parameters.bit_transition_flag invalidates the value of acq_parameters.max_dwells } + d_tmp_buffer = static_cast(volk_gnsssdr_malloc(d_fft_size * sizeof(float), volk_gnsssdr_get_alignment())); d_fft_codes = static_cast(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment())); d_magnitude = static_cast(volk_gnsssdr_malloc(d_fft_size * sizeof(float), volk_gnsssdr_get_alignment())); + d_input_signal = static_cast(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment())); // Direct FFT d_fft_if = new gr::fft::fft_complex(d_fft_size, true); @@ -114,10 +123,10 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu d_grid_doppler_wipeoffs_step_two = nullptr; d_magnitude_grid = nullptr; d_worker_active = false; - d_data_buffer = static_cast(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment())); + d_data_buffer = static_cast(volk_gnsssdr_malloc(d_consumed_samples * sizeof(gr_complex), volk_gnsssdr_get_alignment())); if (d_cshort) { - d_data_buffer_sc = static_cast(volk_gnsssdr_malloc(d_fft_size * sizeof(lv_16sc_t), volk_gnsssdr_get_alignment())); + d_data_buffer_sc = static_cast(volk_gnsssdr_malloc(d_consumed_samples * sizeof(lv_16sc_t), volk_gnsssdr_get_alignment())); } else { @@ -163,6 +172,7 @@ pcps_acquisition::~pcps_acquisition() volk_gnsssdr_free(d_fft_codes); volk_gnsssdr_free(d_magnitude); volk_gnsssdr_free(d_tmp_buffer); + volk_gnsssdr_free(d_input_signal); delete d_ifft; delete d_fft_if; volk_gnsssdr_free(d_data_buffer); @@ -195,7 +205,15 @@ void pcps_acquisition::set_local_code(std::complex* code) } else { - memcpy(d_fft_if->get_inbuf(), code, sizeof(gr_complex) * d_fft_size); + if (acq_parameters.sampled_ms == 1) + { + memcpy(d_fft_if->get_inbuf(), code, sizeof(gr_complex) * d_consumed_samples); + } + else + { + std::fill_n(d_fft_if->get_inbuf(), d_fft_size - d_consumed_samples, gr_complex(0.0, 0.0)); + memcpy(d_fft_if->get_inbuf() + d_consumed_samples, code, sizeof(gr_complex) * d_consumed_samples); + } } d_fft_if->execute(); // We need the FFT of local code @@ -530,12 +548,20 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) float magt = 0.0; int doppler = 0; uint32_t indext = 0; - const gr_complex* in = d_data_buffer; // Get the input samples pointer int effective_fft_size = (acq_parameters.bit_transition_flag ? d_fft_size / 2 : d_fft_size); if (d_cshort) { - volk_gnsssdr_16ic_convert_32fc(d_data_buffer, d_data_buffer_sc, d_fft_size); + volk_gnsssdr_16ic_convert_32fc(d_data_buffer, d_data_buffer_sc, d_consumed_samples); } + memcpy(d_input_signal, d_data_buffer, d_consumed_samples * sizeof(gr_complex)); + if (d_fft_size > d_consumed_samples) + { + for (unsigned int i = d_consumed_samples; i < d_fft_size; i++) + { + d_input_signal[i] = gr_complex(0.0, 0.0); + } + } + const gr_complex* in = d_input_signal; // Get the input samples pointer float fft_normalization_factor = static_cast(d_fft_size) * static_cast(d_fft_size); d_input_power = 0.0; @@ -551,7 +577,7 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) lk.unlock(); - if (d_use_CFAR_algorithm_flag) + if (d_use_CFAR_algorithm_flag or acq_parameters.bit_transition_flag) { // Compute the input signal power estimation volk_32fc_magnitude_squared_32f(d_tmp_buffer, in, d_fft_size); @@ -780,7 +806,7 @@ int pcps_acquisition::general_work(int noutput_items __attribute__((unused)), { if (!acq_parameters.blocking_on_standby) { - d_sample_counter += d_fft_size * ninput_items[0]; + d_sample_counter += d_consumed_samples * ninput_items[0]; consume_each(ninput_items[0]); } if (d_step_two) @@ -807,7 +833,7 @@ int pcps_acquisition::general_work(int noutput_items __attribute__((unused)), d_state = 1; if (!acq_parameters.blocking_on_standby) { - d_sample_counter += d_fft_size * ninput_items[0]; // sample counter + d_sample_counter += d_consumed_samples * ninput_items[0]; // sample counter consume_each(ninput_items[0]); } break; @@ -818,11 +844,11 @@ int pcps_acquisition::general_work(int noutput_items __attribute__((unused)), // Copy the data to the core and let it know that new data is available if (d_cshort) { - memcpy(d_data_buffer_sc, input_items[0], d_fft_size * sizeof(lv_16sc_t)); + memcpy(d_data_buffer_sc, input_items[0], d_consumed_samples * sizeof(lv_16sc_t)); } else { - memcpy(d_data_buffer, input_items[0], d_fft_size * sizeof(gr_complex)); + memcpy(d_data_buffer, input_items[0], d_consumed_samples * sizeof(gr_complex)); } if (acq_parameters.blocking) { @@ -834,7 +860,7 @@ int pcps_acquisition::general_work(int noutput_items __attribute__((unused)), gr::thread::thread d_worker(&pcps_acquisition::acquisition_core, this, d_sample_counter); d_worker_active = true; } - d_sample_counter += d_fft_size; + d_sample_counter += d_consumed_samples; consume_each(1); break; } diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h index 4ca381ce0..67689a86c 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h @@ -112,6 +112,7 @@ private: float* d_magnitude; float** d_magnitude_grid; float* d_tmp_buffer; + gr_complex* d_input_signal; uint32_t samplesPerChip; long d_old_freq; int d_state; @@ -120,6 +121,7 @@ private: float d_doppler_center_step_two; unsigned int d_num_noncoherent_integrations_counter; unsigned int d_fft_size; + unsigned int d_consumed_samples; unsigned int d_num_doppler_bins; unsigned long int d_sample_counter; gr_complex** d_grid_doppler_wipeoffs; diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc index 164dd96b4..fa9b9e7f9 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc @@ -707,7 +707,7 @@ TEST_F(AcquisitionPerformanceTest, ROC) std::cout << "Num executions: " << num_executions << std::endl; for (int execution = 1; execution <= num_executions; execution++) { - acquisition_dump_reader acq_dump(basename, observed_satellite, config->property("Acquisition_1C.doppler_max", 0), config->property("Acquisition_1C.doppler_step", 0), config->property("GNSS-SDR.internal_fs_sps", 0) * GPS_L1_CA_CODE_PERIOD * static_cast(coh_time_ms), ch, execution); + acquisition_dump_reader acq_dump(basename, observed_satellite, config->property("Acquisition_1C.doppler_max", 0), config->property("Acquisition_1C.doppler_step", 0), config->property("GNSS-SDR.internal_fs_sps", 0) * GPS_L1_CA_CODE_PERIOD * static_cast(coh_time_ms) * (config->property("Acquisition_1C.bit_transition_flag", false) ? 2 : 1), ch, execution); acq_dump.read_binary_acq(); if (acq_dump.positive_acq) { From f965cf750d7eddef0ffbe2502948e6c5274bb9c9 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 10 Jul 2018 17:20:37 +0200 Subject: [PATCH 07/11] Accept coherent and noncoherent integration --- .../acquisition/gps_l1_acq_performance_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc index 164dd96b4..af2ed3b65 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc @@ -181,7 +181,7 @@ protected: num_thresholds = pfa_vector.size(); - int aux2 = ((generated_signal_duration_s * 1000 - FLAGS_acq_test_coherent_time_ms) / FLAGS_acq_test_coherent_time_ms); + int aux2 = ((generated_signal_duration_s * 1000 - (FLAGS_acq_test_coherent_time_ms * FLAGS_acq_test_max_dwells)) / (FLAGS_acq_test_coherent_time_ms * FLAGS_acq_test_max_dwells)); if ((FLAGS_acq_test_num_meas > 0) and (FLAGS_acq_test_num_meas < aux2)) { num_of_measurements = static_cast(FLAGS_acq_test_num_meas); From d9b9df3718cd7cafa379ea8fbfbc5c2cf7cf6ed0 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 10 Jul 2018 17:43:05 +0200 Subject: [PATCH 08/11] Fix warning, improve code consistency --- .../gnuradio_blocks/pcps_acquisition.cc | 18 +++++++++--------- .../gnuradio_blocks/pcps_acquisition.h | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc index cc71eb59d..646975ae4 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc @@ -136,7 +136,7 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu d_step_two = false; d_dump_number = 0; d_dump_channel = acq_parameters.dump_channel; - samplesPerChip = acq_parameters.samples_per_chip; + d_samplesPerChip = acq_parameters.samples_per_chip; // todo: CFAR statistic not available for non-coherent integration if (acq_parameters.max_dwells == 1) { @@ -458,13 +458,13 @@ void pcps_acquisition::dump_results(int effective_fft_size) float pcps_acquisition::max_to_input_power_statistic(uint32_t& indext, int& doppler, float input_power) { float grid_maximum = 0.0; - int index_doppler = 0; + unsigned int index_doppler = 0; uint32_t tmp_intex_t = 0; uint32_t index_time = 0; float fft_normalization_factor = static_cast(d_fft_size) * static_cast(d_fft_size); // Find the correlation peak and the carrier frequency - for (int i = 0; i < d_num_doppler_bins; i++) + for (unsigned int i = 0; i < d_num_doppler_bins; i++) { volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_magnitude_grid[i], d_fft_size); if (d_magnitude_grid[i][tmp_intex_t] > grid_maximum) @@ -475,7 +475,7 @@ float pcps_acquisition::max_to_input_power_statistic(uint32_t& indext, int& dopp } } indext = index_time; - doppler = -static_cast(acq_parameters.doppler_max) + d_doppler_step * index_doppler; + doppler = -static_cast(acq_parameters.doppler_max) + d_doppler_step * static_cast(index_doppler); float magt = grid_maximum / (fft_normalization_factor * fft_normalization_factor); return magt / input_power; @@ -489,12 +489,12 @@ float pcps_acquisition::first_vs_second_peak_statistic(uint32_t& indext, int& do // The second peak is chosen not closer than 1 chip to the highest peak float firstPeak = 0.0; - int index_doppler = 0; + unsigned int index_doppler = 0; uint32_t tmp_intex_t = 0; uint32_t index_time = 0; // Find the correlation peak and the carrier frequency - for (int i = 0; i < d_num_doppler_bins; i++) + for (unsigned int i = 0; i < d_num_doppler_bins; i++) { volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_magnitude_grid[i], d_fft_size); if (d_magnitude_grid[i][tmp_intex_t] > firstPeak) @@ -505,11 +505,11 @@ float pcps_acquisition::first_vs_second_peak_statistic(uint32_t& indext, int& do } } indext = index_time; - doppler = -static_cast(acq_parameters.doppler_max) + d_doppler_step * index_doppler; + doppler = -static_cast(acq_parameters.doppler_max) + d_doppler_step * static_cast(index_doppler); // Find 1 chip wide code phase exclude range around the peak - int32_t excludeRangeIndex1 = index_time - samplesPerChip; - int32_t excludeRangeIndex2 = index_time + samplesPerChip; + int32_t excludeRangeIndex1 = index_time - d_samplesPerChip; + int32_t excludeRangeIndex2 = index_time + d_samplesPerChip; // Correct code phase exclude range if the range includes array boundaries if (excludeRangeIndex1 < 0) diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h index 67689a86c..e39648525 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h @@ -113,7 +113,7 @@ private: float** d_magnitude_grid; float* d_tmp_buffer; gr_complex* d_input_signal; - uint32_t samplesPerChip; + uint32_t d_samplesPerChip; long d_old_freq; int d_state; unsigned int d_channel; From 0bc894a91f356f75927e3bbce08b51fd4fe4d01f Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 10 Jul 2018 18:41:24 +0200 Subject: [PATCH 09/11] Header fix --- src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc | 2 +- src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.h | 2 +- .../{gps_l1_acq_performance_test.cc => acq_performance_test.cc} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename src/tests/unit-tests/signal-processing-blocks/acquisition/{gps_l1_acq_performance_test.cc => acq_performance_test.cc} (100%) diff --git a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc index 82d9d0720..66537426c 100644 --- a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc @@ -1,5 +1,5 @@ /*! - * \file gps_l5i pcps_acquisition.cc + * \file gps_l5i_pcps_acquisition.cc * \brief Adapts a PCPS acquisition block to an Acquisition Interface for * GPS L5i signals * \authors
    diff --git a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.h b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.h index 01d15def8..3db500def 100644 --- a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.h +++ b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.h @@ -1,5 +1,5 @@ /*! - * \file GPS_L5i_PCPS_Acquisition.h + * \file gps_l5i_pcps_acquisition.h * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for * GPS L5i signals * \authors
      diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/acq_performance_test.cc similarity index 100% rename from src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc rename to src/tests/unit-tests/signal-processing-blocks/acquisition/acq_performance_test.cc From 0ad24adeabbed0a12bf9143d7cbafe7fa556c791 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 10 Jul 2018 18:43:36 +0200 Subject: [PATCH 10/11] Make acquisition performance test multisystem --- src/tests/test_main.cc | 2 +- .../acquisition/acq_performance_test.cc | 182 +++++++++++++----- 2 files changed, 130 insertions(+), 54 deletions(-) diff --git a/src/tests/test_main.cc b/src/tests/test_main.cc index eb010b807..caaff6be4 100644 --- a/src/tests/test_main.cc +++ b/src/tests/test_main.cc @@ -145,7 +145,7 @@ DECLARE_string(log_dir); #if EXTRA_TESTS #include "unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc" #include "unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc" -#include "unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc" +#include "unit-tests/signal-processing-blocks/acquisition/acq_performance_test.cc" #include "unit-tests/signal-processing-blocks/tracking/gps_l2_m_dll_pll_tracking_test.cc" #include "unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc" #include "unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_pull-in_test.cc" diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/acq_performance_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/acq_performance_test.cc index ea78cd410..111dc775d 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/acq_performance_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/acq_performance_test.cc @@ -1,5 +1,5 @@ /*! - * \file gps_l1_acq_performance_test.cc + * \file acq_performance_test.cc * \brief This class implements an acquisition performance test * \author Carles Fernandez-Prades, 2018. cfernandez(at)cttc.cat * @@ -29,22 +29,27 @@ * ------------------------------------------------------------------------- */ -#include "test_flags.h" -#include "signal_generator_flags.h" -#include "tracking_true_obs_reader.h" -#include "true_observables_reader.h" #include "gps_l1_ca_pcps_acquisition.h" #include "gps_l1_ca_pcps_acquisition_fine_doppler.h" +#include "galileo_e1_pcps_ambiguous_acquisition.h" +#include "galileo_e5a_pcps_acquisition.h" +#include "glonass_l1_ca_pcps_acquisition.h" +#include "glonass_l2_ca_pcps_acquisition.h" +#include "gps_l2_m_pcps_acquisition.h" +#include "gps_l5i_pcps_acquisition.h" #include "display.h" #include "gnuplot_i.h" +#include "signal_generator_flags.h" +#include "test_flags.h" +#include "tracking_true_obs_reader.h" +#include "true_observables_reader.h" #include #include -#include -#include + DEFINE_string(config_file_ptest, std::string(""), "File containing alternative configuration parameters for the acquisition performance test."); DEFINE_string(acq_test_input_file, std::string(""), "File containing raw signal data, must be in int8_t format. The signal generator will not be used."); -DEFINE_string(acq_test_implementation, std::string("GPS_L1_CA_PCPS_Acquisition"), "Acquisition block implementation under test. Alternative: GPS_L1_CA_PCPS_Acquisition_Fine_Doppler"); +DEFINE_string(acq_test_implementation, std::string("GPS_L1_CA_PCPS_Acquisition"), "Acquisition block implementation under test. Alternatives: GPS_L1_CA_PCPS_Acquisition, GPS_L1_CA_PCPS_Acquisition_Fine_Doppler, Galileo_E1_PCPS_Ambiguous_Acquisition, GLONASS_L1_CA_PCPS_Acquisition, GLONASS_L2_CA_PCPS_Acquisition, GPS_L2_M_PCPS_Acquisition, Galileo_E5a_Pcps_Acquisition, GPS_L5i_PCPS_Acquisition"); DEFINE_int32(acq_test_doppler_max, 5000, "Maximum Doppler, in Hz"); DEFINE_int32(acq_test_doppler_step, 125, "Doppler step, in Hz."); @@ -154,6 +159,53 @@ protected: { cn0_vector = {0.0}; } + + if (implementation.compare("GPS_L1_CA_PCPS_Acquisition") == 0) + { + signal_id = "1C"; + system_id = 'G'; + } + else if (implementation.compare("GPS_L1_CA_PCPS_Acquisition_Fine_Doppler") == 0) + { + signal_id = "1C"; + system_id = 'G'; + } + else if (implementation.compare("Galileo_E1_PCPS_Ambiguous_Acquisition") == 0) + { + signal_id = "1B"; + system_id = 'E'; + } + else if (implementation.compare("GLONASS_L1_CA_PCPS_Acquisition") == 0) + { + signal_id = "1G"; + system_id = 'R'; + } + else if (implementation.compare("GLONASS_L2_CA_PCPS_Acquisition") == 0) + { + signal_id = "2G"; + system_id = 'R'; + } + else if (implementation.compare("GPS_L2_M_PCPS_Acquisition") == 0) + { + signal_id = "2S"; + system_id = 'G'; + } + else if (implementation.compare("Galileo_E5a_Pcps_Acquisition") == 0) + { + signal_id = "5X"; + system_id = 'E'; + } + else if (implementation.compare("GPS_L5i_PCPS_Acquisition") == 0) + { + signal_id = "L5"; + system_id = 'G'; + } + else + { + signal_id = "1C"; + system_id = 'G'; + } + init(); if (FLAGS_acq_test_pfa_init > 0.0) @@ -257,6 +309,8 @@ protected: std::vector> Pfa; std::vector> Pd_correct; + std::string signal_id; + private: std::string generator_binary; std::string p1; @@ -268,6 +322,7 @@ private: std::string filename_rinex_obs = FLAGS_filename_rinex_obs; std::string filename_raw_data = FLAGS_filename_raw_data; + char system_id; double compute_stdev_precision(const std::vector& vec); double compute_stdev_accuracy(const std::vector& vec, double ref); @@ -277,8 +332,8 @@ private: void AcquisitionPerformanceTest::init() { gnss_synchro.Channel_ID = 0; - gnss_synchro.System = 'G'; - std::string signal = "1C"; + gnss_synchro.System = system_id; + std::string signal = signal_id; signal.copy(gnss_synchro.Signal, 2, 0); gnss_synchro.PRN = observed_satellite; message = 0; @@ -378,51 +433,51 @@ int AcquisitionPerformanceTest::configure_receiver(double cn0, float pfa, unsign config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(sampling_rate_internal)); // Set Acquisition - config->set_property("Acquisition_1C.implementation", implementation); - config->set_property("Acquisition_1C.item_type", "gr_complex"); - config->set_property("Acquisition_1C.doppler_max", std::to_string(doppler_max)); - config->set_property("Acquisition_1C.doppler_min", std::to_string(-doppler_max)); - config->set_property("Acquisition_1C.doppler_step", std::to_string(doppler_step)); + config->set_property("Acquisition.implementation", implementation); + config->set_property("Acquisition.item_type", "gr_complex"); + config->set_property("Acquisition.doppler_max", std::to_string(doppler_max)); + config->set_property("Acquisition.doppler_min", std::to_string(-doppler_max)); + config->set_property("Acquisition.doppler_step", std::to_string(doppler_step)); - config->set_property("Acquisition_1C.threshold", std::to_string(pfa)); - //if (FLAGS_acq_test_pfa_init > 0.0) config->supersede_property("Acquisition_1C.pfa", std::to_string(pfa)); + config->set_property("Acquisition.threshold", std::to_string(pfa)); + //if (FLAGS_acq_test_pfa_init > 0.0) config->supersede_property("Acquisition.pfa", std::to_string(pfa)); if (FLAGS_acq_test_pfa_init > 0.0) { - config->supersede_property("Acquisition_1C.pfa", std::to_string(pfa)); + config->supersede_property("Acquisition.pfa", std::to_string(pfa)); } if (FLAGS_acq_test_use_CFAR_algorithm) { - config->set_property("Acquisition_1C.use_CFAR_algorithm", "true"); + config->set_property("Acquisition.use_CFAR_algorithm", "true"); } else { - config->set_property("Acquisition_1C.use_CFAR_algorithm", "false"); + config->set_property("Acquisition.use_CFAR_algorithm", "false"); } - config->set_property("Acquisition_1C.coherent_integration_time_ms", std::to_string(coherent_integration_time_ms)); + config->set_property("Acquisition.coherent_integration_time_ms", std::to_string(coherent_integration_time_ms)); if (FLAGS_acq_test_bit_transition_flag) { - config->set_property("Acquisition_1C.bit_transition_flag", "true"); + config->set_property("Acquisition.bit_transition_flag", "true"); } else { - config->set_property("Acquisition_1C.bit_transition_flag", "false"); + config->set_property("Acquisition.bit_transition_flag", "false"); } - config->set_property("Acquisition_1C.max_dwells", std::to_string(FLAGS_acq_test_max_dwells)); + config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_acq_test_max_dwells)); - config->set_property("Acquisition_1C.repeat_satellite", "true"); + config->set_property("Acquisition.repeat_satellite", "true"); - config->set_property("Acquisition_1C.blocking", "true"); - config->set_property("Acquisition_1C.make_two_steps", "false"); - config->set_property("Acquisition_1C.second_nbins", std::to_string(4)); - config->set_property("Acquisition_1C.second_doppler_step", std::to_string(125)); + config->set_property("Acquisition.blocking", "true"); + config->set_property("Acquisition.make_two_steps", "false"); + config->set_property("Acquisition.second_nbins", std::to_string(4)); + config->set_property("Acquisition.second_doppler_step", std::to_string(125)); - config->set_property("Acquisition_1C.dump", "true"); + config->set_property("Acquisition.dump", "true"); std::string dump_file = path_str + std::string("/acquisition_") + std::to_string(cn0) + "_" + std::to_string(iter) + "_" + std::to_string(pfa); - config->set_property("Acquisition_1C.dump_filename", dump_file); - config->set_property("Acquisition_1C.dump_channel", std::to_string(dump_channel)); - config->set_property("Acquisition_1C.blocking_on_standby", "true"); + config->set_property("Acquisition.dump_filename", dump_file); + config->set_property("Acquisition.dump_channel", std::to_string(dump_channel)); + config->set_property("Acquisition.blocking_on_standby", "true"); config_f = 0; } @@ -462,26 +517,47 @@ int AcquisitionPerformanceTest::run_receiver() boost::shared_ptr valve = gnss_sdr_make_valve(sizeof(gr_complex), nsamples, queue); if (implementation.compare("GPS_L1_CA_PCPS_Acquisition") == 0) { - acquisition = std::make_shared(config.get(), "Acquisition_1C", 1, 0); + acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); + } + else if (implementation.compare("GPS_L1_CA_PCPS_Acquisition_Fine_Doppler") == 0) + { + acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); + } + else if (implementation.compare("Galileo_E1_PCPS_Ambiguous_Acquisition") == 0) + { + acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); + } + else if (implementation.compare("GLONASS_L1_CA_PCPS_Acquisition") == 0) + { + acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); + } + else if (implementation.compare("GLONASS_L2_CA_PCPS_Acquisition") == 0) + { + acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); + } + else if (implementation.compare("GPS_L2_M_PCPS_Acquisition") == 0) + { + acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); + } + else if (implementation.compare("Galileo_E5a_Pcps_Acquisition") == 0) + { + acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); + } + else if (implementation.compare("GPS_L5i_PCPS_Acquisition") == 0) + { + acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); } else { - if (implementation.compare("GPS_L1_CA_PCPS_Acquisition_Fine_Doppler") == 0) - { - acquisition = std::make_shared(config.get(), "Acquisition_1C", 1, 0); - } - else - { - bool aux = false; - EXPECT_EQ(true, aux); - } + bool aux = false; + EXPECT_EQ(true, aux); } acquisition->set_gnss_synchro(&gnss_synchro); acquisition->set_channel(0); - acquisition->set_doppler_max(config->property("Acquisition_1C.doppler_max", 10000)); - acquisition->set_doppler_step(config->property("Acquisition_1C.doppler_step", 500)); - acquisition->set_threshold(config->property("Acquisition_1C.threshold", 0.0)); + acquisition->set_doppler_max(config->property("Acquisition.doppler_max", 10000)); + acquisition->set_doppler_step(config->property("Acquisition.doppler_step", 500)); + acquisition->set_threshold(config->property("Acquisition.threshold", 0.0)); acquisition->init(); acquisition->set_local_code(); @@ -563,7 +639,7 @@ void AcquisitionPerformanceTest::plot_results() } g1.cmd("set font \"Times,18\""); g1.set_title("Receiver Operating Characteristic for GPS L1 C/A acquisition"); - g1.cmd("set label 1 \"" + std::string("Coherent integration time: ") + std::to_string(config->property("Acquisition_1C.coherent_integration_time_ms", 1)) + " ms, Non-coherent integrations: " + std::to_string(config->property("Acquisition_1C.max_dwells", 1)) + " \" at screen 0.12, 0.83 font \"Times,16\""); + g1.cmd("set label 1 \"" + std::string("Coherent integration time: ") + std::to_string(config->property("Acquisition.coherent_integration_time_ms", 1)) + " ms, Non-coherent integrations: " + std::to_string(config->property("Acquisition.max_dwells", 1)) + " \" at screen 0.12, 0.83 font \"Times,16\""); g1.cmd("set logscale x"); g1.cmd("set yrange [0:1]"); g1.cmd("set xrange[0.0001:1]"); @@ -599,7 +675,7 @@ void AcquisitionPerformanceTest::plot_results() } g2.cmd("set font \"Times,18\""); g2.set_title("Receiver Operating Characteristic for GPS L1 C/A valid acquisition"); - g2.cmd("set label 1 \"" + std::string("Coherent integration time: ") + std::to_string(config->property("Acquisition_1C.coherent_integration_time_ms", 1)) + " ms, Non-coherent integrations: " + std::to_string(config->property("Acquisition_1C.max_dwells", 1)) + " \" at screen 0.12, 0.83 font \"Times,16\""); + g2.cmd("set label 1 \"" + std::string("Coherent integration time: ") + std::to_string(config->property("Acquisition.coherent_integration_time_ms", 1)) + " ms, Non-coherent integrations: " + std::to_string(config->property("Acquisition.max_dwells", 1)) + " \" at screen 0.12, 0.83 font \"Times,16\""); g2.cmd("set logscale x"); g2.cmd("set yrange [0:1]"); g2.cmd("set xrange[0.0001:1]"); @@ -692,22 +768,22 @@ TEST_F(AcquisitionPerformanceTest, ROC) run_receiver(); // count executions - std::string basename = path_str + std::string("/acquisition_") + std::to_string(*it) + "_" + std::to_string(iter) + "_" + std::to_string(pfa_vector[pfa_iter]) + "_" + gnss_synchro.System + "_1C"; + std::string basename = path_str + std::string("/acquisition_") + std::to_string(*it) + "_" + std::to_string(iter) + "_" + std::to_string(pfa_vector[pfa_iter]) + "_" + gnss_synchro.System + "_" + signal_id; int num_executions = count_executions(basename, observed_satellite); // Read measured data - int ch = config->property("Acquisition_1C.dump_channel", 0); + int ch = config->property("Acquisition.dump_channel", 0); arma::vec meas_timestamp_s = arma::zeros(num_executions, 1); arma::vec meas_doppler = arma::zeros(num_executions, 1); arma::vec positive_acq = arma::zeros(num_executions, 1); arma::vec meas_acq_delay_chips = arma::zeros(num_executions, 1); - double coh_time_ms = config->property("Acquisition_1C.coherent_integration_time_ms", 1); + double coh_time_ms = config->property("Acquisition.coherent_integration_time_ms", 1); std::cout << "Num executions: " << num_executions << std::endl; for (int execution = 1; execution <= num_executions; execution++) { - acquisition_dump_reader acq_dump(basename, observed_satellite, config->property("Acquisition_1C.doppler_max", 0), config->property("Acquisition_1C.doppler_step", 0), config->property("GNSS-SDR.internal_fs_sps", 0) * GPS_L1_CA_CODE_PERIOD * static_cast(coh_time_ms) * (config->property("Acquisition_1C.bit_transition_flag", false) ? 2 : 1), ch, execution); + acquisition_dump_reader acq_dump(basename, observed_satellite, config->property("Acquisition.doppler_max", 0), config->property("Acquisition.doppler_step", 0), config->property("GNSS-SDR.internal_fs_sps", 0) * GPS_L1_CA_CODE_PERIOD * static_cast(coh_time_ms) * (config->property("Acquisition.bit_transition_flag", false) ? 2 : 1), ch, execution); acq_dump.read_binary_acq(); if (acq_dump.positive_acq) { @@ -827,7 +903,7 @@ TEST_F(AcquisitionPerformanceTest, ROC) for (int i = 0; i < num_clean_executions - 1; i++) { - if (abs(clean_delay_estimation_error(i)) < 0.5 and abs(clean_doppler_estimation_error(i)) < static_cast(config->property("Acquisition_1C.doppler_step", 1)) / 2.0) + if (abs(clean_delay_estimation_error(i)) < 0.5 and abs(clean_doppler_estimation_error(i)) < static_cast(config->property("Acquisition.doppler_step", 1)) / 2.0) { correctly_detected = correctly_detected + 1.0; } From 9881857fa599673471646420ea41a9b9a3b288ac Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 11 Jul 2018 14:51:34 +0200 Subject: [PATCH 11/11] Fix Acquisition for L2C and E1B --- .../galileo_e1_pcps_ambiguous_acquisition.cc | 13 +++++----- .../adapters/gps_l2_m_pcps_acquisition.cc | 4 +-- .../gnuradio_blocks/pcps_acquisition.cc | 4 +-- .../acquisition/acq_performance_test.cc | 25 ++++++++++++++++++- .../ieee-access18/L2-access18.conf | 2 +- 5 files changed, 35 insertions(+), 13 deletions(-) diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc index a98207678..7f1df1c2f 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc @@ -59,24 +59,23 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition( fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); acq_parameters.fs_in = fs_in_; acq_parameters.samples_per_chip = static_cast(ceil((1.0 / Galileo_E1_CODE_CHIP_RATE_HZ) * static_cast(acq_parameters.fs_in))); - dump_ = configuration_->property(role + ".dump", false); - acq_parameters.dump = dump_; - acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0); - blocking_ = configuration_->property(role + ".blocking", true); - acq_parameters.blocking = blocking_; doppler_max_ = configuration_->property(role + ".doppler_max", 5000); if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max; acq_parameters.doppler_max = doppler_max_; - sampled_ms_ = 4; + sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 4); acq_parameters.sampled_ms = sampled_ms_; bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false); acq_parameters.bit_transition_flag = bit_transition_flag_; use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions acq_parameters.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_; acquire_pilot_ = configuration_->property(role + ".acquire_pilot", false); //will be true in future versions - max_dwells_ = configuration_->property(role + ".max_dwells", 1); acq_parameters.max_dwells = max_dwells_; + dump_ = configuration_->property(role + ".dump", false); + acq_parameters.dump = dump_; + acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0); + blocking_ = configuration_->property(role + ".blocking", true); + acq_parameters.blocking = blocking_; dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename); acq_parameters.dump_filename = dump_filename_; //--- Find number of samples per spreading code (4 ms) ----------------- diff --git a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc index e68de5230..132c5ff1c 100644 --- a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc @@ -100,10 +100,10 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition( acq_parameters.samples_per_ms = static_cast(std::round(static_cast(fs_in_) * 0.001)); acq_parameters.samples_per_code = code_length_; acq_parameters.it_size = item_size_; - acq_parameters.sampled_ms = 20; + acq_parameters.sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 20); acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0); - acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", true); + acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false); acq_parameters.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false); acquisition_ = pcps_make_acquisition(acq_parameters); DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc index 646975ae4..3ff1ac23c 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc @@ -65,7 +65,7 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu d_old_freq = 0; d_num_noncoherent_integrations_counter = 0; d_consumed_samples = acq_parameters.sampled_ms * acq_parameters.samples_per_ms * (acq_parameters.bit_transition_flag ? 2 : 1); - if (acq_parameters.sampled_ms == 1) + if (acq_parameters.sampled_ms == (acq_parameters.samples_per_code / acq_parameters.samples_per_ms)) // { d_fft_size = d_consumed_samples; } @@ -205,7 +205,7 @@ void pcps_acquisition::set_local_code(std::complex* code) } else { - if (acq_parameters.sampled_ms == 1) + if (acq_parameters.sampled_ms == (acq_parameters.samples_per_code / acq_parameters.samples_per_ms)) { memcpy(d_fft_if->get_inbuf(), code, sizeof(gr_complex) * d_consumed_samples); } diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/acq_performance_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/acq_performance_test.cc index 111dc775d..312085442 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/acq_performance_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/acq_performance_test.cc @@ -164,46 +164,69 @@ protected: { signal_id = "1C"; system_id = 'G'; + coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; } else if (implementation.compare("GPS_L1_CA_PCPS_Acquisition_Fine_Doppler") == 0) { signal_id = "1C"; system_id = 'G'; + coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; } else if (implementation.compare("Galileo_E1_PCPS_Ambiguous_Acquisition") == 0) { signal_id = "1B"; system_id = 'E'; + if (FLAGS_acq_test_coherent_time_ms == 1) + { + coherent_integration_time_ms = 4; + } + else + { + coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; + } } else if (implementation.compare("GLONASS_L1_CA_PCPS_Acquisition") == 0) { signal_id = "1G"; system_id = 'R'; + coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; } else if (implementation.compare("GLONASS_L2_CA_PCPS_Acquisition") == 0) { signal_id = "2G"; system_id = 'R'; + coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; } else if (implementation.compare("GPS_L2_M_PCPS_Acquisition") == 0) { signal_id = "2S"; system_id = 'G'; + if (FLAGS_acq_test_coherent_time_ms == 1) + { + coherent_integration_time_ms = 20; + } + else + { + coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; + } } else if (implementation.compare("Galileo_E5a_Pcps_Acquisition") == 0) { signal_id = "5X"; system_id = 'E'; + coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; } else if (implementation.compare("GPS_L5i_PCPS_Acquisition") == 0) { signal_id = "L5"; system_id = 'G'; + coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; } else { signal_id = "1C"; system_id = 'G'; + coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; } init(); @@ -292,7 +315,7 @@ protected: std::string implementation = FLAGS_acq_test_implementation; const double baseband_sampling_freq = static_cast(FLAGS_fs_gen_sps); - const int coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; + int coherent_integration_time_ms; const int in_acquisition = 1; const int dump_channel = 0; diff --git a/src/utils/reproducibility/ieee-access18/L2-access18.conf b/src/utils/reproducibility/ieee-access18/L2-access18.conf index e4bc4ae44..d51a040d2 100644 --- a/src/utils/reproducibility/ieee-access18/L2-access18.conf +++ b/src/utils/reproducibility/ieee-access18/L2-access18.conf @@ -85,7 +85,7 @@ Acquisition_2S.doppler_step=125 Acquisition_2S.use_CFAR_algorithm=false -Acquisition_2S.threshold=19.5 +Acquisition_2S.threshold=10 Acquisition_2S.blocking=true