mirror of
				https://github.com/gnss-sdr/gnss-sdr
				synced 2025-10-31 15:23:04 +00:00 
			
		
		
		
	Added Notch Filter tests
Unit test fot Notch input filter
This commit is contained in:
		| @@ -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; |     noise_pow_est = 0.0; | ||||||
|     this->p_c_factor = gr_complex(p_c_factor , 0); |     this->p_c_factor = gr_complex(p_c_factor , 0); | ||||||
|     this->length_ = length_; //Set the number of samples per segment |     this->length_ = length_; //Set the number of samples per segment | ||||||
|     set_output_multiple(length_); |  | ||||||
|     filter_state_ = false; //Initial state of the filter |     filter_state_ = false; //Initial state of the filter | ||||||
|     n_deg_fred = 2 * length_; //Number of dregrees of freedom |     n_deg_fred = 2 * length_; //Number of dregrees of freedom | ||||||
|     n_segments = 0;  |     n_segments = 0;  | ||||||
| @@ -81,6 +80,14 @@ Notch::~Notch() | |||||||
|     volk_free(power_spect); |     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)), | 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_vector_const_void_star &input_items, gr_vector_void_star &output_items) | ||||||
| { | { | ||||||
|   | |||||||
| @@ -71,6 +71,8 @@ public: | |||||||
|      |      | ||||||
|     ~Notch(); |     ~Notch(); | ||||||
|      |      | ||||||
|  |     void forecast(int noutput_items, gr_vector_int &ninput_items_required); | ||||||
|  |      | ||||||
|     int general_work (int noutput_items, gr_vector_int &ninput_items,  |     int general_work (int noutput_items, gr_vector_int &ninput_items,  | ||||||
|                       gr_vector_const_void_star &input_items, |                       gr_vector_const_void_star &input_items, | ||||||
|                       gr_vector_void_star &output_items); |                       gr_vector_void_star &output_items); | ||||||
|   | |||||||
| @@ -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/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/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/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/pass_through_test.cc | ||||||
|                                     ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/adapter/adapter_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 |                                     ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/control-plane/gnss_block_factory_test.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/fir_filter_test.cc" | ||||||
| #include "unit-tests/signal-processing-blocks/filter/pulse_blanking_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" | #include "unit-tests/signal-processing-blocks/resampler/direct_resampler_conditioner_cc_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 <http://www.gnu.org/licenses/>. | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include <chrono> | ||||||
|  | #include <complex> | ||||||
|  | #include <iostream> | ||||||
|  | #include <stdint.h> | ||||||
|  | #include <gflags/gflags.h> | ||||||
|  | #include <gnuradio/top_block.h> | ||||||
|  | #include <gnuradio/analog/sig_source_waveform.h> | ||||||
|  | #include <gnuradio/analog/sig_source_c.h> | ||||||
|  | #include <gnuradio/msg_queue.h> | ||||||
|  | #include <gnuradio/blocks/null_sink.h> | ||||||
|  | #include <gtest/gtest.h> | ||||||
|  | #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<InMemoryConfiguration>(); | ||||||
|  |         nsamples = FLAGS_notch_filter_test_nsamples; | ||||||
|  |     } | ||||||
|  |     ~NotchFilterTest() | ||||||
|  |     {} | ||||||
|  |  | ||||||
|  |     void init(); | ||||||
|  |     void configure_gr_complex_gr_complex(); | ||||||
|  |     boost::shared_ptr<gr::msg_queue> queue; | ||||||
|  |     gr::top_block_sptr top_block; | ||||||
|  |     std::shared_ptr<InMemoryConfiguration> 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<NotchFilter> 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<std::chrono::system_clock> start, end; | ||||||
|  |     std::chrono::duration<double> elapsed_seconds(0); | ||||||
|  |     top_block = gr::make_top_block("Notch filter test"); | ||||||
|  |     init(); | ||||||
|  |     configure_gr_complex_gr_complex(); | ||||||
|  |     std::shared_ptr<NotchFilter> filter = std::make_shared<NotchFilter>(config.get(), "InputFilter", 1, 1); | ||||||
|  |     item_size = sizeof(gr_complex); | ||||||
|  |     ASSERT_NO_THROW( { | ||||||
|  |         filter->connect(top_block); | ||||||
|  |         boost::shared_ptr<gr::block> 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<gr::block> valve = gnss_sdr_make_valve(sizeof(gr_complex), nsamples, queue); | ||||||
|  |         boost::shared_ptr<gr::block> 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<std::chrono::system_clock> start, end; | ||||||
|  |     std::chrono::duration<double> elapsed_seconds(0); | ||||||
|  |     top_block = gr::make_top_block("Notch filter test"); | ||||||
|  |     init(); | ||||||
|  |     configure_gr_complex_gr_complex(); | ||||||
|  |     std::shared_ptr<NotchFilter> filter = std::make_shared<NotchFilter>(config.get(), "InputFilter", 1, 1); | ||||||
|  |     std::shared_ptr<InMemoryConfiguration> config2 = std::make_shared<InMemoryConfiguration>(); | ||||||
|  |  | ||||||
|  |     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<FileSignalSource> source(new FileSignalSource(config2.get(), "Test_Source", 1, 1, queue)); | ||||||
|  |         source->connect(top_block); | ||||||
|  |  | ||||||
|  |         boost::shared_ptr<gr::block> 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; | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user
	 Unknown
					Unknown