mirror of
				https://github.com/gnss-sdr/gnss-sdr
				synced 2025-11-04 09:13:05 +00:00 
			
		
		
		
	Add coherent integration for GPS L2C, L5 and Galileo E1
This commit is contained in:
		@@ -62,12 +62,13 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition(
 | 
			
		||||
    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_ = 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_;
 | 
			
		||||
    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";
 | 
			
		||||
            acq_parameters.sampled_ms = 4;
 | 
			
		||||
            acq_parameters.sampled_ms = acq_parameters.ms_per_code;
 | 
			
		||||
        }
 | 
			
		||||
    bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
 | 
			
		||||
    acq_parameters.bit_transition_flag = bit_transition_flag_;
 | 
			
		||||
 
 | 
			
		||||
@@ -103,6 +103,7 @@ GalileoE5aPcpsAcquisition::GalileoE5aPcpsAcquisition(ConfigurationInterface* con
 | 
			
		||||
    acq_parameters.it_size = item_size_;
 | 
			
		||||
    acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
 | 
			
		||||
    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.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
 | 
			
		||||
    acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
 | 
			
		||||
 
 | 
			
		||||
@@ -101,6 +101,7 @@ GlonassL1CaPcpsAcquisition::GlonassL1CaPcpsAcquisition(
 | 
			
		||||
    acq_parameters.it_size = item_size_;
 | 
			
		||||
    acq_parameters.sampled_ms = sampled_ms_;
 | 
			
		||||
    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.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
 | 
			
		||||
    acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
 | 
			
		||||
 
 | 
			
		||||
@@ -100,6 +100,7 @@ GlonassL2CaPcpsAcquisition::GlonassL2CaPcpsAcquisition(
 | 
			
		||||
    acq_parameters.it_size = item_size_;
 | 
			
		||||
    acq_parameters.sampled_ms = sampled_ms_;
 | 
			
		||||
    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.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
 | 
			
		||||
    acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
 | 
			
		||||
 
 | 
			
		||||
@@ -71,6 +71,7 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition(
 | 
			
		||||
    acq_parameters.doppler_max = doppler_max_;
 | 
			
		||||
    sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 1);
 | 
			
		||||
    acq_parameters.sampled_ms = sampled_ms_;
 | 
			
		||||
    acq_parameters.ms_per_code = 1;
 | 
			
		||||
    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
 | 
			
		||||
 
 | 
			
		||||
@@ -79,21 +79,17 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition(
 | 
			
		||||
    acq_parameters.dump_filename = dump_filename_;
 | 
			
		||||
    //--- Find number of samples per spreading code -------------------------
 | 
			
		||||
    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)
 | 
			
		||||
    acq_parameters.ms_per_code = 20;
 | 
			
		||||
    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";
 | 
			
		||||
            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_;
 | 
			
		||||
 | 
			
		||||
    if (bit_transition_flag_)
 | 
			
		||||
        {
 | 
			
		||||
            vector_length_ *= 2;
 | 
			
		||||
        }
 | 
			
		||||
    vector_length_ = acq_parameters.sampled_ms * acq_parameters.samples_per_ms * (acq_parameters.bit_transition_flag ? 2 : 1);
 | 
			
		||||
 | 
			
		||||
    code_ = new gr_complex[vector_length_];
 | 
			
		||||
 | 
			
		||||
@@ -129,6 +125,7 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition(
 | 
			
		||||
    threshold_ = 0.0;
 | 
			
		||||
    doppler_step_ = 0;
 | 
			
		||||
    gnss_synchro_ = 0;
 | 
			
		||||
    num_codes_ = acq_parameters.sampled_ms / acq_parameters.ms_per_code;
 | 
			
		||||
    if (in_streams_ > 1)
 | 
			
		||||
        {
 | 
			
		||||
            LOG(ERROR) << "This implementation only supports one input stream";
 | 
			
		||||
@@ -217,9 +214,18 @@ void GpsL2MPcpsAcquisition::init()
 | 
			
		||||
 | 
			
		||||
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_);
 | 
			
		||||
    delete[] code;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -160,6 +160,7 @@ private:
 | 
			
		||||
    std::string role_;
 | 
			
		||||
    unsigned int in_streams_;
 | 
			
		||||
    unsigned int out_streams_;
 | 
			
		||||
    unsigned int num_codes_;
 | 
			
		||||
 | 
			
		||||
    float calculate_threshold(float pfa);
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -98,8 +98,10 @@ GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition(
 | 
			
		||||
        }
 | 
			
		||||
    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.ms_per_code = 1;
 | 
			
		||||
    acq_parameters.it_size = item_size_;
 | 
			
		||||
    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.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
 | 
			
		||||
    acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
 | 
			
		||||
@@ -206,9 +208,18 @@ void GpsL5iPcpsAcquisition::init()
 | 
			
		||||
 | 
			
		||||
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_);
 | 
			
		||||
    delete[] code;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -158,6 +158,7 @@ private:
 | 
			
		||||
    std::complex<float>* code_;
 | 
			
		||||
    Gnss_Synchro* gnss_synchro_;
 | 
			
		||||
    std::string role_;
 | 
			
		||||
    unsigned int num_codes_;
 | 
			
		||||
    unsigned int in_streams_;
 | 
			
		||||
    unsigned int out_streams_;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -65,7 +65,7 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu
 | 
			
		||||
    d_old_freq = 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);
 | 
			
		||||
    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;
 | 
			
		||||
        }
 | 
			
		||||
@@ -205,7 +205,7 @@ void pcps_acquisition::set_local_code(std::complex<float>* code)
 | 
			
		||||
        }
 | 
			
		||||
    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);
 | 
			
		||||
                }
 | 
			
		||||
 
 | 
			
		||||
@@ -35,6 +35,7 @@ Acq_Conf::Acq_Conf()
 | 
			
		||||
{
 | 
			
		||||
    /* PCPS acquisition configuration */
 | 
			
		||||
    sampled_ms = 0;
 | 
			
		||||
    ms_per_code = 0;
 | 
			
		||||
    max_dwells = 0;
 | 
			
		||||
    samples_per_chip = 0;
 | 
			
		||||
    doppler_max = 0;
 | 
			
		||||
 
 | 
			
		||||
@@ -40,6 +40,7 @@ class Acq_Conf
 | 
			
		||||
public:
 | 
			
		||||
    /* PCPS Acquisition configuration */
 | 
			
		||||
    unsigned int sampled_ms;
 | 
			
		||||
    unsigned int ms_per_code;
 | 
			
		||||
    unsigned int samples_per_chip;
 | 
			
		||||
    unsigned int max_dwells;
 | 
			
		||||
    unsigned int doppler_max;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user