mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2024-12-14 20:20:35 +00:00
Add coherent and non-coherent acquisition to multi-signal Acquisition block
Both methods can be combined. For example, coherent_integration_time_ms=10, max_dwells=2 will perform 2 non-coherent dwells of 10 ms coherent integrations. This is a major improvement in acquisition sensitivity.
This commit is contained in:
commit
ac089eded9
@ -58,24 +58,24 @@ 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_;
|
||||
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_;
|
||||
acq_parameters.samples_per_chip = static_cast<unsigned int>(ceil((1.0 / Galileo_E1_CODE_CHIP_RATE_HZ) * static_cast<float>(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_;
|
||||
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) -----------------
|
||||
|
@ -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<unsigned int>(ceil((1.0 / Galileo_E5a_CODE_CHIP_RATE_HZ) * static_cast<float>(acq_parameters.fs_in)));
|
||||
acq_pilot_ = configuration_->property(role + ".acquire_pilot", false);
|
||||
acq_iq_ = configuration_->property(role + ".acquire_iq", false);
|
||||
if (acq_iq_)
|
||||
|
@ -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<unsigned int>(ceil(GLONASS_L1_CA_CHIP_PERIOD * static_cast<float>(acq_parameters.fs_in)));
|
||||
dump_ = configuration_->property(role + ".dump", false);
|
||||
acq_parameters.dump = dump_;
|
||||
acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0);
|
||||
|
@ -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<unsigned int>(ceil(GLONASS_L2_CA_CHIP_PERIOD * static_cast<float>(acq_parameters.fs_in)));
|
||||
dump_ = configuration_->property(role + ".dump", false);
|
||||
acq_parameters.dump = dump_;
|
||||
acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0);
|
||||
|
@ -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<unsigned int>(ceil(GPS_L1_CA_CHIP_PERIOD * static_cast<float>(acq_parameters.fs_in)));
|
||||
dump_ = configuration_->property(role + ".dump", false);
|
||||
acq_parameters.dump = dump_;
|
||||
acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0);
|
||||
|
@ -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<unsigned int>(ceil(GPS_L1_CA_CHIP_PERIOD * static_cast<float>(acq_parameters.fs_in)));
|
||||
dump_ = configuration->property(role + ".dump", false);
|
||||
acq_parameters.dump = dump_;
|
||||
dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename);
|
||||
|
@ -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<unsigned int>(ceil(GPS_L1_CA_CHIP_PERIOD * static_cast<float>(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_;
|
||||
|
@ -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<unsigned int>(ceil((1.0 / GPS_L2_M_CODE_RATE_HZ) * static_cast<float>(acq_parameters.fs_in)));
|
||||
dump_ = configuration_->property(role + ".dump", false);
|
||||
acq_parameters.dump = dump_;
|
||||
acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0);
|
||||
@ -99,10 +100,10 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition(
|
||||
acq_parameters.samples_per_ms = static_cast<int>(std::round(static_cast<double>(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() << ")";
|
||||
|
@ -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 <ul>
|
||||
@ -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<unsigned int>(ceil((1.0 / GPS_L5i_CODE_RATE_HZ) * static_cast<float>(acq_parameters.fs_in)));
|
||||
dump_ = configuration_->property(role + ".dump", false);
|
||||
acq_parameters.dump = dump_;
|
||||
acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0);
|
||||
|
@ -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 <ul>
|
||||
|
@ -63,8 +63,17 @@ 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_fft_size = acq_parameters.sampled_ms * acq_parameters.samples_per_ms;
|
||||
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 == (acq_parameters.samples_per_code / acq_parameters.samples_per_ms)) //
|
||||
{
|
||||
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;
|
||||
@ -94,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;
|
||||
acq_parameters.max_dwells = 1; //Activation of acq_parameters.bit_transition_flag invalidates the value of acq_parameters.max_dwells
|
||||
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<float*>(volk_gnsssdr_malloc(d_fft_size * sizeof(float), volk_gnsssdr_get_alignment()));
|
||||
d_fft_codes = static_cast<gr_complex*>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
|
||||
d_magnitude = static_cast<float*>(volk_gnsssdr_malloc(d_fft_size * sizeof(float), volk_gnsssdr_get_alignment()));
|
||||
d_input_signal = static_cast<gr_complex*>(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);
|
||||
@ -110,11 +121,12 @@ 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<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_consumed_samples * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
|
||||
if (d_cshort)
|
||||
{
|
||||
d_data_buffer_sc = static_cast<lv_16sc_t*>(volk_gnsssdr_malloc(d_fft_size * sizeof(lv_16sc_t), volk_gnsssdr_get_alignment()));
|
||||
d_data_buffer_sc = static_cast<lv_16sc_t*>(volk_gnsssdr_malloc(d_consumed_samples * sizeof(lv_16sc_t), volk_gnsssdr_get_alignment()));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -124,6 +136,16 @@ 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;
|
||||
d_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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -134,8 +156,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 +171,8 @@ 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);
|
||||
@ -179,7 +205,15 @@ void pcps_acquisition::set_local_code(std::complex<float>* code)
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(d_fft_if->get_inbuf(), code, sizeof(gr_complex) * d_fft_size);
|
||||
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);
|
||||
}
|
||||
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
|
||||
@ -243,9 +277,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_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<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;
|
||||
update_local_carrier(d_grid_doppler_wipeoffs[doppler_index], d_fft_size, d_old_freq + doppler);
|
||||
}
|
||||
@ -268,6 +305,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 +315,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 +325,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;
|
||||
@ -417,109 +455,184 @@ 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;
|
||||
unsigned int index_doppler = 0;
|
||||
uint32_t tmp_intex_t = 0;
|
||||
uint32_t index_time = 0;
|
||||
float fft_normalization_factor = static_cast<float>(d_fft_size) * static_cast<float>(d_fft_size);
|
||||
|
||||
// Find the correlation peak and the carrier frequency
|
||||
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)
|
||||
{
|
||||
grid_maximum = d_magnitude_grid[i][tmp_intex_t];
|
||||
index_doppler = i;
|
||||
index_time = tmp_intex_t;
|
||||
}
|
||||
}
|
||||
indext = index_time;
|
||||
doppler = -static_cast<int>(acq_parameters.doppler_max) + d_doppler_step * static_cast<int>(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;
|
||||
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 (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)
|
||||
{
|
||||
firstPeak = d_magnitude_grid[i][tmp_intex_t];
|
||||
index_doppler = i;
|
||||
index_time = tmp_intex_t;
|
||||
}
|
||||
}
|
||||
indext = index_time;
|
||||
doppler = -static_cast<int>(acq_parameters.doppler_max) + d_doppler_step * static_cast<int>(index_doppler);
|
||||
|
||||
// Find 1 chip wide code phase exclude range around the peak
|
||||
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)
|
||||
{
|
||||
excludeRangeIndex1 = d_fft_size + excludeRangeIndex1;
|
||||
}
|
||||
else if (excludeRangeIndex2 >= static_cast<int>(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<int>(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];
|
||||
|
||||
// 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;
|
||||
const gr_complex* in = d_data_buffer; // Get the input samples pointer
|
||||
int doppler = 0;
|
||||
uint32_t indext = 0;
|
||||
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<float>(d_fft_size) * static_cast<float>(d_fft_size);
|
||||
|
||||
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
|
||||
<< " ,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 or acq_parameters.bit_transition_flag)
|
||||
{
|
||||
// 1- (optional) 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);
|
||||
// Compute the input signal power estimation
|
||||
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<float>(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++)
|
||||
{
|
||||
// doppler search steps
|
||||
int doppler = -static_cast<int>(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)
|
||||
// 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();
|
||||
|
||||
// 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);
|
||||
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 (acq_parameters.use_CFAR_algorithm_flag)
|
||||
if (d_num_noncoherent_integrations_counter == 1)
|
||||
{
|
||||
// Normalize the maximum value to correct the scale factor introduced by FFTW
|
||||
magt = d_magnitude[indext] / (fft_normalization_factor * fft_normalization_factor);
|
||||
volk_32fc_magnitude_squared_32f(d_magnitude_grid[doppler_index], d_ifft->get_outbuf() + offset, effective_fft_size);
|
||||
}
|
||||
// 4- record the maximum peak and the associated synchronization parameters
|
||||
if (d_mag < magt)
|
||||
else
|
||||
{
|
||||
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, 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<double>(indext % acq_parameters.samples_per_code);
|
||||
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(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;
|
||||
}
|
||||
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);
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
// Compute the test statistic
|
||||
if (d_use_CFAR_algorithm_flag)
|
||||
{
|
||||
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<double>(indext % acq_parameters.samples_per_code);
|
||||
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
|
||||
d_gnss_synchro->Acq_samplestamp_samples = samp_count;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -547,7 +660,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);
|
||||
@ -557,7 +670,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);
|
||||
@ -590,6 +703,7 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lk.lock();
|
||||
if (!acq_parameters.bit_transition_flag)
|
||||
{
|
||||
@ -616,12 +730,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 +772,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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -685,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)
|
||||
@ -706,14 +827,13 @@ 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;
|
||||
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;
|
||||
@ -724,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)
|
||||
{
|
||||
@ -740,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;
|
||||
}
|
||||
|
@ -95,24 +95,33 @@ private:
|
||||
|
||||
void dump_results(int effective_fft_size);
|
||||
|
||||
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;
|
||||
float d_input_power;
|
||||
float d_test_statistics;
|
||||
float* d_magnitude;
|
||||
float** d_magnitude_grid;
|
||||
float* d_tmp_buffer;
|
||||
gr_complex* d_input_signal;
|
||||
uint32_t d_samplesPerChip;
|
||||
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_consumed_samples;
|
||||
unsigned int d_num_doppler_bins;
|
||||
unsigned long int d_sample_counter;
|
||||
gr_complex** d_grid_doppler_wipeoffs;
|
||||
@ -150,7 +159,7 @@ public:
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Initializes acquisition algorithm.
|
||||
* \brief Initializes acquisition algorithm and reserves memory.
|
||||
*/
|
||||
void init();
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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 <boost/filesystem.hpp>
|
||||
#include <gnuradio/top_block.h>
|
||||
#include <glog/logging.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
|
||||
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,76 @@ protected:
|
||||
{
|
||||
cn0_vector = {0.0};
|
||||
}
|
||||
|
||||
if (implementation.compare("GPS_L1_CA_PCPS_Acquisition") == 0)
|
||||
{
|
||||
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();
|
||||
|
||||
if (FLAGS_acq_test_pfa_init > 0.0)
|
||||
@ -181,7 +256,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<unsigned int>(FLAGS_acq_test_num_meas);
|
||||
@ -240,7 +315,7 @@ protected:
|
||||
std::string implementation = FLAGS_acq_test_implementation;
|
||||
|
||||
const double baseband_sampling_freq = static_cast<double>(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;
|
||||
|
||||
@ -257,6 +332,8 @@ protected:
|
||||
std::vector<std::vector<float>> Pfa;
|
||||
std::vector<std::vector<float>> Pd_correct;
|
||||
|
||||
std::string signal_id;
|
||||
|
||||
private:
|
||||
std::string generator_binary;
|
||||
std::string p1;
|
||||
@ -268,6 +345,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<double>& vec);
|
||||
double compute_stdev_accuracy(const std::vector<double>& vec, double ref);
|
||||
@ -277,8 +355,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 +456,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 +540,47 @@ int AcquisitionPerformanceTest::run_receiver()
|
||||
boost::shared_ptr<gr::block> valve = gnss_sdr_make_valve(sizeof(gr_complex), nsamples, queue);
|
||||
if (implementation.compare("GPS_L1_CA_PCPS_Acquisition") == 0)
|
||||
{
|
||||
acquisition = std::make_shared<GpsL1CaPcpsAcquisition>(config.get(), "Acquisition_1C", 1, 0);
|
||||
acquisition = std::make_shared<GpsL1CaPcpsAcquisition>(config.get(), "Acquisition", 1, 0);
|
||||
}
|
||||
else if (implementation.compare("GPS_L1_CA_PCPS_Acquisition_Fine_Doppler") == 0)
|
||||
{
|
||||
acquisition = std::make_shared<GpsL1CaPcpsAcquisitionFineDoppler>(config.get(), "Acquisition", 1, 0);
|
||||
}
|
||||
else if (implementation.compare("Galileo_E1_PCPS_Ambiguous_Acquisition") == 0)
|
||||
{
|
||||
acquisition = std::make_shared<GalileoE1PcpsAmbiguousAcquisition>(config.get(), "Acquisition", 1, 0);
|
||||
}
|
||||
else if (implementation.compare("GLONASS_L1_CA_PCPS_Acquisition") == 0)
|
||||
{
|
||||
acquisition = std::make_shared<GlonassL1CaPcpsAcquisition>(config.get(), "Acquisition", 1, 0);
|
||||
}
|
||||
else if (implementation.compare("GLONASS_L2_CA_PCPS_Acquisition") == 0)
|
||||
{
|
||||
acquisition = std::make_shared<GlonassL2CaPcpsAcquisition>(config.get(), "Acquisition", 1, 0);
|
||||
}
|
||||
else if (implementation.compare("GPS_L2_M_PCPS_Acquisition") == 0)
|
||||
{
|
||||
acquisition = std::make_shared<GpsL2MPcpsAcquisition>(config.get(), "Acquisition", 1, 0);
|
||||
}
|
||||
else if (implementation.compare("Galileo_E5a_Pcps_Acquisition") == 0)
|
||||
{
|
||||
acquisition = std::make_shared<GalileoE5aPcpsAcquisition>(config.get(), "Acquisition", 1, 0);
|
||||
}
|
||||
else if (implementation.compare("GPS_L5i_PCPS_Acquisition") == 0)
|
||||
{
|
||||
acquisition = std::make_shared<GpsL5iPcpsAcquisition>(config.get(), "Acquisition", 1, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (implementation.compare("GPS_L1_CA_PCPS_Acquisition_Fine_Doppler") == 0)
|
||||
{
|
||||
acquisition = std::make_shared<GpsL1CaPcpsAcquisitionFineDoppler>(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 +662,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 +698,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 +791,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<double>(coh_time_ms), 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<double>(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 +926,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<float>(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<float>(config->property("Acquisition.doppler_step", 1)) / 2.0)
|
||||
{
|
||||
correctly_detected = correctly_detected + 1.0;
|
||||
}
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user