1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-12-15 20:50:33 +00:00

Add coherent integration for GPS L2C, L5 and Galileo E1

This commit is contained in:
Carles Fernandez 2018-07-15 04:12:20 +02:00
parent 1d728909d4
commit ee90b739b5
No known key found for this signature in database
GPG Key ID: 4C583C52B0C3877D
12 changed files with 43 additions and 17 deletions

View File

@ -62,12 +62,13 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition(
doppler_max_ = configuration_->property(role + ".doppler_max", 5000); doppler_max_ = configuration_->property(role + ".doppler_max", 5000);
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max; if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max;
acq_parameters.doppler_max = doppler_max_; acq_parameters.doppler_max = doppler_max_;
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 4); acq_parameters.ms_per_code = 4;
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", acq_parameters.ms_per_code);
acq_parameters.sampled_ms = sampled_ms_; acq_parameters.sampled_ms = sampled_ms_;
if ((acq_parameters.sampled_ms % 4) != 0) if ((acq_parameters.sampled_ms % acq_parameters.ms_per_code) != 0)
{ {
LOG(WARNING) << "Parameter coherent_integration_time_ms should be a multiple of 4. Setting it to 4"; LOG(WARNING) << "Parameter coherent_integration_time_ms should be a multiple of 4. Setting it to 4";
acq_parameters.sampled_ms = 4; acq_parameters.sampled_ms = acq_parameters.ms_per_code;
} }
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_;

View File

@ -103,6 +103,7 @@ GalileoE5aPcpsAcquisition::GalileoE5aPcpsAcquisition(ConfigurationInterface* con
acq_parameters.it_size = item_size_; acq_parameters.it_size = item_size_;
acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001; acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
acq_parameters.sampled_ms = sampled_ms_; acq_parameters.sampled_ms = sampled_ms_;
acq_parameters.ms_per_code = 1;
acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GALILEO_E5a_CODE_PERIOD_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);

View File

@ -101,6 +101,7 @@ 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 = static_cast<float>(fs_in_) * 0.001; acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
acq_parameters.ms_per_code = 1;
acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GLONASS_L1_CA_CODE_PERIOD * 1000.0); 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);

View File

@ -100,6 +100,7 @@ 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 = static_cast<float>(fs_in_) * 0.001; acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
acq_parameters.ms_per_code = 1;
acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GLONASS_L2_CA_CODE_PERIOD * 1000.0); 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);

View File

@ -71,6 +71,7 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition(
acq_parameters.doppler_max = doppler_max_; acq_parameters.doppler_max = doppler_max_;
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 1); sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 1);
acq_parameters.sampled_ms = sampled_ms_; acq_parameters.sampled_ms = sampled_ms_;
acq_parameters.ms_per_code = 1;
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

View File

@ -79,21 +79,17 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition(
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 -------------------------
acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001; acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
acq_parameters.sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 20); acq_parameters.ms_per_code = 20;
if ((acq_parameters.sampled_ms % 20) != 0) acq_parameters.sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", acq_parameters.ms_per_code);
if ((acq_parameters.sampled_ms % acq_parameters.ms_per_code) != 0)
{ {
LOG(WARNING) << "Parameter coherent_integration_time_ms should be a multiple of 20. Setting it to 20"; LOG(WARNING) << "Parameter coherent_integration_time_ms should be a multiple of 20. Setting it to 20";
acq_parameters.sampled_ms = 20; acq_parameters.sampled_ms = acq_parameters.ms_per_code;
} }
code_length_ = acq_parameters.sampled_ms * acq_parameters.samples_per_ms * (acq_parameters.bit_transition_flag ? 2 : 1); code_length_ = acq_parameters.ms_per_code * acq_parameters.samples_per_ms;
vector_length_ = code_length_; vector_length_ = acq_parameters.sampled_ms * acq_parameters.samples_per_ms * (acq_parameters.bit_transition_flag ? 2 : 1);
if (bit_transition_flag_)
{
vector_length_ *= 2;
}
code_ = new gr_complex[vector_length_]; code_ = new gr_complex[vector_length_];
@ -129,6 +125,7 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition(
threshold_ = 0.0; threshold_ = 0.0;
doppler_step_ = 0; doppler_step_ = 0;
gnss_synchro_ = 0; gnss_synchro_ = 0;
num_codes_ = acq_parameters.sampled_ms / acq_parameters.ms_per_code;
if (in_streams_ > 1) if (in_streams_ > 1)
{ {
LOG(ERROR) << "This implementation only supports one input stream"; LOG(ERROR) << "This implementation only supports one input stream";
@ -217,9 +214,18 @@ void GpsL2MPcpsAcquisition::init()
void GpsL2MPcpsAcquisition::set_local_code() void GpsL2MPcpsAcquisition::set_local_code()
{ {
gps_l2c_m_code_gen_complex_sampled(code_, gnss_synchro_->PRN, fs_in_); std::complex<float>* code = new std::complex<float>[code_length_];
gps_l2c_m_code_gen_complex_sampled(code, gnss_synchro_->PRN, fs_in_);
for (unsigned int i = 0; i < num_codes_; i++)
{
memcpy(&(code_[i * code_length_]), code,
sizeof(gr_complex) * code_length_);
}
acquisition_->set_local_code(code_); acquisition_->set_local_code(code_);
delete[] code;
} }

View File

@ -160,6 +160,7 @@ private:
std::string role_; std::string role_;
unsigned int in_streams_; unsigned int in_streams_;
unsigned int out_streams_; unsigned int out_streams_;
unsigned int num_codes_;
float calculate_threshold(float pfa); float calculate_threshold(float pfa);
}; };

View File

@ -98,8 +98,10 @@ GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition(
} }
acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001; 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.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GPS_L5i_PERIOD * 1000.0);
acq_parameters.ms_per_code = 1;
acq_parameters.it_size = item_size_; acq_parameters.it_size = item_size_;
acq_parameters.sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 1); acq_parameters.sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 1);
num_codes_ = acq_parameters.sampled_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);
@ -206,9 +208,18 @@ void GpsL5iPcpsAcquisition::init()
void GpsL5iPcpsAcquisition::set_local_code() void GpsL5iPcpsAcquisition::set_local_code()
{ {
gps_l5i_code_gen_complex_sampled(code_, gnss_synchro_->PRN, fs_in_); std::complex<float>* code = new std::complex<float>[code_length_];
gps_l5i_code_gen_complex_sampled(code, gnss_synchro_->PRN, fs_in_);
for (unsigned int i = 0; i < num_codes_; i++)
{
memcpy(&(code_[i * code_length_]), code,
sizeof(gr_complex) * code_length_);
}
acquisition_->set_local_code(code_); acquisition_->set_local_code(code_);
delete[] code;
} }

View File

@ -158,6 +158,7 @@ private:
std::complex<float>* code_; std::complex<float>* code_;
Gnss_Synchro* gnss_synchro_; Gnss_Synchro* gnss_synchro_;
std::string role_; std::string role_;
unsigned int num_codes_;
unsigned int in_streams_; unsigned int in_streams_;
unsigned int out_streams_; unsigned int out_streams_;

View File

@ -65,7 +65,7 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu
d_old_freq = 0; d_old_freq = 0;
d_num_noncoherent_integrations_counter = 0; d_num_noncoherent_integrations_counter = 0;
d_consumed_samples = acq_parameters.sampled_ms * acq_parameters.samples_per_ms * (acq_parameters.bit_transition_flag ? 2 : 1); 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)) // if (acq_parameters.sampled_ms == acq_parameters.ms_per_code)
{ {
d_fft_size = d_consumed_samples; d_fft_size = d_consumed_samples;
} }
@ -205,7 +205,7 @@ void pcps_acquisition::set_local_code(std::complex<float>* code)
} }
else else
{ {
if (acq_parameters.sampled_ms == (acq_parameters.samples_per_code / acq_parameters.samples_per_ms)) if (acq_parameters.sampled_ms == acq_parameters.ms_per_code)
{ {
memcpy(d_fft_if->get_inbuf(), code, sizeof(gr_complex) * d_consumed_samples); memcpy(d_fft_if->get_inbuf(), code, sizeof(gr_complex) * d_consumed_samples);
} }

View File

@ -35,6 +35,7 @@ Acq_Conf::Acq_Conf()
{ {
/* PCPS acquisition configuration */ /* PCPS acquisition configuration */
sampled_ms = 0; sampled_ms = 0;
ms_per_code = 0;
max_dwells = 0; max_dwells = 0;
samples_per_chip = 0; samples_per_chip = 0;
doppler_max = 0; doppler_max = 0;

View File

@ -40,6 +40,7 @@ class Acq_Conf
public: public:
/* PCPS Acquisition configuration */ /* PCPS Acquisition configuration */
unsigned int sampled_ms; unsigned int sampled_ms;
unsigned int ms_per_code;
unsigned int samples_per_chip; unsigned int samples_per_chip;
unsigned int max_dwells; unsigned int max_dwells;
unsigned int doppler_max; unsigned int doppler_max;