diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.cc index 94558ef76..9f2b53e59 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.cc @@ -28,7 +28,7 @@ * along with GNSS-SDR. If not, see . * * ------------------------------------------------------------------------- - */ + */ #include "galileo_e1_pcps_ambiguous_acquisition_fpga.h" #include "Galileo_E1.h" @@ -62,13 +62,13 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga( // item_type_ = configuration_->property(role + ".item_type", default_item_type); - int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 4000000); - int64_t fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); + int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 4000000); + int64_t fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); float downsampling_factor = configuration_->property(role + ".downsampling_factor", 4.0); acq_parameters.downsampling_factor = downsampling_factor; - fs_in = fs_in/downsampling_factor; + fs_in = fs_in / downsampling_factor; acq_parameters.fs_in = fs_in; @@ -85,7 +85,7 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga( acq_parameters.code_length = code_length; // The FPGA can only use FFT lengths that are a power of two. - float nbits = ceilf(log2f((float)code_length*2)); + float nbits = ceilf(log2f((float)code_length * 2)); uint32_t nsamples_total = pow(2, nbits); uint32_t select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", 0); @@ -107,58 +107,56 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga( for (uint32_t PRN = 1; PRN <= GALILEO_E1_NUMBER_OF_CODES; PRN++) { + bool cboc = false; // cboc is set to 0 when using the FPGA - bool cboc = false; // cboc is set to 0 when using the FPGA + if (acquire_pilot_ == true) + { + //set local signal generator to Galileo E1 pilot component (1C) + char pilot_signal[3] = "1C"; + galileo_e1_code_gen_complex_sampled(code, pilot_signal, + cboc, PRN, fs_in, 0, false); + } + else + { + char data_signal[3] = "1B"; + galileo_e1_code_gen_complex_sampled(code, data_signal, + cboc, PRN, fs_in, 0, false); + } - if (acquire_pilot_ == true) - { - //set local signal generator to Galileo E1 pilot component (1C) - char pilot_signal[3] = "1C"; - galileo_e1_code_gen_complex_sampled(code, pilot_signal, - cboc, PRN, fs_in, 0, false); - } - else - { - char data_signal[3] = "1B"; - galileo_e1_code_gen_complex_sampled(code, data_signal, - cboc, PRN, fs_in, 0, false); - } - - for (uint32_t s = code_length; s < 2*code_length; s++) - { - code[s] = code[s - code_length]; - } + for (uint32_t s = code_length; s < 2 * code_length; s++) + { + code[s] = code[s - code_length]; + } - // fill in zero padding - for (uint32_t s = 2*code_length; s < nsamples_total; s++) - { - code[s] = std::complex(static_cast(0,0)); - } + // fill in zero padding + for (uint32_t s = 2 * code_length; s < nsamples_total; s++) + { + code[s] = std::complex(static_cast(0, 0)); + } - memcpy(fft_if->get_inbuf(), code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer - fft_if->execute(); // Run the FFT of local code - volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values - - // normalize the code - max = 0; // initialize maximum value - for (uint32_t i = 0; i < nsamples_total; i++) // search for maxima - { - if (std::abs(fft_codes_padded[i].real()) > max) - { - max = std::abs(fft_codes_padded[i].real()); - } - if (std::abs(fft_codes_padded[i].imag()) > max) - { - max = std::abs(fft_codes_padded[i].imag()); - } - } - for (uint32_t i = 0; i < nsamples_total; i++) // map the FFT to the dynamic range of the fixed point values an copy to buffer containing all FFTs - { - d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast(floor(fft_codes_padded[i].real() * (pow(2, 9) - 1) / max)), - static_cast(floor(fft_codes_padded[i].imag() * (pow(2, 9) - 1) / max))); - } + memcpy(fft_if->get_inbuf(), code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer + fft_if->execute(); // Run the FFT of local code + volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values + // normalize the code + max = 0; // initialize maximum value + for (uint32_t i = 0; i < nsamples_total; i++) // search for maxima + { + if (std::abs(fft_codes_padded[i].real()) > max) + { + max = std::abs(fft_codes_padded[i].real()); + } + if (std::abs(fft_codes_padded[i].imag()) > max) + { + max = std::abs(fft_codes_padded[i].imag()); + } + } + for (uint32_t i = 0; i < nsamples_total; i++) // map the FFT to the dynamic range of the fixed point values an copy to buffer containing all FFTs + { + d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast(floor(fft_codes_padded[i].real() * (pow(2, 9) - 1) / max)), + static_cast(floor(fft_codes_padded[i].imag() * (pow(2, 9) - 1) / max))); + } } acq_parameters.all_fft_codes = d_all_fft_codes_; @@ -188,8 +186,8 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::~GalileoE1PcpsAmbiguousAcquisitionFpga() void GalileoE1PcpsAmbiguousAcquisitionFpga::stop_acquisition() { - // this command causes the SW to reset the HW. - acquisition_fpga_->reset_acquisition(); + // this command causes the SW to reset the HW. + acquisition_fpga_->reset_acquisition(); } diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.h b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.h index 550c6f159..428f13210 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.h @@ -28,7 +28,7 @@ * along with GNSS-SDR. If not, see . * * ------------------------------------------------------------------------- - */ + */ #ifndef GNSS_SDR_GALILEO_E1_PCPS_AMBIGUOUS_ACQUISITION_FPGA_H_ #define GNSS_SDR_GALILEO_E1_PCPS_AMBIGUOUS_ACQUISITION_FPGA_H_ @@ -135,10 +135,10 @@ public: */ void set_state(int state) override; - /*! + /*! * \brief Stop running acquisition */ - void stop_acquisition() override; + void stop_acquisition() override; void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{}; diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.cc index 15a11df57..69520f1a9 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.cc @@ -27,7 +27,7 @@ * along with GNSS-SDR. If not, see . * * ------------------------------------------------------------------------- - */ + */ #include "galileo_e5a_pcps_acquisition_fpga.h" #include "Galileo_E5a.h" @@ -55,12 +55,12 @@ GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga(ConfigurationInterf DLOG(INFO) << "Role " << role; - int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 32000000); - int64_t fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); + int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 32000000); + int64_t fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); float downsampling_factor = configuration_->property(role + ".downsampling_factor", 1.0); acq_parameters.downsampling_factor = downsampling_factor; - fs_in = fs_in/downsampling_factor; + fs_in = fs_in / downsampling_factor; acq_parameters.fs_in = fs_in; @@ -82,7 +82,7 @@ GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga(ConfigurationInterf acq_parameters.code_length = code_length; // The FPGA can only use FFT lengths that are a power of two. - float nbits = ceilf(log2f((float)code_length*2)); + float nbits = ceilf(log2f((float)code_length * 2)); uint32_t nsamples_total = pow(2, nbits); uint32_t select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", 1); acq_parameters.select_queue_Fpga = select_queue_Fpga; @@ -122,13 +122,13 @@ GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga(ConfigurationInterf galileo_e5_a_code_gen_complex_sampled(code, signal_, PRN, fs_in, 0); - for (uint32_t s = code_length; s < 2*code_length; s++) + for (uint32_t s = code_length; s < 2 * code_length; s++) { code[s] = code[s - code_length]; } // fill in zero padding - for (uint32_t s = 2*code_length; s < nsamples_total; s++) + for (uint32_t s = 2 * code_length; s < nsamples_total; s++) { code[s] = std::complex(0.0, 0.0); } @@ -137,7 +137,7 @@ GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga(ConfigurationInterf fft_if->execute(); // Run the FFT of local code volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values - max = 0; // initialize maximum value + max = 0; // initialize maximum value for (uint32_t i = 0; i < nsamples_total; i++) // search for maxima { if (std::abs(fft_codes_padded[i].real()) > max) @@ -173,7 +173,6 @@ GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga(ConfigurationInterf delete[] code; delete fft_if; delete[] fft_codes_padded; - } @@ -185,8 +184,8 @@ GalileoE5aPcpsAcquisitionFpga::~GalileoE5aPcpsAcquisitionFpga() void GalileoE5aPcpsAcquisitionFpga::stop_acquisition() { - // this command causes the SW to reset the HW. - acquisition_fpga_->reset_acquisition(); + // this command causes the SW to reset the HW. + acquisition_fpga_->reset_acquisition(); } @@ -255,13 +254,13 @@ void GalileoE5aPcpsAcquisitionFpga::set_state(int state) void GalileoE5aPcpsAcquisitionFpga::connect(gr::top_block_sptr top_block) { - // nothing to connect + // nothing to connect } void GalileoE5aPcpsAcquisitionFpga::disconnect(gr::top_block_sptr top_block) { - // nothing to connect + // nothing to connect } diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.h index d53d62076..8e8a08972 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.h @@ -145,7 +145,6 @@ public: void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{}; private: - ConfigurationInterface* configuration_; pcps_acquisition_fpga_sptr acquisition_fpga_; diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc index 365270199..dabf94a15 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc @@ -32,7 +32,7 @@ * along with GNSS-SDR. If not, see . * * ------------------------------------------------------------------------- - */ + */ #include "gps_l1_ca_pcps_acquisition_fpga.h" #include "GPS_L1_CA.h" @@ -63,13 +63,13 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga( DLOG(INFO) << "role " << role; - int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); - int64_t fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); + int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); + int64_t fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); float downsampling_factor = configuration_->property(role + ".downsampling_factor", 4.0); acq_parameters.downsampling_factor = downsampling_factor; - fs_in = fs_in/downsampling_factor; + fs_in = fs_in / downsampling_factor; acq_parameters.fs_in = fs_in; doppler_max_ = configuration_->property(role + ".doppler_max", 5000); @@ -80,7 +80,7 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga( auto code_length = static_cast(std::round(static_cast(fs_in) / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS))); acq_parameters.code_length = code_length; // The FPGA can only use FFT lengths that are a power of two. - float nbits = ceilf(log2f((float)code_length*2)); + float nbits = ceilf(log2f((float)code_length * 2)); uint32_t nsamples_total = pow(2, nbits); uint32_t select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", 0); acq_parameters.select_queue_Fpga = select_queue_Fpga; @@ -102,23 +102,23 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga( for (uint32_t PRN = 1; PRN <= NUM_PRNs; PRN++) { gps_l1_ca_code_gen_complex_sampled(code, PRN, fs_in, 0); // generate PRN code - - for (uint32_t s = code_length; s < 2*code_length; s++) + + for (uint32_t s = code_length; s < 2 * code_length; s++) { code[s] = code[s - code_length]; } // fill in zero padding - for (uint32_t s = 2*code_length; s < nsamples_total; s++) + for (uint32_t s = 2 * code_length; s < nsamples_total; s++) { code[s] = std::complex(0.0, 0.0); } - memcpy(fft_if->get_inbuf(), code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer + memcpy(fft_if->get_inbuf(), code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer fft_if->execute(); // Run the FFT of local code volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values - max = 0; // initialize maximum value + max = 0; // initialize maximum value for (uint32_t i = 0; i < nsamples_total; i++) // search for maxima { if (std::abs(fft_codes_padded[i].real()) > max) @@ -135,7 +135,6 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga( d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast(floor(fft_codes_padded[i].real() * (pow(2, 9) - 1) / max)), static_cast(floor(fft_codes_padded[i].imag() * (pow(2, 9) - 1) / max))); } - } //acq_parameters @@ -155,7 +154,6 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga( delete[] code; delete fft_if; delete[] fft_codes_padded; - } @@ -167,8 +165,8 @@ GpsL1CaPcpsAcquisitionFpga::~GpsL1CaPcpsAcquisitionFpga() void GpsL1CaPcpsAcquisitionFpga::stop_acquisition() { - // this command causes the SW to reset the HW. - acquisition_fpga_->reset_acquisition(); + // this command causes the SW to reset the HW. + acquisition_fpga_->reset_acquisition(); } @@ -227,7 +225,7 @@ void GpsL1CaPcpsAcquisitionFpga::set_local_code() void GpsL1CaPcpsAcquisitionFpga::reset() { - // this function starts the acquisition process + // this function starts the acquisition process acquisition_fpga_->set_active(true); } diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h index 93e2456b9..7d91f04d0 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h @@ -32,7 +32,7 @@ * along with GNSS-SDR. If not, see . * * ------------------------------------------------------------------------- - */ + */ #ifndef GNSS_SDR_GPS_L1_CA_PCPS_ACQUISITION_FPGA_H_ #define GNSS_SDR_GPS_L1_CA_PCPS_ACQUISITION_FPGA_H_ diff --git a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.cc index be7cb07fc..04e30c63c 100644 --- a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.cc @@ -59,13 +59,13 @@ GpsL5iPcpsAcquisitionFpga::GpsL5iPcpsAcquisitionFpga( LOG(INFO) << "role " << role; - int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); - int64_t fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); + int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); + int64_t fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); float downsampling_factor = configuration_->property(role + ".downsampling_factor", 1.0); acq_parameters.downsampling_factor = downsampling_factor; - fs_in = fs_in/downsampling_factor; + fs_in = fs_in / downsampling_factor; acq_parameters.fs_in = fs_in; @@ -79,14 +79,14 @@ GpsL5iPcpsAcquisitionFpga::GpsL5iPcpsAcquisitionFpga( auto code_length = static_cast(std::round(static_cast(fs_in) / (GPS_L5I_CODE_RATE_HZ / static_cast(GPS_L5I_CODE_LENGTH_CHIPS)))); acq_parameters.code_length = code_length; // The FPGA can only use FFT lengths that are a power of two. - float nbits = ceilf(log2f((float)code_length*2)); + float nbits = ceilf(log2f((float)code_length * 2)); uint32_t nsamples_total = pow(2, nbits); uint32_t select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", 1); acq_parameters.select_queue_Fpga = select_queue_Fpga; std::string default_device_name = "/dev/uio0"; std::string device_name = configuration_->property(role + ".devicename", default_device_name); acq_parameters.device_name = device_name; - acq_parameters.samples_per_ms = nsamples_total/sampled_ms; + acq_parameters.samples_per_ms = nsamples_total / sampled_ms; acq_parameters.samples_per_code = nsamples_total; acq_parameters.excludelimit = static_cast(ceil((1.0 / GPS_L5I_CODE_RATE_HZ) * static_cast(acq_parameters.fs_in))); @@ -100,41 +100,41 @@ GpsL5iPcpsAcquisitionFpga::GpsL5iPcpsAcquisitionFpga( float max; // temporary maxima search for (uint32_t PRN = 1; PRN <= NUM_PRNs; PRN++) - { - gps_l5i_code_gen_complex_sampled(code, PRN, fs_in); + { + gps_l5i_code_gen_complex_sampled(code, PRN, fs_in); - for (uint32_t s = code_length; s < 2*code_length; s++) - { - code[s] = code[s - code_length]; - } + for (uint32_t s = code_length; s < 2 * code_length; s++) + { + code[s] = code[s - code_length]; + } - for (uint32_t s = 2*code_length; s < nsamples_total; s++) - { - // fill in zero padding - code[s] = std::complex(static_cast(0,0)); - } - memcpy(fft_if->get_inbuf(), code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer - fft_if->execute(); // Run the FFT of local code - volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values + for (uint32_t s = 2 * code_length; s < nsamples_total; s++) + { + // fill in zero padding + code[s] = std::complex(static_cast(0, 0)); + } + memcpy(fft_if->get_inbuf(), code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer + fft_if->execute(); // Run the FFT of local code + volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values - max = 0; // initialize maximum value - for (uint32_t i = 0; i < nsamples_total; i++) // search for maxima - { - if (std::abs(fft_codes_padded[i].real()) > max) - { - max = std::abs(fft_codes_padded[i].real()); - } - if (std::abs(fft_codes_padded[i].imag()) > max) - { - max = std::abs(fft_codes_padded[i].imag()); - } - } - for (uint32_t i = 0; i < nsamples_total; i++) // map the FFT to the dynamic range of the fixed point values an copy to buffer containing all FFTs - { - d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast(floor(fft_codes_padded[i].real() * (pow(2, 9) - 1) / max)), - static_cast(floor(fft_codes_padded[i].imag() * (pow(2, 9) - 1) / max))); - } - } + max = 0; // initialize maximum value + for (uint32_t i = 0; i < nsamples_total; i++) // search for maxima + { + if (std::abs(fft_codes_padded[i].real()) > max) + { + max = std::abs(fft_codes_padded[i].real()); + } + if (std::abs(fft_codes_padded[i].imag()) > max) + { + max = std::abs(fft_codes_padded[i].imag()); + } + } + for (uint32_t i = 0; i < nsamples_total; i++) // map the FFT to the dynamic range of the fixed point values an copy to buffer containing all FFTs + { + d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast(floor(fft_codes_padded[i].real() * (pow(2, 9) - 1) / max)), + static_cast(floor(fft_codes_padded[i].imag() * (pow(2, 9) - 1) / max))); + } + } //acq_parameters acq_parameters.all_fft_codes = d_all_fft_codes_; @@ -153,7 +153,6 @@ GpsL5iPcpsAcquisitionFpga::GpsL5iPcpsAcquisitionFpga( delete[] code; delete fft_if; delete[] fft_codes_padded; - } @@ -166,8 +165,8 @@ GpsL5iPcpsAcquisitionFpga::~GpsL5iPcpsAcquisitionFpga() void GpsL5iPcpsAcquisitionFpga::stop_acquisition() { - // this command causes the SW to reset the HW. - acquisition_fpga_->reset_acquisition(); + // this command causes the SW to reset the HW. + acquisition_fpga_->reset_acquisition(); } diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fpga.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fpga.cc index 091092c89..8aed78c5a 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fpga.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fpga.cc @@ -32,7 +32,7 @@ * along with GNSS-SDR. If not, see . * * ------------------------------------------------------------------------- - */ + */ #include "pcps_acquisition_fpga.h" @@ -77,7 +77,6 @@ pcps_acquisition_fpga::pcps_acquisition_fpga(pcpsconf_fpga_t conf_) : gr::block( acquisition_fpga = std::make_shared(acq_parameters.device_name, acq_parameters.code_length, acq_parameters.doppler_max, d_fft_size, acq_parameters.fs_in, acq_parameters.sampled_ms, acq_parameters.select_queue_Fpga, acq_parameters.all_fft_codes, acq_parameters.excludelimit); - } @@ -105,9 +104,9 @@ void pcps_acquisition_fpga::init() d_mag = 0.0; d_input_power = 0.0; - d_num_doppler_bins = static_cast(std::ceil(static_cast(static_cast(acq_parameters.doppler_max) - static_cast(-acq_parameters.doppler_max)) / static_cast(d_doppler_step))) + 1; + d_num_doppler_bins = static_cast(std::ceil(static_cast(static_cast(acq_parameters.doppler_max) - static_cast(-acq_parameters.doppler_max)) / static_cast(d_doppler_step))) + 1; - acquisition_fpga->init(); + acquisition_fpga->init(); } @@ -171,7 +170,6 @@ void pcps_acquisition_fpga::send_negative_acquisition() void pcps_acquisition_fpga::set_active(bool active) { - d_active = active; // initialize acquisition algorithm @@ -203,47 +201,44 @@ void pcps_acquisition_fpga::set_active(bool active) acquisition_fpga->read_acquisition_results(&indext, &firstpeak, &secondpeak, &initial_sample, &d_input_power, &d_doppler_index, &total_block_exp); if (total_block_exp > d_total_block_exp) - { - // if the attenuation factor of the FPGA FFT-IFFT is smaller than the reference attenuation factor then we need to update the reference attenuation factor - std::cout << "changing blk exp..... d_total_block_exp = " << d_total_block_exp << " total_block_exp = " << total_block_exp << " chan = " << d_channel << std::endl; - d_total_block_exp = total_block_exp; + { + // if the attenuation factor of the FPGA FFT-IFFT is smaller than the reference attenuation factor then we need to update the reference attenuation factor + std::cout << "changing blk exp..... d_total_block_exp = " << d_total_block_exp << " total_block_exp = " << total_block_exp << " chan = " << d_channel << std::endl; + d_total_block_exp = total_block_exp; + } - } + doppler = -static_cast(acq_parameters.doppler_max) + d_doppler_step * (d_doppler_index - 1); - doppler = -static_cast(acq_parameters.doppler_max) + d_doppler_step * (d_doppler_index - 1); - - if (secondpeak > 0) - { - d_test_statistics = firstpeak/secondpeak; - } - else - { - d_test_statistics = 0.0; - } + if (secondpeak > 0) + { + d_test_statistics = firstpeak / secondpeak; + } + else + { + d_test_statistics = 0.0; + } d_gnss_synchro->Acq_doppler_hz = static_cast(doppler); d_sample_counter = initial_sample; if (d_select_queue_Fpga == 0) - { - if (d_downsampling_factor > 1) - { - - d_gnss_synchro->Acq_delay_samples = static_cast(d_downsampling_factor*(indext)); - d_gnss_synchro->Acq_samplestamp_samples = d_downsampling_factor*d_sample_counter - 44; //33; //41; //+ 81*0.5; // delay due to the downsampling filter in the acquisition - - } - else - { - d_gnss_synchro->Acq_delay_samples = static_cast(indext); - d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter; // delay due to the downsampling filter in the acquisition + { + if (d_downsampling_factor > 1) + { + d_gnss_synchro->Acq_delay_samples = static_cast(d_downsampling_factor * (indext)); + d_gnss_synchro->Acq_samplestamp_samples = d_downsampling_factor * d_sample_counter - 44; //33; //41; //+ 81*0.5; // delay due to the downsampling filter in the acquisition + } + else + { + d_gnss_synchro->Acq_delay_samples = static_cast(indext); + d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter; // delay due to the downsampling filter in the acquisition + } } - } else - { - d_gnss_synchro->Acq_delay_samples = static_cast(indext); - d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter; // delay due to the downsampling filter in the acquisition - } + { + d_gnss_synchro->Acq_delay_samples = static_cast(indext); + d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter; // delay due to the downsampling filter in the acquisition + } if (d_test_statistics > d_threshold) { @@ -270,14 +265,11 @@ int pcps_acquisition_fpga::general_work(int noutput_items __attribute__((unused) void pcps_acquisition_fpga::reset_acquisition(void) { - // this function triggers a HW reset of the FPGA PL. - acquisition_fpga->reset_acquisition(); + // this function triggers a HW reset of the FPGA PL. + acquisition_fpga->reset_acquisition(); } -void pcps_acquisition_fpga::read_fpga_total_scale_factor(uint32_t *total_scale_factor, uint32_t *fw_scale_factor) +void pcps_acquisition_fpga::read_fpga_total_scale_factor(uint32_t* total_scale_factor, uint32_t* fw_scale_factor) { - acquisition_fpga->read_fpga_total_scale_factor(total_scale_factor, fw_scale_factor); + acquisition_fpga->read_fpga_total_scale_factor(total_scale_factor, fw_scale_factor); } - - - diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fpga.h b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fpga.h index a08cd5363..bdb83a257 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fpga.h @@ -39,7 +39,7 @@ * along with GNSS-SDR. If not, see . * * ------------------------------------------------------------------------- - */ + */ #ifndef GNSS_SDR_PCPS_ACQUISITION_FPGA_H_ #define GNSS_SDR_PCPS_ACQUISITION_FPGA_H_ @@ -216,7 +216,7 @@ public: /*! * \brief This funciton is only used for the unit tests */ - void read_fpga_total_scale_factor(uint32_t *total_scale_factor, uint32_t *fw_scale_factor); + void read_fpga_total_scale_factor(uint32_t* total_scale_factor, uint32_t* fw_scale_factor); }; #endif /* GNSS_SDR_PCPS_ACQUISITION_FPGA_H_*/ diff --git a/src/algorithms/acquisition/libs/fpga_acquisition.cc b/src/algorithms/acquisition/libs/fpga_acquisition.cc index 9a14f779a..979fd47ea 100644 --- a/src/algorithms/acquisition/libs/fpga_acquisition.cc +++ b/src/algorithms/acquisition/libs/fpga_acquisition.cc @@ -31,7 +31,7 @@ * along with GNSS-SDR. If not, see . * * ------------------------------------------------------------------------- - */ + */ #include "fpga_acquisition.h" #include "GPS_L1_CA.h" @@ -43,7 +43,6 @@ #include - // FPGA register parameters #define PAGE_SIZE 0x10000 // default page size for the multicorrelator memory map #define MAX_PHASE_STEP_RAD 0.999999999534339 // 1 - pow(2,-31); @@ -58,10 +57,10 @@ #define SELECT_MSB 0XFF00 // value to select the most significant byte #define SELECT_16_BITS 0xFFFF // value to select 16 bits #define SHL_8_BITS 256 // value used to shift a value 8 bits to the left -#define SELECT_LSBits 0x000003FF // Select the 10 LSbits out of a 20-bit word -#define SELECT_MSBbits 0x000FFC00 // Select the 10 MSbits out of a 20-bit word -#define SELECT_ALL_CODE_BITS 0x000FFFFF // Select a 20 bit word -#define SHL_CODE_BITS 1024 // shift left by 10 bits +#define SELECT_LSBits 0x000003FF // Select the 10 LSbits out of a 20-bit word +#define SELECT_MSBbits 0x000FFC00 // Select the 10 MSbits out of a 20-bit word +#define SELECT_ALL_CODE_BITS 0x000FFFFF // Select a 20 bit word +#define SHL_CODE_BITS 1024 // shift left by 10 bits bool fpga_acquisition::init() @@ -73,7 +72,7 @@ bool fpga_acquisition::init() bool fpga_acquisition::set_local_code(uint32_t PRN) { // select the code with the chosen PRN - d_PRN = PRN; + d_PRN = PRN; return true; } @@ -82,7 +81,6 @@ void fpga_acquisition::write_local_code() { fpga_acquisition::fpga_configure_acquisition_local_code( &d_all_fft_codes[d_nsamples_total * (d_PRN - 1)]); - } fpga_acquisition::fpga_acquisition(std::string device_name, @@ -91,7 +89,7 @@ fpga_acquisition::fpga_acquisition(std::string device_name, uint32_t nsamples_total, int64_t fs_in, uint32_t sampled_ms, uint32_t select_queue, lv_16sc_t *all_fft_codes, - uint32_t excludelimit) + uint32_t excludelimit) { uint32_t vector_length = nsamples_total; @@ -116,7 +114,6 @@ fpga_acquisition::fpga_acquisition(std::string device_name, d_PRN = 0; DLOG(INFO) << "Acquisition FPGA class created"; - } void fpga_acquisition::open_device() @@ -135,12 +132,10 @@ void fpga_acquisition::open_device() LOG(WARNING) << "Cannot map the FPGA acquisition module into user memory"; std::cout << "Acq: cannot map deviceio" << d_device_name << std::endl; } - } fpga_acquisition::~fpga_acquisition() { - } @@ -152,7 +147,6 @@ bool fpga_acquisition::free() void fpga_acquisition::fpga_acquisition_test_register() { - // sanity check : check test register uint32_t writeval = TEST_REG_SANITY_CHECK; uint32_t readval; @@ -190,14 +184,12 @@ void fpga_acquisition::fpga_configure_acquisition_local_code(lv_16sc_t fft_local local_code = (tmp & SELECT_LSBits) | ((tmp2 * SHL_CODE_BITS) & SELECT_MSBbits); // put together the real part and the imaginary part fft_data = local_code & SELECT_ALL_CODE_BITS; d_map_base[6] = fft_data; - } } void fpga_acquisition::run_acquisition(void) { - // enable interrupts int32_t reenable = 1; int32_t disable_int = 0; @@ -212,67 +204,63 @@ void fpga_acquisition::run_acquisition(void) nb = read(d_fd, &irq_count, sizeof(irq_count)); if (nb != sizeof(irq_count)) { - std::cout << "acquisition module Read failed to retrieve 4 bytes!" << std::endl; - std::cout << "acquisition module Interrupt number " << irq_count << std::endl; + std::cout << "acquisition module Read failed to retrieve 4 bytes!" << std::endl; + std::cout << "acquisition module Interrupt number " << irq_count << std::endl; } write(d_fd, reinterpret_cast(&disable_int), sizeof(int32_t)); - } void fpga_acquisition::set_block_exp(uint32_t total_block_exp) { - d_map_base[11] = total_block_exp; + d_map_base[11] = total_block_exp; } void fpga_acquisition::set_doppler_sweep(uint32_t num_sweeps) { + float phase_step_rad_real; + float phase_step_rad_int_temp; + int32_t phase_step_rad_int; + int32_t doppler = static_cast(-d_doppler_max); + float phase_step_rad = GPS_TWO_PI * (doppler) / static_cast(d_fs_in); + // The doppler step can never be outside the range -pi to +pi, otherwise there would be aliasing + // The FPGA expects phase_step_rad between -1 (-pi) to +1 (+pi) + // The FPGA also expects the phase to be negative since it produces cos(x) -j*sin(x) + phase_step_rad_real = phase_step_rad / (GPS_TWO_PI / 2); - float phase_step_rad_real; - float phase_step_rad_int_temp; - int32_t phase_step_rad_int; - int32_t doppler = static_cast(-d_doppler_max); - float phase_step_rad = GPS_TWO_PI * (doppler) / static_cast(d_fs_in); - // The doppler step can never be outside the range -pi to +pi, otherwise there would be aliasing - // The FPGA expects phase_step_rad between -1 (-pi) to +1 (+pi) - // The FPGA also expects the phase to be negative since it produces cos(x) -j*sin(x) - phase_step_rad_real = phase_step_rad / (GPS_TWO_PI / 2); - - // avoid saturation of the fixed point representation in the fpga - // (only the positive value can saturate due to the 2's complement representation) - if (phase_step_rad_real >= 1.0) - { - phase_step_rad_real = MAX_PHASE_STEP_RAD; - } - phase_step_rad_int_temp = phase_step_rad_real * POW_2_2; // * 2^2 - phase_step_rad_int = static_cast(phase_step_rad_int_temp * (POW_2_29)); // * 2^29 (in total it makes x2^31 in two steps to avoid the warnings - d_map_base[3] = phase_step_rad_int; - - // repeat the calculation with the doppler step - doppler = static_cast(d_doppler_step); - phase_step_rad = GPS_TWO_PI * (doppler) / static_cast(d_fs_in); - phase_step_rad_real = phase_step_rad / (GPS_TWO_PI / 2); - if (phase_step_rad_real >= 1.0) - { - phase_step_rad_real = MAX_PHASE_STEP_RAD; - } - phase_step_rad_int_temp = phase_step_rad_real * POW_2_2; // * 2^2 - phase_step_rad_int = static_cast(phase_step_rad_int_temp * (POW_2_29)); // * 2^29 (in total it makes x2^31 in two steps to avoid the warnings - d_map_base[4] = phase_step_rad_int; - d_map_base[5] = num_sweeps; + // avoid saturation of the fixed point representation in the fpga + // (only the positive value can saturate due to the 2's complement representation) + if (phase_step_rad_real >= 1.0) + { + phase_step_rad_real = MAX_PHASE_STEP_RAD; + } + phase_step_rad_int_temp = phase_step_rad_real * POW_2_2; // * 2^2 + phase_step_rad_int = static_cast(phase_step_rad_int_temp * (POW_2_29)); // * 2^29 (in total it makes x2^31 in two steps to avoid the warnings + d_map_base[3] = phase_step_rad_int; + // repeat the calculation with the doppler step + doppler = static_cast(d_doppler_step); + phase_step_rad = GPS_TWO_PI * (doppler) / static_cast(d_fs_in); + phase_step_rad_real = phase_step_rad / (GPS_TWO_PI / 2); + if (phase_step_rad_real >= 1.0) + { + phase_step_rad_real = MAX_PHASE_STEP_RAD; + } + phase_step_rad_int_temp = phase_step_rad_real * POW_2_2; // * 2^2 + phase_step_rad_int = static_cast(phase_step_rad_int_temp * (POW_2_29)); // * 2^29 (in total it makes x2^31 in two steps to avoid the warnings + d_map_base[4] = phase_step_rad_int; + d_map_base[5] = num_sweeps; } void fpga_acquisition::configure_acquisition() { - fpga_acquisition::open_device(); + fpga_acquisition::open_device(); d_map_base[0] = d_select_queue; d_map_base[1] = d_vector_length; d_map_base[2] = d_nsamples; d_map_base[7] = static_cast(log2(static_cast(d_vector_length))); // log2 FFTlength d_map_base[12] = d_excludelimit; - } @@ -303,7 +291,6 @@ void fpga_acquisition::set_phase_step(uint32_t doppler_index) void fpga_acquisition::read_acquisition_results(uint32_t *max_index, float *firstpeak, float *secondpeak, uint64_t *initial_sample, float *power_sum, uint32_t *doppler_index, uint32_t *total_blk_exp) { - uint64_t initial_sample_tmp = 0; uint32_t readval = 0; uint64_t readval_long = 0; @@ -313,7 +300,7 @@ void fpga_acquisition::read_acquisition_results(uint32_t *max_index, initial_sample_tmp = readval; readval_long = d_map_base[2]; - readval_long_shifted = readval_long << 32; // 2^32 + readval_long_shifted = readval_long << 32; // 2^32 initial_sample_tmp = initial_sample_tmp + readval_long_shifted; // 2^32 *initial_sample = initial_sample_tmp; @@ -335,10 +322,9 @@ void fpga_acquisition::read_acquisition_results(uint32_t *max_index, readval = d_map_base[7]; // read doppler index -- this read releases the interrupt line *doppler_index = readval; - readval = d_map_base[15]; // read dummy + readval = d_map_base[15]; // read dummy fpga_acquisition::close_device(); - } @@ -367,7 +353,7 @@ void fpga_acquisition::close_device() void fpga_acquisition::reset_acquisition(void) { - fpga_acquisition::open_device(); + fpga_acquisition::open_device(); d_map_base[8] = RESET_ACQUISITION; // writing a 2 to d_map_base[8] resets the multicorrelator fpga_acquisition::close_device(); } @@ -376,19 +362,17 @@ void fpga_acquisition::reset_acquisition(void) // this function is only used for the unit tests void fpga_acquisition::read_fpga_total_scale_factor(uint32_t *total_scale_factor, uint32_t *fw_scale_factor) { + uint32_t readval = 0; + readval = d_map_base[8]; + *total_scale_factor = readval; - uint32_t readval = 0; - readval = d_map_base[8]; - *total_scale_factor = readval; - - //readval = d_map_base[8]; - *fw_scale_factor = 0; - + //readval = d_map_base[8]; + *fw_scale_factor = 0; } void fpga_acquisition::read_result_valid(uint32_t *result_valid) { - uint32_t readval = 0; - readval = d_map_base[0]; - *result_valid = readval; + uint32_t readval = 0; + readval = d_map_base[0]; + *result_valid = readval; } diff --git a/src/algorithms/acquisition/libs/fpga_acquisition.h b/src/algorithms/acquisition/libs/fpga_acquisition.h index ff599f4ff..6140e9ade 100644 --- a/src/algorithms/acquisition/libs/fpga_acquisition.h +++ b/src/algorithms/acquisition/libs/fpga_acquisition.h @@ -54,7 +54,7 @@ public: uint32_t sampled_ms, uint32_t select_queue, lv_16sc_t *all_fft_codes, - uint32_t excludelimit); + uint32_t excludelimit); ~fpga_acquisition(); bool init(); @@ -113,18 +113,17 @@ private: lv_16sc_t *d_all_fft_codes; // memory that contains all the code ffts uint32_t d_vector_length; // number of samples incluing padding and number of ms uint32_t d_excludelimit; - uint32_t d_nsamples_total; // number of samples including padding - uint32_t d_nsamples; // number of samples not including padding - uint32_t d_select_queue; // queue selection - std::string d_device_name; // HW device name - uint32_t d_doppler_max; // max doppler - uint32_t d_doppler_step; // doppler step - uint32_t d_PRN; // PRN + uint32_t d_nsamples_total; // number of samples including padding + uint32_t d_nsamples; // number of samples not including padding + uint32_t d_select_queue; // queue selection + std::string d_device_name; // HW device name + uint32_t d_doppler_max; // max doppler + uint32_t d_doppler_step; // doppler step + uint32_t d_PRN; // PRN // FPGA private functions void fpga_acquisition_test_register(void); void fpga_configure_acquisition_local_code(lv_16sc_t fft_local_code[]); void read_result_valid(uint32_t *result_valid); - }; #endif /* GNSS_SDR_FPGA_ACQUISITION_H_ */ diff --git a/src/algorithms/libs/gnss_sdr_fpga_sample_counter.cc b/src/algorithms/libs/gnss_sdr_fpga_sample_counter.cc index 9a5427c60..51f3a6547 100644 --- a/src/algorithms/libs/gnss_sdr_fpga_sample_counter.cc +++ b/src/algorithms/libs/gnss_sdr_fpga_sample_counter.cc @@ -251,7 +251,7 @@ void gnss_sdr_fpga_sample_counter::close_device() auto *aux = const_cast(map_base); if (munmap(static_cast(aux), PAGE_SIZE) == -1) { - std::cout << "Failed to unmap memory uio" << std::endl; + std::cout << "Failed to unmap memory uio" << std::endl; } close(fd); } @@ -270,8 +270,8 @@ uint32_t gnss_sdr_fpga_sample_counter::wait_for_interrupt_and_read_counter() nb = read(fd, &irq_count, sizeof(irq_count)); if (nb != sizeof(irq_count)) { - std::cout << "fpga sample counter module read failed to retrieve 4 bytes!" << std::endl; - std::cout << "fpga sample counter module interrupt number " << irq_count << std::endl; + std::cout << "fpga sample counter module read failed to retrieve 4 bytes!" << std::endl; + std::cout << "fpga sample counter module interrupt number " << irq_count << std::endl; } // it is a rising edge interrupt, the interrupt does not need to be acknowledged diff --git a/src/algorithms/libs/gnss_sdr_fpga_sample_counter.h b/src/algorithms/libs/gnss_sdr_fpga_sample_counter.h index 3ec323e6a..a11a94be5 100644 --- a/src/algorithms/libs/gnss_sdr_fpga_sample_counter.h +++ b/src/algorithms/libs/gnss_sdr_fpga_sample_counter.h @@ -66,9 +66,9 @@ private: uint32_t current_days; // Receiver time in days since the beginning of the run int32_t report_interval_ms; bool flag_enable_send_msg; - int32_t fd; // driver descriptor - volatile uint32_t *map_base; // driver memory map - std::string device_name = "/dev/uio2"; // HW device name + int32_t fd; // driver descriptor + volatile uint32_t *map_base; // driver memory map + std::string device_name = "/dev/uio2"; // HW device name public: friend gnss_sdr_fpga_sample_counter_sptr gnss_sdr_make_fpga_sample_counter(double _fs, int32_t _interval_ms); diff --git a/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking_fpga.cc b/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking_fpga.cc index cb054c87c..f66c967bd 100644 --- a/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking_fpga.cc +++ b/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking_fpga.cc @@ -55,7 +55,6 @@ GalileoE5aDllPllTrackingFpga::GalileoE5aDllPllTrackingFpga( ConfigurationInterface *configuration, const std::string &role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) { - Dll_Pll_Conf_Fpga trk_param_fpga = Dll_Pll_Conf_Fpga(); DLOG(INFO) << "role " << role; //################# CONFIGURATION PARAMETERS ######################## @@ -138,15 +137,6 @@ GalileoE5aDllPllTrackingFpga::GalileoE5aDllPllTrackingFpga( auto *aux_code = static_cast(volk_gnsssdr_malloc(sizeof(gr_complex) * code_length_chips * code_samples_per_chip, volk_gnsssdr_get_alignment())); - float *tracking_code; - float *data_code; - - if (trk_param_fpga.track_pilot) - { - data_code = static_cast(volk_gnsssdr_malloc(code_samples_per_chip * code_length_chips * sizeof(float), volk_gnsssdr_get_alignment())); - } - tracking_code = static_cast(volk_gnsssdr_malloc(code_samples_per_chip * code_length_chips * sizeof(float), volk_gnsssdr_get_alignment())); - d_ca_codes = static_cast(volk_gnsssdr_malloc(static_cast(code_length_chips) * code_samples_per_chip * GALILEO_E5A_NUMBER_OF_CODES * sizeof(int32_t), volk_gnsssdr_get_alignment())); if (trk_param_fpga.track_pilot) @@ -160,37 +150,22 @@ GalileoE5aDllPllTrackingFpga::GalileoE5aDllPllTrackingFpga( galileo_e5_a_code_gen_complex_primary(aux_code, PRN, const_cast(sig_)); if (trk_param_fpga.track_pilot) { - for (uint32_t i = 0; i < code_length_chips; i++) - { - tracking_code[i] = aux_code[i].imag(); - data_code[i] = aux_code[i].real(); - } for (uint32_t s = 0; s < code_length_chips; s++) { - d_ca_codes[static_cast(code_length_chips) * (PRN - 1) + s] = static_cast(tracking_code[s]); - d_data_codes[static_cast(code_length_chips) * (PRN - 1) + s] = static_cast(data_code[s]); + d_ca_codes[static_cast(code_length_chips) * (PRN - 1) + s] = static_cast(aux_code[s].imag()); + d_data_codes[static_cast(code_length_chips) * (PRN - 1) + s] = static_cast(aux_code[s].real()); } } else { - for (uint32_t i = 0; i < code_length_chips; i++) - { - tracking_code[i] = aux_code[i].real(); - } - for (uint32_t s = 0; s < code_length_chips; s++) { - d_ca_codes[static_cast(code_length_chips) * (PRN - 1) + s] = static_cast(tracking_code[s]); + d_ca_codes[static_cast(code_length_chips) * (PRN - 1) + s] = static_cast(aux_code[s].real()); } } } volk_gnsssdr_free(aux_code); - volk_gnsssdr_free(tracking_code); - if (trk_param_fpga.track_pilot) - { - volk_gnsssdr_free(data_code); - } trk_param_fpga.ca_codes = d_ca_codes; trk_param_fpga.data_codes = d_data_codes; trk_param_fpga.code_length_chips = code_length_chips; diff --git a/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking_fpga.cc b/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking_fpga.cc index d51415471..764a69a97 100644 --- a/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking_fpga.cc +++ b/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking_fpga.cc @@ -153,7 +153,7 @@ GpsL5DllPllTrackingFpga::GpsL5DllPllTrackingFpga( for (uint32_t PRN = 1; PRN <= NUM_PRNs; PRN++) { - if (track_pilot) + if (trk_param_fpga.track_pilot) { gps_l5q_code_gen_float(tracking_code, PRN); gps_l5i_code_gen_float(data_code, PRN); diff --git a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.cc b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.cc index 691990ced..fe944d612 100644 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.cc +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.cc @@ -36,21 +36,21 @@ */ #include "dll_pll_veml_tracking_fpga.h" -#include "tracking_discriminators.h" -#include "lock_detectors.h" -#include "control_message_factory.h" -#include "MATH_CONSTANTS.h" -#include "Galileo_E1.h" -#include "galileo_e1_signal_processing.h" -#include "Galileo_E5a.h" -#include "galileo_e5_signal_processing.h" #include "GPS_L1_CA.h" -#include "gps_sdr_signal_processing.h" #include "GPS_L2C.h" -#include "gps_l2c_signal.h" #include "GPS_L5.h" -#include "gps_l5_signal.h" +#include "Galileo_E1.h" +#include "Galileo_E5a.h" +#include "MATH_CONSTANTS.h" +#include "control_message_factory.h" +#include "galileo_e1_signal_processing.h" +#include "galileo_e5_signal_processing.h" #include "gnss_sdr_create_directory.h" +#include "gps_l2c_signal.h" +#include "gps_l5_signal.h" +#include "gps_sdr_signal_processing.h" +#include "lock_detectors.h" +#include "tracking_discriminators.h" #include #include #include @@ -60,8 +60,8 @@ #include #include #include -#include #include +#include using google::LogMessage; @@ -72,7 +72,7 @@ dll_pll_veml_tracking_fpga_sptr dll_pll_veml_make_tracking_fpga(const Dll_Pll_Co dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(const Dll_Pll_Conf_Fpga &conf_) : gr::block("dll_pll_veml_tracking_fpga", gr::io_signature::make(0, 0, sizeof(lv_16sc_t)), - gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) + gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) { trk_parameters = conf_; // Telemetry bit synchronization message port input @@ -326,7 +326,7 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(const Dll_Pll_Conf_Fpga & trk_parameters.extend_correlation_symbols = 1; } - // --- Initializations --- + // --- Initializations --- // Initial code frequency basis of NCO d_code_freq_chips = d_code_chip_rate; // Residual code phase (in chips) @@ -423,14 +423,11 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(const Dll_Pll_Conf_Fpga & uint32_t multicorr_type = trk_parameters.multicorr_type; multicorrelator_fpga = std::make_shared(d_n_correlator_taps, device_name, device_base, ca_codes, data_codes, d_code_length_chips, trk_parameters.track_pilot, multicorr_type, d_code_samples_per_chip); multicorrelator_fpga->set_output_vectors(d_correlator_outs, d_Prompt_Data); - - } void dll_pll_veml_tracking_fpga::start_tracking() { - // correct the code phase according to the delay between acq and trk d_acq_code_phase_samples = d_acquisition_gnss_synchro->Acq_delay_samples; d_acq_carrier_doppler_hz = d_acquisition_gnss_synchro->Acq_doppler_hz; @@ -508,7 +505,6 @@ void dll_pll_veml_tracking_fpga::start_tracking() d_cloop = true; d_Prompt_buffer_deque.clear(); d_last_prompt = gr_complex(0.0, 0.0); - } @@ -553,13 +549,11 @@ dll_pll_veml_tracking_fpga::~dll_pll_veml_tracking_fpga() { LOG(WARNING) << "Exception in destructor " << ex.what(); } - } bool dll_pll_veml_tracking_fpga::acquire_secondary() { - // ******* preamble correlation ******** int32_t corr_value = 0; for (uint32_t i = 0; i < d_secondary_code_length; i++) @@ -596,13 +590,11 @@ bool dll_pll_veml_tracking_fpga::acquire_secondary() { return false; } - } bool dll_pll_veml_tracking_fpga::cn0_and_tracking_lock_status(double coh_integration_time_s) { - // ####### CN0 ESTIMATION AND LOCK DETECTORS ###### if (d_cn0_estimation_counter < trk_parameters.cn0_samples) @@ -642,7 +634,6 @@ bool dll_pll_veml_tracking_fpga::cn0_and_tracking_lock_status(double coh_integra return true; } } - } @@ -654,25 +645,20 @@ bool dll_pll_veml_tracking_fpga::cn0_and_tracking_lock_status(double coh_integra //void dll_pll_veml_tracking_fpga::do_correlation_step(const gr_complex *input_samples) void dll_pll_veml_tracking_fpga::do_correlation_step(void) { + // // ################# CARRIER WIPEOFF AND CORRELATORS ############################## -// // ################# CARRIER WIPEOFF AND CORRELATORS ############################## - - multicorrelator_fpga->Carrier_wipeoff_multicorrelator_resampler( + multicorrelator_fpga->Carrier_wipeoff_multicorrelator_resampler( d_rem_carr_phase_rad, - d_carrier_phase_step_rad, d_carrier_phase_rate_step_rad, - static_cast(d_rem_code_phase_chips) * static_cast(d_code_samples_per_chip), - static_cast(d_code_phase_step_chips) * static_cast(d_code_samples_per_chip), - static_cast(d_code_phase_rate_step_chips) * static_cast(d_code_samples_per_chip), + d_carrier_phase_step_rad, d_carrier_phase_rate_step_rad, + static_cast(d_rem_code_phase_chips) * static_cast(d_code_samples_per_chip), + static_cast(d_code_phase_step_chips) * static_cast(d_code_samples_per_chip), + static_cast(d_code_phase_rate_step_chips) * static_cast(d_code_samples_per_chip), d_current_prn_length_samples); - - - } void dll_pll_veml_tracking_fpga::run_dll_pll() { - // ################## PLL ########################################################## // PLL discriminator if (d_cloop) @@ -707,13 +693,11 @@ void dll_pll_veml_tracking_fpga::run_dll_pll() // New code Doppler frequency estimation d_code_freq_chips = (1.0 + (d_carrier_doppler_hz / d_signal_carrier_freq)) * d_code_chip_rate - d_code_error_filt_chips; - } void dll_pll_veml_tracking_fpga::clear_tracking_vars() { - std::fill_n(d_correlator_outs, d_n_correlator_taps, gr_complex(0.0, 0.0)); if (trk_parameters.track_pilot) d_Prompt_Data[0] = gr_complex(0.0, 0.0); d_carr_error_hz = 0.0; @@ -727,13 +711,11 @@ void dll_pll_veml_tracking_fpga::clear_tracking_vars() d_code_phase_rate_step_chips = 0.0; d_carr_ph_history.clear(); d_code_ph_history.clear(); - } void dll_pll_veml_tracking_fpga::update_tracking_vars() { - T_chip_seconds = 1.0 / d_code_freq_chips; T_prn_seconds = T_chip_seconds * static_cast(d_code_length_chips); @@ -800,13 +782,11 @@ void dll_pll_veml_tracking_fpga::update_tracking_vars() // remnant code phase [chips] d_rem_code_phase_samples = K_blk_samples - static_cast(d_current_prn_length_samples); // rounding error < 1 sample d_rem_code_phase_chips = d_code_freq_chips * d_rem_code_phase_samples / trk_parameters.fs_in; - } void dll_pll_veml_tracking_fpga::save_correlation_results() { - if (d_secondary) { if (d_secondary_code_string->at(d_current_symbol) == '0') @@ -853,13 +833,11 @@ void dll_pll_veml_tracking_fpga::save_correlation_results() d_cloop = false; else d_cloop = true; - } void dll_pll_veml_tracking_fpga::log_data(bool integrating) { - if (d_dump) { // Dump results to file @@ -980,13 +958,11 @@ void dll_pll_veml_tracking_fpga::log_data(bool integrating) LOG(WARNING) << "Exception writing trk dump file " << e.what(); } } - } int32_t dll_pll_veml_tracking_fpga::save_matfile() { - // READ DUMP FILE std::ifstream::pos_type size; int32_t number_of_double_vars = 1; @@ -1228,13 +1204,11 @@ int32_t dll_pll_veml_tracking_fpga::save_matfile() delete[] aux2; delete[] PRN; return 0; - } void dll_pll_veml_tracking_fpga::set_channel(uint32_t channel) { - d_channel = channel; multicorrelator_fpga->set_channel(d_channel); LOG(INFO) << "Tracking Channel set to " << d_channel; @@ -1261,7 +1235,6 @@ void dll_pll_veml_tracking_fpga::set_channel(uint32_t channel) } } } - } @@ -1279,8 +1252,6 @@ void dll_pll_veml_tracking_fpga::stop_tracking() int dll_pll_veml_tracking_fpga::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { - - Gnss_Synchro **out = reinterpret_cast(&output_items[0]); Gnss_Synchro current_synchro_data = Gnss_Synchro(); @@ -1296,33 +1267,33 @@ int dll_pll_veml_tracking_fpga::general_work(int noutput_items __attribute__((un } case 1: // Pull-in { - int64_t acq_trk_diff_samples; - double acq_trk_diff_seconds; - double delta_trk_to_acq_prn_start_samples; + int64_t acq_trk_diff_samples; + double acq_trk_diff_seconds; + double delta_trk_to_acq_prn_start_samples; multicorrelator_fpga->lock_channel(); uint64_t counter_value = multicorrelator_fpga->read_sample_counter(); uint64_t absolute_samples_offset; if (counter_value > (d_acq_sample_stamp + d_acq_code_phase_samples)) - { - // Signal alignment (skip samples until the incoming signal is aligned with local replica) - acq_trk_diff_samples = static_cast(counter_value) - static_cast(d_acq_sample_stamp); - acq_trk_diff_seconds = static_cast(acq_trk_diff_samples) / trk_parameters.fs_in; - delta_trk_to_acq_prn_start_samples = static_cast(acq_trk_diff_samples) - d_acq_code_phase_samples; + { + // Signal alignment (skip samples until the incoming signal is aligned with local replica) + acq_trk_diff_samples = static_cast(counter_value) - static_cast(d_acq_sample_stamp); + acq_trk_diff_seconds = static_cast(acq_trk_diff_samples) / trk_parameters.fs_in; + delta_trk_to_acq_prn_start_samples = static_cast(acq_trk_diff_samples) - d_acq_code_phase_samples; - uint32_t num_frames = ceil((delta_trk_to_acq_prn_start_samples) / d_correlation_length_samples); - absolute_samples_offset = static_cast(d_acq_code_phase_samples + d_acq_sample_stamp + num_frames * d_correlation_length_samples); - } + uint32_t num_frames = ceil((delta_trk_to_acq_prn_start_samples) / d_correlation_length_samples); + absolute_samples_offset = static_cast(d_acq_code_phase_samples + d_acq_sample_stamp + num_frames * d_correlation_length_samples); + } else - { - // test mode + { + // test mode - acq_trk_diff_samples = - static_cast(counter_value) + static_cast(d_acq_sample_stamp); - acq_trk_diff_seconds = static_cast(acq_trk_diff_samples) / trk_parameters.fs_in; - delta_trk_to_acq_prn_start_samples = static_cast(acq_trk_diff_samples) + d_acq_code_phase_samples; + acq_trk_diff_samples = -static_cast(counter_value) + static_cast(d_acq_sample_stamp); + acq_trk_diff_seconds = static_cast(acq_trk_diff_samples) / trk_parameters.fs_in; + delta_trk_to_acq_prn_start_samples = static_cast(acq_trk_diff_samples) + d_acq_code_phase_samples; - absolute_samples_offset = static_cast(delta_trk_to_acq_prn_start_samples); - } + absolute_samples_offset = static_cast(delta_trk_to_acq_prn_start_samples); + } multicorrelator_fpga->set_initial_sample(absolute_samples_offset); d_absolute_samples_offset = absolute_samples_offset; d_sample_counter = absolute_samples_offset; @@ -1357,13 +1328,12 @@ int dll_pll_veml_tracking_fpga::general_work(int noutput_items __attribute__((un // don't leave the HW module blocking the signal path before the first sample arrives // start the first tracking process - run_state_2(current_synchro_data); + run_state_2(current_synchro_data); break; - } case 2: // Wide tracking and symbol synchronization { - run_state_2(current_synchro_data); + run_state_2(current_synchro_data); break; } case 3: // coherent integration (correlation time extension) @@ -1497,9 +1467,9 @@ int dll_pll_veml_tracking_fpga::general_work(int noutput_items __attribute__((un if (current_synchro_data.Flag_valid_symbol_output) { current_synchro_data.fs = static_cast(trk_parameters.fs_in); - // two choices for the reporting of the sample counter: - // either the sample counter position that should be (d_sample_counter_next) - //or the sample counter corresponding to the number of samples that the FPGA actually consumed. + // two choices for the reporting of the sample counter: + // either the sample counter position that should be (d_sample_counter_next) + //or the sample counter corresponding to the number of samples that the FPGA actually consumed. current_synchro_data.Tracking_sample_counter = d_sample_counter_next; *out[0] = current_synchro_data; return 1; @@ -1678,7 +1648,6 @@ void dll_pll_veml_tracking_fpga::run_state_2(Gnss_Synchro ¤t_synchro_data) } } } - } diff --git a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.h b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.h index c0411b142..a280c2cad 100644 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.h +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.h @@ -44,7 +44,6 @@ #include #include #include -#include //#include class dll_pll_veml_tracking_fpga; diff --git a/src/algorithms/tracking/libs/dll_pll_conf_fpga.cc b/src/algorithms/tracking/libs/dll_pll_conf_fpga.cc index 36cdd264b..14ec6ccab 100644 --- a/src/algorithms/tracking/libs/dll_pll_conf_fpga.cc +++ b/src/algorithms/tracking/libs/dll_pll_conf_fpga.cc @@ -37,8 +37,8 @@ Dll_Pll_Conf_Fpga::Dll_Pll_Conf_Fpga() { /* DLL/PLL tracking configuration */ - high_dyn = false; - smoother_length = 10; + high_dyn = false; + smoother_length = 10; fs_in = 0.0; vector_length = 0U; dump = false; diff --git a/src/algorithms/tracking/libs/fpga_multicorrelator.cc b/src/algorithms/tracking/libs/fpga_multicorrelator.cc index b23014af2..a19784fbe 100644 --- a/src/algorithms/tracking/libs/fpga_multicorrelator.cc +++ b/src/algorithms/tracking/libs/fpga_multicorrelator.cc @@ -35,40 +35,36 @@ */ #include "fpga_multicorrelator.h" -#include -#include -#include -#include -#include -#include +#include #include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include #include #include -#include -#include -#include -#include -#include #include // FPGA register access constants -#define PAGE_SIZE 0x10000 -#define MAX_LENGTH_DEVICEIO_NAME 50 -#define CODE_RESAMPLER_NUM_BITS_PRECISION 20 -#define CODE_PHASE_STEP_CHIPS_NUM_NBITS CODE_RESAMPLER_NUM_BITS_PRECISION -#define pwrtwo(x) (1 << (x)) -#define MAX_CODE_RESAMPLER_COUNTER pwrtwo(CODE_PHASE_STEP_CHIPS_NUM_NBITS) // 2^CODE_PHASE_STEP_CHIPS_NUM_NBITS -#define PHASE_CARR_NBITS 32 -#define PHASE_CARR_NBITS_INT 1 -#define PHASE_CARR_NBITS_FRAC PHASE_CARR_NBITS - PHASE_CARR_NBITS_INT -#define LOCAL_CODE_FPGA_CORRELATOR_SELECT_COUNT 0x20000000 -#define LOCAL_CODE_FPGA_CLEAR_ADDRESS_COUNTER 0x10000000 -#define LOCAL_CODE_FPGA_ENABLE_WRITE_MEMORY 0x0C000000 -#define TEST_REGISTER_TRACK_WRITEVAL 0x55AA - - - +#define PAGE_SIZE 0x10000 +#define MAX_LENGTH_DEVICEIO_NAME 50 +#define CODE_RESAMPLER_NUM_BITS_PRECISION 20 +#define CODE_PHASE_STEP_CHIPS_NUM_NBITS CODE_RESAMPLER_NUM_BITS_PRECISION +#define pwrtwo(x) (1 << (x)) +#define MAX_CODE_RESAMPLER_COUNTER pwrtwo(CODE_PHASE_STEP_CHIPS_NUM_NBITS) // 2^CODE_PHASE_STEP_CHIPS_NUM_NBITS +#define PHASE_CARR_NBITS 32 +#define PHASE_CARR_NBITS_INT 1 +#define PHASE_CARR_NBITS_FRAC PHASE_CARR_NBITS - PHASE_CARR_NBITS_INT +#define LOCAL_CODE_FPGA_CORRELATOR_SELECT_COUNT 0x20000000 +#define LOCAL_CODE_FPGA_CLEAR_ADDRESS_COUNTER 0x10000000 +#define LOCAL_CODE_FPGA_ENABLE_WRITE_MEMORY 0x0C000000 +#define TEST_REGISTER_TRACK_WRITEVAL 0x55AA uint64_t fpga_multicorrelator_8sc::read_sample_counter() @@ -111,9 +107,9 @@ void fpga_multicorrelator_8sc::update_local_code(float rem_code_phase_chips) void fpga_multicorrelator_8sc::Carrier_wipeoff_multicorrelator_resampler( float rem_carrier_phase_in_rad, float phase_step_rad, - float carrier_phase_rate_step_rad, + float carrier_phase_rate_step_rad, float rem_code_phase_chips, float code_phase_step_chips, - float code_phase_rate_step_chips, + float code_phase_rate_step_chips, int32_t signal_length_samples) { update_local_code(rem_code_phase_chips); @@ -130,7 +126,7 @@ void fpga_multicorrelator_8sc::Carrier_wipeoff_multicorrelator_resampler( if (nb != sizeof(irq_count)) { std::cout << "Tracking_module Read failed to retrieve 4 bytes!" << std::endl; - std::cout << "Tracking_module Interrupt number " << irq_count << std::endl; + std::cout << "Tracking_module Interrupt number " << irq_count << std::endl; } fpga_multicorrelator_8sc::read_tracking_gps_results(); } @@ -294,7 +290,6 @@ void fpga_multicorrelator_8sc::fpga_configure_tracking_gps_local_code(int32_t PR } if (d_track_pilot) { - d_map_base[PROG_MEMS_ADDR] = LOCAL_CODE_FPGA_CLEAR_ADDRESS_COUNTER; for (k = 0; k < d_code_length_chips * d_code_samples_per_chip; k++) { @@ -410,7 +405,6 @@ void fpga_multicorrelator_8sc::fpga_compute_signal_parameters_in_fpga(void) { d_phase_step_rad_int = -d_phase_step_rad_int; } - } @@ -451,9 +445,9 @@ void fpga_multicorrelator_8sc::read_tracking_gps_results(void) } if (d_track_pilot) { - readval_real = d_map_base[RESULT_REG_REAL_BASE_ADDR + d_n_correlators]; - readval_imag = d_map_base[RESULT_REG_IMAG_BASE_ADDR + d_n_correlators]; - d_Prompt_Data[0] = gr_complex(readval_real, readval_imag); + readval_real = d_map_base[RESULT_REG_REAL_BASE_ADDR + d_n_correlators]; + readval_imag = d_map_base[RESULT_REG_IMAG_BASE_ADDR + d_n_correlators]; + d_Prompt_Data[0] = gr_complex(readval_real, readval_imag); } } @@ -461,8 +455,8 @@ void fpga_multicorrelator_8sc::read_tracking_gps_results(void) void fpga_multicorrelator_8sc::unlock_channel(void) { // unlock the channel to let the next samples go through - d_map_base[DROP_SAMPLES_REG_ADDR] = 1; // unlock the channel - d_map_base[STOP_TRACKING_REG_ADDR] = 1; // set the tracking module back to idle + d_map_base[DROP_SAMPLES_REG_ADDR] = 1; // unlock the channel + d_map_base[STOP_TRACKING_REG_ADDR] = 1; // set the tracking module back to idle } void fpga_multicorrelator_8sc::close_device() @@ -481,4 +475,3 @@ void fpga_multicorrelator_8sc::lock_channel(void) // lock the channel for processing d_map_base[DROP_SAMPLES_REG_ADDR] = 0; // lock the channel } - diff --git a/src/algorithms/tracking/libs/fpga_multicorrelator.h b/src/algorithms/tracking/libs/fpga_multicorrelator.h index 95d5c580a..6229ea0de 100644 --- a/src/algorithms/tracking/libs/fpga_multicorrelator.h +++ b/src/algorithms/tracking/libs/fpga_multicorrelator.h @@ -44,27 +44,26 @@ // FPGA register addresses // write addresses -#define CODE_PHASE_STEP_CHIPS_NUM_REG_ADDR 0 -#define INITIAL_INDEX_REG_BASE_ADDR 1 -#define INITIAL_INTERP_COUNTER_REG_BASE_ADDR 7 -#define NSAMPLES_MINUS_1_REG_ADDR 13 -#define CODE_LENGTH_MINUS_1_REG_ADDR 14 -#define REM_CARR_PHASE_RAD_REG_ADDR 15 -#define PHASE_STEP_RAD_REG_ADDR 16 -#define PROG_MEMS_ADDR 17 -#define DROP_SAMPLES_REG_ADDR 18 -#define INITIAL_COUNTER_VALUE_REG_ADDR_LSW 19 -#define INITIAL_COUNTER_VALUE_REG_ADDR_MSW 20 -#define STOP_TRACKING_REG_ADDR 23 -#define START_FLAG_ADDR 30 +#define CODE_PHASE_STEP_CHIPS_NUM_REG_ADDR 0 +#define INITIAL_INDEX_REG_BASE_ADDR 1 +#define INITIAL_INTERP_COUNTER_REG_BASE_ADDR 7 +#define NSAMPLES_MINUS_1_REG_ADDR 13 +#define CODE_LENGTH_MINUS_1_REG_ADDR 14 +#define REM_CARR_PHASE_RAD_REG_ADDR 15 +#define PHASE_STEP_RAD_REG_ADDR 16 +#define PROG_MEMS_ADDR 17 +#define DROP_SAMPLES_REG_ADDR 18 +#define INITIAL_COUNTER_VALUE_REG_ADDR_LSW 19 +#define INITIAL_COUNTER_VALUE_REG_ADDR_MSW 20 +#define STOP_TRACKING_REG_ADDR 23 +#define START_FLAG_ADDR 30 // read-write addresses -#define TEST_REG_ADDR 31 +#define TEST_REG_ADDR 31 // read addresses -#define RESULT_REG_REAL_BASE_ADDR 1 -#define RESULT_REG_IMAG_BASE_ADDR 7 -#define SAMPLE_COUNTER_REG_ADDR_LSW 13 -#define SAMPLE_COUNTER_REG_ADDR_MSW 14 - +#define RESULT_REG_REAL_BASE_ADDR 1 +#define RESULT_REG_IMAG_BASE_ADDR 7 +#define SAMPLE_COUNTER_REG_ADDR_LSW 13 +#define SAMPLE_COUNTER_REG_ADDR_MSW 14 /*! @@ -74,18 +73,18 @@ class fpga_multicorrelator_8sc { public: fpga_multicorrelator_8sc(int32_t n_correlators, std::string device_name, - uint32_t device_base, int32_t *ca_codes, int32_t *data_codes, uint32_t code_length_chips, bool track_pilot, uint32_t multicorr_type, uint32_t code_samples_per_chip); + uint32_t device_base, int32_t *ca_codes, int32_t *data_codes, uint32_t code_length_chips, bool track_pilot, uint32_t multicorr_type, uint32_t code_samples_per_chip); ~fpga_multicorrelator_8sc(); void set_output_vectors(gr_complex *corr_out, gr_complex *Prompt_Data); void set_local_code_and_taps( - float *shifts_chips, float *prompt_data_shift, int32_t PRN); + float *shifts_chips, float *prompt_data_shift, int32_t PRN); void update_local_code(float rem_code_phase_chips); void Carrier_wipeoff_multicorrelator_resampler( - float rem_carrier_phase_in_rad, float phase_step_rad, - float carrier_phase_rate_step_rad, - float rem_code_phase_chips, float code_phase_step_chips, - float code_phase_rate_step_chips, - int32_t signal_length_samples); + float rem_carrier_phase_in_rad, float phase_step_rad, + float carrier_phase_rate_step_rad, + float rem_code_phase_chips, float code_phase_step_chips, + float code_phase_rate_step_chips, + int32_t signal_length_samples); bool free(); void set_channel(uint32_t channel); void set_initial_sample(uint64_t samples_offset); @@ -144,7 +143,6 @@ private: void fpga_launch_multicorrelator_fpga(void); void read_tracking_gps_results(void); void close_device(void); - }; #endif /* GNSS_SDR_FPGA_MULTICORRELATOR_H_ */ diff --git a/src/core/receiver/control_thread.cc b/src/core/receiver/control_thread.cc index fba66d309..4e66f110d 100644 --- a/src/core/receiver/control_thread.cc +++ b/src/core/receiver/control_thread.cc @@ -274,9 +274,9 @@ int ControlThread::run() cmd_interface_thread_ = std::thread(&ControlThread::telecommand_listener, this); #ifdef ENABLE_FPGA - // Create a task for the acquisition such that id doesn't block the flow of the control thread - fpga_helper_thread_=boost::thread(&GNSSFlowgraph::start_acquisition_helper, - flowgraph_); + // Create a task for the acquisition such that id doesn't block the flow of the control thread + fpga_helper_thread_ = boost::thread(&GNSSFlowgraph::start_acquisition_helper, + flowgraph_); #endif // Main loop to read and process the control messages while (flowgraph_->running() && !stop_) @@ -299,7 +299,7 @@ int ControlThread::run() // The HW reset causes any HW accelerator module that is waiting for more samples to complete its calculations // to trigger an interrupt and finish its signal processing tasks immediately. In this way all SW threads that // are waiting for interrupts in the HW can exit in a normal way. - flowgraph_->perform_hw_reset(); + flowgraph_->perform_hw_reset(); #endif pthread_t id = keyboard_thread_.native_handle(); @@ -308,7 +308,7 @@ int ControlThread::run() #ifdef ENABLE_FPGA - fpga_helper_thread_.try_join_until(boost::chrono::steady_clock::now() + boost::chrono::milliseconds(1000)); + fpga_helper_thread_.try_join_until(boost::chrono::steady_clock::now() + boost::chrono::milliseconds(1000)); #endif diff --git a/src/core/receiver/control_thread.h b/src/core/receiver/control_thread.h index c5cb3f647..23ffa877c 100644 --- a/src/core/receiver/control_thread.h +++ b/src/core/receiver/control_thread.h @@ -168,16 +168,16 @@ private: bool delete_configuration_; unsigned int processed_control_messages_; unsigned int applied_actions_; -//<<<<<<< HEAD -// boost::thread keyboard_thread_; -// boost::thread sysv_queue_thread_; -// boost::thread gps_acq_assist_data_collector_thread_; + //<<<<<<< HEAD + // boost::thread keyboard_thread_; + // boost::thread sysv_queue_thread_; + // boost::thread gps_acq_assist_data_collector_thread_; boost::thread fpga_helper_thread_; -//======= + //======= std::thread keyboard_thread_; std::thread sysv_queue_thread_; std::thread gps_acq_assist_data_collector_thread_; -//>>>>>>> 4fe976ba016fa9c1c64ece88b26a9a93d93a84f4 + //>>>>>>> 4fe976ba016fa9c1c64ece88b26a9a93d93a84f4 void keyboard_listener(); void sysv_queue_listener(); diff --git a/src/core/receiver/gnss_flowgraph.cc b/src/core/receiver/gnss_flowgraph.cc index cd270a002..8c01a9afc 100644 --- a/src/core/receiver/gnss_flowgraph.cc +++ b/src/core/receiver/gnss_flowgraph.cc @@ -212,65 +212,65 @@ void GNSSFlowgraph::connect() for (int i = 0; i < sources_count_; i++) { - try - { - //TODO: Remove this array implementation and create generic multistream connector - //(if a signal source has more than 1 stream, then connect it to the multistream signal conditioner) - if (sig_source_.at(i)->implementation() == "Raw_Array_Signal_Source") - { - //Multichannel Array - std::cout << "ARRAY MODE" << std::endl; - for (int j = 0; j < GNSS_SDR_ARRAY_SIGNAL_CONDITIONER_CHANNELS; j++) - { - std::cout << "connecting ch " << j << std::endl; - top_block_->connect(sig_source_.at(i)->get_right_block(), j, sig_conditioner_.at(i)->get_left_block(), j); - } - } - else - { - //TODO: Create a class interface for SignalSources, derived from GNSSBlockInterface. - //Include GetRFChannels in the interface to avoid read config parameters here - //read the number of RF channels for each front-end - RF_Channels = configuration_->property(sig_source_.at(i)->role() + ".RF_channels", 1); + try + { + //TODO: Remove this array implementation and create generic multistream connector + //(if a signal source has more than 1 stream, then connect it to the multistream signal conditioner) + if (sig_source_.at(i)->implementation() == "Raw_Array_Signal_Source") + { + //Multichannel Array + std::cout << "ARRAY MODE" << std::endl; + for (int j = 0; j < GNSS_SDR_ARRAY_SIGNAL_CONDITIONER_CHANNELS; j++) + { + std::cout << "connecting ch " << j << std::endl; + top_block_->connect(sig_source_.at(i)->get_right_block(), j, sig_conditioner_.at(i)->get_left_block(), j); + } + } + else + { + //TODO: Create a class interface for SignalSources, derived from GNSSBlockInterface. + //Include GetRFChannels in the interface to avoid read config parameters here + //read the number of RF channels for each front-end + RF_Channels = configuration_->property(sig_source_.at(i)->role() + ".RF_channels", 1); - for (int j = 0; j < RF_Channels; j++) - { - //Connect the multichannel signal source to multiple signal conditioners - // GNURADIO max_streams=-1 means infinite ports! - LOG(INFO) << "sig_source_.at(i)->get_right_block()->output_signature()->max_streams()=" << sig_source_.at(i)->get_right_block()->output_signature()->max_streams(); - LOG(INFO) << "sig_conditioner_.at(signal_conditioner_ID)->get_left_block()->input_signature()=" << sig_conditioner_.at(signal_conditioner_ID)->get_left_block()->input_signature()->max_streams(); + for (int j = 0; j < RF_Channels; j++) + { + //Connect the multichannel signal source to multiple signal conditioners + // GNURADIO max_streams=-1 means infinite ports! + LOG(INFO) << "sig_source_.at(i)->get_right_block()->output_signature()->max_streams()=" << sig_source_.at(i)->get_right_block()->output_signature()->max_streams(); + LOG(INFO) << "sig_conditioner_.at(signal_conditioner_ID)->get_left_block()->input_signature()=" << sig_conditioner_.at(signal_conditioner_ID)->get_left_block()->input_signature()->max_streams(); - if (sig_source_.at(i)->get_right_block()->output_signature()->max_streams() > 1) - { - LOG(INFO) << "connecting sig_source_ " << i << " stream " << j << " to conditioner " << j; - top_block_->connect(sig_source_.at(i)->get_right_block(), j, sig_conditioner_.at(signal_conditioner_ID)->get_left_block(), 0); - } - else - { - if (j == 0) - { - // RF_channel 0 backward compatibility with single channel sources - LOG(INFO) << "connecting sig_source_ " << i << " stream " << 0 << " to conditioner " << j; - top_block_->connect(sig_source_.at(i)->get_right_block(), 0, sig_conditioner_.at(signal_conditioner_ID)->get_left_block(), 0); - } - else - { - // Multiple channel sources using multiple output blocks of single channel (requires RF_channel selector in call) - LOG(INFO) << "connecting sig_source_ " << i << " stream " << j << " to conditioner " << j; - top_block_->connect(sig_source_.at(i)->get_right_block(j), 0, sig_conditioner_.at(signal_conditioner_ID)->get_left_block(), 0); - } - } - signal_conditioner_ID++; - } - } - } - catch (const std::exception& e) - { - LOG(WARNING) << "Can't connect signal source " << i << " to signal conditioner " << i; - LOG(ERROR) << e.what(); - top_block_->disconnect_all(); - return; - } + if (sig_source_.at(i)->get_right_block()->output_signature()->max_streams() > 1) + { + LOG(INFO) << "connecting sig_source_ " << i << " stream " << j << " to conditioner " << j; + top_block_->connect(sig_source_.at(i)->get_right_block(), j, sig_conditioner_.at(signal_conditioner_ID)->get_left_block(), 0); + } + else + { + if (j == 0) + { + // RF_channel 0 backward compatibility with single channel sources + LOG(INFO) << "connecting sig_source_ " << i << " stream " << 0 << " to conditioner " << j; + top_block_->connect(sig_source_.at(i)->get_right_block(), 0, sig_conditioner_.at(signal_conditioner_ID)->get_left_block(), 0); + } + else + { + // Multiple channel sources using multiple output blocks of single channel (requires RF_channel selector in call) + LOG(INFO) << "connecting sig_source_ " << i << " stream " << j << " to conditioner " << j; + top_block_->connect(sig_source_.at(i)->get_right_block(j), 0, sig_conditioner_.at(signal_conditioner_ID)->get_left_block(), 0); + } + } + signal_conditioner_ID++; + } + } + } + catch (const std::exception& e) + { + LOG(WARNING) << "Can't connect signal source " << i << " to signal conditioner " << i; + LOG(ERROR) << e.what(); + top_block_->disconnect_all(); + return; + } } DLOG(INFO) << "Signal source connected to signal conditioner"; @@ -306,7 +306,6 @@ void GNSSFlowgraph::connect() } else { - //create a hardware-defined gnss_synchro pulse for the observables block try { @@ -362,7 +361,6 @@ void GNSSFlowgraph::connect() uint32_t fs = configuration_->property("GNSS-SDR.internal_fs_sps", 0); for (unsigned int i = 0; i < channels_count_; i++) { - #ifndef ENABLE_FPGA if (configuration_->property(sig_source_.at(0)->role() + ".enable_FPGA", false) == false) { @@ -670,7 +668,7 @@ void GNSSFlowgraph::connect() LOG(INFO) << "Channel " << i << " assigned to " << channels_.at(i)->get_signal(); if (channels_state_[i] == 1) { - channels_.at(i)->start_acquisition(); + channels_.at(i)->start_acquisition(); LOG(INFO) << "Channel " << i << " connected to observables and ready for acquisition"; } else @@ -703,114 +701,114 @@ void GNSSFlowgraph::disconnect() #ifdef ENABLE_FPGA if (configuration_->property(sig_source_.at(0)->role() + ".enable_FPGA", false) == false) - { - for (int i = 0; i < sources_count_; i++) - { - try - { - // TODO: Remove this array implementation and create generic multistream connector - // (if a signal source has more than 1 stream, then connect it to the multistream signal conditioner) - if (sig_source_.at(i)->implementation() == "Raw_Array_Signal_Source") - { - //Multichannel Array - for (int j = 0; j < GNSS_SDR_ARRAY_SIGNAL_CONDITIONER_CHANNELS; j++) - { - top_block_->disconnect(sig_source_.at(i)->get_right_block(), j, sig_conditioner_.at(i)->get_left_block(), j); - } - } - else - { - // TODO: Create a class interface for SignalSources, derived from GNSSBlockInterface. - // Include GetRFChannels in the interface to avoid read config parameters here - // read the number of RF channels for each front-end - RF_Channels = configuration_->property(sig_source_.at(i)->role() + ".RF_channels", 1); + { + for (int i = 0; i < sources_count_; i++) + { + try + { + // TODO: Remove this array implementation and create generic multistream connector + // (if a signal source has more than 1 stream, then connect it to the multistream signal conditioner) + if (sig_source_.at(i)->implementation() == "Raw_Array_Signal_Source") + { + //Multichannel Array + for (int j = 0; j < GNSS_SDR_ARRAY_SIGNAL_CONDITIONER_CHANNELS; j++) + { + top_block_->disconnect(sig_source_.at(i)->get_right_block(), j, sig_conditioner_.at(i)->get_left_block(), j); + } + } + else + { + // TODO: Create a class interface for SignalSources, derived from GNSSBlockInterface. + // Include GetRFChannels in the interface to avoid read config parameters here + // read the number of RF channels for each front-end + RF_Channels = configuration_->property(sig_source_.at(i)->role() + ".RF_channels", 1); - for (int j = 0; j < RF_Channels; j++) - { - if (sig_source_.at(i)->get_right_block()->output_signature()->max_streams() > 1) - { - top_block_->disconnect(sig_source_.at(i)->get_right_block(), j, sig_conditioner_.at(signal_conditioner_ID)->get_left_block(), 0); - } - else - { - if (j == 0) - { - // RF_channel 0 backward compatibility with single channel sources - top_block_->disconnect(sig_source_.at(i)->get_right_block(), 0, sig_conditioner_.at(signal_conditioner_ID)->get_left_block(), 0); - } - else - { - // Multiple channel sources using multiple output blocks of single channel (requires RF_channel selector in call) - top_block_->disconnect(sig_source_.at(i)->get_right_block(j), 0, sig_conditioner_.at(signal_conditioner_ID)->get_left_block(), 0); - } - } - signal_conditioner_ID++; - } - } - } - catch (const std::exception& e) - { - LOG(INFO) << "Can't disconnect signal source " << i << " to signal conditioner " << i << ": " << e.what(); - top_block_->disconnect_all(); - return; - } - } - } + for (int j = 0; j < RF_Channels; j++) + { + if (sig_source_.at(i)->get_right_block()->output_signature()->max_streams() > 1) + { + top_block_->disconnect(sig_source_.at(i)->get_right_block(), j, sig_conditioner_.at(signal_conditioner_ID)->get_left_block(), 0); + } + else + { + if (j == 0) + { + // RF_channel 0 backward compatibility with single channel sources + top_block_->disconnect(sig_source_.at(i)->get_right_block(), 0, sig_conditioner_.at(signal_conditioner_ID)->get_left_block(), 0); + } + else + { + // Multiple channel sources using multiple output blocks of single channel (requires RF_channel selector in call) + top_block_->disconnect(sig_source_.at(i)->get_right_block(j), 0, sig_conditioner_.at(signal_conditioner_ID)->get_left_block(), 0); + } + } + signal_conditioner_ID++; + } + } + } + catch (const std::exception& e) + { + LOG(INFO) << "Can't disconnect signal source " << i << " to signal conditioner " << i << ": " << e.what(); + top_block_->disconnect_all(); + return; + } + } + } #else - for (int i = 0; i < sources_count_; i++) - { - try - { - // TODO: Remove this array implementation and create generic multistream connector - // (if a signal source has more than 1 stream, then connect it to the multistream signal conditioner) - if (sig_source_.at(i)->implementation() == "Raw_Array_Signal_Source") - { - //Multichannel Array - for (int j = 0; j < GNSS_SDR_ARRAY_SIGNAL_CONDITIONER_CHANNELS; j++) - { - top_block_->disconnect(sig_source_.at(i)->get_right_block(), j, sig_conditioner_.at(i)->get_left_block(), j); - } - } - else - { - // TODO: Create a class interface for SignalSources, derived from GNSSBlockInterface. - // Include GetRFChannels in the interface to avoid read config parameters here - // read the number of RF channels for each front-end - RF_Channels = configuration_->property(sig_source_.at(i)->role() + ".RF_channels", 1); + for (int i = 0; i < sources_count_; i++) + { + try + { + // TODO: Remove this array implementation and create generic multistream connector + // (if a signal source has more than 1 stream, then connect it to the multistream signal conditioner) + if (sig_source_.at(i)->implementation() == "Raw_Array_Signal_Source") + { + //Multichannel Array + for (int j = 0; j < GNSS_SDR_ARRAY_SIGNAL_CONDITIONER_CHANNELS; j++) + { + top_block_->disconnect(sig_source_.at(i)->get_right_block(), j, sig_conditioner_.at(i)->get_left_block(), j); + } + } + else + { + // TODO: Create a class interface for SignalSources, derived from GNSSBlockInterface. + // Include GetRFChannels in the interface to avoid read config parameters here + // read the number of RF channels for each front-end + RF_Channels = configuration_->property(sig_source_.at(i)->role() + ".RF_channels", 1); - for (int j = 0; j < RF_Channels; j++) - { - if (sig_source_.at(i)->get_right_block()->output_signature()->max_streams() > 1) - { - top_block_->disconnect(sig_source_.at(i)->get_right_block(), j, sig_conditioner_.at(signal_conditioner_ID)->get_left_block(), 0); - } - else - { - if (j == 0) - { - // RF_channel 0 backward compatibility with single channel sources - top_block_->disconnect(sig_source_.at(i)->get_right_block(), 0, sig_conditioner_.at(signal_conditioner_ID)->get_left_block(), 0); - } - else - { - // Multiple channel sources using multiple output blocks of single channel (requires RF_channel selector in call) - top_block_->disconnect(sig_source_.at(i)->get_right_block(j), 0, sig_conditioner_.at(signal_conditioner_ID)->get_left_block(), 0); - } - } - signal_conditioner_ID++; - } - } - } - catch (const std::exception& e) - { - LOG(INFO) << "Can't disconnect signal source " << i << " to signal conditioner " << i << ": " << e.what(); - top_block_->disconnect_all(); - return; - } - } + for (int j = 0; j < RF_Channels; j++) + { + if (sig_source_.at(i)->get_right_block()->output_signature()->max_streams() > 1) + { + top_block_->disconnect(sig_source_.at(i)->get_right_block(), j, sig_conditioner_.at(signal_conditioner_ID)->get_left_block(), 0); + } + else + { + if (j == 0) + { + // RF_channel 0 backward compatibility with single channel sources + top_block_->disconnect(sig_source_.at(i)->get_right_block(), 0, sig_conditioner_.at(signal_conditioner_ID)->get_left_block(), 0); + } + else + { + // Multiple channel sources using multiple output blocks of single channel (requires RF_channel selector in call) + top_block_->disconnect(sig_source_.at(i)->get_right_block(j), 0, sig_conditioner_.at(signal_conditioner_ID)->get_left_block(), 0); + } + } + signal_conditioner_ID++; + } + } + } + catch (const std::exception& e) + { + LOG(INFO) << "Can't disconnect signal source " << i << " to signal conditioner " << i << ": " << e.what(); + top_block_->disconnect_all(); + return; + } + } #endif #ifdef ENABLE_FPGA @@ -1133,7 +1131,7 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what) channels_[ch_index]->start_acquisition(); #else // create a task for the FPGA such that it doesn't stop the flow - std::thread tmp_thread(&ChannelInterface::start_acquisition,channels_[ch_index]); + std::thread tmp_thread(&ChannelInterface::start_acquisition, channels_[ch_index]); tmp_thread.detach(); #endif } @@ -1210,7 +1208,7 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what) channels_[i]->start_acquisition(); #else // create a task for the FPGA such that it doesn't stop the flow - std::thread tmp_thread(&ChannelInterface::start_acquisition,channels_[i]); + std::thread tmp_thread(&ChannelInterface::start_acquisition, channels_[i]); tmp_thread.detach(); #endif } @@ -1231,7 +1229,7 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what) channels_[who]->start_acquisition(); #else // create a task for the FPGA such that it doesn't stop the flow - std::thread tmp_thread(&ChannelInterface::start_acquisition,channels_[who]); + std::thread tmp_thread(&ChannelInterface::start_acquisition, channels_[who]); tmp_thread.detach(); #endif } @@ -1366,7 +1364,7 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what) channels_[ch_index]->start_acquisition(); #else // create a task for the FPGA such that it doesn't stop the flow - std::thread tmp_thread(&ChannelInterface::start_acquisition,channels_[ch_index]); + std::thread tmp_thread(&ChannelInterface::start_acquisition, channels_[ch_index]); tmp_thread.detach(); #endif } @@ -1400,7 +1398,7 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what) channels_[ch_index]->start_acquisition(); #else // create a task for the FPGA such that it doesn't stop the flow - std::thread tmp_thread(&ChannelInterface::start_acquisition,channels_[ch_index]); + std::thread tmp_thread(&ChannelInterface::start_acquisition, channels_[ch_index]); tmp_thread.detach(); #endif } @@ -1435,7 +1433,7 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what) channels_[ch_index]->start_acquisition(); #else // create a task for the FPGA such that it doesn't stop the flow - std::thread tmp_thread(&ChannelInterface::start_acquisition,channels_[ch_index]); + std::thread tmp_thread(&ChannelInterface::start_acquisition, channels_[ch_index]); tmp_thread.detach(); #endif } @@ -1531,15 +1529,12 @@ void GNSSFlowgraph::start_acquisition_helper() } - void GNSSFlowgraph::perform_hw_reset() { - - // a stop acquisition command causes the SW to reset the HW + // a stop acquisition command causes the SW to reset the HW std::shared_ptr channel_ptr; channel_ptr = std::dynamic_pointer_cast(channels_.at(0)); channel_ptr->acquisition()->stop_acquisition(); - } #endif diff --git a/src/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test_fpga.cc b/src/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test_fpga.cc index 877ca888b..c8024eb2c 100644 --- a/src/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test_fpga.cc +++ b/src/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test_fpga.cc @@ -30,62 +30,62 @@ * ------------------------------------------------------------------------- */ -#include -#include -#include +#include "GPS_L1_CA.h" +#include "gnss_block_factory.h" +#include "gnss_block_interface.h" +#include "gnss_satellite.h" +#include "gnss_sdr_fpga_sample_counter.h" +#include "gnss_synchro.h" +#include "gnuplot_i.h" +#include "gps_l1_ca_dll_pll_tracking.h" +#include "gps_l1_ca_dll_pll_tracking_fpga.h" +#include "gps_l1_ca_telemetry_decoder.h" +#include "hybrid_observables.h" +#include "in_memory_configuration.h" +#include "observable_tests_flags.h" +#include "observables_dump_reader.h" +#include "signal_generator_flags.h" +#include "telemetry_decoder_interface.h" +#include "test_flags.h" +#include "tlm_dump_reader.h" +#include "tracking_dump_reader.h" +#include "tracking_interface.h" +#include "tracking_tests_flags.h" +#include "tracking_true_obs_reader.h" +#include "true_observables_reader.h" #include -#include #include #include #include -#include -#include +#include #include #include #include #include +#include +#include #include -#include "GPS_L1_CA.h" -#include "gnss_satellite.h" -#include "gnss_block_factory.h" -#include "gnss_block_interface.h" -#include "tracking_interface.h" -#include "telemetry_decoder_interface.h" -#include "in_memory_configuration.h" -#include "gnss_synchro.h" -#include "gps_l1_ca_telemetry_decoder.h" -#include "tracking_true_obs_reader.h" -#include "true_observables_reader.h" -#include "tracking_dump_reader.h" -#include "observables_dump_reader.h" -#include "tlm_dump_reader.h" -#include "gps_l1_ca_dll_pll_tracking.h" -#include "gps_l1_ca_dll_pll_tracking_fpga.h" -#include "hybrid_observables.h" -#include "signal_generator_flags.h" -#include "gnss_sdr_fpga_sample_counter.h" -#include "test_flags.h" -#include "tracking_tests_flags.h" -#include "observable_tests_flags.h" -#include "gnuplot_i.h" +#include +#include +#include // threads -#include // for pthread stuff -#include // for open, O_RDWR, O_SYNC -#include // for cout, endl -#include // for mmap +#include // for open, O_RDWR, O_SYNC +#include // for cout, endl +#include // for pthread stuff +#include // for mmap -#define TEST_OBS_MAX_INPUT_COMPLEX_SAMPLES_TOTAL 8192 // maximum DMA sample block size in complex samples -#define TEST_OBS_COMPLEX_SAMPLE_SIZE 2 // sample size in bytes -#define TEST_OBS_NUM_QUEUES 2 // number of queues (1 for GPS L1/Galileo E1, and 1 for GPS L5/Galileo E5) -#define TEST_OBS_DOWNAMPLING_FILTER_INIT_SAMPLES 100 // some samples to initialize the state of the downsampling filter +#define TEST_OBS_MAX_INPUT_COMPLEX_SAMPLES_TOTAL 8192 // maximum DMA sample block size in complex samples +#define TEST_OBS_COMPLEX_SAMPLE_SIZE 2 // sample size in bytes +#define TEST_OBS_NUM_QUEUES 2 // number of queues (1 for GPS L1/Galileo E1, and 1 for GPS L5/Galileo E5) +#define TEST_OBS_DOWNAMPLING_FILTER_INIT_SAMPLES 100 // some samples to initialize the state of the downsampling filter #define TEST_OBS_DOWNSAMPLING_FILTER_DELAY 48 // HW related options -bool test_observables_show_results_table = 0; // 1 => show matrix of (doppler, (max value, power sum)) results (only if test_observables_doppler_control_in_sw = 1), 0=> do not show it -bool test_observables_skip_samples_already_used = 1; // if test_observables_doppler_control_in_sw = 1 and test_observables_skip_samples_already_used = 1 => for each PRN loop skip the samples used in the previous PRN loops - // (exactly in the same way as the SW) +bool test_observables_show_results_table = 0; // 1 => show matrix of (doppler, (max value, power sum)) results (only if test_observables_doppler_control_in_sw = 1), 0=> do not show it +bool test_observables_skip_samples_already_used = 1; // if test_observables_doppler_control_in_sw = 1 and test_observables_skip_samples_already_used = 1 => for each PRN loop skip the samples used in the previous PRN loops + // (exactly in the same way as the SW) class HybridObservablesTest_msg_rx_Fpga; @@ -316,16 +316,17 @@ const unsigned int TEST_OBS_TEST_REGISTER_TRACK_WRITEVAL = 0x55AA; void setup_fpga_switch_obs_test(void) { int switch_device_descriptor; // driver descriptor - volatile unsigned *switch_map_base; // driver memory map + volatile unsigned* switch_map_base; // driver memory map if ((switch_device_descriptor = open("/dev/uio1", O_RDWR | O_SYNC)) == -1) { - LOG(WARNING) << "Cannot open deviceio" << "/dev/uio1"; + LOG(WARNING) << "Cannot open deviceio" + << "/dev/uio1"; } - switch_map_base = reinterpret_cast(mmap(nullptr, TEST_OBS_PAGE_SIZE, + switch_map_base = reinterpret_cast(mmap(nullptr, TEST_OBS_PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, switch_device_descriptor, 0)); - if (switch_map_base == reinterpret_cast(-1)) + if (switch_map_base == reinterpret_cast(-1)) { LOG(WARNING) << "Cannot map the FPGA switch module into tracking memory"; std::cout << "Could not map switch memory." << std::endl; @@ -348,7 +349,7 @@ void setup_fpga_switch_obs_test(void) LOG(INFO) << "Test register sanity check success !"; } - switch_map_base[0] = 0; //0 -> DMA to queue 0, 1 -> DMA to queue 1, 2 -> A/Ds to queues + switch_map_base[0] = 0; //0 -> DMA to queue 0, 1 -> DMA to queue 1, 2 -> A/Ds to queues } @@ -356,128 +357,127 @@ static pthread_mutex_t mutex_obs_test = PTHREAD_MUTEX_INITIALIZER; volatile unsigned int send_samples_start_obs_test = 0; -int8_t input_samples_obs_test[TEST_OBS_MAX_INPUT_COMPLEX_SAMPLES_TOTAL*TEST_OBS_COMPLEX_SAMPLE_SIZE]; // re - im -int8_t input_samples_dma_obs_test[TEST_OBS_MAX_INPUT_COMPLEX_SAMPLES_TOTAL*TEST_OBS_COMPLEX_SAMPLE_SIZE*TEST_OBS_NUM_QUEUES]; +int8_t input_samples_obs_test[TEST_OBS_MAX_INPUT_COMPLEX_SAMPLES_TOTAL * TEST_OBS_COMPLEX_SAMPLE_SIZE]; // re - im +int8_t input_samples_dma_obs_test[TEST_OBS_MAX_INPUT_COMPLEX_SAMPLES_TOTAL * TEST_OBS_COMPLEX_SAMPLE_SIZE * TEST_OBS_NUM_QUEUES]; -struct DMA_handler_args_obs_test { +struct DMA_handler_args_obs_test +{ std::string file; unsigned int nsamples_tx; unsigned int skip_used_samples; - unsigned int freq_band; // 0 for GPS L1/ Galileo E1, 1 for GPS L5/Galileo E5 + unsigned int freq_band; // 0 for GPS L1/ Galileo E1, 1 for GPS L5/Galileo E5 }; -void *handler_DMA_obs_test(void *arguments) +void* handler_DMA_obs_test(void* arguments) { + // DMA process that configures the DMA to send the samples to the acquisition engine + int tx_fd; // DMA descriptor + FILE* rx_signal_file_id; // Input file descriptor + bool file_completed = false; // flag to indicate if the file is completed + unsigned int nsamples_block; // number of samples to send in the next DMA block of samples + unsigned int nread_elements; // number of elements effectively read from the input file + unsigned int nsamples = 0; // number of complex samples effectively transferred + unsigned int index0, dma_index = 0; // counters used for putting the samples in the order expected by the DMA - // DMA process that configures the DMA to send the samples to the acquisition engine - int tx_fd; // DMA descriptor - FILE *rx_signal_file_id; // Input file descriptor - bool file_completed = false; // flag to indicate if the file is completed - unsigned int nsamples_block; // number of samples to send in the next DMA block of samples - unsigned int nread_elements; // number of elements effectively read from the input file - unsigned int nsamples = 0; // number of complex samples effectively transferred - unsigned int index0, dma_index = 0; // counters used for putting the samples in the order expected by the DMA + unsigned int nsamples_transmitted; - unsigned int nsamples_transmitted; + struct DMA_handler_args* args = (struct DMA_handler_args*)arguments; - struct DMA_handler_args *args = (struct DMA_handler_args *) arguments; + unsigned int nsamples_tx = args->nsamples_tx; + std::string file = args->file; // input filename + unsigned int skip_used_samples = args->skip_used_samples; - unsigned int nsamples_tx = args->nsamples_tx; - std::string file = args->file; // input filename - unsigned int skip_used_samples = args->skip_used_samples; + // open DMA device + tx_fd = open("/dev/loop_tx", O_WRONLY); + if (tx_fd < 0) + { + std::cout << "DMA can't open loop device" << std::endl; + exit(1); + } + else - // open DMA device - tx_fd = open("/dev/loop_tx", O_WRONLY); - if ( tx_fd < 0 ) - { - std::cout << "DMA can't open loop device" << std::endl; - exit(1); - } - else + // open input file + rx_signal_file_id = fopen(file.c_str(), "rb"); + if (rx_signal_file_id == NULL) + { + std::cout << "DMA can't open input file" << std::endl; + exit(1); + } + while (send_samples_start_obs_test == 0) + ; // wait until acquisition starts + // skip initial samples + int skip_samples = (int)FLAGS_skip_samples; - // open input file - rx_signal_file_id = fopen(file.c_str(), "rb"); - if (rx_signal_file_id == NULL) - { - std::cout << "DMA can't open input file" << std::endl; - exit(1); - } - while(send_samples_start_obs_test == 0); // wait until acquisition starts - // skip initial samples - int skip_samples = (int) FLAGS_skip_samples; + fseek(rx_signal_file_id, (skip_samples + skip_used_samples) * 2, SEEK_SET); - fseek( rx_signal_file_id, (skip_samples + skip_used_samples)*2, SEEK_SET ); + usleep(50000); // wait some time to give time to the main thread to start the acquisition module - usleep(50000); // wait some time to give time to the main thread to start the acquisition module + while (file_completed == false) + { + if (nsamples_tx - nsamples > TEST_OBS_MAX_INPUT_COMPLEX_SAMPLES_TOTAL) + { + nsamples_block = TEST_OBS_MAX_INPUT_COMPLEX_SAMPLES_TOTAL; + } + else + { + nsamples_block = nsamples_tx - nsamples; // remaining samples to be sent + file_completed = true; + } - while (file_completed == false) - { - if (nsamples_tx - nsamples > TEST_OBS_MAX_INPUT_COMPLEX_SAMPLES_TOTAL) - { - nsamples_block = TEST_OBS_MAX_INPUT_COMPLEX_SAMPLES_TOTAL; - } - else - { - nsamples_block = nsamples_tx - nsamples; // remaining samples to be sent - file_completed = true; - } + nread_elements = fread(input_samples_obs_test, sizeof(int8_t), nsamples_block * TEST_OBS_COMPLEX_SAMPLE_SIZE, rx_signal_file_id); - nread_elements = fread(input_samples_obs_test, sizeof(int8_t), nsamples_block*TEST_OBS_COMPLEX_SAMPLE_SIZE, rx_signal_file_id); + if (nread_elements != nsamples_block * TEST_OBS_COMPLEX_SAMPLE_SIZE) + { + std::cout << "file completed" << std::endl; + file_completed = true; + } - if (nread_elements != nsamples_block * TEST_OBS_COMPLEX_SAMPLE_SIZE) - { - std::cout << "file completed" << std::endl; - file_completed = true; - } + nsamples += (nread_elements / TEST_OBS_COMPLEX_SAMPLE_SIZE); - nsamples+=(nread_elements/TEST_OBS_COMPLEX_SAMPLE_SIZE); - - if (nread_elements > 0) - { - // for the 32-BIT DMA - dma_index = 0; - for (index0 = 0;index0 < (nread_elements);index0+=TEST_OBS_COMPLEX_SAMPLE_SIZE) - { - if (args->freq_band == 0) - { - // channel 1 (queue 1) -> E5/L5 - input_samples_dma_obs_test[dma_index] = 0; - input_samples_dma_obs_test[dma_index+1] = 0; - // channel 0 (queue 0) -> E1/L1 - input_samples_dma_obs_test[dma_index+2] = input_samples_obs_test[index0]; - input_samples_dma_obs_test[dma_index+3] = input_samples_obs_test[index0+1]; - } - else - { - // channel 1 (queue 1) -> E5/L5 - input_samples_dma_obs_test[dma_index] = input_samples_obs_test[index0]; - input_samples_dma_obs_test[dma_index+1] = input_samples_obs_test[index0+1]; - // channel 0 (queue 0) -> E1/L1 - input_samples_dma_obs_test[dma_index+2] = 0; - input_samples_dma_obs_test[dma_index+3] = 0; - } - dma_index += 4; - } - nsamples_transmitted = write(tx_fd, &input_samples_dma_obs_test[0], nread_elements*TEST_OBS_NUM_QUEUES); - if (nsamples_transmitted != nread_elements*TEST_OBS_NUM_QUEUES) - { - std::cout << "Error : DMA could not send all the requested samples" << std::endl; - } - } - } + if (nread_elements > 0) + { + // for the 32-BIT DMA + dma_index = 0; + for (index0 = 0; index0 < (nread_elements); index0 += TEST_OBS_COMPLEX_SAMPLE_SIZE) + { + if (args->freq_band == 0) + { + // channel 1 (queue 1) -> E5/L5 + input_samples_dma_obs_test[dma_index] = 0; + input_samples_dma_obs_test[dma_index + 1] = 0; + // channel 0 (queue 0) -> E1/L1 + input_samples_dma_obs_test[dma_index + 2] = input_samples_obs_test[index0]; + input_samples_dma_obs_test[dma_index + 3] = input_samples_obs_test[index0 + 1]; + } + else + { + // channel 1 (queue 1) -> E5/L5 + input_samples_dma_obs_test[dma_index] = input_samples_obs_test[index0]; + input_samples_dma_obs_test[dma_index + 1] = input_samples_obs_test[index0 + 1]; + // channel 0 (queue 0) -> E1/L1 + input_samples_dma_obs_test[dma_index + 2] = 0; + input_samples_dma_obs_test[dma_index + 3] = 0; + } + dma_index += 4; + } + nsamples_transmitted = write(tx_fd, &input_samples_dma_obs_test[0], nread_elements * TEST_OBS_NUM_QUEUES); + if (nsamples_transmitted != nread_elements * TEST_OBS_NUM_QUEUES) + { + std::cout << "Error : DMA could not send all the requested samples" << std::endl; + } + } + } - close(tx_fd); - fclose(rx_signal_file_id); - return NULL; - + close(tx_fd); + fclose(rx_signal_file_id); + return NULL; } bool HybridObservablesTestFpga::acquire_signal() { - - pthread_t thread_DMA; + pthread_t thread_DMA; // 1. Setup GNU Radio flowgraph (file_source -> Acquisition_10m) gr::top_block_sptr top_block; @@ -508,7 +508,6 @@ bool HybridObservablesTestFpga::acquire_signal() args.freq_band = 0; acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); - } else if (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") == 0) { @@ -521,7 +520,6 @@ bool HybridObservablesTestFpga::acquire_signal() args.freq_band = 0; acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); - } else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking_Fpga") == 0) @@ -535,7 +533,6 @@ bool HybridObservablesTestFpga::acquire_signal() args.freq_band = 1; acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); - } else if (implementation.compare("GPS_L5_DLL_PLL_Tracking_Fpga") == 0) { @@ -548,7 +545,6 @@ bool HybridObservablesTestFpga::acquire_signal() args.freq_band = 1; acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); - } else { @@ -603,143 +599,135 @@ bool HybridObservablesTestFpga::acquire_signal() setup_fpga_switch_obs_test(); - unsigned int nsamples_to_transfer; - if (implementation.compare("GPS_L1_CA_DLL_PLL_Tracking_Fpga") == 0) - { - nsamples_to_transfer = static_cast(std::round(static_cast(baseband_sampling_freq) / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS))); - } - else if (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") == 0) - { - nsamples_to_transfer = static_cast(std::round(static_cast(baseband_sampling_freq) / (GALILEO_E1_CODE_CHIP_RATE_HZ / GALILEO_E1_B_CODE_LENGTH_CHIPS))); - } - else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking_Fpga") == 0) - { - nsamples_to_transfer = static_cast(std::round(static_cast(baseband_sampling_freq) / (GALILEO_E5A_CODE_CHIP_RATE_HZ / GALILEO_E5A_CODE_LENGTH_CHIPS))); - } - else // (if (implementation.compare("GPS_L5_DLL_PLL_Tracking_Fpga") == 0)) - { - nsamples_to_transfer = static_cast(std::round(static_cast(baseband_sampling_freq) / (GPS_L5I_CODE_RATE_HZ / GPS_L5I_CODE_LENGTH_CHIPS))); - } + unsigned int nsamples_to_transfer; + if (implementation.compare("GPS_L1_CA_DLL_PLL_Tracking_Fpga") == 0) + { + nsamples_to_transfer = static_cast(std::round(static_cast(baseband_sampling_freq) / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS))); + } + else if (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") == 0) + { + nsamples_to_transfer = static_cast(std::round(static_cast(baseband_sampling_freq) / (GALILEO_E1_CODE_CHIP_RATE_HZ / GALILEO_E1_B_CODE_LENGTH_CHIPS))); + } + else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking_Fpga") == 0) + { + nsamples_to_transfer = static_cast(std::round(static_cast(baseband_sampling_freq) / (GALILEO_E5A_CODE_CHIP_RATE_HZ / GALILEO_E5A_CODE_LENGTH_CHIPS))); + } + else // (if (implementation.compare("GPS_L5_DLL_PLL_Tracking_Fpga") == 0)) + { + nsamples_to_transfer = static_cast(std::round(static_cast(baseband_sampling_freq) / (GPS_L5I_CODE_RATE_HZ / GPS_L5I_CODE_LENGTH_CHIPS))); + } - int acq_doppler_max = config->property("Acquisition.doppler_max", FLAGS_external_signal_acquisition_doppler_max_hz); - int acq_doppler_step = config->property("Acquisition.doppler_step", FLAGS_external_signal_acquisition_doppler_step_hz); + int acq_doppler_max = config->property("Acquisition.doppler_max", FLAGS_external_signal_acquisition_doppler_max_hz); + int acq_doppler_step = config->property("Acquisition.doppler_step", FLAGS_external_signal_acquisition_doppler_step_hz); + for (unsigned int PRN = 1; PRN < MAX_PRN_IDX; PRN++) + { + tmp_gnss_synchro.PRN = PRN; - for (unsigned int PRN = 1; PRN < MAX_PRN_IDX; PRN++) - { + acquisition->stop_acquisition(); // reset the whole system including the sample counters + acquisition->set_doppler_max(acq_doppler_max); + acquisition->set_doppler_step(acq_doppler_step); + acquisition->set_gnss_synchro(&tmp_gnss_synchro); + acquisition->init(); + acquisition->set_local_code(); - tmp_gnss_synchro.PRN = PRN; - - acquisition->stop_acquisition(); // reset the whole system including the sample counters - acquisition->set_doppler_max(acq_doppler_max); - acquisition->set_doppler_step(acq_doppler_step); - acquisition->set_gnss_synchro(&tmp_gnss_synchro); - acquisition->init(); - acquisition->set_local_code(); - - args.file = file; + args.file = file; - send_samples_start_obs_test = 0; + send_samples_start_obs_test = 0; - if ((implementation.compare("GPS_L1_CA_DLL_PLL_Tracking_Fpga") == 0) or (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") == 0)) - { + if ((implementation.compare("GPS_L1_CA_DLL_PLL_Tracking_Fpga") == 0) or (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") == 0)) + { + args.skip_used_samples = -TEST_OBS_DOWNAMPLING_FILTER_INIT_SAMPLES; - args.skip_used_samples = - TEST_OBS_DOWNAMPLING_FILTER_INIT_SAMPLES; + args.nsamples_tx = TEST_OBS_DOWNAMPLING_FILTER_INIT_SAMPLES + TEST_OBS_DOWNSAMPLING_FILTER_DELAY; - args.nsamples_tx = TEST_OBS_DOWNAMPLING_FILTER_INIT_SAMPLES + TEST_OBS_DOWNSAMPLING_FILTER_DELAY; + if (pthread_create(&thread_DMA, NULL, handler_DMA_obs_test, (void*)&args) < 0) + { + std::cout << "ERROR cannot create DMA Process" << std::endl; + } + pthread_mutex_lock(&mutex); + send_samples_start_obs_test = 1; + pthread_mutex_unlock(&mutex); + pthread_join(thread_DMA, NULL); + send_samples_start_obs_test = 0; - if (pthread_create(&thread_DMA, NULL, handler_DMA_obs_test, (void *)&args) < 0) - { - std::cout << "ERROR cannot create DMA Process" << std::endl; - } - pthread_mutex_lock(&mutex); - send_samples_start_obs_test = 1; - pthread_mutex_unlock(&mutex); - pthread_join(thread_DMA, NULL); - send_samples_start_obs_test = 0; + args.nsamples_tx = nsamples_to_transfer; - args.nsamples_tx = nsamples_to_transfer; + args.skip_used_samples = TEST_OBS_DOWNSAMPLING_FILTER_DELAY; + } + else + { + args.nsamples_tx = nsamples_to_transfer; - args.skip_used_samples = TEST_OBS_DOWNSAMPLING_FILTER_DELAY; - - } - else - { - - args.nsamples_tx = nsamples_to_transfer; - - args.skip_used_samples = 0; - } + args.skip_used_samples = 0; + } - // create DMA child process - if (pthread_create(&thread_DMA, NULL, handler_DMA_obs_test, (void *)&args) < 0) - { - std::cout << "ERROR cannot create DMA Process" << std::endl; - } + // create DMA child process + if (pthread_create(&thread_DMA, NULL, handler_DMA_obs_test, (void*)&args) < 0) + { + std::cout << "ERROR cannot create DMA Process" << std::endl; + } - msg_rx->rx_message = 0; - top_block->start(); + msg_rx->rx_message = 0; + top_block->start(); - pthread_mutex_lock(&mutex); - send_samples_start_obs_test = 1; - pthread_mutex_unlock(&mutex); + pthread_mutex_lock(&mutex); + send_samples_start_obs_test = 1; + pthread_mutex_unlock(&mutex); - acquisition->reset(); // set active + acquisition->reset(); // set active - if (start_msg == true) - { - std::cout << "Reading external signal file: " << FLAGS_signal_file << std::endl; - std::cout << "Searching for " << System_and_Signal << " Satellites..." << std::endl; - std::cout << "["; - start_msg = false; - } + if (start_msg == true) + { + std::cout << "Reading external signal file: " << FLAGS_signal_file << std::endl; + std::cout << "Searching for " << System_and_Signal << " Satellites..." << std::endl; + std::cout << "["; + start_msg = false; + } - // wait for the child DMA process to finish - pthread_join(thread_DMA, NULL); + // wait for the child DMA process to finish + pthread_join(thread_DMA, NULL); - pthread_mutex_lock(&mutex); - send_samples_start_obs_test = 0; - pthread_mutex_unlock(&mutex); + pthread_mutex_lock(&mutex); + send_samples_start_obs_test = 0; + pthread_mutex_unlock(&mutex); - // the DMA sends the exact number of samples needed for the acquisition. - // however because of the LPF in the GPS L1/Gal E1 acquisition, this calculation is approximate - // and some extra samples might be sent. Wait at least once to give time the HW to consume any extra - // sample the DMA might have sent. - do { - usleep(100000); - } while (msg_rx->rx_message == 0); + // the DMA sends the exact number of samples needed for the acquisition. + // however because of the LPF in the GPS L1/Gal E1 acquisition, this calculation is approximate + // and some extra samples might be sent. Wait at least once to give time the HW to consume any extra + // sample the DMA might have sent. + do + { + usleep(100000); + } + while (msg_rx->rx_message == 0); - if (msg_rx->rx_message == 1) - { - std::cout << " " << PRN << " "; + if (msg_rx->rx_message == 1) + { + std::cout << " " << PRN << " "; - tmp_gnss_synchro.Acq_doppler_hz = tmp_gnss_synchro.Acq_doppler_hz; - tmp_gnss_synchro.Acq_delay_samples = tmp_gnss_synchro.Acq_delay_samples; - tmp_gnss_synchro.Acq_samplestamp_samples = 0; // do not take into account the filter internal state initialisation - tmp_gnss_synchro.Acq_samplestamp_samples = tmp_gnss_synchro.Acq_samplestamp_samples; // delay due to the downsampling filter in the acquisition + tmp_gnss_synchro.Acq_doppler_hz = tmp_gnss_synchro.Acq_doppler_hz; + tmp_gnss_synchro.Acq_delay_samples = tmp_gnss_synchro.Acq_delay_samples; + tmp_gnss_synchro.Acq_samplestamp_samples = 0; // do not take into account the filter internal state initialisation + tmp_gnss_synchro.Acq_samplestamp_samples = tmp_gnss_synchro.Acq_samplestamp_samples; // delay due to the downsampling filter in the acquisition - gnss_synchro_vec.push_back(tmp_gnss_synchro); + gnss_synchro_vec.push_back(tmp_gnss_synchro); + } + else + { + std::cout << " . "; + } - } - else - { - std::cout << " . "; - } + top_block->stop(); - top_block->stop(); - - - - - std::cout.flush(); - - } + std::cout.flush(); + } std::cout << "]" << std::endl; std::cout << "-------------------------------------------\n"; @@ -826,7 +814,7 @@ void HybridObservablesTestFpga::configure_receiver( config->set_property("TelemetryDecoder.implementation", "Galileo_E1B_Telemetry_Decoder"); } - else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking_Fpga") == 0) // or implementation.compare("Galileo_E5a_DLL_PLL_Tracking_b") == 0) + else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking_Fpga") == 0) // or implementation.compare("Galileo_E5a_DLL_PLL_Tracking_b") == 0) { gnss_synchro_master.System = 'E'; std::string signal = "5X"; @@ -1478,11 +1466,10 @@ bool HybridObservablesTestFpga::ReadRinexObs(std::vector* obs_vec, Gn } TEST_F(HybridObservablesTestFpga, ValidationOfResults) { + // pointer to the DMA thread that sends the samples to the acquisition engine + pthread_t thread_DMA; - // pointer to the DMA thread that sends the samples to the acquisition engine - pthread_t thread_DMA; - - struct DMA_handler_args_obs_test args; + struct DMA_handler_args_obs_test args; // Configure the signal generator configure_generator(); @@ -1575,46 +1562,45 @@ TEST_F(HybridObservablesTestFpga, ValidationOfResults) } - // The HW has been reset after the acquisition phase when the acquisition class was destroyed. - // No more samples remained in the DMA. Therefore any intermediate state in the LPF of the - // GPS L1 / Galileo E1 filter has been cleared. - // During this test all the samples coming from the DMA are consumed so in principle there would be - // no need to reset the HW. However we need to clear the sample counter in each test. Therefore we have - // to reset the HW at the beginning of each test. + // The HW has been reset after the acquisition phase when the acquisition class was destroyed. + // No more samples remained in the DMA. Therefore any intermediate state in the LPF of the + // GPS L1 / Galileo E1 filter has been cleared. + // During this test all the samples coming from the DMA are consumed so in principle there would be + // no need to reset the HW. However we need to clear the sample counter in each test. Therefore we have + // to reset the HW at the beginning of each test. - // instantiate the acquisition modules in order to use them to reset the HW. - // (note that the constructor of the acquisition modules resets the HW too) + // instantiate the acquisition modules in order to use them to reset the HW. + // (note that the constructor of the acquisition modules resets the HW too) - std::shared_ptr acquisition; + std::shared_ptr acquisition; // reset the HW to clear the sample counters: the acquisition constructor generates a reset - if (implementation.compare("GPS_L1_CA_DLL_PLL_Tracking_Fpga") == 0) - { - acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); - args.freq_band = 0; - - } - else if (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") == 0) - { - acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); - args.freq_band = 0; - } - else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking_Fpga") == 0) - { - acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); - args.freq_band = 1; - } - else if (implementation.compare("GPS_L5_DLL_PLL_Tracking_Fpga") == 0) - { - acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); - args.freq_band = 1; - } - else - { - std::cout << "The test can not run with the selected tracking implementation\n "; - throw(std::exception()); - } + if (implementation.compare("GPS_L1_CA_DLL_PLL_Tracking_Fpga") == 0) + { + acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); + args.freq_band = 0; + } + else if (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") == 0) + { + acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); + args.freq_band = 0; + } + else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking_Fpga") == 0) + { + acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); + args.freq_band = 1; + } + else if (implementation.compare("GPS_L5_DLL_PLL_Tracking_Fpga") == 0) + { + acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); + args.freq_band = 1; + } + else + { + std::cout << "The test can not run with the selected tracking implementation\n "; + throw(std::exception()); + } std::vector> tracking_ch_vec; @@ -1661,336 +1647,333 @@ TEST_F(HybridObservablesTestFpga, ValidationOfResults) }) << "Failure setting gnss_synchro."; } - top_block = gr::make_top_block("Telemetry_Decoder test"); - boost::shared_ptr dummy_msg_rx_trk = HybridObservablesTest_msg_rx_Fpga_make(); - boost::shared_ptr dummy_tlm_msg_rx = HybridObservablesTest_tlm_msg_rx_Fpga_make(); - //Observables - std::shared_ptr observables(new HybridObservables(config.get(), "Observables", tracking_ch_vec.size() + 1, tracking_ch_vec.size())); + top_block = gr::make_top_block("Telemetry_Decoder test"); + boost::shared_ptr dummy_msg_rx_trk = HybridObservablesTest_msg_rx_Fpga_make(); + boost::shared_ptr dummy_tlm_msg_rx = HybridObservablesTest_tlm_msg_rx_Fpga_make(); + //Observables + std::shared_ptr observables(new HybridObservables(config.get(), "Observables", tracking_ch_vec.size() + 1, tracking_ch_vec.size())); - for (unsigned int n = 0; n < tracking_ch_vec.size(); n++) - { - ASSERT_NO_THROW({ - tracking_ch_vec.at(n)->connect(top_block); - }) << "Failure connecting tracking to the top_block."; - } + for (unsigned int n = 0; n < tracking_ch_vec.size(); n++) + { + ASSERT_NO_THROW({ + tracking_ch_vec.at(n)->connect(top_block); + }) << "Failure connecting tracking to the top_block."; + } - std::string file; + std::string file; - ASSERT_NO_THROW({ - if (!FLAGS_enable_external_signal_file) - { - file = "./" + filename_raw_data; - } - else - { - file = FLAGS_signal_file; - } - int observable_interval_ms = 20; + ASSERT_NO_THROW({ + if (!FLAGS_enable_external_signal_file) + { + file = "./" + filename_raw_data; + } + else + { + file = FLAGS_signal_file; + } + int observable_interval_ms = 20; - double fs = static_cast(config->property("GNSS-SDR.internal_fs_sps", 0)); + double fs = static_cast(config->property("GNSS-SDR.internal_fs_sps", 0)); - gnss_sdr_fpga_sample_counter_sptr ch_out_fpga_sample_counter; - ch_out_fpga_sample_counter = gnss_sdr_make_fpga_sample_counter(fs, observable_interval_ms); + gnss_sdr_fpga_sample_counter_sptr ch_out_fpga_sample_counter; + ch_out_fpga_sample_counter = gnss_sdr_make_fpga_sample_counter(fs, observable_interval_ms); - - for (unsigned int n = 0; n < tracking_ch_vec.size(); n++) - { - //top_block->connect(gr_interleaved_char_to_complex, 0, tracking_ch_vec.at(n)->get_left_block(), 0); - top_block->connect(tracking_ch_vec.at(n)->get_right_block(), 0, tlm_ch_vec.at(n)->get_left_block(), 0); - top_block->connect(tlm_ch_vec.at(n)->get_right_block(), 0, observables->get_left_block(), n); - top_block->msg_connect(tracking_ch_vec.at(n)->get_right_block(), pmt::mp("events"), dummy_msg_rx_trk, pmt::mp("events")); - top_block->connect(observables->get_right_block(), n, null_sink_vec.at(n), 0); - } - //connect sample counter and timmer to the last channel in observables block (extra channel) - //top_block->connect(samp_counter, 0, observables->get_left_block(), tracking_ch_vec.size()); - top_block->connect(ch_out_fpga_sample_counter, 0, observables->get_left_block(), tracking_ch_vec.size()); //extra port for the sample counter pulse - - }) << "Failure connecting the blocks."; + for (unsigned int n = 0; n < tracking_ch_vec.size(); n++) + { + //top_block->connect(gr_interleaved_char_to_complex, 0, tracking_ch_vec.at(n)->get_left_block(), 0); + top_block->connect(tracking_ch_vec.at(n)->get_right_block(), 0, tlm_ch_vec.at(n)->get_left_block(), 0); + top_block->connect(tlm_ch_vec.at(n)->get_right_block(), 0, observables->get_left_block(), n); + top_block->msg_connect(tracking_ch_vec.at(n)->get_right_block(), pmt::mp("events"), dummy_msg_rx_trk, pmt::mp("events")); + top_block->connect(observables->get_right_block(), n, null_sink_vec.at(n), 0); + } + //connect sample counter and timmer to the last channel in observables block (extra channel) + //top_block->connect(samp_counter, 0, observables->get_left_block(), tracking_ch_vec.size()); + top_block->connect(ch_out_fpga_sample_counter, 0, observables->get_left_block(), tracking_ch_vec.size()); //extra port for the sample counter pulse + }) << "Failure connecting the blocks."; - args.file = file; - args.nsamples_tx = baseband_sampling_freq*FLAGS_duration;; + args.file = file; + args.nsamples_tx = baseband_sampling_freq * FLAGS_duration; + ; - args.skip_used_samples = 0; + args.skip_used_samples = 0; - if (pthread_create(&thread_DMA, NULL, handler_DMA_obs_test, (void *)&args) < 0) - { - std::cout << "ERROR cannot create DMA Process" << std::endl; - } + if (pthread_create(&thread_DMA, NULL, handler_DMA_obs_test, (void*)&args) < 0) + { + std::cout << "ERROR cannot create DMA Process" << std::endl; + } - for (unsigned int n = 0; n < tracking_ch_vec.size(); n++) - { - tracking_ch_vec.at(n)->start_tracking(); - } + for (unsigned int n = 0; n < tracking_ch_vec.size(); n++) + { + tracking_ch_vec.at(n)->start_tracking(); + } - pthread_mutex_lock(&mutex_obs_test); - send_samples_start_obs_test = 1; - pthread_mutex_unlock(&mutex_obs_test); + pthread_mutex_lock(&mutex_obs_test); + send_samples_start_obs_test = 1; + pthread_mutex_unlock(&mutex_obs_test); - top_block->start(); + top_block->start(); - - EXPECT_NO_THROW({ - start = std::chrono::system_clock::now(); - //top_block->run(); // Start threads and wait - end = std::chrono::system_clock::now(); - elapsed_seconds = end - start; - }) << "Failure running the top_block."; + EXPECT_NO_THROW({ + start = std::chrono::system_clock::now(); + //top_block->run(); // Start threads and wait + end = std::chrono::system_clock::now(); + elapsed_seconds = end - start; + }) << "Failure running the top_block."; - // wait for the child DMA process to finish - pthread_join(thread_DMA, NULL); + // wait for the child DMA process to finish + pthread_join(thread_DMA, NULL); - top_block->stop(); + top_block->stop(); // reset the HW AGAIN - acquisition->stop_acquisition(); + acquisition->stop_acquisition(); - // pthread_mutex_lock(&mutex_obs_test); - // send_samples_start_obs_test = 0; - // pthread_mutex_unlock(&mutex_obs_test); + // pthread_mutex_lock(&mutex_obs_test); + // send_samples_start_obs_test = 0; + // pthread_mutex_unlock(&mutex_obs_test); + //check results + // Matrices for storing columnwise true GPS time, Range, Doppler and Carrier phase + std::vector true_obs_vec; - //check results - // Matrices for storing columnwise true GPS time, Range, Doppler and Carrier phase - std::vector true_obs_vec; + if (!FLAGS_enable_external_signal_file) + { + //load the true values + True_Observables_Reader true_observables; + ASSERT_NO_THROW({ + if (true_observables.open_obs_file(std::string("./obs_out.bin")) == false) + { + throw std::exception(); + } + }) << "Failure opening true observables file"; - if (!FLAGS_enable_external_signal_file) - { - //load the true values - True_Observables_Reader true_observables; - ASSERT_NO_THROW({ - if (true_observables.open_obs_file(std::string("./obs_out.bin")) == false) - { - throw std::exception(); - } - }) << "Failure opening true observables file"; + unsigned int nepoch = static_cast(true_observables.num_epochs()); - unsigned int nepoch = static_cast(true_observables.num_epochs()); + std::cout << "True observation epochs = " << nepoch << std::endl; - std::cout << "True observation epochs = " << nepoch << std::endl; + true_observables.restart(); + int64_t epoch_counter = 0; + for (unsigned int n = 0; n < tracking_ch_vec.size(); n++) + { + true_obs_vec.push_back(arma::zeros(nepoch, 4)); + } - true_observables.restart(); - int64_t epoch_counter = 0; - for (unsigned int n = 0; n < tracking_ch_vec.size(); n++) - { - true_obs_vec.push_back(arma::zeros(nepoch, 4)); - } - - ASSERT_NO_THROW({ - while (true_observables.read_binary_obs()) - { - for (unsigned int n = 0; n < true_obs_vec.size(); n++) - { - if (round(true_observables.prn[n]) != gnss_synchro_vec.at(n).PRN) - { - std::cout << "True observables SV PRN does not match measured ones: " - << round(true_observables.prn[n]) << " vs. " << gnss_synchro_vec.at(n).PRN << std::endl; - throw std::exception(); - } - true_obs_vec.at(n)(epoch_counter, 0) = true_observables.gps_time_sec[n]; - true_obs_vec.at(n)(epoch_counter, 1) = true_observables.dist_m[n]; - true_obs_vec.at(n)(epoch_counter, 2) = true_observables.doppler_l1_hz[n]; - true_obs_vec.at(n)(epoch_counter, 3) = true_observables.acc_carrier_phase_l1_cycles[n]; - } - epoch_counter++; - } - }); - } - else - { - ASSERT_EQ(ReadRinexObs(&true_obs_vec, gnss_synchro_master), true) - << "Failure reading RINEX file"; - } + ASSERT_NO_THROW({ + while (true_observables.read_binary_obs()) + { + for (unsigned int n = 0; n < true_obs_vec.size(); n++) + { + if (round(true_observables.prn[n]) != gnss_synchro_vec.at(n).PRN) + { + std::cout << "True observables SV PRN does not match measured ones: " + << round(true_observables.prn[n]) << " vs. " << gnss_synchro_vec.at(n).PRN << std::endl; + throw std::exception(); + } + true_obs_vec.at(n)(epoch_counter, 0) = true_observables.gps_time_sec[n]; + true_obs_vec.at(n)(epoch_counter, 1) = true_observables.dist_m[n]; + true_obs_vec.at(n)(epoch_counter, 2) = true_observables.doppler_l1_hz[n]; + true_obs_vec.at(n)(epoch_counter, 3) = true_observables.acc_carrier_phase_l1_cycles[n]; + } + epoch_counter++; + } + }); + } + else + { + ASSERT_EQ(ReadRinexObs(&true_obs_vec, gnss_synchro_master), true) + << "Failure reading RINEX file"; + } - //read measured values - Observables_Dump_Reader estimated_observables(tracking_ch_vec.size()); - ASSERT_NO_THROW({ - if (estimated_observables.open_obs_file(std::string("./observables.dat")) == false) - { - throw std::exception(); - } - }) << "Failure opening dump observables file"; + //read measured values + Observables_Dump_Reader estimated_observables(tracking_ch_vec.size()); + ASSERT_NO_THROW({ + if (estimated_observables.open_obs_file(std::string("./observables.dat")) == false) + { + throw std::exception(); + } + }) << "Failure opening dump observables file"; - unsigned int nepoch = static_cast(estimated_observables.num_epochs()); - std::cout << "Measured observations epochs = " << nepoch << std::endl; + unsigned int nepoch = static_cast(estimated_observables.num_epochs()); + std::cout << "Measured observations epochs = " << nepoch << std::endl; - // Matrices for storing columnwise measured RX_time, TOW, Doppler, Carrier phase and Pseudorange - std::vector measured_obs_vec; - std::vector epoch_counters_vec; - for (unsigned int n = 0; n < tracking_ch_vec.size(); n++) - { - measured_obs_vec.push_back(arma::zeros(nepoch, 5)); - epoch_counters_vec.push_back(0); - } + // Matrices for storing columnwise measured RX_time, TOW, Doppler, Carrier phase and Pseudorange + std::vector measured_obs_vec; + std::vector epoch_counters_vec; + for (unsigned int n = 0; n < tracking_ch_vec.size(); n++) + { + measured_obs_vec.push_back(arma::zeros(nepoch, 5)); + epoch_counters_vec.push_back(0); + } - estimated_observables.restart(); - while (estimated_observables.read_binary_obs()) - { - for (unsigned int n = 0; n < measured_obs_vec.size(); n++) - { - if (static_cast(estimated_observables.valid[n])) - { - measured_obs_vec.at(n)(epoch_counters_vec.at(n), 0) = estimated_observables.RX_time[n]; - measured_obs_vec.at(n)(epoch_counters_vec.at(n), 1) = estimated_observables.TOW_at_current_symbol_s[n]; - measured_obs_vec.at(n)(epoch_counters_vec.at(n), 2) = estimated_observables.Carrier_Doppler_hz[n]; - measured_obs_vec.at(n)(epoch_counters_vec.at(n), 3) = estimated_observables.Acc_carrier_phase_hz[n]; - measured_obs_vec.at(n)(epoch_counters_vec.at(n), 4) = estimated_observables.Pseudorange_m[n]; - epoch_counters_vec.at(n)++; - } - } - } + estimated_observables.restart(); + while (estimated_observables.read_binary_obs()) + { + for (unsigned int n = 0; n < measured_obs_vec.size(); n++) + { + if (static_cast(estimated_observables.valid[n])) + { + measured_obs_vec.at(n)(epoch_counters_vec.at(n), 0) = estimated_observables.RX_time[n]; + measured_obs_vec.at(n)(epoch_counters_vec.at(n), 1) = estimated_observables.TOW_at_current_symbol_s[n]; + measured_obs_vec.at(n)(epoch_counters_vec.at(n), 2) = estimated_observables.Carrier_Doppler_hz[n]; + measured_obs_vec.at(n)(epoch_counters_vec.at(n), 3) = estimated_observables.Acc_carrier_phase_hz[n]; + measured_obs_vec.at(n)(epoch_counters_vec.at(n), 4) = estimated_observables.Pseudorange_m[n]; + epoch_counters_vec.at(n)++; + } + } + } - //Cut measurement tail zeros - arma::uvec index; - for (unsigned int n = 0; n < measured_obs_vec.size(); n++) - { - index = arma::find(measured_obs_vec.at(n).col(0) > 0.0, 1, "last"); - if ((index.size() > 0) and index(0) < (nepoch - 1)) - { - measured_obs_vec.at(n).shed_rows(index(0) + 1, nepoch - 1); - } - } + //Cut measurement tail zeros + arma::uvec index; + for (unsigned int n = 0; n < measured_obs_vec.size(); n++) + { + index = arma::find(measured_obs_vec.at(n).col(0) > 0.0, 1, "last"); + if ((index.size() > 0) and index(0) < (nepoch - 1)) + { + measured_obs_vec.at(n).shed_rows(index(0) + 1, nepoch - 1); + } + } - //Cut measurement initial transitory of the measurements + //Cut measurement initial transitory of the measurements - double initial_transitory_s = FLAGS_skip_obs_transitory_s; + double initial_transitory_s = FLAGS_skip_obs_transitory_s; - for (unsigned int n = 0; n < measured_obs_vec.size(); n++) - { - index = arma::find(measured_obs_vec.at(n).col(0) >= (measured_obs_vec.at(n)(0, 0) + initial_transitory_s), 1, "first"); - if ((index.size() > 0) and (index(0) > 0)) - { - measured_obs_vec.at(n).shed_rows(0, index(0)); - } + for (unsigned int n = 0; n < measured_obs_vec.size(); n++) + { + index = arma::find(measured_obs_vec.at(n).col(0) >= (measured_obs_vec.at(n)(0, 0) + initial_transitory_s), 1, "first"); + if ((index.size() > 0) and (index(0) > 0)) + { + measured_obs_vec.at(n).shed_rows(0, index(0)); + } - index = arma::find(measured_obs_vec.at(n).col(0) >= true_obs_vec.at(n)(0, 0), 1, "first"); - if ((index.size() > 0) and (index(0) > 0)) - { - measured_obs_vec.at(n).shed_rows(0, index(0)); - } - } + index = arma::find(measured_obs_vec.at(n).col(0) >= true_obs_vec.at(n)(0, 0), 1, "first"); + if ((index.size() > 0) and (index(0) > 0)) + { + measured_obs_vec.at(n).shed_rows(0, index(0)); + } + } - //Correct the clock error using true values (it is not possible for a receiver to correct - //the receiver clock offset error at the observables level because it is required the - //decoding of the ephemeris data and solve the PVT equations) + //Correct the clock error using true values (it is not possible for a receiver to correct + //the receiver clock offset error at the observables level because it is required the + //decoding of the ephemeris data and solve the PVT equations) - //Find the reference satellite (the nearest) and compute the receiver time offset at observable level - double min_pr = std::numeric_limits::max(); - unsigned int min_pr_ch_id = 0; - for (unsigned int n = 0; n < measured_obs_vec.size(); n++) - { - if (epoch_counters_vec.at(n) > 10) //discard non-valid channels - { - { - if (measured_obs_vec.at(n)(0, 4) < min_pr) - { - min_pr = measured_obs_vec.at(n)(0, 4); - min_pr_ch_id = n; - } - } - } - else - { - std::cout << "PRN " << gnss_synchro_vec.at(n).PRN << " has NO observations!\n"; - } - } + //Find the reference satellite (the nearest) and compute the receiver time offset at observable level + double min_pr = std::numeric_limits::max(); + unsigned int min_pr_ch_id = 0; + for (unsigned int n = 0; n < measured_obs_vec.size(); n++) + { + if (epoch_counters_vec.at(n) > 10) //discard non-valid channels + { + { + if (measured_obs_vec.at(n)(0, 4) < min_pr) + { + min_pr = measured_obs_vec.at(n)(0, 4); + min_pr_ch_id = n; + } + } + } + else + { + std::cout << "PRN " << gnss_synchro_vec.at(n).PRN << " has NO observations!\n"; + } + } - arma::vec receiver_time_offset_ref_channel_s; - //receiver_time_offset_ref_channel_s = true_obs_vec.at(min_pr_ch_id).col(1) / GPS_C_m_s - GPS_STARTOFFSET_ms / 1000.0; - receiver_time_offset_ref_channel_s = (true_obs_vec.at(min_pr_ch_id).col(1)(0) - measured_obs_vec.at(min_pr_ch_id).col(4)(0)) / GPS_C_M_S; - std::cout << "Ref channel initial Receiver time offset " << receiver_time_offset_ref_channel_s(0) * 1e3 << " [ms]" << std::endl; + arma::vec receiver_time_offset_ref_channel_s; + //receiver_time_offset_ref_channel_s = true_obs_vec.at(min_pr_ch_id).col(1) / GPS_C_m_s - GPS_STARTOFFSET_ms / 1000.0; + receiver_time_offset_ref_channel_s = (true_obs_vec.at(min_pr_ch_id).col(1)(0) - measured_obs_vec.at(min_pr_ch_id).col(4)(0)) / GPS_C_M_S; + std::cout << "Ref channel initial Receiver time offset " << receiver_time_offset_ref_channel_s(0) * 1e3 << " [ms]" << std::endl; - for (unsigned int n = 0; n < measured_obs_vec.size(); n++) - { - //debug save to .mat - std::vector tmp_vector_x(true_obs_vec.at(n).col(0).colptr(0), - true_obs_vec.at(n).col(0).colptr(0) + true_obs_vec.at(n).col(0).n_rows); - std::vector tmp_vector_y(true_obs_vec.at(n).col(1).colptr(0), - true_obs_vec.at(n).col(1).colptr(0) + true_obs_vec.at(n).col(1).n_rows); - save_mat_xy(tmp_vector_x, tmp_vector_y, std::string("true_pr_ch_" + std::to_string(n))); + for (unsigned int n = 0; n < measured_obs_vec.size(); n++) + { + //debug save to .mat + std::vector tmp_vector_x(true_obs_vec.at(n).col(0).colptr(0), + true_obs_vec.at(n).col(0).colptr(0) + true_obs_vec.at(n).col(0).n_rows); + std::vector tmp_vector_y(true_obs_vec.at(n).col(1).colptr(0), + true_obs_vec.at(n).col(1).colptr(0) + true_obs_vec.at(n).col(1).n_rows); + save_mat_xy(tmp_vector_x, tmp_vector_y, std::string("true_pr_ch_" + std::to_string(n))); - std::vector tmp_vector_x2(measured_obs_vec.at(n).col(0).colptr(0), - measured_obs_vec.at(n).col(0).colptr(0) + measured_obs_vec.at(n).col(0).n_rows); - std::vector tmp_vector_y2(measured_obs_vec.at(n).col(4).colptr(0), - measured_obs_vec.at(n).col(4).colptr(0) + measured_obs_vec.at(n).col(4).n_rows); - save_mat_xy(tmp_vector_x2, tmp_vector_y2, std::string("measured_pr_ch_" + std::to_string(n))); + std::vector tmp_vector_x2(measured_obs_vec.at(n).col(0).colptr(0), + measured_obs_vec.at(n).col(0).colptr(0) + measured_obs_vec.at(n).col(0).n_rows); + std::vector tmp_vector_y2(measured_obs_vec.at(n).col(4).colptr(0), + measured_obs_vec.at(n).col(4).colptr(0) + measured_obs_vec.at(n).col(4).n_rows); + save_mat_xy(tmp_vector_x2, tmp_vector_y2, std::string("measured_pr_ch_" + std::to_string(n))); - std::vector tmp_vector_x3(true_obs_vec.at(n).col(0).colptr(0), - true_obs_vec.at(n).col(0).colptr(0) + true_obs_vec.at(n).col(0).n_rows); - std::vector tmp_vector_y3(true_obs_vec.at(n).col(2).colptr(0), - true_obs_vec.at(n).col(2).colptr(0) + true_obs_vec.at(n).col(2).n_rows); - save_mat_xy(tmp_vector_x3, tmp_vector_y3, std::string("true_doppler_ch_" + std::to_string(n))); + std::vector tmp_vector_x3(true_obs_vec.at(n).col(0).colptr(0), + true_obs_vec.at(n).col(0).colptr(0) + true_obs_vec.at(n).col(0).n_rows); + std::vector tmp_vector_y3(true_obs_vec.at(n).col(2).colptr(0), + true_obs_vec.at(n).col(2).colptr(0) + true_obs_vec.at(n).col(2).n_rows); + save_mat_xy(tmp_vector_x3, tmp_vector_y3, std::string("true_doppler_ch_" + std::to_string(n))); - std::vector tmp_vector_x4(measured_obs_vec.at(n).col(0).colptr(0), - measured_obs_vec.at(n).col(0).colptr(0) + measured_obs_vec.at(n).col(0).n_rows); - std::vector tmp_vector_y4(measured_obs_vec.at(n).col(2).colptr(0), - measured_obs_vec.at(n).col(2).colptr(0) + measured_obs_vec.at(n).col(2).n_rows); - save_mat_xy(tmp_vector_x4, tmp_vector_y4, std::string("measured_doppler_ch_" + std::to_string(n))); + std::vector tmp_vector_x4(measured_obs_vec.at(n).col(0).colptr(0), + measured_obs_vec.at(n).col(0).colptr(0) + measured_obs_vec.at(n).col(0).n_rows); + std::vector tmp_vector_y4(measured_obs_vec.at(n).col(2).colptr(0), + measured_obs_vec.at(n).col(2).colptr(0) + measured_obs_vec.at(n).col(2).n_rows); + save_mat_xy(tmp_vector_x4, tmp_vector_y4, std::string("measured_doppler_ch_" + std::to_string(n))); - if (epoch_counters_vec.at(n) > 10) //discard non-valid channels - { - arma::vec true_TOW_ref_ch_s = true_obs_vec.at(min_pr_ch_id).col(0) - receiver_time_offset_ref_channel_s(0); - arma::vec true_TOW_ch_s = true_obs_vec.at(n).col(0) - receiver_time_offset_ref_channel_s(0); - //Compare measured observables - if (min_pr_ch_id != n) - { - check_results_code_pseudorange(true_obs_vec.at(n), - true_obs_vec.at(min_pr_ch_id), - true_TOW_ch_s, - true_TOW_ref_ch_s, - measured_obs_vec.at(n), - measured_obs_vec.at(min_pr_ch_id), - "[CH " + std::to_string(n) + "] PRN " + std::to_string(gnss_synchro_vec.at(n).PRN) + " "); - check_results_carrier_phase_double_diff(true_obs_vec.at(n), - true_obs_vec.at(min_pr_ch_id), - true_TOW_ch_s, - true_TOW_ref_ch_s, - measured_obs_vec.at(n), - measured_obs_vec.at(min_pr_ch_id), - "[CH " + std::to_string(n) + "] PRN " + std::to_string(gnss_synchro_vec.at(n).PRN) + " "); + if (epoch_counters_vec.at(n) > 10) //discard non-valid channels + { + arma::vec true_TOW_ref_ch_s = true_obs_vec.at(min_pr_ch_id).col(0) - receiver_time_offset_ref_channel_s(0); + arma::vec true_TOW_ch_s = true_obs_vec.at(n).col(0) - receiver_time_offset_ref_channel_s(0); + //Compare measured observables + if (min_pr_ch_id != n) + { + check_results_code_pseudorange(true_obs_vec.at(n), + true_obs_vec.at(min_pr_ch_id), + true_TOW_ch_s, + true_TOW_ref_ch_s, + measured_obs_vec.at(n), + measured_obs_vec.at(min_pr_ch_id), + "[CH " + std::to_string(n) + "] PRN " + std::to_string(gnss_synchro_vec.at(n).PRN) + " "); + check_results_carrier_phase_double_diff(true_obs_vec.at(n), + true_obs_vec.at(min_pr_ch_id), + true_TOW_ch_s, + true_TOW_ref_ch_s, + measured_obs_vec.at(n), + measured_obs_vec.at(min_pr_ch_id), + "[CH " + std::to_string(n) + "] PRN " + std::to_string(gnss_synchro_vec.at(n).PRN) + " "); - check_results_carrier_doppler_double_diff(true_obs_vec.at(n), - true_obs_vec.at(min_pr_ch_id), - true_TOW_ch_s, - true_TOW_ref_ch_s, - measured_obs_vec.at(n), - measured_obs_vec.at(min_pr_ch_id), - "[CH " + std::to_string(n) + "] PRN " + std::to_string(gnss_synchro_vec.at(n).PRN) + " "); - } - else - { - std::cout << "[CH " << std::to_string(n) << "] PRN " << std::to_string(gnss_synchro_vec.at(n).PRN) << " is the reference satellite" << std::endl; - } - if (FLAGS_compute_single_diffs) - { - check_results_carrier_phase(true_obs_vec.at(n), - true_TOW_ch_s, - measured_obs_vec.at(n), - "[CH " + std::to_string(n) + "] PRN " + std::to_string(gnss_synchro_vec.at(n).PRN) + " "); - check_results_carrier_doppler(true_obs_vec.at(n), - true_TOW_ch_s, - measured_obs_vec.at(n), - "[CH " + std::to_string(n) + "] PRN " + std::to_string(gnss_synchro_vec.at(n).PRN) + " "); - } - } - else - { - std::cout << "PRN " << gnss_synchro_vec.at(n).PRN << " has NO observations!\n"; - } - } + check_results_carrier_doppler_double_diff(true_obs_vec.at(n), + true_obs_vec.at(min_pr_ch_id), + true_TOW_ch_s, + true_TOW_ref_ch_s, + measured_obs_vec.at(n), + measured_obs_vec.at(min_pr_ch_id), + "[CH " + std::to_string(n) + "] PRN " + std::to_string(gnss_synchro_vec.at(n).PRN) + " "); + } + else + { + std::cout << "[CH " << std::to_string(n) << "] PRN " << std::to_string(gnss_synchro_vec.at(n).PRN) << " is the reference satellite" << std::endl; + } + if (FLAGS_compute_single_diffs) + { + check_results_carrier_phase(true_obs_vec.at(n), + true_TOW_ch_s, + measured_obs_vec.at(n), + "[CH " + std::to_string(n) + "] PRN " + std::to_string(gnss_synchro_vec.at(n).PRN) + " "); + check_results_carrier_doppler(true_obs_vec.at(n), + true_TOW_ch_s, + measured_obs_vec.at(n), + "[CH " + std::to_string(n) + "] PRN " + std::to_string(gnss_synchro_vec.at(n).PRN) + " "); + } + } + else + { + std::cout << "PRN " << gnss_synchro_vec.at(n).PRN << " has NO observations!\n"; + } + } - std::cout << "Test completed in " << elapsed_seconds.count() << " [s]" << std::endl; + std::cout << "Test completed in " << elapsed_seconds.count() << " [s]" << std::endl; } diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test_fpga.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test_fpga.cc index 3675efe5d..9205d0ba6 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test_fpga.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test_fpga.cc @@ -32,13 +32,12 @@ #include "GPS_L1_CA.h" #include "acquisition_msg_rx.h" +#include "galileo_e1_pcps_ambiguous_acquisition_fpga.h" #include "galileo_e5a_noncoherent_iq_acquisition_caf.h" #include "galileo_e5a_pcps_acquisition.h" -#include "gnss_block_factory.h" -#include "tracking_interface.h" -#include "gps_l1_ca_pcps_acquisition_fpga.h" -#include "galileo_e1_pcps_ambiguous_acquisition_fpga.h" #include "galileo_e5a_pcps_acquisition_fpga.h" +#include "gnss_block_factory.h" +#include "gps_l1_ca_pcps_acquisition_fpga.h" #include "gps_l5i_pcps_acquisition_fpga.h" #include "in_memory_configuration.h" #include "signal_generator_flags.h" @@ -61,21 +60,21 @@ #include // threads -#include // for pthread stuff -#include // for open, O_RDWR, O_SYNC -#include // for cout, endl -#include // for mmap +#include // for open, O_RDWR, O_SYNC +#include // for cout, endl +#include // for pthread stuff +#include // for mmap -#define MAX_INPUT_COMPLEX_SAMPLES_TOTAL 8192 // maximum DMA sample block size in complex samples -#define COMPLEX_SAMPLE_SIZE 2 // sample size in bytes -#define NUM_QUEUES 2 // number of queues (1 for GPS L1/Galileo E1, and 1 for GPS L5/Galileo E5) -#define DOWNAMPLING_FILTER_INIT_SAMPLES 100 // some samples to initialize the state of the downsampling filter -#define DOWNSAMPLING_FILTER_DELAY 48 // delay of the downsampling filter in samples +#define MAX_INPUT_COMPLEX_SAMPLES_TOTAL 8192 // maximum DMA sample block size in complex samples +#define COMPLEX_SAMPLE_SIZE 2 // sample size in bytes +#define NUM_QUEUES 2 // number of queues (1 for GPS L1/Galileo E1, and 1 for GPS L5/Galileo E5) +#define DOWNAMPLING_FILTER_INIT_SAMPLES 100 // some samples to initialize the state of the downsampling filter +#define DOWNSAMPLING_FILTER_DELAY 48 // delay of the downsampling filter in samples // HW related options -bool skip_samples_already_used = 0; // if skip_samples_already_used = 1 => for each PRN loop skip the samples used in the previous PRN loops - // (exactly in the same way as the SW) +bool skip_samples_already_used = 0; // if skip_samples_already_used = 1 => for each PRN loop skip the samples used in the previous PRN loops + // (exactly in the same way as the SW) class Acquisition_msg_rx_Fpga; @@ -316,8 +315,6 @@ void TrackingPullInTestFpga::configure_receiver( config->set_property("Tracking.early_late_space_chips", "0.5"); config->set_property("Tracking.if", "0"); config->set_property("Tracking.order", "3"); - - } else if (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") == 0) { @@ -335,7 +332,7 @@ void TrackingPullInTestFpga::configure_receiver( config->set_property("Tracking.device_base", "15"); } - else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking_Fpga") == 0) // or implementation.compare("Galileo_E5a_DLL_PLL_Tracking_b") == 0) + else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking_Fpga") == 0) // or implementation.compare("Galileo_E5a_DLL_PLL_Tracking_b") == 0) { gnss_synchro.System = 'E'; std::string signal = "5X"; @@ -381,16 +378,17 @@ const unsigned int TEST_REGISTER_TRACK_WRITEVAL = 0x55AA; void setup_fpga_switch(void) { int switch_device_descriptor; // driver descriptor - volatile unsigned *switch_map_base; // driver memory map + volatile unsigned* switch_map_base; // driver memory map if ((switch_device_descriptor = open("/dev/uio1", O_RDWR | O_SYNC)) == -1) { - LOG(WARNING) << "Cannot open deviceio" << "/dev/uio1"; + LOG(WARNING) << "Cannot open deviceio" + << "/dev/uio1"; } - switch_map_base = reinterpret_cast(mmap(nullptr, PAGE_SIZE, + switch_map_base = reinterpret_cast(mmap(nullptr, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, switch_device_descriptor, 0)); - if (switch_map_base == reinterpret_cast(-1)) + if (switch_map_base == reinterpret_cast(-1)) { LOG(WARNING) << "Cannot map the FPGA switch module into tracking memory"; std::cout << "Could not map switch memory." << std::endl; @@ -413,7 +411,7 @@ void setup_fpga_switch(void) LOG(INFO) << "Test register sanity check success !"; } - switch_map_base[0] = 0; //0 -> DMA to queue 0, 1 -> DMA to queue 1, 2 -> A/Ds to queues + switch_map_base[0] = 0; //0 -> DMA to queue 0, 1 -> DMA to queue 1, 2 -> A/Ds to queues } @@ -421,133 +419,130 @@ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; volatile unsigned int send_samples_start = 0; -int8_t input_samples[MAX_INPUT_COMPLEX_SAMPLES_TOTAL*COMPLEX_SAMPLE_SIZE]; // re - im -int8_t input_samples_dma[MAX_INPUT_COMPLEX_SAMPLES_TOTAL*COMPLEX_SAMPLE_SIZE*NUM_QUEUES]; +int8_t input_samples[MAX_INPUT_COMPLEX_SAMPLES_TOTAL * COMPLEX_SAMPLE_SIZE]; // re - im +int8_t input_samples_dma[MAX_INPUT_COMPLEX_SAMPLES_TOTAL * COMPLEX_SAMPLE_SIZE * NUM_QUEUES]; -struct DMA_handler_args { +struct DMA_handler_args +{ std::string file; unsigned int nsamples_tx; unsigned int skip_used_samples; - unsigned int freq_band; // 0 for GPS L1/ Galileo E1, 1 for GPS L5/Galileo E5 + unsigned int freq_band; // 0 for GPS L1/ Galileo E1, 1 for GPS L5/Galileo E5 }; -void *handler_DMA(void *arguments) +void* handler_DMA(void* arguments) { + // DMA process that configures the DMA to send the samples to the acquisition engine + int tx_fd; // DMA descriptor + FILE* rx_signal_file_id; // Input file descriptor + bool file_completed = false; // flag to indicate if the file is completed + unsigned int nsamples_block; // number of samples to send in the next DMA block of samples + unsigned int nread_elements; // number of elements effectively read from the input file + unsigned int nsamples = 0; // number of complex samples effectively transferred + unsigned int index0, dma_index = 0; // counters used for putting the samples in the order expected by the DMA - // DMA process that configures the DMA to send the samples to the acquisition engine - int tx_fd; // DMA descriptor - FILE *rx_signal_file_id; // Input file descriptor - bool file_completed = false; // flag to indicate if the file is completed - unsigned int nsamples_block; // number of samples to send in the next DMA block of samples - unsigned int nread_elements; // number of elements effectively read from the input file - unsigned int nsamples = 0; // number of complex samples effectively transferred - unsigned int index0, dma_index = 0; // counters used for putting the samples in the order expected by the DMA + unsigned int nsamples_transmitted; - unsigned int nsamples_transmitted; + struct DMA_handler_args* args = (struct DMA_handler_args*)arguments; - struct DMA_handler_args *args = (struct DMA_handler_args *) arguments; + unsigned int nsamples_tx = args->nsamples_tx; + std::string file = args->file; // input filename + unsigned int skip_used_samples = args->skip_used_samples; - unsigned int nsamples_tx = args->nsamples_tx; - std::string file = args->file; // input filename - unsigned int skip_used_samples = args->skip_used_samples; + // open DMA device + tx_fd = open("/dev/loop_tx", O_WRONLY); + if (tx_fd < 0) + { + std::cout << "DMA can't open loop device" << std::endl; + exit(1); + } + else - // open DMA device - tx_fd = open("/dev/loop_tx", O_WRONLY); - if ( tx_fd < 0 ) - { - std::cout << "DMA can't open loop device" << std::endl; - exit(1); - } - else + // open input file + rx_signal_file_id = fopen(file.c_str(), "rb"); + if (rx_signal_file_id == NULL) + { + std::cout << "DMA can't open input file" << std::endl; + exit(1); + } + while (send_samples_start == 0) + ; // wait until main thread tells the DMA to start - // open input file - rx_signal_file_id = fopen(file.c_str(), "rb"); - if (rx_signal_file_id == NULL) - { - std::cout << "DMA can't open input file" << std::endl; - exit(1); - } - while(send_samples_start == 0); // wait until main thread tells the DMA to start + // skip initial samples + int skip_samples = (int)FLAGS_skip_samples; - // skip initial samples - int skip_samples = (int) FLAGS_skip_samples; + fseek(rx_signal_file_id, (skip_samples + skip_used_samples) * 2, SEEK_SET); - fseek( rx_signal_file_id, (skip_samples + skip_used_samples)*2, SEEK_SET ); + usleep(50000); // wait some time to give time to the main thread to start the acquisition module - usleep(50000); // wait some time to give time to the main thread to start the acquisition module + while (file_completed == false) + { + if (nsamples_tx - nsamples > MAX_INPUT_COMPLEX_SAMPLES_TOTAL) + { + nsamples_block = MAX_INPUT_COMPLEX_SAMPLES_TOTAL; + } + else + { + nsamples_block = nsamples_tx - nsamples; // remaining samples to be sent + file_completed = true; + } - while (file_completed == false) - { - if (nsamples_tx - nsamples > MAX_INPUT_COMPLEX_SAMPLES_TOTAL) - { - nsamples_block = MAX_INPUT_COMPLEX_SAMPLES_TOTAL; - } - else - { - nsamples_block = nsamples_tx - nsamples; // remaining samples to be sent - file_completed = true; - } + nread_elements = fread(input_samples, sizeof(int8_t), nsamples_block * COMPLEX_SAMPLE_SIZE, rx_signal_file_id); - nread_elements = fread(input_samples, sizeof(int8_t), nsamples_block*COMPLEX_SAMPLE_SIZE, rx_signal_file_id); + if (nread_elements != nsamples_block * COMPLEX_SAMPLE_SIZE) + { + std::cout << "file completed" << std::endl; + file_completed = true; + } - if (nread_elements != nsamples_block * COMPLEX_SAMPLE_SIZE) - { - std::cout << "file completed" << std::endl; - file_completed = true; - } + nsamples += (nread_elements / COMPLEX_SAMPLE_SIZE); - nsamples+=(nread_elements/COMPLEX_SAMPLE_SIZE); - - if (nread_elements > 0) - { - // for the 32-BIT DMA - dma_index = 0; - for (index0 = 0;index0 < (nread_elements);index0+=COMPLEX_SAMPLE_SIZE) - { - if (args->freq_band == 0) - { - // channel 1 (queue 1) -> E5/L5 - input_samples_dma[dma_index] = 0; - input_samples_dma[dma_index+1] = 0; - // channel 0 (queue 0) -> E1/L1 - input_samples_dma[dma_index+2] = input_samples[index0]; - input_samples_dma[dma_index+3] = input_samples[index0+1]; - } - else - { - // channel 1 (queue 1) -> E5/L5 - input_samples_dma[dma_index] = input_samples[index0]; - input_samples_dma[dma_index+1] = input_samples[index0+1]; - // channel 0 (queue 0) -> E1/L1 - input_samples_dma[dma_index+2] = 0; - input_samples_dma[dma_index+3] = 0; - } - dma_index += 4; - } - nsamples_transmitted = write(tx_fd, &input_samples_dma[0], nread_elements*NUM_QUEUES); - if (nsamples_transmitted != nread_elements*NUM_QUEUES) - { - std::cout << "Error : DMA could not send all the requested samples" << std::endl; - } - } - } + if (nread_elements > 0) + { + // for the 32-BIT DMA + dma_index = 0; + for (index0 = 0; index0 < (nread_elements); index0 += COMPLEX_SAMPLE_SIZE) + { + if (args->freq_band == 0) + { + // channel 1 (queue 1) -> E5/L5 + input_samples_dma[dma_index] = 0; + input_samples_dma[dma_index + 1] = 0; + // channel 0 (queue 0) -> E1/L1 + input_samples_dma[dma_index + 2] = input_samples[index0]; + input_samples_dma[dma_index + 3] = input_samples[index0 + 1]; + } + else + { + // channel 1 (queue 1) -> E5/L5 + input_samples_dma[dma_index] = input_samples[index0]; + input_samples_dma[dma_index + 1] = input_samples[index0 + 1]; + // channel 0 (queue 0) -> E1/L1 + input_samples_dma[dma_index + 2] = 0; + input_samples_dma[dma_index + 3] = 0; + } + dma_index += 4; + } + nsamples_transmitted = write(tx_fd, &input_samples_dma[0], nread_elements * NUM_QUEUES); + if (nsamples_transmitted != nread_elements * NUM_QUEUES) + { + std::cout << "Error : DMA could not send all the requested samples" << std::endl; + } + } + } - close(tx_fd); - fclose(rx_signal_file_id); - return NULL; + close(tx_fd); + fclose(rx_signal_file_id); + return NULL; } - - - - bool TrackingPullInTestFpga::acquire_signal(int SV_ID) { - pthread_t thread_DMA; + pthread_t thread_DMA; - // 1. Setup GNU Radio flowgraph (file_source -> Acquisition_10m) + // 1. Setup GNU Radio flowgraph (file_source -> Acquisition_10m) gr::top_block_sptr top_block; top_block = gr::make_top_block("Acquisition test"); @@ -566,8 +561,7 @@ bool TrackingPullInTestFpga::acquire_signal(int SV_ID) if (implementation.compare("GPS_L1_CA_DLL_PLL_Tracking_Fpga") == 0) { - - tmp_gnss_synchro.System = 'G'; + tmp_gnss_synchro.System = 'G'; std::string signal = "1C"; const char* str = signal.c_str(); // get a C style null terminated string std::memcpy(static_cast(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null @@ -576,14 +570,12 @@ bool TrackingPullInTestFpga::acquire_signal(int SV_ID) args.freq_band = 0; - acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); - + acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); } else if (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") == 0) { - tmp_gnss_synchro.System = 'E'; std::string signal = "1B"; const char* str = signal.c_str(); // get a C style null terminated string @@ -594,7 +586,6 @@ bool TrackingPullInTestFpga::acquire_signal(int SV_ID) args.freq_band = 0; acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); - } else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking_Fpga") == 0) { @@ -608,8 +599,6 @@ bool TrackingPullInTestFpga::acquire_signal(int SV_ID) args.freq_band = 1; acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); - - } else if (implementation.compare("GPS_L5_DLL_PLL_Tracking_Fpga") == 0) { @@ -622,7 +611,6 @@ bool TrackingPullInTestFpga::acquire_signal(int SV_ID) args.freq_band = 1; acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); - } else { @@ -651,7 +639,7 @@ bool TrackingPullInTestFpga::acquire_signal(int SV_ID) msg_rx->top_block = top_block; - top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); + top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); // 5. Run the flowgraph @@ -683,134 +671,130 @@ bool TrackingPullInTestFpga::acquire_signal(int SV_ID) setup_fpga_switch(); - unsigned int nsamples_to_transfer; - if (implementation.compare("GPS_L1_CA_DLL_PLL_Tracking_Fpga") == 0) - { - nsamples_to_transfer = static_cast(std::round(static_cast(baseband_sampling_freq) / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS))); - } - else if (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") == 0) - { - nsamples_to_transfer = static_cast(std::round(static_cast(baseband_sampling_freq) / (GALILEO_E1_CODE_CHIP_RATE_HZ / GALILEO_E1_B_CODE_LENGTH_CHIPS))); - } - else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking_Fpga") == 0) - { - nsamples_to_transfer = static_cast(std::round(static_cast(baseband_sampling_freq) / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS))); - } - else // (if (implementation.compare("GPS_L5_DLL_PLL_Tracking_Fpga") == 0)) - { - nsamples_to_transfer = static_cast(std::round(static_cast(baseband_sampling_freq) / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS))); - } + unsigned int nsamples_to_transfer; + if (implementation.compare("GPS_L1_CA_DLL_PLL_Tracking_Fpga") == 0) + { + nsamples_to_transfer = static_cast(std::round(static_cast(baseband_sampling_freq) / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS))); + } + else if (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") == 0) + { + nsamples_to_transfer = static_cast(std::round(static_cast(baseband_sampling_freq) / (GALILEO_E1_CODE_CHIP_RATE_HZ / GALILEO_E1_B_CODE_LENGTH_CHIPS))); + } + else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking_Fpga") == 0) + { + nsamples_to_transfer = static_cast(std::round(static_cast(baseband_sampling_freq) / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS))); + } + else // (if (implementation.compare("GPS_L5_DLL_PLL_Tracking_Fpga") == 0)) + { + nsamples_to_transfer = static_cast(std::round(static_cast(baseband_sampling_freq) / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS))); + } - int acq_doppler_max = config->property("Acquisition.doppler_max", FLAGS_external_signal_acquisition_doppler_max_hz); - int acq_doppler_step = config->property("Acquisition.doppler_step", FLAGS_external_signal_acquisition_doppler_step_hz); + int acq_doppler_max = config->property("Acquisition.doppler_max", FLAGS_external_signal_acquisition_doppler_max_hz); + int acq_doppler_step = config->property("Acquisition.doppler_step", FLAGS_external_signal_acquisition_doppler_step_hz); - for (unsigned int PRN = 1; PRN < MAX_PRN_IDX; PRN++) - { + for (unsigned int PRN = 1; PRN < MAX_PRN_IDX; PRN++) + { + tmp_gnss_synchro.PRN = PRN; - tmp_gnss_synchro.PRN = PRN; + acquisition->stop_acquisition(); // reset the whole system including the sample counters + acquisition->set_doppler_max(acq_doppler_max); + acquisition->set_doppler_step(acq_doppler_step); + acquisition->set_gnss_synchro(&tmp_gnss_synchro); + acquisition->init(); + acquisition->set_local_code(); - acquisition->stop_acquisition(); // reset the whole system including the sample counters - acquisition->set_doppler_max(acq_doppler_max); - acquisition->set_doppler_step(acq_doppler_step); - acquisition->set_gnss_synchro(&tmp_gnss_synchro); - acquisition->init(); - acquisition->set_local_code(); - - args.file = file; + args.file = file; - if ((implementation.compare("GPS_L1_CA_DLL_PLL_Tracking_Fpga") == 0) or (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") == 0)) - { - // send the previous samples to set the downsampling filter in a good condition - send_samples_start = 0; + if ((implementation.compare("GPS_L1_CA_DLL_PLL_Tracking_Fpga") == 0) or (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") == 0)) + { + // send the previous samples to set the downsampling filter in a good condition + send_samples_start = 0; - args.skip_used_samples = - DOWNAMPLING_FILTER_INIT_SAMPLES; + args.skip_used_samples = -DOWNAMPLING_FILTER_INIT_SAMPLES; - args.nsamples_tx = DOWNAMPLING_FILTER_INIT_SAMPLES + DOWNSAMPLING_FILTER_DELAY; + args.nsamples_tx = DOWNAMPLING_FILTER_INIT_SAMPLES + DOWNSAMPLING_FILTER_DELAY; - if (pthread_create(&thread_DMA, NULL, handler_DMA, (void *)&args) < 0) - { - std::cout << "ERROR cannot create DMA Process" << std::endl; - } - pthread_mutex_lock(&mutex); - send_samples_start = 1; - pthread_mutex_unlock(&mutex); - pthread_join(thread_DMA, NULL); - send_samples_start = 0; + if (pthread_create(&thread_DMA, NULL, handler_DMA, (void*)&args) < 0) + { + std::cout << "ERROR cannot create DMA Process" << std::endl; + } + pthread_mutex_lock(&mutex); + send_samples_start = 1; + pthread_mutex_unlock(&mutex); + pthread_join(thread_DMA, NULL); + send_samples_start = 0; - args.nsamples_tx = nsamples_to_transfer; + args.nsamples_tx = nsamples_to_transfer; - args.skip_used_samples = DOWNSAMPLING_FILTER_DELAY; + args.skip_used_samples = DOWNSAMPLING_FILTER_DELAY; + } + else + { + args.nsamples_tx = nsamples_to_transfer; - } - else - { - args.nsamples_tx = nsamples_to_transfer; - - args.skip_used_samples = 0; - } + args.skip_used_samples = 0; + } + if (pthread_create(&thread_DMA, NULL, handler_DMA, (void*)&args) < 0) + { + std::cout << "ERROR cannot create DMA Process" << std::endl; + } + + msg_rx->rx_message = 0; + top_block->start(); + + pthread_mutex_lock(&mutex); + send_samples_start = 1; + pthread_mutex_unlock(&mutex); + acquisition->reset(); // set active - if (pthread_create(&thread_DMA, NULL, handler_DMA, (void *)&args) < 0) - { - std::cout << "ERROR cannot create DMA Process" << std::endl; - } + if (start_msg == true) + { + std::cout << "Reading external signal file: " << FLAGS_signal_file << std::endl; + std::cout << "Searching for " << System_and_Signal << " Satellites..." << std::endl; + std::cout << "["; + start_msg = false; + } - msg_rx->rx_message = 0; - top_block->start(); + // wait for the child DMA process to finish + pthread_join(thread_DMA, NULL); - pthread_mutex_lock(&mutex); - send_samples_start = 1; - pthread_mutex_unlock(&mutex); + pthread_mutex_lock(&mutex); + send_samples_start = 0; + pthread_mutex_unlock(&mutex); + + // the DMA sends the exact number of samples needed for the acquisition. + // however because of the LPF in the GPS L1/Gal E1 acquisition, this calculation is approximate + // and some extra samples might be sent. Wait at least once to give time the HW to consume any extra + // sample the DMA might have sent. + do + { + usleep(100000); + } + while (msg_rx->rx_message == 0); + + if (msg_rx->rx_message == 1) + { + std::cout << " " << PRN << " "; + doppler_measurements_map.insert(std::pair(PRN, tmp_gnss_synchro.Acq_doppler_hz)); + code_delay_measurements_map.insert(std::pair(PRN, tmp_gnss_synchro.Acq_delay_samples)); + tmp_gnss_synchro.Acq_samplestamp_samples = 0; // do not take into account the filter internal state initialisation + acq_samplestamp_map.insert(std::pair(PRN, tmp_gnss_synchro.Acq_samplestamp_samples)); + } + else + { + std::cout << " . "; + } - acquisition->reset(); // set active + top_block->stop(); - if (start_msg == true) - { - std::cout << "Reading external signal file: " << FLAGS_signal_file << std::endl; - std::cout << "Searching for " << System_and_Signal << " Satellites..." << std::endl; - std::cout << "["; - start_msg = false; - } - - // wait for the child DMA process to finish - pthread_join(thread_DMA, NULL); - - pthread_mutex_lock(&mutex); - send_samples_start = 0; - pthread_mutex_unlock(&mutex); - - // the DMA sends the exact number of samples needed for the acquisition. - // however because of the LPF in the GPS L1/Gal E1 acquisition, this calculation is approximate - // and some extra samples might be sent. Wait at least once to give time the HW to consume any extra - // sample the DMA might have sent. - do { - usleep(100000); - } while (msg_rx->rx_message == 0); - - if (msg_rx->rx_message == 1) - { - std::cout << " " << PRN << " "; - doppler_measurements_map.insert(std::pair(PRN, tmp_gnss_synchro.Acq_doppler_hz)); - code_delay_measurements_map.insert(std::pair(PRN, tmp_gnss_synchro.Acq_delay_samples)); - tmp_gnss_synchro.Acq_samplestamp_samples = 0; // do not take into account the filter internal state initialisation - acq_samplestamp_map.insert(std::pair(PRN, tmp_gnss_synchro.Acq_samplestamp_samples)); - } - else - { - std::cout << " . "; - } - - - top_block->stop(); - - std::cout.flush(); - - } + std::cout.flush(); + } std::cout << "]" << std::endl; std::cout << "-------------------------------------------\n"; @@ -821,7 +805,6 @@ bool TrackingPullInTestFpga::acquire_signal(int SV_ID) } - // report the elapsed time end = std::chrono::system_clock::now(); elapsed_seconds = end - start; @@ -833,13 +816,11 @@ bool TrackingPullInTestFpga::acquire_signal(int SV_ID) TEST_F(TrackingPullInTestFpga, ValidationOfResults) { + // pointer to the DMA thread that sends the samples to the acquisition engine + pthread_t thread_DMA; - // pointer to the DMA thread that sends the samples to the acquisition engine - pthread_t thread_DMA; - - - struct DMA_handler_args args; + struct DMA_handler_args args; //************************************************* @@ -886,7 +867,6 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults) } - // use generator or use an external capture file if (FLAGS_enable_external_signal_file) { @@ -953,71 +933,69 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults) std::cout << "Estimated Initial Doppler " << true_acq_doppler_hz << " [Hz], estimated Initial code delay " << true_acq_delay_samples << " [Samples]" << " Acquisition SampleStamp is " << acq_samplestamp_samples << std::endl; - } std::vector> pull_in_results_v_v; - unsigned int code_length; - if (implementation.compare("GPS_L1_CA_DLL_PLL_Tracking_Fpga") == 0) - { - code_length = static_cast(std::round(static_cast(baseband_sampling_freq) / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS))); - } - else if (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") == 0) - { - code_length = static_cast(std::round(static_cast(baseband_sampling_freq) / (GALILEO_E1_CODE_CHIP_RATE_HZ / GALILEO_E1_B_CODE_LENGTH_CHIPS))); - } - else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking_Fpga") == 0) - { - code_length = static_cast(std::round(static_cast(baseband_sampling_freq) / GALILEO_E5A_CODE_CHIP_RATE_HZ * static_cast(GALILEO_E5A_CODE_LENGTH_CHIPS))); + unsigned int code_length; + if (implementation.compare("GPS_L1_CA_DLL_PLL_Tracking_Fpga") == 0) + { + code_length = static_cast(std::round(static_cast(baseband_sampling_freq) / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS))); + } + else if (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") == 0) + { + code_length = static_cast(std::round(static_cast(baseband_sampling_freq) / (GALILEO_E1_CODE_CHIP_RATE_HZ / GALILEO_E1_B_CODE_LENGTH_CHIPS))); + } + else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking_Fpga") == 0) + { + code_length = static_cast(std::round(static_cast(baseband_sampling_freq) / GALILEO_E5A_CODE_CHIP_RATE_HZ * static_cast(GALILEO_E5A_CODE_LENGTH_CHIPS))); + } + else // (if (implementation.compare("GPS_L5_DLL_PLL_Tracking_Fpga") == 0)) + { + code_length = static_cast(std::round(static_cast(baseband_sampling_freq) / (GPS_L5I_CODE_RATE_HZ / static_cast(GPS_L5I_CODE_LENGTH_CHIPS)))); + } - } - else // (if (implementation.compare("GPS_L5_DLL_PLL_Tracking_Fpga") == 0)) - { - code_length = static_cast(std::round(static_cast(baseband_sampling_freq) / (GPS_L5I_CODE_RATE_HZ / static_cast(GPS_L5I_CODE_LENGTH_CHIPS)))); - } + float nbits = ceilf(log2f((float)code_length)); + unsigned int fft_size = pow(2, nbits); - float nbits = ceilf(log2f((float)code_length)); - unsigned int fft_size = pow(2, nbits); + // The HW has been reset after the acquisition phase when the acquisition class was destroyed. + // No more samples remained in the DMA. Therefore any intermediate state in the LPF of the + // GPS L1 / Galileo E1 filter has been cleared. + // During this test all the samples coming from the DMA are consumed so in principle there would be + // no need to reset the HW. However we need to clear the sample counter in each test. Therefore we have + // to reset the HW at the beginning of each test. - // The HW has been reset after the acquisition phase when the acquisition class was destroyed. - // No more samples remained in the DMA. Therefore any intermediate state in the LPF of the - // GPS L1 / Galileo E1 filter has been cleared. - // During this test all the samples coming from the DMA are consumed so in principle there would be - // no need to reset the HW. However we need to clear the sample counter in each test. Therefore we have - // to reset the HW at the beginning of each test. + // instantiate the acquisition modules in order to use them to reset the HW. + // (note that the constructor of the acquisition modules resets the HW too) - // instantiate the acquisition modules in order to use them to reset the HW. - // (note that the constructor of the acquisition modules resets the HW too) - - std::shared_ptr acquisition; + std::shared_ptr acquisition; - if (implementation.compare("GPS_L1_CA_DLL_PLL_Tracking_Fpga") == 0) - { - acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); - args.freq_band = 0; - } - else if (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") == 0) - { - acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); - args.freq_band = 0; - } - else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking_Fpga") == 0) - { - acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); - args.freq_band = 1; - } - else if (implementation.compare("GPS_L5_DLL_PLL_Tracking_Fpga") == 0) - { - acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); - args.freq_band = 1; - } + if (implementation.compare("GPS_L1_CA_DLL_PLL_Tracking_Fpga") == 0) + { + acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); + args.freq_band = 0; + } + else if (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") == 0) + { + acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); + args.freq_band = 0; + } + else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking_Fpga") == 0) + { + acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); + args.freq_band = 1; + } + else if (implementation.compare("GPS_L5_DLL_PLL_Tracking_Fpga") == 0) + { + acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); + args.freq_band = 1; + } else - { - std::cout << "The test can not run with the selected tracking implementation\n "; - throw(std::exception()); - } + { + std::cout << "The test can not run with the selected tracking implementation\n "; + throw(std::exception()); + } for (unsigned int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) { @@ -1026,11 +1004,10 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults) { for (unsigned int current_acq_code_error_idx = 0; current_acq_code_error_idx < acq_delay_error_chips_values.at(current_acq_doppler_error_idx).size(); current_acq_code_error_idx++) { + // reset the HW to clear the sample counters + acquisition->stop_acquisition(); - // reset the HW to clear the sample counters - acquisition->stop_acquisition(); - - gnss_synchro.Acq_samplestamp_samples = acq_samplestamp_samples; + gnss_synchro.Acq_samplestamp_samples = acq_samplestamp_samples; //simulate a Doppler error in acquisition gnss_synchro.Acq_doppler_hz = true_acq_doppler_hz + acq_doppler_error_hz_values.at(current_acq_doppler_error_idx); //simulate Code Delay error in acquisition @@ -1065,13 +1042,13 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults) args.file = file; - if (skip_samples_already_used == 1) + if (skip_samples_already_used == 1) { - args.skip_used_samples = (gnss_synchro.PRN - 1)*fft_size; + args.skip_used_samples = (gnss_synchro.PRN - 1) * fft_size; } - else + else { - args.skip_used_samples = 0; + args.skip_used_samples = 0; } @@ -1080,13 +1057,13 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults) //******************************************************************** - args.nsamples_tx = baseband_sampling_freq*FLAGS_duration; + args.nsamples_tx = baseband_sampling_freq * FLAGS_duration; - if (pthread_create(&thread_DMA, NULL, handler_DMA, (void *)&args) < 0) - { - std::cout << "ERROR cannot create DMA Process" << std::endl; - } + if (pthread_create(&thread_DMA, NULL, handler_DMA, (void*)&args) < 0) + { + std::cout << "ERROR cannot create DMA Process" << std::endl; + } std::cout << "--- START TRACKING WITH PULL-IN ERROR: " << acq_doppler_error_hz_values.at(current_acq_doppler_error_idx) << " [Hz] and " << acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx) << " [Chips] ---" << std::endl; @@ -1098,17 +1075,17 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults) top_block->start(); - // wait for the child DMA process to finish - pthread_join(thread_DMA, NULL); + // wait for the child DMA process to finish + pthread_join(thread_DMA, NULL); - top_block->stop(); + top_block->stop(); - // reset the HW to launch the pending interrupts - acquisition->stop_acquisition(); + // reset the HW to launch the pending interrupts + acquisition->stop_acquisition(); - pthread_mutex_lock(&mutex); - send_samples_start = 0; - pthread_mutex_unlock(&mutex); + pthread_mutex_lock(&mutex); + send_samples_start = 0; + pthread_mutex_unlock(&mutex); pull_in_results_v.push_back(msg_rx->rx_message != 3); //save last asynchronous tracking message in order to detect a loss of lock @@ -1280,9 +1257,9 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults) } //end acquisition Delay errors loop - usleep(100000); // give time to the HW to consume all the remaining samples + usleep(100000); // give time to the HW to consume all the remaining samples - } //end acquisition Doppler errors loop + } //end acquisition Doppler errors loop pull_in_results_v_v.push_back(pull_in_results_v); @@ -1308,44 +1285,40 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults) if (FLAGS_show_plots) { - Gnuplot g4("points palette pointsize 2 pointtype 7"); - g4.showonscreen(); // window output - g4.cmd("set palette defined ( 0 \"black\", 1 \"green\" )"); - g4.cmd("set key off"); - g4.cmd("set view map"); - std::string title; - if (!FLAGS_enable_external_signal_file) - { - title = std::string("Tracking Pull-in result grid at CN0:" + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + " [dB-Hz], PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz]."); - } - else - { - title = std::string("Tracking Pull-in result grid, PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], GPS L1 C/A (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); - } - - g4.set_title(title); - g4.set_grid(); - g4.set_xlabel("Acquisition Doppler error [Hz]"); - g4.set_ylabel("Acquisition Code Delay error [Chips]"); - g4.cmd("set cbrange[0:1]"); - g4.plot_xyz(doppler_error_mesh, - code_delay_error_mesh, - pull_in_result_mesh); - g4.set_legend(); - if (!FLAGS_enable_external_signal_file) - { - g4.savetops("trk_pull_in_grid_" + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx))))); - g4.savetopdf("trk_pull_in_grid_" + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))), 12); - } - else - { - g4.savetops("trk_pull_in_grid_external_file"); - g4.savetopdf("trk_pull_in_grid_external_file", 12); - } + Gnuplot g4("points palette pointsize 2 pointtype 7"); + g4.showonscreen(); // window output + g4.cmd("set palette defined ( 0 \"black\", 1 \"green\" )"); + g4.cmd("set key off"); + g4.cmd("set view map"); + std::string title; + if (!FLAGS_enable_external_signal_file) + { + title = std::string("Tracking Pull-in result grid at CN0:" + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + " [dB-Hz], PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz]."); + } + else + { + title = std::string("Tracking Pull-in result grid, PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], GPS L1 C/A (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + } + g4.set_title(title); + g4.set_grid(); + g4.set_xlabel("Acquisition Doppler error [Hz]"); + g4.set_ylabel("Acquisition Code Delay error [Chips]"); + g4.cmd("set cbrange[0:1]"); + g4.plot_xyz(doppler_error_mesh, + code_delay_error_mesh, + pull_in_result_mesh); + g4.set_legend(); + if (!FLAGS_enable_external_signal_file) + { + g4.savetops("trk_pull_in_grid_" + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx))))); + g4.savetopdf("trk_pull_in_grid_" + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))), 12); + } + else + { + g4.savetops("trk_pull_in_grid_external_file"); + g4.savetopdf("trk_pull_in_grid_external_file", 12); + } } - } - - }