mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2025-01-16 12:12:57 +00:00
Beta version Pulse Blanking Filter
First version of the pulse blanking input filter
This commit is contained in:
parent
0b8e3c9399
commit
cbe54da10f
@ -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
|
||||
{
|
||||
|
@ -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_;
|
||||
|
@ -29,62 +29,88 @@
|
||||
*/
|
||||
|
||||
#include "pulse_blanking_cc.h"
|
||||
#include <boost/math/distributions/chi_squared.hpp>
|
||||
#include <cmath>
|
||||
#include <complex>
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include <volk/volk.h>
|
||||
#include <volk_gnsssdr/volk_gnsssdr.h>
|
||||
|
||||
|
||||
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<float> my_dist_(n_deg_fred);
|
||||
thres_ = boost::math::quantile(boost::math::complement(my_dist_, pfa));
|
||||
zeros_ = static_cast<gr_complex *>(volk_malloc(length_ * sizeof(gr_complex), volk_get_alignment()));
|
||||
magnitude = static_cast<float *>(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<float*>(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<float>(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;
|
||||
}
|
||||
|
@ -38,19 +38,27 @@ class pulse_blanking_cc;
|
||||
|
||||
typedef boost::shared_ptr<pulse_blanking_cc> 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<short> 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);
|
||||
|
Loading…
Reference in New Issue
Block a user