From 37e9984c7ca8d45f180df22af1a3681d2c5e1f03 Mon Sep 17 00:00:00 2001 From: Mathieu Favreau Date: Thu, 23 Oct 2025 01:14:02 +0000 Subject: [PATCH 1/2] Add base aquisition class --- .../acquisition/adapters/CMakeLists.txt | 2 + .../adapters/base_pcps_acquisition.cc | 245 ++++++++++++++++++ .../adapters/base_pcps_acquisition.h | 171 ++++++++++++ .../adapters/beidou_b1i_pcps_acquisition.cc | 217 +--------------- .../adapters/beidou_b1i_pcps_acquisition.h | 126 +-------- .../adapters/beidou_b3i_pcps_acquisition.cc | 214 +-------------- .../adapters/beidou_b3i_pcps_acquisition.h | 127 +-------- .../adapters/galileo_e5a_pcps_acquisition.cc | 177 +------------ .../adapters/galileo_e5a_pcps_acquisition.h | 133 +--------- .../adapters/galileo_e5b_pcps_acquisition.cc | 194 +------------- .../adapters/galileo_e5b_pcps_acquisition.h | 156 +---------- .../adapters/galileo_e6_pcps_acquisition.cc | 233 +---------------- .../adapters/galileo_e6_pcps_acquisition.h | 134 +--------- .../glonass_l1_ca_pcps_acquisition.cc | 210 +-------------- .../adapters/glonass_l1_ca_pcps_acquisition.h | 122 +-------- .../glonass_l2_ca_pcps_acquisition.cc | 210 +-------------- .../adapters/glonass_l2_ca_pcps_acquisition.h | 112 +------- .../adapters/gps_l1_ca_pcps_acquisition.cc | 229 +--------------- .../adapters/gps_l1_ca_pcps_acquisition.h | 130 +--------- .../adapters/gps_l2_m_pcps_acquisition.cc | 231 +---------------- .../adapters/gps_l2_m_pcps_acquisition.h | 131 +--------- .../adapters/gps_l5i_pcps_acquisition.cc | 233 +---------------- .../adapters/gps_l5i_pcps_acquisition.h | 130 +--------- 23 files changed, 481 insertions(+), 3386 deletions(-) create mode 100644 src/algorithms/acquisition/adapters/base_pcps_acquisition.cc create mode 100644 src/algorithms/acquisition/adapters/base_pcps_acquisition.h diff --git a/src/algorithms/acquisition/adapters/CMakeLists.txt b/src/algorithms/acquisition/adapters/CMakeLists.txt index 85eb8672e..6bd9958b1 100644 --- a/src/algorithms/acquisition/adapters/CMakeLists.txt +++ b/src/algorithms/acquisition/adapters/CMakeLists.txt @@ -6,6 +6,7 @@ set(ACQ_ADAPTER_SOURCES + base_pcps_acquisition.cc gps_l1_ca_pcps_acquisition.cc gps_l1_ca_pcps_assisted_acquisition.cc gps_l1_ca_pcps_acquisition_fine_doppler.cc @@ -29,6 +30,7 @@ set(ACQ_ADAPTER_SOURCES ) set(ACQ_ADAPTER_HEADERS + base_pcps_acquisition.h gps_l1_ca_pcps_acquisition.h gps_l1_ca_pcps_assisted_acquisition.h gps_l1_ca_pcps_acquisition_fine_doppler.h diff --git a/src/algorithms/acquisition/adapters/base_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/base_pcps_acquisition.cc new file mode 100644 index 000000000..09b5c89f0 --- /dev/null +++ b/src/algorithms/acquisition/adapters/base_pcps_acquisition.cc @@ -0,0 +1,245 @@ +/*! + * \file gps_l1_ca_pcps_acquisition.cc + * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for + * GPS L1 C/A signals + * \authors + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#include "base_pcps_acquisition.h" +#include "acq_conf.h" +#include "configuration_interface.h" +#include "gnss_sdr_flags.h" + +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + +#if HAS_STD_SPAN +#include +namespace own = std; +#else +#include +namespace own = gsl_lite; +#endif + +namespace +{ +Acq_Conf get_acq_conf(const ConfigurationInterface* configuration, const std::string& role, double chip_rate, double opt_freq, uint32_t ms_per_code) +{ + Acq_Conf acq_parameters; + acq_parameters.ms_per_code = ms_per_code; + acq_parameters.SetFromConfiguration(configuration, role, chip_rate, opt_freq); + +#if USE_GLOG_AND_GFLAGS + if (FLAGS_doppler_max != 0) + { + acq_parameters.doppler_max = FLAGS_doppler_max; + } +#else + if (absl::GetFlag(FLAGS_doppler_max) != 0) + { + acq_parameters.doppler_max = absl::GetFlag(FLAGS_doppler_max); + } +#endif + + return acq_parameters; +} +} // namespace + +BasePcpsAcquisition::BasePcpsAcquisition( + const ConfigurationInterface* configuration, + const std::string& role, + unsigned int in_streams, + unsigned int out_streams, + double chip_rate, + double opt_freq, + double code_length_chips, + uint32_t ms_per_code) : acq_parameters_(get_acq_conf(configuration, role, chip_rate, opt_freq, ms_per_code)), + role_(role), + vector_length_(std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2.0 : 1.0)), + code_length_(static_cast(std::floor(static_cast(acq_parameters_.resampled_fs) / (chip_rate / code_length_chips)))), + code_(vector_length_), + acquisition_(pcps_make_acquisition(acq_parameters_)) +{ + DLOG(INFO) << "role " << role; + DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; + + if (acq_parameters_.item_type == "cbyte") + { + cbyte_to_float_x2_ = make_complex_byte_to_float_x2(); + float_to_complex_ = gr::blocks::float_to_complex::make(); + } + + if (in_streams > 1) + { + LOG(ERROR) << "This implementation only supports one input stream"; + } + if (out_streams > 0) + { + LOG(ERROR) << "This implementation does not provide an output stream"; + } +} + + +void BasePcpsAcquisition::stop_acquisition() +{ + acquisition_->set_active(false); +} + + +void BasePcpsAcquisition::set_threshold(float threshold) +{ + acquisition_->set_threshold(threshold); +} + + +void BasePcpsAcquisition::set_doppler_max(unsigned int doppler_max) +{ + acquisition_->set_doppler_max(doppler_max); +} + + +void BasePcpsAcquisition::set_doppler_step(unsigned int doppler_step) +{ + acquisition_->set_doppler_step(doppler_step); +} + + +void BasePcpsAcquisition::set_doppler_center(int doppler_center) +{ + acquisition_->set_doppler_center(doppler_center); +} + + +void BasePcpsAcquisition::set_gnss_synchro(Gnss_Synchro* gnss_synchro) +{ + gnss_synchro_ = gnss_synchro; + acquisition_->set_gnss_synchro(gnss_synchro_); +} + + +signed int BasePcpsAcquisition::mag() +{ + return acquisition_->mag(); +} + + +void BasePcpsAcquisition::init() +{ + acquisition_->init(); +} + + +void BasePcpsAcquisition::reset() +{ + acquisition_->set_active(true); +} + + +void BasePcpsAcquisition::set_state(int state) +{ + acquisition_->set_state(state); +} + + +void BasePcpsAcquisition::connect(gr::top_block_sptr top_block) +{ + if (acq_parameters_.item_type == "gr_complex" || acq_parameters_.item_type == "cshort") + { + // nothing to connect + } + else if (acq_parameters_.item_type == "cbyte") + { + // Since a byte-based acq implementation is not available, + // we just convert cshorts to gr_complex + top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0); + top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1); + top_block->connect(float_to_complex_, 0, acquisition_, 0); + } + else + { + LOG(WARNING) << acq_parameters_.item_type << " unknown acquisition item type"; + } +} + + +void BasePcpsAcquisition::disconnect(gr::top_block_sptr top_block) +{ + if (acq_parameters_.item_type == "gr_complex" || acq_parameters_.item_type == "cshort") + { + // nothing to disconnect + } + else if (acq_parameters_.item_type == "cbyte") + { + top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0); + top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1); + top_block->disconnect(float_to_complex_, 0, acquisition_, 0); + } + else + { + LOG(WARNING) << acq_parameters_.item_type << " unknown acquisition item type"; + } +} + + +gr::basic_block_sptr BasePcpsAcquisition::get_left_block() +{ + if (acq_parameters_.item_type == "gr_complex" || acq_parameters_.item_type == "cshort") + { + return acquisition_; + } + if (acq_parameters_.item_type == "cbyte") + { + return cbyte_to_float_x2_; + } + + LOG(WARNING) << acq_parameters_.item_type << " unknown acquisition item type"; + return nullptr; +} + + +gr::basic_block_sptr BasePcpsAcquisition::get_right_block() +{ + return acquisition_; +} + + +void BasePcpsAcquisition::set_resampler_latency(uint32_t latency_samples) +{ + acquisition_->set_resampler_latency(latency_samples); +} + + +void BasePcpsAcquisition::set_local_code() +{ + volk_gnsssdr::vector> code(code_length_); + + const auto sampling_freq = acq_parameters_.use_automatic_resampler ? acq_parameters_.resampled_fs : acq_parameters_.fs_in; + code_gen_complex_sampled(code, gnss_synchro_->PRN, sampling_freq); + + const auto num_codes = acq_parameters_.sampled_ms / acq_parameters_.ms_per_code; + + own::span code_span(code_.data(), vector_length_); + for (unsigned int i = 0; i < num_codes; i++) + { + std::copy_n(code.data(), code_length_, code_span.subspan(i * code_length_, code_length_).data()); + } + + acquisition_->set_local_code(code_.data()); +} diff --git a/src/algorithms/acquisition/adapters/base_pcps_acquisition.h b/src/algorithms/acquisition/adapters/base_pcps_acquisition.h new file mode 100644 index 000000000..e1da2523b --- /dev/null +++ b/src/algorithms/acquisition/adapters/base_pcps_acquisition.h @@ -0,0 +1,171 @@ +/*! + * \file base_ca_pcps_acquisition.h + * \brief Adapts a PCPS acquisition block to an AcquisitionInterface + * \authors
    + *
  • Mathieu Favreau, 2011. favreau.mathieu(at)hotmail.com + *
+ * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2025 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_BASE_PCPS_ACQUISITION_H +#define GNSS_SDR_BASE_PCPS_ACQUISITION_H + +#include "acq_conf.h" +#include "channel_fsm.h" +#include "complex_byte_to_float_x2.h" +#include "gnss_synchro.h" +#include "pcps_acquisition.h" +#include +#include + +/** \addtogroup Acquisition + * Classes for GNSS signal acquisition + * \{ */ +/** \addtogroup Acq_adapters acquisition_adapters + * Wrap GNU Radio acquisition blocks with an AcquisitionInterface + * \{ */ + + +class ConfigurationInterface; + +/*! + * \brief This class adapts a PCPS acquisition block to an AcquisitionInterface + */ +class BasePcpsAcquisition : public AcquisitionInterface +{ +public: + BasePcpsAcquisition( + const ConfigurationInterface* configuration, + const std::string& role, + unsigned int in_streams, + unsigned int out_streams, + double chip_rate, + double opt_freq, + double code_length_chips, + uint32_t ms_per_code); + + ~BasePcpsAcquisition() = default; + + inline std::string role() override + { + return role_; + } + + inline size_t item_size() override + { + return acq_parameters_.it_size; + } + + void connect(gr::top_block_sptr top_block) override; + void disconnect(gr::top_block_sptr top_block) override; + gr::basic_block_sptr get_left_block() override; + gr::basic_block_sptr get_right_block() override; + + /*! + * \brief Set acquisition/tracking common Gnss_Synchro object pointer + * to efficiently exchange synchronization data between acquisition and + * tracking blocks + */ + void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; + + /*! + * \brief Set acquisition channel unique ID + */ + inline void set_channel(unsigned int channel) override + { + acquisition_->set_channel(channel); + } + + /*! + * \brief Set channel fsm associated to this acquisition instance + */ + inline void set_channel_fsm(std::weak_ptr channel_fsm) override + { + acquisition_->set_channel_fsm(std::move(channel_fsm)); + } + + /*! + * \brief Set statistics threshold of PCPS algorithm + */ + void set_threshold(float threshold) override; + + /*! + * \brief Set maximum Doppler off grid search + */ + void set_doppler_max(unsigned int doppler_max) override; + + /*! + * \brief Set Doppler steps for the grid search + */ + void set_doppler_step(unsigned int doppler_step) override; + + /*! + * \brief Set Doppler center for the grid search + */ + void set_doppler_center(int doppler_center) override; + + /*! + * \brief Initializes acquisition algorithm. + */ + void init() override; + + /*! + * \brief Returns the maximum peak of grid search + */ + signed int mag() override; + + /*! + * \brief Restart acquisition algorithm + */ + void reset() override; + + /*! + * \brief If state = 1, it forces the block to start acquiring from the first sample + */ + void set_state(int state) override; + + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + + /*! + * \brief Sets the resampler latency to account it in the acquisition code delay estimation + */ + void set_resampler_latency(uint32_t latency_samples) override; + + /*! + * \brief Sets local code + */ + void set_local_code() override; + +private: + /*! + * \brief Generate code + */ + virtual void code_gen_complex_sampled(own::span> dest, uint32_t prn, int32_t sampling_freq) = 0; + + const Acq_Conf acq_parameters_; + gr::blocks::float_to_complex::sptr float_to_complex_; + complex_byte_to_float_x2_sptr cbyte_to_float_x2_; + Gnss_Synchro* gnss_synchro_; + const std::string role_; + const unsigned int vector_length_; + const unsigned int code_length_; + volk_gnsssdr::vector> code_; + pcps_acquisition_sptr acquisition_; +}; + + +/** \} */ +/** \} */ +#endif // GNSS_SDR_BASE_PCPS_ACQUISITION_H diff --git a/src/algorithms/acquisition/adapters/beidou_b1i_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/beidou_b1i_pcps_acquisition.cc index 06ca206ee..a5d1e7e4e 100644 --- a/src/algorithms/acquisition/adapters/beidou_b1i_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/beidou_b1i_pcps_acquisition.cc @@ -19,230 +19,19 @@ #include "beidou_b1i_pcps_acquisition.h" #include "Beidou_B1I.h" -#include "acq_conf.h" #include "beidou_b1i_signal_replica.h" -#include "configuration_interface.h" -#include "gnss_sdr_flags.h" -#include -#include - -#if USE_GLOG_AND_GFLAGS -#include -#else -#include -#endif - -#if HAS_STD_SPAN -#include -namespace own = std; -#else -#include -namespace own = gsl_lite; -#endif BeidouB1iPcpsAcquisition::BeidouB1iPcpsAcquisition( const ConfigurationInterface* configuration, const std::string& role, unsigned int in_streams, - unsigned int out_streams) : gnss_synchro_(nullptr), - role_(role), - threshold_(0.0), - channel_(0), - in_streams_(in_streams), - out_streams_(out_streams) + unsigned int out_streams) : BasePcpsAcquisition(configuration, role, in_streams, out_streams, BEIDOU_B1I_CODE_RATE_CPS, 10e6, BEIDOU_B1I_CODE_LENGTH_CHIPS, 1) { - acq_parameters_.ms_per_code = 1; - acq_parameters_.SetFromConfiguration(configuration, role, BEIDOU_B1I_CODE_RATE_CPS, 10e6); - - LOG(INFO) << "role " << role; - -#if USE_GLOG_AND_GFLAGS - if (FLAGS_doppler_max != 0) - { - acq_parameters_.doppler_max = FLAGS_doppler_max; - } -#else - if (absl::GetFlag(FLAGS_doppler_max) != 0) - { - acq_parameters_.doppler_max = absl::GetFlag(FLAGS_doppler_max); - } -#endif - doppler_max_ = acq_parameters_.doppler_max; - doppler_step_ = static_cast(acq_parameters_.doppler_step); - fs_in_ = acq_parameters_.fs_in; - item_type_ = acq_parameters_.item_type; - item_size_ = acq_parameters_.it_size; - - num_codes_ = acq_parameters_.sampled_ms; - code_length_ = static_cast(std::floor(static_cast(fs_in_) / (BEIDOU_B1I_CODE_RATE_CPS / BEIDOU_B1I_CODE_LENGTH_CHIPS))); - vector_length_ = static_cast(std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2.0 : 1.0)); - code_ = volk_gnsssdr::vector>(vector_length_); - - acquisition_ = pcps_make_acquisition(acq_parameters_); - DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; - - if (item_type_ == "cbyte") - { - cbyte_to_float_x2_ = make_complex_byte_to_float_x2(); - float_to_complex_ = gr::blocks::float_to_complex::make(); - } - - if (in_streams_ > 1) - { - LOG(ERROR) << "This implementation only supports one input stream"; - } - if (out_streams_ > 0) - { - LOG(ERROR) << "This implementation does not provide an output stream"; - } } -void BeidouB1iPcpsAcquisition::stop_acquisition() +void BeidouB1iPcpsAcquisition::code_gen_complex_sampled(own::span> dest, uint32_t prn, int32_t sampling_freq) { - acquisition_->set_active(false); -} - - -void BeidouB1iPcpsAcquisition::set_threshold(float threshold) -{ - threshold_ = threshold; - - acquisition_->set_threshold(threshold_); -} - - -void BeidouB1iPcpsAcquisition::set_doppler_max(uint32_t doppler_max) -{ - doppler_max_ = doppler_max; - - acquisition_->set_doppler_max(doppler_max_); -} - - -void BeidouB1iPcpsAcquisition::set_doppler_step(uint32_t doppler_step) -{ - doppler_step_ = doppler_step; - - acquisition_->set_doppler_step(doppler_step_); -} - - -void BeidouB1iPcpsAcquisition::set_gnss_synchro(Gnss_Synchro* gnss_synchro) -{ - gnss_synchro_ = gnss_synchro; - - acquisition_->set_gnss_synchro(gnss_synchro_); -} - - -signed int BeidouB1iPcpsAcquisition::mag() -{ - return acquisition_->mag(); -} - - -void BeidouB1iPcpsAcquisition::init() -{ - acquisition_->init(); - set_local_code(); -} - - -void BeidouB1iPcpsAcquisition::set_local_code() -{ - volk_gnsssdr::vector> code(code_length_); - - beidou_b1i_code_gen_complex_sampled(code, gnss_synchro_->PRN, fs_in_, 0); - - own::span code_span(code_.data(), vector_length_); - for (unsigned int i = 0; i < num_codes_; i++) - { - std::copy_n(code.data(), code_length_, code_span.subspan(i * code_length_, code_length_).data()); - } - - acquisition_->set_local_code(code_.data()); -} - - -void BeidouB1iPcpsAcquisition::reset() -{ - acquisition_->set_active(true); -} - - -void BeidouB1iPcpsAcquisition::set_state(int state) -{ - acquisition_->set_state(state); -} - - -void BeidouB1iPcpsAcquisition::connect(gr::top_block_sptr top_block) -{ - if (item_type_ == "gr_complex" || item_type_ == "cshort") - { - // nothing to connect - } - else if (item_type_ == "cbyte") - { - // Since a byte-based acq implementation is not available, - // we just convert cshorts to gr_complex - top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0); - top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1); - top_block->connect(float_to_complex_, 0, acquisition_, 0); - } - else - { - LOG(WARNING) << item_type_ << " unknown acquisition item type"; - } -} - - -void BeidouB1iPcpsAcquisition::disconnect(gr::top_block_sptr top_block) -{ - if (item_type_ == "gr_complex" || item_type_ == "cshort") - { - // nothing to disconnect - } - else if (item_type_ == "cbyte") - { - top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0); - top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1); - top_block->disconnect(float_to_complex_, 0, acquisition_, 0); - } - else - { - LOG(WARNING) << item_type_ << " unknown acquisition item type"; - } -} - - -gr::basic_block_sptr BeidouB1iPcpsAcquisition::get_left_block() -{ - if (item_type_ == "gr_complex" || item_type_ == "cshort") - { - return acquisition_; - } - if (item_type_ == "cbyte") - { - return cbyte_to_float_x2_; - } - else - { - LOG(WARNING) << item_type_ << " unknown acquisition item type"; - return nullptr; - } -} - - -gr::basic_block_sptr BeidouB1iPcpsAcquisition::get_right_block() -{ - return acquisition_; -} - - -void BeidouB1iPcpsAcquisition::set_resampler_latency(uint32_t latency_samples) -{ - acquisition_->set_resampler_latency(latency_samples); + beidou_b1i_code_gen_complex_sampled(dest, prn, sampling_freq, 0); } diff --git a/src/algorithms/acquisition/adapters/beidou_b1i_pcps_acquisition.h b/src/algorithms/acquisition/adapters/beidou_b1i_pcps_acquisition.h index 9e0a37ac7..ac04886bb 100644 --- a/src/algorithms/acquisition/adapters/beidou_b1i_pcps_acquisition.h +++ b/src/algorithms/acquisition/adapters/beidou_b1i_pcps_acquisition.h @@ -20,17 +20,7 @@ #ifndef GNSS_SDR_BEIDOU_B1I_PCPS_ACQUISITION_H #define GNSS_SDR_BEIDOU_B1I_PCPS_ACQUISITION_H -#include "channel_fsm.h" -#include "complex_byte_to_float_x2.h" -#include "gnss_synchro.h" -#include "pcps_acquisition.h" -#include -#include -#include -#include -#include -#include -#include +#include "base_pcps_acquisition.h" /** \addtogroup Acquisition * \{ */ @@ -44,7 +34,7 @@ class ConfigurationInterface; * \brief This class adapts a PCPS acquisition block to an AcquisitionInterface * for GPS L1 C/A signals */ -class BeidouB1iPcpsAcquisition : public AcquisitionInterface +class BeidouB1iPcpsAcquisition : public BasePcpsAcquisition { public: BeidouB1iPcpsAcquisition(const ConfigurationInterface* configuration, @@ -53,11 +43,6 @@ public: ~BeidouB1iPcpsAcquisition() = default; - inline std::string role() override - { - return role_; - } - /*! * \brief Returns "BEIDOU_B1I_PCPS_Acquisition" */ @@ -66,113 +51,8 @@ public: return "BEIDOU_B1I_PCPS_Acquisition"; } - inline size_t item_size() override - { - return item_size_; - } - - void connect(gr::top_block_sptr top_block) override; - void disconnect(gr::top_block_sptr top_block) override; - gr::basic_block_sptr get_left_block() override; - gr::basic_block_sptr get_right_block() override; - - /*! - * \brief Set acquisition/tracking common Gnss_Synchro object pointer - * to efficiently exchange synchronization data between acquisition and - * tracking blocks - */ - void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; - - /*! - * \brief Set acquisition channel unique ID - */ - inline void set_channel(unsigned int channel) override - { - channel_ = channel; - acquisition_->set_channel(channel_); - } - - /*! - * \brief Set channel fsm associated to this acquisition instance - */ - inline void set_channel_fsm(std::weak_ptr channel_fsm) override - { - channel_fsm_ = std::move(channel_fsm); - acquisition_->set_channel_fsm(channel_fsm_); - } - - /*! - * \brief Set statistics threshold of PCPS algorithm - */ - void set_threshold(float threshold) override; - - /*! - * \brief Set maximum Doppler off grid search - */ - void set_doppler_max(uint32_t doppler_max) override; - - /*! - * \brief Set Doppler steps for the grid search - */ - void set_doppler_step(uint32_t doppler_step) override; - - /*! - * \brief Initializes acquisition algorithm. - */ - void init() override; - - /*! - * \brief Sets local code for GPS L1/CA PCPS acquisition algorithm. - */ - void set_local_code() override; - - /*! - * \brief Returns the maximum peak of grid search - */ - signed int mag() override; - - /*! - * \brief Restart acquisition algorithm - */ - void reset() override; - - /*! - * \brief If state = 1, it forces the block to start acquiring from the first sample - */ - void set_state(int state) override; - - /*! - * \brief Stop running acquisition - */ - void stop_acquisition() override; - - /*! - * \brief Sets the resampler latency to account it in the acquisition code delay estimation - */ - void set_resampler_latency(uint32_t latency_samples) override; - private: - pcps_acquisition_sptr acquisition_; - volk_gnsssdr::vector> code_; - std::weak_ptr channel_fsm_; - gr::blocks::float_to_complex::sptr float_to_complex_; - complex_byte_to_float_x2_sptr cbyte_to_float_x2_; - Gnss_Synchro* gnss_synchro_; - Acq_Conf acq_parameters_; - std::string item_type_; - std::string role_; - std::string dump_filename_; - size_t item_size_; - int64_t fs_in_; - float threshold_; - unsigned int vector_length_; - unsigned int code_length_; - unsigned int channel_; - unsigned int doppler_max_; - unsigned int doppler_step_; - unsigned int num_codes_; - unsigned int in_streams_; - unsigned int out_streams_; + void code_gen_complex_sampled(own::span> dest, uint32_t prn, int32_t sampling_freq) override; }; diff --git a/src/algorithms/acquisition/adapters/beidou_b3i_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/beidou_b3i_pcps_acquisition.cc index a8a524cfa..36f447072 100644 --- a/src/algorithms/acquisition/adapters/beidou_b3i_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/beidou_b3i_pcps_acquisition.cc @@ -17,227 +17,19 @@ #include "beidou_b3i_pcps_acquisition.h" #include "Beidou_B3I.h" -#include "acq_conf.h" #include "beidou_b3i_signal_replica.h" -#include "configuration_interface.h" -#include "gnss_sdr_flags.h" -#include -#if USE_GLOG_AND_GFLAGS -#include -#else -#include -#endif - -#if HAS_STD_SPAN -#include -namespace own = std; -#else -#include -namespace own = gsl_lite; -#endif BeidouB3iPcpsAcquisition::BeidouB3iPcpsAcquisition( const ConfigurationInterface* configuration, const std::string& role, unsigned int in_streams, - unsigned int out_streams) : gnss_synchro_(nullptr), - role_(role), - threshold_(0.0), - channel_(0), - in_streams_(in_streams), - out_streams_(out_streams) + unsigned int out_streams) : BasePcpsAcquisition(configuration, role, in_streams, out_streams, BEIDOU_B3I_CODE_RATE_CPS, 100e6, BEIDOU_B3I_CODE_LENGTH_CHIPS, 1) { - acq_parameters_.ms_per_code = 1; - acq_parameters_.SetFromConfiguration(configuration, role, BEIDOU_B3I_CODE_RATE_CPS, 100e6); - - LOG(INFO) << "role " << role; - -#if USE_GLOG_AND_GFLAGS - if (FLAGS_doppler_max != 0) - { - acq_parameters_.doppler_max = FLAGS_doppler_max; - } -#else - if (absl::GetFlag(FLAGS_doppler_max) != 0) - { - acq_parameters_.doppler_max = absl::GetFlag(FLAGS_doppler_max); - } -#endif - doppler_max_ = acq_parameters_.doppler_max; - doppler_step_ = static_cast(acq_parameters_.doppler_step); - item_type_ = acq_parameters_.item_type; - item_size_ = acq_parameters_.it_size; - fs_in_ = acq_parameters_.fs_in; - - num_codes_ = acq_parameters_.sampled_ms; - code_length_ = static_cast(std::floor(static_cast(fs_in_) / (BEIDOU_B3I_CODE_RATE_CPS / BEIDOU_B3I_CODE_LENGTH_CHIPS))); - vector_length_ = static_cast(std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2.0 : 1.0)); - code_ = volk_gnsssdr::vector>(vector_length_); - - acquisition_ = pcps_make_acquisition(acq_parameters_); - DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; - - if (item_type_ == "cbyte") - { - cbyte_to_float_x2_ = make_complex_byte_to_float_x2(); - float_to_complex_ = gr::blocks::float_to_complex::make(); - } - - if (in_streams_ > 1) - { - LOG(ERROR) << "This implementation only supports one input stream"; - } - if (out_streams_ > 0) - { - LOG(ERROR) << "This implementation does not provide an output stream"; - } } -void BeidouB3iPcpsAcquisition::stop_acquisition() +void BeidouB3iPcpsAcquisition::code_gen_complex_sampled(own::span> dest, uint32_t prn, int32_t sampling_freq) { - acquisition_->set_active(false); -} - - -void BeidouB3iPcpsAcquisition::set_threshold(float threshold) -{ - threshold_ = threshold; - - acquisition_->set_threshold(threshold_); -} - - -void BeidouB3iPcpsAcquisition::set_doppler_max(unsigned int doppler_max) -{ - doppler_max_ = doppler_max; - - acquisition_->set_doppler_max(doppler_max_); -} - - -void BeidouB3iPcpsAcquisition::set_doppler_step(unsigned int doppler_step) -{ - doppler_step_ = doppler_step; - - acquisition_->set_doppler_step(doppler_step_); -} - - -void BeidouB3iPcpsAcquisition::set_gnss_synchro(Gnss_Synchro* gnss_synchro) -{ - gnss_synchro_ = gnss_synchro; - - acquisition_->set_gnss_synchro(gnss_synchro_); -} - - -signed int BeidouB3iPcpsAcquisition::mag() -{ - return acquisition_->mag(); -} - - -void BeidouB3iPcpsAcquisition::init() -{ - acquisition_->init(); -} - - -void BeidouB3iPcpsAcquisition::set_local_code() -{ - volk_gnsssdr::vector> code(code_length_); - - beidou_b3i_code_gen_complex_sampled(code, gnss_synchro_->PRN, fs_in_, 0); - - own::span code_span(code_.data(), vector_length_); - for (unsigned int i = 0; i < num_codes_; i++) - { - std::copy_n(code.data(), code_length_, code_span.subspan(i * code_length_, code_length_).data()); - } - - acquisition_->set_local_code(code_.data()); -} - - -void BeidouB3iPcpsAcquisition::reset() -{ - acquisition_->set_active(true); -} - - -void BeidouB3iPcpsAcquisition::set_state(int state) -{ - acquisition_->set_state(state); -} - - -void BeidouB3iPcpsAcquisition::connect(gr::top_block_sptr top_block) -{ - if (item_type_ == "gr_complex" || item_type_ == "cshort") - { - // nothing to connect - } - else if (item_type_ == "cbyte") - { - // Since a byte-based acq implementation is not available, - // we just convert cshorts to gr_complex - top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0); - top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1); - top_block->connect(float_to_complex_, 0, acquisition_, 0); - } - else - { - LOG(WARNING) << item_type_ << " unknown acquisition item type"; - } -} - - -void BeidouB3iPcpsAcquisition::disconnect(gr::top_block_sptr top_block) -{ - if (item_type_ == "gr_complex" || item_type_ == "cshort") - { - // nothing to disconnect - } - else if (item_type_ == "cbyte") - { - top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0); - top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1); - top_block->disconnect(float_to_complex_, 0, acquisition_, 0); - } - else - { - LOG(WARNING) << item_type_ << " unknown acquisition item type"; - } -} - - -gr::basic_block_sptr BeidouB3iPcpsAcquisition::get_left_block() -{ - if (item_type_ == "gr_complex" || item_type_ == "cshort") - { - return acquisition_; - } - if (item_type_ == "cbyte") - { - return cbyte_to_float_x2_; - } - else - { - LOG(WARNING) << item_type_ << " unknown acquisition item type"; - return nullptr; - } -} - - -gr::basic_block_sptr BeidouB3iPcpsAcquisition::get_right_block() -{ - return acquisition_; -} - - -void BeidouB3iPcpsAcquisition::set_resampler_latency(uint32_t latency_samples) -{ - acquisition_->set_resampler_latency(latency_samples); + beidou_b3i_code_gen_complex_sampled(dest, prn, sampling_freq, 0); } diff --git a/src/algorithms/acquisition/adapters/beidou_b3i_pcps_acquisition.h b/src/algorithms/acquisition/adapters/beidou_b3i_pcps_acquisition.h index 105f3e45c..30da657e5 100644 --- a/src/algorithms/acquisition/adapters/beidou_b3i_pcps_acquisition.h +++ b/src/algorithms/acquisition/adapters/beidou_b3i_pcps_acquisition.h @@ -18,18 +18,7 @@ #ifndef GNSS_SDR_BEIDOU_B3I_PCPS_ACQUISITION_H #define GNSS_SDR_BEIDOU_B3I_PCPS_ACQUISITION_H -#include "acq_conf.h" -#include "channel_fsm.h" -#include "complex_byte_to_float_x2.h" -#include "gnss_synchro.h" -#include "pcps_acquisition.h" -#include -#include -#include -#include -#include -#include -#include +#include "base_pcps_acquisition.h" /** \addtogroup Acquisition * \{ */ @@ -43,7 +32,7 @@ class ConfigurationInterface; * \brief This class adapts a PCPS acquisition block to an AcquisitionInterface * for BeiDou B3I signals */ -class BeidouB3iPcpsAcquisition : public AcquisitionInterface +class BeidouB3iPcpsAcquisition : public BasePcpsAcquisition { public: BeidouB3iPcpsAcquisition(const ConfigurationInterface* configuration, @@ -52,11 +41,6 @@ public: ~BeidouB3iPcpsAcquisition() = default; - inline std::string role() override - { - return role_; - } - /*! * \brief Returns "BEIDOU_B1I_PCPS_Acquisition" */ @@ -65,113 +49,8 @@ public: return "BEIDOU_B3I_PCPS_Acquisition"; } - inline size_t item_size() override - { - return item_size_; - } - - void connect(gr::top_block_sptr top_block) override; - void disconnect(gr::top_block_sptr top_block) override; - gr::basic_block_sptr get_left_block() override; - gr::basic_block_sptr get_right_block() override; - - /*! - * \brief Set acquisition/tracking common Gnss_Synchro object pointer - * to efficiently exchange synchronization data between acquisition and - * tracking blocks - */ - void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; - - /*! - * \brief Set acquisition channel unique ID - */ - inline void set_channel(unsigned int channel) override - { - channel_ = channel; - acquisition_->set_channel(channel_); - } - - /*! - * \brief Set channel fsm associated to this acquisition instance - */ - inline void set_channel_fsm(std::weak_ptr channel_fsm) override - { - channel_fsm_ = std::move(channel_fsm); - acquisition_->set_channel_fsm(channel_fsm_); - } - - /*! - * \brief Set statistics threshold of PCPS algorithm - */ - void set_threshold(float threshold) override; - - /*! - * \brief Set maximum Doppler off grid search - */ - void set_doppler_max(unsigned int doppler_max) override; - - /*! - * \brief Set Doppler steps for the grid search - */ - void set_doppler_step(unsigned int doppler_step) override; - - /*! - * \brief Initializes acquisition algorithm. - */ - void init() override; - - /*! - * \brief Sets local code for GPS L1/CA PCPS acquisition algorithm. - */ - void set_local_code() override; - - /*! - * \brief Returns the maximum peak of grid search - */ - signed int mag() override; - - /*! - * \brief Restart acquisition algorithm - */ - void reset() override; - - /*! - * \brief If state = 1, it forces the block to start acquiring from the first sample - */ - void set_state(int state) override; - - /*! - * \brief Stop running acquisition - */ - void stop_acquisition() override; - - /*! - * \brief Sets the resampler latency to account it in the acquisition code delay estimation - */ - void set_resampler_latency(uint32_t latency_samples) override; - private: - pcps_acquisition_sptr acquisition_; - volk_gnsssdr::vector> code_; - std::weak_ptr channel_fsm_; - gr::blocks::float_to_complex::sptr float_to_complex_; - complex_byte_to_float_x2_sptr cbyte_to_float_x2_; - Gnss_Synchro* gnss_synchro_; - Acq_Conf acq_parameters_; - std::string item_type_; - std::string role_; - std::string dump_filename_; - size_t item_size_; - int64_t fs_in_; - float threshold_; - unsigned int vector_length_; - unsigned int code_length_; - unsigned int channel_; - unsigned int doppler_max_; - unsigned int doppler_step_; - unsigned int num_codes_; - unsigned int in_streams_; - unsigned int out_streams_; + void code_gen_complex_sampled(own::span> dest, uint32_t prn, int32_t sampling_freq) override; }; diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.cc index f2bca0108..c4a45cab7 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.cc @@ -43,120 +43,19 @@ GalileoE5aPcpsAcquisition::GalileoE5aPcpsAcquisition( const std::string& role, unsigned int in_streams, unsigned int out_streams) - : gnss_synchro_(nullptr), - role_(role), - threshold_(0.0), - doppler_center_(0), - channel_(0), - in_streams_(in_streams), - out_streams_(out_streams), + : BasePcpsAcquisition(configuration, role, in_streams, out_streams, GALILEO_E5A_CODE_CHIP_RATE_CPS, GALILEO_E5A_OPT_ACQ_FS_SPS, GALILEO_E5A_CODE_LENGTH_CHIPS, 1), acq_pilot_(configuration->property(role + ".acquire_pilot", false)), acq_iq_(configuration->property(role + ".acquire_iq", false)) { - acq_parameters_.ms_per_code = 1; - acq_parameters_.SetFromConfiguration(configuration, role_, GALILEO_E5A_CODE_CHIP_RATE_CPS, GALILEO_E5A_OPT_ACQ_FS_SPS); - -#if USE_GLOG_AND_GFLAGS - if (FLAGS_doppler_max != 0) - { - acq_parameters_.doppler_max = FLAGS_doppler_max; - } -#else - if (absl::GetFlag(FLAGS_doppler_max) != 0) - { - acq_parameters_.doppler_max = absl::GetFlag(FLAGS_doppler_max); - } -#endif - doppler_max_ = acq_parameters_.doppler_max; - doppler_step_ = static_cast(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(std::floor(static_cast(acq_parameters_.resampled_fs) / (GALILEO_E5A_CODE_CHIP_RATE_CPS / GALILEO_E5A_CODE_LENGTH_CHIPS))); - vector_length_ = static_cast(std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2.0 : 1.0)); - code_ = volk_gnsssdr::vector>(vector_length_); - - sampled_ms_ = acq_parameters_.sampled_ms; - - DLOG(INFO) << "Role " << role_; - acquisition_ = pcps_make_acquisition(acq_parameters_); - DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; - if (acq_iq_) { acq_pilot_ = false; } - - if (in_streams_ > 1) - { - LOG(ERROR) << "This implementation only supports one input stream"; - } - if (out_streams_ > 0) - { - LOG(ERROR) << "This implementation does not provide an output stream"; - } } -void GalileoE5aPcpsAcquisition::stop_acquisition() +void GalileoE5aPcpsAcquisition::code_gen_complex_sampled(own::span> dest, uint32_t prn, int32_t sampling_freq) { - acquisition_->set_active(false); -} - - -void GalileoE5aPcpsAcquisition::set_threshold(float threshold) -{ - threshold_ = threshold; - - acquisition_->set_threshold(threshold_); -} - - -void GalileoE5aPcpsAcquisition::set_doppler_max(unsigned int doppler_max) -{ - doppler_max_ = doppler_max; - acquisition_->set_doppler_max(doppler_max_); -} - - -void GalileoE5aPcpsAcquisition::set_doppler_step(unsigned int doppler_step) -{ - doppler_step_ = doppler_step; - acquisition_->set_doppler_step(doppler_step_); -} - - -void GalileoE5aPcpsAcquisition::set_doppler_center(int doppler_center) -{ - doppler_center_ = doppler_center; - - acquisition_->set_doppler_center(doppler_center_); -} - - -void GalileoE5aPcpsAcquisition::set_gnss_synchro(Gnss_Synchro* gnss_synchro) -{ - gnss_synchro_ = gnss_synchro; - acquisition_->set_gnss_synchro(gnss_synchro_); -} - - -signed int GalileoE5aPcpsAcquisition::mag() -{ - return acquisition_->mag(); -} - - -void GalileoE5aPcpsAcquisition::init() -{ - acquisition_->init(); -} - - -void GalileoE5aPcpsAcquisition::set_local_code() -{ - volk_gnsssdr::vector> code(code_length_); std::array signal_{}; signal_[0] = '5'; signal_[2] = '\0'; @@ -174,75 +73,5 @@ void GalileoE5aPcpsAcquisition::set_local_code() signal_[1] = 'I'; } - if (acq_parameters_.use_automatic_resampler) - { - galileo_e5_a_code_gen_complex_sampled(code, gnss_synchro_->PRN, signal_, acq_parameters_.resampled_fs, 0); - } - else - { - galileo_e5_a_code_gen_complex_sampled(code, gnss_synchro_->PRN, signal_, fs_in_, 0); - } - own::span code_span(code_.data(), vector_length_); - for (unsigned int i = 0; i < sampled_ms_; i++) - { - std::copy_n(code.data(), code_length_, code_span.subspan(i * code_length_, code_length_).data()); - } - - acquisition_->set_local_code(code_.data()); -} - - -void GalileoE5aPcpsAcquisition::reset() -{ - acquisition_->set_active(true); -} - - -void GalileoE5aPcpsAcquisition::set_state(int state) -{ - acquisition_->set_state(state); -} - - -void GalileoE5aPcpsAcquisition::connect(gr::top_block_sptr top_block __attribute__((unused))) -{ - if (item_type_ == "gr_complex" || item_type_ == "cshort") - { - // nothing to connect - } - else - { - LOG(WARNING) << item_type_ << " unknown acquisition item type"; - } -} - - -void GalileoE5aPcpsAcquisition::disconnect(gr::top_block_sptr top_block __attribute__((unused))) -{ - if (item_type_ == "gr_complex" || item_type_ == "cshort") - { - // nothing to disconnect - } - else - { - LOG(WARNING) << item_type_ << " unknown acquisition item type"; - } -} - - -gr::basic_block_sptr GalileoE5aPcpsAcquisition::get_left_block() -{ - return acquisition_; -} - - -gr::basic_block_sptr GalileoE5aPcpsAcquisition::get_right_block() -{ - return acquisition_; -} - - -void GalileoE5aPcpsAcquisition::set_resampler_latency(uint32_t latency_samples) -{ - acquisition_->set_resampler_latency(latency_samples); + galileo_e5_a_code_gen_complex_sampled(dest, prn, signal_, sampling_freq, 0); } diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.h b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.h index a2194a729..f238dfd5e 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.h +++ b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.h @@ -19,13 +19,7 @@ #define GNSS_SDR_GALILEO_E5A_PCPS_ACQUISITION_H -#include "channel_fsm.h" -#include "gnss_synchro.h" -#include "pcps_acquisition.h" -#include -#include -#include -#include +#include "base_pcps_acquisition.h" /** \addtogroup Acquisition * \{ */ @@ -33,9 +27,7 @@ * \{ */ -class ConfigurationInterface; - -class GalileoE5aPcpsAcquisition : public AcquisitionInterface +class GalileoE5aPcpsAcquisition : public BasePcpsAcquisition { public: GalileoE5aPcpsAcquisition( @@ -46,131 +38,16 @@ public: ~GalileoE5aPcpsAcquisition() = default; - inline std::string role() override - { - return role_; - } - inline std::string implementation() override { return "Galileo_E5a_Pcps_Acquisition"; } - inline size_t item_size() override - { - return item_size_; - } - - void connect(gr::top_block_sptr top_block) override; - void disconnect(gr::top_block_sptr top_block) override; - gr::basic_block_sptr get_left_block() override; - gr::basic_block_sptr get_right_block() override; - - /*! - * \brief Set acquisition/tracking common Gnss_Synchro object pointer - * to efficiently exchange synchronization data between acquisition and - * tracking blocks - */ - void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; - - /*! - * \brief Set acquisition channel unique ID - */ - inline void set_channel(unsigned int channel) override - { - channel_ = channel; - acquisition_->set_channel(channel_); - } - - /*! - * \brief Set channel fsm associated to this acquisition instance - */ - inline void set_channel_fsm(std::weak_ptr channel_fsm) override - { - channel_fsm_ = std::move(channel_fsm); - acquisition_->set_channel_fsm(channel_fsm_); - } - - /*! - * \brief Set statistics threshold of PCPS algorithm - */ - void set_threshold(float threshold) override; - - /*! - * \brief Set maximum Doppler off grid search - */ - void set_doppler_max(unsigned int doppler_max) override; - - /*! - * \brief Set Doppler steps for the grid search - */ - void set_doppler_step(unsigned int doppler_step) override; - - /*! - * \brief Set Doppler center for the grid search - */ - void set_doppler_center(int doppler_center) override; - - /*! - * \brief Initializes acquisition algorithm. - */ - void init() override; - - /*! - * \brief Sets local Galileo E5a code for PCPS acquisition algorithm. - */ - void set_local_code() override; - - /*! - * \brief Returns the maximum peak of grid search - */ - signed int mag() override; - - /*! - * \brief Restart acquisition algorithm - */ - void reset() override; - - /*! - * \brief If set to 1, ensures that acquisition starts at the - * first available sample. - * \param state - int=1 forces start of acquisition - */ - void set_state(int state) override; - - /*! - * \brief Stop running acquisition - */ - void stop_acquisition() override; - - /*! - * \brief Sets the resampler latency to account it in the acquisition code delay estimation - */ - void set_resampler_latency(uint32_t latency_samples) override; - private: - pcps_acquisition_sptr acquisition_; - volk_gnsssdr::vector> code_; - std::weak_ptr channel_fsm_; - Gnss_Synchro* gnss_synchro_; - Acq_Conf acq_parameters_; - std::string item_type_; - std::string dump_filename_; - std::string role_; - int64_t fs_in_; - size_t item_size_; - float threshold_; - int doppler_center_; - unsigned int vector_length_; - unsigned int code_length_; - unsigned int channel_; - unsigned int doppler_max_; - unsigned int doppler_step_; - unsigned int sampled_ms_; - unsigned int in_streams_; - unsigned int out_streams_; + void code_gen_complex_sampled(own::span> dest, uint32_t prn, int32_t sampling_freq) override; + bool acq_pilot_; - bool acq_iq_; + const bool acq_iq_; }; diff --git a/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition.cc index 45b3f7ac6..6be32df12 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition.cc @@ -18,143 +18,25 @@ #include "galileo_e5b_pcps_acquisition.h" #include "Galileo_E5b.h" -#include "acq_conf.h" -#include "configuration_interface.h" #include "galileo_e5_signal_replica.h" -#include "gnss_sdr_flags.h" -#include -#include - -#if USE_GLOG_AND_GFLAGS -#include -#else -#include -#endif - -#if HAS_STD_SPAN -#include -namespace own = std; -#else -#include -namespace own = gsl_lite; -#endif GalileoE5bPcpsAcquisition::GalileoE5bPcpsAcquisition(const ConfigurationInterface* configuration, const std::string& role, unsigned int in_streams, unsigned int out_streams) - : gnss_synchro_(nullptr), - role_(role), - threshold_(0.0), - doppler_center_(0), - channel_(0), - in_streams_(in_streams), - out_streams_(out_streams), + : BasePcpsAcquisition(configuration, role, in_streams, out_streams, GALILEO_E5B_CODE_CHIP_RATE_CPS, GALILEO_E5B_OPT_ACQ_FS_SPS, GALILEO_E5B_CODE_LENGTH_CHIPS, 1), acq_pilot_(configuration->property(role + ".acquire_pilot", false)), acq_iq_(configuration->property(role + ".acquire_iq", false)) { - acq_parameters_.ms_per_code = 1; - acq_parameters_.SetFromConfiguration(configuration, role_, GALILEO_E5B_CODE_CHIP_RATE_CPS, GALILEO_E5B_OPT_ACQ_FS_SPS); - -#if USE_GLOG_AND_GFLAGS - if (FLAGS_doppler_max != 0) - { - acq_parameters_.doppler_max = FLAGS_doppler_max; - } -#else - if (absl::GetFlag(FLAGS_doppler_max) != 0) - { - acq_parameters_.doppler_max = absl::GetFlag(FLAGS_doppler_max); - } -#endif - doppler_max_ = acq_parameters_.doppler_max; - doppler_step_ = static_cast(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(std::floor(static_cast(acq_parameters_.resampled_fs) / (GALILEO_E5B_CODE_CHIP_RATE_CPS / GALILEO_E5B_CODE_LENGTH_CHIPS))); - vector_length_ = static_cast(std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2.0F : 1.0F)); - code_ = volk_gnsssdr::vector>(vector_length_); - - sampled_ms_ = acq_parameters_.sampled_ms; - - DLOG(INFO) << "role " << role_; - acquisition_ = pcps_make_acquisition(acq_parameters_); - DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; - if (acq_iq_) { acq_pilot_ = false; } - - if (in_streams_ > 1) - { - LOG(ERROR) << "This implementation only supports one input stream"; - } - if (out_streams_ > 0) - { - LOG(ERROR) << "This implementation does not provide an output stream"; - } } -void GalileoE5bPcpsAcquisition::stop_acquisition() +void GalileoE5bPcpsAcquisition::code_gen_complex_sampled(own::span> dest, uint32_t prn, int32_t sampling_freq) { - acquisition_->set_active(false); -} - - -void GalileoE5bPcpsAcquisition::set_threshold(float threshold) -{ - threshold_ = threshold; - acquisition_->set_threshold(threshold_); -} - - -void GalileoE5bPcpsAcquisition::set_doppler_max(unsigned int doppler_max) -{ - doppler_max_ = doppler_max; - acquisition_->set_doppler_max(doppler_max_); -} - - -void GalileoE5bPcpsAcquisition::set_doppler_step(unsigned int doppler_step) -{ - doppler_step_ = doppler_step; - acquisition_->set_doppler_step(doppler_step_); -} - - -void GalileoE5bPcpsAcquisition::set_doppler_center(int doppler_center) -{ - doppler_center_ = doppler_center; - acquisition_->set_doppler_center(doppler_center_); -} - - -void GalileoE5bPcpsAcquisition::set_gnss_synchro(Gnss_Synchro* gnss_synchro) -{ - gnss_synchro_ = gnss_synchro; - acquisition_->set_gnss_synchro(gnss_synchro_); -} - - -signed int GalileoE5bPcpsAcquisition::mag() -{ - return acquisition_->mag(); -} - - -void GalileoE5bPcpsAcquisition::init() -{ - acquisition_->init(); -} - - -void GalileoE5bPcpsAcquisition::set_local_code() -{ - volk_gnsssdr::vector> code(code_length_); std::array signal_{}; signal_[0] = '7'; signal_[2] = '\0'; @@ -172,75 +54,5 @@ void GalileoE5bPcpsAcquisition::set_local_code() signal_[1] = 'I'; } - if (acq_parameters_.use_automatic_resampler) - { - galileo_e5_b_code_gen_complex_sampled(code, gnss_synchro_->PRN, signal_, acq_parameters_.resampled_fs, 0); - } - else - { - galileo_e5_b_code_gen_complex_sampled(code, gnss_synchro_->PRN, signal_, fs_in_, 0); - } - own::span code_span(code_.data(), vector_length_); - for (unsigned int i = 0; i < sampled_ms_; i++) - { - std::copy_n(code.data(), code_length_, code_span.subspan(i * code_length_, code_length_).data()); - } - - acquisition_->set_local_code(code_.data()); -} - - -void GalileoE5bPcpsAcquisition::reset() -{ - acquisition_->set_active(true); -} - - -void GalileoE5bPcpsAcquisition::set_state(int state) -{ - acquisition_->set_state(state); -} - - -void GalileoE5bPcpsAcquisition::connect(gr::top_block_sptr top_block __attribute__((unused))) -{ - if ((item_type_ == "gr_complex") || (item_type_ == "cshort")) - { - // nothing to connect - } - else - { - LOG(WARNING) << item_type_ << " unknown acquisition item type"; - } -} - - -void GalileoE5bPcpsAcquisition::disconnect(gr::top_block_sptr top_block __attribute__((unused))) -{ - if ((item_type_ == "gr_complex") || (item_type_ == "cshort")) - { - // nothing to disconnect - } - else - { - LOG(WARNING) << item_type_ << " unknown acquisition item type"; - } -} - - -gr::basic_block_sptr GalileoE5bPcpsAcquisition::get_left_block() -{ - return acquisition_; -} - - -gr::basic_block_sptr GalileoE5bPcpsAcquisition::get_right_block() -{ - return acquisition_; -} - - -void GalileoE5bPcpsAcquisition::set_resampler_latency(uint32_t latency_samples) -{ - acquisition_->set_resampler_latency(latency_samples); + galileo_e5_b_code_gen_complex_sampled(dest, prn, signal_, sampling_freq, 0); } diff --git a/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition.h b/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition.h index 940dac140..8f99d5f69 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition.h +++ b/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition.h @@ -20,13 +20,7 @@ #define GNSS_SDR_GALILEO_E5B_PCPS_ACQUISITION_H -#include "channel_fsm.h" -#include "gnss_synchro.h" -#include "pcps_acquisition.h" -#include -#include -#include -#include +#include "base_pcps_acquisition.h" /** \addtogroup Acquisition * \{ */ @@ -36,7 +30,7 @@ class ConfigurationInterface; -class GalileoE5bPcpsAcquisition : public AcquisitionInterface +class GalileoE5bPcpsAcquisition : public BasePcpsAcquisition { public: /*! @@ -52,14 +46,6 @@ public: */ ~GalileoE5bPcpsAcquisition() = default; - /*! - * \brief Role - */ - inline std::string role() override - { - return role_; - } - /*! * \brief Returns "GALILEO_E5b_PCPS_Acquisition" */ @@ -69,145 +55,11 @@ public: return "Galileo_E5b_PCPS_Acquisition"; } - /*! - * \brief Returns size of lv_16sc_t - */ - inline size_t item_size() override - { - return sizeof(int16_t); - } - - /*! - * \brief Connect - */ - void connect(gr::top_block_sptr top_block) override; - - /*! - * \brief Disconnect - */ - void disconnect(gr::top_block_sptr top_block) override; - - /*! - * \brief Get left block - */ - gr::basic_block_sptr get_left_block() override; - - /*! - * \brief Get right block - */ - gr::basic_block_sptr get_right_block() override; - - /*! - * \brief Set acquisition/tracking common Gnss_Synchro object pointer - * to efficiently exchange synchronization data between acquisition and - * tracking blocks - */ - void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; - - /*! - * \brief Set acquisition channel unique ID - */ - inline void set_channel(unsigned int channel) override - { - channel_ = channel; - acquisition_->set_channel(channel_); - } - - /*! - * \brief Set channel fsm associated to this acquisition instance - */ - inline void set_channel_fsm(std::weak_ptr channel_fsm) override - { - channel_fsm_ = std::move(channel_fsm); - acquisition_->set_channel_fsm(channel_fsm_); - } - - /*! - * \brief Set statistics threshold of PCPS algorithm - */ - void set_threshold(float threshold) override; - - /*! - * \brief Set maximum Doppler off grid search - */ - void set_doppler_max(unsigned int doppler_max) override; - - /*! - * \brief Set Doppler steps for the grid search - */ - void set_doppler_step(unsigned int doppler_step) override; - - /*! - * \brief Set Doppler center for the grid search - */ - void set_doppler_center(int doppler_center) override; - - /*! - * \brief Initializes acquisition algorithm. - */ - void init() override; - - /*! - * \brief Sets local Galileo E5b code for PCPS acquisition algorithm. - */ - void set_local_code() override; - - /*! - * \brief Returns the maximum peak of grid search - */ - signed int mag() override; - - /*! - * \brief Restart acquisition algorithm - */ - void reset() override; - - /*! - * \brief If set to 1, ensures that acquisition starts at the - * first available sample. - * \param state - int=1 forces start of acquisition - */ - void set_state(int state) override; - - /*! - * \brief Stop running acquisition - */ - void stop_acquisition() override; - - /*! - * \brief Sets the resampler latency to account it in the acquisition code delay estimation - */ - void set_resampler_latency(uint32_t latency_samples) override; - private: - pcps_acquisition_sptr acquisition_; - - volk_gnsssdr::vector> code_; - std::weak_ptr channel_fsm_; - - Gnss_Synchro* gnss_synchro_; - Acq_Conf acq_parameters_; - - std::string item_type_; - std::string dump_filename_; - std::string role_; - - size_t item_size_; - int64_t fs_in_; - - float threshold_; - int doppler_center_; - unsigned int vector_length_; - unsigned int code_length_; - unsigned int channel_; - unsigned int doppler_max_; - unsigned int doppler_step_; - unsigned int sampled_ms_; - unsigned int in_streams_; - unsigned int out_streams_; + void code_gen_complex_sampled(own::span> dest, uint32_t prn, int32_t sampling_freq) override; bool acq_pilot_; - bool acq_iq_; + const bool acq_iq_; }; diff --git a/src/algorithms/acquisition/adapters/galileo_e6_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e6_pcps_acquisition.cc index 41affc4a2..d456ab3b5 100644 --- a/src/algorithms/acquisition/adapters/galileo_e6_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e6_pcps_acquisition.cc @@ -17,246 +17,19 @@ #include "galileo_e6_pcps_acquisition.h" #include "Galileo_E6.h" -#include "acq_conf.h" -#include "configuration_interface.h" #include "galileo_e6_signal_replica.h" -#include "gnss_sdr_flags.h" -#include -#if USE_GLOG_AND_GFLAGS -#include -#else -#include -#endif - -#if HAS_STD_SPAN -#include -namespace own = std; -#else -#include -namespace own = gsl_lite; -#endif GalileoE6PcpsAcquisition::GalileoE6PcpsAcquisition( const ConfigurationInterface* configuration, const std::string& role, unsigned int in_streams, - unsigned int out_streams) : gnss_synchro_(nullptr), - configuration_(configuration), - role_(role), - threshold_(0), - doppler_center_(0), - channel_(0), - doppler_step_(0), - in_streams_(in_streams), - out_streams_(out_streams) + unsigned int out_streams) : BasePcpsAcquisition(configuration, role, in_streams, out_streams, GALILEO_E6_B_CODE_CHIP_RATE_CPS, GALILEO_E6_OPT_ACQ_FS_SPS, GALILEO_E6_B_CODE_LENGTH_CHIPS, 1) { - acq_parameters_.ms_per_code = 1; - acq_parameters_.SetFromConfiguration(configuration_, role, GALILEO_E6_B_CODE_CHIP_RATE_CPS, GALILEO_E6_OPT_ACQ_FS_SPS); - - DLOG(INFO) << "role " << role; - -#if USE_GLOG_AND_GFLAGS - if (FLAGS_doppler_max != 0) - { - acq_parameters_.doppler_max = FLAGS_doppler_max; - } -#else - if (absl::GetFlag(FLAGS_doppler_max) != 0) - { - acq_parameters_.doppler_max = absl::GetFlag(FLAGS_doppler_max); - } -#endif - doppler_max_ = acq_parameters_.doppler_max; - doppler_step_ = static_cast(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(std::floor(static_cast(acq_parameters_.resampled_fs) / (GALILEO_E6_B_CODE_CHIP_RATE_CPS / GALILEO_E6_B_CODE_LENGTH_CHIPS))); - vector_length_ = static_cast(std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2.0 : 1.0)); - code_ = volk_gnsssdr::vector>(vector_length_); - - sampled_ms_ = acq_parameters_.sampled_ms; - - acquisition_ = pcps_make_acquisition(acq_parameters_); - DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; - - if (item_type_ == "cbyte") - { - cbyte_to_float_x2_ = make_complex_byte_to_float_x2(); - float_to_complex_ = gr::blocks::float_to_complex::make(); - } - - if (in_streams_ > 1) - { - LOG(ERROR) << "This implementation only supports one input stream"; - } - if (out_streams_ > 0) - { - LOG(ERROR) << "This implementation does not provide an output stream"; - } } -void GalileoE6PcpsAcquisition::stop_acquisition() +void GalileoE6PcpsAcquisition::code_gen_complex_sampled(own::span> dest, uint32_t prn, int32_t sampling_freq) { - acquisition_->set_active(false); -} - - -void GalileoE6PcpsAcquisition::set_threshold(float threshold) -{ - threshold_ = threshold; - - acquisition_->set_threshold(threshold_); -} - - -void GalileoE6PcpsAcquisition::set_doppler_max(unsigned int doppler_max) -{ - doppler_max_ = doppler_max; - - acquisition_->set_doppler_max(doppler_max_); -} - - -void GalileoE6PcpsAcquisition::set_doppler_step(unsigned int doppler_step) -{ - doppler_step_ = doppler_step; - - acquisition_->set_doppler_step(doppler_step_); -} - - -void GalileoE6PcpsAcquisition::set_doppler_center(int doppler_center) -{ - doppler_center_ = doppler_center; - - acquisition_->set_doppler_center(doppler_center_); -} - - -void GalileoE6PcpsAcquisition::set_gnss_synchro(Gnss_Synchro* gnss_synchro) -{ - gnss_synchro_ = gnss_synchro; - - acquisition_->set_gnss_synchro(gnss_synchro_); -} - - -signed int GalileoE6PcpsAcquisition::mag() -{ - return acquisition_->mag(); -} - - -void GalileoE6PcpsAcquisition::init() -{ - acquisition_->init(); -} - - -void GalileoE6PcpsAcquisition::set_local_code() -{ - volk_gnsssdr::vector> code(code_length_); - - if (acq_parameters_.use_automatic_resampler) - { - galileo_e6_b_code_gen_complex_sampled(code, - gnss_synchro_->PRN, acq_parameters_.resampled_fs, 0); - } - else - { - galileo_e6_b_code_gen_complex_sampled(code, - gnss_synchro_->PRN, fs_in_, 0); - } - - own::span code_span(code_.data(), vector_length_); - for (unsigned int i = 0; i < sampled_ms_; i++) - { - std::copy_n(code.data(), code_length_, code_span.subspan(i * code_length_, code_length_).data()); - } - - acquisition_->set_local_code(code_.data()); -} - - -void GalileoE6PcpsAcquisition::reset() -{ - acquisition_->set_active(true); -} - - -void GalileoE6PcpsAcquisition::set_state(int state) -{ - acquisition_->set_state(state); -} - - -void GalileoE6PcpsAcquisition::connect(gr::top_block_sptr top_block) -{ - if (item_type_ == "gr_complex" || item_type_ == "cshort") - { - // nothing to connect - } - else if (item_type_ == "cbyte") - { - // Since a byte-based acq implementation is not available, - // we just convert cshorts to gr_complex - top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0); - top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1); - top_block->connect(float_to_complex_, 0, acquisition_, 0); - } - else - { - LOG(WARNING) << item_type_ << " unknown acquisition item type"; - } -} - - -void GalileoE6PcpsAcquisition::disconnect(gr::top_block_sptr top_block) -{ - if (item_type_ == "gr_complex" || item_type_ == "cshort") - { - // nothing to disconnect - } - else if (item_type_ == "cbyte") - { - top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0); - top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1); - top_block->disconnect(float_to_complex_, 0, acquisition_, 0); - } - else - { - LOG(WARNING) << item_type_ << " unknown acquisition item type"; - } -} - - -gr::basic_block_sptr GalileoE6PcpsAcquisition::get_left_block() -{ - if (item_type_ == "gr_complex" || item_type_ == "cshort") - { - return acquisition_; - } - if (item_type_ == "cbyte") - { - return cbyte_to_float_x2_; - } - - LOG(WARNING) << item_type_ << " unknown acquisition item type"; - return nullptr; -} - - -gr::basic_block_sptr GalileoE6PcpsAcquisition::get_right_block() -{ - return acquisition_; -} - - -void GalileoE6PcpsAcquisition::set_resampler_latency(uint32_t latency_samples) -{ - acquisition_->set_resampler_latency(latency_samples); + galileo_e6_b_code_gen_complex_sampled(dest, prn, sampling_freq, 0); } diff --git a/src/algorithms/acquisition/adapters/galileo_e6_pcps_acquisition.h b/src/algorithms/acquisition/adapters/galileo_e6_pcps_acquisition.h index a3fe58ca2..eb2705da6 100644 --- a/src/algorithms/acquisition/adapters/galileo_e6_pcps_acquisition.h +++ b/src/algorithms/acquisition/adapters/galileo_e6_pcps_acquisition.h @@ -18,16 +18,7 @@ #ifndef GNSS_SDR_GALILEO_E6_PCPS_ACQUISITION_H #define GNSS_SDR_GALILEO_E6_PCPS_ACQUISITION_H -#include "acq_conf.h" -#include "channel_fsm.h" -#include "complex_byte_to_float_x2.h" -#include "gnss_synchro.h" -#include "pcps_acquisition.h" -#include -#include -#include -#include -#include +#include "base_pcps_acquisition.h" /** \addtogroup Acquisition * \{ */ @@ -35,13 +26,11 @@ * \{ */ -class ConfigurationInterface; - /*! * \brief This class adapts a PCPS acquisition block to an * AcquisitionInterface for Galileo E6 Signals */ -class GalileoE6PcpsAcquisition : public AcquisitionInterface +class GalileoE6PcpsAcquisition : public BasePcpsAcquisition { public: GalileoE6PcpsAcquisition( @@ -52,11 +41,6 @@ public: ~GalileoE6PcpsAcquisition() = default; - inline std::string role() override - { - return role_; - } - /*! * \brief Returns "Galileo_E6_PCPS_Acquisition" */ @@ -65,120 +49,8 @@ public: return "Galileo_E6_PCPS_Acquisition"; } - size_t item_size() override - { - return item_size_; - } - - void connect(gr::top_block_sptr top_block) override; - void disconnect(gr::top_block_sptr top_block) override; - gr::basic_block_sptr get_left_block() override; - gr::basic_block_sptr get_right_block() override; - - /*! - * \brief Set acquisition/tracking common Gnss_Synchro object pointer - * to efficiently exchange synchronization data between acquisition and - * tracking blocks - */ - void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; - - /*! - * \brief Set acquisition channel unique ID - */ - inline void set_channel(unsigned int channel) override - { - channel_ = channel; - acquisition_->set_channel(channel_); - } - - /*! - * \brief Set channel fsm associated to this acquisition instance - */ - inline void set_channel_fsm(std::weak_ptr channel_fsm) override - { - channel_fsm_ = std::move(channel_fsm); - acquisition_->set_channel_fsm(channel_fsm_); - } - - /*! - * \brief Set statistics threshold of PCPS algorithm - */ - void set_threshold(float threshold) override; - - /*! - * \brief Set maximum Doppler off grid search - */ - void set_doppler_max(unsigned int doppler_max) override; - - /*! - * \brief Set Doppler steps for the grid search - */ - void set_doppler_step(unsigned int doppler_step) override; - - /*! - * \brief Set Doppler center for the grid search - */ - void set_doppler_center(int doppler_center) override; - - /*! - * \brief Initializes acquisition algorithm. - */ - void init() override; - - /*! - * \brief Sets local code for Galileo E1 PCPS acquisition algorithm. - */ - void set_local_code() override; - - /*! - * \brief Returns the maximum peak of grid search - */ - signed int mag() override; - - /*! - * \brief Restart acquisition algorithm - */ - void reset() override; - - /*! - * \brief If state = 1, it forces the block to start acquiring from the first sample - */ - void set_state(int state) override; - - /*! - * \brief Stop running acquisition - */ - void stop_acquisition() override; - - /*! - * \brief Sets the resampler latency to account it in the acquisition code delay estimation - */ - void set_resampler_latency(uint32_t latency_samples) override; - private: - pcps_acquisition_sptr acquisition_; - volk_gnsssdr::vector> code_; - std::weak_ptr channel_fsm_; - gr::blocks::float_to_complex::sptr float_to_complex_; - complex_byte_to_float_x2_sptr cbyte_to_float_x2_; - Gnss_Synchro* gnss_synchro_; - const ConfigurationInterface* configuration_; - Acq_Conf acq_parameters_; - std::string item_type_; - std::string dump_filename_; - std::string role_; - int64_t fs_in_; - size_t item_size_; - float threshold_; - int doppler_center_; - unsigned int vector_length_; - unsigned int code_length_; - unsigned int channel_; - unsigned int doppler_max_; - unsigned int doppler_step_; - unsigned int sampled_ms_; - unsigned int in_streams_; - unsigned int out_streams_; + void code_gen_complex_sampled(own::span> dest, uint32_t prn, int32_t sampling_freq) override; }; diff --git a/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc index 78903a000..ad6494f73 100644 --- a/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc @@ -19,223 +19,19 @@ #include "glonass_l1_ca_pcps_acquisition.h" #include "GLONASS_L1_L2_CA.h" -#include "acq_conf.h" -#include "configuration_interface.h" #include "glonass_l1_signal_replica.h" -#include "gnss_sdr_flags.h" -#include -#if USE_GLOG_AND_GFLAGS -#include -#else -#include -#endif - -#if HAS_STD_SPAN -#include -namespace own = std; -#else -#include -namespace own = gsl_lite; -#endif GlonassL1CaPcpsAcquisition::GlonassL1CaPcpsAcquisition( const ConfigurationInterface* configuration, const std::string& role, unsigned int in_streams, - unsigned int out_streams) : gnss_synchro_(nullptr), - role_(role), - threshold_(0), - channel_(0), - doppler_step_(0), - in_streams_(in_streams), - out_streams_(out_streams) + unsigned int out_streams) : BasePcpsAcquisition(configuration, role, in_streams, out_streams, GLONASS_L1_CA_CODE_RATE_CPS, 100e6, GLONASS_L1_CA_CODE_LENGTH_CHIPS, 1) { - acq_parameters_.ms_per_code = 1; - acq_parameters_.SetFromConfiguration(configuration, role, GLONASS_L1_CA_CODE_RATE_CPS, 100e6); - - DLOG(INFO) << "role " << role; - -#if USE_GLOG_AND_GFLAGS - if (FLAGS_doppler_max != 0) - { - acq_parameters_.doppler_max = FLAGS_doppler_max; - } -#else - if (absl::GetFlag(FLAGS_doppler_max) != 0) - { - acq_parameters_.doppler_max = absl::GetFlag(FLAGS_doppler_max); - } -#endif - doppler_max_ = acq_parameters_.doppler_max; - doppler_step_ = static_cast(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(std::floor(static_cast(acq_parameters_.resampled_fs) / (GLONASS_L1_CA_CODE_RATE_CPS / GLONASS_L1_CA_CODE_LENGTH_CHIPS))); - vector_length_ = static_cast(std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2.0 : 1.0)); - code_ = volk_gnsssdr::vector>(vector_length_); - - sampled_ms_ = acq_parameters_.sampled_ms; - - acquisition_ = pcps_make_acquisition(acq_parameters_); - DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; - - if (item_type_ == "cbyte") - { - cbyte_to_float_x2_ = make_complex_byte_to_float_x2(); - float_to_complex_ = gr::blocks::float_to_complex::make(); - } - - if (in_streams_ > 1) - { - LOG(ERROR) << "This implementation only supports one input stream"; - } - if (out_streams_ > 0) - { - LOG(ERROR) << "This implementation does not provide an output stream"; - } } -void GlonassL1CaPcpsAcquisition::stop_acquisition() +void GlonassL1CaPcpsAcquisition::code_gen_complex_sampled(own::span> dest, uint32_t /*prn*/, int32_t sampling_freq) { - acquisition_->set_active(false); -} - - -void GlonassL1CaPcpsAcquisition::set_threshold(float threshold) -{ - threshold_ = threshold; - - acquisition_->set_threshold(threshold_); -} - - -void GlonassL1CaPcpsAcquisition::set_doppler_max(unsigned int doppler_max) -{ - doppler_max_ = doppler_max; - - acquisition_->set_doppler_max(doppler_max_); -} - - -void GlonassL1CaPcpsAcquisition::set_doppler_step(unsigned int doppler_step) -{ - doppler_step_ = doppler_step; - - acquisition_->set_doppler_step(doppler_step_); -} - - -void GlonassL1CaPcpsAcquisition::set_gnss_synchro(Gnss_Synchro* gnss_synchro) -{ - gnss_synchro_ = gnss_synchro; - - acquisition_->set_gnss_synchro(gnss_synchro_); -} - - -signed int GlonassL1CaPcpsAcquisition::mag() -{ - return acquisition_->mag(); -} - - -void GlonassL1CaPcpsAcquisition::init() -{ - acquisition_->init(); - - set_local_code(); -} - - -void GlonassL1CaPcpsAcquisition::set_local_code() -{ - volk_gnsssdr::vector> code(code_length_); - - glonass_l1_ca_code_gen_complex_sampled(code, fs_in_, 0); - - own::span code_span(code_.data(), vector_length_); - for (unsigned int i = 0; i < sampled_ms_; i++) - { - std::copy_n(code.data(), code_length_, code_span.subspan(i * code_length_, code_length_).data()); - } - - acquisition_->set_local_code(code_.data()); -} - - -void GlonassL1CaPcpsAcquisition::reset() -{ - acquisition_->set_active(true); -} - - -void GlonassL1CaPcpsAcquisition::set_state(int state) -{ - acquisition_->set_state(state); -} - - -void GlonassL1CaPcpsAcquisition::connect(gr::top_block_sptr top_block) -{ - if (item_type_ == "gr_complex" || item_type_ == "cshort") - { - // nothing to connect - } - else if (item_type_ == "cbyte") - { - top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0); - top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1); - top_block->connect(float_to_complex_, 0, acquisition_, 0); - } - else - { - LOG(WARNING) << item_type_ << " unknown acquisition item type"; - } -} - - -void GlonassL1CaPcpsAcquisition::disconnect(gr::top_block_sptr top_block) -{ - if (item_type_ == "gr_complex" || item_type_ == "cshort") - { - // nothing to disconnect - } - else if (item_type_ == "cbyte") - { - // Since a byte-based acq implementation is not available, - // we just convert cshorts to gr_complex - top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0); - top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1); - top_block->disconnect(float_to_complex_, 0, acquisition_, 0); - } - else - { - LOG(WARNING) << item_type_ << " unknown acquisition item type"; - } -} - - -gr::basic_block_sptr GlonassL1CaPcpsAcquisition::get_left_block() -{ - if (item_type_ == "gr_complex" || item_type_ == "cshort") - { - return acquisition_; - } - if (item_type_ == "cbyte") - { - return cbyte_to_float_x2_; - } - - LOG(WARNING) << item_type_ << " unknown acquisition item type"; - return nullptr; -} - - -gr::basic_block_sptr GlonassL1CaPcpsAcquisition::get_right_block() -{ - return acquisition_; + glonass_l1_ca_code_gen_complex_sampled(dest, sampling_freq, 0); } diff --git a/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.h b/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.h index 533508fd7..7478d294c 100644 --- a/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.h +++ b/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.h @@ -20,16 +20,7 @@ #ifndef 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 "complex_byte_to_float_x2.h" -#include "gnss_synchro.h" -#include "pcps_acquisition.h" -#include -#include -#include -#include -#include +#include "base_pcps_acquisition.h" /** \addtogroup Acquisition * \{ */ @@ -43,7 +34,7 @@ class ConfigurationInterface; * \brief This class adapts a PCPS acquisition block to an AcquisitionInterface * for GPS L1 C/A signals */ -class GlonassL1CaPcpsAcquisition : public AcquisitionInterface +class GlonassL1CaPcpsAcquisition : public BasePcpsAcquisition { public: GlonassL1CaPcpsAcquisition( @@ -54,11 +45,6 @@ public: ~GlonassL1CaPcpsAcquisition() = default; - inline std::string role() override - { - return role_; - } - /*! * \brief Returns "GLONASS_L1_CA_PCPS_Acquisition" */ @@ -67,110 +53,8 @@ public: return "GLONASS_L1_CA_PCPS_Acquisition"; } - inline size_t item_size() override - { - return item_size_; - } - - void connect(gr::top_block_sptr top_block) override; - void disconnect(gr::top_block_sptr top_block) override; - gr::basic_block_sptr get_left_block() override; - gr::basic_block_sptr get_right_block() override; - - /*! - * \brief Set acquisition/tracking common Gnss_Synchro object pointer - * to efficiently exchange synchronization data between acquisition and - * tracking blocks - */ - void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; - - /*! - * \brief Set acquisition channel unique ID - */ - inline void set_channel(unsigned int channel) override - { - channel_ = channel; - acquisition_->set_channel(channel_); - } - - /*! - * \brief Set channel fsm associated to this acquisition instance - */ - inline void set_channel_fsm(std::weak_ptr channel_fsm) override - { - channel_fsm_ = std::move(channel_fsm); - acquisition_->set_channel_fsm(channel_fsm_); - } - - /*! - * \brief Set statistics threshold of PCPS algorithm - */ - void set_threshold(float threshold) override; - - /*! - * \brief Set maximum Doppler off grid search - */ - void set_doppler_max(unsigned int doppler_max) override; - - /*! - * \brief Set Doppler steps for the grid search - */ - void set_doppler_step(unsigned int doppler_step) override; - - /*! - * \brief Initializes acquisition algorithm. - */ - void init() override; - - /*! - * \brief Sets local code for GPS L1/CA PCPS acquisition algorithm. - */ - void set_local_code() override; - - /*! - * \brief Returns the maximum peak of grid search - */ - signed int mag() override; - - /*! - * \brief Restart acquisition algorithm - */ - void reset() override; - - /*! - * \brief If state = 1, it forces the block to start acquiring from the first sample - */ - void set_state(int state) override; - - /*! - * \brief Stop running acquisition - */ - void stop_acquisition() override; - - void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override {}; - private: - pcps_acquisition_sptr acquisition_; - volk_gnsssdr::vector> code_; - std::weak_ptr channel_fsm_; - gr::blocks::float_to_complex::sptr float_to_complex_; - complex_byte_to_float_x2_sptr cbyte_to_float_x2_; - Gnss_Synchro* gnss_synchro_; - Acq_Conf acq_parameters_; - std::string item_type_; - std::string dump_filename_; - std::string role_; - int64_t fs_in_; - size_t item_size_; - float threshold_; - unsigned int vector_length_; - unsigned int code_length_; - unsigned int channel_; - unsigned int doppler_max_; - unsigned int doppler_step_; - unsigned int sampled_ms_; - unsigned int in_streams_; - unsigned int out_streams_; + void code_gen_complex_sampled(own::span> dest, uint32_t prn, int32_t sampling_freq) override; }; diff --git a/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.cc index ac2260c0a..ba78a1760 100644 --- a/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.cc @@ -18,223 +18,19 @@ #include "glonass_l2_ca_pcps_acquisition.h" #include "GLONASS_L1_L2_CA.h" -#include "acq_conf.h" -#include "configuration_interface.h" #include "glonass_l2_signal_replica.h" -#include "gnss_sdr_flags.h" -#include -#if USE_GLOG_AND_GFLAGS -#include -#else -#include -#endif - -#if HAS_STD_SPAN -#include -namespace own = std; -#else -#include -namespace own = gsl_lite; -#endif GlonassL2CaPcpsAcquisition::GlonassL2CaPcpsAcquisition( const ConfigurationInterface* configuration, const std::string& role, unsigned int in_streams, - unsigned int out_streams) : gnss_synchro_(nullptr), - role_(role), - threshold_(0), - channel_(0), - doppler_step_(0), - in_streams_(in_streams), - out_streams_(out_streams) + unsigned int out_streams) : BasePcpsAcquisition(configuration, role, in_streams, out_streams, GLONASS_L2_CA_CODE_RATE_CPS, 100e6, GLONASS_L2_CA_CODE_LENGTH_CHIPS, 1) { - acq_parameters_.ms_per_code = 1; - acq_parameters_.SetFromConfiguration(configuration, role, GLONASS_L2_CA_CODE_RATE_CPS, 100e6); - - DLOG(INFO) << "role " << role; - -#if USE_GLOG_AND_GFLAGS - if (FLAGS_doppler_max != 0) - { - acq_parameters_.doppler_max = FLAGS_doppler_max; - } -#else - if (absl::GetFlag(FLAGS_doppler_max) != 0) - { - acq_parameters_.doppler_max = absl::GetFlag(FLAGS_doppler_max); - } -#endif - doppler_max_ = acq_parameters_.doppler_max; - doppler_step_ = static_cast(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(std::floor(static_cast(acq_parameters_.resampled_fs) / (GLONASS_L2_CA_CODE_RATE_CPS / GLONASS_L2_CA_CODE_LENGTH_CHIPS))); - vector_length_ = static_cast(std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2.0 : 1.0)); - code_ = volk_gnsssdr::vector>(vector_length_); - - sampled_ms_ = acq_parameters_.sampled_ms; - - acquisition_ = pcps_make_acquisition(acq_parameters_); - DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; - - if (item_type_ == "cbyte") - { - cbyte_to_float_x2_ = make_complex_byte_to_float_x2(); - float_to_complex_ = gr::blocks::float_to_complex::make(); - } - - if (in_streams_ > 1) - { - LOG(ERROR) << "This implementation only supports one input stream"; - } - if (out_streams_ > 0) - { - LOG(ERROR) << "This implementation does not provide an output stream"; - } } -void GlonassL2CaPcpsAcquisition::stop_acquisition() +void GlonassL2CaPcpsAcquisition::code_gen_complex_sampled(own::span> dest, uint32_t /*prn*/, int32_t sampling_freq) { - acquisition_->set_active(false); -} - - -void GlonassL2CaPcpsAcquisition::set_threshold(float threshold) -{ - threshold_ = threshold; - - acquisition_->set_threshold(threshold_); -} - - -void GlonassL2CaPcpsAcquisition::set_doppler_max(unsigned int doppler_max) -{ - doppler_max_ = doppler_max; - - acquisition_->set_doppler_max(doppler_max_); -} - - -void GlonassL2CaPcpsAcquisition::set_doppler_step(unsigned int doppler_step) -{ - doppler_step_ = doppler_step; - - acquisition_->set_doppler_step(doppler_step_); -} - - -void GlonassL2CaPcpsAcquisition::set_gnss_synchro(Gnss_Synchro* gnss_synchro) -{ - gnss_synchro_ = gnss_synchro; - - acquisition_->set_gnss_synchro(gnss_synchro_); -} - - -signed int GlonassL2CaPcpsAcquisition::mag() -{ - return acquisition_->mag(); -} - - -void GlonassL2CaPcpsAcquisition::init() -{ - acquisition_->init(); - - set_local_code(); -} - - -void GlonassL2CaPcpsAcquisition::set_local_code() -{ - volk_gnsssdr::vector> code(code_length_); - - glonass_l2_ca_code_gen_complex_sampled(code, fs_in_, 0); - - own::span code_span(code_.data(), vector_length_); - for (unsigned int i = 0; i < sampled_ms_; i++) - { - std::copy_n(code.data(), code_length_, code_span.subspan(i * code_length_, code_length_).data()); - } - - acquisition_->set_local_code(code_.data()); -} - - -void GlonassL2CaPcpsAcquisition::reset() -{ - acquisition_->set_active(true); -} - - -void GlonassL2CaPcpsAcquisition::set_state(int state) -{ - acquisition_->set_state(state); -} - - -void GlonassL2CaPcpsAcquisition::connect(gr::top_block_sptr top_block) -{ - if (item_type_ == "gr_complex" || item_type_ == "cshort") - { - // nothing to connect - } - else if (item_type_ == "cbyte") - { - // Since a byte-based acq implementation is not available, - // we just convert cshorts to gr_complex - top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0); - top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1); - top_block->connect(float_to_complex_, 0, acquisition_, 0); - } - else - { - LOG(WARNING) << item_type_ << " unknown acquisition item type"; - } -} - - -void GlonassL2CaPcpsAcquisition::disconnect(gr::top_block_sptr top_block) -{ - if (item_type_ == "gr_complex" || item_type_ == "cshort") - { - // nothing to disconnect - } - else if (item_type_ == "cbyte") - { - top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0); - top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1); - top_block->disconnect(float_to_complex_, 0, acquisition_, 0); - } - else - { - LOG(WARNING) << item_type_ << " unknown acquisition item type"; - } -} - - -gr::basic_block_sptr GlonassL2CaPcpsAcquisition::get_left_block() -{ - if (item_type_ == "gr_complex" || item_type_ == "cshort") - { - return acquisition_; - } - if (item_type_ == "cbyte") - { - return cbyte_to_float_x2_; - } - - LOG(WARNING) << item_type_ << " unknown acquisition item type"; - return nullptr; -} - - -gr::basic_block_sptr GlonassL2CaPcpsAcquisition::get_right_block() -{ - return acquisition_; + glonass_l2_ca_code_gen_complex_sampled(dest, sampling_freq, 0); } diff --git a/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.h b/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.h index b8a6adf45..b9d91337e 100644 --- a/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.h +++ b/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.h @@ -20,6 +20,7 @@ #define GNSS_SDR_GLONASS_L2_CA_PCPS_ACQUISITION_H #include "acq_conf.h" +#include "base_pcps_acquisition.h" #include "channel_fsm.h" #include "complex_byte_to_float_x2.h" #include "gnss_synchro.h" @@ -42,7 +43,7 @@ class ConfigurationInterface; * \brief This class adapts a PCPS acquisition block to an AcquisitionInterface * for GLONASS L2 C/A signals */ -class GlonassL2CaPcpsAcquisition : public AcquisitionInterface +class GlonassL2CaPcpsAcquisition : public BasePcpsAcquisition { public: GlonassL2CaPcpsAcquisition( @@ -53,11 +54,6 @@ public: ~GlonassL2CaPcpsAcquisition() = default; - inline std::string role() override - { - return role_; - } - /*! * \brief Returns "GLONASS_L2_CA_PCPS_Acquisition" */ @@ -66,110 +62,8 @@ public: return "GLONASS_L2_CA_PCPS_Acquisition"; } - inline size_t item_size() override - { - return item_size_; - } - - void connect(gr::top_block_sptr top_block) override; - void disconnect(gr::top_block_sptr top_block) override; - gr::basic_block_sptr get_left_block() override; - gr::basic_block_sptr get_right_block() override; - - /*! - * \brief Set acquisition/tracking common Gnss_Synchro object pointer - * to efficiently exchange synchronization data between acquisition and - * tracking blocks - */ - void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; - - /*! - * \brief Set acquisition channel unique ID - */ - inline void set_channel(unsigned int channel) override - { - channel_ = channel; - acquisition_->set_channel(channel_); - } - - /*! - * \brief Set channel fsm associated to this acquisition instance - */ - inline void set_channel_fsm(std::weak_ptr channel_fsm) override - { - channel_fsm_ = std::move(channel_fsm); - acquisition_->set_channel_fsm(channel_fsm_); - } - - /*! - * \brief Set statistics threshold of PCPS algorithm - */ - void set_threshold(float threshold) override; - - /*! - * \brief Set maximum Doppler off grid search - */ - void set_doppler_max(unsigned int doppler_max) override; - - /*! - * \brief Set Doppler steps for the grid search - */ - void set_doppler_step(unsigned int doppler_step) override; - - /*! - * \brief Initializes acquisition algorithm. - */ - void init() override; - - /*! - * \brief Sets local code for GLONASS L2/CA PCPS acquisition algorithm. - */ - void set_local_code() override; - - /*! - * \brief Returns the maximum peak of grid search - */ - signed int mag() override; - - /*! - * \brief Restart acquisition algorithm - */ - void reset() override; - - /*! - * \brief If state = 1, it forces the block to start acquiring from the first sample - */ - void set_state(int state) override; - - /*! - * \brief Stop running acquisition - */ - void stop_acquisition() override; - - void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override {}; - private: - pcps_acquisition_sptr acquisition_; - volk_gnsssdr::vector> code_; - std::weak_ptr channel_fsm_; - gr::blocks::float_to_complex::sptr float_to_complex_; - complex_byte_to_float_x2_sptr cbyte_to_float_x2_; - Gnss_Synchro* gnss_synchro_; - Acq_Conf acq_parameters_; - std::string item_type_; - std::string dump_filename_; - std::string role_; - int64_t fs_in_; - size_t item_size_; - float threshold_; - unsigned int vector_length_; - unsigned int code_length_; - unsigned int channel_; - unsigned int doppler_max_; - unsigned int doppler_step_; - unsigned int sampled_ms_; - unsigned int in_streams_; - unsigned int out_streams_; + void code_gen_complex_sampled(own::span> dest, uint32_t prn, int32_t sampling_freq) override; }; diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc index 193239030..846861a6a 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc @@ -21,242 +21,19 @@ #include "gps_l1_ca_pcps_acquisition.h" #include "GPS_L1_CA.h" -#include "acq_conf.h" -#include "configuration_interface.h" -#include "gnss_sdr_flags.h" #include "gps_sdr_signal_replica.h" -#include -#if USE_GLOG_AND_GFLAGS -#include -#else -#include -#endif - -#if HAS_STD_SPAN -#include -namespace own = std; -#else -#include -namespace own = gsl_lite; -#endif GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition( const ConfigurationInterface* configuration, const std::string& role, unsigned int in_streams, - unsigned int out_streams) : gnss_synchro_(nullptr), - role_(role), - threshold_(0.0), - doppler_center_(0), - channel_(0), - doppler_step_(0), - in_streams_(in_streams), - out_streams_(out_streams) + unsigned int out_streams) : BasePcpsAcquisition(configuration, role, in_streams, out_streams, GPS_L1_CA_CODE_RATE_CPS, GPS_L1_CA_OPT_ACQ_FS_SPS, GPS_L1_CA_CODE_LENGTH_CHIPS, 1) { - acq_parameters_.ms_per_code = 1; - acq_parameters_.SetFromConfiguration(configuration, role, GPS_L1_CA_CODE_RATE_CPS, GPS_L1_CA_OPT_ACQ_FS_SPS); - - DLOG(INFO) << "role " << role; - -#if USE_GLOG_AND_GFLAGS - if (FLAGS_doppler_max != 0) - { - acq_parameters_.doppler_max = FLAGS_doppler_max; - } -#else - if (absl::GetFlag(FLAGS_doppler_max) != 0) - { - acq_parameters_.doppler_max = absl::GetFlag(FLAGS_doppler_max); - } -#endif - - doppler_max_ = acq_parameters_.doppler_max; - doppler_step_ = static_cast(acq_parameters_.doppler_step); - item_type_ = acq_parameters_.item_type; - item_size_ = acq_parameters_.it_size; - - code_length_ = static_cast(std::floor(static_cast(acq_parameters_.resampled_fs) / (GPS_L1_CA_CODE_RATE_CPS / GPS_L1_CA_CODE_LENGTH_CHIPS))); - vector_length_ = static_cast(std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2.0 : 1.0)); - code_ = volk_gnsssdr::vector>(vector_length_); - - sampled_ms_ = acq_parameters_.sampled_ms; - - acquisition_ = pcps_make_acquisition(acq_parameters_); - DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; - - if (item_type_ == "cbyte") - { - cbyte_to_float_x2_ = make_complex_byte_to_float_x2(); - float_to_complex_ = gr::blocks::float_to_complex::make(); - } - - if (in_streams_ > 1) - { - LOG(ERROR) << "This implementation only supports one input stream"; - } - if (out_streams_ > 0) - { - LOG(ERROR) << "This implementation does not provide an output stream"; - } } -void GpsL1CaPcpsAcquisition::stop_acquisition() +void GpsL1CaPcpsAcquisition::code_gen_complex_sampled(own::span> dest, uint32_t prn, int32_t sampling_freq) { - acquisition_->set_active(false); -} - - -void GpsL1CaPcpsAcquisition::set_threshold(float threshold) -{ - threshold_ = threshold; - - acquisition_->set_threshold(threshold_); -} - - -void GpsL1CaPcpsAcquisition::set_doppler_max(unsigned int doppler_max) -{ - doppler_max_ = doppler_max; - - acquisition_->set_doppler_max(doppler_max_); -} - - -void GpsL1CaPcpsAcquisition::set_doppler_step(unsigned int doppler_step) -{ - doppler_step_ = doppler_step; - - acquisition_->set_doppler_step(doppler_step_); -} - - -void GpsL1CaPcpsAcquisition::set_doppler_center(int doppler_center) -{ - doppler_center_ = doppler_center; - - acquisition_->set_doppler_center(doppler_center_); -} - - -void GpsL1CaPcpsAcquisition::set_gnss_synchro(Gnss_Synchro* gnss_synchro) -{ - gnss_synchro_ = gnss_synchro; - - acquisition_->set_gnss_synchro(gnss_synchro_); -} - - -signed int GpsL1CaPcpsAcquisition::mag() -{ - return acquisition_->mag(); -} - - -void GpsL1CaPcpsAcquisition::init() -{ - acquisition_->init(); -} - - -void GpsL1CaPcpsAcquisition::set_local_code() -{ - volk_gnsssdr::vector> code(code_length_); - - if (acq_parameters_.use_automatic_resampler) - { - gps_l1_ca_code_gen_complex_sampled(code, gnss_synchro_->PRN, acq_parameters_.resampled_fs, 0); - } - else - { - gps_l1_ca_code_gen_complex_sampled(code, gnss_synchro_->PRN, acq_parameters_.fs_in, 0); - } - own::span code_span(code_.data(), vector_length_); - for (unsigned int i = 0; i < sampled_ms_; i++) - { - std::copy_n(code.data(), code_length_, code_span.subspan(i * code_length_, code_length_).data()); - } - - acquisition_->set_local_code(code_.data()); -} - - -void GpsL1CaPcpsAcquisition::reset() -{ - acquisition_->set_active(true); -} - - -void GpsL1CaPcpsAcquisition::set_state(int state) -{ - acquisition_->set_state(state); -} - - -void GpsL1CaPcpsAcquisition::connect(gr::top_block_sptr top_block) -{ - if (item_type_ == "gr_complex" || item_type_ == "cshort") - { - // nothing to connect - } - else if (item_type_ == "cbyte") - { - // Since a byte-based acq implementation is not available, - // we just convert cshorts to gr_complex - top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0); - top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1); - top_block->connect(float_to_complex_, 0, acquisition_, 0); - } - else - { - LOG(WARNING) << item_type_ << " unknown acquisition item type: " << item_type_; - } -} - - -void GpsL1CaPcpsAcquisition::disconnect(gr::top_block_sptr top_block) -{ - if (item_type_ == "gr_complex" || item_type_ == "cshort") - { - // nothing to disconnect - } - else if (item_type_ == "cbyte") - { - top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0); - top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1); - top_block->disconnect(float_to_complex_, 0, acquisition_, 0); - } - else - { - LOG(WARNING) << item_type_ << " unknown acquisition item type" << item_type_; - } -} - - -gr::basic_block_sptr GpsL1CaPcpsAcquisition::get_left_block() -{ - if (item_type_ == "gr_complex" || item_type_ == "cshort") - { - return acquisition_; - } - if (item_type_ == "cbyte") - { - return cbyte_to_float_x2_; - } - - LOG(WARNING) << item_type_ << " unknown acquisition item type" << item_type_; - return nullptr; -} - - -gr::basic_block_sptr GpsL1CaPcpsAcquisition::get_right_block() -{ - return acquisition_; -} - - -void GpsL1CaPcpsAcquisition::set_resampler_latency(uint32_t latency_samples) -{ - acquisition_->set_resampler_latency(latency_samples); + gps_l1_ca_code_gen_complex_sampled(dest, prn, sampling_freq, 0); } diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.h b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.h index 0fd769bce..7e0c55f23 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.h +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.h @@ -22,16 +22,7 @@ #ifndef GNSS_SDR_GPS_L1_CA_PCPS_ACQUISITION_H #define GNSS_SDR_GPS_L1_CA_PCPS_ACQUISITION_H -#include "acq_conf.h" -#include "channel_fsm.h" -#include "complex_byte_to_float_x2.h" -#include "gnss_synchro.h" -#include "pcps_acquisition.h" -#include -#include -#include -#include -#include +#include "base_pcps_acquisition.h" /** \addtogroup Acquisition * Classes for GNSS signal acquisition @@ -47,7 +38,7 @@ class ConfigurationInterface; * \brief This class adapts a PCPS acquisition block to an AcquisitionInterface * for GPS L1 C/A signals */ -class GpsL1CaPcpsAcquisition : public AcquisitionInterface +class GpsL1CaPcpsAcquisition : public BasePcpsAcquisition { public: GpsL1CaPcpsAcquisition( @@ -58,11 +49,6 @@ public: ~GpsL1CaPcpsAcquisition() = default; - inline std::string role() override - { - return role_; - } - /*! * \brief Returns "GPS_L1_CA_PCPS_Acquisition" */ @@ -71,118 +57,8 @@ public: return "GPS_L1_CA_PCPS_Acquisition"; } - inline size_t item_size() override - { - return item_size_; - } - - void connect(gr::top_block_sptr top_block) override; - void disconnect(gr::top_block_sptr top_block) override; - gr::basic_block_sptr get_left_block() override; - gr::basic_block_sptr get_right_block() override; - - /*! - * \brief Set acquisition/tracking common Gnss_Synchro object pointer - * to efficiently exchange synchronization data between acquisition and - * tracking blocks - */ - void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; - - /*! - * \brief Set acquisition channel unique ID - */ - inline void set_channel(unsigned int channel) override - { - channel_ = channel; - acquisition_->set_channel(channel_); - } - - /*! - * \brief Set channel fsm associated to this acquisition instance - */ - inline void set_channel_fsm(std::weak_ptr channel_fsm) override - { - channel_fsm_ = std::move(channel_fsm); - acquisition_->set_channel_fsm(channel_fsm_); - } - - /*! - * \brief Set statistics threshold of PCPS algorithm - */ - void set_threshold(float threshold) override; - - /*! - * \brief Set maximum Doppler off grid search - */ - void set_doppler_max(unsigned int doppler_max) override; - - /*! - * \brief Set Doppler steps for the grid search - */ - void set_doppler_step(unsigned int doppler_step) override; - - /*! - * \brief Set Doppler center for the grid search - */ - void set_doppler_center(int doppler_center) override; - - /*! - * \brief Initializes acquisition algorithm. - */ - void init() override; - - /*! - * \brief Sets local code for GPS L1/CA PCPS acquisition algorithm. - */ - void set_local_code() override; - - /*! - * \brief Returns the maximum peak of grid search - */ - signed int mag() override; - - /*! - * \brief Restart acquisition algorithm - */ - void reset() override; - - /*! - * \brief If state = 1, it forces the block to start acquiring from the first sample - */ - void set_state(int state) override; - - /*! - * \brief Stop running acquisition - */ - void stop_acquisition() override; - - /*! - * \brief Sets the resampler latency to account it in the acquisition code delay estimation - */ - void set_resampler_latency(uint32_t latency_samples) override; - private: - pcps_acquisition_sptr acquisition_; - volk_gnsssdr::vector> code_; - std::weak_ptr channel_fsm_; - gr::blocks::float_to_complex::sptr float_to_complex_; - complex_byte_to_float_x2_sptr cbyte_to_float_x2_; - Gnss_Synchro* gnss_synchro_; - Acq_Conf acq_parameters_; - std::string item_type_; - std::string dump_filename_; - std::string role_; - size_t item_size_; - float threshold_; - int doppler_center_; - unsigned int vector_length_; - unsigned int code_length_; - unsigned int channel_; - unsigned int doppler_max_; - unsigned int doppler_step_; - unsigned int sampled_ms_; - unsigned int in_streams_; - unsigned int out_streams_; + void code_gen_complex_sampled(own::span> dest, uint32_t prn, int32_t sampling_freq) override; }; diff --git a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc index 7ff8ae26a..118d668f5 100644 --- a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc @@ -19,244 +19,19 @@ #include "gps_l2_m_pcps_acquisition.h" #include "GPS_L2C.h" -#include "acq_conf.h" -#include "configuration_interface.h" -#include "gnss_sdr_flags.h" #include "gps_l2c_signal_replica.h" -#include -#if USE_GLOG_AND_GFLAGS -#include -#else -#include -#endif - -#if HAS_STD_SPAN -#include -namespace own = std; -#else -#include -namespace own = gsl_lite; -#endif GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition( const ConfigurationInterface* configuration, const std::string& role, unsigned int in_streams, - unsigned int out_streams) : gnss_synchro_(nullptr), - role_(role), - threshold_(0), - doppler_center_(0), - channel_(0), - doppler_step_(0), - in_streams_(in_streams), - out_streams_(out_streams) + unsigned int out_streams) : BasePcpsAcquisition(configuration, role, in_streams, out_streams, GPS_L2_M_CODE_RATE_CPS, GPS_L2C_OPT_ACQ_FS_SPS, GPS_L2_M_CODE_LENGTH_CHIPS, 20) { - acq_parameters_.ms_per_code = 20; - acq_parameters_.SetFromConfiguration(configuration, role, GPS_L2_M_CODE_RATE_CPS, GPS_L2C_OPT_ACQ_FS_SPS); - - DLOG(INFO) << "Role " << role; - -#if USE_GLOG_AND_GFLAGS - if (FLAGS_doppler_max != 0) - { - acq_parameters_.doppler_max = FLAGS_doppler_max; - } -#else - if (absl::GetFlag(FLAGS_doppler_max) != 0) - { - acq_parameters_.doppler_max = absl::GetFlag(FLAGS_doppler_max); - } -#endif - doppler_max_ = acq_parameters_.doppler_max; - doppler_step_ = static_cast(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(std::floor(static_cast(acq_parameters_.resampled_fs) / (GPS_L2_M_CODE_RATE_CPS / GPS_L2_M_CODE_LENGTH_CHIPS))); - vector_length_ = static_cast(std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2.0 : 1.0)); - code_ = volk_gnsssdr::vector>(vector_length_); - - acquisition_ = pcps_make_acquisition(acq_parameters_); - DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; - - if (item_type_ == "cbyte") - { - cbyte_to_float_x2_ = make_complex_byte_to_float_x2(); - float_to_complex_ = gr::blocks::float_to_complex::make(); - } - - num_codes_ = acq_parameters_.sampled_ms / acq_parameters_.ms_per_code; - if (in_streams_ > 1) - { - LOG(ERROR) << "This implementation only supports one input stream"; - } - if (out_streams_ > 0) - { - LOG(ERROR) << "This implementation does not provide an output stream"; - } } -void GpsL2MPcpsAcquisition::stop_acquisition() +void GpsL2MPcpsAcquisition::code_gen_complex_sampled(own::span> dest, uint32_t prn, int32_t sampling_freq) { - acquisition_->set_active(false); -} - - -void GpsL2MPcpsAcquisition::set_threshold(float threshold) -{ - threshold_ = threshold; - - acquisition_->set_threshold(threshold_); -} - - -void GpsL2MPcpsAcquisition::set_doppler_max(unsigned int doppler_max) -{ - doppler_max_ = doppler_max; - - acquisition_->set_doppler_max(doppler_max_); -} - - -// Be aware that Doppler step should be set to 2/(3T) Hz, where T is the coherent integration time (GPS L2 period is 0.02s) -// Doppler bin minimum size= 33 Hz -void GpsL2MPcpsAcquisition::set_doppler_step(unsigned int doppler_step) -{ - doppler_step_ = doppler_step; - - acquisition_->set_doppler_step(doppler_step_); -} - - -void GpsL2MPcpsAcquisition::set_doppler_center(int doppler_center) -{ - doppler_center_ = doppler_center; - - acquisition_->set_doppler_center(doppler_center_); -} - - -void GpsL2MPcpsAcquisition::set_gnss_synchro(Gnss_Synchro* gnss_synchro) -{ - gnss_synchro_ = gnss_synchro; - - acquisition_->set_gnss_synchro(gnss_synchro_); -} - - -signed int GpsL2MPcpsAcquisition::mag() -{ - return acquisition_->mag(); -} - - -void GpsL2MPcpsAcquisition::init() -{ - acquisition_->init(); -} - - -void GpsL2MPcpsAcquisition::set_local_code() -{ - volk_gnsssdr::vector> code(code_length_); - - if (acq_parameters_.use_automatic_resampler) - { - gps_l2c_m_code_gen_complex_sampled(code, gnss_synchro_->PRN, acq_parameters_.resampled_fs); - } - else - { - gps_l2c_m_code_gen_complex_sampled(code, gnss_synchro_->PRN, fs_in_); - } - - own::span code_span(code_.data(), vector_length_); - for (unsigned int i = 0; i < num_codes_; i++) - { - std::copy_n(code.data(), code_length_, code_span.subspan(i * code_length_, code_length_).data()); - } - - acquisition_->set_local_code(code_.data()); -} - - -void GpsL2MPcpsAcquisition::reset() -{ - acquisition_->set_active(true); -} - - -void GpsL2MPcpsAcquisition::set_state(int state) -{ - acquisition_->set_state(state); -} - - -void GpsL2MPcpsAcquisition::connect(gr::top_block_sptr top_block) -{ - if (item_type_ == "gr_complex" || item_type_ == "cshort") - { - // nothing to connect - } - else if (item_type_ == "cbyte") - { - // Since a byte-based acq implementation is not available, - // we just convert cshorts to gr_complex - top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0); - top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1); - top_block->connect(float_to_complex_, 0, acquisition_, 0); - } - else - { - LOG(WARNING) << item_type_ << " unknown acquisition item type"; - } -} - - -void GpsL2MPcpsAcquisition::disconnect(gr::top_block_sptr top_block) -{ - if (item_type_ == "gr_complex" || item_type_ == "cshort") - { - // nothing to disconnect - } - else if (item_type_ == "cbyte") - { - top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0); - top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1); - top_block->disconnect(float_to_complex_, 0, acquisition_, 0); - } - else - { - LOG(WARNING) << item_type_ << " unknown acquisition item type"; - } -} - - -gr::basic_block_sptr GpsL2MPcpsAcquisition::get_left_block() -{ - if (item_type_ == "gr_complex" || item_type_ == "cshort") - { - return acquisition_; - } - if (item_type_ == "cbyte") - { - return cbyte_to_float_x2_; - } - - LOG(WARNING) << item_type_ << " unknown acquisition item type"; - return nullptr; -} - - -gr::basic_block_sptr GpsL2MPcpsAcquisition::get_right_block() -{ - return acquisition_; -} - - -void GpsL2MPcpsAcquisition::set_resampler_latency(uint32_t latency_samples) -{ - acquisition_->set_resampler_latency(latency_samples); + gps_l2c_m_code_gen_complex_sampled(dest, prn, sampling_freq); } diff --git a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.h b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.h index f485ccd1b..10a5ff8fc 100644 --- a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.h +++ b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.h @@ -20,16 +20,7 @@ #ifndef GNSS_SDR_GPS_L2_M_PCPS_ACQUISITION_H #define GNSS_SDR_GPS_L2_M_PCPS_ACQUISITION_H -#include "channel_fsm.h" -#include "complex_byte_to_float_x2.h" -#include "gnss_synchro.h" -#include "pcps_acquisition.h" -#include -#include -#include -#include -#include -#include +#include "base_pcps_acquisition.h" /** \addtogroup Acquisition * \{ */ @@ -43,7 +34,7 @@ class ConfigurationInterface; * \brief This class adapts a PCPS acquisition block to an AcquisitionInterface * for GPS L2 M signals */ -class GpsL2MPcpsAcquisition : public AcquisitionInterface +class GpsL2MPcpsAcquisition : public BasePcpsAcquisition { public: GpsL2MPcpsAcquisition( @@ -54,11 +45,6 @@ public: ~GpsL2MPcpsAcquisition() = default; - inline std::string role() override - { - return role_; - } - /*! * \brief Returns "GPS_L2_M_PCPS_Acquisition" */ @@ -67,119 +53,8 @@ public: return "GPS_L2_M_PCPS_Acquisition"; } - inline size_t item_size() override - { - return item_size_; - } - - void connect(gr::top_block_sptr top_block) override; - void disconnect(gr::top_block_sptr top_block) override; - gr::basic_block_sptr get_left_block() override; - gr::basic_block_sptr get_right_block() override; - - /*! - * \brief Set acquisition/tracking common Gnss_Synchro object pointer - * to efficiently exchange synchronization data between acquisition and - * tracking blocks - */ - void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; - - /*! - * \brief Set acquisition channel unique ID - */ - inline void set_channel(unsigned int channel) override - { - channel_ = channel; - acquisition_->set_channel(channel_); - } - - /*! - * \brief Set channel fsm associated to this acquisition instance - */ - inline void set_channel_fsm(std::weak_ptr channel_fsm) override - { - channel_fsm_ = std::move(channel_fsm); - acquisition_->set_channel_fsm(channel_fsm_); - } - - /*! - * \brief Set statistics threshold of PCPS algorithm - */ - void set_threshold(float threshold) override; - - /*! - * \brief Set maximum Doppler off grid search - */ - void set_doppler_max(unsigned int doppler_max) override; - - /*! - * \brief Set Doppler steps for the grid search - */ - void set_doppler_step(unsigned int doppler_step) override; - - /*! - * \brief Set Doppler center for the grid search - */ - void set_doppler_center(int doppler_center) override; - - /*! - * \brief Initializes acquisition algorithm. - */ - void init() override; - - /*! - * \brief Sets local code for GPS L2/M PCPS acquisition algorithm. - */ - void set_local_code() override; - - /*! - * \brief Returns the maximum peak of grid search - */ - signed int mag() override; - - /*! - * \brief Restart acquisition algorithm - */ - void reset() override; - - /*! - * \brief If state = 1, it forces the block to start acquiring from the first sample - */ - void set_state(int state) override; - - /*! - * \brief Stop running acquisition - */ - void stop_acquisition() override; - - /*! - * \brief Sets the resampler latency to account it in the acquisition code delay estimation - */ - void set_resampler_latency(uint32_t latency_samples) override; - private: - pcps_acquisition_sptr acquisition_; - volk_gnsssdr::vector> code_; - gr::blocks::float_to_complex::sptr float_to_complex_; - complex_byte_to_float_x2_sptr cbyte_to_float_x2_; - std::weak_ptr channel_fsm_; - Gnss_Synchro* gnss_synchro_; - Acq_Conf acq_parameters_; - std::string item_type_; - std::string dump_filename_; - std::string role_; - size_t item_size_; - int64_t fs_in_; - float threshold_; - int doppler_center_; - unsigned int vector_length_; - unsigned int code_length_; - unsigned int channel_; - unsigned int doppler_max_; - unsigned int doppler_step_; - unsigned int in_streams_; - unsigned int out_streams_; - unsigned int num_codes_; + void code_gen_complex_sampled(own::span> dest, uint32_t prn, int32_t sampling_freq) override; }; diff --git a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc index 8a94303e0..eecd5d478 100644 --- a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc @@ -19,246 +19,19 @@ #include "gps_l5i_pcps_acquisition.h" #include "GPS_L5.h" -#include "acq_conf.h" -#include "configuration_interface.h" -#include "gnss_sdr_flags.h" #include "gps_l5_signal_replica.h" -#include -#if USE_GLOG_AND_GFLAGS -#include -#else -#include -#endif - -#if HAS_STD_SPAN -#include -namespace own = std; -#else -#include -namespace own = gsl_lite; -#endif GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition( const ConfigurationInterface* configuration, const std::string& role, unsigned int in_streams, - unsigned int out_streams) : gnss_synchro_(nullptr), - role_(role), - threshold_(0.0), - doppler_center_(0), - channel_(0), - doppler_step_(0), - in_streams_(in_streams), - out_streams_(out_streams) + unsigned int out_streams) : BasePcpsAcquisition(configuration, role, in_streams, out_streams, GPS_L5I_CODE_RATE_CPS, GPS_L5_OPT_ACQ_FS_SPS, GPS_L5I_CODE_LENGTH_CHIPS, 1) { - acq_parameters_.ms_per_code = 1; - acq_parameters_.SetFromConfiguration(configuration, role, GPS_L5I_CODE_RATE_CPS, GPS_L5_OPT_ACQ_FS_SPS); - - DLOG(INFO) << "role " << role; - -#if USE_GLOG_AND_GFLAGS - if (FLAGS_doppler_max != 0) - { - acq_parameters_.doppler_max = FLAGS_doppler_max; - } -#else - if (absl::GetFlag(FLAGS_doppler_max) != 0) - { - acq_parameters_.doppler_max = absl::GetFlag(FLAGS_doppler_max); - } -#endif - - doppler_max_ = acq_parameters_.doppler_max; - doppler_step_ = static_cast(acq_parameters_.doppler_step); - item_type_ = acq_parameters_.item_type; - item_size_ = acq_parameters_.it_size; - - code_length_ = static_cast(std::floor(static_cast(acq_parameters_.resampled_fs) / (GPS_L5I_CODE_RATE_CPS / GPS_L5I_CODE_LENGTH_CHIPS))); - vector_length_ = static_cast(std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2.0 : 1.0)); - code_ = volk_gnsssdr::vector>(vector_length_); - fs_in_ = acq_parameters_.fs_in; - - num_codes_ = acq_parameters_.sampled_ms; - - acquisition_ = pcps_make_acquisition(acq_parameters_); - DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; - - if (item_type_ == "cbyte") - { - cbyte_to_float_x2_ = make_complex_byte_to_float_x2(); - float_to_complex_ = gr::blocks::float_to_complex::make(); - } - - if (in_streams_ > 1) - { - LOG(ERROR) << "This implementation only supports one input stream"; - } - if (out_streams_ > 0) - { - LOG(ERROR) << "This implementation does not provide an output stream"; - } } -void GpsL5iPcpsAcquisition::stop_acquisition() +void GpsL5iPcpsAcquisition::code_gen_complex_sampled(own::span> dest, uint32_t prn, int32_t sampling_freq) { - acquisition_->set_active(false); -} - - -void GpsL5iPcpsAcquisition::set_threshold(float threshold) -{ - threshold_ = threshold; - - acquisition_->set_threshold(threshold_); -} - - -void GpsL5iPcpsAcquisition::set_doppler_max(unsigned int doppler_max) -{ - doppler_max_ = doppler_max; - - acquisition_->set_doppler_max(doppler_max_); -} - - -// Be aware that Doppler step should be set to 2/(3T) Hz, where T is the coherent integration time (GPS L2 period is 0.02s) -// Doppler bin minimum size= 33 Hz -void GpsL5iPcpsAcquisition::set_doppler_step(unsigned int doppler_step) -{ - doppler_step_ = doppler_step; - - acquisition_->set_doppler_step(doppler_step_); -} - - -void GpsL5iPcpsAcquisition::set_doppler_center(int doppler_center) -{ - doppler_center_ = doppler_center; - - acquisition_->set_doppler_center(doppler_center_); -} - - -void GpsL5iPcpsAcquisition::set_gnss_synchro(Gnss_Synchro* gnss_synchro) -{ - gnss_synchro_ = gnss_synchro; - - acquisition_->set_gnss_synchro(gnss_synchro_); -} - - -signed int GpsL5iPcpsAcquisition::mag() -{ - return acquisition_->mag(); -} - - -void GpsL5iPcpsAcquisition::init() -{ - acquisition_->init(); -} - - -void GpsL5iPcpsAcquisition::set_local_code() -{ - volk_gnsssdr::vector> code(code_length_); - - if (acq_parameters_.use_automatic_resampler) - { - gps_l5i_code_gen_complex_sampled(code, gnss_synchro_->PRN, acq_parameters_.resampled_fs); - } - else - { - gps_l5i_code_gen_complex_sampled(code, gnss_synchro_->PRN, fs_in_); - } - - own::span code_span(code_.data(), vector_length_); - for (unsigned int i = 0; i < num_codes_; i++) - { - std::copy_n(code.data(), code_length_, code_span.subspan(i * code_length_, code_length_).data()); - } - - acquisition_->set_local_code(code_.data()); -} - - -void GpsL5iPcpsAcquisition::reset() -{ - acquisition_->set_active(true); -} - - -void GpsL5iPcpsAcquisition::set_state(int state) -{ - acquisition_->set_state(state); -} - - -void GpsL5iPcpsAcquisition::connect(gr::top_block_sptr top_block) -{ - if (item_type_ == "gr_complex" || item_type_ == "cshort") - { - // nothing to connect - } - else if (item_type_ == "cbyte") - { - // Since a byte-based acq implementation is not available, - // we just convert cshorts to gr_complex - top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0); - top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1); - top_block->connect(float_to_complex_, 0, acquisition_, 0); - } - else - { - LOG(WARNING) << item_type_ << " unknown acquisition item type: " << item_type_; - } -} - - -void GpsL5iPcpsAcquisition::disconnect(gr::top_block_sptr top_block) -{ - if (item_type_ == "gr_complex" || item_type_ == "cshort") - { - // nothing to disconnect - } - else if (item_type_ == "cbyte") - { - top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0); - top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1); - top_block->disconnect(float_to_complex_, 0, acquisition_, 0); - } - else - { - LOG(WARNING) << item_type_ << " unknown acquisition item type" << item_type_; - } -} - - -gr::basic_block_sptr GpsL5iPcpsAcquisition::get_left_block() -{ - if (item_type_ == "gr_complex" || item_type_ == "cshort") - { - return acquisition_; - } - if (item_type_ == "cbyte") - { - return cbyte_to_float_x2_; - } - - LOG(WARNING) << item_type_ << " unknown acquisition item type" << item_type_; - return nullptr; -} - - -gr::basic_block_sptr GpsL5iPcpsAcquisition::get_right_block() -{ - return acquisition_; -} - - -void GpsL5iPcpsAcquisition::set_resampler_latency(uint32_t latency_samples) -{ - acquisition_->set_resampler_latency(latency_samples); + gps_l5i_code_gen_complex_sampled(dest, prn, sampling_freq); } diff --git a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.h b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.h index 6230e7a57..7fad5c612 100644 --- a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.h +++ b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.h @@ -20,15 +20,7 @@ #ifndef GNSS_SDR_GPS_L5I_PCPS_ACQUISITION_H #define GNSS_SDR_GPS_L5I_PCPS_ACQUISITION_H -#include "channel_fsm.h" -#include "complex_byte_to_float_x2.h" -#include "gnss_synchro.h" -#include "pcps_acquisition.h" -#include -#include -#include -#include -#include +#include "base_pcps_acquisition.h" /** \addtogroup Acquisition * \{ */ @@ -42,7 +34,7 @@ class ConfigurationInterface; * \brief This class adapts a PCPS acquisition block to an AcquisitionInterface * for GPS L5i signals */ -class GpsL5iPcpsAcquisition : public AcquisitionInterface +class GpsL5iPcpsAcquisition : public BasePcpsAcquisition { public: GpsL5iPcpsAcquisition( @@ -53,11 +45,6 @@ public: ~GpsL5iPcpsAcquisition() = default; - inline std::string role() override - { - return role_; - } - /*! * \brief Returns "GPS_L5i_PCPS_Acquisition" */ @@ -66,119 +53,8 @@ public: return "GPS_L5i_PCPS_Acquisition"; } - inline size_t item_size() override - { - return item_size_; - } - - void connect(gr::top_block_sptr top_block) override; - void disconnect(gr::top_block_sptr top_block) override; - gr::basic_block_sptr get_left_block() override; - gr::basic_block_sptr get_right_block() override; - - /*! - * \brief Set acquisition/tracking common Gnss_Synchro object pointer - * to efficiently exchange synchronization data between acquisition and - * tracking blocks - */ - void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; - - /*! - * \brief Set acquisition channel unique ID - */ - inline void set_channel(unsigned int channel) override - { - channel_ = channel; - acquisition_->set_channel(channel_); - } - - /*! - * \brief Set channel fsm associated to this acquisition instance - */ - inline void set_channel_fsm(std::weak_ptr channel_fsm) override - { - channel_fsm_ = std::move(channel_fsm); - acquisition_->set_channel_fsm(channel_fsm_); - } - - /*! - * \brief Set statistics threshold of PCPS algorithm - */ - void set_threshold(float threshold) override; - - /*! - * \brief Set maximum Doppler off grid search - */ - void set_doppler_max(unsigned int doppler_max) override; - - /*! - * \brief Set Doppler steps for the grid search - */ - void set_doppler_step(unsigned int doppler_step) override; - - /*! - * \brief Set Doppler center for the grid search - */ - void set_doppler_center(int doppler_center) override; - - /*! - * \brief Initializes acquisition algorithm. - */ - void init() override; - - /*! - * \brief Sets local code for GPS L2/M PCPS acquisition algorithm. - */ - void set_local_code() override; - - /*! - * \brief Returns the maximum peak of grid search - */ - signed int mag() override; - - /*! - * \brief Restart acquisition algorithm - */ - void reset() override; - - /*! - * \brief If state = 1, it forces the block to start acquiring from the first sample - */ - void set_state(int state) override; - - /*! - * \brief Stop running acquisition - */ - void stop_acquisition() override; - - /*! - * \brief Sets the resampler latency to account it in the acquisition code delay estimation - */ - void set_resampler_latency(uint32_t latency_samples) override; - private: - pcps_acquisition_sptr acquisition_; - volk_gnsssdr::vector> code_; - gr::blocks::float_to_complex::sptr float_to_complex_; - complex_byte_to_float_x2_sptr cbyte_to_float_x2_; - std::weak_ptr channel_fsm_; - Gnss_Synchro* gnss_synchro_; - Acq_Conf acq_parameters_; - std::string item_type_; - std::string dump_filename_; - std::string role_; - size_t item_size_; - int64_t fs_in_; - float threshold_; - int doppler_center_; - unsigned int vector_length_; - unsigned int code_length_; - unsigned int channel_; - unsigned int doppler_max_; - unsigned int doppler_step_; - unsigned int in_streams_; - unsigned int out_streams_; - unsigned int num_codes_; + void code_gen_complex_sampled(own::span> dest, uint32_t prn, int32_t sampling_freq) override; }; From 7fc42094287af9aa6dc75b5893fcae28b8707377 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sat, 25 Oct 2025 16:56:54 +0200 Subject: [PATCH 2/2] Add base class for FPGA-based acquisition adapters Update changelog --- docs/CHANGELOG.md | 3 + .../acquisition/adapters/CMakeLists.txt | 2 + .../adapters/base_pcps_acquisition_fpga.cc | 252 ++++++++++++++++++ .../adapters/base_pcps_acquisition_fpga.h | 116 ++++++++ ...ileo_e1_pcps_ambiguous_acquisition_fpga.cc | 181 ++----------- ...lileo_e1_pcps_ambiguous_acquisition_fpga.h | 153 +---------- .../galileo_e5a_pcps_acquisition_fpga.cc | 182 ++----------- .../galileo_e5a_pcps_acquisition_fpga.h | 159 +---------- .../galileo_e5b_pcps_acquisition_fpga.cc | 193 ++------------ .../galileo_e5b_pcps_acquisition_fpga.h | 160 +---------- .../gps_l1_ca_pcps_acquisition_fpga.cc | 186 ++----------- .../gps_l1_ca_pcps_acquisition_fpga.h | 155 +---------- .../gps_l2_m_pcps_acquisition_fpga.cc | 177 ++---------- .../adapters/gps_l2_m_pcps_acquisition_fpga.h | 123 +-------- .../adapters/gps_l5i_pcps_acquisition_fpga.cc | 181 ++----------- .../adapters/gps_l5i_pcps_acquisition_fpga.h | 155 +---------- 16 files changed, 509 insertions(+), 1869 deletions(-) create mode 100644 src/algorithms/acquisition/adapters/base_pcps_acquisition_fpga.cc create mode 100644 src/algorithms/acquisition/adapters/base_pcps_acquisition_fpga.h diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 9a4638cec..c9eae4ede 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -33,6 +33,9 @@ All notable changes to GNSS-SDR will be documented in this file. implementations, greatly improving maintainability, simplifying the addition of new signals, and eliminating a lot of duplicated code. Awesome contribution by @MathieuFavreau. +- Added a base class for the main acquisition adapters, improving + maintainability and extensibility. Another excellent contribution by + @MathieuFavreau. - Refactored the internal handling of multi-signal configurations in the PVT block for improved maintainability and extensibility. Another excellent contribution by @MathieuFavreau. diff --git a/src/algorithms/acquisition/adapters/CMakeLists.txt b/src/algorithms/acquisition/adapters/CMakeLists.txt index 6bd9958b1..b191c5de4 100644 --- a/src/algorithms/acquisition/adapters/CMakeLists.txt +++ b/src/algorithms/acquisition/adapters/CMakeLists.txt @@ -55,6 +55,7 @@ set(ACQ_ADAPTER_HEADERS if(ENABLE_FPGA) set(ACQ_ADAPTER_SOURCES ${ACQ_ADAPTER_SOURCES} + base_pcps_acquisition_fpga.cc gps_l1_ca_pcps_acquisition_fpga.cc gps_l2_m_pcps_acquisition_fpga.cc galileo_e1_pcps_ambiguous_acquisition_fpga.cc @@ -63,6 +64,7 @@ if(ENABLE_FPGA) gps_l5i_pcps_acquisition_fpga.cc ) set(ACQ_ADAPTER_HEADERS ${ACQ_ADAPTER_HEADERS} + base_pcps_acquisition_fpga.h gps_l1_ca_pcps_acquisition_fpga.h gps_l2_m_pcps_acquisition_fpga.h galileo_e1_pcps_ambiguous_acquisition_fpga.h diff --git a/src/algorithms/acquisition/adapters/base_pcps_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/base_pcps_acquisition_fpga.cc new file mode 100644 index 000000000..7d3dc6aec --- /dev/null +++ b/src/algorithms/acquisition/adapters/base_pcps_acquisition_fpga.cc @@ -0,0 +1,252 @@ +/*! + * \file base_pcps_acquisition_fpga.cc + * \brief Shared implementation for FPGA-based PCPS acquisition adapters + * \authors Carles Fernandez, 2025. carles.fernandez(at)cttc.cat + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2025 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + + +#include "base_pcps_acquisition_fpga.h" +#include "configuration_interface.h" +#include "gnss_sdr_flags.h" +#include + +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + +BasePcpsAcquisitionFpga::BasePcpsAcquisitionFpga( + const ConfigurationInterface* configuration, + std::string role, + double code_rate_cps, + double code_length_chips, + uint32_t opt_acq_fs_sps, + uint32_t default_fpga_blk_exp, + uint32_t acq_buff, + unsigned int in_streams, + unsigned int out_streams) + : doppler_center_(0), + doppler_max_(0), + doppler_step_(0), + role_(std::move(role)), + gnss_synchro_(nullptr), + channel_(0), + in_streams_(in_streams), + out_streams_(out_streams) +{ + if (in_streams_ > 1) + { + LOG(ERROR) << "This implementation only supports one input stream"; + } + if (out_streams_ > 0) + { + LOG(ERROR) << "This implementation does not provide an output stream"; + } + + // set acquisition parameters + acq_parameters_.SetFromConfiguration(configuration, role_, default_fpga_blk_exp, code_rate_cps, code_length_chips); + + // Query the capabilities of the instantiated FPGA Acquisition IP Core + std::vector> downsampling_filter_specs; + uint32_t max_FFT_size; + acquisition_fpga_ = pcps_make_acquisition_fpga(&acq_parameters_, acq_buff, downsampling_filter_specs, max_FFT_size); + + // Configure the automatic resampler according to the capabilities of the instantiated FPGA Acquisition IP Core. + // When the FPGA is in use, the acquisition resampler operates only in the L1/E1 frequency band. + if (acq_buff == 0) + { + bool acq_configuration_valid = acq_parameters_.ConfigureAutomaticResampler(downsampling_filter_specs, max_FFT_size, opt_acq_fs_sps); + if (!acq_configuration_valid) + { + std::cout << "The FPGA acquisition IP does not support the required sampling frequency of " << acq_parameters_.fs_in << " SPS for the L1/E1 band. Please update the sampling frequency in the configuration file." << std::endl; + exit(0); + } + } + else + { + bool acq_configuration_valid = acq_parameters_.Is_acq_config_valid(max_FFT_size); + if (!acq_configuration_valid) + { + std::cout << "The FPGA acquisition IP does not support the required sampling frequency of " << acq_parameters_.fs_in << " SPS for the L2/L5 band. Please update the sampling frequency in the configuration file." << std::endl; + exit(0); + } + } + + DLOG(INFO) << "role " << role_; + +#if USE_GLOG_AND_GFLAGS + if (FLAGS_doppler_max != 0) + { + acq_parameters_.doppler_max = FLAGS_doppler_max; + } +#else + if (absl::GetFlag(FLAGS_doppler_max) != 0) + { + acq_parameters_.doppler_max = absl::GetFlag(FLAGS_doppler_max); + } +#endif + doppler_max_ = acq_parameters_.doppler_max; + doppler_step_ = static_cast(acq_parameters_.doppler_step); +} + + +void BasePcpsAcquisitionFpga::connect(gr::top_block_sptr top_block) +{ + if (top_block) + { + // FPGA acquisition blocks usually don’t connect to GNU Radio flowgraphs + } +} + + +void BasePcpsAcquisitionFpga::disconnect(gr::top_block_sptr top_block) +{ + if (top_block) + { + // No connections to remove + } +} + + +gr::basic_block_sptr BasePcpsAcquisitionFpga::get_left_block() +{ + return nullptr; +} + + +gr::basic_block_sptr BasePcpsAcquisitionFpga::get_right_block() +{ + return nullptr; +} + + +void BasePcpsAcquisitionFpga::set_gnss_synchro(Gnss_Synchro* gnss_synchro) +{ + gnss_synchro_ = gnss_synchro; + if (acquisition_fpga_) + { + acquisition_fpga_->set_gnss_synchro(gnss_synchro_); + } +} + + +void BasePcpsAcquisitionFpga::set_channel(unsigned int channel) +{ + channel_ = channel; + if (acquisition_fpga_) + { + acquisition_fpga_->set_channel(channel_); + } +} + + +void BasePcpsAcquisitionFpga::set_channel_fsm(std::weak_ptr channel_fsm) +{ + channel_fsm_ = std::move(channel_fsm); + if (acquisition_fpga_) + { + acquisition_fpga_->set_channel_fsm(channel_fsm_); + } +} + + +void BasePcpsAcquisitionFpga::set_threshold(float threshold) +{ + if (acquisition_fpga_) + { + acquisition_fpga_->set_threshold(threshold); + } +} + + +void BasePcpsAcquisitionFpga::set_doppler_max(unsigned int doppler_max) +{ + doppler_max_ = doppler_max; + if (acquisition_fpga_) + { + acquisition_fpga_->set_doppler_max(doppler_max_); + } +} + + +void BasePcpsAcquisitionFpga::set_doppler_step(unsigned int doppler_step) +{ + doppler_step_ = doppler_step; + if (acquisition_fpga_) + { + acquisition_fpga_->set_doppler_step(doppler_step_); + } +} + + +void BasePcpsAcquisitionFpga::set_doppler_center(int doppler_center) +{ + doppler_center_ = doppler_center; + if (acquisition_fpga_) + { + acquisition_fpga_->set_doppler_center(doppler_center_); + } +} + + +void BasePcpsAcquisitionFpga::set_state(int state) +{ + if (acquisition_fpga_) + { + acquisition_fpga_->set_state(state); + } +} + + +void BasePcpsAcquisitionFpga::reset() +{ + if (acquisition_fpga_) + { + acquisition_fpga_->set_active(true); + } +} + + +void BasePcpsAcquisitionFpga::stop_acquisition() +{ + if (acquisition_fpga_) + { + acquisition_fpga_->stop_acquisition(); + } +} + + +void BasePcpsAcquisitionFpga::init() +{ + if (acquisition_fpga_) + { + acquisition_fpga_->init(); + } +} + + +signed int BasePcpsAcquisitionFpga::mag() +{ + if (acquisition_fpga_) + { + return acquisition_fpga_->mag(); + } + return 0; +} + + +void BasePcpsAcquisitionFpga::set_local_code() +{ + acquisition_fpga_->set_local_code(); +} diff --git a/src/algorithms/acquisition/adapters/base_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/base_pcps_acquisition_fpga.h new file mode 100644 index 000000000..10ee76b6f --- /dev/null +++ b/src/algorithms/acquisition/adapters/base_pcps_acquisition_fpga.h @@ -0,0 +1,116 @@ +/*! + * \file base_pcps_acquisition_fpga.h + * \brief Shared implementation for FPGA-based PCPS acquisition adapters + * \authors Carles Fernandez, 2025. carles.fernandez(at)cttc.cat + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2025 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + + +#ifndef GNSS_SDR_BASE_PCPS_ACQUISITION_FPGA_H +#define GNSS_SDR_BASE_PCPS_ACQUISITION_FPGA_H + +#include "acq_conf_fpga.h" +#include "channel_fsm.h" +#include "gnss_synchro.h" +#include "pcps_acquisition_fpga.h" +#include // for basic_block_sptr, top_block_sptr +#include +#include +#include +#include +#include +#include + +/** \addtogroup Acquisition + * Classes for GNSS signal acquisition + * \{ */ +/** \addtogroup Acq_adapters acquisition_adapters + * Wrap GNU Radio acquisition blocks with an AcquisitionInterface + * \{ */ + +class ConfigurationInterface; + +/*! + * \brief Base class providing shared logic for FPGA-based GPS PCPS acquisition adapters. + */ +class BasePcpsAcquisitionFpga : public AcquisitionInterface +{ +public: + BasePcpsAcquisitionFpga(const ConfigurationInterface* configuration, + std::string role, + double code_rate_cps, + double code_length_chips, + uint32_t opt_acq_fs_sps, + uint32_t default_fpga_blk_exp, + uint32_t acq_buff, + unsigned int in_streams, + unsigned int out_streams); + + ~BasePcpsAcquisitionFpga() override = default; + + inline std::string role() override final { return role_; } + + inline size_t item_size() override { return sizeof(int16_t); } + + // Common AcquisitionInterface overrides + void connect(gr::top_block_sptr top_block) override; + void disconnect(gr::top_block_sptr top_block) override; + gr::basic_block_sptr get_left_block() override; + gr::basic_block_sptr get_right_block() override; + + signed int mag() override; + void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; + void set_channel(unsigned int channel) override; + void set_channel_fsm(std::weak_ptr channel_fsm) override; + void set_threshold(float threshold) override; + void set_doppler_max(unsigned int doppler_max) override; + void set_doppler_step(unsigned int doppler_step) override; + void set_doppler_center(int doppler_center) override; + void set_state(int state) override; + void reset() override; + void stop_acquisition() override; + void init() override; + void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override {} + void set_local_code() override; + +protected: + // Members subclasses can use + static const uint32_t QUANT_BITS_LOCAL_CODE = 16; + static const uint32_t SELECT_LSBITS = 0x0000FFFF; // Select the 10 LSbits out of a 20-bit word + static const uint32_t SELECT_MSBITS = 0xFFFF0000; // Select the 10 MSbits out of a 20-bit word + static const uint32_t SELECT_ALL_CODE_BITS = 0xFFFFFFFF; // Select a 20 bit word + static const uint32_t SHL_CODE_BITS = 65536; // shift left by 10 bits + static const uint32_t ACQ_BUFF_0 = 0; // FPGA Acquisition IP buffer containing L1/E1 frequency band samples by default. + static const uint32_t ACQ_BUFF_1 = 1; // FPGA Acquisition IP buffer containing L2 or L5/E5 frequency band samples by default. + + // Members subclasses must set + pcps_acquisition_fpga_sptr acquisition_fpga_; + volk_gnsssdr::vector d_all_fft_codes_; + Acq_Conf_Fpga acq_parameters_; + int32_t doppler_center_; + uint32_t doppler_max_; + uint32_t doppler_step_; + +private: + // Managed entirely by the base class + std::weak_ptr channel_fsm_; + std::string role_; + Gnss_Synchro* gnss_synchro_; + uint32_t channel_; + unsigned int in_streams_; + unsigned int out_streams_; +}; + + +/** \} */ +/** \} */ +#endif // GNSS_SDR_BASE_PCPS_ACQUISITION_FPGA_H \ No newline at end of file diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.cc index 12c0426f8..831dcae06 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.cc @@ -20,12 +20,12 @@ #include "configuration_interface.h" #include "galileo_e1_signal_replica.h" #include "gnss_sdr_fft.h" -#include "gnss_sdr_flags.h" #include // for fft_complex #include // for gr_complex #include // for volk_32fc_conjugate_32fc #include #include // for copy_n +#include // for array #include // for abs, pow, floor #include // for complex @@ -40,65 +40,26 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga( const std::string& role, unsigned int in_streams, unsigned int out_streams) - : gnss_synchro_(nullptr), - role_(role), - doppler_center_(0), - channel_(0), - doppler_step_(0), - in_streams_(in_streams), - out_streams_(out_streams), - acquire_pilot_(configuration->property(role + ".acquire_pilot", false)) + : BasePcpsAcquisitionFpga(configuration, + role, + GALILEO_E1_CODE_CHIP_RATE_CPS, + GALILEO_E1_B_CODE_LENGTH_CHIPS, + GALILEO_E1_OPT_ACQ_FS_SPS, + DEFAULT_FPGA_BLK_EXP, + ACQ_BUFF_0, + in_streams, + out_streams) { - // Set acquisition parameters - acq_parameters_.SetFromConfiguration(configuration, role_, DEFAULT_FPGA_BLK_EXP, GALILEO_E1_CODE_CHIP_RATE_CPS, GALILEO_E1_B_CODE_LENGTH_CHIPS); - - // Query the capabilities of the instantiated FPGA Acquisition IP Core - std::vector> downsampling_filter_specs; - uint32_t max_FFT_size; - acquisition_fpga_ = pcps_make_acquisition_fpga(&acq_parameters_, ACQ_BUFF_0, downsampling_filter_specs, max_FFT_size); - - // Configure the automatic resampler according to the capabilities of the instantiated FPGA Acquisition IP Core. - // When the FPGA is in use, the acquisition resampler operates only in the L1/E1 frequency band. - bool acq_configuration_valid = acq_parameters_.ConfigureAutomaticResampler(downsampling_filter_specs, max_FFT_size, GALILEO_E1_OPT_ACQ_FS_SPS); - - if (!acq_configuration_valid) - { - std::cout << "The FPGA acquisition IP does not support the required sampling frequency of " << acq_parameters_.fs_in << " SPS for the L1/E1 band. Please update the sampling frequency in the configuration file." << std::endl; - exit(0); - } - - DLOG(INFO) << "role " << role; - + acquire_pilot_ = configuration->property(role + ".acquire_pilot", false); generate_galileo_e1_prn_codes(); - -#if USE_GLOG_AND_GFLAGS - if (FLAGS_doppler_max != 0) - { - acq_parameters_.doppler_max = FLAGS_doppler_max; - } -#else - if (absl::GetFlag(FLAGS_doppler_max) != 0) - { - acq_parameters_.doppler_max = absl::GetFlag(FLAGS_doppler_max); - } -#endif - doppler_max_ = acq_parameters_.doppler_max; - doppler_step_ = static_cast(acq_parameters_.doppler_step); - - if (in_streams_ > 1) - { - LOG(ERROR) << "This implementation only supports one input stream"; - } - if (out_streams_ > 0) - { - LOG(ERROR) << "This implementation does not provide an output stream"; - } + DLOG(INFO) << "Initialized FPGA acquisition adapter for role " << role; } + void GalileoE1PcpsAmbiguousAcquisitionFpga::generate_galileo_e1_prn_codes() { - uint32_t code_length = acq_parameters_.code_length; - uint32_t nsamples_total = acq_parameters_.fft_size; + const uint32_t code_length = acq_parameters_.code_length; + const uint32_t nsamples_total = acq_parameters_.fft_size; // compute all the GALILEO E1 PRN Codes (this is done only once in the class constructor in order to avoid re-computing the PRN codes every time // a channel is assigned) @@ -112,7 +73,7 @@ void GalileoE1PcpsAmbiguousAcquisitionFpga::generate_galileo_e1_prn_codes() int32_t tmp2; int32_t local_code; int32_t fft_data; - for (uint32_t PRN = 1; PRN <= GALILEO_E1_NUMBER_OF_CODES; PRN++) + for (uint32_t prn = 1; prn <= GALILEO_E1_NUMBER_OF_CODES; prn++) { bool cboc = false; // cboc is set to 0 when using the FPGA @@ -121,13 +82,13 @@ void GalileoE1PcpsAmbiguousAcquisitionFpga::generate_galileo_e1_prn_codes() // set local signal generator to Galileo E1 pilot component (1C) std::array pilot_signal = {{'1', 'C', '\0'}}; galileo_e1_code_gen_complex_sampled(code, pilot_signal, - cboc, PRN, acq_parameters_.resampled_fs, 0, false); + cboc, prn, acq_parameters_.resampled_fs, 0, false); } else { std::array data_signal = {{'1', 'B', '\0'}}; galileo_e1_code_gen_complex_sampled(code, data_signal, - cboc, PRN, acq_parameters_.resampled_fs, 0, false); + cboc, prn, acq_parameters_.resampled_fs, 0, false); } if (acq_parameters_.enable_zero_padding) @@ -138,7 +99,6 @@ void GalileoE1PcpsAmbiguousAcquisitionFpga::generate_galileo_e1_prn_codes() std::fill(code.begin() + (acq_parameters_.enable_zero_padding ? 2 * code_length : code_length), code.end(), std::complex(0.0, 0.0)); } - std::copy_n(code.data(), nsamples_total, fft_if->get_inbuf()); // copy to FFT buffer fft_if->execute(); // Run the FFT of local code volk_32fc_conjugate_32fc(fft_code.data(), fft_if->get_outbuf(), nsamples_total); // conjugate values @@ -164,112 +124,9 @@ void GalileoE1PcpsAmbiguousAcquisitionFpga::generate_galileo_e1_prn_codes() tmp2 = static_cast(floor(fft_code[i].imag() * (pow(2, QUANT_BITS_LOCAL_CODE - 1) - 1) / max)); local_code = (tmp & SELECT_LSBITS) | ((tmp2 * SHL_CODE_BITS) & SELECT_MSBITS); // put together the real part and the imaginary part fft_data = local_code & SELECT_ALL_CODE_BITS; - d_all_fft_codes_[i + (nsamples_total * (PRN - 1))] = fft_data; + d_all_fft_codes_[i + (nsamples_total * (prn - 1))] = fft_data; } } acq_parameters_.all_fft_codes = d_all_fft_codes_.data(); } - -void GalileoE1PcpsAmbiguousAcquisitionFpga::stop_acquisition() -{ - // stop the acquisition and the other FPGA modules. - acquisition_fpga_->stop_acquisition(); -} - - -void GalileoE1PcpsAmbiguousAcquisitionFpga::set_threshold(float threshold) -{ - DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold; - acquisition_fpga_->set_threshold(threshold); -} - - -void GalileoE1PcpsAmbiguousAcquisitionFpga::set_doppler_max(unsigned int doppler_max) -{ - doppler_max_ = doppler_max; - acquisition_fpga_->set_doppler_max(doppler_max_); -} - - -void GalileoE1PcpsAmbiguousAcquisitionFpga::set_doppler_step(unsigned int doppler_step) -{ - doppler_step_ = doppler_step; - acquisition_fpga_->set_doppler_step(doppler_step_); -} - - -void GalileoE1PcpsAmbiguousAcquisitionFpga::set_doppler_center(int doppler_center) -{ - doppler_center_ = doppler_center; - - acquisition_fpga_->set_doppler_center(doppler_center_); -} - - -void GalileoE1PcpsAmbiguousAcquisitionFpga::set_gnss_synchro(Gnss_Synchro* gnss_synchro) -{ - gnss_synchro_ = gnss_synchro; - acquisition_fpga_->set_gnss_synchro(gnss_synchro_); -} - - -signed int GalileoE1PcpsAmbiguousAcquisitionFpga::mag() -{ - return acquisition_fpga_->mag(); -} - - -void GalileoE1PcpsAmbiguousAcquisitionFpga::init() -{ - acquisition_fpga_->init(); -} - - -void GalileoE1PcpsAmbiguousAcquisitionFpga::set_local_code() -{ - acquisition_fpga_->set_local_code(); -} - - -void GalileoE1PcpsAmbiguousAcquisitionFpga::reset() -{ - // This command starts the acquisition process - acquisition_fpga_->set_active(true); -} - - -void GalileoE1PcpsAmbiguousAcquisitionFpga::set_state(int state) -{ - acquisition_fpga_->set_state(state); -} - - -void GalileoE1PcpsAmbiguousAcquisitionFpga::connect(gr::top_block_sptr top_block) -{ - if (top_block) - { /* top_block is not null */ - }; - // Nothing to connect -} - - -void GalileoE1PcpsAmbiguousAcquisitionFpga::disconnect(gr::top_block_sptr top_block) -{ - if (top_block) - { /* top_block is not null */ - }; - // Nothing to disconnect -} - - -gr::basic_block_sptr GalileoE1PcpsAmbiguousAcquisitionFpga::get_left_block() -{ - return nullptr; -} - - -gr::basic_block_sptr GalileoE1PcpsAmbiguousAcquisitionFpga::get_right_block() -{ - return nullptr; -} diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.h b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.h index 6e660fa7c..2fb1e5bd3 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.h @@ -18,15 +18,7 @@ #ifndef GNSS_SDR_GALILEO_E1_PCPS_AMBIGUOUS_ACQUISITION_FPGA_H #define GNSS_SDR_GALILEO_E1_PCPS_AMBIGUOUS_ACQUISITION_FPGA_H -#include "acq_conf_fpga.h" -#include "channel_fsm.h" -#include "gnss_synchro.h" -#include "pcps_acquisition_fpga.h" -#include -#include -#include -#include -#include +#include "base_pcps_acquisition_fpga.h" /** \addtogroup Acquisition * \{ */ @@ -40,7 +32,7 @@ class ConfigurationInterface; * \brief This class adapts a PCPS acquisition block off-loaded on an FPGA * to an AcquisitionInterface for Galileo E1 Signals */ -class GalileoE1PcpsAmbiguousAcquisitionFpga : public AcquisitionInterface +class GalileoE1PcpsAmbiguousAcquisitionFpga : public BasePcpsAcquisitionFpga { public: /*! @@ -52,19 +44,6 @@ public: unsigned int in_streams, unsigned int out_streams); - /*! - * \brief Destructor - */ - ~GalileoE1PcpsAmbiguousAcquisitionFpga() = default; - - /*! - * \brief Role - */ - inline std::string role() override - { - return role_; - } - /*! * \brief Returns "Galileo_E1_PCPS_Ambiguous_Acquisition_FPGA" */ @@ -73,137 +52,9 @@ public: return "Galileo_E1_PCPS_Ambiguous_Acquisition_FPGA"; } - /*! - * \brief Returns size of lv_16sc_t - */ - size_t item_size() override - { - return sizeof(int16_t); - } - - /*! - * \brief Connect - */ - void connect(gr::top_block_sptr top_block) override; - - /*! - * \brief Disconnect - */ - void disconnect(gr::top_block_sptr top_block) override; - - /*! - * \brief Get left block - */ - gr::basic_block_sptr get_left_block() override; - - /*! - * \brief Get right block - */ - gr::basic_block_sptr get_right_block() override; - - /*! - * \brief Set acquisition/tracking common Gnss_Synchro object pointer - * to efficiently exchange synchronization data between acquisition and - * tracking blocks - */ - void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; - - /*! - * \brief Set acquisition channel unique ID - */ - inline void set_channel(unsigned int channel) override - { - channel_ = channel; - acquisition_fpga_->set_channel(channel_); - } - - /*! - * \brief Set channel fsm associated to this acquisition instance - */ - inline void set_channel_fsm(std::weak_ptr channel_fsm) override - { - channel_fsm_ = std::move(channel_fsm); - acquisition_fpga_->set_channel_fsm(channel_fsm_); - } - - /*! - * \brief Set statistics threshold of PCPS algorithm - */ - void set_threshold(float threshold) override; - - /*! - * \brief Set maximum Doppler off grid search - */ - void set_doppler_max(unsigned int doppler_max) override; - - /*! - * \brief Set Doppler steps for the grid search - */ - void set_doppler_step(unsigned int doppler_step) override; - - /*! - * \brief Set Doppler center for the grid search - */ - void set_doppler_center(int doppler_center) override; - - /*! - * \brief Initializes acquisition algorithm. - */ - void init() override; - - /*! - * \brief Sets local code for Galileo E1 PCPS acquisition algorithm. - */ - void set_local_code() override; - - /*! - * \brief Returns the maximum peak of grid search - */ - signed int mag() override; - - /*! - * \brief Restart acquisition algorithm - */ - void reset() override; - - /*! - * \brief If state = 1, it forces the block to start acquiring from the first sample - */ - void set_state(int state) override; - - /*! - * \brief Stop running acquisition - */ - void stop_acquisition() override; - - /*! - * \brief Set resampler latency - */ - void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override {}; - private: - static const uint32_t ACQ_BUFF_0 = 0; // FPGA Acquisition IP buffer containing L1/E1 frequency band samples by default. static const uint32_t DEFAULT_FPGA_BLK_EXP = 13; // default block exponent - static const uint32_t QUANT_BITS_LOCAL_CODE = 16; - static const uint32_t SELECT_LSBITS = 0x0000FFFF; // Select the 10 LSbits out of a 20-bit word - static const uint32_t SELECT_MSBITS = 0xFFFF0000; // Select the 10 MSbits out of a 20-bit word - static const uint32_t SELECT_ALL_CODE_BITS = 0xFFFFFFFF; // Select a 20 bit word - static const uint32_t SHL_CODE_BITS = 65536; // shift left by 10 bits - void generate_galileo_e1_prn_codes(); - - pcps_acquisition_fpga_sptr acquisition_fpga_; - volk_gnsssdr::vector d_all_fft_codes_; // memory that contains all the code ffts - std::weak_ptr channel_fsm_; - Gnss_Synchro* gnss_synchro_; - Acq_Conf_Fpga acq_parameters_; - std::string role_; - int32_t doppler_center_; - uint32_t channel_; - uint32_t doppler_max_; - uint32_t doppler_step_; - unsigned int in_streams_; - unsigned int out_streams_; bool acquire_pilot_; }; diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.cc index c43787c84..7a146001f 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.cc @@ -20,11 +20,10 @@ #include "configuration_interface.h" #include "galileo_e5_signal_replica.h" #include "gnss_sdr_fft.h" -#include "gnss_sdr_flags.h" -#include // for gr_complex -#include // for volk_32fc_conjugate_32fc +#include // for volk_32fc_conjugate_32fc #include #include // for copy_n +#include // for array #include // for abs, pow, floor #include // for complex @@ -39,65 +38,27 @@ GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga( const std::string& role, unsigned int in_streams, unsigned int out_streams) - : gnss_synchro_(nullptr), - role_(role), - doppler_center_(0), - channel_(0), - in_streams_(in_streams), - out_streams_(out_streams), - acq_pilot_(configuration->property(role + ".acquire_pilot", false)), - acq_iq_(configuration->property(role + ".acquire_iq", false)) + : BasePcpsAcquisitionFpga(configuration, + role, + GALILEO_E5A_CODE_CHIP_RATE_CPS, + GALILEO_E5A_CODE_LENGTH_CHIPS, + 0.0, + DEFAULT_FPGA_BLK_EXP, + ACQ_BUFF_1, + in_streams, + out_streams) { - // Set acquisition parameters - acq_parameters_.SetFromConfiguration(configuration, role_, DEFAULT_FPGA_BLK_EXP, GALILEO_E5A_CODE_CHIP_RATE_CPS, GALILEO_E5A_CODE_LENGTH_CHIPS); - - // Query the capabilities of the instantiated FPGA Acquisition IP Core. When the FPGA is in use, the acquisition resampler operates only in the L1/E1 frequency band. - std::vector> downsampling_filter_specs; - uint32_t max_FFT_size; - acquisition_fpga_ = pcps_make_acquisition_fpga(&acq_parameters_, ACQ_BUFF_1, downsampling_filter_specs, max_FFT_size); - - // When the FPGA is in use, the acquisition resampler operates only in the L1/E1 frequency band. - // Check whether the acquisition configuration is supported by the FPGA. - bool acq_configuration_valid = acq_parameters_.Is_acq_config_valid(max_FFT_size); - - if (!acq_configuration_valid) - { - std::cout << "The FPGA acquisition IP does not support the required sampling frequency of " << acq_parameters_.fs_in << " SPS for the L5/E5a band. Please update the sampling frequency in the configuration file." << std::endl; - exit(0); - } - - DLOG(INFO) << "role " << role; - + acq_pilot_ = configuration->property(role + ".acquire_pilot", false); + acq_iq_ = configuration->property(role + ".acquire_iq", false); generate_galileo_e5a_prn_codes(); - -#if USE_GLOG_AND_GFLAGS - if (FLAGS_doppler_max != 0) - { - acq_parameters_.doppler_max = FLAGS_doppler_max; - } -#else - if (absl::GetFlag(FLAGS_doppler_max) != 0) - { - acq_parameters_.doppler_max = absl::GetFlag(FLAGS_doppler_max); - } -#endif - doppler_max_ = acq_parameters_.doppler_max; - doppler_step_ = static_cast(acq_parameters_.doppler_step); - - if (in_streams_ > 1) - { - LOG(ERROR) << "This implementation only supports one input stream"; - } - if (out_streams_ > 0) - { - LOG(ERROR) << "This implementation does not provide an output stream"; - } + DLOG(INFO) << "Initialized FPGA acquisition adapter for role " << role; } + void GalileoE5aPcpsAcquisitionFpga::generate_galileo_e5a_prn_codes() { - uint32_t code_length = acq_parameters_.code_length; - uint32_t nsamples_total = acq_parameters_.fft_size; + const uint32_t code_length = acq_parameters_.code_length; + const uint32_t nsamples_total = acq_parameters_.fft_size; // compute all the GALILEO E5 PRN Codes (this is done only once in the class constructor in order to avoid re-computing the PRN codes every time // a channel is assigned) @@ -117,7 +78,7 @@ void GalileoE5aPcpsAcquisitionFpga::generate_galileo_e5a_prn_codes() int32_t local_code; int32_t fft_data; - for (uint32_t PRN = 1; PRN <= GALILEO_E5A_NUMBER_OF_CODES; PRN++) + for (uint32_t prn = 1; prn <= GALILEO_E5A_NUMBER_OF_CODES; prn++) { std::array signal_; signal_[0] = '5'; @@ -136,7 +97,7 @@ void GalileoE5aPcpsAcquisitionFpga::generate_galileo_e5a_prn_codes() signal_[1] = 'I'; } - galileo_e5_a_code_gen_complex_sampled(code, PRN, signal_, acq_parameters_.fs_in, 0); + galileo_e5_a_code_gen_complex_sampled(code, prn, signal_, acq_parameters_.fs_in, 0); if (acq_parameters_.enable_zero_padding) { @@ -146,7 +107,6 @@ void GalileoE5aPcpsAcquisitionFpga::generate_galileo_e5a_prn_codes() std::fill(code.begin() + (acq_parameters_.enable_zero_padding ? 2 * code_length : code_length), code.end(), std::complex(0.0, 0.0)); } - std::copy_n(code.data(), nsamples_total, fft_if->get_inbuf()); // copy to FFT buffer fft_if->execute(); // Run the FFT of local code volk_32fc_conjugate_32fc(fft_code.data(), fft_if->get_outbuf(), nsamples_total); // conjugate values @@ -171,111 +131,9 @@ void GalileoE5aPcpsAcquisitionFpga::generate_galileo_e5a_prn_codes() tmp2 = static_cast(floor(fft_code[i].imag() * (pow(2, QUANT_BITS_LOCAL_CODE - 1) - 1) / max)); local_code = (tmp & SELECT_LSBITS) | ((tmp2 * SHL_CODE_BITS) & SELECT_MSBITS); // put together the real part and the imaginary part fft_data = local_code & SELECT_ALL_CODE_BITS; - d_all_fft_codes_[i + (nsamples_total * (PRN - 1))] = fft_data; + d_all_fft_codes_[i + (nsamples_total * (prn - 1))] = fft_data; } } acq_parameters_.all_fft_codes = d_all_fft_codes_.data(); } - -void GalileoE5aPcpsAcquisitionFpga::stop_acquisition() -{ - // stop the acquisition and the other FPGA modules. - acquisition_fpga_->stop_acquisition(); -} - - -void GalileoE5aPcpsAcquisitionFpga::set_threshold(float threshold) -{ - DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold; - acquisition_fpga_->set_threshold(threshold); -} - - -void GalileoE5aPcpsAcquisitionFpga::set_doppler_max(unsigned int doppler_max) -{ - doppler_max_ = doppler_max; - acquisition_fpga_->set_doppler_max(doppler_max_); -} - - -void GalileoE5aPcpsAcquisitionFpga::set_doppler_step(unsigned int doppler_step) -{ - doppler_step_ = doppler_step; - acquisition_fpga_->set_doppler_step(doppler_step_); -} - - -void GalileoE5aPcpsAcquisitionFpga::set_doppler_center(int doppler_center) -{ - doppler_center_ = doppler_center; - - acquisition_fpga_->set_doppler_center(doppler_center_); -} - - -void GalileoE5aPcpsAcquisitionFpga::set_gnss_synchro(Gnss_Synchro* gnss_synchro) -{ - gnss_synchro_ = gnss_synchro; - acquisition_fpga_->set_gnss_synchro(gnss_synchro_); -} - - -signed int GalileoE5aPcpsAcquisitionFpga::mag() -{ - return acquisition_fpga_->mag(); -} - - -void GalileoE5aPcpsAcquisitionFpga::init() -{ - acquisition_fpga_->init(); -} - - -void GalileoE5aPcpsAcquisitionFpga::set_local_code() -{ - acquisition_fpga_->set_local_code(); -} - - -void GalileoE5aPcpsAcquisitionFpga::reset() -{ - acquisition_fpga_->set_active(true); -} - - -void GalileoE5aPcpsAcquisitionFpga::set_state(int state) -{ - acquisition_fpga_->set_state(state); -} - - -void GalileoE5aPcpsAcquisitionFpga::connect(gr::top_block_sptr top_block) -{ - if (top_block) - { /* top_block is not null */ - }; - // Nothing to connect -} - - -void GalileoE5aPcpsAcquisitionFpga::disconnect(gr::top_block_sptr top_block) -{ - if (top_block) - { /* top_block is not null */ - }; - // Nothing to disconnect -} - - -gr::basic_block_sptr GalileoE5aPcpsAcquisitionFpga::get_left_block() -{ - return nullptr; -} - - -gr::basic_block_sptr GalileoE5aPcpsAcquisitionFpga::get_right_block() -{ - return nullptr; -} diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.h index 2b210c729..fd071b27e 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.h @@ -18,14 +18,7 @@ #ifndef GNSS_SDR_GALILEO_E5A_PCPS_ACQUISITION_FPGA_H #define GNSS_SDR_GALILEO_E5A_PCPS_ACQUISITION_FPGA_H -#include "acq_conf_fpga.h" -#include "channel_fsm.h" -#include "gnss_synchro.h" -#include "pcps_acquisition_fpga.h" -#include -#include -#include -#include +#include "base_pcps_acquisition_fpga.h" /** \addtogroup Acquisition * \{ */ @@ -40,7 +33,7 @@ class ConfigurationInterface; * \brief This class adapts a PCPS acquisition block off-loaded on an FPGA * to an AcquisitionInterface for Galileo E5a signals */ -class GalileoE5aPcpsAcquisitionFpga : public AcquisitionInterface +class GalileoE5aPcpsAcquisitionFpga : public BasePcpsAcquisitionFpga { public: /*! @@ -52,19 +45,6 @@ public: unsigned int in_streams, unsigned int out_streams); - /*! - * \brief Destructor - */ - ~GalileoE5aPcpsAcquisitionFpga() = default; - - /*! - * \brief Role - */ - inline std::string role() override - { - return role_; - } - /*! * \brief Returns "Galileo_E5a_Pcps_Acquisition_FPGA" */ @@ -73,144 +53,9 @@ public: return "Galileo_E5a_Pcps_Acquisition_FPGA"; } - /*! - * \brief Returns size of lv_16sc_t - */ - inline size_t item_size() override - { - return sizeof(int16_t); - } - - /*! - * \brief Connect - */ - void connect(gr::top_block_sptr top_block) override; - - /*! - * \brief Disconnect - */ - void disconnect(gr::top_block_sptr top_block) override; - - /*! - * \brief Get left block - */ - gr::basic_block_sptr get_left_block() override; - - /*! - * \brief Get right block - */ - gr::basic_block_sptr get_right_block() override; - - /*! - * \brief Set acquisition/tracking common Gnss_Synchro object pointer - * to efficiently exchange synchronization data between acquisition and - * tracking blocks - */ - void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; - - /*! - * \brief Set acquisition channel unique ID - */ - inline void set_channel(unsigned int channel) override - { - channel_ = channel; - acquisition_fpga_->set_channel(channel_); - } - - /*! - * \brief Set channel fsm associated to this acquisition instance - */ - inline void set_channel_fsm(std::weak_ptr channel_fsm) override - { - channel_fsm_ = std::move(channel_fsm); - acquisition_fpga_->set_channel_fsm(channel_fsm_); - } - - /*! - * \brief Set statistics threshold of PCPS algorithm - */ - void set_threshold(float threshold) override; - - /*! - * \brief Set maximum Doppler off grid search - */ - void set_doppler_max(unsigned int doppler_max) override; - - /*! - * \brief Set Doppler steps for the grid search - */ - void set_doppler_step(unsigned int doppler_step) override; - - /*! - * \brief Set Doppler center for the grid search - */ - void set_doppler_center(int doppler_center) override; - - /*! - * \brief Initializes acquisition algorithm. - */ - void init() override; - - /*! - * \brief Sets local Galileo E5a code for PCPS acquisition algorithm. - */ - void set_local_code() override; - - /*! - * \brief Returns the maximum peak of grid search - */ - signed int mag() override; - - /*! - * \brief Restart acquisition algorithm - */ - void reset() override; - - /*! - * \brief If set to 1, ensures that acquisition starts at the - * first available sample. - * \param state - int=1 forces start of acquisition - */ - void set_state(int state) override; - - /*! - * \brief This function is only used in the unit tests - */ - void set_single_doppler_flag(unsigned int single_doppler_flag); - - /*! - * \brief Stop running acquisition - */ - void stop_acquisition() override; - - /*! - * \brief Set resampler latency - */ - void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override {}; - private: - static const uint32_t ACQ_BUFF_1 = 1; // FPGA Acquisition IP buffer containing L2 or L5/E5 frequency band samples by default. static const uint32_t DEFAULT_FPGA_BLK_EXP = 13; // default block exponent - static const uint32_t QUANT_BITS_LOCAL_CODE = 16; - static const uint32_t SELECT_LSBITS = 0x0000FFFF; // Select the 10 LSbits out of a 20-bit word - static const uint32_t SELECT_MSBITS = 0xFFFF0000; // Select the 10 MSbits out of a 20-bit word - static const uint32_t SELECT_ALL_CODE_BITS = 0xFFFFFFFF; // Select a 20 bit word - static const uint32_t SHL_CODE_BITS = 65536; // shift left by 10 bits - void generate_galileo_e5a_prn_codes(); - - pcps_acquisition_fpga_sptr acquisition_fpga_; - std::weak_ptr channel_fsm_; - volk_gnsssdr::vector d_all_fft_codes_; // memory that contains all the code ffts - Gnss_Synchro* gnss_synchro_; - Acq_Conf_Fpga acq_parameters_; - std::string role_; - int32_t doppler_center_; - uint32_t channel_; - uint32_t doppler_max_; - uint32_t doppler_step_; - unsigned int in_streams_; - unsigned int out_streams_; bool acq_pilot_; bool acq_iq_; }; diff --git a/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.cc index b83eb623c..db0d4b440 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.cc @@ -21,12 +21,11 @@ #include "configuration_interface.h" #include "galileo_e5_signal_replica.h" #include "gnss_sdr_fft.h" -#include "gnss_sdr_flags.h" -#include // for gr_complex -#include // for volk_32fc_conjugate_32fc -#include // for copy_n -#include // for abs, pow, floor -#include // for complex +#include // for volk_32fc_conjugate_32fc +#include // for copy_n +#include // for array +#include // for abs, pow, floor +#include // for complex #if USE_GLOG_AND_GFLAGS #include @@ -34,70 +33,32 @@ #include #endif -GalileoE5bPcpsAcquisitionFpga::GalileoE5bPcpsAcquisitionFpga(const ConfigurationInterface* configuration, +GalileoE5bPcpsAcquisitionFpga::GalileoE5bPcpsAcquisitionFpga( + const ConfigurationInterface* configuration, const std::string& role, unsigned int in_streams, unsigned int out_streams) - : gnss_synchro_(nullptr), - role_(role), - doppler_center_(0), - channel_(0), - doppler_step_(0), - in_streams_(in_streams), - out_streams_(out_streams), - acq_pilot_(configuration->property(role + ".acquire_pilot", false)), - acq_iq_(configuration->property(role + ".acquire_iq", false)) + : BasePcpsAcquisitionFpga(configuration, + role, + GALILEO_E5B_CODE_CHIP_RATE_CPS, + GALILEO_E5B_CODE_LENGTH_CHIPS, + 0.0, + DEFAULT_FPGA_BLK_EXP, + ACQ_BUFF_1, + in_streams, + out_streams) { - // Set acquisition parameters - acq_parameters_.SetFromConfiguration(configuration, role_, DEFAULT_FPGA_BLK_EXP, GALILEO_E5B_CODE_CHIP_RATE_CPS, GALILEO_E5B_CODE_LENGTH_CHIPS); - - // Query the capabilities of the instantiated FPGA Acquisition IP Core. When the FPGA is in use, the acquisition resampler operates only in the L1/E1 frequency band. - std::vector> downsampling_filter_specs; - uint32_t max_FFT_size; - acquisition_fpga_ = pcps_make_acquisition_fpga(&acq_parameters_, ACQ_BUFF_1, downsampling_filter_specs, max_FFT_size); - - // When the FPGA is in use, the acquisition resampler operates only in the L1/E1 frequency band. - // Check whether the acquisition configuration is supported by the FPGA. - bool acq_configuration_valid = acq_parameters_.Is_acq_config_valid(max_FFT_size); - - if (!acq_configuration_valid) - { - std::cout << "The FPGA acquisition IP does not support the required sampling frequency of " << acq_parameters_.fs_in << " SPS for the E5b band. Please update the sampling frequency in the configuration file." << std::endl; - exit(0); - } - - DLOG(INFO) << "role " << role; - + acq_pilot_ = configuration->property(role + ".acquire_pilot", false); + acq_iq_ = configuration->property(role + ".acquire_iq", false); generate_galileo_e5b_prn_codes(); - -#if USE_GLOG_AND_GFLAGS - if (FLAGS_doppler_max != 0) - { - acq_parameters_.doppler_max = FLAGS_doppler_max; - } -#else - if (absl::GetFlag(FLAGS_doppler_max) != 0) - { - acq_parameters_.doppler_max = absl::GetFlag(FLAGS_doppler_max); - } -#endif - doppler_max_ = acq_parameters_.doppler_max; - doppler_step_ = static_cast(acq_parameters_.doppler_step); - - if (in_streams_ > 1) - { - LOG(ERROR) << "This implementation only supports one input stream"; - } - if (out_streams_ > 0) - { - LOG(ERROR) << "This implementation does not provide an output stream"; - } + DLOG(INFO) << "Initialized FPGA acquisition adapter for role " << role; } + void GalileoE5bPcpsAcquisitionFpga::generate_galileo_e5b_prn_codes() { - uint32_t code_length = acq_parameters_.code_length; - uint32_t nsamples_total = acq_parameters_.fft_size; + const uint32_t code_length = acq_parameters_.code_length; + const uint32_t nsamples_total = acq_parameters_.fft_size; // compute all the GALILEO E5b PRN Codes (this is done only once in the class constructor in order to avoid re-computing the PRN codes every time // a channel is assigned) @@ -117,7 +78,7 @@ void GalileoE5bPcpsAcquisitionFpga::generate_galileo_e5b_prn_codes() int32_t local_code; int32_t fft_data; - for (uint32_t PRN = 1; PRN <= GALILEO_E5B_NUMBER_OF_CODES; PRN++) + for (uint32_t prn = 1; prn <= GALILEO_E5B_NUMBER_OF_CODES; prn++) { std::array signal_; signal_[0] = '7'; @@ -136,7 +97,7 @@ void GalileoE5bPcpsAcquisitionFpga::generate_galileo_e5b_prn_codes() signal_[1] = 'I'; } - galileo_e5_b_code_gen_complex_sampled(code, PRN, signal_, acq_parameters_.fs_in, 0); + galileo_e5_b_code_gen_complex_sampled(code, prn, signal_, acq_parameters_.fs_in, 0); if (acq_parameters_.enable_zero_padding) { @@ -146,7 +107,6 @@ void GalileoE5bPcpsAcquisitionFpga::generate_galileo_e5b_prn_codes() std::fill(code.begin() + (acq_parameters_.enable_zero_padding ? 2 * code_length : code_length), code.end(), std::complex(0.0, 0.0)); } - std::copy_n(code.data(), nsamples_total, fft_if->get_inbuf()); // copy to FFT buffer fft_if->execute(); // Run the FFT of local code volk_32fc_conjugate_32fc(fft_code.data(), fft_if->get_outbuf(), nsamples_total); // conjugate values @@ -171,112 +131,9 @@ void GalileoE5bPcpsAcquisitionFpga::generate_galileo_e5b_prn_codes() tmp2 = static_cast(floor(fft_code[i].imag() * (pow(2, QUANT_BITS_LOCAL_CODE - 1) - 1) / max)); local_code = (tmp & SELECT_LSBITS) | ((tmp2 * SHL_CODE_BITS) & SELECT_MSBITS); // put together the real part and the imaginary part fft_data = local_code & SELECT_ALL_CODE_BITS; - d_all_fft_codes_[i + (nsamples_total * (PRN - 1))] = fft_data; + d_all_fft_codes_[i + (nsamples_total * (prn - 1))] = fft_data; } } acq_parameters_.all_fft_codes = d_all_fft_codes_.data(); } - -void GalileoE5bPcpsAcquisitionFpga::stop_acquisition() -{ - // this command causes the SW to reset the HW. - acquisition_fpga_->reset_acquisition(); -} - - -void GalileoE5bPcpsAcquisitionFpga::set_threshold(float threshold) -{ - DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold; - acquisition_fpga_->set_threshold(threshold); -} - - -void GalileoE5bPcpsAcquisitionFpga::set_doppler_max(unsigned int doppler_max) -{ - doppler_max_ = doppler_max; - acquisition_fpga_->set_doppler_max(doppler_max_); -} - - -void GalileoE5bPcpsAcquisitionFpga::set_doppler_step(unsigned int doppler_step) -{ - doppler_step_ = doppler_step; - acquisition_fpga_->set_doppler_step(doppler_step_); -} - - -void GalileoE5bPcpsAcquisitionFpga::set_doppler_center(int doppler_center) -{ - doppler_center_ = doppler_center; - acquisition_fpga_->set_doppler_center(doppler_center_); -} - - -void GalileoE5bPcpsAcquisitionFpga::set_gnss_synchro(Gnss_Synchro* gnss_synchro) -{ - gnss_synchro_ = gnss_synchro; - acquisition_fpga_->set_gnss_synchro(gnss_synchro_); -} - - -signed int GalileoE5bPcpsAcquisitionFpga::mag() -{ - return acquisition_fpga_->mag(); -} - - -void GalileoE5bPcpsAcquisitionFpga::init() -{ - acquisition_fpga_->init(); -} - - -void GalileoE5bPcpsAcquisitionFpga::set_local_code() -{ - acquisition_fpga_->set_local_code(); -} - - -void GalileoE5bPcpsAcquisitionFpga::reset() -{ - acquisition_fpga_->set_active(true); -} - - -void GalileoE5bPcpsAcquisitionFpga::set_state(int state) -{ - acquisition_fpga_->set_state(state); -} - - -void GalileoE5bPcpsAcquisitionFpga::connect(gr::top_block_sptr top_block) -{ - if (top_block) - { - /* top_block is not null */ - }; - // Nothing to connect -} - - -void GalileoE5bPcpsAcquisitionFpga::disconnect(gr::top_block_sptr top_block) -{ - if (top_block) - { - /* top_block is not null */ - }; - // Nothing to disconnect -} - - -gr::basic_block_sptr GalileoE5bPcpsAcquisitionFpga::get_left_block() -{ - return nullptr; -} - - -gr::basic_block_sptr GalileoE5bPcpsAcquisitionFpga::get_right_block() -{ - return nullptr; -} diff --git a/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.h index 68707647c..07c074749 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.h @@ -19,14 +19,7 @@ #ifndef GNSS_SDR_GALILEO_E5B_PCPS_ACQUISITION_FPGA_H #define GNSS_SDR_GALILEO_E5B_PCPS_ACQUISITION_FPGA_H -#include "acq_conf_fpga.h" -#include "channel_fsm.h" -#include "gnss_synchro.h" -#include "pcps_acquisition_fpga.h" -#include -#include -#include -#include +#include "base_pcps_acquisition_fpga.h" /** \addtogroup Acquisition * \{ */ @@ -40,7 +33,7 @@ class ConfigurationInterface; * \brief This class adapts a PCPS acquisition block off-loaded on an FPGA * to an AcquisitionInterface for Galileo E5b signals */ -class GalileoE5bPcpsAcquisitionFpga : public AcquisitionInterface +class GalileoE5bPcpsAcquisitionFpga : public BasePcpsAcquisitionFpga { public: /*! @@ -51,19 +44,6 @@ public: unsigned int in_streams, unsigned int out_streams); - /*! - * \brief Destructor - */ - ~GalileoE5bPcpsAcquisitionFpga() = default; - - /*! - * \brief Role - */ - inline std::string role() override - { - return role_; - } - /*! * \brief Returns "Galileo_E5b_Pcps_Acquisition_FPGA" */ @@ -72,145 +52,9 @@ public: return "Galileo_E5b_PCPS_Acquisition_FPGA"; } - /*! - * \brief Returns size of lv_16sc_t - */ - inline size_t item_size() override - { - return sizeof(int16_t); - } - - /*! - * \brief Connect - */ - void connect(gr::top_block_sptr top_block) override; - - /*! - * \brief Disconnect - */ - void disconnect(gr::top_block_sptr top_block) override; - - /*! - * \brief Get left block - */ - gr::basic_block_sptr get_left_block() override; - - /*! - * \brief Get right block - */ - gr::basic_block_sptr get_right_block() override; - - /*! - * \brief Set acquisition/tracking common Gnss_Synchro object pointer - * to efficiently exchange synchronization data between acquisition and - * tracking blocks - */ - void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; - - /*! - * \brief Set acquisition channel unique ID - */ - inline void set_channel(unsigned int channel) override - { - channel_ = channel; - acquisition_fpga_->set_channel(channel_); - } - - /*! - * \brief Set channel fsm associated to this acquisition instance - */ - inline void set_channel_fsm(std::weak_ptr channel_fsm) override - { - channel_fsm_ = std::move(channel_fsm); - acquisition_fpga_->set_channel_fsm(channel_fsm_); - } - - /*! - * \brief Set statistics threshold of PCPS algorithm - */ - void set_threshold(float threshold) override; - - /*! - * \brief Set maximum Doppler off grid search - */ - void set_doppler_max(unsigned int doppler_max) override; - - /*! - * \brief Set Doppler steps for the grid search - */ - void set_doppler_step(unsigned int doppler_step) override; - - /*! - * \brief Set Doppler center for the grid search - */ - void set_doppler_center(int doppler_center) override; - - /*! - * \brief Initializes acquisition algorithm. - */ - void init() override; - - /*! - * \brief Sets local Galileo E5b code for PCPS acquisition algorithm. - */ - void set_local_code() override; - - /*! - * \brief Returns the maximum peak of grid search - */ - signed int mag() override; - - /*! - * \brief Restart acquisition algorithm - */ - void reset() override; - - /*! - * \brief If set to 1, ensures that acquisition starts at the - * first available sample. - * \param state - int=1 forces start of acquisition - */ - void set_state(int state) override; - - /*! - * \brief This function is only used in the unit tests - */ - void set_single_doppler_flag(unsigned int single_doppler_flag); - - /*! - * \brief Stop running acquisition - */ - void stop_acquisition() override; - - /*! - * \brief Set resampler latency - */ - void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override {}; - private: - static const uint32_t ACQ_BUFF_1 = 1; // FPGA Acquisition IP buffer containing L2 or L5/E5 frequency band samples by default. static const uint32_t DEFAULT_FPGA_BLK_EXP = 13; // default block exponent - static const uint32_t QUANT_BITS_LOCAL_CODE = 16; - static const uint32_t SELECT_LSBITS = 0x0000FFFF; // Select the 10 LSbits out of a 20-bit word - static const uint32_t SELECT_MSBITS = 0xFFFF0000; // Select the 10 MSbits out of a 20-bit word - static const uint32_t SELECT_ALL_CODE_BITS = 0xFFFFFFFF; // Select a 20 bit word - static const uint32_t SHL_CODE_BITS = 65536; // shift left by 10 bits - void generate_galileo_e5b_prn_codes(); - - pcps_acquisition_fpga_sptr acquisition_fpga_; - volk_gnsssdr::vector d_all_fft_codes_; // memory that contains all the code ffts - std::weak_ptr channel_fsm_; - - Gnss_Synchro* gnss_synchro_; - Acq_Conf_Fpga acq_parameters_; - std::string role_; - int32_t doppler_center_; - uint32_t channel_; - uint32_t doppler_max_; - uint32_t doppler_step_; - unsigned int in_streams_; - unsigned int out_streams_; bool acq_pilot_; bool acq_iq_; }; diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc index 226078036..be73eccc2 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc @@ -22,13 +22,11 @@ #include "GPS_L1_CA.h" #include "configuration_interface.h" #include "gnss_sdr_fft.h" -#include "gnss_sdr_flags.h" #include "gps_sdr_signal_replica.h" -#include // for gr_complex -#include // for volk_32fc_conjugate_32fc -#include // for copy_n -#include // for abs, pow, floor -#include // for complex +#include // for volk_32fc_conjugate_32fc +#include // for copy_n +#include // for abs, pow, floor +#include // for complex #if USE_GLOG_AND_GFLAGS #include @@ -40,64 +38,27 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga( const ConfigurationInterface* configuration, const std::string& role, unsigned int in_streams, - unsigned int out_streams) : gnss_synchro_(nullptr), - role_(role), - doppler_center_(0), - channel_(0), - doppler_step_(0), - in_streams_(in_streams), - out_streams_(out_streams) + unsigned int out_streams) + : BasePcpsAcquisitionFpga(configuration, + role, + GPS_L1_CA_CODE_RATE_CPS, + GPS_L1_CA_CODE_LENGTH_CHIPS, + GPS_L1_CA_OPT_ACQ_FS_SPS, + DEFAULT_FPGA_BLK_EXP, + ACQ_BUFF_0, + in_streams, + out_streams) { - // set acquisition parameters - acq_parameters_.SetFromConfiguration(configuration, role_, DEFAULT_FPGA_BLK_EXP, GPS_L1_CA_CODE_RATE_CPS, GPS_L1_CA_CODE_LENGTH_CHIPS); - - // Query the capabilities of the instantiated FPGA Acquisition IP Core - std::vector> downsampling_filter_specs; - uint32_t max_FFT_size; - acquisition_fpga_ = pcps_make_acquisition_fpga(&acq_parameters_, ACQ_BUFF_0, downsampling_filter_specs, max_FFT_size); - - // Configure the automatic resampler according to the capabilities of the instantiated FPGA Acquisition IP Core. - // When the FPGA is in use, the acquisition resampler operates only in the L1/E1 frequency band. - bool acq_configuration_valid = acq_parameters_.ConfigureAutomaticResampler(downsampling_filter_specs, max_FFT_size, GPS_L1_CA_OPT_ACQ_FS_SPS); - - if (!acq_configuration_valid) - { - std::cout << "The FPGA acquisition IP does not support the required sampling frequency of " << acq_parameters_.fs_in << " SPS for the L1/E1 band. Please update the sampling frequency in the configuration file." << std::endl; - exit(0); - } - - DLOG(INFO) << "role " << role; - generate_gps_l1_ca_prn_codes(); - -#if USE_GLOG_AND_GFLAGS - if (FLAGS_doppler_max != 0) - { - acq_parameters_.doppler_max = FLAGS_doppler_max; - } -#else - if (absl::GetFlag(FLAGS_doppler_max) != 0) - { - acq_parameters_.doppler_max = absl::GetFlag(FLAGS_doppler_max); - } -#endif - doppler_max_ = acq_parameters_.doppler_max; - doppler_step_ = static_cast(acq_parameters_.doppler_step); - - if (in_streams_ > 1) - { - LOG(ERROR) << "This implementation only supports one input stream"; - } - if (out_streams_ > 0) - { - LOG(ERROR) << "This implementation does not provide an output stream"; - } + DLOG(INFO) << "Initialized FPGA acquisition adapter for role " << role; } + void GpsL1CaPcpsAcquisitionFpga::generate_gps_l1_ca_prn_codes() { - uint32_t code_length = acq_parameters_.code_length; - uint32_t nsamples_total = acq_parameters_.fft_size; + const uint32_t NUM_PRNs = 32; + const uint32_t code_length = acq_parameters_.code_length; + const uint32_t nsamples_total = acq_parameters_.fft_size; // compute all the GPS L1 PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time // a channel is assigned) @@ -112,9 +73,9 @@ void GpsL1CaPcpsAcquisitionFpga::generate_gps_l1_ca_prn_codes() int32_t local_code; int32_t fft_data; // temporary maxima search - for (uint32_t PRN = 1; PRN <= NUM_PRNs; PRN++) + for (uint32_t prn = 1; prn <= NUM_PRNs; prn++) { - gps_l1_ca_code_gen_complex_sampled(code, PRN, acq_parameters_.resampled_fs, 0); // generate PRN code + gps_l1_ca_code_gen_complex_sampled(code, prn, acq_parameters_.resampled_fs, 0); // generate PRN code if (acq_parameters_.enable_zero_padding) { @@ -148,112 +109,9 @@ void GpsL1CaPcpsAcquisitionFpga::generate_gps_l1_ca_prn_codes() tmp2 = static_cast(floor(fft_code[i].imag() * (pow(2, QUANT_BITS_LOCAL_CODE - 1) - 1) / max)); local_code = (tmp & SELECT_LSBITS) | ((tmp2 * SHL_CODE_BITS) & SELECT_MSBITS); // put together the real part and the imaginary part fft_data = local_code & SELECT_ALL_CODE_BITS; - d_all_fft_codes_[i + (nsamples_total * (PRN - 1))] = fft_data; + d_all_fft_codes_[i + (nsamples_total * (prn - 1))] = fft_data; } } acq_parameters_.all_fft_codes = d_all_fft_codes_.data(); } - -void GpsL1CaPcpsAcquisitionFpga::stop_acquisition() -{ - // stop the acquisition and the other FPGA modules. - acquisition_fpga_->stop_acquisition(); -} - - -void GpsL1CaPcpsAcquisitionFpga::set_threshold(float threshold) -{ - DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold; - acquisition_fpga_->set_threshold(threshold); -} - - -void GpsL1CaPcpsAcquisitionFpga::set_doppler_max(unsigned int doppler_max) -{ - doppler_max_ = doppler_max; - acquisition_fpga_->set_doppler_max(doppler_max_); -} - - -void GpsL1CaPcpsAcquisitionFpga::set_doppler_step(unsigned int doppler_step) -{ - doppler_step_ = doppler_step; - acquisition_fpga_->set_doppler_step(doppler_step_); -} - - -void GpsL1CaPcpsAcquisitionFpga::set_doppler_center(int doppler_center) -{ - doppler_center_ = doppler_center; - - acquisition_fpga_->set_doppler_center(doppler_center_); -} - - -void GpsL1CaPcpsAcquisitionFpga::set_gnss_synchro(Gnss_Synchro* gnss_synchro) -{ - gnss_synchro_ = gnss_synchro; - acquisition_fpga_->set_gnss_synchro(gnss_synchro_); -} - - -signed int GpsL1CaPcpsAcquisitionFpga::mag() -{ - return acquisition_fpga_->mag(); -} - - -void GpsL1CaPcpsAcquisitionFpga::init() -{ - acquisition_fpga_->init(); -} - - -void GpsL1CaPcpsAcquisitionFpga::set_local_code() -{ - acquisition_fpga_->set_local_code(); -} - - -void GpsL1CaPcpsAcquisitionFpga::reset() -{ - // this function starts the acquisition process - acquisition_fpga_->set_active(true); -} - - -void GpsL1CaPcpsAcquisitionFpga::set_state(int state) -{ - acquisition_fpga_->set_state(state); -} - - -void GpsL1CaPcpsAcquisitionFpga::connect(gr::top_block_sptr top_block) -{ - if (top_block) - { /* top_block is not null */ - }; - // Nothing to connect -} - - -void GpsL1CaPcpsAcquisitionFpga::disconnect(gr::top_block_sptr top_block) -{ - if (top_block) - { /* top_block is not null */ - }; - // Nothing to disconnect -} - - -gr::basic_block_sptr GpsL1CaPcpsAcquisitionFpga::get_left_block() -{ - return nullptr; -} - - -gr::basic_block_sptr GpsL1CaPcpsAcquisitionFpga::get_right_block() -{ - return nullptr; -} diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h index e0dc57672..b878f2de6 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h @@ -21,14 +21,7 @@ #ifndef GNSS_SDR_GPS_L1_CA_PCPS_ACQUISITION_FPGA_H #define GNSS_SDR_GPS_L1_CA_PCPS_ACQUISITION_FPGA_H -#include "acq_conf_fpga.h" -#include "channel_fsm.h" -#include "gnss_synchro.h" -#include "pcps_acquisition_fpga.h" -#include -#include -#include -#include +#include "base_pcps_acquisition_fpga.h" /** \addtogroup Acquisition * \{ */ @@ -42,7 +35,7 @@ class ConfigurationInterface; * \brief This class adapts a PCPS acquisition block off-loaded on an FPGA * to an AcquisitionInterface for GPS L1 C/A signals */ -class GpsL1CaPcpsAcquisitionFpga : public AcquisitionInterface +class GpsL1CaPcpsAcquisitionFpga : public BasePcpsAcquisitionFpga { public: /*! @@ -53,19 +46,6 @@ public: unsigned int in_streams, unsigned int out_streams); - /*! - * \brief Destructor - */ - ~GpsL1CaPcpsAcquisitionFpga() = default; - - /*! - * \brief Role - */ - inline std::string role() override - { - return role_; - } - /*! * \brief Returns "GPS_L1_CA_PCPS_Acquisition_FPGA" */ @@ -74,140 +54,9 @@ public: return "GPS_L1_CA_PCPS_Acquisition_FPGA"; } - /*! - * \brief Returns size of lv_16sc_t - */ - inline size_t item_size() override - { - return sizeof(int16_t); - } - - /*! - * \brief Connect - */ - void connect(gr::top_block_sptr top_block) override; - - /*! - * \brief Disconnect - */ - void disconnect(gr::top_block_sptr top_block) override; - - /*! - * \brief Get left block - */ - gr::basic_block_sptr get_left_block() override; - - /*! - * \brief Get right block - */ - gr::basic_block_sptr get_right_block() override; - - /*! - * \brief Set acquisition/tracking common Gnss_Synchro object pointer - * to efficiently exchange synchronization data between acquisition and - * tracking blocks - */ - void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; - - /*! - * \brief Set acquisition channel unique ID - */ - inline void set_channel(unsigned int channel) override - { - channel_ = channel; - acquisition_fpga_->set_channel(channel_); - } - - /*! - * \brief Set channel fsm associated to this acquisition instance - */ - inline void set_channel_fsm(std::weak_ptr channel_fsm) override - { - channel_fsm_ = std::move(channel_fsm); - acquisition_fpga_->set_channel_fsm(channel_fsm_); - } - - /*! - * \brief Set statistics threshold of PCPS algorithm - */ - std::string item_type_; - - void set_threshold(float threshold) override; - - /*! - * \brief Set maximum Doppler off grid search - */ - void set_doppler_max(unsigned int doppler_max) override; - - /*! - * \brief Set Doppler steps for the grid search - */ - void set_doppler_step(unsigned int doppler_step) override; - - /*! - * \brief Set Doppler center for the grid search - */ - void set_doppler_center(int doppler_center) override; - - /*! - * \brief Initializes acquisition algorithm. - */ - void init() override; - - /*! - * \brief Sets local code for GPS L1/CA PCPS acquisition algorithm. - */ - void set_local_code() override; - - /*! - * \brief Returns the maximum peak of grid search - */ - signed int mag() override; - - /*! - * \brief Restart acquisition algorithm - */ - void reset() override; - - /*! - * \brief If state = 1, it forces the block to start acquiring from the first sample - */ - void set_state(int state) override; - - /*! - * \brief Stop running acquisition - */ - void stop_acquisition() override; - - /*! - * \brief Set Resampler Latency - */ - void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override {}; - private: - static const uint32_t ACQ_BUFF_0 = 0; // FPGA Acquisition IP buffer containing L1/E1 frequency band samples by default. static const uint32_t DEFAULT_FPGA_BLK_EXP = 10; // default block exponent - static const uint32_t NUM_PRNs = 32; - static const uint32_t QUANT_BITS_LOCAL_CODE = 16; - static const uint32_t SELECT_LSBITS = 0x0000FFFF; // Select the 10 LSbits out of a 20-bit word - static const uint32_t SELECT_MSBITS = 0xFFFF0000; // Select the 10 MSbits out of a 20-bit word - static const uint32_t SELECT_ALL_CODE_BITS = 0xFFFFFFFF; // Select a 20 bit word - static const uint32_t SHL_CODE_BITS = 65536; // shift left by 10 bits - void generate_gps_l1_ca_prn_codes(); - - pcps_acquisition_fpga_sptr acquisition_fpga_; - std::weak_ptr channel_fsm_; - volk_gnsssdr::vector d_all_fft_codes_; // memory that contains all the code ffts - Gnss_Synchro* gnss_synchro_; - Acq_Conf_Fpga acq_parameters_; - std::string role_; - int32_t doppler_center_; - uint32_t channel_; - uint32_t doppler_max_; - uint32_t doppler_step_; - unsigned int in_streams_; - unsigned int out_streams_; }; diff --git a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.cc index 91c90db90..87edb6a64 100644 --- a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.cc @@ -21,10 +21,8 @@ #include "GPS_L2C.h" #include "configuration_interface.h" #include "gnss_sdr_fft.h" -#include "gnss_sdr_flags.h" #include "gps_l2c_signal_replica.h" -#include // for gr_complex -#include // for volk_32fc_conjugate_32fc +#include // for volk_32fc_conjugate_32fc #include #include // for copy_n #include // for abs, pow, floor @@ -40,64 +38,27 @@ GpsL2MPcpsAcquisitionFpga::GpsL2MPcpsAcquisitionFpga( const ConfigurationInterface* configuration, const std::string& role, unsigned int in_streams, - unsigned int out_streams) : gnss_synchro_(nullptr), - role_(role), - threshold_(0), - channel_(0), - doppler_step_(0), - in_streams_(in_streams), - out_streams_(out_streams) + unsigned int out_streams) + : BasePcpsAcquisitionFpga(configuration, + role, + GPS_L2_M_CODE_RATE_CPS, + GPS_L2_M_CODE_LENGTH_CHIPS, + 0.0, + DEFAULT_FPGA_BLK_EXP, + ACQ_BUFF_1, + in_streams, + out_streams) { - // Set acquisition parameters - acq_parameters_.SetFromConfiguration(configuration, role_, DEFAULT_FPGA_BLK_EXP, GPS_L2_M_CODE_RATE_CPS, GPS_L2_M_CODE_LENGTH_CHIPS); - - // Query the capabilities of the instantiated FPGA Acquisition IP Core. When the FPGA is in use, the acquisition resampler operates only in the L1/E1 frequency band. - std::vector> downsampling_filter_specs; - uint32_t max_FFT_size; - acquisition_fpga_ = pcps_make_acquisition_fpga(&acq_parameters_, ACQ_BUFF_1, downsampling_filter_specs, max_FFT_size); - - // When the FPGA is in use, the acquisition resampler operates only in the L1/E1 frequency band. - // Check whether the acquisition configuration is supported by the FPGA. - bool acq_configuration_valid = acq_parameters_.Is_acq_config_valid(max_FFT_size); - - if (!acq_configuration_valid) - { - std::cout << "The FPGA acquisition IP does not support the required sampling frequency of " << acq_parameters_.fs_in << " SPS for the L2 band. Please update the sampling frequency in the configuration file." << std::endl; - exit(0); - } - - DLOG(INFO) << "role " << role; - generate_gps_l2c_m_prn_codes(); - -#if USE_GLOG_AND_GFLAGS - if (FLAGS_doppler_max != 0) - { - acq_parameters_.doppler_max = FLAGS_doppler_max; - } -#else - if (absl::GetFlag(FLAGS_doppler_max) != 0) - { - acq_parameters_.doppler_max = absl::GetFlag(FLAGS_doppler_max); - } -#endif - doppler_max_ = acq_parameters_.doppler_max; - doppler_step_ = static_cast(acq_parameters_.doppler_step); - - if (in_streams_ > 1) - { - LOG(ERROR) << "This implementation only supports one input stream"; - } - if (out_streams_ > 0) - { - LOG(ERROR) << "This implementation does not provide an output stream"; - } + DLOG(INFO) << "Initialized FPGA acquisition adapter for role " << role; } + void GpsL2MPcpsAcquisitionFpga::generate_gps_l2c_m_prn_codes() { - uint32_t code_length = acq_parameters_.code_length; - uint32_t nsamples_total = acq_parameters_.fft_size; + const uint32_t code_length = acq_parameters_.code_length; + const uint32_t nsamples_total = acq_parameters_.fft_size; + const uint32_t NUM_PRNs = 32; // compute all the GPS L2C PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time // a channel is assigned) @@ -113,9 +74,9 @@ void GpsL2MPcpsAcquisitionFpga::generate_gps_l2c_m_prn_codes() int32_t local_code; int32_t fft_data; - for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++) + for (uint32_t prn = 1; prn <= NUM_PRNs; prn++) { - gps_l2c_m_code_gen_complex_sampled(code, PRN, acq_parameters_.fs_in); + gps_l2c_m_code_gen_complex_sampled(code, prn, acq_parameters_.fs_in); if (acq_parameters_.enable_zero_padding) { @@ -148,109 +109,9 @@ void GpsL2MPcpsAcquisitionFpga::generate_gps_l2c_m_prn_codes() tmp2 = static_cast(floor(fft_codes[i].imag() * (pow(2, QUANT_BITS_LOCAL_CODE - 1) - 1) / max)); local_code = (tmp & SELECT_LSBITS) | ((tmp2 * SHL_CODE_BITS) & SELECT_MSBITS); // put together the real part and the imaginary part fft_data = local_code & SELECT_ALL_CODE_BITS; - d_all_fft_codes_[i + (nsamples_total * (PRN - 1))] = fft_data; + d_all_fft_codes_[i + (nsamples_total * (prn - 1))] = fft_data; } } acq_parameters_.all_fft_codes = d_all_fft_codes_.data(); } - -void GpsL2MPcpsAcquisitionFpga::stop_acquisition() -{ - // stop the acquisition and the other FPGA modules. - acquisition_fpga_->stop_acquisition(); -} - - -void GpsL2MPcpsAcquisitionFpga::set_threshold(float threshold) -{ - threshold_ = threshold; - DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold_; - acquisition_fpga_->set_threshold(threshold_); -} - - -void GpsL2MPcpsAcquisitionFpga::set_doppler_max(unsigned int doppler_max) -{ - doppler_max_ = doppler_max; - - acquisition_fpga_->set_doppler_max(doppler_max_); -} - - -// Be aware that Doppler step should be set to 2/(3T) Hz, where T is the coherent integration time (GPS L2 period is 0.02s) -// Doppler bin minimum size= 33 Hz -void GpsL2MPcpsAcquisitionFpga::set_doppler_step(unsigned int doppler_step) -{ - doppler_step_ = doppler_step; - - acquisition_fpga_->set_doppler_step(doppler_step_); -} - - -void GpsL2MPcpsAcquisitionFpga::set_gnss_synchro(Gnss_Synchro* gnss_synchro) -{ - gnss_synchro_ = gnss_synchro; - - acquisition_fpga_->set_gnss_synchro(gnss_synchro_); -} - - -signed int GpsL2MPcpsAcquisitionFpga::mag() -{ - return acquisition_fpga_->mag(); -} - - -void GpsL2MPcpsAcquisitionFpga::init() -{ - acquisition_fpga_->init(); -} - - -void GpsL2MPcpsAcquisitionFpga::set_local_code() -{ - acquisition_fpga_->set_local_code(); -} - - -void GpsL2MPcpsAcquisitionFpga::reset() -{ - acquisition_fpga_->set_active(true); -} - - -void GpsL2MPcpsAcquisitionFpga::set_state(int state) -{ - acquisition_fpga_->set_state(state); -} - - -void GpsL2MPcpsAcquisitionFpga::connect(gr::top_block_sptr top_block) -{ - if (top_block) - { /* top_block is not null */ - }; - // Nothing to connect -} - - -void GpsL2MPcpsAcquisitionFpga::disconnect(gr::top_block_sptr top_block) -{ - if (top_block) - { /* top_block is not null */ - }; - // Nothing to disconnect -} - - -gr::basic_block_sptr GpsL2MPcpsAcquisitionFpga::get_left_block() -{ - return nullptr; -} - - -gr::basic_block_sptr GpsL2MPcpsAcquisitionFpga::get_right_block() -{ - return nullptr; -} diff --git a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.h index 4e1b8c8ac..ea4f2536a 100644 --- a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.h @@ -20,16 +20,7 @@ #ifndef GNSS_SDR_GPS_L2_M_PCPS_ACQUISITION_FPGA_H #define GNSS_SDR_GPS_L2_M_PCPS_ACQUISITION_FPGA_H -#include "acq_conf_fpga.h" -#include "channel_fsm.h" -#include "gnss_synchro.h" -#include "pcps_acquisition_fpga.h" -#include // for basic_block_sptr, top_block_sptr -#include -#include // for size_t -#include // for weak_ptr -#include // for string -#include +#include "base_pcps_acquisition_fpga.h" /** \addtogroup Acquisition * \{ */ @@ -43,7 +34,7 @@ class ConfigurationInterface; * \brief This class adapts a PCPS acquisition block off-loaded on an FPGA * to an AcquisitionInterface for GPS L2 M signals */ -class GpsL2MPcpsAcquisitionFpga : public AcquisitionInterface +class GpsL2MPcpsAcquisitionFpga : public BasePcpsAcquisitionFpga { public: GpsL2MPcpsAcquisitionFpga( @@ -52,13 +43,6 @@ public: unsigned int in_streams, unsigned int out_streams); - ~GpsL2MPcpsAcquisitionFpga() = default; - - inline std::string role() override - { - return role_; - } - /*! * \brief Returns "GPS_L2_M_PCPS_Acquisition_FPGA" */ @@ -67,112 +51,9 @@ public: return "GPS_L2_M_PCPS_Acquisition_FPGA"; } - inline size_t item_size() override - { - return sizeof(float); - } - - void connect(gr::top_block_sptr top_block) override; - void disconnect(gr::top_block_sptr top_block) override; - gr::basic_block_sptr get_left_block() override; - gr::basic_block_sptr get_right_block() override; - - /*! - * \brief Set acquisition/tracking common Gnss_Synchro object pointer - * to efficiently exchange synchronization data between acquisition and - * tracking blocks - */ - void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; - - /*! - * \brief Set acquisition channel unique ID - */ - inline void set_channel(unsigned int channel) override - { - channel_ = channel; - acquisition_fpga_->set_channel(channel_); - } - - /*! - * \brief Set channel fsm associated to this acquisition instance - */ - inline void set_channel_fsm(std::weak_ptr channel_fsm) override - { - channel_fsm_ = std::move(channel_fsm); - acquisition_fpga_->set_channel_fsm(channel_fsm_); - } - - /*! - * \brief Set statistics threshold of PCPS algorithm - */ - void set_threshold(float threshold) override; - - /*! - * \brief Set maximum Doppler off grid search - */ - void set_doppler_max(unsigned int doppler_max) override; - - /*! - * \brief Set Doppler steps for the grid search - */ - void set_doppler_step(unsigned int doppler_step) override; - - /*! - * \brief Initializes acquisition algorithm. - */ - void init() override; - - /*! - * \brief Sets local code for GPS L2/M PCPS acquisition algorithm. - */ - void set_local_code() override; - - /*! - * \brief Returns the maximum peak of grid search - */ - signed int mag() override; - - /*! - * \brief Restart acquisition algorithm - */ - void reset() override; - - /*! - * \brief If state = 1, it forces the block to start acquiring from the first sample - */ - void set_state(int state) override; - - /*! - * \brief Stop running acquisition - */ - void stop_acquisition() override; - - void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override {}; - private: - static const uint32_t ACQ_BUFF_1 = 1; // FPGA Acquisition IP buffer containing L2 or L5/E5 frequency band samples by default. static const uint32_t DEFAULT_FPGA_BLK_EXP = 13; // default block exponent - static const uint32_t NUM_PRNs = 32; - static const uint32_t QUANT_BITS_LOCAL_CODE = 16; - static const uint32_t SELECT_LSBITS = 0x0000FFFF; // Select the 10 LSbits out of a 20-bit word - static const uint32_t SELECT_MSBITS = 0xFFFF0000; // Select the 10 MSbits out of a 20-bit word - static const uint32_t SELECT_ALL_CODE_BITS = 0xFFFFFFFF; // Select a 20 bit word - static const uint32_t SHL_CODE_BITS = 65536; // shift left by 10 bits - void generate_gps_l2c_m_prn_codes(); - - pcps_acquisition_fpga_sptr acquisition_fpga_; - volk_gnsssdr::vector d_all_fft_codes_; // memory that contains all the code ffts - std::weak_ptr channel_fsm_; - Gnss_Synchro* gnss_synchro_; - Acq_Conf_Fpga acq_parameters_; - std::string role_; - float threshold_; - unsigned int channel_; - unsigned int doppler_max_; - unsigned int doppler_step_; - unsigned int in_streams_; - unsigned int out_streams_; }; diff --git a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.cc index 29b1a1887..a291776cf 100644 --- a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.cc @@ -22,10 +22,8 @@ #include "GPS_L5.h" #include "configuration_interface.h" #include "gnss_sdr_fft.h" -#include "gnss_sdr_flags.h" #include "gps_l5_signal_replica.h" -#include // for gr_complex -#include // for volk_32fc_conjugate_32fc +#include // for volk_32fc_conjugate_32fc #include #include // for copy_n #include // for abs, pow, floor @@ -41,64 +39,27 @@ GpsL5iPcpsAcquisitionFpga::GpsL5iPcpsAcquisitionFpga( const ConfigurationInterface* configuration, const std::string& role, unsigned int in_streams, - unsigned int out_streams) : gnss_synchro_(nullptr), - role_(role), - doppler_center_(0), - channel_(0), - doppler_step_(0), - in_streams_(in_streams), - out_streams_(out_streams) + unsigned int out_streams) + : BasePcpsAcquisitionFpga(configuration, + role, + GPS_L5I_CODE_RATE_CPS, + GPS_L5I_CODE_LENGTH_CHIPS, + 0.0, + DEFAULT_FPGA_BLK_EXP, + ACQ_BUFF_1, + in_streams, + out_streams) { - // Set acquisition parameters - acq_parameters_.SetFromConfiguration(configuration, role_, DEFAULT_FPGA_BLK_EXP, GPS_L5I_CODE_RATE_CPS, GPS_L5I_CODE_LENGTH_CHIPS); - - // Query the capabilities of the instantiated FPGA Acquisition IP Core. When the FPGA is in use, the acquisition resampler operates only in the L1/E1 frequency band. - std::vector> downsampling_filter_specs; - uint32_t max_FFT_size; - acquisition_fpga_ = pcps_make_acquisition_fpga(&acq_parameters_, ACQ_BUFF_1, downsampling_filter_specs, max_FFT_size); - - // When the FPGA is in use, the acquisition resampler operates only in the L1/E1 frequency band. - // Check whether the acquisition configuration is supported by the FPGA. - bool acq_configuration_valid = acq_parameters_.Is_acq_config_valid(max_FFT_size); - - if (!acq_configuration_valid) - { - std::cout << "The FPGA acquisition IP does not support the required sampling frequency of " << acq_parameters_.fs_in << " SPS for the L5/E5a band. Please update the sampling frequency in the configuration file." << std::endl; - exit(0); - } - - DLOG(INFO) << "role " << role; - generate_gps_l5i_prn_codes(); - -#if USE_GLOG_AND_GFLAGS - if (FLAGS_doppler_max != 0) - { - acq_parameters_.doppler_max = FLAGS_doppler_max; - } -#else - if (absl::GetFlag(FLAGS_doppler_max) != 0) - { - acq_parameters_.doppler_max = absl::GetFlag(FLAGS_doppler_max); - } -#endif - doppler_max_ = acq_parameters_.doppler_max; - doppler_step_ = static_cast(acq_parameters_.doppler_step); - - if (in_streams_ > 1) - { - LOG(ERROR) << "This implementation only supports one input stream"; - } - if (out_streams_ > 0) - { - LOG(ERROR) << "This implementation does not provide an output stream"; - } + DLOG(INFO) << "Initialized FPGA acquisition adapter for role " << role; } + void GpsL5iPcpsAcquisitionFpga::generate_gps_l5i_prn_codes() { - uint32_t code_length = acq_parameters_.code_length; - uint32_t nsamples_total = acq_parameters_.fft_size; + const uint32_t code_length = acq_parameters_.code_length; + const uint32_t nsamples_total = acq_parameters_.fft_size; + const uint32_t NUM_PRNs = 32; // compute all the GPS L5 PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time // a channel is assigned) @@ -113,9 +74,9 @@ void GpsL5iPcpsAcquisitionFpga::generate_gps_l5i_prn_codes() int32_t local_code; int32_t fft_data; - for (uint32_t PRN = 1; PRN <= NUM_PRNs; PRN++) + for (uint32_t prn = 1; prn <= NUM_PRNs; prn++) { - gps_l5i_code_gen_complex_sampled(code, PRN, acq_parameters_.fs_in); + gps_l5i_code_gen_complex_sampled(code, prn, acq_parameters_.fs_in); if (acq_parameters_.enable_zero_padding) { @@ -149,113 +110,9 @@ void GpsL5iPcpsAcquisitionFpga::generate_gps_l5i_prn_codes() tmp2 = static_cast(floor(fft_codes[i].imag() * (pow(2, QUANT_BITS_LOCAL_CODE - 1) - 1) / max)); local_code = (tmp & SELECT_LSBITS) | ((tmp2 * SHL_CODE_BITS) & SELECT_MSBITS); // put together the real part and the imaginary part fft_data = local_code & SELECT_ALL_CODE_BITS; - d_all_fft_codes_[i + (nsamples_total * (PRN - 1))] = fft_data; + d_all_fft_codes_[i + (nsamples_total * (prn - 1))] = fft_data; } } acq_parameters_.all_fft_codes = d_all_fft_codes_.data(); } - -void GpsL5iPcpsAcquisitionFpga::stop_acquisition() -{ - // stop the acquisition and the other FPGA modules. - acquisition_fpga_->stop_acquisition(); -} - - -void GpsL5iPcpsAcquisitionFpga::set_threshold(float threshold) -{ - DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold; - acquisition_fpga_->set_threshold(threshold); -} - - -void GpsL5iPcpsAcquisitionFpga::set_doppler_max(unsigned int doppler_max) -{ - doppler_max_ = doppler_max; - acquisition_fpga_->set_doppler_max(doppler_max_); -} - - -// Be aware that Doppler step should be set to 2/(3T) Hz, where T is the coherent integration time (GPS L2 period is 0.02s) -// Doppler bin minimum size= 33 Hz -void GpsL5iPcpsAcquisitionFpga::set_doppler_step(unsigned int doppler_step) -{ - doppler_step_ = doppler_step; - acquisition_fpga_->set_doppler_step(doppler_step_); -} - - -void GpsL5iPcpsAcquisitionFpga::set_doppler_center(int doppler_center) -{ - doppler_center_ = doppler_center; - - acquisition_fpga_->set_doppler_center(doppler_center_); -} - - -void GpsL5iPcpsAcquisitionFpga::set_gnss_synchro(Gnss_Synchro* gnss_synchro) -{ - gnss_synchro_ = gnss_synchro; - acquisition_fpga_->set_gnss_synchro(gnss_synchro_); -} - - -signed int GpsL5iPcpsAcquisitionFpga::mag() -{ - return acquisition_fpga_->mag(); -} - - -void GpsL5iPcpsAcquisitionFpga::init() -{ - acquisition_fpga_->init(); -} - - -void GpsL5iPcpsAcquisitionFpga::set_local_code() -{ - acquisition_fpga_->set_local_code(); -} - - -void GpsL5iPcpsAcquisitionFpga::reset() -{ - acquisition_fpga_->set_active(true); -} - - -void GpsL5iPcpsAcquisitionFpga::set_state(int state) -{ - acquisition_fpga_->set_state(state); -} - - -void GpsL5iPcpsAcquisitionFpga::connect(gr::top_block_sptr top_block) -{ - if (top_block) - { /* top_block is not null */ - }; - // Nothing to connect -} - - -void GpsL5iPcpsAcquisitionFpga::disconnect(gr::top_block_sptr top_block) -{ - if (top_block) - { /* top_block is not null */ - }; - // Nothing to disconnect -} - - -gr::basic_block_sptr GpsL5iPcpsAcquisitionFpga::get_left_block() -{ - return nullptr; -} - - -gr::basic_block_sptr GpsL5iPcpsAcquisitionFpga::get_right_block() -{ - return nullptr; -} diff --git a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.h index e3b97df39..ff0f6444d 100644 --- a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.h @@ -21,15 +21,7 @@ #ifndef GNSS_SDR_GPS_L5I_PCPS_ACQUISITION_FPGA_H #define GNSS_SDR_GPS_L5I_PCPS_ACQUISITION_FPGA_H -#include "acq_conf_fpga.h" -#include "channel_fsm.h" -#include "gnss_synchro.h" -#include "pcps_acquisition_fpga.h" -#include -#include -#include -#include -#include +#include "base_pcps_acquisition_fpga.h" /** \addtogroup Acquisition * \{ */ @@ -43,7 +35,7 @@ class ConfigurationInterface; * \brief This class adapts a PCPS acquisition block off-loaded on an FPGA * to an AcquisitionInterface for GPS L5i signals */ -class GpsL5iPcpsAcquisitionFpga : public AcquisitionInterface +class GpsL5iPcpsAcquisitionFpga : public BasePcpsAcquisitionFpga { public: /*! @@ -55,19 +47,6 @@ public: unsigned int in_streams, unsigned int out_streams); - /*! - * \brief Destructor - */ - ~GpsL5iPcpsAcquisitionFpga() = default; - - /*! - * \brief Role - */ - inline std::string role() override - { - return role_; - } - /*! * \brief Returns "GPS_L5i_PCPS_Acquisition_FPGA" */ @@ -76,139 +55,9 @@ public: return "GPS_L5i_PCPS_Acquisition_FPGA"; } - /*! - * \brief Returns size of lv_16sc_t - */ - inline size_t item_size() override - { - return sizeof(int16_t); - } - - /*! - * \brief Connect - */ - void connect(gr::top_block_sptr top_block) override; - - /*! - * \brief Disconnect - */ - void disconnect(gr::top_block_sptr top_block) override; - - /*! - * \brief Get left block - */ - gr::basic_block_sptr get_left_block() override; - - /*! - * \brief Get right block - */ - gr::basic_block_sptr get_right_block() override; - - /*! - * \brief Set acquisition/tracking common Gnss_Synchro object pointer - * to efficiently exchange synchronization data between acquisition and - * tracking blocks - */ - void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; - - /*! - * \brief Set acquisition channel unique ID - */ - inline void set_channel(unsigned int channel) override - { - channel_ = channel; - acquisition_fpga_->set_channel(channel_); - } - - /*! - * \brief Set channel fsm associated to this acquisition instance - */ - inline void set_channel_fsm(std::weak_ptr channel_fsm) override - { - channel_fsm_ = std::move(channel_fsm); - acquisition_fpga_->set_channel_fsm(channel_fsm_); - } - - /*! - * \brief Set statistics threshold of PCPS algorithm - */ - void set_threshold(float threshold) override; - - /*! - * \brief Set maximum Doppler off grid search - */ - void set_doppler_max(unsigned int doppler_max) override; - - /*! - * \brief Set Doppler steps for the grid search - */ - void set_doppler_step(unsigned int doppler_step) override; - - /*! - * \brief Set Doppler center for the grid search - */ - void set_doppler_center(int doppler_center) override; - - /*! - * \brief Initializes acquisition algorithm. - */ - void init() override; - - /*! - * \brief Sets local code for GPS L5 PCPS acquisition algorithm. - */ - void set_local_code() override; - - /*! - * \brief Returns the maximum peak of grid search - */ - signed int mag() override; - - /*! - * \brief Restart acquisition algorithm - */ - void reset() override; - - /*! - * \brief If state = 1, it forces the block to start acquiring from the first sample - */ - void set_state(int state) override; - - /*! - * \brief Stop running acquisition - */ - void stop_acquisition() override; - - /*! - * \brief Set resampler latency - */ - void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override {}; - private: - static const uint32_t ACQ_BUFF_1 = 1; // FPGA Acquisition IP buffer containing L2 or L5/E5 frequency band samples by default. static const uint32_t DEFAULT_FPGA_BLK_EXP = 13; // default block exponent - static const uint32_t NUM_PRNs = 32; - static const uint32_t QUANT_BITS_LOCAL_CODE = 16; - static const uint32_t SELECT_LSBITS = 0x0000FFFF; // Select the 10 LSbits out of a 20-bit word - static const uint32_t SELECT_MSBITS = 0xFFFF0000; // Select the 10 MSbits out of a 20-bit word - static const uint32_t SELECT_ALL_CODE_BITS = 0xFFFFFFFF; // Select a 20 bit word - static const uint32_t SHL_CODE_BITS = 65536; // shift left by 10 bits - void generate_gps_l5i_prn_codes(); - float calculate_threshold(float pfa); - - pcps_acquisition_fpga_sptr acquisition_fpga_; - std::weak_ptr channel_fsm_; - volk_gnsssdr::vector d_all_fft_codes_; // memory that contains all the code ffts - Gnss_Synchro* gnss_synchro_; - Acq_Conf_Fpga acq_parameters_; - std::string role_; - int32_t doppler_center_; - uint32_t channel_; - uint32_t doppler_max_; - uint32_t doppler_step_; - unsigned int in_streams_; - unsigned int out_streams_; };