From 75a0019896b69fa02abd549d6d741fc2017d37b1 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Sun, 28 May 2017 18:08:03 +0200 Subject: [PATCH 01/81] Adding notch filter files Creation of empty files for notch input filter --- src/algorithms/input_filter/adapters/CMakeLists.txt | 1 + src/algorithms/input_filter/adapters/notch_filter.cc | 0 src/algorithms/input_filter/adapters/notch_filter.h | 0 src/algorithms/input_filter/gnuradio_blocks/CMakeLists.txt | 3 ++- src/algorithms/input_filter/gnuradio_blocks/notch_filter_cc.cc | 0 src/algorithms/input_filter/gnuradio_blocks/notch_filter_cc.h | 0 6 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 src/algorithms/input_filter/adapters/notch_filter.cc create mode 100644 src/algorithms/input_filter/adapters/notch_filter.h create mode 100644 src/algorithms/input_filter/gnuradio_blocks/notch_filter_cc.cc create mode 100644 src/algorithms/input_filter/gnuradio_blocks/notch_filter_cc.h diff --git a/src/algorithms/input_filter/adapters/CMakeLists.txt b/src/algorithms/input_filter/adapters/CMakeLists.txt index daafaf401..38c35012a 100644 --- a/src/algorithms/input_filter/adapters/CMakeLists.txt +++ b/src/algorithms/input_filter/adapters/CMakeLists.txt @@ -21,6 +21,7 @@ set(INPUT_FILTER_ADAPTER_SOURCES freq_xlating_fir_filter.cc beamformer_filter.cc pulse_blanking_filter.cc + notch_filter.cc ) include_directories( diff --git a/src/algorithms/input_filter/adapters/notch_filter.cc b/src/algorithms/input_filter/adapters/notch_filter.cc new file mode 100644 index 000000000..e69de29bb diff --git a/src/algorithms/input_filter/adapters/notch_filter.h b/src/algorithms/input_filter/adapters/notch_filter.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/algorithms/input_filter/gnuradio_blocks/CMakeLists.txt b/src/algorithms/input_filter/gnuradio_blocks/CMakeLists.txt index e2c3a3674..857e54140 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/input_filter/gnuradio_blocks/CMakeLists.txt @@ -20,6 +20,7 @@ set(INPUT_FILTER_GR_BLOCKS_SOURCES beamformer.cc pulse_blanking_cc.cc + notch_filter_cc.cc ) include_directories( @@ -38,4 +39,4 @@ target_link_libraries(input_filter_gr_blocks ${GNURADIO_FILTER_LIBRARIES} ${VOL if(NOT VOLK_GNSSSDR_FOUND) add_dependencies(input_filter_gr_blocks volk_gnsssdr_module) -endif(NOT VOLK_GNSSSDR_FOUND) \ No newline at end of file +endif(NOT VOLK_GNSSSDR_FOUND) diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_filter_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/notch_filter_cc.cc new file mode 100644 index 000000000..e69de29bb diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_filter_cc.h b/src/algorithms/input_filter/gnuradio_blocks/notch_filter_cc.h new file mode 100644 index 000000000..e69de29bb From 405d9dea5cc1f2519c58f6abcf50a5b6194b5725 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Mon, 5 Jun 2017 17:00:33 +0200 Subject: [PATCH 02/81] Modifying notch filter files Little changes in the files --- .../input_filter/adapters/notch_filter.h | 37 +++++++++++++++++++ .../gnuradio_blocks/CMakeLists.txt | 2 +- .../{notch_filter_cc.cc => notch_cc.cc} | 0 .../input_filter/gnuradio_blocks/notch_cc.h | 36 ++++++++++++++++++ .../gnuradio_blocks/notch_filter_cc.h | 0 5 files changed, 74 insertions(+), 1 deletion(-) rename src/algorithms/input_filter/gnuradio_blocks/{notch_filter_cc.cc => notch_cc.cc} (100%) create mode 100644 src/algorithms/input_filter/gnuradio_blocks/notch_cc.h delete mode 100644 src/algorithms/input_filter/gnuradio_blocks/notch_filter_cc.h diff --git a/src/algorithms/input_filter/adapters/notch_filter.h b/src/algorithms/input_filter/adapters/notch_filter.h index e69de29bb..2783dcd37 100644 --- a/src/algorithms/input_filter/adapters/notch_filter.h +++ b/src/algorithms/input_filter/adapters/notch_filter.h @@ -0,0 +1,37 @@ +/*! + * \file notch_filter.h + * \brief + * \author Antonio Ramos, 2017. antonio.ramosdet(at)gmail.com + * + * Detailed description of the file here if needed. + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_NOTCH_FILTER_H_ +#define GNSS_SDR_NOTCH_FILTER_H_ + + +#endif diff --git a/src/algorithms/input_filter/gnuradio_blocks/CMakeLists.txt b/src/algorithms/input_filter/gnuradio_blocks/CMakeLists.txt index 857e54140..718ac1c9a 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/input_filter/gnuradio_blocks/CMakeLists.txt @@ -20,7 +20,7 @@ set(INPUT_FILTER_GR_BLOCKS_SOURCES beamformer.cc pulse_blanking_cc.cc - notch_filter_cc.cc + notch_cc.cc ) include_directories( diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_filter_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc similarity index 100% rename from src/algorithms/input_filter/gnuradio_blocks/notch_filter_cc.cc rename to src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h new file mode 100644 index 000000000..dbe4fa76a --- /dev/null +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h @@ -0,0 +1,36 @@ +/*! + * \file notch_cc.h + * \brief Implements a notch filter algorithm + * \author Antonio Ramos (antonio.ramosdet(at)gmail.com) + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_NOTCH_H_ +#define GNSS_SDR_NOTCH_H_ + + + +#endif \ No newline at end of file diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_filter_cc.h b/src/algorithms/input_filter/gnuradio_blocks/notch_filter_cc.h deleted file mode 100644 index e69de29bb..000000000 From 4c52774da1062b414be24f830b7d5f2db1170705 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Fri, 9 Jun 2017 14:11:20 +0200 Subject: [PATCH 03/81] Including notch filter header to GNSSBlockFactory Adding #include "notch_filter.h" --- src/core/receiver/gnss_block_factory.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/receiver/gnss_block_factory.cc b/src/core/receiver/gnss_block_factory.cc index 0e85d4f2d..a10836917 100644 --- a/src/core/receiver/gnss_block_factory.cc +++ b/src/core/receiver/gnss_block_factory.cc @@ -65,6 +65,7 @@ #include "freq_xlating_fir_filter.h" #include "beamformer_filter.h" #include "pulse_blanking_filter.h" +#include "notch_filter.h" #include "gps_l1_ca_pcps_acquisition.h" #include "gps_l2_m_pcps_acquisition.h" #include "gps_l1_ca_pcps_multithread_acquisition.h" From 2731be3939dea5294aad6da0f86477f84ec2edff Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Fri, 9 Jun 2017 14:12:55 +0200 Subject: [PATCH 04/81] Adding some lines to notch_filter.h Coding the class NotchFilter --- .../input_filter/adapters/notch_filter.h | 42 ++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/src/algorithms/input_filter/adapters/notch_filter.h b/src/algorithms/input_filter/adapters/notch_filter.h index 2783dcd37..d583ecc11 100644 --- a/src/algorithms/input_filter/adapters/notch_filter.h +++ b/src/algorithms/input_filter/adapters/notch_filter.h @@ -33,5 +33,45 @@ #ifndef GNSS_SDR_NOTCH_FILTER_H_ #define GNSS_SDR_NOTCH_FILTER_H_ +#include +#include +#include +#include "gnss_block_interface.h" +#include "notch_cc.h" -#endif +class ConfigurationInterface; + +class NotchFilter: public GNSSBlockInterface +{ +public: + NotchFilter(ConfigurationInterface* configuration, + std::string role, unsigned int in_streams, + unsigned int out_streams); + + virtual ~NotchFilter(); + std::string role() + { + return role_; + } + + //! Returns "Notch_Filter" + std::string implementation() + { + return "Notch_Filter"; + } + size_t item_size() + { + return 0; + } + void connect(gr::top_block_sptr top_block); + void disconnect(gr::top_block_sptr top_block); + gr::basic_block_sptr get_left_block(); + gr::basic_block_sptr get_right_block(); + +private: + ConfigurationInterface* config_; + + +}; + +#endif //GNSS_SDR_NOTCH_FILTER_H_ From 3ed545ac3f48909f56b98502b0877cb5ab1b43bf Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Thu, 15 Jun 2017 10:00:20 +0200 Subject: [PATCH 05/81] Minor changes in notch filter files --- .../input_filter/adapters/notch_filter.cc | 75 +++++++++++++++++++ .../input_filter/adapters/notch_filter.h | 10 +++ .../input_filter/gnuradio_blocks/notch_cc.h | 2 +- 3 files changed, 86 insertions(+), 1 deletion(-) diff --git a/src/algorithms/input_filter/adapters/notch_filter.cc b/src/algorithms/input_filter/adapters/notch_filter.cc index e69de29bb..38517a304 100644 --- a/src/algorithms/input_filter/adapters/notch_filter.cc +++ b/src/algorithms/input_filter/adapters/notch_filter.cc @@ -0,0 +1,75 @@ +/*! + * \file notch_filter.cc + * \brief Adapts a gnuradio gr_notch_filter + * \author Antonio Ramos, 2017. antonio.ramosdet(at)gmail.com + * + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include "notch_filter.h" +#include +#include +#include +#include "configuration_interface.h" + +using google::LogMessage; + +NotchFilter::NotchFilter(ConfigurationInterface* configuration, std::string role, + unsigned int in_streams, unsigned int out_streams) : + config_(configuration), role_(role), in_streams_(in_streams), + out_streams_(out_streams) +{ + (*this).init(); +} + +NotchFilter::~NotchFilter() +{} + +void NotchFilter::connect(gr::top_block_sptr top_block) +{ + +} + +void NotchFilter::disconnect(gr::top_block_sptr top_block) +{ + +} + + +gr::basic_block_sptr NotchFilter::get_left_block() +{ + +} + +gr::basic_block_sptr NotchFilter::get_right_block() +{ + +} + +void NotchFilter::init() +{ + +} \ No newline at end of file diff --git a/src/algorithms/input_filter/adapters/notch_filter.h b/src/algorithms/input_filter/adapters/notch_filter.h index d583ecc11..8f929b6a3 100644 --- a/src/algorithms/input_filter/adapters/notch_filter.h +++ b/src/algorithms/input_filter/adapters/notch_filter.h @@ -69,7 +69,17 @@ public: gr::basic_block_sptr get_right_block(); private: + gr::filter::iir_filter_ccc::sptr iir_filter_ccf_; ConfigurationInterface* config_; + bool dump_; + std::string dump_filename_; + std::string input_item_type_; + std::string output_item_type_; + std::string role_; + unsigned int in_streams_; + unsigned int out_streams_; + gr::blocks::file_sink::sptr file_sink_; + void init(); }; diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h index dbe4fa76a..a3727c73f 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h @@ -33,4 +33,4 @@ -#endif \ No newline at end of file +#endif //GNSS_SDR_NOTCH_H_ \ No newline at end of file From 70dc68b984349ccc673215816654352bda9dd089 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Fri, 16 Jun 2017 13:55:15 +0200 Subject: [PATCH 06/81] Several changes in notch input filter adapter Re-definition of the adapter --- .../input_filter/adapters/notch_filter.cc | 61 +++++++++++++++---- .../input_filter/adapters/notch_filter.h | 11 ++-- 2 files changed, 53 insertions(+), 19 deletions(-) diff --git a/src/algorithms/input_filter/adapters/notch_filter.cc b/src/algorithms/input_filter/adapters/notch_filter.cc index 38517a304..665d634b0 100644 --- a/src/algorithms/input_filter/adapters/notch_filter.cc +++ b/src/algorithms/input_filter/adapters/notch_filter.cc @@ -30,19 +30,50 @@ */ #include "notch_filter.h" +#include +#include +#include #include +#include #include -#include #include "configuration_interface.h" +#include "notch_cc.cc" using google::LogMessage; NotchFilter::NotchFilter(ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : - config_(configuration), role_(role), in_streams_(in_streams), + role_(role), in_streams_(in_streams), out_streams_(out_streams) { - (*this).init(); + size_t item_size_; + std::string default_item_type = "gr_complex"; + std::string default_dump_file = "./data/input_filter.dat"; + item_type_ = configuration->property(role + ".item_type", default_item_type); + dump_ = configuration->property(role + ".dump", false); + DLOG(INFO) << "dump_ is " << dump_; + dump_filename_ = configuration->property(role + ".dump_filename", default_dump_file); + + if (item_type_.compare("gr_complex") == 0) + { + item_size_ = sizeof(gr_complex); + notch_filter_ = make_notch_filter(); + DLOG(INFO) << "Item size " << item_size_; + DLOG(INFO) << "input filter(" << notch_filter_->unique_id() << ")"; + + } + else + { + LOG(WARNING) << item_type_ + << " unrecognized item type for notch filter"; + item_size_ = sizeof(gr_complex); + } + if (dump_) + { + DLOG(INFO) << "Dumping output into file " << dump_filename_; + file_sink_ = gr::blocks::file_sink::make(item_size_, dump_filename_.c_str()); + DLOG(INFO) << "file_sink(" << file_sink_->unique_id() << ")"; + } } NotchFilter::~NotchFilter() @@ -50,26 +81,32 @@ NotchFilter::~NotchFilter() void NotchFilter::connect(gr::top_block_sptr top_block) { - + if (dump_) + { + top_block->connect(notch_filter_, 0, file_sink_, 0); + DLOG(INFO) << "connected notch filter output to file sink"; + } + else + { + DLOG(INFO) << "nothing to connect internally"; + } } void NotchFilter::disconnect(gr::top_block_sptr top_block) { - + if (dump_) + { + top_block->disconnect(notch_filter_, 0, file_sink_, 0); + } } gr::basic_block_sptr NotchFilter::get_left_block() { - + return notch_filter_; } gr::basic_block_sptr NotchFilter::get_right_block() { - + return notch_filter_; } - -void NotchFilter::init() -{ - -} \ No newline at end of file diff --git a/src/algorithms/input_filter/adapters/notch_filter.h b/src/algorithms/input_filter/adapters/notch_filter.h index 8f929b6a3..31ae255ba 100644 --- a/src/algorithms/input_filter/adapters/notch_filter.h +++ b/src/algorithms/input_filter/adapters/notch_filter.h @@ -37,7 +37,7 @@ #include #include #include "gnss_block_interface.h" -#include "notch_cc.h" + class ConfigurationInterface; @@ -69,19 +69,16 @@ public: gr::basic_block_sptr get_right_block(); private: - gr::filter::iir_filter_ccc::sptr iir_filter_ccf_; + ConfigurationInterface* config_; bool dump_; std::string dump_filename_; - std::string input_item_type_; - std::string output_item_type_; std::string role_; + std::string item_type_; unsigned int in_streams_; unsigned int out_streams_; gr::blocks::file_sink::sptr file_sink_; - void init(); - - + gr::block_sptr notch_filter_; }; #endif //GNSS_SDR_NOTCH_FILTER_H_ From 93de803b4172a3a4b40b6129ab5d08ac67fa3b2a Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Mon, 19 Jun 2017 15:22:54 +0200 Subject: [PATCH 07/81] GetBlock method modification Adding Notch_Filter to the list of implementations --- src/core/receiver/gnss_block_factory.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/core/receiver/gnss_block_factory.cc b/src/core/receiver/gnss_block_factory.cc index a10836917..cac56293a 100644 --- a/src/core/receiver/gnss_block_factory.cc +++ b/src/core/receiver/gnss_block_factory.cc @@ -883,6 +883,12 @@ std::unique_ptr GNSSBlockFactory::GetBlock( out_streams)); block = std::move(block_); } + else if (implementation.compare("Notch_Filter") == 0) + { + std::unique_ptr block_(new NotchFilter(configuration.get(), role, in_streams, + out_streams)); + block = std::move(block_); + } // RESAMPLER ------------------------------------------------------------------- From cf516566d6175e65383e9ed3cf207d8d6939e952 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Mon, 19 Jun 2017 15:51:57 +0200 Subject: [PATCH 08/81] New lines in notch filter files Adapter is ready and gnuradio block in progress --- .../input_filter/adapters/notch_filter.cc | 12 +++- .../input_filter/adapters/notch_filter.h | 1 - .../input_filter/gnuradio_blocks/notch_cc.cc | 64 +++++++++++++++++++ .../input_filter/gnuradio_blocks/notch_cc.h | 40 +++++++++++- 4 files changed, 113 insertions(+), 4 deletions(-) diff --git a/src/algorithms/input_filter/adapters/notch_filter.cc b/src/algorithms/input_filter/adapters/notch_filter.cc index 665d634b0..31fb6a93d 100644 --- a/src/algorithms/input_filter/adapters/notch_filter.cc +++ b/src/algorithms/input_filter/adapters/notch_filter.cc @@ -47,17 +47,25 @@ NotchFilter::NotchFilter(ConfigurationInterface* configuration, std::string role out_streams_(out_streams) { size_t item_size_; + double pfa; + double default_pfa = 0.001; + double p_c_factor; + double default_p_c_factor = 0.9; + unsigned int length_; + unsigned int default_length_ = 5; std::string default_item_type = "gr_complex"; std::string default_dump_file = "./data/input_filter.dat"; item_type_ = configuration->property(role + ".item_type", default_item_type); dump_ = configuration->property(role + ".dump", false); DLOG(INFO) << "dump_ is " << dump_; dump_filename_ = configuration->property(role + ".dump_filename", default_dump_file); - + pfa = configuration->property(role + ".pfa", default_pfa); + p_c_factor = configuration->property(role + ".p_c_factor", default_p_c_factor); + length_ = configuration->property(role + ".length", default_length_); if (item_type_.compare("gr_complex") == 0) { item_size_ = sizeof(gr_complex); - notch_filter_ = make_notch_filter(); + notch_filter_ = make_notch_filter(pfa, p_c_factor, length_); DLOG(INFO) << "Item size " << item_size_; DLOG(INFO) << "input filter(" << notch_filter_->unique_id() << ")"; diff --git a/src/algorithms/input_filter/adapters/notch_filter.h b/src/algorithms/input_filter/adapters/notch_filter.h index 31ae255ba..9341cd77b 100644 --- a/src/algorithms/input_filter/adapters/notch_filter.h +++ b/src/algorithms/input_filter/adapters/notch_filter.h @@ -70,7 +70,6 @@ public: private: - ConfigurationInterface* config_; bool dump_; std::string dump_filename_; std::string role_; diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc index e69de29bb..a802c67a0 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc @@ -0,0 +1,64 @@ +/*! + * \file notch_cc.cc + * \brief Implements a multi state notch filter algorithm + * \author Antonio Ramos (antonio.ramosdet(at)gmail.com) + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include "notch_cc.h" +#include +#include +#include +#include +#include + +notch_sptr make_notch_filter(double pfa, double p_c_factor, + unsigned int length_) +{ + return notch_sptr(new Notch(pfa, p_c_factor, length_)); +} + +Notch::Notch(double pfa, double p_c_factor, unsigned int length_) : gr::block("Notch", + gr::io_signature::make (1, 1, sizeof(gr_complex)), + gr::io_signature::make (1, 1, sizeof(gr_complex))) +{ + this->pfa = pfa; + this->noise_pow_est = 0.0; + this->p_c_factor = p_c_factor; + this->length_ = length_; + filter_state_ = 0; + n_deg_fred = 2 * length_; + z_0 = gr_complex(0 , 0); + thres_ = + +} + + +int Notch::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), + gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) +{ + +} diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h index a3727c73f..6a34d0955 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h @@ -31,6 +31,44 @@ #ifndef GNSS_SDR_NOTCH_H_ #define GNSS_SDR_NOTCH_H_ +#include +#include +class Notch; -#endif //GNSS_SDR_NOTCH_H_ \ No newline at end of file +typedef boost::shared_ptr notch_sptr; + +notch_sptr make_notch_filter(double pfa, double p_c_factor, + unsigned int length_); + +/*! + * \brief This class implements a real-time software-defined multi state notch filter + */ + +class Notch: public gr::block +{ +private: + + friend notch_sptr make_notch_filter(double pfa, double p_c_factor, + unsigned int length_); + double pfa; + double noise_pow_est; + double p_c_factor; + double thres_; + unsigned int length_; + unsigned int n_deg_fred; + unsigned int filter_state_; + gr_complex z_0; + + +public: + + Notch(double pfa, double p_c_factor, unsigned int length_); + + ~Notch(); + + int work (int noutput_items, gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +#endif //GNSS_SDR_NOTCH_H_ From 660e3fe3aa28d42649cda3c1c9a2a2d83d055a33 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Tue, 20 Jun 2017 18:13:52 +0200 Subject: [PATCH 09/81] Beta version of notch input filter Beta version of general_work method implemented --- .../input_filter/adapters/notch_filter.cc | 14 ++-- .../input_filter/adapters/notch_filter.h | 3 +- .../input_filter/gnuradio_blocks/notch_cc.cc | 75 +++++++++++++++++-- .../input_filter/gnuradio_blocks/notch_cc.h | 34 +++++---- 4 files changed, 95 insertions(+), 31 deletions(-) diff --git a/src/algorithms/input_filter/adapters/notch_filter.cc b/src/algorithms/input_filter/adapters/notch_filter.cc index 31fb6a93d..abab1a03e 100644 --- a/src/algorithms/input_filter/adapters/notch_filter.cc +++ b/src/algorithms/input_filter/adapters/notch_filter.cc @@ -37,7 +37,7 @@ #include #include #include "configuration_interface.h" -#include "notch_cc.cc" +#include "notch_cc.h" using google::LogMessage; @@ -47,12 +47,12 @@ NotchFilter::NotchFilter(ConfigurationInterface* configuration, std::string role out_streams_(out_streams) { size_t item_size_; - double pfa; - double default_pfa = 0.001; - double p_c_factor; - double default_p_c_factor = 0.9; - unsigned int length_; - unsigned int default_length_ = 5; + float pfa; + float default_pfa = 0.001; + float p_c_factor; + float default_p_c_factor = 0.9; + int length_; + int default_length_ = 5; std::string default_item_type = "gr_complex"; std::string default_dump_file = "./data/input_filter.dat"; item_type_ = configuration->property(role + ".item_type", default_item_type); diff --git a/src/algorithms/input_filter/adapters/notch_filter.h b/src/algorithms/input_filter/adapters/notch_filter.h index 9341cd77b..09ac10e99 100644 --- a/src/algorithms/input_filter/adapters/notch_filter.h +++ b/src/algorithms/input_filter/adapters/notch_filter.h @@ -37,6 +37,7 @@ #include #include #include "gnss_block_interface.h" +#include "notch_cc.h" class ConfigurationInterface; @@ -77,7 +78,7 @@ private: unsigned int in_streams_; unsigned int out_streams_; gr::blocks::file_sink::sptr file_sink_; - gr::block_sptr notch_filter_; + notch_sptr notch_filter_; }; #endif //GNSS_SDR_NOTCH_FILTER_H_ diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc index a802c67a0..f111412f5 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc @@ -32,27 +32,32 @@ #include #include #include -#include #include +#include -notch_sptr make_notch_filter(double pfa, double p_c_factor, - unsigned int length_) +notch_sptr make_notch_filter(float pfa, float p_c_factor, + int length_) { return notch_sptr(new Notch(pfa, p_c_factor, length_)); } -Notch::Notch(double pfa, double p_c_factor, unsigned int length_) : gr::block("Notch", +Notch::Notch(float pfa, float p_c_factor, int length_) : gr::block("Notch", gr::io_signature::make (1, 1, sizeof(gr_complex)), gr::io_signature::make (1, 1, sizeof(gr_complex))) { + const int alignment_multiple = volk_get_alignment() / sizeof(gr_complex); + set_alignment(std::max(1, alignment_multiple)); this->pfa = pfa; - this->noise_pow_est = 0.0; + noise_pow_est = 0.0; this->p_c_factor = p_c_factor; this->length_ = length_; - filter_state_ = 0; + filter_state_ = false; n_deg_fred = 2 * length_; + n_segments_est = 5; + n_segments = 0; z_0 = gr_complex(0 , 0); - thres_ = + boost::math::chi_squared_distribution my_dist_(n_deg_fred); + thres_ = boost::math::quantile(boost::math::complement(my_dist_, pfa)); } @@ -60,5 +65,59 @@ Notch::Notch(double pfa, double p_c_factor, unsigned int length_) : gr::block("N int Notch::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { - + gr_complex * in = (gr_complex *) input_items[0]; + gr_complex *out = (gr_complex *) output_items[0]; + gr_complex * paux; + int samples_proc = 0; + int aux = 0; + gr_complex magnitude; + float sig2 = 0.0; + float* angle_; + gr_complex * c_samples; + c_samples = static_cast(volk_malloc(length_ * sizeof(gr_complex), volk_get_alignment())); + angle_ = static_cast(volk_malloc(length_ * sizeof(float), volk_get_alignment())); + while(((samples_proc + length_) < noutput_items) && (n_segments < n_segments_est)) + { + volk_32fc_x2_conjugate_dot_prod_32fc(&magnitude, in, in, length_); + sig2 = magnitude.real() / ((float) n_deg_fred); + noise_pow_est = (((float) n_segments) * noise_pow_est + sig2) / ((float)(n_segments + 1)); + samples_proc = samples_proc + length_; + n_segments++; + memcpy(out, in, sizeof(gr_complex)*length_); + in = (gr_complex *) input_items[samples_proc]; + out = (gr_complex *) output_items[samples_proc]; + } + while((samples_proc + length_) < noutput_items) + { + volk_32fc_x2_conjugate_dot_prod_32fc(&magnitude, in, in, length_); + if( (magnitude.real() / noise_pow_est) > thres_) + { + filter_state_ = true; + paux = (gr_complex *) input_items[samples_proc-1]; + volk_32fc_x2_multiply_conjugate_32fc(c_samples, in, paux, length_); + volk_32fc_s32f_atan2_32f(angle_, c_samples, (float)1.0, length_); + for(aux = 0; aux < length_; aux++) + { + z_0 = std::exp(gr_complex(0,1) *angle_[aux]); + out[samples_proc] = in[samples_proc] - z_0 * in[samples_proc - 1] + + gr_complex(p_c_factor,0) * z_0 * out[samples_proc -1]; + samples_proc++; + in = (gr_complex *) input_items[samples_proc]; + out = (gr_complex *) output_items[samples_proc]; + } + + } + else + { + filter_state_ = false; + samples_proc = samples_proc + length_; + memcpy(out, in, sizeof(gr_complex)*length_); + in = (gr_complex *) input_items[samples_proc]; + out = (gr_complex *) output_items[samples_proc]; + } + } + volk_free(c_samples); + volk_free(angle_); + consume_each(samples_proc); + return samples_proc; } diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h index 6a34d0955..ad12c49c4 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h @@ -38,37 +38,41 @@ class Notch; typedef boost::shared_ptr notch_sptr; -notch_sptr make_notch_filter(double pfa, double p_c_factor, - unsigned int length_); +notch_sptr make_notch_filter(float pfa, float p_c_factor, + int length_); /*! * \brief This class implements a real-time software-defined multi state notch filter */ -class Notch: public gr::block +class Notch : public gr::block { private: - friend notch_sptr make_notch_filter(double pfa, double p_c_factor, - unsigned int length_); - double pfa; - double noise_pow_est; - double p_c_factor; - double thres_; - unsigned int length_; - unsigned int n_deg_fred; - unsigned int filter_state_; + float pfa; + float noise_pow_est; + float p_c_factor; + float thres_; + int length_; + int n_segments_est; + int n_segments; + int n_deg_fred; + bool filter_state_; gr_complex z_0; public: - Notch(double pfa, double p_c_factor, unsigned int length_); + //friend notch_sptr make_notch_filter(float pfa, float p_c_factor, + // int length_); + + Notch(float pfa, float p_c_factor, int length_); ~Notch(); - int work (int noutput_items, gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); + int general_work (int noutput_items, gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); }; #endif //GNSS_SDR_NOTCH_H_ From 7fba751a49b9059195dfdca62fd56e89b7444086 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Tue, 20 Jun 2017 18:13:52 +0200 Subject: [PATCH 10/81] Beta version of notch input filter Beta version of general_work method implemented --- .../input_filter/adapters/notch_filter.cc | 14 ++-- .../input_filter/adapters/notch_filter.h | 3 +- .../input_filter/gnuradio_blocks/notch_cc.cc | 75 +++++++++++++++++-- .../input_filter/gnuradio_blocks/notch_cc.h | 36 ++++----- 4 files changed, 95 insertions(+), 33 deletions(-) diff --git a/src/algorithms/input_filter/adapters/notch_filter.cc b/src/algorithms/input_filter/adapters/notch_filter.cc index 31fb6a93d..abab1a03e 100644 --- a/src/algorithms/input_filter/adapters/notch_filter.cc +++ b/src/algorithms/input_filter/adapters/notch_filter.cc @@ -37,7 +37,7 @@ #include #include #include "configuration_interface.h" -#include "notch_cc.cc" +#include "notch_cc.h" using google::LogMessage; @@ -47,12 +47,12 @@ NotchFilter::NotchFilter(ConfigurationInterface* configuration, std::string role out_streams_(out_streams) { size_t item_size_; - double pfa; - double default_pfa = 0.001; - double p_c_factor; - double default_p_c_factor = 0.9; - unsigned int length_; - unsigned int default_length_ = 5; + float pfa; + float default_pfa = 0.001; + float p_c_factor; + float default_p_c_factor = 0.9; + int length_; + int default_length_ = 5; std::string default_item_type = "gr_complex"; std::string default_dump_file = "./data/input_filter.dat"; item_type_ = configuration->property(role + ".item_type", default_item_type); diff --git a/src/algorithms/input_filter/adapters/notch_filter.h b/src/algorithms/input_filter/adapters/notch_filter.h index 9341cd77b..09ac10e99 100644 --- a/src/algorithms/input_filter/adapters/notch_filter.h +++ b/src/algorithms/input_filter/adapters/notch_filter.h @@ -37,6 +37,7 @@ #include #include #include "gnss_block_interface.h" +#include "notch_cc.h" class ConfigurationInterface; @@ -77,7 +78,7 @@ private: unsigned int in_streams_; unsigned int out_streams_; gr::blocks::file_sink::sptr file_sink_; - gr::block_sptr notch_filter_; + notch_sptr notch_filter_; }; #endif //GNSS_SDR_NOTCH_FILTER_H_ diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc index a802c67a0..f111412f5 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc @@ -32,27 +32,32 @@ #include #include #include -#include #include +#include -notch_sptr make_notch_filter(double pfa, double p_c_factor, - unsigned int length_) +notch_sptr make_notch_filter(float pfa, float p_c_factor, + int length_) { return notch_sptr(new Notch(pfa, p_c_factor, length_)); } -Notch::Notch(double pfa, double p_c_factor, unsigned int length_) : gr::block("Notch", +Notch::Notch(float pfa, float p_c_factor, int length_) : gr::block("Notch", gr::io_signature::make (1, 1, sizeof(gr_complex)), gr::io_signature::make (1, 1, sizeof(gr_complex))) { + const int alignment_multiple = volk_get_alignment() / sizeof(gr_complex); + set_alignment(std::max(1, alignment_multiple)); this->pfa = pfa; - this->noise_pow_est = 0.0; + noise_pow_est = 0.0; this->p_c_factor = p_c_factor; this->length_ = length_; - filter_state_ = 0; + filter_state_ = false; n_deg_fred = 2 * length_; + n_segments_est = 5; + n_segments = 0; z_0 = gr_complex(0 , 0); - thres_ = + boost::math::chi_squared_distribution my_dist_(n_deg_fred); + thres_ = boost::math::quantile(boost::math::complement(my_dist_, pfa)); } @@ -60,5 +65,59 @@ Notch::Notch(double pfa, double p_c_factor, unsigned int length_) : gr::block("N int Notch::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { - + gr_complex * in = (gr_complex *) input_items[0]; + gr_complex *out = (gr_complex *) output_items[0]; + gr_complex * paux; + int samples_proc = 0; + int aux = 0; + gr_complex magnitude; + float sig2 = 0.0; + float* angle_; + gr_complex * c_samples; + c_samples = static_cast(volk_malloc(length_ * sizeof(gr_complex), volk_get_alignment())); + angle_ = static_cast(volk_malloc(length_ * sizeof(float), volk_get_alignment())); + while(((samples_proc + length_) < noutput_items) && (n_segments < n_segments_est)) + { + volk_32fc_x2_conjugate_dot_prod_32fc(&magnitude, in, in, length_); + sig2 = magnitude.real() / ((float) n_deg_fred); + noise_pow_est = (((float) n_segments) * noise_pow_est + sig2) / ((float)(n_segments + 1)); + samples_proc = samples_proc + length_; + n_segments++; + memcpy(out, in, sizeof(gr_complex)*length_); + in = (gr_complex *) input_items[samples_proc]; + out = (gr_complex *) output_items[samples_proc]; + } + while((samples_proc + length_) < noutput_items) + { + volk_32fc_x2_conjugate_dot_prod_32fc(&magnitude, in, in, length_); + if( (magnitude.real() / noise_pow_est) > thres_) + { + filter_state_ = true; + paux = (gr_complex *) input_items[samples_proc-1]; + volk_32fc_x2_multiply_conjugate_32fc(c_samples, in, paux, length_); + volk_32fc_s32f_atan2_32f(angle_, c_samples, (float)1.0, length_); + for(aux = 0; aux < length_; aux++) + { + z_0 = std::exp(gr_complex(0,1) *angle_[aux]); + out[samples_proc] = in[samples_proc] - z_0 * in[samples_proc - 1] + + gr_complex(p_c_factor,0) * z_0 * out[samples_proc -1]; + samples_proc++; + in = (gr_complex *) input_items[samples_proc]; + out = (gr_complex *) output_items[samples_proc]; + } + + } + else + { + filter_state_ = false; + samples_proc = samples_proc + length_; + memcpy(out, in, sizeof(gr_complex)*length_); + in = (gr_complex *) input_items[samples_proc]; + out = (gr_complex *) output_items[samples_proc]; + } + } + volk_free(c_samples); + volk_free(angle_); + consume_each(samples_proc); + return samples_proc; } diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h index 6a34d0955..29e292b95 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h @@ -38,37 +38,39 @@ class Notch; typedef boost::shared_ptr notch_sptr; -notch_sptr make_notch_filter(double pfa, double p_c_factor, - unsigned int length_); +notch_sptr make_notch_filter(float pfa, float p_c_factor, + int length_); /*! * \brief This class implements a real-time software-defined multi state notch filter */ -class Notch: public gr::block +class Notch : public gr::block { private: - friend notch_sptr make_notch_filter(double pfa, double p_c_factor, - unsigned int length_); - double pfa; - double noise_pow_est; - double p_c_factor; - double thres_; - unsigned int length_; - unsigned int n_deg_fred; - unsigned int filter_state_; + float pfa; + float noise_pow_est; + float p_c_factor; + float thres_; + int length_; + int n_segments_est; + int n_segments; + int n_deg_fred; + bool filter_state_; gr_complex z_0; public: - Notch(double pfa, double p_c_factor, unsigned int length_); + //friend notch_sptr make_notch_filter(float pfa, float p_c_factor, + // int length_); - ~Notch(); - - int work (int noutput_items, gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); + Notch(float pfa, float p_c_factor, int length_); + + int general_work (int noutput_items, gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); }; #endif //GNSS_SDR_NOTCH_H_ From d67d9b270e65282b799eaf41c879bfee626cfa43 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Fri, 23 Jun 2017 11:34:02 +0200 Subject: [PATCH 11/81] Improved multistate notch filter Better managing of the system memory --- .../input_filter/gnuradio_blocks/notch_cc.cc | 92 +++++++++++-------- .../input_filter/gnuradio_blocks/notch_cc.h | 20 ++-- 2 files changed, 69 insertions(+), 43 deletions(-) diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc index f111412f5..cde7eae38 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc @@ -47,77 +47,97 @@ Notch::Notch(float pfa, float p_c_factor, int length_) : gr::block("Notch", { const int alignment_multiple = volk_get_alignment() / sizeof(gr_complex); set_alignment(std::max(1, alignment_multiple)); + set_history(2); this->pfa = pfa; noise_pow_est = 0.0; this->p_c_factor = p_c_factor; - this->length_ = length_; - filter_state_ = false; - n_deg_fred = 2 * length_; - n_segments_est = 5; - n_segments = 0; + this->length_ = length_; //Set the number of samples per segment + set_output_multiple(length_); + filter_state_ = false; //Initial state of the filter + n_deg_fred = 2 * length_; //Number of dregrees of freedom + n_segments = 0; + n_segments_est = 8; // Set the number of segments for noise power estimation + n_segments_reset = 1000000; // Set the period (in segments) when the noise power is estimated z_0 = gr_complex(0 , 0); boost::math::chi_squared_distribution my_dist_(n_deg_fred); thres_ = boost::math::quantile(boost::math::complement(my_dist_, pfa)); - + in = NULL; + out = NULL; + paux = NULL; + c_samples = static_cast(volk_malloc(length_ * sizeof(gr_complex), volk_get_alignment())); + angle_ = static_cast(volk_malloc(length_ * sizeof(float), volk_get_alignment())); + last_out = gr_complex(0,0); } +Notch::~Notch() +{ + volk_free(c_samples); + volk_free(angle_); +} int Notch::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { - gr_complex * in = (gr_complex *) input_items[0]; - gr_complex *out = (gr_complex *) output_items[0]; - gr_complex * paux; - int samples_proc = 0; + int index_in = 1; + int index_out = 0; + in = (gr_complex *) input_items[index_in]; + out = (gr_complex *) output_items[index_out]; int aux = 0; gr_complex magnitude; float sig2 = 0.0; - float* angle_; - gr_complex * c_samples; - c_samples = static_cast(volk_malloc(length_ * sizeof(gr_complex), volk_get_alignment())); - angle_ = static_cast(volk_malloc(length_ * sizeof(float), volk_get_alignment())); - while(((samples_proc + length_) < noutput_items) && (n_segments < n_segments_est)) + while(((index_out + length_) < noutput_items) && (n_segments < n_segments_est) && (filter_state_ == false)) { volk_32fc_x2_conjugate_dot_prod_32fc(&magnitude, in, in, length_); sig2 = magnitude.real() / ((float) n_deg_fred); noise_pow_est = (((float) n_segments) * noise_pow_est + sig2) / ((float)(n_segments + 1)); - samples_proc = samples_proc + length_; + index_out = index_out + length_; + index_in = index_in +length_; n_segments++; - memcpy(out, in, sizeof(gr_complex)*length_); - in = (gr_complex *) input_items[samples_proc]; - out = (gr_complex *) output_items[samples_proc]; + memcpy(out, in, sizeof(gr_complex) * length_); + in = (gr_complex *) input_items[index_in]; + out = (gr_complex *) output_items[index_out]; } - while((samples_proc + length_) < noutput_items) + while((index_out + length_) < noutput_items) { + n_segments++; volk_32fc_x2_conjugate_dot_prod_32fc(&magnitude, in, in, length_); if( (magnitude.real() / noise_pow_est) > thres_) { - filter_state_ = true; - paux = (gr_complex *) input_items[samples_proc-1]; + if(filter_state_ == false) + { + filter_state_ = true; + last_out = gr_complex(0,0); + } + paux = (gr_complex *) input_items[index_in-1]; volk_32fc_x2_multiply_conjugate_32fc(c_samples, in, paux, length_); volk_32fc_s32f_atan2_32f(angle_, c_samples, (float)1.0, length_); for(aux = 0; aux < length_; aux++) { - z_0 = std::exp(gr_complex(0,1) *angle_[aux]); - out[samples_proc] = in[samples_proc] - z_0 * in[samples_proc - 1] - + gr_complex(p_c_factor,0) * z_0 * out[samples_proc -1]; - samples_proc++; - in = (gr_complex *) input_items[samples_proc]; - out = (gr_complex *) output_items[samples_proc]; + z_0 = std::exp(gr_complex(0,1) * angle_[aux]); + out[index_out] = in[index_in] - z_0 * in[index_in - 1] + + gr_complex(p_c_factor,0) * z_0 * last_out; + last_out = out[index_out]; + index_out++; + index_in++; + in = (gr_complex *) input_items[index_in]; + out = (gr_complex *) output_items[index_out]; } } else { + if (n_segments > n_segments_reset) + { + n_segments = 0; + } filter_state_ = false; - samples_proc = samples_proc + length_; - memcpy(out, in, sizeof(gr_complex)*length_); - in = (gr_complex *) input_items[samples_proc]; - out = (gr_complex *) output_items[samples_proc]; + index_out = index_out + length_; + index_in = index_in +length_; + memcpy(out, in, sizeof(gr_complex) * length_); + in = (gr_complex *) input_items[index_in]; + out = (gr_complex *) output_items[index_out]; } } - volk_free(c_samples); - volk_free(angle_); - consume_each(samples_proc); - return samples_proc; + consume_each(index_out); + return index_out; } diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h index 29e292b95..5f7c469a8 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h @@ -54,20 +54,26 @@ private: float p_c_factor; float thres_; int length_; - int n_segments_est; - int n_segments; + unsigned int n_segments; + unsigned int n_segments_est; + unsigned int n_segments_reset; int n_deg_fred; bool filter_state_; + gr_complex last_out; gr_complex z_0; + gr_complex* in; + gr_complex* out; + gr_complex* paux; + gr_complex* c_samples; + float* angle_; public: - - //friend notch_sptr make_notch_filter(float pfa, float p_c_factor, - // int length_); - + Notch(float pfa, float p_c_factor, int length_); - + + ~Notch(); + int general_work (int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); From 119c8c19663fa5e4236fc0a9ddd352f5b90eb9bd Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Fri, 7 Jul 2017 11:48:54 +0200 Subject: [PATCH 12/81] Notch filter solved problems Segmentation fault due to pointers in the notch filter gnu radio block solved --- .../input_filter/adapters/notch_filter.cc | 2 +- .../input_filter/gnuradio_blocks/notch_cc.cc | 56 ++++++++++--------- .../input_filter/gnuradio_blocks/notch_cc.h | 8 +-- 3 files changed, 34 insertions(+), 32 deletions(-) diff --git a/src/algorithms/input_filter/adapters/notch_filter.cc b/src/algorithms/input_filter/adapters/notch_filter.cc index abab1a03e..a69c0c9c0 100644 --- a/src/algorithms/input_filter/adapters/notch_filter.cc +++ b/src/algorithms/input_filter/adapters/notch_filter.cc @@ -52,7 +52,7 @@ NotchFilter::NotchFilter(ConfigurationInterface* configuration, std::string role float p_c_factor; float default_p_c_factor = 0.9; int length_; - int default_length_ = 5; + int default_length_ = 32; std::string default_item_type = "gr_complex"; std::string default_dump_file = "./data/input_filter.dat"; item_type_ = configuration->property(role + ".item_type", default_item_type); diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc index cde7eae38..7b5d7db6e 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc @@ -32,8 +32,14 @@ #include #include #include +#include +#include #include #include +#include +#include + +using google::LogMessage; notch_sptr make_notch_filter(float pfa, float p_c_factor, int length_) @@ -50,7 +56,7 @@ Notch::Notch(float pfa, float p_c_factor, int length_) : gr::block("Notch", set_history(2); this->pfa = pfa; noise_pow_est = 0.0; - this->p_c_factor = p_c_factor; + this->p_c_factor = gr_complex(p_c_factor , 0); this->length_ = length_; //Set the number of samples per segment set_output_multiple(length_); filter_state_ = false; //Initial state of the filter @@ -61,9 +67,6 @@ Notch::Notch(float pfa, float p_c_factor, int length_) : gr::block("Notch", z_0 = gr_complex(0 , 0); boost::math::chi_squared_distribution my_dist_(n_deg_fred); thres_ = boost::math::quantile(boost::math::complement(my_dist_, pfa)); - in = NULL; - out = NULL; - paux = NULL; c_samples = static_cast(volk_malloc(length_ * sizeof(gr_complex), volk_get_alignment())); angle_ = static_cast(volk_malloc(length_ * sizeof(float), volk_get_alignment())); last_out = gr_complex(0,0); @@ -78,49 +81,52 @@ Notch::~Notch() int Notch::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { + int index_in = 1; int index_out = 0; - in = (gr_complex *) input_items[index_in]; - out = (gr_complex *) output_items[index_out]; int aux = 0; - gr_complex magnitude; + lv_32fc_t magnitude; float sig2 = 0.0; + gr_complex* in = (gr_complex *) input_items[0]; + gr_complex* out = (gr_complex *) output_items[0]; + gr_complex* paux; + in++; while(((index_out + length_) < noutput_items) && (n_segments < n_segments_est) && (filter_state_ == false)) { volk_32fc_x2_conjugate_dot_prod_32fc(&magnitude, in, in, length_); - sig2 = magnitude.real() / ((float) n_deg_fred); + sig2 = lv_creal(magnitude) / ((float) n_deg_fred); noise_pow_est = (((float) n_segments) * noise_pow_est + sig2) / ((float)(n_segments + 1)); - index_out = index_out + length_; - index_in = index_in +length_; + index_out += length_; + index_in += length_; n_segments++; memcpy(out, in, sizeof(gr_complex) * length_); - in = (gr_complex *) input_items[index_in]; - out = (gr_complex *) output_items[index_out]; + in += length_; + out += length_; } while((index_out + length_) < noutput_items) { n_segments++; volk_32fc_x2_conjugate_dot_prod_32fc(&magnitude, in, in, length_); - if( (magnitude.real() / noise_pow_est) > thres_) + if( (lv_creal(magnitude) / noise_pow_est) > thres_) { if(filter_state_ == false) { filter_state_ = true; last_out = gr_complex(0,0); } - paux = (gr_complex *) input_items[index_in-1]; + paux = in - 1; volk_32fc_x2_multiply_conjugate_32fc(c_samples, in, paux, length_); - volk_32fc_s32f_atan2_32f(angle_, c_samples, (float)1.0, length_); + volk_32fc_s32f_atan2_32f(angle_, c_samples, ((float)1.0), length_); for(aux = 0; aux < length_; aux++) { - z_0 = std::exp(gr_complex(0,1) * angle_[aux]); - out[index_out] = in[index_in] - z_0 * in[index_in - 1] - + gr_complex(p_c_factor,0) * z_0 * last_out; - last_out = out[index_out]; + z_0 = std::exp(gr_complex(0,1) * (*(angle_ + aux))); + *out = *in - z_0 * (*(in - 1)) + + p_c_factor * z_0 * last_out; + last_out = *out; index_out++; index_in++; - in = (gr_complex *) input_items[index_in]; - out = (gr_complex *) output_items[index_out]; + in ++; + out ++; } } @@ -131,11 +137,11 @@ int Notch::general_work(int noutput_items __attribute__((unused)), gr_vector_int n_segments = 0; } filter_state_ = false; - index_out = index_out + length_; - index_in = index_in +length_; + index_out += length_; + index_in += length_; memcpy(out, in, sizeof(gr_complex) * length_); - in = (gr_complex *) input_items[index_in]; - out = (gr_complex *) output_items[index_out]; + in += length_; + out += length_; } } consume_each(index_out); diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h index 5f7c469a8..c3a843310 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h @@ -51,7 +51,7 @@ private: float pfa; float noise_pow_est; - float p_c_factor; + gr_complex p_c_factor; float thres_; int length_; unsigned int n_segments; @@ -61,12 +61,8 @@ private: bool filter_state_; gr_complex last_out; gr_complex z_0; - gr_complex* in; - gr_complex* out; - gr_complex* paux; gr_complex* c_samples; - float* angle_; - + float* angle_; public: From 0b8e3c93991c3e7c8445eba604dd2db6ae05f4fe Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Mon, 10 Jul 2017 09:48:38 +0200 Subject: [PATCH 13/81] New noise floor power estimation in notch filter In this version, the noise floor power is estimated via a VOLK Kernel --- .../input_filter/gnuradio_blocks/notch_cc.cc | 31 ++++++++++++------- .../input_filter/gnuradio_blocks/notch_cc.h | 7 +++-- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc index 7b5d7db6e..8c79d3b50 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc @@ -38,6 +38,7 @@ #include #include #include +#include using google::LogMessage; @@ -63,12 +64,13 @@ Notch::Notch(float pfa, float p_c_factor, int length_) : gr::block("Notch", n_deg_fred = 2 * length_; //Number of dregrees of freedom n_segments = 0; n_segments_est = 8; // Set the number of segments for noise power estimation - n_segments_reset = 1000000; // Set the period (in segments) when the noise power is estimated + n_segments_reset = 10000; // Set the period (in segments) when the noise power is estimated z_0 = gr_complex(0 , 0); boost::math::chi_squared_distribution my_dist_(n_deg_fred); thres_ = boost::math::quantile(boost::math::complement(my_dist_, pfa)); c_samples = static_cast(volk_malloc(length_ * sizeof(gr_complex), volk_get_alignment())); angle_ = static_cast(volk_malloc(length_ * sizeof(float), volk_get_alignment())); + power_spect = static_cast(volk_malloc(length_ * sizeof(float), volk_get_alignment())); last_out = gr_complex(0,0); } @@ -76,6 +78,7 @@ Notch::~Notch() { volk_free(c_samples); volk_free(angle_); + volk_free(power_spect); } int Notch::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), @@ -85,29 +88,35 @@ int Notch::general_work(int noutput_items __attribute__((unused)), gr_vector_int int index_in = 1; int index_out = 0; int aux = 0; - lv_32fc_t magnitude; - float sig2 = 0.0; + float sig2dB = 0.0; + float sig2lin = 0.0; + lv_32fc_t dot_prod_; gr_complex* in = (gr_complex *) input_items[0]; gr_complex* out = (gr_complex *) output_items[0]; gr_complex* paux; in++; + arma::cx_fvec signal_segment; + arma::cx_fvec signal_segment_fft; while(((index_out + length_) < noutput_items) && (n_segments < n_segments_est) && (filter_state_ == false)) { - volk_32fc_x2_conjugate_dot_prod_32fc(&magnitude, in, in, length_); - sig2 = lv_creal(magnitude) / ((float) n_deg_fred); - noise_pow_est = (((float) n_segments) * noise_pow_est + sig2) / ((float)(n_segments + 1)); + signal_segment = arma::cx_fvec(in, length_, false, false); + signal_segment_fft = arma::fft(signal_segment); + volk_32fc_s32f_power_spectrum_32f(power_spect, signal_segment_fft.memptr(), 1.0, length_); + volk_32f_s32f_calc_spectral_noise_floor_32f(&sig2dB, power_spect, 15.0, length_); + sig2lin = std::pow(10.0, (sig2dB / 10.0)) / ((float) n_deg_fred); + noise_pow_est = (((float) n_segments) * noise_pow_est + sig2lin) / ((float)(n_segments + 1)); + memcpy(out, in, sizeof(gr_complex) * length_); index_out += length_; index_in += length_; n_segments++; - memcpy(out, in, sizeof(gr_complex) * length_); in += length_; out += length_; } while((index_out + length_) < noutput_items) { n_segments++; - volk_32fc_x2_conjugate_dot_prod_32fc(&magnitude, in, in, length_); - if( (lv_creal(magnitude) / noise_pow_est) > thres_) + volk_32fc_x2_conjugate_dot_prod_32fc(&dot_prod_, in, in, length_); + if( (lv_creal(dot_prod_) / noise_pow_est) > thres_) { if(filter_state_ == false) { @@ -120,7 +129,7 @@ int Notch::general_work(int noutput_items __attribute__((unused)), gr_vector_int for(aux = 0; aux < length_; aux++) { z_0 = std::exp(gr_complex(0,1) * (*(angle_ + aux))); - *out = *in - z_0 * (*(in - 1)) + *out = (*in) - z_0 * (*(in - 1)) + p_c_factor * z_0 * last_out; last_out = *out; index_out++; @@ -137,9 +146,9 @@ int Notch::general_work(int noutput_items __attribute__((unused)), gr_vector_int n_segments = 0; } filter_state_ = false; + memcpy(out, in, sizeof(gr_complex) * length_); index_out += length_; index_in += length_; - memcpy(out, in, sizeof(gr_complex) * length_); in += length_; out += length_; } diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h index c3a843310..faf7c5d0c 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h @@ -51,18 +51,19 @@ private: float pfa; float noise_pow_est; - gr_complex p_c_factor; float thres_; int length_; + int n_deg_fred; unsigned int n_segments; unsigned int n_segments_est; unsigned int n_segments_reset; - int n_deg_fred; bool filter_state_; gr_complex last_out; gr_complex z_0; + gr_complex p_c_factor; gr_complex* c_samples; - float* angle_; + float* angle_; + float* power_spect; public: From cbe54da10fa71676e5decc74b8ab89829391d70e Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Mon, 10 Jul 2017 12:53:26 +0200 Subject: [PATCH 14/81] Beta version Pulse Blanking Filter First version of the pulse blanking input filter --- .../adapters/pulse_blanking_filter.cc | 11 ++- .../adapters/pulse_blanking_filter.h | 2 - .../gnuradio_blocks/pulse_blanking_cc.cc | 94 ++++++++++++------- .../gnuradio_blocks/pulse_blanking_cc.h | 24 +++-- 4 files changed, 82 insertions(+), 49 deletions(-) diff --git a/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc b/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc index 4bca7a799..7dfe27b62 100644 --- a/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc +++ b/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc @@ -46,21 +46,22 @@ PulseBlankingFilter::PulseBlankingFilter(ConfigurationInterface* configuration, std::string default_input_item_type = "gr_complex"; std::string default_output_item_type = "gr_complex"; std::string default_dump_filename = "../data/input_filter.dat"; - + DLOG(INFO) << "role " << role_; input_item_type_ = config_->property(role_ + ".input_item_type", default_input_item_type); output_item_type_ = config_->property(role_ + ".output_item_type", default_output_item_type); dump_ = config_->property(role_ + ".dump", false); dump_filename_ = config_->property(role_ + ".dump_filename", default_dump_filename); - - double Pfa = config_->property(role_ + ".Pfa", 0.001); - + float default_pfa_ = 0.001; + float pfa = config_->property(role_ + ".pfa", default_pfa_); + int default_length_ = 32; + int length_ = config_->property(role_ + ".length", default_length_); if (input_item_type_.compare("gr_complex") == 0) { item_size = sizeof(gr_complex); //output input_size_ = sizeof(gr_complex); //input - pulse_blanking_cc_ = make_pulse_blanking_cc(Pfa); + pulse_blanking_cc_ = make_pulse_blanking_cc(pfa, length_); } else { diff --git a/src/algorithms/input_filter/adapters/pulse_blanking_filter.h b/src/algorithms/input_filter/adapters/pulse_blanking_filter.h index ce812556d..4382e4281 100644 --- a/src/algorithms/input_filter/adapters/pulse_blanking_filter.h +++ b/src/algorithms/input_filter/adapters/pulse_blanking_filter.h @@ -76,8 +76,6 @@ private: std::string input_item_type_; size_t input_size_; std::string output_item_type_; - double intermediate_freq_; - double sampling_freq_; std::string role_; unsigned int in_streams_; unsigned int out_streams_; diff --git a/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc index f2ec0f198..c7cfc0475 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc @@ -29,62 +29,88 @@ */ #include "pulse_blanking_cc.h" +#include #include #include #include #include -#include - -pulse_blanking_cc_sptr make_pulse_blanking_cc(double Pfa) +pulse_blanking_cc_sptr make_pulse_blanking_cc(float pfa, int length_) { - return pulse_blanking_cc_sptr(new pulse_blanking_cc(Pfa)); + return pulse_blanking_cc_sptr(new pulse_blanking_cc(pfa, length_)); } -pulse_blanking_cc::pulse_blanking_cc(double Pfa) : gr::block("pulse_blanking_cc", +pulse_blanking_cc::pulse_blanking_cc(float pfa, int length_) : gr::block("pulse_blanking_cc", gr::io_signature::make (1, 1, sizeof(gr_complex)), gr::io_signature::make (1, 1, sizeof(gr_complex))) { const int alignment_multiple = volk_get_alignment() / sizeof(gr_complex); set_alignment(std::max(1, alignment_multiple)); - d_Pfa = Pfa; + this->pfa = pfa; + this->length_ = length_; + set_output_multiple(length_); + last_filtered = false; + n_segments = 0; + n_segments_est = 8; + n_segments_reset = 10000; + noise_power_estimation = 0.0; + n_deg_fred = 2*length_; + boost::math::chi_squared_distribution my_dist_(n_deg_fred); + thres_ = boost::math::quantile(boost::math::complement(my_dist_, pfa)); + zeros_ = static_cast(volk_malloc(length_ * sizeof(gr_complex), volk_get_alignment())); + magnitude = static_cast(volk_malloc(length_ * sizeof(float), volk_get_alignment())); + for (int aux = 0; aux < length_; aux++) + { + zeros_[aux] = gr_complex(0, 0); + } } +pulse_blanking_cc::~pulse_blanking_cc() +{ + volk_free(zeros_); + volk_free(magnitude); +} int pulse_blanking_cc::general_work (int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { - const gr_complex *in = (const gr_complex *) input_items[0]; + gr_complex *in = (gr_complex *) input_items[0]; gr_complex *out = (gr_complex *) output_items[0]; - - // 1- (optional) Compute the input signal power estimation - //float mean; - //float stddev; - //volk_32f_stddev_and_mean_32f_x2(&stddev, &mean, in, noutput_items); - - float* magnitude; - magnitude = static_cast(volk_gnsssdr_malloc(noutput_items * sizeof(float), volk_gnsssdr_get_alignment())); - - float var; - volk_32fc_magnitude_squared_32f(magnitude, in, noutput_items); - volk_32f_accumulator_s32f(&var, magnitude, noutput_items); - var /= static_cast(noutput_items); - // compute pulse blanking threshold (Paper Borio 2016) - - float Th = sqrt(-2.0 * var * log10(d_Pfa)); - - //apply the pulse blanking - //todo: write volk kernel to optimize the blanking - memcpy(out,in, sizeof(gr_complex)*noutput_items); - for (int n = 0; n < noutput_items; n++) + int sample_index = 0; + float segment_energy; + while((sample_index + length_) < noutput_items) + { + volk_32fc_magnitude_squared_32f(magnitude, in, length_); + volk_32f_accumulator_s32f(&segment_energy, magnitude, length_); + if((n_segments < n_segments_est) && (last_filtered == false)) { - if (std::abs(out[n]) > Th) - { - out[n] = gr_complex(0,0); - } + noise_power_estimation = (((float) n_segments) * noise_power_estimation + segment_energy / ((float)n_deg_fred)) / ((float)(n_segments + 1)); + memcpy(out, in, sizeof(gr_complex)*length_); } - consume_each(noutput_items); - return noutput_items; + else + { + if((segment_energy/noise_power_estimation) > thres_) + { + memcpy(out, zeros_, sizeof(gr_complex)*length_); + last_filtered = true; + } + else + { + memcpy(out, in, sizeof(gr_complex)*length_); + last_filtered = false; + if (n_segments > n_segments_reset) + { + n_segments = 0; + } + } + } + in+=length_; + out+=length_; + sample_index+=length_; + n_segments++; + } + consume_each(sample_index); + return sample_index; } diff --git a/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.h b/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.h index 8e23d39ad..620e4731f 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.h +++ b/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.h @@ -38,19 +38,27 @@ class pulse_blanking_cc; typedef boost::shared_ptr pulse_blanking_cc_sptr; -pulse_blanking_cc_sptr make_pulse_blanking_cc(double Pfa); +pulse_blanking_cc_sptr make_pulse_blanking_cc(float pfa, int length_); + -/*! - * \brief This class adapts a short (16-bits) interleaved sample stream - * into a std::complex stream - */ class pulse_blanking_cc : public gr::block { private: - friend pulse_blanking_cc_sptr make_pulse_blanking_cc(double Pfa); - double d_Pfa; + int length_; + int n_segments; + int n_segments_est; + int n_segments_reset; + int n_deg_fred; + bool last_filtered; + float noise_power_estimation; + float thres_; + float pfa; + float* magnitude; + gr_complex* zeros_; public: - pulse_blanking_cc(double Pfa); + pulse_blanking_cc(float pfa, int length_); + + ~pulse_blanking_cc(); int general_work (int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); From 8f1fcb382a60717b3eedb5ce32fd90dcf3dcab18 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Wed, 12 Jul 2017 09:12:56 +0200 Subject: [PATCH 15/81] Improved Pulse Blanking Filter Number of signal segments for estimating the noise power is passed now as a parameter in the configuration file --- .../adapters/pulse_blanking_filter.cc | 11 ++++++---- .../adapters/pulse_blanking_filter.h | 3 --- .../gnuradio_blocks/pulse_blanking_cc.cc | 20 +++++++++++-------- .../gnuradio_blocks/pulse_blanking_cc.h | 8 ++++++-- 4 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc b/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc index 7dfe27b62..cedad7741 100644 --- a/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc +++ b/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc @@ -42,7 +42,6 @@ PulseBlankingFilter::PulseBlankingFilter(ConfigurationInterface* configuration, out_streams_(out_streams) { size_t item_size; - std::string default_input_item_type = "gr_complex"; std::string default_output_item_type = "gr_complex"; std::string default_dump_filename = "../data/input_filter.dat"; @@ -53,15 +52,19 @@ PulseBlankingFilter::PulseBlankingFilter(ConfigurationInterface* configuration, output_item_type_ = config_->property(role_ + ".output_item_type", default_output_item_type); dump_ = config_->property(role_ + ".dump", false); dump_filename_ = config_->property(role_ + ".dump_filename", default_dump_filename); - float default_pfa_ = 0.001; + float default_pfa_ = 0.01; float pfa = config_->property(role_ + ".pfa", default_pfa_); - int default_length_ = 32; + int default_length_ = 16; int length_ = config_->property(role_ + ".length", default_length_); + int default_n_segments_est = 25000; + int n_segments_est = config_->property(role_ + ".segments_estimation", default_n_segments_est); + int default_n_segments_reset = 500000; + int n_segments_reset = config_->property(role_ + ".segments_reset", default_n_segments_reset); if (input_item_type_.compare("gr_complex") == 0) { item_size = sizeof(gr_complex); //output input_size_ = sizeof(gr_complex); //input - pulse_blanking_cc_ = make_pulse_blanking_cc(pfa, length_); + pulse_blanking_cc_ = make_pulse_blanking_cc(pfa, length_, n_segments_est, n_segments_reset); } else { diff --git a/src/algorithms/input_filter/adapters/pulse_blanking_filter.h b/src/algorithms/input_filter/adapters/pulse_blanking_filter.h index 4382e4281..041ba2251 100644 --- a/src/algorithms/input_filter/adapters/pulse_blanking_filter.h +++ b/src/algorithms/input_filter/adapters/pulse_blanking_filter.h @@ -39,9 +39,6 @@ class ConfigurationInterface; -/*! - * \brief TODO - */ class PulseBlankingFilter: public GNSSBlockInterface { public: diff --git a/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc index c7cfc0475..ec758e511 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc @@ -34,15 +34,19 @@ #include #include #include +#include -pulse_blanking_cc_sptr make_pulse_blanking_cc(float pfa, int length_) +using google::LogMessage; + +pulse_blanking_cc_sptr make_pulse_blanking_cc(float pfa, int length_, + int n_segments_est, int n_segments_reset) { - return pulse_blanking_cc_sptr(new pulse_blanking_cc(pfa, length_)); + return pulse_blanking_cc_sptr(new pulse_blanking_cc(pfa, length_, n_segments_est, n_segments_reset)); } -pulse_blanking_cc::pulse_blanking_cc(float pfa, int length_) : gr::block("pulse_blanking_cc", +pulse_blanking_cc::pulse_blanking_cc(float pfa, int length_, int n_segments_est, int n_segments_reset) : gr::block("pulse_blanking_cc", gr::io_signature::make (1, 1, sizeof(gr_complex)), gr::io_signature::make (1, 1, sizeof(gr_complex))) { @@ -53,8 +57,8 @@ pulse_blanking_cc::pulse_blanking_cc(float pfa, int length_) : gr::block("pulse_ set_output_multiple(length_); last_filtered = false; n_segments = 0; - n_segments_est = 8; - n_segments_reset = 10000; + this->n_segments_est = n_segments_est; + this->n_segments_reset = n_segments_reset; noise_power_estimation = 0.0; n_deg_fred = 2*length_; boost::math::chi_squared_distribution my_dist_(n_deg_fred); @@ -64,13 +68,13 @@ pulse_blanking_cc::pulse_blanking_cc(float pfa, int length_) : gr::block("pulse_ for (int aux = 0; aux < length_; aux++) { zeros_[aux] = gr_complex(0, 0); - } + } } pulse_blanking_cc::~pulse_blanking_cc() { volk_free(zeros_); - volk_free(magnitude); + volk_free(magnitude); } int pulse_blanking_cc::general_work (int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), @@ -87,7 +91,7 @@ int pulse_blanking_cc::general_work (int noutput_items __attribute__((unused)), if((n_segments < n_segments_est) && (last_filtered == false)) { noise_power_estimation = (((float) n_segments) * noise_power_estimation + segment_energy / ((float)n_deg_fred)) / ((float)(n_segments + 1)); - memcpy(out, in, sizeof(gr_complex)*length_); + memcpy(out, in, sizeof(gr_complex)*length_); } else { diff --git a/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.h b/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.h index 620e4731f..1bb9a7550 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.h +++ b/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.h @@ -38,12 +38,13 @@ class pulse_blanking_cc; typedef boost::shared_ptr pulse_blanking_cc_sptr; -pulse_blanking_cc_sptr make_pulse_blanking_cc(float pfa, int length_); +pulse_blanking_cc_sptr make_pulse_blanking_cc(float pfa, int length_, int n_segments_est, int n_segments_reset); class pulse_blanking_cc : public gr::block { private: + int length_; int n_segments; int n_segments_est; @@ -55,13 +56,16 @@ private: float pfa; float* magnitude; gr_complex* zeros_; + public: - pulse_blanking_cc(float pfa, int length_); + + pulse_blanking_cc(float pfa, int length_, int n_segments_est, int n_segments_reset); ~pulse_blanking_cc(); int general_work (int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); + }; #endif From 1e753e5f5479b3ed690848f83be0baebe00aa6b4 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Mon, 21 Aug 2017 13:08:33 +0200 Subject: [PATCH 16/81] Adding Single state Notch Filter New Notch_Filter_Lite input filter block --- .../input_filter/adapters/CMakeLists.txt | 1 + .../adapters/notch_filter_lite.cc | 114 ++++++++++++++++++ .../input_filter/adapters/notch_filter_lite.h | 84 +++++++++++++ .../gnuradio_blocks/CMakeLists.txt | 1 + .../gnuradio_blocks/notch_lite_cc.cc | 80 ++++++++++++ .../gnuradio_blocks/notch_lite_cc.h | 66 ++++++++++ 6 files changed, 346 insertions(+) create mode 100644 src/algorithms/input_filter/adapters/notch_filter_lite.cc create mode 100644 src/algorithms/input_filter/adapters/notch_filter_lite.h create mode 100644 src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc create mode 100644 src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.h diff --git a/src/algorithms/input_filter/adapters/CMakeLists.txt b/src/algorithms/input_filter/adapters/CMakeLists.txt index 38c35012a..2cee74880 100644 --- a/src/algorithms/input_filter/adapters/CMakeLists.txt +++ b/src/algorithms/input_filter/adapters/CMakeLists.txt @@ -22,6 +22,7 @@ set(INPUT_FILTER_ADAPTER_SOURCES beamformer_filter.cc pulse_blanking_filter.cc notch_filter.cc + notch_filter_lite.cc ) include_directories( diff --git a/src/algorithms/input_filter/adapters/notch_filter_lite.cc b/src/algorithms/input_filter/adapters/notch_filter_lite.cc new file mode 100644 index 000000000..ec2ac636e --- /dev/null +++ b/src/algorithms/input_filter/adapters/notch_filter_lite.cc @@ -0,0 +1,114 @@ +/*! + * \file notch_filter_lite.cc + * \brief Adapts a gnuradio gr_notch_filter_lite + * \author Antonio Ramos, 2017. antonio.ramosdet(at)gmail.com + * + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include "notch_filter_lite.h" +#include +#include +#include +#include +#include +#include +#include "configuration_interface.h" +#include "notch_lite_cc.h" + +using google::LogMessage; + +NotchFilterLite::NotchFilterLite(ConfigurationInterface* configuration, std::string role, + unsigned int in_streams, unsigned int out_streams) : + role_(role), in_streams_(in_streams), + out_streams_(out_streams) +{ + size_t item_size_; + float p_c_factor; + float default_p_c_factor = 0.9; + std::string default_item_type = "gr_complex"; + std::string default_dump_file = "./data/input_filter.dat"; + item_type_ = configuration->property(role + ".item_type", default_item_type); + dump_ = configuration->property(role + ".dump", false); + DLOG(INFO) << "dump_ is " << dump_; + dump_filename_ = configuration->property(role + ".dump_filename", default_dump_file); + p_c_factor = configuration->property(role + ".p_c_factor", default_p_c_factor); + if (item_type_.compare("gr_complex") == 0) + { + item_size_ = sizeof(gr_complex); + notch_filter_lite_ = make_notch_filter_lite(p_c_factor); + DLOG(INFO) << "Item size " << item_size_; + DLOG(INFO) << "input filter(" << notch_filter_lite_->unique_id() << ")"; + + } + else + { + LOG(WARNING) << item_type_ + << " unrecognized item type for notch filter"; + item_size_ = sizeof(gr_complex); + } + if (dump_) + { + DLOG(INFO) << "Dumping output into file " << dump_filename_; + file_sink_ = gr::blocks::file_sink::make(item_size_, dump_filename_.c_str()); + DLOG(INFO) << "file_sink(" << file_sink_->unique_id() << ")"; + } +} + +NotchFilterLite::~NotchFilterLite() +{} + +void NotchFilterLite::connect(gr::top_block_sptr top_block) +{ + if (dump_) + { + top_block->connect(notch_filter_lite_, 0, file_sink_, 0); + DLOG(INFO) << "connected notch filter output to file sink"; + } + else + { + DLOG(INFO) << "nothing to connect internally"; + } +} + +void NotchFilterLite::disconnect(gr::top_block_sptr top_block) +{ + if (dump_) + { + top_block->disconnect(notch_filter_lite_, 0, file_sink_, 0); + } +} + + +gr::basic_block_sptr NotchFilterLite::get_left_block() +{ + return notch_filter_lite_; +} + +gr::basic_block_sptr NotchFilterLite::get_right_block() +{ + return notch_filter_lite_; +} diff --git a/src/algorithms/input_filter/adapters/notch_filter_lite.h b/src/algorithms/input_filter/adapters/notch_filter_lite.h new file mode 100644 index 000000000..03796f319 --- /dev/null +++ b/src/algorithms/input_filter/adapters/notch_filter_lite.h @@ -0,0 +1,84 @@ +/*! + * \file notch_filter_lite.h + * \brief + * \author Antonio Ramos, 2017. antonio.ramosdet(at)gmail.com + * + * Detailed description of the file here if needed. + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_NOTCH_FILTER_LITE_H_ +#define GNSS_SDR_NOTCH_FILTER_LITE_H_ + +#include +#include +#include +#include "gnss_block_interface.h" +#include "notch_lite_cc.h" + + +class ConfigurationInterface; + +class NotchFilterLite: public GNSSBlockInterface +{ +public: + NotchFilterLite(ConfigurationInterface* configuration, + std::string role, unsigned int in_streams, + unsigned int out_streams); + + virtual ~NotchFilterLite(); + std::string role() + { + return role_; + } + + //! Returns "Notch_Filter_Lite" + std::string implementation() + { + return "Notch_Filter_Lite"; + } + size_t item_size() + { + return 0; + } + void connect(gr::top_block_sptr top_block); + void disconnect(gr::top_block_sptr top_block); + gr::basic_block_sptr get_left_block(); + gr::basic_block_sptr get_right_block(); + +private: + + bool dump_; + std::string dump_filename_; + std::string role_; + std::string item_type_; + unsigned int in_streams_; + unsigned int out_streams_; + gr::blocks::file_sink::sptr file_sink_; + notch_lite_sptr notch_filter_lite_; +}; + +#endif //GNSS_SDR_NOTCH_FILTER_LITE_H_ diff --git a/src/algorithms/input_filter/gnuradio_blocks/CMakeLists.txt b/src/algorithms/input_filter/gnuradio_blocks/CMakeLists.txt index 718ac1c9a..b0ce4a55e 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/input_filter/gnuradio_blocks/CMakeLists.txt @@ -21,6 +21,7 @@ set(INPUT_FILTER_GR_BLOCKS_SOURCES beamformer.cc pulse_blanking_cc.cc notch_cc.cc + notch_lite_cc.cc ) include_directories( diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc new file mode 100644 index 000000000..4b21bf33e --- /dev/null +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc @@ -0,0 +1,80 @@ +/*! + * \file notch_lite_cc.cc + * \brief Implements a multi state notch filter algorithm + * \author Antonio Ramos (antonio.ramosdet(at)gmail.com) + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include "notch_lite_cc.h" +#include +#include +#include +#include +#include +#include +#include +#include + +using google::LogMessage; + +notch_lite_sptr make_notch_filter_lite(float p_c_factor) +{ + return notch_lite_sptr(new NotchLite(p_c_factor)); +} + +NotchLite::NotchLite(float p_c_factor) : gr::block("NotchLite", + gr::io_signature::make (1, 1, sizeof(gr_complex)), + gr::io_signature::make (1, 1, sizeof(gr_complex))) +{ + const int alignment_multiple = volk_get_alignment() / sizeof(gr_complex); + set_alignment(std::max(1, alignment_multiple)); + set_history(2); + this->p_c_factor = gr_complex(p_c_factor , 0); + z_0 = gr_complex(0 , 0); + last_out = gr_complex(0,0); +} + +int NotchLite::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), + gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) +{ + gr_complex* in = (gr_complex *) input_items[0]; + gr_complex* out = (gr_complex *) output_items[0]; + c_samples = static_cast(volk_malloc(noutput_items * sizeof(gr_complex), volk_get_alignment())); + angle_ = static_cast(volk_malloc(noutput_items * sizeof(float), volk_get_alignment())); + + volk_32fc_x2_multiply_conjugate_32fc(c_samples, (in + 1), in, noutput_items); + volk_32fc_s32f_atan2_32f(angle_, c_samples, ((float)1.0), noutput_items); + for (int aux = 0; aux < noutput_items; aux++) + { + z_0 = std::exp(gr_complex(0,1) * (*(angle_ + aux))); + *(out + aux) = *(in + aux + 1) - z_0 * (*(in + aux)) + p_c_factor * z_0 * last_out; + last_out = *(out + aux); + } + volk_free(c_samples); + volk_free(angle_); + consume_each(noutput_items); + return noutput_items; +} diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.h b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.h new file mode 100644 index 000000000..16f56286d --- /dev/null +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.h @@ -0,0 +1,66 @@ +/*! + * \file notch_lite_cc.h + * \brief Implements a notch filter algorithm + * \author Antonio Ramos (antonio.ramosdet(at)gmail.com) + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_NOTCH_LITE_H_ +#define GNSS_SDR_NOTCH_LITE_H_ + +#include +#include + +class NotchLite; + +typedef boost::shared_ptr notch_lite_sptr; + +notch_lite_sptr make_notch_filter_lite(float p_c_factor); + +/*! + * \brief This class implements a real-time software-defined single state notch filter + */ + +class NotchLite : public gr::block +{ +private: + + gr_complex last_out; + gr_complex z_0; + gr_complex p_c_factor; + gr_complex* c_samples; + float* angle_; + +public: + + NotchLite(float p_c_factor); + + int general_work (int noutput_items, gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +#endif //GNSS_SDR_NOTCH_LITE_H_ From e1dc9f5aac6799f9cb118585bb4cb6092ed89205 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Mon, 21 Aug 2017 13:11:18 +0200 Subject: [PATCH 17/81] Improving real-time performances of input filters Pulse blanking and Notch filters improved --- .../adapters/pulse_blanking_filter.cc | 8 +- .../input_filter/gnuradio_blocks/notch_cc.cc | 94 ++++++++----------- .../gnuradio_blocks/pulse_blanking_cc.cc | 12 +-- .../gnuradio_blocks/pulse_blanking_cc.h | 1 - src/core/receiver/gnss_block_factory.cc | 7 ++ 5 files changed, 56 insertions(+), 66 deletions(-) diff --git a/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc b/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc index cedad7741..fed7205cc 100644 --- a/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc +++ b/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc @@ -52,13 +52,13 @@ PulseBlankingFilter::PulseBlankingFilter(ConfigurationInterface* configuration, output_item_type_ = config_->property(role_ + ".output_item_type", default_output_item_type); dump_ = config_->property(role_ + ".dump", false); dump_filename_ = config_->property(role_ + ".dump_filename", default_dump_filename); - float default_pfa_ = 0.01; + float default_pfa_ = 0.04; float pfa = config_->property(role_ + ".pfa", default_pfa_); - int default_length_ = 16; + int default_length_ = 32; int length_ = config_->property(role_ + ".length", default_length_); - int default_n_segments_est = 25000; + int default_n_segments_est = 12500; int n_segments_est = config_->property(role_ + ".segments_estimation", default_n_segments_est); - int default_n_segments_reset = 500000; + int default_n_segments_reset = 5000000; int n_segments_reset = config_->property(role_ + ".segments_reset", default_n_segments_reset); if (input_item_type_.compare("gr_complex") == 0) { diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc index 8c79d3b50..007b3d9b3 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc @@ -84,75 +84,61 @@ Notch::~Notch() int Notch::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { - - int index_in = 1; int index_out = 0; - int aux = 0; float sig2dB = 0.0; float sig2lin = 0.0; lv_32fc_t dot_prod_; gr_complex* in = (gr_complex *) input_items[0]; gr_complex* out = (gr_complex *) output_items[0]; - gr_complex* paux; in++; arma::cx_fvec signal_segment; arma::cx_fvec signal_segment_fft; - while(((index_out + length_) < noutput_items) && (n_segments < n_segments_est) && (filter_state_ == false)) + while((index_out + length_) < noutput_items) { - signal_segment = arma::cx_fvec(in, length_, false, false); - signal_segment_fft = arma::fft(signal_segment); - volk_32fc_s32f_power_spectrum_32f(power_spect, signal_segment_fft.memptr(), 1.0, length_); - volk_32f_s32f_calc_spectral_noise_floor_32f(&sig2dB, power_spect, 15.0, length_); - sig2lin = std::pow(10.0, (sig2dB / 10.0)) / ((float) n_deg_fred); - noise_pow_est = (((float) n_segments) * noise_pow_est + sig2lin) / ((float)(n_segments + 1)); - memcpy(out, in, sizeof(gr_complex) * length_); + if((n_segments < n_segments_est) && (filter_state_ == false)) + { + signal_segment = arma::cx_fvec(in, length_, false, false); + signal_segment_fft = arma::fft(signal_segment); + volk_32fc_s32f_power_spectrum_32f(power_spect, signal_segment_fft.memptr(), 1.0, length_); + volk_32f_s32f_calc_spectral_noise_floor_32f(&sig2dB, power_spect, 15.0, length_); + sig2lin = std::pow(10.0, (sig2dB / 10.0)) / ((float) n_deg_fred); + noise_pow_est = (((float) n_segments) * noise_pow_est + sig2lin) / ((float)(n_segments + 1)); + memcpy(out, in, sizeof(gr_complex) * length_); + } + else + { + volk_32fc_x2_conjugate_dot_prod_32fc(&dot_prod_, in, in, length_); + if( (lv_creal(dot_prod_) / noise_pow_est) > thres_) + { + if(filter_state_ == false) + { + filter_state_ = true; + last_out = gr_complex(0,0); + } + volk_32fc_x2_multiply_conjugate_32fc(c_samples, in, (in - 1), length_); + volk_32fc_s32f_atan2_32f(angle_, c_samples, ((float)1.0), length_); + for(int aux = 0; aux < length_; aux++) + { + z_0 = std::exp(gr_complex(0,1) * (*(angle_ + aux))); + *(out + aux) = *(in + aux) - z_0 * (*(in + aux - 1)) + p_c_factor * z_0 * last_out; + last_out = *(out + aux); + } + } + else + { + if (n_segments > n_segments_reset) + { + n_segments = 0; + } + filter_state_ = false; + memcpy(out, in, sizeof(gr_complex) * length_); + } + } index_out += length_; - index_in += length_; n_segments++; in += length_; out += length_; } - while((index_out + length_) < noutput_items) - { - n_segments++; - volk_32fc_x2_conjugate_dot_prod_32fc(&dot_prod_, in, in, length_); - if( (lv_creal(dot_prod_) / noise_pow_est) > thres_) - { - if(filter_state_ == false) - { - filter_state_ = true; - last_out = gr_complex(0,0); - } - paux = in - 1; - volk_32fc_x2_multiply_conjugate_32fc(c_samples, in, paux, length_); - volk_32fc_s32f_atan2_32f(angle_, c_samples, ((float)1.0), length_); - for(aux = 0; aux < length_; aux++) - { - z_0 = std::exp(gr_complex(0,1) * (*(angle_ + aux))); - *out = (*in) - z_0 * (*(in - 1)) - + p_c_factor * z_0 * last_out; - last_out = *out; - index_out++; - index_in++; - in ++; - out ++; - } - - } - else - { - if (n_segments > n_segments_reset) - { - n_segments = 0; - } - filter_state_ = false; - memcpy(out, in, sizeof(gr_complex) * length_); - index_out += length_; - index_in += length_; - in += length_; - out += length_; - } - } consume_each(index_out); return index_out; } diff --git a/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc index ec758e511..a744f8747 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc @@ -44,8 +44,6 @@ pulse_blanking_cc_sptr make_pulse_blanking_cc(float pfa, int length_, return pulse_blanking_cc_sptr(new pulse_blanking_cc(pfa, length_, n_segments_est, n_segments_reset)); } - - pulse_blanking_cc::pulse_blanking_cc(float pfa, int length_, int n_segments_est, int n_segments_reset) : gr::block("pulse_blanking_cc", gr::io_signature::make (1, 1, sizeof(gr_complex)), gr::io_signature::make (1, 1, sizeof(gr_complex))) @@ -64,7 +62,6 @@ pulse_blanking_cc::pulse_blanking_cc(float pfa, int length_, int n_segments_est, boost::math::chi_squared_distribution my_dist_(n_deg_fred); thres_ = boost::math::quantile(boost::math::complement(my_dist_, pfa)); zeros_ = static_cast(volk_malloc(length_ * sizeof(gr_complex), volk_get_alignment())); - magnitude = static_cast(volk_malloc(length_ * sizeof(float), volk_get_alignment())); for (int aux = 0; aux < length_; aux++) { zeros_[aux] = gr_complex(0, 0); @@ -73,8 +70,7 @@ pulse_blanking_cc::pulse_blanking_cc(float pfa, int length_, int n_segments_est, pulse_blanking_cc::~pulse_blanking_cc() { - volk_free(zeros_); - volk_free(magnitude); + volk_free(zeros_); } int pulse_blanking_cc::general_work (int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), @@ -82,12 +78,13 @@ int pulse_blanking_cc::general_work (int noutput_items __attribute__((unused)), { gr_complex *in = (gr_complex *) input_items[0]; gr_complex *out = (gr_complex *) output_items[0]; + float* magnitude = static_cast(volk_malloc(noutput_items * sizeof(float), volk_get_alignment())); + volk_32fc_magnitude_squared_32f(magnitude, in, noutput_items); int sample_index = 0; float segment_energy; while((sample_index + length_) < noutput_items) { - volk_32fc_magnitude_squared_32f(magnitude, in, length_); - volk_32f_accumulator_s32f(&segment_energy, magnitude, length_); + volk_32f_accumulator_s32f(&segment_energy, (magnitude + sample_index), length_); if((n_segments < n_segments_est) && (last_filtered == false)) { noise_power_estimation = (((float) n_segments) * noise_power_estimation + segment_energy / ((float)n_deg_fred)) / ((float)(n_segments + 1)); @@ -115,6 +112,7 @@ int pulse_blanking_cc::general_work (int noutput_items __attribute__((unused)), sample_index+=length_; n_segments++; } + volk_free(magnitude); consume_each(sample_index); return sample_index; } diff --git a/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.h b/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.h index 1bb9a7550..a77cf4deb 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.h +++ b/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.h @@ -54,7 +54,6 @@ private: float noise_power_estimation; float thres_; float pfa; - float* magnitude; gr_complex* zeros_; public: diff --git a/src/core/receiver/gnss_block_factory.cc b/src/core/receiver/gnss_block_factory.cc index cac56293a..6efe76db5 100644 --- a/src/core/receiver/gnss_block_factory.cc +++ b/src/core/receiver/gnss_block_factory.cc @@ -66,6 +66,7 @@ #include "beamformer_filter.h" #include "pulse_blanking_filter.h" #include "notch_filter.h" +#include "notch_filter_lite.h" #include "gps_l1_ca_pcps_acquisition.h" #include "gps_l2_m_pcps_acquisition.h" #include "gps_l1_ca_pcps_multithread_acquisition.h" @@ -889,6 +890,12 @@ std::unique_ptr GNSSBlockFactory::GetBlock( out_streams)); block = std::move(block_); } + else if (implementation.compare("Notch_Filter_Lite") == 0) + { + std::unique_ptr block_(new NotchFilterLite(configuration.get(), role, in_streams, + out_streams)); + block = std::move(block_); + } // RESAMPLER ------------------------------------------------------------------- From a18c3467a18661f9f1b17176f73a7ea75e39a5cc Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Tue, 22 Aug 2017 13:21:28 +0200 Subject: [PATCH 18/81] Improved Notch Filter Lite Updated version of the filter --- .../input_filter/adapters/notch_filter.cc | 8 +- .../adapters/notch_filter_lite.cc | 23 +++- .../input_filter/gnuradio_blocks/notch_cc.cc | 10 +- .../input_filter/gnuradio_blocks/notch_cc.h | 4 +- .../gnuradio_blocks/notch_lite_cc.cc | 105 +++++++++++++++--- .../gnuradio_blocks/notch_lite_cc.h | 24 +++- 6 files changed, 142 insertions(+), 32 deletions(-) diff --git a/src/algorithms/input_filter/adapters/notch_filter.cc b/src/algorithms/input_filter/adapters/notch_filter.cc index a69c0c9c0..405f1f430 100644 --- a/src/algorithms/input_filter/adapters/notch_filter.cc +++ b/src/algorithms/input_filter/adapters/notch_filter.cc @@ -53,6 +53,10 @@ NotchFilter::NotchFilter(ConfigurationInterface* configuration, std::string role float default_p_c_factor = 0.9; int length_; int default_length_ = 32; + int n_segments_est; + int default_n_segments_est = 12500; + int n_segments_reset; + int default_n_segments_reset = 5000000; std::string default_item_type = "gr_complex"; std::string default_dump_file = "./data/input_filter.dat"; item_type_ = configuration->property(role + ".item_type", default_item_type); @@ -62,10 +66,12 @@ NotchFilter::NotchFilter(ConfigurationInterface* configuration, std::string role pfa = configuration->property(role + ".pfa", default_pfa); p_c_factor = configuration->property(role + ".p_c_factor", default_p_c_factor); length_ = configuration->property(role + ".length", default_length_); + n_segments_est = configuration->property(role + ".segments_est", default_n_segments_est); + n_segments_reset = configuration->property(role + ".segments_reset", default_n_segments_reset); if (item_type_.compare("gr_complex") == 0) { item_size_ = sizeof(gr_complex); - notch_filter_ = make_notch_filter(pfa, p_c_factor, length_); + notch_filter_ = make_notch_filter(pfa, p_c_factor, length_, n_segments_est, n_segments_reset); DLOG(INFO) << "Item size " << item_size_; DLOG(INFO) << "input filter(" << notch_filter_->unique_id() << ")"; diff --git a/src/algorithms/input_filter/adapters/notch_filter_lite.cc b/src/algorithms/input_filter/adapters/notch_filter_lite.cc index ec2ac636e..a91aa39e6 100644 --- a/src/algorithms/input_filter/adapters/notch_filter_lite.cc +++ b/src/algorithms/input_filter/adapters/notch_filter_lite.cc @@ -31,6 +31,7 @@ #include "notch_filter_lite.h" #include +#include #include #include #include @@ -49,6 +50,18 @@ NotchFilterLite::NotchFilterLite(ConfigurationInterface* configuration, std::str size_t item_size_; float p_c_factor; float default_p_c_factor = 0.9; + float pfa; + float default_pfa = 0.001; + int length_; + int default_length_ = 32; + int n_segments_est; + int default_n_segments_est = 12500; + int n_segments_reset; + int default_n_segments_reset = 5000000; + float default_samp_freq = 4000000; + float samp_freq = configuration->property("SignalSource.sampling_frequency", default_samp_freq); + float default_coeff_rate = samp_freq * 0.1; + float coeff_rate; std::string default_item_type = "gr_complex"; std::string default_dump_file = "./data/input_filter.dat"; item_type_ = configuration->property(role + ".item_type", default_item_type); @@ -56,13 +69,19 @@ NotchFilterLite::NotchFilterLite(ConfigurationInterface* configuration, std::str DLOG(INFO) << "dump_ is " << dump_; dump_filename_ = configuration->property(role + ".dump_filename", default_dump_file); p_c_factor = configuration->property(role + ".p_c_factor", default_p_c_factor); + pfa = configuration->property(role + ".pfa", default_pfa); + coeff_rate = configuration->property(role + ".coeff_rate", default_coeff_rate); + length_ = configuration->property(role + ".length", default_length_); + n_segments_est = configuration->property(role + ".segments_est", default_n_segments_est); + n_segments_reset = configuration->property(role + ".segments_reset", default_n_segments_reset); + int n_segments_coeff = (int) ((samp_freq / coeff_rate) / ((float) length_)); + n_segments_coeff = std::max(1, n_segments_coeff); if (item_type_.compare("gr_complex") == 0) { item_size_ = sizeof(gr_complex); - notch_filter_lite_ = make_notch_filter_lite(p_c_factor); + notch_filter_lite_ = make_notch_filter_lite(p_c_factor, pfa, length_, n_segments_est, n_segments_reset, n_segments_coeff); DLOG(INFO) << "Item size " << item_size_; DLOG(INFO) << "input filter(" << notch_filter_lite_->unique_id() << ")"; - } else { diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc index 007b3d9b3..700ccfea8 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc @@ -43,12 +43,12 @@ using google::LogMessage; notch_sptr make_notch_filter(float pfa, float p_c_factor, - int length_) + int length_, int n_segments_est, int n_segments_reset) { - return notch_sptr(new Notch(pfa, p_c_factor, length_)); + return notch_sptr(new Notch(pfa, p_c_factor, length_, n_segments_est, n_segments_reset)); } -Notch::Notch(float pfa, float p_c_factor, int length_) : gr::block("Notch", +Notch::Notch(float pfa, float p_c_factor, int length_, int n_segments_est, int n_segments_reset) : gr::block("Notch", gr::io_signature::make (1, 1, sizeof(gr_complex)), gr::io_signature::make (1, 1, sizeof(gr_complex))) { @@ -63,8 +63,8 @@ Notch::Notch(float pfa, float p_c_factor, int length_) : gr::block("Notch", filter_state_ = false; //Initial state of the filter n_deg_fred = 2 * length_; //Number of dregrees of freedom n_segments = 0; - n_segments_est = 8; // Set the number of segments for noise power estimation - n_segments_reset = 10000; // Set the period (in segments) when the noise power is estimated + this->n_segments_est = n_segments_est; // Set the number of segments for noise power estimation + this->n_segments_reset = n_segments_reset; // Set the period (in segments) when the noise power is estimated z_0 = gr_complex(0 , 0); boost::math::chi_squared_distribution my_dist_(n_deg_fred); thres_ = boost::math::quantile(boost::math::complement(my_dist_, pfa)); diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h index faf7c5d0c..5be7dfda6 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h @@ -39,7 +39,7 @@ class Notch; typedef boost::shared_ptr notch_sptr; notch_sptr make_notch_filter(float pfa, float p_c_factor, - int length_); + int length_, int n_segments_est, int n_segments_reset); /*! * \brief This class implements a real-time software-defined multi state notch filter @@ -67,7 +67,7 @@ private: public: - Notch(float pfa, float p_c_factor, int length_); + Notch(float pfa, float p_c_factor, int length_, int n_segments_est, int n_segments_reset); ~Notch(); diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc index 4b21bf33e..3ce19f656 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc @@ -37,15 +37,17 @@ #include #include #include +#include +#include using google::LogMessage; -notch_lite_sptr make_notch_filter_lite(float p_c_factor) +notch_lite_sptr make_notch_filter_lite(float p_c_factor, float pfa, int length_, int n_segments_est, int n_segments_reset, int n_segments_coeff) { - return notch_lite_sptr(new NotchLite(p_c_factor)); + return notch_lite_sptr(new NotchLite(p_c_factor, pfa, length_, n_segments_est, n_segments_reset, n_segments_coeff)); } -NotchLite::NotchLite(float p_c_factor) : gr::block("NotchLite", +NotchLite::NotchLite(float p_c_factor, float pfa, int length_, int n_segments_est, int n_segments_reset, int n_segments_coeff) : gr::block("NotchLite", gr::io_signature::make (1, 1, sizeof(gr_complex)), gr::io_signature::make (1, 1, sizeof(gr_complex))) { @@ -53,28 +55,97 @@ NotchLite::NotchLite(float p_c_factor) : gr::block("NotchLite", set_alignment(std::max(1, alignment_multiple)); set_history(2); this->p_c_factor = gr_complex(p_c_factor , 0); + this->n_segments_est = n_segments_est; + this->n_segments_reset = n_segments_reset; + this->n_segments_coeff_reset = n_segments_coeff; + this->n_segments_coeff = 0; + this->length_ = length_; + set_output_multiple(length_); + this->pfa = pfa; + n_segments = 0; + n_deg_fred = 2 * length_; + noise_pow_est = 0.0; + filter_state_ = false; z_0 = gr_complex(0 , 0); - last_out = gr_complex(0,0); + last_out = gr_complex(0, 0); + boost::math::chi_squared_distribution my_dist_(n_deg_fred); + thres_ = boost::math::quantile(boost::math::complement(my_dist_, pfa)); + c_samples = gr_complex(0, 0); + angle_ = 0.0; + power_spect = static_cast(volk_malloc(length_ * sizeof(float), volk_get_alignment())); + } +NotchLite::~NotchLite() +{ + volk_free(power_spect); +} + + int NotchLite::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { + int index_out = 0; + float sig2dB = 0.0; + float sig2lin = 0.0; + lv_32fc_t dot_prod_; gr_complex* in = (gr_complex *) input_items[0]; gr_complex* out = (gr_complex *) output_items[0]; - c_samples = static_cast(volk_malloc(noutput_items * sizeof(gr_complex), volk_get_alignment())); - angle_ = static_cast(volk_malloc(noutput_items * sizeof(float), volk_get_alignment())); - - volk_32fc_x2_multiply_conjugate_32fc(c_samples, (in + 1), in, noutput_items); - volk_32fc_s32f_atan2_32f(angle_, c_samples, ((float)1.0), noutput_items); - for (int aux = 0; aux < noutput_items; aux++) + in++; + arma::cx_fvec signal_segment; + arma::cx_fvec signal_segment_fft; + while((index_out + length_) < noutput_items) { - z_0 = std::exp(gr_complex(0,1) * (*(angle_ + aux))); - *(out + aux) = *(in + aux + 1) - z_0 * (*(in + aux)) + p_c_factor * z_0 * last_out; - last_out = *(out + aux); + if((n_segments < n_segments_est) && (filter_state_ == false)) + { + signal_segment = arma::cx_fvec(in, length_, false, false); + signal_segment_fft = arma::fft(signal_segment); + volk_32fc_s32f_power_spectrum_32f(power_spect, signal_segment_fft.memptr(), 1.0, length_); + volk_32f_s32f_calc_spectral_noise_floor_32f(&sig2dB, power_spect, 15.0, length_); + sig2lin = std::pow(10.0, (sig2dB / 10.0)) / ((float) n_deg_fred); + noise_pow_est = (((float) n_segments) * noise_pow_est + sig2lin) / ((float)(n_segments + 1)); + memcpy(out, in, sizeof(gr_complex) * length_); + } + else + { + volk_32fc_x2_conjugate_dot_prod_32fc(&dot_prod_, in, in, length_); + if( (lv_creal(dot_prod_) / noise_pow_est) > thres_) + { + if(filter_state_ == false) + { + filter_state_ = true; + last_out = gr_complex(0,0); + n_segments_coeff = 0; + } + if(n_segments_coeff == 0) + { + volk_32fc_x2_multiply_conjugate_32fc(&c_samples, in, (in - 1), 1); + volk_32fc_s32f_atan2_32f(&angle_, &c_samples, ((float)1.0), 1); + z_0 = std::exp(gr_complex(0,1) * angle_); + } + for(int aux = 0; aux < length_; aux++) + { + *(out + aux) = *(in + aux) - z_0 * (*(in + aux - 1)) + p_c_factor * z_0 * last_out; + last_out = *(out + aux); + } + n_segments_coeff++; + n_segments_coeff = n_segments_coeff % n_segments_coeff_reset; + } + else + { + if (n_segments > n_segments_reset) + { + n_segments = 0; + } + filter_state_ = false; + memcpy(out, in, sizeof(gr_complex) * length_); + } + } + index_out += length_; + n_segments++; + in += length_; + out += length_; } - volk_free(c_samples); - volk_free(angle_); - consume_each(noutput_items); - return noutput_items; + consume_each(index_out); + return index_out; } diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.h b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.h index 16f56286d..64dcb8d53 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.h +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.h @@ -38,7 +38,7 @@ class NotchLite; typedef boost::shared_ptr notch_lite_sptr; -notch_lite_sptr make_notch_filter_lite(float p_c_factor); +notch_lite_sptr make_notch_filter_lite(float p_c_factor, float pfa, int length_, int n_segments_est, int n_segments_reset, int n_segments_coeff); /*! * \brief This class implements a real-time software-defined single state notch filter @@ -48,15 +48,29 @@ class NotchLite : public gr::block { private: + int length_; + int n_segments; + int n_segments_est; + int n_segments_reset; + int n_segments_coeff_reset; + int n_segments_coeff; + int n_deg_fred; + float pfa; + float thres_; + float noise_pow_est; + bool filter_state_; gr_complex last_out; gr_complex z_0; gr_complex p_c_factor; - gr_complex* c_samples; - float* angle_; - + gr_complex c_samples; + float angle_; + float* power_spect; + public: - NotchLite(float p_c_factor); + NotchLite(float p_c_factor, float pfa, int length_, int n_segments_est, int n_segments_reset, int n_segments_coeff); + + ~NotchLite(); int general_work (int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, From 0441f3c24c57601ebb21a09a7513e7aac4165d16 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Thu, 24 Aug 2017 19:21:24 +0200 Subject: [PATCH 19/81] Minor changes Changing some variable names --- src/algorithms/input_filter/adapters/notch_filter.h | 2 +- .../input_filter/adapters/notch_filter_lite.h | 2 +- .../input_filter/adapters/pulse_blanking_filter.cc | 4 ++-- .../input_filter/adapters/pulse_blanking_filter.h | 1 + .../input_filter/gnuradio_blocks/notch_lite_cc.cc | 13 +++++++++---- .../input_filter/gnuradio_blocks/notch_lite_cc.h | 10 ++++++---- .../gnuradio_blocks/pulse_blanking_cc.cc | 4 ++-- .../gnuradio_blocks/pulse_blanking_cc.h | 4 ++-- 8 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/algorithms/input_filter/adapters/notch_filter.h b/src/algorithms/input_filter/adapters/notch_filter.h index 09ac10e99..a8ab2136b 100644 --- a/src/algorithms/input_filter/adapters/notch_filter.h +++ b/src/algorithms/input_filter/adapters/notch_filter.h @@ -1,6 +1,6 @@ /*! * \file notch_filter.h - * \brief + * \brief Adapter of a multistate Notch filter * \author Antonio Ramos, 2017. antonio.ramosdet(at)gmail.com * * Detailed description of the file here if needed. diff --git a/src/algorithms/input_filter/adapters/notch_filter_lite.h b/src/algorithms/input_filter/adapters/notch_filter_lite.h index 03796f319..f9088db52 100644 --- a/src/algorithms/input_filter/adapters/notch_filter_lite.h +++ b/src/algorithms/input_filter/adapters/notch_filter_lite.h @@ -1,6 +1,6 @@ /*! * \file notch_filter_lite.h - * \brief + * \brief Adapts a ligth version of a multistate notch filter * \author Antonio Ramos, 2017. antonio.ramosdet(at)gmail.com * * Detailed description of the file here if needed. diff --git a/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc b/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc index fed7205cc..0786f3f3e 100644 --- a/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc +++ b/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc @@ -2,7 +2,7 @@ * \file pulse_blanking_filter.cc * \brief Instantiates the GNSS-SDR pulse blanking filter * \author Javier Arribas 2017 - * + * Antonio Ramos 2017 * ------------------------------------------------------------------------- * * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) @@ -57,7 +57,7 @@ PulseBlankingFilter::PulseBlankingFilter(ConfigurationInterface* configuration, int default_length_ = 32; int length_ = config_->property(role_ + ".length", default_length_); int default_n_segments_est = 12500; - int n_segments_est = config_->property(role_ + ".segments_estimation", default_n_segments_est); + int n_segments_est = config_->property(role_ + ".segments_est", default_n_segments_est); int default_n_segments_reset = 5000000; int n_segments_reset = config_->property(role_ + ".segments_reset", default_n_segments_reset); if (input_item_type_.compare("gr_complex") == 0) diff --git a/src/algorithms/input_filter/adapters/pulse_blanking_filter.h b/src/algorithms/input_filter/adapters/pulse_blanking_filter.h index 041ba2251..c57c68d10 100644 --- a/src/algorithms/input_filter/adapters/pulse_blanking_filter.h +++ b/src/algorithms/input_filter/adapters/pulse_blanking_filter.h @@ -2,6 +2,7 @@ * \file pulse_blanking_filter.h * \brief Instantiates the GNSS-SDR pulse blanking filter * \author Javier Arribas 2017 + * Antonio Ramos 2017 * * ------------------------------------------------------------------------- * diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc index 3ce19f656..a84ec6ae6 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc @@ -70,8 +70,10 @@ NotchLite::NotchLite(float p_c_factor, float pfa, int length_, int n_segments_es last_out = gr_complex(0, 0); boost::math::chi_squared_distribution my_dist_(n_deg_fred); thres_ = boost::math::quantile(boost::math::complement(my_dist_, pfa)); - c_samples = gr_complex(0, 0); - angle_ = 0.0; + c_samples1 = gr_complex(0, 0); + c_samples2 = gr_complex(0, 0); + angle1 = 0.0; + angle2 = 0.0; power_spect = static_cast(volk_malloc(length_ * sizeof(float), volk_get_alignment())); } @@ -119,8 +121,11 @@ int NotchLite::general_work(int noutput_items __attribute__((unused)), gr_vector } if(n_segments_coeff == 0) { - volk_32fc_x2_multiply_conjugate_32fc(&c_samples, in, (in - 1), 1); - volk_32fc_s32f_atan2_32f(&angle_, &c_samples, ((float)1.0), 1); + volk_32fc_x2_multiply_conjugate_32fc(&c_samples1, (in + 1), in, 1); + volk_32fc_s32f_atan2_32f(&angle1, &c_samples1, ((float)1.0), 1); + volk_32fc_x2_multiply_conjugate_32fc(&c_samples2, (in + length_ - 1), (in + length_ - 2), 1); + volk_32fc_s32f_atan2_32f(&angle2, &c_samples2, ((float)1.0), 1); + float angle_ = (angle1 + angle2) / 2.0; z_0 = std::exp(gr_complex(0,1) * angle_); } for(int aux = 0; aux < length_; aux++) diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.h b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.h index 64dcb8d53..2151a459f 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.h +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.h @@ -1,6 +1,6 @@ /*! * \file notch_lite_cc.h - * \brief Implements a notch filter algorithm + * \brief Implements a notch filter ligth algorithm * \author Antonio Ramos (antonio.ramosdet(at)gmail.com) * * ------------------------------------------------------------------------- @@ -41,7 +41,7 @@ typedef boost::shared_ptr notch_lite_sptr; notch_lite_sptr make_notch_filter_lite(float p_c_factor, float pfa, int length_, int n_segments_est, int n_segments_reset, int n_segments_coeff); /*! - * \brief This class implements a real-time software-defined single state notch filter + * \brief This class implements a real-time software-defined multi state notch filter ligth version */ class NotchLite : public gr::block @@ -62,8 +62,10 @@ private: gr_complex last_out; gr_complex z_0; gr_complex p_c_factor; - gr_complex c_samples; - float angle_; + gr_complex c_samples1; + gr_complex c_samples2; + float angle1; + float angle2; float* power_spect; public: diff --git a/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc index a744f8747..7924f17ba 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc @@ -1,8 +1,8 @@ /*! * \file pulse_blanking_cc.cc - * \brief Implements a simple pulse blanking algorithm + * \brief Implements a pulse blanking algorithm * \author Javier Arribas (jarribas(at)cttc.es) - * + * Antonio Ramos (antonio.ramosdet(at)gmail.com) * ------------------------------------------------------------------------- * * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) diff --git a/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.h b/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.h index a77cf4deb..7a19bf74e 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.h +++ b/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.h @@ -1,8 +1,8 @@ /*! * \file pulse_blanking_cc.h - * \brief Implements a simple pulse blanking algorithm + * \brief Implements a pulse blanking algorithm * \author Javier Arribas (jarribas(at)cttc.es) - * + * Antonio Ramos (antonio.ramosdet(at)gmail.com) * ------------------------------------------------------------------------- * * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) From 3536bce55cd2420dce027de0643d76fc9a37728b Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Tue, 22 Aug 2017 13:21:28 +0200 Subject: [PATCH 20/81] Improved Notch Filter Lite Updated version of the filter --- .../input_filter/adapters/notch_filter.cc | 8 +- .../adapters/notch_filter_lite.cc | 23 +++- .../input_filter/gnuradio_blocks/notch_cc.cc | 10 +- .../input_filter/gnuradio_blocks/notch_cc.h | 4 +- .../gnuradio_blocks/notch_lite_cc.cc | 105 +++++++++++++++--- .../gnuradio_blocks/notch_lite_cc.h | 24 +++- 6 files changed, 142 insertions(+), 32 deletions(-) diff --git a/src/algorithms/input_filter/adapters/notch_filter.cc b/src/algorithms/input_filter/adapters/notch_filter.cc index a69c0c9c0..405f1f430 100644 --- a/src/algorithms/input_filter/adapters/notch_filter.cc +++ b/src/algorithms/input_filter/adapters/notch_filter.cc @@ -53,6 +53,10 @@ NotchFilter::NotchFilter(ConfigurationInterface* configuration, std::string role float default_p_c_factor = 0.9; int length_; int default_length_ = 32; + int n_segments_est; + int default_n_segments_est = 12500; + int n_segments_reset; + int default_n_segments_reset = 5000000; std::string default_item_type = "gr_complex"; std::string default_dump_file = "./data/input_filter.dat"; item_type_ = configuration->property(role + ".item_type", default_item_type); @@ -62,10 +66,12 @@ NotchFilter::NotchFilter(ConfigurationInterface* configuration, std::string role pfa = configuration->property(role + ".pfa", default_pfa); p_c_factor = configuration->property(role + ".p_c_factor", default_p_c_factor); length_ = configuration->property(role + ".length", default_length_); + n_segments_est = configuration->property(role + ".segments_est", default_n_segments_est); + n_segments_reset = configuration->property(role + ".segments_reset", default_n_segments_reset); if (item_type_.compare("gr_complex") == 0) { item_size_ = sizeof(gr_complex); - notch_filter_ = make_notch_filter(pfa, p_c_factor, length_); + notch_filter_ = make_notch_filter(pfa, p_c_factor, length_, n_segments_est, n_segments_reset); DLOG(INFO) << "Item size " << item_size_; DLOG(INFO) << "input filter(" << notch_filter_->unique_id() << ")"; diff --git a/src/algorithms/input_filter/adapters/notch_filter_lite.cc b/src/algorithms/input_filter/adapters/notch_filter_lite.cc index ec2ac636e..a91aa39e6 100644 --- a/src/algorithms/input_filter/adapters/notch_filter_lite.cc +++ b/src/algorithms/input_filter/adapters/notch_filter_lite.cc @@ -31,6 +31,7 @@ #include "notch_filter_lite.h" #include +#include #include #include #include @@ -49,6 +50,18 @@ NotchFilterLite::NotchFilterLite(ConfigurationInterface* configuration, std::str size_t item_size_; float p_c_factor; float default_p_c_factor = 0.9; + float pfa; + float default_pfa = 0.001; + int length_; + int default_length_ = 32; + int n_segments_est; + int default_n_segments_est = 12500; + int n_segments_reset; + int default_n_segments_reset = 5000000; + float default_samp_freq = 4000000; + float samp_freq = configuration->property("SignalSource.sampling_frequency", default_samp_freq); + float default_coeff_rate = samp_freq * 0.1; + float coeff_rate; std::string default_item_type = "gr_complex"; std::string default_dump_file = "./data/input_filter.dat"; item_type_ = configuration->property(role + ".item_type", default_item_type); @@ -56,13 +69,19 @@ NotchFilterLite::NotchFilterLite(ConfigurationInterface* configuration, std::str DLOG(INFO) << "dump_ is " << dump_; dump_filename_ = configuration->property(role + ".dump_filename", default_dump_file); p_c_factor = configuration->property(role + ".p_c_factor", default_p_c_factor); + pfa = configuration->property(role + ".pfa", default_pfa); + coeff_rate = configuration->property(role + ".coeff_rate", default_coeff_rate); + length_ = configuration->property(role + ".length", default_length_); + n_segments_est = configuration->property(role + ".segments_est", default_n_segments_est); + n_segments_reset = configuration->property(role + ".segments_reset", default_n_segments_reset); + int n_segments_coeff = (int) ((samp_freq / coeff_rate) / ((float) length_)); + n_segments_coeff = std::max(1, n_segments_coeff); if (item_type_.compare("gr_complex") == 0) { item_size_ = sizeof(gr_complex); - notch_filter_lite_ = make_notch_filter_lite(p_c_factor); + notch_filter_lite_ = make_notch_filter_lite(p_c_factor, pfa, length_, n_segments_est, n_segments_reset, n_segments_coeff); DLOG(INFO) << "Item size " << item_size_; DLOG(INFO) << "input filter(" << notch_filter_lite_->unique_id() << ")"; - } else { diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc index 007b3d9b3..700ccfea8 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc @@ -43,12 +43,12 @@ using google::LogMessage; notch_sptr make_notch_filter(float pfa, float p_c_factor, - int length_) + int length_, int n_segments_est, int n_segments_reset) { - return notch_sptr(new Notch(pfa, p_c_factor, length_)); + return notch_sptr(new Notch(pfa, p_c_factor, length_, n_segments_est, n_segments_reset)); } -Notch::Notch(float pfa, float p_c_factor, int length_) : gr::block("Notch", +Notch::Notch(float pfa, float p_c_factor, int length_, int n_segments_est, int n_segments_reset) : gr::block("Notch", gr::io_signature::make (1, 1, sizeof(gr_complex)), gr::io_signature::make (1, 1, sizeof(gr_complex))) { @@ -63,8 +63,8 @@ Notch::Notch(float pfa, float p_c_factor, int length_) : gr::block("Notch", filter_state_ = false; //Initial state of the filter n_deg_fred = 2 * length_; //Number of dregrees of freedom n_segments = 0; - n_segments_est = 8; // Set the number of segments for noise power estimation - n_segments_reset = 10000; // Set the period (in segments) when the noise power is estimated + this->n_segments_est = n_segments_est; // Set the number of segments for noise power estimation + this->n_segments_reset = n_segments_reset; // Set the period (in segments) when the noise power is estimated z_0 = gr_complex(0 , 0); boost::math::chi_squared_distribution my_dist_(n_deg_fred); thres_ = boost::math::quantile(boost::math::complement(my_dist_, pfa)); diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h index faf7c5d0c..5be7dfda6 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h @@ -39,7 +39,7 @@ class Notch; typedef boost::shared_ptr notch_sptr; notch_sptr make_notch_filter(float pfa, float p_c_factor, - int length_); + int length_, int n_segments_est, int n_segments_reset); /*! * \brief This class implements a real-time software-defined multi state notch filter @@ -67,7 +67,7 @@ private: public: - Notch(float pfa, float p_c_factor, int length_); + Notch(float pfa, float p_c_factor, int length_, int n_segments_est, int n_segments_reset); ~Notch(); diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc index 4b21bf33e..3ce19f656 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc @@ -37,15 +37,17 @@ #include #include #include +#include +#include using google::LogMessage; -notch_lite_sptr make_notch_filter_lite(float p_c_factor) +notch_lite_sptr make_notch_filter_lite(float p_c_factor, float pfa, int length_, int n_segments_est, int n_segments_reset, int n_segments_coeff) { - return notch_lite_sptr(new NotchLite(p_c_factor)); + return notch_lite_sptr(new NotchLite(p_c_factor, pfa, length_, n_segments_est, n_segments_reset, n_segments_coeff)); } -NotchLite::NotchLite(float p_c_factor) : gr::block("NotchLite", +NotchLite::NotchLite(float p_c_factor, float pfa, int length_, int n_segments_est, int n_segments_reset, int n_segments_coeff) : gr::block("NotchLite", gr::io_signature::make (1, 1, sizeof(gr_complex)), gr::io_signature::make (1, 1, sizeof(gr_complex))) { @@ -53,28 +55,97 @@ NotchLite::NotchLite(float p_c_factor) : gr::block("NotchLite", set_alignment(std::max(1, alignment_multiple)); set_history(2); this->p_c_factor = gr_complex(p_c_factor , 0); + this->n_segments_est = n_segments_est; + this->n_segments_reset = n_segments_reset; + this->n_segments_coeff_reset = n_segments_coeff; + this->n_segments_coeff = 0; + this->length_ = length_; + set_output_multiple(length_); + this->pfa = pfa; + n_segments = 0; + n_deg_fred = 2 * length_; + noise_pow_est = 0.0; + filter_state_ = false; z_0 = gr_complex(0 , 0); - last_out = gr_complex(0,0); + last_out = gr_complex(0, 0); + boost::math::chi_squared_distribution my_dist_(n_deg_fred); + thres_ = boost::math::quantile(boost::math::complement(my_dist_, pfa)); + c_samples = gr_complex(0, 0); + angle_ = 0.0; + power_spect = static_cast(volk_malloc(length_ * sizeof(float), volk_get_alignment())); + } +NotchLite::~NotchLite() +{ + volk_free(power_spect); +} + + int NotchLite::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { + int index_out = 0; + float sig2dB = 0.0; + float sig2lin = 0.0; + lv_32fc_t dot_prod_; gr_complex* in = (gr_complex *) input_items[0]; gr_complex* out = (gr_complex *) output_items[0]; - c_samples = static_cast(volk_malloc(noutput_items * sizeof(gr_complex), volk_get_alignment())); - angle_ = static_cast(volk_malloc(noutput_items * sizeof(float), volk_get_alignment())); - - volk_32fc_x2_multiply_conjugate_32fc(c_samples, (in + 1), in, noutput_items); - volk_32fc_s32f_atan2_32f(angle_, c_samples, ((float)1.0), noutput_items); - for (int aux = 0; aux < noutput_items; aux++) + in++; + arma::cx_fvec signal_segment; + arma::cx_fvec signal_segment_fft; + while((index_out + length_) < noutput_items) { - z_0 = std::exp(gr_complex(0,1) * (*(angle_ + aux))); - *(out + aux) = *(in + aux + 1) - z_0 * (*(in + aux)) + p_c_factor * z_0 * last_out; - last_out = *(out + aux); + if((n_segments < n_segments_est) && (filter_state_ == false)) + { + signal_segment = arma::cx_fvec(in, length_, false, false); + signal_segment_fft = arma::fft(signal_segment); + volk_32fc_s32f_power_spectrum_32f(power_spect, signal_segment_fft.memptr(), 1.0, length_); + volk_32f_s32f_calc_spectral_noise_floor_32f(&sig2dB, power_spect, 15.0, length_); + sig2lin = std::pow(10.0, (sig2dB / 10.0)) / ((float) n_deg_fred); + noise_pow_est = (((float) n_segments) * noise_pow_est + sig2lin) / ((float)(n_segments + 1)); + memcpy(out, in, sizeof(gr_complex) * length_); + } + else + { + volk_32fc_x2_conjugate_dot_prod_32fc(&dot_prod_, in, in, length_); + if( (lv_creal(dot_prod_) / noise_pow_est) > thres_) + { + if(filter_state_ == false) + { + filter_state_ = true; + last_out = gr_complex(0,0); + n_segments_coeff = 0; + } + if(n_segments_coeff == 0) + { + volk_32fc_x2_multiply_conjugate_32fc(&c_samples, in, (in - 1), 1); + volk_32fc_s32f_atan2_32f(&angle_, &c_samples, ((float)1.0), 1); + z_0 = std::exp(gr_complex(0,1) * angle_); + } + for(int aux = 0; aux < length_; aux++) + { + *(out + aux) = *(in + aux) - z_0 * (*(in + aux - 1)) + p_c_factor * z_0 * last_out; + last_out = *(out + aux); + } + n_segments_coeff++; + n_segments_coeff = n_segments_coeff % n_segments_coeff_reset; + } + else + { + if (n_segments > n_segments_reset) + { + n_segments = 0; + } + filter_state_ = false; + memcpy(out, in, sizeof(gr_complex) * length_); + } + } + index_out += length_; + n_segments++; + in += length_; + out += length_; } - volk_free(c_samples); - volk_free(angle_); - consume_each(noutput_items); - return noutput_items; + consume_each(index_out); + return index_out; } diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.h b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.h index 16f56286d..64dcb8d53 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.h +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.h @@ -38,7 +38,7 @@ class NotchLite; typedef boost::shared_ptr notch_lite_sptr; -notch_lite_sptr make_notch_filter_lite(float p_c_factor); +notch_lite_sptr make_notch_filter_lite(float p_c_factor, float pfa, int length_, int n_segments_est, int n_segments_reset, int n_segments_coeff); /*! * \brief This class implements a real-time software-defined single state notch filter @@ -48,15 +48,29 @@ class NotchLite : public gr::block { private: + int length_; + int n_segments; + int n_segments_est; + int n_segments_reset; + int n_segments_coeff_reset; + int n_segments_coeff; + int n_deg_fred; + float pfa; + float thres_; + float noise_pow_est; + bool filter_state_; gr_complex last_out; gr_complex z_0; gr_complex p_c_factor; - gr_complex* c_samples; - float* angle_; - + gr_complex c_samples; + float angle_; + float* power_spect; + public: - NotchLite(float p_c_factor); + NotchLite(float p_c_factor, float pfa, int length_, int n_segments_est, int n_segments_reset, int n_segments_coeff); + + ~NotchLite(); int general_work (int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, From 9df36dcd831535a1e64f2b779edf3c9d4111b863 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Thu, 24 Aug 2017 19:21:24 +0200 Subject: [PATCH 21/81] Minor changes Changing some variable names --- src/algorithms/input_filter/adapters/notch_filter.h | 2 +- .../input_filter/adapters/notch_filter_lite.h | 2 +- .../input_filter/adapters/pulse_blanking_filter.cc | 4 ++-- .../input_filter/adapters/pulse_blanking_filter.h | 1 + .../input_filter/gnuradio_blocks/notch_lite_cc.cc | 13 +++++++++---- .../input_filter/gnuradio_blocks/notch_lite_cc.h | 10 ++++++---- .../gnuradio_blocks/pulse_blanking_cc.cc | 4 ++-- .../gnuradio_blocks/pulse_blanking_cc.h | 4 ++-- 8 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/algorithms/input_filter/adapters/notch_filter.h b/src/algorithms/input_filter/adapters/notch_filter.h index 09ac10e99..a8ab2136b 100644 --- a/src/algorithms/input_filter/adapters/notch_filter.h +++ b/src/algorithms/input_filter/adapters/notch_filter.h @@ -1,6 +1,6 @@ /*! * \file notch_filter.h - * \brief + * \brief Adapter of a multistate Notch filter * \author Antonio Ramos, 2017. antonio.ramosdet(at)gmail.com * * Detailed description of the file here if needed. diff --git a/src/algorithms/input_filter/adapters/notch_filter_lite.h b/src/algorithms/input_filter/adapters/notch_filter_lite.h index 03796f319..f9088db52 100644 --- a/src/algorithms/input_filter/adapters/notch_filter_lite.h +++ b/src/algorithms/input_filter/adapters/notch_filter_lite.h @@ -1,6 +1,6 @@ /*! * \file notch_filter_lite.h - * \brief + * \brief Adapts a ligth version of a multistate notch filter * \author Antonio Ramos, 2017. antonio.ramosdet(at)gmail.com * * Detailed description of the file here if needed. diff --git a/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc b/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc index fed7205cc..0786f3f3e 100644 --- a/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc +++ b/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc @@ -2,7 +2,7 @@ * \file pulse_blanking_filter.cc * \brief Instantiates the GNSS-SDR pulse blanking filter * \author Javier Arribas 2017 - * + * Antonio Ramos 2017 * ------------------------------------------------------------------------- * * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) @@ -57,7 +57,7 @@ PulseBlankingFilter::PulseBlankingFilter(ConfigurationInterface* configuration, int default_length_ = 32; int length_ = config_->property(role_ + ".length", default_length_); int default_n_segments_est = 12500; - int n_segments_est = config_->property(role_ + ".segments_estimation", default_n_segments_est); + int n_segments_est = config_->property(role_ + ".segments_est", default_n_segments_est); int default_n_segments_reset = 5000000; int n_segments_reset = config_->property(role_ + ".segments_reset", default_n_segments_reset); if (input_item_type_.compare("gr_complex") == 0) diff --git a/src/algorithms/input_filter/adapters/pulse_blanking_filter.h b/src/algorithms/input_filter/adapters/pulse_blanking_filter.h index 041ba2251..c57c68d10 100644 --- a/src/algorithms/input_filter/adapters/pulse_blanking_filter.h +++ b/src/algorithms/input_filter/adapters/pulse_blanking_filter.h @@ -2,6 +2,7 @@ * \file pulse_blanking_filter.h * \brief Instantiates the GNSS-SDR pulse blanking filter * \author Javier Arribas 2017 + * Antonio Ramos 2017 * * ------------------------------------------------------------------------- * diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc index 3ce19f656..a84ec6ae6 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc @@ -70,8 +70,10 @@ NotchLite::NotchLite(float p_c_factor, float pfa, int length_, int n_segments_es last_out = gr_complex(0, 0); boost::math::chi_squared_distribution my_dist_(n_deg_fred); thres_ = boost::math::quantile(boost::math::complement(my_dist_, pfa)); - c_samples = gr_complex(0, 0); - angle_ = 0.0; + c_samples1 = gr_complex(0, 0); + c_samples2 = gr_complex(0, 0); + angle1 = 0.0; + angle2 = 0.0; power_spect = static_cast(volk_malloc(length_ * sizeof(float), volk_get_alignment())); } @@ -119,8 +121,11 @@ int NotchLite::general_work(int noutput_items __attribute__((unused)), gr_vector } if(n_segments_coeff == 0) { - volk_32fc_x2_multiply_conjugate_32fc(&c_samples, in, (in - 1), 1); - volk_32fc_s32f_atan2_32f(&angle_, &c_samples, ((float)1.0), 1); + volk_32fc_x2_multiply_conjugate_32fc(&c_samples1, (in + 1), in, 1); + volk_32fc_s32f_atan2_32f(&angle1, &c_samples1, ((float)1.0), 1); + volk_32fc_x2_multiply_conjugate_32fc(&c_samples2, (in + length_ - 1), (in + length_ - 2), 1); + volk_32fc_s32f_atan2_32f(&angle2, &c_samples2, ((float)1.0), 1); + float angle_ = (angle1 + angle2) / 2.0; z_0 = std::exp(gr_complex(0,1) * angle_); } for(int aux = 0; aux < length_; aux++) diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.h b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.h index 64dcb8d53..2151a459f 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.h +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.h @@ -1,6 +1,6 @@ /*! * \file notch_lite_cc.h - * \brief Implements a notch filter algorithm + * \brief Implements a notch filter ligth algorithm * \author Antonio Ramos (antonio.ramosdet(at)gmail.com) * * ------------------------------------------------------------------------- @@ -41,7 +41,7 @@ typedef boost::shared_ptr notch_lite_sptr; notch_lite_sptr make_notch_filter_lite(float p_c_factor, float pfa, int length_, int n_segments_est, int n_segments_reset, int n_segments_coeff); /*! - * \brief This class implements a real-time software-defined single state notch filter + * \brief This class implements a real-time software-defined multi state notch filter ligth version */ class NotchLite : public gr::block @@ -62,8 +62,10 @@ private: gr_complex last_out; gr_complex z_0; gr_complex p_c_factor; - gr_complex c_samples; - float angle_; + gr_complex c_samples1; + gr_complex c_samples2; + float angle1; + float angle2; float* power_spect; public: diff --git a/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc index a744f8747..7924f17ba 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc @@ -1,8 +1,8 @@ /*! * \file pulse_blanking_cc.cc - * \brief Implements a simple pulse blanking algorithm + * \brief Implements a pulse blanking algorithm * \author Javier Arribas (jarribas(at)cttc.es) - * + * Antonio Ramos (antonio.ramosdet(at)gmail.com) * ------------------------------------------------------------------------- * * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) diff --git a/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.h b/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.h index a77cf4deb..7a19bf74e 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.h +++ b/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.h @@ -1,8 +1,8 @@ /*! * \file pulse_blanking_cc.h - * \brief Implements a simple pulse blanking algorithm + * \brief Implements a pulse blanking algorithm * \author Javier Arribas (jarribas(at)cttc.es) - * + * Antonio Ramos (antonio.ramosdet(at)gmail.com) * ------------------------------------------------------------------------- * * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) From 173b6c7d8af7434d21fc9512bae03da09949e8e0 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Thu, 12 Oct 2017 19:15:44 +0200 Subject: [PATCH 22/81] Pass Gnns_Satellite object by reference instead of by value --- .../gnuradio_blocks/galileo_e5a_telemetry_decoder_cc.cc | 4 ++-- .../gnuradio_blocks/galileo_e5a_telemetry_decoder_cc.h | 8 +++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e5a_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e5a_telemetry_decoder_cc.cc index 4dbccde7a..2077ba4ab 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e5a_telemetry_decoder_cc.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e5a_telemetry_decoder_cc.cc @@ -109,7 +109,7 @@ void galileo_e5a_telemetry_decoder_cc::deinterleaver(int rows, int cols, double } -void galileo_e5a_telemetry_decoder_cc::decode_word(double *page_symbols,int frame_length) +void galileo_e5a_telemetry_decoder_cc::decode_word(double *page_symbols, int frame_length) { double page_symbols_deint[frame_length]; // 1. De-interleave @@ -530,7 +530,7 @@ int galileo_e5a_telemetry_decoder_cc::general_work (int noutput_items __attribut } -void galileo_e5a_telemetry_decoder_cc::set_satellite(Gnss_Satellite satellite) +void galileo_e5a_telemetry_decoder_cc::set_satellite(const Gnss_Satellite & satellite) { d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); DLOG(INFO) << "Setting decoder Finite State Machine to satellite " << d_satellite; diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e5a_telemetry_decoder_cc.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e5a_telemetry_decoder_cc.h index 2389bfb2e..46620a86e 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e5a_telemetry_decoder_cc.h +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e5a_telemetry_decoder_cc.h @@ -66,8 +66,8 @@ class galileo_e5a_telemetry_decoder_cc : public gr::block { public: ~galileo_e5a_telemetry_decoder_cc(); - void set_satellite(Gnss_Satellite satellite); //!< Set satellite PRN - void set_channel(int channel); //!< Set receiver's channel + void set_satellite(const Gnss_Satellite & satellite); //!< Set satellite PRN + void set_channel(int channel); //!< Set receiver's channel /*! * \brief This is where all signal processing takes place */ @@ -83,13 +83,11 @@ private: void deinterleaver(int rows, int cols, double *in, double *out); - void decode_word(double *page_symbols,int frame_length); + void decode_word(double *page_symbols, int frame_length); int d_preamble_bits[GALILEO_FNAV_PREAMBLE_LENGTH_BITS]; - // signed int d_page_symbols[GALILEO_FNAV_SYMBOLS_PER_PAGE + GALILEO_FNAV_PREAMBLE_LENGTH_BITS]; double d_page_symbols[GALILEO_FNAV_SYMBOLS_PER_PAGE + GALILEO_FNAV_PREAMBLE_LENGTH_BITS]; - // signed int *d_preamble_symbols; double d_current_symbol; long unsigned int d_symbol_counter; int d_prompt_counter; From bda1f15594d114216fa2f4c2817a3d10e9694646 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 13 Oct 2017 11:18:19 +0200 Subject: [PATCH 23/81] Fix compilation problem with Xcode 9 The following error appeared when working with the latest macOS Xcode 9 SDK: error: unknown type name 'mach_port_t' mach_port_t __libcpp_thread_get_port(); Added: #ifdef __APPLE__ #define _DARWIN_C_SOURCE #endif (solution found at https://github.com/arvidn/libtorrent/issues/2364 ) --- .../libs/volk_gnsssdr_module/volk_gnsssdr/lib/qa_utils.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/qa_utils.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/qa_utils.h index aa3192524..b01a29bc1 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/qa_utils.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/qa_utils.h @@ -19,6 +19,10 @@ #ifndef GNSS_SDR_VOLK_QA_UTILS_H #define GNSS_SDR_VOLK_QA_UTILS_H +#ifdef __APPLE__ +#define _DARWIN_C_SOURCE +#endif + #include #include #include From 9b1ae8590455e00514dcf770144df78bbcdb990b Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 13 Oct 2017 11:26:39 +0200 Subject: [PATCH 24/81] Fix identical code for different branches --- .../libs/volk_gnsssdr_module/volk_gnsssdr/lib/qa_utils.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/qa_utils.cc b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/qa_utils.cc index 8019b3a8a..3d60c2714 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/qa_utils.cc +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/qa_utils.cc @@ -717,11 +717,11 @@ bool run_volk_gnsssdr_tests(volk_gnsssdr_func_desc_t desc, { if(both_sigs[j].is_signed) { - fail = icompare((int16_t *) test_data[generic_offset][j], (int16_t *) test_data[i][j], vlen*(both_sigs[j].is_complex ? 2 : 1), tol_i); + fail = icompare((int8_t *) test_data[generic_offset][j], (int8_t *) test_data[i][j], vlen*(both_sigs[j].is_complex ? 2 : 1), tol_i); } else { - fail = icompare((uint16_t *) test_data[generic_offset][j], (uint16_t *) test_data[i][j], vlen*(both_sigs[j].is_complex ? 2 : 1), tol_i); + fail = icompare((uint8_t *) test_data[generic_offset][j], (uint8_t *) test_data[i][j], vlen*(both_sigs[j].is_complex ? 2 : 1), tol_i); } } else From c94a0dcd613123111c36a8d5b0ec92186a628113 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 13 Oct 2017 11:27:15 +0200 Subject: [PATCH 25/81] Added __VOLK_ASM and __VOLK_VOLATILE --- .../volk_gnsssdr/include/volk_gnsssdr/volk_gnsssdr_common.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/include/volk_gnsssdr/volk_gnsssdr_common.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/include/volk_gnsssdr/volk_gnsssdr_common.h index 87841616d..24b6501b8 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/include/volk_gnsssdr/volk_gnsssdr_common.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/include/volk_gnsssdr/volk_gnsssdr_common.h @@ -49,6 +49,8 @@ # define __VOLK_ATTR_UNUSED __attribute__((unused)) # define __VOLK_ATTR_INLINE __attribute__((always_inline)) # define __VOLK_ATTR_DEPRECATED __attribute__((deprecated)) +# define __VOLK_ASM __asm__ +# define __VOLK_VOLATILE __volatile__ # if __GNUC__ >= 4 # define __VOLK_ATTR_EXPORT __attribute__((visibility("default"))) # define __VOLK_ATTR_IMPORT __attribute__((visibility("default"))) @@ -63,6 +65,8 @@ # define __VOLK_ATTR_DEPRECATED __declspec(deprecated) # define __VOLK_ATTR_EXPORT __declspec(dllexport) # define __VOLK_ATTR_IMPORT __declspec(dllimport) +# define __VOLK_ASM __asm +# define __VOLK_VOLATILE #else # define __VOLK_ATTR_ALIGNED(x) # define __VOLK_ATTR_UNUSED @@ -70,6 +74,8 @@ # define __VOLK_ATTR_DEPRECATED # define __VOLK_ATTR_EXPORT # define __VOLK_ATTR_IMPORT +# define __VOLK_ASM __asm__ +# define __VOLK_VOLATILE __volatile__ #endif //////////////////////////////////////////////////////////////////////// From 0be23787d7bb6cc299ee3eb35d92b6d263ea402a Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 13 Oct 2017 11:32:00 +0200 Subject: [PATCH 26/81] Use __VOLK_ASM and __VOLK_VOLATILE keywords --- .../volk_gnsssdr/tmpl/volk_gnsssdr_cpu.tmpl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/tmpl/volk_gnsssdr_cpu.tmpl.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/tmpl/volk_gnsssdr_cpu.tmpl.c index d77bf49ad..1d094a87a 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/tmpl/volk_gnsssdr_cpu.tmpl.c +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/tmpl/volk_gnsssdr_cpu.tmpl.c @@ -42,7 +42,7 @@ struct VOLK_CPU volk_gnsssdr_cpu; #if ((__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 2) || (__clang_major__ >= 3)) && defined(HAVE_XGETBV) static inline unsigned long long _xgetbv(unsigned int index){ unsigned int eax, edx; - __asm__ __volatile__("xgetbv" : "=a"(eax), "=d"(edx) : "c"(index)); + __VOLK_ASM __VOLK_VOLATILE ("xgetbv" : "=a"(eax), "=d"(edx) : "c"(index)); return ((unsigned long long)edx << 32) | eax; } #define __xgetbv() _xgetbv(0) From 76e6adf3ade1eb1e5169deb30b2b6867d7ab9841 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 13 Oct 2017 11:35:12 +0200 Subject: [PATCH 27/81] Include some files that were not getting installed --- .../libs/volk_gnsssdr_module/volk_gnsssdr/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/CMakeLists.txt b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/CMakeLists.txt index 8178609a2..1699ea5e9 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/CMakeLists.txt +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/CMakeLists.txt @@ -192,7 +192,9 @@ install(FILES ${PROJECT_SOURCE_DIR}/include/volk_gnsssdr/volk_gnsssdr_prefs.h ${PROJECT_SOURCE_DIR}/include/volk_gnsssdr/volk_gnsssdr_complex.h ${PROJECT_SOURCE_DIR}/include/volk_gnsssdr/volk_gnsssdr_common.h + ${PROJECT_SOURCE_DIR}/include/volk_gnsssdr/saturation_arithmetic.h ${PROJECT_SOURCE_DIR}/include/volk_gnsssdr/volk_gnsssdr_avx_intrinsics.h + ${PROJECT_SOURCE_DIR}/include/volk_gnsssdr/volk_gnsssdr_sse_intrinsics.h ${PROJECT_SOURCE_DIR}/include/volk_gnsssdr/volk_gnsssdr_sse3_intrinsics.h ${PROJECT_SOURCE_DIR}/include/volk_gnsssdr/volk_gnsssdr_neon_intrinsics.h ${PROJECT_BINARY_DIR}/include/volk_gnsssdr/volk_gnsssdr.h From 0f45e7d2116f84e3ed338f2eb231488cff9d452f Mon Sep 17 00:00:00 2001 From: Unknown Date: Fri, 13 Oct 2017 16:21:26 +0200 Subject: [PATCH 28/81] Block Factory filter instantiation tests Added test cases for Pulse_Blanking, Notch and Notch_Lite filters --- .../control-plane/gnss_block_factory_test.cc | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/tests/unit-tests/control-plane/gnss_block_factory_test.cc b/src/tests/unit-tests/control-plane/gnss_block_factory_test.cc index 3f6aee435..e2fcd9880 100644 --- a/src/tests/unit-tests/control-plane/gnss_block_factory_test.cc +++ b/src/tests/unit-tests/control-plane/gnss_block_factory_test.cc @@ -155,6 +155,45 @@ TEST(GNSSBlockFactoryTest, InstantiateFreqXlatingFIRFilter) EXPECT_STREQ("Freq_Xlating_Fir_Filter", input_filter->implementation().c_str()); } +TEST(GNSSBlockFactoryTest, InstantiatePulseBlankingFilter) +{ + std::shared_ptr configuration = std::make_shared(); + gr::msg_queue::sptr queue = gr::msg_queue::make(0); + configuration->set_property("InputFilter.implementation", "Pulse_Blanking_Filter"); + + std::unique_ptr factory; + std::unique_ptr input_filter = factory->GetBlock(configuration, "InputFilter", "Pulse_Blanking_Filter", 1, 1); + + EXPECT_STREQ("InputFilter", input_filter->role().c_str()); + EXPECT_STREQ("Pulse_Blanking_Filter", input_filter->implementation().c_str()); +} + +TEST(GNSSBlockFactoryTest, InstantiateNotchFilter) +{ + std::shared_ptr configuration = std::make_shared(); + gr::msg_queue::sptr queue = gr::msg_queue::make(0); + configuration->set_property("InputFilter.implementation", "Notch_Filter"); + + std::unique_ptr factory; + std::unique_ptr input_filter = factory->GetBlock(configuration, "InputFilter", "Notch_Filter", 1, 1); + + EXPECT_STREQ("InputFilter", input_filter->role().c_str()); + EXPECT_STREQ("Notch_Filter", input_filter->implementation().c_str()); +} + +TEST(GNSSBlockFactoryTest, InstantiateNotchFilterLite) +{ + std::shared_ptr configuration = std::make_shared(); + gr::msg_queue::sptr queue = gr::msg_queue::make(0); + configuration->set_property("InputFilter.implementation", "Notch_Filter_Lite"); + + std::unique_ptr factory; + std::unique_ptr input_filter = factory->GetBlock(configuration, "InputFilter", "Notch_Filter_Lite", 1, 1); + + EXPECT_STREQ("InputFilter", input_filter->role().c_str()); + EXPECT_STREQ("Notch_Filter_Lite", input_filter->implementation().c_str()); +} + TEST(GNSSBlockFactoryTest, InstantiateDirectResampler) { std::shared_ptr configuration = std::make_shared(); From acfd4cc0c976757fdca9c049c47f266f1ed09fd5 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sat, 14 Oct 2017 12:30:03 +0200 Subject: [PATCH 29/81] Replace C-style casts by C++ casts Apply code styling Fix a GCC warning (unused variable) --- .../gnuradio_blocks/hybrid_observables_cc.cc | 553 +++++++++--------- .../gnuradio_blocks/hybrid_observables_cc.h | 32 +- .../gps_l1_ca_telemetry_decoder_cc.cc | 10 +- 3 files changed, 296 insertions(+), 299 deletions(-) diff --git a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc index 9ee672c7b..45cc3a3fc 100644 --- a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc +++ b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc @@ -46,345 +46,342 @@ using google::LogMessage; hybrid_observables_cc_sptr hybrid_make_observables_cc(unsigned int nchannels, bool dump, std::string dump_filename, unsigned int deep_history) { - return hybrid_observables_cc_sptr(new hybrid_observables_cc(nchannels, dump, dump_filename, deep_history)); + return hybrid_observables_cc_sptr(new hybrid_observables_cc(nchannels, dump, dump_filename, deep_history)); } hybrid_observables_cc::hybrid_observables_cc(unsigned int nchannels, bool dump, std::string dump_filename, unsigned int deep_history) : - gr::block("hybrid_observables_cc", gr::io_signature::make(nchannels, nchannels, sizeof(Gnss_Synchro)), - gr::io_signature::make(nchannels, nchannels, sizeof(Gnss_Synchro))) + gr::block("hybrid_observables_cc", gr::io_signature::make(nchannels, nchannels, sizeof(Gnss_Synchro)), + gr::io_signature::make(nchannels, nchannels, sizeof(Gnss_Synchro))) { - // initialize internal vars - d_dump = dump; - d_nchannels = nchannels; - d_dump_filename = dump_filename; - history_deep = deep_history; - T_rx_s = 0.0; - T_rx_step_s = 1e-3;// todo: move to gnss-sdr config - for (unsigned int i = 0; i < d_nchannels; i++) - { - d_gnss_synchro_history_queue.push_back(std::deque()); - } - //todo: this is a gnuradio scheduler hack. - // Migrate the queues to gnuradio set_history to see if the scheduler can handle - // the multiple output flow - d_max_noutputs = 100; - this->set_min_noutput_items(100); - - // ############# ENABLE DATA FILE LOG ################# - if (d_dump == true) - { - if (d_dump_file.is_open() == false) + // initialize internal vars + d_dump = dump; + d_nchannels = nchannels; + d_dump_filename = dump_filename; + history_deep = deep_history; + T_rx_s = 0.0; + T_rx_step_s = 1e-3; // todo: move to gnss-sdr config + for (unsigned int i = 0; i < d_nchannels; i++) { - try - { - d_dump_file.exceptions (std::ifstream::failbit | std::ifstream::badbit ); - d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); - LOG(INFO) << "Observables dump enabled Log file: " << d_dump_filename.c_str(); - } - catch (const std::ifstream::failure & e) - { - LOG(WARNING) << "Exception opening observables dump file " << e.what(); - } + d_gnss_synchro_history_queue.push_back(std::deque()); + } + // todo: this is a gnuradio scheduler hack. + // Migrate the queues to gnuradio set_history to see if the scheduler can handle + // the multiple output flow + d_max_noutputs = 100; + this->set_min_noutput_items(100); + + // ############# ENABLE DATA FILE LOG ################# + if (d_dump == true) + { + if (d_dump_file.is_open() == false) + { + try + { + d_dump_file.exceptions (std::ifstream::failbit | std::ifstream::badbit ); + d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); + LOG(INFO) << "Observables dump enabled Log file: " << d_dump_filename.c_str(); + } + catch (const std::ifstream::failure & e) + { + LOG(WARNING) << "Exception opening observables dump file " << e.what(); + } + } } - } } hybrid_observables_cc::~hybrid_observables_cc() { - if (d_dump_file.is_open() == true) - { - try - { - d_dump_file.close(); - } - catch(const std::exception & ex) - { - LOG(WARNING) << "Exception in destructor closing the dump file " << ex.what(); - } - } + if (d_dump_file.is_open() == true) + { + try + { + d_dump_file.close(); + } + catch(const std::exception & ex) + { + LOG(WARNING) << "Exception in destructor closing the dump file " << ex.what(); + } + } } bool Hybrid_pairCompare_gnss_synchro_sample_counter(const std::pair& a, const std::pair& b) { - return (a.second.Tracking_sample_counter) < (b.second.Tracking_sample_counter); + return (a.second.Tracking_sample_counter) < (b.second.Tracking_sample_counter); } bool Hybrid_valueCompare_gnss_synchro_sample_counter(const Gnss_Synchro& a, unsigned long int b) { - return (a.Tracking_sample_counter) < (b); + return (a.Tracking_sample_counter) < (b); } bool Hybrid_valueCompare_gnss_synchro_receiver_time(const Gnss_Synchro& a, double b) { - return (((double)a.Tracking_sample_counter+a.Code_phase_samples)/(double)a.fs) < (b); + return (((double)a.Tracking_sample_counter+a.Code_phase_samples)/(double)a.fs) < (b); } bool Hybrid_pairCompare_gnss_synchro_d_TOW(const std::pair& a, const std::pair& b) { - return (a.second.TOW_at_current_symbol_s) < (b.second.TOW_at_current_symbol_s); + return (a.second.TOW_at_current_symbol_s) < (b.second.TOW_at_current_symbol_s); } bool Hybrid_valueCompare_gnss_synchro_d_TOW(const Gnss_Synchro& a, double b) { - return (a.TOW_at_current_symbol_s) < (b); + return (a.TOW_at_current_symbol_s) < (b); } -int hybrid_observables_cc::general_work (int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) +int hybrid_observables_cc::general_work (int noutput_items __attribute__((unused)), + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) { - Gnss_Synchro **in = (Gnss_Synchro **) &input_items[0]; // Get the input pointer - Gnss_Synchro **out = (Gnss_Synchro **) &output_items[0]; // Get the output pointer - int n_outputs = 0; - int n_consume[d_nchannels]; - double past_history_s = 100e-3; + const Gnss_Synchro **in = reinterpret_cast(&input_items[0]); // Get the input buffer pointer + Gnss_Synchro **out = reinterpret_cast(&output_items[0]); // Get the output buffer pointer + int n_outputs = 0; + int n_consume[d_nchannels]; + double past_history_s = 100e-3; - Gnss_Synchro current_gnss_synchro[d_nchannels]; + Gnss_Synchro current_gnss_synchro[d_nchannels]; - /* - * 1. Read the GNSS SYNCHRO objects from available channels. - * Multi-rate GNURADIO Block. Read how many input items are avaliable in each channel - * Record all synchronization data into queues - */ - for (unsigned int i = 0; i < d_nchannels; i++) - { - n_consume[i] = ninput_items[i];// full throttle - for (int j = 0; j < n_consume[i]; j++) + /* + * 1. Read the GNSS SYNCHRO objects from available channels. + * Multi-rate GNURADIO Block. Read how many input items are avaliable in each channel + * Record all synchronization data into queues + */ + for (unsigned int i = 0; i < d_nchannels; i++) { - d_gnss_synchro_history_queue[i].push_back(in[i][j]); - } - //std::cout<<"push["<::iterator gnss_synchro_map_iter; - std::deque::iterator gnss_synchro_deque_iter; - - //1. If the RX time is not set, set the Rx time - if (T_rx_s == 0) - { - //0. Read a gnss_synchro snapshot from the queue and store it in a map - std::map gnss_synchro_map; - for (unsigned int i = 0; i < d_nchannels; i++) + n_consume[i] = ninput_items[i];// full throttle + for (int j = 0; j < n_consume[i]; j++) { - gnss_synchro_map.insert(std::pair( - d_gnss_synchro_history_queue[i].front().Channel_ID, - d_gnss_synchro_history_queue[i].front())); + d_gnss_synchro_history_queue[i].push_back(in[i][j]); } - gnss_synchro_map_iter = min_element(gnss_synchro_map.begin(), - gnss_synchro_map.end(), - Hybrid_pairCompare_gnss_synchro_sample_counter); - T_rx_s = (double)gnss_synchro_map_iter->second.Tracking_sample_counter / (double)gnss_synchro_map_iter->second.fs; - T_rx_s = floor(T_rx_s * 1000.0) / 1000.0; // truncate to ms - T_rx_s += past_history_s; // increase T_rx to have a minimum past history to interpolate - } + //std::cout<<"push["< realigned_gnss_synchro_map; //container for the aligned set of observables for the selected T_rx - std::map adjacent_gnss_synchro_map; //container for the previous observable values to interpolate - //shift channels history to match the reference TOW - for (unsigned int i = 0; i < d_nchannels; i++) - { - gnss_synchro_deque_iter = std::lower_bound(d_gnss_synchro_history_queue[i].begin(), - d_gnss_synchro_history_queue[i].end(), - T_rx_s, - Hybrid_valueCompare_gnss_synchro_receiver_time); - if (gnss_synchro_deque_iter != d_gnss_synchro_history_queue[i].end()) + bool channel_history_ok; + do + { + channel_history_ok = true; + for (unsigned int i = 0; i < d_nchannels; i++) { - if (gnss_synchro_deque_iter->Flag_valid_word == true) - { - double T_rx_channel = (double)gnss_synchro_deque_iter->Tracking_sample_counter / (double)gnss_synchro_deque_iter->fs; - double delta_T_rx_s = T_rx_channel - T_rx_s; - - //check that T_rx difference is less than a threshold (the correlation interval) - if (delta_T_rx_s * 1000.0 < (double)gnss_synchro_deque_iter->correlation_length_ms) + if (d_gnss_synchro_history_queue[i].size() < history_deep) { - //record the word structure in a map for pseudorange computation - //save the previous observable - int distance = std::distance(d_gnss_synchro_history_queue[i].begin(), gnss_synchro_deque_iter); - if (distance > 0) - { - if (d_gnss_synchro_history_queue[i].at(distance-1).Flag_valid_word) + channel_history_ok = false; + } + + } + if (channel_history_ok == true) + { + std::map::iterator gnss_synchro_map_iter; + std::deque::iterator gnss_synchro_deque_iter; + + // 1. If the RX time is not set, set the Rx time + if (T_rx_s == 0) + { + // 0. Read a gnss_synchro snapshot from the queue and store it in a map + std::map gnss_synchro_map; + for (unsigned int i = 0; i < d_nchannels; i++) { - double T_rx_channel_prev = (double)d_gnss_synchro_history_queue[i].at(distance - 1).Tracking_sample_counter / (double)gnss_synchro_deque_iter->fs; - double delta_T_rx_s_prev = T_rx_channel_prev - T_rx_s; - if (fabs(delta_T_rx_s_prev) < fabs(delta_T_rx_s)) + gnss_synchro_map.insert(std::pair(d_gnss_synchro_history_queue[i].front().Channel_ID, + d_gnss_synchro_history_queue[i].front())); + } + gnss_synchro_map_iter = min_element(gnss_synchro_map.begin(), + gnss_synchro_map.end(), + Hybrid_pairCompare_gnss_synchro_sample_counter); + T_rx_s = static_cast(gnss_synchro_map_iter->second.Tracking_sample_counter) / static_cast(gnss_synchro_map_iter->second.fs); + T_rx_s = floor(T_rx_s * 1000.0) / 1000.0; // truncate to ms + T_rx_s += past_history_s; // increase T_rx to have a minimum past history to interpolate + } + + // 2. Realign RX time in all valid channels + std::map realigned_gnss_synchro_map; // container for the aligned set of observables for the selected T_rx + std::map adjacent_gnss_synchro_map; // container for the previous observable values to interpolate + // shift channels history to match the reference TOW + for (unsigned int i = 0; i < d_nchannels; i++) + { + gnss_synchro_deque_iter = std::lower_bound(d_gnss_synchro_history_queue[i].begin(), + d_gnss_synchro_history_queue[i].end(), + T_rx_s, + Hybrid_valueCompare_gnss_synchro_receiver_time); + if (gnss_synchro_deque_iter != d_gnss_synchro_history_queue[i].end()) + { + if (gnss_synchro_deque_iter->Flag_valid_word == true) + { + double T_rx_channel = static_cast(gnss_synchro_deque_iter->Tracking_sample_counter) / static_cast(gnss_synchro_deque_iter->fs); + double delta_T_rx_s = T_rx_channel - T_rx_s; + + // check that T_rx difference is less than a threshold (the correlation interval) + if (delta_T_rx_s * 1000.0 < static_cast(gnss_synchro_deque_iter->correlation_length_ms)) + { + // record the word structure in a map for pseudorange computation + // save the previous observable + int distance = std::distance(d_gnss_synchro_history_queue[i].begin(), gnss_synchro_deque_iter); + if (distance > 0) + { + if (d_gnss_synchro_history_queue[i].at(distance-1).Flag_valid_word) + { + double T_rx_channel_prev = static_cast(d_gnss_synchro_history_queue[i].at(distance - 1).Tracking_sample_counter) / static_cast(gnss_synchro_deque_iter->fs); + double delta_T_rx_s_prev = T_rx_channel_prev - T_rx_s; + if (fabs(delta_T_rx_s_prev) < fabs(delta_T_rx_s)) + { + realigned_gnss_synchro_map.insert(std::pair(d_gnss_synchro_history_queue[i].at(distance - 1).Channel_ID, + d_gnss_synchro_history_queue[i].at(distance - 1))); + adjacent_gnss_synchro_map.insert(std::pair(gnss_synchro_deque_iter->Channel_ID, *gnss_synchro_deque_iter)); + } + else + { + realigned_gnss_synchro_map.insert(std::pair(gnss_synchro_deque_iter->Channel_ID, *gnss_synchro_deque_iter)); + adjacent_gnss_synchro_map.insert(std::pair(d_gnss_synchro_history_queue[i].at(distance - 1).Channel_ID, + d_gnss_synchro_history_queue[i].at(distance - 1))); + } + } + } + else + { + realigned_gnss_synchro_map.insert(std::pair(gnss_synchro_deque_iter->Channel_ID, *gnss_synchro_deque_iter)); + } + + } + else + { + //std::cout<<"ch["< this will be the reference symbol + gnss_synchro_map_iter = max_element(realigned_gnss_synchro_map.begin(), + realigned_gnss_synchro_map.end(), + Hybrid_pairCompare_gnss_synchro_d_TOW); + double ref_fs_hz = static_cast(gnss_synchro_map_iter->second.fs); + + // compute interpolated TOW value at T_rx_s + int ref_channel_key = gnss_synchro_map_iter->second.Channel_ID; + Gnss_Synchro adj_obs = adjacent_gnss_synchro_map.at(ref_channel_key); + double ref_adj_T_rx_s = static_cast(adj_obs.Tracking_sample_counter) / ref_fs_hz + adj_obs.Code_phase_samples / ref_fs_hz; + + double d_TOW_reference = gnss_synchro_map_iter->second.TOW_at_current_symbol_s; + double d_ref_T_rx_s = static_cast(gnss_synchro_map_iter->second.Tracking_sample_counter) / ref_fs_hz + gnss_synchro_map_iter->second.Code_phase_samples / ref_fs_hz; + + double selected_T_rx_s = T_rx_s; + // two points linear interpolation using adjacent (adj) values: y=y1+(x-x1)*(y2-y1)/(x2-x1) + double ref_TOW_at_T_rx_s = adj_obs.TOW_at_current_symbol_s + + (selected_T_rx_s - ref_adj_T_rx_s) * (d_TOW_reference - adj_obs.TOW_at_current_symbol_s) / (d_ref_T_rx_s - ref_adj_T_rx_s); + + // Now compute RX time differences due to the PRN alignment in the correlators + double traveltime_ms; + double pseudorange_m; + double channel_T_rx_s; + double channel_fs_hz; + double channel_TOW_s; + for(gnss_synchro_map_iter = realigned_gnss_synchro_map.begin(); gnss_synchro_map_iter != realigned_gnss_synchro_map.end(); gnss_synchro_map_iter++) + { + channel_fs_hz = static_cast(gnss_synchro_map_iter->second.fs); + channel_TOW_s = gnss_synchro_map_iter->second.TOW_at_current_symbol_s; + channel_T_rx_s = static_cast(gnss_synchro_map_iter->second.Tracking_sample_counter) / channel_fs_hz + gnss_synchro_map_iter->second.Code_phase_samples / channel_fs_hz; + // compute interpolated observation values + // two points linear interpolation using adjacent (adj) values: y=y1+(x-x1)*(y2-y1)/(x2-x1) + // TOW at the selected receiver time T_rx_s + int element_key = gnss_synchro_map_iter->second.Channel_ID; + adj_obs = adjacent_gnss_synchro_map.at(element_key); + + double adj_T_rx_s = static_cast(adj_obs.Tracking_sample_counter) / channel_fs_hz + adj_obs.Code_phase_samples / channel_fs_hz; + + double channel_TOW_at_T_rx_s = adj_obs.TOW_at_current_symbol_s + (selected_T_rx_s - adj_T_rx_s) * (channel_TOW_s - adj_obs.TOW_at_current_symbol_s) / (channel_T_rx_s - adj_T_rx_s); + + // Doppler and Accumulated carrier phase + double Carrier_phase_lin_rads = adj_obs.Carrier_phase_rads + (selected_T_rx_s - adj_T_rx_s) * (gnss_synchro_map_iter->second.Carrier_phase_rads - adj_obs.Carrier_phase_rads) / (channel_T_rx_s - adj_T_rx_s); + double Carrier_Doppler_lin_hz = adj_obs.Carrier_Doppler_hz + (selected_T_rx_s - adj_T_rx_s) * (gnss_synchro_map_iter->second.Carrier_Doppler_hz - adj_obs.Carrier_Doppler_hz) / (channel_T_rx_s - adj_T_rx_s); + + // compute the pseudorange (no rx time offset correction) + traveltime_ms = (ref_TOW_at_T_rx_s - channel_TOW_at_T_rx_s) * 1000.0 + GPS_STARTOFFSET_ms; + // convert to meters + pseudorange_m = traveltime_ms * GPS_C_m_ms; // [m] + // update the pseudorange object + current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID] = gnss_synchro_map_iter->second; + current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID].Pseudorange_m = pseudorange_m; + current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID].Flag_valid_pseudorange = true; + // Save the estimated RX time (no RX clock offset correction yet!) + current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID].RX_time = ref_TOW_at_T_rx_s + GPS_STARTOFFSET_ms / 1000.0; + + current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID].Carrier_phase_rads = Carrier_phase_lin_rads; + current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID].Carrier_Doppler_hz = Carrier_Doppler_lin_hz; + } + + if(d_dump == true) + { + // MULTIPLEXED FILE RECORDING - Record results to file + try { - realigned_gnss_synchro_map.insert(std::pair( - d_gnss_synchro_history_queue[i].at(distance-1).Channel_ID, - d_gnss_synchro_history_queue[i].at(distance-1))); - adjacent_gnss_synchro_map.insert(std::pair(gnss_synchro_deque_iter->Channel_ID, *gnss_synchro_deque_iter)); + double tmp_double; + for (unsigned int i = 0; i < d_nchannels; i++) + { + tmp_double = current_gnss_synchro[i].RX_time; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_double = current_gnss_synchro[i].TOW_at_current_symbol_s; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_double = current_gnss_synchro[i].Carrier_Doppler_hz; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_double = current_gnss_synchro[i].Carrier_phase_rads/GPS_TWO_PI; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_double = current_gnss_synchro[i].Pseudorange_m; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_double = current_gnss_synchro[i].PRN; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_double = current_gnss_synchro[i].Flag_valid_pseudorange; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + } } - else + catch (const std::ifstream::failure& e) { - realigned_gnss_synchro_map.insert(std::pair(gnss_synchro_deque_iter->Channel_ID, *gnss_synchro_deque_iter)); - adjacent_gnss_synchro_map.insert(std::pair( - d_gnss_synchro_history_queue[i].at(distance-1).Channel_ID, - d_gnss_synchro_history_queue[i].at(distance-1))); + LOG(WARNING) << "Exception writing observables dump file " << e.what(); } } - } - else - { - realigned_gnss_synchro_map.insert(std::pair(gnss_synchro_deque_iter->Channel_ID, *gnss_synchro_deque_iter)); - } + for (unsigned int i = 0; i < d_nchannels; i++) + { + out[i][n_outputs] = current_gnss_synchro[i]; + } + + n_outputs++; } - else + + // Move RX time + T_rx_s = T_rx_s + T_rx_step_s; + // pop old elements from queue + for (unsigned int i = 0; i < d_nchannels; i++) { - //std::cout<<"ch["<(d_gnss_synchro_history_queue[i].front().Tracking_sample_counter) / static_cast(d_gnss_synchro_history_queue[i].front().fs) < (T_rx_s - past_history_s)) + { + d_gnss_synchro_history_queue[i].pop_front(); + } } - } } - } + } while(channel_history_ok == true && d_max_noutputs > n_outputs); - if(!realigned_gnss_synchro_map.empty()) - { - /* - * 2.1 Use CURRENT set of measurements and find the nearest satellite - * common RX time algorithm - */ - // what is the most recent symbol TOW in the current set? -> this will be the reference symbol - gnss_synchro_map_iter = max_element(realigned_gnss_synchro_map.begin(), - realigned_gnss_synchro_map.end(), - Hybrid_pairCompare_gnss_synchro_d_TOW); - double ref_fs_hz = (double)gnss_synchro_map_iter->second.fs; - - // compute interpolated TOW value at T_rx_s - int ref_channel_key = gnss_synchro_map_iter->second.Channel_ID; - Gnss_Synchro adj_obs = adjacent_gnss_synchro_map.at(ref_channel_key); - double ref_adj_T_rx_s = (double)adj_obs.Tracking_sample_counter / ref_fs_hz + adj_obs.Code_phase_samples / ref_fs_hz; - - double d_TOW_reference = gnss_synchro_map_iter->second.TOW_at_current_symbol_s; - double d_ref_T_rx_s = (double)gnss_synchro_map_iter->second.Tracking_sample_counter / ref_fs_hz + gnss_synchro_map_iter->second.Code_phase_samples / ref_fs_hz; - - double selected_T_rx_s = T_rx_s; - // two points linear interpolation using adjacent (adj) values: y=y1+(x-x1)*(y2-y1)/(x2-x1) - double ref_TOW_at_T_rx_s = adj_obs.TOW_at_current_symbol_s + (selected_T_rx_s - ref_adj_T_rx_s) - * (d_TOW_reference - adj_obs.TOW_at_current_symbol_s) / (d_ref_T_rx_s - ref_adj_T_rx_s); - - // Now compute RX time differences due to the PRN alignment in the correlators - double traveltime_ms; - double pseudorange_m; - double channel_T_rx_s; - double channel_fs_hz; - double channel_TOW_s; - for(gnss_synchro_map_iter = realigned_gnss_synchro_map.begin(); gnss_synchro_map_iter != realigned_gnss_synchro_map.end(); gnss_synchro_map_iter++) - { - channel_fs_hz = (double)gnss_synchro_map_iter->second.fs; - channel_TOW_s = gnss_synchro_map_iter->second.TOW_at_current_symbol_s; - channel_T_rx_s = (double)gnss_synchro_map_iter->second.Tracking_sample_counter / channel_fs_hz + gnss_synchro_map_iter->second.Code_phase_samples / channel_fs_hz; - // compute interpolated observation values - // two points linear interpolation using adjacent (adj) values: y=y1+(x-x1)*(y2-y1)/(x2-x1) - // TOW at the selected receiver time T_rx_s - int element_key = gnss_synchro_map_iter->second.Channel_ID; - adj_obs = adjacent_gnss_synchro_map.at(element_key); - - double adj_T_rx_s = (double)adj_obs.Tracking_sample_counter / channel_fs_hz + adj_obs.Code_phase_samples / channel_fs_hz; - - double channel_TOW_at_T_rx_s = adj_obs.TOW_at_current_symbol_s + (selected_T_rx_s - adj_T_rx_s) * (channel_TOW_s - adj_obs.TOW_at_current_symbol_s) / (channel_T_rx_s - adj_T_rx_s); - - //Doppler and Accumulated carrier phase - double Carrier_phase_lin_rads = adj_obs.Carrier_phase_rads + (selected_T_rx_s - adj_T_rx_s) * (gnss_synchro_map_iter->second.Carrier_phase_rads - adj_obs.Carrier_phase_rads) / (channel_T_rx_s - adj_T_rx_s); - double Carrier_Doppler_lin_hz = adj_obs.Carrier_Doppler_hz + (selected_T_rx_s - adj_T_rx_s) * (gnss_synchro_map_iter->second.Carrier_Doppler_hz - adj_obs.Carrier_Doppler_hz) / (channel_T_rx_s - adj_T_rx_s); - - //compute the pseudorange (no rx time offset correction) - traveltime_ms = (ref_TOW_at_T_rx_s - channel_TOW_at_T_rx_s) * 1000.0 + GPS_STARTOFFSET_ms; - //convert to meters - pseudorange_m = traveltime_ms * GPS_C_m_ms; // [m] - // update the pseudorange object - current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID] = gnss_synchro_map_iter->second; - current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID].Pseudorange_m = pseudorange_m; - current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID].Flag_valid_pseudorange = true; - // Save the estimated RX time (no RX clock offset correction yet!) - current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID].RX_time = ref_TOW_at_T_rx_s + GPS_STARTOFFSET_ms / 1000.0; - - current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID].Carrier_phase_rads = Carrier_phase_lin_rads; - current_gnss_synchro[gnss_synchro_map_iter->second.Channel_ID].Carrier_Doppler_hz = Carrier_Doppler_lin_hz; - } - - if(d_dump == true) - { - // MULTIPLEXED FILE RECORDING - Record results to file - try - { - double tmp_double; - for (unsigned int i = 0; i < d_nchannels; i++) - { - tmp_double = current_gnss_synchro[i].RX_time; - d_dump_file.write((char*)&tmp_double, sizeof(double)); - tmp_double = current_gnss_synchro[i].TOW_at_current_symbol_s; - d_dump_file.write((char*)&tmp_double, sizeof(double)); - tmp_double = current_gnss_synchro[i].Carrier_Doppler_hz; - d_dump_file.write((char*)&tmp_double, sizeof(double)); - tmp_double = current_gnss_synchro[i].Carrier_phase_rads/GPS_TWO_PI; - d_dump_file.write((char*)&tmp_double, sizeof(double)); - tmp_double = current_gnss_synchro[i].Pseudorange_m; - d_dump_file.write((char*)&tmp_double, sizeof(double)); - tmp_double = current_gnss_synchro[i].PRN; - d_dump_file.write((char*)&tmp_double, sizeof(double)); - tmp_double = current_gnss_synchro[i].Flag_valid_pseudorange; - d_dump_file.write((char*)&tmp_double, sizeof(double)); - } - } - catch (const std::ifstream::failure& e) - { - LOG(WARNING) << "Exception writing observables dump file " << e.what(); - } - } - - for (unsigned int i = 0; i < d_nchannels; i++) - { - out[i][n_outputs] = current_gnss_synchro[i]; - } - - n_outputs++; - } - - //Move RX time - T_rx_s = T_rx_s + T_rx_step_s; - //pop old elements from queue - for (unsigned int i = 0; i < d_nchannels; i++) - { - while (d_gnss_synchro_history_queue[i].front().Tracking_sample_counter / (double)d_gnss_synchro_history_queue[i].front().fs < (T_rx_s - past_history_s)) - { - d_gnss_synchro_history_queue[i].pop_front(); - } - } + // Multi-rate consume! + for (unsigned int i = 0; i < d_nchannels; i++) + { + consume(i, n_consume[i]); // which input, how many items } - }while(channel_history_ok == true && d_max_noutputs>n_outputs); - //Multi-rate consume! - for (unsigned int i = 0; i < d_nchannels; i++) - { - consume(i, n_consume[i]); //which input, how many items - } - - return n_outputs; + return n_outputs; } diff --git a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.h b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.h index a647b24de..202a8582e 100644 --- a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.h +++ b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.h @@ -52,26 +52,26 @@ hybrid_make_observables_cc(unsigned int n_channels, bool dump, std::string dump_ class hybrid_observables_cc : public gr::block { public: - ~hybrid_observables_cc (); - int general_work (int noutput_items, gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); + ~hybrid_observables_cc (); + int general_work (int noutput_items, gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); private: - friend hybrid_observables_cc_sptr - hybrid_make_observables_cc(unsigned int nchannels, bool dump, std::string dump_filename, unsigned int deep_history); - hybrid_observables_cc(unsigned int nchannels, bool dump, std::string dump_filename, unsigned int deep_history); + friend hybrid_observables_cc_sptr + hybrid_make_observables_cc(unsigned int nchannels, bool dump, std::string dump_filename, unsigned int deep_history); + hybrid_observables_cc(unsigned int nchannels, bool dump, std::string dump_filename, unsigned int deep_history); - //Tracking observable history - std::vector> d_gnss_synchro_history_queue; + //Tracking observable history + std::vector> d_gnss_synchro_history_queue; - double T_rx_s; - double T_rx_step_s; - int d_max_noutputs; - bool d_dump; - unsigned int d_nchannels; - unsigned int history_deep; - std::string d_dump_filename; - std::ofstream d_dump_file; + double T_rx_s; + double T_rx_step_s; + int d_max_noutputs; + bool d_dump; + unsigned int d_nchannels; + unsigned int history_deep; + std::string d_dump_filename; + std::ofstream d_dump_file; }; #endif diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_cc.cc index e9189e213..7ccb0c825 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_cc.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_cc.cc @@ -237,7 +237,7 @@ int gps_l1_ca_telemetry_decoder_cc::general_work (int noutput_items __attribute_ if (d_stat == 1) { preamble_diff_ms = round(((static_cast(d_symbol_history.at(0).Tracking_sample_counter) - static_cast(d_preamble_time_samples)) / static_cast(d_symbol_history.at(0).fs)) * 1000.0); - if (preamble_diff_ms > GPS_SUBFRAME_MS+1) + if (preamble_diff_ms > GPS_SUBFRAME_MS + 1) { DLOG(INFO) << "Lost of frame sync SAT " << this->d_satellite << " preamble_diff= " << preamble_diff_ms; d_stat = 0; //lost of frame sync @@ -344,16 +344,16 @@ int gps_l1_ca_telemetry_decoder_cc::general_work (int noutput_items __attribute_ } //2. Add the telemetry decoder information - if (this->d_flag_preamble == true and d_flag_new_tow_available==true) + if (this->d_flag_preamble == true and d_flag_new_tow_available == true) { //double decoder_latency_ms=(double)(current_symbol.Tracking_sample_counter-d_symbol_history.at(0).Tracking_sample_counter) // /(double)current_symbol.fs; // update TOW at the preamble instant (account with decoder latency) - d_TOW_at_Preamble = d_GPS_FSM.d_nav.d_TOW + 2*GPS_L1_CA_CODE_PERIOD + GPS_CA_PREAMBLE_DURATION_S; + d_TOW_at_Preamble = d_GPS_FSM.d_nav.d_TOW + 2 * GPS_L1_CA_CODE_PERIOD + GPS_CA_PREAMBLE_DURATION_S; - d_TOW_at_current_symbol = floor(d_TOW_at_Preamble*1000.0)/1000.0; + d_TOW_at_current_symbol = floor(d_TOW_at_Preamble * 1000.0) / 1000.0; flag_TOW_set = true; - d_flag_new_tow_available=false; + d_flag_new_tow_available = false; } else { From 732597860f20334653ff1ab699958ad0ff71a599 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Mon, 16 Oct 2017 11:39:22 +0200 Subject: [PATCH 30/81] Fix building --- .../input_filter/gnuradio_blocks/CMakeLists.txt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/algorithms/input_filter/gnuradio_blocks/CMakeLists.txt b/src/algorithms/input_filter/gnuradio_blocks/CMakeLists.txt index 0d169b019..caac50136 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/input_filter/gnuradio_blocks/CMakeLists.txt @@ -17,7 +17,7 @@ # -set(INPUT_FILTER_GR_BLOCKS_SOURCES +set(INPUT_FILTER_GR_BLOCKS_SOURCES beamformer.cc pulse_blanking_cc.cc notch_cc.cc @@ -29,6 +29,8 @@ include_directories( ${GNURADIO_RUNTIME_INCLUDE_DIRS} ${GNURADIO_BLOCKS_INCLUDE_DIRS} ${VOLK_GNSSSDR_INCLUDE_DIRS} + ${GLOG_INCLUDE_DIRS} + ${GFlags_INCLUDE_DIRS} ) file(GLOB INPUT_FILTER_GR_BLOCKS_HEADERS "*.h") @@ -39,5 +41,7 @@ source_group(Headers FILES ${INPUT_FILTER_GR_BLOCKS_HEADERS}) target_link_libraries(input_filter_gr_blocks ${GNURADIO_FILTER_LIBRARIES} ${VOLK_GNSSSDR_LIBRARIES} ${LOG4CPP_LIBRARIES}) if(NOT VOLK_GNSSSDR_FOUND) - add_dependencies(input_filter_gr_blocks volk_gnsssdr_module) + add_dependencies(input_filter_gr_blocks volk_gnsssdr_module glog-${glog_RELEASE}) +else(NOT VOLK_GNSSSDR_FOUND) + add_dependencies(input_filter_gr_blocks glog-${glog_RELEASE}) endif(NOT VOLK_GNSSSDR_FOUND) From d8481d927b1429cdde32d7c6be2df9e09650cb10 Mon Sep 17 00:00:00 2001 From: Unknown Date: Mon, 16 Oct 2017 16:36:51 +0200 Subject: [PATCH 31/81] Added Pulse Blanking unit tests New unit tests for the pulse blanking input filter --- .../gnuradio_blocks/pulse_blanking_cc.cc | 9 +- .../gnuradio_blocks/pulse_blanking_cc.h | 2 + src/tests/CMakeLists.txt | 1 + src/tests/test_main.cc | 1 + .../filter/pulse_blanking_filter_test.cc | 168 ++++++++++++++++++ 5 files changed, 180 insertions(+), 1 deletion(-) create mode 100644 src/tests/unit-tests/signal-processing-blocks/filter/pulse_blanking_filter_test.cc diff --git a/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc index 7924f17ba..c619bd2a7 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc @@ -52,7 +52,6 @@ pulse_blanking_cc::pulse_blanking_cc(float pfa, int length_, int n_segments_est, set_alignment(std::max(1, alignment_multiple)); this->pfa = pfa; this->length_ = length_; - set_output_multiple(length_); last_filtered = false; n_segments = 0; this->n_segments_est = n_segments_est; @@ -73,6 +72,14 @@ pulse_blanking_cc::~pulse_blanking_cc() volk_free(zeros_); } +void pulse_blanking_cc::forecast(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items_required) +{ + for(unsigned int aux=0; aux < ninput_items_required.size(); aux++) + { + ninput_items_required[aux] = length_; + } +} + int pulse_blanking_cc::general_work (int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { diff --git a/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.h b/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.h index 7a19bf74e..b149bc72e 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.h +++ b/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.h @@ -65,6 +65,8 @@ public: int general_work (int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); + void forecast(int noutput_items, gr_vector_int &ninput_items_required); + }; #endif diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 4403d3616..87256a1f0 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -563,6 +563,7 @@ if(NOT ${ENABLE_PACKAGING}) add_executable(gnss_block_test ${CMAKE_CURRENT_SOURCE_DIR}/single_test_main.cc ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/sources/file_signal_source_test.cc ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/filter/fir_filter_test.cc + ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/filter/pulse_blanking_filter_test.cc ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/adapter/pass_through_test.cc ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/adapter/adapter_test.cc ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/control-plane/gnss_block_factory_test.cc diff --git a/src/tests/test_main.cc b/src/tests/test_main.cc index 36662fb67..55233102e 100644 --- a/src/tests/test_main.cc +++ b/src/tests/test_main.cc @@ -86,6 +86,7 @@ DECLARE_string(log_dir); #include "unit-tests/signal-processing-blocks/adapter/adapter_test.cc" #include "unit-tests/signal-processing-blocks/filter/fir_filter_test.cc" +#include "unit-tests/signal-processing-blocks/filter/pulse_blanking_filter_test.cc" #include "unit-tests/signal-processing-blocks/resampler/direct_resampler_conditioner_cc_test.cc" diff --git a/src/tests/unit-tests/signal-processing-blocks/filter/pulse_blanking_filter_test.cc b/src/tests/unit-tests/signal-processing-blocks/filter/pulse_blanking_filter_test.cc new file mode 100644 index 000000000..f157bf3a6 --- /dev/null +++ b/src/tests/unit-tests/signal-processing-blocks/filter/pulse_blanking_filter_test.cc @@ -0,0 +1,168 @@ +/*! + * \file pulse_blanking_filter_test.cc + * \brief Implements Unit Test for the PulseBlankingFilter class. + * \author Antonio Ramos, 2017. antonio.ramos(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "gnss_block_factory.h" +#include "gnss_block_interface.h" +#include "in_memory_configuration.h" +#include "gnss_sdr_valve.h" +#include "pulse_blanking_filter.h" +#include "file_signal_source.h" + + +DEFINE_int32(pb_filter_test_nsamples, 1000000 , "Number of samples to filter in the tests (max: 2147483647)"); + +class PulseBlankingFilterTest: public ::testing::Test +{ +protected: + PulseBlankingFilterTest() + { + queue = gr::msg_queue::make(0); + item_size = sizeof(gr_complex); + config = std::make_shared(); + nsamples = FLAGS_pb_filter_test_nsamples; + } + ~PulseBlankingFilterTest() + {} + + void init(); + void configure_gr_complex_gr_complex(); + boost::shared_ptr queue; + gr::top_block_sptr top_block; + std::shared_ptr config; + size_t item_size; + int nsamples; +}; + + +void PulseBlankingFilterTest::init() +{ + config->set_property("InputFilter.pfa", "0.04"); + config->set_property("InputFilter.length", "32"); + config->set_property("InputFilter.segments_est", "12500"); + config->set_property("InputFilter.segments_reset", "5000000"); +} + +void PulseBlankingFilterTest::configure_gr_complex_gr_complex() +{ + config->set_property("InputFilter.input_item_type", "gr_complex"); + config->set_property("InputFilter.output_item_type", "gr_complex"); +} + +TEST_F(PulseBlankingFilterTest, InstantiateGrComplexGrComplex) +{ + init(); + configure_gr_complex_gr_complex(); + std::unique_ptr filter(new PulseBlankingFilter(config.get(), "InputFilter", 1, 1)); + int res = 0; + if (filter) res = 1; + ASSERT_EQ(1, res); +} + +TEST_F(PulseBlankingFilterTest, ConnectAndRun) +{ + int fs_in = 4000000; + std::chrono::time_point start, end; + std::chrono::duration elapsed_seconds(0); + top_block = gr::make_top_block("Pulse Blanking filter test"); + init(); + configure_gr_complex_gr_complex(); + std::shared_ptr filter = std::make_shared(config.get(), "InputFilter", 1, 1); + item_size = sizeof(gr_complex); + ASSERT_NO_THROW( { + filter->connect(top_block); + boost::shared_ptr source = gr::analog::sig_source_c::make(fs_in, gr::analog::GR_SIN_WAVE, 1000.0, 1.0, gr_complex(0.0)); + boost::shared_ptr valve = gnss_sdr_make_valve(sizeof(gr_complex), nsamples, queue); + boost::shared_ptr null_sink = gr::blocks::null_sink::make(item_size); + + top_block->connect(source, 0, valve, 0); + top_block->connect(valve, 0, filter->get_left_block(), 0); + top_block->connect(filter->get_right_block(), 0, null_sink, 0); + }) << "Failure connecting the top_block."<< std::endl; + + 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::endl; + std::cout << "Filtered " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; +} + + +TEST_F(PulseBlankingFilterTest, ConnectAndRunGrcomplex) +{ + std::chrono::time_point start, end; + std::chrono::duration elapsed_seconds(0); + top_block = gr::make_top_block("Pulse Blanking filter test"); + init(); + configure_gr_complex_gr_complex(); + std::shared_ptr filter = std::make_shared(config.get(), "InputFilter", 1, 1); + std::shared_ptr config2 = std::make_shared(); + + config2->set_property("Test_Source.samples", std::to_string(nsamples)); + config2->set_property("Test_Source.sampling_frequency", "4000000"); + std::string path = std::string(TEST_PATH); + std::string filename = path + "signal_samples/GPS_L1_CA_ID_1_Fs_4Msps_2ms.dat"; + config2->set_property("Test_Source.filename", filename); + config2->set_property("Test_Source.item_type", "gr_complex"); + config2->set_property("Test_Source.repeat", "true"); + + item_size = sizeof(gr_complex); + ASSERT_NO_THROW( { + filter->connect(top_block); + + boost::shared_ptr source(new FileSignalSource(config2.get(), "Test_Source", 1, 1, queue)); + source->connect(top_block); + + boost::shared_ptr null_sink = gr::blocks::null_sink::make(item_size); + + top_block->connect(source->get_right_block(), 0, filter->get_left_block(), 0); + top_block->connect(filter->get_right_block(), 0, null_sink, 0); + }) << "Failure connecting the top_block."<< std::endl; + + 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::endl; + std::cout << "Filtered " << nsamples << " gr_complex samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; +} From 8ef49734db353c1cec01697fa8ba1a00a7c0547d Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Mon, 16 Oct 2017 20:17:32 +0200 Subject: [PATCH 32/81] Avoid writing in the input buffer This was uncovered when replacing C-style casts to C++-style casts. Apply project's indentation style --- .../input_filter/gnuradio_blocks/notch_cc.cc | 96 ++++++++------- .../gnuradio_blocks/notch_lite_cc.cc | 113 ++++++++++-------- .../gnuradio_blocks/pulse_blanking_cc.cc | 69 ++++++----- 3 files changed, 148 insertions(+), 130 deletions(-) diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc index 700ccfea8..10a4d3894 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc @@ -43,14 +43,15 @@ using google::LogMessage; notch_sptr make_notch_filter(float pfa, float p_c_factor, - int length_, int n_segments_est, int n_segments_reset) + int length_, int n_segments_est, int n_segments_reset) { return notch_sptr(new Notch(pfa, p_c_factor, length_, n_segments_est, n_segments_reset)); } + Notch::Notch(float pfa, float p_c_factor, int length_, int n_segments_est, int n_segments_reset) : gr::block("Notch", - gr::io_signature::make (1, 1, sizeof(gr_complex)), - gr::io_signature::make (1, 1, sizeof(gr_complex))) + gr::io_signature::make (1, 1, sizeof(gr_complex)), + gr::io_signature::make (1, 1, sizeof(gr_complex))) { const int alignment_multiple = volk_get_alignment() / sizeof(gr_complex); set_alignment(std::max(1, alignment_multiple)); @@ -74,6 +75,7 @@ Notch::Notch(float pfa, float p_c_factor, int length_, int n_segments_est, int n last_out = gr_complex(0,0); } + Notch::~Notch() { volk_free(c_samples); @@ -81,64 +83,70 @@ Notch::~Notch() volk_free(power_spect); } -int Notch::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), + +int Notch::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { int index_out = 0; float sig2dB = 0.0; float sig2lin = 0.0; lv_32fc_t dot_prod_; - gr_complex* in = (gr_complex *) input_items[0]; - gr_complex* out = (gr_complex *) output_items[0]; + const gr_complex* in = reinterpret_cast(input_items[0]); + gr_complex* out = reinterpret_cast(output_items[0]); + + gr_complex* in_aux = static_cast(volk_malloc(ninput_items[0] * sizeof(gr_complex), volk_get_alignment())); + memcpy(in_aux, in, ninput_items[0] * sizeof(gr_complex)); + in++; arma::cx_fvec signal_segment; arma::cx_fvec signal_segment_fft; while((index_out + length_) < noutput_items) - { - if((n_segments < n_segments_est) && (filter_state_ == false)) { - signal_segment = arma::cx_fvec(in, length_, false, false); - signal_segment_fft = arma::fft(signal_segment); - volk_32fc_s32f_power_spectrum_32f(power_spect, signal_segment_fft.memptr(), 1.0, length_); - volk_32f_s32f_calc_spectral_noise_floor_32f(&sig2dB, power_spect, 15.0, length_); - sig2lin = std::pow(10.0, (sig2dB / 10.0)) / ((float) n_deg_fred); - noise_pow_est = (((float) n_segments) * noise_pow_est + sig2lin) / ((float)(n_segments + 1)); - memcpy(out, in, sizeof(gr_complex) * length_); - } - else - { - volk_32fc_x2_conjugate_dot_prod_32fc(&dot_prod_, in, in, length_); - if( (lv_creal(dot_prod_) / noise_pow_est) > thres_) - { - if(filter_state_ == false) + if((n_segments < n_segments_est) && (filter_state_ == false)) { - filter_state_ = true; - last_out = gr_complex(0,0); + signal_segment = arma::cx_fvec(in_aux, length_, false, false); + signal_segment_fft = arma::fft(signal_segment); + volk_32fc_s32f_power_spectrum_32f(power_spect, signal_segment_fft.memptr(), 1.0, length_); + volk_32f_s32f_calc_spectral_noise_floor_32f(&sig2dB, power_spect, 15.0, length_); + sig2lin = std::pow(10.0, (sig2dB / 10.0)) / (static_cast(n_deg_fred) ); + noise_pow_est = (static_cast(n_segments) * noise_pow_est + sig2lin) / (static_cast(n_segments + 1)); + memcpy(out, in, sizeof(gr_complex) * length_); } - volk_32fc_x2_multiply_conjugate_32fc(c_samples, in, (in - 1), length_); - volk_32fc_s32f_atan2_32f(angle_, c_samples, ((float)1.0), length_); - for(int aux = 0; aux < length_; aux++) - { - z_0 = std::exp(gr_complex(0,1) * (*(angle_ + aux))); - *(out + aux) = *(in + aux) - z_0 * (*(in + aux - 1)) + p_c_factor * z_0 * last_out; - last_out = *(out + aux); - } - } else - { - if (n_segments > n_segments_reset) { - n_segments = 0; + volk_32fc_x2_conjugate_dot_prod_32fc(&dot_prod_, in, in, length_); + if( (lv_creal(dot_prod_) / noise_pow_est) > thres_) + { + if(filter_state_ == false) + { + filter_state_ = true; + last_out = gr_complex(0,0); + } + volk_32fc_x2_multiply_conjugate_32fc(c_samples, in, (in - 1), length_); + volk_32fc_s32f_atan2_32f(angle_, c_samples, static_cast(1.0), length_); + for(int aux = 0; aux < length_; aux++) + { + z_0 = std::exp(gr_complex(0,1) * (*(angle_ + aux))); + *(out + aux) = *(in + aux) - z_0 * (*(in + aux - 1)) + p_c_factor * z_0 * last_out; + last_out = *(out + aux); + } + } + else + { + if (n_segments > n_segments_reset) + { + n_segments = 0; + } + filter_state_ = false; + memcpy(out, in, sizeof(gr_complex) * length_); + } } - filter_state_ = false; - memcpy(out, in, sizeof(gr_complex) * length_); - } + index_out += length_; + n_segments++; + in += length_; + out += length_; } - index_out += length_; - n_segments++; - in += length_; - out += length_; - } + volk_free(in_aux); consume_each(index_out); return index_out; } diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc index a84ec6ae6..9628614a5 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc @@ -47,9 +47,10 @@ notch_lite_sptr make_notch_filter_lite(float p_c_factor, float pfa, int length_, return notch_lite_sptr(new NotchLite(p_c_factor, pfa, length_, n_segments_est, n_segments_reset, n_segments_coeff)); } + NotchLite::NotchLite(float p_c_factor, float pfa, int length_, int n_segments_est, int n_segments_reset, int n_segments_coeff) : gr::block("NotchLite", - gr::io_signature::make (1, 1, sizeof(gr_complex)), - gr::io_signature::make (1, 1, sizeof(gr_complex))) + gr::io_signature::make (1, 1, sizeof(gr_complex)), + gr::io_signature::make (1, 1, sizeof(gr_complex))) { const int alignment_multiple = volk_get_alignment() / sizeof(gr_complex); set_alignment(std::max(1, alignment_multiple)); @@ -75,82 +76,88 @@ NotchLite::NotchLite(float p_c_factor, float pfa, int length_, int n_segments_es angle1 = 0.0; angle2 = 0.0; power_spect = static_cast(volk_malloc(length_ * sizeof(float), volk_get_alignment())); - + } + NotchLite::~NotchLite() { volk_free(power_spect); } -int NotchLite::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), +int NotchLite::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { int index_out = 0; float sig2dB = 0.0; float sig2lin = 0.0; lv_32fc_t dot_prod_; - gr_complex* in = (gr_complex *) input_items[0]; - gr_complex* out = (gr_complex *) output_items[0]; + const gr_complex* in = reinterpret_cast(input_items[0]); + gr_complex* out = reinterpret_cast(output_items[0]); + + gr_complex* in_aux = static_cast(volk_malloc(ninput_items[0] * sizeof(gr_complex), volk_get_alignment())); + memcpy(in_aux, in, ninput_items[0] * sizeof(gr_complex)); + in++; arma::cx_fvec signal_segment; arma::cx_fvec signal_segment_fft; while((index_out + length_) < noutput_items) - { - if((n_segments < n_segments_est) && (filter_state_ == false)) { - signal_segment = arma::cx_fvec(in, length_, false, false); - signal_segment_fft = arma::fft(signal_segment); - volk_32fc_s32f_power_spectrum_32f(power_spect, signal_segment_fft.memptr(), 1.0, length_); - volk_32f_s32f_calc_spectral_noise_floor_32f(&sig2dB, power_spect, 15.0, length_); - sig2lin = std::pow(10.0, (sig2dB / 10.0)) / ((float) n_deg_fred); - noise_pow_est = (((float) n_segments) * noise_pow_est + sig2lin) / ((float)(n_segments + 1)); - memcpy(out, in, sizeof(gr_complex) * length_); - } - else - { - volk_32fc_x2_conjugate_dot_prod_32fc(&dot_prod_, in, in, length_); - if( (lv_creal(dot_prod_) / noise_pow_est) > thres_) - { - if(filter_state_ == false) + if((n_segments < n_segments_est) && (filter_state_ == false)) { - filter_state_ = true; - last_out = gr_complex(0,0); - n_segments_coeff = 0; + signal_segment = arma::cx_fvec(in_aux, length_, false, false); + signal_segment_fft = arma::fft(signal_segment); + volk_32fc_s32f_power_spectrum_32f(power_spect, signal_segment_fft.memptr(), 1.0, length_); + volk_32f_s32f_calc_spectral_noise_floor_32f(&sig2dB, power_spect, 15.0, length_); + sig2lin = std::pow(10.0, (sig2dB / 10.0)) / static_cast(n_deg_fred); + noise_pow_est = (static_cast(n_segments) * noise_pow_est + sig2lin) / static_cast(n_segments + 1); + memcpy(out, in, sizeof(gr_complex) * length_); } - if(n_segments_coeff == 0) - { - volk_32fc_x2_multiply_conjugate_32fc(&c_samples1, (in + 1), in, 1); - volk_32fc_s32f_atan2_32f(&angle1, &c_samples1, ((float)1.0), 1); - volk_32fc_x2_multiply_conjugate_32fc(&c_samples2, (in + length_ - 1), (in + length_ - 2), 1); - volk_32fc_s32f_atan2_32f(&angle2, &c_samples2, ((float)1.0), 1); - float angle_ = (angle1 + angle2) / 2.0; - z_0 = std::exp(gr_complex(0,1) * angle_); - } - for(int aux = 0; aux < length_; aux++) - { - *(out + aux) = *(in + aux) - z_0 * (*(in + aux - 1)) + p_c_factor * z_0 * last_out; - last_out = *(out + aux); - } - n_segments_coeff++; - n_segments_coeff = n_segments_coeff % n_segments_coeff_reset; - } else - { - if (n_segments > n_segments_reset) { - n_segments = 0; + volk_32fc_x2_conjugate_dot_prod_32fc(&dot_prod_, in, in, length_); + if( (lv_creal(dot_prod_) / noise_pow_est) > thres_) + { + if(filter_state_ == false) + { + filter_state_ = true; + last_out = gr_complex(0,0); + n_segments_coeff = 0; + } + if(n_segments_coeff == 0) + { + volk_32fc_x2_multiply_conjugate_32fc(&c_samples1, (in + 1), in, 1); + volk_32fc_s32f_atan2_32f(&angle1, &c_samples1, static_cast(1.0), 1); + volk_32fc_x2_multiply_conjugate_32fc(&c_samples2, (in + length_ - 1), (in + length_ - 2), 1); + volk_32fc_s32f_atan2_32f(&angle2, &c_samples2, static_cast(1.0), 1); + float angle_ = (angle1 + angle2) / 2.0; + z_0 = std::exp(gr_complex(0,1) * angle_); + } + for(int aux = 0; aux < length_; aux++) + { + *(out + aux) = *(in + aux) - z_0 * (*(in + aux - 1)) + p_c_factor * z_0 * last_out; + last_out = *(out + aux); + } + n_segments_coeff++; + n_segments_coeff = n_segments_coeff % n_segments_coeff_reset; + } + else + { + if (n_segments > n_segments_reset) + { + n_segments = 0; + } + filter_state_ = false; + memcpy(out, in, sizeof(gr_complex) * length_); + } } - filter_state_ = false; - memcpy(out, in, sizeof(gr_complex) * length_); - } + index_out += length_; + n_segments++; + in += length_; + out += length_; } - index_out += length_; - n_segments++; - in += length_; - out += length_; - } + volk_free(in_aux); consume_each(index_out); return index_out; } diff --git a/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc index 7924f17ba..311cc4d82 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc @@ -39,14 +39,15 @@ using google::LogMessage; pulse_blanking_cc_sptr make_pulse_blanking_cc(float pfa, int length_, - int n_segments_est, int n_segments_reset) + int n_segments_est, int n_segments_reset) { return pulse_blanking_cc_sptr(new pulse_blanking_cc(pfa, length_, n_segments_est, n_segments_reset)); } + pulse_blanking_cc::pulse_blanking_cc(float pfa, int length_, int n_segments_est, int n_segments_reset) : gr::block("pulse_blanking_cc", - gr::io_signature::make (1, 1, sizeof(gr_complex)), - gr::io_signature::make (1, 1, sizeof(gr_complex))) + gr::io_signature::make (1, 1, sizeof(gr_complex)), + gr::io_signature::make (1, 1, sizeof(gr_complex))) { const int alignment_multiple = volk_get_alignment() / sizeof(gr_complex); set_alignment(std::max(1, alignment_multiple)); @@ -63,55 +64,57 @@ pulse_blanking_cc::pulse_blanking_cc(float pfa, int length_, int n_segments_est, thres_ = boost::math::quantile(boost::math::complement(my_dist_, pfa)); zeros_ = static_cast(volk_malloc(length_ * sizeof(gr_complex), volk_get_alignment())); for (int aux = 0; aux < length_; aux++) - { - zeros_[aux] = gr_complex(0, 0); - } + { + zeros_[aux] = gr_complex(0, 0); + } } + pulse_blanking_cc::~pulse_blanking_cc() { volk_free(zeros_); } + int pulse_blanking_cc::general_work (int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { - gr_complex *in = (gr_complex *) input_items[0]; - gr_complex *out = (gr_complex *) output_items[0]; + const gr_complex* in = reinterpret_cast(input_items[0]); + gr_complex* out = reinterpret_cast(output_items[0]); float* magnitude = static_cast(volk_malloc(noutput_items * sizeof(float), volk_get_alignment())); volk_32fc_magnitude_squared_32f(magnitude, in, noutput_items); int sample_index = 0; float segment_energy; while((sample_index + length_) < noutput_items) - { - volk_32f_accumulator_s32f(&segment_energy, (magnitude + sample_index), length_); - if((n_segments < n_segments_est) && (last_filtered == false)) { - noise_power_estimation = (((float) n_segments) * noise_power_estimation + segment_energy / ((float)n_deg_fred)) / ((float)(n_segments + 1)); - memcpy(out, in, sizeof(gr_complex)*length_); - } - else - { - if((segment_energy/noise_power_estimation) > thres_) - { - memcpy(out, zeros_, sizeof(gr_complex)*length_); - last_filtered = true; - } - else - { - memcpy(out, in, sizeof(gr_complex)*length_); - last_filtered = false; - if (n_segments > n_segments_reset) + volk_32f_accumulator_s32f(&segment_energy, (magnitude + sample_index), length_); + if((n_segments < n_segments_est) && (last_filtered == false)) { - n_segments = 0; + noise_power_estimation = (((float) n_segments) * noise_power_estimation + segment_energy / ((float)n_deg_fred)) / ((float)(n_segments + 1)); + memcpy(out, in, sizeof(gr_complex)*length_); } - } + else + { + if((segment_energy/noise_power_estimation) > thres_) + { + memcpy(out, zeros_, sizeof(gr_complex)*length_); + last_filtered = true; + } + else + { + memcpy(out, in, sizeof(gr_complex)*length_); + last_filtered = false; + if (n_segments > n_segments_reset) + { + n_segments = 0; + } + } + } + in+=length_; + out+=length_; + sample_index+=length_; + n_segments++; } - in+=length_; - out+=length_; - sample_index+=length_; - n_segments++; - } volk_free(magnitude); consume_each(sample_index); return sample_index; From 66a585bfeb0df1b4c14fffb9e889252ac01f6540 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Mon, 16 Oct 2017 20:35:06 +0200 Subject: [PATCH 33/81] Replace C-style casts by C++-style casts --- .../gnuradio_blocks/pulse_blanking_cc.cc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc index 311cc4d82..8b75bbc38 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc @@ -59,7 +59,7 @@ pulse_blanking_cc::pulse_blanking_cc(float pfa, int length_, int n_segments_est, this->n_segments_est = n_segments_est; this->n_segments_reset = n_segments_reset; noise_power_estimation = 0.0; - n_deg_fred = 2*length_; + n_deg_fred = 2 * length_; boost::math::chi_squared_distribution my_dist_(n_deg_fred); thres_ = boost::math::quantile(boost::math::complement(my_dist_, pfa)); zeros_ = static_cast(volk_malloc(length_ * sizeof(gr_complex), volk_get_alignment())); @@ -90,19 +90,19 @@ int pulse_blanking_cc::general_work (int noutput_items __attribute__((unused)), volk_32f_accumulator_s32f(&segment_energy, (magnitude + sample_index), length_); if((n_segments < n_segments_est) && (last_filtered == false)) { - noise_power_estimation = (((float) n_segments) * noise_power_estimation + segment_energy / ((float)n_deg_fred)) / ((float)(n_segments + 1)); - memcpy(out, in, sizeof(gr_complex)*length_); + noise_power_estimation = ( static_cast(n_segments) * noise_power_estimation + segment_energy / static_cast(n_deg_fred) ) / static_cast(n_segments + 1); + memcpy(out, in, sizeof(gr_complex) * length_); } else { - if((segment_energy/noise_power_estimation) > thres_) + if((segment_energy / noise_power_estimation) > thres_) { - memcpy(out, zeros_, sizeof(gr_complex)*length_); + memcpy(out, zeros_, sizeof(gr_complex) * length_); last_filtered = true; } else { - memcpy(out, in, sizeof(gr_complex)*length_); + memcpy(out, in, sizeof(gr_complex) * length_); last_filtered = false; if (n_segments > n_segments_reset) { @@ -110,9 +110,9 @@ int pulse_blanking_cc::general_work (int noutput_items __attribute__((unused)), } } } - in+=length_; - out+=length_; - sample_index+=length_; + in += length_; + out += length_; + sample_index += length_; n_segments++; } volk_free(magnitude); From a1d432f9e845636e8bdbf966445784dc866fbefc Mon Sep 17 00:00:00 2001 From: Unknown Date: Tue, 17 Oct 2017 09:38:16 +0200 Subject: [PATCH 34/81] Added Notch Filter tests Unit test fot Notch input filter --- .../input_filter/gnuradio_blocks/notch_cc.cc | 9 +- .../input_filter/gnuradio_blocks/notch_cc.h | 2 + src/tests/CMakeLists.txt | 1 + src/tests/test_main.cc | 1 + .../filter/notch_filter_test.cc | 169 ++++++++++++++++++ 5 files changed, 181 insertions(+), 1 deletion(-) create mode 100644 src/tests/unit-tests/signal-processing-blocks/filter/notch_filter_test.cc diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc index 700ccfea8..2982b4aec 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc @@ -59,7 +59,6 @@ Notch::Notch(float pfa, float p_c_factor, int length_, int n_segments_est, int n noise_pow_est = 0.0; this->p_c_factor = gr_complex(p_c_factor , 0); this->length_ = length_; //Set the number of samples per segment - set_output_multiple(length_); filter_state_ = false; //Initial state of the filter n_deg_fred = 2 * length_; //Number of dregrees of freedom n_segments = 0; @@ -81,6 +80,14 @@ Notch::~Notch() volk_free(power_spect); } +void Notch::forecast(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items_required) +{ + for(unsigned int aux = 0; aux < ninput_items_required.size(); aux++) + { + ninput_items_required[aux] = length_; + } +} + int Notch::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h index 5be7dfda6..3c9f00987 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h @@ -71,6 +71,8 @@ public: ~Notch(); + void forecast(int noutput_items, gr_vector_int &ninput_items_required); + int general_work (int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 87256a1f0..7c05836c9 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -564,6 +564,7 @@ if(NOT ${ENABLE_PACKAGING}) ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/sources/file_signal_source_test.cc ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/filter/fir_filter_test.cc ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/filter/pulse_blanking_filter_test.cc + ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/filter/notch_filter_test.cc ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/adapter/pass_through_test.cc ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/adapter/adapter_test.cc ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/control-plane/gnss_block_factory_test.cc diff --git a/src/tests/test_main.cc b/src/tests/test_main.cc index 55233102e..9ecc2e99e 100644 --- a/src/tests/test_main.cc +++ b/src/tests/test_main.cc @@ -87,6 +87,7 @@ DECLARE_string(log_dir); #include "unit-tests/signal-processing-blocks/filter/fir_filter_test.cc" #include "unit-tests/signal-processing-blocks/filter/pulse_blanking_filter_test.cc" +#include "unit-tests/signal-processing-blocks/filter/notch_filter_test.cc" #include "unit-tests/signal-processing-blocks/resampler/direct_resampler_conditioner_cc_test.cc" diff --git a/src/tests/unit-tests/signal-processing-blocks/filter/notch_filter_test.cc b/src/tests/unit-tests/signal-processing-blocks/filter/notch_filter_test.cc new file mode 100644 index 000000000..f3997ecc2 --- /dev/null +++ b/src/tests/unit-tests/signal-processing-blocks/filter/notch_filter_test.cc @@ -0,0 +1,169 @@ +/*! + * \file notch_filter_test.cc + * \brief Implements Unit Test for the NotchFilter class. + * \author Antonio Ramos, 2017. antonio.ramos(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "gnss_block_factory.h" +#include "gnss_block_interface.h" +#include "in_memory_configuration.h" +#include "gnss_sdr_valve.h" +#include "notch_filter.h" +#include "file_signal_source.h" + + +DEFINE_int32(notch_filter_test_nsamples, 1000000 , "Number of samples to filter in the tests (max: 2147483647)"); + +class NotchFilterTest: public ::testing::Test +{ +protected: + NotchFilterTest() + { + queue = gr::msg_queue::make(0); + item_size = sizeof(gr_complex); + config = std::make_shared(); + nsamples = FLAGS_notch_filter_test_nsamples; + } + ~NotchFilterTest() + {} + + void init(); + void configure_gr_complex_gr_complex(); + boost::shared_ptr queue; + gr::top_block_sptr top_block; + std::shared_ptr config; + size_t item_size; + int nsamples; +}; + + +void NotchFilterTest::init() +{ + config->set_property("InputFilter.pfa", "0.01"); + config->set_property("InputFilter.p_c_factor", "0.9"); + config->set_property("InputFilter.length", "32"); + config->set_property("InputFilter.segments_est", "12500"); + config->set_property("InputFilter.segments_reset", "5000000"); +} + +void NotchFilterTest::configure_gr_complex_gr_complex() +{ + config->set_property("InputFilter.input_item_type", "gr_complex"); + config->set_property("InputFilter.output_item_type", "gr_complex"); +} + +TEST_F(NotchFilterTest, InstantiateGrComplexGrComplex) +{ + init(); + configure_gr_complex_gr_complex(); + std::unique_ptr filter(new NotchFilter(config.get(), "InputFilter", 1, 1)); + int res = 0; + if (filter) res = 1; + ASSERT_EQ(1, res); +} + +TEST_F(NotchFilterTest, ConnectAndRun) +{ + int fs_in = 4000000; + std::chrono::time_point start, end; + std::chrono::duration elapsed_seconds(0); + top_block = gr::make_top_block("Notch filter test"); + init(); + configure_gr_complex_gr_complex(); + std::shared_ptr filter = std::make_shared(config.get(), "InputFilter", 1, 1); + item_size = sizeof(gr_complex); + ASSERT_NO_THROW( { + filter->connect(top_block); + boost::shared_ptr source = gr::analog::sig_source_c::make(fs_in, gr::analog::GR_SIN_WAVE, 1000.0, 1.0, gr_complex(0.0)); + boost::shared_ptr valve = gnss_sdr_make_valve(sizeof(gr_complex), nsamples, queue); + boost::shared_ptr null_sink = gr::blocks::null_sink::make(item_size); + + top_block->connect(source, 0, valve, 0); + top_block->connect(valve, 0, filter->get_left_block(), 0); + top_block->connect(filter->get_right_block(), 0, null_sink, 0); + }) << "Failure connecting the top_block."<< std::endl; + + 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::endl; + std::cout << "Filtered " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; +} + + +TEST_F(NotchFilterTest, ConnectAndRunGrcomplex) +{ + std::chrono::time_point start, end; + std::chrono::duration elapsed_seconds(0); + top_block = gr::make_top_block("Notch filter test"); + init(); + configure_gr_complex_gr_complex(); + std::shared_ptr filter = std::make_shared(config.get(), "InputFilter", 1, 1); + std::shared_ptr config2 = std::make_shared(); + + config2->set_property("Test_Source.samples", std::to_string(nsamples)); + config2->set_property("Test_Source.sampling_frequency", "4000000"); + std::string path = std::string(TEST_PATH); + std::string filename = path + "signal_samples/GPS_L1_CA_ID_1_Fs_4Msps_2ms.dat"; + config2->set_property("Test_Source.filename", filename); + config2->set_property("Test_Source.item_type", "gr_complex"); + config2->set_property("Test_Source.repeat", "true"); + + item_size = sizeof(gr_complex); + ASSERT_NO_THROW( { + filter->connect(top_block); + + boost::shared_ptr source(new FileSignalSource(config2.get(), "Test_Source", 1, 1, queue)); + source->connect(top_block); + + boost::shared_ptr null_sink = gr::blocks::null_sink::make(item_size); + + top_block->connect(source->get_right_block(), 0, filter->get_left_block(), 0); + top_block->connect(filter->get_right_block(), 0, null_sink, 0); + }) << "Failure connecting the top_block."<< std::endl; + + 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::endl; + std::cout << "Filtered " << nsamples << " gr_complex samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; +} From 93cd6a17133e211693180eeb621287d815f95a28 Mon Sep 17 00:00:00 2001 From: Unknown Date: Tue, 17 Oct 2017 10:40:45 +0200 Subject: [PATCH 35/81] Avoiding copying input buffers Improving performances of Notch and Notch Lite input filters --- src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc | 8 ++------ .../input_filter/gnuradio_blocks/notch_lite_cc.cc | 8 ++------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc index 10a4d3894..80d60991d 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc @@ -84,7 +84,7 @@ Notch::~Notch() } -int Notch::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items, +int Notch::general_work(int noutput_items, gr_vector_int &ninput_items __attribute__((unused)), gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { int index_out = 0; @@ -94,9 +94,6 @@ int Notch::general_work(int noutput_items __attribute__((unused)), gr_vector_int const gr_complex* in = reinterpret_cast(input_items[0]); gr_complex* out = reinterpret_cast(output_items[0]); - gr_complex* in_aux = static_cast(volk_malloc(ninput_items[0] * sizeof(gr_complex), volk_get_alignment())); - memcpy(in_aux, in, ninput_items[0] * sizeof(gr_complex)); - in++; arma::cx_fvec signal_segment; arma::cx_fvec signal_segment_fft; @@ -104,7 +101,7 @@ int Notch::general_work(int noutput_items __attribute__((unused)), gr_vector_int { if((n_segments < n_segments_est) && (filter_state_ == false)) { - signal_segment = arma::cx_fvec(in_aux, length_, false, false); + signal_segment = arma::cx_fvec(in, length_); signal_segment_fft = arma::fft(signal_segment); volk_32fc_s32f_power_spectrum_32f(power_spect, signal_segment_fft.memptr(), 1.0, length_); volk_32f_s32f_calc_spectral_noise_floor_32f(&sig2dB, power_spect, 15.0, length_); @@ -146,7 +143,6 @@ int Notch::general_work(int noutput_items __attribute__((unused)), gr_vector_int in += length_; out += length_; } - volk_free(in_aux); consume_each(index_out); return index_out; } diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc index 9628614a5..591e3f2e2 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc @@ -86,7 +86,7 @@ NotchLite::~NotchLite() } -int NotchLite::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items, +int NotchLite::general_work(int noutput_items, gr_vector_int &ninput_items __attribute__((unused)), gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { int index_out = 0; @@ -96,9 +96,6 @@ int NotchLite::general_work(int noutput_items __attribute__((unused)), gr_vector const gr_complex* in = reinterpret_cast(input_items[0]); gr_complex* out = reinterpret_cast(output_items[0]); - gr_complex* in_aux = static_cast(volk_malloc(ninput_items[0] * sizeof(gr_complex), volk_get_alignment())); - memcpy(in_aux, in, ninput_items[0] * sizeof(gr_complex)); - in++; arma::cx_fvec signal_segment; arma::cx_fvec signal_segment_fft; @@ -106,7 +103,7 @@ int NotchLite::general_work(int noutput_items __attribute__((unused)), gr_vector { if((n_segments < n_segments_est) && (filter_state_ == false)) { - signal_segment = arma::cx_fvec(in_aux, length_, false, false); + signal_segment = arma::cx_fvec(in, length_); signal_segment_fft = arma::fft(signal_segment); volk_32fc_s32f_power_spectrum_32f(power_spect, signal_segment_fft.memptr(), 1.0, length_); volk_32f_s32f_calc_spectral_noise_floor_32f(&sig2dB, power_spect, 15.0, length_); @@ -157,7 +154,6 @@ int NotchLite::general_work(int noutput_items __attribute__((unused)), gr_vector in += length_; out += length_; } - volk_free(in_aux); consume_each(index_out); return index_out; } From 117329c1fc270abec5b2e35d15d32dd9a314b3cf Mon Sep 17 00:00:00 2001 From: Unknown Date: Tue, 17 Oct 2017 10:40:45 +0200 Subject: [PATCH 36/81] Avoiding copying input buffers Improving performances of Notch and Notch Lite input filters --- src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc | 8 ++------ .../input_filter/gnuradio_blocks/notch_lite_cc.cc | 8 ++------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc index 10a4d3894..80d60991d 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc @@ -84,7 +84,7 @@ Notch::~Notch() } -int Notch::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items, +int Notch::general_work(int noutput_items, gr_vector_int &ninput_items __attribute__((unused)), gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { int index_out = 0; @@ -94,9 +94,6 @@ int Notch::general_work(int noutput_items __attribute__((unused)), gr_vector_int const gr_complex* in = reinterpret_cast(input_items[0]); gr_complex* out = reinterpret_cast(output_items[0]); - gr_complex* in_aux = static_cast(volk_malloc(ninput_items[0] * sizeof(gr_complex), volk_get_alignment())); - memcpy(in_aux, in, ninput_items[0] * sizeof(gr_complex)); - in++; arma::cx_fvec signal_segment; arma::cx_fvec signal_segment_fft; @@ -104,7 +101,7 @@ int Notch::general_work(int noutput_items __attribute__((unused)), gr_vector_int { if((n_segments < n_segments_est) && (filter_state_ == false)) { - signal_segment = arma::cx_fvec(in_aux, length_, false, false); + signal_segment = arma::cx_fvec(in, length_); signal_segment_fft = arma::fft(signal_segment); volk_32fc_s32f_power_spectrum_32f(power_spect, signal_segment_fft.memptr(), 1.0, length_); volk_32f_s32f_calc_spectral_noise_floor_32f(&sig2dB, power_spect, 15.0, length_); @@ -146,7 +143,6 @@ int Notch::general_work(int noutput_items __attribute__((unused)), gr_vector_int in += length_; out += length_; } - volk_free(in_aux); consume_each(index_out); return index_out; } diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc index 9628614a5..591e3f2e2 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc @@ -86,7 +86,7 @@ NotchLite::~NotchLite() } -int NotchLite::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items, +int NotchLite::general_work(int noutput_items, gr_vector_int &ninput_items __attribute__((unused)), gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { int index_out = 0; @@ -96,9 +96,6 @@ int NotchLite::general_work(int noutput_items __attribute__((unused)), gr_vector const gr_complex* in = reinterpret_cast(input_items[0]); gr_complex* out = reinterpret_cast(output_items[0]); - gr_complex* in_aux = static_cast(volk_malloc(ninput_items[0] * sizeof(gr_complex), volk_get_alignment())); - memcpy(in_aux, in, ninput_items[0] * sizeof(gr_complex)); - in++; arma::cx_fvec signal_segment; arma::cx_fvec signal_segment_fft; @@ -106,7 +103,7 @@ int NotchLite::general_work(int noutput_items __attribute__((unused)), gr_vector { if((n_segments < n_segments_est) && (filter_state_ == false)) { - signal_segment = arma::cx_fvec(in_aux, length_, false, false); + signal_segment = arma::cx_fvec(in, length_); signal_segment_fft = arma::fft(signal_segment); volk_32fc_s32f_power_spectrum_32f(power_spect, signal_segment_fft.memptr(), 1.0, length_); volk_32f_s32f_calc_spectral_noise_floor_32f(&sig2dB, power_spect, 15.0, length_); @@ -157,7 +154,6 @@ int NotchLite::general_work(int noutput_items __attribute__((unused)), gr_vector in += length_; out += length_; } - volk_free(in_aux); consume_each(index_out); return index_out; } From 9a74120e7ceee9a9143d484512321ed05d8b3b41 Mon Sep 17 00:00:00 2001 From: Unknown Date: Tue, 17 Oct 2017 11:44:23 +0200 Subject: [PATCH 37/81] Added Notch Filter Lite tests Unit tests for Notch Lite input filter --- .../input_filter/gnuradio_blocks/notch_cc.cc | 6 +- .../gnuradio_blocks/notch_lite_cc.cc | 7 + .../gnuradio_blocks/notch_lite_cc.h | 2 + .../gnuradio_blocks/pulse_blanking_cc.cc | 8 +- src/tests/CMakeLists.txt | 1 + src/tests/test_main.cc | 1 + .../filter/notch_filter_lite_test.cc | 169 ++++++++++++++++++ 7 files changed, 187 insertions(+), 7 deletions(-) create mode 100644 src/tests/unit-tests/signal-processing-blocks/filter/notch_filter_lite_test.cc diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc index 720583c35..3aeb161b1 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc @@ -85,9 +85,9 @@ Notch::~Notch() void Notch::forecast(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items_required) { for(unsigned int aux = 0; aux < ninput_items_required.size(); aux++) - { - ninput_items_required[aux] = length_; - } + { + ninput_items_required[aux] = length_; + } } int Notch::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc index 591e3f2e2..3df58c7a7 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc @@ -85,6 +85,13 @@ NotchLite::~NotchLite() volk_free(power_spect); } +void NotchLite::forecast(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items_required) +{ + for(unsigned int aux = 0; aux < ninput_items_required.size(); aux++) + { + ninput_items_required[aux] = length_; + } +} int NotchLite::general_work(int noutput_items, gr_vector_int &ninput_items __attribute__((unused)), gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.h b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.h index 2151a459f..a5ef994f0 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.h +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.h @@ -74,6 +74,8 @@ public: ~NotchLite(); + void forecast(int noutput_items, gr_vector_int &ninput_items_required); + int general_work (int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); diff --git a/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc index 5d5ef8830..c0a6249b0 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc @@ -77,12 +77,12 @@ pulse_blanking_cc::~pulse_blanking_cc() void pulse_blanking_cc::forecast(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items_required) { for(unsigned int aux=0; aux < ninput_items_required.size(); aux++) - { - ninput_items_required[aux] = length_; - } + { + ninput_items_required[aux] = length_; + } } -int pulse_blanking_cc::general_work (int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), +int pulse_blanking_cc::general_work (int noutput_items, gr_vector_int &ninput_items __attribute__((unused)), gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { const gr_complex* in = reinterpret_cast(input_items[0]); diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 7c05836c9..f37753413 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -565,6 +565,7 @@ if(NOT ${ENABLE_PACKAGING}) ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/filter/fir_filter_test.cc ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/filter/pulse_blanking_filter_test.cc ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/filter/notch_filter_test.cc + ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/filter/notch_filter_lite_test.cc ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/adapter/pass_through_test.cc ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/adapter/adapter_test.cc ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/control-plane/gnss_block_factory_test.cc diff --git a/src/tests/test_main.cc b/src/tests/test_main.cc index 9ecc2e99e..f13ee945d 100644 --- a/src/tests/test_main.cc +++ b/src/tests/test_main.cc @@ -88,6 +88,7 @@ DECLARE_string(log_dir); #include "unit-tests/signal-processing-blocks/filter/fir_filter_test.cc" #include "unit-tests/signal-processing-blocks/filter/pulse_blanking_filter_test.cc" #include "unit-tests/signal-processing-blocks/filter/notch_filter_test.cc" +#include "unit-tests/signal-processing-blocks/filter/notch_filter_lite_test.cc" #include "unit-tests/signal-processing-blocks/resampler/direct_resampler_conditioner_cc_test.cc" diff --git a/src/tests/unit-tests/signal-processing-blocks/filter/notch_filter_lite_test.cc b/src/tests/unit-tests/signal-processing-blocks/filter/notch_filter_lite_test.cc new file mode 100644 index 000000000..363ff89ce --- /dev/null +++ b/src/tests/unit-tests/signal-processing-blocks/filter/notch_filter_lite_test.cc @@ -0,0 +1,169 @@ +/*! + * \file notch_filter_lite_test.cc + * \brief Implements Unit Test for the NotchFilterLite class. + * \author Antonio Ramos, 2017. antonio.ramos(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "gnss_block_factory.h" +#include "gnss_block_interface.h" +#include "in_memory_configuration.h" +#include "gnss_sdr_valve.h" +#include "notch_filter_lite.h" +#include "file_signal_source.h" + + +DEFINE_int32(notch_filter_lite_test_nsamples, 1000000 , "Number of samples to filter in the tests (max: 2147483647)"); + +class NotchFilterLiteTest: public ::testing::Test +{ +protected: + NotchFilterLiteTest() + { + queue = gr::msg_queue::make(0); + item_size = sizeof(gr_complex); + config = std::make_shared(); + nsamples = FLAGS_notch_filter_lite_test_nsamples; + } + ~NotchFilterLiteTest() + {} + + void init(); + void configure_gr_complex_gr_complex(); + boost::shared_ptr queue; + gr::top_block_sptr top_block; + std::shared_ptr config; + size_t item_size; + int nsamples; +}; + + +void NotchFilterLiteTest::init() +{ + config->set_property("InputFilter.pfa", "0.01"); + config->set_property("InputFilter.p_c_factor", "0.9"); + config->set_property("InputFilter.length", "32"); + config->set_property("InputFilter.segments_est", "12500"); + config->set_property("InputFilter.segments_reset", "5000000"); +} + +void NotchFilterLiteTest::configure_gr_complex_gr_complex() +{ + config->set_property("InputFilter.input_item_type", "gr_complex"); + config->set_property("InputFilter.output_item_type", "gr_complex"); +} + +TEST_F(NotchFilterLiteTest, InstantiateGrComplexGrComplex) +{ + init(); + configure_gr_complex_gr_complex(); + std::unique_ptr filter(new NotchFilterLite(config.get(), "InputFilter", 1, 1)); + int res = 0; + if (filter) res = 1; + ASSERT_EQ(1, res); +} + +TEST_F(NotchFilterLiteTest, ConnectAndRun) +{ + int fs_in = 4000000; + std::chrono::time_point start, end; + std::chrono::duration elapsed_seconds(0); + top_block = gr::make_top_block("Notch filter lite test"); + init(); + configure_gr_complex_gr_complex(); + std::shared_ptr filter = std::make_shared(config.get(), "InputFilter", 1, 1); + item_size = sizeof(gr_complex); + ASSERT_NO_THROW( { + filter->connect(top_block); + boost::shared_ptr source = gr::analog::sig_source_c::make(fs_in, gr::analog::GR_SIN_WAVE, 1000.0, 1.0, gr_complex(0.0)); + boost::shared_ptr valve = gnss_sdr_make_valve(sizeof(gr_complex), nsamples, queue); + boost::shared_ptr null_sink = gr::blocks::null_sink::make(item_size); + + top_block->connect(source, 0, valve, 0); + top_block->connect(valve, 0, filter->get_left_block(), 0); + top_block->connect(filter->get_right_block(), 0, null_sink, 0); + }) << "Failure connecting the top_block."<< std::endl; + + 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::endl; + std::cout << "Filtered " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; +} + + +TEST_F(NotchFilterLiteTest, ConnectAndRunGrcomplex) +{ + std::chrono::time_point start, end; + std::chrono::duration elapsed_seconds(0); + top_block = gr::make_top_block("Notch filter lite test"); + init(); + configure_gr_complex_gr_complex(); + std::shared_ptr filter = std::make_shared(config.get(), "InputFilter", 1, 1); + std::shared_ptr config2 = std::make_shared(); + + config2->set_property("Test_Source.samples", std::to_string(nsamples)); + config2->set_property("Test_Source.sampling_frequency", "4000000"); + std::string path = std::string(TEST_PATH); + std::string filename = path + "signal_samples/GPS_L1_CA_ID_1_Fs_4Msps_2ms.dat"; + config2->set_property("Test_Source.filename", filename); + config2->set_property("Test_Source.item_type", "gr_complex"); + config2->set_property("Test_Source.repeat", "true"); + + item_size = sizeof(gr_complex); + ASSERT_NO_THROW( { + filter->connect(top_block); + + boost::shared_ptr source(new FileSignalSource(config2.get(), "Test_Source", 1, 1, queue)); + source->connect(top_block); + + boost::shared_ptr null_sink = gr::blocks::null_sink::make(item_size); + + top_block->connect(source->get_right_block(), 0, filter->get_left_block(), 0); + top_block->connect(filter->get_right_block(), 0, null_sink, 0); + }) << "Failure connecting the top_block."<< std::endl; + + 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::endl; + std::cout << "Filtered " << nsamples << " gr_complex samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; +} From 2c739a26bfceaefbfa9b401435ffcbbac45eb49f Mon Sep 17 00:00:00 2001 From: Unknown Date: Tue, 17 Oct 2017 14:17:11 +0200 Subject: [PATCH 38/81] Added Armadillo VS GNU Radio FFT speed test Unit test comparing the two FFT implementations --- src/tests/test_main.cc | 1 + .../unit-tests/arithmetic/fft_speed_test.cc | 84 +++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 src/tests/unit-tests/arithmetic/fft_speed_test.cc diff --git a/src/tests/test_main.cc b/src/tests/test_main.cc index f13ee945d..b84fa312a 100644 --- a/src/tests/test_main.cc +++ b/src/tests/test_main.cc @@ -69,6 +69,7 @@ DECLARE_string(log_dir); #include "unit-tests/arithmetic/multiply_test.cc" #include "unit-tests/arithmetic/code_generation_test.cc" #include "unit-tests/arithmetic/fft_length_test.cc" +#include "unit-tests/arithmetic/fft_speed_test.cc" #include "unit-tests/control-plane/file_configuration_test.cc" #include "unit-tests/control-plane/in_memory_configuration_test.cc" diff --git a/src/tests/unit-tests/arithmetic/fft_speed_test.cc b/src/tests/unit-tests/arithmetic/fft_speed_test.cc new file mode 100644 index 000000000..f3e53152a --- /dev/null +++ b/src/tests/unit-tests/arithmetic/fft_speed_test.cc @@ -0,0 +1,84 @@ +/*! + * \file fft_speed_test.cc + * \brief This file implements timing tests for the Armadillo + * and GNU Radio FFT implementations + * \author Antonio Ramos, 2017. antonio.ramos(at)cttc.es + * + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include +#include +#include +#include + + +DEFINE_int32(fft_speed_iterations_test, 1000, "Number of averaged iterations in FFT length timing test"); + +TEST(FFTSpeedTest, ArmadilloVSGNURadioExecutionTime) +{ + unsigned int d_fft_size; + std::chrono::time_point start, end; + std::chrono::duration elapsed_seconds; + + unsigned int fft_sizes [13] = { 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536 }; + double d_execution_time; + EXPECT_NO_THROW( + for(int i = 0; i < 13; i++) + { + d_fft_size = fft_sizes[i]; + + gr::fft::fft_complex* d_gr_fft; + d_gr_fft = new gr::fft::fft_complex(d_fft_size, true); + + arma::cx_vec d_arma_fft(d_fft_size); + d_arma_fft = arma::cx_vec(d_fft_size).randn() + gr_complex(0.0, 1.0) * arma::cx_vec(d_fft_size).randn(); + + memcpy(d_gr_fft->get_inbuf(), d_arma_fft.memptr(), sizeof(gr_complex) * d_fft_size); + + start = std::chrono::system_clock::now(); + for(int k = 0; k < FLAGS_fft_speed_iterations_test; k++) + { + d_gr_fft->execute(); + } + end = std::chrono::system_clock::now(); + elapsed_seconds = end - start; + d_execution_time = elapsed_seconds.count() / static_cast(FLAGS_fft_speed_iterations_test); + std::cout << "GNU Radio FFT execution time for length = " << d_fft_size << " : " << d_execution_time << " [s]" << std::endl; + delete d_gr_fft; + + start = std::chrono::system_clock::now(); + for(int k = 0; k < FLAGS_fft_speed_iterations_test; k++) + { + arma::fft(d_arma_fft); + } + end = std::chrono::system_clock::now(); + elapsed_seconds = end - start; + d_execution_time = elapsed_seconds.count() / static_cast(FLAGS_fft_speed_iterations_test); + std::cout << "Armadillo FFT execution time for length = " << d_fft_size << " : " << d_execution_time << " [s]" << std::endl; + } + ); +} From 511675a97ed010af1fad54217b31d40f2d5ec171 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 18 Oct 2017 09:08:13 +0200 Subject: [PATCH 39/81] Apply project's coding style --- .../gnuradio_blocks/rtl_tcp_signal_source_c.h | 14 ++- .../signal_source/libs/rtl_tcp_commands.cc | 22 ++-- .../signal_source/libs/rtl_tcp_commands.h | 5 +- .../signal_source/libs/rtl_tcp_dongle_info.cc | 115 ++++++++++-------- .../signal_source/libs/rtl_tcp_dongle_info.h | 37 +++--- 5 files changed, 103 insertions(+), 90 deletions(-) diff --git a/src/algorithms/signal_source/gnuradio_blocks/rtl_tcp_signal_source_c.h b/src/algorithms/signal_source/gnuradio_blocks/rtl_tcp_signal_source_c.h index 7ce11eeb3..d73a40509 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/rtl_tcp_signal_source_c.h +++ b/src/algorithms/signal_source/gnuradio_blocks/rtl_tcp_signal_source_c.h @@ -36,7 +36,7 @@ */ #ifndef GNSS_SDR_RTL_TCP_SIGNAL_SOURCE_C_H -#define GNSS_SDR_RTL_TCP_SIGNAL_SOURCE_C_H +#define GNSS_SDR_RTL_TCP_SIGNAL_SOURCE_C_H #include "rtl_tcp_dongle_info.h" #include @@ -67,8 +67,8 @@ public: ~rtl_tcp_signal_source_c(); int work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); void set_frequency (int frequency); void set_sample_rate (int sample_rate); @@ -110,13 +110,15 @@ private: void handle_read (const boost::system::error_code &ec, size_t bytes_transferred); - inline bool not_full ( ) const { + inline bool not_full ( ) const + { return unread_ < buffer_.capacity( ); } - inline bool not_empty ( ) const { + inline bool not_empty ( ) const + { return unread_ > 0 || io_service_.stopped (); } }; -#endif //GNSS_SDR_RTL_TCP_SIGNAL_SOURCE_C_H +#endif // GNSS_SDR_RTL_TCP_SIGNAL_SOURCE_C_H diff --git a/src/algorithms/signal_source/libs/rtl_tcp_commands.cc b/src/algorithms/signal_source/libs/rtl_tcp_commands.cc index 7cf21eafd..35fe1fad7 100644 --- a/src/algorithms/signal_source/libs/rtl_tcp_commands.cc +++ b/src/algorithms/signal_source/libs/rtl_tcp_commands.cc @@ -29,25 +29,21 @@ * * ------------------------------------------------------------------------- */ + #include "rtl_tcp_commands.h" -#include +#include -using boost::asio::ip::tcp; - - -boost::system::error_code -rtl_tcp_command (RTL_TCP_COMMAND id, unsigned param, tcp::socket &socket) { +boost::system::error_code rtl_tcp_command (RTL_TCP_COMMAND id, unsigned param, boost::asio::ip::tcp::socket &socket) +{ // Data payload - unsigned char data[sizeof (unsigned char) + sizeof (unsigned)]; + unsigned char data[sizeof(unsigned char) + sizeof(unsigned)]; - data[0] = static_cast (id); + data[0] = static_cast(id); - - unsigned nparam = - boost::asio::detail::socket_ops::host_to_network_long (param); - ::memcpy (&data[1], &nparam, sizeof (nparam)); + unsigned nparam = boost::asio::detail::socket_ops::host_to_network_long(param); + std::memcpy(&data[1], &nparam, sizeof(nparam)); boost::system::error_code ec; - socket.send (boost::asio::buffer (data), 0, ec); + socket.send(boost::asio::buffer(data), 0, ec); return ec; } diff --git a/src/algorithms/signal_source/libs/rtl_tcp_commands.h b/src/algorithms/signal_source/libs/rtl_tcp_commands.h index 361dc10a4..b9ef78e3d 100644 --- a/src/algorithms/signal_source/libs/rtl_tcp_commands.h +++ b/src/algorithms/signal_source/libs/rtl_tcp_commands.h @@ -48,8 +48,7 @@ enum RTL_TCP_COMMAND { /*! * \brief Send a command to rtl_tcp over the given socket. */ -boost::system::error_code -rtl_tcp_command (RTL_TCP_COMMAND id, unsigned param, - boost::asio::ip::tcp::socket &socket); +boost::system::error_code rtl_tcp_command (RTL_TCP_COMMAND id, unsigned param, + boost::asio::ip::tcp::socket &socket); #endif // GNSS_SDR_RTL_TCP_COMMANDS_H diff --git a/src/algorithms/signal_source/libs/rtl_tcp_dongle_info.cc b/src/algorithms/signal_source/libs/rtl_tcp_dongle_info.cc index e7e7b15ef..ad736a0cc 100644 --- a/src/algorithms/signal_source/libs/rtl_tcp_dongle_info.cc +++ b/src/algorithms/signal_source/libs/rtl_tcp_dongle_info.cc @@ -30,45 +30,47 @@ * * ------------------------------------------------------------------------- */ + #include "rtl_tcp_dongle_info.h" -#include +#include #include using boost::asio::ip::tcp; -rtl_tcp_dongle_info::rtl_tcp_dongle_info () - : tuner_type_ (0), tuner_gain_count_ (0) +rtl_tcp_dongle_info::rtl_tcp_dongle_info() : tuner_type_(0), tuner_gain_count_(0) { - ::memset (magic_, 0, sizeof (magic_)); + std::memset(magic_, 0, sizeof(magic_)); } -boost::system::error_code rtl_tcp_dongle_info::read (tcp::socket &socket) { + +boost::system::error_code rtl_tcp_dongle_info::read(boost::asio::ip::tcp::socket &socket) +{ boost::system::error_code ec; - unsigned char data[sizeof (char) * 4 + sizeof (uint32_t) * 2]; - socket.receive (boost::asio::buffer (data), 0, ec); - if (!ec) { - ::memcpy (magic_, data, 4); + unsigned char data[sizeof(char) * 4 + sizeof(uint32_t) * 2]; + socket.receive(boost::asio::buffer(data), 0, ec); + if (!ec) + { + std::memcpy(magic_, data, 4); - uint32_t type; - ::memcpy (&type, &data[4], 4); + uint32_t type; + std::memcpy(&type, &data[4], 4); - tuner_type_ = - boost::asio::detail::socket_ops::network_to_host_long (type); + tuner_type_ = boost::asio::detail::socket_ops::network_to_host_long(type); + uint32_t count; + std ::memcpy(&count, &data[8], 4); - uint32_t count; - ::memcpy (&count, &data[8], 4); - - tuner_gain_count_ = - boost::asio::detail::socket_ops::network_to_host_long (count); - } + tuner_gain_count_ = boost::asio::detail::socket_ops::network_to_host_long(count); + } return ec; } -const char *rtl_tcp_dongle_info::get_type_name () const { - switch (get_tuner_type()) { +const char *rtl_tcp_dongle_info::get_type_name() const +{ + switch(get_tuner_type()) + { default: return "UNKNOWN"; case TUNER_E4000: @@ -86,29 +88,32 @@ const char *rtl_tcp_dongle_info::get_type_name () const { } } -double rtl_tcp_dongle_info::clip_gain (int gain) const { + +double rtl_tcp_dongle_info::clip_gain(int gain) const +{ // the following gain values have been copied from librtlsdr // all gain values are expressed in tenths of a dB std::vector gains; - switch (get_tuner_type()) { + switch (get_tuner_type()) + { case TUNER_E4000: gains = { -10, 15, 40, 65, 90, 115, 140, 165, 190, 215, - 240, 290, 340, 420 }; + 240, 290, 340, 420 }; break; case TUNER_FC0012: gains = { -99, -40, 71, 179, 192 }; break; case TUNER_FC0013: gains = { -99, -73, -65, -63, -60, -58, -54, 58, 61, - 63, 65, 67, 68, 70, 71, 179, 181, 182, - 184, 186, 188, 191, 197 }; + 63, 65, 67, 68, 70, 71, 179, 181, 182, + 184, 186, 188, 191, 197 }; break; case TUNER_R820T: gains = { 0, 9, 14, 27, 37, 77, 87, 125, 144, 157, - 166, 197, 207, 229, 254, 280, 297, 328, - 338, 364, 372, 386, 402, 421, 434, 439, - 445, 480, 496 }; + 166, 197, 207, 229, 254, 280, 297, 328, + 338, 364, 372, 386, 402, 421, 434, 439, + 445, 480, 496 }; break; default: // no gains @@ -116,29 +121,37 @@ double rtl_tcp_dongle_info::clip_gain (int gain) const { } // clip - if (gains.size() == 0) { - // no defined gains to clip to - return gain; - } - else { - double last_stop = gains.front (); - BOOST_FOREACH (double g, gains) { - g /= 10.0; - - if (gain < g) { - if (std::abs (gain - g) < std::abs (gain - last_stop)) { - return g; - } - else { - return last_stop; - } - } - last_stop = g; + if (gains.size() == 0) + { + // no defined gains to clip to + return gain; + } + else + { + double last_stop = gains.front(); + BOOST_FOREACH (double g, gains) + { + g /= 10.0; + + if (gain < g) + { + if (std::abs(gain - g) < std::abs(gain - last_stop)) + { + return g; + } + else + { + return last_stop; + } + } + last_stop = g; + } + return last_stop; } - return last_stop; - } } -bool rtl_tcp_dongle_info::is_valid () const { - return ::memcmp (magic_, "RTL0", 4) == 0; + +bool rtl_tcp_dongle_info::is_valid() const +{ + return std::memcmp(magic_, "RTL0", 4) == 0; } diff --git a/src/algorithms/signal_source/libs/rtl_tcp_dongle_info.h b/src/algorithms/signal_source/libs/rtl_tcp_dongle_info.h index 78e0ff646..18098f3b8 100644 --- a/src/algorithms/signal_source/libs/rtl_tcp_dongle_info.h +++ b/src/algorithms/signal_source/libs/rtl_tcp_dongle_info.h @@ -29,6 +29,7 @@ * * ------------------------------------------------------------------------- */ + #ifndef GNSS_SDR_RTL_TCP_DONGLE_INFO_H #define GNSS_SDR_RTL_TCP_DONGLE_INFO_H @@ -38,9 +39,16 @@ * \brief This class represents the dongle information * which is sent by rtl_tcp. */ -class rtl_tcp_dongle_info { - public: - enum { +class rtl_tcp_dongle_info +{ +private: + char magic_[4]; + uint32_t tuner_type_; + uint32_t tuner_gain_count_; + +public: + enum + { TUNER_UNKNOWN = 0, TUNER_E4000, TUNER_FC0012, @@ -50,28 +58,23 @@ class rtl_tcp_dongle_info { TUNER_R828D }; - private: - char magic_[4]; - uint32_t tuner_type_; - uint32_t tuner_gain_count_; + rtl_tcp_dongle_info(); - public: - rtl_tcp_dongle_info (); + boost::system::error_code read(boost::asio::ip::tcp::socket &socket); - boost::system::error_code read ( - boost::asio::ip::tcp::socket &socket); + bool is_valid() const; - bool is_valid () const; + const char *get_type_name() const; - const char *get_type_name () const; + double clip_gain(int gain) const; - double clip_gain (int gain) const; - - inline uint32_t get_tuner_type () const { + inline uint32_t get_tuner_type() const + { return tuner_type_; } - inline uint32_t get_tuner_gain_count () const { + inline uint32_t get_tuner_gain_count() const + { return tuner_gain_count_; } }; From d5590eefe4e5421343f06ec3ce4ed2d423f7b936 Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 18 Oct 2017 11:04:17 +0200 Subject: [PATCH 40/81] Added FFT speed test Unit test comparing GNU Radio and Armadillo FFT implementations --- .../unit-tests/arithmetic/fft_speed_test.cc | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/tests/unit-tests/arithmetic/fft_speed_test.cc b/src/tests/unit-tests/arithmetic/fft_speed_test.cc index f3e53152a..9ca28cc7c 100644 --- a/src/tests/unit-tests/arithmetic/fft_speed_test.cc +++ b/src/tests/unit-tests/arithmetic/fft_speed_test.cc @@ -35,7 +35,6 @@ #include #include - DEFINE_int32(fft_speed_iterations_test, 1000, "Number of averaged iterations in FFT length timing test"); TEST(FFTSpeedTest, ArmadilloVSGNURadioExecutionTime) @@ -44,19 +43,17 @@ TEST(FFTSpeedTest, ArmadilloVSGNURadioExecutionTime) std::chrono::time_point start, end; std::chrono::duration elapsed_seconds; - unsigned int fft_sizes [13] = { 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536 }; + unsigned int fft_sizes [19] = { 16, 25, 32, 45, 64, 95, 128, 195, 256, 325, 512, 785, 1024, 1503, 2048, 3127, 4096, 6349, 8192 }; double d_execution_time; EXPECT_NO_THROW( - for(int i = 0; i < 13; i++) + for(int i = 0; i < 19; i++) { d_fft_size = fft_sizes[i]; - gr::fft::fft_complex* d_gr_fft; d_gr_fft = new gr::fft::fft_complex(d_fft_size, true); - - arma::cx_vec d_arma_fft(d_fft_size); - d_arma_fft = arma::cx_vec(d_fft_size).randn() + gr_complex(0.0, 1.0) * arma::cx_vec(d_fft_size).randn(); - + arma::arma_rng::set_seed_random(); + arma::cx_fvec d_arma_fft = arma::cx_fvec(d_fft_size).randn() + gr_complex(0.0, 1.0) * arma::cx_fvec(d_fft_size).randn(); + arma::cx_fvec d_arma_fft_result(d_fft_size); memcpy(d_gr_fft->get_inbuf(), d_arma_fft.memptr(), sizeof(gr_complex) * d_fft_size); start = std::chrono::system_clock::now(); @@ -67,18 +64,18 @@ TEST(FFTSpeedTest, ArmadilloVSGNURadioExecutionTime) end = std::chrono::system_clock::now(); elapsed_seconds = end - start; d_execution_time = elapsed_seconds.count() / static_cast(FLAGS_fft_speed_iterations_test); - std::cout << "GNU Radio FFT execution time for length = " << d_fft_size << " : " << d_execution_time << " [s]" << std::endl; + std::cout << "GNU Radio FFT execution time for length = " << d_fft_size << " : " << d_execution_time * 1e6 << " [us]" << std::endl; delete d_gr_fft; - + start = std::chrono::system_clock::now(); for(int k = 0; k < FLAGS_fft_speed_iterations_test; k++) { - arma::fft(d_arma_fft); - } + d_arma_fft_result = arma::fft(d_arma_fft); + } end = std::chrono::system_clock::now(); elapsed_seconds = end - start; d_execution_time = elapsed_seconds.count() / static_cast(FLAGS_fft_speed_iterations_test); - std::cout << "Armadillo FFT execution time for length = " << d_fft_size << " : " << d_execution_time << " [s]" << std::endl; + std::cout << "Armadillo FFT execution time for length = " << d_fft_size << " : " << d_execution_time * 1e6 << " [us]" << std::endl; } ); } From c114d389757e3313dd29cadf3d7011c051b37a0e Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 18 Oct 2017 12:30:42 +0200 Subject: [PATCH 41/81] Notch filters FFT improved FFT migrated from Armadillo to GNU Radio --- .../input_filter/gnuradio_blocks/notch_cc.cc | 11 ++++------- .../input_filter/gnuradio_blocks/notch_cc.h | 3 +++ .../input_filter/gnuradio_blocks/notch_lite_cc.cc | 14 ++++---------- .../input_filter/gnuradio_blocks/notch_lite_cc.h | 3 +++ src/tests/unit-tests/arithmetic/fft_speed_test.cc | 2 +- 5 files changed, 15 insertions(+), 18 deletions(-) diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc index 781254773..6a5ecc81a 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc @@ -38,7 +38,6 @@ #include #include #include -#include using google::LogMessage; @@ -72,6 +71,7 @@ Notch::Notch(float pfa, float p_c_factor, int length_, int n_segments_est, int n angle_ = static_cast(volk_malloc(length_ * sizeof(float), volk_get_alignment())); power_spect = static_cast(volk_malloc(length_ * sizeof(float), volk_get_alignment())); last_out = gr_complex(0,0); + d_fft = std::unique_ptr(new gr::fft::fft_complex(length_, true)); } @@ -99,17 +99,14 @@ int Notch::general_work(int noutput_items, gr_vector_int &ninput_items __attribu lv_32fc_t dot_prod_; const gr_complex* in = reinterpret_cast(input_items[0]); gr_complex* out = reinterpret_cast(output_items[0]); - in++; - arma::cx_fvec signal_segment; - arma::cx_fvec signal_segment_fft; while((index_out + length_) < noutput_items) { if((n_segments < n_segments_est) && (filter_state_ == false)) { - signal_segment = arma::cx_fvec(in, length_); - signal_segment_fft = arma::fft(signal_segment); - volk_32fc_s32f_power_spectrum_32f(power_spect, signal_segment_fft.memptr(), 1.0, length_); + memcpy(d_fft->get_inbuf(), in, sizeof(gr_complex) * length_); + d_fft->execute(); + volk_32fc_s32f_power_spectrum_32f(power_spect, d_fft->get_outbuf(), 1.0, length_); volk_32f_s32f_calc_spectral_noise_floor_32f(&sig2dB, power_spect, 15.0, length_); sig2lin = std::pow(10.0, (sig2dB / 10.0)) / (static_cast(n_deg_fred) ); noise_pow_est = (static_cast(n_segments) * noise_pow_est + sig2lin) / (static_cast(n_segments + 1)); diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h index 3c9f00987..127acc9d1 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h @@ -33,6 +33,8 @@ #include #include +#include +#include class Notch; @@ -64,6 +66,7 @@ private: gr_complex* c_samples; float* angle_; float* power_spect; + std::unique_ptr d_fft; public: diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc index 3df58c7a7..de224cdcd 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc @@ -38,7 +38,6 @@ #include #include #include -#include using google::LogMessage; @@ -47,7 +46,6 @@ notch_lite_sptr make_notch_filter_lite(float p_c_factor, float pfa, int length_, return notch_lite_sptr(new NotchLite(p_c_factor, pfa, length_, n_segments_est, n_segments_reset, n_segments_coeff)); } - NotchLite::NotchLite(float p_c_factor, float pfa, int length_, int n_segments_est, int n_segments_reset, int n_segments_coeff) : gr::block("NotchLite", gr::io_signature::make (1, 1, sizeof(gr_complex)), gr::io_signature::make (1, 1, sizeof(gr_complex))) @@ -76,10 +74,9 @@ NotchLite::NotchLite(float p_c_factor, float pfa, int length_, int n_segments_es angle1 = 0.0; angle2 = 0.0; power_spect = static_cast(volk_malloc(length_ * sizeof(float), volk_get_alignment())); - + d_fft = std::unique_ptr(new gr::fft::fft_complex(length_, true)); } - NotchLite::~NotchLite() { volk_free(power_spect); @@ -102,17 +99,14 @@ int NotchLite::general_work(int noutput_items, gr_vector_int &ninput_items __att lv_32fc_t dot_prod_; const gr_complex* in = reinterpret_cast(input_items[0]); gr_complex* out = reinterpret_cast(output_items[0]); - in++; - arma::cx_fvec signal_segment; - arma::cx_fvec signal_segment_fft; while((index_out + length_) < noutput_items) { if((n_segments < n_segments_est) && (filter_state_ == false)) { - signal_segment = arma::cx_fvec(in, length_); - signal_segment_fft = arma::fft(signal_segment); - volk_32fc_s32f_power_spectrum_32f(power_spect, signal_segment_fft.memptr(), 1.0, length_); + memcpy(d_fft->get_inbuf(), in, sizeof(gr_complex) * length_); + d_fft->execute(); + volk_32fc_s32f_power_spectrum_32f(power_spect, d_fft->get_outbuf(), 1.0, length_); volk_32f_s32f_calc_spectral_noise_floor_32f(&sig2dB, power_spect, 15.0, length_); sig2lin = std::pow(10.0, (sig2dB / 10.0)) / static_cast(n_deg_fred); noise_pow_est = (static_cast(n_segments) * noise_pow_est + sig2lin) / static_cast(n_segments + 1); diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.h b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.h index a5ef994f0..cfe9df491 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.h +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.h @@ -33,6 +33,8 @@ #include #include +#include +#include class NotchLite; @@ -67,6 +69,7 @@ private: float angle1; float angle2; float* power_spect; + std::unique_ptr d_fft; public: diff --git a/src/tests/unit-tests/arithmetic/fft_speed_test.cc b/src/tests/unit-tests/arithmetic/fft_speed_test.cc index 9ca28cc7c..fa1fd2826 100644 --- a/src/tests/unit-tests/arithmetic/fft_speed_test.cc +++ b/src/tests/unit-tests/arithmetic/fft_speed_test.cc @@ -35,7 +35,7 @@ #include #include -DEFINE_int32(fft_speed_iterations_test, 1000, "Number of averaged iterations in FFT length timing test"); +DEFINE_int32(fft_speed_iterations_test, 100, "Number of averaged iterations in FFT length timing test"); TEST(FFTSpeedTest, ArmadilloVSGNURadioExecutionTime) { From 54a0070a330940337a38d945cc84548590dc056e Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Thu, 19 Oct 2017 19:26:08 +0200 Subject: [PATCH 42/81] Remove unrequired and repeated includes --- .../input_filter/adapters/notch_filter.cc | 11 +++++------ .../input_filter/adapters/notch_filter_lite.cc | 13 ++++++------- .../input_filter/adapters/pulse_blanking_filter.cc | 1 - 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/algorithms/input_filter/adapters/notch_filter.cc b/src/algorithms/input_filter/adapters/notch_filter.cc index 405f1f430..ed13c84d4 100644 --- a/src/algorithms/input_filter/adapters/notch_filter.cc +++ b/src/algorithms/input_filter/adapters/notch_filter.cc @@ -30,11 +30,7 @@ */ #include "notch_filter.h" -#include -#include -#include #include -#include #include #include "configuration_interface.h" #include "notch_cc.h" @@ -78,8 +74,7 @@ NotchFilter::NotchFilter(ConfigurationInterface* configuration, std::string role } else { - LOG(WARNING) << item_type_ - << " unrecognized item type for notch filter"; + LOG(WARNING) << item_type_ << " unrecognized item type for notch filter"; item_size_ = sizeof(gr_complex); } if (dump_) @@ -90,9 +85,11 @@ NotchFilter::NotchFilter(ConfigurationInterface* configuration, std::string role } } + NotchFilter::~NotchFilter() {} + void NotchFilter::connect(gr::top_block_sptr top_block) { if (dump_) @@ -106,6 +103,7 @@ void NotchFilter::connect(gr::top_block_sptr top_block) } } + void NotchFilter::disconnect(gr::top_block_sptr top_block) { if (dump_) @@ -120,6 +118,7 @@ gr::basic_block_sptr NotchFilter::get_left_block() return notch_filter_; } + gr::basic_block_sptr NotchFilter::get_right_block() { return notch_filter_; diff --git a/src/algorithms/input_filter/adapters/notch_filter_lite.cc b/src/algorithms/input_filter/adapters/notch_filter_lite.cc index a91aa39e6..4273c65fa 100644 --- a/src/algorithms/input_filter/adapters/notch_filter_lite.cc +++ b/src/algorithms/input_filter/adapters/notch_filter_lite.cc @@ -30,12 +30,8 @@ */ #include "notch_filter_lite.h" -#include #include -#include -#include #include -#include #include #include "configuration_interface.h" #include "notch_lite_cc.h" @@ -74,7 +70,7 @@ NotchFilterLite::NotchFilterLite(ConfigurationInterface* configuration, std::str length_ = configuration->property(role + ".length", default_length_); n_segments_est = configuration->property(role + ".segments_est", default_n_segments_est); n_segments_reset = configuration->property(role + ".segments_reset", default_n_segments_reset); - int n_segments_coeff = (int) ((samp_freq / coeff_rate) / ((float) length_)); + int n_segments_coeff = static_cast((samp_freq / coeff_rate) / static_cast(length_)); n_segments_coeff = std::max(1, n_segments_coeff); if (item_type_.compare("gr_complex") == 0) { @@ -85,8 +81,7 @@ NotchFilterLite::NotchFilterLite(ConfigurationInterface* configuration, std::str } else { - LOG(WARNING) << item_type_ - << " unrecognized item type for notch filter"; + LOG(WARNING) << item_type_ << " unrecognized item type for notch filter"; item_size_ = sizeof(gr_complex); } if (dump_) @@ -97,9 +92,11 @@ NotchFilterLite::NotchFilterLite(ConfigurationInterface* configuration, std::str } } + NotchFilterLite::~NotchFilterLite() {} + void NotchFilterLite::connect(gr::top_block_sptr top_block) { if (dump_) @@ -113,6 +110,7 @@ void NotchFilterLite::connect(gr::top_block_sptr top_block) } } + void NotchFilterLite::disconnect(gr::top_block_sptr top_block) { if (dump_) @@ -127,6 +125,7 @@ gr::basic_block_sptr NotchFilterLite::get_left_block() return notch_filter_lite_; } + gr::basic_block_sptr NotchFilterLite::get_right_block() { return notch_filter_lite_; diff --git a/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc b/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc index 72a98d576..e6bcc2632 100644 --- a/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc +++ b/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc @@ -30,7 +30,6 @@ #include "pulse_blanking_filter.h" #include -#include #include #include "configuration_interface.h" From 21fbe6124324dbac04d8fb18962c8c79685de578 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Thu, 19 Oct 2017 20:51:30 +0200 Subject: [PATCH 43/81] Remove more unrequired includes and reorder them --- .../input_filter/gnuradio_blocks/notch_cc.cc | 10 ++++------ .../input_filter/gnuradio_blocks/notch_lite_cc.cc | 11 +++++------ .../input_filter/gnuradio_blocks/pulse_blanking_cc.cc | 6 +++--- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc index 6a5ecc81a..03855f454 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc @@ -29,15 +29,13 @@ */ #include "notch_cc.h" -#include -#include -#include -#include #include +#include +#include +#include #include #include -#include -#include + using google::LogMessage; diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc index de224cdcd..178d0cb6b 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc @@ -29,15 +29,14 @@ */ #include "notch_lite_cc.h" -#include -#include -#include + #include +#include +#include +#include #include #include -#include -#include -#include + using google::LogMessage; diff --git a/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc index c0a6249b0..41bc815a9 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc @@ -29,12 +29,12 @@ */ #include "pulse_blanking_cc.h" -#include #include -#include +#include +#include #include #include -#include + using google::LogMessage; From 6f5f8e8948d0dcecf738e82e00556e12716d9895 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Thu, 19 Oct 2017 20:52:32 +0200 Subject: [PATCH 44/81] Catch exception --- src/core/receiver/control_thread.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/core/receiver/control_thread.cc b/src/core/receiver/control_thread.cc index 1a1517de5..44cdc36d3 100644 --- a/src/core/receiver/control_thread.cc +++ b/src/core/receiver/control_thread.cc @@ -422,7 +422,14 @@ void ControlThread::init() { // Instantiates a control queue, a GNSS flowgraph, and a control message factory control_queue_ = gr::msg_queue::make(0); - flowgraph_ = std::make_shared(configuration_, control_queue_); + try + { + flowgraph_ = std::make_shared(configuration_, control_queue_); + } + catch (const boost::bad_lexical_cast& e ) + { + std::cout << "Caught bad lexical cast with error " << e.what() << std::endl; + } control_message_factory_ = std::make_shared(); stop_ = false; processed_control_messages_ = 0; From a1b9b092f57185fef5681c0687efcf6f5cbce1b5 Mon Sep 17 00:00:00 2001 From: Damian Miralles Date: Thu, 19 Oct 2017 13:22:55 -0600 Subject: [PATCH 45/81] Debugging GLONASS code to obtain position solution --- CMakeLists.txt | 2 +- .../PVT/gnuradio_blocks/rtklib_pvt_cc.cc | 6 +- src/algorithms/PVT/libs/rtklib_solver.cc | 5 +- src/algorithms/PVT/libs/rtklib_solver.h | 2 +- .../libs/rtklib/rtklib_conversions.cc | 37 ++--- .../libs/rtklib/rtklib_conversions.h | 3 +- .../glonass_l1_ca_telemetry_decoder_cc.cc | 3 +- src/core/system_parameters/GLONASS_L1_CA.h | 2 - .../glonass_gnav_ephemeris.cc | 71 ++++++++- .../glonass_gnav_ephemeris.h | 11 ++ .../glonass_gnav_navigation_message.cc | 12 +- .../glonass_gnav_navigation_message.h | 4 + src/core/system_parameters/gnss_satellite.cc | 20 +++ src/core/system_parameters/gnss_satellite.h | 1 + .../glonass_gnav_nav_message_test.cc | 32 ++++ .../matlab/hybrid_observables_plot_sample.m | 146 +++++++++--------- 16 files changed, 242 insertions(+), 115 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 265e79ec5..b49ad4217 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -271,7 +271,7 @@ endif(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "") # Append -O2 optimization flag for Debug builds -set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O2") +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0") # allow 'large' files in 32 bit builds if(UNIX) diff --git a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc index 3e6758e58..b0c0c5666 100644 --- a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc +++ b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc @@ -190,8 +190,8 @@ void rtklib_pvt_cc::msg_handler_telemetry(pmt::pmt_t msg) // TODO Add GLONASS with gps week number and tow, // insert new ephemeris record DLOG(INFO) << "GLONASS GNAV New Ephemeris record inserted in global map with TOW =" << glonass_gnav_eph->d_TOW - << ", GLONASS GNAV Week Number =" << glonass_gnav_eph->d_WN - << " and Ephemeris IOD = " << glonass_gnav_eph->compute_GLONASS_time(glonass_gnav_eph->d_t_b) + << ", Week Number =" << glonass_gnav_eph->d_WN + << " and Ephemeris IOD in UTC = " << glonass_gnav_eph->compute_GLONASS_time(glonass_gnav_eph->d_t_b) << " from SV = " << glonass_gnav_eph->i_satellite_slot_number; // update/insert new ephemeris record to the global ephemeris map d_ls_pvt->glonass_gnav_ephemeris_map[glonass_gnav_eph->i_satellite_PRN] = *glonass_gnav_eph; @@ -542,7 +542,7 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite std::map::const_iterator tmp_eph_iter_gps = d_ls_pvt->gps_ephemeris_map.find(in[i][epoch].PRN); std::map::const_iterator tmp_eph_iter_gal = d_ls_pvt->galileo_ephemeris_map.find(in[i][epoch].PRN); std::map::const_iterator tmp_eph_iter_cnav = d_ls_pvt->gps_cnav_ephemeris_map.find(in[i][epoch].PRN); - std::map::const_iterator tmp_eph_iter_glo_gnav = d_ls_pvt->glonass_gnav_ephemeris_map.find(in[i][epoch].PRN); + std::map::const_iterator tmp_eph_iter_glo_gnav = d_ls_pvt->glonass_gnav_ephemeris_map.find(in[i][epoch].PRN); if(((tmp_eph_iter_gps->second.i_satellite_PRN == in[i][epoch].PRN) && (std::string(in[i][epoch].Signal).compare("1C") == 0)) || ((tmp_eph_iter_cnav->second.i_satellite_PRN == in[i][epoch].PRN) && (std::string(in[i][epoch].Signal).compare("2S") == 0)) || ((tmp_eph_iter_gal->second.i_satellite_PRN == in[i][epoch].PRN) && (std::string(in[i][epoch].Signal).compare("1B") == 0)) diff --git a/src/algorithms/PVT/libs/rtklib_solver.cc b/src/algorithms/PVT/libs/rtklib_solver.cc index de34231d7..06dcc618b 100644 --- a/src/algorithms/PVT/libs/rtklib_solver.cc +++ b/src/algorithms/PVT/libs/rtklib_solver.cc @@ -116,6 +116,7 @@ bool rtklib_solver::get_PVT(const std::map & gnss_observables_ std::map::const_iterator gps_ephemeris_iter; std::map::const_iterator gps_cnav_ephemeris_iter; std::map::const_iterator glonass_gnav_ephemeris_iter; + const Glonass_Gnav_Utc_Model gnav_utc = this->glonass_gnav_utc_model; this->set_averaging_flag(flag_averaging); @@ -290,7 +291,7 @@ bool rtklib_solver::get_PVT(const std::map & gnss_observables_ if (glonass_gnav_ephemeris_iter != glonass_gnav_ephemeris_map.cend()) { //convert ephemeris from GNSS-SDR class to RTKLIB structure - geph_data[glo_valid_obs] = eph_to_rtklib(glonass_gnav_ephemeris_iter->second); + geph_data[glo_valid_obs] = eph_to_rtklib(glonass_gnav_ephemeris_iter->second, gnav_utc); //convert observation from GNSS-SDR class to RTKLIB structure obsd_t newobs = {{0,0}, '0', '0', {}, {}, {}, {}, {}, {}}; obs_data[glo_valid_obs] = insert_obs_to_rtklib(newobs, @@ -329,7 +330,7 @@ bool rtklib_solver::get_PVT(const std::map & gnss_observables_ { //insert GLONASS GNAV L2 obs as new obs and also insert its ephemeris //convert ephemeris from GNSS-SDR class to RTKLIB structure - geph_data[glo_valid_obs] = eph_to_rtklib(glonass_gnav_ephemeris_iter->second); + geph_data[glo_valid_obs] = eph_to_rtklib(glonass_gnav_ephemeris_iter->second, gnav_utc); //convert observation from GNSS-SDR class to RTKLIB structure obsd_t newobs = {{0,0}, '0', '0', {}, {}, {}, {}, {}, {}}; obs_data[glo_valid_obs] = insert_obs_to_rtklib(newobs, diff --git a/src/algorithms/PVT/libs/rtklib_solver.h b/src/algorithms/PVT/libs/rtklib_solver.h index 40e0ab250..d8703548e 100644 --- a/src/algorithms/PVT/libs/rtklib_solver.h +++ b/src/algorithms/PVT/libs/rtklib_solver.h @@ -87,7 +87,7 @@ public: std::map galileo_ephemeris_map; //!< Map storing new Galileo_Ephemeris std::map gps_ephemeris_map; //!< Map storing new GPS_Ephemeris std::map gps_cnav_ephemeris_map; //!< Map storing new GPS_CNAV_Ephemeris - std::map glonass_gnav_ephemeris_map; //!< Map storing new GLONASS GNAV Ephmeris + std::map glonass_gnav_ephemeris_map; //!< Map storing new GLONASS GNAV Ephmeris Galileo_Utc_Model galileo_utc_model; Galileo_Iono galileo_iono; diff --git a/src/algorithms/libs/rtklib/rtklib_conversions.cc b/src/algorithms/libs/rtklib/rtklib_conversions.cc index 8b1c8c726..3257ab0bf 100644 --- a/src/algorithms/libs/rtklib/rtklib_conversions.cc +++ b/src/algorithms/libs/rtklib/rtklib_conversions.cc @@ -30,10 +30,11 @@ #include "rtklib_conversions.h" #include "rtklib_rtkcmn.h" +#include obsd_t insert_obs_to_rtklib(obsd_t & rtklib_obs, const Gnss_Synchro & gnss_synchro, int week, int band) { - rtklib_obs.D[band] = gnss_synchro.Carrier_Doppler_hz; + rtklib_obs.D[band] = gnss_synchro.Carrier_Doppler_hz; rtklib_obs.P[band] = gnss_synchro.Pseudorange_m; rtklib_obs.L[band] = gnss_synchro.Carrier_phase_rads / (2.0 * PI); @@ -64,13 +65,12 @@ obsd_t insert_obs_to_rtklib(obsd_t & rtklib_obs, const Gnss_Synchro & gnss_synch return rtklib_obs; } -geph_t eph_to_rtklib(const Glonass_Gnav_Ephemeris & glonass_gnav_eph) +geph_t eph_to_rtklib(const Glonass_Gnav_Ephemeris & glonass_gnav_eph, const Glonass_Gnav_Utc_Model & gnav_clock_model) { - int week; + double week, sec; + int adj_week; geph_t rtklib_sat = {0, 0, 0, 0, 0, 0, {0, 0}, {0, 0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, 0.0, 0.0, 0.0}; - gtime_t t_utc; - struct tm utcinfo; rtklib_sat.sat = glonass_gnav_eph.i_satellite_slot_number + NSATGPS; /* satellite number */ rtklib_sat.iode = static_cast(glonass_gnav_eph.d_t_b); /* IODE (0-6 bit of tb field) */ @@ -91,26 +91,15 @@ geph_t eph_to_rtklib(const Glonass_Gnav_Ephemeris & glonass_gnav_eph) rtklib_sat.gamn = glonass_gnav_eph.d_gamma_n; /* SV relative freq bias */ rtklib_sat.age = static_cast(glonass_gnav_eph.d_Delta_tau_n); /* delay between L1 and L2 (s) */ - utcinfo.tm_mon = 0; - utcinfo.tm_mday = glonass_gnav_eph.d_N_T; - utcinfo.tm_year = glonass_gnav_eph.d_yr - 1900; - utcinfo.tm_hour = -6; - utcinfo.tm_min = 0; - utcinfo.tm_sec = glonass_gnav_eph.d_tod; - t_utc.time = mktime(&utcinfo); - t_utc.sec = glonass_gnav_eph.d_tau_c; - rtklib_sat.toe = utc2gpst(t_utc); /* message frame time (gpst) */ - - utcinfo.tm_mon = 0; - utcinfo.tm_mday = glonass_gnav_eph.d_N_T; - utcinfo.tm_year = glonass_gnav_eph.d_yr - 1900; - utcinfo.tm_hour = -6; - utcinfo.tm_min = 0; - utcinfo.tm_sec = glonass_gnav_eph.d_t_k; - t_utc.time = mktime(&utcinfo); - t_utc.sec = glonass_gnav_eph.d_tau_c; - rtklib_sat.tof = utc2gpst(t_utc); /* message frame time (gpst) */ + // Time expressed in GPS Time but using RTKLib format + glonass_gnav_eph.glot_to_gpst(glonass_gnav_eph.d_tod, gnav_clock_model.d_tau_c, gnav_clock_model.d_tau_gps, &week, &sec); + adj_week = adjgpsweek(static_cast(week)); + rtklib_sat.toe = gpst2time(adj_week, sec); + // Time expressed in GPS Time but using RTKLib format + glonass_gnav_eph.glot_to_gpst(glonass_gnav_eph.d_t_k, gnav_clock_model.d_tau_c, gnav_clock_model.d_tau_gps, &week, &sec); + adj_week = adjgpsweek(static_cast(week)); + rtklib_sat.tof = gpst2time(adj_week, sec); return rtklib_sat; } diff --git a/src/algorithms/libs/rtklib/rtklib_conversions.h b/src/algorithms/libs/rtklib/rtklib_conversions.h index e620adaaa..e5a73e88d 100644 --- a/src/algorithms/libs/rtklib/rtklib_conversions.h +++ b/src/algorithms/libs/rtklib/rtklib_conversions.h @@ -37,6 +37,7 @@ #include "gps_ephemeris.h" #include "gps_cnav_ephemeris.h" #include "glonass_gnav_ephemeris.h" +#include "glonass_gnav_utc_model.h" eph_t eph_to_rtklib(const Galileo_Ephemeris & gal_eph); eph_t eph_to_rtklib(const Gps_Ephemeris & gps_eph); @@ -46,7 +47,7 @@ eph_t eph_to_rtklib(const Gps_CNAV_Ephemeris & gps_cnav_eph); * \param glonass_gnav_eph GLONASS GNAV Ephemeris structure * \return Ephemeris structure for RTKLIB parsing */ -geph_t eph_to_rtklib(const Glonass_Gnav_Ephemeris & glonass_gnav_eph); +geph_t eph_to_rtklib(const Glonass_Gnav_Ephemeris & glonass_gnav_eph, const Glonass_Gnav_Utc_Model & gnav_clock_model); obsd_t insert_obs_to_rtklib(obsd_t & rtklib_obs, const Gnss_Synchro & gnss_synchro, int week, int band); diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.cc index 5a61f5b5a..d04224ed5 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.cc @@ -221,7 +221,8 @@ void glonass_l1_ca_telemetry_decoder_cc::decode_string(double *frame_symbols,int if(d_nav.flag_update_slot_number == true) { LOG(INFO) << "GLONASS GNAV Slot Number Identified on channel " << d_channel; - d_satellite.what_block(d_satellite.get_system(), d_nav.get_ephemeris().d_n); + d_satellite.update_PRN(d_nav.gnav_ephemeris.d_n); + d_satellite.what_block(d_satellite.get_system(), d_nav.gnav_ephemeris.d_n); d_nav.flag_update_slot_number = false; } } diff --git a/src/core/system_parameters/GLONASS_L1_CA.h b/src/core/system_parameters/GLONASS_L1_CA.h index 83a768c93..8da14ffe2 100644 --- a/src/core/system_parameters/GLONASS_L1_CA.h +++ b/src/core/system_parameters/GLONASS_L1_CA.h @@ -91,8 +91,6 @@ const int GLONASS_L1_CA_NBR_SATS = 24; // STRING DATA WITHOUT PREAMB //FIXME Probably should use leap seconds definitions of rtklib const double GLONASS_LEAP_SECONDS[21][7] = { /* leap seconds (y,m,d,h,m,s,utc-gpst) */ - {2019, 1, 1, 0, 0, 0, -20}, - {2018, 1, 1, 0, 0, 0, -19}, {2017, 1, 1, 0, 0, 0, -18}, {2015, 7, 1, 0, 0, 0, -17}, {2012, 7, 1, 0, 0, 0, -16}, diff --git a/src/core/system_parameters/glonass_gnav_ephemeris.cc b/src/core/system_parameters/glonass_gnav_ephemeris.cc index b7b8e2d3a..b3e73e115 100644 --- a/src/core/system_parameters/glonass_gnav_ephemeris.cc +++ b/src/core/system_parameters/glonass_gnav_ephemeris.cc @@ -79,20 +79,87 @@ Glonass_Gnav_Ephemeris::Glonass_Gnav_Ephemeris() d_tau_c = 0.0; d_TOW = 0.0; // tow of the start of frame d_WN = 0.0; // week number of the start of frame + d_tod = 0.0; } boost::posix_time::ptime Glonass_Gnav_Ephemeris::compute_GLONASS_time(const double offset_time) const { - boost::posix_time::time_duration t(0, 0, offset_time + d_tau_c); + boost::posix_time::time_duration t(0, 0, offset_time + d_tau_c + d_tau_n); boost::gregorian::date d1(d_yr, 1, 1); - boost::gregorian::days d2(d_N_T); + boost::gregorian::days d2(d_N_T - 1); boost::posix_time::ptime glonass_time(d1+d2, t); return glonass_time; } +boost::posix_time::ptime Glonass_Gnav_Ephemeris::glot_to_utc(const double offset_time, const double glot2utc_corr) const +{ + double tod = 0.0; + double utcsu2utc = 3*3600; + double glot2utcsu = 3*3600; + + tod = offset_time - glot2utcsu - utcsu2utc + glot2utc_corr + d_tau_n; + boost::posix_time::time_duration t(0, 0, tod); + boost::gregorian::date d1(d_yr, 1, 1); + boost::gregorian::days d2(d_N_T - 1); + boost::posix_time::ptime utc_time(d1+d2, t); + + return utc_time; +} + +void Glonass_Gnav_Ephemeris::glot_to_gpst(double tod_offset, double glot2utc_corr, double glot2gpst_corr, double * wn, double * tow) const +{ + double tod = 0.0; + double dayofweek = 0.0; + double utcsu2utc = 3*3600; + double glot2utcsu = 3*3600; + double days = 0.0; + double total_sec = 0.0, sec_of_day = 0.0; + int i = 0; + + boost::gregorian::date gps_epoch { 1980, 1, 6 }; + + // tk is relative to UTC(SU) + 3.00 hrs, so we need to convert to utc and add corrections + // tk plus 10 sec is the true tod since get_TOW is called when in str5 + tod = tod_offset - glot2utcsu - utcsu2utc ; + + + boost::posix_time::time_duration t(0, 0, tod); + boost::gregorian::date d1(d_yr, 1, 1); + boost::gregorian::days d2(d_N_T - 1); + boost::posix_time::ptime glonass_time(d1+d2, t); + boost::gregorian::date utc_date = glonass_time.date(); + + // Total number of days + days = static_cast((utc_date - gps_epoch).days()); + + // Total number of seconds + sec_of_day = static_cast((glonass_time.time_of_day()).total_seconds()); + total_sec = days*86400 + sec_of_day; + + for (i = 0; GLONASS_LEAP_SECONDS[i][0]>0; i++) + { + if (GLONASS_LEAP_SECONDS[i][0] == d_yr) + { + // We add the leap second when going from utc to gpst + total_sec += abs(GLONASS_LEAP_SECONDS[i][6]); + } + } + + // Compute Week number + *wn = floor(total_sec/604800); + + // Compute day of week + dayofweek = modf (total_sec/604800 , wn); + dayofweek = round(7*dayofweek); + // Compute the arithmetic modules to wrap around range + *tow = total_sec - 604800*floor(total_sec/604800); + *tow = dayofweek*86400 + tod_offset + glot2utc_corr + glot2gpst_corr + d_tau_n; + +} + double Glonass_Gnav_Ephemeris::check_t(double time) { double corrTime; diff --git a/src/core/system_parameters/glonass_gnav_ephemeris.h b/src/core/system_parameters/glonass_gnav_ephemeris.h index 46ece9f95..929fa7262 100644 --- a/src/core/system_parameters/glonass_gnav_ephemeris.h +++ b/src/core/system_parameters/glonass_gnav_ephemeris.h @@ -159,6 +159,17 @@ public: */ boost::posix_time::ptime compute_GLONASS_time(const double offset_time) const; + /*! + * \brief Converts from GLONASST to UTC + * \ param [I] + * \ param offset_time Is the start of day offset to compute the time + * \ returns UTC time as a boost::posix_time::ptime object + */ + boost::posix_time::ptime glot_to_utc(const double offset_time, const double glot2utc_corr) const; + + + void glot_to_gpst(double tod_offset, double glot2utc_corr, double glot2gpst_corr, double * WN, double * TOW) const; + /*! * Default constructor */ diff --git a/src/core/system_parameters/glonass_gnav_navigation_message.cc b/src/core/system_parameters/glonass_gnav_navigation_message.cc index 7a9ea4ea8..403e8eb1e 100644 --- a/src/core/system_parameters/glonass_gnav_navigation_message.cc +++ b/src/core/system_parameters/glonass_gnav_navigation_message.cc @@ -43,6 +43,7 @@ void Glonass_Gnav_Navigation_Message::reset() { //!< Satellite Identification + i_satellite_PRN = 0; i_alm_satellite_slot_number = 0; //!< SV Orbit Slot Number flag_update_slot_number = false; @@ -325,7 +326,7 @@ double Glonass_Gnav_Navigation_Message::get_WN() boost::gregorian::date gps_epoch { 1980, 1, 6 }; // Map to UTC boost::gregorian::date glo_date(gnav_ephemeris.d_yr, 1, 1); - boost::gregorian::days d2(gnav_ephemeris.d_N_T); + boost::gregorian::days d2(gnav_ephemeris.d_N_T-1); glo_date = glo_date + d2; @@ -367,7 +368,7 @@ double Glonass_Gnav_Navigation_Message::get_TOW() boost::gregorian::date glo_date(gnav_ephemeris.d_yr, 1, 1); - boost::gregorian::days d2(gnav_ephemeris.d_N_T); + boost::gregorian::days d2(gnav_ephemeris.d_N_T-1); glo_date = glo_date + d2; dayofweek = static_cast(glo_date.day_of_week()); @@ -514,9 +515,10 @@ int Glonass_Gnav_Navigation_Message::string_decoder(std::string frame_string) // 3). Set TOW once the year has been defined, it helps with leap second determination if (flag_ephemeris_str_1 == true) { - d_TOW = get_TOW(); - gnav_ephemeris.d_TOW = d_TOW; - gnav_ephemeris.d_WN = get_WN(); + //d_TOW = get_TOW(); + gnav_ephemeris.glot_to_gpst(gnav_ephemeris.d_t_k+10, gnav_utc_model.d_tau_c, gnav_utc_model.d_tau_gps, &gnav_ephemeris.d_WN, &gnav_ephemeris.d_TOW); + d_TOW = gnav_ephemeris.d_TOW; + //gnav_ephemeris.d_WN = d_WN(); flag_TOW_set = true; flag_TOW_new = true; } diff --git a/src/core/system_parameters/glonass_gnav_navigation_message.h b/src/core/system_parameters/glonass_gnav_navigation_message.h index 743f4cefa..1b24eaf64 100644 --- a/src/core/system_parameters/glonass_gnav_navigation_message.h +++ b/src/core/system_parameters/glonass_gnav_navigation_message.h @@ -65,6 +65,10 @@ public: unsigned int d_string_ID; bool flag_update_slot_number; + // satellite identification info + int i_channel_ID; + unsigned int i_satellite_PRN; + Glonass_Gnav_Ephemeris gnav_ephemeris; //!< Ephemeris information decoded Glonass_Gnav_Utc_Model gnav_utc_model; //!< UTC model information Glonass_Gnav_Almanac gnav_almanac[GLONASS_L1_CA_NBR_SATS]; //!< Almanac information for all 24 satellites diff --git a/src/core/system_parameters/gnss_satellite.cc b/src/core/system_parameters/gnss_satellite.cc index 7fb9c38ec..ba7d35b73 100644 --- a/src/core/system_parameters/gnss_satellite.cc +++ b/src/core/system_parameters/gnss_satellite.cc @@ -135,6 +135,26 @@ void Gnss_Satellite::set_system(const std::string& system_) } +void Gnss_Satellite::update_PRN(unsigned int PRN_) +{ + if (system.compare("Glonass") != 0) + { + DLOG(INFO) << "Trying to update PRN for not GLONASS system"; + PRN = 0; + } + else + { + if (PRN_ < 1 or PRN_ > 24) + { + DLOG(INFO) << "This PRN is not defined"; + PRN = 0; + } + else + { + PRN = PRN_; + } + } +} void Gnss_Satellite::set_PRN(unsigned int PRN_) diff --git a/src/core/system_parameters/gnss_satellite.h b/src/core/system_parameters/gnss_satellite.h index cfdf1369f..1db5691c2 100644 --- a/src/core/system_parameters/gnss_satellite.h +++ b/src/core/system_parameters/gnss_satellite.h @@ -50,6 +50,7 @@ public: Gnss_Satellite(); //!< Default Constructor. Gnss_Satellite(const std::string& system_, unsigned int PRN_); //!< Concrete GNSS satellite Constructor. ~Gnss_Satellite(); //!< Default Destructor. + void update_PRN(unsigned int PRN); //!< Updates the PRN Number when information is decoded, only applies to GLONASS GNAV messages unsigned int get_PRN() const; //!< Gets satellite's PRN std::string get_system() const; //!< Gets the satellite system {"GPS", "GLONASS", "SBAS", "Galileo", "Beidou"} std::string get_system_short() const; //!< Gets the satellite system {"G", "R", "SBAS", "E", "C"} diff --git a/src/tests/unit-tests/system-parameters/glonass_gnav_nav_message_test.cc b/src/tests/unit-tests/system-parameters/glonass_gnav_nav_message_test.cc index 5fabb4676..f4ea3577d 100644 --- a/src/tests/unit-tests/system-parameters/glonass_gnav_nav_message_test.cc +++ b/src/tests/unit-tests/system-parameters/glonass_gnav_nav_message_test.cc @@ -80,6 +80,38 @@ TEST(GlonassGnavNavigationMessageTest, CRCTestFailure) ASSERT_FALSE(test_result); } +/*! + * \brief Testing string decoding for GLONASS GNAV messages + * \test The provided string (str1.....str15) was generated with a version of + * MATLAB GNSS-SDR that the author coded to perform proper decoding of GLONASS + * GNAV signals. The same assumption is to be applied for ephemeris and almanac + * data provided. + */ +TEST(GlonassGnavNavigationMessageTest, ComputeTOWandWN1) +{ + // Variable declarations + double tow, wn; + Glonass_Gnav_Navigation_Message gnav_nav_message; + Glonass_Gnav_Ephemeris gnav_ephemeris; + + // Fill out ephemeris values for truth + gnav_nav_message.gnav_ephemeris.d_t_k = 70200; + gnav_nav_message.gnav_ephemeris.d_tau_c = 9.6391886472702e-08; + gnav_nav_message.gnav_ephemeris.d_yr = 2005; + gnav_nav_message.gnav_ephemeris.d_N_T = 28; + + // Call target test method + tow = gnav_nav_message.get_TOW(); + wn = gnav_nav_message.get_WN(); + + // Perform assertions of decoded fields + ASSERT_TRUE(gnav_ephemeris.d_P_1 - gnav_nav_message.gnav_ephemeris.d_P_1 < FLT_EPSILON ); + ASSERT_TRUE(gnav_ephemeris.d_t_k - gnav_nav_message.gnav_ephemeris.d_t_k < FLT_EPSILON ); + ASSERT_TRUE(gnav_ephemeris.d_VXn - gnav_nav_message.gnav_ephemeris.d_VXn < FLT_EPSILON ); + ASSERT_TRUE(gnav_ephemeris.d_AXn - gnav_nav_message.gnav_ephemeris.d_AXn < FLT_EPSILON ); + ASSERT_TRUE(gnav_ephemeris.d_Xn - gnav_nav_message.gnav_ephemeris.d_Xn < FLT_EPSILON ); +} + /*! * \brief Testing string decoding for GLONASS GNAV messages * \test The provided string (str1.....str15) was generated with a version of diff --git a/src/utils/matlab/hybrid_observables_plot_sample.m b/src/utils/matlab/hybrid_observables_plot_sample.m index 538575bee..45b6bf31d 100644 --- a/src/utils/matlab/hybrid_observables_plot_sample.m +++ b/src/utils/matlab/hybrid_observables_plot_sample.m @@ -41,76 +41,76 @@ title('Doppler frequency') xlabel('TOW [s]') ylabel('[Hz]'); - -%read true obs from simulator (optional) -GPS_STARTOFFSET_s = 68.802e-3; - -true_observables_log_path='/home/javier/git/gnss-sdr/build/obs_out.bin'; -GNSS_true_observables= read_true_sim_observables_dump(true_observables_log_path); - -%correct the clock error using true values (it is not possible for a receiver to correct -%the receiver clock offset error at the observables level because it is required the -%decoding of the ephemeris data and solve the PVT equations) - -SPEED_OF_LIGHT_M_S = 299792458.0; - -%find the reference satellite -[~,ref_sat_ch]=min(GNSS_observables.Pseudorange_m(:,min_idx+1)); -shift_time_s=GNSS_true_observables.Pseudorange_m(ref_sat_ch,:)/SPEED_OF_LIGHT_M_S-GPS_STARTOFFSET_s; - - -%Compute deltas if required and interpolate to measurement time -delta_true_psudorange_m=GNSS_true_observables.Pseudorange_m(1,:)-GNSS_true_observables.Pseudorange_m(2,:); -delta_true_interp_psudorange_m=interp1(GNSS_true_observables.RX_time(1,:)-shift_time_s, ... - delta_true_psudorange_m,GNSS_observables.RX_time(1,min_idx+1:end),'lineal','extrap'); -true_interp_acc_carrier_phase_ch1_hz=interp1(GNSS_true_observables.RX_time(1,:)-shift_time_s, ... - GNSS_true_observables.Carrier_phase_hz(1,:),GNSS_observables.RX_time(1,min_idx+1:end),'lineal','extrap'); -true_interp_acc_carrier_phase_ch2_hz=interp1(GNSS_true_observables.RX_time(1,:)-shift_time_s, ... - GNSS_true_observables.Carrier_phase_hz(2,:),GNSS_observables.RX_time(2,min_idx+1:end),'lineal','extrap'); - -%Compute measurement errors - -delta_measured_psudorange_m=GNSS_observables.Pseudorange_m(1,min_idx+1:end)-GNSS_observables.Pseudorange_m(2,min_idx+1:end); -psudorange_error_m=delta_measured_psudorange_m-delta_true_interp_psudorange_m; -psudorange_rms_m=sqrt(sum(psudorange_error_m.^2)/length(psudorange_error_m)) - -acc_carrier_error_ch1_hz=GNSS_observables.Carrier_phase_hz(1,min_idx+1:end)-true_interp_acc_carrier_phase_ch1_hz... - -GNSS_observables.Carrier_phase_hz(1,min_idx+1)+true_interp_acc_carrier_phase_ch1_hz(1); - -acc_phase_rms_ch1_hz=sqrt(sum(acc_carrier_error_ch1_hz.^2)/length(acc_carrier_error_ch1_hz)) - -acc_carrier_error_ch2_hz=GNSS_observables.Carrier_phase_hz(2,min_idx+1:end)-true_interp_acc_carrier_phase_ch2_hz... - -GNSS_observables.Carrier_phase_hz(2,min_idx+1)+true_interp_acc_carrier_phase_ch2_hz(1); -acc_phase_rms_ch2_hz=sqrt(sum(acc_carrier_error_ch2_hz.^2)/length(acc_carrier_error_ch2_hz)) - - -%plot results -figure; -plot(GNSS_true_observables.RX_time(1,:),delta_true_psudorange_m,'g'); -hold on; -plot(GNSS_observables.RX_time(1,min_idx+1:end),delta_measured_psudorange_m,'b'); -title('TRUE vs. measured Pseudoranges [m]') -xlabel('TOW [s]') -ylabel('[m]'); - -figure; -plot(GNSS_observables.RX_time(1,min_idx+1:end),psudorange_error_m) -title('Pseudoranges error [m]') -xlabel('TOW [s]') -ylabel('[m]'); - -figure; -plot(GNSS_observables.RX_time(1,min_idx+1:end),acc_carrier_error_ch1_hz) -title('Accumulated carrier phase error CH1 [hz]') -xlabel('TOW [s]') -ylabel('[hz]'); - -figure; -plot(GNSS_observables.RX_time(1,min_idx+1:end),acc_carrier_error_ch2_hz) -title('Accumulated carrier phase error CH2 [hz]') -xlabel('TOW [s]') -ylabel('[hz]'); - - - - +% +% %read true obs from simulator (optional) +% GPS_STARTOFFSET_s = 68.802e-3; +% +% true_observables_log_path='/home/javier/git/gnss-sdr/build/obs_out.bin'; +% GNSS_true_observables= read_true_sim_observables_dump(true_observables_log_path); +% +% %correct the clock error using true values (it is not possible for a receiver to correct +% %the receiver clock offset error at the observables level because it is required the +% %decoding of the ephemeris data and solve the PVT equations) +% +% SPEED_OF_LIGHT_M_S = 299792458.0; +% +% %find the reference satellite +% [~,ref_sat_ch]=min(GNSS_observables.Pseudorange_m(:,min_idx+1)); +% shift_time_s=GNSS_true_observables.Pseudorange_m(ref_sat_ch,:)/SPEED_OF_LIGHT_M_S-GPS_STARTOFFSET_s; +% +% +% %Compute deltas if required and interpolate to measurement time +% delta_true_psudorange_m=GNSS_true_observables.Pseudorange_m(1,:)-GNSS_true_observables.Pseudorange_m(2,:); +% delta_true_interp_psudorange_m=interp1(GNSS_true_observables.RX_time(1,:)-shift_time_s, ... +% delta_true_psudorange_m,GNSS_observables.RX_time(1,min_idx+1:end),'lineal','extrap'); +% true_interp_acc_carrier_phase_ch1_hz=interp1(GNSS_true_observables.RX_time(1,:)-shift_time_s, ... +% GNSS_true_observables.Carrier_phase_hz(1,:),GNSS_observables.RX_time(1,min_idx+1:end),'lineal','extrap'); +% true_interp_acc_carrier_phase_ch2_hz=interp1(GNSS_true_observables.RX_time(1,:)-shift_time_s, ... +% GNSS_true_observables.Carrier_phase_hz(2,:),GNSS_observables.RX_time(2,min_idx+1:end),'lineal','extrap'); +% +% %Compute measurement errors +% +% delta_measured_psudorange_m=GNSS_observables.Pseudorange_m(1,min_idx+1:end)-GNSS_observables.Pseudorange_m(2,min_idx+1:end); +% psudorange_error_m=delta_measured_psudorange_m-delta_true_interp_psudorange_m; +% psudorange_rms_m=sqrt(sum(psudorange_error_m.^2)/length(psudorange_error_m)) +% +% acc_carrier_error_ch1_hz=GNSS_observables.Carrier_phase_hz(1,min_idx+1:end)-true_interp_acc_carrier_phase_ch1_hz... +% -GNSS_observables.Carrier_phase_hz(1,min_idx+1)+true_interp_acc_carrier_phase_ch1_hz(1); +% +% acc_phase_rms_ch1_hz=sqrt(sum(acc_carrier_error_ch1_hz.^2)/length(acc_carrier_error_ch1_hz)) +% +% acc_carrier_error_ch2_hz=GNSS_observables.Carrier_phase_hz(2,min_idx+1:end)-true_interp_acc_carrier_phase_ch2_hz... +% -GNSS_observables.Carrier_phase_hz(2,min_idx+1)+true_interp_acc_carrier_phase_ch2_hz(1); +% acc_phase_rms_ch2_hz=sqrt(sum(acc_carrier_error_ch2_hz.^2)/length(acc_carrier_error_ch2_hz)) +% +% +% %plot results +% figure; +% plot(GNSS_true_observables.RX_time(1,:),delta_true_psudorange_m,'g'); +% hold on; +% plot(GNSS_observables.RX_time(1,min_idx+1:end),delta_measured_psudorange_m,'b'); +% title('TRUE vs. measured Pseudoranges [m]') +% xlabel('TOW [s]') +% ylabel('[m]'); +% +% figure; +% plot(GNSS_observables.RX_time(1,min_idx+1:end),psudorange_error_m) +% title('Pseudoranges error [m]') +% xlabel('TOW [s]') +% ylabel('[m]'); +% +% figure; +% plot(GNSS_observables.RX_time(1,min_idx+1:end),acc_carrier_error_ch1_hz) +% title('Accumulated carrier phase error CH1 [hz]') +% xlabel('TOW [s]') +% ylabel('[hz]'); +% +% figure; +% plot(GNSS_observables.RX_time(1,min_idx+1:end),acc_carrier_error_ch2_hz) +% title('Accumulated carrier phase error CH2 [hz]') +% xlabel('TOW [s]') +% ylabel('[hz]'); +% +% +% +% From 1ac986e207cd55477174f575ae6c5bf110391b7c Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 20 Oct 2017 12:58:44 +0200 Subject: [PATCH 46/81] Test FFT with random numbers instead of all zeros --- .../unit-tests/arithmetic/fft_length_test.cc | 32 ++++++++++++++----- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/src/tests/unit-tests/arithmetic/fft_length_test.cc b/src/tests/unit-tests/arithmetic/fft_length_test.cc index c16dc2509..9fc0b5a8d 100644 --- a/src/tests/unit-tests/arithmetic/fft_length_test.cc +++ b/src/tests/unit-tests/arithmetic/fft_length_test.cc @@ -29,7 +29,10 @@ * ------------------------------------------------------------------------- */ +#include #include +#include +#include #include @@ -37,18 +40,31 @@ DEFINE_int32(fft_iterations_test, 1000, "Number of averaged iterations in FFT le TEST(FFTLengthTest, MeasureExecutionTime) { - unsigned int d_fft_size; + unsigned int fft_sizes [] = { 1000, 1024, 1960, 2000, 2048, 4000, 4096, 4725, 5000, 8000, 8192, 10368, 12000, 16000, 16384, 27000, 32768, 50000, 65536 }; + std::chrono::time_point start, end; - unsigned int fft_sizes [18] = { 1000, 1024, 1960, 2000, 2048, 4000, 4096, 4725, 8000, 8192, 10368, 12000, 16000, 16384, 27000, 32768, 50000, 65536 }; - double execution_times [18]; + std::random_device r; + std::default_random_engine e1(r()); + std::default_random_engine e2(r()); + std::uniform_real_distribution uniform_dist(-1, 1); + auto func = [] (float a, float b) { return gr_complex(a, b); }; // Helper lambda function that returns a gr_complex + auto random_number1 = std::bind(uniform_dist, e1); + auto random_number2 = std::bind(uniform_dist, e2); + auto gen = std::bind(func, random_number1, random_number2); // Function that returns a random gr_complex + + std::vector fft_sizes_v(fft_sizes, fft_sizes + sizeof(fft_sizes) / sizeof(unsigned int) ); + std::vector::const_iterator it; + unsigned int d_fft_size; + EXPECT_NO_THROW( - for(int i = 0; i < 18; i++) + for(it = fft_sizes_v.cbegin(); it != fft_sizes_v.cend(); ++it) { gr::fft::fft_complex* d_fft; - d_fft_size = fft_sizes[i]; + d_fft_size = *it; d_fft = new gr::fft::fft_complex(d_fft_size, true); - std::fill_n( d_fft->get_inbuf(), d_fft_size, gr_complex( 0.0, 0.0 ) ); + + std::generate_n( d_fft->get_inbuf(), d_fft_size, gen ); start = std::chrono::system_clock::now(); for(int k = 0; k < FLAGS_fft_iterations_test; k++) @@ -57,8 +73,8 @@ TEST(FFTLengthTest, MeasureExecutionTime) } end = std::chrono::system_clock::now(); std::chrono::duration elapsed_seconds = end - start; - execution_times[i] = elapsed_seconds.count() / static_cast(FLAGS_fft_iterations_test); - std::cout << "FFT execution time for length=" << d_fft_size << " : " << execution_times[i] << " [s]" << std::endl; + double execution_time = elapsed_seconds.count() / static_cast(FLAGS_fft_iterations_test); + std::cout << "FFT execution time for length=" << d_fft_size << " : " << execution_time << " [s]" << std::endl; delete d_fft; } ); From ff4938702ef305f2ac527d6575873bf1a366f1ad Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sat, 21 Oct 2017 13:05:51 +0200 Subject: [PATCH 47/81] Add Gnuplot-based plot results for FFT MeasureExecutionTime test --- src/tests/CMakeLists.txt | 5 + src/tests/common-files/gnuplot_i.h | 1953 +++++++++++++++++ .../unit-tests/arithmetic/fft_length_test.cc | 70 +- 3 files changed, 2025 insertions(+), 3 deletions(-) create mode 100644 src/tests/common-files/gnuplot_i.h diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index f37753413..651713998 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -158,6 +158,11 @@ if(ENABLE_FPGA) add_definitions(-DFPGA_BLOCKS_TEST=1) endif(ENABLE_FPGA) +find_package(Gnuplot) +if(GNUPLOT_FOUND) + add_definitions(-DGNUPLOT_EXECUTABLE="${GNUPLOT_EXECUTABLE}") +endif(GNUPLOT_FOUND) + ################################################################################ # Optional generator ################################################################################ diff --git a/src/tests/common-files/gnuplot_i.h b/src/tests/common-files/gnuplot_i.h new file mode 100644 index 000000000..615e9084e --- /dev/null +++ b/src/tests/common-files/gnuplot_i.h @@ -0,0 +1,1953 @@ +/*! + * \file gnuplot_i.h + * \brief A C++ interface to gnuplot. + * \author Carles Fernandez-Prades, 2017. cfernandez(at)cttc.es + * + * Source code found at https://code.google.com/archive/p/gnuplot-cpp/ + * by Jeremy Conlin jeremit0(at)gmail.com + * + * Version history: + * 0. C interface + * by N. Devillard (27/01/03) + * 1. C++ interface: direct translation from the C interface + * by Rajarshi Guha (07/03/03) + * 2. corrections for Win32 compatibility + * by V. Chyzhdzenka (20/05/03) + * 3. some member functions added, corrections for Win32 and Linux + * compatibility + * by M. Burgis (10/03/08) + * ------------------------------------------------------------------------- + * + * Copyright (C) 2013-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + + +#ifndef GNSS_SDR_GNUPLOT_I_H_ +#define GNSS_SDR_GNUPLOT_I_H_ + + +#include +#include +#include +#include +#include // for std::ostringstream +#include +#include +#include // for getenv() +#include // for std::list + + +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) +//defined for 32 and 64-bit environments + #include // for _access(), _mktemp() + #define GP_MAX_TMP_FILES 27 // 27 temporary files it's Microsoft restriction +#elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__) +//all UNIX-like OSs (Linux, *BSD, MacOSX, Solaris, ...) + #include // for access(), mkstemp() + #define GP_MAX_TMP_FILES 64 +#else + #error unsupported or unknown operating system +#endif + +//declare classes in global namespace + + +class GnuplotException : public std::runtime_error +{ +public: + GnuplotException(const std::string &msg) : std::runtime_error(msg){} +}; + + + +class Gnuplot +{ +private: + //---------------------------------------------------------------------------------- + // member data + ///\brief pointer to the stream that can be used to write to the pipe + FILE *gnucmd; + ///\brief validation of gnuplot session + bool valid; + ///\brief true = 2d, false = 3d + bool two_dim; + ///\brief number of plots in session + int nplots; + ///\brief functions and data are displayed in a defined styles + std::string pstyle; + ///\brief interpolate and approximate data in defined styles (e.g. spline) + std::string smooth; + ///\brief list of created tmpfiles + std::vector tmpfile_list; + + //---------------------------------------------------------------------------------- + // static data + ///\brief number of all tmpfiles (number of tmpfiles restricted) + static int tmpfile_num; + ///\brief name of executed GNUPlot file + static std::string m_sGNUPlotFileName; + ///\brief gnuplot path + static std::string m_sGNUPlotPath; + ///\brief standart terminal, used by showonscreen + static std::string terminal_std; + + //---------------------------------------------------------------------------------- + // member functions (auxiliary functions) + // --------------------------------------------------- + ///\brief get_program_path(); and popen(); + /// + /// \param --> void + /// + /// \return <-- void + // --------------------------------------------------- + void init(); + // --------------------------------------------------- + ///\brief creates tmpfile and returns its name + /// + /// \param tmp --> points to the tempfile + /// + /// \return <-- the name of the tempfile + // --------------------------------------------------- + std::string create_tmpfile(std::ofstream &tmp); + + //---------------------------------------------------------------------------------- + ///\brief gnuplot path found? + /// + /// \param --- + /// + /// \return <-- found the gnuplot path (yes == true, no == false) + // --------------------------------------------------------------------------------- + static bool get_program_path(); + + // --------------------------------------------------------------------------------- + ///\brief checks if file is available + /// + /// \param filename --> the filename + /// \param mode --> the mode [optional,default value = 0] + /// + /// \return file exists (yes == true, no == false) + // --------------------------------------------------------------------------------- + bool file_available(const std::string &filename); + + // --------------------------------------------------------------------------------- + ///\brief checks if file exists + /// + /// \param filename --> the filename + /// \param mode --> the mode [optional,default value = 0] + /// + /// \return file exists (yes == true, no == false) + // --------------------------------------------------------------------------------- + static bool file_exists(const std::string &filename, int mode=0); + +public: + // ---------------------------------------------------------------------------- + /// \brief optional function: set Gnuplot path manual + /// attention: for windows: path with slash '/' not backslash '\' + /// + /// \param path --> the gnuplot path + /// + /// \return true on success, false otherwise + // ---------------------------------------------------------------------------- + static bool set_GNUPlotPath(const std::string &path); + + // ---------------------------------------------------------------------------- + /// optional: set standart terminal, used by showonscreen + /// defaults: Windows - win, Linux - x11, Mac - aqua + /// + /// \param type --> the terminal type + /// + /// \return --- + // ---------------------------------------------------------------------------- + static void set_terminal_std(const std::string &type); + + //----------------------------------------------------------------------------- + // constructors + // ---------------------------------------------------------------------------- + + ///\brief set a style during construction + Gnuplot(const std::string &style = "points"); + + /// plot a single std::vector at one go + Gnuplot(const std::vector &x, + const std::string &title = "", + const std::string &style = "points", + const std::string &labelx = "x", + const std::string &labely = "y"); + + /// plot pairs std::vector at one go + Gnuplot(const std::vector &x, + const std::vector &y, + const std::string &title = "", + const std::string &style = "points", + const std::string &labelx = "x", + const std::string &labely = "y"); + + /// plot triples std::vector at one go + Gnuplot(const std::vector &x, + const std::vector &y, + const std::vector &z, + const std::string &title = "", + const std::string &style = "points", + const std::string &labelx = "x", + const std::string &labely = "y", + const std::string &labelz = "z"); + + /// destructor: needed to delete temporary files + ~Gnuplot(); + + //---------------------------------------------------------------------------------- + + /// send a command to gnuplot + Gnuplot& cmd(const std::string &cmdstr); + + // --------------------------------------------------------------------------------- + ///\brief Sends a command to an active gnuplot session, identical to cmd() + /// send a command to gnuplot using the << operator + /// + /// \param cmdstr --> the command string + /// + /// \return <-- a reference to the gnuplot object + // --------------------------------------------------------------------------------- + inline Gnuplot& operator<<(const std::string &cmdstr){ + cmd(cmdstr); + return(*this); + } + + //---------------------------------------------------------------------------------- + // show on screen or write to file + + /// sets terminal type to terminal_std + Gnuplot& showonscreen(); // window output is set by default (win/x11/aqua) + + /// saves a gnuplot session to a postscript file, filename without extension + Gnuplot& savetops(const std::string &filename = "gnuplot_output"); + + //---------------------------------------------------------------------------------- + // set and unset + + /// set line style (some of these styles require additional information): + /// lines, points, linespoints, impulses, dots, steps, fsteps, histeps, + /// boxes, histograms, filledcurves + Gnuplot& set_style(const std::string &stylestr = "points"); + + /// interpolation and approximation of data, arguments: + /// csplines, bezier, acsplines (for data values > 0), sbezier, unique, frequency + /// (works only with plot_x, plot_xy, plotfile_x, plotfile_xy + /// (if smooth is set, set_style has no effekt on data plotting) + Gnuplot& set_smooth(const std::string &stylestr = "csplines"); + + // ---------------------------------------------------------------------- + /// \brief unset smooth + /// attention: smooth is not set by default + /// + /// \param --- + /// + /// \return <-- a reference to a gnuplot object + // ---------------------------------------------------------------------- + inline Gnuplot& unset_smooth(){ smooth = ""; return *this;}; + + /// scales the size of the points used in plots + Gnuplot& set_pointsize(const double pointsize = 1.0); + + /// turns grid on/off + inline Gnuplot& set_grid() {cmd("set grid");return *this;}; + /// grid is not set by default + inline Gnuplot& unset_grid(){cmd("unset grid");return *this;}; + + // ----------------------------------------------- + /// set the mulitplot mode + /// + /// \param --- + /// + /// \return <-- reference to the gnuplot object + // ----------------------------------------------- + inline Gnuplot& set_multiplot(){cmd("set multiplot") ;return *this;}; + + // ----------------------------------------------- + /// unsets the mulitplot mode + /// + /// \param --- + /// + /// \return <-- reference to the gnuplot object + // ----------------------------------------------- + inline Gnuplot& unset_multiplot(){cmd("unset multiplot");return *this;}; + + /// set sampling rate of functions, or for interpolating data + Gnuplot& set_samples(const int samples = 100); + /// set isoline density (grid) for plotting functions as surfaces (for 3d plots) + Gnuplot& set_isosamples(const int isolines = 10); + + // -------------------------------------------------------------------------- + /// enables/disables hidden line removal for surface plotting (for 3d plot) + /// + /// \param --- + /// + /// \return <-- reference to the gnuplot object + // -------------------------------------------------------------------------- + Gnuplot& set_hidden3d(){cmd("set hidden3d");return *this;}; + + // --------------------------------------------------------------------------- + /// hidden3d is not set by default + /// + /// \param --- + /// + /// \return <-- reference to the gnuplot object + // --------------------------------------------------------------------------- + inline Gnuplot& unset_hidden3d(){cmd("unset hidden3d"); return *this;}; + + /// enables/disables contour drawing for surfaces (for 3d plot) + /// base, surface, both + Gnuplot& set_contour(const std::string &position = "base"); + // -------------------------------------------------------------------------- + /// contour is not set by default, it disables contour drawing for surfaces + /// + /// \param --- + /// + /// \return <-- reference to the gnuplot object + // ------------------------------------------------------------------ + inline Gnuplot& unset_contour(){cmd("unset contour");return *this;}; + + // ------------------------------------------------------------ + /// enables/disables the display of surfaces (for 3d plot) + /// + /// \param --- + /// + /// \return <-- reference to the gnuplot object + // ------------------------------------------------------------------ + inline Gnuplot& set_surface(){cmd("set surface");return *this;}; + + // ---------------------------------------------------------- + /// surface is set by default, + /// it disables the display of surfaces (for 3d plot) + /// + /// \param --- + /// + /// \return <-- reference to the gnuplot object + // ------------------------------------------------------------------ + inline Gnuplot& unset_surface(){cmd("unset surface"); return *this;} + + + /// switches legend on/off + /// position: inside/outside, left/center/right, top/center/bottom, nobox/box + Gnuplot& set_legend(const std::string &position = "default"); + + // ------------------------------------------------------------------ + /// \brief Switches legend off + /// attention:legend is set by default + /// + /// \param --- + /// + /// \return <-- reference to the gnuplot object + // ------------------------------------------------------------------ + inline Gnuplot& unset_legend(){cmd("unset key"); return *this;} + + // ----------------------------------------------------------------------- + /// \brief sets and clears the title of a gnuplot session + /// + /// \param title --> the title of the plot [optional, default == ""] + /// + /// \return <-- reference to the gnuplot object + // ----------------------------------------------------------------------- + inline Gnuplot& set_title(const std::string &title = "") + { + std::string cmdstr; + cmdstr = "set title \""; + cmdstr+=title; + cmdstr+="\""; + *this<set_title();return *this;} + + /// set x axis label + Gnuplot& set_ylabel(const std::string &label = "x"); + /// set y axis label + Gnuplot& set_xlabel(const std::string &label = "y"); + /// set z axis label + Gnuplot& set_zlabel(const std::string &label = "z"); + + /// set axis - ranges + Gnuplot& set_xrange(const double iFrom, + const double iTo); + /// set y-axis - ranges + Gnuplot& set_yrange(const double iFrom, + const double iTo); + /// set z-axis - ranges + Gnuplot& set_zrange(const double iFrom, + const double iTo); + /// autoscale axis (set by default) of xaxis + /// + /// \param --- + /// + /// \return <-- reference to the gnuplot object + // ----------------------------------------------- + inline Gnuplot& set_xautoscale(){cmd("set xrange restore");cmd("set autoscale x");return *this;}; + + // ----------------------------------------------- + /// autoscale axis (set by default) of yaxis + /// + /// \param --- + /// + /// \return <-- reference to the gnuplot object + // ----------------------------------------------- + inline Gnuplot& set_yautoscale(){cmd("set yrange restore");cmd("set autoscale y");return *this;}; + + // ----------------------------------------------- + /// autoscale axis (set by default) of zaxis + /// + /// \param --- + /// + /// \return <-- reference to the gnuplot object + // ----------------------------------------------- + inline Gnuplot& set_zautoscale(){cmd("set zrange restore");cmd("set autoscale z");return *this;}; + + /// turns on/off log scaling for the specified xaxis (logscale is not set by default) + Gnuplot& set_xlogscale(const double base = 10); + /// turns on/off log scaling for the specified yaxis (logscale is not set by default) + Gnuplot& set_ylogscale(const double base = 10); + /// turns on/off log scaling for the specified zaxis (logscale is not set by default) + Gnuplot& set_zlogscale(const double base = 10); + + // ----------------------------------------------- + /// turns off log scaling for the x axis + /// + /// \param --- + /// + /// \return <-- reference to the gnuplot object + // ----------------------------------------------- + inline Gnuplot& unset_xlogscale(){cmd("unset logscale x"); return *this;}; + + // ----------------------------------------------- + /// turns off log scaling for the y axis + /// + /// \param --- + /// + /// \return <-- reference to the gnuplot object + // ----------------------------------------------- + inline Gnuplot& unset_ylogscale(){cmd("unset logscale y"); return *this;}; + + // ----------------------------------------------- + /// turns off log scaling for the z axis + /// + /// \param --- + /// + /// \return <-- reference to the gnuplot object + // ----------------------------------------------- + inline Gnuplot& unset_zlogscale(){cmd("unset logscale z"); return *this;}; + + /// set palette range (autoscale by default) + Gnuplot& set_cbrange(const double iFrom, const double iTo); + + //---------------------------------------------------------------------------------- + // plot + + /// plot a single std::vector: x + /// from file + Gnuplot& plotfile_x(const std::string &filename, + const unsigned int column = 1, + const std::string &title = ""); + + /// from std::vector + template + Gnuplot& plot_x(const X& x, const std::string &title = ""); + + /// plot x,y pairs: x y + /// from file + Gnuplot& plotfile_xy(const std::string &filename, + const unsigned int column_x = 1, + const unsigned int column_y = 2, + const std::string &title = ""); + /// from data + template + Gnuplot& plot_xy(const X& x, const Y& y, const std::string &title = ""); + + /// plot x,y pairs with dy errorbars: x y dy + /// from file + Gnuplot& plotfile_xy_err(const std::string &filename, + const unsigned int column_x = 1, + const unsigned int column_y = 2, + const unsigned int column_dy = 3, + const std::string &title = ""); + /// from data + template + Gnuplot& plot_xy_err(const X &x, const Y &y, const E &dy, + const std::string &title = ""); + + /// plot x,y,z triples: x y z + /// from file + Gnuplot& plotfile_xyz(const std::string &filename, + const unsigned int column_x = 1, + const unsigned int column_y = 2, + const unsigned int column_z = 3, + const std::string &title = ""); + /// from std::vector + template + Gnuplot& plot_xyz(const X &x, + const Y &y, + const Z &z, + const std::string &title = ""); + + /// plot an equation of the form: y = ax + b, you supply a and b + Gnuplot& plot_slope(const double a, + const double b, + const std::string &title = ""); + + /// plot an equation supplied as a std::string y=f(x), write only the function f(x) not y= + /// the independent variable has to be x + /// binary operators: ** exponentiation, * multiply, / divide, + add, - substract, % modulo + /// unary operators: - minus, ! factorial + /// elementary functions: rand(x), abs(x), sgn(x), ceil(x), floor(x), int(x), imag(x), real(x), arg(x), + /// sqrt(x), exp(x), log(x), log10(x), sin(x), cos(x), tan(x), asin(x), acos(x), atan(x), atan2(y,x), + /// sinh(x), cosh(x), tanh(x), asinh(x), acosh(x), atanh(x) + /// special functions: erf(x), erfc(x), inverf(x), gamma(x), igamma(a,x), lgamma(x), ibeta(p,q,x), + /// besj0(x), besj1(x), besy0(x), besy1(x), lambertw(x) + /// statistical fuctions: norm(x), invnorm(x) + Gnuplot& plot_equation(const std::string &equation, + const std::string &title = ""); + + /// plot an equation supplied as a std::string z=f(x,y), write only the function f(x,y) not z= + /// the independent variables have to be x and y + Gnuplot& plot_equation3d(const std::string &equation, + const std::string &title = ""); + + /// plot image + Gnuplot& plot_image(const unsigned char *ucPicBuf, + const unsigned int iWidth, + const unsigned int iHeight, + const std::string &title = ""); + + //---------------------------------------------------------------------------------- + ///\brief replot repeats the last plot or splot command. + /// this can be useful for viewing a plot with different set options, + /// or when generating the same plot for several devices (showonscreen, savetops) + /// + /// \param --- + /// + /// \return --- + //---------------------------------------------------------------------------------- + inline Gnuplot& replot(void){if (nplots > 0) cmd("replot");return *this;}; + + /// resets a gnuplot session (next plot will erase previous ones) + Gnuplot& reset_plot(); + + /// resets a gnuplot session and sets all variables to default + Gnuplot& reset_all(); + + /// deletes temporary files + void remove_tmpfiles(); + + // ------------------------------------------------------------------- + /// \brief Is the gnuplot session valid ?? + /// + /// + /// \param --- + /// + /// \return true if valid, false if not + // ------------------------------------------------------------------- + inline bool is_valid(){return(valid);}; +}; + + +//------------------------------------------------------------------------------ +// +// initialize static data +// +int Gnuplot::tmpfile_num = 0; + +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) +std::string Gnuplot::m_sGNUPlotFileName = "pgnuplot.exe"; +std::string Gnuplot::m_sGNUPlotPath = "C:/program files/gnuplot/bin/"; +#elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__) +std::string Gnuplot::m_sGNUPlotFileName = "gnuplot"; +std::string Gnuplot::m_sGNUPlotPath = "/usr/local/bin/"; +#endif + +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) +std::string Gnuplot::terminal_std = "windows"; +#elif ( defined(unix) || defined(__unix) || defined(__unix__) ) && !defined(__APPLE__) +std::string Gnuplot::terminal_std = "x11"; +#elif defined(__APPLE__) +std::string Gnuplot::terminal_std = "aqua"; +#endif + +//------------------------------------------------------------------------------ +// +// constructor: set a style during construction +// +inline Gnuplot::Gnuplot(const std::string &style) +:gnucmd(NULL) ,valid(false) ,two_dim(false) ,nplots(0) + +{ + init(); + set_style(style); +} + + +//------------------------------------------------------------------------------ +// +// constructor: open a new session, plot a signal (x) +// +inline Gnuplot::Gnuplot(const std::vector &x, + const std::string &title, + const std::string &style, + const std::string &labelx, + const std::string &labely) +:gnucmd(NULL) ,valid(false) ,two_dim(false) ,nplots(0) +{ + init(); + + set_style(style); + set_xlabel(labelx); + set_ylabel(labely); + + plot_x(x,title); +} + + +//------------------------------------------------------------------------------ +// +// constructor: open a new session, plot a signal (x,y) +// +inline Gnuplot::Gnuplot(const std::vector &x, + const std::vector &y, + const std::string &title, + const std::string &style, + const std::string &labelx, + const std::string &labely) +:gnucmd(NULL) ,valid(false) ,two_dim(false) ,nplots(0) +{ + init(); + + set_style(style); + set_xlabel(labelx); + set_ylabel(labely); + + plot_xy(x,y,title); +} + + +//------------------------------------------------------------------------------ +// +// constructor: open a new session, plot a signal (x,y,z) +// +inline Gnuplot::Gnuplot(const std::vector &x, + const std::vector &y, + const std::vector &z, + const std::string &title, + const std::string &style, + const std::string &labelx, + const std::string &labely, + const std::string &labelz) +:gnucmd(NULL) ,valid(false) ,two_dim(false) ,nplots(0) +{ + init(); + + set_style(style); + set_xlabel(labelx); + set_ylabel(labely); + set_zlabel(labelz); + + plot_xyz(x,y,z,title); +} + + +//------------------------------------------------------------------------------ +// +/// Plots a 2d graph from a list of doubles: x +// +template +Gnuplot& Gnuplot::plot_x(const X& x, const std::string &title) +{ + if (x.size() == 0) + { + throw GnuplotException("std::vector too small"); + return *this; + } + + std::ofstream tmp; + std::string name = create_tmpfile(tmp); + if (name == "") + return *this; + + // + // write the data to file + // + for (unsigned int i = 0; i < x.size(); i++) + tmp << x[i] << std::endl; + + tmp.flush(); + tmp.close(); + + plotfile_x(name, 1, title); + + return *this; +} + + +//------------------------------------------------------------------------------ +// +/// Plots a 2d graph from a list of doubles: x y +// +template +Gnuplot& Gnuplot::plot_xy(const X& x, const Y& y, const std::string &title) +{ + if (x.size() == 0 || y.size() == 0) + { + throw GnuplotException("std::vectors too small"); + return *this; + } + + if (x.size() != y.size()) + { + throw GnuplotException("Length of the std::vectors differs"); + return *this; + } + + std::ofstream tmp; + std::string name = create_tmpfile(tmp); + if (name == "") + return *this; + + // + // write the data to file + // + for (unsigned int i = 0; i < x.size(); i++) + tmp << x[i] << " " << y[i] << std::endl; + + tmp.flush(); + tmp.close(); + + plotfile_xy(name, 1, 2, title); + + return *this; +} + + +///----------------------------------------------------------------------------- +/// +/// plot x,y pairs with dy errorbars +/// +template +Gnuplot& Gnuplot::plot_xy_err(const X &x, + const Y &y, + const E &dy, + const std::string &title) +{ + if (x.size() == 0 || y.size() == 0 || dy.size() == 0) + { + throw GnuplotException("std::vectors too small"); + return *this; + } + + if (x.size() != y.size() || y.size() != dy.size()) + { + throw GnuplotException("Length of the std::vectors differs"); + return *this; + } + + std::ofstream tmp; + std::string name = create_tmpfile(tmp); + if (name == "") + return *this; + + // + // write the data to file + // + for (unsigned int i = 0; i < x.size(); i++) + tmp << x[i] << " " << y[i] << " " << dy[i] << std::endl; + + tmp.flush(); + tmp.close(); + + // Do the actual plot + plotfile_xy_err(name, 1, 2, 3, title); + + return *this; +} + + +//------------------------------------------------------------------------------ +// +// Plots a 3d graph from a list of doubles: x y z +// +template +Gnuplot& Gnuplot::plot_xyz(const X &x, + const Y &y, + const Z &z, + const std::string &title) +{ + if (x.size() == 0 || y.size() == 0 || z.size() == 0) + { + throw GnuplotException("std::vectors too small"); + return *this; + } + + if (x.size() != y.size() || x.size() != z.size()) + { + throw GnuplotException("Length of the std::vectors differs"); + return *this; + } + + std::ofstream tmp; + std::string name = create_tmpfile(tmp); + if (name == "") + return *this; + + // + // write the data to file + // + for (unsigned int i = 0; i < x.size(); i++) + tmp << x[i] << " " << y[i] << " " << z[i] < +void stringtok (Container &container, + std::string const &in, + const char * const delimiters = " \t\n") +{ + const std::string::size_type len = in.length(); + std::string::size_type i = 0; + + while ( i < len ) + { + // eat leading whitespace + i = in.find_first_not_of (delimiters, i); + + if (i == std::string::npos) + return; // nothing left but white space + + // find the end of the token + std::string::size_type j = in.find_first_of (delimiters, i); + + // push token + if (j == std::string::npos) + { + container.push_back (in.substr(i)); + return; + } + else + container.push_back (in.substr(i, j-i)); + + // set up for next loop + i = j + 1; + } + + return; +} + + +//------------------------------------------------------------------------------ +// +// Destructor: needed to delete temporary files +// +Gnuplot::~Gnuplot() +{ + // remove_tmpfiles(); + + // A stream opened by popen() should be closed by pclose() +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) + if (_pclose(gnucmd) == -1) +#elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__) + if (pclose(gnucmd) == -1) +#endif + throw GnuplotException("Problem closing communication to gnuplot"); +} + + +//------------------------------------------------------------------------------ +// +// Resets a gnuplot session (next plot will erase previous ones) +// +Gnuplot& Gnuplot::reset_plot() +{ + // remove_tmpfiles(); + nplots = 0; + + return *this; +} + + +//------------------------------------------------------------------------------ +// +// resets a gnuplot session and sets all varibles to default +// +Gnuplot& Gnuplot::reset_all() +{ + // remove_tmpfiles(); + nplots = 0; + cmd("reset"); + cmd("clear"); + pstyle = "points"; + smooth = ""; + showonscreen(); + + return *this; +} + + +//------------------------------------------------------------------------------ +// +// Change the plotting style of a gnuplot session +// +Gnuplot& Gnuplot::set_style(const std::string &stylestr) +{ + if (stylestr.find("lines") == std::string::npos && + stylestr.find("points") == std::string::npos && + stylestr.find("linespoints") == std::string::npos && + stylestr.find("impulses") == std::string::npos && + stylestr.find("dots") == std::string::npos && + stylestr.find("steps") == std::string::npos && + stylestr.find("fsteps") == std::string::npos && + stylestr.find("histeps") == std::string::npos && + stylestr.find("boxes") == std::string::npos && // 1-4 columns of data are required + stylestr.find("filledcurves") == std::string::npos && + stylestr.find("histograms") == std::string::npos ) //only for one data column + // stylestr.find("labels") == std::string::npos && // 3 columns of data are required + // stylestr.find("xerrorbars") == std::string::npos && // 3-4 columns of data are required + // stylestr.find("xerrorlines") == std::string::npos && // 3-4 columns of data are required + // stylestr.find("errorbars") == std::string::npos && // 3-4 columns of data are required + // stylestr.find("errorlines") == std::string::npos && // 3-4 columns of data are required + // stylestr.find("yerrorbars") == std::string::npos && // 3-4 columns of data are required + // stylestr.find("yerrorlines") == std::string::npos && // 3-4 columns of data are required + // stylestr.find("boxerrorbars") == std::string::npos && // 3-5 columns of data are required + // stylestr.find("xyerrorbars") == std::string::npos && // 4,6,7 columns of data are required + // stylestr.find("xyerrorlines") == std::string::npos && // 4,6,7 columns of data are required + // stylestr.find("boxxyerrorbars") == std::string::npos && // 4,6,7 columns of data are required + // stylestr.find("financebars") == std::string::npos && // 5 columns of data are required + // stylestr.find("candlesticks") == std::string::npos && // 5 columns of data are required + // stylestr.find("vectors") == std::string::npos && + // stylestr.find("image") == std::string::npos && + // stylestr.find("rgbimage") == std::string::npos && + // stylestr.find("pm3d") == std::string::npos ) + { + pstyle = std::string("points"); + } + else + { + pstyle = stylestr; + } + + return *this; +} + + +//------------------------------------------------------------------------------ +// +// smooth: interpolation and approximation of data +// +Gnuplot& Gnuplot::set_smooth(const std::string &stylestr) +{ + if (stylestr.find("unique") == std::string::npos && + stylestr.find("frequency") == std::string::npos && + stylestr.find("csplines") == std::string::npos && + stylestr.find("acsplines") == std::string::npos && + stylestr.find("bezier") == std::string::npos && + stylestr.find("sbezier") == std::string::npos ) + { + smooth = ""; + } + else + { + smooth = stylestr; + } + + return *this; +} + + +//------------------------------------------------------------------------------ +// +// sets terminal type to windows / x11 +// +Gnuplot& Gnuplot::showonscreen() +{ + cmd("set output"); + cmd("set terminal " + Gnuplot::terminal_std); + + return *this; +} + + +//------------------------------------------------------------------------------ +// +// saves a gnuplot session to a postscript file +// +Gnuplot& Gnuplot::savetops(const std::string &filename) +{ + cmd("set terminal postscript color"); + + std::ostringstream cmdstr; + cmdstr << "set output \"" << filename << ".ps\""; + cmd(cmdstr.str()); + + return *this; +} + + +//------------------------------------------------------------------------------ +// +// Switches legend on +// +Gnuplot& Gnuplot::set_legend(const std::string &position) +{ + std::ostringstream cmdstr; + cmdstr << "set key " << position; + + cmd(cmdstr.str()); + + return *this; +} + + +//------------------------------------------------------------------------------ +// +// turns on log scaling for the x axis +// +Gnuplot& Gnuplot::set_xlogscale(const double base) +{ + std::ostringstream cmdstr; + + cmdstr << "set logscale x " << base; + cmd(cmdstr.str()); + + return *this; +} + + +//------------------------------------------------------------------------------ +// +// turns on log scaling for the y axis +// +Gnuplot& Gnuplot::set_ylogscale(const double base) +{ + std::ostringstream cmdstr; + + cmdstr << "set logscale y " << base; + cmd(cmdstr.str()); + + return *this; +} + + +//------------------------------------------------------------------------------ +// +// turns on log scaling for the z axis +// +Gnuplot& Gnuplot::set_zlogscale(const double base) +{ + std::ostringstream cmdstr; + + cmdstr << "set logscale z " << base; + cmd(cmdstr.str()); + + return *this; +} + + +//------------------------------------------------------------------------------ +// +// scales the size of the points used in plots +// +Gnuplot& Gnuplot::set_pointsize(const double pointsize) +{ + std::ostringstream cmdstr; + cmdstr << "set pointsize " << pointsize; + cmd(cmdstr.str()); + + return *this; +} + + +//------------------------------------------------------------------------------ +// +// set isoline density (grid) for plotting functions as surfaces +// +Gnuplot& Gnuplot::set_samples(const int samples) +{ + std::ostringstream cmdstr; + cmdstr << "set samples " << samples; + cmd(cmdstr.str()); + + return *this; +} + + +//------------------------------------------------------------------------------ +// +// set isoline density (grid) for plotting functions as surfaces +// +Gnuplot& Gnuplot::set_isosamples(const int isolines) +{ + std::ostringstream cmdstr; + cmdstr << "set isosamples " << isolines; + cmd(cmdstr.str()); + + return *this; +} + + +//------------------------------------------------------------------------------ +// +// enables contour drawing for surfaces set contour {base | surface | both} +// +Gnuplot& Gnuplot::set_contour(const std::string &position) +{ + if (position.find("base") == std::string::npos && + position.find("surface") == std::string::npos && + position.find("both") == std::string::npos ) + { + cmd("set contour base"); + } + else + { + cmd("set contour " + position); + } + + return *this; +} + + +//------------------------------------------------------------------------------ +// +// set labels +// +// set the xlabel +Gnuplot& Gnuplot::set_xlabel(const std::string &label) +{ + std::ostringstream cmdstr; + + cmdstr << "set xlabel \"" << label << "\""; + cmd(cmdstr.str()); + + return *this; +} + + +//------------------------------------------------------------------------------ +// set the ylabel +// +Gnuplot& Gnuplot::set_ylabel(const std::string &label) +{ + std::ostringstream cmdstr; + + cmdstr << "set ylabel \"" << label << "\""; + cmd(cmdstr.str()); + + return *this; +} + + +//------------------------------------------------------------------------------ +// set the zlabel +// +Gnuplot& Gnuplot::set_zlabel(const std::string &label) +{ + std::ostringstream cmdstr; + + cmdstr << "set zlabel \"" << label << "\""; + cmd(cmdstr.str()); + + return *this; +} + + +//------------------------------------------------------------------------------ +// +// set range +// +// set the xrange +Gnuplot& Gnuplot::set_xrange(const double iFrom, + const double iTo) +{ + std::ostringstream cmdstr; + + cmdstr << "set xrange[" << iFrom << ":" << iTo << "]"; + cmd(cmdstr.str()); + + return *this; +} + + +//------------------------------------------------------------------------------ +// set the yrange +// +Gnuplot& Gnuplot::set_yrange(const double iFrom, + const double iTo) +{ + std::ostringstream cmdstr; + + cmdstr << "set yrange[" << iFrom << ":" << iTo << "]"; + cmd(cmdstr.str()); + + return *this; +} + + +//------------------------------------------------------------------------------ +// set the zrange +// +Gnuplot& Gnuplot::set_zrange(const double iFrom, + const double iTo) +{ + std::ostringstream cmdstr; + + cmdstr << "set zrange[" << iFrom << ":" << iTo << "]"; + cmd(cmdstr.str()); + + return *this; +} + + +//------------------------------------------------------------------------------ +// +// set the palette range +// +Gnuplot& Gnuplot::set_cbrange(const double iFrom, + const double iTo) +{ + std::ostringstream cmdstr; + + cmdstr << "set cbrange[" << iFrom << ":" << iTo << "]"; + cmd(cmdstr.str()); + + return *this; +} + + +//------------------------------------------------------------------------------ +// +// Plots a linear equation y=ax+b (where you supply the +// slope a and intercept b) +// +Gnuplot& Gnuplot::plot_slope(const double a, + const double b, + const std::string &title) +{ + std::ostringstream cmdstr; + // + // command to be sent to gnuplot + // + if (nplots > 0 && two_dim == true) + cmdstr << "replot "; + else + cmdstr << "plot "; + + cmdstr << a << " * x + " << b << " title \""; + + if (title == "") + cmdstr << "f(x) = " << a << " * x + " << b; + else + cmdstr << title; + + cmdstr << "\" with " << pstyle; + + // + // Do the actual plot + // + cmd(cmdstr.str()); + + return *this; +} + + +//------------------------------------------------------------------------------ +// +// Plot an equation supplied as a std::string y=f(x) (only f(x) expected) +// +Gnuplot& Gnuplot::plot_equation(const std::string &equation, + const std::string &title) +{ + std::ostringstream cmdstr; + // + // command to be sent to gnuplot + // + if (nplots > 0 && two_dim == true) + cmdstr << "replot "; + else + cmdstr << "plot "; + + cmdstr << equation << " title \""; + + if (title == "") + cmdstr << "f(x) = " << equation; + else + cmdstr << title; + + cmdstr << "\" with " << pstyle; + + // + // Do the actual plot + // + cmd(cmdstr.str()); + + return *this; +} + + +//------------------------------------------------------------------------------ +// +// plot an equation supplied as a std::string y=(x) +// +Gnuplot& Gnuplot::plot_equation3d(const std::string &equation, + const std::string &title) +{ + std::ostringstream cmdstr; + // + // command to be sent to gnuplot + // + if (nplots > 0 && two_dim == false) + cmdstr << "replot "; + else + cmdstr << "splot "; + + cmdstr << equation << " title \""; + + if (title == "") + cmdstr << "f(x,y) = " << equation; + else + cmdstr << title; + + cmdstr << "\" with " << pstyle; + + // + // Do the actual plot + // + cmd(cmdstr.str()); + + return *this; +} + + +//------------------------------------------------------------------------------ +// +// Plots a 2d graph from a list of doubles (x) saved in a file +// +Gnuplot& Gnuplot::plotfile_x(const std::string &filename, + const unsigned int column, + const std::string &title) +{ + // + // check if file exists + // + file_available(filename); + + std::ostringstream cmdstr; + // + // command to be sent to gnuplot + // + if (nplots > 0 && two_dim == true) + cmdstr << "replot "; + else + cmdstr << "plot "; + + cmdstr << "\"" << filename << "\" using " << column; + + if (title == "") + cmdstr << " notitle "; + else + cmdstr << " title \"" << title << "\" "; + + if(smooth == "") + cmdstr << "with " << pstyle; + else + cmdstr << "smooth " << smooth; + + // + // Do the actual plot + // + cmd(cmdstr.str()); //nplots++; two_dim = true; already in cmd(); + + return *this; +} + + + +//------------------------------------------------------------------------------ +// +// Plots a 2d graph from a list of doubles (x y) saved in a file +// +Gnuplot& Gnuplot::plotfile_xy(const std::string &filename, + const unsigned int column_x, + const unsigned int column_y, + const std::string &title) +{ + // + // check if file exists + // + file_available(filename); + + std::ostringstream cmdstr; + // + // command to be sent to gnuplot + // + if (nplots > 0 && two_dim == true) + cmdstr << "replot "; + else + cmdstr << "plot "; + + cmdstr << "\"" << filename << "\" using " << column_x << ":" << column_y; + + if (title == "") + cmdstr << " notitle "; + else + cmdstr << " title \"" << title << "\" "; + + if(smooth == "") + cmdstr << "with " << pstyle; + else + cmdstr << "smooth " << smooth; + + // + // Do the actual plot + // + cmd(cmdstr.str()); + + return *this; +} + + +//------------------------------------------------------------------------------ +// +// Plots a 2d graph with errorbars from a list of doubles (x y dy) in a file +// +Gnuplot& Gnuplot::plotfile_xy_err(const std::string &filename, + const unsigned int column_x, + const unsigned int column_y, + const unsigned int column_dy, + const std::string &title) +{ + // + // check if file exists + // + file_available(filename); + + std::ostringstream cmdstr; + // + // command to be sent to gnuplot + // + if (nplots > 0 && two_dim == true) + cmdstr << "replot "; + else + cmdstr << "plot "; + + cmdstr << "\"" << filename << "\" using " + << column_x << ":" << column_y << ":" << column_dy + << " with errorbars "; + + if (title == "") + cmdstr << " notitle "; + else + cmdstr << " title \"" << title << "\" "; + + // + // Do the actual plot + // + cmd(cmdstr.str()); + + return *this; +} + + +//------------------------------------------------------------------------------ +// +// Plots a 3d graph from a list of doubles (x y z) saved in a file +// +Gnuplot& Gnuplot::plotfile_xyz(const std::string &filename, + const unsigned int column_x, + const unsigned int column_y, + const unsigned int column_z, + const std::string &title) +{ + // + // check if file exists + // + file_available(filename); + + std::ostringstream cmdstr; + // + // command to be sent to gnuplot + // + if (nplots > 0 && two_dim == false) + cmdstr << "replot "; + else + cmdstr << "splot "; + + cmdstr << "\"" << filename << "\" using " << column_x << ":" << column_y + << ":" << column_z; + + if (title == "") + cmdstr << " notitle with " << pstyle; + else + cmdstr << " title \"" << title << "\" with " << pstyle; + + // + // Do the actual plot + // + cmd(cmdstr.str()); + + return *this; +} + + + +//------------------------------------------------------------------------------ +// +/// * note that this function is not valid for versions of GNUPlot below 4.2 +// +Gnuplot& Gnuplot::plot_image(const unsigned char * ucPicBuf, + const unsigned int iWidth, + const unsigned int iHeight, + const std::string &title) +{ + std::ofstream tmp; + std::string name = create_tmpfile(tmp); + if (name == "") + return *this; + + // + // write the data to file + // + int iIndex = 0; + for(int iRow = 0; iRow < iHeight; iRow++) + { + for(int iColumn = 0; iColumn < iWidth; iColumn++) + { + tmp << iColumn << " " << iRow << " " + << static_cast(ucPicBuf[iIndex++]) << std::endl; + } + } + + tmp.flush(); + tmp.close(); + + std::ostringstream cmdstr; + // + // command to be sent to gnuplot + // + if (nplots > 0 && two_dim == true) + cmdstr << "replot "; + else + cmdstr << "plot "; + + if (title == "") + cmdstr << "\"" << name << "\" with image"; + else + cmdstr << "\"" << name << "\" title \"" << title << "\" with image"; + + // + // Do the actual plot + // + cmd(cmdstr.str()); + + return *this; +} + + + +//------------------------------------------------------------------------------ +// +// Sends a command to an active gnuplot session +// +Gnuplot& Gnuplot::cmd(const std::string &cmdstr) +{ + if( !(valid) ) + { + return *this; + } + + // int fputs ( const char * str, FILE * stream ); + // writes the string str to the stream. + // The function begins copying from the address specified (str) until it + // reaches the terminating null character ('\0'). This final + // null-character is not copied to the stream. + fputs( (cmdstr+"\n").c_str(), gnucmd ); + + // int fflush ( FILE * stream ); + // If the given stream was open for writing and the last i/o operation was + // an output operation, any unwritten data in the output buffer is written + // to the file. If the argument is a null pointer, all open files are + // flushed. The stream remains open after this call. + fflush(gnucmd); + + if( cmdstr.find("replot") != std::string::npos ) + { + return *this; + } + else if( cmdstr.find("splot") != std::string::npos ) + { + two_dim = false; + nplots++; + } + else if( cmdstr.find("plot") != std::string::npos ) + { + two_dim = true; + nplots++; + } + + return *this; +} + + +//------------------------------------------------------------------------------ +// +// Opens up a gnuplot session, ready to receive commands +// +void Gnuplot::init() +{ + // char * getenv ( const char * name ); get value of environment variable + // Retrieves a C string containing the value of the environment variable + // whose name is specified as argument. If the requested variable is not + // part of the environment list, the function returns a NULL pointer. +#if ( defined(unix) || defined(__unix) || defined(__unix__) ) && !defined(__APPLE__) + if (getenv("DISPLAY") == NULL) + { + valid = false; + throw GnuplotException("Can't find DISPLAY variable"); + } +#endif + + // if gnuplot not available + if (!Gnuplot::get_program_path()) + { + valid = false; + throw GnuplotException("Can't find gnuplot"); + } + + // + // open pipe + // + std::string tmp = Gnuplot::m_sGNUPlotPath + "/" + + Gnuplot::m_sGNUPlotFileName; + + // FILE *popen(const char *command, const char *mode); + // The popen() function shall execute the command specified by the string + // command, create a pipe between the calling program and the executed + // command, and return a pointer to a stream that can be used to either read + // from or write to the pipe. +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) + gnucmd = _popen(tmp.c_str(),"w"); +#elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__) + gnucmd = popen(tmp.c_str(),"w"); +#endif + + // popen() shall return a pointer to an open stream that can be used to read + // or write to the pipe. Otherwise, it shall return a null pointer and may + // set errno to indicate the error. + if (!gnucmd) + { + valid = false; + throw GnuplotException("Couldn't open connection to gnuplot"); + } + + nplots = 0; + valid = true; + smooth = ""; + + //set terminal type + showonscreen(); + + return; +} + + +//------------------------------------------------------------------------------ +// +// Find out if a command lives in m_sGNUPlotPath or in PATH +// +bool Gnuplot::get_program_path() +{ + // + // first look in m_sGNUPlotPath for Gnuplot + // + std::string tmp = Gnuplot::m_sGNUPlotPath + "/" + + Gnuplot::m_sGNUPlotFileName; + +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) + if ( Gnuplot::file_exists(tmp,0) ) // check existence +#elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__) + if ( Gnuplot::file_exists(tmp,1) ) // check existence and execution permission +#endif + { + return true; + } + + // + // second look in PATH for Gnuplot + // + char *path; + // Retrieves a C string containing the value of environment variable PATH + path = getenv("PATH"); + + if (path == NULL) + { + throw GnuplotException("Path is not set"); + return false; + } + else + { + std::list ls; + + //split path (one long string) into list ls of strings +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) + stringtok(ls,path,";"); +#elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__) + stringtok(ls,path,":"); +#endif + + // scan list for Gnuplot program files + for (std::list::const_iterator i = ls.begin(); + i != ls.end(); ++i) + { + tmp = (*i) + "/" + Gnuplot::m_sGNUPlotFileName; +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) + if ( Gnuplot::file_exists(tmp,0) ) // check existence +#elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__) + if ( Gnuplot::file_exists(tmp,1) ) // check existence and execution permission +#endif + { + Gnuplot::m_sGNUPlotPath = *i; // set m_sGNUPlotPath + return true; + } + } + + tmp = "Can't find gnuplot neither in PATH nor in \"" + + Gnuplot::m_sGNUPlotPath + "\""; + throw GnuplotException(tmp); + + Gnuplot::m_sGNUPlotPath = ""; + return false; + } +} + + + +//------------------------------------------------------------------------------ +// +// check if file exists +// +bool Gnuplot::file_exists(const std::string &filename, int mode) +{ + if ( mode < 0 || mode > 7) + { + throw std::runtime_error("In function \"Gnuplot::file_exists\": mode\ + has to be an integer between 0 and 7"); + return false; + } + + // int _access(const char *path, int mode); + // returns 0 if the file has the given mode, + // it returns -1 if the named file does not exist or is not accessible in + // the given mode + // mode = 0 (F_OK) (default): checks file for existence only + // mode = 1 (X_OK): execution permission + // mode = 2 (W_OK): write permission + // mode = 4 (R_OK): read permission + // mode = 6 : read and write permission + // mode = 7 : read, write and execution permission +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) + if (_access(filename.c_str(), mode) == 0) +#elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__) + if (access(filename.c_str(), mode) == 0) +#endif + { + return true; + } + else + { + return false; + } +} + + +bool Gnuplot::file_available(const std::string &filename) +{ + std::ostringstream except; + if( Gnuplot::file_exists(filename,0) ) // check existence + { + if( !(Gnuplot::file_exists(filename,4)) ){// check read permission + except << "No read permission for File \"" << filename << "\""; + throw GnuplotException( except.str() ); + return false; + } + } + else + { + except << "File \"" << filename << "\" does not exist"; + throw GnuplotException( except.str() ); + return false; + } + return true; +} + + + +//------------------------------------------------------------------------------ +// +// Opens a temporary file +// +std::string Gnuplot::create_tmpfile(std::ofstream &tmp) +{ +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) + char name[] = "gnuplotiXXXXXX"; //tmp file in working directory +#elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__) + char name[] = "/tmp/gnuplotiXXXXXX"; // tmp file in /tmp +#endif + + // + // check if maximum number of temporary files reached + // + if (Gnuplot::tmpfile_num == GP_MAX_TMP_FILES - 1) + { + std::ostringstream except; + except << "Maximum number of temporary files reached (" + << GP_MAX_TMP_FILES << "): cannot open more files" << std::endl; + + throw GnuplotException( except.str() ); + return ""; + } + + // int mkstemp(char *name); + // shall replace the contents of the string pointed to by "name" by a unique + // filename, and return a file descriptor for the file open for reading and + // writing. Otherwise, -1 shall be returned if no suitable file could be + // created. The string in template should look like a filename with six + // trailing 'X' s; mkstemp() replaces each 'X' with a character from the + // portable filename character set. The characters are chosen such that the + // resulting name does not duplicate the name of an existing file at the + // time of a call to mkstemp() + + // + // open temporary files for output + // +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) + if (_mktemp(name) == NULL) +#elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__) + if (mkstemp(name) == -1) +#endif + { + std::ostringstream except; + except << "Cannot create temporary file \"" << name << "\""; + throw GnuplotException(except.str()); + return ""; + } + + tmp.open(name); + if (tmp.bad()) + { + std::ostringstream except; + except << "Cannot create temporary file \"" << name << "\""; + throw GnuplotException(except.str()); + return ""; + } + + // + // Save the temporary filename + // + tmpfile_list.push_back(name); + Gnuplot::tmpfile_num++; + + return name; +} + + +void Gnuplot::remove_tmpfiles() +{ + if ((tmpfile_list).size() > 0) + { + for (unsigned int i = 0; i < tmpfile_list.size(); i++) + remove( tmpfile_list[i].c_str() ); + + Gnuplot::tmpfile_num -= tmpfile_list.size(); + } +} + + +#endif diff --git a/src/tests/unit-tests/arithmetic/fft_length_test.cc b/src/tests/unit-tests/arithmetic/fft_length_test.cc index 9fc0b5a8d..4b9d64826 100644 --- a/src/tests/unit-tests/arithmetic/fft_length_test.cc +++ b/src/tests/unit-tests/arithmetic/fft_length_test.cc @@ -33,14 +33,26 @@ #include #include #include +#include #include +#if defined GNUPLOT_EXECUTABLE + #include "gnuplot_i.h" + const bool exists_gnuplot_fft_test_length = true; +#elif !defined GNUPLOT_EXECUTABLE + const bool exists_gnuplot_fft_test_length = false; +#endif + + DEFINE_int32(fft_iterations_test, 1000, "Number of averaged iterations in FFT length timing test"); +DEFINE_bool(plot_fft_length_test, false, "Plots results of FFTLengthTest"); TEST(FFTLengthTest, MeasureExecutionTime) { - unsigned int fft_sizes [] = { 1000, 1024, 1960, 2000, 2048, 4000, 4096, 4725, 5000, 8000, 8192, 10368, 12000, 16000, 16384, 27000, 32768, 50000, 65536 }; + unsigned int fft_sizes [] = { 512, 1000, 1024, 1100, 1297, 1400, 1500, 1960, 2000, 2048, 2221, 2500, 3000, 3500, 4000, + 4096, 4200, 4500, 4725, 5000, 5500, 6000, 6500, 7000, 7500, 8000, 8192, 8500, 9000, 9500, 10000, 10368, 11000, + 12000, 15000, 16000, 16384, 27000, 32768, 50000, 65536 }; std::chrono::time_point start, end; @@ -54,8 +66,12 @@ TEST(FFTLengthTest, MeasureExecutionTime) auto gen = std::bind(func, random_number1, random_number2); // Function that returns a random gr_complex std::vector fft_sizes_v(fft_sizes, fft_sizes + sizeof(fft_sizes) / sizeof(unsigned int) ); + std::sort(fft_sizes_v.begin(), fft_sizes_v.end()); std::vector::const_iterator it; unsigned int d_fft_size; + std::vector execution_times; + std::vector powers_of_two; + std::vector execution_times_powers_of_two; EXPECT_NO_THROW( for(it = fft_sizes_v.cbegin(); it != fft_sizes_v.cend(); ++it) @@ -73,9 +89,57 @@ TEST(FFTLengthTest, MeasureExecutionTime) } end = std::chrono::system_clock::now(); std::chrono::duration elapsed_seconds = end - start; - double execution_time = elapsed_seconds.count() / static_cast(FLAGS_fft_iterations_test); - std::cout << "FFT execution time for length=" << d_fft_size << " : " << execution_time << " [s]" << std::endl; + double exec_time = elapsed_seconds.count() / static_cast(FLAGS_fft_iterations_test); + execution_times.push_back(exec_time * 1e3); + std::cout << "FFT execution time for length=" << d_fft_size << " : " << exec_time << " [s]" << std::endl; delete d_fft; + + if( (d_fft_size & (d_fft_size - 1)) == 0 ) // if it is a power of two + { + powers_of_two.push_back(d_fft_size); + execution_times_powers_of_two.push_back(exec_time / 1e-3); + } + } ); + + if(FLAGS_plot_fft_length_test == true) + { + if(!exists_gnuplot_fft_test_length) + { + std::cout << "WARNING: Although the flag plot_fft_length_test has been set to TRUE," << std::endl; + std::cout << "gnuplot has not been found in your system." << std::endl; + std::cout << "Test results will not be plotted." << std::endl; + } + else + { +#if defined GNUPLOT_EXECUTABLE + std::string gnuplot_executable = std::string(GNUPLOT_EXECUTABLE); + boost::filesystem::path p(gnuplot_executable); + boost::filesystem::path dir = p.parent_path(); + std::string gnuplot_path = dir.native(); + Gnuplot::set_GNUPlotPath(gnuplot_path); + + Gnuplot g1("linespoints"); + g1.set_title("FFT execution times for different lengths"); + g1.set_grid(); + g1.set_xlabel("FFT length"); + g1.set_ylabel("Execution time [ms]"); + g1.plot_xy(fft_sizes_v, execution_times, "FFT execution time (averaged over " + std::to_string(FLAGS_fft_iterations_test) + " iterations)"); + g1.set_style("points").plot_xy(powers_of_two, execution_times_powers_of_two, "Power of 2"); + g1.showonscreen(); // window output + + Gnuplot g2("linespoints"); + g2.set_title("FFT execution times for different lengths (up to 2^{14}=16384)"); + g2.set_grid(); + g2.set_xlabel("FFT length"); + g2.set_ylabel("Execution time [ms]"); + g2.set_xrange(0, 16384); + g2.plot_xy(fft_sizes_v, execution_times, "FFT execution time (averaged over " + std::to_string(FLAGS_fft_iterations_test) + " iterations)"); + g2.set_style("points").plot_xy(powers_of_two, execution_times_powers_of_two, "Power of 2"); + g2.savetops("FFT_execution_times"); + g2.showonscreen(); // window output +#endif + } + } } From d0bd3987e1365a93c662d4f1be260f729947d2f7 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sat, 21 Oct 2017 13:38:25 +0200 Subject: [PATCH 48/81] Fix warnings --- src/tests/common-files/gnuplot_i.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/common-files/gnuplot_i.h b/src/tests/common-files/gnuplot_i.h index 615e9084e..a3bdd1c92 100644 --- a/src/tests/common-files/gnuplot_i.h +++ b/src/tests/common-files/gnuplot_i.h @@ -1596,9 +1596,9 @@ Gnuplot& Gnuplot::plot_image(const unsigned char * ucPicBuf, // write the data to file // int iIndex = 0; - for(int iRow = 0; iRow < iHeight; iRow++) + for(unsigned int iRow = 0; iRow < iHeight; iRow++) { - for(int iColumn = 0; iColumn < iWidth; iColumn++) + for(unsigned int iColumn = 0; iColumn < iWidth; iColumn++) { tmp << iColumn << " " << iRow << " " << static_cast(ucPicBuf[iIndex++]) << std::endl; From c4ba566c425fa2395a6dda828bd1f21b08c7bde0 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sat, 21 Oct 2017 13:39:41 +0200 Subject: [PATCH 49/81] Keep windows open in Linux --- .../unit-tests/arithmetic/fft_length_test.cc | 77 +++++++++++++------ 1 file changed, 53 insertions(+), 24 deletions(-) diff --git a/src/tests/unit-tests/arithmetic/fft_length_test.cc b/src/tests/unit-tests/arithmetic/fft_length_test.cc index 4b9d64826..1b7a98427 100644 --- a/src/tests/unit-tests/arithmetic/fft_length_test.cc +++ b/src/tests/unit-tests/arithmetic/fft_length_test.cc @@ -48,7 +48,26 @@ DEFINE_int32(fft_iterations_test, 1000, "Number of averaged iterations in FFT length timing test"); DEFINE_bool(plot_fft_length_test, false, "Plots results of FFTLengthTest"); -TEST(FFTLengthTest, MeasureExecutionTime) + +class FFTLengthTest: public ::testing::Test +{ +public: + void wait_for_key(); +}; + + +void FFTLengthTest::wait_for_key() +{ + std::cout << std::endl << "Press ENTER to continue..." << std::endl; + + std::cin.clear(); + std::cin.ignore(std::cin.rdbuf()->in_avail()); + std::cin.get(); + return; +} + + +TEST_F(FFTLengthTest, MeasureExecutionTime) { unsigned int fft_sizes [] = { 512, 1000, 1024, 1100, 1297, 1400, 1500, 1960, 2000, 2048, 2221, 2500, 3000, 3500, 4000, 4096, 4200, 4500, 4725, 5000, 5500, 6000, 6500, 7000, 7500, 8000, 8192, 8500, 9000, 9500, 10000, 10368, 11000, @@ -114,31 +133,41 @@ TEST(FFTLengthTest, MeasureExecutionTime) else { #if defined GNUPLOT_EXECUTABLE - std::string gnuplot_executable = std::string(GNUPLOT_EXECUTABLE); - boost::filesystem::path p(gnuplot_executable); - boost::filesystem::path dir = p.parent_path(); - std::string gnuplot_path = dir.native(); - Gnuplot::set_GNUPlotPath(gnuplot_path); + try + { + std::string gnuplot_executable = std::string(GNUPLOT_EXECUTABLE); + boost::filesystem::path p(gnuplot_executable); + boost::filesystem::path dir = p.parent_path(); + std::string gnuplot_path = dir.native(); + Gnuplot::set_GNUPlotPath(gnuplot_path); - Gnuplot g1("linespoints"); - g1.set_title("FFT execution times for different lengths"); - g1.set_grid(); - g1.set_xlabel("FFT length"); - g1.set_ylabel("Execution time [ms]"); - g1.plot_xy(fft_sizes_v, execution_times, "FFT execution time (averaged over " + std::to_string(FLAGS_fft_iterations_test) + " iterations)"); - g1.set_style("points").plot_xy(powers_of_two, execution_times_powers_of_two, "Power of 2"); - g1.showonscreen(); // window output + Gnuplot g1("linespoints"); + g1.set_title("FFT execution times for different lengths"); + g1.set_grid(); + g1.set_xlabel("FFT length"); + g1.set_ylabel("Execution time [ms]"); + g1.plot_xy(fft_sizes_v, execution_times, "FFT execution time (averaged over " + std::to_string(FLAGS_fft_iterations_test) + " iterations)"); + g1.set_style("points").plot_xy(powers_of_two, execution_times_powers_of_two, "Power of 2"); + g1.showonscreen(); // window output - Gnuplot g2("linespoints"); - g2.set_title("FFT execution times for different lengths (up to 2^{14}=16384)"); - g2.set_grid(); - g2.set_xlabel("FFT length"); - g2.set_ylabel("Execution time [ms]"); - g2.set_xrange(0, 16384); - g2.plot_xy(fft_sizes_v, execution_times, "FFT execution time (averaged over " + std::to_string(FLAGS_fft_iterations_test) + " iterations)"); - g2.set_style("points").plot_xy(powers_of_two, execution_times_powers_of_two, "Power of 2"); - g2.savetops("FFT_execution_times"); - g2.showonscreen(); // window output + Gnuplot g2("linespoints"); + g2.set_title("FFT execution times for different lengths (up to 2^{14}=16384)"); + g2.set_grid(); + g2.set_xlabel("FFT length"); + g2.set_ylabel("Execution time [ms]"); + g2.set_xrange(0, 16384); + g2.plot_xy(fft_sizes_v, execution_times, "FFT execution time (averaged over " + std::to_string(FLAGS_fft_iterations_test) + " iterations)"); + g2.set_style("points").plot_xy(powers_of_two, execution_times_powers_of_two, "Power of 2"); + g2.savetops("FFT_execution_times"); + g2.showonscreen(); // window output +#if !defined __APPLE__ + wait_for_key(); +#endif + } + catch (GnuplotException ge) + { + std::cout << ge.what() << std::endl; + } #endif } } From e006b66f510cb61e2ed64395a2bf91456ebd4bcf Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sat, 21 Oct 2017 16:33:26 +0200 Subject: [PATCH 50/81] Fix postscript generation --- src/tests/common-files/gnuplot_i.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tests/common-files/gnuplot_i.h b/src/tests/common-files/gnuplot_i.h index a3bdd1c92..9427bcaac 100644 --- a/src/tests/common-files/gnuplot_i.h +++ b/src/tests/common-files/gnuplot_i.h @@ -1065,7 +1065,9 @@ Gnuplot& Gnuplot::savetops(const std::string &filename) cmd("set terminal postscript color"); std::ostringstream cmdstr; - cmdstr << "set output \"" << filename << ".ps\""; + cmdstr << "set term postscript\n"; + cmdstr << "set output \"" << filename << ".ps\"\n"; + cmdstr << "replot"; cmd(cmdstr.str()); return *this; From 19b280e089b5218a68c8a271326c2f37f854071f Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sun, 22 Oct 2017 08:20:51 +0200 Subject: [PATCH 51/81] Add persist to gnuplot terminal --- src/tests/common-files/gnuplot_i.h | 6 ++--- .../unit-tests/arithmetic/fft_length_test.cc | 25 +++---------------- 2 files changed, 5 insertions(+), 26 deletions(-) diff --git a/src/tests/common-files/gnuplot_i.h b/src/tests/common-files/gnuplot_i.h index 9427bcaac..183e51101 100644 --- a/src/tests/common-files/gnuplot_i.h +++ b/src/tests/common-files/gnuplot_i.h @@ -1050,7 +1050,7 @@ Gnuplot& Gnuplot::set_smooth(const std::string &stylestr) Gnuplot& Gnuplot::showonscreen() { cmd("set output"); - cmd("set terminal " + Gnuplot::terminal_std); + cmd("set terminal " + Gnuplot::terminal_std + " persist"); return *this; } @@ -1062,10 +1062,8 @@ Gnuplot& Gnuplot::showonscreen() // Gnuplot& Gnuplot::savetops(const std::string &filename) { - cmd("set terminal postscript color"); - std::ostringstream cmdstr; - cmdstr << "set term postscript\n"; + cmdstr << "set term postscript landscape enhanced color dashed \"Times-Roman\" 18\n"; cmdstr << "set output \"" << filename << ".ps\"\n"; cmdstr << "replot"; cmd(cmdstr.str()); diff --git a/src/tests/unit-tests/arithmetic/fft_length_test.cc b/src/tests/unit-tests/arithmetic/fft_length_test.cc index 1b7a98427..e04455c04 100644 --- a/src/tests/unit-tests/arithmetic/fft_length_test.cc +++ b/src/tests/unit-tests/arithmetic/fft_length_test.cc @@ -46,26 +46,10 @@ DEFINE_int32(fft_iterations_test, 1000, "Number of averaged iterations in FFT length timing test"); -DEFINE_bool(plot_fft_length_test, false, "Plots results of FFTLengthTest"); - - -class FFTLengthTest: public ::testing::Test -{ -public: - void wait_for_key(); -}; - - -void FFTLengthTest::wait_for_key() -{ - std::cout << std::endl << "Press ENTER to continue..." << std::endl; - - std::cin.clear(); - std::cin.ignore(std::cin.rdbuf()->in_avail()); - std::cin.get(); - return; -} +DEFINE_bool(plot_fft_length_test, false, "Plots results of FFTLengthTest with gnuplot"); +// Note from FFTW documentation: the standard FFTW distribution works most efficiently for arrays whose +// size can be factored into small primes (2, 3, 5, and 7), and otherwise it uses a slower general-purpose routine. TEST_F(FFTLengthTest, MeasureExecutionTime) { @@ -160,9 +144,6 @@ TEST_F(FFTLengthTest, MeasureExecutionTime) g2.set_style("points").plot_xy(powers_of_two, execution_times_powers_of_two, "Power of 2"); g2.savetops("FFT_execution_times"); g2.showonscreen(); // window output -#if !defined __APPLE__ - wait_for_key(); -#endif } catch (GnuplotException ge) { From 5b23e29bebb2d5b52288dc2b6be0eaff92062706 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sun, 22 Oct 2017 08:23:19 +0200 Subject: [PATCH 52/81] Fix error --- src/tests/unit-tests/arithmetic/fft_length_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/unit-tests/arithmetic/fft_length_test.cc b/src/tests/unit-tests/arithmetic/fft_length_test.cc index e04455c04..262055600 100644 --- a/src/tests/unit-tests/arithmetic/fft_length_test.cc +++ b/src/tests/unit-tests/arithmetic/fft_length_test.cc @@ -51,7 +51,7 @@ DEFINE_bool(plot_fft_length_test, false, "Plots results of FFTLengthTest with gn // Note from FFTW documentation: the standard FFTW distribution works most efficiently for arrays whose // size can be factored into small primes (2, 3, 5, and 7), and otherwise it uses a slower general-purpose routine. -TEST_F(FFTLengthTest, MeasureExecutionTime) +TEST(FFTLengthTest, MeasureExecutionTime) { unsigned int fft_sizes [] = { 512, 1000, 1024, 1100, 1297, 1400, 1500, 1960, 2000, 2048, 2221, 2500, 3000, 3500, 4000, 4096, 4200, 4500, 4725, 5000, 5500, 6000, 6500, 7000, 7500, 8000, 8192, 8500, 9000, 9500, 10000, 10368, 11000, From b6573b00e69f40c72ded35266bf43cca285e289c Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sun, 22 Oct 2017 08:28:59 +0200 Subject: [PATCH 53/81] Fix persist for Mac --- src/tests/common-files/gnuplot_i.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/tests/common-files/gnuplot_i.h b/src/tests/common-files/gnuplot_i.h index 183e51101..b2c3356cd 100644 --- a/src/tests/common-files/gnuplot_i.h +++ b/src/tests/common-files/gnuplot_i.h @@ -1049,8 +1049,12 @@ Gnuplot& Gnuplot::set_smooth(const std::string &stylestr) // Gnuplot& Gnuplot::showonscreen() { + std::string persist(" persist"); +#ifdef __APPLE__ + persist = ""; +#endif cmd("set output"); - cmd("set terminal " + Gnuplot::terminal_std + " persist"); + cmd("set terminal " + Gnuplot::terminal_std + persist); return *this; } From 785d6185c3db55f2761421f5298e1770a9525b1a Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sun, 22 Oct 2017 08:29:35 +0200 Subject: [PATCH 54/81] Print both plots --- src/tests/unit-tests/arithmetic/fft_length_test.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tests/unit-tests/arithmetic/fft_length_test.cc b/src/tests/unit-tests/arithmetic/fft_length_test.cc index 262055600..d59c5ab0b 100644 --- a/src/tests/unit-tests/arithmetic/fft_length_test.cc +++ b/src/tests/unit-tests/arithmetic/fft_length_test.cc @@ -132,6 +132,7 @@ TEST(FFTLengthTest, MeasureExecutionTime) g1.set_ylabel("Execution time [ms]"); g1.plot_xy(fft_sizes_v, execution_times, "FFT execution time (averaged over " + std::to_string(FLAGS_fft_iterations_test) + " iterations)"); g1.set_style("points").plot_xy(powers_of_two, execution_times_powers_of_two, "Power of 2"); + g1.savetops("FFT_execution_times_extended"); g1.showonscreen(); // window output Gnuplot g2("linespoints"); From 0164d6725d0d4134cb7d6861567a6b8e743ce300 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sun, 22 Oct 2017 09:14:25 +0200 Subject: [PATCH 55/81] Simplify gnuplot interface usage in tests --- src/tests/common-files/gnuplot_i.h | 65 +++++++++---------- src/tests/common-files/test_flags.h | 42 ++++++++++++ .../unit-tests/arithmetic/fft_length_test.cc | 16 ++--- 3 files changed, 78 insertions(+), 45 deletions(-) create mode 100644 src/tests/common-files/test_flags.h diff --git a/src/tests/common-files/gnuplot_i.h b/src/tests/common-files/gnuplot_i.h index b2c3356cd..7417286cb 100644 --- a/src/tests/common-files/gnuplot_i.h +++ b/src/tests/common-files/gnuplot_i.h @@ -3,7 +3,7 @@ * \brief A C++ interface to gnuplot. * \author Carles Fernandez-Prades, 2017. cfernandez(at)cttc.es * - * Source code found at https://code.google.com/archive/p/gnuplot-cpp/ + * Original source code found at https://code.google.com/archive/p/gnuplot-cpp/ * by Jeremy Conlin jeremit0(at)gmail.com * * Version history: @@ -16,6 +16,8 @@ * 3. some member functions added, corrections for Win32 and Linux * compatibility * by M. Burgis (10/03/08) + * 4. Some fixes and improvements for Linux and macOS + * by C. Fernandez (22/10/17) * ------------------------------------------------------------------------- * * Copyright (C) 2013-2017 (see AUTHORS file for a list of contributors) @@ -120,7 +122,8 @@ private: /// /// \return <-- void // --------------------------------------------------- - void init(); + void init(); + // --------------------------------------------------- ///\brief creates tmpfile and returns its name /// @@ -128,7 +131,7 @@ private: /// /// \return <-- the name of the tempfile // --------------------------------------------------- - std::string create_tmpfile(std::ofstream &tmp); + std::string create_tmpfile(std::ofstream &tmp); //---------------------------------------------------------------------------------- ///\brief gnuplot path found? @@ -137,7 +140,7 @@ private: /// /// \return <-- found the gnuplot path (yes == true, no == false) // --------------------------------------------------------------------------------- - static bool get_program_path(); + static bool get_program_path(); // --------------------------------------------------------------------------------- ///\brief checks if file is available @@ -157,7 +160,7 @@ private: /// /// \return file exists (yes == true, no == false) // --------------------------------------------------------------------------------- - static bool file_exists(const std::string &filename, int mode=0); + static bool file_exists(const std::string &filename, int mode=0); public: // ---------------------------------------------------------------------------- @@ -228,7 +231,8 @@ public: /// /// \return <-- a reference to the gnuplot object // --------------------------------------------------------------------------------- - inline Gnuplot& operator<<(const std::string &cmdstr){ + inline Gnuplot& operator<<(const std::string &cmdstr) + { cmd(cmdstr); return(*this); } @@ -270,9 +274,9 @@ public: Gnuplot& set_pointsize(const double pointsize = 1.0); /// turns grid on/off - inline Gnuplot& set_grid() {cmd("set grid");return *this;}; + inline Gnuplot& set_grid() {cmd("set grid"); return *this;}; /// grid is not set by default - inline Gnuplot& unset_grid(){cmd("unset grid");return *this;}; + inline Gnuplot& unset_grid(){cmd("unset grid"); return *this;}; // ----------------------------------------------- /// set the mulitplot mode @@ -281,7 +285,7 @@ public: /// /// \return <-- reference to the gnuplot object // ----------------------------------------------- - inline Gnuplot& set_multiplot(){cmd("set multiplot") ;return *this;}; + inline Gnuplot& set_multiplot(){cmd("set multiplot") ; return *this;}; // ----------------------------------------------- /// unsets the mulitplot mode @@ -290,7 +294,7 @@ public: /// /// \return <-- reference to the gnuplot object // ----------------------------------------------- - inline Gnuplot& unset_multiplot(){cmd("unset multiplot");return *this;}; + inline Gnuplot& unset_multiplot(){cmd("unset multiplot"); return *this;}; /// set sampling rate of functions, or for interpolating data Gnuplot& set_samples(const int samples = 100); @@ -304,7 +308,7 @@ public: /// /// \return <-- reference to the gnuplot object // -------------------------------------------------------------------------- - Gnuplot& set_hidden3d(){cmd("set hidden3d");return *this;}; + Gnuplot& set_hidden3d(){cmd("set hidden3d"); return *this;}; // --------------------------------------------------------------------------- /// hidden3d is not set by default @@ -325,7 +329,7 @@ public: /// /// \return <-- reference to the gnuplot object // ------------------------------------------------------------------ - inline Gnuplot& unset_contour(){cmd("unset contour");return *this;}; + inline Gnuplot& unset_contour(){cmd("unset contour"); return *this;}; // ------------------------------------------------------------ /// enables/disables the display of surfaces (for 3d plot) @@ -334,7 +338,7 @@ public: /// /// \return <-- reference to the gnuplot object // ------------------------------------------------------------------ - inline Gnuplot& set_surface(){cmd("set surface");return *this;}; + inline Gnuplot& set_surface(){cmd("set surface"); return *this;}; // ---------------------------------------------------------- /// surface is set by default, @@ -386,7 +390,7 @@ public: /// /// \return <-- reference to the gnuplot object // --------------------------------------------------------------------------------- - inline Gnuplot& unset_title(){this->set_title();return *this;} + inline Gnuplot& unset_title(){this->set_title(); return *this;} /// set x axis label Gnuplot& set_ylabel(const std::string &label = "x"); @@ -396,21 +400,19 @@ public: Gnuplot& set_zlabel(const std::string &label = "z"); /// set axis - ranges - Gnuplot& set_xrange(const double iFrom, - const double iTo); + Gnuplot& set_xrange(const double iFrom, const double iTo); /// set y-axis - ranges - Gnuplot& set_yrange(const double iFrom, - const double iTo); + Gnuplot& set_yrange(const double iFrom, const double iTo); /// set z-axis - ranges - Gnuplot& set_zrange(const double iFrom, - const double iTo); + Gnuplot& set_zrange(const double iFrom, const double iTo); + /// autoscale axis (set by default) of xaxis /// /// \param --- /// /// \return <-- reference to the gnuplot object // ----------------------------------------------- - inline Gnuplot& set_xautoscale(){cmd("set xrange restore");cmd("set autoscale x");return *this;}; + inline Gnuplot& set_xautoscale(){cmd("set xrange restore"); cmd("set autoscale x"); return *this;}; // ----------------------------------------------- /// autoscale axis (set by default) of yaxis @@ -419,7 +421,7 @@ public: /// /// \return <-- reference to the gnuplot object // ----------------------------------------------- - inline Gnuplot& set_yautoscale(){cmd("set yrange restore");cmd("set autoscale y");return *this;}; + inline Gnuplot& set_yautoscale(){cmd("set yrange restore"); cmd("set autoscale y"); return *this;}; // ----------------------------------------------- /// autoscale axis (set by default) of zaxis @@ -428,7 +430,7 @@ public: /// /// \return <-- reference to the gnuplot object // ----------------------------------------------- - inline Gnuplot& set_zautoscale(){cmd("set zrange restore");cmd("set autoscale z");return *this;}; + inline Gnuplot& set_zautoscale(){cmd("set zrange restore"); cmd("set autoscale z"); return *this;}; /// turns on/off log scaling for the specified xaxis (logscale is not set by default) Gnuplot& set_xlogscale(const double base = 10); @@ -531,13 +533,11 @@ public: /// special functions: erf(x), erfc(x), inverf(x), gamma(x), igamma(a,x), lgamma(x), ibeta(p,q,x), /// besj0(x), besj1(x), besy0(x), besy1(x), lambertw(x) /// statistical fuctions: norm(x), invnorm(x) - Gnuplot& plot_equation(const std::string &equation, - const std::string &title = ""); + Gnuplot& plot_equation(const std::string &equation, const std::string &title = ""); /// plot an equation supplied as a std::string z=f(x,y), write only the function f(x,y) not z= /// the independent variables have to be x and y - Gnuplot& plot_equation3d(const std::string &equation, - const std::string &title = ""); + Gnuplot& plot_equation3d(const std::string &equation, const std::string &title = ""); /// plot image Gnuplot& plot_image(const unsigned char *ucPicBuf, @@ -554,7 +554,7 @@ public: /// /// \return --- //---------------------------------------------------------------------------------- - inline Gnuplot& replot(void){if (nplots > 0) cmd("replot");return *this;}; + inline Gnuplot& replot(void){if (nplots > 0) cmd("replot"); return *this;}; /// resets a gnuplot session (next plot will erase previous ones) Gnuplot& reset_plot(); @@ -604,7 +604,7 @@ std::string Gnuplot::terminal_std = "aqua"; // constructor: set a style during construction // inline Gnuplot::Gnuplot(const std::string &style) -:gnucmd(NULL) ,valid(false) ,two_dim(false) ,nplots(0) +:gnucmd(NULL), valid(false), two_dim(false), nplots(0) { init(); @@ -621,7 +621,7 @@ inline Gnuplot::Gnuplot(const std::vector &x, const std::string &style, const std::string &labelx, const std::string &labely) -:gnucmd(NULL) ,valid(false) ,two_dim(false) ,nplots(0) +:gnucmd(NULL), valid(false), two_dim(false), nplots(0) { init(); @@ -643,7 +643,7 @@ inline Gnuplot::Gnuplot(const std::vector &x, const std::string &style, const std::string &labelx, const std::string &labely) -:gnucmd(NULL) ,valid(false) ,two_dim(false) ,nplots(0) +:gnucmd(NULL), valid(false), two_dim(false), nplots(0) { init(); @@ -667,7 +667,7 @@ inline Gnuplot::Gnuplot(const std::vector &x, const std::string &labelx, const std::string &labely, const std::string &labelz) -:gnucmd(NULL) ,valid(false) ,two_dim(false) ,nplots(0) +:gnucmd(NULL), valid(false), two_dim(false), nplots(0) { init(); @@ -844,7 +844,6 @@ Gnuplot& Gnuplot::plot_xyz(const X &x, // bool Gnuplot::set_GNUPlotPath(const std::string &path) { - std::string tmp = path + "/" + Gnuplot::m_sGNUPlotFileName; #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) diff --git a/src/tests/common-files/test_flags.h b/src/tests/common-files/test_flags.h new file mode 100644 index 000000000..424d0e7bc --- /dev/null +++ b/src/tests/common-files/test_flags.h @@ -0,0 +1,42 @@ +/*! + * \file test_flags.h + * \brief Helper file for unit testing + * \author Carles Fernandez-Prades, 2017. cfernandez(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_TEST_FLAGS_H_ +#define GNSS_SDR_TEST_FLAGS_H_ + +#include + +#if defined GNUPLOT_EXECUTABLE + DEFINE_string(gnuplot_executable, std::string(GNUPLOT_EXECUTABLE), "Gnuplot binary path"); +#elif !defined GNUPLOT_EXECUTABLE + DEFINE_string(gnuplot_executable, "", "Gnuplot binary path"); +#endif + +#endif diff --git a/src/tests/unit-tests/arithmetic/fft_length_test.cc b/src/tests/unit-tests/arithmetic/fft_length_test.cc index d59c5ab0b..3ccb2b640 100644 --- a/src/tests/unit-tests/arithmetic/fft_length_test.cc +++ b/src/tests/unit-tests/arithmetic/fft_length_test.cc @@ -35,14 +35,8 @@ #include #include #include - - -#if defined GNUPLOT_EXECUTABLE - #include "gnuplot_i.h" - const bool exists_gnuplot_fft_test_length = true; -#elif !defined GNUPLOT_EXECUTABLE - const bool exists_gnuplot_fft_test_length = false; -#endif +#include "gnuplot_i.h" +#include "test_flags.h" DEFINE_int32(fft_iterations_test, 1000, "Number of averaged iterations in FFT length timing test"); @@ -108,7 +102,8 @@ TEST(FFTLengthTest, MeasureExecutionTime) if(FLAGS_plot_fft_length_test == true) { - if(!exists_gnuplot_fft_test_length) + const std::string gnuplot_executable(FLAGS_gnuplot_executable); + if(gnuplot_executable.empty()) { std::cout << "WARNING: Although the flag plot_fft_length_test has been set to TRUE," << std::endl; std::cout << "gnuplot has not been found in your system." << std::endl; @@ -116,10 +111,8 @@ TEST(FFTLengthTest, MeasureExecutionTime) } else { -#if defined GNUPLOT_EXECUTABLE try { - std::string gnuplot_executable = std::string(GNUPLOT_EXECUTABLE); boost::filesystem::path p(gnuplot_executable); boost::filesystem::path dir = p.parent_path(); std::string gnuplot_path = dir.native(); @@ -150,7 +143,6 @@ TEST(FFTLengthTest, MeasureExecutionTime) { std::cout << ge.what() << std::endl; } -#endif } } } From 4d7f93fd43cbf3bb4619b6654efb0019cbeb4b64 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sun, 22 Oct 2017 18:05:02 +0200 Subject: [PATCH 56/81] Add plot of precision results --- src/tests/common-files/gnuplot_i.h | 36 +++++++++++- src/tests/system-tests/position_test.cc | 77 +++++++++++++++++++++++++ 2 files changed, 112 insertions(+), 1 deletion(-) diff --git a/src/tests/common-files/gnuplot_i.h b/src/tests/common-files/gnuplot_i.h index 7417286cb..ef5dbb241 100644 --- a/src/tests/common-files/gnuplot_i.h +++ b/src/tests/common-files/gnuplot_i.h @@ -545,6 +545,9 @@ public: const unsigned int iHeight, const std::string &title = ""); + /// plot circle + Gnuplot& plot_circle(double east, double north, double radius, const std::string &label = ""); + //---------------------------------------------------------------------------------- ///\brief replot repeats the last plot or splot command. /// this can be useful for viewing a plot with different set options, @@ -937,7 +940,8 @@ Gnuplot::~Gnuplot() #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__) if (pclose(gnucmd) == -1) #endif - throw GnuplotException("Problem closing communication to gnuplot"); + // throw GnuplotException("Problem closing communication to gnuplot"); + std::cout << "Gnuplot window left open." << std::endl; } @@ -1634,6 +1638,36 @@ Gnuplot& Gnuplot::plot_image(const unsigned char * ucPicBuf, } +Gnuplot& Gnuplot::plot_circle(double east, double north, double radius, const std::string &label) +{ + std::ostringstream cmdstr; + // + // command to be sent to gnuplot + // + cmdstr << "set object circle at " + std::to_string(east) + "," + std::to_string(north) + " size " + + std::to_string(radius) + " back\n"; + + if (label != "") + { + double east_label = (std::cos(M_PI / 3.0) * radius) * 1.1 + east; + double north_label = (std::sin(M_PI / 3.0) * radius) * 1.1 + north; + cmdstr << "set label \"" + label + "\" at first " + std::to_string(east_label) + + ", " + std::to_string(north_label) + " norotate back nopoint offset 0,0\n"; + } + if (nplots > 0) + cmdstr << "replot "; + else + cmdstr << "plot "; + + // + // Do the actual plot + // + cmd(cmdstr.str()); + + return *this; +} + + //------------------------------------------------------------------------------ // diff --git a/src/tests/system-tests/position_test.cc b/src/tests/system-tests/position_test.cc index 5b14d0e62..bf85b6b50 100644 --- a/src/tests/system-tests/position_test.cc +++ b/src/tests/system-tests/position_test.cc @@ -29,11 +29,13 @@ * ------------------------------------------------------------------------- */ +#include #include #include #include #include #include +#include #include #include #include @@ -43,10 +45,13 @@ #include "in_memory_configuration.h" #include "file_configuration.h" #include "MATH_CONSTANTS.h" +#include "gnuplot_i.h" +#include "test_flags.h" #include "signal_generator_flags.h" DEFINE_string(config_file_ptest, std::string(""), "File containing the configuration parameters for the position test."); +DEFINE_bool(plot_position_test, false, "Plots results of FFTLengthTest with gnuplot"); // For GPS NAVIGATION (L1) concurrent_queue global_gps_acq_assist_queue; @@ -73,6 +78,9 @@ public: int configure_receiver(); int run_receiver(); void check_results(); + void print_results(const std::vector & east, + const std::vector & north, + const std::vector & up); double compute_stdev_precision(const std::vector & vec); double compute_stdev_accuracy(const std::vector & vec, double ref); @@ -542,9 +550,78 @@ void StaticPositionSystemTest::check_results() // Sanity Check double precision_SEP = 0.51 * (sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision); ASSERT_LT(precision_SEP, 20.0); + + if(FLAGS_plot_position_test == true) + { + print_results(pos_e, pos_n, pos_u); + } } +void StaticPositionSystemTest::print_results(const std::vector & east, + const std::vector & north, + const std::vector & up) +{ + const std::string gnuplot_executable(FLAGS_gnuplot_executable); + if(gnuplot_executable.empty()) + { + std::cout << "WARNING: Although the flag plot_position_test has been set to TRUE," << std::endl; + std::cout << "gnuplot has not been found in your system." << std::endl; + std::cout << "Test results will not be plotted." << std::endl; + } + else + { + double sigma_E_2_precision = std::pow(compute_stdev_precision(east), 2.0); + double sigma_N_2_precision = std::pow(compute_stdev_precision(north), 2.0); + double sigma_U_2_precision = std::pow(compute_stdev_precision(up), 2.0); + + double mean_east = std::accumulate(east.begin(), east.end(), 0.0) / east.size(); + double mean_north = std::accumulate(north.begin(), north.end(), 0.0) / north.size(); + + auto it_max_east = std::max_element(std::begin(east), std::end(east)); + auto it_min_east = std::min_element(std::begin(east), std::end(east)); + auto it_max_north = std::max_element(std::begin(north), std::end(north)); + auto it_min_north = std::min_element(std::begin(north), std::end(north)); + + auto east_range = std::max(*it_max_east, std::abs(*it_min_east)); + auto north_range = std::max(*it_max_north, std::abs(*it_min_north)); + + double range = std::max(east_range, north_range) * 1.1; + + double two_drms = 2 * sqrt(sigma_E_2_precision + sigma_N_2_precision); + try + { + boost::filesystem::path p(gnuplot_executable); + boost::filesystem::path dir = p.parent_path(); + std::string gnuplot_path = dir.native(); + Gnuplot::set_GNUPlotPath(gnuplot_path); + + Gnuplot g1("points"); + g1.set_title("2D precision"); + g1.set_xlabel("East [m]"); + g1.set_ylabel("North [m]"); + g1.cmd("set size ratio -1"); + g1.cmd("set xrange [-" + std::to_string(range) + ":" + std::to_string(range) + "]"); + g1.cmd("set yrange [-" + std::to_string(range) + ":" + std::to_string(range) + "]"); + + g1.plot_xy(east, north, "2D Position Fixes"); + g1.set_style("lines").plot_circle(mean_east, mean_north, two_drms, "2DRMS"); + g1.set_style("lines").plot_circle(mean_east, mean_north, two_drms / 2.0, "DRMS"); + + g1.cmd("set grid front"); + g1.cmd("replot"); + + g1.savetops("Position_test_2D"); + g1.showonscreen(); // window output + } + catch (GnuplotException ge) + { + std::cout << ge.what() << std::endl; + } + } + +} + TEST_F(StaticPositionSystemTest, Position_system_test) { if(FLAGS_config_file_ptest.empty()) From d73825ebef4ebd334f79f1bab36e8703db118730 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sun, 22 Oct 2017 19:39:16 +0200 Subject: [PATCH 57/81] Add 3d plot to position test --- src/tests/system-tests/position_test.cc | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/tests/system-tests/position_test.cc b/src/tests/system-tests/position_test.cc index bf85b6b50..64401bb00 100644 --- a/src/tests/system-tests/position_test.cc +++ b/src/tests/system-tests/position_test.cc @@ -582,13 +582,18 @@ void StaticPositionSystemTest::print_results(const std::vector & east, auto it_min_east = std::min_element(std::begin(east), std::end(east)); auto it_max_north = std::max_element(std::begin(north), std::end(north)); auto it_min_north = std::min_element(std::begin(north), std::end(north)); + auto it_max_up = std::max_element(std::begin(up), std::end(up)); + auto it_min_up = std::min_element(std::begin(up), std::end(up)); auto east_range = std::max(*it_max_east, std::abs(*it_min_east)); auto north_range = std::max(*it_max_north, std::abs(*it_min_north)); + auto up_range = std::max(*it_max_up, std::abs(*it_min_up)); double range = std::max(east_range, north_range) * 1.1; + double range_3d = std::max(std::max(east_range, north_range), up_range) * 1.1; double two_drms = 2 * sqrt(sigma_E_2_precision + sigma_N_2_precision); + double ninty_sas = 0.833 * (sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision); try { boost::filesystem::path p(gnuplot_executable); @@ -613,6 +618,25 @@ void StaticPositionSystemTest::print_results(const std::vector & east, g1.savetops("Position_test_2D"); g1.showonscreen(); // window output + + Gnuplot g2("points"); + g2.set_title("3D precision"); + g2.set_xlabel("East [m]"); + g2.set_ylabel("North [m]"); + g2.set_zlabel("Up [m]"); + g2.cmd("set size ratio -1"); + g2.cmd("set xrange [-" + std::to_string(range_3d) + ":" + std::to_string(range_3d) + "]"); + g2.cmd("set yrange [-" + std::to_string(range_3d) + ":" + std::to_string(range_3d) + "]"); + g2.cmd("set zrange [-" + std::to_string(range_3d) + ":" + std::to_string(range_3d) + "]"); + g2.cmd("set view equal xyz"); + + g2.cmd("set style fill transparent solid 0.30 border\n set parametric\n set urange [0:2.0*pi]\n set vrange [-pi/2:pi/2]\n r = " + + std::to_string(ninty_sas) + + "\n fx(v,u) = r*cos(v)*cos(u)\n fy(v,u) = r*cos(v)*sin(u)\n fz(v) = r*sin(v) \n splot fx(v,u),fy(v,u),fz(v) title \"90\%-SAS\" lt rgb \"gray\"\n"); + g2.plot_xyz(east, north, up, "3D Position Fixes"); + + g2.savetops("Position_test_3D"); + g2.showonscreen(); // window output } catch (GnuplotException ge) { From 32dde633486e5a103492eb4873a1ddb3b968af9d Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sun, 22 Oct 2017 22:33:27 +0200 Subject: [PATCH 58/81] Save figures in pdf format --- src/tests/common-files/gnuplot_i.h | 19 +++++++++++++++++++ src/tests/system-tests/position_test.cc | 2 ++ .../unit-tests/arithmetic/fft_length_test.cc | 2 ++ 3 files changed, 23 insertions(+) diff --git a/src/tests/common-files/gnuplot_i.h b/src/tests/common-files/gnuplot_i.h index ef5dbb241..25ae7b681 100644 --- a/src/tests/common-files/gnuplot_i.h +++ b/src/tests/common-files/gnuplot_i.h @@ -246,6 +246,9 @@ public: /// saves a gnuplot session to a postscript file, filename without extension Gnuplot& savetops(const std::string &filename = "gnuplot_output"); + /// saves a gnuplot session to a pdf file, filename without extension + Gnuplot& savetopdf(const std::string &filename = "gnuplot_output"); + //---------------------------------------------------------------------------------- // set and unset @@ -1063,6 +1066,22 @@ Gnuplot& Gnuplot::showonscreen() } +//------------------------------------------------------------------------------ +// +// saves a gnuplot session to a pdf file +// +Gnuplot& Gnuplot::savetopdf(const std::string &filename) +{ + std::ostringstream cmdstr; + cmdstr << "set term pdfcairo enhanced color font \"Times-New-Roman,18\"\n"; + cmdstr << "set output \"" << filename << ".pdf\"\n"; + cmdstr << "replot"; + cmd(cmdstr.str()); + + return *this; +} + + //------------------------------------------------------------------------------ // // saves a gnuplot session to a postscript file diff --git a/src/tests/system-tests/position_test.cc b/src/tests/system-tests/position_test.cc index 64401bb00..c1705eca1 100644 --- a/src/tests/system-tests/position_test.cc +++ b/src/tests/system-tests/position_test.cc @@ -617,6 +617,7 @@ void StaticPositionSystemTest::print_results(const std::vector & east, g1.cmd("replot"); g1.savetops("Position_test_2D"); + g1.savetopdf("Position_test_2D"); g1.showonscreen(); // window output Gnuplot g2("points"); @@ -636,6 +637,7 @@ void StaticPositionSystemTest::print_results(const std::vector & east, g2.plot_xyz(east, north, up, "3D Position Fixes"); g2.savetops("Position_test_3D"); + g2.savetopdf("Position_test_3D"); g2.showonscreen(); // window output } catch (GnuplotException ge) diff --git a/src/tests/unit-tests/arithmetic/fft_length_test.cc b/src/tests/unit-tests/arithmetic/fft_length_test.cc index 3ccb2b640..0448fc114 100644 --- a/src/tests/unit-tests/arithmetic/fft_length_test.cc +++ b/src/tests/unit-tests/arithmetic/fft_length_test.cc @@ -126,6 +126,7 @@ TEST(FFTLengthTest, MeasureExecutionTime) g1.plot_xy(fft_sizes_v, execution_times, "FFT execution time (averaged over " + std::to_string(FLAGS_fft_iterations_test) + " iterations)"); g1.set_style("points").plot_xy(powers_of_two, execution_times_powers_of_two, "Power of 2"); g1.savetops("FFT_execution_times_extended"); + g1.savetopdf("FFT_execution_times_extended"); g1.showonscreen(); // window output Gnuplot g2("linespoints"); @@ -137,6 +138,7 @@ TEST(FFTLengthTest, MeasureExecutionTime) g2.plot_xy(fft_sizes_v, execution_times, "FFT execution time (averaged over " + std::to_string(FLAGS_fft_iterations_test) + " iterations)"); g2.set_style("points").plot_xy(powers_of_two, execution_times_powers_of_two, "Power of 2"); g2.savetops("FFT_execution_times"); + g2.savetopdf("FFT_execution_times"); g2.showonscreen(); // window output } catch (GnuplotException ge) From d86158a94ae0c22b9730ebbaa37cea3606d04b6c Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sun, 22 Oct 2017 23:04:39 +0200 Subject: [PATCH 59/81] Adjust font size in pdf files --- src/tests/common-files/gnuplot_i.h | 6 +++--- src/tests/system-tests/position_test.cc | 2 +- src/tests/unit-tests/arithmetic/fft_length_test.cc | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tests/common-files/gnuplot_i.h b/src/tests/common-files/gnuplot_i.h index 25ae7b681..614dc678e 100644 --- a/src/tests/common-files/gnuplot_i.h +++ b/src/tests/common-files/gnuplot_i.h @@ -247,7 +247,7 @@ public: Gnuplot& savetops(const std::string &filename = "gnuplot_output"); /// saves a gnuplot session to a pdf file, filename without extension - Gnuplot& savetopdf(const std::string &filename = "gnuplot_output"); + Gnuplot& savetopdf(const std::string &filename = "gnuplot_output", unsigned int font_size = 12); //---------------------------------------------------------------------------------- // set and unset @@ -1070,10 +1070,10 @@ Gnuplot& Gnuplot::showonscreen() // // saves a gnuplot session to a pdf file // -Gnuplot& Gnuplot::savetopdf(const std::string &filename) +Gnuplot& Gnuplot::savetopdf(const std::string &filename, unsigned int font_size) { std::ostringstream cmdstr; - cmdstr << "set term pdfcairo enhanced color font \"Times-New-Roman,18\"\n"; + cmdstr << "set term pdfcairo enhanced color font \"Times-New-Roman," + std::to_string(font_size) + "\"\n"; cmdstr << "set output \"" << filename << ".pdf\"\n"; cmdstr << "replot"; cmd(cmdstr.str()); diff --git a/src/tests/system-tests/position_test.cc b/src/tests/system-tests/position_test.cc index c1705eca1..048abefea 100644 --- a/src/tests/system-tests/position_test.cc +++ b/src/tests/system-tests/position_test.cc @@ -617,7 +617,7 @@ void StaticPositionSystemTest::print_results(const std::vector & east, g1.cmd("replot"); g1.savetops("Position_test_2D"); - g1.savetopdf("Position_test_2D"); + g1.savetopdf("Position_test_2D", 18); g1.showonscreen(); // window output Gnuplot g2("points"); diff --git a/src/tests/unit-tests/arithmetic/fft_length_test.cc b/src/tests/unit-tests/arithmetic/fft_length_test.cc index 0448fc114..f8ea83d22 100644 --- a/src/tests/unit-tests/arithmetic/fft_length_test.cc +++ b/src/tests/unit-tests/arithmetic/fft_length_test.cc @@ -126,7 +126,7 @@ TEST(FFTLengthTest, MeasureExecutionTime) g1.plot_xy(fft_sizes_v, execution_times, "FFT execution time (averaged over " + std::to_string(FLAGS_fft_iterations_test) + " iterations)"); g1.set_style("points").plot_xy(powers_of_two, execution_times_powers_of_two, "Power of 2"); g1.savetops("FFT_execution_times_extended"); - g1.savetopdf("FFT_execution_times_extended"); + g1.savetopdf("FFT_execution_times_extended", 18); g1.showonscreen(); // window output Gnuplot g2("linespoints"); @@ -138,7 +138,7 @@ TEST(FFTLengthTest, MeasureExecutionTime) g2.plot_xy(fft_sizes_v, execution_times, "FFT execution time (averaged over " + std::to_string(FLAGS_fft_iterations_test) + " iterations)"); g2.set_style("points").plot_xy(powers_of_two, execution_times_powers_of_two, "Power of 2"); g2.savetops("FFT_execution_times"); - g2.savetopdf("FFT_execution_times"); + g2.savetopdf("FFT_execution_times", 18); g2.showonscreen(); // window output } catch (GnuplotException ge) From d1ed8a963c4e982e0d09b2583db92111da40a68d Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Mon, 23 Oct 2017 19:25:41 +0200 Subject: [PATCH 60/81] Add plot of correlators\' output --- .../gps_l1_ca_dll_pll_tracking_test.cc | 78 ++++++++++++++++--- 1 file changed, 66 insertions(+), 12 deletions(-) diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc index 894afe228..14678be4a 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc @@ -30,10 +30,12 @@ * ------------------------------------------------------------------------- */ - +#include #include #include +#include #include +#include #include #include #include @@ -53,6 +55,10 @@ #include "tracking_true_obs_reader.h" #include "tracking_dump_reader.h" #include "signal_generator_flags.h" +#include "gnuplot_i.h" +#include "test_flags.h" + +DEFINE_bool(plot_gps_l1_tracking_test, false, "Plots results of GpsL1CADllPllTrackingTest with gnuplot"); // ######## GNURADIO BLOCK MESSAGE RECEVER ######### @@ -358,9 +364,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) generate_signal(); } - struct timeval tv; - long long int begin = 0; - long long int end = 0; + std::chrono::time_point start, end; configure_receiver(); @@ -427,11 +431,9 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) tracking->start_tracking(); EXPECT_NO_THROW( { - gettimeofday(&tv, NULL); - begin = tv.tv_sec * 1000000 + tv.tv_usec; + start = std::chrono::system_clock::now(); top_block->run(); // Start threads and wait - gettimeofday(&tv, NULL); - end = tv.tv_sec * 1000000 + tv.tv_usec; + end = std::chrono::system_clock::now(); }) << "Failure running the top_block." << std::endl; //check results @@ -461,7 +463,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) ASSERT_NO_THROW({ if (trk_dump.open_obs_file(std::string("./tracking_ch_0.dat")) == false) { - + throw std::exception(); }; }) << "Failure opening tracking dump file" << std::endl; @@ -473,7 +475,11 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) arma::vec trk_acc_carrier_phase_cycles = arma::zeros(nepoch, 1); arma::vec trk_Doppler_Hz = arma::zeros(nepoch, 1); arma::vec trk_prn_delay_chips = arma::zeros(nepoch, 1); - + + std::vector prompt; + std::vector early; + std::vector late; + epoch_counter = 0; while(trk_dump.read_binary_obs()) { @@ -486,6 +492,9 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) trk_prn_delay_chips(epoch_counter) = delay_chips; epoch_counter++; + prompt.push_back(trk_dump.abs_P); + early.push_back(trk_dump.abs_E); + late.push_back(trk_dump.abs_L); } //Align initial measurements and cut the tracking pull-in transitory @@ -501,6 +510,51 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) check_results_codephase(true_timestamp_s, true_prn_delay_chips, trk_timestamp_s, trk_prn_delay_chips); check_results_acc_carrier_phase(true_timestamp_s, true_acc_carrier_phase_cycles, trk_timestamp_s, trk_acc_carrier_phase_cycles); - std::cout << "Signal tracking completed in " << (end - begin) << " microseconds" << std::endl; -} + std::chrono::duration elapsed_seconds = end - start; + std::cout << "Signal tracking completed in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; + if(FLAGS_plot_gps_l1_tracking_test == true) + { + const std::string gnuplot_executable(FLAGS_gnuplot_executable); + if(gnuplot_executable.empty()) + { + std::cout << "WARNING: Although the flag plot_gps_l1_tracking_test has been set to TRUE," << std::endl; + std::cout << "gnuplot has not been found in your system." << std::endl; + std::cout << "Test results will not be plotted." << std::endl; + } + else + { + try + { + boost::filesystem::path p(gnuplot_executable); + boost::filesystem::path dir = p.parent_path(); + std::string gnuplot_path = dir.native(); + Gnuplot::set_GNUPlotPath(gnuplot_path); + + std::vector timevec; + //sample_interval = (1 / baseband_sampling_freq) + double t = 0.0; + for (auto it = prompt.begin(); it != prompt.end(); it++) + { + timevec.push_back(t); + t = t + GPS_L1_CA_CODE_PERIOD; + } + Gnuplot g1("linespoints"); + g1.set_title("GPS L1 C/A signal tracking for satellite " + std::to_string(FLAGS_test_satellite_PRN)); + g1.set_grid(); + g1.set_xlabel("Time [s]"); + g1.set_ylabel("Correlators output"); + g1.plot_xy( timevec, prompt, "Prompt"); + g1.plot_xy( timevec, early, "Early"); + g1.plot_xy( timevec, late, "Late"); + g1.savetops("Correlators_outputs"); + g1.savetopdf("Correlators_outputs", 18); + g1.showonscreen(); // window output + } + catch (GnuplotException ge) + { + std::cout << ge.what() << std::endl; + } + } + } +} From 8509b7254a915ac84aabef4b5a9cd2666a028237 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 24 Oct 2017 08:45:13 +0200 Subject: [PATCH 61/81] Add opaque legend --- .../gps_l1_ca_dll_pll_tracking_test.cc | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc index 14678be4a..a41312e8f 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc @@ -103,7 +103,7 @@ void GpsL1CADllPllTrackingTest_msg_rx::msg_handler_events(pmt::pmt_t msg) GpsL1CADllPllTrackingTest_msg_rx::GpsL1CADllPllTrackingTest_msg_rx() : - gr::block("GpsL1CADllPllTrackingTest_msg_rx", gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0)) + gr::block("GpsL1CADllPllTrackingTest_msg_rx", gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0)) { this->message_port_register_in(pmt::mp("events")); this->set_msg_handler(pmt::mp("events"), boost::bind(&GpsL1CADllPllTrackingTest_msg_rx::msg_handler_events, this, _1)); @@ -268,8 +268,8 @@ void GpsL1CADllPllTrackingTest::check_results_doppler(arma::vec & true_time_s, //5. report std::streamsize ss = std::cout.precision(); std::cout << std::setprecision(10) << "TRK Doppler RMSE=" << rmse - << ", mean=" << error_mean - << ", stdev="<< sqrt(error_var) << " (max,min)=" << max_error << "," << min_error << " [Hz]" << std::endl; + << ", mean=" << error_mean + << ", stdev="<< sqrt(error_var) << " (max,min)=" << max_error << "," << min_error << " [Hz]" << std::endl; std::cout.precision (ss); } @@ -526,30 +526,30 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) { try { - boost::filesystem::path p(gnuplot_executable); - boost::filesystem::path dir = p.parent_path(); - std::string gnuplot_path = dir.native(); - Gnuplot::set_GNUPlotPath(gnuplot_path); + boost::filesystem::path p(gnuplot_executable); + boost::filesystem::path dir = p.parent_path(); + std::string gnuplot_path = dir.native(); + Gnuplot::set_GNUPlotPath(gnuplot_path); - std::vector timevec; - //sample_interval = (1 / baseband_sampling_freq) - double t = 0.0; - for (auto it = prompt.begin(); it != prompt.end(); it++) - { - timevec.push_back(t); - t = t + GPS_L1_CA_CODE_PERIOD; - } - Gnuplot g1("linespoints"); - g1.set_title("GPS L1 C/A signal tracking for satellite " + std::to_string(FLAGS_test_satellite_PRN)); - g1.set_grid(); - g1.set_xlabel("Time [s]"); - g1.set_ylabel("Correlators output"); - g1.plot_xy( timevec, prompt, "Prompt"); - g1.plot_xy( timevec, early, "Early"); - g1.plot_xy( timevec, late, "Late"); - g1.savetops("Correlators_outputs"); - g1.savetopdf("Correlators_outputs", 18); - g1.showonscreen(); // window output + std::vector timevec; + double t = 0.0; + for (auto it = prompt.begin(); it != prompt.end(); it++) + { + timevec.push_back(t); + t = t + GPS_L1_CA_CODE_PERIOD; + } + Gnuplot g1("linespoints"); + g1.set_title("GPS L1 C/A signal tracking correlators' output (satellite PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g1.set_grid(); + g1.set_xlabel("Time [s]"); + g1.set_ylabel("Correlators' output"); + g1.cmd("set key box opaque"); + g1.plot_xy( timevec, prompt, "Prompt"); + g1.plot_xy( timevec, early, "Early"); + g1.plot_xy( timevec, late, "Late"); + g1.savetops("Correlators_outputs"); + g1.savetopdf("Correlators_outputs", 18); + g1.showonscreen(); // window output } catch (GnuplotException ge) { From ac99ba5b753d57e47c3105e204692efd5a1a3427 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 24 Oct 2017 11:38:37 +0200 Subject: [PATCH 62/81] Fix exception catching --- .../signal-processing-blocks/libs/tracking_dump_reader.cc | 2 +- .../signal-processing-blocks/libs/tracking_true_obs_reader.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/tracking_dump_reader.cc b/src/tests/unit-tests/signal-processing-blocks/libs/tracking_dump_reader.cc index 9d6e55cdb..368b1ee27 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/tracking_dump_reader.cc +++ b/src/tests/unit-tests/signal-processing-blocks/libs/tracking_dump_reader.cc @@ -54,7 +54,7 @@ bool tracking_dump_reader::read_binary_obs() d_dump_file.read(reinterpret_cast(&aux2), sizeof(double)); d_dump_file.read(reinterpret_cast(&PRN), sizeof(unsigned int)); } - catch (const std::exception &e) + catch (const std::ifstream::failure &e) { return false; } diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/tracking_true_obs_reader.cc b/src/tests/unit-tests/signal-processing-blocks/libs/tracking_true_obs_reader.cc index bd5b2a7fa..bc407fc20 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/tracking_true_obs_reader.cc +++ b/src/tests/unit-tests/signal-processing-blocks/libs/tracking_true_obs_reader.cc @@ -40,7 +40,7 @@ bool tracking_true_obs_reader::read_binary_obs() d_dump_file.read(reinterpret_cast(&prn_delay_chips), sizeof(double)); d_dump_file.read(reinterpret_cast(&tow), sizeof(double)); } - catch (const std::exception &e) + catch (const std::ifstream::failure &e) { return false; } From 2c3ada26f28b134b675a9e781cc92a990fff9b28 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 24 Oct 2017 14:23:59 +0200 Subject: [PATCH 63/81] Add constellation diagram plot --- src/tests/common-files/gnuplot_i.h | 124 +++++++++--------- src/tests/common-files/test_flags.h | 2 + .../gps_l1_ca_dll_pll_tracking_test.cc | 55 +++++--- 3 files changed, 102 insertions(+), 79 deletions(-) diff --git a/src/tests/common-files/gnuplot_i.h b/src/tests/common-files/gnuplot_i.h index 614dc678e..8d1afe8ab 100644 --- a/src/tests/common-files/gnuplot_i.h +++ b/src/tests/common-files/gnuplot_i.h @@ -51,19 +51,19 @@ #include #include #include -#include +#include #include // for std::ostringstream -#include -#include +#include +#include #include // for getenv() #include // for std::list -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) //defined for 32 and 64-bit environments #include // for _access(), _mktemp() #define GP_MAX_TMP_FILES 27 // 27 temporary files it's Microsoft restriction -#elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__) +#elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__) //all UNIX-like OSs (Linux, *BSD, MacOSX, Solaris, ...) #include // for access(), mkstemp() #define GP_MAX_TMP_FILES 64 @@ -266,24 +266,24 @@ public: // ---------------------------------------------------------------------- /// \brief unset smooth /// attention: smooth is not set by default - /// + /// /// \param --- - /// + /// /// \return <-- a reference to a gnuplot object // ---------------------------------------------------------------------- - inline Gnuplot& unset_smooth(){ smooth = ""; return *this;}; + inline Gnuplot& unset_smooth(){ smooth = ""; return *this;}; /// scales the size of the points used in plots Gnuplot& set_pointsize(const double pointsize = 1.0); /// turns grid on/off inline Gnuplot& set_grid() {cmd("set grid"); return *this;}; - /// grid is not set by default + /// grid is not set by default inline Gnuplot& unset_grid(){cmd("unset grid"); return *this;}; // ----------------------------------------------- /// set the mulitplot mode - /// + /// /// \param --- /// /// \return <-- reference to the gnuplot object @@ -292,7 +292,7 @@ public: // ----------------------------------------------- /// unsets the mulitplot mode - /// + /// /// \param --- /// /// \return <-- reference to the gnuplot object @@ -320,7 +320,7 @@ public: /// /// \return <-- reference to the gnuplot object // --------------------------------------------------------------------------- - inline Gnuplot& unset_hidden3d(){cmd("unset hidden3d"); return *this;}; + inline Gnuplot& unset_hidden3d(){cmd("unset hidden3d"); return *this;}; /// enables/disables contour drawing for surfaces (for 3d plot) /// base, surface, both @@ -337,7 +337,7 @@ public: // ------------------------------------------------------------ /// enables/disables the display of surfaces (for 3d plot) /// - /// \param --- + /// \param --- /// /// \return <-- reference to the gnuplot object // ------------------------------------------------------------------ @@ -347,7 +347,7 @@ public: /// surface is set by default, /// it disables the display of surfaces (for 3d plot) /// - /// \param --- + /// \param --- /// /// \return <-- reference to the gnuplot object // ------------------------------------------------------------------ @@ -356,25 +356,25 @@ public: /// switches legend on/off /// position: inside/outside, left/center/right, top/center/bottom, nobox/box - Gnuplot& set_legend(const std::string &position = "default"); + Gnuplot& set_legend(const std::string &position = "default"); // ------------------------------------------------------------------ /// \brief Switches legend off /// attention:legend is set by default /// - /// \param --- + /// \param --- /// /// \return <-- reference to the gnuplot object // ------------------------------------------------------------------ inline Gnuplot& unset_legend(){cmd("unset key"); return *this;} - // ----------------------------------------------------------------------- + // ----------------------------------------------------------------------- /// \brief sets and clears the title of a gnuplot session /// /// \param title --> the title of the plot [optional, default == ""] /// /// \return <-- reference to the gnuplot object - // ----------------------------------------------------------------------- + // ----------------------------------------------------------------------- inline Gnuplot& set_title(const std::string &title = "") { std::string cmdstr; @@ -410,7 +410,7 @@ public: Gnuplot& set_zrange(const double iFrom, const double iTo); /// autoscale axis (set by default) of xaxis - /// + /// /// \param --- /// /// \return <-- reference to the gnuplot object @@ -419,7 +419,7 @@ public: // ----------------------------------------------- /// autoscale axis (set by default) of yaxis - /// + /// /// \param --- /// /// \return <-- reference to the gnuplot object @@ -428,7 +428,7 @@ public: // ----------------------------------------------- /// autoscale axis (set by default) of zaxis - /// + /// /// \param --- /// /// \return <-- reference to the gnuplot object @@ -442,31 +442,31 @@ public: /// turns on/off log scaling for the specified zaxis (logscale is not set by default) Gnuplot& set_zlogscale(const double base = 10); - // ----------------------------------------------- + // ----------------------------------------------- /// turns off log scaling for the x axis - /// + /// /// \param --- /// /// \return <-- reference to the gnuplot object - // ----------------------------------------------- + // ----------------------------------------------- inline Gnuplot& unset_xlogscale(){cmd("unset logscale x"); return *this;}; - // ----------------------------------------------- + // ----------------------------------------------- /// turns off log scaling for the y axis - /// + /// /// \param --- /// /// \return <-- reference to the gnuplot object - // ----------------------------------------------- + // ----------------------------------------------- inline Gnuplot& unset_ylogscale(){cmd("unset logscale y"); return *this;}; - // ----------------------------------------------- + // ----------------------------------------------- /// turns off log scaling for the z axis - /// + /// /// \param --- /// /// \return <-- reference to the gnuplot object - // ----------------------------------------------- + // ----------------------------------------------- inline Gnuplot& unset_zlogscale(){cmd("unset logscale z"); return *this;}; /// set palette range (autoscale by default) @@ -490,10 +490,13 @@ public: Gnuplot& plotfile_xy(const std::string &filename, const unsigned int column_x = 1, const unsigned int column_y = 2, - const std::string &title = ""); + const std::string &title = "", + const unsigned int decimate = 1); /// from data template - Gnuplot& plot_xy(const X& x, const Y& y, const std::string &title = ""); + Gnuplot& plot_xy(const X& x, const Y& y, + const std::string &title = "", + const unsigned int decimate = 1); /// plot x,y pairs with dy errorbars: x y dy /// from file @@ -555,7 +558,7 @@ public: ///\brief replot repeats the last plot or splot command. /// this can be useful for viewing a plot with different set options, /// or when generating the same plot for several devices (showonscreen, savetops) - /// + /// /// \param --- /// /// \return --- @@ -573,12 +576,12 @@ public: // ------------------------------------------------------------------- /// \brief Is the gnuplot session valid ?? - /// + /// /// /// \param --- - /// + /// /// \return true if valid, false if not - // ------------------------------------------------------------------- + // ------------------------------------------------------------------- inline bool is_valid(){return(valid);}; }; @@ -724,7 +727,7 @@ Gnuplot& Gnuplot::plot_x(const X& x, const std::string &title) /// Plots a 2d graph from a list of doubles: x y // template -Gnuplot& Gnuplot::plot_xy(const X& x, const Y& y, const std::string &title) +Gnuplot& Gnuplot::plot_xy(const X& x, const Y& y, const std::string &title, const unsigned int decimate) { if (x.size() == 0 || y.size() == 0) { @@ -752,7 +755,7 @@ Gnuplot& Gnuplot::plot_xy(const X& x, const Y& y, const std::string &title) tmp.flush(); tmp.close(); - plotfile_xy(name, 1, 2, title); + plotfile_xy(name, 1, 2, title, decimate); return *this; } @@ -1483,7 +1486,8 @@ Gnuplot& Gnuplot::plotfile_x(const std::string &filename, Gnuplot& Gnuplot::plotfile_xy(const std::string &filename, const unsigned int column_x, const unsigned int column_y, - const std::string &title) + const std::string &title, + const unsigned int decimate) { // // check if file exists @@ -1499,7 +1503,7 @@ Gnuplot& Gnuplot::plotfile_xy(const std::string &filename, else cmdstr << "plot "; - cmdstr << "\"" << filename << "\" using " << column_x << ":" << column_y; + cmdstr << "\"" << filename << "\" using " << column_x << ":" << column_y << " every " << std::to_string(decimate); if (title == "") cmdstr << " notitle "; @@ -1544,7 +1548,7 @@ Gnuplot& Gnuplot::plotfile_xy_err(const std::string &filename, else cmdstr << "plot "; - cmdstr << "\"" << filename << "\" using " + cmdstr << "\"" << filename << "\" using " << column_x << ":" << column_y << ":" << column_dy << " with errorbars "; @@ -1586,7 +1590,7 @@ Gnuplot& Gnuplot::plotfile_xyz(const std::string &filename, else cmdstr << "splot "; - cmdstr << "\"" << filename << "\" using " << column_x << ":" << column_y + cmdstr << "\"" << filename << "\" using " << column_x << ":" << column_y << ":" << column_z; if (title == "") @@ -1701,15 +1705,15 @@ Gnuplot& Gnuplot::cmd(const std::string &cmdstr) // int fputs ( const char * str, FILE * stream ); // writes the string str to the stream. - // The function begins copying from the address specified (str) until it - // reaches the terminating null character ('\0'). This final + // The function begins copying from the address specified (str) until it + // reaches the terminating null character ('\0'). This final // null-character is not copied to the stream. fputs( (cmdstr+"\n").c_str(), gnucmd ); // int fflush ( FILE * stream ); - // If the given stream was open for writing and the last i/o operation was - // an output operation, any unwritten data in the output buffer is written - // to the file. If the argument is a null pointer, all open files are + // If the given stream was open for writing and the last i/o operation was + // an output operation, any unwritten data in the output buffer is written + // to the file. If the argument is a null pointer, all open files are // flushed. The stream remains open after this call. fflush(gnucmd); @@ -1739,8 +1743,8 @@ Gnuplot& Gnuplot::cmd(const std::string &cmdstr) void Gnuplot::init() { // char * getenv ( const char * name ); get value of environment variable - // Retrieves a C string containing the value of the environment variable - // whose name is specified as argument. If the requested variable is not + // Retrieves a C string containing the value of the environment variable + // whose name is specified as argument. If the requested variable is not // part of the environment list, the function returns a NULL pointer. #if ( defined(unix) || defined(__unix) || defined(__unix__) ) && !defined(__APPLE__) if (getenv("DISPLAY") == NULL) @@ -1760,12 +1764,12 @@ void Gnuplot::init() // // open pipe // - std::string tmp = Gnuplot::m_sGNUPlotPath + "/" + + std::string tmp = Gnuplot::m_sGNUPlotPath + "/" + Gnuplot::m_sGNUPlotFileName; // FILE *popen(const char *command, const char *mode); - // The popen() function shall execute the command specified by the string - // command, create a pipe between the calling program and the executed + // The popen() function shall execute the command specified by the string + // command, create a pipe between the calling program and the executed // command, and return a pointer to a stream that can be used to either read // from or write to the pipe. #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) @@ -1775,7 +1779,7 @@ void Gnuplot::init() #endif // popen() shall return a pointer to an open stream that can be used to read - // or write to the pipe. Otherwise, it shall return a null pointer and may + // or write to the pipe. Otherwise, it shall return a null pointer and may // set errno to indicate the error. if (!gnucmd) { @@ -1803,7 +1807,7 @@ bool Gnuplot::get_program_path() // // first look in m_sGNUPlotPath for Gnuplot // - std::string tmp = Gnuplot::m_sGNUPlotPath + "/" + + std::string tmp = Gnuplot::m_sGNUPlotPath + "/" + Gnuplot::m_sGNUPlotFileName; #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) @@ -1880,7 +1884,7 @@ bool Gnuplot::file_exists(const std::string &filename, int mode) // int _access(const char *path, int mode); // returns 0 if the file has the given mode, - // it returns -1 if the named file does not exist or is not accessible in + // it returns -1 if the named file does not exist or is not accessible in // the given mode // mode = 0 (F_OK) (default): checks file for existence only // mode = 1 (X_OK): execution permission @@ -1952,12 +1956,12 @@ std::string Gnuplot::create_tmpfile(std::ofstream &tmp) // int mkstemp(char *name); // shall replace the contents of the string pointed to by "name" by a unique - // filename, and return a file descriptor for the file open for reading and - // writing. Otherwise, -1 shall be returned if no suitable file could be - // created. The string in template should look like a filename with six - // trailing 'X' s; mkstemp() replaces each 'X' with a character from the + // filename, and return a file descriptor for the file open for reading and + // writing. Otherwise, -1 shall be returned if no suitable file could be + // created. The string in template should look like a filename with six + // trailing 'X' s; mkstemp() replaces each 'X' with a character from the // portable filename character set. The characters are chosen such that the - // resulting name does not duplicate the name of an existing file at the + // resulting name does not duplicate the name of an existing file at the // time of a call to mkstemp() // diff --git a/src/tests/common-files/test_flags.h b/src/tests/common-files/test_flags.h index 424d0e7bc..fac307f84 100644 --- a/src/tests/common-files/test_flags.h +++ b/src/tests/common-files/test_flags.h @@ -39,4 +39,6 @@ DEFINE_string(gnuplot_executable, "", "Gnuplot binary path"); #endif +DEFINE_int32(plot_decimate, 1, "Decimate plots"); + #endif diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc index a41312e8f..21e93139d 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc @@ -32,6 +32,7 @@ #include #include +//#include #include #include #include @@ -50,8 +51,6 @@ #include "tracking_interface.h" #include "in_memory_configuration.h" #include "gnss_synchro.h" -//#include "gps_l1_ca_dll_pll_tracking.h" -#include "gps_l1_ca_dll_pll_c_aid_tracking.h" #include "tracking_true_obs_reader.h" #include "tracking_dump_reader.h" #include "signal_generator_flags.h" @@ -127,6 +126,8 @@ public: std::string p4; std::string p5; + std::string implementation = "GPS_L1_CA_DLL_PLL_Tracking"; //"GPS_L1_CA_DLL_PLL_C_Aid_Tracking"; + const int baseband_sampling_freq = FLAGS_fs_gen_sps; std::string filename_rinex_obs = FLAGS_filename_rinex_obs; @@ -222,14 +223,14 @@ void GpsL1CADllPllTrackingTest::configure_receiver() config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(baseband_sampling_freq)); // Set Tracking - config->set_property("Tracking_1C.implementation", "GPS_L1_CA_DLL_PLL_Tracking"); + config->set_property("Tracking_1C.implementation", implementation); config->set_property("Tracking_1C.item_type", "gr_complex"); - config->set_property("Tracking_1C.if", "0"); - config->set_property("Tracking_1C.dump", "true"); - config->set_property("Tracking_1C.dump_filename", "./tracking_ch_"); - config->set_property("Tracking_1C.pll_bw_hz", "30.0"); + config->set_property("Tracking_1C.pll_bw_hz", "20.0"); config->set_property("Tracking_1C.dll_bw_hz", "2.0"); config->set_property("Tracking_1C.early_late_space_chips", "0.5"); + config->set_property("Tracking_1C.extend_correlation_ms", "1"); + config->set_property("Tracking_1C.dump", "true"); + config->set_property("Tracking_1C.dump_filename", "./tracking_ch_"); } @@ -383,18 +384,17 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) }) << "Failure opening true observables file" << std::endl; top_block = gr::make_top_block("Tracking test"); - //std::shared_ptr tracking = std::make_shared(config.get(), "Tracking_1C", 1, 1); - std::shared_ptr tracking = std::make_shared(config.get(), "Tracking_1C", 1, 1); + + std::shared_ptr trk_ = factory->GetBlock(config, "Tracking_1C", implementation, 1, 1); + std::shared_ptr tracking = std::dynamic_pointer_cast(trk_);//std::make_shared(config.get(), "Tracking_1C", 1, 1); boost::shared_ptr msg_rx = GpsL1CADllPllTrackingTest_msg_rx_make(); // load acquisition data based on the first epoch of the true observations - ASSERT_NO_THROW({ - if (true_obs_data.read_binary_obs() == false) - { - throw std::exception(); - }; - }) << "Failure reading true observables file" << std::endl; + ASSERT_EQ(true_obs_data.read_binary_obs(), true) + << "Failure reading true tracking dump file." << std::endl + << "Maybe sat PRN #" + std::to_string(FLAGS_test_satellite_PRN) + + " is not available?"; //restart the epoch counter true_obs_data.restart(); @@ -479,6 +479,8 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) std::vector prompt; std::vector early; std::vector late; + std::vector promptI; + std::vector promptQ; epoch_counter = 0; while(trk_dump.read_binary_obs()) @@ -495,6 +497,8 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) prompt.push_back(trk_dump.abs_P); early.push_back(trk_dump.abs_E); late.push_back(trk_dump.abs_L); + promptI.push_back(trk_dump.prompt_I); + promptQ.push_back(trk_dump.prompt_Q); } //Align initial measurements and cut the tracking pull-in transitory @@ -511,7 +515,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) check_results_acc_carrier_phase(true_timestamp_s, true_acc_carrier_phase_cycles, trk_timestamp_s, trk_acc_carrier_phase_cycles); std::chrono::duration elapsed_seconds = end - start; - std::cout << "Signal tracking completed in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; + std::cout << "Signal tracking completed in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; if(FLAGS_plot_gps_l1_tracking_test == true) { @@ -544,12 +548,25 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) g1.set_xlabel("Time [s]"); g1.set_ylabel("Correlators' output"); g1.cmd("set key box opaque"); - g1.plot_xy( timevec, prompt, "Prompt"); - g1.plot_xy( timevec, early, "Early"); - g1.plot_xy( timevec, late, "Late"); + unsigned int decimate = static_cast(FLAGS_plot_decimate); + g1.plot_xy( timevec, prompt, "Prompt", decimate); + g1.plot_xy( timevec, early, "Early", decimate); + g1.plot_xy( timevec, late, "Late", decimate); g1.savetops("Correlators_outputs"); g1.savetopdf("Correlators_outputs", 18); g1.showonscreen(); // window output + + Gnuplot g2("points"); + g2.set_title("Constellation diagram (satellite PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g2.set_grid(); + g2.set_xlabel("Inphase"); + g2.set_ylabel("Quadrature"); + g2.cmd("set size ratio -1"); + g2.plot_xy( promptI, promptQ); + g2.savetops("Constellation"); + g2.savetopdf("Constellation", 18); + g2.showonscreen(); // window output + } catch (GnuplotException ge) { From 218c23000b053d1a7bfce9c5198d4094d7aae742 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 24 Oct 2017 14:47:05 +0200 Subject: [PATCH 64/81] Small fixes --- .../libs/true_observables_reader.cc | 2 +- .../gps_l1_ca_dll_pll_tracking_test.cc | 69 ++++++++----------- 2 files changed, 29 insertions(+), 42 deletions(-) diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/true_observables_reader.cc b/src/tests/unit-tests/signal-processing-blocks/libs/true_observables_reader.cc index f9d63af29..2a6d7830a 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/true_observables_reader.cc +++ b/src/tests/unit-tests/signal-processing-blocks/libs/true_observables_reader.cc @@ -34,7 +34,7 @@ bool true_observables_reader::read_binary_obs() { try { - for(int i=0;i<12;i++) + for(int i = 0; i < 12; i++) { d_dump_file.read(reinterpret_cast(&gps_time_sec[i]), sizeof(double)); d_dump_file.read(reinterpret_cast(&doppler_l1_hz), sizeof(double)); diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc index 21e93139d..c10280c44 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc @@ -32,7 +32,6 @@ #include #include -//#include #include #include #include @@ -47,10 +46,8 @@ #include #include "GPS_L1_CA.h" #include "gnss_block_factory.h" -#include "gnss_block_interface.h" #include "tracking_interface.h" #include "in_memory_configuration.h" -#include "gnss_synchro.h" #include "tracking_true_obs_reader.h" #include "tracking_dump_reader.h" #include "signal_generator_flags.h" @@ -239,8 +236,7 @@ void GpsL1CADllPllTrackingTest::check_results_doppler(arma::vec & true_time_s, arma::vec & meas_time_s, arma::vec & meas_value) { - //1. True value interpolation to match the measurement times - + // 1. True value interpolation to match the measurement times arma::vec true_value_interp; arma::uvec true_time_s_valid = find(true_time_s > 0); true_time_s = true_time_s(true_time_s_valid); @@ -251,26 +247,26 @@ void GpsL1CADllPllTrackingTest::check_results_doppler(arma::vec & true_time_s, arma::interp1(true_time_s, true_value, meas_time_s, true_value_interp); - //2. RMSE + // 2. RMSE arma::vec err; err = meas_value - true_value_interp; arma::vec err2 = arma::square(err); double rmse = sqrt(arma::mean(err2)); - //3. Mean err and variance + // 3. Mean err and variance double error_mean = arma::mean(err); double error_var = arma::var(err); - // 5. Peaks + // 4. Peaks double max_error = arma::max(err); double min_error = arma::min(err); - //5. report + // 5. report std::streamsize ss = std::cout.precision(); std::cout << std::setprecision(10) << "TRK Doppler RMSE=" << rmse - << ", mean=" << error_mean - << ", stdev="<< sqrt(error_var) << " (max,min)=" << max_error << "," << min_error << " [Hz]" << std::endl; + << ", mean=" << error_mean + << ", stdev=" << sqrt(error_var) << " (max,min)=" << max_error << "," << min_error << " [Hz]" << std::endl; std::cout.precision (ss); } @@ -280,7 +276,7 @@ void GpsL1CADllPllTrackingTest::check_results_acc_carrier_phase(arma::vec & true arma::vec & meas_time_s, arma::vec & meas_value) { - //1. True value interpolation to match the measurement times + // 1. True value interpolation to match the measurement times arma::vec true_value_interp; arma::uvec true_time_s_valid = find(true_time_s > 0); true_time_s = true_time_s(true_time_s_valid); @@ -291,13 +287,13 @@ void GpsL1CADllPllTrackingTest::check_results_acc_carrier_phase(arma::vec & true arma::interp1(true_time_s, true_value, meas_time_s, true_value_interp); - //2. RMSE + // 2. RMSE arma::vec err; err = meas_value - true_value_interp; arma::vec err2 = arma::square(err); double rmse = sqrt(arma::mean(err2)); - //3. Mean err and variance + // 3. Mean err and variance double error_mean = arma::mean(err); double error_var = arma::var(err); @@ -305,7 +301,7 @@ void GpsL1CADllPllTrackingTest::check_results_acc_carrier_phase(arma::vec & true double max_error = arma::max(err); double min_error = arma::min(err); - //5. report + // 5. report std::streamsize ss = std::cout.precision(); std::cout << std::setprecision(10) << "TRK acc carrier phase RMSE=" << rmse << ", mean=" << error_mean @@ -319,7 +315,7 @@ void GpsL1CADllPllTrackingTest::check_results_codephase(arma::vec & true_time_s, arma::vec & meas_time_s, arma::vec & meas_value) { - //1. True value interpolation to match the measurement times + // 1. True value interpolation to match the measurement times arma::vec true_value_interp; arma::uvec true_time_s_valid = find(true_time_s > 0); true_time_s = true_time_s(true_time_s_valid); @@ -330,14 +326,14 @@ void GpsL1CADllPllTrackingTest::check_results_codephase(arma::vec & true_time_s, arma::interp1(true_time_s, true_value, meas_time_s, true_value_interp); - //2. RMSE + // 2. RMSE arma::vec err; err = meas_value - true_value_interp; arma::vec err2 = arma::square(err); double rmse = sqrt(arma::mean(err2)); - //3. Mean err and variance + // 3. Mean err and variance double error_mean = arma::mean(err); double error_var = arma::var(err); @@ -345,7 +341,7 @@ void GpsL1CADllPllTrackingTest::check_results_codephase(arma::vec & true_time_s, double max_error = arma::max(err); double min_error = arma::min(err); - //5. report + // 5. report std::streamsize ss = std::cout.precision(); std::cout << std::setprecision(10) << "TRK code phase RMSE=" << rmse << ", mean=" << error_mean @@ -369,19 +365,14 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) configure_receiver(); - //open true observables log file written by the simulator + // open true observables log file written by the simulator tracking_true_obs_reader true_obs_data; int test_satellite_PRN = FLAGS_test_satellite_PRN; std::cout << "Testing satellite PRN=" << test_satellite_PRN << std::endl; std::string true_obs_file = std::string("./gps_l1_ca_obs_prn"); true_obs_file.append(std::to_string(test_satellite_PRN)); true_obs_file.append(".dat"); - ASSERT_NO_THROW({ - if (true_obs_data.open_obs_file(true_obs_file) == false) - { - throw std::exception(); - }; - }) << "Failure opening true observables file" << std::endl; + ASSERT_EQ(true_obs_data.open_obs_file(true_obs_file), true) << "Failure opening true observables file"; top_block = gr::make_top_block("Tracking test"); @@ -396,7 +387,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) << "Maybe sat PRN #" + std::to_string(FLAGS_test_satellite_PRN) + " is not available?"; - //restart the epoch counter + // restart the epoch counter true_obs_data.restart(); std::cout << "Initial Doppler [Hz]=" << true_obs_data.doppler_l1_hz << " Initial code delay [Chips]=" << true_obs_data.prn_delay_chips << std::endl; @@ -406,15 +397,15 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) ASSERT_NO_THROW( { tracking->set_channel(gnss_synchro.Channel_ID); - }) << "Failure setting channel." << std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { tracking->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro." << std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { tracking->connect(top_block); - }) << "Failure connecting tracking to the top_block." << std::endl; + }) << "Failure connecting tracking to the top_block."; ASSERT_NO_THROW( { std::string file = "./" + filename_raw_data; @@ -426,7 +417,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) top_block->connect(gr_interleaved_char_to_complex, 0, tracking->get_left_block(), 0); top_block->connect(tracking->get_right_block(), 0, sink, 0); top_block->msg_connect(tracking->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of tracking test." << std::endl; + }) << "Failure connecting the blocks of tracking test."; tracking->start_tracking(); @@ -434,10 +425,10 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) start = std::chrono::system_clock::now(); top_block->run(); // Start threads and wait end = std::chrono::system_clock::now(); - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; - //check results - //load the true values + // check results + // load the true values long int nepoch = true_obs_data.num_epochs(); std::cout << "True observation epochs=" << nepoch << std::endl; @@ -460,13 +451,9 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) //load the measured values tracking_dump_reader trk_dump; - ASSERT_NO_THROW({ - if (trk_dump.open_obs_file(std::string("./tracking_ch_0.dat")) == false) - { - throw std::exception(); - }; - }) << "Failure opening tracking dump file" << std::endl; + ASSERT_EQ(trk_dump.open_obs_file(std::string("./tracking_ch_0.dat")), true) + << "Failure opening tracking dump file"; nepoch = trk_dump.num_epochs(); std::cout << "Measured observation epochs=" << nepoch << std::endl; @@ -501,7 +488,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) promptQ.push_back(trk_dump.prompt_Q); } - //Align initial measurements and cut the tracking pull-in transitory + // Align initial measurements and cut the tracking pull-in transitory double pull_in_offset_s = 1.0; arma::uvec initial_meas_point = arma::find(trk_timestamp_s >= (true_timestamp_s(0) + pull_in_offset_s), 1, "first"); From 791dfbd6d33355f0fdd0b59517ca061ef7b76b37 Mon Sep 17 00:00:00 2001 From: Damian Miralles Date: Thu, 26 Oct 2017 18:43:18 -0600 Subject: [PATCH 65/81] bugfix: Adjusting time of week (TOW) computation for GLONASS Fixing the time of week computation for GLONASS by treating N_T as a day offset from January 1. It also adds more units test for TOW checks --- .../glonass_gnav_ephemeris.cc | 11 +---- .../glonass_gnav_ephemeris_test.cc | 47 +++++++++++++++++-- 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/src/core/system_parameters/glonass_gnav_ephemeris.cc b/src/core/system_parameters/glonass_gnav_ephemeris.cc index 43d337cc4..b1c9d2632 100644 --- a/src/core/system_parameters/glonass_gnav_ephemeris.cc +++ b/src/core/system_parameters/glonass_gnav_ephemeris.cc @@ -118,7 +118,6 @@ void Glonass_Gnav_Ephemeris::glot_to_gpst(double tod_offset, double glot2utc_cor double days = 0.0; double total_sec = 0.0, sec_of_day = 0.0; int i = 0; - boost::gregorian::days d3(0); boost::gregorian::date gps_epoch { 1980, 1, 6 }; @@ -129,14 +128,8 @@ void Glonass_Gnav_Ephemeris::glot_to_gpst(double tod_offset, double glot2utc_cor boost::posix_time::time_duration t(0, 0, tod); boost::gregorian::date d1(d_yr, 1, 1); - boost::gregorian::days d2(d_N_T); - - if(tod < 0) - { - d3 = boost::gregorian::days(-1); - } - - boost::posix_time::ptime glonass_time(d1+d2+d3, t); + boost::gregorian::days d2(d_N_T-1); + boost::posix_time::ptime glonass_time(d1+d2, t); boost::gregorian::date utc_date = glonass_time.date(); // Total number of days diff --git a/src/tests/unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc b/src/tests/unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc index 1d084ab4b..71aa40ac1 100644 --- a/src/tests/unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc +++ b/src/tests/unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc @@ -64,11 +64,12 @@ TEST(GlonassGnavEphemerisTest, ComputeGlonassTime) ASSERT_TRUE(expected_gtime.seconds() - t.seconds() < FLT_EPSILON ); } -TEST(GlonassGnavEphemerisTest, ConvertGlonassT2GpsT) +// testing case where calendar +TEST(GlonassGnavEphemerisTest, ConvertGlonassT2GpsT1) { Glonass_Gnav_Ephemeris gnav_eph; - gnav_eph.d_yr = 2005; - gnav_eph.d_N_T = 32; + gnav_eph.d_yr = 2004; + gnav_eph.d_N_T = 366+28; double tod = 70200; double week = 0.0; @@ -83,3 +84,43 @@ TEST(GlonassGnavEphemerisTest, ConvertGlonassT2GpsT) ASSERT_TRUE(week - true_week < FLT_EPSILON ); ASSERT_TRUE(tow - true_week < FLT_EPSILON ); } + +TEST(GlonassGnavEphemerisTest, ConvertGlonassT2GpsT2) +{ + Glonass_Gnav_Ephemeris gnav_eph; + gnav_eph.d_yr = 2016; + gnav_eph.d_N_T = 268; + + double tod = 7560; + double week = 0.0; + double tow = 0.0; + double true_leap_sec = 13; + double true_week = 1915; + double true_tow = 480600+true_leap_sec; + + gnav_eph.glot_to_gpst(tod, 0.0, 0.0, &week, &tow); + + // Perform assertions of decoded fields + ASSERT_TRUE(week - true_week < FLT_EPSILON ); + ASSERT_TRUE(tow - true_week < FLT_EPSILON ); +} + +TEST(GlonassGnavEphemerisTest, ConvertGlonassT2GpsT3) +{ + Glonass_Gnav_Ephemeris gnav_eph; + gnav_eph.d_yr = 2016; + gnav_eph.d_N_T = 62; + + double tod = 7560 + 6*3600; + double week = 0.0; + double tow = 0.0; + double true_leap_sec = 13; + double true_week = 1307; + double true_tow = 480600+true_leap_sec; + + gnav_eph.glot_to_gpst(tod, 0.0, 0.0, &week, &tow); + + // Perform assertions of decoded fields + ASSERT_TRUE(week - true_week < FLT_EPSILON ); + ASSERT_TRUE(tow - true_week < FLT_EPSILON ); +} From 6e223c42773d424cd300be6b0abb382f1f6df466 Mon Sep 17 00:00:00 2001 From: Damian Miralles Date: Thu, 26 Oct 2017 20:46:16 -0600 Subject: [PATCH 66/81] bugfix: changing flooring operation for tow update --- .../glonass_l1_ca_telemetry_decoder_cc.cc | 5 ++-- .../glonass_gnav_ephemeris.h | 25 +++++++++++++------ .../glonass_gnav_ephemeris_test.cc | 13 +++++++++- 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.cc index 2edbd447c..34e72231b 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.cc @@ -355,8 +355,7 @@ int glonass_l1_ca_telemetry_decoder_cc::general_work (int noutput_items __attrib if (this->d_flag_preamble == true and d_nav.flag_TOW_new == true) //update TOW at the preamble instant { - double dummy_dtow = d_nav.get_TOW() - GLONASS_GNAV_PREAMBLE_DURATION_S; - d_TOW_at_current_symbol = d_nav.gnav_ephemeris.d_TOW - GLONASS_GNAV_PREAMBLE_DURATION_S; + d_TOW_at_current_symbol = floor((d_nav.gnav_ephemeris.d_TOW - GLONASS_GNAV_PREAMBLE_DURATION_S)*1000)/1000; d_nav.flag_TOW_new = false; } @@ -382,7 +381,7 @@ int glonass_l1_ca_telemetry_decoder_cc::general_work (int noutput_items __attrib } current_symbol.PRN = this->d_satellite.get_PRN(); - current_symbol.TOW_at_current_symbol_s = floor(d_TOW_at_current_symbol*1000.0)/1000.0; + current_symbol.TOW_at_current_symbol_s = d_TOW_at_current_symbol; current_symbol.TOW_at_current_symbol_s -=delta_t; //Galileo to GPS TOW if(d_dump == true) diff --git a/src/core/system_parameters/glonass_gnav_ephemeris.h b/src/core/system_parameters/glonass_gnav_ephemeris.h index 929fa7262..5400e890f 100644 --- a/src/core/system_parameters/glonass_gnav_ephemeris.h +++ b/src/core/system_parameters/glonass_gnav_ephemeris.h @@ -99,10 +99,10 @@ public: double d_satClkDrift; //!< GLONASS clock error double d_dtr; //!< relativistic clock correction term double d_iode; //!< Issue of data, ephemeris (Bit 0-6 of tb) - double d_tau_c; - double d_TOW; // tow of the start of frame - double d_WN; // week number of the start of frame - double d_tod; + double d_tau_c; //!< GLONASST 2 UTC correction (todo) may be eliminated + double d_TOW; //!< GLONASST IN GPST seconds of week + double d_WN; //!< GLONASST IN GPST week number of the start of frame + double d_tod; //!< Time of Day since ephemeris where decoded template @@ -161,13 +161,22 @@ public: /*! * \brief Converts from GLONASST to UTC - * \ param [I] - * \ param offset_time Is the start of day offset to compute the time - * \ returns UTC time as a boost::posix_time::ptime object + * \details The function simply adjust for the 6 hrs offset between GLONASST and UTC + * \param[in] offset_time Is the start of day offset + * \param[in] glot2utc_corr Correction from GLONASST to UTC + * \returns UTC time as a boost::posix_time::ptime object */ boost::posix_time::ptime glot_to_utc(const double offset_time, const double glot2utc_corr) const; - + /*! + * \brief Converts from GLONASST to GPST + * \details Converts from GLONASST to GPST in time of week (TOW) and week number (WN) format + * \param[in] tod_offset Is the start of day offset + * \param[in] glot2utc_corr Correction from GLONASST to UTC + * \param[in] glot2gpst_corr Correction from GLONASST to GPST + * \param[out] WN Week Number, not in mod(1024) format + * \param[out] TOW Time of Week in seconds of week + */ void glot_to_gpst(double tod_offset, double glot2utc_corr, double glot2gpst_corr, double * WN, double * TOW) const; /*! diff --git a/src/tests/unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc b/src/tests/unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc index 71aa40ac1..2a4917357 100644 --- a/src/tests/unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc +++ b/src/tests/unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc @@ -64,7 +64,10 @@ TEST(GlonassGnavEphemerisTest, ComputeGlonassTime) ASSERT_TRUE(expected_gtime.seconds() - t.seconds() < FLT_EPSILON ); } -// testing case where calendar +/*! + * \brief Testing conversion from GLONASST to GPST + * \test Tests scenario for N_T when greater than 365 days. Possible values here from 1 to 365*4 + */ TEST(GlonassGnavEphemerisTest, ConvertGlonassT2GpsT1) { Glonass_Gnav_Ephemeris gnav_eph; @@ -85,6 +88,10 @@ TEST(GlonassGnavEphemerisTest, ConvertGlonassT2GpsT1) ASSERT_TRUE(tow - true_week < FLT_EPSILON ); } +/*! + * \brief Testing conversion from GLONASST to GPST + * \test This version tests the conversion for offsets greater than 30 in a leap year + */ TEST(GlonassGnavEphemerisTest, ConvertGlonassT2GpsT2) { Glonass_Gnav_Ephemeris gnav_eph; @@ -105,6 +112,10 @@ TEST(GlonassGnavEphemerisTest, ConvertGlonassT2GpsT2) ASSERT_TRUE(tow - true_week < FLT_EPSILON ); } +/*! + * \brief Testing conversion from GLONASST to GPST + * \test This version tests the conversion around the vicinity of February 29 days when in leap year + */ TEST(GlonassGnavEphemerisTest, ConvertGlonassT2GpsT3) { Glonass_Gnav_Ephemeris gnav_eph; From 41b536524423b326eb6c252d798c3c1b7a01bdda Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sat, 28 Oct 2017 18:15:59 +0200 Subject: [PATCH 67/81] Add acquisition grid plot --- src/tests/common-files/gnuplot_i.h | 61 ++++++++ .../gps_l1_ca_pcps_acquisition_test.cc | 135 ++++++++++++++---- .../libs/CMakeLists.txt | 1 + .../libs/acquisition_dump_reader.cc | 109 ++++++++++++++ .../libs/acquisition_dump_reader.h | 61 ++++++++ 5 files changed, 343 insertions(+), 24 deletions(-) create mode 100644 src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc create mode 100644 src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.h diff --git a/src/tests/common-files/gnuplot_i.h b/src/tests/common-files/gnuplot_i.h index 8d1afe8ab..3627a38af 100644 --- a/src/tests/common-files/gnuplot_i.h +++ b/src/tests/common-files/gnuplot_i.h @@ -510,6 +510,10 @@ public: Gnuplot& plot_xy_err(const X &x, const Y &y, const E &dy, const std::string &title = ""); + template + Gnuplot& plot_grid3d(const X &x, const Y &y, const E &mag, + const std::string &title = ""); + /// plot x,y,z triples: x y z /// from file Gnuplot& plotfile_xyz(const std::string &filename, @@ -804,6 +808,63 @@ Gnuplot& Gnuplot::plot_xy_err(const X &x, } +//------------------------------------------------------------------------------ +// +// Plots a 3d grid +// +template +Gnuplot& Gnuplot::plot_grid3d(const X &x, + const Y &y, + const E &mag, + const std::string &title) +{ + if (x.size() == 0 || y.size() == 0 ) + { + throw GnuplotException("std::vectors too small"); + return *this; + } + std::ofstream tmp; + std::string name = create_tmpfile(tmp); + if (name == "") + return *this; + + // + // write the data to file + // + for (unsigned int i = 0; i < x.size(); i++) + { + for (unsigned int k = 0; k < y.size(); k++) + { + tmp << static_cast(x.at(i)) << " " << static_cast(y.at(k)) << " " << mag.at(i).at(k) << std::endl; + } + tmp.flush(); + } + + tmp.close(); + + std::ostringstream cmdstr; + cmdstr << "set ticslevel 0\n"; + cmdstr << "set hidden3d\n"; + cmdstr << "unset colorbox\n"; + cmdstr << "set border 5\n"; + cmdstr << "unset ztics\n"; + + cmdstr << " splot \"" << name << "\" u 1:2:3"; + + if (title == "") + cmdstr << " notitle with " << pstyle << " palette"; + else + cmdstr << " title \"" << title << "\" with " << pstyle << " palette"; + cmdstr << "\n"; + + // + // Do the actual plot + // + cmd(cmdstr.str()); + + return *this; +} + //------------------------------------------------------------------------------ // // Plots a 3d graph from a list of doubles: x y z diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc index 76aedce64..e1ebcb4c4 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc @@ -34,6 +34,7 @@ #include #include +#include #include #include #include @@ -47,8 +48,14 @@ #include "in_memory_configuration.h" #include "gnss_sdr_valve.h" #include "gnss_synchro.h" +#include "gnuplot_i.h" +#include "test_flags.h" +#include "acquisition_dump_reader.h" #include "gps_l1_ca_pcps_acquisition.h" +DEFINE_bool(plot_acq_grid, false, "Plots results of GpsL1CaPcpsAcquisitionTest with gnuplot"); + + // ######## GNURADIO BLOCK MESSAGE RECEVER ######### class GpsL1CaPcpsAcquisitionTest_msg_rx; @@ -120,6 +127,7 @@ protected: {} void init(); + void plot_grid(); gr::top_block_sptr top_block; std::shared_ptr factory; @@ -136,24 +144,88 @@ void GpsL1CaPcpsAcquisitionTest::init() std::string signal = "1C"; signal.copy(gnss_synchro.Signal, 2, 0); gnss_synchro.PRN = 1; + config->set_property("Acquisition_1C.implementation", "GPS_L1_CA_PCPS_Acquisition"); config->set_property("GNSS-SDR.internal_fs_sps", "4000000"); - config->set_property("Acquisition.item_type", "gr_complex"); - config->set_property("Acquisition.if", "0"); - config->set_property("Acquisition.coherent_integration_time_ms", "1"); - config->set_property("Acquisition.dump", "false"); - config->set_property("Acquisition.implementation", "GPS_L1_CA_PCPS_Acquisition"); - config->set_property("Acquisition.threshold", "0.00001"); - config->set_property("Acquisition.doppler_max", "5000"); - config->set_property("Acquisition.doppler_step", "500"); - config->set_property("Acquisition.repeat_satellite", "false"); - //config->set_property("Acquisition.pfa", "0.0"); + config->set_property("Acquisition_1C.item_type", "gr_complex"); + config->set_property("Acquisition_1C.if", "0"); + config->set_property("Acquisition_1C.coherent_integration_time_ms", "1"); + if(FLAGS_plot_acq_grid == true) + { + config->set_property("Acquisition_1C.dump", "true"); + } + else + { + config->set_property("Acquisition_1C.dump", "false"); + } + config->set_property("Acquisition_1C.threshold", "0.00001"); + config->set_property("Acquisition_1C.doppler_max", "5000"); + config->set_property("Acquisition_1C.doppler_step", "500"); + config->set_property("Acquisition_1C.repeat_satellite", "false"); + //config->set_property("Acquisition_1C.pfa", "0.0"); +} + + +void GpsL1CaPcpsAcquisitionTest::plot_grid() +{ + //load the measured values + std::string basename = "./data/acquisition_G_1C"; + unsigned int sat = static_cast(gnss_synchro.PRN); + unsigned int doppler_max = 5000; // !!! + unsigned int doppler_step = 100; // !! + unsigned int samples_per_code = static_cast(round(4000000 / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS))); // !! + acquisition_dump_reader acq_dump(basename, sat, doppler_max, doppler_step, samples_per_code); + + if(!acq_dump.read_binary_acq()) std::cout << "Error reading files" << std::endl; + + std::vector doppler = acq_dump.doppler; + std::vector samples = acq_dump.samples; + std::vector > mag = acq_dump.mag; + + const std::string gnuplot_executable(FLAGS_gnuplot_executable); + if(gnuplot_executable.empty()) + { + std::cout << "WARNING: Although the flag plot_acq_grid has been set to TRUE," << std::endl; + std::cout << "gnuplot has not been found in your system." << std::endl; + std::cout << "Test results will not be plotted." << std::endl; + } + else + { + std::cout << "Plotting the acquisition grid..." << std::endl; + try + { + boost::filesystem::path p(gnuplot_executable); + boost::filesystem::path dir = p.parent_path(); + std::string gnuplot_path = dir.native(); + Gnuplot::set_GNUPlotPath(gnuplot_path); + + Gnuplot g1("lines"); + g1.set_title("GPS L1 C/A signal acquisition for satellite PRN #" + std::to_string(gnss_synchro.PRN)); + g1.set_xlabel("Doppler [Hz]"); + g1.set_ylabel("Sample"); + //g1.cmd("set view 60, 105, 1, 1"); + g1.plot_grid3d(doppler, samples, mag); + + g1.savetops("GPS_L1_acq_grid"); + g1.savetopdf("GPS_L1_acq_grid"); + g1.showonscreen(); + } + catch (const GnuplotException & ge) + { + std::cout << ge.what() << std::endl; + } + } + std::string data_str = "./data"; + if (boost::filesystem::exists(data_str)) + { + boost::filesystem::remove_all(data_str); + } } TEST_F(GpsL1CaPcpsAcquisitionTest, Instantiate) { init(); - boost::shared_ptr acquisition = boost::make_shared(config.get(), "Acquisition", 1, 1); + boost::shared_ptr acquisition = boost::make_shared(config.get(), "Acquisition_1C", 1, 1); } @@ -167,7 +239,7 @@ TEST_F(GpsL1CaPcpsAcquisitionTest, ConnectAndRun) top_block = gr::make_top_block("Acquisition test"); init(); - boost::shared_ptr acquisition = boost::make_shared(config.get(), "Acquisition", 1, 1); + boost::shared_ptr acquisition = boost::make_shared(config.get(), "Acquisition_1C", 1, 1); boost::shared_ptr msg_rx = GpsL1CaPcpsAcquisitionTest_msg_rx_make(); ASSERT_NO_THROW( { @@ -178,14 +250,14 @@ TEST_F(GpsL1CaPcpsAcquisitionTest, ConnectAndRun) top_block->connect(valve, 0, acquisition->get_left_block(), 0); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of acquisition test." << std::endl; + }) << "Failure connecting the blocks of acquisition test."; 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::endl; + }) << "Failure running the top_block."; std::cout << "Processed " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; } @@ -194,7 +266,7 @@ TEST_F(GpsL1CaPcpsAcquisitionTest, ConnectAndRun) TEST_F(GpsL1CaPcpsAcquisitionTest, ValidationOfResults) { std::chrono::time_point start, end; - std::chrono::duration elapsed_seconds(0); + std::chrono::duration elapsed_seconds(0.0); top_block = gr::make_top_block("Acquisition test"); double expected_delay_samples = 524; @@ -202,32 +274,42 @@ TEST_F(GpsL1CaPcpsAcquisitionTest, ValidationOfResults) init(); - std::shared_ptr acquisition = std::make_shared(config.get(), "Acquisition", 1, 1); + if(FLAGS_plot_acq_grid == true) + { + std::string data_str = "./data"; + if (boost::filesystem::exists(data_str)) + { + boost::filesystem::remove_all(data_str); + } + boost::filesystem::create_directory(data_str); + } + + std::shared_ptr acquisition = std::make_shared(config.get(), "Acquisition_1C", 1, 1); boost::shared_ptr msg_rx = GpsL1CaPcpsAcquisitionTest_msg_rx_make(); ASSERT_NO_THROW( { acquisition->set_channel(1); - }) << "Failure setting channel." << std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { acquisition->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro." << std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { acquisition->set_threshold(0.001); - }) << "Failure setting threshold." << std::endl; + }) << "Failure setting threshold."; ASSERT_NO_THROW( { acquisition->set_doppler_max(5000); - }) << "Failure setting doppler_max." << std::endl; + }) << "Failure setting doppler_max."; ASSERT_NO_THROW( { acquisition->set_doppler_step(100); - }) << "Failure setting doppler_step." << std::endl; + }) << "Failure setting doppler_step."; ASSERT_NO_THROW( { acquisition->connect(top_block); - }) << "Failure connecting acquisition to the top_block." << std::endl; + }) << "Failure connecting acquisition to the top_block."; ASSERT_NO_THROW( { std::string path = std::string(TEST_PATH); @@ -236,7 +318,7 @@ TEST_F(GpsL1CaPcpsAcquisitionTest, ValidationOfResults) gr::blocks::file_source::sptr file_source = gr::blocks::file_source::make(sizeof(gr_complex), file_name, false); top_block->connect(file_source, 0, acquisition->get_left_block(), 0); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of acquisition test." << std::endl; + }) << "Failure connecting the blocks of acquisition test."; acquisition->set_local_code(); acquisition->set_state(1); // Ensure that acquisition starts at the first sample @@ -247,7 +329,7 @@ TEST_F(GpsL1CaPcpsAcquisitionTest, ValidationOfResults) top_block->run(); // Start threads and wait end = std::chrono::system_clock::now(); elapsed_seconds = end - start; - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; unsigned long int nsamples = gnss_synchro.Acq_samplestamp_samples; std::cout << "Acquired " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; @@ -259,4 +341,9 @@ TEST_F(GpsL1CaPcpsAcquisitionTest, ValidationOfResults) EXPECT_LE(doppler_error_hz, 666) << "Doppler error exceeds the expected value: 666 Hz = 2/(3*integration period)"; EXPECT_LT(delay_error_chips, 0.5) << "Delay error exceeds the expected value: 0.5 chips"; + + if(FLAGS_plot_acq_grid == true) + { + plot_grid(); + } } diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/CMakeLists.txt b/src/tests/unit-tests/signal-processing-blocks/libs/CMakeLists.txt index 0ee8ec658..14c2f5bd2 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/CMakeLists.txt +++ b/src/tests/unit-tests/signal-processing-blocks/libs/CMakeLists.txt @@ -18,6 +18,7 @@ set(SIGNAL_PROCESSING_TESTING_LIB_SOURCES + acquisition_dump_reader.cc tracking_dump_reader.cc tlm_dump_reader.cc observables_dump_reader.cc diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc b/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc new file mode 100644 index 000000000..3c9fcfda0 --- /dev/null +++ b/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc @@ -0,0 +1,109 @@ +/*! + * \file acquisition_dump_reader.cc + * \brief Helper file for unit testing + * \author Javier Arribas, 2017. jarribas(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include +#include "acquisition_dump_reader.h" + +bool acquisition_dump_reader::read_binary_acq() +{ + std::complex* aux = new std::complex[1]; + for(int i = 0; i < d_num_doppler_bins; i++) + { + try + { + std::ifstream ifs; + ifs.exceptions( std::ifstream::failbit | std::ifstream::badbit ); + ifs.open(d_dump_filenames.at(i).c_str(), std::ios::in | std::ios::binary); + d_dump_files.at(i).swap(ifs); + if (d_dump_files.at(i).is_open()) + { + for(int k = 0; k < d_samples_per_code; k++) + { + d_dump_files.at(i).read(reinterpret_cast(&aux[0]), sizeof(std::complex)); + mag.at(i).at(k) = std::abs(*aux) / std::pow(d_samples_per_code, 2); + } + } + else + { + std::cout << "File " << d_dump_filenames.at(i).c_str() << " not found." << std::endl; + delete[] aux; + return false; + } + d_dump_files.at(i).close(); + } + catch (const std::ifstream::failure &e) + { + std::cout << e.what() << std::endl; + delete[] aux; + return false; + } + } + delete[] aux; + return true; +} + + +acquisition_dump_reader::acquisition_dump_reader(std::string & basename, unsigned int sat, unsigned int doppler_max, unsigned int doppler_step, unsigned int samples_per_code) +{ + d_basename = basename; + d_sat = sat; + d_doppler_max = doppler_max; + d_doppler_step = doppler_step; + d_samples_per_code = samples_per_code; + d_num_doppler_bins = static_cast(ceil( static_cast(static_cast(d_doppler_max) - static_cast(-d_doppler_max)) / static_cast(d_doppler_step))); + std::vector > mag_aux(d_num_doppler_bins, std::vector(d_samples_per_code)); + mag = mag_aux; + for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++) + { + doppler.push_back(-static_cast(d_doppler_max) + d_doppler_step * doppler_index); + d_dump_filenames.push_back(d_basename + "_sat_" + std::to_string(d_sat) + "_doppler_" + std::to_string(doppler.at(doppler_index)) + ".dat"); + } + for (unsigned int k = 0; k < d_samples_per_code; k++) + { + samples.push_back(k); + } + for(int i = 0; i < d_num_doppler_bins; i++) + { + std::ifstream is; + d_dump_files.push_back(std::move(is)); + } +} + + +acquisition_dump_reader::~acquisition_dump_reader() +{ + for(int i = 0; i < d_num_doppler_bins; i++) + { + if (d_dump_files.at(i).is_open() == true) + { + d_dump_files.at(i).close(); + } + } +} diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.h b/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.h new file mode 100644 index 000000000..8d346cf7d --- /dev/null +++ b/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.h @@ -0,0 +1,61 @@ +/*! + * \file acquisition_dump_reader.h + * \brief Helper file for unit testing + * \author Javier Arribas, 2017. jarribas(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_ACQUISITION_DUMP_READER_H +#define GNSS_SDR_ACQUISITION_DUMP_READER_H + +#include +#include +#include +#include + +class acquisition_dump_reader +{ +public: + acquisition_dump_reader(std::string & basename, unsigned int sat, unsigned int doppler_max, unsigned int doppler_step, unsigned int samples_per_code); + ~acquisition_dump_reader(); + bool read_binary_acq(); + + std::vector doppler; + std::vector samples; + std::vector > mag; + +private: + std::string d_basename; + unsigned int d_sat; + unsigned int d_doppler_max; + unsigned int d_doppler_step; + unsigned int d_samples_per_code; + unsigned int d_num_doppler_bins; + std::vector d_dump_filenames; + std::vector d_dump_files; +}; + +#endif // GNSS_SDR_ACQUISITION_DUMP_READER_H From 4267150445326add4e214319e1fac0463f838488 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sat, 28 Oct 2017 20:17:51 +0200 Subject: [PATCH 68/81] Add Galileo acquisition grid and other fixes in tests --- .../galileo_e1_pcps_ambiguous_acquisition.cc | 2 +- src/tests/common-files/test_flags.h | 1 + ...8ms_ambiguous_acquisition_gsoc2013_test.cc | 110 +++++++------- ...cps_ambiguous_acquisition_gsoc2013_test.cc | 96 ++++++------ ...e1_pcps_ambiguous_acquisition_gsoc_test.cc | 51 ++++--- ...ileo_e1_pcps_ambiguous_acquisition_test.cc | 140 ++++++++++++++---- ...wsr_ambiguous_acquisition_gsoc2013_test.cc | 95 ++++++------ ...ync_ambiguous_acquisition_gsoc2014_test.cc | 137 +++++++++-------- ...ong_ambiguous_acquisition_gsoc2013_test.cc | 90 ++++++----- ...cps_acquisition_gsoc2014_gensource_test.cc | 33 ++--- ...ps_l1_ca_pcps_acquisition_gsoc2013_test.cc | 94 ++++++------ .../gps_l1_ca_pcps_acquisition_test.cc | 6 +- .../gps_l1_ca_pcps_acquisition_test_fpga.cc | 44 +++--- ...a_pcps_opencl_acquisition_gsoc2013_test.cc | 90 ++++++----- ...cps_quicksync_acquisition_gsoc2014_test.cc | 127 +++++++--------- ..._ca_pcps_tong_acquisition_gsoc2013_test.cc | 94 ++++++------ .../gps_l2_m_pcps_acquisition_test.cc | 44 +++--- 17 files changed, 648 insertions(+), 606 deletions(-) diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc index f2060aebb..f9712824c 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc @@ -46,7 +46,7 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition( { configuration_ = configuration; std::string default_item_type = "gr_complex"; - std::string default_dump_filename = "../data/acquisition.dat"; + std::string default_dump_filename = "./data/acquisition.dat"; DLOG(INFO) << "role " << role; diff --git a/src/tests/common-files/test_flags.h b/src/tests/common-files/test_flags.h index fac307f84..a8bac06a6 100644 --- a/src/tests/common-files/test_flags.h +++ b/src/tests/common-files/test_flags.h @@ -39,6 +39,7 @@ DEFINE_string(gnuplot_executable, "", "Gnuplot binary path"); #endif +DEFINE_bool(plot_acq_grid, false, "Plots acquisition grid with gnuplot"); DEFINE_int32(plot_decimate, 1, "Decimate plots"); #endif diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_8ms_ambiguous_acquisition_gsoc2013_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_8ms_ambiguous_acquisition_gsoc2013_test.cc index ccaa8c2af..9d6f79c8e 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_8ms_ambiguous_acquisition_gsoc2013_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_8ms_ambiguous_acquisition_gsoc2013_test.cc @@ -238,15 +238,14 @@ void GalileoE1Pcps8msAmbiguousAcquisitionGSoC2013Test::config_1() config->set_property("InputFilter.filter_type", "bandpass"); config->set_property("InputFilter.grid_density", "16"); - config->set_property("Acquisition.item_type", "gr_complex"); - config->set_property("Acquisition.if", "0"); - config->set_property("Acquisition.coherent_integration_time_ms", std::to_string(integration_time_ms)); - config->set_property("Acquisition.max_dwells", "1"); - config->set_property("Acquisition.implementation", "Galileo_E1_PCPS_8ms_Ambiguous_Acquisition"); - config->set_property("Acquisition.threshold", "0.2"); - config->set_property("Acquisition.doppler_max", "10000"); - config->set_property("Acquisition.doppler_step", "250"); - config->set_property("Acquisition.dump", "false"); + config->set_property("Acquisition_1B.implementation", "Galileo_E1_PCPS_8ms_Ambiguous_Acquisition"); + config->set_property("Acquisition_1B.item_type", "gr_complex"); + config->set_property("Acquisition_1B.coherent_integration_time_ms", std::to_string(integration_time_ms)); + config->set_property("Acquisition_1B.max_dwells", "1"); + config->set_property("Acquisition_1B.threshold", "0.2"); + config->set_property("Acquisition_1B.doppler_max", "10000"); + config->set_property("Acquisition_1B.doppler_step", "250"); + config->set_property("Acquisition_1B.dump", "false"); } @@ -324,15 +323,14 @@ void GalileoE1Pcps8msAmbiguousAcquisitionGSoC2013Test::config_2() config->set_property("InputFilter.filter_type", "bandpass"); config->set_property("InputFilter.grid_density", "16"); - config->set_property("Acquisition.item_type", "gr_complex"); - config->set_property("Acquisition.if", "0"); - config->set_property("Acquisition.coherent_integration_time_ms", std::to_string(integration_time_ms)); - config->set_property("Acquisition.max_dwells", "1"); - config->set_property("Acquisition.implementation", "Galileo_E1_PCPS_8ms_Ambiguous_Acquisition"); - config->set_property("Acquisition.pfa", "0.1"); - config->set_property("Acquisition.doppler_max", "10000"); - config->set_property("Acquisition.doppler_step", "250"); - config->set_property("Acquisition.dump", "false"); + config->set_property("Acquisition_1B.implementation", "Galileo_E1_PCPS_8ms_Ambiguous_Acquisition"); + config->set_property("Acquisition_1B.item_type", "gr_complex"); + config->set_property("Acquisition_1B.coherent_integration_time_ms", std::to_string(integration_time_ms)); + config->set_property("Acquisition_1B.max_dwells", "1"); + config->set_property("Acquisition_1B.pfa", "0.1"); + config->set_property("Acquisition_1B.doppler_max", "10000"); + config->set_property("Acquisition_1B.doppler_step", "250"); + config->set_property("Acquisition_1B.dump", "false"); } @@ -421,43 +419,43 @@ void GalileoE1Pcps8msAmbiguousAcquisitionGSoC2013Test::stop_queue() TEST_F(GalileoE1Pcps8msAmbiguousAcquisitionGSoC2013Test, Instantiate) { config_1(); - std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition", "Galileo_E1_PCPS_8ms_Ambiguous_Acquisition", 1, 1); + std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition_1B", "Galileo_E1_PCPS_8ms_Ambiguous_Acquisition", 1, 1); } TEST_F(GalileoE1Pcps8msAmbiguousAcquisitionGSoC2013Test, ConnectAndRun) { - int nsamples = floor(fs_in*integration_time_ms*1e-3); + int nsamples = floor(fs_in * integration_time_ms * 1e-3); std::chrono::time_point start, end; - std::chrono::duration elapsed_seconds(0); + std::chrono::duration elapsed_seconds(0.0); config_1(); queue = gr::msg_queue::make(0); top_block = gr::make_top_block("Acquisition test"); - std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition", "Galileo_E1_PCPS_8ms_Ambiguous_Acquisition", 1, 1); + std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition_1B", "Galileo_E1_PCPS_8ms_Ambiguous_Acquisition", 1, 1); acquisition = std::dynamic_pointer_cast(acq_); boost::shared_ptr msg_rx = GalileoE1Pcps8msAmbiguousAcquisitionGSoC2013Test_msg_rx_make(channel_internal_queue); ASSERT_NO_THROW( { acquisition->set_channel(1); - }) << "Failure setting channel." << std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { acquisition->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro." << std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { - acquisition->set_doppler_max(config->property("Acquisition.doppler_max", 10000)); - }) << "Failure setting doppler_max." << std::endl; + acquisition->set_doppler_max(config->property("Acquisition_1B.doppler_max", 10000)); + }) << "Failure setting doppler_max."; ASSERT_NO_THROW( { - acquisition->set_doppler_step(config->property("Acquisition.doppler_step", 500)); - }) << "Failure setting doppler_step." << std::endl; + acquisition->set_doppler_step(config->property("Acquisition_1B.doppler_step", 500)); + }) << "Failure setting doppler_step."; ASSERT_NO_THROW( { - acquisition->set_threshold(config->property("Acquisition.threshold", 0.0)); - }) << "Failure setting threshold." << std::endl; + acquisition->set_threshold(config->property("Acquisition_1B.threshold", 0.0)); + }) << "Failure setting threshold."; ASSERT_NO_THROW( { acquisition->connect(top_block); @@ -466,14 +464,14 @@ TEST_F(GalileoE1Pcps8msAmbiguousAcquisitionGSoC2013Test, ConnectAndRun) top_block->connect(source, 0, valve, 0); top_block->connect(valve, 0, acquisition->get_left_block(), 0); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of acquisition test." << std::endl; + }) << "Failure connecting the blocks of acquisition test."; 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::endl; + }) << "Failure running the top_block."; std::cout << "Processed " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; } @@ -485,33 +483,33 @@ TEST_F(GalileoE1Pcps8msAmbiguousAcquisitionGSoC2013Test, ValidationOfResults) queue = gr::msg_queue::make(0); top_block = gr::make_top_block("Acquisition test"); - std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition", "Galileo_E1_PCPS_8ms_Ambiguous_Acquisition", 1, 1, queue); + std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition_1B", "Galileo_E1_PCPS_8ms_Ambiguous_Acquisition", 1, 1, queue); acquisition = std::dynamic_pointer_cast(acq_); boost::shared_ptr msg_rx = GalileoE1Pcps8msAmbiguousAcquisitionGSoC2013Test_msg_rx_make(channel_internal_queue); ASSERT_NO_THROW( { acquisition->set_channel(1); - }) << "Failure setting channel." << std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { acquisition->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro." << std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { - acquisition->set_doppler_max(config->property("Acquisition.doppler_max", 10000)); - }) << "Failure setting doppler_max." << std::endl; + acquisition->set_doppler_max(config->property("Acquisition_1B.doppler_max", 10000)); + }) << "Failure setting doppler_max."; ASSERT_NO_THROW( { - acquisition->set_doppler_step(config->property("Acquisition.doppler_step", 500)); - }) << "Failure setting doppler_step." << std::endl; + acquisition->set_doppler_step(config->property("Acquisition_1B.doppler_step", 500)); + }) << "Failure setting doppler_step."; ASSERT_NO_THROW( { - acquisition->set_threshold(config->property("Acquisition.threshold", 0.0)); - }) << "Failure setting threshold." << std::endl; + acquisition->set_threshold(config->property("Acquisition_1B.threshold", 0.0)); + }) << "Failure setting threshold."; ASSERT_NO_THROW( { acquisition->connect(top_block); - }) << "Failure connecting acquisition to the top_block." << std::endl; + }) << "Failure connecting acquisition to the top_block."; acquisition->init(); @@ -523,7 +521,7 @@ TEST_F(GalileoE1Pcps8msAmbiguousAcquisitionGSoC2013Test, ValidationOfResults) signal_source->connect(top_block); top_block->connect(signal_source->get_right_block(), 0, acquisition->get_left_block(), 0); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of acquisition test." << std::endl; + }) << "Failure connecting the blocks of acquisition test."; // i = 0 --> satellite in acquisition is visible // i = 1 --> satellite in acquisition is not visible @@ -546,7 +544,7 @@ TEST_F(GalileoE1Pcps8msAmbiguousAcquisitionGSoC2013Test, ValidationOfResults) EXPECT_NO_THROW( { top_block->run(); // Start threads and wait - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; stop_queue(); @@ -574,33 +572,33 @@ TEST_F(GalileoE1Pcps8msAmbiguousAcquisitionGSoC2013Test, ValidationOfResultsProb config_2(); queue = gr::msg_queue::make(0); top_block = gr::make_top_block("Acquisition test"); - std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition", "Galileo_E1_PCPS_8ms_Ambiguous_Acquisition", 1, 1); + std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition_1B", "Galileo_E1_PCPS_8ms_Ambiguous_Acquisition", 1, 1); acquisition = std::dynamic_pointer_cast(acq_); boost::shared_ptr msg_rx = GalileoE1Pcps8msAmbiguousAcquisitionGSoC2013Test_msg_rx_make(channel_internal_queue); ASSERT_NO_THROW( { acquisition->set_channel(1); - }) << "Failure setting channel." << std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { acquisition->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro." << std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { - acquisition->set_doppler_max(config->property("Acquisition.doppler_max", 10000)); - }) << "Failure setting doppler_max." << std::endl; + acquisition->set_doppler_max(config->property("Acquisition_1B.doppler_max", 10000)); + }) << "Failure setting doppler_max."; ASSERT_NO_THROW( { - acquisition->set_doppler_step(config->property("Acquisition.doppler_step", 500)); - }) << "Failure setting doppler_step." << std::endl; + acquisition->set_doppler_step(config->property("Acquisition_1B.doppler_step", 500)); + }) << "Failure setting doppler_step."; ASSERT_NO_THROW( { - acquisition->set_threshold(config->property("Acquisition.threshold", 0.0)); - }) << "Failure setting threshold." << std::endl; + acquisition->set_threshold(config->property("Acquisition_1B.threshold", 0.0)); + }) << "Failure setting threshold."; ASSERT_NO_THROW( { acquisition->connect(top_block); - }) << "Failure connecting acquisition to the top_block." << std::endl; + }) << "Failure connecting acquisition to the top_block."; acquisition->init(); @@ -612,7 +610,7 @@ TEST_F(GalileoE1Pcps8msAmbiguousAcquisitionGSoC2013Test, ValidationOfResultsProb signal_source->connect(top_block); top_block->connect(signal_source->get_right_block(), 0, acquisition->get_left_block(), 0); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of acquisition test." << std::endl; + }) << "Failure connecting the blocks of acquisition test."; std::cout << "Probability of false alarm (target) = " << 0.1 << std::endl; @@ -637,7 +635,7 @@ TEST_F(GalileoE1Pcps8msAmbiguousAcquisitionGSoC2013Test, ValidationOfResultsProb EXPECT_NO_THROW( { top_block->run(); // Start threads and wait - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; stop_queue(); if (i == 0) { diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_gsoc2013_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_gsoc2013_test.cc index cda844b61..0f484fdba 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_gsoc2013_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_gsoc2013_test.cc @@ -241,17 +241,16 @@ void GalileoE1PcpsAmbiguousAcquisitionGSoC2013Test::config_1() config->set_property("InputFilter.filter_type", "bandpass"); config->set_property("InputFilter.grid_density", "16"); - config->set_property("Acquisition.item_type", "gr_complex"); - config->set_property("Acquisition.if", "0"); - config->set_property("Acquisition.coherent_integration_time_ms", + config->set_property("Acquisition_1B.implementation", "Galileo_E1_PCPS_Ambiguous_Acquisition"); + config->set_property("Acquisition_1B.item_type", "gr_complex"); + config->set_property("Acquisition_1B.coherent_integration_time_ms", std::to_string(integration_time_ms)); - config->set_property("Acquisition.max_dwells", "1"); - config->set_property("Acquisition.bit_transition_flag","false"); - config->set_property("Acquisition.implementation", "Galileo_E1_PCPS_Ambiguous_Acquisition"); - config->set_property("Acquisition.threshold", "0.1"); - config->set_property("Acquisition.doppler_max", "10000"); - config->set_property("Acquisition.doppler_step", "250"); - config->set_property("Acquisition.dump", "false"); + config->set_property("Acquisition_1B.max_dwells", "1"); + config->set_property("Acquisition_1B.bit_transition_flag","false"); + config->set_property("Acquisition_1B.threshold", "0.1"); + config->set_property("Acquisition_1B.doppler_max", "10000"); + config->set_property("Acquisition_1B.doppler_step", "250"); + config->set_property("Acquisition_1B.dump", "false"); } @@ -267,7 +266,7 @@ void GalileoE1PcpsAmbiguousAcquisitionGSoC2013Test::config_2() expected_delay_chips = 600; expected_doppler_hz = 750; - max_doppler_error_hz = 2/(3*integration_time_ms*1e-3); + max_doppler_error_hz = 2 / (3 * integration_time_ms * 1e-3); max_delay_error_chips = 0.50; num_of_realizations = 100; @@ -331,17 +330,16 @@ void GalileoE1PcpsAmbiguousAcquisitionGSoC2013Test::config_2() config->set_property("InputFilter.filter_type", "bandpass"); config->set_property("InputFilter.grid_density", "16"); - config->set_property("Acquisition.item_type", "gr_complex"); - config->set_property("Acquisition.if", "0"); - config->set_property("Acquisition.coherent_integration_time_ms", + config->set_property("Acquisition_1B.implementation", "Galileo_E1_PCPS_Ambiguous_Acquisition"); + config->set_property("Acquisition_1B.item_type", "gr_complex"); + config->set_property("Acquisition_1B.coherent_integration_time_ms", std::to_string(integration_time_ms)); - config->set_property("Acquisition.max_dwells", "1"); - config->set_property("Acquisition.bit_transition_flag","false"); - config->set_property("Acquisition.implementation", "Galileo_E1_PCPS_Ambiguous_Acquisition"); - config->set_property("Acquisition.pfa", "0.1"); - config->set_property("Acquisition.doppler_max", "10000"); - config->set_property("Acquisition.doppler_step", "250"); - config->set_property("Acquisition.dump", "false"); + config->set_property("Acquisition_1B.max_dwells", "1"); + config->set_property("Acquisition_1B.bit_transition_flag","false"); + config->set_property("Acquisition_1B.pfa", "0.1"); + config->set_property("Acquisition_1B.doppler_max", "10000"); + config->set_property("Acquisition_1B.doppler_step", "250"); + config->set_property("Acquisition_1B.dump", "false"); } @@ -424,7 +422,7 @@ void GalileoE1PcpsAmbiguousAcquisitionGSoC2013Test::stop_queue() TEST_F(GalileoE1PcpsAmbiguousAcquisitionGSoC2013Test, Instantiate) { config_1(); - std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition", "Galileo_E1_PCPS_Ambiguous_Acquisition", 1, 1); + std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition_1B", "Galileo_E1_PCPS_Ambiguous_Acquisition", 1, 1); acquisition = std::dynamic_pointer_cast(acq_); } @@ -438,7 +436,7 @@ TEST_F(GalileoE1PcpsAmbiguousAcquisitionGSoC2013Test, ConnectAndRun) queue = gr::msg_queue::make(0); config_1(); - std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition", "Galileo_E1_PCPS_Ambiguous_Acquisition", 1, 1); + std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition_1B", "Galileo_E1_PCPS_Ambiguous_Acquisition", 1, 1); acquisition = std::dynamic_pointer_cast(acq_); boost::shared_ptr msg_rx = GalileoE1PcpsAmbiguousAcquisitionGSoC2013Test_msg_rx_make(channel_internal_queue); @@ -449,14 +447,14 @@ TEST_F(GalileoE1PcpsAmbiguousAcquisitionGSoC2013Test, ConnectAndRun) top_block->connect(source, 0, valve, 0); top_block->connect(valve, 0, acquisition->get_left_block(), 0); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of acquisition test." << std::endl; + }) << "Failure connecting the blocks of acquisition test."; 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::endl; + }) << "Failure running the top_block."; std::cout << "Processed " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; } @@ -467,33 +465,33 @@ TEST_F(GalileoE1PcpsAmbiguousAcquisitionGSoC2013Test, ValidationOfResults) config_1(); top_block = gr::make_top_block("Acquisition test"); queue = gr::msg_queue::make(0); - std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition", "Galileo_E1_PCPS_Ambiguous_Acquisition", 1, 1); + std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition_1B", "Galileo_E1_PCPS_Ambiguous_Acquisition", 1, 1); acquisition = std::dynamic_pointer_cast(acq_); boost::shared_ptr msg_rx = GalileoE1PcpsAmbiguousAcquisitionGSoC2013Test_msg_rx_make(channel_internal_queue); ASSERT_NO_THROW( { acquisition->set_channel(1); - }) << "Failure setting channel." << std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { acquisition->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro." << std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { - acquisition->set_doppler_max(config->property("Acquisition.doppler_max", 10000)); - }) << "Failure setting doppler_max." << std::endl; + acquisition->set_doppler_max(config->property("Acquisition_1B.doppler_max", 10000)); + }) << "Failure setting doppler_max."; ASSERT_NO_THROW( { - acquisition->set_doppler_step(config->property("Acquisition.doppler_step", 500)); - }) << "Failure setting doppler_step." << std::endl; + acquisition->set_doppler_step(config->property("Acquisition_1B.doppler_step", 500)); + }) << "Failure setting doppler_step."; ASSERT_NO_THROW( { - acquisition->set_threshold(config->property("Acquisition.threshold", 0.0)); - }) << "Failure setting threshold." << std::endl; + acquisition->set_threshold(config->property("Acquisition_1B.threshold", 0.0)); + }) << "Failure setting threshold."; ASSERT_NO_THROW( { acquisition->connect(top_block); - }) << "Failure connecting acquisition to the top_block." << std::endl; + }) << "Failure connecting acquisition to the top_block."; acquisition->init(); @@ -505,7 +503,7 @@ TEST_F(GalileoE1PcpsAmbiguousAcquisitionGSoC2013Test, ValidationOfResults) signal_source->connect(top_block); top_block->connect(signal_source->get_right_block(), 0, acquisition->get_left_block(), 0); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of acquisition test." << std::endl; + }) << "Failure connecting the blocks of acquisition test."; // i = 0 --> satellite in acquisition is visible // i = 1 --> satellite in acquisition is not visible @@ -528,7 +526,7 @@ TEST_F(GalileoE1PcpsAmbiguousAcquisitionGSoC2013Test, ValidationOfResults) EXPECT_NO_THROW( { top_block->run(); // Start threads and wait - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; stop_queue(); if (i == 0) { @@ -553,33 +551,33 @@ TEST_F(GalileoE1PcpsAmbiguousAcquisitionGSoC2013Test, ValidationOfResultsProbabi config_2(); top_block = gr::make_top_block("Acquisition test"); queue = gr::msg_queue::make(0); - std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition", "Galileo_E1_PCPS_Ambiguous_Acquisition", 1, 1); + std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition_1B", "Galileo_E1_PCPS_Ambiguous_Acquisition", 1, 1); acquisition = std::dynamic_pointer_cast(acq_); boost::shared_ptr msg_rx = GalileoE1PcpsAmbiguousAcquisitionGSoC2013Test_msg_rx_make(channel_internal_queue); ASSERT_NO_THROW( { acquisition->set_channel(1); - }) << "Failure setting channel." << std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { acquisition->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro." << std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { - acquisition->set_doppler_max(config->property("Acquisition.doppler_max", 10000)); - }) << "Failure setting doppler_max." << std::endl; + acquisition->set_doppler_max(config->property("Acquisition_1B.doppler_max", 10000)); + }) << "Failure setting doppler_max."; ASSERT_NO_THROW( { - acquisition->set_doppler_step(config->property("Acquisition.doppler_step", 500)); - }) << "Failure setting doppler_step." << std::endl; + acquisition->set_doppler_step(config->property("Acquisition_1B.doppler_step", 500)); + }) << "Failure setting doppler_step."; ASSERT_NO_THROW( { - acquisition->set_threshold(config->property("Acquisition.threshold", 0.0)); - }) << "Failure setting threshold." << std::endl; + acquisition->set_threshold(config->property("Acquisition_1B.threshold", 0.0)); + }) << "Failure setting threshold."; ASSERT_NO_THROW( { acquisition->connect(top_block); - }) << "Failure connecting acquisition to the top_block." << std::endl; + }) << "Failure connecting acquisition to the top_block."; acquisition->init(); @@ -591,7 +589,7 @@ TEST_F(GalileoE1PcpsAmbiguousAcquisitionGSoC2013Test, ValidationOfResultsProbabi signal_source->connect(top_block); top_block->connect(signal_source->get_right_block(), 0, acquisition->get_left_block(), 0); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of acquisition test." << std::endl; + }) << "Failure connecting the blocks of acquisition test."; std::cout << "Probability of false alarm (target) = " << 0.1 << std::endl; @@ -616,7 +614,7 @@ TEST_F(GalileoE1PcpsAmbiguousAcquisitionGSoC2013Test, ValidationOfResultsProbabi EXPECT_NO_THROW( { top_block->run(); // Start threads and wait - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; stop_queue(); diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_gsoc_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_gsoc_test.cc index 55cda548c..ae587a1b3 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_gsoc_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_gsoc_test.cc @@ -158,17 +158,16 @@ void GalileoE1PcpsAmbiguousAcquisitionGSoCTest::init() signal.copy(gnss_synchro.Signal, 2, 0); gnss_synchro.PRN = 11; + config->set_property("Acquisition_1B.implementation", "Galileo_E1_PCPS_Ambiguous_Acquisition"); config->set_property("GNSS-SDR.internal_fs_sps", "4000000"); - config->set_property("Acquisition.item_type", "gr_complex"); - config->set_property("Acquisition.if", "0"); - config->set_property("Acquisition.coherent_integration_time_ms", "4"); - config->set_property("Acquisition.dump", "false"); - config->set_property("Acquisition.implementation", "Galileo_E1_PCPS_Ambiguous_Acquisition"); - config->set_property("Acquisition.threshold", "0.1"); - config->set_property("Acquisition.doppler_max", "10000"); - config->set_property("Acquisition.doppler_step", "125"); - config->set_property("Acquisition.repeat_satellite", "false"); - config->set_property("Acquisition0.cboc", "true"); + config->set_property("Acquisition_1B.item_type", "gr_complex"); + config->set_property("Acquisition_1B.coherent_integration_time_ms", "4"); + config->set_property("Acquisition_1B.dump", "false"); + config->set_property("Acquisition_1B.threshold", "0.1"); + config->set_property("Acquisition_1B.doppler_max", "10000"); + config->set_property("Acquisition_1B.doppler_step", "125"); + config->set_property("Acquisition_1B.repeat_satellite", "false"); + config->set_property("Acquisition_1B.cboc", "true"); } @@ -205,7 +204,7 @@ void GalileoE1PcpsAmbiguousAcquisitionGSoCTest::stop_queue() TEST_F(GalileoE1PcpsAmbiguousAcquisitionGSoCTest, Instantiate) { init(); - std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition", "Galileo_E1_PCPS_Ambiguous_Acquisition", 1, 1); + std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition_1B", "Galileo_E1_PCPS_Ambiguous_Acquisition", 1, 1); std::shared_ptr acquisition = std::dynamic_pointer_cast(acq_); EXPECT_STREQ("Galileo_E1_PCPS_Ambiguous_Acquisition", acquisition->implementation().c_str()); } @@ -221,7 +220,7 @@ TEST_F(GalileoE1PcpsAmbiguousAcquisitionGSoCTest, ConnectAndRun) top_block = gr::make_top_block("Acquisition test"); init(); - std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition", "Galileo_E1_PCPS_Ambiguous_Acquisition", 1, 1); + std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition_1B", "Galileo_E1_PCPS_Ambiguous_Acquisition", 1, 1); std::shared_ptr acquisition = std::dynamic_pointer_cast(acq_); boost::shared_ptr msg_rx = GalileoE1PcpsAmbiguousAcquisitionGSoCTest_msg_rx_make(channel_internal_queue); @@ -232,14 +231,14 @@ TEST_F(GalileoE1PcpsAmbiguousAcquisitionGSoCTest, ConnectAndRun) top_block->connect(source, 0, valve, 0); top_block->connect(valve, 0, acquisition->get_left_block(), 0); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of acquisition test." << std::endl; + }) << "Failure connecting the blocks of acquisition test."; 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::endl; + }) << "Failure running the top_block."; std::cout << "Processed " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; } @@ -258,27 +257,27 @@ TEST_F(GalileoE1PcpsAmbiguousAcquisitionGSoCTest, ValidationOfResults) ASSERT_NO_THROW( { acquisition->set_channel(gnss_synchro.Channel_ID); - }) << "Failure setting channel." << std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { acquisition->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro." << std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { - acquisition->set_threshold(config->property("Acquisition.threshold", 0.00001)); - }) << "Failure setting threshold." << std::endl; + acquisition->set_threshold(config->property("Acquisition_1B.threshold", 0.00001)); + }) << "Failure setting threshold."; ASSERT_NO_THROW( { - acquisition->set_doppler_max(config->property("Acquisition.doppler_max", 10000)); - }) << "Failure setting doppler_max." << std::endl; + acquisition->set_doppler_max(config->property("Acquisition_1B.doppler_max", 10000)); + }) << "Failure setting doppler_max."; ASSERT_NO_THROW( { - acquisition->set_doppler_step(config->property("Acquisition.doppler_step", 250)); - }) << "Failure setting doppler_step." << std::endl; + acquisition->set_doppler_step(config->property("Acquisition_1B.doppler_step", 250)); + }) << "Failure setting doppler_step."; ASSERT_NO_THROW( { acquisition->connect(top_block); - }) << "Failure connecting acquisition to the top_block." << std::endl; + }) << "Failure connecting acquisition to the top_block."; ASSERT_NO_THROW( { std::string path = std::string(TEST_PATH); @@ -288,7 +287,7 @@ TEST_F(GalileoE1PcpsAmbiguousAcquisitionGSoCTest, ValidationOfResults) gr::blocks::file_source::sptr file_source = gr::blocks::file_source::make(sizeof(gr_complex), file_name, false); top_block->connect(file_source, 0, acquisition->get_left_block(), 0); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of acquisition test." << std::endl; + }) << "Failure connecting the blocks of acquisition test."; ASSERT_NO_THROW( { start_queue(); @@ -296,14 +295,14 @@ TEST_F(GalileoE1PcpsAmbiguousAcquisitionGSoCTest, ValidationOfResults) acquisition->init(); acquisition->reset(); acquisition->set_state(1); - }) << "Failure starting acquisition" << std::endl; + }) << "Failure starting acquisition"; 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::endl; + }) << "Failure running the top_block."; stop_queue(); diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test.cc index 46518b583..5dd8dc11e 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test.cc @@ -47,8 +47,11 @@ #include "gnss_sdr_valve.h" #include "gnss_signal.h" #include "gnss_synchro.h" - +#include "gnuplot_i.h" +#include "test_flags.h" +#include "acquisition_dump_reader.h" #include "galileo_e1_pcps_ambiguous_acquisition.h" +#include "Galileo_E1.h" // ######## GNURADIO BLOCK MESSAGE RECEVER ######### class GalileoE1PcpsAmbiguousAcquisitionTest_msg_rx; @@ -121,6 +124,7 @@ protected: {} void init(); + void plot_grid(); gr::top_block_sptr top_block; std::shared_ptr factory; @@ -134,28 +138,93 @@ void GalileoE1PcpsAmbiguousAcquisitionTest::init() { gnss_synchro.Channel_ID = 0; gnss_synchro.System = 'E'; - std::string signal = "1C"; + std::string signal = "1B"; signal.copy(gnss_synchro.Signal, 2, 0); gnss_synchro.PRN = 1; config->set_property("GNSS-SDR.internal_fs_sps", "4000000"); - config->set_property("Acquisition.item_type", "gr_complex"); - config->set_property("Acquisition.if", "0"); - config->set_property("Acquisition.coherent_integration_time_ms", "4"); - config->set_property("Acquisition.dump", "false"); - config->set_property("Acquisition.implementation", "Galileo_E1_PCPS_Ambiguous_Acquisition"); - config->set_property("Acquisition.threshold", "0.0001"); - config->set_property("Acquisition.doppler_max", "10000"); - config->set_property("Acquisition.doppler_step", "250"); - config->set_property("Acquisition.repeat_satellite", "false"); - config->set_property("Acquisition1.cboc", "true"); + config->set_property("Acquisition_1B.item_type", "gr_complex"); + config->set_property("Acquisition_1B.if", "0"); + config->set_property("Acquisition_1B.coherent_integration_time_ms", "4"); + if(FLAGS_plot_acq_grid == true) + { + config->set_property("Acquisition_1B.dump", "true"); + } + else + { + config->set_property("Acquisition_1B.dump", "false"); + } + config->set_property("Acquisition_1B.implementation", "Galileo_E1_PCPS_Ambiguous_Acquisition"); + config->set_property("Acquisition_1B.threshold", "0.0001"); + config->set_property("Acquisition_1B.doppler_max", "10000"); + config->set_property("Acquisition_1B.doppler_step", "250"); + config->set_property("Acquisition_1B.repeat_satellite", "false"); + config->set_property("Acquisition_1B.cboc", "true"); } +void GalileoE1PcpsAmbiguousAcquisitionTest::plot_grid() +{ + //load the measured values + std::string basename = "./data/acquisition_E_1B"; + unsigned int sat = static_cast(gnss_synchro.PRN); + unsigned int doppler_max = 10000; // !!! + unsigned int doppler_step = 250; // !! + unsigned int samples_per_code = static_cast(round(4000000 / (Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS))); // !! + acquisition_dump_reader acq_dump(basename, sat, doppler_max, doppler_step, samples_per_code); + + if(!acq_dump.read_binary_acq()) std::cout << "Error reading files" << std::endl; + + std::vector doppler = acq_dump.doppler; + std::vector samples = acq_dump.samples; + std::vector > mag = acq_dump.mag; + + const std::string gnuplot_executable(FLAGS_gnuplot_executable); + if(gnuplot_executable.empty()) + { + std::cout << "WARNING: Although the flag plot_acq_grid has been set to TRUE," << std::endl; + std::cout << "gnuplot has not been found in your system." << std::endl; + std::cout << "Test results will not be plotted." << std::endl; + } + else + { + std::cout << "Plotting the acquisition grid..." << std::endl; + try + { + boost::filesystem::path p(gnuplot_executable); + boost::filesystem::path dir = p.parent_path(); + std::string gnuplot_path = dir.native(); + Gnuplot::set_GNUPlotPath(gnuplot_path); + + Gnuplot g1("lines"); + g1.set_title("Galileo E1b/c signal acquisition for satellite PRN #" + std::to_string(gnss_synchro.PRN)); + g1.set_xlabel("Doppler [Hz]"); + g1.set_ylabel("Sample"); + //g1.cmd("set view 60, 105, 1, 1"); + g1.plot_grid3d(doppler, samples, mag); + + g1.savetops("Galileo_E1_acq_grid"); + g1.savetopdf("Galileo_E1_acq_grid"); + g1.showonscreen(); + } + catch (const GnuplotException & ge) + { + std::cout << ge.what() << std::endl; + } + } + std::string data_str = "./data"; + if (boost::filesystem::exists(data_str)) + { + boost::filesystem::remove_all(data_str); + } +} + + + TEST_F(GalileoE1PcpsAmbiguousAcquisitionTest, Instantiate) { init(); - std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition", "Galileo_E1_PCPS_Ambiguous_Acquisition", 1, 1); + std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition_1B", "Galileo_E1_PCPS_Ambiguous_Acquisition", 1, 1); std::shared_ptr acquisition = std::dynamic_pointer_cast(acq_); } @@ -169,7 +238,7 @@ TEST_F(GalileoE1PcpsAmbiguousAcquisitionTest, ConnectAndRun) top_block = gr::make_top_block("Acquisition test"); gr::msg_queue::sptr queue = gr::msg_queue::make(0); init(); - std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition", "Galileo_E1_PCPS_Ambiguous_Acquisition", 1, 1); + std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition_1B", "Galileo_E1_PCPS_Ambiguous_Acquisition", 1, 1); std::shared_ptr acquisition = std::dynamic_pointer_cast(acq_); boost::shared_ptr msg_rx = GalileoE1PcpsAmbiguousAcquisitionTest_msg_rx_make(); @@ -180,14 +249,14 @@ TEST_F(GalileoE1PcpsAmbiguousAcquisitionTest, ConnectAndRun) top_block->connect(source, 0, valve, 0); top_block->connect(valve, 0, acquisition->get_left_block(), 0); top_block->msg_connect(acquisition->get_right_block(),pmt::mp("events"), msg_rx,pmt::mp("events")); - }) << "Failure connecting the blocks of acquisition test." << std::endl; + }) << "Failure connecting the blocks of acquisition test."; 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::endl; + }) << "Failure running the top_block."; std::cout << "Processed " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; } @@ -197,37 +266,47 @@ TEST_F(GalileoE1PcpsAmbiguousAcquisitionTest, ValidationOfResults) std::chrono::time_point start, end; std::chrono::duration elapsed_seconds(0); + if(FLAGS_plot_acq_grid == true) + { + std::string data_str = "./data"; + if (boost::filesystem::exists(data_str)) + { + boost::filesystem::remove_all(data_str); + } + boost::filesystem::create_directory(data_str); + } + double expected_delay_samples = 2920; //18250; double expected_doppler_hz = -632; init(); top_block = gr::make_top_block("Acquisition test"); - std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition", "Galileo_E1_PCPS_Ambiguous_Acquisition", 1, 1); + std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition_1B", "Galileo_E1_PCPS_Ambiguous_Acquisition", 1, 1); std::shared_ptr acquisition = std::dynamic_pointer_cast(acq_); boost::shared_ptr msg_rx = GalileoE1PcpsAmbiguousAcquisitionTest_msg_rx_make(); ASSERT_NO_THROW( { acquisition->set_channel(gnss_synchro.Channel_ID); - }) << "Failure setting channel." << std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { acquisition->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro." << std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { - acquisition->set_threshold(config->property("Acquisition.threshold", 1e-9)); - }) << "Failure setting threshold." << std::endl; + acquisition->set_threshold(config->property("Acquisition_1B.threshold", 1e-9)); + }) << "Failure setting threshold."; ASSERT_NO_THROW( { - acquisition->set_doppler_max(config->property("Acquisition.doppler_max", 10000)); - }) << "Failure setting doppler_max." << std::endl; + acquisition->set_doppler_max(config->property("Acquisition_1B.doppler_max", 10000)); + }) << "Failure setting doppler_max."; ASSERT_NO_THROW( { - acquisition->set_doppler_step(config->property("Acquisition.doppler_step", 250)); - }) << "Failure setting doppler_step." << std::endl; + acquisition->set_doppler_step(config->property("Acquisition_1B.doppler_step", 250)); + }) << "Failure setting doppler_step."; ASSERT_NO_THROW( { acquisition->connect(top_block); - }) << "Failure connecting acquisition to the top_block." << std::endl; + }) << "Failure connecting acquisition to the top_block."; ASSERT_NO_THROW( { std::string path = std::string(TEST_PATH); @@ -236,7 +315,7 @@ TEST_F(GalileoE1PcpsAmbiguousAcquisitionTest, ValidationOfResults) gr::blocks::file_source::sptr file_source = gr::blocks::file_source::make(sizeof(gr_complex), file_name, false); top_block->connect(file_source, 0, acquisition->get_left_block(), 0); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of acquisition test." << std::endl; + }) << "Failure connecting the blocks of acquisition test."; acquisition->set_local_code(); acquisition->init(); @@ -248,7 +327,7 @@ TEST_F(GalileoE1PcpsAmbiguousAcquisitionTest, ValidationOfResults) top_block->run(); // Start threads and wait end = std::chrono::system_clock::now(); elapsed_seconds = end - start; - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; unsigned long int nsamples = gnss_synchro.Acq_samplestamp_samples; std::cout << "Acquired " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; @@ -263,5 +342,10 @@ TEST_F(GalileoE1PcpsAmbiguousAcquisitionTest, ValidationOfResults) EXPECT_LE(doppler_error_hz, 166) << "Doppler error exceeds the expected value: 166 Hz = 2/(3*integration period)"; EXPECT_LT(delay_error_chips, 0.175) << "Delay error exceeds the expected value: 0.175 chips"; + + if(FLAGS_plot_acq_grid == true) + { + plot_grid(); + } } diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_cccwsr_ambiguous_acquisition_gsoc2013_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_cccwsr_ambiguous_acquisition_gsoc2013_test.cc index e73ee9912..ba4c01e2d 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_cccwsr_ambiguous_acquisition_gsoc2013_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_cccwsr_ambiguous_acquisition_gsoc2013_test.cc @@ -242,16 +242,16 @@ void GalileoE1PcpsCccwsrAmbiguousAcquisitionTest::config_1() config->set_property("InputFilter.filter_type", "bandpass"); config->set_property("InputFilter.grid_density", "16"); - config->set_property("Acquisition.item_type", "gr_complex"); - config->set_property("Acquisition.if", "0"); - config->set_property("Acquisition.coherent_integration_time_ms", + config->set_property("Acquisition_1B.item_type", "gr_complex"); + config->set_property("Acquisition_1B.if", "0"); + config->set_property("Acquisition_1B.coherent_integration_time_ms", std::to_string(integration_time_ms)); - config->set_property("Acquisition.max_dwells", "1"); - config->set_property("Acquisition.implementation", "Galileo_E1_PCPS_CCCWSR_Ambiguous_Acquisition"); - config->set_property("Acquisition.threshold", "0.7"); - config->set_property("Acquisition.doppler_max", "10000"); - config->set_property("Acquisition.doppler_step", "250"); - config->set_property("Acquisition.dump", "false"); + config->set_property("Acquisition_1B.max_dwells", "1"); + config->set_property("Acquisition_1B.implementation", "Galileo_E1_PCPS_CCCWSR_Ambiguous_Acquisition"); + config->set_property("Acquisition_1B.threshold", "0.7"); + config->set_property("Acquisition_1B.doppler_max", "10000"); + config->set_property("Acquisition_1B.doppler_step", "250"); + config->set_property("Acquisition_1B.dump", "false"); } @@ -331,16 +331,15 @@ void GalileoE1PcpsCccwsrAmbiguousAcquisitionTest::config_2() config->set_property("InputFilter.filter_type", "bandpass"); config->set_property("InputFilter.grid_density", "16"); - config->set_property("Acquisition.item_type", "gr_complex"); - config->set_property("Acquisition.if", "0"); - config->set_property("Acquisition.coherent_integration_time_ms", + config->set_property("Acquisition_1B.implementation", "Galileo_E1_PCPS_CCCWSR_Ambiguous_Acquisition"); + config->set_property("Acquisition_1B.item_type", "gr_complex"); + config->set_property("Acquisition_1B.coherent_integration_time_ms", std::to_string(integration_time_ms)); - config->set_property("Acquisition.max_dwells", "1"); - config->set_property("Acquisition.implementation", "Galileo_E1_PCPS_CCCWSR_Ambiguous_Acquisition"); - config->set_property("Acquisition.threshold", "0.00215"); // Pfa,a = 0.1 - config->set_property("Acquisition.doppler_max", "10000"); - config->set_property("Acquisition.doppler_step", "250"); - config->set_property("Acquisition.dump", "false"); + config->set_property("Acquisition_1B.max_dwells", "1"); + config->set_property("Acquisition_1B.threshold", "0.00215"); // Pfa,a = 0.1 + config->set_property("Acquisition_1B.doppler_max", "10000"); + config->set_property("Acquisition_1B.doppler_step", "250"); + config->set_property("Acquisition_1B.dump", "false"); } @@ -425,7 +424,7 @@ void GalileoE1PcpsCccwsrAmbiguousAcquisitionTest::stop_queue() TEST_F(GalileoE1PcpsCccwsrAmbiguousAcquisitionTest, Instantiate) { config_1(); - std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition", "Galileo_E1_PCPS_CCCWSR_Ambiguous_Acquisition", 1, 1); + std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition_1B", "Galileo_E1_PCPS_CCCWSR_Ambiguous_Acquisition", 1, 1); acquisition = std::dynamic_pointer_cast(acq_); } @@ -440,7 +439,7 @@ TEST_F(GalileoE1PcpsCccwsrAmbiguousAcquisitionTest, ConnectAndRun) top_block = gr::make_top_block("Acquisition test"); queue = gr::msg_queue::make(0); - std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition", "Galileo_E1_PCPS_CCCWSR_Ambiguous_Acquisition", 1, 1); + std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition_1B", "Galileo_E1_PCPS_CCCWSR_Ambiguous_Acquisition", 1, 1); acquisition = std::dynamic_pointer_cast(acq_); boost::shared_ptr msg_rx = GalileoE1PcpsCccwsrAmbiguousAcquisitionTest_msg_rx_make(channel_internal_queue); @@ -451,14 +450,14 @@ TEST_F(GalileoE1PcpsCccwsrAmbiguousAcquisitionTest, ConnectAndRun) top_block->connect(source, 0, valve, 0); top_block->connect(valve, 0, acquisition->get_left_block(), 0); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of acquisition test."<< std::endl; + }) << "Failure connecting the blocks of acquisition test."; 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::endl; + }) << "Failure running the top_block."; std::cout << "Processed " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; } @@ -469,33 +468,33 @@ TEST_F(GalileoE1PcpsCccwsrAmbiguousAcquisitionTest, ValidationOfResults) config_1(); top_block = gr::make_top_block("Acquisition test"); queue = gr::msg_queue::make(0); - std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition", "Galileo_E1_PCPS_CCCWSR_Ambiguous_Acquisition", 1, 1); + std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition_1B", "Galileo_E1_PCPS_CCCWSR_Ambiguous_Acquisition", 1, 1); acquisition = std::dynamic_pointer_cast(acq_); boost::shared_ptr msg_rx = GalileoE1PcpsCccwsrAmbiguousAcquisitionTest_msg_rx_make(channel_internal_queue); ASSERT_NO_THROW( { acquisition->set_channel(1); - }) << "Failure setting channel."<< std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { acquisition->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro."<< std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { - acquisition->set_doppler_max(config->property("Acquisition.doppler_max", 10000)); - }) << "Failure setting doppler_max."<< std::endl; + acquisition->set_doppler_max(config->property("Acquisition_1B.doppler_max", 10000)); + }) << "Failure setting doppler_max."; ASSERT_NO_THROW( { - acquisition->set_doppler_step(config->property("Acquisition.doppler_step", 500)); - }) << "Failure setting doppler_step."<< std::endl; + acquisition->set_doppler_step(config->property("Acquisition_1B.doppler_step", 500)); + }) << "Failure setting doppler_step."; ASSERT_NO_THROW( { - acquisition->set_threshold(config->property("Acquisition.threshold", 0.00001)); - }) << "Failure setting threshold."<< std::endl; + acquisition->set_threshold(config->property("Acquisition_1B.threshold", 0.00001)); + }) << "Failure setting threshold."; ASSERT_NO_THROW( { acquisition->connect(top_block); - }) << "Failure connecting acquisition to the top_block."<< std::endl; + }) << "Failure connecting acquisition to the top_block."; acquisition->init(); acquisition->reset(); @@ -508,7 +507,7 @@ TEST_F(GalileoE1PcpsCccwsrAmbiguousAcquisitionTest, ValidationOfResults) signal_source->connect(top_block); top_block->connect(signal_source->get_right_block(), 0, acquisition->get_left_block(), 0); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of acquisition test." << std::endl; + }) << "Failure connecting the blocks of acquisition test."; // i = 0 --> satellite in acquisition is visible // i = 1 --> satellite in acquisition is not visible @@ -532,7 +531,7 @@ TEST_F(GalileoE1PcpsCccwsrAmbiguousAcquisitionTest, ValidationOfResults) EXPECT_NO_THROW( { top_block->run(); // Start threads and wait - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; stop_queue(); @@ -552,12 +551,12 @@ TEST_F(GalileoE1PcpsCccwsrAmbiguousAcquisitionTest, ValidationOfResults) #ifdef OLD_BOOST ASSERT_NO_THROW( { ch_thread.timed_join(boost::posix_time::seconds(1)); - }) << "Failure while waiting the queue to stop" << std::endl; + }) << "Failure while waiting the queue to stop"; #endif #ifndef OLD_BOOST ASSERT_NO_THROW( { ch_thread.try_join_until(boost::chrono::steady_clock::now() + boost::chrono::milliseconds(50)); - }) << "Failure while waiting the queue to stop" << std::endl; + }) << "Failure while waiting the queue to stop"; #endif } } @@ -568,33 +567,33 @@ TEST_F(GalileoE1PcpsCccwsrAmbiguousAcquisitionTest, ValidationOfResultsProbabili config_2(); top_block = gr::make_top_block("Acquisition test"); queue = gr::msg_queue::make(0); - std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition", "Galileo_E1_PCPS_CCCWSR_Ambiguous_Acquisition", 1, 1); + std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition_1B", "Galileo_E1_PCPS_CCCWSR_Ambiguous_Acquisition", 1, 1); acquisition = std::dynamic_pointer_cast(acq_); boost::shared_ptr msg_rx = GalileoE1PcpsCccwsrAmbiguousAcquisitionTest_msg_rx_make(channel_internal_queue); ASSERT_NO_THROW( { acquisition->set_channel(1); - }) << "Failure setting channel."<< std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { acquisition->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro."<< std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { - acquisition->set_doppler_max(config->property("Acquisition.doppler_max", 10000)); - }) << "Failure setting doppler_max."<< std::endl; + acquisition->set_doppler_max(config->property("Acquisition_1B.doppler_max", 10000)); + }) << "Failure setting doppler_max."; ASSERT_NO_THROW( { - acquisition->set_doppler_step(config->property("Acquisition.doppler_step", 500)); - }) << "Failure setting doppler_step."<< std::endl; + acquisition->set_doppler_step(config->property("Acquisition_1B.doppler_step", 500)); + }) << "Failure setting doppler_step."; ASSERT_NO_THROW( { - acquisition->set_threshold(config->property("Acquisition.threshold", 0.00215)); - }) << "Failure setting threshold."<< std::endl; + acquisition->set_threshold(config->property("Acquisition_1B.threshold", 0.00215)); + }) << "Failure setting threshold."; ASSERT_NO_THROW( { acquisition->connect(top_block); - }) << "Failure connecting acquisition to the top_block."<< std::endl; + }) << "Failure connecting acquisition to the top_block."; acquisition->init(); acquisition->reset(); @@ -607,7 +606,7 @@ TEST_F(GalileoE1PcpsCccwsrAmbiguousAcquisitionTest, ValidationOfResultsProbabili signal_source->connect(top_block); top_block->connect(signal_source->get_right_block(), 0, acquisition->get_left_block(), 0); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of acquisition test." << std::endl; + }) << "Failure connecting the blocks of acquisition test."; std::cout << "Probability of false alarm (target) = " << 0.1 << std::endl; @@ -635,7 +634,7 @@ TEST_F(GalileoE1PcpsCccwsrAmbiguousAcquisitionTest, ValidationOfResultsProbabili EXPECT_NO_THROW( { top_block->run(); // Start threads and wait - }) << "Failure running the top_block."<< std::endl; + }) << "Failure running the top_block."; stop_queue(); diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_quicksync_ambiguous_acquisition_gsoc2014_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_quicksync_ambiguous_acquisition_gsoc2014_test.cc index 5e9b4d92d..b6cb14a8a 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_quicksync_ambiguous_acquisition_gsoc2014_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_quicksync_ambiguous_acquisition_gsoc2014_test.cc @@ -260,18 +260,17 @@ void GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test::config_1() config->set_property("InputFilter.filter_type", "bandpass"); config->set_property("InputFilter.grid_density", "16"); - config->set_property("Acquisition.item_type", "gr_complex"); - config->set_property("Acquisition.if", "0"); - config->set_property("Acquisition.coherent_integration_time_ms", + config->set_property("Acquisition_1B.implementation", "Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition"); + config->set_property("Acquisition_1B.item_type", "gr_complex"); + config->set_property("Acquisition_1B.coherent_integration_time_ms", std::to_string(integration_time_ms)); - config->set_property("Acquisition.max_dwells", "1"); - config->set_property("Acquisition.bit_transition_flag","false"); - config->set_property("Acquisition.implementation", "Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition"); - config->set_property("Acquisition.threshold", "1"); - config->set_property("Acquisition.doppler_max", "10000"); - config->set_property("Acquisition.doppler_step", "250"); - config->set_property("Acquisition.folding_factor", "2"); - config->set_property("Acquisition.dump", "false"); + config->set_property("Acquisition_1B.max_dwells", "1"); + config->set_property("Acquisition_1B.bit_transition_flag","false"); + config->set_property("Acquisition_1B.threshold", "1"); + config->set_property("Acquisition_1Bdoppler_max", "10000"); + config->set_property("Acquisition_1B.doppler_step", "250"); + config->set_property("Acquisition_1B.folding_factor", "2"); + config->set_property("Acquisition_1B.dump", "false"); } @@ -355,18 +354,17 @@ void GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test::config_2() config->set_property("InputFilter.filter_type", "bandpass"); config->set_property("InputFilter.grid_density", "16"); - config->set_property("Acquisition.item_type", "gr_complex"); - config->set_property("Acquisition.if", "0"); - config->set_property("Acquisition.coherent_integration_time_ms", + config->set_property("Acquisition_1B.implementation", "Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition"); + config->set_property("Acquisition_1B.item_type", "gr_complex"); + config->set_property("Acquisition_1B.coherent_integration_time_ms", std::to_string(integration_time_ms)); - config->set_property("Acquisition.max_dwells", "1"); - config->set_property("Acquisition.bit_transition_flag","false"); - config->set_property("Acquisition.implementation", "Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition"); - config->set_property("Acquisition.threshold", std::to_string(FLAGS_e1_value_threshold)); - config->set_property("Acquisition.doppler_max", "10000"); - config->set_property("Acquisition.doppler_step", "125"); - config->set_property("Acquisition.folding_factor", "2"); - config->set_property("Acquisition.dump", "false"); + config->set_property("Acquisition_1B.max_dwells", "1"); + config->set_property("Acquisition_1B.bit_transition_flag","false"); + config->set_property("Acquisition_1B.threshold", std::to_string(FLAGS_e1_value_threshold)); + config->set_property("Acquisition_1B.doppler_max", "10000"); + config->set_property("Acquisition_1B.doppler_step", "125"); + config->set_property("Acquisition_1B.folding_factor", "2"); + config->set_property("Acquisition_1B.dump", "false"); } @@ -446,18 +444,17 @@ void GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test::config_3() config->set_property("InputFilter.filter_type", "bandpass"); config->set_property("InputFilter.grid_density", "16"); - config->set_property("Acquisition.item_type", "gr_complex"); - config->set_property("Acquisition.if", "0"); - config->set_property("Acquisition.coherent_integration_time_ms", + config->set_property("Acquisition_1B.implementation", "Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition"); + config->set_property("Acquisition_1B.item_type", "gr_complex"); + config->set_property("Acquisition_1B.coherent_integration_time_ms", std::to_string(integration_time_ms)); - config->set_property("Acquisition.max_dwells", "1"); - config->set_property("Acquisition.bit_transition_flag","false"); - config->set_property("Acquisition.implementation", "Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition"); - config->set_property("Acquisition.threshold", "0.2"); - config->set_property("Acquisition.doppler_max", "10000"); - config->set_property("Acquisition.doppler_step", "125"); - config->set_property("Acquisition.folding_factor", "4"); - config->set_property("Acquisition.dump", "false"); + config->set_property("Acquisition_1B.max_dwells", "1"); + config->set_property("Acquisition_1B.bit_transition_flag","false"); + config->set_property("Acquisition_1B.threshold", "0.2"); + config->set_property("Acquisition_1B.doppler_max", "10000"); + config->set_property("Acquisition_1B.doppler_step", "125"); + config->set_property("Acquisition_1B.folding_factor", "4"); + config->set_property("Acquisition_1B.dump", "false"); } @@ -551,7 +548,7 @@ void GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test::stop_queue() TEST_F(GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test, Instantiate) { config_1(); - std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition", "Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition", 1, 1); + std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition_1B", "Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition", 1, 1); acquisition = std::dynamic_pointer_cast(acq_); } @@ -567,7 +564,7 @@ TEST_F(GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test, ConnectAndRun) config_1(); - std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition", "Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition", 1, 1); + std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition_1B", "Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition", 1, 1); acquisition = std::dynamic_pointer_cast(acq_); boost::shared_ptr msg_rx = GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test_msg_rx_make(channel_internal_queue); @@ -580,14 +577,14 @@ TEST_F(GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test, ConnectAndRun) top_block->connect(source, 0, valve, 0); top_block->connect(valve, 0, acquisition->get_left_block(), 0); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of acquisition test."<< std::endl; + }) << "Failure connecting the blocks of acquisition test."; EXPECT_NO_THROW( { begin = std::chrono::system_clock::now(); top_block->run(); // Start threads and wait end = std::chrono::system_clock::now(); elapsed_seconds = end - begin; - }) << "Failure running the top_block."<< std::endl; + }) << "Failure running the top_block."; std::cout << "Processed " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; LOG(INFO) << "----end connect and run test-----"; @@ -602,33 +599,33 @@ TEST_F(GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test, ValidationOfResul top_block = gr::make_top_block("Acquisition test"); queue = gr::msg_queue::make(0); - std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition", "Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition", 1, 1); + std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition_1B", "Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition", 1, 1); acquisition = std::dynamic_pointer_cast(acq_); boost::shared_ptr msg_rx = GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test_msg_rx_make(channel_internal_queue); ASSERT_NO_THROW( { acquisition->set_channel(0); - }) << "Failure setting channel."<< std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { acquisition->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro."<< std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { - acquisition->set_doppler_max(config->property("Acquisition.doppler_max", 10000)); - }) << "Failure setting doppler_max."<< std::endl; + acquisition->set_doppler_max(config->property("Acquisition_1B.doppler_max", 10000)); + }) << "Failure setting doppler_max."; ASSERT_NO_THROW( { - acquisition->set_doppler_step(config->property("Acquisition.doppler_step", 125)); - }) << "Failure setting doppler_step."<< std::endl; + acquisition->set_doppler_step(config->property("Acquisition_1B.doppler_step", 125)); + }) << "Failure setting doppler_step."; ASSERT_NO_THROW( { acquisition->set_threshold(1); - }) << "Failure setting threshold."<< std::endl; + }) << "Failure setting threshold."; ASSERT_NO_THROW( { acquisition->connect(top_block); - }) << "Failure connecting acquisition to the top_block." << std::endl; + }) << "Failure connecting acquisition to the top_block."; acquisition->init(); acquisition->reset(); @@ -641,7 +638,7 @@ TEST_F(GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test, ValidationOfResul signal_source->connect(top_block); top_block->connect(signal_source->get_right_block(), 0, acquisition->get_left_block(), 0); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of acquisition test." << std::endl; + }) << "Failure connecting the blocks of acquisition test."; // i = 0 --> satellite in acquisition is visible @@ -666,7 +663,7 @@ TEST_F(GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test, ValidationOfResul EXPECT_NO_THROW( { top_block->run(); // Start threads and wait - }) << "Failure running the top_block."<< std::endl; + }) << "Failure running the top_block."; stop_queue(); @@ -693,33 +690,33 @@ TEST_F(GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test, ValidationOfResul top_block = gr::make_top_block("Acquisition test"); queue = gr::msg_queue::make(0); - std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition", "Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition", 1, 1); + std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition_1B", "Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition", 1, 1); acquisition = std::dynamic_pointer_cast(acq_); boost::shared_ptr msg_rx = GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test_msg_rx_make(channel_internal_queue); ASSERT_NO_THROW( { acquisition->set_channel(1); - }) << "Failure setting channel."<< std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { acquisition->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro."<< std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { - acquisition->set_doppler_max(config->property("Acquisition.doppler_max", 10000)); - }) << "Failure setting doppler_max."<< std::endl; + acquisition->set_doppler_max(config->property("Acquisition_1B.doppler_max", 10000)); + }) << "Failure setting doppler_max."; ASSERT_NO_THROW( { acquisition->set_doppler_step(50); - }) << "Failure setting doppler_step."<< std::endl; + }) << "Failure setting doppler_step."; ASSERT_NO_THROW( { acquisition->set_threshold(5); - }) << "Failure setting threshold."<< std::endl; + }) << "Failure setting threshold."; ASSERT_NO_THROW( { acquisition->connect(top_block); - }) << "Failure connecting acquisition to the top_block." << std::endl; + }) << "Failure connecting acquisition to the top_block."; acquisition->init(); acquisition->reset(); @@ -732,7 +729,7 @@ TEST_F(GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test, ValidationOfResul signal_source->connect(top_block); top_block->connect(signal_source->get_right_block(), 0, acquisition->get_left_block(), 0); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of acquisition test." << std::endl; + }) << "Failure connecting the blocks of acquisition test."; // i = 0 --> satellite in acquisition is visible // i = 1 --> satellite in acquisition is not visible @@ -757,7 +754,7 @@ TEST_F(GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test, ValidationOfResul EXPECT_NO_THROW( { top_block->run(); // Start threads and wait - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; stop_queue(); if (i == 0) @@ -781,33 +778,33 @@ TEST_F(GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test, ValidationOfResul top_block = gr::make_top_block("Acquisition test"); queue = gr::msg_queue::make(0); - std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition", "Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition", 1, 1); + std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition_1B", "Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition", 1, 1); acquisition = std::dynamic_pointer_cast(acq_); boost::shared_ptr msg_rx = GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test_msg_rx_make(channel_internal_queue); ASSERT_NO_THROW( { acquisition->set_channel(1); - }) << "Failure setting channel."<< std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { acquisition->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro."<< std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { - acquisition->set_doppler_max(config->property("Acquisition.doppler_max", 10000)); - }) << "Failure setting doppler_max."<< std::endl; + acquisition->set_doppler_max(config->property("Acquisition_1B.doppler_max", 10000)); + }) << "Failure setting doppler_max."; ASSERT_NO_THROW( { - acquisition->set_doppler_step(config->property("Acquisition.doppler_step", 500)); - }) << "Failure setting doppler_step."<< std::endl; + acquisition->set_doppler_step(config->property("Acquisition_1B.doppler_step", 500)); + }) << "Failure setting doppler_step."; ASSERT_NO_THROW( { - acquisition->set_threshold(config->property("Acquisition.threshold", 0.0)); - }) << "Failure setting threshold."<< std::endl; + acquisition->set_threshold(config->property("Acquisition_1B.threshold", 0.0)); + }) << "Failure setting threshold."; ASSERT_NO_THROW( { acquisition->connect(top_block); - }) << "Failure connecting acquisition to the top_block." << std::endl; + }) << "Failure connecting acquisition to the top_block."; acquisition->init(); @@ -819,7 +816,7 @@ TEST_F(GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test, ValidationOfResul signal_source->connect(top_block); top_block->connect(signal_source->get_right_block(), 0, acquisition->get_left_block(), 0); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of acquisition test." << std::endl; + }) << "Failure connecting the blocks of acquisition test."; std::cout << "Probability of false alarm (target) = " << 0.1 << std::endl; @@ -846,7 +843,7 @@ TEST_F(GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test, ValidationOfResul EXPECT_NO_THROW( { top_block->run(); // Start threads and wait - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; stop_queue(); diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_tong_ambiguous_acquisition_gsoc2013_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_tong_ambiguous_acquisition_gsoc2013_test.cc index 4c7fd42d6..fa1d5dc60 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_tong_ambiguous_acquisition_gsoc2013_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_tong_ambiguous_acquisition_gsoc2013_test.cc @@ -246,17 +246,16 @@ void GalileoE1PcpsTongAmbiguousAcquisitionGSoC2013Test::config_1() config->set_property("InputFilter.filter_type", "bandpass"); config->set_property("InputFilter.grid_density", "16"); - config->set_property("Acquisition_Galileo.item_type", "gr_complex"); - config->set_property("Acquisition_Galileo.if", "0"); - config->set_property("Acquisition_Galileo.coherent_integration_time_ms", + config->set_property("Acquisition_1B.implementation", "Galileo_E1_PCPS_Tong_Ambiguous_Acquisition"); + config->set_property("Acquisition_1B.item_type", "gr_complex"); + config->set_property("Acquisition_1B.coherent_integration_time_ms", std::to_string(integration_time_ms)); - config->set_property("Acquisition_Galileo.tong_init_val", "1"); - config->set_property("Acquisition_Galileo.tong_max_val", "8"); - config->set_property("Acquisition_Galileo.implementation", "Galileo_E1_PCPS_Tong_Ambiguous_Acquisition"); - config->set_property("Acquisition_Galileo.threshold", "0.3"); - config->set_property("Acquisition_Galileo.doppler_max", "10000"); - config->set_property("Acquisition_Galileo.doppler_step", "250"); - config->set_property("Acquisition_Galileo.dump", "false"); + config->set_property("Acquisition_1B.tong_init_val", "1"); + config->set_property("Acquisition_1B.tong_max_val", "8"); + config->set_property("Acquisition_1B.threshold", "0.3"); + config->set_property("Acquisition_1B.doppler_max", "10000"); + config->set_property("Acquisition_1B.doppler_step", "250"); + config->set_property("Acquisition_1B.dump", "false"); } @@ -336,17 +335,16 @@ void GalileoE1PcpsTongAmbiguousAcquisitionGSoC2013Test::config_2() config->set_property("InputFilter.filter_type", "bandpass"); config->set_property("InputFilter.grid_density", "16"); - config->set_property("Acquisition_Galileo.item_type", "gr_complex"); - config->set_property("Acquisition_Galileo.if", "0"); - config->set_property("Acquisition_Galileo.coherent_integration_time_ms", + config->set_property("Acquisition_1B.implementation", "Galileo_E1_PCPS_Tong_Ambiguous_Acquisition"); + config->set_property("Acquisition_1B.item_type", "gr_complex"); + config->set_property("Acquisition_1B.coherent_integration_time_ms", std::to_string(integration_time_ms)); - config->set_property("Acquisition_Galileo.tong_init_val", "1"); - config->set_property("Acquisition_Galileo.tong_max_val", "8"); - config->set_property("Acquisition_Galileo.implementation", "Galileo_E1_PCPS_Tong_Ambiguous_Acquisition"); - config->set_property("Acquisition_Galileo.threshold", "0.00028"); // Pfa,a = 0.1 - config->set_property("Acquisition_Galileo.doppler_max", "10000"); - config->set_property("Acquisition_Galileo.doppler_step", "250"); - config->set_property("Acquisition_Galileo.dump", "false"); + config->set_property("Acquisition_1B.tong_init_val", "1"); + config->set_property("Acquisition_1B.tong_max_val", "8"); + config->set_property("Acquisition_1B.threshold", "0.00028"); // Pfa,a = 0.1 + config->set_property("Acquisition_1B.doppler_max", "10000"); + config->set_property("Acquisition_1B.doppler_step", "250"); + config->set_property("Acquisition_1B.dump", "false"); } @@ -431,7 +429,7 @@ void GalileoE1PcpsTongAmbiguousAcquisitionGSoC2013Test::stop_queue() TEST_F(GalileoE1PcpsTongAmbiguousAcquisitionGSoC2013Test, Instantiate) { config_1(); - std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition", "Galileo_E1_PCPS_Tong_Ambiguous_Acquisition", 1, 1); + std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition_1B", "Galileo_E1_PCPS_Tong_Ambiguous_Acquisition", 1, 1); acquisition = std::dynamic_pointer_cast(acq_); } @@ -440,11 +438,11 @@ TEST_F(GalileoE1PcpsTongAmbiguousAcquisitionGSoC2013Test, ConnectAndRun) { int nsamples = floor(fs_in*integration_time_ms*1e-3); std::chrono::time_point start, end; - std::chrono::duration elapsed_seconds(0); + std::chrono::duration elapsed_seconds(0.0); top_block = gr::make_top_block("Acquisition test"); queue = gr::msg_queue::make(0); config_1(); - std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition", "Galileo_E1_PCPS_Tong_Ambiguous_Acquisition", 1, 1); + std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition_1B", "Galileo_E1_PCPS_Tong_Ambiguous_Acquisition", 1, 1); acquisition = std::dynamic_pointer_cast(acq_); ASSERT_NO_THROW( { @@ -453,14 +451,14 @@ TEST_F(GalileoE1PcpsTongAmbiguousAcquisitionGSoC2013Test, ConnectAndRun) boost::shared_ptr valve = gnss_sdr_make_valve(sizeof(gr_complex), nsamples, queue); top_block->connect(source, 0, valve, 0); top_block->connect(valve, 0, acquisition->get_left_block(), 0); - }) << "Failure connecting the blocks of acquisition test." << std::endl; + }) << "Failure connecting the blocks of acquisition test."; EXPECT_NO_THROW( { start = std::chrono::system_clock::now(); top_block->run(); // Start threads and wait end = std::chrono::system_clock::now(); std::chrono::duration elapsed_seconds = end - start; - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; std::cout << "Processed " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; } @@ -471,33 +469,33 @@ TEST_F(GalileoE1PcpsTongAmbiguousAcquisitionGSoC2013Test, ValidationOfResults) config_1(); top_block = gr::make_top_block("Acquisition test"); queue = gr::msg_queue::make(0); - std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition", "Galileo_E1_PCPS_Tong_Ambiguous_Acquisition", 1, 1); + std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition_1B", "Galileo_E1_PCPS_Tong_Ambiguous_Acquisition", 1, 1); acquisition = std::dynamic_pointer_cast(acq_); boost::shared_ptr msg_rx = GalileoE1PcpsTongAmbiguousAcquisitionGSoC2013Test_msg_rx_make(channel_internal_queue); ASSERT_NO_THROW( { acquisition->set_channel(1); - }) << "Failure setting channel." << std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { acquisition->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro." << std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { acquisition->set_doppler_max(5000); - }) << "Failure setting doppler_max." << std::endl; + }) << "Failure setting doppler_max."; ASSERT_NO_THROW( { acquisition->set_doppler_step(100); - }) << "Failure setting doppler_step." << std::endl; + }) << "Failure setting doppler_step."; ASSERT_NO_THROW( { acquisition->set_threshold(0.01); - }) << "Failure setting threshold." << std::endl; + }) << "Failure setting threshold."; ASSERT_NO_THROW( { acquisition->connect(top_block); - }) << "Failure connecting acquisition to the top_block." << std::endl; + }) << "Failure connecting acquisition to the top_block."; acquisition->reset(); acquisition->init(); @@ -510,7 +508,7 @@ TEST_F(GalileoE1PcpsTongAmbiguousAcquisitionGSoC2013Test, ValidationOfResults) signal_source->connect(top_block); top_block->connect(signal_source->get_right_block(), 0, acquisition->get_left_block(), 0); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of acquisition test." << std::endl; + }) << "Failure connecting the blocks of acquisition test."; // i = 0 --> satellite in acquisition is visible // i = 1 --> satellite in acquisition is not visible @@ -534,7 +532,7 @@ TEST_F(GalileoE1PcpsTongAmbiguousAcquisitionGSoC2013Test, ValidationOfResults) EXPECT_NO_THROW( { top_block->run(); // Start threads and wait - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; stop_queue(); @@ -560,33 +558,33 @@ TEST_F(GalileoE1PcpsTongAmbiguousAcquisitionGSoC2013Test, ValidationOfResultsPro config_2(); top_block = gr::make_top_block("Acquisition test"); queue = gr::msg_queue::make(0); - std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition", "Galileo_E1_PCPS_Tong_Ambiguous_Acquisition", 1, 1); + std::shared_ptr acq_ = factory->GetBlock(config, "Acquisition_1B", "Galileo_E1_PCPS_Tong_Ambiguous_Acquisition", 1, 1); acquisition = std::dynamic_pointer_cast(acq_); boost::shared_ptr msg_rx = GalileoE1PcpsTongAmbiguousAcquisitionGSoC2013Test_msg_rx_make(channel_internal_queue); ASSERT_NO_THROW( { acquisition->set_channel(1); - }) << "Failure setting channel." << std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { acquisition->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro." << std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { - acquisition->set_doppler_max(config->property("Acquisition.doppler_max", 10000)); - }) << "Failure setting doppler_max." << std::endl; + acquisition->set_doppler_max(config->property("Acquisition_1B.doppler_max", 10000)); + }) << "Failure setting doppler_max."; ASSERT_NO_THROW( { - acquisition->set_doppler_step(config->property("Acquisition.doppler_step", 500)); - }) << "Failure setting doppler_step." << std::endl; + acquisition->set_doppler_step(config->property("Acquisition_1B.doppler_step", 500)); + }) << "Failure setting doppler_step."; ASSERT_NO_THROW( { - acquisition->set_threshold(config->property("Acquisition.threshold", 0.00028)); - }) << "Failure setting threshold." << std::endl; + acquisition->set_threshold(config->property("Acquisition_1B.threshold", 0.00028)); + }) << "Failure setting threshold."; ASSERT_NO_THROW( { acquisition->connect(top_block); - }) << "Failure connecting acquisition to the top_block." << std::endl; + }) << "Failure connecting acquisition to the top_block."; acquisition->init(); @@ -598,7 +596,7 @@ TEST_F(GalileoE1PcpsTongAmbiguousAcquisitionGSoC2013Test, ValidationOfResultsPro signal_source->connect(top_block); top_block->connect(signal_source->get_right_block(), 0, acquisition->get_left_block(), 0); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of acquisition test." << std::endl; + }) << "Failure connecting the blocks of acquisition test."; std::cout << "Probability of false alarm (target) = " << 0.1 << std::endl; @@ -623,7 +621,7 @@ TEST_F(GalileoE1PcpsTongAmbiguousAcquisitionGSoC2013Test, ValidationOfResultsPro EXPECT_NO_THROW( { top_block->run(); // Start threads and wait - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; stop_queue(); diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e5a_pcps_acquisition_gsoc2014_gensource_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e5a_pcps_acquisition_gsoc2014_gensource_test.cc index de4508341..86f2f85b3 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e5a_pcps_acquisition_gsoc2014_gensource_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e5a_pcps_acquisition_gsoc2014_gensource_test.cc @@ -257,15 +257,13 @@ void GalileoE5aPcpsAcquisitionGSoC2014GensourceTest::config_1() config->set_property("InputFilter.filter_type", "bandpass"); config->set_property("InputFilter.grid_density", "16"); + config->set_property("Acquisition_5X.implementation", "Galileo_E5a_Noncoherent_IQ_Acquisition_CAF"); config->set_property("Acquisition_5X.item_type", "gr_complex"); - config->set_property("Acquisition_5X.if", "0"); config->set_property("Acquisition_5X.coherent_integration_time_ms", std::to_string(integration_time_ms)); config->set_property("Acquisition_5X.max_dwells", "1"); config->set_property("Acquisition_5X.CAF_window_hz",std::to_string(CAF_window_hz)); config->set_property("Acquisition_5X.Zero_padding",std::to_string(Zero_padding)); - - config->set_property("Acquisition_5X.implementation", "Galileo_E5a_Noncoherent_IQ_Acquisition_CAF"); config->set_property("Acquisition_5X.pfa","0.003"); // config->set_property("Acquisition_5X.threshold", "0.01"); config->set_property("Acquisition_5X.doppler_max", "10000"); @@ -298,12 +296,11 @@ void GalileoE5aPcpsAcquisitionGSoC2014GensourceTest::config_2() config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(fs_in)); + config->set_property("Acquisition_5X.implementation", "Galileo_E5a_PCPS_Acquisition"); config->set_property("Acquisition_5X.item_type", "gr_complex"); - config->set_property("Acquisition_5X.if", "0"); config->set_property("Acquisition_5X.coherent_integration_time_ms", std::to_string(integration_time_ms)); config->set_property("Acquisition_5X.max_dwells", "1"); - config->set_property("Acquisition_5X.implementation", "Galileo_E5a_PCPS_Acquisition"); config->set_property("Acquisition_5X.threshold", "0.1"); config->set_property("Acquisition_5X.doppler_max", "10000"); config->set_property("Acquisition_5X.doppler_step", "250"); @@ -530,7 +527,7 @@ void GalileoE5aPcpsAcquisitionGSoC2014GensourceTest::stop_queue() TEST_F(GalileoE5aPcpsAcquisitionGSoC2014GensourceTest, Instantiate) { config_1(); - acquisition = std::make_shared(config.get(), "Acquisition", 1, 1); + acquisition = std::make_shared(config.get(), "Acquisition_5X", 1, 1); } @@ -541,7 +538,7 @@ TEST_F(GalileoE5aPcpsAcquisitionGSoC2014GensourceTest, ConnectAndRun) int nsamples = 21000*3; std::chrono::time_point start, end; std::chrono::duration elapsed_seconds(0); - acquisition = std::make_shared(config.get(), "Acquisition", 1, 1); + acquisition = std::make_shared(config.get(), "Acquisition_5X", 1, 1); boost::shared_ptr msg_rx = GalileoE5aPcpsAcquisitionGSoC2014GensourceTest_msg_rx_make(channel_internal_queue); queue = gr::msg_queue::make(0); top_block = gr::make_top_block("Acquisition test"); @@ -553,14 +550,14 @@ TEST_F(GalileoE5aPcpsAcquisitionGSoC2014GensourceTest, ConnectAndRun) top_block->connect(source, 0, valve, 0); top_block->connect(valve, 0, acquisition->get_left_block(), 0); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of acquisition test."<< std::endl; + }) << "Failure connecting the blocks of acquisition test."; 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::endl; + }) << "Failure running the top_block."; std::cout << "Processed " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; } @@ -571,32 +568,32 @@ TEST_F(GalileoE5aPcpsAcquisitionGSoC2014GensourceTest, ValidationOfSIM) config_1(); queue = gr::msg_queue::make(0); top_block = gr::make_top_block("Acquisition test"); - acquisition = std::make_shared(config.get(), "Acquisition", 1, 1); + acquisition = std::make_shared(config.get(), "Acquisition_5X", 1, 1); boost::shared_ptr msg_rx = GalileoE5aPcpsAcquisitionGSoC2014GensourceTest_msg_rx_make(channel_internal_queue); ASSERT_NO_THROW( { acquisition->set_channel(0); - }) << "Failure setting channel."<< std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { acquisition->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro."<< std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { acquisition->set_doppler_max(config->property("Acquisition_5X.doppler_max", 5000)); - }) << "Failure setting doppler_max."<< std::endl; + }) << "Failure setting doppler_max."; ASSERT_NO_THROW( { acquisition->set_doppler_step(config->property("Acquisition_5X.doppler_step", 100)); - }) << "Failure setting doppler_step."<< std::endl; + }) << "Failure setting doppler_step."; ASSERT_NO_THROW( { acquisition->set_threshold(config->property("Acquisition_5X.threshold", 0.0001)); - }) << "Failure setting threshold."<< std::endl; + }) << "Failure setting threshold."; ASSERT_NO_THROW( { acquisition->connect(top_block); - }) << "Failure connecting acquisition to the top_block."<< std::endl; + }) << "Failure connecting acquisition to the top_block."; // USING THE SIGNAL GENERATOR @@ -609,7 +606,7 @@ TEST_F(GalileoE5aPcpsAcquisitionGSoC2014GensourceTest, ValidationOfSIM) signal_source->connect(top_block); top_block->connect(signal_source->get_right_block(), 0, acquisition->get_left_block(), 0); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of acquisition test." << std::endl; + }) << "Failure connecting the blocks of acquisition test."; acquisition->reset(); acquisition->init(); @@ -641,7 +638,7 @@ TEST_F(GalileoE5aPcpsAcquisitionGSoC2014GensourceTest, ValidationOfSIM) EXPECT_NO_THROW( { top_block->run(); // Start threads and wait - }) << "Failure running the top_block."<< std::endl; + }) << "Failure running the top_block."; stop_queue(); diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_gsoc2013_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_gsoc2013_test.cc index a4a6ec153..6243fb8bf 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_gsoc2013_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_gsoc2013_test.cc @@ -244,17 +244,16 @@ void GpsL1CaPcpsAcquisitionGSoC2013Test::config_1() config->set_property("InputFilter.filter_type", "bandpass"); config->set_property("InputFilter.grid_density", "16"); - config->set_property("Acquisition.item_type", "gr_complex"); - config->set_property("Acquisition.if", "0"); - config->set_property("Acquisition.coherent_integration_time_ms", + config->set_property("Acquisition_1C.implementation", "GPS_L1_CA_PCPS_Acquisition"); + config->set_property("Acquisition_1C.item_type", "gr_complex"); + config->set_property("Acquisition_1C.coherent_integration_time_ms", std::to_string(integration_time_ms)); - config->set_property("Acquisition.max_dwells", "1"); - config->set_property("Acquisition.implementation", "GPS_L1_CA_PCPS_Acquisition"); - config->set_property("Acquisition.threshold", "0.8"); - config->set_property("Acquisition.doppler_max", "10000"); - config->set_property("Acquisition.doppler_step", "250"); - config->set_property("Acquisition.bit_transition_flag", "false"); - config->set_property("Acquisition.dump", "false"); + config->set_property("Acquisition_1C.max_dwells", "1"); + config->set_property("Acquisition_1C.threshold", "0.8"); + config->set_property("Acquisition_1C.doppler_max", "10000"); + config->set_property("Acquisition_1C.doppler_step", "250"); + config->set_property("Acquisition_1C.bit_transition_flag", "false"); + config->set_property("Acquisition_1C.dump", "false"); } @@ -332,17 +331,16 @@ void GpsL1CaPcpsAcquisitionGSoC2013Test::config_2() config->set_property("InputFilter.filter_type", "bandpass"); config->set_property("InputFilter.grid_density", "16"); - config->set_property("Acquisition.item_type", "gr_complex"); - config->set_property("Acquisition.if", "0"); - config->set_property("Acquisition.coherent_integration_time_ms", + config->set_property("Acquisition_1C.implementation", "GPS_L1_CA_PCPS_Acquisition"); + config->set_property("Acquisition_1C.item_type", "gr_complex"); + config->set_property("Acquisition_1C.coherent_integration_time_ms", std::to_string(integration_time_ms)); - config->set_property("Acquisition.max_dwells", "1"); - config->set_property("Acquisition.implementation", "GPS_L1_CA_PCPS_Acquisition"); - config->set_property("Acquisition.pfa", "0.1"); - config->set_property("Acquisition.doppler_max", "10000"); - config->set_property("Acquisition.doppler_step", "250"); - config->set_property("Acquisition.bit_transition_flag", "false"); - config->set_property("Acquisition.dump", "false"); + config->set_property("Acquisition_1C.max_dwells", "1"); + config->set_property("Acquisition_1C.pfa", "0.1"); + config->set_property("Acquisition_1C.doppler_max", "10000"); + config->set_property("Acquisition_1C.doppler_step", "250"); + config->set_property("Acquisition_1C.bit_transition_flag", "false"); + config->set_property("Acquisition_1C.dump", "false"); } @@ -439,7 +437,7 @@ TEST_F(GpsL1CaPcpsAcquisitionGSoC2013Test, ConnectAndRun) top_block = gr::make_top_block("Acquisition test"); config_1(); - acquisition = new GpsL1CaPcpsAcquisition(config.get(), "Acquisition", 1, 1); + acquisition = new GpsL1CaPcpsAcquisition(config.get(), "Acquisition_1C", 1, 1); boost::shared_ptr msg_rx = GpsL1CaPcpsAcquisitionGSoC2013Test_msg_rx_make(channel_internal_queue); ASSERT_NO_THROW( { @@ -449,14 +447,14 @@ TEST_F(GpsL1CaPcpsAcquisitionGSoC2013Test, ConnectAndRun) top_block->connect(source, 0, valve, 0); top_block->connect(valve, 0, acquisition->get_left_block(), 0); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of acquisition test."<< std::endl; + }) << "Failure connecting the blocks of acquisition test."; 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::endl; + }) << "Failure running the top_block."; std::cout << "Processed " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; @@ -470,33 +468,33 @@ TEST_F(GpsL1CaPcpsAcquisitionGSoC2013Test, ValidationOfResults) queue = gr::msg_queue::make(0); top_block = gr::make_top_block("Acquisition test"); - acquisition = new GpsL1CaPcpsAcquisition(config.get(), "Acquisition", 1, 1); + acquisition = new GpsL1CaPcpsAcquisition(config.get(), "Acquisition_1C", 1, 1); boost::shared_ptr msg_rx = GpsL1CaPcpsAcquisitionGSoC2013Test_msg_rx_make(channel_internal_queue); ASSERT_NO_THROW( { acquisition->set_channel(1); - }) << "Failure setting channel."<< std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { acquisition->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro."<< std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { acquisition->set_doppler_max(10000); - }) << "Failure setting doppler_max."<< std::endl; + }) << "Failure setting doppler_max."; ASSERT_NO_THROW( { acquisition->set_doppler_step(500); - }) << "Failure setting doppler_step."<< std::endl; + }) << "Failure setting doppler_step."; ASSERT_NO_THROW( { acquisition->set_threshold(0.5); - }) << "Failure setting threshold."<< std::endl; + }) << "Failure setting threshold."; ASSERT_NO_THROW( { acquisition->connect(top_block); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting acquisition to the top_block."<< std::endl; + }) << "Failure connecting acquisition to the top_block."; acquisition->init(); @@ -507,7 +505,7 @@ TEST_F(GpsL1CaPcpsAcquisitionGSoC2013Test, ValidationOfResults) signal_source.reset(new GenSignalSource(signal_generator, filter, "SignalSource", queue)); signal_source->connect(top_block); top_block->connect(signal_source->get_right_block(), 0, acquisition->get_left_block(), 0); - }) << "Failure connecting the blocks of acquisition test." << std::endl; + }) << "Failure connecting the blocks of acquisition test."; // i = 0 --> satellite in acquisition is visible // i = 1 --> satellite in acquisition is not visible @@ -530,7 +528,7 @@ TEST_F(GpsL1CaPcpsAcquisitionGSoC2013Test, ValidationOfResults) EXPECT_NO_THROW( { top_block->run(); // Start threads and wait - }) << "Failure running the top_block."<< std::endl; + }) << "Failure running the top_block."; if (i == 0) { @@ -548,12 +546,12 @@ TEST_F(GpsL1CaPcpsAcquisitionGSoC2013Test, ValidationOfResults) #ifdef OLD_BOOST ASSERT_NO_THROW( { ch_thread.timed_join(boost::posix_time::seconds(1)); - }) << "Failure while waiting the queue to stop" << std::endl; + }) << "Failure while waiting the queue to stop"; #endif #ifndef OLD_BOOST ASSERT_NO_THROW( { ch_thread.try_join_until(boost::chrono::steady_clock::now() + boost::chrono::milliseconds(50)); - }) << "Failure while waiting the queue to stop" << std::endl; + }) << "Failure while waiting the queue to stop"; #endif } @@ -566,33 +564,33 @@ TEST_F(GpsL1CaPcpsAcquisitionGSoC2013Test, ValidationOfResultsProbabilities) config_2(); queue = gr::msg_queue::make(0); top_block = gr::make_top_block("Acquisition test"); - acquisition = new GpsL1CaPcpsAcquisition(config.get(), "Acquisition", 1, 1); + acquisition = new GpsL1CaPcpsAcquisition(config.get(), "Acquisition_1C", 1, 1); boost::shared_ptr msg_rx = GpsL1CaPcpsAcquisitionGSoC2013Test_msg_rx_make(channel_internal_queue); ASSERT_NO_THROW( { acquisition->set_channel(1); - }) << "Failure setting channel."<< std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { acquisition->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro."<< std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { - acquisition->set_doppler_max(config->property("Acquisition.doppler_max", 10000)); - }) << "Failure setting doppler_max."<< std::endl; + acquisition->set_doppler_max(config->property("Acquisition_1C.doppler_max", 10000)); + }) << "Failure setting doppler_max."; ASSERT_NO_THROW( { - acquisition->set_doppler_step(config->property("Acquisition.doppler_step", 500)); - }) << "Failure setting doppler_step."<< std::endl; + acquisition->set_doppler_step(config->property("Acquisition_1C.doppler_step", 500)); + }) << "Failure setting doppler_step."; ASSERT_NO_THROW( { - acquisition->set_threshold(config->property("Acquisition.threshold", 0.0)); - }) << "Failure setting threshold."<< std::endl; + acquisition->set_threshold(config->property("Acquisition_1C.threshold", 0.0)); + }) << "Failure setting threshold."; ASSERT_NO_THROW( { acquisition->connect(top_block); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting acquisition to the top_block."<< std::endl; + }) << "Failure connecting acquisition to the top_block."; acquisition->init(); @@ -603,7 +601,7 @@ TEST_F(GpsL1CaPcpsAcquisitionGSoC2013Test, ValidationOfResultsProbabilities) signal_source.reset(new GenSignalSource(signal_generator, filter, "SignalSource", queue)); signal_source->connect(top_block); top_block->connect(signal_source->get_right_block(), 0, acquisition->get_left_block(), 0); - }) << "Failure connecting the blocks of acquisition test." << std::endl; + }) << "Failure connecting the blocks of acquisition test." ; std::cout << "Probability of false alarm (target) = " << 0.1 << std::endl; @@ -628,7 +626,7 @@ TEST_F(GpsL1CaPcpsAcquisitionGSoC2013Test, ValidationOfResultsProbabilities) EXPECT_NO_THROW( { top_block->run(); // Start threads and wait - }) << "Failure running the top_block."<< std::endl; + }) << "Failure running the top_block."; if (i == 0) { @@ -643,12 +641,12 @@ TEST_F(GpsL1CaPcpsAcquisitionGSoC2013Test, ValidationOfResultsProbabilities) #ifdef OLD_BOOST ASSERT_NO_THROW( { ch_thread.timed_join(boost::posix_time::seconds(1)); - }) << "Failure while waiting the queue to stop" << std::endl; + }) << "Failure while waiting the queue to stop"; #endif #ifndef OLD_BOOST ASSERT_NO_THROW( { ch_thread.try_join_until(boost::chrono::steady_clock::now() + boost::chrono::milliseconds(50)); - }) << "Failure while waiting the queue to stop" << std::endl; + }) << "Failure while waiting the queue to stop"; #endif } diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc index e1ebcb4c4..0ddd45bd3 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc @@ -53,9 +53,6 @@ #include "acquisition_dump_reader.h" #include "gps_l1_ca_pcps_acquisition.h" -DEFINE_bool(plot_acq_grid, false, "Plots results of GpsL1CaPcpsAcquisitionTest with gnuplot"); - - // ######## GNURADIO BLOCK MESSAGE RECEVER ######### class GpsL1CaPcpsAcquisitionTest_msg_rx; @@ -144,10 +141,9 @@ void GpsL1CaPcpsAcquisitionTest::init() std::string signal = "1C"; signal.copy(gnss_synchro.Signal, 2, 0); gnss_synchro.PRN = 1; - config->set_property("Acquisition_1C.implementation", "GPS_L1_CA_PCPS_Acquisition"); config->set_property("GNSS-SDR.internal_fs_sps", "4000000"); + config->set_property("Acquisition_1C.implementation", "GPS_L1_CA_PCPS_Acquisition"); config->set_property("Acquisition_1C.item_type", "gr_complex"); - config->set_property("Acquisition_1C.if", "0"); config->set_property("Acquisition_1C.coherent_integration_time_ms", "1"); if(FLAGS_plot_acq_grid == true) { diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test_fpga.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test_fpga.cc index ecf841a7c..985e7d16e 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test_fpga.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test_fpga.cc @@ -259,19 +259,17 @@ void GpsL1CaPcpsAcquisitionTestFpga::init() signal.copy(gnss_synchro.Signal, 2, 0); gnss_synchro.PRN = 1; config->set_property("GNSS-SDR.internal_fs_sps", "4000000"); - config->set_property("Acquisition.item_type", "cshort"); - config->set_property("Acquisition.if", "0"); - config->set_property("Acquisition.coherent_integration_time_ms", "1"); - config->set_property("Acquisition.dump", "false"); - config->set_property("Acquisition.implementation", - "GPS_L1_CA_PCPS_Acquisition"); - config->set_property("Acquisition.threshold", "0.001"); - config->set_property("Acquisition.doppler_max", "5000"); - config->set_property("Acquisition.doppler_step", "500"); - config->set_property("Acquisition.repeat_satellite", "false"); - config->set_property("Acquisition.pfa", "0.0"); - config->set_property("Acquisition.select_queue_Fpga", "0"); - config->set_property("Acquisition.devicename", "/dev/uio0"); + config->set_property("Acquisition_1C.implementation", "GPS_L1_CA_PCPS_Acquisition"); + config->set_property("Acquisition_1C.item_type", "cshort"); + config->set_property("Acquisition_1C.coherent_integration_time_ms", "1"); + config->set_property("Acquisition_1C.dump", "false"); + config->set_property("Acquisition_1C.threshold", "0.001"); + config->set_property("Acquisition_1C.doppler_max", "5000"); + config->set_property("Acquisition_1C.doppler_step", "500"); + config->set_property("Acquisition_1C.repeat_satellite", "false"); + config->set_property("Acquisition_1C.pfa", "0.0"); + config->set_property("Acquisition_1C.select_queue_Fpga", "0"); + config->set_property("Acquisition_1C.devicename", "/dev/uio0"); } @@ -279,7 +277,7 @@ TEST_F(GpsL1CaPcpsAcquisitionTestFpga, Instantiate) { init(); boost::shared_ptr acquisition = - boost::make_shared(config.get(), "Acquisition", 0, 1); + boost::make_shared(config.get(), "Acquisition_1C", 0, 1); } @@ -294,39 +292,39 @@ TEST_F(GpsL1CaPcpsAcquisitionTestFpga, ValidationOfResults) init(); std::shared_ptr < GpsL1CaPcpsAcquisitionFpga > acquisition = - std::make_shared < GpsL1CaPcpsAcquisitionFpga > (config.get(), "Acquisition", 0, 1); + std::make_shared < GpsL1CaPcpsAcquisitionFpga > (config.get(), "Acquisition_1C", 0, 1); boost::shared_ptr msg_rx = GpsL1CaPcpsAcquisitionTestFpga_msg_rx_make(); ASSERT_NO_THROW( { acquisition->set_channel(1); - })<< "Failure setting channel." << std::endl; + })<< "Failure setting channel."; ASSERT_NO_THROW( { acquisition->set_gnss_synchro(&gnss_synchro); - })<< "Failure setting gnss_synchro." << std::endl; + })<< "Failure setting gnss_synchro."; ASSERT_NO_THROW( { acquisition->set_threshold(0.1); - })<< "Failure setting threshold." << std::endl; + })<< "Failure setting threshold."; ASSERT_NO_THROW( { acquisition->set_doppler_max(10000); - })<< "Failure setting doppler_max." << std::endl; + })<< "Failure setting doppler_max."; ASSERT_NO_THROW( { acquisition->set_doppler_step(250); - })<< "Failure setting doppler_step." << std::endl; + })<< "Failure setting doppler_step."; ASSERT_NO_THROW( { acquisition->connect(top_block); - })<< "Failure connecting acquisition to the top_block." << std::endl; + })<< "Failure connecting acquisition to the top_block."; // uncomment the next line to load the file from the current directory std::string file = "./GPS_L1_CA_ID_1_Fs_4Msps_2ms.dat"; @@ -349,7 +347,7 @@ TEST_F(GpsL1CaPcpsAcquisitionTestFpga, ValidationOfResults) top_block->connect(file_source, 0, throttle_block, 0); top_block->connect(throttle_block, 0, null_sink, 0); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - })<< "Failure connecting the blocks of acquisition test." << std::endl; + })<< "Failure connecting the blocks of acquisition test." ; acquisition->set_state(1); // Ensure that acquisition starts at the first state acquisition->init(); @@ -366,7 +364,7 @@ TEST_F(GpsL1CaPcpsAcquisitionTestFpga, ValidationOfResults) top_block->wait(); end = std::chrono::system_clock::now(); elapsed_seconds = end - start; - })<< "Failure running the top_block." << std::endl; + })<< "Failure running the top_block."; t3.join(); diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_opencl_acquisition_gsoc2013_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_opencl_acquisition_gsoc2013_test.cc index adb069ca7..1d070e69d 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_opencl_acquisition_gsoc2013_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_opencl_acquisition_gsoc2013_test.cc @@ -240,17 +240,16 @@ void GpsL1CaPcpsOpenClAcquisitionGSoC2013Test::config_1() config->set_property("InputFilter.filter_type", "bandpass"); config->set_property("InputFilter.grid_density", "16"); - config->set_property("Acquisition.item_type", "gr_complex"); - config->set_property("Acquisition.if", "0"); - config->set_property("Acquisition.coherent_integration_time_ms", + config->set_property("Acquisition_1C.implementation", "GPS_L1_CA_PCPS_OpenCl_Acquisition"); + config->set_property("Acquisition_1C.item_type", "gr_complex"); + config->set_property("Acquisition_1C.coherent_integration_time_ms", std::to_string(integration_time_ms)); - config->set_property("Acquisition.max_dwells", "1"); - config->set_property("Acquisition.implementation", "GPS_L1_CA_PCPS_OpenCl_Acquisition"); - config->set_property("Acquisition.threshold", "0.8"); - config->set_property("Acquisition.doppler_max", "10000"); - config->set_property("Acquisition.doppler_step", "250"); - config->set_property("Acquisition.bit_transition_flag", "false"); - config->set_property("Acquisition.dump", "false"); + config->set_property("Acquisition_1C.max_dwells", "1"); + config->set_property("Acquisition_1C.threshold", "0.8"); + config->set_property("Acquisition_1C.doppler_max", "10000"); + config->set_property("Acquisition_1C.doppler_step", "250"); + config->set_property("Acquisition_1C.bit_transition_flag", "false"); + config->set_property("Acquisition_1C.dump", "false"); } @@ -328,17 +327,16 @@ void GpsL1CaPcpsOpenClAcquisitionGSoC2013Test::config_2() config->set_property("InputFilter.filter_type", "bandpass"); config->set_property("InputFilter.grid_density", "16"); - config->set_property("Acquisition.item_type", "gr_complex"); - config->set_property("Acquisition.if", "0"); + config->set_property("Acquisition_1C.implementation", "GPS_L1_CA_PCPS_OpenCl_Acquisition"); + config->set_property("Acquisition_1C.item_type", "gr_complex"); config->set_property("Acquisition.coherent_integration_time_ms", std::to_string(integration_time_ms)); - config->set_property("Acquisition.max_dwells", "1"); - config->set_property("Acquisition.implementation", "GPS_L1_CA_PCPS_OpenCl_Acquisition"); - config->set_property("Acquisition.pfa", "0.1"); - config->set_property("Acquisition.doppler_max", "10000"); - config->set_property("Acquisition.doppler_step", "250"); - config->set_property("Acquisition.bit_transition_flag", "false"); - config->set_property("Acquisition.dump", "false"); + config->set_property("Acquisition_1C.max_dwells", "1"); + config->set_property("Acquisition_1C.pfa", "0.1"); + config->set_property("Acquisition_1C.doppler_max", "10000"); + config->set_property("Acquisition_1C.doppler_step", "250"); + config->set_property("Acquisition_1C.bit_transition_flag", "false"); + config->set_property("Acquisition_1C.dump", "false"); } @@ -423,7 +421,7 @@ void GpsL1CaPcpsOpenClAcquisitionGSoC2013Test::stop_queue() TEST_F(GpsL1CaPcpsOpenClAcquisitionGSoC2013Test, Instantiate) { config_1(); - acquisition = std::make_shared(config.get(), "Acquisition", 1, 1); + acquisition = std::make_shared(config.get(), "Acquisition_1C", 1, 1); } @@ -434,7 +432,7 @@ TEST_F(GpsL1CaPcpsOpenClAcquisitionGSoC2013Test, ConnectAndRun) std::chrono::duration elapsed_seconds(0); config_1(); - acquisition = std::make_shared(config.get(), "Acquisition", 1, 1); + acquisition = std::make_shared(config.get(), "Acquisition_1C", 1, 1); boost::shared_ptr msg_rx = GpsL1CaPcpsOpenClAcquisitionGSoC2013Test_msg_rx_make(channel_internal_queue); ASSERT_NO_THROW( { @@ -444,14 +442,14 @@ TEST_F(GpsL1CaPcpsOpenClAcquisitionGSoC2013Test, ConnectAndRun) top_block->connect(source, 0, valve, 0); top_block->connect(valve, 0, acquisition->get_left_block(), 0); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of acquisition test." << std::endl; + }) << "Failure connecting the blocks of acquisition test."; 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::endl; + }) << "Failure running the top_block."; std::cout << "Processed " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; } @@ -466,27 +464,27 @@ TEST_F(GpsL1CaPcpsOpenClAcquisitionGSoC2013Test, ValidationOfResults) ASSERT_NO_THROW( { acquisition->set_channel(1); - }) << "Failure setting channel." << std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { acquisition->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro." << std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { - acquisition->set_doppler_max(config->property("Acquisition.doppler_max", 10000)); - }) << "Failure setting doppler_max." << std::endl; + acquisition->set_doppler_max(config->property("Acquisition_1C.doppler_max", 10000)); + }) << "Failure setting doppler_max."; ASSERT_NO_THROW( { - acquisition->set_doppler_step(config->property("Acquisition.doppler_step", 500)); - }) << "Failure setting doppler_step." << std::endl; + acquisition->set_doppler_step(config->property("Acquisition_1C.doppler_step", 500)); + }) << "Failure setting doppler_step."; ASSERT_NO_THROW( { - acquisition->set_threshold(config->property("Acquisition.threshold", 0.0)); - }) << "Failure setting threshold." << std::endl; + acquisition->set_threshold(config->property("Acquisition_1C.threshold", 0.0)); + }) << "Failure setting threshold."; ASSERT_NO_THROW( { acquisition->connect(top_block); - }) << "Failure connecting acquisition to the top_block." << std::endl; + }) << "Failure connecting acquisition to the top_block."; acquisition->init(); @@ -498,7 +496,7 @@ TEST_F(GpsL1CaPcpsOpenClAcquisitionGSoC2013Test, ValidationOfResults) signal_source->connect(top_block); top_block->connect(signal_source->get_right_block(), 0, acquisition->get_left_block(), 0); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of acquisition test." << std::endl; + }) << "Failure connecting the blocks of acquisition test."; // i = 0 --> satellite in acquisition is visible // i = 1 --> satellite in acquisition is not visible @@ -521,7 +519,7 @@ TEST_F(GpsL1CaPcpsOpenClAcquisitionGSoC2013Test, ValidationOfResults) EXPECT_NO_THROW( { top_block->run(); // Start threads and wait - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; if (i == 0) { @@ -544,32 +542,32 @@ TEST_F(GpsL1CaPcpsOpenClAcquisitionGSoC2013Test, ValidationOfResultsProbabilitie { config_2(); - acquisition = std::make_shared(config.get(), "Acquisition", 1, 1); + acquisition = std::make_shared(config.get(), "Acquisition_1C", 1, 1); boost::shared_ptr msg_rx = GpsL1CaPcpsOpenClAcquisitionGSoC2013Test_msg_rx_make(channel_internal_queue); ASSERT_NO_THROW( { acquisition->set_channel(1); - }) << "Failure setting channel." << std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { acquisition->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro." << std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { - acquisition->set_doppler_max(config->property("Acquisition.doppler_max", 10000)); - }) << "Failure setting doppler_max." << std::endl; + acquisition->set_doppler_max(config->property("Acquisition_1C.doppler_max", 10000)); + }) << "Failure setting doppler_max."; ASSERT_NO_THROW( { - acquisition->set_doppler_step(config->property("Acquisition.doppler_step", 500)); - }) << "Failure setting doppler_step." << std::endl; + acquisition->set_doppler_step(config->property("Acquisition_1C.doppler_step", 500)); + }) << "Failure setting doppler_step."; ASSERT_NO_THROW( { - acquisition->set_threshold(config->property("Acquisition.threshold", 0.0)); - }) << "Failure setting threshold." << std::endl; + acquisition->set_threshold(config->property("Acquisition_1C.threshold", 0.0)); + }) << "Failure setting threshold."; ASSERT_NO_THROW( { acquisition->connect(top_block); - }) << "Failure connecting acquisition to the top_block." << std::endl; + }) << "Failure connecting acquisition to the top_block."; acquisition->init(); @@ -581,7 +579,7 @@ TEST_F(GpsL1CaPcpsOpenClAcquisitionGSoC2013Test, ValidationOfResultsProbabilitie signal_source->connect(top_block); top_block->connect(signal_source->get_right_block(), 0, acquisition->get_left_block(), 0); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of acquisition test." << std::endl; + }) << "Failure connecting the blocks of acquisition test."; std::cout << "Probability of false alarm (target) = " << 0.1 << std::endl; @@ -606,7 +604,7 @@ TEST_F(GpsL1CaPcpsOpenClAcquisitionGSoC2013Test, ValidationOfResultsProbabilitie EXPECT_NO_THROW( { top_block->run(); // Start threads and wait - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; if (i == 0) { diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_quicksync_acquisition_gsoc2014_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_quicksync_acquisition_gsoc2014_test.cc index bdbeffa10..02d44029a 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_quicksync_acquisition_gsoc2014_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_quicksync_acquisition_gsoc2014_test.cc @@ -255,17 +255,16 @@ void GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test::config_1() config->set_property("InputFilter.filter_type", "bandpass"); config->set_property("InputFilter.grid_density", "16"); - config->set_property("Acquisition.item_type", "gr_complex"); - config->set_property("Acquisition.if", "0"); - config->set_property("Acquisition.coherent_integration_time_ms", + config->set_property("Acquisition_1C.implementation", "GPS_L1_CA_PCPS_QuickSync_Acquisition"); + config->set_property("Acquisition_1C.item_type", "gr_complex"); + config->set_property("Acquisition_1C.coherent_integration_time_ms", std::to_string(integration_time_ms)); - config->set_property("Acquisition.max_dwells", "1"); - config->set_property("Acquisition.implementation", "GPS_L1_CA_PCPS_QuickSync_Acquisition"); - config->set_property("Acquisition.threshold", "250"); - config->set_property("Acquisition.doppler_max", "10000"); - config->set_property("Acquisition.doppler_step", "250"); - config->set_property("Acquisition.bit_transition_flag", "false"); - config->set_property("Acquisition.dump", "false"); + config->set_property("Acquisition_1C.max_dwells", "1"); + config->set_property("Acquisition_1C.threshold", "250"); + config->set_property("Acquisition_1C.doppler_max", "10000"); + config->set_property("Acquisition_1C.doppler_step", "250"); + config->set_property("Acquisition_1C.bit_transition_flag", "false"); + config->set_property("Acquisition_1C.dump", "false"); } @@ -347,17 +346,16 @@ void GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test::config_2() config->set_property("InputFilter.filter_type", "bandpass"); config->set_property("InputFilter.grid_density", "16"); - config->set_property("Acquisition.item_type", "gr_complex"); - config->set_property("Acquisition.if", "0"); - config->set_property("Acquisition.coherent_integration_time_ms", + config->set_property("Acquisition_1C.implementation", "GPS_L1_CA_PCPS_QuickSync_Acquisition"); + config->set_property("Acquisition_1C.item_type", "gr_complex"); + config->set_property("Acquisition_1C.coherent_integration_time_ms", std::to_string(integration_time_ms)); - config->set_property("Acquisition.max_dwells", "1"); - config->set_property("Acquisition.implementation", "GPS_L1_CA_PCPS_QuickSync_Acquisition"); - config->set_property("Acquisition.threshold", std::to_string(FLAGS_value_threshold)); - config->set_property("Acquisition.doppler_max", "10000"); - config->set_property("Acquisition.doppler_step", "100"); - config->set_property("Acquisition.bit_transition_flag", "false"); - config->set_property("Acquisition.dump", "false"); + config->set_property("Acquisition_1C.max_dwells", "1"); + config->set_property("Acquisition_1C.threshold", std::to_string(FLAGS_value_threshold)); + config->set_property("Acquisition_1C.doppler_max", "10000"); + config->set_property("Acquisition_1C.doppler_step", "100"); + config->set_property("Acquisition_1C.bit_transition_flag", "false"); + config->set_property("Acquisition_1C.dump", "false"); } @@ -439,17 +437,16 @@ void GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test::config_3() config->set_property("InputFilter.filter_type", "bandpass"); config->set_property("InputFilter.grid_density", "16"); - config->set_property("Acquisition.item_type", "gr_complex"); - config->set_property("Acquisition.if", "0"); - config->set_property("Acquisition.coherent_integration_time_ms", + config->set_property("Acquisition_1C.implementation", "GPS_L1_CA_PCPS_QuickSync_Acquisition"); + config->set_property("Acquisition_1C.item_type", "gr_complex"); + config->set_property("Acquisition_1C.coherent_integration_time_ms", std::to_string(integration_time_ms)); - config->set_property("Acquisition.max_dwells", "2"); - config->set_property("Acquisition.implementation", "GPS_L1_CA_PCPS_QuickSync_Acquisition"); - config->set_property("Acquisition.threshold", "0.01"); - config->set_property("Acquisition.doppler_max", "10000"); - config->set_property("Acquisition.doppler_step", "250"); - config->set_property("Acquisition.bit_transition_flag", "false"); - config->set_property("Acquisition.dump", "false"); + config->set_property("Acquisition_1C.max_dwells", "2"); + config->set_property("Acquisition_1C.threshold", "0.01"); + config->set_property("Acquisition_1C.doppler_max", "10000"); + config->set_property("Acquisition_1C.doppler_step", "250"); + config->set_property("Acquisition_1C.bit_transition_flag", "false"); + config->set_property("Acquisition_1C.dump", "false"); } @@ -537,7 +534,7 @@ void GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test::stop_queue() TEST_F(GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test, Instantiate) { config_1(); - acquisition = std::make_shared(config.get(), "Acquisition", 1, 1); + acquisition = std::make_shared(config.get(), "Acquisition_1C", 1, 1); } @@ -545,13 +542,13 @@ TEST_F(GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test, ConnectAndRun) { int nsamples = floor(fs_in * integration_time_ms * 1e-3); std::chrono::time_point start, end; - std::chrono::duration elapsed_seconds(0); + std::chrono::duration elapsed_seconds(0.0); top_block = gr::make_top_block("Acquisition test"); queue = gr::msg_queue::make(0); boost::shared_ptr msg_rx = GpsL1CaPcpsAcquisitionGSoC2013Test_msg_rx_make(channel_internal_queue); config_1(); - acquisition = std::make_shared(config.get(), "Acquisition", 1, 1); + acquisition = std::make_shared(config.get(), "Acquisition_1C", 1, 1); ASSERT_NO_THROW( { acquisition->connect(top_block); @@ -560,14 +557,14 @@ TEST_F(GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test, ConnectAndRun) top_block->connect(source, 0, valve, 0); top_block->connect(valve, 0, acquisition->get_left_block(), 0); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of acquisition test."<< std::endl; + }) << "Failure connecting the blocks of acquisition test."; 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::endl; + }) << "Failure running the top_block."; std::cout << "Processed " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; } @@ -578,32 +575,32 @@ TEST_F(GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test, ValidationOfResults) config_1(); top_block = gr::make_top_block("Acquisition test"); queue = gr::msg_queue::make(0); - acquisition = std::make_shared(config.get(), "Acquisition", 1, 1); + acquisition = std::make_shared(config.get(), "Acquisition_1C", 1, 1); boost::shared_ptr msg_rx = GpsL1CaPcpsAcquisitionGSoC2013Test_msg_rx_make(channel_internal_queue); ASSERT_NO_THROW( { acquisition->set_channel(1); - }) << "Failure setting channel."<< std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { acquisition->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro."<< std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { acquisition->set_doppler_max(10000); - }) << "Failure setting doppler_max."<< std::endl; + }) << "Failure setting doppler_max."; ASSERT_NO_THROW( { acquisition->set_doppler_step(250); - }) << "Failure setting doppler_step."<< std::endl; + }) << "Failure setting doppler_step."; ASSERT_NO_THROW( { acquisition->set_threshold(100); - }) << "Failure setting threshold."<< std::endl; + }) << "Failure setting threshold."; ASSERT_NO_THROW( { acquisition->connect(top_block); - }) << "Failure connecting acquisition to the top_block."<< std::endl; + }) << "Failure connecting acquisition to the top_block."; acquisition->init(); acquisition->reset(); @@ -616,7 +613,7 @@ TEST_F(GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test, ValidationOfResults) signal_source->connect(top_block); top_block->connect(signal_source->get_right_block(), 0, acquisition->get_left_block(), 0); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of acquisition test." << std::endl; + }) << "Failure connecting the blocks of acquisition test."; // i = 0 --> satellite in acquisition is visible // i = 1 --> satellite in acquisition is not visible @@ -642,7 +639,7 @@ TEST_F(GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test, ValidationOfResults) EXPECT_NO_THROW( { top_block->run(); // Start threads and wait - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; stop_queue(); @@ -672,32 +669,32 @@ TEST_F(GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test, ValidationOfResultsWithNoise config_1(); top_block = gr::make_top_block("Acquisition test"); queue = gr::msg_queue::make(0); - acquisition = std::make_shared(config.get(), "Acquisition", 1, 1); + acquisition = std::make_shared(config.get(), "Acquisition_1C", 1, 1); boost::shared_ptr msg_rx = GpsL1CaPcpsAcquisitionGSoC2013Test_msg_rx_make(channel_internal_queue); ASSERT_NO_THROW( { acquisition->set_channel(1); - }) << "Failure setting channel."<< std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { acquisition->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro." << std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { acquisition->set_doppler_max(10000); - }) << "Failure setting doppler_max."<< std::endl; + }) << "Failure setting doppler_max."; ASSERT_NO_THROW( { acquisition->set_doppler_step(250); - }) << "Failure setting doppler_step."<< std::endl; + }) << "Failure setting doppler_step."; ASSERT_NO_THROW( { acquisition->set_threshold(100); - }) << "Failure setting threshold." << std::endl; + }) << "Failure setting threshold."; ASSERT_NO_THROW( { acquisition->connect(top_block); - }) << "Failure connecting acquisition to the top_block." << std::endl; + }) << "Failure connecting acquisition to the top_block."; acquisition->init(); acquisition->reset(); @@ -710,7 +707,7 @@ TEST_F(GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test, ValidationOfResultsWithNoise signal_source->connect(top_block); top_block->connect(signal_source->get_right_block(), 0, acquisition->get_left_block(), 0); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of acquisition test." << std::endl; + }) << "Failure connecting the blocks of acquisition test."; // i = 0 --> satellite in acquisition is visible // i = 1 --> satellite in acquisition is not visible @@ -736,7 +733,7 @@ TEST_F(GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test, ValidationOfResultsWithNoise EXPECT_NO_THROW( { top_block->run(); // Start threads and wait - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; stop_queue(); @@ -764,32 +761,20 @@ TEST_F(GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test, ValidationOfResultsProbabili config_2(); top_block = gr::make_top_block("Acquisition test"); queue = gr::msg_queue::make(0); - acquisition = std::make_shared(config.get(), "Acquisition", 1, 1); + acquisition = std::make_shared(config.get(), "Acquisition_1C", 1, 1); boost::shared_ptr msg_rx = GpsL1CaPcpsAcquisitionGSoC2013Test_msg_rx_make(channel_internal_queue); ASSERT_NO_THROW( { acquisition->set_channel(1); - }) << "Failure setting channel."<< std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { acquisition->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro."<< std::endl; - - /* ASSERT_NO_THROW( { - acquisition->set_doppler_max(config->property("Acquisition.doppler_max", 10000)); - }) << "Failure setting doppler_max."<< std::endl; - - ASSERT_NO_THROW( { - acquisition->set_doppler_step(config->property("Acquisition.doppler_step", 500)); - }) << "Failure setting doppler_step."<< std::endl; - - ASSERT_NO_THROW( { - acquisition->set_threshold(config->property("Acquisition.threshold", 0.0)); - }) << "Failure setting threshold."<< std::endl; */ + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { acquisition->connect(top_block); - }) << "Failure connecting acquisition to the top_block."<< std::endl; + }) << "Failure connecting acquisition to the top_block."; acquisition->init(); acquisition->reset(); @@ -802,7 +787,7 @@ TEST_F(GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test, ValidationOfResultsProbabili signal_source->connect(top_block); top_block->connect(signal_source->get_right_block(), 0, acquisition->get_left_block(), 0); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of acquisition test." << std::endl; + }) << "Failure connecting the blocks of acquisition test."; std::cout << "Probability of false alarm (target) = " << 0.1 << std::endl; @@ -829,7 +814,7 @@ TEST_F(GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test, ValidationOfResultsProbabili EXPECT_NO_THROW( { top_block->run(); // Start threads and wait - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; stop_queue(); diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_tong_acquisition_gsoc2013_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_tong_acquisition_gsoc2013_test.cc index b4275a582..cfff6ff70 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_tong_acquisition_gsoc2013_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_tong_acquisition_gsoc2013_test.cc @@ -240,17 +240,16 @@ void GpsL1CaPcpsTongAcquisitionGSoC2013Test::config_1() config->set_property("InputFilter.filter_type", "bandpass"); config->set_property("InputFilter.grid_density", "16"); - config->set_property("Acquisition.item_type", "gr_complex"); - config->set_property("Acquisition.if", "0"); - config->set_property("Acquisition.coherent_integration_time_ms", + config->set_property("Acquisition_1C.implementation", "GPS_L1_CA_PCPS_Tong_Acquisition"); + config->set_property("Acquisition_1C.item_type", "gr_complex"); + config->set_property("Acquisition_1C.coherent_integration_time_ms", std::to_string(integration_time_ms)); - config->set_property("Acquisition.implementation", "GPS_L1_CA_PCPS_Tong_Acquisition"); - config->set_property("Acquisition.threshold", "0.8"); - config->set_property("Acquisition.tong_init_val", "1"); - config->set_property("Acquisition.tong_max_val", "8"); - config->set_property("Acquisition.doppler_max", "10000"); - config->set_property("Acquisition.doppler_step", "250"); - config->set_property("Acquisition.dump", "false"); + config->set_property("Acquisition_1C.threshold", "0.8"); + config->set_property("Acquisition_1C.tong_init_val", "1"); + config->set_property("Acquisition_1C.tong_max_val", "8"); + config->set_property("Acquisition_1C.doppler_max", "10000"); + config->set_property("Acquisition_1C.doppler_step", "250"); + config->set_property("Acquisition_1C.dump", "false"); } @@ -328,17 +327,16 @@ void GpsL1CaPcpsTongAcquisitionGSoC2013Test::config_2() config->set_property("InputFilter.filter_type", "bandpass"); config->set_property("InputFilter.grid_density", "16"); - config->set_property("Acquisition.item_type", "gr_complex"); - config->set_property("Acquisition.if", "0"); - config->set_property("Acquisition.coherent_integration_time_ms", + config->set_property("Acquisition_1C.implementation", "GPS_L1_CA_PCPS_Tong_Acquisition"); + config->set_property("Acquisition_1C.item_type", "gr_complex"); + config->set_property("Acquisition_1C.coherent_integration_time_ms", std::to_string(integration_time_ms)); - config->set_property("Acquisition.implementation", "GPS_L1_CA_PCPS_Tong_Acquisition"); - config->set_property("Acquisition.threshold", "0.00108"); // Pfa,a = 0.1 - config->set_property("Acquisition.tong_init_val", "1"); - config->set_property("Acquisition.tong_max_val", "8"); - config->set_property("Acquisition.doppler_max", "10000"); - config->set_property("Acquisition.doppler_step", "250"); - config->set_property("Acquisition.dump", "false"); + config->set_property("Acquisition_1C.threshold", "0.00108"); // Pfa,a = 0.1 + config->set_property("Acquisition_1C.tong_init_val", "1"); + config->set_property("Acquisition_1C.tong_max_val", "8"); + config->set_property("Acquisition_1C.doppler_max", "10000"); + config->set_property("Acquisition_1C.doppler_step", "250"); + config->set_property("Acquisition_1C.dump", "false"); } @@ -422,7 +420,7 @@ void GpsL1CaPcpsTongAcquisitionGSoC2013Test::stop_queue() TEST_F(GpsL1CaPcpsTongAcquisitionGSoC2013Test, Instantiate) { config_1(); - acquisition = std::make_shared(config.get(), "Acquisition", 1, 1); + acquisition = std::make_shared(config.get(), "Acquisition_1C", 1, 1); } @@ -435,7 +433,7 @@ TEST_F(GpsL1CaPcpsTongAcquisitionGSoC2013Test, ConnectAndRun) queue = gr::msg_queue::make(0); config_1(); - acquisition = std::make_shared(config.get(), "Acquisition", 1, 1); + acquisition = std::make_shared(config.get(), "Acquisition_1C", 1, 1); boost::shared_ptr msg_rx = GpsL1CaPcpsTongAcquisitionGSoC2013Test_msg_rx_make(channel_internal_queue); ASSERT_NO_THROW( { @@ -445,14 +443,14 @@ TEST_F(GpsL1CaPcpsTongAcquisitionGSoC2013Test, ConnectAndRun) top_block->connect(source, 0, valve, 0); top_block->connect(valve, 0, acquisition->get_left_block(), 0); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of acquisition test." << std::endl; + }) << "Failure connecting the blocks of acquisition test."; 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::endl; + }) << "Failure running the top_block."; std::cout << "Processed " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; } @@ -464,32 +462,32 @@ TEST_F(GpsL1CaPcpsTongAcquisitionGSoC2013Test, ValidationOfResults) top_block = gr::make_top_block("Acquisition test"); queue = gr::msg_queue::make(0); - acquisition = std::make_shared(config.get(), "Acquisition", 1, 1); + acquisition = std::make_shared(config.get(), "Acquisition_1C", 1, 1); boost::shared_ptr msg_rx = GpsL1CaPcpsTongAcquisitionGSoC2013Test_msg_rx_make(channel_internal_queue); ASSERT_NO_THROW( { acquisition->set_channel(1); - }) << "Failure setting channel." << std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { acquisition->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro." << std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { - acquisition->set_doppler_max(config->property("Acquisition.doppler_max", 10000)); - }) << "Failure setting doppler_max." << std::endl; + acquisition->set_doppler_max(config->property("Acquisition_1C.doppler_max", 10000)); + }) << "Failure setting doppler_max."; ASSERT_NO_THROW( { - acquisition->set_doppler_step(config->property("Acquisition.doppler_step", 500)); - }) << "Failure setting doppler_step." << std::endl; + acquisition->set_doppler_step(config->property("Acquisition_1C.doppler_step", 500)); + }) << "Failure setting doppler_step."; ASSERT_NO_THROW( { - acquisition->set_threshold(config->property("Acquisition.threshold", 0.0)); - }) << "Failure setting threshold." << std::endl; + acquisition->set_threshold(config->property("Acquisition_1C.threshold", 0.0)); + }) << "Failure setting threshold."; ASSERT_NO_THROW( { acquisition->connect(top_block); - }) << "Failure connecting acquisition to the top_block." << std::endl; + }) << "Failure connecting acquisition to the top_block."; acquisition->init(); @@ -501,7 +499,7 @@ TEST_F(GpsL1CaPcpsTongAcquisitionGSoC2013Test, ValidationOfResults) signal_source->connect(top_block); top_block->connect(signal_source->get_right_block(), 0, acquisition->get_left_block(), 0); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of acquisition test." << std::endl; + }) << "Failure connecting the blocks of acquisition test."; // i = 0 --> satellite in acquisition is visible // i = 1 --> satellite in acquisition is not visible @@ -525,7 +523,7 @@ TEST_F(GpsL1CaPcpsTongAcquisitionGSoC2013Test, ValidationOfResults) EXPECT_NO_THROW( { top_block->run(); // Start threads and wait - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; stop_queue(); @@ -552,32 +550,32 @@ TEST_F(GpsL1CaPcpsTongAcquisitionGSoC2013Test, ValidationOfResultsProbabilities) config_2(); top_block = gr::make_top_block("Acquisition test"); queue = gr::msg_queue::make(0); - acquisition = std::make_shared(config.get(), "Acquisition", 1, 1); + acquisition = std::make_shared(config.get(), "Acquisition_1C", 1, 1); boost::shared_ptr msg_rx = GpsL1CaPcpsTongAcquisitionGSoC2013Test_msg_rx_make(channel_internal_queue); ASSERT_NO_THROW( { acquisition->set_channel(1); - }) << "Failure setting channel." << std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { acquisition->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro." << std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { - acquisition->set_doppler_max(config->property("Acquisition.doppler_max", 10000)); - }) << "Failure setting doppler_max." << std::endl; + acquisition->set_doppler_max(config->property("Acquisition_1C.doppler_max", 10000)); + }) << "Failure setting doppler_max."; ASSERT_NO_THROW( { - acquisition->set_doppler_step(config->property("Acquisition.doppler_step", 500)); - }) << "Failure setting doppler_step." << std::endl; + acquisition->set_doppler_step(config->property("Acquisition_1C.doppler_step", 500)); + }) << "Failure setting doppler_step."; ASSERT_NO_THROW( { - acquisition->set_threshold(config->property("Acquisition.threshold", 0.0)); - }) << "Failure setting threshold." << std::endl; + acquisition->set_threshold(config->property("Acquisition_1C.threshold", 0.0)); + }) << "Failure setting threshold."; ASSERT_NO_THROW( { acquisition->connect(top_block); - }) << "Failure connecting acquisition to the top_block." << std::endl; + }) << "Failure connecting acquisition to the top_block."; acquisition->init(); @@ -589,7 +587,7 @@ TEST_F(GpsL1CaPcpsTongAcquisitionGSoC2013Test, ValidationOfResultsProbabilities) signal_source->connect(top_block); top_block->connect(signal_source->get_right_block(), 0, acquisition->get_left_block(), 0); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of acquisition test." << std::endl; + }) << "Failure connecting the blocks of acquisition test."; std::cout << "Probability of false alarm (target) = " << 0.1 << std::endl; @@ -614,7 +612,7 @@ TEST_F(GpsL1CaPcpsTongAcquisitionGSoC2013Test, ValidationOfResultsProbabilities) EXPECT_NO_THROW( { top_block->run(); // Start threads and wait - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; stop_queue(); diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc index 69b36f01c..7b7dcc083 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc @@ -148,14 +148,13 @@ void GpsL2MPcpsAcquisitionTest::init() sampling_freqeuncy_hz = 5000000; nsamples = round(static_cast(sampling_freqeuncy_hz) * GPS_L2_M_PERIOD) * 2; config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(sampling_freqeuncy_hz)); - config->set_property("Acquisition.item_type", "gr_complex"); - config->set_property("Acquisition.if", "0"); - config->set_property("Acquisition.dump", "false"); - config->set_property("Acquisition.implementation", "GPS_L2_M_PCPS_Acquisition"); - config->set_property("Acquisition.threshold", "0.001"); - config->set_property("Acquisition.doppler_max", "5000"); - config->set_property("Acquisition.doppler_step", "100"); - config->set_property("Acquisition.repeat_satellite", "false"); + config->set_property("Acquisition_2S.implementation", "GPS_L2_M_PCPS_Acquisition"); + config->set_property("Acquisition_2S.item_type", "gr_complex"); + config->set_property("Acquisition_2S.dump", "false"); + config->set_property("Acquisition_2S.threshold", "0.001"); + config->set_property("Acquisition_2S.doppler_max", "5000"); + config->set_property("Acquisition_2S.doppler_step", "100"); + config->set_property("Acquisition_2S.repeat_satellite", "false"); } @@ -163,7 +162,7 @@ TEST_F(GpsL2MPcpsAcquisitionTest, Instantiate) { init(); queue = gr::msg_queue::make(0); - std::shared_ptr acquisition = std::make_shared(config.get(), "Acquisition", 1, 1); + std::shared_ptr acquisition = std::make_shared(config.get(), "Acquisition_2S", 1, 1); } @@ -175,7 +174,7 @@ TEST_F(GpsL2MPcpsAcquisitionTest, ConnectAndRun) queue = gr::msg_queue::make(0); init(); - std::shared_ptr acquisition = std::make_shared(config.get(), "Acquisition", 1, 1); + std::shared_ptr acquisition = std::make_shared(config.get(), "Acquisition_2S", 1, 1); ASSERT_NO_THROW( { acquisition->connect(top_block); @@ -184,15 +183,14 @@ TEST_F(GpsL2MPcpsAcquisitionTest, ConnectAndRun) top_block->connect(source, 0, valve, 0); top_block->connect(valve, 0, acquisition->get_left_block(), 0); boost::shared_ptr msg_rx = GpsL2MPcpsAcquisitionTest_msg_rx_make(); - - }) << "Failure connecting the blocks of acquisition test." << std::endl; + }) << "Failure connecting the blocks of acquisition test."; 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::endl; + }) << "Failure running the top_block."; std::cout << "Processed " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; } @@ -207,32 +205,32 @@ TEST_F(GpsL2MPcpsAcquisitionTest, ValidationOfResults) double expected_delay_samples = 1;//2004; double expected_doppler_hz = 1200;//3000; init(); - std::shared_ptr acquisition = std::make_shared(config.get(), "Acquisition", 1, 1); + std::shared_ptr acquisition = std::make_shared(config.get(), "Acquisition_2S", 1, 1); boost::shared_ptr msg_rx = GpsL2MPcpsAcquisitionTest_msg_rx_make(); ASSERT_NO_THROW( { acquisition->set_channel(1); - }) << "Failure setting channel." << std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { acquisition->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro." << std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { acquisition->set_threshold(0.001); - }) << "Failure setting threshold." << std::endl; + }) << "Failure setting threshold."; ASSERT_NO_THROW( { acquisition->set_doppler_max(5000); - }) << "Failure setting doppler_max." << std::endl; + }) << "Failure setting doppler_max."; ASSERT_NO_THROW( { acquisition->set_doppler_step(10); - }) << "Failure setting doppler_step." << std::endl; + }) << "Failure setting doppler_step."; ASSERT_NO_THROW( { acquisition->connect(top_block); - }) << "Failure connecting acquisition to the top_block." << std::endl; + }) << "Failure connecting acquisition to the top_block."; ASSERT_NO_THROW( { std::string path = std::string(TEST_PATH); @@ -249,20 +247,20 @@ TEST_F(GpsL2MPcpsAcquisitionTest, ValidationOfResults) top_block->connect(file_source, 0, valve , 0); top_block->connect(valve, 0, acquisition->get_left_block(), 0); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of acquisition test." << std::endl; + }) << "Failure connecting the blocks of acquisition test."; ASSERT_NO_THROW( { acquisition->set_local_code(); acquisition->set_state(1); // Ensure that acquisition starts at the first sample acquisition->init(); - }) << "Failure set_state and init acquisition test" << std::endl; + }) << "Failure set_state and init acquisition test"; 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::endl; + }) << "Failure running the top_block."; //unsigned long int Acq_samplestamp_samples = gnss_synchro.Acq_samplestamp_samples; std::cout << "Acquisition process runtime duration: " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; From 396415b6f2692df70ebf4cd996c2b527e54d5faa Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sun, 29 Oct 2017 00:44:38 +0200 Subject: [PATCH 69/81] Fixes in testing code --- src/tests/system-tests/position_test.cc | 5 +- .../unit-tests/arithmetic/fft_length_test.cc | 3 +- .../libs/observables_dump_reader.cc | 20 ++++---- .../libs/tracking_dump_reader.cc | 3 +- .../libs/true_observables_reader.cc | 20 ++++---- .../galileo_e1_dll_pll_veml_tracking_test.cc | 41 ++++++++-------- .../tracking/galileo_e5a_tracking_test.cc | 39 ++++++++------- .../gps_l1_ca_dll_pll_tracking_test.cc | 2 +- .../gps_l1_ca_dll_pll_tracking_test_fpga.cc | 16 +++---- .../gps_l2_m_dll_pll_tracking_test.cc | 14 +++--- .../tracking/tracking_loop_filter_test.cc | 48 +++++++++---------- 11 files changed, 104 insertions(+), 107 deletions(-) diff --git a/src/tests/system-tests/position_test.cc b/src/tests/system-tests/position_test.cc index 048abefea..c139216e5 100644 --- a/src/tests/system-tests/position_test.cc +++ b/src/tests/system-tests/position_test.cc @@ -341,7 +341,6 @@ int StaticPositionSystemTest::configure_receiver() // Set Acquisition config->set_property("Acquisition_1C.implementation", "GPS_L1_CA_PCPS_Tong_Acquisition"); config->set_property("Acquisition_1C.item_type", "gr_complex"); - config->set_property("Acquisition_1C.if", std::to_string(zero)); config->set_property("Acquisition_1C.coherent_integration_time_ms", std::to_string(coherent_integration_time_ms)); config->set_property("Acquisition_1C.threshold", std::to_string(threshold)); config->set_property("Acquisition_1C.doppler_max", std::to_string(doppler_max)); @@ -356,7 +355,6 @@ int StaticPositionSystemTest::configure_receiver() config->set_property("Tracking_1C.implementation", "GPS_L1_CA_DLL_PLL_Tracking"); //config->set_property("Tracking_1C.implementation", "GPS_L1_CA_DLL_PLL_C_Aid_Tracking"); config->set_property("Tracking_1C.item_type", "gr_complex"); - config->set_property("Tracking_1C.if", std::to_string(zero)); config->set_property("Tracking_1C.dump", "false"); config->set_property("Tracking_1C.dump_filename", "./tracking_ch_"); config->set_property("Tracking_1C.pll_bw_hz", std::to_string(pll_bw_hz)); @@ -630,6 +628,7 @@ void StaticPositionSystemTest::print_results(const std::vector & east, g2.cmd("set yrange [-" + std::to_string(range_3d) + ":" + std::to_string(range_3d) + "]"); g2.cmd("set zrange [-" + std::to_string(range_3d) + ":" + std::to_string(range_3d) + "]"); g2.cmd("set view equal xyz"); + g2.cmd("set ticslevel 0"); g2.cmd("set style fill transparent solid 0.30 border\n set parametric\n set urange [0:2.0*pi]\n set vrange [-pi/2:pi/2]\n r = " + std::to_string(ninty_sas) + @@ -640,7 +639,7 @@ void StaticPositionSystemTest::print_results(const std::vector & east, g2.savetopdf("Position_test_3D"); g2.showonscreen(); // window output } - catch (GnuplotException ge) + catch (const GnuplotException & ge) { std::cout << ge.what() << std::endl; } diff --git a/src/tests/unit-tests/arithmetic/fft_length_test.cc b/src/tests/unit-tests/arithmetic/fft_length_test.cc index f8ea83d22..27f076dc4 100644 --- a/src/tests/unit-tests/arithmetic/fft_length_test.cc +++ b/src/tests/unit-tests/arithmetic/fft_length_test.cc @@ -96,7 +96,6 @@ TEST(FFTLengthTest, MeasureExecutionTime) powers_of_two.push_back(d_fft_size); execution_times_powers_of_two.push_back(exec_time / 1e-3); } - } ); @@ -141,7 +140,7 @@ TEST(FFTLengthTest, MeasureExecutionTime) g2.savetopdf("FFT_execution_times", 18); g2.showonscreen(); // window output } - catch (GnuplotException ge) + catch (const GnuplotException & ge) { std::cout << ge.what() << std::endl; } diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/observables_dump_reader.cc b/src/tests/unit-tests/signal-processing-blocks/libs/observables_dump_reader.cc index 648938146..47832b888 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/observables_dump_reader.cc +++ b/src/tests/unit-tests/signal-processing-blocks/libs/observables_dump_reader.cc @@ -34,16 +34,16 @@ bool observables_dump_reader::read_binary_obs() { try { - for(int i = 0; i < n_channels; i++) - { - d_dump_file.read(reinterpret_cast(&RX_time[i]), sizeof(double)); - d_dump_file.read(reinterpret_cast(&TOW_at_current_symbol_s[i]), sizeof(double)); - d_dump_file.read(reinterpret_cast(&Carrier_Doppler_hz[i]), sizeof(double)); - d_dump_file.read(reinterpret_cast(&Acc_carrier_phase_hz[i]), sizeof(double)); - d_dump_file.read(reinterpret_cast(&Pseudorange_m[i]), sizeof(double)); - d_dump_file.read(reinterpret_cast(&PRN[i]), sizeof(double)); - d_dump_file.read(reinterpret_cast(&valid[i]), sizeof(double)); - } + for(int i = 0; i < n_channels; i++) + { + d_dump_file.read(reinterpret_cast(&RX_time[i]), sizeof(double)); + d_dump_file.read(reinterpret_cast(&TOW_at_current_symbol_s[i]), sizeof(double)); + d_dump_file.read(reinterpret_cast(&Carrier_Doppler_hz[i]), sizeof(double)); + d_dump_file.read(reinterpret_cast(&Acc_carrier_phase_hz[i]), sizeof(double)); + d_dump_file.read(reinterpret_cast(&Pseudorange_m[i]), sizeof(double)); + d_dump_file.read(reinterpret_cast(&PRN[i]), sizeof(double)); + d_dump_file.read(reinterpret_cast(&valid[i]), sizeof(double)); + } } catch (const std::ifstream::failure &e) { diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/tracking_dump_reader.cc b/src/tests/unit-tests/signal-processing-blocks/libs/tracking_dump_reader.cc index 368b1ee27..1ff2c67e3 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/tracking_dump_reader.cc +++ b/src/tests/unit-tests/signal-processing-blocks/libs/tracking_dump_reader.cc @@ -32,7 +32,8 @@ bool tracking_dump_reader::read_binary_obs() { - try { + try + { d_dump_file.read(reinterpret_cast(&abs_E), sizeof(float)); d_dump_file.read(reinterpret_cast(&abs_P), sizeof(float)); d_dump_file.read(reinterpret_cast(&abs_L), sizeof(float)); diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/true_observables_reader.cc b/src/tests/unit-tests/signal-processing-blocks/libs/true_observables_reader.cc index 2a6d7830a..8b4bcb07b 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/true_observables_reader.cc +++ b/src/tests/unit-tests/signal-processing-blocks/libs/true_observables_reader.cc @@ -34,16 +34,16 @@ bool true_observables_reader::read_binary_obs() { try { - for(int i = 0; i < 12; i++) - { - d_dump_file.read(reinterpret_cast(&gps_time_sec[i]), sizeof(double)); - d_dump_file.read(reinterpret_cast(&doppler_l1_hz), sizeof(double)); - d_dump_file.read(reinterpret_cast(&acc_carrier_phase_l1_cycles[i]), sizeof(double)); - d_dump_file.read(reinterpret_cast(&dist_m[i]), sizeof(double)); - d_dump_file.read(reinterpret_cast(&true_dist_m[i]), sizeof(double)); - d_dump_file.read(reinterpret_cast(&carrier_phase_l1_cycles[i]), sizeof(double)); - d_dump_file.read(reinterpret_cast(&prn[i]), sizeof(double)); - } + for(int i = 0; i < 12; i++) + { + d_dump_file.read(reinterpret_cast(&gps_time_sec[i]), sizeof(double)); + d_dump_file.read(reinterpret_cast(&doppler_l1_hz), sizeof(double)); + d_dump_file.read(reinterpret_cast(&acc_carrier_phase_l1_cycles[i]), sizeof(double)); + d_dump_file.read(reinterpret_cast(&dist_m[i]), sizeof(double)); + d_dump_file.read(reinterpret_cast(&true_dist_m[i]), sizeof(double)); + d_dump_file.read(reinterpret_cast(&carrier_phase_l1_cycles[i]), sizeof(double)); + d_dump_file.read(reinterpret_cast(&prn[i]), sizeof(double)); + } } catch (const std::ifstream::failure &e) { diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/galileo_e1_dll_pll_veml_tracking_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/galileo_e1_dll_pll_veml_tracking_test.cc index 4de9eb7ed..ea9740b90 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/galileo_e1_dll_pll_veml_tracking_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/galileo_e1_dll_pll_veml_tracking_test.cc @@ -87,21 +87,21 @@ void GalileoE1DllPllVemlTrackingInternalTest::init() gnss_synchro.PRN = 11; config->set_property("GNSS-SDR.internal_fs_sps", "8000000"); - config->set_property("Tracking_Galileo.item_type", "gr_complex"); - config->set_property("Tracking_Galileo.dump", "false"); - config->set_property("Tracking_Galileo.dump_filename", "../data/veml_tracking_ch_"); - config->set_property("Tracking_Galileo.implementation", "Galileo_E1_DLL_PLL_VEML_Tracking"); - config->set_property("Tracking_Galileo.early_late_space_chips", "0.15"); - config->set_property("Tracking_Galileo.very_early_late_space_chips", "0.6"); - config->set_property("Tracking_Galileo.pll_bw_hz", "30.0"); - config->set_property("Tracking_Galileo.dll_bw_hz", "2.0"); + config->set_property("Tracking_1B.implementation", "Galileo_E1_DLL_PLL_VEML_Tracking"); + config->set_property("Tracking_1B.item_type", "gr_complex"); + config->set_property("Tracking_1B.dump", "false"); + config->set_property("Tracking_1B.dump_filename", "../data/veml_tracking_ch_"); + config->set_property("Tracking_1B.early_late_space_chips", "0.15"); + config->set_property("Tracking_1B.very_early_late_space_chips", "0.6"); + config->set_property("Tracking_1B.pll_bw_hz", "30.0"); + config->set_property("Tracking_1B.dll_bw_hz", "2.0"); } TEST_F(GalileoE1DllPllVemlTrackingInternalTest, Instantiate) { init(); - auto tracking = factory->GetBlock(config, "Tracking", "Galileo_E1_DLL_PLL_VEML_Tracking", 1, 1); + auto tracking = factory->GetBlock(config, "Tracking_1B", "Galileo_E1_DLL_PLL_VEML_Tracking", 1, 1); EXPECT_STREQ("Galileo_E1_DLL_PLL_VEML_Tracking", tracking->implementation().c_str()); } @@ -117,16 +117,16 @@ TEST_F(GalileoE1DllPllVemlTrackingInternalTest, ConnectAndRun) top_block = gr::make_top_block("Tracking test"); // Example using smart pointers and the block factory - std::shared_ptr trk_ = factory->GetBlock(config, "Tracking", "Galileo_E1_DLL_PLL_VEML_Tracking", 1, 1); + std::shared_ptr trk_ = factory->GetBlock(config, "Tracking_1B", "Galileo_E1_DLL_PLL_VEML_Tracking", 1, 1); std::shared_ptr tracking = std::dynamic_pointer_cast(trk_); ASSERT_NO_THROW( { tracking->set_channel(gnss_synchro.Channel_ID); - }) << "Failure setting channel." << std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { tracking->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro." << std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { tracking->connect(top_block); @@ -136,8 +136,7 @@ TEST_F(GalileoE1DllPllVemlTrackingInternalTest, ConnectAndRun) 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." << std::endl; + }) << "Failure connecting the blocks of tracking test."; tracking->start_tracking(); @@ -146,7 +145,7 @@ TEST_F(GalileoE1DllPllVemlTrackingInternalTest, ConnectAndRun) top_block->run(); //Start threads and wait end = std::chrono::system_clock::now(); elapsed_seconds = end - start; - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; std::cout << "Processed " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; } @@ -165,7 +164,7 @@ TEST_F(GalileoE1DllPllVemlTrackingInternalTest, ValidationOfResults) top_block = gr::make_top_block("Tracking test"); // Example using smart pointers and the block factory - std::shared_ptr trk_ = factory->GetBlock(config, "Tracking", "Galileo_E1_DLL_PLL_VEML_Tracking", 1, 1); + std::shared_ptr trk_ = factory->GetBlock(config, "Tracking_1B", "Galileo_E1_DLL_PLL_VEML_Tracking", 1, 1); std::shared_ptr tracking = std::dynamic_pointer_cast(trk_); // gnss_synchro.Acq_delay_samples = 1753; // 4 Msps @@ -176,15 +175,15 @@ TEST_F(GalileoE1DllPllVemlTrackingInternalTest, ValidationOfResults) ASSERT_NO_THROW( { tracking->set_channel(gnss_synchro.Channel_ID); - }) << "Failure setting channel." << std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { tracking->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro." << std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { tracking->connect(top_block); - }) << "Failure connecting tracking to the top_block." << std::endl; + }) << "Failure connecting tracking to the top_block."; ASSERT_NO_THROW( { std::string path = std::string(TEST_PATH); @@ -198,7 +197,7 @@ TEST_F(GalileoE1DllPllVemlTrackingInternalTest, ValidationOfResults) top_block->connect(skip_head, 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." << std::endl; + }) << "Failure connecting the blocks of tracking test."; tracking->start_tracking(); @@ -207,7 +206,7 @@ TEST_F(GalileoE1DllPllVemlTrackingInternalTest, ValidationOfResults) top_block->run(); // Start threads and wait end = std::chrono::system_clock::now(); elapsed_seconds = end - start; - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; std::cout << "Tracked " << num_samples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; } diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/galileo_e5a_tracking_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/galileo_e5a_tracking_test.cc index 974f4193e..5aed31f4a 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/galileo_e5a_tracking_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/galileo_e5a_tracking_test.cc @@ -81,22 +81,22 @@ void GalileoE5aTrackingTest::init() { gnss_synchro.Channel_ID = 0; gnss_synchro.System = 'E'; - std::string signal = "5Q"; + std::string signal = "5X"; signal.copy(gnss_synchro.Signal, 2, 0); gnss_synchro.PRN = 11; config->set_property("GNSS-SDR.internal_fs_sps", "32000000"); - config->set_property("Tracking_Galileo.item_type", "gr_complex"); - config->set_property("Tracking_Galileo.dump", "false"); - config->set_property("Tracking_Galileo.dump_filename", "../data/e5a_tracking_ch_"); - config->set_property("Tracking_Galileo.implementation", "Galileo_E5a_DLL_PLL_Tracking"); - config->set_property("Tracking_Galileo.early_late_space_chips", "0.5"); - config->set_property("Tracking_Galileo.order", "2"); - config->set_property("Tracking_Galileo.pll_bw_hz_init","20.0"); - config->set_property("Tracking_Galileo.pll_bw_hz", "5"); - config->set_property("Tracking_Galileo.dll_bw_hz_init","2.0"); - config->set_property("Tracking_Galileo.dll_bw_hz", "2"); - config->set_property("Tracking_Galileo.ti_ms", "1"); + config->set_property("Tracking_5X.implementation", "Galileo_E5a_DLL_PLL_Tracking"); + config->set_property("Tracking_5X.item_type", "gr_complex"); + config->set_property("Tracking_5X.dump", "false"); + config->set_property("Tracking_5X.dump_filename", "../data/e5a_tracking_ch_"); + config->set_property("Tracking_5X.early_late_space_chips", "0.5"); + config->set_property("Tracking_5X.order", "2"); + config->set_property("Tracking_5X.pll_bw_hz_init","20.0"); + config->set_property("Tracking_5X.pll_bw_hz", "5"); + config->set_property("Tracking_5X.dll_bw_hz_init","2.0"); + config->set_property("Tracking_5X.dll_bw_hz", "2"); + config->set_property("Tracking_5X.ti_ms", "1"); } @@ -105,13 +105,13 @@ TEST_F(GalileoE5aTrackingTest, ValidationOfResults) std::chrono::time_point start, end; std::chrono::duration elapsed_seconds(0); int fs_in = 32000000; - int nsamples = 32000000*5; + int nsamples = 32000000 * 5; init(); queue = gr::msg_queue::make(0); top_block = gr::make_top_block("Tracking test"); // Example using smart pointers and the block factory - std::shared_ptr trk_ = factory->GetBlock(config, "Tracking", "Galileo_E5a_DLL_PLL_Tracking", 1, 1); + std::shared_ptr trk_ = factory->GetBlock(config, "Tracking_5X", "Galileo_E5a_DLL_PLL_Tracking", 1, 1); std::shared_ptr tracking = std::dynamic_pointer_cast(trk_); //REAL @@ -123,15 +123,15 @@ TEST_F(GalileoE5aTrackingTest, ValidationOfResults) ASSERT_NO_THROW( { tracking->set_channel(gnss_synchro.Channel_ID); - }) << "Failure setting channel." << std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { tracking->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro." << std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { tracking->connect(top_block); - }) << "Failure connecting tracking to the top_block." << std::endl; + }) << "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)); @@ -140,8 +140,7 @@ TEST_F(GalileoE5aTrackingTest, ValidationOfResults) 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." << std::endl; + }) << "Failure connecting the blocks of tracking test."; tracking->start_tracking(); @@ -150,7 +149,7 @@ TEST_F(GalileoE5aTrackingTest, ValidationOfResults) top_block->run(); // Start threads and wait end = std::chrono::system_clock::now(); elapsed_seconds = end - start; - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; std::cout << "Tracked " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; } diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc index c10280c44..32d0388cf 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc @@ -555,7 +555,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) g2.showonscreen(); // window output } - catch (GnuplotException ge) + catch (const GnuplotException & ge) { std::cout << ge.what() << std::endl; } diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test_fpga.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test_fpga.cc index 1bd317a95..43442611f 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test_fpga.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test_fpga.cc @@ -465,7 +465,7 @@ TEST_F(GpsL1CADllPllTrackingTestFpga, ValidationOfResultsFpga) { throw std::exception(); }; - })<< "Failure opening true observables file" << std::endl; + }) << "Failure opening true observables file"; top_block = gr::make_top_block("Tracking test"); std::shared_ptr tracking = std::make_shared (config.get(), "Tracking_1C", 1, 1); @@ -479,7 +479,7 @@ TEST_F(GpsL1CADllPllTrackingTestFpga, ValidationOfResultsFpga) { throw std::exception(); }; - })<< "Failure reading true observables file" << std::endl; + }) << "Failure reading true observables file"; //restart the epoch counter true_obs_data.restart(); @@ -497,24 +497,24 @@ TEST_F(GpsL1CADllPllTrackingTestFpga, ValidationOfResultsFpga) ASSERT_NO_THROW( { tracking->set_channel(gnss_synchro.Channel_ID); - })<< "Failure setting channel." << std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { tracking->set_gnss_synchro(&gnss_synchro); - })<< "Failure setting gnss_synchro." << std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { tracking->connect(top_block); - })<< "Failure connecting tracking to the top_block." << std::endl; + }) << "Failure connecting tracking to the top_block."; ASSERT_NO_THROW( { gr::blocks::null_sink::sptr sink = gr::blocks::null_sink::make(sizeof(Gnss_Synchro)); top_block->connect(tracking->get_right_block(), 0, sink, 0); top_block->msg_connect(tracking->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - })<< "Failure connecting the blocks of tracking test." << std::endl; + }) << "Failure connecting the blocks of tracking test."; tracking->start_tracking(); @@ -533,7 +533,7 @@ TEST_F(GpsL1CADllPllTrackingTestFpga, ValidationOfResultsFpga) tracking->reset();// unlock the channel end = std::chrono::system_clock::now(); elapsed_seconds = end - start; - })<< "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; // wait until child thread terminates t.join(); @@ -568,7 +568,7 @@ TEST_F(GpsL1CADllPllTrackingTestFpga, ValidationOfResultsFpga) { throw std::exception(); }; - })<< "Failure opening tracking dump file" << std::endl; + }) << "Failure opening tracking dump file"; nepoch = trk_dump.num_epochs(); std::cout << "Measured observation epochs=" << nepoch << std::endl; diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l2_m_dll_pll_tracking_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l2_m_dll_pll_tracking_test.cc index 220543ffd..bc750c062 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l2_m_dll_pll_tracking_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l2_m_dll_pll_tracking_test.cc @@ -155,9 +155,9 @@ void GpsL2MDllPllTrackingTest::init() TEST_F(GpsL2MDllPllTrackingTest, ValidationOfResults) { std::chrono::time_point start, end; - std::chrono::duration elapsed_seconds(0); + std::chrono::duration elapsed_seconds(0.0); int fs_in = 5000000; - int nsamples = fs_in*9; + int nsamples = fs_in * 9; init(); queue = gr::msg_queue::make(0); @@ -171,15 +171,15 @@ TEST_F(GpsL2MDllPllTrackingTest, ValidationOfResults) ASSERT_NO_THROW( { tracking->set_channel(gnss_synchro.Channel_ID); - }) << "Failure setting channel." << std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { tracking->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro." << std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { tracking->connect(top_block); - }) << "Failure connecting tracking to the top_block." << std::endl; + }) << "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)); @@ -193,7 +193,7 @@ TEST_F(GpsL2MDllPllTrackingTest, ValidationOfResults) top_block->connect(valve, 0, tracking->get_left_block(), 0); top_block->connect(tracking->get_right_block(), 0, sink, 0); top_block->msg_connect(tracking->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks of tracking test." << std::endl; + }) << "Failure connecting the blocks of tracking test."; tracking->start_tracking(); @@ -202,7 +202,7 @@ TEST_F(GpsL2MDllPllTrackingTest, ValidationOfResults) top_block->run(); // Start threads and wait end = std::chrono::system_clock::now(); elapsed_seconds = end - start; - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; // TODO: Verify tracking results std::cout << "Tracked " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/tracking_loop_filter_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/tracking_loop_filter_test.cc index a240ac09d..a1c904b02 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/tracking_loop_filter_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/tracking_loop_filter_test.cc @@ -57,10 +57,10 @@ TEST(TrackingLoopFilterTest, FirstOrderLoop) float result = 0.0; for( unsigned int i = 0; i < sample_data.size(); ++i ) - { - result = theFilter.apply( sample_data[i] ); - EXPECT_FLOAT_EQ( result, sample_data[i]*g1 ); - } + { + result = theFilter.apply( sample_data[i] ); + EXPECT_FLOAT_EQ( result, sample_data[i]*g1 ); + } } @@ -88,10 +88,10 @@ TEST(TrackingLoopFilterTest, FirstOrderLoopWithLastIntegrator) float result = 0.0; for( unsigned int i = 0; i < sample_data.size(); ++i ) - { - result = theFilter.apply( sample_data[i] ); - EXPECT_NEAR( result, expected_out[i], 1e-4 ); - } + { + result = theFilter.apply( sample_data[i] ); + EXPECT_NEAR( result, expected_out[i], 1e-4 ); + } } @@ -120,10 +120,10 @@ TEST(TrackingLoopFilterTest, SecondOrderLoop) float result = 0.0; for( unsigned int i = 0; i < sample_data.size(); ++i ) - { - result = theFilter.apply( sample_data[i] ); - EXPECT_NEAR( result, expected_out[i], 1e-4 ); - } + { + result = theFilter.apply( sample_data[i] ); + EXPECT_NEAR( result, expected_out[i], 1e-4 ); + } } @@ -151,10 +151,10 @@ TEST(TrackingLoopFilterTest, SecondOrderLoopWithLastIntegrator) float result = 0.0; for( unsigned int i = 0; i < sample_data.size(); ++i ) - { - result = theFilter.apply( sample_data[i] ); - EXPECT_NEAR( result, expected_out[i], 1e-4 ); - } + { + result = theFilter.apply( sample_data[i] ); + EXPECT_NEAR( result, expected_out[i], 1e-4 ); + } } @@ -182,10 +182,10 @@ TEST(TrackingLoopFilterTest, ThirdOrderLoop) float result = 0.0; for( unsigned int i = 0; i < sample_data.size(); ++i ) - { - result = theFilter.apply( sample_data[i] ); - EXPECT_NEAR( result, expected_out[i], 1e-4 ); - } + { + result = theFilter.apply( sample_data[i] ); + EXPECT_NEAR( result, expected_out[i], 1e-4 ); + } } @@ -213,10 +213,10 @@ TEST(TrackingLoopFilterTest, ThirdOrderLoopWithLastIntegrator) float result = 0.0; for( unsigned int i = 0; i < sample_data.size(); ++i ) - { - result = theFilter.apply( sample_data[i] ); - EXPECT_NEAR( result, expected_out[i], 1e-4 ); - } + { + result = theFilter.apply( sample_data[i] ); + EXPECT_NEAR( result, expected_out[i], 1e-4 ); + } } From 23fa911dd5f35a094ce1c4609da78defe3bcfae7 Mon Sep 17 00:00:00 2001 From: lmne Date: Sun, 29 Oct 2017 02:51:22 -0300 Subject: [PATCH 70/81] Add support to fmcomms2 SDR hardware --- README.md | 48 +++++ conf/gnss-sdr_GPS_L1_fmcomms2_realtime.conf | 145 ++++++++++++++ conf/gnss-sdr_GPS_L1_plutosdr_realtime.conf | 89 +++++++++ .../signal_source/adapters/CMakeLists.txt | 28 +++ .../adapters/fmcomms2_signal_source.cc | 178 ++++++++++++++++++ .../adapters/fmcomms2_signal_source.h | 115 +++++++++++ .../adapters/plutosdr_signal_source.cc | 138 ++++++++++++++ .../adapters/plutosdr_signal_source.h | 81 ++++++++ src/core/receiver/CMakeLists.txt | 10 + src/core/receiver/gnss_block_factory.cc | 26 +++ 10 files changed, 858 insertions(+) create mode 100644 conf/gnss-sdr_GPS_L1_fmcomms2_realtime.conf create mode 100644 conf/gnss-sdr_GPS_L1_plutosdr_realtime.conf create mode 100644 src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc create mode 100644 src/algorithms/signal_source/adapters/fmcomms2_signal_source.h create mode 100644 src/algorithms/signal_source/adapters/plutosdr_signal_source.cc create mode 100644 src/algorithms/signal_source/adapters/plutosdr_signal_source.h diff --git a/README.md b/README.md index 9a14d8343..f15352cb1 100644 --- a/README.md +++ b/README.md @@ -368,7 +368,55 @@ $ sudo make install (in order to disable the `Osmosdr_Signal_Source` compilation, you can pass `DENABLE_OSMOSDR=OFF` to cmake and build GNSS-SDR again). +###### Build FMCOMMS2 based SDR Hardware support (OPTIONAL): +Install [libiio] (https://github.com/analogdevicesinc/libiio.git +), [libad9361] (clone https://github.com/analogdevicesinc/libad9361-iio.git) and [gr-iio] (clone https://github.com/analogdevicesinc/gr-iio.git) gnuradio block (based on https://www.plutosdr.com/viewtopic.php?t=5): + +~~~~~~ +$ git clone https://github.com/analogdevicesinc/libiio.git +$ cd libiio +$ mkdir build +$ cd build +$ cmake .. +$ make +$ sudo make install +$ sudo ldconfig +$ git clone https://github.com/analogdevicesinc/libad9361-iio.git +$ cd libad9361-iio +$ mkdir build +$ cd build +$ cmake .. +$ make +$ sudo make install +$ sudo ldconfig +$ git clone https://github.com/analogdevicesinc/gr-iio.git +$ cd gr-iio +$ mv include/gnuradio/iio include/iio +$ rm -r include/gnuradio +$ sed -i 's/gnuradio\/iio/iio/g' CMakeLists.txt +$ sed -i 's/gnuradio\/iio/iio/g' swig/* +$ sed -i 's/gnuradio\/iio/iio/g' include/iio/* +$ sed -i 's/gnuradio\/iio/iio/g' lib/* +$ sed -i 's/gnuradio\/iio/iio/g' python/iio/* +$ sed -i 's/from\ gnuradio\ import\ iio/import\ iio/g' grc/iio_pluto_sink.xml +$ sed -i 's/from\ gnuradio\ import\ iio/import\ iio/g' grc/iio_pluto_source.xml +$ sed -i 's/from\ gnuradio\ import\ iio/import\ iio/g' grc/iio_fmcomms2_sink.xml +$ sed -i 's/from\ gnuradio\ import\ iio/import\ iio/g' grc/iio_fmcomms2_source.xml +$ mkdir build +$ cd build +$ cmake .. +$ make +$ sudo make install +$ sudo ldconfig +~~~~~~ + +Then configure the gnss-sdr to build the `Fmcomms2_Signal_Source`: +~~~~~~ +$ cmake -DENABLE_FMCOMMS2=ON ../ +$ make +$ sudo make install +~~~~~~ ###### Build OpenCL support (OPTIONAL): diff --git a/conf/gnss-sdr_GPS_L1_fmcomms2_realtime.conf b/conf/gnss-sdr_GPS_L1_fmcomms2_realtime.conf new file mode 100644 index 000000000..aecfad5cd --- /dev/null +++ b/conf/gnss-sdr_GPS_L1_fmcomms2_realtime.conf @@ -0,0 +1,145 @@ +; You can define your own receiver and invoke it by doing +; gnss-sdr --config_file=my_GNSS_SDR_configuration.conf +; + +[GNSS-SDR] + +;######### GLOBAL OPTIONS ################## +;internal_fs_hz: Internal signal sampling frequency after the signal conditioning stage [Hz]. +;FOR USE GNSS-SDR WITH RTLSDR DONGLES USER MUST SET THE CALIBRATED SAMPLE RATE HERE +; i.e. using front-end-cal as reported here:http://www.cttc.es/publication/turning-a-television-into-a-gnss-receiver/ +GNSS-SDR.internal_fs_hz=2000000 + + +;######### SUPL RRLP GPS assistance configuration ##### +; Check http://www.mcc-mnc.com/ +; On Android: https://play.google.com/store/apps/details?id=net.its_here.cellidinfo&hl=en +GNSS-SDR.SUPL_gps_enabled=false +GNSS-SDR.SUPL_read_gps_assistance_xml=false +GNSS-SDR.SUPL_gps_ephemeris_server=supl.google.com +GNSS-SDR.SUPL_gps_ephemeris_port=7275 +GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com +GNSS-SDR.SUPL_gps_acquisition_port=7275 +GNSS-SDR.SUPL_MCC=244 +GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_LAC=0x59e2 +GNSS-SDR.SUPL_CI=0x31b0 + +;######### SIGNAL_SOURCE CONFIG ############ +SignalSource.implementation=Fmcomms2_Signal_Source +;SignalSource.filename=/media/DATALOGGER_/signals/RTL-SDR/geo/pmt4.dat +SignalSource.item_type=gr_complex +SignalSource.device_address=10.42.0.196 +SignalSource.sampling_frequency=2000000 +SignalSource.freq=1575420000 +SignalSource.bandwidth=2000000 +SignalSource.decimation=0 +SignalSource.rx1_enable=true +SignalSource.gain_mode_rx1=manual +SignalSource.rf_port_select=A_BALANCED +SignalSource.gain_rx1=64 +SignalSource.samples=0 +SignalSource.repeat=false +SignalSource.dump=false +SignalSource.dump_filename=../data/signal_source.dat +SignalSource.enable_throttle_control=false + +;######### SIGNAL_CONDITIONER CONFIG ############ +SignalConditioner.implementation=Signal_Conditioner + +;######### DATA_TYPE_ADAPTER CONFIG ############ +DataTypeAdapter.implementation=Pass_Through + +;######### INPUT_FILTER CONFIG ############ +InputFilter.implementation=Freq_Xlating_Fir_Filter +InputFilter.dump=false +InputFilter.dump_filename=../data/input_filter.dat +InputFilter.input_item_type=gr_complex +InputFilter.output_item_type=gr_complex +InputFilter.taps_item_type=float +InputFilter.number_of_taps=5 +InputFilter.number_of_bands=2 +InputFilter.band1_begin=0.0 +InputFilter.band1_end=0.45 +InputFilter.band2_begin=0.55 +InputFilter.band2_end=1.0 +InputFilter.ampl1_begin=1.0 +InputFilter.ampl1_end=1.0 +InputFilter.ampl2_begin=0.0 +InputFilter.ampl2_end=0.0 +InputFilter.band1_error=1.0 +InputFilter.band2_error=1.0 +InputFilter.filter_type=bandpass +InputFilter.grid_density=16 +InputFilter.sampling_frequency=2000000 +InputFilter.IF=0; IF deviation due to front-end LO inaccuracies [Hz] + +;######### RESAMPLER CONFIG ############ +;## Resamples the input data. +;# DISABLED IN THE RTL-SDR REALTIME +;#implementation: Use [Pass_Through] or [Direct_Resampler] +;#[Pass_Through] disables this block +Resampler.implementation=Pass_Through + +;######### CHANNELS GLOBAL CONFIG ############ +Channels_1C.count=5 +Channels.in_acquisition=1 +Channel.signal=1C + + +;######### ACQUISITION GLOBAL CONFIG ############ +Acquisition_1C.dump=false +Acquisition_1C.dump_filename=./acq_dump.dat +Acquisition_1C.item_type=gr_complex +Acquisition_1C.if=0 +Acquisition_1C.sampled_ms=1 +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition_Fine_Doppler +Acquisition_1C.threshold=0.015 +;Acquisition_1C.pfa=0.0001 +Acquisition_1C.doppler_max=10000 +Acquisition_1C.doppler_min=-10000 +Acquisition_1C.doppler_step=500 +Acquisition_1C.max_dwells=15 + + +;######### TRACKING GLOBAL CONFIG ############ +Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking +Tracking_1C.item_type=gr_complex +Tracking_1C.if=0 +Tracking_1C.dump=false +Tracking_1C.dump_filename=./tracking_ch_ +Tracking_1C.pll_bw_hz=40.0; +Tracking_1C.dll_bw_hz=2.0; +Tracking_1C.order=3; +Tracking_1C.early_late_space_chips=0.5; + +;######### TELEMETRY DECODER GPS CONFIG ############ +TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder +TelemetryDecoder_1C.dump=false +TelemetryDecoder_1C.decimation_factor=1; + +;######### OBSERVABLES CONFIG ############ +Observables.implementation=GPS_L1_CA_Observables +Observables.dump=false +Observables.dump_filename=./observables.dat + + +;######### PVT CONFIG ############ +;#implementation: Position Velocity and Time (PVT) implementation algorithm: Use [GPS_L1_CA_PVT] in this version. +PVT.implementation=GPS_L1_CA_PVT + +;#averaging_depth: Number of PVT observations in the moving average algorithm +PVT.averaging_depth=10 + +;#flag_average: Enables the PVT averaging between output intervals (arithmetic mean) [true] or [false] +PVT.flag_averaging=true +PVT.output_rate_ms=100 +PVT.display_rate_ms=500 +PVT.dump_filename=./PVT +PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea; +PVT.flag_nmea_tty_port=false; +PVT.nmea_dump_devname=/dev/pts/4 +PVT.dump=false +PVT.flag_rtcm_server=false +PVT.flag_rtcm_tty_port=false +PVT.rtcm_dump_devname=/dev/pts/1 diff --git a/conf/gnss-sdr_GPS_L1_plutosdr_realtime.conf b/conf/gnss-sdr_GPS_L1_plutosdr_realtime.conf new file mode 100644 index 000000000..5c6f4fdd6 --- /dev/null +++ b/conf/gnss-sdr_GPS_L1_plutosdr_realtime.conf @@ -0,0 +1,89 @@ +; You can define your own receiver and invoke it by doing +; gnss-sdr --config_file=my_GNSS_SDR_configuration.conf +; + +[GNSS-SDR] + +;######### GLOBAL OPTIONS ################## +;internal_fs_hz: Internal signal sampling frequency after the signal conditioning stage [Hz]. +;FOR USE GNSS-SDR WITH RTLSDR DONGLES USER MUST SET THE CALIBRATED SAMPLE RATE HERE +; i.e. using front-end-cal as reported here:http://www.cttc.es/publication/turning-a-television-into-a-gnss-receiver/ +GNSS-SDR.internal_fs_hz=2000000 + + +;######### SUPL RRLP GPS assistance configuration ##### +; Check http://www.mcc-mnc.com/ +; On Android: https://play.google.com/store/apps/details?id=net.its_here.cellidinfo&hl=en +GNSS-SDR.SUPL_gps_enabled=false +GNSS-SDR.SUPL_read_gps_assistance_xml=false +GNSS-SDR.SUPL_gps_ephemeris_server=supl.google.com +GNSS-SDR.SUPL_gps_ephemeris_port=7275 +GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com +GNSS-SDR.SUPL_gps_acquisition_port=7275 +GNSS-SDR.SUPL_MCC=244 +GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_LAC=0x59e2 +GNSS-SDR.SUPL_CI=0x31b0 + +;######### SIGNAL_SOURCE CONFIG ############ +SignalSource.implementation=Plutosdr_Signal_Source +;SignalSource.filename=/media/DATALOGGER_/signals/RTL-SDR/geo/pmt4.dat +SignalSource.item_type=gr_complex +SignalSource.device_address=192.168.2.1 +SignalSource.sampling_frequency=3000000 +SignalSource.freq=1575420000 +SignalSource.bandwidth=2600000 +SignalSource.decimation=0 +SignalSource.gain_mode=manual +SignalSource.gain=30 +SignalSource.samples=0 +SignalSource.buffer_size=65000 +SignalSource.repeat=false +SignalSource.dump=false +SignalSource.dump_filename=./capture.dat +SignalSource.enable_throttle_control=false + +;######### SIGNAL_CONDITIONER CONFIG ############ +SignalConditioner.implementation=Signal_Conditioner +InputFilter.implementation=Pass_Through +InputFilter.item_type=gr_complex +Resampler.implementation=Direct_Resampler +Resampler.sample_freq_in=4000000 +Resampler.sample_freq_out=2000000 +Resampler.item_type=gr_complex + + +;######### DATA_TYPE_ADAPTER CONFIG ############ +DataTypeAdapter.implementation=Pass_Through +DataTypeAdapter.item_type=gr_complex + +;######### CHANNELS GLOBAL CONFIG ############ +Channels_1C.count=6 +Channels.in_acquisition=1 +Channel.signal=1C + +;######### ACQUISITION GLOBAL CONFIG ############ +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition +Acquisition_1C.item_type=gr_complex +Acquisition_1C.threshold=0.008 +Acquisition_1C.doppler_max=10000 +Acquisition_1C.doppler_step=250 + +;######### TRACKING GLOBAL CONFIG ############ +Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking +Tracking_1C.item_type=gr_complex +Tracking_1C.pll_bw_hz=40.0; +Tracking_1C.dll_bw_hz=4.0; + +;######### TELEMETRY DECODER GPS CONFIG ############ +TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder + +;######### OBSERVABLES CONFIG ############ +Observables.implementation=GPS_L1_CA_Observables + +;######### PVT CONFIG ############ +PVT.implementation=GPS_L1_CA_PVT +PVT.averaging_depth=100 +PVT.flag_averaging=true +PVT.output_rate_ms=10 +PVT.display_rate_ms=500 diff --git a/src/algorithms/signal_source/adapters/CMakeLists.txt b/src/algorithms/signal_source/adapters/CMakeLists.txt index 388b2ed59..2cc169ed9 100644 --- a/src/algorithms/signal_source/adapters/CMakeLists.txt +++ b/src/algorithms/signal_source/adapters/CMakeLists.txt @@ -21,6 +21,34 @@ list(SORT SIGNAL_SOURCE_ADAPTER_HEADERS) # Optional drivers +if(ENABLE_PLUTOSDR) + ############################################## + # ADALM-PLUTO (Analog Devices Inc.) + ############################################## + find_package(iio REQUIRED) + if(NOT IIO_FOUND) + message("gnuradio-iio not found, installation is required") + message(FATAL_ERROR "gnuradio-iio required for building gnss-sdr with this option enabled") + endif(NOT IIO_FOUND) + set(OPT_LIBRARIES ${OPT_LIBRARIES} ${IIO_LIBRARIES}) + set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${IIO_INCLUDE_DIRS}) + set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} plutosdr_signal_source.cc) +endif(ENABLE_PLUTOSDR) + +if(ENABLE_FMCOMMS2) + ############################################### + # FMCOMMS2 based SDR Hardware + ############################################### + find_package(iio REQUIRED) + if(NOT IIO_FOUND) + message("gnuradio-iio not found, installation is required") + message(FATAL_ERROR "gnuradio-iio required for building gnss-sdr with this option enabled") + endif(NOT IIO_FOUND) + set(OPT_LIBRARIES ${OPT_LIBRARIES} ${IIO_LIBRARIES}) + set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${IIO_INCLUDE_DIRS}) + set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} fmcomms2_signal_source.cc plutosdr_signal_source.cc) +endif(ENABLE_FMCOMMS2) + if(ENABLE_GN3S) ############################################## # GN3S (USB dongle) diff --git a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc new file mode 100644 index 000000000..a77215327 --- /dev/null +++ b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc @@ -0,0 +1,178 @@ +/*! + * \filei fmcomms2_signal_source.cc + * \brief signal source for sdr hardware from analog devices based on + * fmcomms2 evaluation board. + * \author Rodrigo Muñoz, 2017, rmunozl(at)inacap.cl + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include "fmcomms2_signal_source.h" +#include +#include +#include +#include +#include +#include "configuration_interface.h" +#include "gnss_sdr_valve.h" +#include "GPS_L1_CA.h" + +using google::LogMessage; + +Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration, + std::string role, unsigned int in_stream, unsigned int out_stream, + boost::shared_ptr queue) : + role_(role), in_stream_(in_stream), out_stream_(out_stream), + queue_(queue) +{ + std::string default_item_type="gr_complex"; + std::string default_dump_file="./data/signal_source.dat"; + uri_= configuration->property(role+".device_address",std::string("192.168.2.1")); + freq_= configuration->property(role+".freq",GPS_L1_FREQ_HZ); + sample_rate_=configuration->property(role+".sampling_frequency",2600000); + bandwidth_= configuration->property(role+".bandwidth",2000000); + rx1_en_=configuration->property(role+".rx1_enable",true); + rx2_en_=configuration->property(role+".rx2_enable",false); + buffer_size_=configuration->property(role+".buffer_size",0xA0000); + decimation_=configuration->property(role+".decimation",1); + quadrature_=configuration->property(role+".quadrature",true); + rf_dc_=configuration->property(role+".rf_dc",true); + bb_dc_=configuration->property(role+".bb_dc",true); + gain_mode_rx1_=configuration->property(role+".gain_mode_rx1",std::string("manual")); + gain_mode_rx2_=configuration->property(role+".gain_mode_rx2",std::string("manual")); + rf_gain_rx1_=configuration->property(role+".gain_rx1",64.0); + rf_gain_rx2_=configuration->property(role+".gain_rx2",64.0); + rf_port_select_=configuration->property(role+".rf_port_select",std::string("A_BALANCED")); + filter_file_=configuration->property(role+".filter_file",std::string("")); + filter_auto_=configuration->property(role+".filter_auto",true); + item_type_=configuration->property(role+".item_type",default_item_type); + samples_=configuration->property(role+".samples",0); + dump_=configuration->property(role+".dump",false); + dump_filename_=configuration->property(role+".dump_filename",default_dump_file); + + item_size_=sizeof(gr_complex); + + std::cout<<"device address: "<unique_id() << ")"; + } + + if (dump_) + { + DLOG(INFO) << "Dumping output into file " << dump_filename_; + file_sink_ = gr::blocks::file_sink::make(item_size_, dump_filename_.c_str()); + DLOG(INFO) << "file_sink(" << file_sink_->unique_id() << ")"; + } +} + +Fmcomms2SignalSource::~Fmcomms2SignalSource() +{ +} + +void Fmcomms2SignalSource::connect(gr::top_block_sptr top_block) +{ + if (samples_ != 0) + { + top_block->connect(fmcomms2_source_f32c_, 0, valve_, 0); + DLOG(INFO) << "connected fmcomms2 source to valve"; + if (dump_) + { + top_block->connect(valve_, 0, file_sink_, 0); + DLOG(INFO) << "connected valve to file sink"; + } + } + else + { + if (dump_) + { + + top_block->connect(fmcomms2_source_f32c_ , 0, file_sink_, 0); + DLOG(INFO) << "connected fmcomms2 source to file sink"; + } + } +} + + +void Fmcomms2SignalSource::disconnect(gr::top_block_sptr top_block) +{ + if (samples_ != 0) + { + top_block->disconnect(fmcomms2_source_f32c_, 0, valve_, 0); + if (dump_) + { + top_block->disconnect(valve_, 0, file_sink_, 0); + } + } + else + { + if (dump_) + { + top_block->disconnect(fmcomms2_source_f32c_, 0, file_sink_, 0); + } + } +} + + +gr::basic_block_sptr Fmcomms2SignalSource::get_left_block() +{ + LOG(WARNING) << "Trying to get signal source left block."; + return gr::basic_block_sptr(); +} + + +gr::basic_block_sptr Fmcomms2SignalSource::get_right_block() +{ + if (samples_ != 0) + { + return valve_; + } + else + { + return (fmcomms2_source_f32c_); + } +} diff --git a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.h b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.h new file mode 100644 index 000000000..c9b690cdd --- /dev/null +++ b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.h @@ -0,0 +1,115 @@ +/*! + * \file fmcomms2_signal_source.h + * \brief Interface to use SDR hardware based in FMCOMMS2 driver from analog + * devices, for example FMCOMMS4 and ADALM-PLUTO (PlutoSdr) + * \author Rodrigo Muñoz, 2017. rmunozl(at)inacap.cl + * + * This class represent a fmcomms2 signal source. It use the gr_iio block + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_FMCOMMS2_SIGNAL_SOURCE_H_ +#define GNSS_SDR_FMCOMMS2_SIGNAL_SOURCE_H_ + +#include +#include +#include +#include +#include +#include "gnss_block_interface.h" + +class ConfigurationInterface; + +class Fmcomms2SignalSource: public GNSSBlockInterface +{ +public: + Fmcomms2SignalSource(ConfigurationInterface* configuration, + std::string role, unsigned int in_stream, + unsigned int out_stream, boost::shared_ptr queue); + + virtual ~Fmcomms2SignalSource(); + + std::string role() + { + return role_; + } + + /*! + * \brief Returns "fmcomms2_Signal_Source" + */ + std::string implementation() + { + return "Fmcomms2_Signal_Source"; + } + size_t item_size() + { + return item_size_; + } + + void connect(gr::top_block_sptr top_block); + void disconnect(gr::top_block_sptr top_block); + gr::basic_block_sptr get_left_block(); + gr::basic_block_sptr get_right_block(); + +private: + std::string role_; + + // Front-end settings + std::string uri_;//device direction + unsigned long freq_; //frequency of local oscilator + unsigned long sample_rate_; + unsigned long bandwidth_; + unsigned long buffer_size_; //reception buffer + unsigned int decimation_; + bool rx1_en_; + bool rx2_en_; + bool quadrature_; + bool rf_dc_; + bool bb_dc_; + std::string gain_mode_rx1_; + std::string gain_mode_rx2_; + double rf_gain_rx1_; + double rf_gain_rx2_; + std::string rf_port_select_; + std::string filter_file_; + bool filter_auto_; + + unsigned int in_stream_; + unsigned int out_stream_; + + std::string item_type_; + size_t item_size_; + long samples_; + bool dump_; + std::string dump_filename_; + + gr::iio::fmcomms2_source_f32c::sptr fmcomms2_source_f32c_; + + boost::shared_ptr valve_; + gr::blocks::file_sink::sptr file_sink_; + boost::shared_ptr queue_; +}; + +#endif /*GNSS_SDR_FMCOMMS2_SIGNAL_SOURCE_H_*/ diff --git a/src/algorithms/signal_source/adapters/plutosdr_signal_source.cc b/src/algorithms/signal_source/adapters/plutosdr_signal_source.cc new file mode 100644 index 000000000..45e0f3deb --- /dev/null +++ b/src/algorithms/signal_source/adapters/plutosdr_signal_source.cc @@ -0,0 +1,138 @@ +#include "plutosdr_signal_source.h" +#include +#include +#include +#include +#include "configuration_interface.h" +#include "gnss_sdr_valve.h" +#include "GPS_L1_CA.h" + + +using google::LogMessage; + + +PlutosdrSignalSource::PlutosdrSignalSource(ConfigurationInterface* configuration, + std::string role, unsigned int in_stream, unsigned int out_stream, + boost::shared_ptr queue) : + role_(role), in_stream_(in_stream), out_stream_(out_stream), + queue_(queue) +{ + std::string default_item_type="gr_complex"; + std::string default_dump_file="./data/signal_source.dat"; + uri_ = configuration->property(role+".device_address",std::string("192.168.2.1")); + freq_= configuration->property(role+".freq",GPS_L1_FREQ_HZ); + sample_rate_=configuration->property(role+".sampling_frequency",3000000); + bandwidth_ = configuration->property(role+".bandwidth",2000000); + buffer_size_=configuration->property(role+".buffer_size",0xA0000); + decimation_=configuration->property(role+".decimation",1); + quadrature_=configuration->property(role+".quadrature",true); + rf_dc_ =configuration->property(role+".rf_dc",true); + bb_dc_ =configuration->property(role+".bb_dc",true); + gain_mode_=configuration->property(role+".gain_mode",std::string("manual")); + rf_gain_=configuration->property(role+".gain",50.0); + filter_file_=configuration->property(role+".filter_file",std::string("")); + filter_auto_=configuration->property(role+".filter_auto",true); + + item_type_=configuration->property(role+".item_type",default_item_type); + samples_=configuration->property(role+".samples",0); + dump_=configuration->property(role+".dump",false); + dump_filename_=configuration->property(role+".dump_filename",default_dump_file); + + if(item_type_.compare("gr_complex") != 0) + { + std::cout<<"bad item_type!!"<unique_id() << ")"; + } + + if (dump_) + { + DLOG(INFO) << "Dumping output into file " << dump_filename_; + file_sink_ = gr::blocks::file_sink::make(item_size_, dump_filename_.c_str()); + DLOG(INFO) << "file_sink(" << file_sink_->unique_id() << ")"; + } +} + +PlutosdrSignalSource::~PlutosdrSignalSource() +{} + +void PlutosdrSignalSource::connect(gr::top_block_sptr top_block) +{ + if (samples_ != 0) + { + top_block->connect(plutosdr_source_, 0, valve_, 0); + DLOG(INFO) << "connected plutosdr source to valve"; + if (dump_) + { + top_block->connect(valve_, 0, file_sink_, 0); + DLOG(INFO) << "connected valve to file sink"; + } + } + else + { + if (dump_) + { + top_block->connect(plutosdr_source_, 0, file_sink_, 0); + DLOG(INFO) << "connected plutosdr source to file sink"; + } + } +} + + +void PlutosdrSignalSource::disconnect(gr::top_block_sptr top_block) +{ + if (samples_ != 0) + { + top_block->disconnect(plutosdr_source_, 0, valve_, 0); + if (dump_) + { + top_block->disconnect(valve_, 0, file_sink_, 0); + } + } + else + { + if (dump_) + { + top_block->disconnect(plutosdr_source_, 0, file_sink_, 0); + } + } +} + + +gr::basic_block_sptr PlutosdrSignalSource::get_left_block() +{ + LOG(WARNING) << "Trying to get signal source left block."; + return gr::basic_block_sptr(); +} + + +gr::basic_block_sptr PlutosdrSignalSource::get_right_block() +{ + if (samples_ != 0) + { + return valve_; + } + else + { + return plutosdr_source_; + } +} diff --git a/src/algorithms/signal_source/adapters/plutosdr_signal_source.h b/src/algorithms/signal_source/adapters/plutosdr_signal_source.h new file mode 100644 index 000000000..eadee361d --- /dev/null +++ b/src/algorithms/signal_source/adapters/plutosdr_signal_source.h @@ -0,0 +1,81 @@ + +#ifndef GNSS_SDR_PLUTOSDR_SIGNAL_SOURCE_H_ +#define GNSS_SDR_PLUTOSDR_SIGNAL_SOURCE_H_ + +#include +#include +#include +#include +#include +#include "gnss_block_interface.h" + +class ConfigurationInterface; + +/*! + */ +class PlutosdrSignalSource: public GNSSBlockInterface +{ +public: + PlutosdrSignalSource(ConfigurationInterface* configuration, + std::string role, unsigned int in_stream, + unsigned int out_stream, boost::shared_ptr queue); + + virtual ~PlutosdrSignalSource(); + + std::string role() + { + return role_; + } + + /*! + * \brief Returns "Plutosdr_Signal_Source" + */ + std::string implementation() + { + return "Plutosdr_Signal_Source"; + } + size_t item_size() + { + return item_size_; + } + + void connect(gr::top_block_sptr top_block); + void disconnect(gr::top_block_sptr top_block); + gr::basic_block_sptr get_left_block(); + gr::basic_block_sptr get_right_block(); + +private: + std::string role_; + + // Front-end settings + std::string uri_;//device direction + unsigned long freq_; //frequency of local oscilator + unsigned long sample_rate_; + unsigned long bandwidth_; + unsigned long buffer_size_; //reception buffer + unsigned int decimation_; + bool quadrature_; + bool rf_dc_; + bool bb_dc_; + std::string gain_mode_; + double rf_gain_; + std::string filter_file_; + bool filter_auto_; + + unsigned int in_stream_; + unsigned int out_stream_; + + std::string item_type_; + size_t item_size_; + long samples_; + bool dump_; + std::string dump_filename_; + + gr::iio::pluto_source::sptr plutosdr_source_; + + boost::shared_ptr valve_; + gr::blocks::file_sink::sptr file_sink_; + boost::shared_ptr queue_; +}; + +#endif /*GNSS_SDR_PLUTOSDR_SIGNAL_SOURCE_H_*/ diff --git a/src/core/receiver/CMakeLists.txt b/src/core/receiver/CMakeLists.txt index 7c3992785..ae6908495 100644 --- a/src/core/receiver/CMakeLists.txt +++ b/src/core/receiver/CMakeLists.txt @@ -124,6 +124,16 @@ else(OPENCL_FOUND) add_definitions(-DOPENCL_BLOCKS=0) endif(OPENCL_FOUND) +#enable SDR Hardware based on fmcomms2 +if(ENABLE_PLUTOSDR) + add_definitions(-DPLUTOSDR_DRIVER=1) +endif(ENABLE_PLUTOSDR) + +if(ENABLE_FMCOMMS2) + add_definitions(-DFMCOMMS2_DRIVER=1) + add_definitions(-DPLUTOSDR_DRIVER=1) +endif(ENABLE_FMCOMMS2) + add_definitions(-DGNSSSDR_INSTALL_DIR="${CMAKE_INSTALL_PREFIX}") file(GLOB GNSS_RECEIVER_HEADERS "*.h") diff --git a/src/core/receiver/gnss_block_factory.cc b/src/core/receiver/gnss_block_factory.cc index 4daad0c79..6ec273785 100644 --- a/src/core/receiver/gnss_block_factory.cc +++ b/src/core/receiver/gnss_block_factory.cc @@ -119,6 +119,14 @@ #include "uhd_signal_source.h" #endif +#if PLUTOSDR_DRIVER +#include "plutosdr_signal_source.h" +#endif + +#if FMCOMMS2_DRIVER +#include "fmcomms2_signal_source.h" +#endif + #if FLEXIBAND_DRIVER #include "flexiband_signal_source.h" #endif @@ -811,6 +819,24 @@ std::unique_ptr GNSSBlockFactory::GetBlock( } #endif +#if PLUTOSDR_DRIVER + else if (implementation.compare("Plutosdr_Signal_Source") == 0) + { + std::unique_ptr block_(new PlutosdrSignalSource(configuration.get(), role, in_streams, + out_streams, queue)); + block = std::move(block_); + } +#endif + +#if FMCOMMS2_DRIVER + else if (implementation.compare("Fmcomms2_Signal_Source") == 0) + { + std::unique_ptr block_(new Fmcomms2SignalSource(configuration.get(), role, in_streams, + out_streams, queue)); + block = std::move(block_); + } +#endif + #if FLEXIBAND_DRIVER else if (implementation.compare("Flexiband_Signal_Source") == 0) { From de7bdac26f31b2f0ec102f6ee51317413921637a Mon Sep 17 00:00:00 2001 From: lmne Date: Sun, 29 Oct 2017 03:01:12 -0300 Subject: [PATCH 71/81] Fixed links in README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index f15352cb1..a3d81f8af 100644 --- a/README.md +++ b/README.md @@ -370,8 +370,7 @@ $ sudo make install ###### Build FMCOMMS2 based SDR Hardware support (OPTIONAL): -Install [libiio] (https://github.com/analogdevicesinc/libiio.git -), [libad9361] (clone https://github.com/analogdevicesinc/libad9361-iio.git) and [gr-iio] (clone https://github.com/analogdevicesinc/gr-iio.git) gnuradio block (based on https://www.plutosdr.com/viewtopic.php?t=5): +Install [libiio](https://github.com/analogdevicesinc/libiio.git), [libad9361](https://github.com/analogdevicesinc/libad9361-iio.git) and [gr-iio](https://github.com/analogdevicesinc/gr-iio.git) gnuradio block (instructions based on https://www.plutosdr.com/viewtopic.php?t=5): ~~~~~~ $ git clone https://github.com/analogdevicesinc/libiio.git From ee1285218eca9302213c3b5d34d7461a42bc96e9 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sun, 29 Oct 2017 12:26:06 +0100 Subject: [PATCH 72/81] Add GPS L2 acqusitition grid plot and other small fixes --- ...ileo_e1_pcps_ambiguous_acquisition_test.cc | 35 +++--- .../gps_l1_ca_pcps_acquisition_test.cc | 34 +++--- .../gps_l2_m_pcps_acquisition_test.cc | 115 +++++++++++++++--- .../libs/acquisition_dump_reader.cc | 11 +- .../libs/acquisition_dump_reader.h | 4 +- .../observables/hybrid_observables_test.cc | 29 ++--- .../gps_l1_ca_telemetry_decoder_test.cc | 17 ++- 7 files changed, 165 insertions(+), 80 deletions(-) diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test.cc index 5dd8dc11e..0f8c36cdf 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test.cc @@ -118,6 +118,8 @@ protected: config = std::make_shared(); item_size = sizeof(gr_complex); gnss_synchro = Gnss_Synchro(); + doppler_max = 10000; + doppler_step = 250; } ~GalileoE1PcpsAmbiguousAcquisitionTest() @@ -131,6 +133,8 @@ protected: std::shared_ptr config; Gnss_Synchro gnss_synchro; size_t item_size; + unsigned int doppler_max; + unsigned int doppler_step; }; @@ -142,9 +146,9 @@ void GalileoE1PcpsAmbiguousAcquisitionTest::init() signal.copy(gnss_synchro.Signal, 2, 0); gnss_synchro.PRN = 1; + config->set_property("Acquisition_1B.implementation", "Galileo_E1_PCPS_Ambiguous_Acquisition"); config->set_property("GNSS-SDR.internal_fs_sps", "4000000"); config->set_property("Acquisition_1B.item_type", "gr_complex"); - config->set_property("Acquisition_1B.if", "0"); config->set_property("Acquisition_1B.coherent_integration_time_ms", "4"); if(FLAGS_plot_acq_grid == true) { @@ -154,10 +158,10 @@ void GalileoE1PcpsAmbiguousAcquisitionTest::init() { config->set_property("Acquisition_1B.dump", "false"); } - config->set_property("Acquisition_1B.implementation", "Galileo_E1_PCPS_Ambiguous_Acquisition"); + config->set_property("Acquisition_1B.dump_filename", "./tmp-acq-gal1/acquisition.dat"); config->set_property("Acquisition_1B.threshold", "0.0001"); - config->set_property("Acquisition_1B.doppler_max", "10000"); - config->set_property("Acquisition_1B.doppler_step", "250"); + config->set_property("Acquisition_1B.doppler_max", std::to_string(doppler_max)); + config->set_property("Acquisition_1B.doppler_step", std::to_string(doppler_step)); config->set_property("Acquisition_1B.repeat_satellite", "false"); config->set_property("Acquisition_1B.cboc", "true"); } @@ -166,18 +170,17 @@ void GalileoE1PcpsAmbiguousAcquisitionTest::init() void GalileoE1PcpsAmbiguousAcquisitionTest::plot_grid() { //load the measured values - std::string basename = "./data/acquisition_E_1B"; + std::string basename = "./tmp-acq-gal1/acquisition_E_1B"; unsigned int sat = static_cast(gnss_synchro.PRN); - unsigned int doppler_max = 10000; // !!! - unsigned int doppler_step = 250; // !! + unsigned int samples_per_code = static_cast(round(4000000 / (Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS))); // !! acquisition_dump_reader acq_dump(basename, sat, doppler_max, doppler_step, samples_per_code); if(!acq_dump.read_binary_acq()) std::cout << "Error reading files" << std::endl; - std::vector doppler = acq_dump.doppler; - std::vector samples = acq_dump.samples; - std::vector > mag = acq_dump.mag; + std::vector * doppler = &acq_dump.doppler; + std::vector * samples = &acq_dump.samples; + std::vector > * mag = &acq_dump.mag; const std::string gnuplot_executable(FLAGS_gnuplot_executable); if(gnuplot_executable.empty()) @@ -188,7 +191,7 @@ void GalileoE1PcpsAmbiguousAcquisitionTest::plot_grid() } else { - std::cout << "Plotting the acquisition grid..." << std::endl; + std::cout << "Plotting the acquisition grid. This can take a while..." << std::endl; try { boost::filesystem::path p(gnuplot_executable); @@ -201,7 +204,7 @@ void GalileoE1PcpsAmbiguousAcquisitionTest::plot_grid() g1.set_xlabel("Doppler [Hz]"); g1.set_ylabel("Sample"); //g1.cmd("set view 60, 105, 1, 1"); - g1.plot_grid3d(doppler, samples, mag); + g1.plot_grid3d(*doppler, *samples, *mag); g1.savetops("Galileo_E1_acq_grid"); g1.savetopdf("Galileo_E1_acq_grid"); @@ -212,7 +215,7 @@ void GalileoE1PcpsAmbiguousAcquisitionTest::plot_grid() std::cout << ge.what() << std::endl; } } - std::string data_str = "./data"; + std::string data_str = "./tmp-acq-gal1"; if (boost::filesystem::exists(data_str)) { boost::filesystem::remove_all(data_str); @@ -268,7 +271,7 @@ TEST_F(GalileoE1PcpsAmbiguousAcquisitionTest, ValidationOfResults) if(FLAGS_plot_acq_grid == true) { - std::string data_str = "./data"; + std::string data_str = "./tmp-acq-gal1"; if (boost::filesystem::exists(data_str)) { boost::filesystem::remove_all(data_str); @@ -297,11 +300,11 @@ TEST_F(GalileoE1PcpsAmbiguousAcquisitionTest, ValidationOfResults) }) << "Failure setting threshold."; ASSERT_NO_THROW( { - acquisition->set_doppler_max(config->property("Acquisition_1B.doppler_max", 10000)); + acquisition->set_doppler_max(config->property("Acquisition_1B.doppler_max", doppler_max)); }) << "Failure setting doppler_max."; ASSERT_NO_THROW( { - acquisition->set_doppler_step(config->property("Acquisition_1B.doppler_step", 250)); + acquisition->set_doppler_step(config->property("Acquisition_1B.doppler_step", doppler_step)); }) << "Failure setting doppler_step."; ASSERT_NO_THROW( { diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc index 0ddd45bd3..41a6dad97 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc @@ -118,6 +118,8 @@ protected: config = std::make_shared(); item_size = sizeof(gr_complex); gnss_synchro = Gnss_Synchro(); + doppler_max = 5000; + doppler_step = 100; } ~GpsL1CaPcpsAcquisitionTest() @@ -131,6 +133,8 @@ protected: std::shared_ptr config; Gnss_Synchro gnss_synchro; size_t item_size; + unsigned int doppler_max; + unsigned int doppler_step; }; @@ -153,9 +157,10 @@ void GpsL1CaPcpsAcquisitionTest::init() { config->set_property("Acquisition_1C.dump", "false"); } + config->set_property("Acquisition_1C.dump_filename", "./tmp-acq-gps1/acquisition.dat"); config->set_property("Acquisition_1C.threshold", "0.00001"); - config->set_property("Acquisition_1C.doppler_max", "5000"); - config->set_property("Acquisition_1C.doppler_step", "500"); + config->set_property("Acquisition_1C.doppler_max", std::to_string(doppler_max)); + config->set_property("Acquisition_1C.doppler_step", std::to_string(doppler_step)); config->set_property("Acquisition_1C.repeat_satellite", "false"); //config->set_property("Acquisition_1C.pfa", "0.0"); } @@ -164,18 +169,17 @@ void GpsL1CaPcpsAcquisitionTest::init() void GpsL1CaPcpsAcquisitionTest::plot_grid() { //load the measured values - std::string basename = "./data/acquisition_G_1C"; + std::string basename = "./tmp-acq-gps1/acquisition_G_1C"; unsigned int sat = static_cast(gnss_synchro.PRN); - unsigned int doppler_max = 5000; // !!! - unsigned int doppler_step = 100; // !! - unsigned int samples_per_code = static_cast(round(4000000 / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS))); // !! + + unsigned int samples_per_code = static_cast(round(4000000 / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS))); // !! acquisition_dump_reader acq_dump(basename, sat, doppler_max, doppler_step, samples_per_code); if(!acq_dump.read_binary_acq()) std::cout << "Error reading files" << std::endl; - std::vector doppler = acq_dump.doppler; - std::vector samples = acq_dump.samples; - std::vector > mag = acq_dump.mag; + std::vector *doppler = &acq_dump.doppler; + std::vector *samples = &acq_dump.samples; + std::vector > *mag = &acq_dump.mag; const std::string gnuplot_executable(FLAGS_gnuplot_executable); if(gnuplot_executable.empty()) @@ -186,7 +190,7 @@ void GpsL1CaPcpsAcquisitionTest::plot_grid() } else { - std::cout << "Plotting the acquisition grid..." << std::endl; + std::cout << "Plotting the acquisition grid. This can take a while..." << std::endl; try { boost::filesystem::path p(gnuplot_executable); @@ -199,7 +203,7 @@ void GpsL1CaPcpsAcquisitionTest::plot_grid() g1.set_xlabel("Doppler [Hz]"); g1.set_ylabel("Sample"); //g1.cmd("set view 60, 105, 1, 1"); - g1.plot_grid3d(doppler, samples, mag); + g1.plot_grid3d(*doppler, *samples, *mag); g1.savetops("GPS_L1_acq_grid"); g1.savetopdf("GPS_L1_acq_grid"); @@ -210,7 +214,7 @@ void GpsL1CaPcpsAcquisitionTest::plot_grid() std::cout << ge.what() << std::endl; } } - std::string data_str = "./data"; + std::string data_str = "./tmp-acq-gps1"; if (boost::filesystem::exists(data_str)) { boost::filesystem::remove_all(data_str); @@ -272,7 +276,7 @@ TEST_F(GpsL1CaPcpsAcquisitionTest, ValidationOfResults) if(FLAGS_plot_acq_grid == true) { - std::string data_str = "./data"; + std::string data_str = "./tmp-acq-gps1"; if (boost::filesystem::exists(data_str)) { boost::filesystem::remove_all(data_str); @@ -296,11 +300,11 @@ TEST_F(GpsL1CaPcpsAcquisitionTest, ValidationOfResults) }) << "Failure setting threshold."; ASSERT_NO_THROW( { - acquisition->set_doppler_max(5000); + acquisition->set_doppler_max(doppler_max); }) << "Failure setting doppler_max."; ASSERT_NO_THROW( { - acquisition->set_doppler_step(100); + acquisition->set_doppler_step(doppler_step); }) << "Failure setting doppler_step."; ASSERT_NO_THROW( { diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc index 7b7dcc083..04480d7c8 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc @@ -34,6 +34,7 @@ #include #include +#include #include #include #include @@ -49,6 +50,9 @@ #include "in_memory_configuration.h" #include "gnss_sdr_valve.h" #include "gnss_synchro.h" +#include "gnuplot_i.h" +#include "test_flags.h" +#include "acquisition_dump_reader.h" #include "gps_l2_m_pcps_acquisition.h" #include "GPS_L2C.h" @@ -70,7 +74,6 @@ private: public: int rx_message; ~GpsL2MPcpsAcquisitionTest_msg_rx(); //!< Default destructor - }; GpsL2MPcpsAcquisitionTest_msg_rx_sptr GpsL2MPcpsAcquisitionTest_msg_rx_make() @@ -114,8 +117,10 @@ protected: factory = std::make_shared(); config = std::make_shared(); item_size = sizeof(gr_complex); - sampling_freqeuncy_hz = 0; + sampling_frequency_hz = 5000000; nsamples = 0; + doppler_max = 3000; + doppler_step = 125; gnss_synchro = Gnss_Synchro(); } @@ -123,6 +128,7 @@ protected: {} void init(); + void plot_grid(); gr::msg_queue::sptr queue; gr::top_block_sptr top_block; @@ -130,8 +136,10 @@ protected: std::shared_ptr config; Gnss_Synchro gnss_synchro; size_t item_size; - int sampling_freqeuncy_hz; + int sampling_frequency_hz; int nsamples; + unsigned int doppler_max; + unsigned int doppler_step; }; @@ -140,24 +148,86 @@ void GpsL2MPcpsAcquisitionTest::init() gnss_synchro.Channel_ID = 0; gnss_synchro.System = 'G'; std::string signal = "2S"; - //strncpy(gnss_synchro.Signal, signal.c_str(), 3); std::memcpy(static_cast(gnss_synchro.Signal), signal.c_str(), 3); // copy string into synchro char array: 2 char + null gnss_synchro.Signal[2] = 0; // make sure that string length is only two characters gnss_synchro.PRN = 7; - sampling_freqeuncy_hz = 5000000; - nsamples = round(static_cast(sampling_freqeuncy_hz) * GPS_L2_M_PERIOD) * 2; - config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(sampling_freqeuncy_hz)); + nsamples = round(static_cast(sampling_frequency_hz) * GPS_L2_M_PERIOD) * 2; + config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(sampling_frequency_hz)); config->set_property("Acquisition_2S.implementation", "GPS_L2_M_PCPS_Acquisition"); config->set_property("Acquisition_2S.item_type", "gr_complex"); - config->set_property("Acquisition_2S.dump", "false"); + if(FLAGS_plot_acq_grid == true) + { + config->set_property("Acquisition_2S.dump", "true"); + } + else + { + config->set_property("Acquisition_2S.dump", "false"); + } + config->set_property("Acquisition_2S.dump_filename", "./tmp-acq-gps2/acquisition.dat"); config->set_property("Acquisition_2S.threshold", "0.001"); - config->set_property("Acquisition_2S.doppler_max", "5000"); - config->set_property("Acquisition_2S.doppler_step", "100"); + config->set_property("Acquisition_2S.doppler_max", std::to_string(doppler_max)); + config->set_property("Acquisition_2S.doppler_step", std::to_string(doppler_step)); config->set_property("Acquisition_2S.repeat_satellite", "false"); } +void GpsL2MPcpsAcquisitionTest::plot_grid() +{ + //load the measured values + std::string basename = "./tmp-acq-gps2/acquisition_G_2S"; + unsigned int sat = static_cast(gnss_synchro.PRN); + + unsigned int samples_per_code = static_cast(floor(sampling_frequency_hz / (GPS_L2_M_CODE_RATE_HZ / GPS_L2_M_CODE_LENGTH_CHIPS)) - 1000); // !! + acquisition_dump_reader acq_dump(basename, sat, doppler_max, doppler_step, samples_per_code); + + if(!acq_dump.read_binary_acq()) std::cout << "Error reading files" << std::endl; + + std::vector *doppler = &acq_dump.doppler; + std::vector *samples = &acq_dump.samples; + std::vector > *mag = &acq_dump.mag; + + const std::string gnuplot_executable(FLAGS_gnuplot_executable); + if(gnuplot_executable.empty()) + { + std::cout << "WARNING: Although the flag plot_acq_grid has been set to TRUE," << std::endl; + std::cout << "gnuplot has not been found in your system." << std::endl; + std::cout << "Test results will not be plotted." << std::endl; + } + else + { + std::cout << "Plotting the acquisition grid. This can take a while..." << std::endl; + try + { + boost::filesystem::path p(gnuplot_executable); + boost::filesystem::path dir = p.parent_path(); + std::string gnuplot_path = dir.native(); + Gnuplot::set_GNUPlotPath(gnuplot_path); + + Gnuplot g1("lines"); + g1.set_title("GPS L2CM signal acquisition for satellite PRN #" + std::to_string(gnss_synchro.PRN)); + g1.set_xlabel("Doppler [Hz]"); + g1.set_ylabel("Sample"); + //g1.cmd("set view 60, 105, 1, 1"); + g1.plot_grid3d(*doppler, *samples, *mag); + + g1.savetops("GPS_L2CM_acq_grid"); + g1.savetopdf("GPS_L2CM_acq_grid"); + g1.showonscreen(); + } + catch (const GnuplotException & ge) + { + std::cout << ge.what() << std::endl; + } + } + std::string data_str = "./tmp-acq-gps2"; + if (boost::filesystem::exists(data_str)) + { + boost::filesystem::remove_all(data_str); + } +} + + TEST_F(GpsL2MPcpsAcquisitionTest, Instantiate) { init(); @@ -178,7 +248,7 @@ TEST_F(GpsL2MPcpsAcquisitionTest, ConnectAndRun) ASSERT_NO_THROW( { acquisition->connect(top_block); - boost::shared_ptr source = gr::analog::sig_source_c::make(sampling_freqeuncy_hz, gr::analog::GR_SIN_WAVE, 1000, 1, gr_complex(0)); + boost::shared_ptr source = gr::analog::sig_source_c::make(sampling_frequency_hz, gr::analog::GR_SIN_WAVE, 2000, 1, gr_complex(0)); boost::shared_ptr valve = gnss_sdr_make_valve(sizeof(gr_complex), nsamples, queue); top_block->connect(source, 0, valve, 0); top_block->connect(valve, 0, acquisition->get_left_block(), 0); @@ -204,6 +274,17 @@ TEST_F(GpsL2MPcpsAcquisitionTest, ValidationOfResults) queue = gr::msg_queue::make(0); double expected_delay_samples = 1;//2004; double expected_doppler_hz = 1200;//3000; + + if(FLAGS_plot_acq_grid == true) + { + std::string data_str = "./tmp-acq-gps2"; + if (boost::filesystem::exists(data_str)) + { + boost::filesystem::remove_all(data_str); + } + boost::filesystem::create_directory(data_str); + } + init(); std::shared_ptr acquisition = std::make_shared(config.get(), "Acquisition_2S", 1, 1); boost::shared_ptr msg_rx = GpsL2MPcpsAcquisitionTest_msg_rx_make(); @@ -221,11 +302,11 @@ TEST_F(GpsL2MPcpsAcquisitionTest, ValidationOfResults) }) << "Failure setting threshold."; ASSERT_NO_THROW( { - acquisition->set_doppler_max(5000); + acquisition->set_doppler_max(doppler_max); }) << "Failure setting doppler_max."; ASSERT_NO_THROW( { - acquisition->set_doppler_step(10); + acquisition->set_doppler_step(doppler_step); }) << "Failure setting doppler_step."; ASSERT_NO_THROW( { @@ -262,7 +343,6 @@ TEST_F(GpsL2MPcpsAcquisitionTest, ValidationOfResults) elapsed_seconds = end - start; }) << "Failure running the top_block."; - //unsigned long int Acq_samplestamp_samples = gnss_synchro.Acq_samplestamp_samples; std::cout << "Acquisition process runtime duration: " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; std::cout << "gnss_synchro.Acq_doppler_hz = " << gnss_synchro.Acq_doppler_hz << " Hz" << std::endl; @@ -274,6 +354,11 @@ TEST_F(GpsL2MPcpsAcquisitionTest, ValidationOfResults) float delay_error_chips = static_cast(delay_error_samples * 1023 / 4000); double doppler_error_hz = std::abs(expected_doppler_hz - gnss_synchro.Acq_doppler_hz); - EXPECT_LE(doppler_error_hz, 200) << "Doppler error exceeds the expected value: 666 Hz = 2/(3*integration period)"; + EXPECT_LE(doppler_error_hz, 200) << "Doppler error exceeds the expected value: 2/(3*integration period)"; EXPECT_LT(delay_error_chips, 0.5) << "Delay error exceeds the expected value: 0.5 chips"; + + if(FLAGS_plot_acq_grid == true) + { + plot_grid(); + } } diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc b/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc index 3c9fcfda0..87c5c02b2 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc +++ b/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc @@ -1,7 +1,7 @@ /*! * \file acquisition_dump_reader.cc * \brief Helper file for unit testing - * \author Javier Arribas, 2017. jarribas(at)cttc.es + * \author Carles Fernandez-Prades, 2017. cfernandez(at)cttc.es * * ------------------------------------------------------------------------- * @@ -70,7 +70,7 @@ bool acquisition_dump_reader::read_binary_acq() } -acquisition_dump_reader::acquisition_dump_reader(std::string & basename, unsigned int sat, unsigned int doppler_max, unsigned int doppler_step, unsigned int samples_per_code) +acquisition_dump_reader::acquisition_dump_reader(const std::string & basename, unsigned int sat, unsigned int doppler_max, unsigned int doppler_step, unsigned int samples_per_code) { d_basename = basename; d_sat = sat; @@ -84,16 +84,13 @@ acquisition_dump_reader::acquisition_dump_reader(std::string & basename, unsigne { doppler.push_back(-static_cast(d_doppler_max) + d_doppler_step * doppler_index); d_dump_filenames.push_back(d_basename + "_sat_" + std::to_string(d_sat) + "_doppler_" + std::to_string(doppler.at(doppler_index)) + ".dat"); + std::ifstream ifs; + d_dump_files.push_back(std::move(ifs)); } for (unsigned int k = 0; k < d_samples_per_code; k++) { samples.push_back(k); } - for(int i = 0; i < d_num_doppler_bins; i++) - { - std::ifstream is; - d_dump_files.push_back(std::move(is)); - } } diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.h b/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.h index 8d346cf7d..02c75ea66 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.h +++ b/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.h @@ -1,7 +1,7 @@ /*! * \file acquisition_dump_reader.h * \brief Helper file for unit testing - * \author Javier Arribas, 2017. jarribas(at)cttc.es + * \author Carles Fernandez-Prades, 2017. cfernandez(at)cttc.es * * ------------------------------------------------------------------------- * @@ -39,7 +39,7 @@ class acquisition_dump_reader { public: - acquisition_dump_reader(std::string & basename, unsigned int sat, unsigned int doppler_max, unsigned int doppler_step, unsigned int samples_per_code); + acquisition_dump_reader(const std::string & basename, unsigned int sat, unsigned int doppler_max, unsigned int doppler_step, unsigned int samples_per_code); ~acquisition_dump_reader(); bool read_binary_acq(); diff --git a/src/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc b/src/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc index 546bf600a..d9b02fdbb 100644 --- a/src/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc @@ -379,9 +379,9 @@ void HybridObservablesTest::check_results_carrier_phase( ASSERT_LT(error_var_ch1, 1e-2); ASSERT_LT(max_error_ch1, 5e-2); ASSERT_GT(min_error_ch1, -5e-2); - } + void HybridObservablesTest::check_results_code_psudorange( arma::vec & true_ch0_dist_m, arma::vec & true_ch1_dist_m, @@ -401,8 +401,6 @@ void HybridObservablesTest::check_results_code_psudorange( arma::vec delta_true_dist_m = true_ch0_dist_interp-true_ch1_dist_interp; arma::vec delta_measured_dist_m = measuded_ch0_Pseudorange_m-measuded_ch1_Pseudorange_m; - - //2. RMSE arma::vec err; @@ -467,7 +465,7 @@ TEST_F(HybridObservablesTest, ValidationOfResults) { throw std::exception(); }; - }) << "Failure opening true observables file" << std::endl; + }) << "Failure opening true observables file"; true_obs_file = std::string("./gps_l1_ca_obs_prn"); true_obs_file.append(std::to_string(test_satellite_PRN2)); @@ -477,7 +475,7 @@ TEST_F(HybridObservablesTest, ValidationOfResults) { throw std::exception(); }; - }) << "Failure opening true observables file" << std::endl; + }) << "Failure opening true observables file"; top_block = gr::make_top_block("Telemetry_Decoder test"); std::shared_ptr tracking_ch0 = std::make_shared(config.get(), "Tracking_1C", 1, 1); @@ -494,14 +492,14 @@ TEST_F(HybridObservablesTest, ValidationOfResults) { throw std::exception(); }; - })<< "Failure reading true observables file" << std::endl; + }) << "Failure reading true observables file"; ASSERT_NO_THROW({ if (true_obs_data_ch1.read_binary_obs() == false) { throw std::exception(); }; - }) << "Failure reading true observables file" << std::endl; + }) << "Failure reading true observables file"; //restart the epoch counter true_obs_data_ch0.restart(); @@ -529,7 +527,7 @@ TEST_F(HybridObservablesTest, ValidationOfResults) tlm_ch0->set_satellite(Gnss_Satellite(std::string("GPS"),gnss_synchro_ch0.PRN)); tlm_ch1->set_satellite(Gnss_Satellite(std::string("GPS"),gnss_synchro_ch1.PRN)); - }) << "Failure setting gnss_synchro." << std::endl; + }) << "Failure setting gnss_synchro."; boost::shared_ptr tlm_msg_rx_ch1 = HybridObservablesTest_tlm_msg_rx_make(); boost::shared_ptr tlm_msg_rx_ch2 = HybridObservablesTest_tlm_msg_rx_make(); @@ -540,17 +538,17 @@ TEST_F(HybridObservablesTest, ValidationOfResults) ASSERT_NO_THROW( { tracking_ch0->set_channel(gnss_synchro_ch0.Channel_ID); tracking_ch1->set_channel(gnss_synchro_ch1.Channel_ID); - }) << "Failure setting channel." << std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { tracking_ch0->set_gnss_synchro(&gnss_synchro_ch0); tracking_ch1->set_gnss_synchro(&gnss_synchro_ch1); - }) << "Failure setting gnss_synchro." << std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { tracking_ch0->connect(top_block); tracking_ch1->connect(top_block); - }) << "Failure connecting tracking to the top_block." << std::endl; + }) << "Failure connecting tracking to the top_block."; ASSERT_NO_THROW( { std::string file = "./" + filename_raw_data; @@ -574,7 +572,7 @@ TEST_F(HybridObservablesTest, ValidationOfResults) top_block->connect(observables->get_right_block(), 0, sink_ch0, 0); top_block->connect(observables->get_right_block(), 1, sink_ch1, 0); - }) << "Failure connecting the blocks." << std::endl; + }) << "Failure connecting the blocks."; tracking_ch0->start_tracking(); tracking_ch1->start_tracking(); @@ -584,7 +582,7 @@ TEST_F(HybridObservablesTest, ValidationOfResults) top_block->run(); // Start threads and wait end = std::chrono::system_clock::now(); elapsed_seconds = end - start; - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; //check results //load the true values @@ -596,7 +594,7 @@ TEST_F(HybridObservablesTest, ValidationOfResults) { throw std::exception(); }; - }) << "Failure opening true observables file" << std::endl; + }) << "Failure opening true observables file"; long int nepoch = true_observables.num_epochs(); @@ -637,7 +635,6 @@ TEST_F(HybridObservablesTest, ValidationOfResults) epoch_counter++; } - }); //read measured values @@ -647,7 +644,7 @@ TEST_F(HybridObservablesTest, ValidationOfResults) { throw std::exception(); }; - }) << "Failure opening dump observables file" << std::endl; + }) << "Failure opening dump observables file"; nepoch = estimated_observables.num_epochs(); std::cout << "Measured observation epochs=" << nepoch << std::endl; diff --git a/src/tests/unit-tests/signal-processing-blocks/telemetry_decoder/gps_l1_ca_telemetry_decoder_test.cc b/src/tests/unit-tests/signal-processing-blocks/telemetry_decoder/gps_l1_ca_telemetry_decoder_test.cc index c75139ff6..5799a7beb 100644 --- a/src/tests/unit-tests/signal-processing-blocks/telemetry_decoder/gps_l1_ca_telemetry_decoder_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/telemetry_decoder/gps_l1_ca_telemetry_decoder_test.cc @@ -170,7 +170,6 @@ GpsL1CADllPllTelemetryDecoderTest_tlm_msg_rx::~GpsL1CADllPllTelemetryDecoderTest class GpsL1CATelemetryDecoderTest: public ::testing::Test { - public: std::string generator_binary; std::string p1; @@ -357,7 +356,7 @@ TEST_F(GpsL1CATelemetryDecoderTest, ValidationOfResults) { throw std::exception(); }; - }) << "Failure opening true observables file" << std::endl; + }) << "Failure opening true observables file"; top_block = gr::make_top_block("Telemetry_Decoder test"); std::shared_ptr tracking = std::make_shared(config.get(), "Tracking_1C", 1, 1); @@ -371,7 +370,7 @@ TEST_F(GpsL1CATelemetryDecoderTest, ValidationOfResults) { throw std::exception(); }; - })<< "Failure reading true observables file" << std::endl; + }) << "Failure reading true observables file"; //restart the epoch counter true_obs_data.restart(); @@ -388,15 +387,15 @@ TEST_F(GpsL1CATelemetryDecoderTest, ValidationOfResults) ASSERT_NO_THROW( { tracking->set_channel(gnss_synchro.Channel_ID); - }) << "Failure setting channel." << std::endl; + }) << "Failure setting channel."; ASSERT_NO_THROW( { tracking->set_gnss_synchro(&gnss_synchro); - }) << "Failure setting gnss_synchro." << std::endl; + }) << "Failure setting gnss_synchro."; ASSERT_NO_THROW( { tracking->connect(top_block); - }) << "Failure connecting tracking to the top_block." << std::endl; + }) << "Failure connecting tracking to the top_block."; ASSERT_NO_THROW( { std::string file = "./" + filename_raw_data; @@ -409,7 +408,7 @@ TEST_F(GpsL1CATelemetryDecoderTest, ValidationOfResults) top_block->connect(tracking->get_right_block(), 0, tlm->get_left_block(), 0); top_block->connect(tlm->get_right_block(), 0, sink, 0); top_block->msg_connect(tracking->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - }) << "Failure connecting the blocks." << std::endl; + }) << "Failure connecting the blocks."; tracking->start_tracking(); @@ -418,7 +417,7 @@ TEST_F(GpsL1CATelemetryDecoderTest, ValidationOfResults) top_block->run(); // Start threads and wait end = std::chrono::system_clock::now(); elapsed_seconds = end - start; - }) << "Failure running the top_block." << std::endl; + }) << "Failure running the top_block."; //check results //load the true values @@ -449,7 +448,7 @@ TEST_F(GpsL1CATelemetryDecoderTest, ValidationOfResults) { throw std::exception(); }; - }) << "Failure opening telemetry dump file" << std::endl; + }) << "Failure opening telemetry dump file"; nepoch = tlm_dump.num_epochs(); std::cout << "Measured observation epochs=" << nepoch << std::endl; From cccb77783abd207630f9b17d91a77be0fb36545c Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sun, 29 Oct 2017 12:55:10 +0100 Subject: [PATCH 73/81] Avoid comparison between signed and unsigned integer warning --- .../libs/acquisition_dump_reader.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc b/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc index 87c5c02b2..8e16812df 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc +++ b/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc @@ -34,7 +34,7 @@ bool acquisition_dump_reader::read_binary_acq() { std::complex* aux = new std::complex[1]; - for(int i = 0; i < d_num_doppler_bins; i++) + for(unsigned int i = 0; i < d_num_doppler_bins; i++) { try { @@ -44,7 +44,7 @@ bool acquisition_dump_reader::read_binary_acq() d_dump_files.at(i).swap(ifs); if (d_dump_files.at(i).is_open()) { - for(int k = 0; k < d_samples_per_code; k++) + for(unsigned int k = 0; k < d_samples_per_code; k++) { d_dump_files.at(i).read(reinterpret_cast(&aux[0]), sizeof(std::complex)); mag.at(i).at(k) = std::abs(*aux) / std::pow(d_samples_per_code, 2); @@ -96,7 +96,7 @@ acquisition_dump_reader::acquisition_dump_reader(const std::string & basename, u acquisition_dump_reader::~acquisition_dump_reader() { - for(int i = 0; i < d_num_doppler_bins; i++) + for(unsigned int i = 0; i < d_num_doppler_bins; i++) { if (d_dump_files.at(i).is_open() == true) { From 31b4228d8b45889b9013557bd3db13fa4313854a Mon Sep 17 00:00:00 2001 From: rmunozl Date: Mon, 30 Oct 2017 15:17:53 +0000 Subject: [PATCH 74/81] add better explanation in README.md and improve format of some files --- README.md | 15 ++++++++++++--- .../signal_source/adapters/CMakeLists.txt | 18 ++++++++++-------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index a3d81f8af..4c938a0ad 100644 --- a/README.md +++ b/README.md @@ -370,7 +370,7 @@ $ sudo make install ###### Build FMCOMMS2 based SDR Hardware support (OPTIONAL): -Install [libiio](https://github.com/analogdevicesinc/libiio.git), [libad9361](https://github.com/analogdevicesinc/libad9361-iio.git) and [gr-iio](https://github.com/analogdevicesinc/gr-iio.git) gnuradio block (instructions based on https://www.plutosdr.com/viewtopic.php?t=5): +Install the [libiio](https://github.com/analogdevicesinc/libiio.git) (>=v0.11), [libad9361](https://github.com/analogdevicesinc/libad9361-iio.git) (>=v0.1-1) libraries and [gr-iio](https://github.com/analogdevicesinc/gr-iio.git) (>=v0.2) gnuradio block. For example in Ubuntu 16.04 follow these instructions (based on https://github.com/blurbdust/blurbdust.github.io): ~~~~~~ $ git clone https://github.com/analogdevicesinc/libiio.git @@ -410,13 +410,22 @@ $ sudo make install $ sudo ldconfig ~~~~~~ -Then configure the gnss-sdr to build the `Fmcomms2_Signal_Source`: +Then configure the gnss-sdr to build the `Fmcomms2_Signal_Source` and `Plutosdr_Signal_Source`: ~~~~~~ $ cmake -DENABLE_FMCOMMS2=ON ../ -$ make +$ make $ sudo make install ~~~~~~ +or configure only `Plutosdr_Signal_Source`: +~~~~~~ +$ cmake -DENABLE_PLUTOSDR=ON ../ +$ make +$ sudo make install +~~~~~~ + +With `Fmcomms2_Signal_Source` you can use any SDR hardware based on fmcomms2, including the ADALM-PLUTO (PlutoSdr) by configuring correctly the .conf file. The `Plutosdr_Signal_Source` offers a simplier manner to use the ADALM-PLUTO because implements only a subset of fmcomms2's parameters valid for it device. + ###### Build OpenCL support (OPTIONAL): In order to enable the building of blocks that use OpenCL, type: diff --git a/src/algorithms/signal_source/adapters/CMakeLists.txt b/src/algorithms/signal_source/adapters/CMakeLists.txt index 2cc169ed9..009f56433 100644 --- a/src/algorithms/signal_source/adapters/CMakeLists.txt +++ b/src/algorithms/signal_source/adapters/CMakeLists.txt @@ -29,10 +29,11 @@ if(ENABLE_PLUTOSDR) if(NOT IIO_FOUND) message("gnuradio-iio not found, installation is required") message(FATAL_ERROR "gnuradio-iio required for building gnss-sdr with this option enabled") - endif(NOT IIO_FOUND) - set(OPT_LIBRARIES ${OPT_LIBRARIES} ${IIO_LIBRARIES}) - set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${IIO_INCLUDE_DIRS}) - set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} plutosdr_signal_source.cc) + else(NOT IIO_FOUND) + set(OPT_LIBRARIES ${OPT_LIBRARIES} ${IIO_LIBRARIES}) + set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${IIO_INCLUDE_DIRS}) + set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} plutosdr_signal_source.cc) + endif(NOT IIO_FOUND) endif(ENABLE_PLUTOSDR) if(ENABLE_FMCOMMS2) @@ -43,10 +44,11 @@ if(ENABLE_FMCOMMS2) if(NOT IIO_FOUND) message("gnuradio-iio not found, installation is required") message(FATAL_ERROR "gnuradio-iio required for building gnss-sdr with this option enabled") - endif(NOT IIO_FOUND) - set(OPT_LIBRARIES ${OPT_LIBRARIES} ${IIO_LIBRARIES}) - set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${IIO_INCLUDE_DIRS}) - set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} fmcomms2_signal_source.cc plutosdr_signal_source.cc) + else(NOT IIO_FOUND) + set(OPT_LIBRARIES ${OPT_LIBRARIES} ${IIO_LIBRARIES}) + set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${IIO_INCLUDE_DIRS}) + set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} fmcomms2_signal_source.cc plutosdr_signal_source.cc) + endif(NOT IIO_FOUND) endif(ENABLE_FMCOMMS2) if(ENABLE_GN3S) From f92c910e05aae63cc8950994896eae1d1b9f3d81 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Mon, 30 Oct 2017 20:15:12 +0100 Subject: [PATCH 75/81] Detect and document macOS High Sierra Fix old CMAKE flag for Eclipse (from ECLIPSE_CDT4_GENERATE_SOURCE_PROJECT to ECLIPSE_GENERATE_SOURCE_PROJECT) --- CMakeLists.txt | 10 ++++++++-- README.md | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 265e79ec5..cbf6b9805 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -214,15 +214,21 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") message(STATUS "Configuring GNSS-SDR v${VERSION} to be built on ${LINUX_DISTRIBUTION} GNU/Linux Release ${LINUX_VER} ${ARCH_}") endif(${CMAKE_SYSTEM_NAME} MATCHES "Linux") -# Detect Mac OS X Version +# Detect macOS / Mac OS X Version if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set(OperatingSystem "Mac OS X") set(OS_IS_MACOSX TRUE) exec_program(uname ARGS -v OUTPUT_VARIABLE DARWIN_VERSION) string(REGEX MATCH "[0-9]+" DARWIN_VERSION ${DARWIN_VERSION}) + if(${DARWIN_VERSION} MATCHES "17") + set(MACOS_HIGH_SIERRA TRUE) + set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++14") + set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++") + message(STATUS "Configuring GNSS-SDR v${VERSION} to be built on macOS High Sierra 10.13") + endif(${DARWIN_VERSION} MATCHES "17") if(${DARWIN_VERSION} MATCHES "16") set(MACOS_SIERRA TRUE) - set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++11") + set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++14") set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++") message(STATUS "Configuring GNSS-SDR v${VERSION} to be built on macOS Sierra 10.12") endif(${DARWIN_VERSION} MATCHES "16") diff --git a/README.md b/README.md index 9a14d8343..e11172b02 100644 --- a/README.md +++ b/README.md @@ -291,7 +291,7 @@ GNSS-SDR comes with a library which is a module of the Vector-Optimized Library If you are using Eclipse as your development environment, CMake can create the project for you. Type: ~~~~~~ -$ cmake -G "Eclipse CDT4 - Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DECLIPSE_CDT4_GENERATE_SOURCE_PROJECT=TRUE -DCMAKE_ECLIPSE_VERSION=3.7 -DCMAKE_ECLIPSE_MAKE_ARGUMENTS=-j8 ../ +$ cmake -G "Eclipse CDT4 - Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DECLIPSE_GENERATE_SOURCE_PROJECT=TRUE -DCMAKE_ECLIPSE_VERSION=4.5 . ~~~~~~ and then import the created project file into Eclipse: @@ -413,7 +413,7 @@ More details can be found in our tutorial about [GNSS-SDR configuration options --------- -### macOS Sierra, Mac OS X 10.11 (El Capitan), 10.10 (Yosemite) and 10.9 (Mavericks). +### macOS 10.13 (High Sierra) and 10.12 (Sierra), Mac OS X 10.11 (El Capitan), 10.10 (Yosemite) and 10.9 (Mavericks). If you still have not installed [Xcode](http://developer.apple.com/xcode/ "Xcode"), do it now from the App Store (it's free). You will also need the Xcode Command Line Tools. Launch the Terminal, found in /Applications/Utilities/, and type: From cc3ed4c672d98e88c5bcd50ecb03395709f63039 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Mon, 30 Oct 2017 22:31:20 +0100 Subject: [PATCH 76/81] Apply project's coding style --- CMakeLists.txt | 2 + README.md | 2 +- conf/gnss-sdr_GPS_L1_fmcomms2_realtime.conf | 20 ++- conf/gnss-sdr_GPS_L1_plutosdr_realtime.conf | 26 +++- .../adapters/fmcomms2_signal_source.cc | 129 +++++++++--------- .../adapters/fmcomms2_signal_source.h | 55 ++++---- .../adapters/plutosdr_signal_source.cc | 125 ++++++++++------- .../adapters/plutosdr_signal_source.h | 72 +++++++--- 8 files changed, 252 insertions(+), 179 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cbf6b9805..30d4f6eaf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,6 +48,8 @@ option(ENABLE_OSMOSDR "Enable the use of OsmoSDR and other front-ends (RTL-based option(ENABLE_FLEXIBAND "Enable the use of the signal source adater for the Teleorbit Flexiband GNURadio driver" OFF) option(ENABLE_ARRAY "Enable the use of CTTC's antenna array front-end as signal source (experimental)" OFF) option(ENABLE_GN3S "Enable the use of the GN3S dongle as signal source (experimental)" OFF) +option(ENABLE_PLUTOSDR "Enable the use of ADALM-PLUTO Evaluation Boards (Analog Devices Inc.), requires gr-iio" OFF) +option(ENABLE_FMCOMMS2 "Enable the use of FMCOMMS4-EBZ + ZedBoard hardware" OFF) # Performance analysis tools option(ENABLE_GPERFTOOLS "Enable linking to Gperftools libraries (tcmalloc and profiler)" OFF) diff --git a/README.md b/README.md index 77403cf92..6935a4067 100644 --- a/README.md +++ b/README.md @@ -424,7 +424,7 @@ $ make $ sudo make install ~~~~~~ -With `Fmcomms2_Signal_Source` you can use any SDR hardware based on fmcomms2, including the ADALM-PLUTO (PlutoSdr) by configuring correctly the .conf file. The `Plutosdr_Signal_Source` offers a simplier manner to use the ADALM-PLUTO because implements only a subset of fmcomms2's parameters valid for it device. +With `Fmcomms2_Signal_Source` you can use any SDR hardware based on fmcomms2, including the ADALM-PLUTO (PlutoSdr) by configuring correctly the .conf file. The `Plutosdr_Signal_Source` offers a simplier manner to use the ADALM-PLUTO because implements only a subset of fmcomms2's parameters valid for those devices. ###### Build OpenCL support (OPTIONAL): diff --git a/conf/gnss-sdr_GPS_L1_fmcomms2_realtime.conf b/conf/gnss-sdr_GPS_L1_fmcomms2_realtime.conf index aecfad5cd..ae832f901 100644 --- a/conf/gnss-sdr_GPS_L1_fmcomms2_realtime.conf +++ b/conf/gnss-sdr_GPS_L1_fmcomms2_realtime.conf @@ -5,10 +5,10 @@ [GNSS-SDR] ;######### GLOBAL OPTIONS ################## -;internal_fs_hz: Internal signal sampling frequency after the signal conditioning stage [Hz]. +;internal_fs_sps: Internal signal sampling frequency after the signal conditioning stage [Sps]. ;FOR USE GNSS-SDR WITH RTLSDR DONGLES USER MUST SET THE CALIBRATED SAMPLE RATE HERE ; i.e. using front-end-cal as reported here:http://www.cttc.es/publication/turning-a-television-into-a-gnss-receiver/ -GNSS-SDR.internal_fs_hz=2000000 +GNSS-SDR.internal_fs_sps=2000000 ;######### SUPL RRLP GPS assistance configuration ##### @@ -119,27 +119,23 @@ TelemetryDecoder_1C.dump=false TelemetryDecoder_1C.decimation_factor=1; ;######### OBSERVABLES CONFIG ############ -Observables.implementation=GPS_L1_CA_Observables +Observables.implementation=Hybrid_Observables Observables.dump=false Observables.dump_filename=./observables.dat ;######### PVT CONFIG ############ -;#implementation: Position Velocity and Time (PVT) implementation algorithm: Use [GPS_L1_CA_PVT] in this version. -PVT.implementation=GPS_L1_CA_PVT - -;#averaging_depth: Number of PVT observations in the moving average algorithm -PVT.averaging_depth=10 - -;#flag_average: Enables the PVT averaging between output intervals (arithmetic mean) [true] or [false] -PVT.flag_averaging=true +PVT.implementation=RTKLIB_PVT +PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic +PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX +PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad PVT.output_rate_ms=100 PVT.display_rate_ms=500 PVT.dump_filename=./PVT PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea; PVT.flag_nmea_tty_port=false; PVT.nmea_dump_devname=/dev/pts/4 -PVT.dump=false PVT.flag_rtcm_server=false PVT.flag_rtcm_tty_port=false PVT.rtcm_dump_devname=/dev/pts/1 +PVT.dump=false diff --git a/conf/gnss-sdr_GPS_L1_plutosdr_realtime.conf b/conf/gnss-sdr_GPS_L1_plutosdr_realtime.conf index 5c6f4fdd6..97c9deded 100644 --- a/conf/gnss-sdr_GPS_L1_plutosdr_realtime.conf +++ b/conf/gnss-sdr_GPS_L1_plutosdr_realtime.conf @@ -5,10 +5,10 @@ [GNSS-SDR] ;######### GLOBAL OPTIONS ################## -;internal_fs_hz: Internal signal sampling frequency after the signal conditioning stage [Hz]. +;internal_fs_sps: Internal signal sampling frequency after the signal conditioning stage [sps]. ;FOR USE GNSS-SDR WITH RTLSDR DONGLES USER MUST SET THE CALIBRATED SAMPLE RATE HERE ; i.e. using front-end-cal as reported here:http://www.cttc.es/publication/turning-a-television-into-a-gnss-receiver/ -GNSS-SDR.internal_fs_hz=2000000 +GNSS-SDR.internal_fs_sps=2000000 ;######### SUPL RRLP GPS assistance configuration ##### @@ -79,11 +79,23 @@ Tracking_1C.dll_bw_hz=4.0; TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder ;######### OBSERVABLES CONFIG ############ -Observables.implementation=GPS_L1_CA_Observables +Observables.implementation=Hybrid_Observables +Observables.dump=false +Observables.dump_filename=./observables.dat + ;######### PVT CONFIG ############ -PVT.implementation=GPS_L1_CA_PVT -PVT.averaging_depth=100 -PVT.flag_averaging=true -PVT.output_rate_ms=10 +PVT.implementation=RTKLIB_PVT +PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic +PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX +PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad +PVT.output_rate_ms=100 PVT.display_rate_ms=500 +PVT.dump_filename=./PVT +PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea; +PVT.flag_nmea_tty_port=false; +PVT.nmea_dump_devname=/dev/pts/4 +PVT.flag_rtcm_server=false +PVT.flag_rtcm_tty_port=false +PVT.rtcm_dump_devname=/dev/pts/1 +PVT.dump=false diff --git a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc index a77215327..26640d840 100644 --- a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc +++ b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc @@ -6,7 +6,7 @@ * * ------------------------------------------------------------------------- * - * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) * * GNSS-SDR is a software defined Global Navigation * Satellite Systems receiver @@ -44,93 +44,94 @@ using google::LogMessage; Fmcomms2SignalSource::Fmcomms2SignalSource(ConfigurationInterface* configuration, std::string role, unsigned int in_stream, unsigned int out_stream, boost::shared_ptr queue) : - role_(role), in_stream_(in_stream), out_stream_(out_stream), - queue_(queue) + role_(role), in_stream_(in_stream), out_stream_(out_stream), + queue_(queue) { - std::string default_item_type="gr_complex"; - std::string default_dump_file="./data/signal_source.dat"; - uri_= configuration->property(role+".device_address",std::string("192.168.2.1")); - freq_= configuration->property(role+".freq",GPS_L1_FREQ_HZ); - sample_rate_=configuration->property(role+".sampling_frequency",2600000); - bandwidth_= configuration->property(role+".bandwidth",2000000); - rx1_en_=configuration->property(role+".rx1_enable",true); - rx2_en_=configuration->property(role+".rx2_enable",false); - buffer_size_=configuration->property(role+".buffer_size",0xA0000); - decimation_=configuration->property(role+".decimation",1); - quadrature_=configuration->property(role+".quadrature",true); - rf_dc_=configuration->property(role+".rf_dc",true); - bb_dc_=configuration->property(role+".bb_dc",true); - gain_mode_rx1_=configuration->property(role+".gain_mode_rx1",std::string("manual")); - gain_mode_rx2_=configuration->property(role+".gain_mode_rx2",std::string("manual")); - rf_gain_rx1_=configuration->property(role+".gain_rx1",64.0); - rf_gain_rx2_=configuration->property(role+".gain_rx2",64.0); - rf_port_select_=configuration->property(role+".rf_port_select",std::string("A_BALANCED")); - filter_file_=configuration->property(role+".filter_file",std::string("")); - filter_auto_=configuration->property(role+".filter_auto",true); - item_type_=configuration->property(role+".item_type",default_item_type); - samples_=configuration->property(role+".samples",0); - dump_=configuration->property(role+".dump",false); - dump_filename_=configuration->property(role+".dump_filename",default_dump_file); - - item_size_=sizeof(gr_complex); + std::string default_item_type = "gr_complex"; + std::string default_dump_file = "./data/signal_source.dat"; + uri_ = configuration->property(role + ".device_address", std::string("192.168.2.1")); + freq_ = configuration->property(role + ".freq", GPS_L1_FREQ_HZ); + sample_rate_ = configuration->property(role + ".sampling_frequency", 2600000); + bandwidth_ = configuration->property(role + ".bandwidth", 2000000); + rx1_en_ = configuration->property(role + ".rx1_enable", true); + rx2_en_ = configuration->property(role + ".rx2_enable", false); + buffer_size_ = configuration->property(role + ".buffer_size", 0xA0000); + decimation_ = configuration->property(role + ".decimation", 1); + quadrature_ = configuration->property(role + ".quadrature", true); + rf_dc_ = configuration->property(role + ".rf_dc", true); + bb_dc_ = configuration->property(role + ".bb_dc", true); + gain_mode_rx1_ = configuration->property(role + ".gain_mode_rx1", std::string("manual")); + gain_mode_rx2_ = configuration->property(role + ".gain_mode_rx2", std::string("manual")); + rf_gain_rx1_ = configuration->property(role + ".gain_rx1", 64.0); + rf_gain_rx2_ = configuration->property(role + ".gain_rx2", 64.0); + rf_port_select_ = configuration->property(role + ".rf_port_select", std::string("A_BALANCED")); + filter_file_ = configuration->property(role + ".filter_file", std::string("")); + filter_auto_ = configuration->property(role + ".filter_auto", true); + item_type_ = configuration->property(role + ".item_type", default_item_type); + samples_ = configuration->property(role + ".samples", 0); + dump_ = configuration->property(role + ".dump", false); + dump_filename_ = configuration->property(role + ".dump_filename", default_dump_file); - std::cout<<"device address: "<unique_id() << ")"; - } + if(item_type_.compare("gr_complex")==0) + { + fmcomms2_source_f32c_ = gr::iio::fmcomms2_source_f32c::make( + uri_.c_str(), freq_, sample_rate_, + decimation_, bandwidth_, + rx1_en_, rx2_en_, + buffer_size_, quadrature_, rf_dc_, + bb_dc_, gain_mode_rx1_.c_str(), rf_gain_rx1_, + gain_mode_rx2_.c_str(), rf_gain_rx2_, + rf_port_select_.c_str(), filter_file_.c_str(), + filter_auto_); + } + else + { + LOG(FATAL) << "Exception: item type " << item_type_ << " not suported!"; + } + + if (samples_ != 0) + { + DLOG(INFO) << "Send STOP signal after " << samples_ << " samples"; + valve_ = gnss_sdr_make_valve(item_size_, samples_, queue_); + DLOG(INFO) << "valve(" << valve_->unique_id() << ")"; + } if (dump_) - { - DLOG(INFO) << "Dumping output into file " << dump_filename_; - file_sink_ = gr::blocks::file_sink::make(item_size_, dump_filename_.c_str()); - DLOG(INFO) << "file_sink(" << file_sink_->unique_id() << ")"; - } + { + DLOG(INFO) << "Dumping output into file " << dump_filename_; + file_sink_ = gr::blocks::file_sink::make(item_size_, dump_filename_.c_str()); + DLOG(INFO) << "file_sink(" << file_sink_->unique_id() << ")"; + } } + Fmcomms2SignalSource::~Fmcomms2SignalSource() -{ -} +{} + void Fmcomms2SignalSource::connect(gr::top_block_sptr top_block) { if (samples_ != 0) { - top_block->connect(fmcomms2_source_f32c_, 0, valve_, 0); + top_block->connect(fmcomms2_source_f32c_, 0, valve_, 0); DLOG(INFO) << "connected fmcomms2 source to valve"; if (dump_) { top_block->connect(valve_, 0, file_sink_, 0); DLOG(INFO) << "connected valve to file sink"; } - } + } else { if (dump_) { - + top_block->connect(fmcomms2_source_f32c_ , 0, file_sink_, 0); DLOG(INFO) << "connected fmcomms2 source to file sink"; } diff --git a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.h b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.h index c9b690cdd..0672770f5 100644 --- a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.h +++ b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.h @@ -7,7 +7,7 @@ * This class represent a fmcomms2 signal source. It use the gr_iio block * ------------------------------------------------------------------------- * - * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) * * GNSS-SDR is a software defined Global Navigation * Satellite Systems receiver @@ -51,7 +51,7 @@ public: virtual ~Fmcomms2SignalSource(); - std::string role() + inline std::string role() override { return role_; } @@ -59,42 +59,43 @@ public: /*! * \brief Returns "fmcomms2_Signal_Source" */ - std::string implementation() + inline std::string implementation() override { return "Fmcomms2_Signal_Source"; } - size_t item_size() + + inline size_t item_size() override { return item_size_; } - void connect(gr::top_block_sptr top_block); - void disconnect(gr::top_block_sptr top_block); - gr::basic_block_sptr get_left_block(); - gr::basic_block_sptr get_right_block(); + 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; private: std::string role_; // Front-end settings - std::string uri_;//device direction - unsigned long freq_; //frequency of local oscilator - unsigned long sample_rate_; - unsigned long bandwidth_; - unsigned long buffer_size_; //reception buffer - unsigned int decimation_; - bool rx1_en_; - bool rx2_en_; - bool quadrature_; - bool rf_dc_; - bool bb_dc_; - std::string gain_mode_rx1_; - std::string gain_mode_rx2_; - double rf_gain_rx1_; - double rf_gain_rx2_; - std::string rf_port_select_; - std::string filter_file_; - bool filter_auto_; + std::string uri_;//device direction + unsigned long freq_; //frequency of local oscilator + unsigned long sample_rate_; + unsigned long bandwidth_; + unsigned long buffer_size_; //reception buffer + unsigned int decimation_; + bool rx1_en_; + bool rx2_en_; + bool quadrature_; + bool rf_dc_; + bool bb_dc_; + std::string gain_mode_rx1_; + std::string gain_mode_rx2_; + double rf_gain_rx1_; + double rf_gain_rx2_; + std::string rf_port_select_; + std::string filter_file_; + bool filter_auto_; unsigned int in_stream_; unsigned int out_stream_; @@ -105,7 +106,7 @@ private: bool dump_; std::string dump_filename_; - gr::iio::fmcomms2_source_f32c::sptr fmcomms2_source_f32c_; + gr::iio::fmcomms2_source_f32c::sptr fmcomms2_source_f32c_; boost::shared_ptr valve_; gr::blocks::file_sink::sptr file_sink_; diff --git a/src/algorithms/signal_source/adapters/plutosdr_signal_source.cc b/src/algorithms/signal_source/adapters/plutosdr_signal_source.cc index 45e0f3deb..64d59a113 100644 --- a/src/algorithms/signal_source/adapters/plutosdr_signal_source.cc +++ b/src/algorithms/signal_source/adapters/plutosdr_signal_source.cc @@ -1,3 +1,33 @@ +/*! + * \file plutosdr_signal_source.cc + * \brief Signal source for PlutoSDR + * \author Rodrigo Muñoz, 2017, rmunozl(at)inacap.cl + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + #include "plutosdr_signal_source.h" #include #include @@ -14,67 +44,68 @@ using google::LogMessage; PlutosdrSignalSource::PlutosdrSignalSource(ConfigurationInterface* configuration, std::string role, unsigned int in_stream, unsigned int out_stream, boost::shared_ptr queue) : - role_(role), in_stream_(in_stream), out_stream_(out_stream), - queue_(queue) + role_(role), in_stream_(in_stream), out_stream_(out_stream), + queue_(queue) { - std::string default_item_type="gr_complex"; - std::string default_dump_file="./data/signal_source.dat"; - uri_ = configuration->property(role+".device_address",std::string("192.168.2.1")); - freq_= configuration->property(role+".freq",GPS_L1_FREQ_HZ); - sample_rate_=configuration->property(role+".sampling_frequency",3000000); - bandwidth_ = configuration->property(role+".bandwidth",2000000); - buffer_size_=configuration->property(role+".buffer_size",0xA0000); - decimation_=configuration->property(role+".decimation",1); - quadrature_=configuration->property(role+".quadrature",true); - rf_dc_ =configuration->property(role+".rf_dc",true); - bb_dc_ =configuration->property(role+".bb_dc",true); - gain_mode_=configuration->property(role+".gain_mode",std::string("manual")); - rf_gain_=configuration->property(role+".gain",50.0); - filter_file_=configuration->property(role+".filter_file",std::string("")); - filter_auto_=configuration->property(role+".filter_auto",true); + std::string default_item_type = "gr_complex"; + std::string default_dump_file = "./data/signal_source.dat"; + uri_ = configuration->property(role + ".device_address", std::string("192.168.2.1")); + freq_ = configuration->property(role + ".freq", GPS_L1_FREQ_HZ); + sample_rate_ configuration->property(role + ".sampling_frequency", 3000000); + bandwidth_ = configuration->property(role + ".bandwidth", 2000000); + buffer_size_ = configuration->property(role + ".buffer_size", 0xA0000); + decimation_ = configuration->property(role + ".decimation", 1); + quadrature_ = configuration->property(role + ".quadrature", true); + rf_dc_ = configuration->property(role + ".rf_dc", true); + bb_dc_ = configuration->property(role + ".bb_dc", true); + gain_mode_ = configuration->property(role + ".gain_mode", std::string("manual")); + rf_gain_ = configuration->property(role + ".gain", 50.0); + filter_file_ = configuration->property(role + ".filter_file", std::string("")); + filter_auto_ = configuration->property(role + ".filter_auto", true); - item_type_=configuration->property(role+".item_type",default_item_type); - samples_=configuration->property(role+".samples",0); - dump_=configuration->property(role+".dump",false); - dump_filename_=configuration->property(role+".dump_filename",default_dump_file); - - if(item_type_.compare("gr_complex") != 0) - { - std::cout<<"bad item_type!!"<property(role + ".item_type", default_item_type); + samples_ = configuration->property(role + ".samples", 0); + dump_ = configuration->property(role + ".dump", false); + dump_filename_ = configuration->property(role + ".dump_filename", default_dump_file); + if(item_type_.compare("gr_complex") != 0) + { + std::cout << "bad item_type!!" << std::endl; + LOG(FATAL) << "Exception: item type must be gr_complex!"; + } - std::cout<<"device address: "<unique_id() << ")"; - } + plutosdr_source_ = gr::iio::pluto_source::make(uri_, freq_, sample_rate_, + decimation_, bandwidth_, buffer_size_, quadrature_, rf_dc_, bb_dc_, + gain_mode_.c_str(), rf_gain_,filter_file_.c_str(), filter_auto_); + + if (samples_ != 0) + { + DLOG(INFO) << "Send STOP signal after " << samples_ << " samples"; + valve_ = gnss_sdr_make_valve(item_size_, samples_, queue_); + DLOG(INFO) << "valve(" << valve_->unique_id() << ")"; + } if (dump_) - { - DLOG(INFO) << "Dumping output into file " << dump_filename_; - file_sink_ = gr::blocks::file_sink::make(item_size_, dump_filename_.c_str()); - DLOG(INFO) << "file_sink(" << file_sink_->unique_id() << ")"; + { + DLOG(INFO) << "Dumping output into file " << dump_filename_; + file_sink_ = gr::blocks::file_sink::make(item_size_, dump_filename_.c_str()); + DLOG(INFO) << "file_sink(" << file_sink_->unique_id() << ")"; } } + PlutosdrSignalSource::~PlutosdrSignalSource() {} + void PlutosdrSignalSource::connect(gr::top_block_sptr top_block) { if (samples_ != 0) diff --git a/src/algorithms/signal_source/adapters/plutosdr_signal_source.h b/src/algorithms/signal_source/adapters/plutosdr_signal_source.h index eadee361d..79a310089 100644 --- a/src/algorithms/signal_source/adapters/plutosdr_signal_source.h +++ b/src/algorithms/signal_source/adapters/plutosdr_signal_source.h @@ -1,3 +1,33 @@ +/*! + * \file plutosdr_signal_source.h + * \brief Signal source for PlutoSDR + * \author Rodrigo Muñoz, 2017, rmunozl(at)inacap.cl + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + #ifndef GNSS_SDR_PLUTOSDR_SIGNAL_SOURCE_H_ #define GNSS_SDR_PLUTOSDR_SIGNAL_SOURCE_H_ @@ -22,7 +52,7 @@ public: virtual ~PlutosdrSignalSource(); - std::string role() + std::string role() override { return role_; } @@ -30,37 +60,37 @@ public: /*! * \brief Returns "Plutosdr_Signal_Source" */ - std::string implementation() + std::string implementation() override { return "Plutosdr_Signal_Source"; } - size_t item_size() + size_t item_size() override { return item_size_; } - void connect(gr::top_block_sptr top_block); - void disconnect(gr::top_block_sptr top_block); - gr::basic_block_sptr get_left_block(); - gr::basic_block_sptr get_right_block(); + 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; private: std::string role_; // Front-end settings - std::string uri_;//device direction - unsigned long freq_; //frequency of local oscilator - unsigned long sample_rate_; - unsigned long bandwidth_; - unsigned long buffer_size_; //reception buffer - unsigned int decimation_; - bool quadrature_; - bool rf_dc_; - bool bb_dc_; - std::string gain_mode_; - double rf_gain_; - std::string filter_file_; - bool filter_auto_; + std::string uri_; // device direction + unsigned long freq_; // frequency of local oscilator + unsigned long sample_rate_; + unsigned long bandwidth_; + unsigned long buffer_size_; // reception buffer + unsigned int decimation_; + bool quadrature_; + bool rf_dc_; + bool bb_dc_; + std::string gain_mode_; + double rf_gain_; + std::string filter_file_; + bool filter_auto_; unsigned int in_stream_; unsigned int out_stream_; @@ -71,7 +101,7 @@ private: bool dump_; std::string dump_filename_; - gr::iio::pluto_source::sptr plutosdr_source_; + gr::iio::pluto_source::sptr plutosdr_source_; boost::shared_ptr valve_; gr::blocks::file_sink::sptr file_sink_; From 16c0d5a2c8b19c3d1318472ab00d84f6e1099aa1 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 31 Oct 2017 07:23:43 +0100 Subject: [PATCH 77/81] Small fix --- src/algorithms/libs/rtklib/rtklib_rtksvr.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/algorithms/libs/rtklib/rtklib_rtksvr.cc b/src/algorithms/libs/rtklib/rtklib_rtksvr.cc index 0c2aabedf..23d1c188a 100644 --- a/src/algorithms/libs/rtklib/rtklib_rtksvr.cc +++ b/src/algorithms/libs/rtklib/rtklib_rtksvr.cc @@ -357,7 +357,7 @@ void decodefile(rtksvr_t *svr, int index) sbsigp_t sbsigp0[MAXNIGP] = {{{0, 0.0}, 0, 0, 0, 0.0 }}; sbsion_t sbsion0[MAXBAND+1] = {{0, 0, {*sbsigp0} }}; dgps_t dgps0[MAXSAT] = { {{0, 0.0}, 0.0, 0.0, 0, 0.0 }}; - ssr_t ssr0[MAXSAT] = {{ {{0, 0.0}}, {0.0}, {0}, 0, 0, 0, 0, {0.0}, {0.0}, {0.0}, 0.0, {0.0}, {0.0}, {0.0}, 0.0, 0.0, '0' }}; + ssr_t ssr0[MAXSAT] = {{ {{0, 0.0}}, {0.0}, {0}, 0, 0, 0, 0, {0.0}, {0.0}, {0.0}, 0.0, {0.0}, {0.0}, {0.0}, 0.0, 0.0, {'0'} }}; lexeph_t lexeph0[MAXSAT] = {{ {0,0.0}, {0,0.0}, 0, 0, 0, {0.0}, {0.0}, {0.0}, {0.0}, 0.0, 0.0, 0.0, {0.0} }}; stec_t stec0[MAXSTA] = {{ {0,0.0}, 0, 0.0, 0.0, {0.0}, 0}}; trop_t trop0[MAXSTA] = {{ {0, 0.0}, {0.0}, {0.0}}}; @@ -365,8 +365,8 @@ void decodefile(rtksvr_t *svr, int index) nav_t nav = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, (erpd_t *){0}}, {0.0}, {0.0}, {0.0}, {0.0}, {0.0}, {0.0}, {0.0}, {0.0}, - {0.0}, {0.0}, {0.0}, {0.0}, 0, {{0.0},{0.0}}, {{0.0},{0.0}}, {{0.0},{0.0},{0.0}}, - {0.0}, {0.0}, '0', {*pcvt0}, sbssat0, {*sbsion0}, {*dgps0}, {*ssr0}, {*lexeph0}, + {0.0}, {0.0}, {0.0}, {0.0}, 0, {{0.0},{0.0}}, {{0.0},{0.0}}, {{0.0}, {0.0}, {0.0}}, + {0.0}, {0.0}, {'0'}, {*pcvt0}, sbssat0, {*sbsion0}, {*dgps0}, {*ssr0}, {*lexeph0}, {{0,0.0}, 0.0, {0.0}, {{0.0},{0.0}} }, pppcorr0} ; char file[1024]; From 3ad5a99d0ab5413ebdee86f987a1074c27d5d7fb Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 31 Oct 2017 07:24:23 +0100 Subject: [PATCH 78/81] Use const iterators instead of iterators --- .../gnuradio_blocks/hybrid_observables_cc.cc | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc index 45cc3a3fc..9bc7f7e00 100644 --- a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc +++ b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc @@ -179,12 +179,11 @@ int hybrid_observables_cc::general_work (int noutput_items __attribute__((unused { channel_history_ok = false; } - } if (channel_history_ok == true) { - std::map::iterator gnss_synchro_map_iter; - std::deque::iterator gnss_synchro_deque_iter; + std::map::const_iterator gnss_synchro_map_iter; + std::deque::const_iterator gnss_synchro_deque_iter; // 1. If the RX time is not set, set the Rx time if (T_rx_s == 0) @@ -196,8 +195,8 @@ int hybrid_observables_cc::general_work (int noutput_items __attribute__((unused gnss_synchro_map.insert(std::pair(d_gnss_synchro_history_queue[i].front().Channel_ID, d_gnss_synchro_history_queue[i].front())); } - gnss_synchro_map_iter = min_element(gnss_synchro_map.begin(), - gnss_synchro_map.end(), + gnss_synchro_map_iter = min_element(gnss_synchro_map.cbegin(), + gnss_synchro_map.cend(), Hybrid_pairCompare_gnss_synchro_sample_counter); T_rx_s = static_cast(gnss_synchro_map_iter->second.Tracking_sample_counter) / static_cast(gnss_synchro_map_iter->second.fs); T_rx_s = floor(T_rx_s * 1000.0) / 1000.0; // truncate to ms @@ -210,11 +209,11 @@ int hybrid_observables_cc::general_work (int noutput_items __attribute__((unused // shift channels history to match the reference TOW for (unsigned int i = 0; i < d_nchannels; i++) { - gnss_synchro_deque_iter = std::lower_bound(d_gnss_synchro_history_queue[i].begin(), - d_gnss_synchro_history_queue[i].end(), + gnss_synchro_deque_iter = std::lower_bound(d_gnss_synchro_history_queue[i].cbegin(), + d_gnss_synchro_history_queue[i].cend(), T_rx_s, Hybrid_valueCompare_gnss_synchro_receiver_time); - if (gnss_synchro_deque_iter != d_gnss_synchro_history_queue[i].end()) + if (gnss_synchro_deque_iter != d_gnss_synchro_history_queue[i].cend()) { if (gnss_synchro_deque_iter->Flag_valid_word == true) { @@ -226,10 +225,10 @@ int hybrid_observables_cc::general_work (int noutput_items __attribute__((unused { // record the word structure in a map for pseudorange computation // save the previous observable - int distance = std::distance(d_gnss_synchro_history_queue[i].begin(), gnss_synchro_deque_iter); + int distance = std::distance(d_gnss_synchro_history_queue[i].cbegin(), gnss_synchro_deque_iter); if (distance > 0) { - if (d_gnss_synchro_history_queue[i].at(distance-1).Flag_valid_word) + if (d_gnss_synchro_history_queue[i].at(distance - 1).Flag_valid_word) { double T_rx_channel_prev = static_cast(d_gnss_synchro_history_queue[i].at(distance - 1).Tracking_sample_counter) / static_cast(gnss_synchro_deque_iter->fs); double delta_T_rx_s_prev = T_rx_channel_prev - T_rx_s; @@ -268,8 +267,8 @@ int hybrid_observables_cc::general_work (int noutput_items __attribute__((unused * common RX time algorithm */ // what is the most recent symbol TOW in the current set? -> this will be the reference symbol - gnss_synchro_map_iter = max_element(realigned_gnss_synchro_map.begin(), - realigned_gnss_synchro_map.end(), + gnss_synchro_map_iter = max_element(realigned_gnss_synchro_map.cbegin(), + realigned_gnss_synchro_map.cend(), Hybrid_pairCompare_gnss_synchro_d_TOW); double ref_fs_hz = static_cast(gnss_synchro_map_iter->second.fs); @@ -292,7 +291,7 @@ int hybrid_observables_cc::general_work (int noutput_items __attribute__((unused double channel_T_rx_s; double channel_fs_hz; double channel_TOW_s; - for(gnss_synchro_map_iter = realigned_gnss_synchro_map.begin(); gnss_synchro_map_iter != realigned_gnss_synchro_map.end(); gnss_synchro_map_iter++) + for(gnss_synchro_map_iter = realigned_gnss_synchro_map.cbegin(); gnss_synchro_map_iter != realigned_gnss_synchro_map.cend(); gnss_synchro_map_iter++) { channel_fs_hz = static_cast(gnss_synchro_map_iter->second.fs); channel_TOW_s = gnss_synchro_map_iter->second.TOW_at_current_symbol_s; From d2879010415d9cca34aca0bac27235d2cca9ba9f Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 31 Oct 2017 07:31:43 +0100 Subject: [PATCH 79/81] Add override keyword --- .../adapters/glonass_l1_ca_telemetry_decoder.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/algorithms/telemetry_decoder/adapters/glonass_l1_ca_telemetry_decoder.h b/src/algorithms/telemetry_decoder/adapters/glonass_l1_ca_telemetry_decoder.h index ddcc4dd40..6eef6e858 100644 --- a/src/algorithms/telemetry_decoder/adapters/glonass_l1_ca_telemetry_decoder.h +++ b/src/algorithms/telemetry_decoder/adapters/glonass_l1_ca_telemetry_decoder.h @@ -53,13 +53,13 @@ public: unsigned int out_streams); virtual ~GlonassL1CaTelemetryDecoder(); - std::string role() + std::string role() override { return role_; } //! Returns "GLONASS_L1_CA_Telemetry_Decoder" - std::string implementation() + std::string implementation() override { return "GLONASS_L1_CA_Telemetry_Decoder"; } @@ -69,11 +69,11 @@ public: gr::basic_block_sptr get_right_block() override; void set_satellite(const Gnss_Satellite & satellite) override; void set_channel(int channel) override {telemetry_decoder_->set_channel(channel);} - void reset() + void reset() override { return; } - size_t item_size() + size_t item_size() override { return 0; } From 468b24c3a1cf2902997d9eb4a630475da3756753 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 31 Oct 2017 07:47:56 +0100 Subject: [PATCH 80/81] Optimize with O2 when debugging --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3f0f4adec..30d4f6eaf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -279,7 +279,7 @@ endif(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "") # Append -O2 optimization flag for Debug builds -set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0") +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O2") # allow 'large' files in 32 bit builds if(UNIX) From ffde1309b9f3267236a21e7e77209f3a23d71683 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 31 Oct 2017 11:23:41 +0100 Subject: [PATCH 81/81] Fix compilation error --- src/algorithms/libs/rtklib/rtklib_rtksvr.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/algorithms/libs/rtklib/rtklib_rtksvr.cc b/src/algorithms/libs/rtklib/rtklib_rtksvr.cc index 23d1c188a..9026c5db2 100644 --- a/src/algorithms/libs/rtklib/rtklib_rtksvr.cc +++ b/src/algorithms/libs/rtklib/rtklib_rtksvr.cc @@ -357,7 +357,7 @@ void decodefile(rtksvr_t *svr, int index) sbsigp_t sbsigp0[MAXNIGP] = {{{0, 0.0}, 0, 0, 0, 0.0 }}; sbsion_t sbsion0[MAXBAND+1] = {{0, 0, {*sbsigp0} }}; dgps_t dgps0[MAXSAT] = { {{0, 0.0}, 0.0, 0.0, 0, 0.0 }}; - ssr_t ssr0[MAXSAT] = {{ {{0, 0.0}}, {0.0}, {0}, 0, 0, 0, 0, {0.0}, {0.0}, {0.0}, 0.0, {0.0}, {0.0}, {0.0}, 0.0, 0.0, {'0'} }}; + ssr_t ssr0[MAXSAT] = {{ {{0, 0.0}}, {0.0}, {0}, 0, 0, 0, 0, {0.0}, {0.0}, {0.0}, 0.0, {0.0}, {0.0}, {0.0}, 0.0, 0.0, '0' }}; lexeph_t lexeph0[MAXSAT] = {{ {0,0.0}, {0,0.0}, 0, 0, 0, {0.0}, {0.0}, {0.0}, {0.0}, 0.0, 0.0, 0.0, {0.0} }}; stec_t stec0[MAXSTA] = {{ {0,0.0}, 0, 0.0, 0.0, {0.0}, 0}}; trop_t trop0[MAXSTA] = {{ {0, 0.0}, {0.0}, {0.0}}};