diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc index a9cf7d51a..fdd6260c8 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc @@ -88,14 +88,37 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition( acq_parameters.blocking = blocking_; dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename); acq_parameters.dump_filename = dump_filename_; - //--- Find number of samples per spreading code (4 ms) ----------------- - code_length_ = static_cast(std::floor(static_cast(fs_in_) / (Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS))); - float samples_per_ms = static_cast(fs_in_) * 0.001; - acq_parameters.samples_per_ms = samples_per_ms; - acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast(Galileo_E1_CODE_PERIOD_MS); - vector_length_ = sampled_ms_ * samples_per_ms; + acq_parameters_.use_automatic_resampler = configuration_->property("GNSS-SDR.use_acquisition_resampler", false); + if (acq_parameters_.use_automatic_resampler == true and item_type_.compare("gr_complex") != 0) + { + LOG(WARNING) << "Galileo E1 acqisition disabled the automatic resampler feature because its item_type is not set to gr_complex"; + acq_parameters_.use_automatic_resampler = false; + } + if (acq_parameters_.use_automatic_resampler) + { + if (acq_parameters_.fs_in > Galileo_E1_OPT_ACQ_FS_HZ) + { + acq_parameters_.resampled_fs = Galileo_E1_OPT_ACQ_FS_HZ; + acq_parameters_.resampler_ratio = static_cast(acq_parameters_.fs_in) / static_cast(acq_parameters_.resampled_fs); + } + //--- Find number of samples per spreading code (4 ms) ----------------- + code_length_ = static_cast(std::floor(static_cast(acq_parameters_.resampled_fs) / (Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS))); + float samples_per_ms = static_cast(acq_parameters_.resampled_fs) * 0.001; + acq_parameters_.samples_per_ms = samples_per_ms; + acq_parameters_.samples_per_code = acq_parameters_.samples_per_ms * static_cast(Galileo_E1_CODE_PERIOD_MS); + vector_length_ = sampled_ms_ * samples_per_ms; + } + else + { + //--- Find number of samples per spreading code (4 ms) ----------------- + code_length_ = static_cast(std::floor(static_cast(fs_in_) / (Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS))); + float samples_per_ms = static_cast(fs_in_) * 0.001; + acq_parameters_.samples_per_ms = samples_per_ms; + acq_parameters_.samples_per_code = acq_parameters_.samples_per_ms * static_cast(Galileo_E1_CODE_PERIOD_MS); + vector_length_ = sampled_ms_ * samples_per_ms; + } if (bit_transition_flag_) { vector_length_ *= 2; @@ -227,13 +250,29 @@ void GalileoE1PcpsAmbiguousAcquisition::set_local_code() { //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, gnss_synchro_->PRN, fs_in_, 0, false); + if (acq_parameters_.use_automatic_resampler) + { + galileo_e1_code_gen_complex_sampled(code, pilot_signal, + cboc, gnss_synchro_->PRN, acq_parameters_.resampled_fs, 0, false); + } + else + { + galileo_e1_code_gen_complex_sampled(code, pilot_signal, + cboc, gnss_synchro_->PRN, fs_in_, 0, false); + } } else { - galileo_e1_code_gen_complex_sampled(code, gnss_synchro_->Signal, - cboc, gnss_synchro_->PRN, fs_in_, 0, false); + if (acq_parameters_.use_automatic_resampler) + { + galileo_e1_code_gen_complex_sampled(code, gnss_synchro_->Signal, + cboc, gnss_synchro_->PRN, acq_parameters_.resampled_fs, 0, false); + } + else + { + galileo_e1_code_gen_complex_sampled(code, gnss_synchro_->Signal, + cboc, gnss_synchro_->PRN, fs_in_, 0, false); + } } diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.h b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.h index 4f4a3c657..8e7859556 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.h +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.h @@ -33,6 +33,7 @@ #define GNSS_SDR_GALILEO_E1_PCPS_AMBIGUOUS_ACQUISITION_H_ #include "acquisition_interface.h" +#include "acq_conf.h" #include "gnss_synchro.h" #include "pcps_acquisition.h" #include "complex_byte_to_float_x2.h" @@ -139,6 +140,7 @@ public: private: ConfigurationInterface* configuration_; + Acq_Conf acq_parameters_; pcps_acquisition_sptr acquisition_; gr::blocks::float_to_complex::sptr float_to_complex_; complex_byte_to_float_x2_sptr cbyte_to_float_x2_; diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc index 7787b34cb..c7c109672 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc @@ -84,16 +84,44 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition( max_dwells_ = configuration_->property(role + ".max_dwells", 1); acq_parameters.max_dwells = max_dwells_; dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename); - acq_parameters.dump_filename = dump_filename_; - acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); - acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0); - acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false); - //--- Find number of samples per spreading code ------------------------- - code_length_ = static_cast(std::floor(static_cast(fs_in_) / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS))); - acq_parameters.samples_per_ms = static_cast(fs_in_) * 0.001; - acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast(GPS_L1_CA_CODE_PERIOD * 1000.0); - - vector_length_ = std::floor(acq_parameters.sampled_ms * acq_parameters.samples_per_ms) * (acq_parameters.bit_transition_flag ? 2 : 1); + acq_parameters_.dump_filename = dump_filename_; + acq_parameters_.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); + acq_parameters_.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0); + acq_parameters_.make_2_steps = configuration_->property(role + ".make_two_steps", false); + acq_parameters_.use_automatic_resampler = configuration_->property("GNSS-SDR.use_acquisition_resampler", false); + if (acq_parameters_.use_automatic_resampler == true and item_type_.compare("gr_complex") != 0) + { + LOG(WARNING) << "GPS L1 CA acquisition disabled the automatic resampler feature because its item_type is not set to gr_complex"; + acq_parameters_.use_automatic_resampler = false; + } + if (acq_parameters_.use_automatic_resampler) + { + if (acq_parameters_.fs_in > GPS_L1_CA_OPT_ACQ_FS_HZ) + { + acq_parameters_.resampler_ratio = floor(static_cast(acq_parameters_.fs_in) / GPS_L1_CA_OPT_ACQ_FS_HZ); + uint32_t decimation = acq_parameters_.fs_in / GPS_L1_CA_OPT_ACQ_FS_HZ; + while (acq_parameters_.fs_in % decimation > 0) + { + decimation--; + }; + acq_parameters_.resampler_ratio = decimation; + acq_parameters_.resampled_fs = acq_parameters_.fs_in / static_cast(acq_parameters_.resampler_ratio); + } + //--- Find number of samples per spreading code ------------------------- + code_length_ = static_cast(std::floor(static_cast(acq_parameters_.resampled_fs) / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS))); + acq_parameters_.samples_per_ms = static_cast(acq_parameters_.resampled_fs) * 0.001; + acq_parameters_.samples_per_code = acq_parameters_.samples_per_ms * static_cast(GPS_L1_CA_CODE_PERIOD * 1000.0); + vector_length_ = std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2 : 1); + } + else + { + acq_parameters_.resampled_fs = fs_in_; + //--- Find number of samples per spreading code ------------------------- + code_length_ = static_cast(std::floor(static_cast(fs_in_) / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS))); + acq_parameters_.samples_per_ms = static_cast(fs_in_) * 0.001; + acq_parameters_.samples_per_code = acq_parameters_.samples_per_ms * static_cast(GPS_L1_CA_CODE_PERIOD * 1000.0); + vector_length_ = std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2 : 1); + } code_ = new gr_complex[vector_length_]; if (item_type_ == "cshort") @@ -208,8 +236,14 @@ void GpsL1CaPcpsAcquisition::set_local_code() { std::complex* code = new std::complex[code_length_]; - gps_l1_ca_code_gen_complex_sampled(code, gnss_synchro_->PRN, fs_in_, 0); - + if (acq_parameters_.use_automatic_resampler) + { + gps_l1_ca_code_gen_complex_sampled(code, gnss_synchro_->PRN, acq_parameters_.resampled_fs, 0); + } + else + { + gps_l1_ca_code_gen_complex_sampled(code, gnss_synchro_->PRN, fs_in_, 0); + } for (unsigned int i = 0; i < sampled_ms_; i++) { memcpy(&(code_[i * code_length_]), code, diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.h b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.h index 5aee6bc7a..e5d8c4719 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.h +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.h @@ -37,6 +37,7 @@ #define GNSS_SDR_GPS_L1_CA_PCPS_ACQUISITION_H_ #include "acquisition_interface.h" +#include "acq_conf.h" #include "gnss_synchro.h" #include "pcps_acquisition.h" #include "complex_byte_to_float_x2.h" @@ -144,6 +145,7 @@ public: private: ConfigurationInterface* configuration_; pcps_acquisition_sptr acquisition_; + Acq_Conf acq_parameters_; gr::blocks::float_to_complex::sptr float_to_complex_; complex_byte_to_float_x2_sptr cbyte_to_float_x2_; size_t item_size_; diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc index a7df810a7..33f6de205 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc @@ -283,7 +283,15 @@ bool pcps_acquisition::is_fdma() void pcps_acquisition::update_local_carrier(gr_complex* carrier_vector, int32_t correlator_length_samples, float freq) { - float phase_step_rad = GPS_TWO_PI * freq / static_cast(acq_parameters.fs_in); + float phase_step_rad; + if (acq_parameters.use_automatic_resampler) + { + phase_step_rad = GPS_TWO_PI * freq / static_cast(acq_parameters.resampled_fs); + } + else + { + phase_step_rad = GPS_TWO_PI * freq / static_cast(acq_parameters.fs_in); + } float _phase[1]; _phase[0] = 0.0; volk_gnsssdr_s32f_sincos_32fc(carrier_vector, -phase_step_rad, _phase, correlator_length_samples); @@ -719,9 +727,19 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count) { d_test_statistics = first_vs_second_peak_statistic(indext, doppler, d_num_doppler_bins, acq_parameters.doppler_max, d_doppler_step); } - d_gnss_synchro->Acq_delay_samples = static_cast(std::fmod(static_cast(indext), acq_parameters.samples_per_code)); - d_gnss_synchro->Acq_doppler_hz = static_cast(doppler); - d_gnss_synchro->Acq_samplestamp_samples = samp_count; + if (acq_parameters.use_automatic_resampler) + { + //take into account the acquisition resampler ratio + d_gnss_synchro->Acq_delay_samples = static_cast(std::fmod(static_cast(indext), acq_parameters.samples_per_code)) * acq_parameters.resampler_ratio; + d_gnss_synchro->Acq_doppler_hz = static_cast(doppler); + d_gnss_synchro->Acq_samplestamp_samples = rint(static_cast(samp_count) * acq_parameters.resampler_ratio); + } + else + { + d_gnss_synchro->Acq_delay_samples = static_cast(std::fmod(static_cast(indext), acq_parameters.samples_per_code)); + d_gnss_synchro->Acq_doppler_hz = static_cast(doppler); + d_gnss_synchro->Acq_samplestamp_samples = samp_count; + } } else { @@ -765,10 +783,22 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count) { d_test_statistics = first_vs_second_peak_statistic(indext, doppler, d_num_doppler_bins_step2, static_cast(d_doppler_center_step_two - (static_cast(d_num_doppler_bins_step2) / 2.0) * acq_parameters.doppler_step2), acq_parameters.doppler_step2); } - d_gnss_synchro->Acq_delay_samples = static_cast(std::fmod(static_cast(indext), acq_parameters.samples_per_code)); - d_gnss_synchro->Acq_doppler_hz = static_cast(doppler); - d_gnss_synchro->Acq_samplestamp_samples = samp_count; - d_gnss_synchro->Acq_doppler_step = acq_parameters.doppler_step2; + + if (acq_parameters.use_automatic_resampler) + { + //take into account the acquisition resampler ratio + d_gnss_synchro->Acq_delay_samples = static_cast(std::fmod(static_cast(indext), acq_parameters.samples_per_code)) * acq_parameters.resampler_ratio; + d_gnss_synchro->Acq_doppler_hz = static_cast(doppler); + d_gnss_synchro->Acq_samplestamp_samples = rint(static_cast(samp_count) * acq_parameters.resampler_ratio); + d_gnss_synchro->Acq_doppler_step = acq_parameters.doppler_step2; + } + else + { + d_gnss_synchro->Acq_delay_samples = static_cast(std::fmod(static_cast(indext), acq_parameters.samples_per_code)); + d_gnss_synchro->Acq_doppler_hz = static_cast(doppler); + d_gnss_synchro->Acq_samplestamp_samples = samp_count; + d_gnss_synchro->Acq_doppler_step = acq_parameters.doppler_step2; + } } lk.lock(); @@ -868,6 +898,12 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count) } } +// Called by gnuradio to enable drivers, etc for i/o devices. +bool pcps_acquisition::start() +{ + d_sample_counter = 0ULL; + return true; +} int pcps_acquisition::general_work(int noutput_items __attribute__((unused)), gr_vector_int& ninput_items, gr_vector_const_void_star& input_items, diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h index 4e46d049b..392332e46 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h @@ -98,6 +98,9 @@ private: float first_vs_second_peak_statistic(uint32_t& indext, int32_t& doppler, uint32_t num_doppler_bins, int32_t doppler_max, int32_t doppler_step); float max_to_input_power_statistic(uint32_t& indext, int32_t& doppler, float input_power, uint32_t num_doppler_bins, int32_t doppler_max, int32_t doppler_step); + bool start(); + + Acq_Conf acq_parameters; bool d_active; bool d_worker_active; @@ -233,6 +236,7 @@ public: d_doppler_step = doppler_step; } + /*! * \brief Parallel Code Phase Search Acquisition signal processing. */ diff --git a/src/algorithms/acquisition/libs/acq_conf.cc b/src/algorithms/acquisition/libs/acq_conf.cc index e98bf3bdf..0640153cf 100644 --- a/src/algorithms/acquisition/libs/acq_conf.cc +++ b/src/algorithms/acquisition/libs/acq_conf.cc @@ -53,4 +53,7 @@ Acq_Conf::Acq_Conf() dump_channel = 0U; it_size = sizeof(char); blocking_on_standby = false; + use_automatic_resampler = false; + resampler_ratio = 1.0; + resampled_fs = 0LL; } diff --git a/src/algorithms/acquisition/libs/acq_conf.h b/src/algorithms/acquisition/libs/acq_conf.h index 445fab878..7582ec9a3 100644 --- a/src/algorithms/acquisition/libs/acq_conf.h +++ b/src/algorithms/acquisition/libs/acq_conf.h @@ -56,6 +56,9 @@ public: bool blocking; bool blocking_on_standby; // enable it only for unit testing to avoid sample consume on idle status bool make_2_steps; + bool use_automatic_resampler; + float resampler_ratio; + int64_t resampled_fs; std::string dump_filename; uint32_t dump_channel; size_t it_size; diff --git a/src/algorithms/channel/adapters/channel.cc b/src/algorithms/channel/adapters/channel.cc index a3d6c9bf3..c39330521 100644 --- a/src/algorithms/channel/adapters/channel.cc +++ b/src/algorithms/channel/adapters/channel.cc @@ -38,12 +38,10 @@ using google::LogMessage; // Constructor -Channel::Channel(ConfigurationInterface* configuration, uint32_t channel, - std::shared_ptr pass_through, std::shared_ptr acq, +Channel::Channel(ConfigurationInterface* configuration, uint32_t channel, std::shared_ptr acq, std::shared_ptr trk, std::shared_ptr nav, std::string role, std::string implementation, gr::msg_queue::sptr queue) { - pass_through_ = std::move(pass_through); acq_ = std::move(acq); trk_ = std::move(trk); nav_ = std::move(nav); @@ -112,32 +110,15 @@ Channel::~Channel() = default; void Channel::connect(gr::top_block_sptr top_block) { - if (connected_) - { - LOG(WARNING) << "channel already connected internally"; - return; - } - if (flag_enable_fpga == false) - { - pass_through_->connect(top_block); - } acq_->connect(top_block); trk_->connect(top_block); nav_->connect(top_block); //Synchronous ports - if (flag_enable_fpga == false) - { - top_block->connect(pass_through_->get_right_block(), 0, acq_->get_left_block(), 0); - DLOG(INFO) << "pass_through_ -> acquisition"; - top_block->connect(pass_through_->get_right_block(), 0, trk_->get_left_block(), 0); - DLOG(INFO) << "pass_through_ -> tracking"; - } top_block->connect(trk_->get_right_block(), 0, nav_->get_left_block(), 0); DLOG(INFO) << "tracking -> telemetry_decoder"; // Message ports - top_block->msg_connect(acq_->get_right_block(), pmt::mp("events"), channel_msg_rx, pmt::mp("events")); top_block->msg_connect(trk_->get_right_block(), pmt::mp("events"), channel_msg_rx, pmt::mp("events")); @@ -153,17 +134,8 @@ void Channel::disconnect(gr::top_block_sptr top_block) return; } - if (flag_enable_fpga == false) - { - top_block->disconnect(pass_through_->get_right_block(), 0, acq_->get_left_block(), 0); - top_block->disconnect(pass_through_->get_right_block(), 0, trk_->get_left_block(), 0); - } top_block->disconnect(trk_->get_right_block(), 0, nav_->get_left_block(), 0); - if (flag_enable_fpga == false) - { - pass_through_->disconnect(top_block); - } acq_->disconnect(top_block); trk_->disconnect(top_block); nav_->disconnect(top_block); @@ -173,9 +145,19 @@ void Channel::disconnect(gr::top_block_sptr top_block) gr::basic_block_sptr Channel::get_left_block() { - return pass_through_->get_left_block(); + LOG(ERROR) << "Deprecated call to get_left_block() in channel interface"; + return NULL; } +gr::basic_block_sptr Channel::get_left_block_trk() +{ + return trk_->get_left_block(); +} + +gr::basic_block_sptr Channel::get_left_block_acq() +{ + return acq_->get_left_block(); +} gr::basic_block_sptr Channel::get_right_block() { diff --git a/src/algorithms/channel/adapters/channel.h b/src/algorithms/channel/adapters/channel.h index 3802ff107..c38585b69 100644 --- a/src/algorithms/channel/adapters/channel.h +++ b/src/algorithms/channel/adapters/channel.h @@ -60,16 +60,17 @@ class Channel : public ChannelInterface { public: //! Constructor - Channel(ConfigurationInterface* configuration, uint32_t channel, - std::shared_ptr pass_through, std::shared_ptr acq, + Channel(ConfigurationInterface* configuration, uint32_t channel, std::shared_ptr acq, std::shared_ptr trk, std::shared_ptr nav, std::string role, std::string implementation, gr::msg_queue::sptr queue); //! Virtual destructor virtual ~Channel(); - void connect(gr::top_block_sptr top_block) override; + void connect(gr::top_block_sptr top_block) override; //!< connects the tracking block to the top_block and to the telemetry void disconnect(gr::top_block_sptr top_block) override; - gr::basic_block_sptr get_left_block() override; + gr::basic_block_sptr get_left_block() override; //!< gets the gnuradio tracking block pointer + gr::basic_block_sptr get_left_block_trk() override; //!< gets the gnuradio tracking block pointer + gr::basic_block_sptr get_left_block_acq() override; //!< gets the gnuradio tracking block pointer gr::basic_block_sptr get_right_block() override; inline std::string role() override { return role_; } @@ -88,7 +89,6 @@ public: private: channel_msg_receiver_cc_sptr channel_msg_rx; - std::shared_ptr pass_through_; std::shared_ptr acq_; std::shared_ptr trk_; std::shared_ptr nav_; diff --git a/src/algorithms/resampler/adapters/mmse_resampler_conditioner.cc b/src/algorithms/resampler/adapters/mmse_resampler_conditioner.cc index 4c5119a4a..83003cc8f 100644 --- a/src/algorithms/resampler/adapters/mmse_resampler_conditioner.cc +++ b/src/algorithms/resampler/adapters/mmse_resampler_conditioner.cc @@ -69,7 +69,7 @@ MmseResamplerConditioner::MmseResamplerConditioner( std::vector taps = gr::filter::firdes::low_pass(1.0, sample_freq_in_, sample_freq_out_ / 2.1, - sample_freq_out_ / 10, + sample_freq_out_ / 5, gr::filter::firdes::win_type::WIN_HAMMING); std::cout << "Enabled fractional resampler low pass filter with " << taps.size() << " taps" << std::endl; fir_filter_ccf_ = gr::filter::fir_filter_ccf::make(1, taps); diff --git a/src/core/interfaces/channel_interface.h b/src/core/interfaces/channel_interface.h index db449941c..d4f97aea5 100644 --- a/src/core/interfaces/channel_interface.h +++ b/src/core/interfaces/channel_interface.h @@ -51,6 +51,10 @@ class ChannelInterface : public GNSSBlockInterface { public: + virtual gr::basic_block_sptr get_left_block_trk() = 0; + virtual gr::basic_block_sptr get_left_block_acq() = 0; + virtual gr::basic_block_sptr get_left_block() = 0; + virtual gr::basic_block_sptr get_right_block() = 0; virtual Gnss_Signal get_signal() const = 0; virtual void start_acquisition() = 0; virtual void stop_channel() = 0; diff --git a/src/core/receiver/gnss_block_factory.cc b/src/core/receiver/gnss_block_factory.cc index 55218ee8d..17019e48a 100644 --- a/src/core/receiver/gnss_block_factory.cc +++ b/src/core/receiver/gnss_block_factory.cc @@ -361,12 +361,11 @@ std::unique_ptr GNSSBlockFactory::GetChannel_1C( } config->set_property("Channel.item_type", acq_item_type); - std::unique_ptr pass_through_ = GetBlock(config, "Channel", "Pass_Through", 1, 1, queue); std::unique_ptr acq_ = GetAcqBlock(configuration, "Acquisition_1C" + appendix1, acq, 1, 0); std::unique_ptr trk_ = GetTrkBlock(configuration, "Tracking_1C" + appendix2, trk, 1, 1); std::unique_ptr tlm_ = GetTlmBlock(configuration, "TelemetryDecoder_1C" + appendix3, tlm, 1, 1); - std::unique_ptr channel_(new Channel(configuration.get(), channel, std::move(pass_through_), + std::unique_ptr channel_(new Channel(configuration.get(), channel, std::move(acq_), std::move(trk_), std::move(tlm_), @@ -426,12 +425,11 @@ std::unique_ptr GNSSBlockFactory::GetChannel_2S( } config->set_property("Channel.item_type", acq_item_type); - std::unique_ptr pass_through_ = GetBlock(configuration, "Channel", "Pass_Through", 1, 1, queue); std::unique_ptr acq_ = GetAcqBlock(configuration, "Acquisition_2S" + appendix1, acq, 1, 0); std::unique_ptr trk_ = GetTrkBlock(configuration, "Tracking_2S" + appendix2, trk, 1, 1); std::unique_ptr tlm_ = GetTlmBlock(configuration, "TelemetryDecoder_2S" + appendix3, tlm, 1, 1); - std::unique_ptr channel_(new Channel(configuration.get(), channel, std::move(pass_through_), + std::unique_ptr channel_(new Channel(configuration.get(), channel, std::move(acq_), std::move(trk_), std::move(tlm_), @@ -494,12 +492,11 @@ std::unique_ptr GNSSBlockFactory::GetChannel_1B( } config->set_property("Channel.item_type", acq_item_type); - std::unique_ptr pass_through_ = GetBlock(configuration, "Channel", "Pass_Through", 1, 1, queue); std::unique_ptr acq_ = GetAcqBlock(configuration, "Acquisition_1B" + appendix1, acq, 1, 0); std::unique_ptr trk_ = GetTrkBlock(configuration, "Tracking_1B" + appendix2, trk, 1, 1); std::unique_ptr tlm_ = GetTlmBlock(configuration, "TelemetryDecoder_1B" + appendix3, tlm, 1, 1); - std::unique_ptr channel_(new Channel(configuration.get(), channel, std::move(pass_through_), + std::unique_ptr channel_(new Channel(configuration.get(), channel, std::move(acq_), std::move(trk_), std::move(tlm_), @@ -562,12 +559,11 @@ std::unique_ptr GNSSBlockFactory::GetChannel_5X( } config->set_property("Channel.item_type", acq_item_type); - std::unique_ptr pass_through_ = GetBlock(configuration, "Channel", "Pass_Through", 1, 1, queue); std::unique_ptr acq_ = GetAcqBlock(configuration, "Acquisition_5X" + appendix1, acq, 1, 0); std::unique_ptr trk_ = GetTrkBlock(configuration, "Tracking_5X" + appendix2, trk, 1, 1); std::unique_ptr tlm_ = GetTlmBlock(configuration, "TelemetryDecoder_5X" + appendix3, tlm, 1, 1); - std::unique_ptr channel_(new Channel(configuration.get(), channel, std::move(pass_through_), + std::unique_ptr channel_(new Channel(configuration.get(), channel, std::move(acq_), std::move(trk_), std::move(tlm_), @@ -631,12 +627,11 @@ std::unique_ptr GNSSBlockFactory::GetChannel_1G( } config->set_property("Channel.item_type", acq_item_type); - std::unique_ptr pass_through_ = GetBlock(config, "Channel", "Pass_Through", 1, 1, queue); std::unique_ptr acq_ = GetAcqBlock(configuration, "Acquisition_1G" + appendix1, acq, 1, 0); std::unique_ptr trk_ = GetTrkBlock(configuration, "Tracking_1G" + appendix2, trk, 1, 1); std::unique_ptr tlm_ = GetTlmBlock(configuration, "TelemetryDecoder_1G" + appendix3, tlm, 1, 1); - std::unique_ptr channel_(new Channel(configuration.get(), channel, std::move(pass_through_), + std::unique_ptr channel_(new Channel(configuration.get(), channel, std::move(acq_), std::move(trk_), std::move(tlm_), @@ -700,12 +695,11 @@ std::unique_ptr GNSSBlockFactory::GetChannel_2G( } config->set_property("Channel.item_type", acq_item_type); - std::unique_ptr pass_through_ = GetBlock(config, "Channel", "Pass_Through", 1, 1, queue); std::unique_ptr acq_ = GetAcqBlock(configuration, "Acquisition_2G" + appendix1, acq, 1, 0); std::unique_ptr trk_ = GetTrkBlock(configuration, "Tracking_2G" + appendix2, trk, 1, 1); std::unique_ptr tlm_ = GetTlmBlock(configuration, "TelemetryDecoder_2G" + appendix3, tlm, 1, 1); - std::unique_ptr channel_(new Channel(configuration.get(), channel, std::move(pass_through_), + std::unique_ptr channel_(new Channel(configuration.get(), channel, std::move(acq_), std::move(trk_), std::move(tlm_), @@ -768,12 +762,11 @@ std::unique_ptr GNSSBlockFactory::GetChannel_L5( } config->set_property("Channel.item_type", acq_item_type); - std::unique_ptr pass_through_ = GetBlock(configuration, "Channel", "Pass_Through", 1, 1, queue); std::unique_ptr acq_ = GetAcqBlock(configuration, "Acquisition_L5" + appendix1, acq, 1, 0); std::unique_ptr trk_ = GetTrkBlock(configuration, "Tracking_L5" + appendix2, trk, 1, 1); std::unique_ptr tlm_ = GetTlmBlock(configuration, "TelemetryDecoder_L5" + appendix3, tlm, 1, 1); - std::unique_ptr channel_(new Channel(configuration.get(), channel, std::move(pass_through_), + std::unique_ptr channel_(new Channel(configuration.get(), channel, std::move(acq_), std::move(trk_), std::move(tlm_), diff --git a/src/core/receiver/gnss_flowgraph.cc b/src/core/receiver/gnss_flowgraph.cc index bb27826bb..f722b0a48 100644 --- a/src/core/receiver/gnss_flowgraph.cc +++ b/src/core/receiver/gnss_flowgraph.cc @@ -32,12 +32,22 @@ * ------------------------------------------------------------------------- */ +#include "GPS_L1_CA.h" +#include "Galileo_E1.h" +#include "GPS_L2C.h" +#include "GPS_L5.h" +#include "Galileo_E5a.h" #include "gnss_flowgraph.h" #include "gnss_synchro.h" #include "configuration_interface.h" #include "gnss_block_interface.h" #include "channel_interface.h" #include "gnss_block_factory.h" +#ifdef GR_GREATER_38 +#include +#else +#include +#endif #include #include #include @@ -343,6 +353,8 @@ void GNSSFlowgraph::connect() #endif // Signal conditioner (selected_signal_source) >> channels (i) (dependent of their associated SignalSource_ID) int selected_signal_conditioner_ID = 0; + bool use_acq_resampler = configuration_->property("GNSS-SDR.use_acquisition_resampler", false); + double fs = static_cast(configuration_->property("GNSS-SDR.internal_fs_sps", 0)); for (unsigned int i = 0; i < channels_count_; i++) { if (FPGA_enabled == false) @@ -357,8 +369,97 @@ void GNSSFlowgraph::connect() } try { - top_block_->connect(sig_conditioner_.at(selected_signal_conditioner_ID)->get_right_block(), 0, - channels_.at(i)->get_left_block(), 0); + // top_block_->connect(sig_conditioner_.at(selected_signal_conditioner_ID)->get_right_block(), 0, + // channels_.at(i)->get_left_block(), 0); + + // Enable automatic resampler for the acquisition, if required + if (use_acq_resampler == true) + { + //create acquisition resamplers if required + double resampler_ratio = 1.0; + double acq_fs = fs; + //find the signal associated to this channel + switch (mapStringValues_[channels_.at(i)->implementation()]) + { + case evGPS_1C: + acq_fs = GPS_L1_CA_OPT_ACQ_FS_HZ; + break; + case evGPS_2S: + acq_fs = GPS_L2C_OPT_ACQ_FS_HZ; + break; + case evGPS_L5: + acq_fs = GPS_L5_OPT_ACQ_FS_HZ; + break; + case evSBAS_1C: + acq_fs = GPS_L1_CA_OPT_ACQ_FS_HZ; + break; + case evGAL_1B: + acq_fs = Galileo_E1_OPT_ACQ_FS_HZ; + break; + case evGAL_5X: + acq_fs = fs; + break; + case evGLO_1G: + acq_fs = fs; + break; + case evGLO_2G: + acq_fs = fs; + break; + } + if (acq_fs < fs) + { + //check if the resampler is already created for the channel system/signal and for the specific RF Channel + std::string map_key = channels_.at(i)->implementation() + std::to_string(selected_signal_conditioner_ID); + + resampler_ratio = fs / acq_fs; + + gr::basic_block_sptr tmp_blk; +#ifdef GR_GREATER_38 + tmp_blk = gr::filter::mmse_resampler_cc::make(0.0, resampler_ratio); +#else + tmp_blk = gr::filter::fractional_resampler_cc::make(0.0, resampler_ratio); +#endif + + std::pair::iterator, bool> ret; + ret = acq_resamplers_.insert(std::pair(map_key, tmp_blk)); + if (ret.second == true) + { + top_block_->connect(sig_conditioner_.at(selected_signal_conditioner_ID)->get_right_block(), 0, + acq_resamplers_.at(map_key), 0); + LOG(INFO) << "Created " + << channels_.at(i)->implementation() + << " acquisition resampler for RF channel " << std::to_string(signal_conditioner_ID) << " with ratio " << resampler_ratio; + } + else + { + LOG(INFO) << "Found " + << channels_.at(i)->implementation() + << " acquisition resampler for RF channel " << std::to_string(signal_conditioner_ID) << " with ratio " << resampler_ratio; + } + + + top_block_->connect(acq_resamplers_.at(map_key), 0, + channels_.at(i)->get_left_block_acq(), 0); + + top_block_->connect(sig_conditioner_.at(selected_signal_conditioner_ID)->get_right_block(), 0, + channels_.at(i)->get_left_block_trk(), 0); + } + else + { + //resampler not required! + top_block_->connect(sig_conditioner_.at(selected_signal_conditioner_ID)->get_right_block(), 0, + channels_.at(i)->get_left_block_acq(), 0); + top_block_->connect(sig_conditioner_.at(selected_signal_conditioner_ID)->get_right_block(), 0, + channels_.at(i)->get_left_block_trk(), 0); + } + } + else + { + top_block_->connect(sig_conditioner_.at(selected_signal_conditioner_ID)->get_right_block(), 0, + channels_.at(i)->get_left_block_acq(), 0); + top_block_->connect(sig_conditioner_.at(selected_signal_conditioner_ID)->get_right_block(), 0, + channels_.at(i)->get_left_block_trk(), 0); + } } catch (const std::exception& e) { @@ -678,7 +779,7 @@ void GNSSFlowgraph::disconnect() try { top_block_->disconnect(sig_conditioner_.at(selected_signal_conditioner_ID)->get_right_block(), 0, - channels_.at(i)->get_left_block(), 0); + channels_.at(i)->get_left_block_trk(), 0); } catch (const std::exception& e) { diff --git a/src/core/receiver/gnss_flowgraph.h b/src/core/receiver/gnss_flowgraph.h index b279f6f67..9ae59323d 100644 --- a/src/core/receiver/gnss_flowgraph.h +++ b/src/core/receiver/gnss_flowgraph.h @@ -55,6 +55,7 @@ #include #include #include +#include #if ENABLE_FPGA #include "gnss_sdr_fpga_sample_counter.h" @@ -166,6 +167,7 @@ private: std::shared_ptr observables_; std::shared_ptr pvt_; + std::map acq_resamplers_; std::vector> channels_; gnss_sdr_sample_counter_sptr ch_out_sample_counter; #if ENABLE_FPGA diff --git a/src/core/system_parameters/GPS_L1_CA.h b/src/core/system_parameters/GPS_L1_CA.h index 9879716e4..f14b9f2f2 100644 --- a/src/core/system_parameters/GPS_L1_CA.h +++ b/src/core/system_parameters/GPS_L1_CA.h @@ -57,6 +57,9 @@ const double GPS_L1_CA_CODE_PERIOD = 0.001; //!< GPS L1 C/A code period const uint32_t GPS_L1_CA_CODE_PERIOD_MS = 1U; //!< GPS L1 C/A code period [ms] const double GPS_L1_CA_CHIP_PERIOD = 9.7752e-07; //!< GPS L1 C/A chip period [seconds] +//optimum parameters +const uint32_t GPS_L1_CA_OPT_ACQ_FS_HZ = 2000000; //!< Sampling frequncy that maximizes the acquisition SNR while using a non-multiple of chip rate + /*! * \brief Maximum Time-Of-Arrival (TOA) difference between satellites for a receiver operated on Earth surface is 20 ms * diff --git a/src/core/system_parameters/GPS_L2C.h b/src/core/system_parameters/GPS_L2C.h index b156dfe4a..28257a204 100644 --- a/src/core/system_parameters/GPS_L2C.h +++ b/src/core/system_parameters/GPS_L2C.h @@ -63,6 +63,10 @@ const double GPS_L2_L_PERIOD = 1.5; //!< GPS L2 L code period [s const int32_t GPS_L2C_HISTORY_DEEP = 5; +//optimum parameters +const uint32_t GPS_L2C_OPT_ACQ_FS_HZ = 2000000; //!< Sampling frequncy that maximizes the acquisition SNR while using a non-multiple of chip rate + + const int32_t GPS_L2C_M_INIT_REG[115] = {0742417664, 0756014035, 0002747144, 0066265724, // 1:4 0601403471, 0703232733, 0124510070, 0617316361, // 5:8 diff --git a/src/core/system_parameters/GPS_L5.h b/src/core/system_parameters/GPS_L5.h index fe270f204..f12c0c14a 100644 --- a/src/core/system_parameters/GPS_L5.h +++ b/src/core/system_parameters/GPS_L5.h @@ -64,6 +64,9 @@ const double GPS_L5q_PERIOD = 0.001; //!< GPS L5 code period [secon const int32_t GPS_L5_HISTORY_DEEP = 5; +//optimum parameters +const uint32_t GPS_L5_OPT_ACQ_FS_HZ = 10000000; + const int32_t GPS_L5i_INIT_REG[210] = {266, 365, 804, 1138, 1509, 1559, 1756, 2084, diff --git a/src/core/system_parameters/Galileo_E1.h b/src/core/system_parameters/Galileo_E1.h index 7cb1ac433..333877ac3 100644 --- a/src/core/system_parameters/Galileo_E1.h +++ b/src/core/system_parameters/Galileo_E1.h @@ -63,6 +63,11 @@ const int32_t Galileo_E1_B_SAMPLES_PER_SYMBOL = 1; //!< (Galileo_E1_CODE_ const int32_t Galileo_E1_C_SECONDARY_CODE_LENGTH = 25; //!< Galileo E1-C secondary code length [chips] const int32_t Galileo_E1_NUMBER_OF_CODES = 50; + +//optimum parameters +const uint32_t Galileo_E1_OPT_ACQ_FS_HZ = 4000000; //!< Sampling frequncy that maximizes the acquisition SNR while using a non-multiple of chip rate + + const double GALILEO_STARTOFFSET_ms = 68.802; //[ms] Initial sign. travel time (this cannot go here) diff --git a/src/core/system_parameters/Galileo_E5a.h b/src/core/system_parameters/Galileo_E5a.h index b8540d32c..6e37cde77 100644 --- a/src/core/system_parameters/Galileo_E5a.h +++ b/src/core/system_parameters/Galileo_E5a.h @@ -57,6 +57,9 @@ const int32_t Galileo_E5a_NUMBER_OF_CODES = 50; const int32_t GALILEO_E5A_HISTORY_DEEP = 20; const int32_t GALILEO_E5A_CRC_ERROR_LIMIT = 6; +//optimum parameters +const uint32_t Galileo_E5A_OPT_ACQ_FS_HZ = 10000000; + // F/NAV message structure const int32_t GALILEO_FNAV_PREAMBLE_LENGTH_BITS = 12; diff --git a/src/tests/common-files/tracking_tests_flags.h b/src/tests/common-files/tracking_tests_flags.h index 2ff85dabf..1724fcf68 100644 --- a/src/tests/common-files/tracking_tests_flags.h +++ b/src/tests/common-files/tracking_tests_flags.h @@ -42,6 +42,7 @@ DEFINE_double(external_signal_acquisition_threshold, 2.5, "Threshold for satelli DEFINE_int32(external_signal_acquisition_dwells, 5, "Maximum dwells count for satellite acquisition when external file is used"); DEFINE_double(external_signal_acquisition_doppler_max_hz, 5000.0, "Doppler max for satellite acquisition when external file is used"); DEFINE_double(external_signal_acquisition_doppler_step_hz, 125.0, "Doppler step for satellite acquisition when external file is used"); +DEFINE_bool(use_acquisition_resampler, false, "Reduce the sampling rate of the input signal for the acquisition in order to optimize the SNR and decrease the processor load"); DEFINE_string(signal_file, std::string("signal_out.bin"), "Path of the external signal capture file"); DEFINE_double(CN0_dBHz_start, std::numeric_limits::infinity(), "Enable noise generator and set the CN0 start sweep value [dB-Hz]"); diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test.cc index 6b33a2c33..ba63a7f18 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test.cc @@ -32,6 +32,10 @@ #include "GPS_L1_CA.h" +#include "Galileo_E1.h" +#include "GPS_L2C.h" +#include "GPS_L5.h" +#include "Galileo_E5a.h" #include "gnss_block_factory.h" #include "control_message_factory.h" #include "tracking_interface.h" @@ -52,6 +56,15 @@ #include "tracking_tests_flags.h" #include "acquisition_msg_rx.h" #include + +#ifdef GR_GREATER_38 +#include +#include +#else +#include +#include +#endif +#include #include #include #include @@ -126,6 +139,19 @@ TrackingPullInTest_msg_rx::~TrackingPullInTest_msg_rx() class TrackingPullInTest : public ::testing::Test { public: + enum StringValue + { + evGPS_1C, + evGPS_2S, + evGPS_L5, + evSBAS_1C, + evGAL_1B, + evGAL_5X, + evGLO_1G, + evGLO_2G + }; + std::map mapStringValues_; + std::string generator_binary; std::string p1; std::string p2; @@ -171,6 +197,13 @@ public: config = std::make_shared(); item_size = sizeof(gr_complex); gnss_synchro = Gnss_Synchro(); + mapStringValues_["1C"] = evGPS_1C; + mapStringValues_["2S"] = evGPS_2S; + mapStringValues_["L5"] = evGPS_L5; + mapStringValues_["1B"] = evGAL_1B; + mapStringValues_["5X"] = evGAL_5X; + mapStringValues_["1G"] = evGLO_1G; + mapStringValues_["2G"] = evGLO_2G; } ~TrackingPullInTest() @@ -345,8 +378,15 @@ bool TrackingPullInTest::acquire_signal(int SV_ID) // Satellite signal definition Gnss_Synchro tmp_gnss_synchro; tmp_gnss_synchro.Channel_ID = 0; + + config = std::make_shared(); config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(baseband_sampling_freq)); + // Enable automatic resampler for the acquisition, if required + if (FLAGS_use_acquisition_resampler == true) + { + config->set_property("GNSS-SDR.use_acquisition_resampler", "true"); + } config->set_property("Acquisition.blocking_on_standby", "true"); config->set_property("Acquisition.blocking", "true"); config->set_property("Acquisition.dump", "false"); @@ -356,11 +396,12 @@ bool TrackingPullInTest::acquire_signal(int SV_ID) std::shared_ptr acquisition; std::string System_and_Signal; + std::string signal; //create the correspondign acquisition block according to the desired tracking signal if (implementation.compare("GPS_L1_CA_DLL_PLL_Tracking") == 0) { tmp_gnss_synchro.System = 'G'; - std::string signal = "1C"; + 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 tmp_gnss_synchro.PRN = SV_ID; @@ -372,7 +413,7 @@ bool TrackingPullInTest::acquire_signal(int SV_ID) else if (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking") == 0) { tmp_gnss_synchro.System = 'E'; - std::string signal = "1B"; + signal = "1B"; 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 tmp_gnss_synchro.PRN = SV_ID; @@ -383,7 +424,7 @@ bool TrackingPullInTest::acquire_signal(int SV_ID) else if (implementation.compare("GPS_L2_M_DLL_PLL_Tracking") == 0) { tmp_gnss_synchro.System = 'G'; - std::string signal = "2S"; + signal = "2S"; 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 tmp_gnss_synchro.PRN = SV_ID; @@ -394,7 +435,7 @@ bool TrackingPullInTest::acquire_signal(int SV_ID) else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking_b") == 0) { tmp_gnss_synchro.System = 'E'; - std::string signal = "5X"; + signal = "5X"; 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 tmp_gnss_synchro.PRN = SV_ID; @@ -410,7 +451,7 @@ bool TrackingPullInTest::acquire_signal(int SV_ID) else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking") == 0) { tmp_gnss_synchro.System = 'E'; - std::string signal = "5X"; + signal = "5X"; 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 tmp_gnss_synchro.PRN = SV_ID; @@ -421,7 +462,7 @@ bool TrackingPullInTest::acquire_signal(int SV_ID) else if (implementation.compare("GPS_L5_DLL_PLL_Tracking") == 0) { tmp_gnss_synchro.System = 'G'; - std::string signal = "L5"; + signal = "L5"; 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 tmp_gnss_synchro.PRN = SV_ID; @@ -449,14 +490,83 @@ bool TrackingPullInTest::acquire_signal(int SV_ID) std::string file = FLAGS_signal_file; const char* file_name = file.c_str(); file_source = gr::blocks::file_source::make(sizeof(int8_t), file_name, false); - file_source->seek(2 * FLAGS_skip_samples, 0); //skip head. ibyte, two bytes per complex sample + file_source->seek(2 * FLAGS_skip_samples, SEEK_SET); //skip head. ibyte, two bytes per complex sample gr::blocks::interleaved_char_to_complex::sptr gr_interleaved_char_to_complex = gr::blocks::interleaved_char_to_complex::make(); //gr::blocks::head::sptr head_samples = gr::blocks::head::make(sizeof(gr_complex), baseband_sampling_freq * FLAGS_duration); top_block->connect(file_source, 0, gr_interleaved_char_to_complex, 0); - top_block->connect(gr_interleaved_char_to_complex, 0, acquisition->get_left_block(), 0); - //top_block->connect(head_samples, 0, acquisition->get_left_block(), 0); + // Enable automatic resampler for the acquisition, if required + std::vector taps; + int decimation = 1; + if (FLAGS_use_acquisition_resampler == true) + { + //create acquisition resamplers if required + double resampler_ratio = 1.0; + + double opt_fs = baseband_sampling_freq; + //find the signal associated to this channel + switch (mapStringValues_[signal]) + { + case evGPS_1C: + opt_fs = GPS_L1_CA_OPT_ACQ_FS_HZ; + break; + case evGPS_2S: + opt_fs = GPS_L2C_OPT_ACQ_FS_HZ; + break; + case evGPS_L5: + opt_fs = GPS_L5_OPT_ACQ_FS_HZ; + break; + case evSBAS_1C: + opt_fs = GPS_L1_CA_OPT_ACQ_FS_HZ; + break; + case evGAL_1B: + opt_fs = Galileo_E1_OPT_ACQ_FS_HZ; + break; + case evGAL_5X: + opt_fs = baseband_sampling_freq; + break; + case evGLO_1G: + opt_fs = baseband_sampling_freq; + break; + case evGLO_2G: + opt_fs = baseband_sampling_freq; + break; + } + if (opt_fs < baseband_sampling_freq) + { + resampler_ratio = baseband_sampling_freq / opt_fs; + decimation = floor(resampler_ratio); + while (baseband_sampling_freq % decimation > 0) + { + decimation--; + }; + double acq_fs = baseband_sampling_freq / decimation; + + //create a FIR low pass filter + taps = gr::filter::firdes::low_pass(1.0, + baseband_sampling_freq, + acq_fs / 2.1, + acq_fs / 20, + gr::filter::firdes::win_type::WIN_HAMMING); + std::cout << "Enabled decimation low pass filter with " << taps.size() << " taps and decimation factor of " << decimation << std::endl; + gr::basic_block_sptr fir_filter_ccf_ = gr::filter::fir_filter_ccf::make(decimation, taps); + + //#ifdef GR_GREATER_38 + // gr::basic_block_sptr resampler = gr::filter::mmse_resampler_cc::make(0.0, resampler_ratio); + //#else + // gr::basic_block_sptr resampler = gr::filter::fractional_resampler_cc::make(0.0, resampler_ratio); + //#endif + top_block->connect(gr_interleaved_char_to_complex, 0, fir_filter_ccf_, 0); + // top_block->connect(fir_filter_ccf_, 0, resampler, 0); + top_block->connect(fir_filter_ccf_, 0, acquisition->get_left_block(), 0); + } + } + else + { + top_block->connect(gr_interleaved_char_to_complex, 0, acquisition->get_left_block(), 0); + //top_block->connect(head_samples, 0, acquisition->get_left_block(), 0); + } boost::shared_ptr msg_rx; try { @@ -523,15 +633,24 @@ bool TrackingPullInTest::acquire_signal(int SV_ID) { 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)); - acq_samplestamp_map.insert(std::pair(PRN, tmp_gnss_synchro.Acq_samplestamp_samples)); + + if (FLAGS_use_acquisition_resampler == true) + { + code_delay_measurements_map.insert(std::pair(PRN, tmp_gnss_synchro.Acq_delay_samples - (taps.size()) / 2)); + acq_samplestamp_map.insert(std::pair(PRN, tmp_gnss_synchro.Acq_samplestamp_samples)); + } + else + { + code_delay_measurements_map.insert(std::pair(PRN, tmp_gnss_synchro.Acq_delay_samples)); + acq_samplestamp_map.insert(std::pair(PRN, tmp_gnss_synchro.Acq_samplestamp_samples)); + } } else { std::cout << " . "; } top_block->stop(); - file_source->seek(2 * FLAGS_skip_samples, 0); //skip head. ibyte, two bytes per complex sample + file_source->seek(2 * FLAGS_skip_samples, SEEK_SET); //skip head. ibyte, two bytes per complex sample std::cout.flush(); } std::cout << "]" << std::endl;