1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2025-01-16 20:23:02 +00:00

Beta version Pulse Blanking Filter

First version of the pulse blanking input filter
This commit is contained in:
Antonio Ramos 2017-07-10 12:53:26 +02:00
parent 0b8e3c9399
commit cbe54da10f
4 changed files with 82 additions and 49 deletions

View File

@ -53,14 +53,15 @@ PulseBlankingFilter::PulseBlankingFilter(ConfigurationInterface* configuration,
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
{

View File

@ -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_;

View File

@ -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;
}

View File

@ -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);