mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2024-09-12 07:19:50 +00:00
Merge branch 'next' of https://github.com/gnss-sdr/gnss-sdr into next
This commit is contained in:
commit
b575a3bead
@ -64,6 +64,11 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition(
|
||||
acq_parameters.doppler_max = doppler_max_;
|
||||
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 4);
|
||||
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);
|
||||
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
|
||||
@ -80,9 +85,10 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition(
|
||||
acq_parameters.dump_filename = dump_filename_;
|
||||
//--- 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)));
|
||||
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_code = acq_parameters.samples_per_ms * static_cast<float>(Galileo_E1_CODE_PERIOD_MS);
|
||||
vector_length_ = sampled_ms_ * samples_per_ms;
|
||||
|
||||
if (bit_transition_flag_)
|
||||
|
@ -101,9 +101,9 @@ GalileoE5aPcpsAcquisition::GalileoE5aPcpsAcquisition(ConfigurationInterface* con
|
||||
LOG(WARNING) << item_type_ << " unknown acquisition item type";
|
||||
}
|
||||
acq_parameters.it_size = item_size_;
|
||||
acq_parameters.samples_per_code = code_length_;
|
||||
acq_parameters.samples_per_ms = code_length_;
|
||||
acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
|
||||
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.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
|
||||
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
|
||||
|
@ -100,8 +100,8 @@ GlonassL1CaPcpsAcquisition::GlonassL1CaPcpsAcquisition(
|
||||
}
|
||||
acq_parameters.it_size = item_size_;
|
||||
acq_parameters.sampled_ms = sampled_ms_;
|
||||
acq_parameters.samples_per_ms = code_length_;
|
||||
acq_parameters.samples_per_code = code_length_;
|
||||
acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
|
||||
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.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
|
||||
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
|
||||
|
@ -99,8 +99,8 @@ GlonassL2CaPcpsAcquisition::GlonassL2CaPcpsAcquisition(
|
||||
}
|
||||
acq_parameters.it_size = item_size_;
|
||||
acq_parameters.sampled_ms = sampled_ms_;
|
||||
acq_parameters.samples_per_ms = code_length_;
|
||||
acq_parameters.samples_per_code = code_length_;
|
||||
acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
|
||||
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.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
|
||||
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
|
||||
|
@ -102,8 +102,8 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition(
|
||||
{
|
||||
item_size_ = sizeof(gr_complex);
|
||||
}
|
||||
acq_parameters.samples_per_ms = code_length_;
|
||||
acq_parameters.samples_per_code = code_length_;
|
||||
acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
|
||||
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.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false);
|
||||
acquisition_ = pcps_make_acquisition(acq_parameters);
|
||||
|
@ -78,7 +78,15 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition(
|
||||
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
|
||||
acq_parameters.dump_filename = dump_filename_;
|
||||
//--- 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_;
|
||||
|
||||
@ -97,10 +105,10 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition(
|
||||
{
|
||||
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.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", false);
|
||||
|
@ -96,10 +96,10 @@ GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition(
|
||||
{
|
||||
item_size_ = sizeof(gr_complex);
|
||||
}
|
||||
acq_parameters.samples_per_code = code_length_;
|
||||
acq_parameters.samples_per_ms = code_length_;
|
||||
acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
|
||||
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.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.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
|
||||
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
|
||||
|
@ -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;
|
||||
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);
|
||||
|
||||
// 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);
|
||||
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;
|
||||
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);
|
||||
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
|
||||
// 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;
|
||||
|
||||
// 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);
|
||||
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;
|
||||
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
|
||||
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);
|
||||
|
||||
// initialize acquisition algorithm
|
||||
float magt = 0.0;
|
||||
int doppler = 0;
|
||||
uint32_t indext = 0;
|
||||
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
|
||||
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;
|
||||
@ -629,13 +642,13 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count)
|
||||
// Compute the test statistic
|
||||
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
|
||||
{
|
||||
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_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++)
|
||||
{
|
||||
// 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);
|
||||
|
||||
// 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
|
||||
d_ifft->execute();
|
||||
|
||||
// Search maximum
|
||||
size_t offset = (acq_parameters.bit_transition_flag ? effective_fft_size : 0);
|
||||
volk_32fc_magnitude_squared_32f(d_magnitude, d_ifft->get_outbuf() + offset, effective_fft_size);
|
||||
volk_gnsssdr_32f_index_max_32u(&indext, d_magnitude, effective_fft_size);
|
||||
magt = d_magnitude[indext];
|
||||
|
||||
if (d_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 (!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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
// 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();
|
||||
|
@ -95,8 +95,8 @@ 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);
|
||||
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, unsigned int num_doppler_bins, int doppler_max, int doppler_step);
|
||||
|
||||
Acq_Conf acq_parameters;
|
||||
bool d_active;
|
||||
|
@ -41,8 +41,8 @@ Acq_Conf::Acq_Conf()
|
||||
num_doppler_bins_step2 = 0;
|
||||
doppler_step2 = 0.0;
|
||||
fs_in = 0;
|
||||
samples_per_ms = 0;
|
||||
samples_per_code = 0;
|
||||
samples_per_ms = 0.0;
|
||||
samples_per_code = 0.0;
|
||||
bit_transition_flag = false;
|
||||
use_CFAR_algorithm_flag = false;
|
||||
dump = false;
|
||||
|
@ -46,8 +46,8 @@ public:
|
||||
unsigned int num_doppler_bins_step2;
|
||||
float doppler_step2;
|
||||
long fs_in;
|
||||
int samples_per_ms;
|
||||
int samples_per_code;
|
||||
float samples_per_ms;
|
||||
float samples_per_code;
|
||||
bool bit_transition_flag;
|
||||
bool use_CFAR_algorithm_flag;
|
||||
bool dump;
|
||||
|
@ -2,6 +2,7 @@
|
||||
* \file dll_pll_veml_tracking.cc
|
||||
* \brief Implementation of a code DLL + carrier PLL tracking block.
|
||||
* \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:
|
||||
* [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->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
|
||||
d_veml = false;
|
||||
d_cloop = true;
|
||||
d_synchonizing = false;
|
||||
d_code_chip_rate = 0.0;
|
||||
d_secondary_code_length = 0;
|
||||
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;
|
||||
trk_parameters.track_pilot = 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)
|
||||
{
|
||||
@ -521,7 +548,6 @@ void dll_pll_veml_tracking::start_tracking()
|
||||
|
||||
// enable tracking pull-in
|
||||
d_state = 1;
|
||||
d_synchonizing = false;
|
||||
d_cloop = true;
|
||||
d_Prompt_buffer_deque.clear();
|
||||
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()
|
||||
{
|
||||
if (signal_type.compare("1C") == 0)
|
||||
{
|
||||
volk_gnsssdr_free(d_gps_l1ca_preambles_symbols);
|
||||
}
|
||||
|
||||
if (d_dump_file.is_open())
|
||||
{
|
||||
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
|
||||
{
|
||||
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;
|
||||
d_current_symbol = 1;
|
||||
//std::cout << "Preamble detected at tracking!" << std::endl;
|
||||
next_state = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
d_current_symbol = 1;
|
||||
d_last_prompt = *d_Prompt;
|
||||
next_state = false;
|
||||
}
|
||||
}
|
||||
else if (d_last_prompt.real() != 0.0)
|
||||
{
|
||||
d_current_symbol++;
|
||||
if (d_current_symbol == d_symbols_per_bit) next_state = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
d_last_prompt = *d_Prompt;
|
||||
d_synchonizing = true;
|
||||
d_current_symbol = 1;
|
||||
next_state = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
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)
|
||||
{ // reset extended correlator
|
||||
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_Prompt_buffer_deque.clear();
|
||||
d_current_symbol = 0;
|
||||
d_synchonizing = false;
|
||||
|
||||
if (d_enable_extended_integration)
|
||||
{
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <boost/circular_buffer.hpp>
|
||||
|
||||
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_);
|
||||
|
||||
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 acquire_secondary();
|
||||
@ -102,9 +104,12 @@ private:
|
||||
std::string *d_secondary_code_string;
|
||||
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
|
||||
int d_state;
|
||||
bool d_synchonizing;
|
||||
//Integration period in samples
|
||||
int d_correlation_length_ms;
|
||||
int d_n_correlator_taps;
|
||||
|
@ -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_step, 125, "Doppler step, in Hz.");
|
||||
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_bool(acq_test_use_CFAR_algorithm, true, "Use CFAR algorithm");
|
||||
DEFINE_bool(acq_test_bit_transition_flag, false, "Bit transition flag");
|
||||
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_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_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_step, 3.0, "CN0 step, in dB.");
|
||||
|
||||
DEFINE_double(acq_test_threshold_init, 11.0, "Initial acquisition threshold");
|
||||
DEFINE_double(acq_test_threshold_final, 16.0, "Final acquisition threshold");
|
||||
DEFINE_double(acq_test_threshold_step, 1.0, "Acquisition threshold step");
|
||||
DEFINE_double(acq_test_threshold_init, 3.0, "Initial acquisition threshold");
|
||||
DEFINE_double(acq_test_threshold_final, 4.0, "Final acquisition threshold");
|
||||
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");
|
||||
|
||||
@ -165,17 +168,20 @@ protected:
|
||||
signal_id = "1C";
|
||||
system_id = 'G';
|
||||
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)
|
||||
{
|
||||
signal_id = "1C";
|
||||
system_id = 'G';
|
||||
coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms;
|
||||
min_integration_ms = 1;
|
||||
}
|
||||
else if (implementation.compare("Galileo_E1_PCPS_Ambiguous_Acquisition") == 0)
|
||||
{
|
||||
signal_id = "1B";
|
||||
system_id = 'E';
|
||||
min_integration_ms = 4;
|
||||
if (FLAGS_acq_test_coherent_time_ms == 1)
|
||||
{
|
||||
coherent_integration_time_ms = 4;
|
||||
@ -190,12 +196,14 @@ protected:
|
||||
signal_id = "1G";
|
||||
system_id = 'R';
|
||||
coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms;
|
||||
min_integration_ms = 1;
|
||||
}
|
||||
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;
|
||||
min_integration_ms = 1;
|
||||
}
|
||||
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;
|
||||
}
|
||||
min_integration_ms = 20;
|
||||
}
|
||||
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;
|
||||
min_integration_ms = 1;
|
||||
}
|
||||
else if (implementation.compare("GPS_L5i_PCPS_Acquisition") == 0)
|
||||
{
|
||||
@ -227,6 +237,7 @@ protected:
|
||||
signal_id = "1C";
|
||||
system_id = 'G';
|
||||
coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms;
|
||||
min_integration_ms = 1;
|
||||
}
|
||||
|
||||
init();
|
||||
@ -327,6 +338,7 @@ protected:
|
||||
std::string path_str = "./acq-perf-test";
|
||||
|
||||
int num_thresholds;
|
||||
unsigned int min_integration_ms;
|
||||
|
||||
std::vector<std::vector<float>> Pd;
|
||||
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.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));
|
||||
if (FLAGS_acq_test_make_two_steps)
|
||||
{
|
||||
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");
|
||||
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);
|
||||
|
||||
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++)
|
||||
{
|
||||
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();
|
||||
if (acq_dump.positive_acq)
|
||||
{
|
||||
|
@ -341,7 +341,7 @@ void GlonassL1CaPcpsAcquisitionGSoC2017Test::config_2()
|
||||
std::to_string(integration_time_ms));
|
||||
config->set_property("Acquisition.max_dwells", "1");
|
||||
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_step", "250");
|
||||
config->set_property("Acquisition.bit_transition_flag", "false");
|
||||
@ -496,7 +496,7 @@ TEST_F(GlonassL1CaPcpsAcquisitionGSoC2017Test, ValidationOfResults)
|
||||
}) << "Failure setting doppler_step.";
|
||||
|
||||
ASSERT_NO_THROW({
|
||||
acquisition->set_threshold(0.5);
|
||||
acquisition->set_threshold(0.05);
|
||||
}) << "Failure setting threshold.";
|
||||
|
||||
ASSERT_NO_THROW({
|
||||
|
Loading…
Reference in New Issue
Block a user