Porównaj commity

...

5 Commity

Autor SHA1 Wiadomość Data
David Protzman 3b30b48402 Removed unused code from create_zc (MATLAB) 2022-10-09 18:00:25 -04:00
David Protzman 19ab4e3e35 Updated hash for utils class 2022-10-09 18:00:15 -04:00
David Protzman b28013d211 Updated tests for utils to use a single instance of MATLAB
There were issues before where the single MATLAB instance would cause a segfault at the end of the test
Now it truly uses a single instance
2022-10-09 17:59:05 -04:00
David Protzman 4a493badb1 Removed constructor and deconstructor as these are set to default now 2022-10-09 17:58:43 -04:00
David Protzman c3c8320c8f Added comments for utils class 2022-10-09 17:58:10 -04:00
5 zmienionych plików z 72 dodań i 33 usunięć

Wyświetl plik

@ -24,18 +24,61 @@ namespace dji_droneid {
class DJI_DRONEID_API utils
{
public:
utils();
~utils();
utils() = default;
~utils() = default;
// Hz between each carrier in DroneID
static constexpr float CARRIER_SPACING = 15e3;
static constexpr uint32_t DATA_CARRIER_COUNT = 600;
static constexpr std::complex<float> I = std::complex<float>(0, 1);
// Number of OFDM data carriers in DroneID (independent of sample rate)
static constexpr uint32_t DATA_CARRIER_COUNT = 600;
/**
* Get the correct FFT size based on the sample rate
* @param sample_rate Sample rate (in Hz) of the collected samples
* @return Number of FFT bins required
*/
static uint32_t get_fft_size(float sample_rate);
/**
* Get the correct sample rate based on the FFT size
* @param fft_size Number of FFT bins
* @return Sample rate (in Hz)
*/
static float get_sample_rate(uint32_t fft_size);
/**
* Get a list of FFT bins (all positive, assuming that DC is in the middle) that should be used as data carriers
* @param sample_rate Sample rate (in Hz)
* @return List of utils::DATA_CARRIER_COUNT values denoting position of all data carriers
*/
static std::vector<uint32_t> get_data_carrier_indices(float sample_rate);
/**
* Create a Zadoff Chu sequence of `length` elements using the root index `root`
* @param root Root index
* @param length Number of elements to create
* @return Vector of complex floats
*/
static std::vector<std::complex<float>> zadoff_chu(uint32_t root, uint32_t length);
/**
* Create a time domain ZC sequence for the specified OFDM symbol index (4 or 6)
*
* Will be `fft_size` elements long
*
* <b>This only currently works for drones that have two ZC sequences present!!!</b>
* @param fft_size Number of FFT bins the sequence should be generated for
* @param symbol_idx Symbol index to generate the sequence for (must be 4 or 6)
* @return Complex float vector of `fft_bins` elements representing the gold ZC sequence in the time domain
*/
static std::vector<std::complex<float>> create_zc(uint32_t fft_size, uint8_t symbol_idx);
/**
* Get the long and short cyclic prefix lengths for the provided sample rate
* @param sample_rate Sample rate (in Hz)
* @return Pair with the first element being the long cyclic prefix length in samples, second being the short
*/
static std::pair<uint16_t, uint16_t> get_cyclic_prefix_lengths(float sample_rate);
private:
@ -44,6 +87,4 @@ private:
} // namespace dji_droneid
} // namespace gr
#endif /* INCLUDED_DJI_DRONEID_UTILS_H */

Wyświetl plik

@ -19,27 +19,32 @@ using namespace matlab::engine;
std::unique_ptr<MATLABEngine> matlab_engine = nullptr;
matlab::data::ArrayFactory factory;
struct MatlabHandler {
MatlabHandler() {
matlab_engine = startMATLAB();
matlab_engine->eval(u"addpath(genpath('" MATLAB_SOURCE_PATH "'));");
}
~MatlabHandler() {
matlab_engine = nullptr;
}
};
BOOST_GLOBAL_FIXTURE(MatlabHandler);
struct TestFixture {
TestFixture () {
if (matlab_engine == nullptr) {
BOOST_TEST_MESSAGE("Starting MATLAB");
matlab_engine = startMATLAB();
BOOST_TEST_MESSAGE("MATLAB started");
matlab_engine->eval(u"addpath(genpath('" MATLAB_SOURCE_PATH "'));");
BOOST_TEST_MESSAGE("Added MATLAB source directory " MATLAB_SOURCE_PATH " to the path");
} else {
BOOST_TEST_MESSAGE("MATLAB already running");
}
BOOST_REQUIRE(matlab_engine != nullptr);
}
static void setup() {
// Since the MATLAB instance is never reset, the workspace needs to be cleared each time for sanity
TestFixture::clear_workspace();
}
~TestFixture() = default;
static void clear_workspace() {
std::cout << "[INFO] Clearing workspace\n";
matlab_engine->eval(u"clear all;");
}
@ -65,8 +70,6 @@ struct TestFixture {
matlab_engine->setVariable("fft_size", factory.createScalar(static_cast<double>(fft_size)));
matlab_engine->setVariable("symbol_idx", factory.createScalar(static_cast<double>(symbol_idx)));
matlab_engine->eval(u"zc = create_zc(fft_size, symbol_idx);");
matlab_engine->eval(u"fft_size");
matlab_engine->eval(u"symbol_idx");
const matlab::data::TypedArray<std::complex<double>> ret = matlab_engine->getVariable("zc");
@ -112,8 +115,9 @@ struct TestFixture {
}
};
BOOST_FIXTURE_TEST_SUITE(Utils_Test_Suite, TestFixture);
BOOST_FIXTURE_TEST_CASE(test_utils__get_fft_size, TestFixture)
BOOST_AUTO_TEST_CASE(test_utils__get_fft_size)
{
const std::vector<float> rates = {15.36e6, 30.72e6, 61.44e6};
for (const auto & rate : rates) {
@ -126,7 +130,7 @@ BOOST_FIXTURE_TEST_CASE(test_utils__get_fft_size, TestFixture)
BOOST_REQUIRE_THROW(utils::get_fft_size(10.1e6), std::runtime_error);
}
BOOST_FIXTURE_TEST_CASE(test_utils__get_data_carrier_indices, TestFixture)
BOOST_AUTO_TEST_CASE(test_utils__get_data_carrier_indices)
{
const std::vector<float> rates = {15.36e6, 30.72e6, 61.44e6};
for (const auto & rate : rates) {
@ -137,7 +141,7 @@ BOOST_FIXTURE_TEST_CASE(test_utils__get_data_carrier_indices, TestFixture)
}
}
BOOST_FIXTURE_TEST_CASE(test_utils__get_sample_rate, TestFixture) {
BOOST_AUTO_TEST_CASE(test_utils__get_sample_rate) {
const std::vector<uint32_t> fft_sizes = {1024, 2048, 4096, 8192, 16384};
for (const auto & fft_size : fft_sizes) {
const auto expected = static_cast<float>(fft_size) * utils::CARRIER_SPACING;
@ -147,7 +151,7 @@ BOOST_FIXTURE_TEST_CASE(test_utils__get_sample_rate, TestFixture) {
}
}
BOOST_FIXTURE_TEST_CASE(test_utils__create_zc, TestFixture) {
BOOST_AUTO_TEST_CASE(test_utils__create_zc) {
const std::vector<uint32_t> lengths = {1024, 2048, 4096, 8192};
const std::vector<uint8_t> symbol_indices = {4, 6};
@ -170,7 +174,7 @@ BOOST_FIXTURE_TEST_CASE(test_utils__create_zc, TestFixture) {
}
}
BOOST_FIXTURE_TEST_CASE(test_utils__zadoff_chu, TestFixture) {
BOOST_AUTO_TEST_CASE(test_utils__zadoff_chu) {
std::vector<uint32_t> roots = {600, 147};
std::vector<uint32_t> lengths = {601};
@ -185,7 +189,7 @@ BOOST_FIXTURE_TEST_CASE(test_utils__zadoff_chu, TestFixture) {
}
}
BOOST_FIXTURE_TEST_CASE(test_utils__get_cyclic_prefix, TestFixture) {
BOOST_AUTO_TEST_CASE(test_utils__get_cyclic_prefix) {
std::vector<float> sample_rates = {15.36e6, 30.72e6, 61.44e6};
for (const auto & sample_rate : sample_rates) {
@ -197,5 +201,7 @@ BOOST_FIXTURE_TEST_CASE(test_utils__get_cyclic_prefix, TestFixture) {
}
}
BOOST_AUTO_TEST_SUITE_END()
} /* namespace dji_droneid */
} /* namespace gr */

Wyświetl plik

@ -15,9 +15,6 @@
namespace gr {
namespace dji_droneid {
utils::utils() {}
utils::~utils() {}
std::vector<uint32_t> utils::get_data_carrier_indices(const float sample_rate)
{
const auto fft_size = get_fft_size(sample_rate);

Wyświetl plik

@ -14,7 +14,7 @@
/* BINDTOOL_GEN_AUTOMATIC(0) */
/* BINDTOOL_USE_PYGCCXML(0) */
/* BINDTOOL_HEADER_FILE(utils.h) */
/* BINDTOOL_HEADER_FILE_HASH(5d705b1f8dd1119e4d23e6638798b4ed) */
/* BINDTOOL_HEADER_FILE_HASH(341b0421657c63a408a05e68560d4ff8) */
/***********************************************************************************/
#include <pybind11/complex.h>

Wyświetl plik

@ -20,14 +20,9 @@ function [samples] = create_zc(fft_size, symbol_index)
else
root = 147;
end
root
% Would use MATLAB's zadoffChuSeq function, but Octave doesn't have that
% The logic below was tested against the MATLAB function
% vals = pi * root * (0:600) .* (1:601) / 601;
% zc = cos(vals) + (1j * sin(vals));
zc = reshape(exp(-1j * pi * root * (0:600) .* (1:601) / 601), [], 1);
% Remove the middle value (this would be DC in the FFT)