Added extractor module

gr-droneid-update-3.10
David Protzman 2022-09-22 21:29:47 -04:00
rodzic a344cfddfb
commit f480f56c65
12 zmienionych plików z 365 dodań i 3 usunięć

Wyświetl plik

@ -8,5 +8,6 @@
install(FILES
droneid_decode.block.yml
droneid_demodulation.block.yml DESTINATION share/gnuradio/grc/blocks
droneid_demodulation.block.yml
droneid_extractor.block.yml DESTINATION share/gnuradio/grc/blocks
)

Wyświetl plik

@ -0,0 +1,49 @@
id: droneid_extractor
label: extractor
category: '[droneid]'
templates:
imports: from gnuradio import droneid
make: droneid.extractor(${sample_rate}, ${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)
# * label (label shown in the GUI)
# * dtype (e.g. int, float, complex, byte, short, xxx_vector, ...)
# * default
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:
# * 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: samples
domain: stream
dtype: complex
vlen: 1
optional: 0
- label: corr
domain: stream
dtype: float
vlen: 1
optional: 0
outputs:
- label: pdus
domain: message
optional: true
# 'file_format' specifies the version of the GRC yml format used in the file
# and should usually not be changed.
file_format: 1

Wyświetl plik

@ -14,5 +14,6 @@ install(FILES
misc_utils.h
decode.h
demodulation.h
lte_decode.h DESTINATION include/gnuradio/droneid
lte_decode.h
extractor.h DESTINATION include/gnuradio/droneid
)

Wyświetl plik

@ -0,0 +1,43 @@
/* -*- c++ -*- */
/*
* Copyright 2022 gr-droneid author.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#ifndef INCLUDED_DRONEID_EXTRACTOR_H
#define INCLUDED_DRONEID_EXTRACTOR_H
#include <gnuradio/droneid/api.h>
#include <gnuradio/sync_block.h>
namespace gr {
namespace droneid {
/*!
* \brief <+description of block+>
* \ingroup droneid
*
*/
class DRONEID_API extractor : virtual public gr::sync_block
{
public:
typedef std::shared_ptr<extractor> sptr;
/*!
* \brief Return a shared_ptr to a new instance of droneid::extractor.
*
* To avoid accidental use of raw pointers, droneid::extractor's
* constructor is in a private implementation
* class. droneid::extractor::make is the public interface for
* creating new instances.
*/
static sptr make(double /*sample_rate*/, float /*threshold*/);
virtual void set_threshold(float /*threshold*/) = 0;
};
} // namespace droneid
} // namespace gr
#endif /* INCLUDED_DRONEID_EXTRACTOR_H */

Wyświetl plik

@ -16,6 +16,7 @@ list(APPEND droneid_sources
decode_impl.cc
demodulation_impl.cc
lte_decode.cc
extractor_impl.cc
)
set(droneid_sources "${droneid_sources}" PARENT_SCOPE)
@ -60,6 +61,7 @@ include(GrTest)
#include_directories()
# List all files that contain Boost.UTF unit tests here
list(APPEND test_droneid_sources
qa_extractor.cc
qa_demodulation.cc
qa_decode.cc
)

Wyświetl plik

@ -0,0 +1,102 @@
/* -*- c++ -*- */
/*
* Copyright 2022 gr-droneid author.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include "extractor_impl.h"
#include <gnuradio/io_signature.h>
#include <gnuradio/droneid/misc_utils.h>
namespace gr {
namespace droneid {
extractor::sptr
extractor::make(const double sample_rate, const float threshold) {
return gnuradio::get_initial_sptr
(new extractor_impl(sample_rate, threshold));
}
/*
* The private constructor
*/
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)),
long_cp_len_(misc_utils::get_long_cp_len(sample_rate)), short_cp_len_(misc_utils::get_short_cp_len(sample_rate)),
extract_samples_count_((fft_size_ * 13) + (long_cp_len_ * 2) + (short_cp_len_ * 7)){
this->message_port_register_out(pmt::mp("pdus"));
buffer_.resize(extract_samples_count_);
current_state_ = state_t::WAITING_FOR_THRESHOLD;
collected_samples_ = 0;
total_samples_read_ = 0;
threshold_ = threshold;
}
/*
* Our virtual destructor.
*/
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,
gr_vector_void_star &output_items) {
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] > 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;
collected_samples_ = 1;
buffer_[0] = samples[idx];
}
break;
}
case state_t::COLLECTING_SAMPLES: {
buffer_[collected_samples_++] = samples[idx];
if (collected_samples_ == extract_samples_count_) {
current_state_ = state_t::WAITING_FOR_THRESHOLD;
const pmt::pmt_t vec = pmt::init_c32vector(buffer_.size(), buffer_);
pmt::pmt_t meta = pmt::make_dict();
meta = pmt::dict_add(meta, pmt::mp("start_offset"), pmt::from_uint64(start_sample_index_));
std::cout << "Sending message with " << pmt::length(vec) << " elements (" << extract_samples_count_ << ") starting at " << start_sample_index_ << "\n";
message_port_pub(pmt::mp("pdus"), pmt::cons(meta, vec));
collected_samples_ = 0;
}
break;
}
}
}
// Do <+signal processing+>
// Tell runtime system how many output items we produced.
return noutput_items;
}
} /* namespace droneid */
} /* namespace gr */

Wyświetl plik

@ -0,0 +1,56 @@
/* -*- c++ -*- */
/*
* Copyright 2022 gr-droneid author.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#ifndef INCLUDED_DRONEID_EXTRACTOR_IMPL_H
#define INCLUDED_DRONEID_EXTRACTOR_IMPL_H
#include <gnuradio/droneid/extractor.h>
namespace gr {
namespace droneid {
class extractor_impl : public extractor {
private:
enum class state_t {
WAITING_FOR_THRESHOLD,
COLLECTING_SAMPLES
};
static constexpr float CARRIER_SPACING = 15e3;
uint64_t start_sample_index_;
uint64_t total_samples_read_;
state_t current_state_;
uint32_t collected_samples_;
const uint32_t fft_size_;
const uint32_t long_cp_len_;
const uint32_t short_cp_len_;
const uint32_t extract_samples_count_;
std::vector<gr_complex> buffer_;
float threshold_;
std::mutex parameter_lock_;
public:
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,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items
);
};
} // namespace droneid
} // namespace gr
#endif /* INCLUDED_DRONEID_EXTRACTOR_IMPL_H */

Wyświetl plik

@ -0,0 +1,21 @@
/* -*- c++ -*- */
/*
* Copyright 2022 gr-droneid author.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include <gnuradio/attributes.h>
#include <gnuradio/droneid/extractor.h>
#include <boost/test/unit_test.hpp>
namespace gr {
namespace droneid {
BOOST_AUTO_TEST_CASE(test_extractor_replace_with_specific_test_name)
{
// Put test here
}
} /* namespace droneid */
} /* namespace gr */

Wyświetl plik

@ -32,7 +32,8 @@ list(APPEND droneid_python_files
misc_utils_python.cc
decode_python.cc
demodulation_python.cc
lte_decode_python.cc python_bindings.cc)
lte_decode_python.cc
extractor_python.cc python_bindings.cc)
GR_PYBIND_MAKE_OOT(droneid
../../..

Wyświetl plik

@ -0,0 +1,30 @@
/*
* Copyright 2022 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "pydoc_macros.h"
#define D(...) DOC(gr, droneid, __VA_ARGS__)
/*
This file contains placeholders for docstrings for the Python bindings.
Do not edit! These were automatically extracted during the binding process
and will be overwritten during the build process
*/
static const char* __doc_gr_droneid_extractor = R"doc()doc";
static const char* __doc_gr_droneid_extractor_extractor_0 = R"doc()doc";
static const char* __doc_gr_droneid_extractor_extractor_1 = R"doc()doc";
static const char* __doc_gr_droneid_extractor_make = R"doc()doc";
static const char* __doc_gr_droneid_extractor_set_threshold = R"doc()doc";

Wyświetl plik

@ -0,0 +1,54 @@
/*
* Copyright 2022 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
/***********************************************************************************/
/* This file is automatically generated using bindtool and can be manually edited */
/* The following lines can be configured to regenerate this file during cmake */
/* If manual edits are made, the following tags should be modified accordingly. */
/* BINDTOOL_GEN_AUTOMATIC(0) */
/* BINDTOOL_USE_PYGCCXML(0) */
/* BINDTOOL_HEADER_FILE(extractor.h) */
/* BINDTOOL_HEADER_FILE_HASH(18a466547b48a63d103e999c9547d6b3) */
/***********************************************************************************/
#include <pybind11/complex.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
namespace py = pybind11;
#include <gnuradio/droneid/extractor.h>
// pydoc.h is automatically generated in the build directory
#include <extractor_pydoc.h>
void bind_extractor(py::module& m)
{
using extractor = ::gr::droneid::extractor;
py::class_<extractor,
gr::sync_block,
gr::block,
gr::basic_block,
std::shared_ptr<extractor>>(m, "extractor", D(extractor))
.def(py::init(&extractor::make),
py::arg("arg0"),
py::arg("arg1"),
D(extractor, make))
.def("set_threshold",
&extractor::set_threshold,
py::arg("arg0"),
D(extractor, set_threshold))
;
}

Wyświetl plik

@ -25,6 +25,7 @@ namespace py = pybind11;
void bind_decode(py::module& m);
void bind_demodulation(py::module& m);
void bind_lte_decode(py::module& m);
void bind_extractor(py::module& m);
// ) END BINDING_FUNCTION_PROTOTYPES
@ -59,5 +60,6 @@ PYBIND11_MODULE(droneid_python, m)
bind_decode(m);
bind_demodulation(m);
bind_lte_decode(m);
bind_extractor(m);
// ) END BINDING_FUNCTION_CALLS
}