From d8481d927b1429cdde32d7c6be2df9e09650cb10 Mon Sep 17 00:00:00 2001 From: Unknown Date: Mon, 16 Oct 2017 16:36:51 +0200 Subject: [PATCH] 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; +}