diff --git a/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition.cc new file mode 100644 index 000000000..95a70fe7e --- /dev/null +++ b/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition.cc @@ -0,0 +1,247 @@ +/*! + * \file galileo_e5b_pcps_acquisition.cc + * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for + * Galileo E5b data and pilot Signals + * \author Piyush Gupta, 2020. piyush04111999@gmail.com + * \note Code added as part of GSoC 2020 program. + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ------------------------------------------------------------------------- + */ + +#include "galileo_e5b_pcps_acquisition.h" +#include "Galileo_E5b.h" +#include "acq_conf.h" +#include "configuration_interface.h" +#include "galileo_e5_signal_processing.h" +#include "gnss_sdr_flags.h" +#include +#include +#include + +#if HAS_STD_SPAN +#include +namespace own = std; +#else +#include +namespace own = gsl; +#endif + +GalileoE5bPcpsAcquisition::GalileoE5bPcpsAcquisition(ConfigurationInterface* configuration, + const std::string& role, + unsigned int in_streams, + unsigned int out_streams) : role_(role), + in_streams_(in_streams), + out_streams_(out_streams) +{ + configuration_ = configuration; + acq_parameters_.ms_per_code = 1; + acq_parameters_.SetFromConfiguration(configuration_, role, GALILEO_E5B_CODE_CHIP_RATE_CPS, GALILEO_E5B_OPT_ACQ_FS_SPS); + + DLOG(INFO) << "Role " << role; + + if (FLAGS_doppler_max != 0) + { + acq_parameters_.doppler_max = FLAGS_doppler_max; + } + doppler_max_ = acq_parameters_.doppler_max; + doppler_step_ = acq_parameters_.doppler_step; + item_type_ = acq_parameters_.item_type; + item_size_ = acq_parameters_.it_size; + fs_in_ = acq_parameters_.fs_in; + + acq_pilot_ = configuration_->property(role + ".acquire_pilot", false); + acq_iq_ = configuration_->property(role + ".acquire_iq", false); + if (acq_iq_) + { + acq_pilot_ = false; + } + + 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_ = std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2 : 1); + code_ = std::vector>(vector_length_); + + sampled_ms_ = acq_parameters_.sampled_ms; + + acquisition_ = pcps_make_acquisition(acq_parameters_); + DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; + + + channel_ = 0; + threshold_ = 0.0; + doppler_center_ = 0; + gnss_synchro_ = nullptr; + + 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::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() +{ + std::vector> code(code_length_); + std::array signal_{}; + signal_[0] = '7'; + signal_[2] = '\0'; + + if (acq_iq_) + { + signal_[1] = 'X'; + } + else if (acq_pilot_) + { + signal_[1] = 'Q'; + } + else + { + 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") + { + // nothing to connect + } + else if (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") + { + // nothing to disconnect + } + else if (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); +} diff --git a/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition.h b/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition.h new file mode 100644 index 000000000..c8a92cbdc --- /dev/null +++ b/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition.h @@ -0,0 +1,204 @@ +/*! + * \file galileo_e5b_pcps_acquisition.h + * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for + * Galileo E5b data and pilot Signals + * \author Piyush Gupta, 2020. piyush04111999@gmail.com + * \note Code added as part of GSoC 2020 program. + + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_GALILEO_E5B_PCPS_ACQUISITION_H +#define GNSS_SDR_GALILEO_E5B_PCPS_ACQUISITION_H + + +#include "channel_fsm.h" +#include "gnss_synchro.h" +#include "pcps_acquisition.h" +#include +#include +#include + +class ConfigurationInterface; + +class GalileoE5bPcpsAcquisition : public AcquisitionInterface +{ +public: + /*! + * \brief Constructor + */ + GalileoE5bPcpsAcquisition(ConfigurationInterface* configuration, + const std::string& role, + unsigned int in_streams, + unsigned int out_streams); + + /*! + * \brief Destructor + */ + ~GalileoE5bPcpsAcquisition() = default; + + /*! + * \brief Role + */ + inline std::string role() override + { + return role_; + } + + /*! + * \brief Returns "GALILEO_E5b_PCPS_Acquisition" + */ + + inline std::string implementation() override + { + 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_ = 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: + ConfigurationInterface* configuration_; + pcps_acquisition_sptr acquisition_; + Acq_Conf acq_parameters_; + size_t item_size_; + std::string item_type_; + std::string dump_filename_; + std::string role_; + bool acq_pilot_; + bool acq_iq_; + unsigned int vector_length_; + unsigned int code_length_; + unsigned int channel_; + std::weak_ptr channel_fsm_; + unsigned int doppler_max_; + unsigned int doppler_step_; + int doppler_center_; + unsigned int sampled_ms_; + unsigned int in_streams_; + unsigned int out_streams_; + int64_t fs_in_; + float threshold_; + std::vector> code_; + Gnss_Synchro* gnss_synchro_; +}; + +#endif // GNSS_SDR_GALILEO_E5B_PCPS_ACQUISITION_H