1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2025-10-23 19:47:40 +00:00

Added freq_xlating_fir_filter class, this class implements a FIR filter and a composite frequency translation that shifts center_frequency down to zero Hz.

git-svn-id: https://svn.code.sf.net/p/gnss-sdr/code/trunk@215 64b25241-fba3-4117-9849-534c7e92360d
This commit is contained in:
Luis Esteve
2012-07-18 13:29:18 +00:00
parent 5ff5e8e7bd
commit 6f7b4f5aea
9 changed files with 495 additions and 72 deletions

View File

@@ -0,0 +1,189 @@
/*!
* \file freq_xlating_fir_filter.cc
* \brief Adapts a gnuradio gr_freq_xlating_fir_filter designed with gr_remez
* \author Luis Esteve, 2012. luis(at)epsilon-formacion.com
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2012 (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 "freq_xlating_fir_filter.h"
#include "configuration_interface.h"
#include <string>
#include <boost/lexical_cast.hpp>
#include <gnuradio/gr_io_signature.h>
#include <gnuradio/gr_file_sink.h>
#include <gnuradio/gr_remez.h>
#include <glog/log_severity.h>
#include <glog/logging.h>
using google::LogMessage;
FreqXlatingFirFilter::FreqXlatingFirFilter(ConfigurationInterface* configuration, std::string role,
unsigned int in_streams, unsigned int out_streams,
gr_msg_queue_sptr queue) :
config_(configuration), role_(role), in_streams_(in_streams),
out_streams_(out_streams), queue_(queue)
{
size_t item_size;
(*this).init();
if ((taps_item_type_.compare("float") == 0) && (input_item_type_.compare(
"gr_complex") == 0) && (output_item_type_.compare("gr_complex")
== 0))
{
item_size = sizeof(gr_complex);
freq_xlating_fir_filter_ccf_ = gr_make_freq_xlating_fir_filter_ccf(1, taps_, center_freq_, sampling_freq_);
DLOG(INFO) << "input_filter(" << freq_xlating_fir_filter_ccf_->unique_id() << ")";
}
else
{
LOG_AT_LEVEL(ERROR) << taps_item_type_
<< " unknown input filter item type";
}
if (dump_)
{
DLOG(INFO) << "Dumping output into file " << dump_filename_;
file_sink_ = gr_make_file_sink(item_size, dump_filename_.c_str());
}
}
FreqXlatingFirFilter::~FreqXlatingFirFilter()
{}
void FreqXlatingFirFilter::connect(gr_top_block_sptr top_block)
{
if (dump_)
{
top_block->connect(freq_xlating_fir_filter_ccf_, 0, file_sink_, 0);
}
else
{
DLOG(INFO) << "Nothing to connect internally";
}
}
void FreqXlatingFirFilter::disconnect(gr_top_block_sptr top_block)
{
if (dump_)
{
top_block->connect(freq_xlating_fir_filter_ccf_, 0, file_sink_, 0);
}
}
gr_basic_block_sptr FreqXlatingFirFilter::get_left_block()
{
return freq_xlating_fir_filter_ccf_;
}
gr_basic_block_sptr FreqXlatingFirFilter::get_right_block()
{
return freq_xlating_fir_filter_ccf_;
}
void FreqXlatingFirFilter::init()
{
std::string default_input_item_type = "gr_complex";
std::string default_output_item_type = "gr_complex";
std::string default_taps_item_type = "float";
std::string default_dump_filename = "../data/input_filter.dat";
double default_center_freq = 0;
double default_sampling_freq = 4000000;
int default_number_of_taps = 6;
unsigned int default_number_of_bands = 2;
std::vector<double> default_bands = { 0.0, 0.4, 0.6, 1.0 };
std::vector<double> default_ampl = { 1.0, 1.0, 0.0, 0.0 };
std::vector<double> default_error_w = { 1.0, 1.0 };
std::string default_filter_type = "bandpass";
int default_grid_density = 16;
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);
taps_item_type_ = config_->property(role_ + ".taps_item_type",
default_taps_item_type);
dump_ = config_->property(role_ + ".dump", false);
dump_filename_ = config_->property(role_ + ".dump_filename",
default_dump_filename);
center_freq_ = config_->property(role_ + ".center_frequency",
default_center_freq);
sampling_freq_ = config_->property(role_ + ".sampling_frequency",
default_sampling_freq);
int number_of_taps = config_->property(role_ + ".number_of_taps",
default_number_of_taps);
unsigned int number_of_bands = config_->property(role_ + ".number_of_bands",
default_number_of_bands);
std::vector<double> bands;
std::vector<double> ampl;
std::vector<double> error_w;
std::string option;
double option_value;
for (unsigned int i = 0; i < number_of_bands; i++)
{
option = ".band" + boost::lexical_cast<std::string>(i + 1) + "_begin";
option_value = config_->property(role_ + option, default_bands[i]);
bands.push_back(option_value);
option = ".band" + boost::lexical_cast<std::string>(i + 1) + "_end";
option_value = config_->property(role_ + option, default_bands[i]);
bands.push_back(option_value);
option = ".ampl" + boost::lexical_cast<std::string>(i + 1) + "_begin";
option_value = config_->property(role_ + option, default_bands[i]);
ampl.push_back(option_value);
option = ".ampl" + boost::lexical_cast<std::string>(i + 1) + "_end";
option_value = config_->property(role_ + option, default_bands[i]);
ampl.push_back(option_value);
option = ".band" + boost::lexical_cast<std::string>(i + 1) + "_error";
option_value = config_->property(role_ + option, default_bands[i]);
error_w.push_back(option_value);
}
std::string filter_type = config_->property(role_ + ".filter_type", default_filter_type);
int grid_density = config_->property(role_ + ".grid_density", default_grid_density);
std::vector<double> taps_d = gr_remez(number_of_taps - 1, bands, ampl,
error_w, filter_type, grid_density);
taps_.reserve(taps_d.size());
for (std::vector<double>::iterator it = taps_d.begin(); it != taps_d.end(); it++)
{
taps_.push_back(float(*it));
}
}

View File

@@ -0,0 +1,108 @@
/*!
* \file freq_xlating_fir_filter.h
* \brief Adapts a gnuradio gr_freq_xlating_fir_filter designed with gr_remez
* \author Luis Esteve, 2012. luis(at)epsilon-formacion.com
*
* Detailed description of the file here if needed.
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2012 (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/>.
*
* -------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_FREQ_XLATING_FIR_FILTER_H_
#define GNSS_SDR_FREQ_XLATING_FIR_FILTER_H_
#include "gnss_synchro.h"
#include "gnss_block_interface.h"
#include <gnuradio/gr_freq_xlating_fir_filter_ccc.h>
#include <gnuradio/gr_freq_xlating_fir_filter_ccf.h>
#include <gnuradio/gr_freq_xlating_fir_filter_fcc.h>
#include <gnuradio/gr_freq_xlating_fir_filter_scc.h>
#include <gnuradio/gr_msg_queue.h>
class ConfigurationInterface;
/*!
* \brief This class adapts a gnuradio gr_freq_xlating_fir_filter designed with gr_remez
*
* Construct a FIR filter with the given taps and a composite frequency
* translation that shifts center_freq down to zero Hz. The frequency
* translation logically comes before the filtering operation.
*
* See Parks-McClellan FIR filter design, http://en.wikipedia.org/wiki/Parks-McClellan_filter_design_algorithm
* Calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse response
* given a set of band edges, the desired response on those bands, and the weight given
* to the error in those bands.
*/
class FreqXlatingFirFilter: public GNSSBlockInterface
{
public:
FreqXlatingFirFilter(ConfigurationInterface* configuration,
std::string role, unsigned int in_streams,
unsigned int out_streams, gr_msg_queue_sptr queue);
virtual ~FreqXlatingFirFilter();
std::string role()
{
return role_;
}
std::string implementation()
{
return "Freq_Xlating_Fir_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:
gr_freq_xlating_fir_filter_ccf_sptr freq_xlating_fir_filter_ccf_;
ConfigurationInterface* config_;
bool dump_;
std::string dump_filename_;
std::string input_item_type_;
std::string output_item_type_;
std::string taps_item_type_;
std::vector <float> taps_;
double center_freq_;
double sampling_freq_;
std::string role_;
unsigned int in_streams_;
unsigned int out_streams_;
gr_msg_queue_sptr queue_;
gr_block_sptr file_sink_;
void init();
};
#endif // GNSS_SDR_FREQ_XLATING_FIR_FILTER_H_

View File

@@ -1,3 +1,4 @@
project : build-dir ../../../../build ;
obj fir_filter : fir_filter.cc ;
obj fir_filter : fir_filter.cc ;
obj freq_xlating_fir_filter : freq_xlating_fir_filter.cc ;

View File

@@ -51,6 +51,7 @@
#include "signal_conditioner.h"
#include "direct_resampler_conditioner.h"
#include "fir_filter.h"
#include "freq_xlating_fir_filter.h"
#include "gps_l1_ca_pcps_acquisition.h"
#include "gps_l1_ca_dll_pll_tracking.h"
#include "gps_l1_ca_dll_fll_pll_tracking.h"
@@ -91,12 +92,27 @@ GNSSBlockInterface* GNSSBlockFactory::GetSignalConditioner(
{
std::string default_implementation = "Pass_Through";
std::string data_type_adapter = configuration->property(
"DataTypeAdapter.implementation", default_implementation);
std::string input_filter = configuration->property(
"InputFilter.implementation", default_implementation);
std::string resampler = configuration->property(
"Resampler.implementation", default_implementation);
std::string signal_conditioner = configuration->property(
"SignalConditioner.implementation", default_implementation);
std::string data_type_adapter;
std::string input_filter;
std::string resampler;
if(signal_conditioner.compare("Pass_Through")==0)
{
data_type_adapter = "Pass_Through";
input_filter = "Pass_Through";
resampler = "Pass_Through";
}
else
{
data_type_adapter = configuration->property(
"DataTypeAdapter.implementation", default_implementation);
input_filter = configuration->property(
"InputFilter.implementation", default_implementation);
resampler = configuration->property(
"Resampler.implementation", default_implementation);
}
DLOG(INFO) << "Getting SignalConditioner with DataTypeAdapter implementation: "
<< data_type_adapter << ", InputFilter implementation: "
@@ -271,6 +287,12 @@ GNSSBlockInterface* GNSSBlockFactory::GetBlock(
block = new FirFilter(configuration, role, in_streams,
out_streams, queue);
}
else if (implementation.compare("Freq_Xlating_Fir_Filter") == 0)
{
block = new FreqXlatingFirFilter(configuration, role, in_streams,
out_streams, queue);
}
// RESAMPLER -------------------------------------------------------------------

View File

@@ -7,6 +7,7 @@ exe gnss-sdr : main.cc
../algorithms/channel/libs//gps_l1_ca_channel_fsm
../algorithms/conditioner/adapters//signal_conditioner
../algorithms/input_filter/adapters//fir_filter
../algorithms/input_filter/adapters//freq_xlating_fir_filter
../algorithms/libs//gnss_signal_processing
../algorithms/libs//gps_sdr_signal_processing
../algorithms/libs//galileo_e1_signal_processing

View File

@@ -150,6 +150,46 @@ TEST(GNSS_Block_Factory_Test, InstantiateFIRFilter) {
delete input_filter;
}
TEST(GNSS_Block_Factory_Test, InstantiateFreqXlatingFIRFilter) {
InMemoryConfiguration *configuration = new InMemoryConfiguration();
gr_msg_queue_sptr queue = gr_make_msg_queue(0);
configuration->set_property("InputFilter.implementation", "Freq_Xlating_Fir_Filter");
configuration->set_property("InputFilter.number_of_taps", "4");
configuration->set_property("InputFilter.number_of_bands", "2");
configuration->set_property("InputFilter.band1_begin", "0.0");
configuration->set_property("InputFilter.band1_end", "0.45");
configuration->set_property("InputFilter.band2_begin", "0.55");
configuration->set_property("InputFilter.band2_end", "1.0");
configuration->set_property("InputFilter.ampl1_begin", "1.0");
configuration->set_property("InputFilter.ampl1_end", "1.0");
configuration->set_property("InputFilter.ampl2_begin", "0.0");
configuration->set_property("InputFilter.ampl2_end", "0.0");
configuration->set_property("InputFilter.band1_error", "1.0");
configuration->set_property("InputFilter.band2_error", "1.0");
configuration->set_property("InputFilter.filter_type", "bandpass");
configuration->set_property("InputFilter.grid_density", "16");
configuration->set_property("InputFilter.sampling_frequency","4000000");
configuration->set_property("InputFilter.center_frequency","34000");
GNSSBlockFactory *factory = new GNSSBlockFactory();
GNSSBlockInterface *input_filter = factory->GetBlock(configuration, "InputFilter", "Freq_Xlating_Fir_Filter", 1,1, queue);
EXPECT_STREQ("InputFilter", input_filter->role().c_str());
EXPECT_STREQ("Freq_Xlating_Fir_Filter", input_filter->implementation().c_str());
delete configuration;
delete factory;
delete input_filter;
}
TEST(GNSS_Block_Factory_Test, InstantiateDirectResampler) {
InMemoryConfiguration *configuration = new InMemoryConfiguration();

View File

@@ -8,6 +8,7 @@ exe run_tests : test_main.cc
../algorithms/channel/libs//gps_l1_ca_channel_fsm
../algorithms/conditioner/adapters//signal_conditioner
../algorithms/input_filter/adapters//fir_filter
../algorithms/input_filter/adapters//freq_xlating_fir_filter
../algorithms/libs//gnss_signal_processing
../algorithms/libs//gps_sdr_signal_processing
../algorithms/libs//galileo_e1_signal_processing