kopia lustrzana https://github.com/proto17/dji_droneid
Porównaj commity
12 Commity
5d59a14618
...
675fc65dfc
Autor | SHA1 | Data |
---|---|---|
David Protzman | 675fc65dfc | |
David Protzman | 1ba794cbee | |
David Protzman | c6598f9253 | |
David Protzman | 4b46d30248 | |
David Protzman | 2e33165cbe | |
David Protzman | 7606a61e8a | |
David Protzman | 66b749c3ad | |
David Protzman | 0fdac0e259 | |
David Protzman | 10052a6b8d | |
David Protzman | c89d6e6004 | |
David Protzman | 17f3465f3a | |
David Protzman | bb791dbac5 |
|
@ -24,5 +24,6 @@ install(FILES
|
|||
droneid_demodulation.block.yml
|
||||
droneid_misc_utils.block.yml
|
||||
droneid_lte_decode.block.yml
|
||||
droneid_decode.block.yml DESTINATION share/gnuradio/grc/blocks
|
||||
droneid_decode.block.yml
|
||||
droneid_normalized_xcorr_estimate.block.yml DESTINATION share/gnuradio/grc/blocks
|
||||
)
|
||||
|
|
|
@ -4,8 +4,9 @@ category: '[droneid]'
|
|||
|
||||
templates:
|
||||
imports: import droneid
|
||||
make: droneid.extractor(${sample_rate})
|
||||
|
||||
make: droneid.extractor(${sample_rate}, ${threshold})
|
||||
callbacks:
|
||||
- set_threshold(${threshold})
|
||||
# Make one 'parameters' list entry for every parameter you want settable from the GUI.
|
||||
# Keys include:
|
||||
# * id (makes the value accessible as \$keyname, e.g. in the make entry)
|
||||
|
@ -15,6 +16,9 @@ parameters:
|
|||
- id: sample_rate
|
||||
label: Sample Rate
|
||||
dtype: float
|
||||
- id: threshold
|
||||
label: Correlator threshold
|
||||
dtype: float
|
||||
|
||||
# Make one 'inputs' list entry per input and one 'outputs' list entry per output.
|
||||
# Keys include:
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
id: droneid_normalized_xcorr_estimate
|
||||
label: normalized_xcorr_estimate
|
||||
category: '[droneid]'
|
||||
|
||||
templates:
|
||||
imports: import droneid
|
||||
make: droneid.normalized_xcorr_estimate(${filter_taps})
|
||||
|
||||
# Make one 'parameters' list entry for every parameter you want settable from the GUI.
|
||||
# Keys include:
|
||||
# * id (makes the value accessible as \$keyname, e.g. in the make entry)
|
||||
# * label (label shown in the GUI)
|
||||
# * dtype (e.g. int, float, complex, byte, short, xxx_vector, ...)
|
||||
parameters:
|
||||
- id: filter_taps
|
||||
label: Filter Taps
|
||||
dtype: complex_vector
|
||||
|
||||
# Make one 'inputs' list entry per input and one 'outputs' list entry per output.
|
||||
# Keys include:
|
||||
# * label (an identifier for the GUI)
|
||||
# * domain (optional - stream or message. Default is stream)
|
||||
# * dtype (e.g. int, float, complex, byte, short, xxx_vector, ...)
|
||||
# * vlen (optional - data stream vector length. Default is 1)
|
||||
# * optional (optional - set to 1 for optional inputs. Default is 0)
|
||||
inputs:
|
||||
- label: in
|
||||
domain: stream
|
||||
dtype: complex
|
||||
vlen: 1
|
||||
optional: 0
|
||||
|
||||
outputs:
|
||||
- label: out
|
||||
domain: stream
|
||||
dtype: float
|
||||
vlen: 1
|
||||
optional: 0
|
||||
|
||||
# 'file_format' specifies the version of the GRC yml format used in the file
|
||||
# and should usually not be changed.
|
||||
file_format: 1
|
|
@ -29,5 +29,7 @@ install(FILES
|
|||
demodulation.h
|
||||
misc_utils.h
|
||||
lte_decode.h
|
||||
decode.h DESTINATION include/droneid
|
||||
decode.h
|
||||
normalized_xcorr.h
|
||||
normalized_xcorr_estimate.h DESTINATION include/droneid
|
||||
)
|
||||
|
|
|
@ -45,7 +45,9 @@ namespace gr {
|
|||
* class. droneid::extractor::make is the public interface for
|
||||
* creating new instances.
|
||||
*/
|
||||
static sptr make(double sample_rate);
|
||||
static sptr make(double /*sample_rate*/, float /*threshold*/);
|
||||
|
||||
virtual void set_threshold(float /*threshold*/) = 0;
|
||||
};
|
||||
|
||||
} // namespace droneid
|
||||
|
|
|
@ -46,6 +46,15 @@ namespace gr {
|
|||
static std::vector<std::complex<float>> create_zc_sequence(double sample_rate, uint32_t root);
|
||||
static std::vector<std::complex<float>> conj(const std::vector<std::complex<float>> & input);
|
||||
|
||||
static std::complex<float> mean(const std::vector<std::complex<float>> & samples);
|
||||
static float var(const std::vector<std::complex<float>> & samples);
|
||||
static float var_no_mean(const std::vector<std::complex<float>> & samples);
|
||||
|
||||
static std::complex<float> mean(const std::complex<float> * samples, uint32_t sample_count);
|
||||
static float var(const std::complex<float> * samples, uint32_t sample_count);
|
||||
|
||||
static float var_no_mean(const std::complex<float> * samples, uint32_t sample_count);
|
||||
|
||||
static void write(const std::string & path, const void * element, uint32_t element_size, uint32_t element_count);
|
||||
static void write(const std::string & path, const std::vector<uint32_t> & elements);
|
||||
static void write_samples(const std::string &path, const std::complex<float> * samples, uint32_t element_count);
|
||||
|
@ -80,6 +89,9 @@ namespace gr {
|
|||
return angles;
|
||||
}
|
||||
|
||||
static std::vector<float> abs_squared(const std::vector<std::complex<float>> & samples);
|
||||
static std::vector<float> abs_squared(const std::vector<std::complex<float>> && samples);
|
||||
|
||||
misc_utils();
|
||||
|
||||
~misc_utils();
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2022 gr-droneid author.
|
||||
*
|
||||
* This 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, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This software 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 this software; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_DRONEID_NORMALIZED_XCORR_H
|
||||
#define INCLUDED_DRONEID_NORMALIZED_XCORR_H
|
||||
|
||||
#include <droneid/api.h>
|
||||
#include <vector>
|
||||
#include <complex>
|
||||
|
||||
namespace gr {
|
||||
namespace droneid {
|
||||
|
||||
/*!
|
||||
* \brief <+description+>
|
||||
*
|
||||
*/
|
||||
class DRONEID_API normalized_xcorr {
|
||||
public:
|
||||
using sample_t = float;
|
||||
using complex_t = std::complex<sample_t>;
|
||||
using complex_vec_t = std::vector<complex_t>;
|
||||
|
||||
explicit normalized_xcorr(const complex_vec_t & filter_taps);
|
||||
|
||||
uint32_t run(const complex_t * samples, uint32_t sample_count, sample_t * output_samples);
|
||||
|
||||
~normalized_xcorr();
|
||||
protected:
|
||||
complex_t * taps_;
|
||||
complex_t * scores_;
|
||||
uint32_t scores_size_;
|
||||
double taps_var_;
|
||||
uint32_t window_size_;
|
||||
|
||||
complex_t * temp_;
|
||||
// complex_vec_t scores_;
|
||||
complex_t scalar_;
|
||||
private:
|
||||
};
|
||||
|
||||
} // namespace droneid
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_DRONEID_NORMALIZED_XCORR_H */
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2022 gr-droneid author.
|
||||
*
|
||||
* This 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, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This software 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 this software; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_DRONEID_NORMALIZED_XCORR_ESTIMATE_H
|
||||
#define INCLUDED_DRONEID_NORMALIZED_XCORR_ESTIMATE_H
|
||||
|
||||
#include <droneid/api.h>
|
||||
#include <gnuradio/sync_block.h>
|
||||
|
||||
namespace gr {
|
||||
namespace droneid {
|
||||
|
||||
/*!
|
||||
* \brief <+description of block+>
|
||||
* \ingroup droneid
|
||||
*
|
||||
*/
|
||||
class DRONEID_API normalized_xcorr_estimate : virtual public gr::sync_block
|
||||
{
|
||||
public:
|
||||
typedef boost::shared_ptr<normalized_xcorr_estimate> sptr;
|
||||
|
||||
/*!
|
||||
* \brief Return a shared_ptr to a new instance of droneid::normalized_xcorr_estimate.
|
||||
*
|
||||
* To avoid accidental use of raw pointers, droneid::normalized_xcorr_estimate's
|
||||
* constructor is in a private implementation
|
||||
* class. droneid::normalized_xcorr_estimate::make is the public interface for
|
||||
* creating new instances.
|
||||
*/
|
||||
static sptr make(std::vector<std::complex<float>> filter_taps);
|
||||
};
|
||||
|
||||
} // namespace droneid
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_DRONEID_NORMALIZED_XCORR_ESTIMATE_H */
|
||||
|
|
@ -31,6 +31,8 @@ list(APPEND droneid_sources
|
|||
misc_utils.cc
|
||||
lte_decode.cc
|
||||
decode_impl.cc
|
||||
normalized_xcorr.cc
|
||||
normalized_xcorr_estimate_impl.cc
|
||||
)
|
||||
|
||||
set(droneid_sources "${droneid_sources}" PARENT_SCOPE)
|
||||
|
@ -40,6 +42,9 @@ if(NOT droneid_sources)
|
|||
endif(NOT droneid_sources)
|
||||
|
||||
add_library(gnuradio-droneid SHARED ${droneid_sources})
|
||||
# Compile with all optimizations on
|
||||
target_compile_options(gnuradio-droneid PRIVATE -Ofast -march=native)
|
||||
|
||||
target_link_libraries(gnuradio-droneid gnuradio::gnuradio-runtime gnuradio::gnuradio-fft gnuradio::gnuradio-filter)
|
||||
target_link_libraries(gnuradio-droneid turbofec)
|
||||
target_include_directories(gnuradio-droneid
|
||||
|
@ -75,6 +80,8 @@ include(GrTest)
|
|||
#include_directories()
|
||||
# List all files that contain Boost.UTF unit tests here
|
||||
list(APPEND test_droneid_sources
|
||||
qa_normalized_xcorr.cc
|
||||
qa_normalized_xcorr_estimate.cc
|
||||
)
|
||||
# Anything we need to link to for the unit tests go here
|
||||
list(APPEND GR_TEST_TARGET_DEPS gnuradio-droneid)
|
||||
|
@ -88,4 +95,4 @@ foreach(qa_file ${test_droneid_sources})
|
|||
GR_ADD_CPP_TEST("droneid_${qa_file}"
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${qa_file}
|
||||
)
|
||||
endforeach(qa_file)
|
||||
endforeach(qa_file)
|
|
@ -30,16 +30,16 @@ namespace gr {
|
|||
namespace droneid {
|
||||
|
||||
extractor::sptr
|
||||
extractor::make(double sample_rate) {
|
||||
extractor::make(const double sample_rate, const float threshold) {
|
||||
return gnuradio::get_initial_sptr
|
||||
(new extractor_impl(sample_rate));
|
||||
(new extractor_impl(sample_rate, threshold));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The private constructor
|
||||
*/
|
||||
extractor_impl::extractor_impl(double sample_rate)
|
||||
extractor_impl::extractor_impl(double sample_rate, const float threshold)
|
||||
: gr::sync_block("extractor",
|
||||
gr::io_signature::make2(2, 2, sizeof(gr_complex), sizeof(float)),
|
||||
gr::io_signature::make(0, 0, 0)), fft_size_(misc_utils::get_fft_size(sample_rate)),
|
||||
|
@ -51,6 +51,7 @@ namespace gr {
|
|||
current_state_ = state_t::WAITING_FOR_THRESHOLD;
|
||||
collected_samples_ = 0;
|
||||
total_samples_read_ = 0;
|
||||
threshold_ = threshold;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -59,6 +60,11 @@ namespace gr {
|
|||
extractor_impl::~extractor_impl() {
|
||||
}
|
||||
|
||||
void extractor_impl::set_threshold(const float threshold) {
|
||||
std::lock_guard<decltype(parameter_lock_)> l(parameter_lock_);
|
||||
threshold_ = threshold;
|
||||
}
|
||||
|
||||
int
|
||||
extractor_impl::work(int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
|
@ -66,11 +72,17 @@ namespace gr {
|
|||
const gr_complex *samples = (const gr_complex *) input_items[0];
|
||||
const float *correlation_scores = (const float *) input_items[1];
|
||||
|
||||
float threshold;
|
||||
{
|
||||
std::lock_guard<decltype(parameter_lock_)> lock(parameter_lock_);
|
||||
threshold = threshold_;
|
||||
}
|
||||
|
||||
for (int idx = 0; idx < noutput_items; idx++) {
|
||||
total_samples_read_++;
|
||||
switch (current_state_) {
|
||||
case state_t::WAITING_FOR_THRESHOLD: {
|
||||
if (correlation_scores[idx] > 0.2) {
|
||||
if (correlation_scores[idx] > threshold) {
|
||||
start_sample_index_ = nitems_read(0) + idx;
|
||||
std::cout << "Found burst @ " << total_samples_read_ << " / " << start_sample_index_ << "\n";
|
||||
current_state_ = state_t::COLLECTING_SAMPLES;
|
||||
|
|
|
@ -45,11 +45,16 @@ namespace gr {
|
|||
const uint32_t extract_samples_count_;
|
||||
std::vector<gr_complex> buffer_;
|
||||
|
||||
float threshold_;
|
||||
std::mutex parameter_lock_;
|
||||
|
||||
public:
|
||||
extractor_impl(double sample_rate);
|
||||
extractor_impl(double sample_rate, float threshold);
|
||||
|
||||
~extractor_impl();
|
||||
|
||||
void set_threshold(float threshold) override;
|
||||
|
||||
// Where all the action really happens
|
||||
int work(
|
||||
int noutput_items,
|
||||
|
|
|
@ -341,6 +341,64 @@ namespace gr {
|
|||
return bits;
|
||||
}
|
||||
|
||||
std::complex<float> misc_utils::mean(const std::vector<std::complex<float>> &samples) {
|
||||
return mean(&samples[0], samples.size());
|
||||
}
|
||||
|
||||
float misc_utils::var(const std::vector<std::complex<float>> &samples) {
|
||||
return var(&samples[0], samples.size());
|
||||
}
|
||||
|
||||
std::complex<float> misc_utils::mean(const std::complex<float> *const samples, const uint32_t sample_count) {
|
||||
auto sum = std::accumulate(samples, samples + sample_count, std::complex<float>{0, 0});
|
||||
return sum / static_cast<float>(sample_count);
|
||||
}
|
||||
|
||||
float misc_utils::var(const std::complex<float> *const samples, uint32_t sample_count) {
|
||||
const auto mean_val = mean(samples, sample_count);
|
||||
const auto recip = 1.0f / static_cast<float>(sample_count - 1);
|
||||
float var_val = 0;
|
||||
|
||||
for (uint32_t idx = 0; idx < sample_count; idx++) {
|
||||
const auto sample = samples[idx] - mean_val;
|
||||
var_val += (static_cast<float>(std::pow(sample.real(), 2) + std::pow(sample.imag(), 2))) * recip;
|
||||
}
|
||||
|
||||
return var_val;
|
||||
}
|
||||
|
||||
float misc_utils::var_no_mean(const std::complex<float> *samples, uint32_t sample_count) {
|
||||
const auto recip = 1.0f / static_cast<float>(sample_count - 1);
|
||||
float var_val = 0;
|
||||
|
||||
for (uint32_t idx = 0; idx < sample_count; idx++) {
|
||||
const auto & sample = samples[idx];
|
||||
var_val += (static_cast<float>(std::pow(sample.real(), 2) + std::pow(sample.imag(), 2))) * recip;
|
||||
}
|
||||
|
||||
return var_val;
|
||||
}
|
||||
|
||||
float misc_utils::var_no_mean(const std::vector<std::complex<float>> &samples) {
|
||||
return var_no_mean(&samples[0], samples.size());
|
||||
}
|
||||
|
||||
std::vector<float> misc_utils::abs_squared(const std::vector<std::complex<float>> &samples) {
|
||||
std::vector<float> ret(samples.size());
|
||||
|
||||
for (auto idx = decltype(samples.size()){0}; idx < samples.size(); idx++) {
|
||||
const auto & sample = samples[idx];
|
||||
ret[idx] = (sample.real() * sample.real()) + (sample.imag() * sample.imag());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<float> misc_utils::abs_squared(const std::vector<std::complex<float>> && samples) {
|
||||
return abs_squared(samples);
|
||||
}
|
||||
|
||||
|
||||
} /* namespace droneid */
|
||||
} /* namespace gr */
|
||||
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2022 gr-droneid author.
|
||||
*
|
||||
* This 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, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This software 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 this software; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <numeric>
|
||||
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include <droneid/normalized_xcorr.h>
|
||||
#include <droneid/misc_utils.h>
|
||||
|
||||
#include <volk/volk.h>
|
||||
|
||||
namespace gr {
|
||||
namespace droneid {
|
||||
|
||||
normalized_xcorr::normalized_xcorr(const complex_vec_t & filter_taps) {
|
||||
window_size_ = filter_taps.size();
|
||||
taps_ = (complex_t *)volk_malloc(sizeof(complex_t) * window_size_, volk_get_alignment());
|
||||
temp_ = (decltype(temp_))volk_malloc(sizeof(temp_[0]) * window_size_, volk_get_alignment());
|
||||
std::copy(filter_taps.begin(), filter_taps.end(), taps_);
|
||||
|
||||
const auto mean = misc_utils::mean(taps_, window_size_);
|
||||
std::for_each(taps_, taps_ + window_size_, [&mean](complex_t & sample){
|
||||
sample -= mean;
|
||||
});
|
||||
|
||||
taps_var_ = misc_utils::var(taps_, window_size_);
|
||||
|
||||
scalar_ = {1 / static_cast<sample_t>(sqrt(taps_var_) * window_size_), 0};
|
||||
scores_size_ = 0;
|
||||
}
|
||||
|
||||
normalized_xcorr::~normalized_xcorr() {
|
||||
if (taps_ != nullptr) {
|
||||
volk_free(taps_);
|
||||
}
|
||||
|
||||
if (temp_ != nullptr) {
|
||||
volk_free(temp_);
|
||||
}
|
||||
|
||||
if (scores_ != nullptr) {
|
||||
volk_free(scores_);
|
||||
}
|
||||
};
|
||||
|
||||
uint32_t normalized_xcorr::run(const normalized_xcorr::complex_t * const samples, const uint32_t sample_count,
|
||||
normalized_xcorr::sample_t * const output_samples) {
|
||||
if (sample_count < window_size_) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const auto max_correlations = sample_count - window_size_;
|
||||
if (scores_size_ < max_correlations) {
|
||||
if (scores_ != nullptr) {
|
||||
volk_free(scores_);
|
||||
}
|
||||
scores_ = (decltype(scores_))volk_malloc(sizeof(scores_[0]) * max_correlations, volk_get_alignment());
|
||||
scores_size_ = max_correlations;
|
||||
}
|
||||
|
||||
for (auto offset = decltype(max_correlations){0}; offset < max_correlations; offset++) {
|
||||
volk_32fc_x2_dot_prod_32fc(&scores_[offset], samples + offset, &taps_[0], window_size_);
|
||||
}
|
||||
|
||||
volk_32fc_s32fc_multiply_32fc_a(&scores_[0], &scores_[0], scalar_, max_correlations);
|
||||
volk_32fc_magnitude_squared_32f_a(output_samples, &scores_[0], max_correlations);
|
||||
|
||||
return max_correlations;
|
||||
}
|
||||
|
||||
} /* namespace droneid */
|
||||
} /* namespace gr */
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2022 gr-droneid author.
|
||||
*
|
||||
* This 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, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This software 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 this software; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include "normalized_xcorr_estimate_impl.h"
|
||||
|
||||
#include <volk/volk.h>
|
||||
|
||||
namespace gr {
|
||||
namespace droneid {
|
||||
|
||||
normalized_xcorr_estimate::sptr
|
||||
normalized_xcorr_estimate::make(std::vector<std::complex<float>> filter_taps) {
|
||||
return gnuradio::get_initial_sptr
|
||||
(new normalized_xcorr_estimate_impl(filter_taps));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The private constructor
|
||||
*/
|
||||
normalized_xcorr_estimate_impl::normalized_xcorr_estimate_impl(std::vector<std::complex<float>> filter_taps)
|
||||
: gr::sync_block("normalized_xcorr_estimate",
|
||||
gr::io_signature::make(1, 1, sizeof(gr_complex)),
|
||||
gr::io_signature::make(1, 1, sizeof(float))) {
|
||||
xcorr_ = std::unique_ptr<normalized_xcorr>(new normalized_xcorr(filter_taps));
|
||||
|
||||
set_history(filter_taps.size());
|
||||
set_alignment(std::max(1, static_cast<int32_t>(volk_get_alignment() / sizeof(float))));
|
||||
}
|
||||
|
||||
/*
|
||||
* Our virtual destructor.
|
||||
*/
|
||||
normalized_xcorr_estimate_impl::~normalized_xcorr_estimate_impl() {
|
||||
}
|
||||
|
||||
int
|
||||
normalized_xcorr_estimate_impl::work(int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items) {
|
||||
const auto *in = (const gr_complex *) input_items[0];
|
||||
auto *out = (float *) output_items[0];
|
||||
|
||||
xcorr_->run(in, noutput_items, out);
|
||||
|
||||
// Do <+signal processing+>
|
||||
|
||||
// Tell runtime system how many output items we produced.
|
||||
return noutput_items;
|
||||
}
|
||||
|
||||
} /* namespace droneid */
|
||||
} /* namespace gr */
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2022 gr-droneid author.
|
||||
*
|
||||
* This 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, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This software 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 this software; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_DRONEID_NORMALIZED_XCORR_ESTIMATE_IMPL_H
|
||||
#define INCLUDED_DRONEID_NORMALIZED_XCORR_ESTIMATE_IMPL_H
|
||||
|
||||
#include <droneid/normalized_xcorr_estimate.h>
|
||||
#include <droneid/normalized_xcorr.h>
|
||||
|
||||
namespace gr {
|
||||
namespace droneid {
|
||||
|
||||
class normalized_xcorr_estimate_impl : public normalized_xcorr_estimate {
|
||||
private:
|
||||
std::unique_ptr<gr::droneid::normalized_xcorr> xcorr_;
|
||||
|
||||
public:
|
||||
normalized_xcorr_estimate_impl(std::vector<std::complex<float>> filter_taps);
|
||||
|
||||
~normalized_xcorr_estimate_impl();
|
||||
|
||||
// Where all the action really happens
|
||||
int work(
|
||||
int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items
|
||||
);
|
||||
};
|
||||
|
||||
} // namespace droneid
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_DRONEID_NORMALIZED_XCORR_ESTIMATE_IMPL_H */
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2022 gr-droneid author.
|
||||
*
|
||||
* This 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, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This software 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 this software; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <gnuradio/attributes.h>
|
||||
#include <cppunit/TestAssert.h>
|
||||
#include "qa_normalized_xcorr.h"
|
||||
#include <droneid/normalized_xcorr.h>
|
||||
#include <iostream>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <gnuradio/random.h>
|
||||
#include <chrono>
|
||||
|
||||
#include <droneid/misc_utils.h>
|
||||
|
||||
namespace gr {
|
||||
namespace droneid {
|
||||
using sample_t = float;
|
||||
using complex_t = std::complex<sample_t>;
|
||||
using complex_vec_t = std::vector<complex_t>;
|
||||
|
||||
BOOST_AUTO_TEST_CASE(foo) {
|
||||
auto rng = gr::random();
|
||||
complex_vec_t noise_vector(1e6, {0, 0});
|
||||
for (auto & sample : noise_vector) {
|
||||
sample = rng.rayleigh_complex();
|
||||
}
|
||||
|
||||
const auto start_offset = 102313; // Just a random starting offset that's not on an even boundary
|
||||
const auto filter_length = 1023;
|
||||
|
||||
const auto filter_taps = complex_vec_t(noise_vector.begin() + start_offset, noise_vector.begin() + start_offset + filter_length);
|
||||
|
||||
|
||||
normalized_xcorr xcorr(filter_taps);
|
||||
|
||||
std::vector<sample_t> mags(noise_vector.size() - filter_length, 0);
|
||||
|
||||
const auto start = std::chrono::high_resolution_clock::now();
|
||||
xcorr.run(&noise_vector[0], noise_vector.size(), &mags[0]);
|
||||
const auto end = std::chrono::high_resolution_clock::now();
|
||||
const auto duration = std::chrono::duration<float>(end - start).count();
|
||||
const auto rate = noise_vector.size() / duration;
|
||||
std::cout << "Took " << duration << " seconds to run through " << noise_vector.size() << " samples\n";
|
||||
std::cout << "Average of " << rate << " samples per second\n";
|
||||
|
||||
|
||||
misc_utils::write("/tmp/mags", &mags[0], sizeof(mags[0]), mags.size());
|
||||
|
||||
const auto max_element_iter = std::max_element(mags.begin(), mags.end());
|
||||
const auto distance = std::distance(mags.begin(), max_element_iter);
|
||||
std::cout << "Distance: " << distance << "\n";
|
||||
}
|
||||
|
||||
|
||||
} /* namespace droneid */
|
||||
} /* namespace gr */
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2022 gr-droneid author.
|
||||
*
|
||||
* This 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, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This software 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 this software; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef _QA_NORMALIZED_XCORR_H_
|
||||
#define _QA_NORMALIZED_XCORR_H_
|
||||
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
#include <cppunit/TestCase.h>
|
||||
|
||||
namespace gr {
|
||||
namespace droneid {
|
||||
|
||||
class qa_normalized_xcorr : public CppUnit::TestCase {
|
||||
public:
|
||||
CPPUNIT_TEST_SUITE(qa_normalized_xcorr);
|
||||
CPPUNIT_TEST(t1);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
private:
|
||||
void t1();
|
||||
};
|
||||
|
||||
} /* namespace droneid */
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* _QA_NORMALIZED_XCORR_H_ */
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2022 gr-droneid author.
|
||||
*
|
||||
* This 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, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This software 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 this software; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <gnuradio/attributes.h>
|
||||
#include <cppunit/TestAssert.h>
|
||||
#include "qa_normalized_xcorr_estimate.h"
|
||||
#include <droneid/normalized_xcorr_estimate.h>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
|
||||
namespace gr {
|
||||
namespace droneid {
|
||||
|
||||
BOOST_AUTO_TEST_CASE(foo) {
|
||||
|
||||
}
|
||||
|
||||
} /* namespace droneid */
|
||||
} /* namespace gr */
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2022 gr-droneid author.
|
||||
*
|
||||
* This 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, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This software 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 this software; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef _QA_NORMALIZED_XCORR_ESTIMATE_H_
|
||||
#define _QA_NORMALIZED_XCORR_ESTIMATE_H_
|
||||
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
#include <cppunit/TestCase.h>
|
||||
|
||||
namespace gr {
|
||||
namespace droneid {
|
||||
|
||||
class qa_normalized_xcorr_estimate : public CppUnit::TestCase
|
||||
{
|
||||
public:
|
||||
CPPUNIT_TEST_SUITE(qa_normalized_xcorr_estimate);
|
||||
CPPUNIT_TEST(t1);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
private:
|
||||
void t1();
|
||||
};
|
||||
|
||||
} /* namespace droneid */
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* _QA_NORMALIZED_XCORR_ESTIMATE_H_ */
|
||||
|
|
@ -45,3 +45,4 @@ set(GR_TEST_PYTHON_DIRS ${CMAKE_BINARY_DIR}/swig)
|
|||
GR_ADD_TEST(qa_extractor ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_extractor.py)
|
||||
GR_ADD_TEST(qa_time_sync ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_time_sync.py)
|
||||
GR_ADD_TEST(qa_demodulation ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_demodulation.py)
|
||||
GR_ADD_TEST(qa_normalized_xcorr_estimate ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_normalized_xcorr_estimate.py)
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright 2022 gr-droneid author.
|
||||
#
|
||||
# This 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, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This software 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 this software; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
#
|
||||
|
||||
from gnuradio import gr, gr_unittest
|
||||
from gnuradio import blocks
|
||||
import droneid_swig as droneid
|
||||
|
||||
class qa_normalized_xcorr_estimate(gr_unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.tb = gr.top_block()
|
||||
|
||||
def tearDown(self):
|
||||
self.tb = None
|
||||
|
||||
def test_001_t(self):
|
||||
# set up fg
|
||||
self.tb.run()
|
||||
# check data
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
gr_unittest.run(qa_normalized_xcorr_estimate)
|
|
@ -15,6 +15,8 @@
|
|||
#include "droneid/misc_utils.h"
|
||||
#include "droneid/lte_decode.h"
|
||||
#include "droneid/decode.h"
|
||||
#include "droneid/normalized_xcorr.h"
|
||||
#include "droneid/normalized_xcorr_estimate.h"
|
||||
//#include "droneid/utils.h"
|
||||
%}
|
||||
|
||||
|
@ -35,3 +37,6 @@ GR_SWIG_BLOCK_MAGIC2(droneid, demodulation);
|
|||
%include "droneid/lte_decode.h"
|
||||
%include "droneid/decode.h"
|
||||
GR_SWIG_BLOCK_MAGIC2(droneid, decode);
|
||||
%include "droneid/normalized_xcorr.h"
|
||||
%include "droneid/normalized_xcorr_estimate.h"
|
||||
GR_SWIG_BLOCK_MAGIC2(droneid, normalized_xcorr_estimate);
|
||||
|
|
Ładowanie…
Reference in New Issue