1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-11-09 03:20:01 +00:00

Merge branch 'next' of https://github.com/gnss-sdr/gnss-sdr into next

This commit is contained in:
Carles Fernandez 2018-07-13 16:48:57 +02:00
commit b575a3bead
No known key found for this signature in database
GPG Key ID: 4C583C52B0C3877D
15 changed files with 226 additions and 111 deletions

View File

@ -64,6 +64,11 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition(
acq_parameters.doppler_max = doppler_max_; acq_parameters.doppler_max = doppler_max_;
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 4); sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 4);
acq_parameters.sampled_ms = sampled_ms_; acq_parameters.sampled_ms = sampled_ms_;
if ((acq_parameters.sampled_ms % 4) != 0)
{
LOG(WARNING) << "Parameter coherent_integration_time_ms should be a multiple of 4. Setting it to 4";
acq_parameters.sampled_ms = 4;
}
bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false); bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
acq_parameters.bit_transition_flag = bit_transition_flag_; 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 use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions
@ -80,9 +85,10 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition(
acq_parameters.dump_filename = dump_filename_; acq_parameters.dump_filename = dump_filename_;
//--- Find number of samples per spreading code (4 ms) ----------------- //--- Find number of samples per spreading code (4 ms) -----------------
code_length_ = static_cast<unsigned int>(std::round(static_cast<double>(fs_in_) / (Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS))); code_length_ = static_cast<unsigned int>(std::round(static_cast<double>(fs_in_) / (Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS)));
acq_parameters.samples_per_code = code_length_;
int samples_per_ms = static_cast<int>(std::round(static_cast<double>(fs_in_) * 0.001)); float samples_per_ms = static_cast<float>(fs_in_) * 0.001;
acq_parameters.samples_per_ms = samples_per_ms; acq_parameters.samples_per_ms = samples_per_ms;
acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(Galileo_E1_CODE_PERIOD_MS);
vector_length_ = sampled_ms_ * samples_per_ms; vector_length_ = sampled_ms_ * samples_per_ms;
if (bit_transition_flag_) if (bit_transition_flag_)

View File

@ -101,9 +101,9 @@ GalileoE5aPcpsAcquisition::GalileoE5aPcpsAcquisition(ConfigurationInterface* con
LOG(WARNING) << item_type_ << " unknown acquisition item type"; LOG(WARNING) << item_type_ << " unknown acquisition item type";
} }
acq_parameters.it_size = item_size_; acq_parameters.it_size = item_size_;
acq_parameters.samples_per_code = code_length_; acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
acq_parameters.samples_per_ms = code_length_;
acq_parameters.sampled_ms = sampled_ms_; acq_parameters.sampled_ms = sampled_ms_;
acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GALILEO_E5a_CODE_PERIOD_MS);
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); 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.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false); acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);

View File

@ -100,8 +100,8 @@ GlonassL1CaPcpsAcquisition::GlonassL1CaPcpsAcquisition(
} }
acq_parameters.it_size = item_size_; acq_parameters.it_size = item_size_;
acq_parameters.sampled_ms = sampled_ms_; acq_parameters.sampled_ms = sampled_ms_;
acq_parameters.samples_per_ms = code_length_; acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
acq_parameters.samples_per_code = code_length_; acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GLONASS_L1_CA_CODE_PERIOD * 1000.0);
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); 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.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false); acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);

View File

@ -99,8 +99,8 @@ GlonassL2CaPcpsAcquisition::GlonassL2CaPcpsAcquisition(
} }
acq_parameters.it_size = item_size_; acq_parameters.it_size = item_size_;
acq_parameters.sampled_ms = sampled_ms_; acq_parameters.sampled_ms = sampled_ms_;
acq_parameters.samples_per_ms = code_length_; acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
acq_parameters.samples_per_code = code_length_; acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GLONASS_L2_CA_CODE_PERIOD * 1000.0);
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); 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.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false); acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);

View File

@ -102,8 +102,8 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition(
{ {
item_size_ = sizeof(gr_complex); item_size_ = sizeof(gr_complex);
} }
acq_parameters.samples_per_ms = code_length_; acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
acq_parameters.samples_per_code = code_length_; acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GPS_L1_CA_CODE_PERIOD * 1000.0);
acq_parameters.it_size = item_size_; acq_parameters.it_size = item_size_;
acq_parameters.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false); acq_parameters.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false);
acquisition_ = pcps_make_acquisition(acq_parameters); acquisition_ = pcps_make_acquisition(acq_parameters);

View File

@ -78,7 +78,15 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition(
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename); dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
acq_parameters.dump_filename = dump_filename_; acq_parameters.dump_filename = dump_filename_;
//--- Find number of samples per spreading code ------------------------- //--- Find number of samples per spreading code -------------------------
code_length_ = std::round(static_cast<double>(fs_in_) / (GPS_L2_M_CODE_RATE_HZ / static_cast<double>(GPS_L2_M_CODE_LENGTH_CHIPS))); acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
acq_parameters.sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 20);
if ((acq_parameters.sampled_ms % 20) != 0)
{
LOG(WARNING) << "Parameter coherent_integration_time_ms should be a multiple of 20. Setting it to 20";
acq_parameters.sampled_ms = 20;
}
code_length_ = acq_parameters.sampled_ms * acq_parameters.samples_per_ms * (acq_parameters.bit_transition_flag ? 2 : 1);
vector_length_ = code_length_; vector_length_ = code_length_;
@ -97,10 +105,10 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition(
{ {
item_size_ = sizeof(gr_complex); item_size_ = sizeof(gr_complex);
} }
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.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GPS_L2_M_PERIOD * 1000.0);
acq_parameters.it_size = item_size_; acq_parameters.it_size = item_size_;
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.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0); acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false); acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);

View File

@ -96,10 +96,10 @@ GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition(
{ {
item_size_ = sizeof(gr_complex); item_size_ = sizeof(gr_complex);
} }
acq_parameters.samples_per_code = code_length_; acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
acq_parameters.samples_per_ms = code_length_; acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GPS_L5i_PERIOD * 1000.0);
acq_parameters.it_size = item_size_; acq_parameters.it_size = item_size_;
acq_parameters.sampled_ms = 1; acq_parameters.sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 1);
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); 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.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false); acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);

View File

@ -460,7 +460,7 @@ 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 pcps_acquisition::max_to_input_power_statistic(uint32_t& indext, int& doppler, float input_power, unsigned int num_doppler_bins, int doppler_max, int doppler_step)
{ {
float grid_maximum = 0.0; float grid_maximum = 0.0;
unsigned int index_doppler = 0; unsigned int index_doppler = 0;
@ -469,7 +469,7 @@ float pcps_acquisition::max_to_input_power_statistic(uint32_t& indext, int& dopp
float fft_normalization_factor = static_cast<float>(d_fft_size) * static_cast<float>(d_fft_size); float fft_normalization_factor = static_cast<float>(d_fft_size) * static_cast<float>(d_fft_size);
// Find the correlation peak and the carrier frequency // Find the correlation peak and the carrier frequency
for (unsigned int i = 0; i < d_num_doppler_bins; i++) for (unsigned int i = 0; i < num_doppler_bins; i++)
{ {
volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_magnitude_grid[i], d_fft_size); 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) if (d_magnitude_grid[i][tmp_intex_t] > grid_maximum)
@ -480,14 +480,21 @@ float pcps_acquisition::max_to_input_power_statistic(uint32_t& indext, int& dopp
} }
} }
indext = index_time; indext = index_time;
doppler = -static_cast<int>(acq_parameters.doppler_max) + d_doppler_step * static_cast<int>(index_doppler); if (!d_step_two)
{
doppler = -static_cast<int>(doppler_max) + doppler_step * static_cast<int>(index_doppler);
}
else
{
doppler = static_cast<int>(d_doppler_center_step_two + (index_doppler - (acq_parameters.num_doppler_bins_step2 / 2.0) * acq_parameters.doppler_step2));
}
float magt = grid_maximum / (fft_normalization_factor * fft_normalization_factor); float magt = grid_maximum / (fft_normalization_factor * fft_normalization_factor);
return magt / input_power; return magt / input_power;
} }
float pcps_acquisition::first_vs_second_peak_statistic(uint32_t& indext, int& doppler) float pcps_acquisition::first_vs_second_peak_statistic(uint32_t& indext, int& doppler, unsigned int num_doppler_bins, int doppler_max, int doppler_step)
{ {
// Look for correlation peaks in the results // Look for correlation peaks in the results
// Find the highest peak and compare it to the second highest peak // Find the highest peak and compare it to the second highest peak
@ -499,7 +506,7 @@ float pcps_acquisition::first_vs_second_peak_statistic(uint32_t& indext, int& do
uint32_t index_time = 0; uint32_t index_time = 0;
// Find the correlation peak and the carrier frequency // Find the correlation peak and the carrier frequency
for (unsigned int i = 0; i < d_num_doppler_bins; i++) for (unsigned int i = 0; i < num_doppler_bins; i++)
{ {
volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_magnitude_grid[i], d_fft_size); 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) if (d_magnitude_grid[i][tmp_intex_t] > firstPeak)
@ -510,7 +517,15 @@ float pcps_acquisition::first_vs_second_peak_statistic(uint32_t& indext, int& do
} }
} }
indext = index_time; indext = index_time;
doppler = -static_cast<int>(acq_parameters.doppler_max) + d_doppler_step * static_cast<int>(index_doppler);
if (!d_step_two)
{
doppler = -static_cast<int>(doppler_max) + doppler_step * static_cast<int>(index_doppler);
}
else
{
doppler = static_cast<int>(d_doppler_center_step_two + (index_doppler - (acq_parameters.num_doppler_bins_step2 / 2.0) * acq_parameters.doppler_step2));
}
// Find 1 chip wide code phase exclude range around the peak // Find 1 chip wide code phase exclude range around the peak
int32_t excludeRangeIndex1 = index_time - d_samplesPerChip; int32_t excludeRangeIndex1 = index_time - d_samplesPerChip;
@ -550,7 +565,6 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count)
gr::thread::scoped_lock lk(d_setlock); gr::thread::scoped_lock lk(d_setlock);
// initialize acquisition algorithm // initialize acquisition algorithm
float magt = 0.0;
int doppler = 0; int doppler = 0;
uint32_t indext = 0; uint32_t indext = 0;
int effective_fft_size = (acq_parameters.bit_transition_flag ? d_fft_size / 2 : d_fft_size); int effective_fft_size = (acq_parameters.bit_transition_flag ? d_fft_size / 2 : d_fft_size);
@ -567,7 +581,6 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count)
} }
} }
const gr_complex* in = d_input_signal; // Get the input samples pointer 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_input_power = 0.0;
d_mag = 0.0; d_mag = 0.0;
@ -629,13 +642,13 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count)
// Compute the test statistic // Compute the test statistic
if (d_use_CFAR_algorithm_flag) if (d_use_CFAR_algorithm_flag)
{ {
d_test_statistics = max_to_input_power_statistic(indext, doppler, d_input_power); d_test_statistics = max_to_input_power_statistic(indext, doppler, d_input_power, d_num_doppler_bins, acq_parameters.doppler_max, d_doppler_step);
} }
else else
{ {
d_test_statistics = first_vs_second_peak_statistic(indext, doppler); d_test_statistics = first_vs_second_peak_statistic(indext, doppler, d_num_doppler_bins, acq_parameters.doppler_max, d_doppler_step);
} }
d_gnss_synchro->Acq_delay_samples = static_cast<double>(indext % acq_parameters.samples_per_code); d_gnss_synchro->Acq_delay_samples = static_cast<double>(std::fmod(static_cast<float>(indext), acq_parameters.samples_per_code));
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler); d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
d_gnss_synchro->Acq_samplestamp_samples = samp_count; d_gnss_synchro->Acq_samplestamp_samples = samp_count;
} }
@ -643,9 +656,6 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count)
{ {
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++)
{ {
// doppler search steps
float doppler = d_doppler_center_step_two + (static_cast<float>(doppler_index) - static_cast<float>(acq_parameters.num_doppler_bins_step2) / 2.0) * acq_parameters.doppler_step2;
volk_32fc_x2_multiply_32fc(d_fft_if->get_inbuf(), in, d_grid_doppler_wipeoffs_step_two[doppler_index], d_fft_size); volk_32fc_x2_multiply_32fc(d_fft_if->get_inbuf(), in, d_grid_doppler_wipeoffs_step_two[doppler_index], d_fft_size);
// 3- Perform the FFT-based convolution (parallel time search) // 3- Perform the FFT-based convolution (parallel time search)
@ -659,54 +669,29 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count)
// compute the inverse FFT // compute the inverse FFT
d_ifft->execute(); d_ifft->execute();
// 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];
if (d_use_CFAR_algorithm_flag)
{ {
// Normalize the maximum value to correct the scale factor introduced by FFTW volk_32fc_magnitude_squared_32f(d_magnitude_grid[doppler_index], d_ifft->get_outbuf() + offset, effective_fft_size);
magt = d_magnitude[indext] / (fft_normalization_factor * fft_normalization_factor);
} }
// 4- record the maximum peak and the associated synchronization parameters else
if (d_mag < magt)
{ {
d_mag = magt; 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);
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);
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;
}
}
// 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);
} }
} }
// Compute the test statistic
if (d_use_CFAR_algorithm_flag)
{
d_test_statistics = max_to_input_power_statistic(indext, doppler, d_input_power, acq_parameters.num_doppler_bins_step2, static_cast<int>(d_doppler_center_step_two - (static_cast<float>(acq_parameters.num_doppler_bins_step2) / 2.0) * acq_parameters.doppler_step2), acq_parameters.doppler_step2);
}
else
{
d_test_statistics = first_vs_second_peak_statistic(indext, doppler, acq_parameters.num_doppler_bins_step2, static_cast<int>(d_doppler_center_step_two - (static_cast<float>(acq_parameters.num_doppler_bins_step2) / 2.0) * acq_parameters.doppler_step2), acq_parameters.doppler_step2);
}
d_gnss_synchro->Acq_delay_samples = static_cast<double>(std::fmod(static_cast<float>(indext), acq_parameters.samples_per_code));
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
d_gnss_synchro->Acq_samplestamp_samples = samp_count;
} }
lk.lock(); lk.lock();

View File

@ -95,8 +95,8 @@ private:
void dump_results(int effective_fft_size); void dump_results(int effective_fft_size);
float first_vs_second_peak_statistic(uint32_t& indext, int& doppler); float first_vs_second_peak_statistic(uint32_t& indext, int& doppler, unsigned int num_doppler_bins, int doppler_max, int doppler_step);
float max_to_input_power_statistic(uint32_t& indext, int& doppler, float input_power); float max_to_input_power_statistic(uint32_t& indext, int& doppler, float input_power, unsigned int num_doppler_bins, int doppler_max, int doppler_step);
Acq_Conf acq_parameters; Acq_Conf acq_parameters;
bool d_active; bool d_active;

View File

@ -41,8 +41,8 @@ Acq_Conf::Acq_Conf()
num_doppler_bins_step2 = 0; num_doppler_bins_step2 = 0;
doppler_step2 = 0.0; doppler_step2 = 0.0;
fs_in = 0; fs_in = 0;
samples_per_ms = 0; samples_per_ms = 0.0;
samples_per_code = 0; samples_per_code = 0.0;
bit_transition_flag = false; bit_transition_flag = false;
use_CFAR_algorithm_flag = false; use_CFAR_algorithm_flag = false;
dump = false; dump = false;

View File

@ -46,8 +46,8 @@ public:
unsigned int num_doppler_bins_step2; unsigned int num_doppler_bins_step2;
float doppler_step2; float doppler_step2;
long fs_in; long fs_in;
int samples_per_ms; float samples_per_ms;
int samples_per_code; float samples_per_code;
bool bit_transition_flag; bool bit_transition_flag;
bool use_CFAR_algorithm_flag; bool use_CFAR_algorithm_flag;
bool dump; bool dump;

View File

@ -2,6 +2,7 @@
* \file dll_pll_veml_tracking.cc * \file dll_pll_veml_tracking.cc
* \brief Implementation of a code DLL + carrier PLL tracking block. * \brief Implementation of a code DLL + carrier PLL tracking block.
* \author Antonio Ramos, 2018 antonio.ramosdet(at)gmail.com * \author Antonio Ramos, 2018 antonio.ramosdet(at)gmail.com
* Javier Arribas, 2018. jarribas(at)cttc.es
* *
* Code DLL + carrier PLL according to the algorithms described in: * Code DLL + carrier PLL according to the algorithms described in:
* [1] K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen, * [1] K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen,
@ -84,10 +85,12 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl
this->message_port_register_out(pmt::mp("events")); this->message_port_register_out(pmt::mp("events"));
this->set_relative_rate(1.0 / static_cast<double>(trk_parameters.vector_length)); this->set_relative_rate(1.0 / static_cast<double>(trk_parameters.vector_length));
// Telemetry bit synchronization message port input (mainly for GPS L1 CA)
this->message_port_register_in(pmt::mp("preamble_samplestamp"));
// initialize internal vars // initialize internal vars
d_veml = false; d_veml = false;
d_cloop = true; d_cloop = true;
d_synchonizing = false;
d_code_chip_rate = 0.0; d_code_chip_rate = 0.0;
d_secondary_code_length = 0; d_secondary_code_length = 0;
d_secondary_code_string = nullptr; d_secondary_code_string = nullptr;
@ -120,6 +123,30 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl
d_secondary = false; d_secondary = false;
trk_parameters.track_pilot = false; trk_parameters.track_pilot = false;
interchange_iq = false; interchange_iq = false;
// set the preamble
unsigned short int preambles_bits[GPS_CA_PREAMBLE_LENGTH_BITS] = GPS_PREAMBLE;
// preamble bits to sampled symbols
d_gps_l1ca_preambles_symbols = static_cast<int *>(volk_gnsssdr_malloc(GPS_CA_PREAMBLE_LENGTH_SYMBOLS * sizeof(int), volk_gnsssdr_get_alignment()));
int n = 0;
for (int i = 0; i < GPS_CA_PREAMBLE_LENGTH_BITS; i++)
{
for (unsigned int j = 0; j < GPS_CA_TELEMETRY_SYMBOLS_PER_BIT; j++)
{
if (preambles_bits[i] == 1)
{
d_gps_l1ca_preambles_symbols[n] = 1;
}
else
{
d_gps_l1ca_preambles_symbols[n] = -1;
}
n++;
}
}
d_symbol_history.resize(GPS_CA_PREAMBLE_LENGTH_SYMBOLS); // Change fixed buffer size
d_symbol_history.clear(); // Clear all the elements in the buffer
} }
else if (signal_type.compare("2S") == 0) else if (signal_type.compare("2S") == 0)
{ {
@ -521,7 +548,6 @@ void dll_pll_veml_tracking::start_tracking()
// enable tracking pull-in // enable tracking pull-in
d_state = 1; d_state = 1;
d_synchonizing = false;
d_cloop = true; d_cloop = true;
d_Prompt_buffer_deque.clear(); d_Prompt_buffer_deque.clear();
d_last_prompt = gr_complex(0.0, 0.0); d_last_prompt = gr_complex(0.0, 0.0);
@ -533,6 +559,11 @@ void dll_pll_veml_tracking::start_tracking()
dll_pll_veml_tracking::~dll_pll_veml_tracking() dll_pll_veml_tracking::~dll_pll_veml_tracking()
{ {
if (signal_type.compare("1C") == 0)
{
volk_gnsssdr_free(d_gps_l1ca_preambles_symbols);
}
if (d_dump_file.is_open()) if (d_dump_file.is_open())
{ {
try try
@ -1281,39 +1312,82 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused)
} }
else if (d_symbols_per_bit > 1) //Signal does not have secondary code. Search a bit transition by sign change else if (d_symbols_per_bit > 1) //Signal does not have secondary code. Search a bit transition by sign change
{ {
if (d_synchonizing) float current_tracking_time_s = static_cast<float>(d_sample_counter - d_acq_sample_stamp) / trk_parameters.fs_in;
if (current_tracking_time_s > 10)
{ {
if (d_Prompt->real() * d_last_prompt.real() > 0.0) d_symbol_history.push_back(d_Prompt->real());
//******* preamble correlation ********
int corr_value = 0;
if ((d_symbol_history.size() == GPS_CA_PREAMBLE_LENGTH_SYMBOLS)) // and (d_make_correlation or !d_flag_frame_sync))
{ {
d_current_symbol++; for (unsigned int i = 0; i < GPS_CA_PREAMBLE_LENGTH_SYMBOLS; i++)
{
if (d_symbol_history.at(i) < 0) // symbols clipping
{
corr_value -= d_gps_l1ca_preambles_symbols[i];
}
else
{
corr_value += d_gps_l1ca_preambles_symbols[i];
}
}
} }
else if (d_current_symbol > d_symbols_per_bit) if (corr_value == GPS_CA_PREAMBLE_LENGTH_SYMBOLS)
{ {
d_synchonizing = false; //std::cout << "Preamble detected at tracking!" << std::endl;
d_current_symbol = 1; next_state = true;
} }
else else
{ {
d_current_symbol = 1; next_state = false;
d_last_prompt = *d_Prompt;
} }
} }
else if (d_last_prompt.real() != 0.0)
{
d_current_symbol++;
if (d_current_symbol == d_symbols_per_bit) next_state = true;
}
else else
{ {
d_last_prompt = *d_Prompt; next_state = false;
d_synchonizing = true;
d_current_symbol = 1;
} }
} }
else else
{ {
next_state = true; next_state = true;
} }
// ########### Output the tracking results to Telemetry block ##########
if (interchange_iq)
{
if (trk_parameters.track_pilot)
{
// Note that data and pilot components are in quadrature. I and Q are interchanged
current_synchro_data.Prompt_I = static_cast<double>((*d_Prompt_Data).imag());
current_synchro_data.Prompt_Q = static_cast<double>((*d_Prompt_Data).real());
}
else
{
current_synchro_data.Prompt_I = static_cast<double>((*d_Prompt).imag());
current_synchro_data.Prompt_Q = static_cast<double>((*d_Prompt).real());
}
}
else
{
if (trk_parameters.track_pilot)
{
// Note that data and pilot components are in quadrature. I and Q are interchanged
current_synchro_data.Prompt_I = static_cast<double>((*d_Prompt_Data).real());
current_synchro_data.Prompt_Q = static_cast<double>((*d_Prompt_Data).imag());
}
else
{
current_synchro_data.Prompt_I = static_cast<double>((*d_Prompt).real());
current_synchro_data.Prompt_Q = static_cast<double>((*d_Prompt).imag());
}
}
current_synchro_data.Code_phase_samples = d_rem_code_phase_samples;
current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad;
current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz;
current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz;
current_synchro_data.Flag_valid_symbol_output = true;
current_synchro_data.correlation_length_ms = d_correlation_length_ms;
if (next_state) if (next_state)
{ // reset extended correlator { // reset extended correlator
d_VE_accu = gr_complex(0.0, 0.0); d_VE_accu = gr_complex(0.0, 0.0);
@ -1324,7 +1398,6 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused)
d_last_prompt = gr_complex(0.0, 0.0); d_last_prompt = gr_complex(0.0, 0.0);
d_Prompt_buffer_deque.clear(); d_Prompt_buffer_deque.clear();
d_current_symbol = 0; d_current_symbol = 0;
d_synchonizing = false;
if (d_enable_extended_integration) if (d_enable_extended_integration)
{ {

View File

@ -41,6 +41,7 @@
#include <string> #include <string>
#include <map> #include <map>
#include <queue> #include <queue>
#include <boost/circular_buffer.hpp>
class dll_pll_veml_tracking; class dll_pll_veml_tracking;
@ -69,6 +70,7 @@ private:
friend dll_pll_veml_tracking_sptr dll_pll_veml_make_tracking(const Dll_Pll_Conf &conf_); friend dll_pll_veml_tracking_sptr dll_pll_veml_make_tracking(const Dll_Pll_Conf &conf_);
dll_pll_veml_tracking(const Dll_Pll_Conf &conf_); dll_pll_veml_tracking(const Dll_Pll_Conf &conf_);
void msg_handler_preamble_index(pmt::pmt_t msg);
bool cn0_and_tracking_lock_status(double coh_integration_time_s); bool cn0_and_tracking_lock_status(double coh_integration_time_s);
bool acquire_secondary(); bool acquire_secondary();
@ -102,9 +104,12 @@ private:
std::string *d_secondary_code_string; std::string *d_secondary_code_string;
std::string signal_pretty_name; std::string signal_pretty_name;
uint64_t d_preamble_sample_counter;
int *d_gps_l1ca_preambles_symbols;
boost::circular_buffer<float> d_symbol_history;
//tracking state machine //tracking state machine
int d_state; int d_state;
bool d_synchonizing;
//Integration period in samples //Integration period in samples
int d_correlation_length_ms; int d_correlation_length_ms;
int d_n_correlator_taps; int d_n_correlator_taps;

View File

@ -54,9 +54,12 @@ DEFINE_string(acq_test_implementation, std::string("GPS_L1_CA_PCPS_Acquisition")
DEFINE_int32(acq_test_doppler_max, 5000, "Maximum Doppler, in Hz"); DEFINE_int32(acq_test_doppler_max, 5000, "Maximum Doppler, in Hz");
DEFINE_int32(acq_test_doppler_step, 125, "Doppler step, in Hz."); DEFINE_int32(acq_test_doppler_step, 125, "Doppler step, in Hz.");
DEFINE_int32(acq_test_coherent_time_ms, 1, "Acquisition coherent time, in ms"); DEFINE_int32(acq_test_coherent_time_ms, 1, "Acquisition coherent time, in ms");
DEFINE_int32(acq_test_max_dwells, 1, "Number of non-coherent integrations"); DEFINE_int32(acq_test_max_dwells, 1, "Number of non-coherent integrations.");
DEFINE_bool(acq_test_use_CFAR_algorithm, true, "Use CFAR algorithm"); DEFINE_bool(acq_test_use_CFAR_algorithm, true, "Use CFAR algorithm.");
DEFINE_bool(acq_test_bit_transition_flag, false, "Bit transition flag"); DEFINE_bool(acq_test_bit_transition_flag, false, "Bit transition flag.");
DEFINE_bool(acq_test_make_two_steps, false, "Perform second step in a thinner grid.");
DEFINE_int32(acq_test_second_nbins, 4, "If --acq_test_make_two_steps is set to true, this parameter sets the number of bins done in the acquisition refinement stage.");
DEFINE_int32(acq_test_second_doppler_step, 10, "If --acq_test_make_two_steps is set to true, this parameter sets the Doppler step applied in the acquisition refinement stage, in Hz.");
DEFINE_int32(acq_test_signal_duration_s, 2, "Generated signal duration, in s"); DEFINE_int32(acq_test_signal_duration_s, 2, "Generated signal duration, in s");
DEFINE_int32(acq_test_num_meas, 0, "Number of measurements per run. 0 means the complete file."); DEFINE_int32(acq_test_num_meas, 0, "Number of measurements per run. 0 means the complete file.");
@ -64,9 +67,9 @@ DEFINE_double(acq_test_cn0_init, 33.0, "Initial CN0, in dBHz.");
DEFINE_double(acq_test_cn0_final, 45.0, "Final CN0, in dBHz."); DEFINE_double(acq_test_cn0_final, 45.0, "Final CN0, in dBHz.");
DEFINE_double(acq_test_cn0_step, 3.0, "CN0 step, in dB."); DEFINE_double(acq_test_cn0_step, 3.0, "CN0 step, in dB.");
DEFINE_double(acq_test_threshold_init, 11.0, "Initial acquisition threshold"); DEFINE_double(acq_test_threshold_init, 3.0, "Initial acquisition threshold");
DEFINE_double(acq_test_threshold_final, 16.0, "Final acquisition threshold"); DEFINE_double(acq_test_threshold_final, 4.0, "Final acquisition threshold");
DEFINE_double(acq_test_threshold_step, 1.0, "Acquisition threshold step"); DEFINE_double(acq_test_threshold_step, 0.5, "Acquisition threshold step");
DEFINE_double(acq_test_pfa_init, 1e-5, "Set initial threshold via probability of false alarm. Disable with -1.0"); DEFINE_double(acq_test_pfa_init, 1e-5, "Set initial threshold via probability of false alarm. Disable with -1.0");
@ -165,17 +168,20 @@ protected:
signal_id = "1C"; signal_id = "1C";
system_id = 'G'; system_id = 'G';
coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms;
min_integration_ms = 1;
} }
else if (implementation.compare("GPS_L1_CA_PCPS_Acquisition_Fine_Doppler") == 0) else if (implementation.compare("GPS_L1_CA_PCPS_Acquisition_Fine_Doppler") == 0)
{ {
signal_id = "1C"; signal_id = "1C";
system_id = 'G'; system_id = 'G';
coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms;
min_integration_ms = 1;
} }
else if (implementation.compare("Galileo_E1_PCPS_Ambiguous_Acquisition") == 0) else if (implementation.compare("Galileo_E1_PCPS_Ambiguous_Acquisition") == 0)
{ {
signal_id = "1B"; signal_id = "1B";
system_id = 'E'; system_id = 'E';
min_integration_ms = 4;
if (FLAGS_acq_test_coherent_time_ms == 1) if (FLAGS_acq_test_coherent_time_ms == 1)
{ {
coherent_integration_time_ms = 4; coherent_integration_time_ms = 4;
@ -190,12 +196,14 @@ protected:
signal_id = "1G"; signal_id = "1G";
system_id = 'R'; system_id = 'R';
coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms;
min_integration_ms = 1;
} }
else if (implementation.compare("GLONASS_L2_CA_PCPS_Acquisition") == 0) else if (implementation.compare("GLONASS_L2_CA_PCPS_Acquisition") == 0)
{ {
signal_id = "2G"; signal_id = "2G";
system_id = 'R'; system_id = 'R';
coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms;
min_integration_ms = 1;
} }
else if (implementation.compare("GPS_L2_M_PCPS_Acquisition") == 0) else if (implementation.compare("GPS_L2_M_PCPS_Acquisition") == 0)
{ {
@ -209,12 +217,14 @@ protected:
{ {
coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms;
} }
min_integration_ms = 20;
} }
else if (implementation.compare("Galileo_E5a_Pcps_Acquisition") == 0) else if (implementation.compare("Galileo_E5a_Pcps_Acquisition") == 0)
{ {
signal_id = "5X"; signal_id = "5X";
system_id = 'E'; system_id = 'E';
coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms;
min_integration_ms = 1;
} }
else if (implementation.compare("GPS_L5i_PCPS_Acquisition") == 0) else if (implementation.compare("GPS_L5i_PCPS_Acquisition") == 0)
{ {
@ -227,6 +237,7 @@ protected:
signal_id = "1C"; signal_id = "1C";
system_id = 'G'; system_id = 'G';
coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms;
min_integration_ms = 1;
} }
init(); init();
@ -327,6 +338,7 @@ protected:
std::string path_str = "./acq-perf-test"; std::string path_str = "./acq-perf-test";
int num_thresholds; int num_thresholds;
unsigned int min_integration_ms;
std::vector<std::vector<float>> Pd; std::vector<std::vector<float>> Pd;
std::vector<std::vector<float>> Pfa; std::vector<std::vector<float>> Pfa;
@ -492,9 +504,17 @@ int AcquisitionPerformanceTest::configure_receiver(double cn0, float pfa, unsign
config->set_property("Acquisition.repeat_satellite", "true"); config->set_property("Acquisition.repeat_satellite", "true");
config->set_property("Acquisition.blocking", "true"); config->set_property("Acquisition.blocking", "true");
config->set_property("Acquisition.make_two_steps", "false"); if (FLAGS_acq_test_make_two_steps)
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.make_two_steps", "true");
config->set_property("Acquisition.second_nbins", std::to_string(FLAGS_acq_test_second_nbins));
config->set_property("Acquisition.second_doppler_step", std::to_string(FLAGS_acq_test_second_doppler_step));
}
else
{
config->set_property("Acquisition.make_two_steps", "false");
}
config->set_property("Acquisition.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); std::string dump_file = path_str + std::string("/acquisition_") + std::to_string(cn0) + "_" + std::to_string(iter) + "_" + std::to_string(pfa);
@ -804,9 +824,27 @@ TEST_F(AcquisitionPerformanceTest, ROC)
double coh_time_ms = config->property("Acquisition.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; std::cout << "Num executions: " << num_executions << std::endl;
unsigned int fft_size = 0;
unsigned int d_consumed_samples = coh_time_ms * config->property("GNSS-SDR.internal_fs_sps", 0) * 0.001; // * (config->property("Acquisition.bit_transition_flag", false) ? 2 : 1);
if (coh_time_ms == min_integration_ms)
{
fft_size = d_consumed_samples;
}
else
{
fft_size = d_consumed_samples * 2;
}
for (int execution = 1; execution <= num_executions; execution++) for (int execution = 1; execution <= num_executions; 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); acquisition_dump_reader acq_dump(basename,
observed_satellite,
config->property("Acquisition.doppler_max", 0),
config->property("Acquisition.doppler_step", 0),
fft_size,
ch,
execution);
acq_dump.read_binary_acq(); acq_dump.read_binary_acq();
if (acq_dump.positive_acq) if (acq_dump.positive_acq)
{ {

View File

@ -341,7 +341,7 @@ void GlonassL1CaPcpsAcquisitionGSoC2017Test::config_2()
std::to_string(integration_time_ms)); std::to_string(integration_time_ms));
config->set_property("Acquisition.max_dwells", "1"); config->set_property("Acquisition.max_dwells", "1");
config->set_property("Acquisition.implementation", "GLONASS_L1_CA_PCPS_Acquisition"); config->set_property("Acquisition.implementation", "GLONASS_L1_CA_PCPS_Acquisition");
config->set_property("Acquisition.pfa", "0.1"); //config->set_property("Acquisition.pfa", "0.1");
config->set_property("Acquisition.doppler_max", "10000"); config->set_property("Acquisition.doppler_max", "10000");
config->set_property("Acquisition.doppler_step", "250"); config->set_property("Acquisition.doppler_step", "250");
config->set_property("Acquisition.bit_transition_flag", "false"); config->set_property("Acquisition.bit_transition_flag", "false");
@ -496,7 +496,7 @@ TEST_F(GlonassL1CaPcpsAcquisitionGSoC2017Test, ValidationOfResults)
}) << "Failure setting doppler_step."; }) << "Failure setting doppler_step.";
ASSERT_NO_THROW({ ASSERT_NO_THROW({
acquisition->set_threshold(0.5); acquisition->set_threshold(0.05);
}) << "Failure setting threshold."; }) << "Failure setting threshold.";
ASSERT_NO_THROW({ ASSERT_NO_THROW({