1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-12-16 05:00:35 +00:00

Implement non-coherent acquisition

This commit is contained in:
Carles Fernandez 2018-07-08 13:26:30 +02:00
parent 89c00560f2
commit d76dab6248
No known key found for this signature in database
GPG Key ID: 4C583C52B0C3877D
2 changed files with 43 additions and 17 deletions

View File

@ -63,7 +63,7 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu
d_positive_acq = 0; d_positive_acq = 0;
d_state = 0; d_state = 0;
d_old_freq = 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_fft_size = acq_parameters.sampled_ms * acq_parameters.samples_per_ms;
d_mag = 0; d_mag = 0;
d_input_power = 0.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_cshort = true;
} }
d_tmp_buffer = static_cast<float*>(volk_gnsssdr_malloc(d_fft_size * sizeof(float), volk_gnsssdr_get_alignment()));
// COD: // COD:
// Experimenting with the overlap/save technique for handling bit trannsitions // Experimenting with the overlap/save technique for handling bit trannsitions
// The problem: Circular correlation is asynchronous with the received code. // 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_gnss_synchro = 0;
d_grid_doppler_wipeoffs = nullptr; d_grid_doppler_wipeoffs = nullptr;
d_grid_doppler_wipeoffs_step_two = nullptr; d_grid_doppler_wipeoffs_step_two = nullptr;
d_magnitude_grid = nullptr;
d_worker_active = false; d_worker_active = false;
d_data_buffer = static_cast<gr_complex*>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment())); d_data_buffer = static_cast<gr_complex*>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
if (d_cshort) if (d_cshort)
@ -134,8 +137,10 @@ pcps_acquisition::~pcps_acquisition()
for (unsigned int i = 0; i < d_num_doppler_bins; i++) for (unsigned int i = 0; i < d_num_doppler_bins; i++)
{ {
volk_gnsssdr_free(d_grid_doppler_wipeoffs[i]); volk_gnsssdr_free(d_grid_doppler_wipeoffs[i]);
volk_gnsssdr_free(d_magnitude_grid[i]);
} }
delete[] d_grid_doppler_wipeoffs; delete[] d_grid_doppler_wipeoffs;
delete[] d_magnitude_grid;
} }
if (acq_parameters.make_2_steps) if (acq_parameters.make_2_steps)
{ {
@ -147,6 +152,7 @@ pcps_acquisition::~pcps_acquisition()
} }
volk_gnsssdr_free(d_fft_codes); volk_gnsssdr_free(d_fft_codes);
volk_gnsssdr_free(d_magnitude); volk_gnsssdr_free(d_magnitude);
volk_gnsssdr_free(d_tmp_buffer);
delete d_ifft; delete d_ifft;
delete d_fft_if; delete d_fft_if;
volk_gnsssdr_free(d_data_buffer); volk_gnsssdr_free(d_data_buffer);
@ -243,9 +249,12 @@ void pcps_acquisition::init()
d_grid_doppler_wipeoffs_step_two[doppler_index] = static_cast<gr_complex*>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment())); d_grid_doppler_wipeoffs_step_two[doppler_index] = static_cast<gr_complex*>(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++) for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
{ {
d_grid_doppler_wipeoffs[doppler_index] = static_cast<gr_complex*>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment())); d_grid_doppler_wipeoffs[doppler_index] = static_cast<gr_complex*>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
d_magnitude_grid[doppler_index] = static_cast<float*>(volk_gnsssdr_malloc(d_fft_size * sizeof(float), volk_gnsssdr_get_alignment()));
int doppler = -static_cast<int>(acq_parameters.doppler_max) + d_doppler_step * doppler_index; int doppler = -static_cast<int>(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); 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() void pcps_acquisition::update_grid_doppler_wipeoffs_step2()
{ {
for (unsigned int doppler_index = 0; doppler_index < acq_parameters.num_doppler_bins_step2; doppler_index++) 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) void pcps_acquisition::set_state(int state)
{ {
gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler 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_delay_samples = 0.0;
d_gnss_synchro->Acq_doppler_hz = 0.0; d_gnss_synchro->Acq_doppler_hz = 0.0;
d_gnss_synchro->Acq_samplestamp_samples = 0; d_gnss_synchro->Acq_samplestamp_samples = 0;
d_well_count = 0;
d_mag = 0.0; d_mag = 0.0;
d_input_power = 0.0; d_input_power = 0.0;
d_test_statistics = 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_input_power = 0.0;
d_mag = 0.0; d_mag = 0.0;
d_well_count++; d_num_noncoherent_integrations_counter++;
DLOG(INFO) << "Channel: " << d_channel DLOG(INFO) << "Channel: " << d_channel
<< " , doing acquisition of satellite: " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN << " , 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 // Search maximum
size_t offset = (acq_parameters.bit_transition_flag ? effective_fft_size : 0); 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); if (d_num_noncoherent_integrations_counter == 1)
volk_gnsssdr_32f_index_max_32u(&indext, d_magnitude, effective_fft_size); {
magt = d_magnitude[indext]; 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) if (acq_parameters.use_CFAR_algorithm_flag)
{ {
// Normalize the maximum value to correct the scale factor introduced by FFTW // 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 // 4- record the maximum peak and the associated synchronization parameters
if (d_mag < magt) 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) if (!acq_parameters.use_CFAR_algorithm_flag)
{ {
// Search grid noise floor approximation for this doppler line // 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); 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 // Record results to file if required
if (acq_parameters.dump and d_channel == d_dump_channel) 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 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_state = 0;
d_active = false; d_active = false;
d_step_two = false; d_step_two = false;
send_negative_acquisition();
} }
} }
else else
@ -657,10 +676,16 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count)
} }
} }
d_worker_active = false; 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_delay_samples = 0.0;
d_gnss_synchro->Acq_doppler_hz = 0.0; d_gnss_synchro->Acq_doppler_hz = 0.0;
d_gnss_synchro->Acq_samplestamp_samples = 0; d_gnss_synchro->Acq_samplestamp_samples = 0;
d_well_count = 0;
d_mag = 0.0; d_mag = 0.0;
d_input_power = 0.0; d_input_power = 0.0;
d_test_statistics = 0.0; d_test_statistics = 0.0;

View File

@ -106,12 +106,14 @@ private:
float d_input_power; float d_input_power;
float d_test_statistics; float d_test_statistics;
float* d_magnitude; float* d_magnitude;
float** d_magnitude_grid;
float* d_tmp_buffer;
long d_old_freq; long d_old_freq;
int d_state; int d_state;
unsigned int d_channel; unsigned int d_channel;
unsigned int d_doppler_step; unsigned int d_doppler_step;
float d_doppler_center_step_two; 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_fft_size;
unsigned int d_num_doppler_bins; unsigned int d_num_doppler_bins;
unsigned long int d_sample_counter; unsigned long int d_sample_counter;
@ -150,7 +152,7 @@ public:
} }
/*! /*!
* \brief Initializes acquisition algorithm. * \brief Initializes acquisition algorithm and reserves memory.
*/ */
void init(); void init();