mirror of
				https://github.com/gnss-sdr/gnss-sdr
				synced 2025-10-31 07:13:03 +00:00 
			
		
		
		
	Adding initial functional changes for the smart acquisition resampler
This commit is contained in:
		| @@ -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<unsigned int>(std::floor(static_cast<double>(fs_in_) / (Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS))); | ||||
|  | ||||
|     float samples_per_ms = static_cast<float>(fs_in_) * 0.001; | ||||
|     acq_parameters.samples_per_ms = samples_per_ms; | ||||
|     acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(Galileo_E1_CODE_PERIOD_MS); | ||||
|     vector_length_ = sampled_ms_ * samples_per_ms; | ||||
|     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<float>(acq_parameters_.fs_in) / static_cast<float>(acq_parameters_.resampled_fs); | ||||
|                 } | ||||
|  | ||||
|             //--- Find number of samples per spreading code (4 ms)  ----------------- | ||||
|             code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(acq_parameters_.resampled_fs) / (Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS))); | ||||
|             float samples_per_ms = static_cast<float>(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<float>(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<unsigned int>(std::floor(static_cast<double>(fs_in_) / (Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS))); | ||||
|             float samples_per_ms = static_cast<float>(fs_in_) * 0.001; | ||||
|             acq_parameters_.samples_per_ms = samples_per_ms; | ||||
|             acq_parameters_.samples_per_code = acq_parameters_.samples_per_ms * static_cast<float>(Galileo_E1_CODE_PERIOD_MS); | ||||
|             vector_length_ = sampled_ms_ * samples_per_ms; | ||||
|         } | ||||
|     if (bit_transition_flag_) | ||||
|         { | ||||
|             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); | ||||
|                 } | ||||
|         } | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -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_; | ||||
|   | ||||
| @@ -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<unsigned int>(std::floor(static_cast<double>(fs_in_) / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS))); | ||||
|     acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001; | ||||
|     acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GPS_L1_CA_CODE_PERIOD * 1000.0); | ||||
|  | ||||
|     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<float>(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<int>(acq_parameters_.resampler_ratio); | ||||
|                 } | ||||
|             //--- Find number of samples per spreading code ------------------------- | ||||
|             code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(acq_parameters_.resampled_fs) / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS))); | ||||
|             acq_parameters_.samples_per_ms = static_cast<float>(acq_parameters_.resampled_fs) * 0.001; | ||||
|             acq_parameters_.samples_per_code = acq_parameters_.samples_per_ms * static_cast<float>(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<unsigned int>(std::floor(static_cast<double>(fs_in_) / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS))); | ||||
|             acq_parameters_.samples_per_ms = static_cast<float>(fs_in_) * 0.001; | ||||
|             acq_parameters_.samples_per_code = acq_parameters_.samples_per_ms * static_cast<float>(GPS_L1_CA_CODE_PERIOD * 1000.0); | ||||
|             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<float>* code = new std::complex<float>[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, | ||||
|   | ||||
| @@ -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_; | ||||
|   | ||||
| @@ -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<float>(acq_parameters.fs_in); | ||||
|     float phase_step_rad; | ||||
|     if (acq_parameters.use_automatic_resampler) | ||||
|         { | ||||
|             phase_step_rad = GPS_TWO_PI * freq / static_cast<float>(acq_parameters.resampled_fs); | ||||
|         } | ||||
|     else | ||||
|         { | ||||
|             phase_step_rad = GPS_TWO_PI * freq / static_cast<float>(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<double>(std::fmod(static_cast<float>(indext), acq_parameters.samples_per_code)); | ||||
|             d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler); | ||||
|             d_gnss_synchro->Acq_samplestamp_samples = samp_count; | ||||
|             if (acq_parameters.use_automatic_resampler) | ||||
|                 { | ||||
|                     //take into account the acquisition resampler ratio | ||||
|                     d_gnss_synchro->Acq_delay_samples = static_cast<double>(std::fmod(static_cast<float>(indext), acq_parameters.samples_per_code)) * acq_parameters.resampler_ratio; | ||||
|                     d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler); | ||||
|                     d_gnss_synchro->Acq_samplestamp_samples = rint(static_cast<double>(samp_count) * acq_parameters.resampler_ratio); | ||||
|                 } | ||||
|             else | ||||
|                 { | ||||
|                     d_gnss_synchro->Acq_delay_samples = static_cast<double>(std::fmod(static_cast<float>(indext), acq_parameters.samples_per_code)); | ||||
|                     d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler); | ||||
|                     d_gnss_synchro->Acq_samplestamp_samples = samp_count; | ||||
|                 } | ||||
|         } | ||||
|     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<int32_t>(d_doppler_center_step_two - (static_cast<float>(d_num_doppler_bins_step2) / 2.0) * acq_parameters.doppler_step2), acq_parameters.doppler_step2); | ||||
|                 } | ||||
|             d_gnss_synchro->Acq_delay_samples = static_cast<double>(std::fmod(static_cast<float>(indext), acq_parameters.samples_per_code)); | ||||
|             d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler); | ||||
|             d_gnss_synchro->Acq_samplestamp_samples = samp_count; | ||||
|             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<double>(std::fmod(static_cast<float>(indext), acq_parameters.samples_per_code)) * acq_parameters.resampler_ratio; | ||||
|                     d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler); | ||||
|                     d_gnss_synchro->Acq_samplestamp_samples = rint(static_cast<double>(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<double>(std::fmod(static_cast<float>(indext), acq_parameters.samples_per_code)); | ||||
|                     d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler); | ||||
|                     d_gnss_synchro->Acq_samplestamp_samples = samp_count; | ||||
|                     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, | ||||
|   | ||||
| @@ -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. | ||||
|       */ | ||||
|   | ||||
| @@ -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; | ||||
| } | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -38,12 +38,10 @@ | ||||
| using google::LogMessage; | ||||
|  | ||||
| // Constructor | ||||
| Channel::Channel(ConfigurationInterface* configuration, uint32_t channel, | ||||
|     std::shared_ptr<GNSSBlockInterface> pass_through, std::shared_ptr<AcquisitionInterface> acq, | ||||
| Channel::Channel(ConfigurationInterface* configuration, uint32_t channel, std::shared_ptr<AcquisitionInterface> acq, | ||||
|     std::shared_ptr<TrackingInterface> trk, std::shared_ptr<TelemetryDecoderInterface> 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() | ||||
| { | ||||
|   | ||||
| @@ -60,16 +60,17 @@ class Channel : public ChannelInterface | ||||
| { | ||||
| public: | ||||
|     //! Constructor | ||||
|     Channel(ConfigurationInterface* configuration, uint32_t channel, | ||||
|         std::shared_ptr<GNSSBlockInterface> pass_through, std::shared_ptr<AcquisitionInterface> acq, | ||||
|     Channel(ConfigurationInterface* configuration, uint32_t channel, std::shared_ptr<AcquisitionInterface> acq, | ||||
|         std::shared_ptr<TrackingInterface> trk, std::shared_ptr<TelemetryDecoderInterface> 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<GNSSBlockInterface> pass_through_; | ||||
|     std::shared_ptr<AcquisitionInterface> acq_; | ||||
|     std::shared_ptr<TrackingInterface> trk_; | ||||
|     std::shared_ptr<TelemetryDecoderInterface> nav_; | ||||
|   | ||||
| @@ -69,7 +69,7 @@ MmseResamplerConditioner::MmseResamplerConditioner( | ||||
|             std::vector<float> 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); | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -361,12 +361,11 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetChannel_1C( | ||||
|         } | ||||
|     config->set_property("Channel.item_type", acq_item_type); | ||||
|  | ||||
|     std::unique_ptr<GNSSBlockInterface> pass_through_ = GetBlock(config, "Channel", "Pass_Through", 1, 1, queue); | ||||
|     std::unique_ptr<AcquisitionInterface> acq_ = GetAcqBlock(configuration, "Acquisition_1C" + appendix1, acq, 1, 0); | ||||
|     std::unique_ptr<TrackingInterface> trk_ = GetTrkBlock(configuration, "Tracking_1C" + appendix2, trk, 1, 1); | ||||
|     std::unique_ptr<TelemetryDecoderInterface> tlm_ = GetTlmBlock(configuration, "TelemetryDecoder_1C" + appendix3, tlm, 1, 1); | ||||
|  | ||||
|     std::unique_ptr<GNSSBlockInterface> channel_(new Channel(configuration.get(), channel, std::move(pass_through_), | ||||
|     std::unique_ptr<GNSSBlockInterface> channel_(new Channel(configuration.get(), channel, | ||||
|         std::move(acq_), | ||||
|         std::move(trk_), | ||||
|         std::move(tlm_), | ||||
| @@ -426,12 +425,11 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetChannel_2S( | ||||
|         } | ||||
|     config->set_property("Channel.item_type", acq_item_type); | ||||
|  | ||||
|     std::unique_ptr<GNSSBlockInterface> pass_through_ = GetBlock(configuration, "Channel", "Pass_Through", 1, 1, queue); | ||||
|     std::unique_ptr<AcquisitionInterface> acq_ = GetAcqBlock(configuration, "Acquisition_2S" + appendix1, acq, 1, 0); | ||||
|     std::unique_ptr<TrackingInterface> trk_ = GetTrkBlock(configuration, "Tracking_2S" + appendix2, trk, 1, 1); | ||||
|     std::unique_ptr<TelemetryDecoderInterface> tlm_ = GetTlmBlock(configuration, "TelemetryDecoder_2S" + appendix3, tlm, 1, 1); | ||||
|  | ||||
|     std::unique_ptr<GNSSBlockInterface> channel_(new Channel(configuration.get(), channel, std::move(pass_through_), | ||||
|     std::unique_ptr<GNSSBlockInterface> channel_(new Channel(configuration.get(), channel, | ||||
|         std::move(acq_), | ||||
|         std::move(trk_), | ||||
|         std::move(tlm_), | ||||
| @@ -494,12 +492,11 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetChannel_1B( | ||||
|         } | ||||
|     config->set_property("Channel.item_type", acq_item_type); | ||||
|  | ||||
|     std::unique_ptr<GNSSBlockInterface> pass_through_ = GetBlock(configuration, "Channel", "Pass_Through", 1, 1, queue); | ||||
|     std::unique_ptr<AcquisitionInterface> acq_ = GetAcqBlock(configuration, "Acquisition_1B" + appendix1, acq, 1, 0); | ||||
|     std::unique_ptr<TrackingInterface> trk_ = GetTrkBlock(configuration, "Tracking_1B" + appendix2, trk, 1, 1); | ||||
|     std::unique_ptr<TelemetryDecoderInterface> tlm_ = GetTlmBlock(configuration, "TelemetryDecoder_1B" + appendix3, tlm, 1, 1); | ||||
|  | ||||
|     std::unique_ptr<GNSSBlockInterface> channel_(new Channel(configuration.get(), channel, std::move(pass_through_), | ||||
|     std::unique_ptr<GNSSBlockInterface> channel_(new Channel(configuration.get(), channel, | ||||
|         std::move(acq_), | ||||
|         std::move(trk_), | ||||
|         std::move(tlm_), | ||||
| @@ -562,12 +559,11 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetChannel_5X( | ||||
|         } | ||||
|     config->set_property("Channel.item_type", acq_item_type); | ||||
|  | ||||
|     std::unique_ptr<GNSSBlockInterface> pass_through_ = GetBlock(configuration, "Channel", "Pass_Through", 1, 1, queue); | ||||
|     std::unique_ptr<AcquisitionInterface> acq_ = GetAcqBlock(configuration, "Acquisition_5X" + appendix1, acq, 1, 0); | ||||
|     std::unique_ptr<TrackingInterface> trk_ = GetTrkBlock(configuration, "Tracking_5X" + appendix2, trk, 1, 1); | ||||
|     std::unique_ptr<TelemetryDecoderInterface> tlm_ = GetTlmBlock(configuration, "TelemetryDecoder_5X" + appendix3, tlm, 1, 1); | ||||
|  | ||||
|     std::unique_ptr<GNSSBlockInterface> channel_(new Channel(configuration.get(), channel, std::move(pass_through_), | ||||
|     std::unique_ptr<GNSSBlockInterface> channel_(new Channel(configuration.get(), channel, | ||||
|         std::move(acq_), | ||||
|         std::move(trk_), | ||||
|         std::move(tlm_), | ||||
| @@ -631,12 +627,11 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetChannel_1G( | ||||
|         } | ||||
|     config->set_property("Channel.item_type", acq_item_type); | ||||
|  | ||||
|     std::unique_ptr<GNSSBlockInterface> pass_through_ = GetBlock(config, "Channel", "Pass_Through", 1, 1, queue); | ||||
|     std::unique_ptr<AcquisitionInterface> acq_ = GetAcqBlock(configuration, "Acquisition_1G" + appendix1, acq, 1, 0); | ||||
|     std::unique_ptr<TrackingInterface> trk_ = GetTrkBlock(configuration, "Tracking_1G" + appendix2, trk, 1, 1); | ||||
|     std::unique_ptr<TelemetryDecoderInterface> tlm_ = GetTlmBlock(configuration, "TelemetryDecoder_1G" + appendix3, tlm, 1, 1); | ||||
|  | ||||
|     std::unique_ptr<GNSSBlockInterface> channel_(new Channel(configuration.get(), channel, std::move(pass_through_), | ||||
|     std::unique_ptr<GNSSBlockInterface> channel_(new Channel(configuration.get(), channel, | ||||
|         std::move(acq_), | ||||
|         std::move(trk_), | ||||
|         std::move(tlm_), | ||||
| @@ -700,12 +695,11 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetChannel_2G( | ||||
|         } | ||||
|     config->set_property("Channel.item_type", acq_item_type); | ||||
|  | ||||
|     std::unique_ptr<GNSSBlockInterface> pass_through_ = GetBlock(config, "Channel", "Pass_Through", 1, 1, queue); | ||||
|     std::unique_ptr<AcquisitionInterface> acq_ = GetAcqBlock(configuration, "Acquisition_2G" + appendix1, acq, 1, 0); | ||||
|     std::unique_ptr<TrackingInterface> trk_ = GetTrkBlock(configuration, "Tracking_2G" + appendix2, trk, 1, 1); | ||||
|     std::unique_ptr<TelemetryDecoderInterface> tlm_ = GetTlmBlock(configuration, "TelemetryDecoder_2G" + appendix3, tlm, 1, 1); | ||||
|  | ||||
|     std::unique_ptr<GNSSBlockInterface> channel_(new Channel(configuration.get(), channel, std::move(pass_through_), | ||||
|     std::unique_ptr<GNSSBlockInterface> channel_(new Channel(configuration.get(), channel, | ||||
|         std::move(acq_), | ||||
|         std::move(trk_), | ||||
|         std::move(tlm_), | ||||
| @@ -768,12 +762,11 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetChannel_L5( | ||||
|         } | ||||
|     config->set_property("Channel.item_type", acq_item_type); | ||||
|  | ||||
|     std::unique_ptr<GNSSBlockInterface> pass_through_ = GetBlock(configuration, "Channel", "Pass_Through", 1, 1, queue); | ||||
|     std::unique_ptr<AcquisitionInterface> acq_ = GetAcqBlock(configuration, "Acquisition_L5" + appendix1, acq, 1, 0); | ||||
|     std::unique_ptr<TrackingInterface> trk_ = GetTrkBlock(configuration, "Tracking_L5" + appendix2, trk, 1, 1); | ||||
|     std::unique_ptr<TelemetryDecoderInterface> tlm_ = GetTlmBlock(configuration, "TelemetryDecoder_L5" + appendix3, tlm, 1, 1); | ||||
|  | ||||
|     std::unique_ptr<GNSSBlockInterface> channel_(new Channel(configuration.get(), channel, std::move(pass_through_), | ||||
|     std::unique_ptr<GNSSBlockInterface> channel_(new Channel(configuration.get(), channel, | ||||
|         std::move(acq_), | ||||
|         std::move(trk_), | ||||
|         std::move(tlm_), | ||||
|   | ||||
| @@ -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 <gnuradio/filter/mmse_resampler_cc.h> | ||||
| #else | ||||
| #include <gnuradio/filter/fractional_resampler_cc.h> | ||||
| #endif | ||||
| #include <boost/lexical_cast.hpp> | ||||
| #include <boost/tokenizer.hpp> | ||||
| #include <glog/logging.h> | ||||
| @@ -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<double>(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<std::map<std::string, gr::basic_block_sptr>::iterator, bool> ret; | ||||
|                                             ret = acq_resamplers_.insert(std::pair<std::string, gr::basic_block_sptr>(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) | ||||
|                 { | ||||
|   | ||||
| @@ -55,6 +55,7 @@ | ||||
| #include <queue> | ||||
| #include <string> | ||||
| #include <vector> | ||||
| #include <map> | ||||
|  | ||||
| #if ENABLE_FPGA | ||||
| #include "gnss_sdr_fpga_sample_counter.h" | ||||
| @@ -166,6 +167,7 @@ private: | ||||
|     std::shared_ptr<GNSSBlockInterface> observables_; | ||||
|     std::shared_ptr<GNSSBlockInterface> pvt_; | ||||
|  | ||||
|     std::map<std::string, gr::basic_block_sptr> acq_resamplers_; | ||||
|     std::vector<std::shared_ptr<ChannelInterface>> channels_; | ||||
|     gnss_sdr_sample_counter_sptr ch_out_sample_counter; | ||||
| #if ENABLE_FPGA | ||||
|   | ||||
| @@ -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 | ||||
|  * | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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, | ||||
|   | ||||
| @@ -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) | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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<double>::infinity(), "Enable noise generator and set the CN0 start sweep value [dB-Hz]"); | ||||
|   | ||||
| @@ -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 <boost/filesystem.hpp> | ||||
|  | ||||
| #ifdef GR_GREATER_38 | ||||
| #include <gnuradio/filter/mmse_resampler_cc.h> | ||||
| #include <gnuradio/filter/fir_filter_blk.h> | ||||
| #else | ||||
| #include <gnuradio/filter/fractional_resampler_cc.h> | ||||
| #include <gnuradio/filter/fir_filter_ccf.h> | ||||
| #endif | ||||
| #include <gnuradio/filter/firdes.h> | ||||
| #include <gnuradio/top_block.h> | ||||
| #include <gnuradio/blocks/file_source.h> | ||||
| #include <gnuradio/blocks/interleaved_char_to_complex.h> | ||||
| @@ -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<std::string, StringValue> mapStringValues_; | ||||
|  | ||||
|     std::string generator_binary; | ||||
|     std::string p1; | ||||
|     std::string p2; | ||||
| @@ -171,6 +197,13 @@ public: | ||||
|         config = std::make_shared<InMemoryConfiguration>(); | ||||
|         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<InMemoryConfiguration>(); | ||||
|     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<AcquisitionInterface> 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<void*>(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<void*>(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<void*>(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<void*>(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<void*>(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<void*>(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<float> 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<Acquisition_msg_rx> msg_rx; | ||||
|     try | ||||
|         { | ||||
| @@ -523,15 +633,24 @@ bool TrackingPullInTest::acquire_signal(int SV_ID) | ||||
|                 { | ||||
|                     std::cout << " " << PRN << " "; | ||||
|                     doppler_measurements_map.insert(std::pair<int, double>(PRN, tmp_gnss_synchro.Acq_doppler_hz)); | ||||
|                     code_delay_measurements_map.insert(std::pair<int, double>(PRN, tmp_gnss_synchro.Acq_delay_samples)); | ||||
|                     acq_samplestamp_map.insert(std::pair<int, double>(PRN, tmp_gnss_synchro.Acq_samplestamp_samples)); | ||||
|  | ||||
|                     if (FLAGS_use_acquisition_resampler == true) | ||||
|                         { | ||||
|                             code_delay_measurements_map.insert(std::pair<int, double>(PRN, tmp_gnss_synchro.Acq_delay_samples - (taps.size()) / 2)); | ||||
|                             acq_samplestamp_map.insert(std::pair<int, double>(PRN, tmp_gnss_synchro.Acq_samplestamp_samples)); | ||||
|                         } | ||||
|                     else | ||||
|                         { | ||||
|                             code_delay_measurements_map.insert(std::pair<int, double>(PRN, tmp_gnss_synchro.Acq_delay_samples)); | ||||
|                             acq_samplestamp_map.insert(std::pair<int, double>(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; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Javier Arribas
					Javier Arribas