kopia lustrzana https://github.com/proto17/dji_droneid
Porównaj commity
5 Commity
e4618831b0
...
8cf47662f7
Autor | SHA1 | Data |
---|---|---|
David Protzman | 8cf47662f7 | |
David Protzman | 03d29eb84e | |
David Protzman | ce82d18caf | |
David Protzman | 718875173b | |
David Protzman | b1b2be57c3 |
|
@ -1,3 +1,4 @@
|
|||
cmake-build-debug
|
||||
build
|
||||
.idea
|
||||
examples/*.py
|
|
@ -1,3 +1,5 @@
|
|||
It is considered good practice to add examples in here to demonstrate the
|
||||
functionality of your OOT module. Python scripts, GRC flow graphs or other
|
||||
code can go here.
|
||||
The `autocorrelator.grc` graph is just a demonstration of how to detect DroneID frames without any OOT modules.
|
||||
It does still require the use of the GNU Radio module as there are functions in the OOT that are needed. Just no
|
||||
normal OOT blocks required.
|
||||
|
||||
This ended up being a lot faster than doing the coding by hand, so huzzah to the GNU Radio devs!
|
Plik diff jest za duży
Load Diff
|
@ -107,6 +107,24 @@ public:
|
|||
* @return Variance of the complex vector
|
||||
*/
|
||||
static float variance(const std::complex<float> * samples, uint32_t sample_count);
|
||||
|
||||
/**
|
||||
* Calculate the variance of a complex vector where the mean is not known to be zero
|
||||
*
|
||||
* This function is mostly the same as utils::variance_no_mean but does have to calculate the
|
||||
* mean value of the input vector and subtract it from each sample, so this will take longer
|
||||
* @param samples Vector of complex samples
|
||||
* @return Variance of the complex vector
|
||||
*/
|
||||
static float variance_vector(const std::vector<std::complex<float>> & samples);
|
||||
|
||||
/**
|
||||
* Get the conjugate of the provided vector
|
||||
* @param samples Vector of complex samples
|
||||
* @return Conjugate of the input sample vector
|
||||
*/
|
||||
static std::vector<std::complex<float>> conj_vector(const std::vector<std::complex<float>> & samples);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ if(NOT dji_droneid_sources)
|
|||
endif(NOT dji_droneid_sources)
|
||||
|
||||
add_library(gnuradio-dji_droneid SHARED ${dji_droneid_sources})
|
||||
target_link_libraries(gnuradio-dji_droneid gnuradio::gnuradio-runtime gnuradio-fft fftw3)
|
||||
target_link_libraries(gnuradio-dji_droneid gnuradio::gnuradio-runtime gnuradio-fft fftw3 gnuradio-blocks gnuradio-filter)
|
||||
target_include_directories(gnuradio-dji_droneid
|
||||
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>
|
||||
PUBLIC $<INSTALL_INTERFACE:include>
|
||||
|
@ -92,6 +92,7 @@ include(GrTest)
|
|||
#include_directories()
|
||||
# List all files that contain Boost.UTF unit tests here
|
||||
list(APPEND test_dji_droneid_sources
|
||||
# Only tests that do not require MATLAB will live here
|
||||
)
|
||||
# Anything we need to link to for the unit tests go here
|
||||
list(APPEND GR_TEST_TARGET_DEPS gnuradio-dji_droneid)
|
||||
|
|
|
@ -145,6 +145,17 @@ struct TestFixture {
|
|||
return {output_samples.begin(), output_samples.end()};
|
||||
}
|
||||
|
||||
static std::vector<std::complex<float>> conj(const std::vector<std::complex<float>> & samples) {
|
||||
matlab_engine->setVariable("samples", factory.createArray({1, samples.size()}, samples.begin(), samples.end()));
|
||||
matlab_engine->eval(u"samples = single(conj(samples));");
|
||||
const matlab::data::TypedArray<std::complex<float>> output_samples = matlab_engine->getVariable("samples");
|
||||
matlab_engine->eval(u"clear samples");
|
||||
|
||||
BOOST_REQUIRE_EQUAL(output_samples.getNumberOfElements(), samples.size());
|
||||
|
||||
return {output_samples.begin(), output_samples.end()};
|
||||
}
|
||||
|
||||
static std::vector<std::complex<float>> create_test_vector(const uint32_t sample_count) {
|
||||
matlab_engine->setVariable("sample_count", factory.createScalar(static_cast<double>(sample_count)));
|
||||
matlab_engine->eval(u"samples = single(complex(randn(1, sample_count), randn(1, sample_count)));");
|
||||
|
@ -279,6 +290,20 @@ BOOST_AUTO_TEST_CASE(test_utils__variance) {
|
|||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_utils__variance_vector) {
|
||||
const uint32_t iters = 100;
|
||||
const uint32_t length = 10000;
|
||||
|
||||
for (auto iter = decltype(iters){0}; iter < iters; iter++) {
|
||||
const auto samples = create_test_vector(length);
|
||||
|
||||
const auto expected = var(samples);
|
||||
const auto calculated = utils::variance_vector(samples);
|
||||
|
||||
BOOST_REQUIRE_CLOSE(expected, calculated, 0.002);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_utils__variance_no_mean) {
|
||||
const uint32_t iters = 100;
|
||||
const uint32_t length = 10000;
|
||||
|
@ -293,6 +318,20 @@ BOOST_AUTO_TEST_CASE(test_utils__variance_no_mean) {
|
|||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_utils__conj_vector) {
|
||||
const uint32_t iters = 100;
|
||||
const uint32_t length = 10000;
|
||||
|
||||
for (auto iter = decltype(iters){0}; iter < iters; iter++) {
|
||||
const auto samples = create_test_vector(length);
|
||||
|
||||
const auto expected = conj(samples);
|
||||
const auto calculated = utils::conj_vector(samples);
|
||||
|
||||
BOOST_REQUIRE_EQUAL_COLLECTIONS(expected.begin(), expected.end(), calculated.begin(), calculated.end());
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
} /* namespace dji_droneid */
|
||||
|
|
|
@ -172,5 +172,25 @@ float utils::variance(const std::complex<float> * const samples, const uint32_t
|
|||
return total / static_cast<float>(sample_count - 1);
|
||||
}
|
||||
|
||||
std::vector<std::complex<float>>
|
||||
utils::conj_vector(const std::vector<std::complex<float>>& samples)
|
||||
{
|
||||
std::vector<std::complex<float>> output(samples.size());
|
||||
for (auto idx = decltype(samples.size()){0}; idx < samples.size(); idx++) {
|
||||
const auto & sample = samples[idx];
|
||||
output[idx] = {
|
||||
sample.real(),
|
||||
-sample.imag()
|
||||
};
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
float utils::variance_vector(const std::vector<std::complex<float>>& samples)
|
||||
{
|
||||
return variance(&samples[0], samples.size());
|
||||
}
|
||||
|
||||
} /* namespace dji_droneid */
|
||||
} /* namespace gr */
|
||||
|
|
|
@ -40,3 +40,18 @@ static const char* __doc_gr_dji_droneid_utils_create_zc = R"doc()doc";
|
|||
|
||||
|
||||
static const char* __doc_gr_dji_droneid_utils_get_cyclic_prefix_lengths = R"doc()doc";
|
||||
|
||||
|
||||
static const char* __doc_gr_dji_droneid_utils_mean_fast = R"doc()doc";
|
||||
|
||||
|
||||
static const char* __doc_gr_dji_droneid_utils_variance_no_mean = R"doc()doc";
|
||||
|
||||
|
||||
static const char* __doc_gr_dji_droneid_utils_variance = R"doc()doc";
|
||||
|
||||
|
||||
static const char* __doc_gr_dji_droneid_utils_variance_vector = R"doc()doc";
|
||||
|
||||
|
||||
static const char* __doc_gr_dji_droneid_utils_conj_vector = R"doc()doc";
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
/* BINDTOOL_GEN_AUTOMATIC(0) */
|
||||
/* BINDTOOL_USE_PYGCCXML(0) */
|
||||
/* BINDTOOL_HEADER_FILE(utils.h) */
|
||||
/* BINDTOOL_HEADER_FILE_HASH(341b0421657c63a408a05e68560d4ff8) */
|
||||
/* BINDTOOL_HEADER_FILE_HASH(2b797448fb8ea6ebcdf63ff38c33eb3c) */
|
||||
/***********************************************************************************/
|
||||
|
||||
#include <pybind11/complex.h>
|
||||
|
@ -78,5 +78,36 @@ void bind_utils(py::module& m)
|
|||
py::arg("sample_rate"),
|
||||
D(utils, get_cyclic_prefix_lengths))
|
||||
|
||||
|
||||
.def_static("mean_fast",
|
||||
&utils::mean_fast,
|
||||
py::arg("samples"),
|
||||
py::arg("sample_count"),
|
||||
D(utils, mean_fast))
|
||||
|
||||
|
||||
.def_static("variance_no_mean",
|
||||
&utils::variance_no_mean,
|
||||
py::arg("samples"),
|
||||
py::arg("sample_count"),
|
||||
D(utils, variance_no_mean))
|
||||
|
||||
|
||||
.def_static("variance",
|
||||
&utils::variance,
|
||||
py::arg("samples"),
|
||||
py::arg("sample_count"),
|
||||
D(utils, variance))
|
||||
|
||||
|
||||
.def_static("variance_vector",
|
||||
&utils::variance_vector,
|
||||
py::arg("samples"),
|
||||
D(utils, variance_vector))
|
||||
|
||||
|
||||
.def_static(
|
||||
"conj_vector", &utils::conj_vector, py::arg("samples"), D(utils, conj_vector))
|
||||
|
||||
;
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue