mirror of
				https://github.com/gnss-sdr/gnss-sdr
				synced 2025-10-30 14:53:03 +00:00 
			
		
		
		
	Merge branch 'odrisci-fix_pcps_threshold' into next. Fixes: #331
This commit is contained in:
		| @@ -28,6 +28,7 @@ | |||||||
|  * ------------------------------------------------------------------------- |  * ------------------------------------------------------------------------- | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | #include "rtklib_pvt_gs.h" | ||||||
| #include "MATH_CONSTANTS.h" | #include "MATH_CONSTANTS.h" | ||||||
| #include "beidou_dnav_almanac.h" | #include "beidou_dnav_almanac.h" | ||||||
| #include "beidou_dnav_ephemeris.h" | #include "beidou_dnav_ephemeris.h" | ||||||
| @@ -60,7 +61,6 @@ | |||||||
| #include "pvt_conf.h" | #include "pvt_conf.h" | ||||||
| #include "rinex_printer.h" | #include "rinex_printer.h" | ||||||
| #include "rtcm_printer.h" | #include "rtcm_printer.h" | ||||||
| #include "rtklib_pvt_gs.h" |  | ||||||
| #include "rtklib_solver.h" | #include "rtklib_solver.h" | ||||||
| #include <boost/any.hpp>                   // for any_cast, any | #include <boost/any.hpp>                   // for any_cast, any | ||||||
| #include <boost/archive/xml_iarchive.hpp>  // for xml_iarchive | #include <boost/archive/xml_iarchive.hpp>  // for xml_iarchive | ||||||
| @@ -1921,11 +1921,11 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item | |||||||
|                 { |                 { | ||||||
|                     if (in[i][epoch].Flag_valid_pseudorange) |                     if (in[i][epoch].Flag_valid_pseudorange) | ||||||
|                         { |                         { | ||||||
|                             std::map<int, Gps_Ephemeris>::const_iterator tmp_eph_iter_gps = d_internal_pvt_solver->gps_ephemeris_map.find(in[i][epoch].PRN); |                             auto tmp_eph_iter_gps = d_internal_pvt_solver->gps_ephemeris_map.find(in[i][epoch].PRN); | ||||||
|                             std::map<int, Galileo_Ephemeris>::const_iterator tmp_eph_iter_gal = d_internal_pvt_solver->galileo_ephemeris_map.find(in[i][epoch].PRN); |                             auto tmp_eph_iter_gal = d_internal_pvt_solver->galileo_ephemeris_map.find(in[i][epoch].PRN); | ||||||
|                             std::map<int, Gps_CNAV_Ephemeris>::const_iterator tmp_eph_iter_cnav = d_internal_pvt_solver->gps_cnav_ephemeris_map.find(in[i][epoch].PRN); |                             auto tmp_eph_iter_cnav = d_internal_pvt_solver->gps_cnav_ephemeris_map.find(in[i][epoch].PRN); | ||||||
|                             std::map<int, Glonass_Gnav_Ephemeris>::const_iterator tmp_eph_iter_glo_gnav = d_internal_pvt_solver->glonass_gnav_ephemeris_map.find(in[i][epoch].PRN); |                             auto tmp_eph_iter_glo_gnav = d_internal_pvt_solver->glonass_gnav_ephemeris_map.find(in[i][epoch].PRN); | ||||||
|                             std::map<int, Beidou_Dnav_Ephemeris>::const_iterator tmp_eph_iter_bds_dnav = d_internal_pvt_solver->beidou_dnav_ephemeris_map.find(in[i][epoch].PRN); |                             auto tmp_eph_iter_bds_dnav = d_internal_pvt_solver->beidou_dnav_ephemeris_map.find(in[i][epoch].PRN); | ||||||
|  |  | ||||||
|                             bool store_valid_observable = false; |                             bool store_valid_observable = false; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -53,6 +53,7 @@ Pvt_Solution::Pvt_Solution() | |||||||
|     d_valid_observations = 0; |     d_valid_observations = 0; | ||||||
|     d_rx_pos = arma::zeros(3, 1); |     d_rx_pos = arma::zeros(3, 1); | ||||||
|     d_rx_dt_s = 0.0; |     d_rx_dt_s = 0.0; | ||||||
|  |     d_rx_clock_drift_ppm = 0.0; | ||||||
|     d_pre_2009_file = false;  // disabled by default |     d_pre_2009_file = false;  // disabled by default | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -37,7 +37,6 @@ | |||||||
| #include "beidou_b1i_signal_processing.h" | #include "beidou_b1i_signal_processing.h" | ||||||
| #include "configuration_interface.h" | #include "configuration_interface.h" | ||||||
| #include "gnss_sdr_flags.h" | #include "gnss_sdr_flags.h" | ||||||
| #include <boost/math/distributions/exponential.hpp> |  | ||||||
| #include <glog/logging.h> | #include <glog/logging.h> | ||||||
| #include <algorithm> | #include <algorithm> | ||||||
| #include <memory> | #include <memory> | ||||||
| @@ -52,65 +51,26 @@ BeidouB1iPcpsAcquisition::BeidouB1iPcpsAcquisition( | |||||||
|                                 out_streams_(out_streams) |                                 out_streams_(out_streams) | ||||||
| { | { | ||||||
|     configuration_ = configuration; |     configuration_ = configuration; | ||||||
|     std::string default_item_type = "gr_complex"; |     acq_parameters_.ms_per_code = 1; | ||||||
|     std::string default_dump_filename = "./acquisition.mat"; |     acq_parameters_.SetFromConfiguration(configuration_, role, BEIDOU_B1I_CODE_RATE_CPS, 10e6); | ||||||
|  |  | ||||||
|     LOG(INFO) << "role " << role; |     LOG(INFO) << "role " << role; | ||||||
|  |  | ||||||
|     item_type_ = configuration_->property(role + ".item_type", default_item_type); |  | ||||||
|  |  | ||||||
|     int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); |  | ||||||
|     fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); |  | ||||||
|     acq_parameters_.fs_in = fs_in_; |  | ||||||
|     dump_ = configuration_->property(role + ".dump", false); |  | ||||||
|     acq_parameters_.dump = dump_; |  | ||||||
|     acq_parameters_.dump_channel = configuration_->property(role + ".dump_channel", 0); |  | ||||||
|     blocking_ = configuration_->property(role + ".blocking", true); |  | ||||||
|     acq_parameters_.blocking = blocking_; |  | ||||||
|     doppler_max_ = configuration->property(role + ".doppler_max", 5000); |  | ||||||
|     if (FLAGS_doppler_max != 0) |     if (FLAGS_doppler_max != 0) | ||||||
|         { |         { | ||||||
|             doppler_max_ = FLAGS_doppler_max; |             acq_parameters_.doppler_max = FLAGS_doppler_max; | ||||||
|         } |         } | ||||||
|     acq_parameters_.doppler_max = doppler_max_; |     doppler_max_ = acq_parameters_.doppler_max; | ||||||
|     bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false); |     doppler_step_ = acq_parameters_.doppler_step; | ||||||
|     acq_parameters_.bit_transition_flag = bit_transition_flag_; |     fs_in_ = acq_parameters_.fs_in; | ||||||
|     use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true);  // will be false in future versions |     item_type_ = acq_parameters_.item_type; | ||||||
|     acq_parameters_.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_; |     item_size_ = acq_parameters_.it_size; | ||||||
|     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_.sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 1); |  | ||||||
|  |  | ||||||
|     if (item_type_ == "cshort") |  | ||||||
|         { |  | ||||||
|             item_size_ = sizeof(lv_16sc_t); |  | ||||||
|         } |  | ||||||
|     else |  | ||||||
|         { |  | ||||||
|             item_size_ = sizeof(gr_complex); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     acq_parameters_.ms_per_code = 1; |  | ||||||
|     acq_parameters_.it_size = item_size_; |  | ||||||
|     num_codes_ = acq_parameters_.sampled_ms; |     num_codes_ = acq_parameters_.sampled_ms; | ||||||
|     acq_parameters_.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); |  | ||||||
|     acq_parameters_.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0); |  | ||||||
|     acq_parameters_.make_2_steps = configuration_->property(role + ".make_two_steps", false); |  | ||||||
|     acq_parameters_.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false); |  | ||||||
|     acq_parameters_.use_automatic_resampler = configuration_->property("GNSS-SDR.use_acquisition_resampler", false); |  | ||||||
|  |  | ||||||
|     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_) / (BEIDOU_B1I_CODE_RATE_CPS / BEIDOU_B1I_CODE_LENGTH_CHIPS))); |     code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(fs_in_) / (BEIDOU_B1I_CODE_RATE_CPS / BEIDOU_B1I_CODE_LENGTH_CHIPS))); | ||||||
|     acq_parameters_.samples_per_ms = static_cast<float>(fs_in_) * 0.001; |  | ||||||
|     acq_parameters_.samples_per_chip = static_cast<unsigned int>(ceil((1.0 / BEIDOU_B1I_CODE_RATE_CPS) * static_cast<float>(acq_parameters_.fs_in))); |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     acq_parameters_.samples_per_code = acq_parameters_.samples_per_ms * static_cast<float>(BEIDOU_B1I_CODE_PERIOD_S * 1000.0); |  | ||||||
|     vector_length_ = std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2 : 1); |     vector_length_ = std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2 : 1); | ||||||
|     code_ = std::vector<std::complex<float>>(vector_length_); |     code_ = std::vector<std::complex<float>>(vector_length_); | ||||||
|  |  | ||||||
|     acquisition_ = pcps_make_acquisition(acq_parameters_); |     acquisition_ = pcps_make_acquisition(acq_parameters_); | ||||||
|     DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; |     DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; | ||||||
|  |  | ||||||
| @@ -122,7 +82,6 @@ BeidouB1iPcpsAcquisition::BeidouB1iPcpsAcquisition( | |||||||
|  |  | ||||||
|     channel_ = 0; |     channel_ = 0; | ||||||
|     threshold_ = 0.0; |     threshold_ = 0.0; | ||||||
|     doppler_step_ = 0; |  | ||||||
|     gnss_synchro_ = nullptr; |     gnss_synchro_ = nullptr; | ||||||
|  |  | ||||||
|     if (in_streams_ > 1) |     if (in_streams_ > 1) | ||||||
| @@ -143,18 +102,7 @@ void BeidouB1iPcpsAcquisition::stop_acquisition() | |||||||
|  |  | ||||||
| void BeidouB1iPcpsAcquisition::set_threshold(float threshold) | void BeidouB1iPcpsAcquisition::set_threshold(float threshold) | ||||||
| { | { | ||||||
|     float pfa = configuration_->property(role_ + ".pfa", 0.0); |     threshold_ = threshold; | ||||||
|  |  | ||||||
|     if (pfa == 0.0) |  | ||||||
|         { |  | ||||||
|             threshold_ = threshold; |  | ||||||
|         } |  | ||||||
|     else |  | ||||||
|         { |  | ||||||
|             threshold_ = calculate_threshold(pfa); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold_; |  | ||||||
|  |  | ||||||
|     acquisition_->set_threshold(threshold_); |     acquisition_->set_threshold(threshold_); | ||||||
| } | } | ||||||
| @@ -225,23 +173,6 @@ void BeidouB1iPcpsAcquisition::set_state(int state) | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| float BeidouB1iPcpsAcquisition::calculate_threshold(float pfa) |  | ||||||
| { |  | ||||||
|     // Calculate the threshold |  | ||||||
|     uint32_t frequency_bins = 0; |  | ||||||
|     frequency_bins = (2 * doppler_max_ + doppler_step_) / doppler_step_; |  | ||||||
|     DLOG(INFO) << "Channel " << channel_ << "  Pfa = " << pfa; |  | ||||||
|     uint32_t ncells = vector_length_ * frequency_bins; |  | ||||||
|     double exponent = 1 / static_cast<double>(ncells); |  | ||||||
|     double val = pow(1.0 - pfa, exponent); |  | ||||||
|     auto lambda = static_cast<double>(vector_length_); |  | ||||||
|     boost::math::exponential_distribution<double> mydist(lambda); |  | ||||||
|     auto threshold = static_cast<float>(quantile(mydist, val)); |  | ||||||
|  |  | ||||||
|     return threshold; |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| void BeidouB1iPcpsAcquisition::connect(gr::top_block_sptr top_block) | void BeidouB1iPcpsAcquisition::connect(gr::top_block_sptr top_block) | ||||||
| { | { | ||||||
|     if (item_type_ == "gr_complex") |     if (item_type_ == "gr_complex") | ||||||
|   | |||||||
| @@ -170,17 +170,12 @@ private: | |||||||
|     std::string item_type_; |     std::string item_type_; | ||||||
|     unsigned int vector_length_; |     unsigned int vector_length_; | ||||||
|     unsigned int code_length_; |     unsigned int code_length_; | ||||||
|     bool bit_transition_flag_; |  | ||||||
|     bool use_CFAR_algorithm_flag_; |  | ||||||
|     unsigned int channel_; |     unsigned int channel_; | ||||||
|     std::weak_ptr<ChannelFsm> channel_fsm_; |     std::weak_ptr<ChannelFsm> channel_fsm_; | ||||||
|     float threshold_; |     float threshold_; | ||||||
|     unsigned int doppler_max_; |     unsigned int doppler_max_; | ||||||
|     unsigned int doppler_step_; |     unsigned int doppler_step_; | ||||||
|     unsigned int max_dwells_; |  | ||||||
|     int64_t fs_in_; |     int64_t fs_in_; | ||||||
|     bool dump_; |  | ||||||
|     bool blocking_; |  | ||||||
|     std::string dump_filename_; |     std::string dump_filename_; | ||||||
|     std::vector<std::complex<float>> code_; |     std::vector<std::complex<float>> code_; | ||||||
|     Gnss_Synchro* gnss_synchro_; |     Gnss_Synchro* gnss_synchro_; | ||||||
| @@ -188,7 +183,6 @@ private: | |||||||
|     unsigned int num_codes_; |     unsigned int num_codes_; | ||||||
|     unsigned int in_streams_; |     unsigned int in_streams_; | ||||||
|     unsigned int out_streams_; |     unsigned int out_streams_; | ||||||
|     float calculate_threshold(float pfa); |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif /* GNSS_SDR_BEIDOU_B1I_PCPS_ACQUISITION_H_ */ | #endif /* GNSS_SDR_BEIDOU_B1I_PCPS_ACQUISITION_H_ */ | ||||||
|   | |||||||
| @@ -35,7 +35,6 @@ | |||||||
| #include "beidou_b3i_signal_processing.h" | #include "beidou_b3i_signal_processing.h" | ||||||
| #include "configuration_interface.h" | #include "configuration_interface.h" | ||||||
| #include "gnss_sdr_flags.h" | #include "gnss_sdr_flags.h" | ||||||
| #include <boost/math/distributions/exponential.hpp> |  | ||||||
| #include <glog/logging.h> | #include <glog/logging.h> | ||||||
| #include <algorithm> | #include <algorithm> | ||||||
|  |  | ||||||
| @@ -50,65 +49,26 @@ BeidouB3iPcpsAcquisition::BeidouB3iPcpsAcquisition( | |||||||
|                                 out_streams_(out_streams) |                                 out_streams_(out_streams) | ||||||
| { | { | ||||||
|     configuration_ = configuration; |     configuration_ = configuration; | ||||||
|     std::string default_item_type = "gr_complex"; |     acq_parameters_.ms_per_code = 1; | ||||||
|     std::string default_dump_filename = "./acquisition.mat"; |     acq_parameters_.SetFromConfiguration(configuration_, role, BEIDOU_B3I_CODE_RATE_CPS, 100e6); | ||||||
|  |  | ||||||
|     LOG(INFO) << "role " << role; |     LOG(INFO) << "role " << role; | ||||||
|  |  | ||||||
|     item_type_ = configuration_->property(role + ".item_type", default_item_type); |  | ||||||
|  |  | ||||||
|     int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); |  | ||||||
|     fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); |  | ||||||
|     acq_parameters_.fs_in = fs_in_; |  | ||||||
|     dump_ = configuration_->property(role + ".dump", false); |  | ||||||
|     acq_parameters_.dump = dump_; |  | ||||||
|     acq_parameters_.dump_channel = configuration_->property(role + ".dump_channel", 0); |  | ||||||
|     blocking_ = configuration_->property(role + ".blocking", true); |  | ||||||
|     acq_parameters_.blocking = blocking_; |  | ||||||
|     doppler_max_ = configuration->property(role + ".doppler_max", 5000); |  | ||||||
|     if (FLAGS_doppler_max != 0) |     if (FLAGS_doppler_max != 0) | ||||||
|         { |         { | ||||||
|             doppler_max_ = FLAGS_doppler_max; |             acq_parameters_.doppler_max = FLAGS_doppler_max; | ||||||
|         } |         } | ||||||
|     acq_parameters_.doppler_max = doppler_max_; |     doppler_max_ = acq_parameters_.doppler_max; | ||||||
|     bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false); |     doppler_step_ = acq_parameters_.doppler_step; | ||||||
|     acq_parameters_.bit_transition_flag = bit_transition_flag_; |     item_type_ = acq_parameters_.item_type; | ||||||
|     use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true);  // will be false in future versions |     item_size_ = acq_parameters_.it_size; | ||||||
|     acq_parameters_.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_; |     fs_in_ = acq_parameters_.fs_in; | ||||||
|     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_.sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 1); |  | ||||||
|  |  | ||||||
|     if (item_type_ == "cshort") |  | ||||||
|         { |  | ||||||
|             item_size_ = sizeof(lv_16sc_t); |  | ||||||
|         } |  | ||||||
|     else |  | ||||||
|         { |  | ||||||
|             item_size_ = sizeof(gr_complex); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     acq_parameters_.ms_per_code = 1; |  | ||||||
|     acq_parameters_.it_size = item_size_; |  | ||||||
|     num_codes_ = acq_parameters_.sampled_ms; |     num_codes_ = acq_parameters_.sampled_ms; | ||||||
|     acq_parameters_.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); |  | ||||||
|     acq_parameters_.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0); |  | ||||||
|     acq_parameters_.make_2_steps = configuration_->property(role + ".make_two_steps", false); |  | ||||||
|     acq_parameters_.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false); |  | ||||||
|     acq_parameters_.use_automatic_resampler = configuration_->property("GNSS-SDR.use_acquisition_resampler", false); |  | ||||||
|  |  | ||||||
|     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_) / (BEIDOU_B3I_CODE_RATE_CPS / BEIDOU_B3I_CODE_LENGTH_CHIPS))); |     code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(fs_in_) / (BEIDOU_B3I_CODE_RATE_CPS / BEIDOU_B3I_CODE_LENGTH_CHIPS))); | ||||||
|     acq_parameters_.samples_per_ms = static_cast<float>(fs_in_) * 0.001; |  | ||||||
|     acq_parameters_.samples_per_chip = static_cast<unsigned int>(ceil((1.0 / BEIDOU_B3I_CODE_RATE_CPS) * static_cast<float>(acq_parameters_.fs_in))); |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     acq_parameters_.samples_per_code = acq_parameters_.samples_per_ms * static_cast<float>(BEIDOU_B3I_CODE_PERIOD_S * 1000.0); |  | ||||||
|     vector_length_ = std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2 : 1); |     vector_length_ = std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2 : 1); | ||||||
|     code_ = std::vector<std::complex<float>>(vector_length_); |     code_ = std::vector<std::complex<float>>(vector_length_); | ||||||
|  |  | ||||||
|     acquisition_ = pcps_make_acquisition(acq_parameters_); |     acquisition_ = pcps_make_acquisition(acq_parameters_); | ||||||
|     DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; |     DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; | ||||||
|  |  | ||||||
| @@ -120,7 +80,6 @@ BeidouB3iPcpsAcquisition::BeidouB3iPcpsAcquisition( | |||||||
|  |  | ||||||
|     channel_ = 0; |     channel_ = 0; | ||||||
|     threshold_ = 0.0; |     threshold_ = 0.0; | ||||||
|     doppler_step_ = 0; |  | ||||||
|     gnss_synchro_ = nullptr; |     gnss_synchro_ = nullptr; | ||||||
|  |  | ||||||
|     if (in_streams_ > 1) |     if (in_streams_ > 1) | ||||||
| @@ -141,22 +100,7 @@ void BeidouB3iPcpsAcquisition::stop_acquisition() | |||||||
|  |  | ||||||
| void BeidouB3iPcpsAcquisition::set_threshold(float threshold) | void BeidouB3iPcpsAcquisition::set_threshold(float threshold) | ||||||
| { | { | ||||||
|     float pfa = configuration_->property(role_ + std::to_string(channel_) + ".pfa", 0.0); |     threshold_ = threshold; | ||||||
|  |  | ||||||
|     if (pfa == 0.0) |  | ||||||
|         { |  | ||||||
|             pfa = configuration_->property(role_ + ".pfa", 0.0); |  | ||||||
|         } |  | ||||||
|     if (pfa == 0.0) |  | ||||||
|         { |  | ||||||
|             threshold_ = threshold; |  | ||||||
|         } |  | ||||||
|     else |  | ||||||
|         { |  | ||||||
|             threshold_ = calculate_threshold(pfa); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold_; |  | ||||||
|  |  | ||||||
|     acquisition_->set_threshold(threshold_); |     acquisition_->set_threshold(threshold_); | ||||||
| } | } | ||||||
| @@ -226,23 +170,6 @@ void BeidouB3iPcpsAcquisition::set_state(int state) | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| float BeidouB3iPcpsAcquisition::calculate_threshold(float pfa) |  | ||||||
| { |  | ||||||
|     // Calculate the threshold |  | ||||||
|     unsigned int frequency_bins = 0; |  | ||||||
|     frequency_bins = (2 * doppler_max_ + doppler_step_) / doppler_step_; |  | ||||||
|     DLOG(INFO) << "Channel " << channel_ << "  Pfa = " << pfa; |  | ||||||
|     unsigned int ncells = vector_length_ * frequency_bins; |  | ||||||
|     double exponent = 1.0 / static_cast<double>(ncells); |  | ||||||
|     double val = pow(1.0 - pfa, exponent); |  | ||||||
|     auto lambda = static_cast<double>(vector_length_); |  | ||||||
|     boost::math::exponential_distribution<double> mydist(lambda); |  | ||||||
|     auto threshold = static_cast<float>(quantile(mydist, val)); |  | ||||||
|  |  | ||||||
|     return threshold; |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| void BeidouB3iPcpsAcquisition::connect(gr::top_block_sptr top_block) | void BeidouB3iPcpsAcquisition::connect(gr::top_block_sptr top_block) | ||||||
| { | { | ||||||
|     if (item_type_ == "gr_complex") |     if (item_type_ == "gr_complex") | ||||||
|   | |||||||
| @@ -169,17 +169,12 @@ private: | |||||||
|     std::string item_type_; |     std::string item_type_; | ||||||
|     unsigned int vector_length_; |     unsigned int vector_length_; | ||||||
|     unsigned int code_length_; |     unsigned int code_length_; | ||||||
|     bool bit_transition_flag_; |  | ||||||
|     bool use_CFAR_algorithm_flag_; |  | ||||||
|     unsigned int channel_; |     unsigned int channel_; | ||||||
|     std::weak_ptr<ChannelFsm> channel_fsm_; |     std::weak_ptr<ChannelFsm> channel_fsm_; | ||||||
|     float threshold_; |     float threshold_; | ||||||
|     unsigned int doppler_max_; |     unsigned int doppler_max_; | ||||||
|     unsigned int doppler_step_; |     unsigned int doppler_step_; | ||||||
|     unsigned int max_dwells_; |  | ||||||
|     int64_t fs_in_; |     int64_t fs_in_; | ||||||
|     bool dump_; |  | ||||||
|     bool blocking_; |  | ||||||
|     std::string dump_filename_; |     std::string dump_filename_; | ||||||
|     std::vector<std::complex<float>> code_; |     std::vector<std::complex<float>> code_; | ||||||
|     Gnss_Synchro* gnss_synchro_; |     Gnss_Synchro* gnss_synchro_; | ||||||
| @@ -187,7 +182,6 @@ private: | |||||||
|     unsigned int num_codes_; |     unsigned int num_codes_; | ||||||
|     unsigned int in_streams_; |     unsigned int in_streams_; | ||||||
|     unsigned int out_streams_; |     unsigned int out_streams_; | ||||||
|     float calculate_threshold(float pfa); |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif /* GNSS_SDR_BEIDOU_B3I_PCPS_ACQUISITION_H_ */ | #endif /* GNSS_SDR_BEIDOU_B3I_PCPS_ACQUISITION_H_ */ | ||||||
|   | |||||||
| @@ -49,99 +49,28 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition( | |||||||
|                                 out_streams_(out_streams) |                                 out_streams_(out_streams) | ||||||
| { | { | ||||||
|     configuration_ = configuration; |     configuration_ = configuration; | ||||||
|     std::string default_item_type = "gr_complex"; |     acq_parameters_.ms_per_code = 4; | ||||||
|     std::string default_dump_filename = "./acquisition.mat"; |     acq_parameters_.SetFromConfiguration(configuration_, role, GALILEO_E1_CODE_CHIP_RATE_CPS, GALILEO_E1_OPT_ACQ_FS_SPS); | ||||||
|  |  | ||||||
|     DLOG(INFO) << "role " << role; |     DLOG(INFO) << "role " << role; | ||||||
|  |  | ||||||
|     item_type_ = configuration_->property(role + ".item_type", default_item_type); |  | ||||||
|  |  | ||||||
|     int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 4000000); |  | ||||||
|     fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); |  | ||||||
|     acq_parameters_.fs_in = fs_in_; |  | ||||||
|     doppler_max_ = configuration_->property(role + ".doppler_max", 5000); |  | ||||||
|     if (FLAGS_doppler_max != 0) |     if (FLAGS_doppler_max != 0) | ||||||
|         { |         { | ||||||
|             doppler_max_ = FLAGS_doppler_max; |             acq_parameters_.doppler_max = FLAGS_doppler_max; | ||||||
|         } |  | ||||||
|     acq_parameters_.doppler_max = doppler_max_; |  | ||||||
|     acq_parameters_.ms_per_code = 4; |  | ||||||
|     sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", acq_parameters_.ms_per_code); |  | ||||||
|     acq_parameters_.sampled_ms = sampled_ms_; |  | ||||||
|     if ((acq_parameters_.sampled_ms % acq_parameters_.ms_per_code) != 0) |  | ||||||
|         { |  | ||||||
|             LOG(WARNING) << "Parameter coherent_integration_time_ms should be a multiple of 4. Setting it to 4"; |  | ||||||
|             acq_parameters_.sampled_ms = acq_parameters_.ms_per_code; |  | ||||||
|         } |  | ||||||
|     bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false); |  | ||||||
|     acq_parameters_.bit_transition_flag = bit_transition_flag_; |  | ||||||
|     use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true);  // will be false in future versions |  | ||||||
|     acq_parameters_.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_; |  | ||||||
|     acquire_pilot_ = configuration_->property(role + ".acquire_pilot", false);  // will be true in future versions |  | ||||||
|     max_dwells_ = configuration_->property(role + ".max_dwells", 1); |  | ||||||
|     acq_parameters_.max_dwells = max_dwells_; |  | ||||||
|     dump_ = configuration_->property(role + ".dump", false); |  | ||||||
|     acq_parameters_.dump = dump_; |  | ||||||
|     acq_parameters_.dump_channel = configuration_->property(role + ".dump_channel", 0); |  | ||||||
|     blocking_ = configuration_->property(role + ".blocking", true); |  | ||||||
|     acq_parameters_.blocking = blocking_; |  | ||||||
|     dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename); |  | ||||||
|     acq_parameters_.dump_filename = dump_filename_; |  | ||||||
|  |  | ||||||
|     acq_parameters_.use_automatic_resampler = configuration_->property("GNSS-SDR.use_acquisition_resampler", false); |  | ||||||
|     if (acq_parameters_.use_automatic_resampler == true and item_type_ != "gr_complex") |  | ||||||
|         { |  | ||||||
|             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_SPS) |  | ||||||
|                 { |  | ||||||
|                     acq_parameters_.resampler_ratio = floor(static_cast<float>(acq_parameters_.fs_in) / GALILEO_E1_OPT_ACQ_FS_SPS); |  | ||||||
|                     uint32_t decimation = acq_parameters_.fs_in / GALILEO_E1_OPT_ACQ_FS_SPS; |  | ||||||
|                     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 (4 ms)  ----------------- |  | ||||||
|             code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(acq_parameters_.resampled_fs) / (GALILEO_E1_CODE_CHIP_RATE_CPS / GALILEO_E1_B_CODE_LENGTH_CHIPS))); |  | ||||||
|             acq_parameters_.samples_per_ms = static_cast<float>(acq_parameters_.resampled_fs) * 0.001; |  | ||||||
|             acq_parameters_.samples_per_chip = static_cast<unsigned int>(ceil((1.0 / GALILEO_E1_CODE_CHIP_RATE_CPS) * static_cast<float>(acq_parameters_.resampled_fs))); |  | ||||||
|         } |  | ||||||
|     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_CPS / GALILEO_E1_B_CODE_LENGTH_CHIPS))); |  | ||||||
|             acq_parameters_.samples_per_ms = static_cast<float>(fs_in_) * 0.001; |  | ||||||
|             acq_parameters_.samples_per_chip = static_cast<unsigned int>(ceil((1.0 / GALILEO_E1_CODE_CHIP_RATE_CPS) * static_cast<float>(acq_parameters_.fs_in))); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     acq_parameters_.samples_per_code = acq_parameters_.samples_per_ms * static_cast<float>(GALILEO_E1_CODE_PERIOD_MS); |  | ||||||
|     vector_length_ = sampled_ms_ * acq_parameters_.samples_per_ms; |  | ||||||
|     if (bit_transition_flag_) |  | ||||||
|         { |  | ||||||
|             vector_length_ *= 2; |  | ||||||
|         } |         } | ||||||
|  |     doppler_max_ = acq_parameters_.doppler_max; | ||||||
|  |     doppler_step_ = acq_parameters_.doppler_step; | ||||||
|  |     item_type_ = acq_parameters_.item_type; | ||||||
|  |     item_size_ = acq_parameters_.it_size; | ||||||
|  |     fs_in_ = acq_parameters_.fs_in; | ||||||
|  |     acquire_pilot_ = configuration->property(role + ".acquire_pilot", false); | ||||||
|  |  | ||||||
|  |     code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(acq_parameters_.resampled_fs) / (GALILEO_E1_CODE_CHIP_RATE_CPS / GALILEO_E1_B_CODE_LENGTH_CHIPS))); | ||||||
|  |     vector_length_ = std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2 : 1); | ||||||
|     code_ = std::vector<std::complex<float>>(vector_length_); |     code_ = std::vector<std::complex<float>>(vector_length_); | ||||||
|  |  | ||||||
|     if (item_type_ == "cshort") |     sampled_ms_ = acq_parameters_.sampled_ms; | ||||||
|         { |  | ||||||
|             item_size_ = sizeof(lv_16sc_t); |  | ||||||
|         } |  | ||||||
|     else |  | ||||||
|         { |  | ||||||
|             item_size_ = sizeof(gr_complex); |  | ||||||
|         } |  | ||||||
|     acq_parameters_.it_size = item_size_; |  | ||||||
|     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_.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false); |  | ||||||
|     acquisition_ = pcps_make_acquisition(acq_parameters_); |     acquisition_ = pcps_make_acquisition(acq_parameters_); | ||||||
|     DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; |     DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; | ||||||
|  |  | ||||||
| @@ -153,7 +82,6 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition( | |||||||
|  |  | ||||||
|     channel_ = 0; |     channel_ = 0; | ||||||
|     threshold_ = 0.0; |     threshold_ = 0.0; | ||||||
|     doppler_step_ = 0; |  | ||||||
|     doppler_center_ = 0; |     doppler_center_ = 0; | ||||||
|     gnss_synchro_ = nullptr; |     gnss_synchro_ = nullptr; | ||||||
|  |  | ||||||
| @@ -175,23 +103,7 @@ void GalileoE1PcpsAmbiguousAcquisition::stop_acquisition() | |||||||
|  |  | ||||||
| void GalileoE1PcpsAmbiguousAcquisition::set_threshold(float threshold) | void GalileoE1PcpsAmbiguousAcquisition::set_threshold(float threshold) | ||||||
| { | { | ||||||
|     float pfa = configuration_->property(role_ + std::to_string(channel_) + ".pfa", 0.0); |     threshold_ = threshold; | ||||||
|  |  | ||||||
|     if (pfa == 0.0) |  | ||||||
|         { |  | ||||||
|             pfa = configuration_->property(role_ + ".pfa", 0.0); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     if (pfa == 0.0) |  | ||||||
|         { |  | ||||||
|             threshold_ = threshold; |  | ||||||
|         } |  | ||||||
|     else |  | ||||||
|         { |  | ||||||
|             threshold_ = calculate_threshold(pfa); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold_; |  | ||||||
|  |  | ||||||
|     acquisition_->set_threshold(threshold_); |     acquisition_->set_threshold(threshold_); | ||||||
| } | } | ||||||
| @@ -303,27 +215,6 @@ void GalileoE1PcpsAmbiguousAcquisition::set_state(int state) | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| float GalileoE1PcpsAmbiguousAcquisition::calculate_threshold(float pfa) |  | ||||||
| { |  | ||||||
|     unsigned int frequency_bins = 0; |  | ||||||
|     for (int doppler = static_cast<int>(-doppler_max_); doppler <= static_cast<int>(doppler_max_); doppler += doppler_step_) |  | ||||||
|         { |  | ||||||
|             frequency_bins++; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     DLOG(INFO) << "Channel " << channel_ << "  Pfa = " << pfa; |  | ||||||
|  |  | ||||||
|     unsigned int ncells = vector_length_ * frequency_bins; |  | ||||||
|     double exponent = 1 / static_cast<double>(ncells); |  | ||||||
|     double val = pow(1.0 - pfa, exponent); |  | ||||||
|     auto lambda = static_cast<double>(vector_length_); |  | ||||||
|     boost::math::exponential_distribution<double> mydist(lambda); |  | ||||||
|     auto threshold = static_cast<float>(quantile(mydist, val)); |  | ||||||
|  |  | ||||||
|     return threshold; |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| void GalileoE1PcpsAmbiguousAcquisition::connect(gr::top_block_sptr top_block) | void GalileoE1PcpsAmbiguousAcquisition::connect(gr::top_block_sptr top_block) | ||||||
| { | { | ||||||
|     if (item_type_ == "gr_complex") |     if (item_type_ == "gr_complex") | ||||||
|   | |||||||
| @@ -173,8 +173,6 @@ private: | |||||||
|     std::string item_type_; |     std::string item_type_; | ||||||
|     unsigned int vector_length_; |     unsigned int vector_length_; | ||||||
|     unsigned int code_length_; |     unsigned int code_length_; | ||||||
|     bool bit_transition_flag_; |  | ||||||
|     bool use_CFAR_algorithm_flag_; |  | ||||||
|     bool acquire_pilot_; |     bool acquire_pilot_; | ||||||
|     unsigned int channel_; |     unsigned int channel_; | ||||||
|     std::weak_ptr<ChannelFsm> channel_fsm_; |     std::weak_ptr<ChannelFsm> channel_fsm_; | ||||||
| @@ -183,17 +181,13 @@ private: | |||||||
|     unsigned int doppler_step_; |     unsigned int doppler_step_; | ||||||
|     int doppler_center_; |     int doppler_center_; | ||||||
|     unsigned int sampled_ms_; |     unsigned int sampled_ms_; | ||||||
|     unsigned int max_dwells_; |  | ||||||
|     int64_t fs_in_; |     int64_t fs_in_; | ||||||
|     bool dump_; |  | ||||||
|     bool blocking_; |  | ||||||
|     std::string dump_filename_; |     std::string dump_filename_; | ||||||
|     std::vector<std::complex<float>> code_; |     std::vector<std::complex<float>> code_; | ||||||
|     Gnss_Synchro* gnss_synchro_; |     Gnss_Synchro* gnss_synchro_; | ||||||
|     std::string role_; |     std::string role_; | ||||||
|     unsigned int in_streams_; |     unsigned int in_streams_; | ||||||
|     unsigned int out_streams_; |     unsigned int out_streams_; | ||||||
|     float calculate_threshold(float pfa); |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif /* GNSS_SDR_GALILEO_E1_PCPS_AMBIGUOUS_ACQUISITION_H_ */ | #endif /* GNSS_SDR_GALILEO_E1_PCPS_AMBIGUOUS_ACQUISITION_H_ */ | ||||||
|   | |||||||
| @@ -34,7 +34,6 @@ | |||||||
| #include "configuration_interface.h" | #include "configuration_interface.h" | ||||||
| #include "galileo_e5_signal_processing.h" | #include "galileo_e5_signal_processing.h" | ||||||
| #include "gnss_sdr_flags.h" | #include "gnss_sdr_flags.h" | ||||||
| #include <boost/math/distributions/exponential.hpp> |  | ||||||
| #include <glog/logging.h> | #include <glog/logging.h> | ||||||
| #include <volk_gnsssdr/volk_gnsssdr_complex.h> | #include <volk_gnsssdr/volk_gnsssdr_complex.h> | ||||||
| #include <algorithm> | #include <algorithm> | ||||||
| @@ -48,109 +47,40 @@ GalileoE5aPcpsAcquisition::GalileoE5aPcpsAcquisition(ConfigurationInterface* con | |||||||
|                                 out_streams_(out_streams) |                                 out_streams_(out_streams) | ||||||
| { | { | ||||||
|     configuration_ = configuration; |     configuration_ = configuration; | ||||||
|     std::string default_item_type = "gr_complex"; |     acq_parameters_.ms_per_code = 1; | ||||||
|     std::string default_dump_filename = "./acquisition.mat"; |     acq_parameters_.SetFromConfiguration(configuration_, role, GALILEO_E5A_CODE_CHIP_RATE_CPS, GALILEO_E5A_OPT_ACQ_FS_SPS); | ||||||
|  |  | ||||||
|     DLOG(INFO) << "Role " << role; |     DLOG(INFO) << "Role " << role; | ||||||
|  |  | ||||||
|     item_type_ = configuration_->property(role + ".item_type", default_item_type); |     if (FLAGS_doppler_max != 0) | ||||||
|  |         { | ||||||
|  |             acq_parameters_.doppler_max = FLAGS_doppler_max; | ||||||
|  |         } | ||||||
|  |     doppler_max_ = acq_parameters_.doppler_max; | ||||||
|  |     doppler_step_ = acq_parameters_.doppler_step; | ||||||
|  |     item_type_ = acq_parameters_.item_type; | ||||||
|  |     item_size_ = acq_parameters_.it_size; | ||||||
|  |     fs_in_ = acq_parameters_.fs_in; | ||||||
|  |  | ||||||
|     int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 32000000); |  | ||||||
|     fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); |  | ||||||
|     acq_parameters_.fs_in = fs_in_; |  | ||||||
|     acq_pilot_ = configuration_->property(role + ".acquire_pilot", false); |     acq_pilot_ = configuration_->property(role + ".acquire_pilot", false); | ||||||
|     acq_iq_ = configuration_->property(role + ".acquire_iq", false); |     acq_iq_ = configuration_->property(role + ".acquire_iq", false); | ||||||
|     if (acq_iq_) |     if (acq_iq_) | ||||||
|         { |         { | ||||||
|             acq_pilot_ = false; |             acq_pilot_ = false; | ||||||
|         } |         } | ||||||
|     dump_ = configuration_->property(role + ".dump", false); |  | ||||||
|     acq_parameters_.dump = dump_; |  | ||||||
|     acq_parameters_.dump_channel = configuration_->property(role + ".dump_channel", 0); |  | ||||||
|     doppler_max_ = configuration_->property(role + ".doppler_max", 5000); |  | ||||||
|     if (FLAGS_doppler_max != 0) |  | ||||||
|         { |  | ||||||
|             doppler_max_ = FLAGS_doppler_max; |  | ||||||
|         } |  | ||||||
|     acq_parameters_.doppler_max = doppler_max_; |  | ||||||
|     sampled_ms_ = 1; |  | ||||||
|     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_; |  | ||||||
|     bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false); |  | ||||||
|     acq_parameters_.bit_transition_flag = bit_transition_flag_; |  | ||||||
|     use_CFAR_ = configuration_->property(role + ".use_CFAR_algorithm", false); |  | ||||||
|     acq_parameters_.use_CFAR_algorithm_flag = use_CFAR_; |  | ||||||
|     blocking_ = configuration_->property(role + ".blocking", true); |  | ||||||
|     acq_parameters_.blocking = blocking_; |  | ||||||
|  |  | ||||||
|     acq_parameters_.use_automatic_resampler = configuration_->property("GNSS-SDR.use_acquisition_resampler", false); |  | ||||||
|     if (acq_parameters_.use_automatic_resampler == true and item_type_ != "gr_complex") |  | ||||||
|         { |  | ||||||
|             LOG(WARNING) << "Galileo E5a 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 > GALILEO_E5A_OPT_ACQ_FS_SPS) |  | ||||||
|                 { |  | ||||||
|                     acq_parameters_.resampler_ratio = floor(static_cast<float>(acq_parameters_.fs_in) / GALILEO_E5A_OPT_ACQ_FS_SPS); |  | ||||||
|                     uint32_t decimation = acq_parameters_.fs_in / GALILEO_E5A_OPT_ACQ_FS_SPS; |  | ||||||
|                     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) / (GALILEO_E5A_CODE_CHIP_RATE_CPS / GALILEO_E5A_CODE_LENGTH_CHIPS))); |  | ||||||
|             acq_parameters_.samples_per_ms = static_cast<float>(acq_parameters_.resampled_fs) * 0.001; |  | ||||||
|             acq_parameters_.samples_per_chip = static_cast<unsigned int>(ceil((1.0 / GALILEO_E5A_CODE_CHIP_RATE_CPS) * static_cast<float>(acq_parameters_.resampled_fs))); |  | ||||||
|         } |  | ||||||
|     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_) / (GALILEO_E5A_CODE_CHIP_RATE_CPS / GALILEO_E5A_CODE_LENGTH_CHIPS))); |  | ||||||
|             acq_parameters_.samples_per_ms = static_cast<float>(fs_in_) * 0.001; |  | ||||||
|             acq_parameters_.samples_per_chip = static_cast<unsigned int>(ceil((1.0 / GALILEO_E5A_CODE_CHIP_RATE_CPS) * static_cast<float>(acq_parameters_.fs_in))); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     // -- Find number of samples per spreading code (1ms)------------------------- |  | ||||||
|     code_length_ = static_cast<unsigned int>(std::round(static_cast<double>(fs_in_) / GALILEO_E5A_CODE_CHIP_RATE_CPS * static_cast<double>(GALILEO_E5A_CODE_LENGTH_CHIPS))); |  | ||||||
|     vector_length_ = code_length_ * sampled_ms_; |  | ||||||
|  |  | ||||||
|  |     code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(acq_parameters_.resampled_fs) / (GALILEO_E5A_CODE_CHIP_RATE_CPS / GALILEO_E5A_CODE_LENGTH_CHIPS))); | ||||||
|  |     vector_length_ = std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2 : 1); | ||||||
|     code_ = std::vector<std::complex<float>>(vector_length_); |     code_ = std::vector<std::complex<float>>(vector_length_); | ||||||
|  |  | ||||||
|     if (item_type_ == "gr_complex") |     sampled_ms_ = acq_parameters_.sampled_ms; | ||||||
|         { |  | ||||||
|             item_size_ = sizeof(gr_complex); |  | ||||||
|         } |  | ||||||
|     else if (item_type_ == "cshort") |  | ||||||
|         { |  | ||||||
|             item_size_ = sizeof(lv_16sc_t); |  | ||||||
|         } |  | ||||||
|     else |  | ||||||
|         { |  | ||||||
|             item_size_ = sizeof(gr_complex); |  | ||||||
|             LOG(WARNING) << item_type_ << " unknown acquisition item type"; |  | ||||||
|         } |  | ||||||
|     acq_parameters_.it_size = item_size_; |  | ||||||
|     acq_parameters_.sampled_ms = sampled_ms_; |  | ||||||
|     acq_parameters_.ms_per_code = 1; |  | ||||||
|     acq_parameters_.samples_per_code = acq_parameters_.samples_per_ms * static_cast<float>(GALILEO_E5A_CODE_PERIOD_MS); |  | ||||||
|     acq_parameters_.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); |  | ||||||
|     acq_parameters_.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0); |  | ||||||
|     acq_parameters_.make_2_steps = configuration_->property(role + ".make_two_steps", false); |  | ||||||
|     acq_parameters_.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false); |  | ||||||
|     acquisition_ = pcps_make_acquisition(acq_parameters_); |     acquisition_ = pcps_make_acquisition(acq_parameters_); | ||||||
|  |     DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; | ||||||
|  |  | ||||||
|  |  | ||||||
|     channel_ = 0; |     channel_ = 0; | ||||||
|     threshold_ = 0.0; |     threshold_ = 0.0; | ||||||
|     doppler_step_ = 0; |  | ||||||
|     doppler_center_ = 0; |     doppler_center_ = 0; | ||||||
|     gnss_synchro_ = nullptr; |     gnss_synchro_ = nullptr; | ||||||
|  |  | ||||||
| @@ -172,24 +102,7 @@ void GalileoE5aPcpsAcquisition::stop_acquisition() | |||||||
|  |  | ||||||
| void GalileoE5aPcpsAcquisition::set_threshold(float threshold) | void GalileoE5aPcpsAcquisition::set_threshold(float threshold) | ||||||
| { | { | ||||||
|     float pfa = configuration_->property(role_ + std::to_string(channel_) + ".pfa", 0.0); |     threshold_ = threshold; | ||||||
|  |  | ||||||
|     if (pfa == 0.0) |  | ||||||
|         { |  | ||||||
|             pfa = configuration_->property(role_ + ".pfa", 0.0); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     if (pfa == 0.0) |  | ||||||
|         { |  | ||||||
|             threshold_ = threshold; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     else |  | ||||||
|         { |  | ||||||
|             threshold_ = calculate_threshold(pfa); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold_; |  | ||||||
|  |  | ||||||
|     acquisition_->set_threshold(threshold_); |     acquisition_->set_threshold(threshold_); | ||||||
| } | } | ||||||
| @@ -280,25 +193,6 @@ void GalileoE5aPcpsAcquisition::reset() | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| float GalileoE5aPcpsAcquisition::calculate_threshold(float pfa) |  | ||||||
| { |  | ||||||
|     unsigned int frequency_bins = 0; |  | ||||||
|     for (int doppler = static_cast<int>(-doppler_max_); doppler <= static_cast<int>(doppler_max_); doppler += doppler_step_) |  | ||||||
|         { |  | ||||||
|             frequency_bins++; |  | ||||||
|         } |  | ||||||
|     DLOG(INFO) << "Channel " << channel_ << "  Pfa = " << pfa; |  | ||||||
|     unsigned int ncells = vector_length_ * frequency_bins; |  | ||||||
|     double exponent = 1 / static_cast<double>(ncells); |  | ||||||
|     double val = pow(1.0 - pfa, exponent); |  | ||||||
|     auto lambda = static_cast<double>(vector_length_); |  | ||||||
|     boost::math::exponential_distribution<double> mydist(lambda); |  | ||||||
|     auto threshold = static_cast<float>(quantile(mydist, val)); |  | ||||||
|  |  | ||||||
|     return threshold; |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| void GalileoE5aPcpsAcquisition::set_state(int state) | void GalileoE5aPcpsAcquisition::set_state(int state) | ||||||
| { | { | ||||||
|     acquisition_->set_state(state); |     acquisition_->set_state(state); | ||||||
|   | |||||||
| @@ -154,7 +154,6 @@ public: | |||||||
|     void set_resampler_latency(uint32_t latency_samples) override; |     void set_resampler_latency(uint32_t latency_samples) override; | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     float calculate_threshold(float pfa); |  | ||||||
|     ConfigurationInterface* configuration_; |     ConfigurationInterface* configuration_; | ||||||
|     pcps_acquisition_sptr acquisition_; |     pcps_acquisition_sptr acquisition_; | ||||||
|     Acq_Conf acq_parameters_; |     Acq_Conf acq_parameters_; | ||||||
| @@ -162,11 +161,7 @@ private: | |||||||
|     std::string item_type_; |     std::string item_type_; | ||||||
|     std::string dump_filename_; |     std::string dump_filename_; | ||||||
|     std::string role_; |     std::string role_; | ||||||
|     bool bit_transition_flag_; |  | ||||||
|     bool dump_; |  | ||||||
|     bool acq_pilot_; |     bool acq_pilot_; | ||||||
|     bool use_CFAR_; |  | ||||||
|     bool blocking_; |  | ||||||
|     bool acq_iq_; |     bool acq_iq_; | ||||||
|     unsigned int vector_length_; |     unsigned int vector_length_; | ||||||
|     unsigned int code_length_; |     unsigned int code_length_; | ||||||
| @@ -176,7 +171,6 @@ private: | |||||||
|     unsigned int doppler_step_; |     unsigned int doppler_step_; | ||||||
|     int doppler_center_; |     int doppler_center_; | ||||||
|     unsigned int sampled_ms_; |     unsigned int sampled_ms_; | ||||||
|     unsigned int max_dwells_; |  | ||||||
|     unsigned int in_streams_; |     unsigned int in_streams_; | ||||||
|     unsigned int out_streams_; |     unsigned int out_streams_; | ||||||
|     int64_t fs_in_; |     int64_t fs_in_; | ||||||
|   | |||||||
| @@ -37,7 +37,6 @@ | |||||||
| #include "configuration_interface.h" | #include "configuration_interface.h" | ||||||
| #include "glonass_l1_signal_processing.h" | #include "glonass_l1_signal_processing.h" | ||||||
| #include "gnss_sdr_flags.h" | #include "gnss_sdr_flags.h" | ||||||
| #include <boost/math/distributions/exponential.hpp> |  | ||||||
| #include <glog/logging.h> | #include <glog/logging.h> | ||||||
| #include <algorithm> | #include <algorithm> | ||||||
|  |  | ||||||
| @@ -50,70 +49,29 @@ GlonassL1CaPcpsAcquisition::GlonassL1CaPcpsAcquisition( | |||||||
|                                 in_streams_(in_streams), |                                 in_streams_(in_streams), | ||||||
|                                 out_streams_(out_streams) |                                 out_streams_(out_streams) | ||||||
| { | { | ||||||
|     Acq_Conf acq_parameters = Acq_Conf(); |  | ||||||
|     configuration_ = configuration; |     configuration_ = configuration; | ||||||
|     std::string default_item_type = "gr_complex"; |     acq_parameters_.ms_per_code = 1; | ||||||
|     std::string default_dump_filename = "./data/acquisition.dat"; |     acq_parameters_.SetFromConfiguration(configuration_, role, GLONASS_L1_CA_CODE_RATE_CPS, 100e6); | ||||||
|  |  | ||||||
|     DLOG(INFO) << "role " << role; |     DLOG(INFO) << "role " << role; | ||||||
|  |  | ||||||
|     item_type_ = configuration_->property(role + ".item_type", default_item_type); |  | ||||||
|  |  | ||||||
|     int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); |  | ||||||
|     fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); |  | ||||||
|     acq_parameters.fs_in = fs_in_; |  | ||||||
|     acq_parameters.samples_per_chip = static_cast<unsigned int>(ceil(GLONASS_L1_CA_CHIP_PERIOD_S * static_cast<float>(acq_parameters.fs_in))); |  | ||||||
|     dump_ = configuration_->property(role + ".dump", false); |  | ||||||
|     acq_parameters.dump = dump_; |  | ||||||
|     acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0); |  | ||||||
|     blocking_ = configuration_->property(role + ".blocking", true); |  | ||||||
|     acq_parameters.blocking = blocking_; |  | ||||||
|     doppler_max_ = configuration_->property(role + ".doppler_max", 5000); |  | ||||||
|     if (FLAGS_doppler_max != 0) |     if (FLAGS_doppler_max != 0) | ||||||
|         { |         { | ||||||
|             doppler_max_ = FLAGS_doppler_max; |             acq_parameters_.doppler_max = FLAGS_doppler_max; | ||||||
|         } |  | ||||||
|     acq_parameters.doppler_max = doppler_max_; |  | ||||||
|     sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 1); |  | ||||||
|     acq_parameters.sampled_ms = sampled_ms_; |  | ||||||
|     bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false); |  | ||||||
|     acq_parameters.bit_transition_flag = bit_transition_flag_; |  | ||||||
|     use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true);  // will be false in future versions |  | ||||||
|     acq_parameters.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_; |  | ||||||
|     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_; |  | ||||||
|     // --- Find number of samples per spreading code ------------------------- |  | ||||||
|     code_length_ = static_cast<unsigned int>(std::round(static_cast<double>(fs_in_) / (GLONASS_L1_CA_CODE_RATE_CPS / GLONASS_L1_CA_CODE_LENGTH_CHIPS))); |  | ||||||
|  |  | ||||||
|     vector_length_ = code_length_ * sampled_ms_; |  | ||||||
|  |  | ||||||
|     if (bit_transition_flag_) |  | ||||||
|         { |  | ||||||
|             vector_length_ *= 2; |  | ||||||
|         } |         } | ||||||
|  |     doppler_max_ = acq_parameters_.doppler_max; | ||||||
|  |     doppler_step_ = acq_parameters_.doppler_step; | ||||||
|  |     item_type_ = acq_parameters_.item_type; | ||||||
|  |     item_size_ = acq_parameters_.it_size; | ||||||
|  |     fs_in_ = acq_parameters_.fs_in; | ||||||
|  |  | ||||||
|  |     code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(acq_parameters_.resampled_fs) / (GLONASS_L1_CA_CODE_RATE_CPS / GLONASS_L1_CA_CODE_LENGTH_CHIPS))); | ||||||
|  |     vector_length_ = std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2 : 1); | ||||||
|     code_ = std::vector<std::complex<float>>(vector_length_); |     code_ = std::vector<std::complex<float>>(vector_length_); | ||||||
|  |  | ||||||
|     if (item_type_ == "cshort") |     sampled_ms_ = acq_parameters_.sampled_ms; | ||||||
|         { |  | ||||||
|             item_size_ = sizeof(lv_16sc_t); |     acquisition_ = pcps_make_acquisition(acq_parameters_); | ||||||
|         } |  | ||||||
|     else |  | ||||||
|         { |  | ||||||
|             item_size_ = sizeof(gr_complex); |  | ||||||
|         } |  | ||||||
|     acq_parameters.it_size = item_size_; |  | ||||||
|     acq_parameters.sampled_ms = sampled_ms_; |  | ||||||
|     acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001; |  | ||||||
|     acq_parameters.ms_per_code = 1; |  | ||||||
|     acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GLONASS_L1_CA_CODE_PERIOD_S * 1000.0); |  | ||||||
|     acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); |  | ||||||
|     acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0); |  | ||||||
|     acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false); |  | ||||||
|     acq_parameters.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false); |  | ||||||
|     acquisition_ = pcps_make_acquisition(acq_parameters); |  | ||||||
|     DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; |     DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; | ||||||
|  |  | ||||||
|     if (item_type_ == "cbyte") |     if (item_type_ == "cbyte") | ||||||
| @@ -145,18 +103,7 @@ void GlonassL1CaPcpsAcquisition::stop_acquisition() | |||||||
|  |  | ||||||
| void GlonassL1CaPcpsAcquisition::set_threshold(float threshold) | void GlonassL1CaPcpsAcquisition::set_threshold(float threshold) | ||||||
| { | { | ||||||
|     float pfa = configuration_->property(role_ + ".pfa", 0.0); |     threshold_ = threshold; | ||||||
|  |  | ||||||
|     if (pfa == 0.0) |  | ||||||
|         { |  | ||||||
|             threshold_ = threshold; |  | ||||||
|         } |  | ||||||
|     else |  | ||||||
|         { |  | ||||||
|             threshold_ = calculate_threshold(pfa); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold_; |  | ||||||
|  |  | ||||||
|     acquisition_->set_threshold(threshold_); |     acquisition_->set_threshold(threshold_); | ||||||
| } | } | ||||||
| @@ -228,31 +175,6 @@ void GlonassL1CaPcpsAcquisition::set_state(int state) | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| float GlonassL1CaPcpsAcquisition::calculate_threshold(float pfa) |  | ||||||
| { |  | ||||||
|     // Calculate the threshold |  | ||||||
|     unsigned int frequency_bins = 0; |  | ||||||
|     /* |  | ||||||
|     for (int doppler = (int)(-doppler_max_); doppler <= (int)doppler_max_; doppler += doppler_step_) |  | ||||||
|         { |  | ||||||
|             frequency_bins++; |  | ||||||
|         } |  | ||||||
|      */ |  | ||||||
|  |  | ||||||
|     frequency_bins = (2 * doppler_max_ + doppler_step_) / doppler_step_; |  | ||||||
|  |  | ||||||
|     DLOG(INFO) << "Channel " << channel_ << "  Pfa = " << pfa; |  | ||||||
|     unsigned int ncells = vector_length_ * frequency_bins; |  | ||||||
|     double exponent = 1 / static_cast<double>(ncells); |  | ||||||
|     double val = pow(1.0 - pfa, exponent); |  | ||||||
|     auto lambda = static_cast<double>(vector_length_); |  | ||||||
|     boost::math::exponential_distribution<double> mydist(lambda); |  | ||||||
|     auto threshold = static_cast<float>(quantile(mydist, val)); |  | ||||||
|  |  | ||||||
|     return threshold; |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| void GlonassL1CaPcpsAcquisition::connect(gr::top_block_sptr top_block) | void GlonassL1CaPcpsAcquisition::connect(gr::top_block_sptr top_block) | ||||||
| { | { | ||||||
|     if (item_type_ == "gr_complex") |     if (item_type_ == "gr_complex") | ||||||
|   | |||||||
| @@ -34,6 +34,7 @@ | |||||||
| #ifndef GNSS_SDR_GLONASS_L1_CA_PCPS_ACQUISITION_H_ | #ifndef GNSS_SDR_GLONASS_L1_CA_PCPS_ACQUISITION_H_ | ||||||
| #define GNSS_SDR_GLONASS_L1_CA_PCPS_ACQUISITION_H_ | #define GNSS_SDR_GLONASS_L1_CA_PCPS_ACQUISITION_H_ | ||||||
|  |  | ||||||
|  | #include "acq_conf.h" | ||||||
| #include "channel_fsm.h" | #include "channel_fsm.h" | ||||||
| #include "complex_byte_to_float_x2.h" | #include "complex_byte_to_float_x2.h" | ||||||
| #include "gnss_synchro.h" | #include "gnss_synchro.h" | ||||||
| @@ -156,6 +157,7 @@ public: | |||||||
|  |  | ||||||
| private: | private: | ||||||
|     ConfigurationInterface* configuration_; |     ConfigurationInterface* configuration_; | ||||||
|  |     Acq_Conf acq_parameters_; | ||||||
|     pcps_acquisition_sptr acquisition_; |     pcps_acquisition_sptr acquisition_; | ||||||
|     gr::blocks::float_to_complex::sptr float_to_complex_; |     gr::blocks::float_to_complex::sptr float_to_complex_; | ||||||
|     complex_byte_to_float_x2_sptr cbyte_to_float_x2_; |     complex_byte_to_float_x2_sptr cbyte_to_float_x2_; | ||||||
| @@ -163,25 +165,19 @@ private: | |||||||
|     std::string item_type_; |     std::string item_type_; | ||||||
|     unsigned int vector_length_; |     unsigned int vector_length_; | ||||||
|     unsigned int code_length_; |     unsigned int code_length_; | ||||||
|     bool bit_transition_flag_; |  | ||||||
|     bool use_CFAR_algorithm_flag_; |  | ||||||
|     unsigned int channel_; |     unsigned int channel_; | ||||||
|     std::weak_ptr<ChannelFsm> channel_fsm_; |     std::weak_ptr<ChannelFsm> channel_fsm_; | ||||||
|     float threshold_; |     float threshold_; | ||||||
|     unsigned int doppler_max_; |     unsigned int doppler_max_; | ||||||
|     unsigned int doppler_step_; |     unsigned int doppler_step_; | ||||||
|     unsigned int sampled_ms_; |     unsigned int sampled_ms_; | ||||||
|     unsigned int max_dwells_; |  | ||||||
|     int64_t fs_in_; |     int64_t fs_in_; | ||||||
|     bool dump_; |  | ||||||
|     bool blocking_; |  | ||||||
|     std::string dump_filename_; |     std::string dump_filename_; | ||||||
|     std::vector<std::complex<float>> code_; |     std::vector<std::complex<float>> code_; | ||||||
|     Gnss_Synchro* gnss_synchro_; |     Gnss_Synchro* gnss_synchro_; | ||||||
|     std::string role_; |     std::string role_; | ||||||
|     unsigned int in_streams_; |     unsigned int in_streams_; | ||||||
|     unsigned int out_streams_; |     unsigned int out_streams_; | ||||||
|     float calculate_threshold(float pfa); |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif /* GNSS_SDR_GLONASS_L1_CA_PCPS_ACQUISITION_H_ */ | #endif /* GNSS_SDR_GLONASS_L1_CA_PCPS_ACQUISITION_H_ */ | ||||||
|   | |||||||
| @@ -36,7 +36,6 @@ | |||||||
| #include "configuration_interface.h" | #include "configuration_interface.h" | ||||||
| #include "glonass_l2_signal_processing.h" | #include "glonass_l2_signal_processing.h" | ||||||
| #include "gnss_sdr_flags.h" | #include "gnss_sdr_flags.h" | ||||||
| #include <boost/math/distributions/exponential.hpp> |  | ||||||
| #include <glog/logging.h> | #include <glog/logging.h> | ||||||
| #include <algorithm> | #include <algorithm> | ||||||
|  |  | ||||||
| @@ -49,70 +48,29 @@ GlonassL2CaPcpsAcquisition::GlonassL2CaPcpsAcquisition( | |||||||
|                                 in_streams_(in_streams), |                                 in_streams_(in_streams), | ||||||
|                                 out_streams_(out_streams) |                                 out_streams_(out_streams) | ||||||
| { | { | ||||||
|     Acq_Conf acq_parameters = Acq_Conf(); |  | ||||||
|     configuration_ = configuration; |     configuration_ = configuration; | ||||||
|     std::string default_item_type = "gr_complex"; |     acq_parameters_.ms_per_code = 1; | ||||||
|     std::string default_dump_filename = "./data/acquisition.dat"; |     acq_parameters_.SetFromConfiguration(configuration_, role, GLONASS_L2_CA_CODE_RATE_CPS, 100e6); | ||||||
|  |  | ||||||
|     DLOG(INFO) << "role " << role; |     DLOG(INFO) << "role " << role; | ||||||
|  |  | ||||||
|     item_type_ = configuration_->property(role + ".item_type", default_item_type); |  | ||||||
|  |  | ||||||
|     int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); |  | ||||||
|     fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); |  | ||||||
|     acq_parameters.fs_in = fs_in_; |  | ||||||
|     acq_parameters.samples_per_chip = static_cast<unsigned int>(ceil(GLONASS_L2_CA_CHIP_PERIOD_S * static_cast<float>(acq_parameters.fs_in))); |  | ||||||
|     dump_ = configuration_->property(role + ".dump", false); |  | ||||||
|     acq_parameters.dump = dump_; |  | ||||||
|     acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0); |  | ||||||
|     blocking_ = configuration_->property(role + ".blocking", true); |  | ||||||
|     acq_parameters.blocking = blocking_; |  | ||||||
|     doppler_max_ = configuration_->property(role + ".doppler_max", 5000); |  | ||||||
|     if (FLAGS_doppler_max != 0) |     if (FLAGS_doppler_max != 0) | ||||||
|         { |         { | ||||||
|             doppler_max_ = FLAGS_doppler_max; |             acq_parameters_.doppler_max = FLAGS_doppler_max; | ||||||
|         } |  | ||||||
|     acq_parameters.doppler_max = doppler_max_; |  | ||||||
|     sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 1); |  | ||||||
|     bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false); |  | ||||||
|     acq_parameters.bit_transition_flag = bit_transition_flag_; |  | ||||||
|     use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true);  // will be false in future versions |  | ||||||
|     acq_parameters.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_; |  | ||||||
|     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_; |  | ||||||
|     // --- Find number of samples per spreading code ------------------------- |  | ||||||
|     code_length_ = static_cast<unsigned int>(std::round(static_cast<double>(fs_in_) / (GLONASS_L2_CA_CODE_RATE_CPS / GLONASS_L2_CA_CODE_LENGTH_CHIPS))); |  | ||||||
|  |  | ||||||
|     vector_length_ = code_length_ * sampled_ms_; |  | ||||||
|  |  | ||||||
|     if (bit_transition_flag_) |  | ||||||
|         { |  | ||||||
|             vector_length_ *= 2; |  | ||||||
|         } |         } | ||||||
|  |     doppler_max_ = acq_parameters_.doppler_max; | ||||||
|  |     doppler_step_ = acq_parameters_.doppler_step; | ||||||
|  |     item_type_ = acq_parameters_.item_type; | ||||||
|  |     item_size_ = acq_parameters_.it_size; | ||||||
|  |     fs_in_ = acq_parameters_.fs_in; | ||||||
|  |  | ||||||
|  |     code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(acq_parameters_.resampled_fs) / (GLONASS_L2_CA_CODE_RATE_CPS / GLONASS_L2_CA_CODE_LENGTH_CHIPS))); | ||||||
|  |     vector_length_ = std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2 : 1); | ||||||
|     code_ = std::vector<std::complex<float>>(vector_length_); |     code_ = std::vector<std::complex<float>>(vector_length_); | ||||||
|  |  | ||||||
|     if (item_type_ == "cshort") |     sampled_ms_ = acq_parameters_.sampled_ms; | ||||||
|         { |  | ||||||
|             item_size_ = sizeof(lv_16sc_t); |     acquisition_ = pcps_make_acquisition(acq_parameters_); | ||||||
|         } |  | ||||||
|     else |  | ||||||
|         { |  | ||||||
|             item_size_ = sizeof(gr_complex); |  | ||||||
|         } |  | ||||||
|     acq_parameters.it_size = item_size_; |  | ||||||
|     acq_parameters.sampled_ms = sampled_ms_; |  | ||||||
|     acq_parameters.samples_per_ms = static_cast<float>(fs_in_) * 0.001; |  | ||||||
|     acq_parameters.ms_per_code = 1; |  | ||||||
|     acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast<float>(GLONASS_L2_CA_CODE_PERIOD_S * 1000.0); |  | ||||||
|     acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); |  | ||||||
|     acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0); |  | ||||||
|     acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false); |  | ||||||
|     acq_parameters.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false); |  | ||||||
|     acquisition_ = pcps_make_acquisition(acq_parameters); |  | ||||||
|     DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; |     DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; | ||||||
|  |  | ||||||
|     if (item_type_ == "cbyte") |     if (item_type_ == "cbyte") | ||||||
| @@ -144,18 +102,7 @@ void GlonassL2CaPcpsAcquisition::stop_acquisition() | |||||||
|  |  | ||||||
| void GlonassL2CaPcpsAcquisition::set_threshold(float threshold) | void GlonassL2CaPcpsAcquisition::set_threshold(float threshold) | ||||||
| { | { | ||||||
|     float pfa = configuration_->property(role_ + ".pfa", 0.0); |     threshold_ = threshold; | ||||||
|  |  | ||||||
|     if (pfa == 0.0) |  | ||||||
|         { |  | ||||||
|             threshold_ = threshold; |  | ||||||
|         } |  | ||||||
|     else |  | ||||||
|         { |  | ||||||
|             threshold_ = calculate_threshold(pfa); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold_; |  | ||||||
|  |  | ||||||
|     acquisition_->set_threshold(threshold_); |     acquisition_->set_threshold(threshold_); | ||||||
| } | } | ||||||
| @@ -227,31 +174,6 @@ void GlonassL2CaPcpsAcquisition::set_state(int state) | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| float GlonassL2CaPcpsAcquisition::calculate_threshold(float pfa) |  | ||||||
| { |  | ||||||
|     // Calculate the threshold |  | ||||||
|     unsigned int frequency_bins = 0; |  | ||||||
|     /* |  | ||||||
|     for (int doppler = (int)(-doppler_max_); doppler <= (int)doppler_max_; doppler += doppler_step_) |  | ||||||
|         { |  | ||||||
|             frequency_bins++; |  | ||||||
|         } |  | ||||||
|      */ |  | ||||||
|  |  | ||||||
|     frequency_bins = (2 * doppler_max_ + doppler_step_) / doppler_step_; |  | ||||||
|  |  | ||||||
|     DLOG(INFO) << "Channel " << channel_ << "  Pfa = " << pfa; |  | ||||||
|     unsigned int ncells = vector_length_ * frequency_bins; |  | ||||||
|     double exponent = 1 / static_cast<double>(ncells); |  | ||||||
|     double val = pow(1.0 - pfa, exponent); |  | ||||||
|     auto lambda = static_cast<double>(vector_length_); |  | ||||||
|     boost::math::exponential_distribution<double> mydist(lambda); |  | ||||||
|     auto threshold = static_cast<float>(quantile(mydist, val)); |  | ||||||
|  |  | ||||||
|     return threshold; |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| void GlonassL2CaPcpsAcquisition::connect(gr::top_block_sptr top_block) | void GlonassL2CaPcpsAcquisition::connect(gr::top_block_sptr top_block) | ||||||
| { | { | ||||||
|     if (item_type_ == "gr_complex") |     if (item_type_ == "gr_complex") | ||||||
|   | |||||||
| @@ -33,6 +33,7 @@ | |||||||
| #ifndef GNSS_SDR_GLONASS_L2_CA_PCPS_ACQUISITION_H_ | #ifndef GNSS_SDR_GLONASS_L2_CA_PCPS_ACQUISITION_H_ | ||||||
| #define GNSS_SDR_GLONASS_L2_CA_PCPS_ACQUISITION_H_ | #define GNSS_SDR_GLONASS_L2_CA_PCPS_ACQUISITION_H_ | ||||||
|  |  | ||||||
|  | #include "acq_conf.h" | ||||||
| #include "channel_fsm.h" | #include "channel_fsm.h" | ||||||
| #include "complex_byte_to_float_x2.h" | #include "complex_byte_to_float_x2.h" | ||||||
| #include "gnss_synchro.h" | #include "gnss_synchro.h" | ||||||
| @@ -155,6 +156,7 @@ public: | |||||||
|  |  | ||||||
| private: | private: | ||||||
|     ConfigurationInterface* configuration_; |     ConfigurationInterface* configuration_; | ||||||
|  |     Acq_Conf acq_parameters_; | ||||||
|     pcps_acquisition_sptr acquisition_; |     pcps_acquisition_sptr acquisition_; | ||||||
|     gr::blocks::float_to_complex::sptr float_to_complex_; |     gr::blocks::float_to_complex::sptr float_to_complex_; | ||||||
|     complex_byte_to_float_x2_sptr cbyte_to_float_x2_; |     complex_byte_to_float_x2_sptr cbyte_to_float_x2_; | ||||||
| @@ -162,25 +164,19 @@ private: | |||||||
|     std::string item_type_; |     std::string item_type_; | ||||||
|     unsigned int vector_length_; |     unsigned int vector_length_; | ||||||
|     unsigned int code_length_; |     unsigned int code_length_; | ||||||
|     bool bit_transition_flag_; |  | ||||||
|     bool use_CFAR_algorithm_flag_; |  | ||||||
|     unsigned int channel_; |     unsigned int channel_; | ||||||
|     std::weak_ptr<ChannelFsm> channel_fsm_; |     std::weak_ptr<ChannelFsm> channel_fsm_; | ||||||
|     float threshold_; |     float threshold_; | ||||||
|     unsigned int doppler_max_; |     unsigned int doppler_max_; | ||||||
|     unsigned int doppler_step_; |     unsigned int doppler_step_; | ||||||
|     unsigned int sampled_ms_; |     unsigned int sampled_ms_; | ||||||
|     unsigned int max_dwells_; |  | ||||||
|     int64_t fs_in_; |     int64_t fs_in_; | ||||||
|     bool dump_; |  | ||||||
|     bool blocking_; |  | ||||||
|     std::string dump_filename_; |     std::string dump_filename_; | ||||||
|     std::vector<std::complex<float>> code_; |     std::vector<std::complex<float>> code_; | ||||||
|     Gnss_Synchro* gnss_synchro_; |     Gnss_Synchro* gnss_synchro_; | ||||||
|     std::string role_; |     std::string role_; | ||||||
|     unsigned int in_streams_; |     unsigned int in_streams_; | ||||||
|     unsigned int out_streams_; |     unsigned int out_streams_; | ||||||
|     float calculate_threshold(float pfa); |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif /* GNSS_SDR_GLONASS_L2_CA_PCPS_ACQUISITION_H_ */ | #endif /* GNSS_SDR_GLONASS_L2_CA_PCPS_ACQUISITION_H_ */ | ||||||
|   | |||||||
| @@ -39,7 +39,6 @@ | |||||||
| #include "configuration_interface.h" | #include "configuration_interface.h" | ||||||
| #include "gnss_sdr_flags.h" | #include "gnss_sdr_flags.h" | ||||||
| #include "gps_sdr_signal_processing.h" | #include "gps_sdr_signal_processing.h" | ||||||
| #include <boost/math/distributions/exponential.hpp> |  | ||||||
| #include <glog/logging.h> | #include <glog/logging.h> | ||||||
| #include <gsl/gsl> | #include <gsl/gsl> | ||||||
| #include <algorithm> | #include <algorithm> | ||||||
| @@ -54,88 +53,27 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition( | |||||||
|                                 out_streams_(out_streams) |                                 out_streams_(out_streams) | ||||||
| { | { | ||||||
|     configuration_ = configuration; |     configuration_ = configuration; | ||||||
|     std::string default_item_type = "gr_complex"; |     acq_parameters_.ms_per_code = 1; | ||||||
|     std::string default_dump_filename = "./acquisition.mat"; |     acq_parameters_.SetFromConfiguration(configuration_, role, GPS_L1_CA_CODE_RATE_CPS, GPS_L1_CA_OPT_ACQ_FS_SPS); | ||||||
|  |  | ||||||
|     DLOG(INFO) << "role " << role; |     DLOG(INFO) << "role " << role; | ||||||
|  |  | ||||||
|     item_type_ = configuration_->property(role + ".item_type", default_item_type); |  | ||||||
|     int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); |  | ||||||
|     fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); |  | ||||||
|     acq_parameters_.fs_in = fs_in_; |  | ||||||
|     dump_ = configuration_->property(role + ".dump", false); |  | ||||||
|     acq_parameters_.dump = dump_; |  | ||||||
|     acq_parameters_.dump_channel = configuration_->property(role + ".dump_channel", 0); |  | ||||||
|     blocking_ = configuration_->property(role + ".blocking", true); |  | ||||||
|     acq_parameters_.blocking = blocking_; |  | ||||||
|     doppler_max_ = configuration_->property(role + ".doppler_max", 5000); |  | ||||||
|     if (FLAGS_doppler_max != 0) |     if (FLAGS_doppler_max != 0) | ||||||
|         { |         { | ||||||
|             doppler_max_ = FLAGS_doppler_max; |             acq_parameters_.doppler_max = FLAGS_doppler_max; | ||||||
|         } |  | ||||||
|     acq_parameters_.doppler_max = doppler_max_; |  | ||||||
|     sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 1); |  | ||||||
|     acq_parameters_.sampled_ms = sampled_ms_; |  | ||||||
|     acq_parameters_.ms_per_code = 1; |  | ||||||
|     bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false); |  | ||||||
|     acq_parameters_.bit_transition_flag = bit_transition_flag_; |  | ||||||
|     use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true);  // will be false in future versions |  | ||||||
|     acq_parameters_.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_; |  | ||||||
|     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); |  | ||||||
|     acq_parameters_.use_automatic_resampler = configuration_->property("GNSS-SDR.use_acquisition_resampler", false); |  | ||||||
|     if (acq_parameters_.use_automatic_resampler == true and item_type_ != "gr_complex") |  | ||||||
|         { |  | ||||||
|             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_SPS) |  | ||||||
|                 { |  | ||||||
|                     acq_parameters_.resampler_ratio = floor(static_cast<float>(acq_parameters_.fs_in) / GPS_L1_CA_OPT_ACQ_FS_SPS); |  | ||||||
|                     uint32_t decimation = acq_parameters_.fs_in / GPS_L1_CA_OPT_ACQ_FS_SPS; |  | ||||||
|                     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_CPS / GPS_L1_CA_CODE_LENGTH_CHIPS))); |  | ||||||
|             acq_parameters_.samples_per_ms = static_cast<float>(acq_parameters_.resampled_fs) * 0.001; |  | ||||||
|             acq_parameters_.samples_per_chip = static_cast<unsigned int>(ceil(GPS_L1_CA_CHIP_PERIOD_S * static_cast<float>(acq_parameters_.resampled_fs))); |  | ||||||
|         } |  | ||||||
|     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_CPS / GPS_L1_CA_CODE_LENGTH_CHIPS))); |  | ||||||
|             acq_parameters_.samples_per_ms = static_cast<float>(fs_in_) * 0.001; |  | ||||||
|             acq_parameters_.samples_per_chip = static_cast<unsigned int>(ceil(GPS_L1_CA_CHIP_PERIOD_S * static_cast<float>(acq_parameters_.fs_in))); |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|     acq_parameters_.samples_per_code = acq_parameters_.samples_per_ms * static_cast<float>(GPS_L1_CA_CODE_PERIOD_S * 1000.0); |     doppler_max_ = acq_parameters_.doppler_max; | ||||||
|  |     doppler_step_ = acq_parameters_.doppler_step; | ||||||
|  |     item_type_ = acq_parameters_.item_type; | ||||||
|  |     item_size_ = acq_parameters_.it_size; | ||||||
|  |  | ||||||
|  |     code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(acq_parameters_.resampled_fs) / (GPS_L1_CA_CODE_RATE_CPS / GPS_L1_CA_CODE_LENGTH_CHIPS))); | ||||||
|     vector_length_ = std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2 : 1); |     vector_length_ = std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2 : 1); | ||||||
|     code_ = std::vector<std::complex<float>>(vector_length_); |     code_ = std::vector<std::complex<float>>(vector_length_); | ||||||
|  |  | ||||||
|     if (item_type_ == "cshort") |     sampled_ms_ = acq_parameters_.sampled_ms; | ||||||
|         { |  | ||||||
|             item_size_ = sizeof(lv_16sc_t); |  | ||||||
|         } |  | ||||||
|     else |  | ||||||
|         { |  | ||||||
|             item_size_ = sizeof(gr_complex); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     acq_parameters_.it_size = item_size_; |  | ||||||
|     acq_parameters_.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false); |  | ||||||
|     acquisition_ = pcps_make_acquisition(acq_parameters_); |     acquisition_ = pcps_make_acquisition(acq_parameters_); | ||||||
|     DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; |     DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; | ||||||
|  |  | ||||||
| @@ -147,7 +85,6 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition( | |||||||
|  |  | ||||||
|     channel_ = 0; |     channel_ = 0; | ||||||
|     threshold_ = 0.0; |     threshold_ = 0.0; | ||||||
|     doppler_step_ = 0; |  | ||||||
|     doppler_center_ = 0; |     doppler_center_ = 0; | ||||||
|     gnss_synchro_ = nullptr; |     gnss_synchro_ = nullptr; | ||||||
|  |  | ||||||
| @@ -169,18 +106,7 @@ void GpsL1CaPcpsAcquisition::stop_acquisition() | |||||||
|  |  | ||||||
| void GpsL1CaPcpsAcquisition::set_threshold(float threshold) | void GpsL1CaPcpsAcquisition::set_threshold(float threshold) | ||||||
| { | { | ||||||
|     float pfa = configuration_->property(role_ + ".pfa", 0.0); |     threshold_ = threshold; | ||||||
|  |  | ||||||
|     if (pfa == 0.0) |  | ||||||
|         { |  | ||||||
|             threshold_ = threshold; |  | ||||||
|         } |  | ||||||
|     else |  | ||||||
|         { |  | ||||||
|             threshold_ = calculate_threshold(pfa); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold_; |  | ||||||
|  |  | ||||||
|     acquisition_->set_threshold(threshold_); |     acquisition_->set_threshold(threshold_); | ||||||
| } | } | ||||||
| @@ -240,7 +166,7 @@ void GpsL1CaPcpsAcquisition::set_local_code() | |||||||
|         } |         } | ||||||
|     else |     else | ||||||
|         { |         { | ||||||
|             gps_l1_ca_code_gen_complex_sampled(code, gnss_synchro_->PRN, fs_in_, 0); |             gps_l1_ca_code_gen_complex_sampled(code, gnss_synchro_->PRN, acq_parameters_.fs_in, 0); | ||||||
|         } |         } | ||||||
|     gsl::span<gr_complex> code_span(code_.data(), vector_length_); |     gsl::span<gr_complex> code_span(code_.data(), vector_length_); | ||||||
|     for (unsigned int i = 0; i < sampled_ms_; i++) |     for (unsigned int i = 0; i < sampled_ms_; i++) | ||||||
| @@ -264,26 +190,6 @@ void GpsL1CaPcpsAcquisition::set_state(int state) | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| float GpsL1CaPcpsAcquisition::calculate_threshold(float pfa) |  | ||||||
| { |  | ||||||
|     // Calculate the threshold |  | ||||||
|     unsigned int frequency_bins = 0; |  | ||||||
|     for (int doppler = static_cast<int>(-doppler_max_); doppler <= static_cast<int>(doppler_max_); doppler += doppler_step_) |  | ||||||
|         { |  | ||||||
|             frequency_bins++; |  | ||||||
|         } |  | ||||||
|     DLOG(INFO) << "Channel " << channel_ << "  Pfa = " << pfa; |  | ||||||
|     unsigned int ncells = vector_length_ * frequency_bins; |  | ||||||
|     double exponent = 1 / static_cast<double>(ncells); |  | ||||||
|     double val = pow(1.0 - pfa, exponent); |  | ||||||
|     auto lambda = static_cast<double>(vector_length_); |  | ||||||
|     boost::math::exponential_distribution<double> mydist(lambda); |  | ||||||
|     auto threshold = static_cast<float>(quantile(mydist, val)); |  | ||||||
|  |  | ||||||
|     return threshold; |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| void GpsL1CaPcpsAcquisition::connect(gr::top_block_sptr top_block) | void GpsL1CaPcpsAcquisition::connect(gr::top_block_sptr top_block) | ||||||
| { | { | ||||||
|     if (item_type_ == "gr_complex") |     if (item_type_ == "gr_complex") | ||||||
| @@ -304,7 +210,7 @@ void GpsL1CaPcpsAcquisition::connect(gr::top_block_sptr top_block) | |||||||
|         } |         } | ||||||
|     else |     else | ||||||
|         { |         { | ||||||
|             LOG(WARNING) << item_type_ << " unknown acquisition item type"; |             LOG(WARNING) << item_type_ << " unknown acquisition item type: " << item_type_; | ||||||
|         } |         } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -327,7 +233,7 @@ void GpsL1CaPcpsAcquisition::disconnect(gr::top_block_sptr top_block) | |||||||
|         } |         } | ||||||
|     else |     else | ||||||
|         { |         { | ||||||
|             LOG(WARNING) << item_type_ << " unknown acquisition item type"; |             LOG(WARNING) << item_type_ << " unknown acquisition item type" << item_type_; | ||||||
|         } |         } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -347,7 +253,7 @@ gr::basic_block_sptr GpsL1CaPcpsAcquisition::get_left_block() | |||||||
|             return cbyte_to_float_x2_; |             return cbyte_to_float_x2_; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|     LOG(WARNING) << item_type_ << " unknown acquisition item type"; |     LOG(WARNING) << item_type_ << " unknown acquisition item type" << item_type_; | ||||||
|     return nullptr; |     return nullptr; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -177,8 +177,6 @@ private: | |||||||
|     std::string item_type_; |     std::string item_type_; | ||||||
|     unsigned int vector_length_; |     unsigned int vector_length_; | ||||||
|     unsigned int code_length_; |     unsigned int code_length_; | ||||||
|     bool bit_transition_flag_; |  | ||||||
|     bool use_CFAR_algorithm_flag_; |  | ||||||
|     unsigned int channel_; |     unsigned int channel_; | ||||||
|     std::weak_ptr<ChannelFsm> channel_fsm_; |     std::weak_ptr<ChannelFsm> channel_fsm_; | ||||||
|     float threshold_; |     float threshold_; | ||||||
| @@ -186,17 +184,12 @@ private: | |||||||
|     unsigned int doppler_step_; |     unsigned int doppler_step_; | ||||||
|     int doppler_center_; |     int doppler_center_; | ||||||
|     unsigned int sampled_ms_; |     unsigned int sampled_ms_; | ||||||
|     unsigned int max_dwells_; |  | ||||||
|     int64_t fs_in_; |  | ||||||
|     bool dump_; |  | ||||||
|     bool blocking_; |  | ||||||
|     std::string dump_filename_; |     std::string dump_filename_; | ||||||
|     std::vector<std::complex<float>> code_; |     std::vector<std::complex<float>> code_; | ||||||
|     Gnss_Synchro* gnss_synchro_; |     Gnss_Synchro* gnss_synchro_; | ||||||
|     std::string role_; |     std::string role_; | ||||||
|     unsigned int in_streams_; |     unsigned int in_streams_; | ||||||
|     unsigned int out_streams_; |     unsigned int out_streams_; | ||||||
|     float calculate_threshold(float pfa); |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif /* GNSS_SDR_GPS_L1_CA_PCPS_ACQUISITION_H_ */ | #endif /* GNSS_SDR_GPS_L1_CA_PCPS_ACQUISITION_H_ */ | ||||||
|   | |||||||
| @@ -37,7 +37,6 @@ | |||||||
| #include "configuration_interface.h" | #include "configuration_interface.h" | ||||||
| #include "gnss_sdr_flags.h" | #include "gnss_sdr_flags.h" | ||||||
| #include "gps_l2c_signal.h" | #include "gps_l2c_signal.h" | ||||||
| #include <boost/math/distributions/exponential.hpp> |  | ||||||
| #include <glog/logging.h> | #include <glog/logging.h> | ||||||
| #include <algorithm> | #include <algorithm> | ||||||
|  |  | ||||||
| @@ -51,94 +50,25 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition( | |||||||
|                                 out_streams_(out_streams) |                                 out_streams_(out_streams) | ||||||
| { | { | ||||||
|     configuration_ = configuration; |     configuration_ = configuration; | ||||||
|     std::string default_item_type = "gr_complex"; |     acq_parameters_.ms_per_code = 20; | ||||||
|     std::string default_dump_filename = "./acquisition.mat"; |     acq_parameters_.SetFromConfiguration(configuration_, role, GPS_L2_M_CODE_RATE_CPS, GPS_L2C_OPT_ACQ_FS_SPS); | ||||||
|  |  | ||||||
|     LOG(INFO) << "role " << role; |     DLOG(INFO) << "Role " << role; | ||||||
|  |  | ||||||
|     item_type_ = configuration_->property(role + ".item_type", default_item_type); |  | ||||||
|     int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); |  | ||||||
|     fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); |  | ||||||
|     acq_parameters_.fs_in = fs_in_; |  | ||||||
|     dump_ = configuration_->property(role + ".dump", false); |  | ||||||
|     acq_parameters_.dump = dump_; |  | ||||||
|     acq_parameters_.dump_channel = configuration_->property(role + ".dump_channel", 0); |  | ||||||
|     blocking_ = configuration_->property(role + ".blocking", true); |  | ||||||
|     acq_parameters_.blocking = blocking_; |  | ||||||
|     doppler_max_ = configuration->property(role + ".doppler_max", 5000); |  | ||||||
|     if (FLAGS_doppler_max != 0) |     if (FLAGS_doppler_max != 0) | ||||||
|         { |         { | ||||||
|             doppler_max_ = FLAGS_doppler_max; |             acq_parameters_.doppler_max = FLAGS_doppler_max; | ||||||
|         } |  | ||||||
|     acq_parameters_.doppler_max = doppler_max_; |  | ||||||
|     bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false); |  | ||||||
|     acq_parameters_.bit_transition_flag = bit_transition_flag_; |  | ||||||
|     use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true);  // will be false in future versions |  | ||||||
|     acq_parameters_.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_; |  | ||||||
|     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_.ms_per_code = 20; |  | ||||||
|     acq_parameters_.sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", acq_parameters_.ms_per_code); |  | ||||||
|     if ((acq_parameters_.sampled_ms % acq_parameters_.ms_per_code) != 0) |  | ||||||
|         { |  | ||||||
|             LOG(WARNING) << "Parameter coherent_integration_time_ms should be a multiple of 20. Setting it to 20"; |  | ||||||
|             acq_parameters_.sampled_ms = acq_parameters_.ms_per_code; |  | ||||||
|         } |         } | ||||||
|  |     doppler_max_ = acq_parameters_.doppler_max; | ||||||
|  |     doppler_step_ = acq_parameters_.doppler_step; | ||||||
|  |     item_type_ = acq_parameters_.item_type; | ||||||
|  |     item_size_ = acq_parameters_.it_size; | ||||||
|  |     fs_in_ = acq_parameters_.fs_in; | ||||||
|  |  | ||||||
|     acq_parameters_.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); |     code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(acq_parameters_.resampled_fs) / (GPS_L2_M_CODE_RATE_CPS / GPS_L2_M_CODE_LENGTH_CHIPS))); | ||||||
|     acq_parameters_.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0); |     vector_length_ = std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2 : 1); | ||||||
|     acq_parameters_.make_2_steps = configuration_->property(role + ".make_two_steps", false); |  | ||||||
|     acq_parameters_.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false); |  | ||||||
|     acq_parameters_.use_automatic_resampler = configuration_->property("GNSS-SDR.use_acquisition_resampler", false); |  | ||||||
|     if (acq_parameters_.use_automatic_resampler == true and item_type_ != "gr_complex") |  | ||||||
|         { |  | ||||||
|             LOG(WARNING) << "GPS L2CM 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_L2C_OPT_ACQ_FS_SPS) |  | ||||||
|                 { |  | ||||||
|                     acq_parameters_.resampler_ratio = floor(static_cast<float>(acq_parameters_.fs_in) / GPS_L2C_OPT_ACQ_FS_SPS); |  | ||||||
|                     uint32_t decimation = acq_parameters_.fs_in / GPS_L2C_OPT_ACQ_FS_SPS; |  | ||||||
|                     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_L2_M_CODE_RATE_CPS / GPS_L2_M_CODE_LENGTH_CHIPS))); |  | ||||||
|             acq_parameters_.samples_per_ms = static_cast<float>(acq_parameters_.resampled_fs) * 0.001; |  | ||||||
|             acq_parameters_.samples_per_chip = static_cast<unsigned int>(ceil((1.0 / GPS_L2_M_CODE_RATE_CPS) * static_cast<float>(acq_parameters_.resampled_fs))); |  | ||||||
|         } |  | ||||||
|     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_L2_M_CODE_RATE_CPS / GPS_L2_M_CODE_LENGTH_CHIPS))); |  | ||||||
|             acq_parameters_.samples_per_ms = static_cast<float>(fs_in_) * 0.001; |  | ||||||
|             acq_parameters_.samples_per_chip = static_cast<unsigned int>(ceil((1.0 / GPS_L2_M_CODE_RATE_CPS) * static_cast<float>(acq_parameters_.fs_in))); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     acq_parameters_.samples_per_code = acq_parameters_.samples_per_ms * static_cast<float>(GPS_L2_M_PERIOD_S * 1000.0); |  | ||||||
|     vector_length_ = acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms * (acq_parameters_.bit_transition_flag ? 2 : 1); |  | ||||||
|     code_ = std::vector<std::complex<float>>(vector_length_); |     code_ = std::vector<std::complex<float>>(vector_length_); | ||||||
|  |  | ||||||
|     if (item_type_ == "cshort") |  | ||||||
|         { |  | ||||||
|             item_size_ = sizeof(lv_16sc_t); |  | ||||||
|         } |  | ||||||
|     else |  | ||||||
|         { |  | ||||||
|             item_size_ = sizeof(gr_complex); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     acq_parameters_.it_size = item_size_; |  | ||||||
|     acquisition_ = pcps_make_acquisition(acq_parameters_); |     acquisition_ = pcps_make_acquisition(acq_parameters_); | ||||||
|     DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; |     DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; | ||||||
|  |  | ||||||
| @@ -150,7 +80,6 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition( | |||||||
|  |  | ||||||
|     channel_ = 0; |     channel_ = 0; | ||||||
|     threshold_ = 0.0; |     threshold_ = 0.0; | ||||||
|     doppler_step_ = 0; |  | ||||||
|     doppler_center_ = 0; |     doppler_center_ = 0; | ||||||
|     gnss_synchro_ = nullptr; |     gnss_synchro_ = nullptr; | ||||||
|  |  | ||||||
| @@ -173,22 +102,7 @@ void GpsL2MPcpsAcquisition::stop_acquisition() | |||||||
|  |  | ||||||
| void GpsL2MPcpsAcquisition::set_threshold(float threshold) | void GpsL2MPcpsAcquisition::set_threshold(float threshold) | ||||||
| { | { | ||||||
|     float pfa = configuration_->property(role_ + std::to_string(channel_) + ".pfa", 0.0); |     threshold_ = threshold; | ||||||
|  |  | ||||||
|     if (pfa == 0.0) |  | ||||||
|         { |  | ||||||
|             pfa = configuration_->property(role_ + ".pfa", 0.0); |  | ||||||
|         } |  | ||||||
|     if (pfa == 0.0) |  | ||||||
|         { |  | ||||||
|             threshold_ = threshold; |  | ||||||
|         } |  | ||||||
|     else |  | ||||||
|         { |  | ||||||
|             threshold_ = calculate_threshold(pfa); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold_; |  | ||||||
|  |  | ||||||
|     acquisition_->set_threshold(threshold_); |     acquisition_->set_threshold(threshold_); | ||||||
| } | } | ||||||
| @@ -275,26 +189,6 @@ void GpsL2MPcpsAcquisition::set_state(int state) | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| float GpsL2MPcpsAcquisition::calculate_threshold(float pfa) |  | ||||||
| { |  | ||||||
|     // Calculate the threshold |  | ||||||
|     unsigned int frequency_bins = 0; |  | ||||||
|     for (int doppler = static_cast<int>(-doppler_max_); doppler <= static_cast<int>(doppler_max_); doppler += doppler_step_) |  | ||||||
|         { |  | ||||||
|             frequency_bins++; |  | ||||||
|         } |  | ||||||
|     DLOG(INFO) << "Channel " << channel_ << "  Pfa = " << pfa; |  | ||||||
|     unsigned int ncells = vector_length_ * frequency_bins; |  | ||||||
|     double exponent = 1.0 / static_cast<double>(ncells); |  | ||||||
|     double val = pow(1.0 - pfa, exponent); |  | ||||||
|     auto lambda = static_cast<double>(vector_length_); |  | ||||||
|     boost::math::exponential_distribution<double> mydist(lambda); |  | ||||||
|     auto threshold = static_cast<float>(quantile(mydist, val)); |  | ||||||
|  |  | ||||||
|     return threshold; |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| void GpsL2MPcpsAcquisition::connect(gr::top_block_sptr top_block) | void GpsL2MPcpsAcquisition::connect(gr::top_block_sptr top_block) | ||||||
| { | { | ||||||
|     if (item_type_ == "gr_complex") |     if (item_type_ == "gr_complex") | ||||||
|   | |||||||
| @@ -174,18 +174,13 @@ private: | |||||||
|     std::string item_type_; |     std::string item_type_; | ||||||
|     unsigned int vector_length_; |     unsigned int vector_length_; | ||||||
|     unsigned int code_length_; |     unsigned int code_length_; | ||||||
|     bool bit_transition_flag_; |  | ||||||
|     bool use_CFAR_algorithm_flag_; |  | ||||||
|     unsigned int channel_; |     unsigned int channel_; | ||||||
|     std::weak_ptr<ChannelFsm> channel_fsm_; |     std::weak_ptr<ChannelFsm> channel_fsm_; | ||||||
|     float threshold_; |     float threshold_; | ||||||
|     unsigned int doppler_max_; |     unsigned int doppler_max_; | ||||||
|     unsigned int doppler_step_; |     unsigned int doppler_step_; | ||||||
|     int doppler_center_; |     int doppler_center_; | ||||||
|     unsigned int max_dwells_; |  | ||||||
|     int64_t fs_in_; |     int64_t fs_in_; | ||||||
|     bool dump_; |  | ||||||
|     bool blocking_; |  | ||||||
|     std::string dump_filename_; |     std::string dump_filename_; | ||||||
|     std::vector<std::complex<float>> code_; |     std::vector<std::complex<float>> code_; | ||||||
|     Gnss_Synchro* gnss_synchro_; |     Gnss_Synchro* gnss_synchro_; | ||||||
| @@ -193,7 +188,6 @@ private: | |||||||
|     unsigned int in_streams_; |     unsigned int in_streams_; | ||||||
|     unsigned int out_streams_; |     unsigned int out_streams_; | ||||||
|     unsigned int num_codes_; |     unsigned int num_codes_; | ||||||
|     float calculate_threshold(float pfa); |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif /* GNSS_SDR_GPS_L2_M_PCPS_ACQUISITION_H_ */ | #endif /* GNSS_SDR_GPS_L2_M_PCPS_ACQUISITION_H_ */ | ||||||
|   | |||||||
| @@ -37,7 +37,6 @@ | |||||||
| #include "configuration_interface.h" | #include "configuration_interface.h" | ||||||
| #include "gnss_sdr_flags.h" | #include "gnss_sdr_flags.h" | ||||||
| #include "gps_l5_signal.h" | #include "gps_l5_signal.h" | ||||||
| #include <boost/math/distributions/exponential.hpp> |  | ||||||
| #include <glog/logging.h> | #include <glog/logging.h> | ||||||
| #include <algorithm> | #include <algorithm> | ||||||
|  |  | ||||||
| @@ -51,90 +50,28 @@ GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition( | |||||||
|                                 out_streams_(out_streams) |                                 out_streams_(out_streams) | ||||||
| { | { | ||||||
|     configuration_ = configuration; |     configuration_ = configuration; | ||||||
|     std::string default_item_type = "gr_complex"; |     acq_parameters_.ms_per_code = 1; | ||||||
|     std::string default_dump_filename = "./acquisition.mat"; |     acq_parameters_.SetFromConfiguration(configuration_, role, GPS_L5I_CODE_RATE_CPS, GPS_L5_OPT_ACQ_FS_SPS); | ||||||
|  |  | ||||||
|     LOG(INFO) << "role " << role; |     DLOG(INFO) << "role " << role; | ||||||
|  |  | ||||||
|     item_type_ = configuration_->property(role + ".item_type", default_item_type); |  | ||||||
|  |  | ||||||
|     int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); |  | ||||||
|     fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); |  | ||||||
|     acq_parameters_.fs_in = fs_in_; |  | ||||||
|     dump_ = configuration_->property(role + ".dump", false); |  | ||||||
|     acq_parameters_.dump = dump_; |  | ||||||
|     acq_parameters_.dump_channel = configuration_->property(role + ".dump_channel", 0); |  | ||||||
|     blocking_ = configuration_->property(role + ".blocking", true); |  | ||||||
|     acq_parameters_.blocking = blocking_; |  | ||||||
|     doppler_max_ = configuration->property(role + ".doppler_max", 5000); |  | ||||||
|     if (FLAGS_doppler_max != 0) |     if (FLAGS_doppler_max != 0) | ||||||
|         { |         { | ||||||
|             doppler_max_ = FLAGS_doppler_max; |             acq_parameters_.doppler_max = FLAGS_doppler_max; | ||||||
|         } |  | ||||||
|     acq_parameters_.doppler_max = doppler_max_; |  | ||||||
|     bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false); |  | ||||||
|     acq_parameters_.bit_transition_flag = bit_transition_flag_; |  | ||||||
|     use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true);  // will be false in future versions |  | ||||||
|     acq_parameters_.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_; |  | ||||||
|     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_.sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 1); |  | ||||||
|  |  | ||||||
|     if (item_type_ == "cshort") |  | ||||||
|         { |  | ||||||
|             item_size_ = sizeof(lv_16sc_t); |  | ||||||
|         } |  | ||||||
|     else |  | ||||||
|         { |  | ||||||
|             item_size_ = sizeof(gr_complex); |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|     acq_parameters_.ms_per_code = 1; |     doppler_max_ = acq_parameters_.doppler_max; | ||||||
|     acq_parameters_.it_size = item_size_; |     doppler_step_ = acq_parameters_.doppler_step; | ||||||
|     num_codes_ = acq_parameters_.sampled_ms; |     item_type_ = acq_parameters_.item_type; | ||||||
|     acq_parameters_.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); |     item_size_ = acq_parameters_.it_size; | ||||||
|     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_.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false); |  | ||||||
|     acq_parameters_.use_automatic_resampler = configuration_->property("GNSS-SDR.use_acquisition_resampler", false); |  | ||||||
|     if (acq_parameters_.use_automatic_resampler == true and item_type_ != "gr_complex") |  | ||||||
|         { |  | ||||||
|             LOG(WARNING) << "GPS L5 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_L5_OPT_ACQ_FS_SPS) |  | ||||||
|                 { |  | ||||||
|                     acq_parameters_.resampler_ratio = floor(static_cast<float>(acq_parameters_.fs_in) / GPS_L5_OPT_ACQ_FS_SPS); |  | ||||||
|                     uint32_t decimation = acq_parameters_.fs_in / GPS_L5_OPT_ACQ_FS_SPS; |  | ||||||
|                     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_L5I_CODE_RATE_CPS / GPS_L5I_CODE_LENGTH_CHIPS))); | ||||||
|             code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(acq_parameters_.resampled_fs) / (GPS_L5I_CODE_RATE_CPS / GPS_L5I_CODE_LENGTH_CHIPS))); |  | ||||||
|             acq_parameters_.samples_per_ms = static_cast<float>(acq_parameters_.resampled_fs) * 0.001; |  | ||||||
|             acq_parameters_.samples_per_chip = static_cast<unsigned int>(ceil((1.0 / GPS_L5I_CODE_RATE_CPS) * static_cast<float>(acq_parameters_.resampled_fs))); |  | ||||||
|         } |  | ||||||
|     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_L5I_CODE_RATE_CPS / GPS_L5I_CODE_LENGTH_CHIPS))); |  | ||||||
|             acq_parameters_.samples_per_ms = static_cast<float>(fs_in_) * 0.001; |  | ||||||
|             acq_parameters_.samples_per_chip = static_cast<unsigned int>(ceil((1.0 / GPS_L5I_CODE_RATE_CPS) * static_cast<float>(acq_parameters_.fs_in))); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     acq_parameters_.samples_per_code = acq_parameters_.samples_per_ms * static_cast<float>(GPS_L5I_PERIOD_S * 1000.0); |  | ||||||
|     vector_length_ = std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2 : 1); |     vector_length_ = std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2 : 1); | ||||||
|     code_ = std::vector<std::complex<float>>(vector_length_); |     code_ = std::vector<std::complex<float>>(vector_length_); | ||||||
|  |     fs_in_ = acq_parameters_.fs_in; | ||||||
|  |  | ||||||
|  |     num_codes_ = acq_parameters_.sampled_ms; | ||||||
|  |  | ||||||
|     acquisition_ = pcps_make_acquisition(acq_parameters_); |     acquisition_ = pcps_make_acquisition(acq_parameters_); | ||||||
|     DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; |     DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; | ||||||
|  |  | ||||||
| @@ -146,7 +83,6 @@ GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition( | |||||||
|  |  | ||||||
|     channel_ = 0; |     channel_ = 0; | ||||||
|     threshold_ = 0.0; |     threshold_ = 0.0; | ||||||
|     doppler_step_ = 0; |  | ||||||
|     doppler_center_ = 0; |     doppler_center_ = 0; | ||||||
|     gnss_synchro_ = nullptr; |     gnss_synchro_ = nullptr; | ||||||
|  |  | ||||||
| @@ -168,22 +104,7 @@ void GpsL5iPcpsAcquisition::stop_acquisition() | |||||||
|  |  | ||||||
| void GpsL5iPcpsAcquisition::set_threshold(float threshold) | void GpsL5iPcpsAcquisition::set_threshold(float threshold) | ||||||
| { | { | ||||||
|     float pfa = configuration_->property(role_ + std::to_string(channel_) + ".pfa", 0.0); |     threshold_ = threshold; | ||||||
|  |  | ||||||
|     if (pfa == 0.0) |  | ||||||
|         { |  | ||||||
|             pfa = configuration_->property(role_ + ".pfa", 0.0); |  | ||||||
|         } |  | ||||||
|     if (pfa == 0.0) |  | ||||||
|         { |  | ||||||
|             threshold_ = threshold; |  | ||||||
|         } |  | ||||||
|     else |  | ||||||
|         { |  | ||||||
|             threshold_ = calculate_threshold(pfa); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold_; |  | ||||||
|  |  | ||||||
|     acquisition_->set_threshold(threshold_); |     acquisition_->set_threshold(threshold_); | ||||||
| } | } | ||||||
| @@ -270,26 +191,6 @@ void GpsL5iPcpsAcquisition::set_state(int state) | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| float GpsL5iPcpsAcquisition::calculate_threshold(float pfa) |  | ||||||
| { |  | ||||||
|     // Calculate the threshold |  | ||||||
|     unsigned int frequency_bins = 0; |  | ||||||
|     for (int doppler = static_cast<int>(-doppler_max_); doppler <= static_cast<int>(doppler_max_); doppler += doppler_step_) |  | ||||||
|         { |  | ||||||
|             frequency_bins++; |  | ||||||
|         } |  | ||||||
|     DLOG(INFO) << "Channel " << channel_ << "  Pfa = " << pfa; |  | ||||||
|     unsigned int ncells = vector_length_ * frequency_bins; |  | ||||||
|     double exponent = 1.0 / static_cast<double>(ncells); |  | ||||||
|     double val = pow(1.0 - pfa, exponent); |  | ||||||
|     auto lambda = static_cast<double>(vector_length_); |  | ||||||
|     boost::math::exponential_distribution<double> mydist(lambda); |  | ||||||
|     auto threshold = static_cast<float>(quantile(mydist, val)); |  | ||||||
|  |  | ||||||
|     return threshold; |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| void GpsL5iPcpsAcquisition::connect(gr::top_block_sptr top_block) | void GpsL5iPcpsAcquisition::connect(gr::top_block_sptr top_block) | ||||||
| { | { | ||||||
|     if (item_type_ == "gr_complex") |     if (item_type_ == "gr_complex") | ||||||
| @@ -310,7 +211,7 @@ void GpsL5iPcpsAcquisition::connect(gr::top_block_sptr top_block) | |||||||
|         } |         } | ||||||
|     else |     else | ||||||
|         { |         { | ||||||
|             LOG(WARNING) << item_type_ << " unknown acquisition item type"; |             LOG(WARNING) << item_type_ << " unknown acquisition item type: " << item_type_; | ||||||
|         } |         } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -333,7 +234,7 @@ void GpsL5iPcpsAcquisition::disconnect(gr::top_block_sptr top_block) | |||||||
|         } |         } | ||||||
|     else |     else | ||||||
|         { |         { | ||||||
|             LOG(WARNING) << item_type_ << " unknown acquisition item type"; |             LOG(WARNING) << item_type_ << " unknown acquisition item type" << item_type_; | ||||||
|         } |         } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -353,7 +254,7 @@ gr::basic_block_sptr GpsL5iPcpsAcquisition::get_left_block() | |||||||
|             return cbyte_to_float_x2_; |             return cbyte_to_float_x2_; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|     LOG(WARNING) << item_type_ << " unknown acquisition item type"; |     LOG(WARNING) << item_type_ << " unknown acquisition item type" << item_type_; | ||||||
|     return nullptr; |     return nullptr; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -174,18 +174,13 @@ private: | |||||||
|     std::string item_type_; |     std::string item_type_; | ||||||
|     unsigned int vector_length_; |     unsigned int vector_length_; | ||||||
|     unsigned int code_length_; |     unsigned int code_length_; | ||||||
|     bool bit_transition_flag_; |  | ||||||
|     bool use_CFAR_algorithm_flag_; |  | ||||||
|     unsigned int channel_; |     unsigned int channel_; | ||||||
|     std::weak_ptr<ChannelFsm> channel_fsm_; |     std::weak_ptr<ChannelFsm> channel_fsm_; | ||||||
|     float threshold_; |     float threshold_; | ||||||
|     unsigned int doppler_max_; |     unsigned int doppler_max_; | ||||||
|     unsigned int doppler_step_; |     unsigned int doppler_step_; | ||||||
|     int doppler_center_; |     int doppler_center_; | ||||||
|     unsigned int max_dwells_; |  | ||||||
|     int64_t fs_in_; |     int64_t fs_in_; | ||||||
|     bool dump_; |  | ||||||
|     bool blocking_; |  | ||||||
|     std::string dump_filename_; |     std::string dump_filename_; | ||||||
|     std::vector<std::complex<float>> code_; |     std::vector<std::complex<float>> code_; | ||||||
|     Gnss_Synchro* gnss_synchro_; |     Gnss_Synchro* gnss_synchro_; | ||||||
| @@ -193,7 +188,6 @@ private: | |||||||
|     unsigned int num_codes_; |     unsigned int num_codes_; | ||||||
|     unsigned int in_streams_; |     unsigned int in_streams_; | ||||||
|     unsigned int out_streams_; |     unsigned int out_streams_; | ||||||
|     float calculate_threshold(float pfa); |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif /* GNSS_SDR_GPS_L5I_PCPS_ACQUISITION_H_ */ | #endif /* GNSS_SDR_GPS_L5I_PCPS_ACQUISITION_H_ */ | ||||||
|   | |||||||
| @@ -48,6 +48,7 @@ | |||||||
| #else | #else | ||||||
| #include <boost/filesystem/path.hpp> | #include <boost/filesystem/path.hpp> | ||||||
| #endif | #endif | ||||||
|  | #include <boost/math/special_functions/gamma.hpp> | ||||||
| #include <gnuradio/io_signature.h> | #include <gnuradio/io_signature.h> | ||||||
| #include <matio.h> | #include <matio.h> | ||||||
| #include <pmt/pmt.h>        // for from_long | #include <pmt/pmt.h>        // for from_long | ||||||
| @@ -105,7 +106,7 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu | |||||||
|     d_input_power = 0.0; |     d_input_power = 0.0; | ||||||
|     d_num_doppler_bins = 0U; |     d_num_doppler_bins = 0U; | ||||||
|     d_threshold = 0.0; |     d_threshold = 0.0; | ||||||
|     d_doppler_step = 0U; |     d_doppler_step = acq_parameters.doppler_step; | ||||||
|     d_doppler_center = 0U; |     d_doppler_center = 0U; | ||||||
|     d_doppler_center_step_two = 0.0; |     d_doppler_center_step_two = 0.0; | ||||||
|     d_test_statistics = 0.0; |     d_test_statistics = 0.0; | ||||||
| @@ -129,11 +130,11 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu | |||||||
|     // |     // | ||||||
|     // We can avoid this by doing linear correlation, effectively doubling the |     // We can avoid this by doing linear correlation, effectively doubling the | ||||||
|     // size of the input buffer and padding the code with zeros. |     // size of the input buffer and padding the code with zeros. | ||||||
|     if (acq_parameters.bit_transition_flag) |     //if (acq_parameters.bit_transition_flag) | ||||||
|         { |     //{ | ||||||
|             d_fft_size = d_consumed_samples * 2; |     //d_fft_size = d_consumed_samples * 2; | ||||||
|             acq_parameters.max_dwells = 1;  // Activation of acq_parameters.bit_transition_flag invalidates the value of acq_parameters.max_dwells |     //acq_parameters.max_dwells = 1;  // Activation of acq_parameters.bit_transition_flag invalidates the value of acq_parameters.max_dwells | ||||||
|         } |     //} | ||||||
|  |  | ||||||
|     d_tmp_buffer = volk_gnsssdr::vector<float>(d_fft_size); |     d_tmp_buffer = volk_gnsssdr::vector<float>(d_fft_size); | ||||||
|     d_fft_codes = volk_gnsssdr::vector<std::complex<float>>(d_fft_size); |     d_fft_codes = volk_gnsssdr::vector<std::complex<float>>(d_fft_size); | ||||||
| @@ -160,14 +161,14 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu | |||||||
|     d_samplesPerChip = acq_parameters.samples_per_chip; |     d_samplesPerChip = acq_parameters.samples_per_chip; | ||||||
|     d_buffer_count = 0U; |     d_buffer_count = 0U; | ||||||
|     // todo: CFAR statistic not available for non-coherent integration |     // todo: CFAR statistic not available for non-coherent integration | ||||||
|     if (acq_parameters.max_dwells == 1) |     //if (acq_parameters.max_dwells == 1) | ||||||
|         { |     //{ | ||||||
|             d_use_CFAR_algorithm_flag = acq_parameters.use_CFAR_algorithm_flag; |     d_use_CFAR_algorithm_flag = acq_parameters.use_CFAR_algorithm_flag; | ||||||
|         } |     //} | ||||||
|     else |     //else | ||||||
|         { |     //{ | ||||||
|             d_use_CFAR_algorithm_flag = false; |     //d_use_CFAR_algorithm_flag = false; | ||||||
|         } |     //} | ||||||
|     d_dump_number = 0LL; |     d_dump_number = 0LL; | ||||||
|     d_dump_channel = acq_parameters.dump_channel; |     d_dump_channel = acq_parameters.dump_channel; | ||||||
|     d_dump = acq_parameters.dump; |     d_dump = acq_parameters.dump; | ||||||
| @@ -364,7 +365,6 @@ void pcps_acquisition::set_state(int32_t state) | |||||||
|             d_gnss_synchro->Acq_samplestamp_samples = 0ULL; |             d_gnss_synchro->Acq_samplestamp_samples = 0ULL; | ||||||
|             d_gnss_synchro->Acq_doppler_step = 0U; |             d_gnss_synchro->Acq_doppler_step = 0U; | ||||||
|             d_mag = 0.0; |             d_mag = 0.0; | ||||||
|             d_input_power = 0.0; |  | ||||||
|             d_test_statistics = 0.0; |             d_test_statistics = 0.0; | ||||||
|             d_active = true; |             d_active = true; | ||||||
|         } |         } | ||||||
| @@ -382,16 +382,16 @@ void pcps_acquisition::send_positive_acquisition() | |||||||
| { | { | ||||||
|     // Declare positive acquisition using a message port |     // Declare positive acquisition using a message port | ||||||
|     // 0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL |     // 0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL | ||||||
|     DLOG(INFO) << "positive acquisition" |     LOG(INFO) << "positive acquisition" | ||||||
|                << ", satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN |               << ", satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN | ||||||
|                << ", sample_stamp " << d_sample_counter |               << ", sample_stamp " << d_sample_counter | ||||||
|                << ", test statistics value " << d_test_statistics |               << ", test statistics value " << d_test_statistics | ||||||
|                << ", test statistics threshold " << d_threshold |               << ", test statistics threshold " << d_threshold | ||||||
|                << ", code phase " << d_gnss_synchro->Acq_delay_samples |               << ", code phase " << d_gnss_synchro->Acq_delay_samples | ||||||
|                << ", doppler " << d_gnss_synchro->Acq_doppler_hz |               << ", doppler " << d_gnss_synchro->Acq_doppler_hz | ||||||
|                << ", magnitude " << d_mag |               << ", magnitude " << d_mag | ||||||
|                << ", input signal power " << d_input_power |               << ", input signal power " << d_input_power | ||||||
|                << ", Assist doppler_center " << d_doppler_center; |               << ", Assist doppler_center " << d_doppler_center; | ||||||
|     d_positive_acq = 1; |     d_positive_acq = 1; | ||||||
|  |  | ||||||
|     if (!d_channel_fsm.expired()) |     if (!d_channel_fsm.expired()) | ||||||
| @@ -410,15 +410,15 @@ void pcps_acquisition::send_negative_acquisition() | |||||||
| { | { | ||||||
|     // Declare negative acquisition using a message port |     // Declare negative acquisition using a message port | ||||||
|     // 0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL |     // 0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL | ||||||
|     DLOG(INFO) << "negative acquisition" |     LOG(INFO) << "negative acquisition" | ||||||
|                << ", satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN |               << ", satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN | ||||||
|                << ", sample_stamp " << d_sample_counter |               << ", sample_stamp " << d_sample_counter | ||||||
|                << ", test statistics value " << d_test_statistics |               << ", test statistics value " << d_test_statistics | ||||||
|                << ", test statistics threshold " << d_threshold |               << ", test statistics threshold " << d_threshold | ||||||
|                << ", code phase " << d_gnss_synchro->Acq_delay_samples |               << ", code phase " << d_gnss_synchro->Acq_delay_samples | ||||||
|                << ", doppler " << d_gnss_synchro->Acq_doppler_hz |               << ", doppler " << d_gnss_synchro->Acq_doppler_hz | ||||||
|                << ", magnitude " << d_mag |               << ", magnitude " << d_mag | ||||||
|                << ", input signal power " << d_input_power; |               << ", input signal power " << d_input_power; | ||||||
|     d_positive_acq = 0; |     d_positive_acq = 0; | ||||||
|     this->message_port_pub(pmt::mp("events"), pmt::from_long(2)); |     this->message_port_pub(pmt::mp("events"), pmt::from_long(2)); | ||||||
| } | } | ||||||
| @@ -527,18 +527,18 @@ void pcps_acquisition::dump_results(int32_t effective_fft_size) | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| float pcps_acquisition::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) | float pcps_acquisition::max_to_input_power_statistic(uint32_t& indext, int32_t& doppler, uint32_t num_doppler_bins, int32_t doppler_max, int32_t doppler_step) | ||||||
| { | { | ||||||
|     float grid_maximum = 0.0; |     float grid_maximum = 0.0; | ||||||
|     uint32_t index_doppler = 0U; |     uint32_t index_doppler = 0U; | ||||||
|     uint32_t tmp_intex_t = 0U; |     uint32_t tmp_intex_t = 0U; | ||||||
|     uint32_t index_time = 0U; |     uint32_t index_time = 0U; | ||||||
|     float fft_normalization_factor = static_cast<float>(d_fft_size) * static_cast<float>(d_fft_size); |     int32_t effective_fft_size = (acq_parameters.bit_transition_flag ? d_fft_size / 2 : d_fft_size); | ||||||
|  |  | ||||||
|     // Find the correlation peak and the carrier frequency |     // Find the correlation peak and the carrier frequency | ||||||
|     for (uint32_t i = 0; i < num_doppler_bins; i++) |     for (uint32_t i = 0; i < num_doppler_bins; i++) | ||||||
|         { |         { | ||||||
|             volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_magnitude_grid[i].data(), d_fft_size); |             volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_magnitude_grid[i].data(), effective_fft_size); | ||||||
|             if (d_magnitude_grid[i][tmp_intex_t] > grid_maximum) |             if (d_magnitude_grid[i][tmp_intex_t] > grid_maximum) | ||||||
|                 { |                 { | ||||||
|                     grid_maximum = d_magnitude_grid[i][tmp_intex_t]; |                     grid_maximum = d_magnitude_grid[i][tmp_intex_t]; | ||||||
| @@ -549,6 +549,8 @@ float pcps_acquisition::max_to_input_power_statistic(uint32_t& indext, int32_t& | |||||||
|     indext = index_time; |     indext = index_time; | ||||||
|     if (!d_step_two) |     if (!d_step_two) | ||||||
|         { |         { | ||||||
|  |             int index_opp = (index_doppler + d_num_doppler_bins / 2) % d_num_doppler_bins; | ||||||
|  |             d_input_power = std::accumulate(d_magnitude_grid[index_opp].data(), d_magnitude_grid[index_opp].data() + effective_fft_size, 0.0) / effective_fft_size / 2.0 / d_num_noncoherent_integrations_counter; | ||||||
|             doppler = -static_cast<int32_t>(doppler_max) + d_doppler_center + doppler_step * static_cast<int32_t>(index_doppler); |             doppler = -static_cast<int32_t>(doppler_max) + d_doppler_center + doppler_step * static_cast<int32_t>(index_doppler); | ||||||
|         } |         } | ||||||
|     else |     else | ||||||
| @@ -556,8 +558,7 @@ float pcps_acquisition::max_to_input_power_statistic(uint32_t& indext, int32_t& | |||||||
|             doppler = static_cast<int32_t>(d_doppler_center_step_two + (static_cast<float>(index_doppler) - static_cast<float>(floor(d_num_doppler_bins_step2 / 2.0))) * acq_parameters.doppler_step2); |             doppler = static_cast<int32_t>(d_doppler_center_step_two + (static_cast<float>(index_doppler) - static_cast<float>(floor(d_num_doppler_bins_step2 / 2.0))) * acq_parameters.doppler_step2); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|     float magt = grid_maximum / (fft_normalization_factor * fft_normalization_factor); |     return grid_maximum / d_input_power; | ||||||
|     return magt / input_power; |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -652,7 +653,6 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count) | |||||||
|         } |         } | ||||||
|     const gr_complex* in = d_input_signal.data();  // Get the input samples pointer |     const gr_complex* in = d_input_signal.data();  // Get the input samples pointer | ||||||
|  |  | ||||||
|     d_input_power = 0.0; |  | ||||||
|     d_mag = 0.0; |     d_mag = 0.0; | ||||||
|     d_num_noncoherent_integrations_counter++; |     d_num_noncoherent_integrations_counter++; | ||||||
|  |  | ||||||
| @@ -665,14 +665,6 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count) | |||||||
|  |  | ||||||
|     lk.unlock(); |     lk.unlock(); | ||||||
|  |  | ||||||
|     if (d_use_CFAR_algorithm_flag or acq_parameters.bit_transition_flag) |  | ||||||
|         { |  | ||||||
|             // Compute the input signal power estimation |  | ||||||
|             volk_32fc_magnitude_squared_32f(d_tmp_buffer.data(), in, d_fft_size); |  | ||||||
|             volk_32f_accumulator_s32f(&d_input_power, d_tmp_buffer.data(), d_fft_size); |  | ||||||
|             d_input_power /= static_cast<float>(d_fft_size); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     // Doppler frequency grid loop |     // Doppler frequency grid loop | ||||||
|     if (!d_step_two) |     if (!d_step_two) | ||||||
|         { |         { | ||||||
| @@ -712,7 +704,7 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count) | |||||||
|             // Compute the test statistic |             // Compute the test statistic | ||||||
|             if (d_use_CFAR_algorithm_flag) |             if (d_use_CFAR_algorithm_flag) | ||||||
|                 { |                 { | ||||||
|                     d_test_statistics = max_to_input_power_statistic(indext, doppler, d_input_power, d_num_doppler_bins, acq_parameters.doppler_max, d_doppler_step); |                     d_test_statistics = max_to_input_power_statistic(indext, doppler, d_num_doppler_bins, acq_parameters.doppler_max, d_doppler_step); | ||||||
|                 } |                 } | ||||||
|             else |             else | ||||||
|                 { |                 { | ||||||
| @@ -769,7 +761,7 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count) | |||||||
|             // Compute the test statistic |             // Compute the test statistic | ||||||
|             if (d_use_CFAR_algorithm_flag) |             if (d_use_CFAR_algorithm_flag) | ||||||
|                 { |                 { | ||||||
|                     d_test_statistics = max_to_input_power_statistic(indext, doppler, d_input_power, 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_test_statistics = max_to_input_power_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); | ||||||
|                 } |                 } | ||||||
|             else |             else | ||||||
|                 { |                 { | ||||||
| @@ -815,6 +807,7 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count) | |||||||
|                                     d_positive_acq = 0; |                                     d_positive_acq = 0; | ||||||
|                                     d_state = 0; |                                     d_state = 0; | ||||||
|                                 } |                                 } | ||||||
|  |                             calculate_threshold(); | ||||||
|                         } |                         } | ||||||
|                     else |                     else | ||||||
|                         { |                         { | ||||||
| @@ -836,7 +829,12 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count) | |||||||
|                         } |                         } | ||||||
|                     d_state = 0; |                     d_state = 0; | ||||||
|                     d_active = false; |                     d_active = false; | ||||||
|  |                     bool was_step_two = d_step_two; | ||||||
|                     d_step_two = false; |                     d_step_two = false; | ||||||
|  |                     if (was_step_two) | ||||||
|  |                         { | ||||||
|  |                             calculate_threshold(); | ||||||
|  |                         } | ||||||
|                 } |                 } | ||||||
|         } |         } | ||||||
|     else |     else | ||||||
| @@ -858,6 +856,7 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count) | |||||||
|                                     d_num_noncoherent_integrations_counter = 0U; |                                     d_num_noncoherent_integrations_counter = 0U; | ||||||
|                                     d_state = 0; |                                     d_state = 0; | ||||||
|                                 } |                                 } | ||||||
|  |                             calculate_threshold(); | ||||||
|                         } |                         } | ||||||
|                     else |                     else | ||||||
|                         { |                         { | ||||||
| @@ -868,7 +867,12 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count) | |||||||
|             else |             else | ||||||
|                 { |                 { | ||||||
|                     d_state = 0;  // Negative acquisition |                     d_state = 0;  // Negative acquisition | ||||||
|  |                     bool was_step_two = d_step_two; | ||||||
|                     d_step_two = false; |                     d_step_two = false; | ||||||
|  |                     if (was_step_two) | ||||||
|  |                         { | ||||||
|  |                             calculate_threshold(); | ||||||
|  |                         } | ||||||
|                     send_negative_acquisition(); |                     send_negative_acquisition(); | ||||||
|                 } |                 } | ||||||
|         } |         } | ||||||
| @@ -899,10 +903,29 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count) | |||||||
| bool pcps_acquisition::start() | bool pcps_acquisition::start() | ||||||
| { | { | ||||||
|     d_sample_counter = 0ULL; |     d_sample_counter = 0ULL; | ||||||
|  |     calculate_threshold(); | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void pcps_acquisition::calculate_threshold() | ||||||
|  | { | ||||||
|  |     float pfa = (d_step_two ? acq_parameters.pfa2 : acq_parameters.pfa); | ||||||
|  |  | ||||||
|  |     if (pfa <= 0.0) | ||||||
|  |         { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     int effective_fft_size = (acq_parameters.bit_transition_flag ? (d_fft_size / 2) : d_fft_size); | ||||||
|  |     int num_doppler_bins = (d_step_two ? d_num_doppler_bins_step2 : d_num_doppler_bins); | ||||||
|  |  | ||||||
|  |     int num_bins = effective_fft_size * num_doppler_bins; | ||||||
|  |  | ||||||
|  |     d_threshold = 2.0 * boost::math::gamma_p_inv(2.0 * acq_parameters.max_dwells, std::pow(1.0 - pfa, 1.0 / static_cast<float>(num_bins))); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| int pcps_acquisition::general_work(int noutput_items __attribute__((unused)), | int pcps_acquisition::general_work(int noutput_items __attribute__((unused)), | ||||||
|     gr_vector_int& ninput_items, |     gr_vector_int& ninput_items, | ||||||
|     gr_vector_const_void_star& input_items, |     gr_vector_const_void_star& input_items, | ||||||
| @@ -946,8 +969,6 @@ int pcps_acquisition::general_work(int noutput_items __attribute__((unused)), | |||||||
|                 d_gnss_synchro->Acq_samplestamp_samples = 0ULL; |                 d_gnss_synchro->Acq_samplestamp_samples = 0ULL; | ||||||
|                 d_gnss_synchro->Acq_doppler_step = 0U; |                 d_gnss_synchro->Acq_doppler_step = 0U; | ||||||
|                 d_mag = 0.0; |                 d_mag = 0.0; | ||||||
|                 d_input_power = 0.0; |  | ||||||
|                 d_test_statistics = 0.0; |  | ||||||
|                 d_state = 1; |                 d_state = 1; | ||||||
|                 d_buffer_count = 0U; |                 d_buffer_count = 0U; | ||||||
|                 if (!acq_parameters.blocking_on_standby) |                 if (!acq_parameters.blocking_on_standby) | ||||||
|   | |||||||
| @@ -267,8 +267,9 @@ private: | |||||||
|     void dump_results(int32_t effective_fft_size); |     void dump_results(int32_t effective_fft_size); | ||||||
|     bool is_fdma(); |     bool is_fdma(); | ||||||
|     bool start(); |     bool start(); | ||||||
|  |     void calculate_threshold(void); | ||||||
|     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 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); |     float max_to_input_power_statistic(uint32_t& indext, int32_t& doppler, uint32_t num_doppler_bins, int32_t doppler_max, int32_t doppler_step); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif /* GNSS_SDR_PCPS_ACQUISITION_H_*/ | #endif /* GNSS_SDR_PCPS_ACQUISITION_H_*/ | ||||||
|   | |||||||
| @@ -30,31 +30,135 @@ | |||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #include "acq_conf.h" | #include "acq_conf.h" | ||||||
|  | #include "item_type_helpers.h" | ||||||
|  | #include <glog/logging.h> | ||||||
|  | #include <gnuradio/gr_complex.h> | ||||||
|  |  | ||||||
| Acq_Conf::Acq_Conf() | Acq_Conf::Acq_Conf() | ||||||
| { | { | ||||||
|     /* PCPS acquisition configuration */ |     /* PCPS acquisition configuration */ | ||||||
|     sampled_ms = 0U; |     sampled_ms = 1U; | ||||||
|     ms_per_code = 0U; |     ms_per_code = 1U; | ||||||
|     max_dwells = 0U; |     max_dwells = 1U; | ||||||
|     samples_per_chip = 0U; |     samples_per_chip = 2U; | ||||||
|     doppler_max = 0U; |     chips_per_second = 1023000; | ||||||
|     num_doppler_bins_step2 = 0U; |     doppler_max = 5000; | ||||||
|     doppler_step2 = 0.0; |     doppler_min = -5000; | ||||||
|     fs_in = 0LL; |     doppler_step = 250.0; | ||||||
|  |     num_doppler_bins_step2 = 4U; | ||||||
|  |     doppler_step2 = 125.0; | ||||||
|  |     pfa = 0.0; | ||||||
|  |     pfa2 = 0.0; | ||||||
|  |     fs_in = 4000000; | ||||||
|     samples_per_ms = 0.0; |     samples_per_ms = 0.0; | ||||||
|     samples_per_code = 0.0; |     samples_per_code = 0.0; | ||||||
|     bit_transition_flag = false; |     bit_transition_flag = false; | ||||||
|     use_CFAR_algorithm_flag = false; |     use_CFAR_algorithm_flag = true; | ||||||
|     dump = false; |     dump = false; | ||||||
|     blocking = false; |     blocking = true; | ||||||
|     make_2_steps = false; |     make_2_steps = false; | ||||||
|     dump_filename = ""; |     dump_filename = ""; | ||||||
|     dump_channel = 0U; |     dump_channel = 0U; | ||||||
|     it_size = sizeof(char); |     it_size = sizeof(gr_complex); | ||||||
|  |     item_type = "gr_complex"; | ||||||
|     blocking_on_standby = false; |     blocking_on_standby = false; | ||||||
|     use_automatic_resampler = false; |     use_automatic_resampler = false; | ||||||
|     resampler_ratio = 1.0; |     resampler_ratio = 1.0; | ||||||
|     resampled_fs = 0LL; |     resampled_fs = 0LL; | ||||||
|     resampler_latency_samples = 0U; |     resampler_latency_samples = 0U; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void Acq_Conf::SetFromConfiguration(ConfigurationInterface *configuration, | ||||||
|  |     const std::string &role, double chip_rate, double opt_freq) | ||||||
|  | { | ||||||
|  |     item_type = configuration->property(role + ".item_type", item_type); | ||||||
|  |     if (!item_type_valid(item_type)) | ||||||
|  |         { | ||||||
|  |             throw std::invalid_argument("Unknown item type: " + item_type); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     chips_per_second = chip_rate; | ||||||
|  |  | ||||||
|  |     int64_t fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", fs_in); | ||||||
|  |     fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); | ||||||
|  |     doppler_max = configuration->property(role + ".doppler_max", doppler_max); | ||||||
|  |     sampled_ms = configuration->property(role + ".coherent_integration_time_ms", sampled_ms); | ||||||
|  |     bit_transition_flag = configuration->property(role + ".bit_transition_flag", bit_transition_flag); | ||||||
|  |     max_dwells = configuration->property(role + ".max_dwells", max_dwells); | ||||||
|  |     dump = configuration->property(role + ".dump", dump); | ||||||
|  |     dump_channel = configuration->property(role + ".dump_channel", dump_channel); | ||||||
|  |     blocking = configuration->property(role + ".blocking", blocking); | ||||||
|  |     dump_filename = configuration->property(role + ".dump_filename", dump_filename); | ||||||
|  |  | ||||||
|  |     use_automatic_resampler = configuration->property("GNSS-SDR.use_acquisition_resampler", use_automatic_resampler); | ||||||
|  |  | ||||||
|  |     if ((sampled_ms % ms_per_code) != 0) | ||||||
|  |         { | ||||||
|  |             LOG(WARNING) << "Parameter coherent_integration_time_ms should be a multiple of " | ||||||
|  |                          << ms_per_code << ". Setting it to " << ms_per_code; | ||||||
|  |             sampled_ms = ms_per_code; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     resampled_fs = fs_in; | ||||||
|  |  | ||||||
|  |     if (use_automatic_resampler) | ||||||
|  |         { | ||||||
|  |             ConfigureAutomaticResampler(opt_freq); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     it_size = item_type_size(item_type); | ||||||
|  |     num_doppler_bins_step2 = configuration->property(role + ".second_nbins", num_doppler_bins_step2); | ||||||
|  |     doppler_step2 = configuration->property(role + ".second_doppler_step", doppler_step2); | ||||||
|  |     doppler_step = configuration->property(role + ".doppler_step", doppler_step); | ||||||
|  |     pfa = configuration->property(role + ".pfa", pfa); | ||||||
|  |     if ((pfa < 0.0) or (pfa > 1.0)) | ||||||
|  |         { | ||||||
|  |             LOG(WARNING) << "Parameter pfa should between 0.0 and 1.0. Setting it to 0.0"; | ||||||
|  |             pfa = 0.0; | ||||||
|  |         } | ||||||
|  |     pfa2 = configuration->property(role + ".pfa_second_step", pfa2); | ||||||
|  |     if ((pfa2 <= 0.0) or (pfa2 > 1.0)) | ||||||
|  |         { | ||||||
|  |             pfa2 = pfa; | ||||||
|  |         } | ||||||
|  |     make_2_steps = configuration->property(role + ".make_two_steps", make_2_steps); | ||||||
|  |     blocking_on_standby = configuration->property(role + ".blocking_on_standby", blocking_on_standby); | ||||||
|  |  | ||||||
|  |     if (pfa <= 0.0) | ||||||
|  |         { | ||||||
|  |             // if pfa is not set, we use the first_vs_second_peak_statistic metric | ||||||
|  |             use_CFAR_algorithm_flag = false; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     SetDerivedParams(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void Acq_Conf::ConfigureAutomaticResampler(double opt_freq) | ||||||
|  | { | ||||||
|  |     if (use_automatic_resampler) | ||||||
|  |         { | ||||||
|  |             if (fs_in > opt_freq) | ||||||
|  |                 { | ||||||
|  |                     resampler_ratio = floor(static_cast<float>(fs_in) / opt_freq); | ||||||
|  |                     uint32_t decimation = fs_in / opt_freq; | ||||||
|  |                     while (fs_in % decimation > 0) | ||||||
|  |                         { | ||||||
|  |                             decimation--; | ||||||
|  |                         }; | ||||||
|  |                     resampler_ratio = decimation; | ||||||
|  |                     resampled_fs = fs_in / static_cast<int>(resampler_ratio); | ||||||
|  |                 } | ||||||
|  |             // --- Find number of samples per spreading code ------------------- | ||||||
|  |             SetDerivedParams(); | ||||||
|  |         } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void Acq_Conf::SetDerivedParams() | ||||||
|  | { | ||||||
|  |     samples_per_ms = static_cast<float>(resampled_fs) * 0.001; | ||||||
|  |     samples_per_chip = static_cast<unsigned int>(ceil(static_cast<float>(resampled_fs) / chips_per_second)); | ||||||
|  |     samples_per_code = samples_per_ms * ms_per_code; | ||||||
|  | } | ||||||
|   | |||||||
| @@ -32,6 +32,7 @@ | |||||||
| #ifndef GNSS_SDR_ACQ_CONF_H_ | #ifndef GNSS_SDR_ACQ_CONF_H_ | ||||||
| #define GNSS_SDR_ACQ_CONF_H_ | #define GNSS_SDR_ACQ_CONF_H_ | ||||||
|  |  | ||||||
|  | #include "configuration_interface.h" | ||||||
| #include <cstddef> | #include <cstddef> | ||||||
| #include <cstdint> | #include <cstdint> | ||||||
| #include <string> | #include <string> | ||||||
| @@ -43,10 +44,15 @@ public: | |||||||
|     uint32_t sampled_ms; |     uint32_t sampled_ms; | ||||||
|     uint32_t ms_per_code; |     uint32_t ms_per_code; | ||||||
|     uint32_t samples_per_chip; |     uint32_t samples_per_chip; | ||||||
|  |     uint32_t chips_per_second; | ||||||
|     uint32_t max_dwells; |     uint32_t max_dwells; | ||||||
|     uint32_t doppler_max; |     int32_t doppler_max; | ||||||
|  |     int32_t doppler_min; | ||||||
|  |     float doppler_step; | ||||||
|     uint32_t num_doppler_bins_step2; |     uint32_t num_doppler_bins_step2; | ||||||
|     float doppler_step2; |     float doppler_step2; | ||||||
|  |     float pfa; | ||||||
|  |     float pfa2; | ||||||
|     int64_t fs_in; |     int64_t fs_in; | ||||||
|     float samples_per_ms; |     float samples_per_ms; | ||||||
|     float samples_per_code; |     float samples_per_code; | ||||||
| @@ -63,8 +69,16 @@ public: | |||||||
|     std::string dump_filename; |     std::string dump_filename; | ||||||
|     uint32_t dump_channel; |     uint32_t dump_channel; | ||||||
|     size_t it_size; |     size_t it_size; | ||||||
|  |     std::string item_type; | ||||||
|  |  | ||||||
|     Acq_Conf(); |     Acq_Conf(); | ||||||
|  |  | ||||||
|  |     void SetFromConfiguration(ConfigurationInterface *configuration, const std::string &role, double chip_rate, double opt_freq); | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     void SetDerivedParams(); | ||||||
|  |  | ||||||
|  |     void ConfigureAutomaticResampler(double opt_freq); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -40,6 +40,7 @@ set(GNSS_SPLIBS_SOURCES | |||||||
|     conjugate_ic.cc |     conjugate_ic.cc | ||||||
|     gnss_sdr_create_directory.cc |     gnss_sdr_create_directory.cc | ||||||
|     geofunctions.cc |     geofunctions.cc | ||||||
|  |     item_type_helpers.cc | ||||||
| ) | ) | ||||||
|  |  | ||||||
| set(GNSS_SPLIBS_HEADERS | set(GNSS_SPLIBS_HEADERS | ||||||
| @@ -65,6 +66,7 @@ set(GNSS_SPLIBS_HEADERS | |||||||
|     gnss_sdr_create_directory.h |     gnss_sdr_create_directory.h | ||||||
|     gnss_circular_deque.h |     gnss_circular_deque.h | ||||||
|     geofunctions.h |     geofunctions.h | ||||||
|  |     item_type_helpers.h | ||||||
| ) | ) | ||||||
|  |  | ||||||
| if(ENABLE_OPENCL) | if(ENABLE_OPENCL) | ||||||
| @@ -133,6 +135,30 @@ target_compile_definitions(algorithms_libs | |||||||
|     PUBLIC -DGNSSSDR_INSTALL_DIR="${CMAKE_INSTALL_PREFIX}" |     PUBLIC -DGNSSSDR_INSTALL_DIR="${CMAKE_INSTALL_PREFIX}" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND NOT WIN32) | ||||||
|  |     if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "6.1.1") | ||||||
|  |         target_compile_definitions(algorithms_libs | ||||||
|  |             PRIVATE -DOLDCOMPILER=1 | ||||||
|  |         ) | ||||||
|  |     endif() | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") | ||||||
|  |     if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") | ||||||
|  |         if(CLANG_VERSION VERSION_LESS "600") | ||||||
|  |             target_compile_definitions(algorithms_libs | ||||||
|  |                 PRIVATE -DOLDCOMPILER=1 | ||||||
|  |             ) | ||||||
|  |         endif() | ||||||
|  |     else() | ||||||
|  |         if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "3.5.0") | ||||||
|  |             target_compile_definitions(algorithms_libs | ||||||
|  |                 PRIVATE -DOLDCOMPILER=1 | ||||||
|  |             ) | ||||||
|  |         endif() | ||||||
|  |     endif() | ||||||
|  | endif() | ||||||
|  |  | ||||||
| set_property(TARGET algorithms_libs | set_property(TARGET algorithms_libs | ||||||
|     APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES |     APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES | ||||||
|         $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> |         $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> | ||||||
|   | |||||||
							
								
								
									
										409
									
								
								src/algorithms/libs/item_type_helpers.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										409
									
								
								src/algorithms/libs/item_type_helpers.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,409 @@ | |||||||
|  | /*! | ||||||
|  |  * \file item_type_helpers.cc | ||||||
|  |  * \brief Utility functions for converting between item types | ||||||
|  |  * \authors <ul> | ||||||
|  |  *          <li> Cillian O'Driscoll, 2019. cillian.odriscoll(at)gmail.com | ||||||
|  |  *          </ul> | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2010-2019  (see AUTHORS file for a list of contributors) | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is a software defined Global Navigation | ||||||
|  |  *          Satellite Systems receiver | ||||||
|  |  * | ||||||
|  |  * This file is part of GNSS-SDR. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License as published by | ||||||
|  |  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  * (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>. | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include "item_type_helpers.h" | ||||||
|  | #include <volk/volk.h> | ||||||
|  | #include <volk_gnsssdr/volk_gnsssdr.h> | ||||||
|  | #include <cstring>  // memcpy | ||||||
|  |  | ||||||
|  | bool item_type_valid(const std::string &item_type) | ||||||
|  | { | ||||||
|  |     if (item_type != "byte" and item_type != "cbyte" and item_type != "ibyte" and | ||||||
|  |         item_type != "short" and item_type != "cshort" and item_type != "ishort" and | ||||||
|  |         item_type != "float" and item_type != "gr_complex") | ||||||
|  |         { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     return true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | size_t item_type_size(const std::string &item_type) | ||||||
|  | { | ||||||
|  |     if (item_type == "byte" or item_type == "ibyte") | ||||||
|  |         { | ||||||
|  |             return sizeof(int8_t); | ||||||
|  |         } | ||||||
|  |     else if (item_type == "cbyte") | ||||||
|  |         { | ||||||
|  |             return 2 * sizeof(int8_t); | ||||||
|  |         } | ||||||
|  |     else if (item_type == "short" or item_type == "ishort") | ||||||
|  |         { | ||||||
|  |             return sizeof(int16_t); | ||||||
|  |         } | ||||||
|  |     else if (item_type == "cshort") | ||||||
|  |         { | ||||||
|  |             return 2 * sizeof(int16_t); | ||||||
|  |         } | ||||||
|  |     else if (item_type == "float") | ||||||
|  |         { | ||||||
|  |             return sizeof(float); | ||||||
|  |         } | ||||||
|  |     else if (item_type == "gr_complex") | ||||||
|  |         { | ||||||
|  |             return 2 * sizeof(float); | ||||||
|  |         } | ||||||
|  |     else | ||||||
|  |         { | ||||||
|  |             return 0; | ||||||
|  |         } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | bool item_type_is_complex(const std::string &item_type) | ||||||
|  | { | ||||||
|  |     return (item_type == "ibyte") or (item_type == "cbyte") or (item_type == "ishort") or (item_type == "cshort") or (item_type == "gr_complex"); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void copy_converter(void *dest, const void *src, unsigned int num_items, size_t item_size) | ||||||
|  | { | ||||||
|  |     std::memcpy(dest, src, num_items * item_size); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void convert_8i_16i(void *dest, const void *src, unsigned int num_items) | ||||||
|  | { | ||||||
|  |     volk_8i_convert_16i(reinterpret_cast<int16_t *>(dest), | ||||||
|  |         reinterpret_cast<const int8_t *>(src), num_items); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void convert_8i_32f(void *dest, const void *src, unsigned int num_items) | ||||||
|  | { | ||||||
|  |     volk_8i_s32f_convert_32f(reinterpret_cast<float *>(dest), | ||||||
|  |         reinterpret_cast<const int8_t *>(src), 1.0F, num_items); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void convert_8ic_16ic(void *dest, const void *src, unsigned int num_items) | ||||||
|  | { | ||||||
|  |     volk_8i_convert_16i(reinterpret_cast<int16_t *>(dest), | ||||||
|  |         reinterpret_cast<const int8_t *>(src), 2 * num_items); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void convert_8ic_32fc(void *dest, const void *src, unsigned int num_items) | ||||||
|  | { | ||||||
|  |     volk_8i_s32f_convert_32f(reinterpret_cast<float *>(dest), | ||||||
|  |         reinterpret_cast<const int8_t *>(src), 1.0F, 2 * num_items); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void convert_16i_8i(void *dest, const void *src, unsigned int num_items) | ||||||
|  | { | ||||||
|  |     volk_16i_convert_8i(reinterpret_cast<int8_t *>(dest), | ||||||
|  |         reinterpret_cast<const int16_t *>(src), num_items); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void convert_16i_32f(void *dest, const void *src, unsigned int num_items) | ||||||
|  | { | ||||||
|  |     volk_16i_s32f_convert_32f(reinterpret_cast<float *>(dest), | ||||||
|  |         reinterpret_cast<const int16_t *>(src), 1.0F, num_items); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void convert_16ic_8ic(void *dest, const void *src, unsigned int num_items) | ||||||
|  | { | ||||||
|  |     volk_16i_convert_8i(reinterpret_cast<int8_t *>(dest), | ||||||
|  |         reinterpret_cast<const int16_t *>(src), 2 * num_items); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void convert_16ic_32fc(void *dest, const void *src, unsigned int num_items) | ||||||
|  | { | ||||||
|  |     volk_16i_s32f_convert_32f(reinterpret_cast<float *>(dest), | ||||||
|  |         reinterpret_cast<const int16_t *>(src), 1.0F, 2 * num_items); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void convert_32f_8i(void *dest, const void *src, unsigned int num_items) | ||||||
|  | { | ||||||
|  |     volk_32f_s32f_convert_8i(reinterpret_cast<int8_t *>(dest), | ||||||
|  |         reinterpret_cast<const float *>(src), 1.0F, num_items); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void convert_32f_16i(void *dest, const void *src, unsigned int num_items) | ||||||
|  | { | ||||||
|  |     volk_32f_s32f_convert_16i(reinterpret_cast<int16_t *>(dest), | ||||||
|  |         reinterpret_cast<const float *>(src), 1.0F, num_items); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void convert_32fc_8ic(void *dest, const void *src, unsigned int num_items) | ||||||
|  | { | ||||||
|  |     volk_32f_s32f_convert_8i(reinterpret_cast<int8_t *>(dest), | ||||||
|  |         reinterpret_cast<const float *>(src), 1.0F, 2 * num_items); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void convert_32fc_16ic(void *dest, const void *src, unsigned int num_items) | ||||||
|  | { | ||||||
|  |     volk_32f_s32f_convert_16i(reinterpret_cast<int16_t *>(dest), | ||||||
|  |         reinterpret_cast<const float *>(src), 1.0F, 2 * num_items); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | item_type_converter_t make_vector_converter(const std::string &input_type, | ||||||
|  |     const std::string &output_type) | ||||||
|  | { | ||||||
|  |     if (not item_type_valid(input_type) or not item_type_valid(output_type)) | ||||||
|  |         { | ||||||
|  |             throw std::runtime_error("make_vector_converter: invalid item types : " + input_type + " " + output_type); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     if (input_type == output_type) | ||||||
|  |         { | ||||||
|  |             size_t input_size = item_type_size(input_type); | ||||||
|  | #ifdef OLDCOMPILER | ||||||
|  |             return std::bind(copy_converter, std::placeholders::_1, std::placeholders::_2, | ||||||
|  |                 std::placeholders::_3, input_size); | ||||||
|  | #else | ||||||
|  |             return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return copy_converter(arg1, arg2, arg3, input_size); }; | ||||||
|  | #endif | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     if (input_type == "byte") | ||||||
|  |         { | ||||||
|  |             if (output_type == "short") | ||||||
|  |                 { | ||||||
|  | #ifdef OLDCOMPILER | ||||||
|  |                     return std::bind(convert_8i_16i, std::placeholders::_1, | ||||||
|  |                         std::placeholders::_2, std::placeholders::_3); | ||||||
|  | #else | ||||||
|  |                     return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return convert_8i_16i(arg1, arg2, arg3); }; | ||||||
|  | #endif | ||||||
|  |                 } | ||||||
|  |             else if (output_type == "float") | ||||||
|  |                 { | ||||||
|  | #ifdef OLDCOMPILER | ||||||
|  |                     return std::bind(convert_8i_32f, std::placeholders::_1, | ||||||
|  |                         std::placeholders::_2, std::placeholders::_3); | ||||||
|  | #else | ||||||
|  |                     return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return convert_8i_32f(arg1, arg2, arg3); }; | ||||||
|  | #endif | ||||||
|  |                 } | ||||||
|  |         } | ||||||
|  |     else if (input_type == "cbyte") | ||||||
|  |         { | ||||||
|  |             if (output_type == "ibyte") | ||||||
|  |                 { | ||||||
|  |                     size_t input_size = item_type_size(input_type); | ||||||
|  | #ifdef OLDCOMPILER | ||||||
|  |                     return std::bind(copy_converter, std::placeholders::_1, std::placeholders::_2, | ||||||
|  |                         std::placeholders::_3, input_size); | ||||||
|  | #else | ||||||
|  |                     return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return copy_converter(arg1, arg2, arg3, input_size); }; | ||||||
|  | #endif | ||||||
|  |                 } | ||||||
|  |             if (output_type == "cshort" or output_type == "ishort") | ||||||
|  |                 { | ||||||
|  | #ifdef OLDCOMPILER | ||||||
|  |                     return std::bind(convert_8ic_16ic, std::placeholders::_1, | ||||||
|  |                         std::placeholders::_2, std::placeholders::_3); | ||||||
|  | #else | ||||||
|  |                     return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return convert_8ic_16ic(arg1, arg2, arg3); }; | ||||||
|  | #endif | ||||||
|  |                 } | ||||||
|  |             else if (output_type == "gr_complex") | ||||||
|  |                 { | ||||||
|  | #ifdef OLDCOMPILER | ||||||
|  |                     return std::bind(convert_8ic_32fc, std::placeholders::_1, | ||||||
|  |                         std::placeholders::_2, std::placeholders::_3); | ||||||
|  | #else | ||||||
|  |                     return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return convert_8ic_32fc(arg1, arg2, arg3); }; | ||||||
|  | #endif | ||||||
|  |                 } | ||||||
|  |         } | ||||||
|  |     else if (input_type == "ibyte") | ||||||
|  |         { | ||||||
|  |             if (output_type == "cbyte") | ||||||
|  |                 { | ||||||
|  |                     size_t input_size = item_type_size(input_type); | ||||||
|  | #ifdef OLDCOMPILER | ||||||
|  |                     return std::bind(copy_converter, std::placeholders::_1, std::placeholders::_2, | ||||||
|  |                         std::placeholders::_3, input_size); | ||||||
|  | #else | ||||||
|  |                     return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return copy_converter(arg1, arg2, arg3, input_size); }; | ||||||
|  | #endif | ||||||
|  |                 } | ||||||
|  |             else if (output_type == "cshort" or output_type == "ishort") | ||||||
|  |                 { | ||||||
|  | #ifdef OLDCOMPILER | ||||||
|  |                     return std::bind(convert_8i_16i, std::placeholders::_1, | ||||||
|  |                         std::placeholders::_2, std::placeholders::_3); | ||||||
|  | #else | ||||||
|  |                     return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return convert_8i_16i(arg1, arg2, arg3); }; | ||||||
|  | #endif | ||||||
|  |                 } | ||||||
|  |             else if (output_type == "gr_complex") | ||||||
|  |                 { | ||||||
|  | #ifdef OLDCOMPILER | ||||||
|  |                     return std::bind(convert_8i_32f, std::placeholders::_1, | ||||||
|  |                         std::placeholders::_2, std::placeholders::_3); | ||||||
|  | #else | ||||||
|  |                     return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return convert_8i_32f(arg1, arg2, arg3); }; | ||||||
|  | #endif | ||||||
|  |                 } | ||||||
|  |         } | ||||||
|  |     else if (input_type == "short") | ||||||
|  |         { | ||||||
|  |             if (output_type == "byte") | ||||||
|  |                 { | ||||||
|  | #ifdef OLDCOMPILER | ||||||
|  |                     return std::bind(convert_16i_8i, std::placeholders::_1, | ||||||
|  |                         std::placeholders::_2, std::placeholders::_3); | ||||||
|  | #else | ||||||
|  |                     return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return convert_16i_8i(arg1, arg2, arg3); }; | ||||||
|  | #endif | ||||||
|  |                 } | ||||||
|  |             else if (output_type == "float") | ||||||
|  |                 { | ||||||
|  | #ifdef OLDCOMPILER | ||||||
|  |                     return std::bind(convert_16i_32f, std::placeholders::_1, | ||||||
|  |                         std::placeholders::_2, std::placeholders::_3); | ||||||
|  | #else | ||||||
|  |                     return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return convert_16i_32f(arg1, arg2, arg3); }; | ||||||
|  | #endif | ||||||
|  |                 } | ||||||
|  |         } | ||||||
|  |     else if (input_type == "cshort") | ||||||
|  |         { | ||||||
|  |             if (output_type == "cbyte" or output_type == "ibyte") | ||||||
|  |                 { | ||||||
|  | #ifdef OLDCOMPILER | ||||||
|  |                     return std::bind(convert_16ic_8ic, std::placeholders::_1, | ||||||
|  |                         std::placeholders::_2, std::placeholders::_3); | ||||||
|  | #else | ||||||
|  |                     return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return convert_16ic_8ic(arg1, arg2, arg3); }; | ||||||
|  | #endif | ||||||
|  |                 } | ||||||
|  |             if (output_type == "ishort") | ||||||
|  |                 { | ||||||
|  |                     size_t input_size = item_type_size(input_type); | ||||||
|  | #ifdef OLDCOMPILER | ||||||
|  |                     return std::bind(copy_converter, std::placeholders::_1, std::placeholders::_2, | ||||||
|  |                         std::placeholders::_3, input_size); | ||||||
|  | #else | ||||||
|  |                     return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return copy_converter(arg1, arg2, arg3, input_size); }; | ||||||
|  | #endif | ||||||
|  |                 } | ||||||
|  |             else if (output_type == "gr_complex") | ||||||
|  |                 { | ||||||
|  | #ifdef OLDCOMPILER | ||||||
|  |                     return std::bind(convert_16ic_32fc, std::placeholders::_1, | ||||||
|  |                         std::placeholders::_2, std::placeholders::_3); | ||||||
|  | #else | ||||||
|  |                     return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return convert_16ic_32fc(arg1, arg2, arg3); }; | ||||||
|  | #endif | ||||||
|  |                 } | ||||||
|  |         } | ||||||
|  |     else if (input_type == "ishort") | ||||||
|  |         { | ||||||
|  |             if (output_type == "cbyte" or output_type == "ibyte") | ||||||
|  |                 { | ||||||
|  | #ifdef OLDCOMPILER | ||||||
|  |                     return std::bind(convert_16i_8i, std::placeholders::_1, | ||||||
|  |                         std::placeholders::_2, std::placeholders::_3); | ||||||
|  | #else | ||||||
|  |                     return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return convert_16i_8i(arg1, arg2, arg3); }; | ||||||
|  | #endif | ||||||
|  |                 } | ||||||
|  |             if (output_type == "cshort") | ||||||
|  |                 { | ||||||
|  |                     size_t input_size = item_type_size(input_type); | ||||||
|  | #ifdef OLDCOMPILER | ||||||
|  |                     return std::bind(copy_converter, std::placeholders::_1, std::placeholders::_2, | ||||||
|  |                         std::placeholders::_3, input_size); | ||||||
|  | #else | ||||||
|  |                     return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return copy_converter(arg1, arg2, arg3, input_size); }; | ||||||
|  | #endif | ||||||
|  |                 } | ||||||
|  |             else if (output_type == "gr_complex") | ||||||
|  |                 { | ||||||
|  | #ifdef OLDCOMPILER | ||||||
|  |                     return std::bind(convert_16i_32f, std::placeholders::_1, | ||||||
|  |                         std::placeholders::_2, std::placeholders::_3); | ||||||
|  | #else | ||||||
|  |                     return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return convert_16i_32f(arg1, arg2, arg3); }; | ||||||
|  | #endif | ||||||
|  |                 } | ||||||
|  |         } | ||||||
|  |     else if (input_type == "float") | ||||||
|  |         { | ||||||
|  |             if (output_type == "byte") | ||||||
|  |                 { | ||||||
|  | #ifdef OLDCOMPILER | ||||||
|  |                     return std::bind(convert_32f_8i, std::placeholders::_1, | ||||||
|  |                         std::placeholders::_2, std::placeholders::_3); | ||||||
|  | #else | ||||||
|  |                     return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return convert_32f_8i(arg1, arg2, arg3); }; | ||||||
|  | #endif | ||||||
|  |                 } | ||||||
|  |             else if (output_type == "short") | ||||||
|  |                 { | ||||||
|  | #ifdef OLDCOMPILER | ||||||
|  |                     return std::bind(convert_32f_16i, std::placeholders::_1, | ||||||
|  |                         std::placeholders::_2, std::placeholders::_3); | ||||||
|  | #else | ||||||
|  |                     return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return convert_32f_16i(arg1, arg2, arg3); }; | ||||||
|  | #endif | ||||||
|  |                 } | ||||||
|  |         } | ||||||
|  |     else if (input_type == "gr_complex") | ||||||
|  |         { | ||||||
|  |             if (output_type == "cbyte" or output_type == "ibyte") | ||||||
|  |                 { | ||||||
|  | #ifdef OLDCOMPILER | ||||||
|  |                     return std::bind(convert_32fc_8ic, std::placeholders::_1, | ||||||
|  |                         std::placeholders::_2, std::placeholders::_3); | ||||||
|  | #else | ||||||
|  |                     return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return convert_32fc_8ic(arg1, arg2, arg3); }; | ||||||
|  | #endif | ||||||
|  |                 } | ||||||
|  |             else if (output_type == "cshort" or output_type == "ishort") | ||||||
|  |                 { | ||||||
|  | #ifdef OLDCOMPILER | ||||||
|  |                     return std::bind(convert_32fc_16ic, std::placeholders::_1, | ||||||
|  |                         std::placeholders::_2, std::placeholders::_3); | ||||||
|  | #else | ||||||
|  |                     return [=](auto &&arg1, auto &&arg2, auto &&arg3) { return convert_32fc_16ic(arg1, arg2, arg3); }; | ||||||
|  | #endif | ||||||
|  |                 } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     throw std::runtime_error("make_vector_converter: invalid conversion : " + input_type + " to " + output_type); | ||||||
|  | } | ||||||
							
								
								
									
										88
									
								
								src/algorithms/libs/item_type_helpers.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								src/algorithms/libs/item_type_helpers.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,88 @@ | |||||||
|  | /*! | ||||||
|  |  * \file item_type_helpers.h | ||||||
|  |  * \brief Utility functions for converting between item types | ||||||
|  |  * \authors <ul> | ||||||
|  |  *          <li> Cillian O'Driscoll, 2019. cillian.odriscoll(at)gmail.com | ||||||
|  |  *          </ul> | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2010-2019  (see AUTHORS file for a list of contributors) | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is a software defined Global Navigation | ||||||
|  |  *          Satellite Systems receiver | ||||||
|  |  * | ||||||
|  |  * This file is part of GNSS-SDR. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License as published by | ||||||
|  |  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  * (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>. | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #ifndef GNSS_SDR_ITEM_TYPE_HELPERS_H_ | ||||||
|  | #define GNSS_SDR_ITEM_TYPE_HELPERS_H_ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #include <functional> | ||||||
|  | #include <string> | ||||||
|  |  | ||||||
|  | using item_type_converter_t = std::function<void(void *, const void *, unsigned)>; | ||||||
|  |  | ||||||
|  | /*! | ||||||
|  |  * \brief Check if a string is a valid item type | ||||||
|  |  * | ||||||
|  |  * \description Valid item types include: | ||||||
|  |  *     "byte", "short", "float", "ibyte", "ishort", "cbyte", "cshort", "gr_complex" | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | bool item_type_valid(const std::string &item_type); | ||||||
|  |  | ||||||
|  | /*! | ||||||
|  |  * \brief Return the size of the given item type, or zero if unknown | ||||||
|  |  */ | ||||||
|  | size_t item_type_size(const std::string &item_type); | ||||||
|  |  | ||||||
|  | /*! | ||||||
|  |  * \brief Determine if an item_type is complex | ||||||
|  |  */ | ||||||
|  | bool item_type_is_complex(const std::string &item_type); | ||||||
|  |  | ||||||
|  | /*! | ||||||
|  |  * \brief Create a function to convert an array of input_type to an array of output_type | ||||||
|  |  * | ||||||
|  |  * \description Provides a generic interface to generate conversion functions for mapping | ||||||
|  |  * arrays of items. | ||||||
|  |  * | ||||||
|  |  * \param input_type - String representation of the input item type | ||||||
|  |  * \param output_type - String representation of the output item type | ||||||
|  |  * | ||||||
|  |  * The item types accepted are: | ||||||
|  |  * | ||||||
|  |  *  1. "byte" for 8 bit integers | ||||||
|  |  *  2. "cbyte" for complex (interleaved) 8 bit integers | ||||||
|  |  *  4. "ibyte" for complex (interleaved) 8 bit integers | ||||||
|  |  *  4. "short" for 16 bit integers | ||||||
|  |  *  5. "cshort" for complex (interleaved) 16 bit integers | ||||||
|  |  *  6. "ishort" for complex (interleaved) 16 bit integers | ||||||
|  |  *  7. "float" for 32 bit floating point values | ||||||
|  |  *  8. "gr_complex" for complex (interleaved) 32 bit floating point values | ||||||
|  |  * | ||||||
|  |  * \returns A function object with the following prototype: | ||||||
|  |  *  void convert_fun( void *dest, void *src, int num_items ); | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | item_type_converter_t make_vector_converter(const std::string &input_type, | ||||||
|  |     const std::string &output_type); | ||||||
|  |  | ||||||
|  | #endif | ||||||
| @@ -5722,7 +5722,7 @@ inline VECTOR_CLASS<char*> cl::Program::getInfo<CL_PROGRAM_BINARIES>(cl_int* err | |||||||
| { | { | ||||||
|     VECTOR_CLASS< ::size_t> sizes = getInfo<CL_PROGRAM_BINARY_SIZES>(); |     VECTOR_CLASS< ::size_t> sizes = getInfo<CL_PROGRAM_BINARY_SIZES>(); | ||||||
|     VECTOR_CLASS<char*> binaries; |     VECTOR_CLASS<char*> binaries; | ||||||
|     for (unsigned long & size : sizes) |     for (unsigned long& size : sizes) | ||||||
|         { |         { | ||||||
|             char* ptr = nullptr; |             char* ptr = nullptr; | ||||||
|             if (size != 0) |             if (size != 0) | ||||||
|   | |||||||
| @@ -196,10 +196,9 @@ int PositionSystemTest::configure_receiver() | |||||||
|             const float threshold = 2.5; |             const float threshold = 2.5; | ||||||
|             const float doppler_max = 5000.0; |             const float doppler_max = 5000.0; | ||||||
|             const float doppler_step = 250.0; |             const float doppler_step = 250.0; | ||||||
|  |             const float pfa = 0.0; | ||||||
|  |             const float pfa_second_step = 0.0; | ||||||
|             const int max_dwells = 10; |             const int max_dwells = 10; | ||||||
|             const int tong_init_val = 2; |  | ||||||
|             const int tong_max_val = 10; |  | ||||||
|             const int tong_max_dwells = 30; |  | ||||||
|             const int coherent_integration_time_ms = 1; |             const int coherent_integration_time_ms = 1; | ||||||
|  |  | ||||||
|             const float pll_bw_hz = 35.0; |             const float pll_bw_hz = 35.0; | ||||||
| @@ -279,13 +278,15 @@ int PositionSystemTest::configure_receiver() | |||||||
|             config->set_property("Acquisition_1C.item_type", "gr_complex"); |             config->set_property("Acquisition_1C.item_type", "gr_complex"); | ||||||
|             config->set_property("Acquisition_1C.coherent_integration_time_ms", std::to_string(coherent_integration_time_ms)); |             config->set_property("Acquisition_1C.coherent_integration_time_ms", std::to_string(coherent_integration_time_ms)); | ||||||
|             config->set_property("Acquisition_1C.threshold", std::to_string(threshold)); |             config->set_property("Acquisition_1C.threshold", std::to_string(threshold)); | ||||||
|  |             config->set_property("Acquisition_1C.pfa", std::to_string(pfa)); | ||||||
|  |             config->set_property("Acquisition_1C.pfa_second_step", std::to_string(pfa_second_step)); | ||||||
|             config->set_property("Acquisition_1C.doppler_max", std::to_string(doppler_max)); |             config->set_property("Acquisition_1C.doppler_max", std::to_string(doppler_max)); | ||||||
|             config->set_property("Acquisition_1C.doppler_step", std::to_string(doppler_step)); |             config->set_property("Acquisition_1C.doppler_step", std::to_string(doppler_step)); | ||||||
|             config->set_property("Acquisition_1C.bit_transition_flag", "false"); |             config->set_property("Acquisition_1C.bit_transition_flag", "false"); | ||||||
|             config->set_property("Acquisition_1C.max_dwells", std::to_string(max_dwells)); |             config->set_property("Acquisition_1C.max_dwells", std::to_string(max_dwells)); | ||||||
|             config->set_property("Acquisition_1C.tong_init_val", std::to_string(tong_init_val)); |             config->set_property("Acquisition_1C.make_two_steps", "false"); | ||||||
|             config->set_property("Acquisition_1C.tong_max_val", std::to_string(tong_max_val)); |             config->set_property("Acquisition_1C.second_nbins", "8"); | ||||||
|             config->set_property("Acquisition_1C.tong_max_dwells", std::to_string(tong_max_dwells)); |             config->set_property("Acquisition_1C.second_doppler_step", "125"); | ||||||
|             config->set_property("Acquisition_1C.dump", "false"); |             config->set_property("Acquisition_1C.dump", "false"); | ||||||
|             config->set_property("Acquisition_1C.dump_filename", "./acquisition"); |             config->set_property("Acquisition_1C.dump_filename", "./acquisition"); | ||||||
|             config->set_property("Acquisition_1C.dump_channel", "1"); |             config->set_property("Acquisition_1C.dump_channel", "1"); | ||||||
|   | |||||||
| @@ -92,6 +92,7 @@ DECLARE_string(log_dir); | |||||||
| #include "unit-tests/signal-processing-blocks/sources/gnss_sdr_valve_test.cc" | #include "unit-tests/signal-processing-blocks/sources/gnss_sdr_valve_test.cc" | ||||||
| #include "unit-tests/signal-processing-blocks/sources/unpack_2bit_samples_test.cc" | #include "unit-tests/signal-processing-blocks/sources/unpack_2bit_samples_test.cc" | ||||||
| // #include "unit-tests/signal-processing-blocks/acquisition/glonass_l2_ca_pcps_acquisition_test.cc" | // #include "unit-tests/signal-processing-blocks/acquisition/glonass_l2_ca_pcps_acquisition_test.cc" | ||||||
|  | #include "unit-tests/signal-processing-blocks/libs/item_type_helpers.cc" | ||||||
|  |  | ||||||
| #if OPENCL_BLOCKS_TEST | #if OPENCL_BLOCKS_TEST | ||||||
| #include "unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_opencl_acquisition_gsoc2013_test.cc" | #include "unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_opencl_acquisition_gsoc2013_test.cc" | ||||||
|   | |||||||
| @@ -249,7 +249,8 @@ void GalileoE1PcpsAmbiguousAcquisitionGSoC2013Test::config_1() | |||||||
|         std::to_string(integration_time_ms)); |         std::to_string(integration_time_ms)); | ||||||
|     config->set_property("Acquisition_1B.max_dwells", "1"); |     config->set_property("Acquisition_1B.max_dwells", "1"); | ||||||
|     config->set_property("Acquisition_1B.bit_transition_flag", "false"); |     config->set_property("Acquisition_1B.bit_transition_flag", "false"); | ||||||
|     config->set_property("Acquisition_1B.threshold", "0.1"); |     //config->set_property("Acquisition_1B.threshold", "0.1"); | ||||||
|  |     config->set_property("Acquisition_1B.pfa", "0.0001"); | ||||||
|     config->set_property("Acquisition_1B.doppler_max", "10000"); |     config->set_property("Acquisition_1B.doppler_max", "10000"); | ||||||
|     config->set_property("Acquisition_1B.doppler_step", "250"); |     config->set_property("Acquisition_1B.doppler_step", "250"); | ||||||
|     config->set_property("Acquisition_1B.dump", "false"); |     config->set_property("Acquisition_1B.dump", "false"); | ||||||
| @@ -338,7 +339,7 @@ void GalileoE1PcpsAmbiguousAcquisitionGSoC2013Test::config_2() | |||||||
|         std::to_string(integration_time_ms)); |         std::to_string(integration_time_ms)); | ||||||
|     config->set_property("Acquisition_1B.max_dwells", "1"); |     config->set_property("Acquisition_1B.max_dwells", "1"); | ||||||
|     config->set_property("Acquisition_1B.bit_transition_flag", "false"); |     config->set_property("Acquisition_1B.bit_transition_flag", "false"); | ||||||
|     config->set_property("Acquisition_1B.pfa", "0.1"); |     config->set_property("Acquisition_1B.pfa", "0.0001"); | ||||||
|     config->set_property("Acquisition_1B.doppler_max", "10000"); |     config->set_property("Acquisition_1B.doppler_max", "10000"); | ||||||
|     config->set_property("Acquisition_1B.doppler_step", "250"); |     config->set_property("Acquisition_1B.doppler_step", "250"); | ||||||
|     config->set_property("Acquisition_1B.dump", "false"); |     config->set_property("Acquisition_1B.dump", "false"); | ||||||
| @@ -487,10 +488,6 @@ TEST_F(GalileoE1PcpsAmbiguousAcquisitionGSoC2013Test, ValidationOfResults) | |||||||
|         acquisition->set_doppler_step(config->property("Acquisition_1B.doppler_step", 500)); |         acquisition->set_doppler_step(config->property("Acquisition_1B.doppler_step", 500)); | ||||||
|     }) << "Failure setting doppler_step."; |     }) << "Failure setting doppler_step."; | ||||||
|  |  | ||||||
|     ASSERT_NO_THROW({ |  | ||||||
|         acquisition->set_threshold(config->property("Acquisition_1B.threshold", 0.0)); |  | ||||||
|     }) << "Failure setting threshold."; |  | ||||||
|  |  | ||||||
|     ASSERT_NO_THROW({ |     ASSERT_NO_THROW({ | ||||||
|         acquisition->connect(top_block); |         acquisition->connect(top_block); | ||||||
|     }) << "Failure connecting acquisition to the top_block."; |     }) << "Failure connecting acquisition to the top_block."; | ||||||
| @@ -519,7 +516,7 @@ TEST_F(GalileoE1PcpsAmbiguousAcquisitionGSoC2013Test, ValidationOfResults) | |||||||
|                 } |                 } | ||||||
|             else if (i == 1) |             else if (i == 1) | ||||||
|                 { |                 { | ||||||
|                     gnss_synchro.PRN = 20;  // This satellite is not visible |                     gnss_synchro.PRN = 36;  // This satellite is not visible | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|             acquisition->set_local_code(); |             acquisition->set_local_code(); | ||||||
| @@ -572,10 +569,6 @@ TEST_F(GalileoE1PcpsAmbiguousAcquisitionGSoC2013Test, ValidationOfResultsProbabi | |||||||
|         acquisition->set_doppler_step(config->property("Acquisition_1B.doppler_step", 500)); |         acquisition->set_doppler_step(config->property("Acquisition_1B.doppler_step", 500)); | ||||||
|     }) << "Failure setting doppler_step."; |     }) << "Failure setting doppler_step."; | ||||||
|  |  | ||||||
|     ASSERT_NO_THROW({ |  | ||||||
|         acquisition->set_threshold(config->property("Acquisition_1B.threshold", 0.0)); |  | ||||||
|     }) << "Failure setting threshold."; |  | ||||||
|  |  | ||||||
|     ASSERT_NO_THROW({ |     ASSERT_NO_THROW({ | ||||||
|         acquisition->connect(top_block); |         acquisition->connect(top_block); | ||||||
|     }) << "Failure connecting acquisition to the top_block."; |     }) << "Failure connecting acquisition to the top_block."; | ||||||
|   | |||||||
| @@ -166,7 +166,8 @@ void GalileoE1PcpsAmbiguousAcquisitionGSoCTest::init() | |||||||
|     config->set_property("Acquisition_1B.item_type", "gr_complex"); |     config->set_property("Acquisition_1B.item_type", "gr_complex"); | ||||||
|     config->set_property("Acquisition_1B.coherent_integration_time_ms", "4"); |     config->set_property("Acquisition_1B.coherent_integration_time_ms", "4"); | ||||||
|     config->set_property("Acquisition_1B.dump", "false"); |     config->set_property("Acquisition_1B.dump", "false"); | ||||||
|     config->set_property("Acquisition_1B.threshold", "0.1"); |     //config->set_property("Acquisition_1B.threshold", "0.1"); | ||||||
|  |     config->set_property("Acquisition_1B.pfa", "0.001"); | ||||||
|     config->set_property("Acquisition_1B.doppler_max", "10000"); |     config->set_property("Acquisition_1B.doppler_max", "10000"); | ||||||
|     config->set_property("Acquisition_1B.doppler_step", "125"); |     config->set_property("Acquisition_1B.doppler_step", "125"); | ||||||
|     config->set_property("Acquisition_1B.repeat_satellite", "false"); |     config->set_property("Acquisition_1B.repeat_satellite", "false"); | ||||||
| @@ -253,7 +254,7 @@ TEST_F(GalileoE1PcpsAmbiguousAcquisitionGSoCTest, ValidationOfResults) | |||||||
|     top_block = gr::make_top_block("Acquisition test"); |     top_block = gr::make_top_block("Acquisition test"); | ||||||
|  |  | ||||||
|     init(); |     init(); | ||||||
|     std::shared_ptr<GNSSBlockInterface> acq_ = factory->GetBlock(config, "Acquisition", "Galileo_E1_PCPS_Ambiguous_Acquisition", 1, 0); |     std::shared_ptr<GNSSBlockInterface> acq_ = factory->GetBlock(config, "Acquisition_1B", "Galileo_E1_PCPS_Ambiguous_Acquisition", 1, 0); | ||||||
|     std::shared_ptr<GalileoE1PcpsAmbiguousAcquisition> acquisition = std::dynamic_pointer_cast<GalileoE1PcpsAmbiguousAcquisition>(acq_); |     std::shared_ptr<GalileoE1PcpsAmbiguousAcquisition> acquisition = std::dynamic_pointer_cast<GalileoE1PcpsAmbiguousAcquisition>(acq_); | ||||||
|     boost::shared_ptr<GalileoE1PcpsAmbiguousAcquisitionGSoCTest_msg_rx> msg_rx = GalileoE1PcpsAmbiguousAcquisitionGSoCTest_msg_rx_make(channel_internal_queue); |     boost::shared_ptr<GalileoE1PcpsAmbiguousAcquisitionGSoCTest_msg_rx> msg_rx = GalileoE1PcpsAmbiguousAcquisitionGSoCTest_msg_rx_make(channel_internal_queue); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -177,7 +177,8 @@ void GalileoE1PcpsAmbiguousAcquisitionTest::init() | |||||||
|             config->set_property("Acquisition_1B.dump", "false"); |             config->set_property("Acquisition_1B.dump", "false"); | ||||||
|         } |         } | ||||||
|     config->set_property("Acquisition_1B.dump_filename", "./tmp-acq-gal1/acquisition"); |     config->set_property("Acquisition_1B.dump_filename", "./tmp-acq-gal1/acquisition"); | ||||||
|     config->set_property("Acquisition_1B.threshold", "0.0001"); |     //config->set_property("Acquisition_1B.threshold", "0.0001"); | ||||||
|  |     config->set_property("Acquisition_1B.pfa", "0.001"); | ||||||
|     config->set_property("Acquisition_1B.doppler_max", std::to_string(doppler_max)); |     config->set_property("Acquisition_1B.doppler_max", std::to_string(doppler_max)); | ||||||
|     config->set_property("Acquisition_1B.doppler_step", std::to_string(doppler_step)); |     config->set_property("Acquisition_1B.doppler_step", std::to_string(doppler_step)); | ||||||
|     config->set_property("Acquisition_1B.repeat_satellite", "false"); |     config->set_property("Acquisition_1B.repeat_satellite", "false"); | ||||||
|   | |||||||
| @@ -254,7 +254,8 @@ void GlonassL1CaPcpsAcquisitionGSoC2017Test::config_1() | |||||||
|         std::to_string(integration_time_ms)); |         std::to_string(integration_time_ms)); | ||||||
|     config->set_property("Acquisition.max_dwells", "1"); |     config->set_property("Acquisition.max_dwells", "1"); | ||||||
|     config->set_property("Acquisition.implementation", "GLONASS_L1_CA_PCPS_Acquisition"); |     config->set_property("Acquisition.implementation", "GLONASS_L1_CA_PCPS_Acquisition"); | ||||||
|     config->set_property("Acquisition.threshold", "0.8"); |     //config->set_property("Acquisition.threshold", "0.8"); | ||||||
|  |     config->set_property("Acquisition.pfa", "0.001"); | ||||||
|     config->set_property("Acquisition.doppler_max", "10000"); |     config->set_property("Acquisition.doppler_max", "10000"); | ||||||
|     config->set_property("Acquisition.doppler_step", "250"); |     config->set_property("Acquisition.doppler_step", "250"); | ||||||
|     config->set_property("Acquisition.bit_transition_flag", "false"); |     config->set_property("Acquisition.bit_transition_flag", "false"); | ||||||
| @@ -343,7 +344,7 @@ void GlonassL1CaPcpsAcquisitionGSoC2017Test::config_2() | |||||||
|         std::to_string(integration_time_ms)); |         std::to_string(integration_time_ms)); | ||||||
|     config->set_property("Acquisition.max_dwells", "1"); |     config->set_property("Acquisition.max_dwells", "1"); | ||||||
|     config->set_property("Acquisition.implementation", "GLONASS_L1_CA_PCPS_Acquisition"); |     config->set_property("Acquisition.implementation", "GLONASS_L1_CA_PCPS_Acquisition"); | ||||||
|     // config->set_property("Acquisition.pfa", "0.1"); |     config->set_property("Acquisition.pfa", "0.001"); | ||||||
|     config->set_property("Acquisition.doppler_max", "10000"); |     config->set_property("Acquisition.doppler_max", "10000"); | ||||||
|     config->set_property("Acquisition.doppler_step", "250"); |     config->set_property("Acquisition.doppler_step", "250"); | ||||||
|     config->set_property("Acquisition.bit_transition_flag", "false"); |     config->set_property("Acquisition.bit_transition_flag", "false"); | ||||||
| @@ -497,9 +498,9 @@ TEST_F(GlonassL1CaPcpsAcquisitionGSoC2017Test, ValidationOfResults) | |||||||
|         acquisition->set_doppler_step(500); |         acquisition->set_doppler_step(500); | ||||||
|     }) << "Failure setting doppler_step."; |     }) << "Failure setting doppler_step."; | ||||||
|  |  | ||||||
|     ASSERT_NO_THROW({ |     //ASSERT_NO_THROW({ | ||||||
|         acquisition->set_threshold(0.05); |     //acquisition->set_threshold(0.05); | ||||||
|     }) << "Failure setting threshold."; |     //}) << "Failure setting threshold."; | ||||||
|  |  | ||||||
|     ASSERT_NO_THROW({ |     ASSERT_NO_THROW({ | ||||||
|         acquisition->connect(top_block); |         acquisition->connect(top_block); | ||||||
| @@ -585,9 +586,9 @@ TEST_F(GlonassL1CaPcpsAcquisitionGSoC2017Test, ValidationOfResultsProbabilities) | |||||||
|         acquisition->set_doppler_step(config->property("Acquisition.doppler_step", 500)); |         acquisition->set_doppler_step(config->property("Acquisition.doppler_step", 500)); | ||||||
|     }) << "Failure setting doppler_step."; |     }) << "Failure setting doppler_step."; | ||||||
|  |  | ||||||
|     ASSERT_NO_THROW({ |     //ASSERT_NO_THROW({ | ||||||
|         acquisition->set_threshold(config->property("Acquisition.threshold", 0.0)); |     //acquisition->set_threshold(config->property("Acquisition.threshold", 0.0)); | ||||||
|     }) << "Failure setting threshold."; |     //}) << "Failure setting threshold."; | ||||||
|  |  | ||||||
|     ASSERT_NO_THROW({ |     ASSERT_NO_THROW({ | ||||||
|         acquisition->connect(top_block); |         acquisition->connect(top_block); | ||||||
|   | |||||||
| @@ -252,7 +252,8 @@ void GpsL1CaPcpsAcquisitionGSoC2013Test::config_1() | |||||||
|     config->set_property("Acquisition_1C.coherent_integration_time_ms", |     config->set_property("Acquisition_1C.coherent_integration_time_ms", | ||||||
|         std::to_string(integration_time_ms)); |         std::to_string(integration_time_ms)); | ||||||
|     config->set_property("Acquisition_1C.max_dwells", "1"); |     config->set_property("Acquisition_1C.max_dwells", "1"); | ||||||
|     config->set_property("Acquisition_1C.threshold", "0.8"); |     //config->set_property("Acquisition_1C.threshold", "0.8"); | ||||||
|  |     config->set_property("Acquisition_1C.pfa", "0.001"); | ||||||
|     config->set_property("Acquisition_1C.doppler_max", "10000"); |     config->set_property("Acquisition_1C.doppler_max", "10000"); | ||||||
|     config->set_property("Acquisition_1C.doppler_step", "250"); |     config->set_property("Acquisition_1C.doppler_step", "250"); | ||||||
|     config->set_property("Acquisition_1C.bit_transition_flag", "false"); |     config->set_property("Acquisition_1C.bit_transition_flag", "false"); | ||||||
| @@ -339,7 +340,7 @@ void GpsL1CaPcpsAcquisitionGSoC2013Test::config_2() | |||||||
|     config->set_property("Acquisition_1C.coherent_integration_time_ms", |     config->set_property("Acquisition_1C.coherent_integration_time_ms", | ||||||
|         std::to_string(integration_time_ms)); |         std::to_string(integration_time_ms)); | ||||||
|     config->set_property("Acquisition_1C.max_dwells", "1"); |     config->set_property("Acquisition_1C.max_dwells", "1"); | ||||||
|     config->set_property("Acquisition_1C.pfa", "0.1"); |     config->set_property("Acquisition_1C.pfa", "0.001"); | ||||||
|     config->set_property("Acquisition_1C.doppler_max", "10000"); |     config->set_property("Acquisition_1C.doppler_max", "10000"); | ||||||
|     config->set_property("Acquisition_1C.doppler_step", "250"); |     config->set_property("Acquisition_1C.doppler_step", "250"); | ||||||
|     config->set_property("Acquisition_1C.bit_transition_flag", "false"); |     config->set_property("Acquisition_1C.bit_transition_flag", "false"); | ||||||
| @@ -490,9 +491,9 @@ TEST_F(GpsL1CaPcpsAcquisitionGSoC2013Test, ValidationOfResults) | |||||||
|         acquisition->set_doppler_step(500); |         acquisition->set_doppler_step(500); | ||||||
|     }) << "Failure setting doppler_step."; |     }) << "Failure setting doppler_step."; | ||||||
|  |  | ||||||
|     ASSERT_NO_THROW({ |     //ASSERT_NO_THROW({ | ||||||
|         acquisition->set_threshold(0.5); |     //acquisition->set_threshold(0.5); | ||||||
|     }) << "Failure setting threshold."; |     //}) << "Failure setting threshold."; | ||||||
|  |  | ||||||
|     ASSERT_NO_THROW({ |     ASSERT_NO_THROW({ | ||||||
|         acquisition->connect(top_block); |         acquisition->connect(top_block); | ||||||
| @@ -579,9 +580,9 @@ TEST_F(GpsL1CaPcpsAcquisitionGSoC2013Test, ValidationOfResultsProbabilities) | |||||||
|         acquisition->set_doppler_step(config->property("Acquisition_1C.doppler_step", 500)); |         acquisition->set_doppler_step(config->property("Acquisition_1C.doppler_step", 500)); | ||||||
|     }) << "Failure setting doppler_step."; |     }) << "Failure setting doppler_step."; | ||||||
|  |  | ||||||
|     ASSERT_NO_THROW({ |     //ASSERT_NO_THROW({ | ||||||
|         acquisition->set_threshold(config->property("Acquisition_1C.threshold", 0.0)); |     //acquisition->set_threshold(config->property("Acquisition_1C.threshold", 0.0)); | ||||||
|     }) << "Failure setting threshold."; |     //}) << "Failure setting threshold."; | ||||||
|  |  | ||||||
|     ASSERT_NO_THROW({ |     ASSERT_NO_THROW({ | ||||||
|         acquisition->connect(top_block); |         acquisition->connect(top_block); | ||||||
|   | |||||||
| @@ -0,0 +1,259 @@ | |||||||
|  | /*! | ||||||
|  |  * \file item_type_helpers_test.cc | ||||||
|  |  * \brief  This file implements unit tests for the item_type_helpers | ||||||
|  |  *      custom block | ||||||
|  |  * \author Cillian O'Driscoll, 2019. cillian.odriscoll (at) gmail.com | ||||||
|  |  * | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2010-2019  (see AUTHORS file for a list of contributors) | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is a software defined Global Navigation | ||||||
|  |  *          Satellite Systems receiver | ||||||
|  |  * | ||||||
|  |  * This file is part of GNSS-SDR. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License as published by | ||||||
|  |  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  * (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>. | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include "item_type_helpers.h" | ||||||
|  | #include <gtest/gtest.h> | ||||||
|  | #include <random> | ||||||
|  |  | ||||||
|  | class ItemTypeHelpersTest : public ::testing::Test | ||||||
|  | { | ||||||
|  | protected: | ||||||
|  |     static constexpr size_t N = 1000; | ||||||
|  |  | ||||||
|  | public: | ||||||
|  |     ItemTypeHelpersTest() | ||||||
|  |     { | ||||||
|  |         std::random_device r; | ||||||
|  |         std::default_random_engine e(r()); | ||||||
|  |  | ||||||
|  |         std::uniform_int_distribution<int8_t> udist_int8(-100, 100); | ||||||
|  |         std::uniform_int_distribution<int16_t> udist_int16(-100, 100); | ||||||
|  |         std::uniform_real_distribution<float> udist_float(-100, 100); | ||||||
|  |  | ||||||
|  |         std::generate(byte_array_in.begin(), byte_array_in.end(), [&udist_int8, &e]() { return udist_int8(e); }); | ||||||
|  |  | ||||||
|  |         std::generate(short_array_in.begin(), short_array_in.end(), [&udist_int16, &e]() { return udist_int16(e); }); | ||||||
|  |  | ||||||
|  |         std::generate(float_array_in.begin(), float_array_in.end(), [&udist_float, &e]() { return udist_float(e); }); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     std::vector<std::string> valid_item_types = {"byte", "ibyte", "cbyte", | ||||||
|  |         "short", "ishort", "cshort", "float", "gr_complex"}; | ||||||
|  |  | ||||||
|  |     std::vector<std::string> invalid_item_types = {"i8", "tfgs", "cbite", | ||||||
|  |         "shirt", "qshort", "csort", "flat", "igr_complex"}; | ||||||
|  |  | ||||||
|  |     std::array<int8_t, 2 * N> byte_array_in; | ||||||
|  |     std::array<int8_t, 2 * N> byte_array_out; | ||||||
|  |  | ||||||
|  |     std::array<int16_t, 2 * N> short_array_in; | ||||||
|  |     std::array<int16_t, 2 * N> short_array_out; | ||||||
|  |  | ||||||
|  |     std::array<float, 2 * N> float_array_in; | ||||||
|  |     std::array<float, 2 * N> float_array_out; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | TEST_F(ItemTypeHelpersTest, CheckValidTypes) | ||||||
|  | { | ||||||
|  |     for (auto &valid_type : valid_item_types) | ||||||
|  |         { | ||||||
|  |             EXPECT_TRUE(item_type_valid(valid_type)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     for (auto &invalid_type : invalid_item_types) | ||||||
|  |         { | ||||||
|  |             EXPECT_FALSE(item_type_valid(invalid_type)); | ||||||
|  |         } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST_F(ItemTypeHelpersTest, CheckSizes) | ||||||
|  | { | ||||||
|  |     EXPECT_EQ(item_type_size("byte"), 1); | ||||||
|  |     EXPECT_EQ(item_type_size("ibyte"), 1); | ||||||
|  |     EXPECT_EQ(item_type_size("cbyte"), 2); | ||||||
|  |  | ||||||
|  |     EXPECT_EQ(item_type_size("short"), 2); | ||||||
|  |     EXPECT_EQ(item_type_size("ishort"), 2); | ||||||
|  |     EXPECT_EQ(item_type_size("cshort"), 4); | ||||||
|  |  | ||||||
|  |     EXPECT_EQ(item_type_size("float"), 4); | ||||||
|  |     EXPECT_EQ(item_type_size("gr_complex"), 8); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     for (auto &invalid_type : invalid_item_types) | ||||||
|  |         { | ||||||
|  |             EXPECT_EQ(item_type_size(invalid_type), 0); | ||||||
|  |         } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST_F(ItemTypeHelpersTest, CheckMakeConverters) | ||||||
|  | { | ||||||
|  |     for (auto &input_type : valid_item_types) | ||||||
|  |         { | ||||||
|  |             for (auto &output_type : valid_item_types) | ||||||
|  |                 { | ||||||
|  |                     item_type_converter_t converter = nullptr; | ||||||
|  |  | ||||||
|  |                     if (item_type_is_complex(input_type) == item_type_is_complex(output_type)) | ||||||
|  |                         { | ||||||
|  |                             converter = make_vector_converter(input_type, output_type); | ||||||
|  |                             EXPECT_NE(converter, nullptr); | ||||||
|  |                         } | ||||||
|  |                     else | ||||||
|  |                         { | ||||||
|  |                             EXPECT_THROW(converter = make_vector_converter(input_type, output_type), std::runtime_error); | ||||||
|  |                         } | ||||||
|  |                 } | ||||||
|  |         } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST_F(ItemTypeHelpersTest, CheckConversionsReal) | ||||||
|  | { | ||||||
|  |     std::string input_type = "byte"; | ||||||
|  |     std::string output_type = "byte"; | ||||||
|  |     item_type_converter_t converter = make_vector_converter(input_type, output_type); | ||||||
|  |     EXPECT_NE(converter, nullptr); | ||||||
|  |     converter(byte_array_out.data(), byte_array_in.data(), N); | ||||||
|  |     EXPECT_TRUE(std::equal(byte_array_in.begin(), byte_array_in.begin() + N, byte_array_out.begin())); | ||||||
|  |  | ||||||
|  |     input_type = "byte"; | ||||||
|  |     output_type = "short"; | ||||||
|  |     converter = make_vector_converter(input_type, output_type); | ||||||
|  |     EXPECT_NE(converter, nullptr); | ||||||
|  |     converter(short_array_out.data(), byte_array_in.data(), N); | ||||||
|  |     converter = make_vector_converter(output_type, input_type); | ||||||
|  |     EXPECT_NE(converter, nullptr); | ||||||
|  |     converter(byte_array_out.data(), short_array_out.data(), N); | ||||||
|  |     EXPECT_TRUE(std::equal(byte_array_out.begin(), byte_array_out.begin() + N, byte_array_in.begin())); | ||||||
|  |  | ||||||
|  |     input_type = "byte"; | ||||||
|  |     output_type = "float"; | ||||||
|  |     converter = make_vector_converter(input_type, output_type); | ||||||
|  |     EXPECT_NE(converter, nullptr); | ||||||
|  |     converter(float_array_out.data(), byte_array_in.data(), N); | ||||||
|  |     converter = make_vector_converter(output_type, input_type); | ||||||
|  |     EXPECT_NE(converter, nullptr); | ||||||
|  |     converter(byte_array_out.data(), float_array_out.data(), N); | ||||||
|  |     EXPECT_TRUE(std::equal(byte_array_out.begin(), byte_array_out.begin() + N, byte_array_in.begin())); | ||||||
|  |  | ||||||
|  |     input_type = "short"; | ||||||
|  |     output_type = "short"; | ||||||
|  |     converter = make_vector_converter(input_type, output_type); | ||||||
|  |     EXPECT_NE(converter, nullptr); | ||||||
|  |     converter(short_array_out.data(), short_array_in.data(), N); | ||||||
|  |     EXPECT_TRUE(std::equal(short_array_in.begin(), short_array_in.begin() + N, short_array_out.begin())); | ||||||
|  |  | ||||||
|  |     input_type = "short"; | ||||||
|  |     output_type = "float"; | ||||||
|  |     converter = make_vector_converter(input_type, output_type); | ||||||
|  |     EXPECT_NE(converter, nullptr); | ||||||
|  |     converter(float_array_out.data(), short_array_in.data(), N); | ||||||
|  |     converter = make_vector_converter(output_type, input_type); | ||||||
|  |     EXPECT_NE(converter, nullptr); | ||||||
|  |     converter(short_array_out.data(), float_array_out.data(), N); | ||||||
|  |     EXPECT_TRUE(std::equal(short_array_out.begin(), short_array_out.begin() + N, short_array_in.begin())); | ||||||
|  |  | ||||||
|  |     input_type = "float"; | ||||||
|  |     output_type = "float"; | ||||||
|  |     converter = make_vector_converter(input_type, output_type); | ||||||
|  |     EXPECT_NE(converter, nullptr); | ||||||
|  |     converter(float_array_out.data(), float_array_in.data(), N); | ||||||
|  |     EXPECT_TRUE(std::equal(float_array_in.begin(), float_array_in.begin() + N, float_array_out.begin())); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST_F(ItemTypeHelpersTest, CheckConversionsComplex) | ||||||
|  | { | ||||||
|  |     std::string input_type = "cbyte"; | ||||||
|  |     std::string output_type = "cbyte"; | ||||||
|  |     item_type_converter_t converter = make_vector_converter(input_type, output_type); | ||||||
|  |     EXPECT_NE(converter, nullptr); | ||||||
|  |     converter(byte_array_out.data(), byte_array_in.data(), N); | ||||||
|  |     EXPECT_TRUE(std::equal(byte_array_in.begin(), byte_array_in.begin() + N, byte_array_out.begin())); | ||||||
|  |  | ||||||
|  |     input_type = "cbyte"; | ||||||
|  |     output_type = "ibyte"; | ||||||
|  |     converter = make_vector_converter(input_type, output_type); | ||||||
|  |     EXPECT_NE(converter, nullptr); | ||||||
|  |     converter(byte_array_out.data(), byte_array_in.data(), N); | ||||||
|  |     EXPECT_TRUE(std::equal(byte_array_in.begin(), byte_array_in.begin() + N, byte_array_out.begin())); | ||||||
|  |  | ||||||
|  |     input_type = "cbyte"; | ||||||
|  |     output_type = "cshort"; | ||||||
|  |     converter = make_vector_converter(input_type, output_type); | ||||||
|  |     EXPECT_NE(converter, nullptr); | ||||||
|  |     converter(short_array_out.data(), byte_array_in.data(), N); | ||||||
|  |     converter = make_vector_converter(output_type, input_type); | ||||||
|  |     EXPECT_NE(converter, nullptr); | ||||||
|  |     converter(byte_array_out.data(), short_array_out.data(), N); | ||||||
|  |     EXPECT_TRUE(std::equal(byte_array_out.begin(), byte_array_out.begin() + N, byte_array_in.begin())); | ||||||
|  |  | ||||||
|  |     input_type = "cbyte"; | ||||||
|  |     output_type = "ishort"; | ||||||
|  |     converter = make_vector_converter(input_type, output_type); | ||||||
|  |     EXPECT_NE(converter, nullptr); | ||||||
|  |     converter(short_array_out.data(), byte_array_in.data(), N); | ||||||
|  |     converter = make_vector_converter(output_type, input_type); | ||||||
|  |     EXPECT_NE(converter, nullptr); | ||||||
|  |     converter(byte_array_out.data(), short_array_out.data(), N); | ||||||
|  |     EXPECT_TRUE(std::equal(byte_array_out.begin(), byte_array_out.begin() + N, byte_array_in.begin())); | ||||||
|  |  | ||||||
|  |     input_type = "cbyte"; | ||||||
|  |     output_type = "gr_complex"; | ||||||
|  |     converter = make_vector_converter(input_type, output_type); | ||||||
|  |     EXPECT_NE(converter, nullptr); | ||||||
|  |     converter(float_array_out.data(), byte_array_in.data(), N); | ||||||
|  |     converter = make_vector_converter(output_type, input_type); | ||||||
|  |     EXPECT_NE(converter, nullptr); | ||||||
|  |     converter(byte_array_out.data(), float_array_out.data(), N); | ||||||
|  |     EXPECT_TRUE(std::equal(byte_array_out.begin(), byte_array_out.begin() + N, byte_array_in.begin())); | ||||||
|  |  | ||||||
|  |     input_type = "cshort"; | ||||||
|  |     output_type = "cshort"; | ||||||
|  |     converter = make_vector_converter(input_type, output_type); | ||||||
|  |     EXPECT_NE(converter, nullptr); | ||||||
|  |     converter(short_array_out.data(), short_array_in.data(), N); | ||||||
|  |     EXPECT_TRUE(std::equal(short_array_in.begin(), short_array_in.begin() + N, short_array_out.begin())); | ||||||
|  |  | ||||||
|  |     input_type = "cshort"; | ||||||
|  |     output_type = "ishort"; | ||||||
|  |     converter = make_vector_converter(input_type, output_type); | ||||||
|  |     EXPECT_NE(converter, nullptr); | ||||||
|  |     converter(short_array_out.data(), short_array_in.data(), N); | ||||||
|  |     EXPECT_TRUE(std::equal(short_array_in.begin(), short_array_in.begin() + N, short_array_out.begin())); | ||||||
|  |  | ||||||
|  |     input_type = "cshort"; | ||||||
|  |     output_type = "gr_complex"; | ||||||
|  |     converter = make_vector_converter(input_type, output_type); | ||||||
|  |     EXPECT_NE(converter, nullptr); | ||||||
|  |     converter(float_array_out.data(), short_array_in.data(), N); | ||||||
|  |     converter = make_vector_converter(output_type, input_type); | ||||||
|  |     EXPECT_NE(converter, nullptr); | ||||||
|  |     converter(short_array_out.data(), float_array_out.data(), N); | ||||||
|  |     EXPECT_TRUE(std::equal(short_array_out.begin(), short_array_out.begin() + N, short_array_in.begin())); | ||||||
|  |  | ||||||
|  |     input_type = "gr_complex"; | ||||||
|  |     output_type = "gr_complex"; | ||||||
|  |     converter = make_vector_converter(input_type, output_type); | ||||||
|  |     EXPECT_NE(converter, nullptr); | ||||||
|  |     converter(float_array_out.data(), float_array_in.data(), N); | ||||||
|  |     EXPECT_TRUE(std::equal(float_array_in.begin(), float_array_in.begin() + N, float_array_out.begin())); | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user
	 Carles Fernandez
					Carles Fernandez