diff --git a/src/algorithms/tracking/adapters/CMakeLists.txt b/src/algorithms/tracking/adapters/CMakeLists.txt index f19e66baa..8872fe2d9 100644 --- a/src/algorithms/tracking/adapters/CMakeLists.txt +++ b/src/algorithms/tracking/adapters/CMakeLists.txt @@ -43,6 +43,7 @@ set(TRACKING_ADAPTER_SOURCES gps_l1_ca_dll_pll_tracking.cc gps_l1_ca_tcp_connector_tracking.cc galileo_e5a_dll_pll_tracking.cc + galileo_e5b_dll_pll_tracking.cc gps_l2_m_dll_pll_tracking.cc glonass_l1_ca_dll_pll_tracking.cc glonass_l1_ca_dll_pll_c_aid_tracking.cc @@ -61,6 +62,7 @@ set(TRACKING_ADAPTER_HEADERS gps_l1_ca_dll_pll_tracking.h gps_l1_ca_tcp_connector_tracking.h galileo_e5a_dll_pll_tracking.h + galileo_e5b_dll_pll_tracking.h gps_l2_m_dll_pll_tracking.h glonass_l1_ca_dll_pll_tracking.h glonass_l1_ca_dll_pll_c_aid_tracking.h diff --git a/src/algorithms/tracking/adapters/galileo_e5b_dll_pll_tracking.cc b/src/algorithms/tracking/adapters/galileo_e5b_dll_pll_tracking.cc new file mode 100644 index 000000000..f5ccf3525 --- /dev/null +++ b/src/algorithms/tracking/adapters/galileo_e5b_dll_pll_tracking.cc @@ -0,0 +1,145 @@ +/*! + * \file galileo_e5b_dll_pll_tracking.cc + * \brief Adapts a code DLL + carrier PLL + * tracking block to a TrackingInterface for Galileo E5b signals + * \author Piyush Gupta, 2020. piyush04111999@gmail.com + * \based on work from: + * + * + * ------------------------------------------------------------------------- + * + * 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_dll_pll_tracking.h" +#include "Galileo_E5b.h" +#include "configuration_interface.h" +#include "display.h" +#include "dll_pll_conf.h" +#include "gnss_sdr_flags.h" +#include +#include + +GalileoE5bDllPllTracking::GalileoE5bDllPllTracking( + const ConfigurationInterface* configuration, const std::string& role, + unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) +{ + Dll_Pll_Conf trk_params = Dll_Pll_Conf(); + DLOG(INFO) << "role " << role; + trk_params.SetFromConfiguration(configuration, role); + + auto vector_length = static_cast(std::round(trk_params.fs_in / (GALILEO_E5B_CODE_CHIP_RATE_CPS / GALILEO_E5B_CODE_LENGTH_CHIPS))); + trk_params.vector_length = vector_length; + if (trk_params.extend_correlation_symbols < 1) + { + trk_params.extend_correlation_symbols = 1; + std::cout << TEXT_RED << "WARNING: Galileo E5b. extend_correlation_symbols must be bigger than 0. Coherent integration has been set to 1 symbol (1 ms)" << TEXT_RESET << '\n'; + } + else if (!trk_params.track_pilot and trk_params.extend_correlation_symbols > GALILEO_E5B_I_SECONDARY_CODE_LENGTH) + { + trk_params.extend_correlation_symbols = GALILEO_E5B_I_SECONDARY_CODE_LENGTH; + std::cout << TEXT_RED << "WARNING: Galileo E5b. extend_correlation_symbols must be lower than 5 when tracking the data component. Coherent integration has been set to 4 symbols (4 ms)" << TEXT_RESET << '\n'; + } + if ((trk_params.extend_correlation_symbols > 1) and (trk_params.pll_bw_narrow_hz > trk_params.pll_bw_hz or trk_params.dll_bw_narrow_hz > trk_params.dll_bw_hz)) + { + std::cout << TEXT_RED << "WARNING: Galileo E5b. PLL or DLL narrow tracking bandwidth is higher than wide tracking one" << TEXT_RESET << '\n'; + } + trk_params.system = 'E'; + std::array sig_{'7', 'X', '\0'}; + std::memcpy(trk_params.signal, sig_.data(), 3); + + // ################# Make a GNU Radio Tracking block object ################ + if (trk_params.item_type == "gr_complex") + { + item_size_ = sizeof(gr_complex); + tracking_ = dll_pll_veml_make_tracking(trk_params); + } + else + { + item_size_ = sizeof(gr_complex); + LOG(WARNING) << trk_params.item_type << " unknown tracking item type."; + } + channel_ = 0; + DLOG(INFO) << "tracking(" << tracking_->unique_id() << ")"; + if (in_streams_ > 1) + { + LOG(ERROR) << "This implementation only supports one input stream"; + } + if (out_streams_ > 1) + { + LOG(ERROR) << "This implementation only supports one output stream"; + } +} + + +void GalileoE5bDllPllTracking::stop_tracking() +{ + tracking_->stop_tracking(); +} + + +void GalileoE5bDllPllTracking::start_tracking() +{ + tracking_->start_tracking(); +} + + +/* + * Set tracking channel unique ID + */ +void GalileoE5bDllPllTracking::set_channel(unsigned int channel) +{ + channel_ = channel; + tracking_->set_channel(channel); +} + + +void GalileoE5bDllPllTracking::set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) +{ + tracking_->set_gnss_synchro(p_gnss_synchro); +} + + +void GalileoE5bDllPllTracking::connect(gr::top_block_sptr top_block) +{ + if (top_block) + { + /* top_block is not null */ + }; + // nothing to connect, now the tracking uses gr_sync_decimator +} + + +void GalileoE5bDllPllTracking::disconnect(gr::top_block_sptr top_block) +{ + if (top_block) + { + /* top_block is not null */ + }; + // nothing to disconnect, now the tracking uses gr_sync_decimator +} + + +gr::basic_block_sptr GalileoE5bDllPllTracking::get_left_block() +{ + return tracking_; +} + + +gr::basic_block_sptr GalileoE5bDllPllTracking::get_right_block() +{ + return tracking_; +} diff --git a/src/algorithms/tracking/adapters/galileo_e5b_dll_pll_tracking.h b/src/algorithms/tracking/adapters/galileo_e5b_dll_pll_tracking.h new file mode 100644 index 000000000..a6e9b5d19 --- /dev/null +++ b/src/algorithms/tracking/adapters/galileo_e5b_dll_pll_tracking.h @@ -0,0 +1,113 @@ +/*! + * \file galileo_e5b_dll_pll_tracking.h + * \brief Adapts a code DLL + carrier PLL + * tracking block to a TrackingInterface for Galileo E5b signals + * \author Piyush Gupta, 2020. piyush04111999@gmail.com + * \based on work from: + *
    + *
  • Javier Arribas, 2011. jarribas@cttc.es + *
  • Luis Esteve, 2012. luis@epsilon-formacion.com + *
  • Marc Sales, 2014. marcsales92@gmail.com + *
+ * + * ------------------------------------------------------------------------- + * + * 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_DLL_PLL_TRACKING_H +#define GNSS_SDR_GALILEO_E5B_DLL_PLL_TRACKING_H + +#include "dll_pll_veml_tracking.h" +#include "tracking_interface.h" +#include + +class ConfigurationInterface; + +/*! + * \brief This class implements a code DLL + carrier PLL tracking loop + */ +class GalileoE5bDllPllTracking : public TrackingInterface +{ +public: + GalileoE5bDllPllTracking( + const ConfigurationInterface* configuration, + const std::string& role, + unsigned int in_streams, + unsigned int out_streams); + + ~GalileoE5bDllPllTracking() = default; + + inline std::string role() override + { + return role_; + } + + //! Returns "Galileo_E5b_DLL_PLL_Tracking" + inline std::string implementation() override + { + return "Galileo_E5b_DLL_PLL_Tracking"; + } + + inline size_t item_size() override + { + return item_size_; + } + + /*! + * \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 tracking channel unique ID + */ + void set_channel(unsigned int channel) 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; + + void start_tracking() override; + + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; + +private: + dll_pll_veml_tracking_sptr tracking_; + size_t item_size_; + unsigned int channel_; + std::string role_; + unsigned int in_streams_; + unsigned int out_streams_; +}; + +#endif // GNSS_SDR_GALILEO_E5B_DLL_PLL_TRACKING_H diff --git a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc index 7a79b3746..f75516c04 100644 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc @@ -11,7 +11,7 @@ * * ------------------------------------------------------------------------- * - * Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors) + * Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors) * * GNSS-SDR is a software defined Global Navigation * Satellite Systems receiver @@ -31,6 +31,7 @@ #include "GPS_L5.h" #include "Galileo_E1.h" #include "Galileo_E5a.h" +#include "Galileo_E5b.h" #include "MATH_CONSTANTS.h" #include "beidou_b1i_signal_processing.h" #include "beidou_b3i_signal_processing.h" @@ -127,6 +128,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl map_signal_pretty_name["2S"] = "L2C"; map_signal_pretty_name["2G"] = "L2 C/A"; map_signal_pretty_name["5X"] = "E5a"; + map_signal_pretty_name["7X"] = "E5b"; map_signal_pretty_name["L5"] = "L5"; map_signal_pretty_name["B1"] = "B1I"; map_signal_pretty_name["B3"] = "B3I"; @@ -283,6 +285,37 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl d_interchange_iq = true; } } + else if (d_signal_type == "7X") + { + d_signal_carrier_freq = GALILEO_E5B_FREQ_HZ; + d_code_period = GALILEO_E5B_CODE_PERIOD_S; + d_code_chip_rate = GALILEO_E5B_CODE_CHIP_RATE_CPS; + d_symbols_per_bit = 4; + d_correlation_length_ms = 1; + d_code_samples_per_chip = 1; + d_code_length_chips = static_cast(GALILEO_E5B_CODE_LENGTH_CHIPS); + d_secondary = true; + d_trk_parameters.slope = 1.0; + d_trk_parameters.spc = d_trk_parameters.early_late_space_chips; + d_trk_parameters.y_intercept = 1.0; + if (d_trk_parameters.track_pilot) + { + // synchronize pilot secondary code + d_secondary_code_length = static_cast(GALILEO_E5B_Q_SECONDARY_CODE_LENGTH); + d_signal_pretty_name = d_signal_pretty_name + "Q"; + // remove data secondary code + d_data_secondary_code_length = static_cast(GALILEO_E5B_I_SECONDARY_CODE_LENGTH); + d_data_secondary_code_string = GALILEO_E5B_I_SECONDARY_CODE; + } + else + { + // synchronize and remove data secondary code + d_secondary_code_length = static_cast(GALILEO_E5B_I_SECONDARY_CODE_LENGTH); + d_secondary_code_string = GALILEO_E5B_I_SECONDARY_CODE; + d_signal_pretty_name = d_signal_pretty_name + "I"; + d_interchange_iq = true; + } + } else { LOG(WARNING) << "Invalid Signal argument when instantiating tracking blocks"; @@ -657,6 +690,30 @@ void dll_pll_veml_tracking::start_tracking() } } } + else if (d_systemName == "Galileo" and d_signal_type == "7X") + { + volk_gnsssdr::vector aux_code(d_code_length_chips); + std::array signal_type_ = {{'7', 'X', '\0'}}; + galileo_e5_b_code_gen_complex_primary(aux_code, d_acquisition_gnss_synchro->PRN, signal_type_); + if (d_trk_parameters.track_pilot) + { + d_secondary_code_string = GALILEO_E5B_Q_SECONDARY_CODE[d_acquisition_gnss_synchro->PRN - 1]; + for (int32_t i = 0; i < d_code_length_chips; i++) + { + d_tracking_code[i] = aux_code[i].imag(); + d_data_code[i] = aux_code[i].real(); // the same because it is generated the full signal (E5bI + E5bsQ) + } + d_Prompt_Data[0] = gr_complex(0.0, 0.0); + d_correlator_data_cpu.set_local_code_and_taps(d_code_length_chips, d_data_code.data(), d_prompt_data_shift); + } + else + { + for (int32_t i = 0; i < d_code_length_chips; i++) + { + d_tracking_code[i] = aux_code[i].real(); + } + } + } else if (d_systemName == "Beidou" and d_signal_type == "B1") { beidou_b1i_code_gen_float(d_tracking_code, d_acquisition_gnss_synchro->PRN, 0); diff --git a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.h b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.h index a2f28a882..78725befa 100644 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.h +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.h @@ -6,7 +6,7 @@ * * ------------------------------------------------------------------------- * - * Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors) + * Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors) * * GNSS-SDR is a software defined Global Navigation * Satellite Systems receiver diff --git a/src/core/receiver/gnss_block_factory.cc b/src/core/receiver/gnss_block_factory.cc index 9b3d32e49..02214b02e 100644 --- a/src/core/receiver/gnss_block_factory.cc +++ b/src/core/receiver/gnss_block_factory.cc @@ -55,6 +55,7 @@ #include "galileo_e5a_noncoherent_iq_acquisition_caf.h" #include "galileo_e5a_pcps_acquisition.h" #include "galileo_e5a_telemetry_decoder.h" +#include "galileo_e5b_dll_pll_tracking.h" #include "galileo_e5b_pcps_acquisition.h" #include "glonass_l1_ca_dll_pll_c_aid_tracking.h" #include "glonass_l1_ca_dll_pll_tracking.h" @@ -1088,6 +1089,12 @@ std::unique_ptr GNSSBlockFactory::GetBlock( out_streams); block = std::move(block_); } + else if (implementation == "Galileo_E5b_DLL_PLL_Tracking") + { + std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, + out_streams); + block = std::move(block_); + } else if (implementation == "GLONASS_L1_CA_DLL_PLL_Tracking") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, @@ -1489,6 +1496,12 @@ std::unique_ptr GNSSBlockFactory::GetTrkBlock( out_streams); block = std::move(block_); } + else if (implementation == "Galileo_E5b_DLL_PLL_Tracking") + { + std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, + out_streams); + block = std::move(block_); + } else if (implementation == "GPS_L2_M_DLL_PLL_Tracking") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, diff --git a/src/tests/test_main.cc b/src/tests/test_main.cc index aba29cd5b..a7a74da2f 100644 --- a/src/tests/test_main.cc +++ b/src/tests/test_main.cc @@ -6,7 +6,7 @@ * * ------------------------------------------------------------------------- * - * Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors) + * Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors) * * GNSS-SDR is a software defined Global Navigation * Satellite Systems receiver @@ -99,6 +99,7 @@ DECLARE_string(log_dir); #include "unit-tests/signal-processing-blocks/tracking/discriminator_test.cc" #include "unit-tests/signal-processing-blocks/tracking/galileo_e1_dll_pll_veml_tracking_test.cc" #include "unit-tests/signal-processing-blocks/tracking/galileo_e5a_tracking_test.cc" +#include "unit-tests/signal-processing-blocks/tracking/galileo_e5b_dll_pll_tracking_test.cc" #include "unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_c_aid_tracking_test.cc" #include "unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_tracking_test.cc" #include "unit-tests/signal-processing-blocks/tracking/tracking_loop_filter_test.cc" diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/galileo_e5b_dll_pll_tracking_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/galileo_e5b_dll_pll_tracking_test.cc new file mode 100644 index 000000000..142bc5e17 --- /dev/null +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/galileo_e5b_dll_pll_tracking_test.cc @@ -0,0 +1,146 @@ +/*! + * \file galileo_e5b_dll_pll_tracking_test.cc + * \brief This class implements a tracking test for Galileo_E5b_DLL_PLL_Tracking + * implementation based on some input parameters. + * \author Piyush Gupta, 2020. piyush04111999@gmail.com + * \note Code added as part of GSoC 2020 Program. + * + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2012-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 "concurrent_queue.h" +#include "galileo_e5b_dll_pll_tracking.h" +#include "gnss_block_factory.h" +#include "gnss_block_interface.h" +#include "gnss_sdr_valve.h" +#include "gnss_synchro.h" +#include "in_memory_configuration.h" +#include +#include +#include +#include +#include +#include +#include +#ifdef GR_GREATER_38 +#include +#else +#include +#endif + + +class GalileoE5bTrackingTest : public ::testing::Test +{ +protected: + GalileoE5bTrackingTest() + { + factory = std::make_shared(); + config = std::make_shared(); + item_size = sizeof(gr_complex); + stop = false; + message = 0; + gnss_synchro = Gnss_Synchro(); + } + + ~GalileoE5bTrackingTest() = default; + + void init(); + + std::shared_ptr> queue; + gr::top_block_sptr top_block; + std::shared_ptr factory; + std::shared_ptr config; + Gnss_Synchro gnss_synchro; + size_t item_size; + bool stop; + int message; +}; + + +void GalileoE5bTrackingTest::init() +{ + gnss_synchro.Channel_ID = 0; + gnss_synchro.System = 'E'; + std::string signal = "7X"; + signal.copy(gnss_synchro.Signal, 2, 0); + gnss_synchro.PRN = 11; + + config->set_property("GNSS-SDR.internal_fs_sps", "32000000"); + config->set_property("Tracking_7X.implementation", "Galileo_E5b_DLL_PLL_Tracking"); + config->set_property("Tracking_7X.item_type", "gr_complex"); + config->set_property("Tracking_7X.dump", "false"); + config->set_property("Tracking_7X.dump_filename", "../data/e5b_tracking"); + config->set_property("Tracking_7X.early_late_space_chips", "0.5"); + config->set_property("Tracking_7X.order", "2"); + config->set_property("Tracking_7X.pll_bw_hz", "20.0"); + config->set_property("Tracking_7X.dll_bw_hz", "5.0"); + config->set_property("Tracking_7X.pll_bw_narrow_hz", "2.0"); + config->set_property("Tracking_7X.pll_bw_narrow_hz", "2.0"); + config->set_property("Tracking_7X.ti_ms", "1"); +} + + +TEST_F(GalileoE5bTrackingTest, ValidationOfResults) +{ + std::chrono::time_point start, end; + std::chrono::duration elapsed_seconds(0); + int fs_in = 32000000; + int nsamples = fs_in * 5; + init(); + queue = std::make_shared>(); + top_block = gr::make_top_block("Tracking test"); + + // Example using smart pointers and the block factory + std::shared_ptr trk_ = factory->GetBlock(config.get(), "Tracking_7X", 1, 1); + std::shared_ptr tracking = std::dynamic_pointer_cast(trk_); + + // REAL + gnss_synchro.Acq_delay_samples = 10; // 32 Msps + gnss_synchro.Acq_doppler_hz = 2000; // 500 Hz resolution + gnss_synchro.Acq_samplestamp_samples = 0; + + ASSERT_NO_THROW({ + tracking->set_channel(gnss_synchro.Channel_ID); + }) << "Failure setting channel."; + + ASSERT_NO_THROW({ + tracking->set_gnss_synchro(&gnss_synchro); + }) << "Failure setting gnss_synchro."; + + ASSERT_NO_THROW({ + tracking->connect(top_block); + }) << "Failure connecting tracking to the top_block."; + + ASSERT_NO_THROW({ + gr::analog::sig_source_c::sptr source = gr::analog::sig_source_c::make(fs_in, gr::analog::GR_SIN_WAVE, 1000, 1, gr_complex(0)); + auto valve = gnss_sdr_make_valve(sizeof(gr_complex), nsamples, queue.get()); + gr::blocks::null_sink::sptr sink = gr::blocks::null_sink::make(sizeof(Gnss_Synchro)); + top_block->connect(source, 0, valve, 0); + top_block->connect(valve, 0, tracking->get_left_block(), 0); + top_block->connect(tracking->get_right_block(), 0, sink, 0); + }) << "Failure connecting the blocks of tracking test."; + + tracking->start_tracking(); + + EXPECT_NO_THROW({ + start = std::chrono::system_clock::now(); + top_block->run(); // Start threads and wait + end = std::chrono::system_clock::now(); + elapsed_seconds = end - start; + }) << "Failure running the top_block."; + + std::cout << "Tracked " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds\n"; +}