From 6f7b4f5aea812d3e82a5f0a824f95b0b65434220 Mon Sep 17 00:00:00 2001 From: Luis Esteve Date: Wed, 18 Jul 2012 13:29:18 +0000 Subject: [PATCH] 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 --- conf/gnss-sdr.conf | 51 +++-- conf/master.conf | 140 ++++++++----- .../adapters/freq_xlating_fir_filter.cc | 189 ++++++++++++++++++ .../adapters/freq_xlating_fir_filter.h | 108 ++++++++++ .../input_filter/adapters/jamfile.jam | 3 +- src/core/receiver/gnss_block_factory.cc | 34 +++- src/main/jamfile.jam | 1 + .../gnss_block/gnss_block_factory_test.cc | 40 ++++ src/tests/jamfile.jam | 1 + 9 files changed, 495 insertions(+), 72 deletions(-) create mode 100644 src/algorithms/input_filter/adapters/freq_xlating_fir_filter.cc create mode 100644 src/algorithms/input_filter/adapters/freq_xlating_fir_filter.h diff --git a/conf/gnss-sdr.conf b/conf/gnss-sdr.conf index 1b4decec3..35ad817b0 100644 --- a/conf/gnss-sdr.conf +++ b/conf/gnss-sdr.conf @@ -2,7 +2,7 @@ ; You can define your own receiver and invoke it by doing ; gnss-sdr --config_file=my_GNSS_SDR_configuration.conf ; -; See examples at conf/master.conf + [GNSS-SDR] ;######### GLOBAL OPTIONS ################## @@ -17,13 +17,13 @@ ControlThread.wait_for_flowgraph=false SignalSource.implementation=File_Signal_Source ;#filename: path to file with the captured GNSS signal samples to be processed -SignalSource.filename=../data/agilent_cap2.dat +SignalSource.filename=../data/my_capture.dat ;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. SignalSource.item_type=gr_complex ;#sampling_frequency: Original Signal sampling frequency in [Hz] -SignalSource.sampling_frequency=4000000 +SignalSource.sampling_frequency=8000000 ;#freq: RF front-end center frequency in [Hz] SignalSource.freq=1575420000 @@ -53,8 +53,10 @@ SignalSource.enable_throttle_control=false ;######### SIGNAL_CONDITIONER CONFIG ############ ;## It holds blocks to change data type, filter and resample input data. -;#implementation: Pass_Through disables this block -SignalConditioner.implementation=Pass_Through +;#implementation: Pass_Through disables this block and the Data_Type_adapter, Input_Filter and Resampler blocks +;#implementation: Signal_Conditioner enables this block. Then you have to configure Data_Type_adapter, Input_Filter and Resampler blocks +SignalConditioner.implementation=Signal_Conditioner +;SignalConditioner.implementation=Pass_Through ;######### DATA_TYPE_ADAPTER CONFIG ############ ;## Changes the type of input data. Please disable it in this version. @@ -65,7 +67,11 @@ DataTypeAdapter.implementation=Pass_Through ;## Filter the input data. Can be combined with frequency translation for IF signals ;#implementation: Pass_Through disables this block +;#implementation: Fir_Filter enables a FIR Filter +;#implementation: Freq_Xlating_Fir_Filter enables FIR filter and a composite frequency translation that shifts center_frequency down to zero Hz. + ;InputFilter.implementation=Fir_Filter +;InputFilter.implementation=Freq_Xlating_Fir_Filter InputFilter.implementation=Pass_Through ;#dump: Dump the filtered data to a file. @@ -74,7 +80,7 @@ InputFilter.dump=false ;#dump_filename: Log path and filename. InputFilter.dump_filename=../data/input_filter.dat -;#The following options are used in the filter design of Fir_Filter implementation. +;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. ;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse reponse given a set of band edges, the desired reponse on those bands, and the weight given to the error in those bands. @@ -122,12 +128,21 @@ InputFilter.filter_type=bandpass ;The minimum value is 16; higher values are slower to compute the filter. InputFilter.grid_density=16 +;#The following options are used only in Freq_Xlating_Fir_Filter implementation. +;#InputFilter.center_frequency is the frequency (in Hz) shifted down to zero Hz + +InputFilter.sampling_frequency=8000000 +InputFilter.center_frequency=0 + + + ;######### RESAMPLER CONFIG ############ ;## Resamples the input data. ;#implementation: Pass_Through disables this block -;Resampler.implementation=Direct_Resampler -Resampler.implementation=Pass_Through +;#implementation: Direct_Resampler enables a resampler that implements a nearest neigbourhood interpolation +Resampler.implementation=Direct_Resampler +;Resampler.implementation=Pass_Through ;#dump: Dump the filtered data to a file. InputFilter.dump=false @@ -138,7 +153,7 @@ InputFilter.dump=../data/resampler.dat Resampler.item_type=gr_complex ;#sample_freq_in: the sample frequency of the input signal -Resampler.sample_freq_in=4000000 +Resampler.sample_freq_in=8000000 ;#sample_freq_out: the desired sample frequency of the output signal Resampler.sample_freq_out=4000000 @@ -147,7 +162,7 @@ Resampler.sample_freq_out=4000000 ;######### CHANNELS GLOBAL CONFIG ############ ;#count: Number of available satellite channels. Channels.count=5 -Channels.in_acquisition=5 +Channels.in_acquisition=1 ;######### CHANNEL 0 CONFIG ############ ;#system: GPS, GLONASS, GALILEO, SBAS or COMPASS @@ -245,7 +260,7 @@ Channel4.signal=1C Channel4.satellite=3 Channel4.repeat_satellite=false -;######### CHANNEL 3 CONFIG ############ +;######### CHANNEL 5 CONFIG ############ Channel5.system=GPS Channel5.signal=1C @@ -272,7 +287,7 @@ Acquisition.sampled_ms=1 ;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] Acquisition0.implementation=GPS_L1_CA_PCPS_Acquisition ;#threshold: Acquisition threshold -Acquisition0.threshold=70 +Acquisition0.threshold=50 ;#doppler_max: Maximum expected Doppler shift [Hz] Acquisition0.doppler_max=10000 ;#doppler_max: Doppler step in the grid search [Hz] @@ -282,35 +297,35 @@ Acquisition0.doppler_step=250 ;######### ACQUISITION CH 1 CONFIG ############ Acquisition1.implementation=GPS_L1_CA_PCPS_Acquisition -Acquisition1.threshold=70 +Acquisition1.threshold=50 Acquisition1.doppler_max=10000 Acquisition1.doppler_step=250 ;######### ACQUISITION CH 2 CONFIG ############ Acquisition2.implementation=GPS_L1_CA_PCPS_Acquisition -Acquisition2.threshold=70 +Acquisition2.threshold=50 Acquisition2.doppler_max=10000 Acquisition2.doppler_step=250 ;######### ACQUISITION CH 3 CONFIG ############ Acquisition3.implementation=GPS_L1_CA_PCPS_Acquisition -Acquisition3.threshold=70 +Acquisition3.threshold=50 Acquisition3.doppler_max=10000 Acquisition3.doppler_step=250 ;######### ACQUISITION CH 4 CONFIG ############ Acquisition4.implementation=GPS_L1_CA_PCPS_Acquisition -Acquisition4.threshold=70 +Acquisition4.threshold=50 Acquisition4.doppler_max=10000 Acquisition4.doppler_step=250 ;######### ACQUISITION CH 5 CONFIG ############ Acquisition5.implementation=GPS_L1_CA_PCPS_Acquisition -Acquisition5.threshold=70 +Acquisition5.threshold=50 Acquisition5.doppler_max=10000 Acquisition5.doppler_step=250 @@ -410,4 +425,4 @@ PVT.dump_filename=./PVT ;# Receiver output filter: Leave this block disabled in this version OutputFilter.implementation=Null_Sink_Output_Filter OutputFilter.filename=data/gnss-sdr.dat -OutputFilter.item_type=gr_complex \ No newline at end of file +OutputFilter.item_type=gr_complex diff --git a/conf/master.conf b/conf/master.conf index 8f47a841a..23a434f89 100644 --- a/conf/master.conf +++ b/conf/master.conf @@ -7,13 +7,13 @@ ;######### GLOBAL OPTIONS ################## ;internal_fs_hz: Internal signal sampling frequency after the signal conditioning stage [Hz]. -GNSS-SDR.internal_fs_hz=2046000 +GNSS-SDR.internal_fs_hz=4000000 ;######### CONTROL_THREAD CONFIG ############ ControlThread.wait_for_flowgraph=false ;######### SIGNAL_SOURCE CONFIG ############ -;#implementation: Use only File_Signal_Source in this version +;#implementation: Use File_Signal_Source or UHD_Signal_Source or GN3S_Signal_Source (experimental) SignalSource.implementation=File_Signal_Source ;#filename: path to file with the captured GNSS signal samples to be processed @@ -23,7 +23,16 @@ SignalSource.filename=../data/my_capture.dat SignalSource.item_type=gr_complex ;#sampling_frequency: Original Signal sampling frequency in [Hz] -SignalSource.sampling_frequency=4000000 +SignalSource.sampling_frequency=8000000 + +;#freq: RF front-end center frequency in [Hz] +SignalSource.freq=1575420000 + +;#gain: Front-end Gain in [dB] +SignalSource.gain=60 + +;#subdevice: UHD subdevice specification (for USRP1 use A:0 or B:0) +SignalSource.subdevice=B:0 ;#samples: Number of samples to be processed. Notice that 0 indicates the entire file. SignalSource.samples=0 @@ -34,14 +43,20 @@ SignalSource.repeat=false ;#dump: Dump the Signal source data to a file. Disable this option in this version SignalSource.dump=false +SignalSource.dump_filename=../data/signal_source.dat + + ;#enable_throttle_control: Enabling this option tells the signal source to keep the delay between samples in post processing. ; it helps to not overload the CPU, but the processing time will be longer. SignalSource.enable_throttle_control=false + ;######### SIGNAL_CONDITIONER CONFIG ############ ;## It holds blocks to change data type, filter and resample input data. -;#implementation: Pass_Through disables this block +;#implementation: Pass_Through disables this block and the Data_Type_adapter, Input_Filter and Resampler blocks +;#implementation: Signal_Conditioner enables this block. Then you have to configure Data_Type_adapter, Input_Filter and Resampler blocks SignalConditioner.implementation=Signal_Conditioner +;SignalConditioner.implementation=Pass_Through ;######### DATA_TYPE_ADAPTER CONFIG ############ ;## Changes the type of input data. Please disable it in this version. @@ -52,16 +67,20 @@ DataTypeAdapter.implementation=Pass_Through ;## Filter the input data. Can be combined with frequency translation for IF signals ;#implementation: Pass_Through disables this block +;#implementation: Fir_Filter enables a FIR Filter +;#implementation: Freq_Xlating_Fir_Filter enables FIR filter and a composite frequency translation that shifts center_frequency down to zero Hz. + ;InputFilter.implementation=Fir_Filter +;InputFilter.implementation=Freq_Xlating_Fir_Filter InputFilter.implementation=Pass_Through ;#dump: Dump the filtered data to a file. InputFilter.dump=false ;#dump_filename: Log path and filename. -InputFilter.dump=../data/input_filter.dat +InputFilter.dump_filename=../data/input_filter.dat -;#The following options are used in the filter design of Fir_Filter implementation. +;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. ;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse reponse given a set of band edges, the desired reponse on those bands, and the weight given to the error in those bands. @@ -109,10 +128,19 @@ InputFilter.filter_type=bandpass ;The minimum value is 16; higher values are slower to compute the filter. InputFilter.grid_density=16 +;#The following options are used only in Freq_Xlating_Fir_Filter implementation. +;#InputFilter.center_frequency is the frequency (in Hz) shifted down to zero Hz + +InputFilter.sampling_frequency=8000000 +InputFilter.center_frequency=0 + + + ;######### RESAMPLER CONFIG ############ ;## Resamples the input data. ;#implementation: Pass_Through disables this block +;#implementation: Direct_Resampler enables a resampler that implements a nearest neigbourhood interpolation Resampler.implementation=Direct_Resampler ;Resampler.implementation=Pass_Through @@ -125,15 +153,16 @@ InputFilter.dump=../data/resampler.dat Resampler.item_type=gr_complex ;#sample_freq_in: the sample frequency of the input signal -Resampler.sample_freq_in=4000000 +Resampler.sample_freq_in=8000000 ;#sample_freq_out: the desired sample frequency of the output signal -Resampler.sample_freq_out=2046000 +Resampler.sample_freq_out=4000000 ;######### CHANNELS GLOBAL CONFIG ############ ;#count: Number of available satellite channels. -Channels.count=4 +Channels.count=5 +Channels.in_acquisition=1 ;######### CHANNEL 0 CONFIG ############ ;#system: GPS, GLONASS, GALILEO, SBAS or COMPASS @@ -200,42 +229,55 @@ Channel0.system=GPS Channel0.signal=1C ;#satellite: Satellite PRN ID for this channel. Disable this option to random search -Channel0.satellite=2 +Channel0.satellite=15 +Channel0.repeat_satellite=false ;######### CHANNEL 1 CONFIG ############ Channel1.system=GPS Channel1.signal=1C -Channel1.satellite=14 +Channel1.satellite=18 +Channel1.repeat_satellite=false ;######### CHANNEL 2 CONFIG ############ Channel2.system=GPS Channel2.signal=1C -Channel2.satellite=21 +Channel2.satellite=16 +Channel2.repeat_satellite=false ;######### CHANNEL 3 CONFIG ############ Channel3.system=GPS Channel3.signal=1C -Channel3.satellite=13 +Channel3.satellite=21 +Channel3.repeat_satellite=false + +;######### CHANNEL 4 CONFIG ############ + +Channel4.system=GPS +Channel4.signal=1C +Channel4.satellite=3 +Channel4.repeat_satellite=false + +;######### CHANNEL 5 CONFIG ############ + +Channel5.system=GPS +Channel5.signal=1C +;Channel5.satellite=21 +;Channel5.repeat_satellite=false ;######### ACQUISITION GLOBAL CONFIG ############ ;#dump: Enable or disable the acquisition internal data file logging [true] or [false] Acquisition.dump=false - ;#filename: Log path and filename Acquisition.dump_filename=./acq_dump.dat - ;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. Acquisition.item_type=gr_complex - - ;#if: Signal intermediate frequency in [Hz] Acquisition.if=0 - ;#sampled_ms: Signal block duration for the acquisition signal detection [ms] Acquisition.sampled_ms=1 @@ -244,68 +286,71 @@ Acquisition.sampled_ms=1 ;######### ACQUISITION CH 0 CONFIG ############ ;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] Acquisition0.implementation=GPS_L1_CA_PCPS_Acquisition - ;#threshold: Acquisition threshold -Acquisition0.threshold=70 - +Acquisition0.threshold=60 ;#doppler_max: Maximum expected Doppler shift [Hz] Acquisition0.doppler_max=10000 - ;#doppler_max: Doppler step in the grid search [Hz] Acquisition0.doppler_step=250 - ;#repeat_satellite: Use only jointly with the satellte PRN ID option. -;#Enable repeat_satellite to keep searching the same satellite during the runtime. -;Acquisition0.repeat_satellite=true + ;######### ACQUISITION CH 1 CONFIG ############ Acquisition1.implementation=GPS_L1_CA_PCPS_Acquisition -Acquisition1.threshold=70 +Acquisition1.threshold=60 Acquisition1.doppler_max=10000 Acquisition1.doppler_step=250 -;Acquisition1.repeat_satellite=true + ;######### ACQUISITION CH 2 CONFIG ############ Acquisition2.implementation=GPS_L1_CA_PCPS_Acquisition -Acquisition2.threshold=70 +Acquisition2.threshold=60 Acquisition2.doppler_max=10000 Acquisition2.doppler_step=250 -;Acquisition2.repeat_satellite=true + ;######### ACQUISITION CH 3 CONFIG ############ Acquisition3.implementation=GPS_L1_CA_PCPS_Acquisition -Acquisition3.threshold=70 +Acquisition3.threshold=60 Acquisition3.doppler_max=10000 Acquisition3.doppler_step=250 -;Acquisition3.repeat_satellite=true + ;######### ACQUISITION CH 4 CONFIG ############ Acquisition4.implementation=GPS_L1_CA_PCPS_Acquisition -Acquisition4.threshold=70 +Acquisition4.threshold=60 Acquisition4.doppler_max=10000 Acquisition4.doppler_step=250 -;Acquisition4.repeat_satellite=true + ;######### ACQUISITION CH 5 CONFIG ############ Acquisition5.implementation=GPS_L1_CA_PCPS_Acquisition -Acquisition5.threshold=70 +Acquisition5.threshold=60 Acquisition5.doppler_max=10000 Acquisition5.doppler_step=250 -;Acquisition5.repeat_satellite=true + ;######### ACQUISITION CH 6 CONFIG ############ Acquisition6.implementation=GPS_L1_CA_PCPS_Acquisition Acquisition6.threshold=70 Acquisition6.doppler_max=10000 Acquisition6.doppler_step=250 -;Acquisition6.repeat_satellite=true + ;######### ACQUISITION CH 7 CONFIG ############ Acquisition7.implementation=GPS_L1_CA_PCPS_Acquisition Acquisition7.threshold=70 Acquisition7.doppler_max=10000 Acquisition7.doppler_step=250 -;Acquisition7.repeat_satellite=true + + +;######### ACQUISITION CH 8 CONFIG ############ +Acquisition8.implementation=GPS_L1_CA_PCPS_Acquisition +Acquisition8.threshold=70 +Acquisition8.doppler_max=10000 +Acquisition8.doppler_step=250 + + ;######### TRACKING GLOBAL CONFIG ############ @@ -330,10 +375,10 @@ Tracking.pll_bw_hz=50.0; Tracking.dll_bw_hz=2.0; ;#fll_bw_hz: FLL loop filter bandwidth [Hz] -Tracking.fll_bw_hz=20.0; +Tracking.fll_bw_hz=10.0; ;#order: PLL/DLL loop filter order [2] or [3] -Tracking.order=2; +Tracking.order=3; ;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] Tracking.early_late_space_chips=0.5; @@ -341,17 +386,12 @@ Tracking.early_late_space_chips=0.5; ;######### TELEMETRY DECODER CONFIG ############ ;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A. TelemetryDecoder.implementation=GPS_L1_CA_Telemetry_Decoder - -;#fs_in: Signal sampling frequency in [Hz] -TelemetryDecoder.fs_in=4000000 +TelemetryDecoder.dump=false ;######### OBSERVABLES CONFIG ############ ;#implementation: Use [GPS_L1_CA_Observables] for GPS L1 C/A. Observables.implementation=GPS_L1_CA_Observables -;#output_rate_ms: Period between two psudoranges outputs. Notice that the minimum period is equal to the tracking integration time (for GPS CA L1 is 1ms) [ms] -Observables.output_rate_ms=100 - ;#dump: Enable or disable the Observables internal binary data file logging [true] or [false] Observables.dump=false @@ -364,11 +404,17 @@ Observables.dump_filename=./observables.dat PVT.implementation=GPS_L1_CA_PVT ;#averaging_depth: Number of PVT observations in the moving average algorithm -PVT.averaging_depth=2 +PVT.averaging_depth=100 ;#flag_average: Enables the PVT averaging between output intervals (arithmetic mean) [true] or [false] PVT.flag_averaging=true +;#output_rate_ms: Period between two PVT outputs. Notice that the minimum period is equal to the tracking integration time (for GPS CA L1 is 1ms) [ms] +PVT.output_rate_ms=100; + +;#display_rate_ms: Position console print (std::out) interval [ms]. Notice that output_rate_ms<=display_rate_ms. +PVT.display_rate_ms=500; + ;#dump: Enable or disable the PVT internal binary data file logging [true] or [false] PVT.dump=false @@ -379,4 +425,4 @@ PVT.dump_filename=./PVT ;# Receiver output filter: Leave this block disabled in this version OutputFilter.implementation=Null_Sink_Output_Filter OutputFilter.filename=data/gnss-sdr.dat -OutputFilter.item_type=gr_complex \ No newline at end of file +OutputFilter.item_type=gr_complex diff --git a/src/algorithms/input_filter/adapters/freq_xlating_fir_filter.cc b/src/algorithms/input_filter/adapters/freq_xlating_fir_filter.cc new file mode 100644 index 000000000..e47b5b242 --- /dev/null +++ b/src/algorithms/input_filter/adapters/freq_xlating_fir_filter.cc @@ -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 . + * + * ------------------------------------------------------------------------- + */ + +#include "freq_xlating_fir_filter.h" +#include "configuration_interface.h" +#include +#include +#include +#include +#include +#include +#include + +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 default_bands = { 0.0, 0.4, 0.6, 1.0 }; + std::vector default_ampl = { 1.0, 1.0, 0.0, 0.0 }; + std::vector 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 bands; + std::vector ampl; + std::vector error_w; + std::string option; + double option_value; + + for (unsigned int i = 0; i < number_of_bands; i++) + { + + option = ".band" + boost::lexical_cast(i + 1) + "_begin"; + option_value = config_->property(role_ + option, default_bands[i]); + bands.push_back(option_value); + + option = ".band" + boost::lexical_cast(i + 1) + "_end"; + option_value = config_->property(role_ + option, default_bands[i]); + bands.push_back(option_value); + + option = ".ampl" + boost::lexical_cast(i + 1) + "_begin"; + option_value = config_->property(role_ + option, default_bands[i]); + ampl.push_back(option_value); + + option = ".ampl" + boost::lexical_cast(i + 1) + "_end"; + option_value = config_->property(role_ + option, default_bands[i]); + ampl.push_back(option_value); + + option = ".band" + boost::lexical_cast(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 taps_d = gr_remez(number_of_taps - 1, bands, ampl, + error_w, filter_type, grid_density); + taps_.reserve(taps_d.size()); + for (std::vector::iterator it = taps_d.begin(); it != taps_d.end(); it++) + { + taps_.push_back(float(*it)); + } +} diff --git a/src/algorithms/input_filter/adapters/freq_xlating_fir_filter.h b/src/algorithms/input_filter/adapters/freq_xlating_fir_filter.h new file mode 100644 index 000000000..59c119a0a --- /dev/null +++ b/src/algorithms/input_filter/adapters/freq_xlating_fir_filter.h @@ -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 . + * + * ------------------------------------------------------------------------- + */ + +#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 +#include +#include +#include +#include + +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 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_ diff --git a/src/algorithms/input_filter/adapters/jamfile.jam b/src/algorithms/input_filter/adapters/jamfile.jam index 9798963e8..8239f40e3 100644 --- a/src/algorithms/input_filter/adapters/jamfile.jam +++ b/src/algorithms/input_filter/adapters/jamfile.jam @@ -1,3 +1,4 @@ project : build-dir ../../../../build ; -obj fir_filter : fir_filter.cc ; \ No newline at end of file +obj fir_filter : fir_filter.cc ; +obj freq_xlating_fir_filter : freq_xlating_fir_filter.cc ; \ No newline at end of file diff --git a/src/core/receiver/gnss_block_factory.cc b/src/core/receiver/gnss_block_factory.cc index 023dcbb78..4218cab11 100644 --- a/src/core/receiver/gnss_block_factory.cc +++ b/src/core/receiver/gnss_block_factory.cc @@ -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 ------------------------------------------------------------------- diff --git a/src/main/jamfile.jam b/src/main/jamfile.jam index a4b3523ef..276f33e04 100644 --- a/src/main/jamfile.jam +++ b/src/main/jamfile.jam @@ -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 diff --git a/src/tests/gnss_block/gnss_block_factory_test.cc b/src/tests/gnss_block/gnss_block_factory_test.cc index 27d997053..b5db083e3 100644 --- a/src/tests/gnss_block/gnss_block_factory_test.cc +++ b/src/tests/gnss_block/gnss_block_factory_test.cc @@ -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(); diff --git a/src/tests/jamfile.jam b/src/tests/jamfile.jam index c0f77ee3f..c7dd7654c 100644 --- a/src/tests/jamfile.jam +++ b/src/tests/jamfile.jam @@ -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