diff --git a/CMakeLists.txt b/CMakeLists.txt index 5ac48c8..cf62050 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,6 +22,7 @@ add_executable(blah2 ${PROJECT_SOURCE_DIR}/process/ambiguity/Ambiguity.cpp ${PROJECT_SOURCE_DIR}/process/clutter/WienerHopf.cpp ${PROJECT_SOURCE_DIR}/process/detection/CfarDetector1D.cpp + ${PROJECT_SOURCE_DIR}/process/detection/Centroid.cpp ${PROJECT_SOURCE_DIR}/data/IqData.cpp ${PROJECT_SOURCE_DIR}/data/Map.cpp ${PROJECT_SOURCE_DIR}/data/Detection.cpp diff --git a/html/js/plot_map.js b/html/js/plot_map.js index 35360de..6ba9328 100644 --- a/html/js/plot_map.js +++ b/html/js/plot_map.js @@ -87,16 +87,17 @@ var intervalId = window.setInterval(function () { .done(function (data) { if (timestamp != data) { timestamp = data; + + // get detection data (no detection lag) + var detectionData = $.getJSON(urlDetection, function () { }) + .done(function (data_detection) { + detection = data_detection; + }); + // get new map data var apiData = $.getJSON(urlMap, function () { }) .done(function (data) { - // get detection data - var detectionData = $.getJSON(urlDetection, function () { }) - .done(function (data_detection) { - detection = data_detection; - }); - // case draw new plot if (data.nRows != nRows) { nRows = data.nRows; diff --git a/src/blah2.cpp b/src/blah2.cpp index 66824a8..2f41045 100644 --- a/src/blah2.cpp +++ b/src/blah2.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -86,6 +87,7 @@ int main(int argc, char **argv) Map *mapdb; std::string mapJson, detectionJson; Detection *detection; + Detection *detection1; // setup fftw multithread if (fftw_init_threads() == 0) @@ -154,6 +156,9 @@ int main(int argc, char **argv) tree["process"]["detection"]["minDoppler"] >> minDoppler; CfarDetector1D *cfarDetector1D = new CfarDetector1D(pfa, nGuard, nTrain, minDelay, minDoppler); + // setup process centroid + Centroid *centroid = new Centroid(nGuard, nGuard, 1/tCpi); + // setup output data bool saveMap; tree["save"]["map"] >> saveMap; @@ -220,7 +225,8 @@ int main(int argc, char **argv) timing_time.push_back(delta_t3); // detection process - detection = cfarDetector1D->process(map); + detection1 = cfarDetector1D->process(map); + detection = centroid->process(detection1); uint64_t t4 = current_time_us(); double delta_t4 = (double)(t4-t3) / 1000; timing_name.push_back("detector"); @@ -248,6 +254,7 @@ int main(int argc, char **argv) socket_detection.write_some(asio::buffer(subdata, subdata.size()), err); } delete detection; + delete detection1; // output radar data timer uint64_t t5 = current_time_us(); diff --git a/src/data/Detection.cpp b/src/data/Detection.cpp index 2342464..293b45d 100644 --- a/src/data/Detection.cpp +++ b/src/data/Detection.cpp @@ -31,7 +31,7 @@ std::vector Detection::get_snr() return snr; } -uint8_t Detection::get_nDetections() +size_t Detection::get_nDetections() { return delay.size(); } diff --git a/src/data/Detection.h b/src/data/Detection.h index a9faaf5..ec89b1b 100644 --- a/src/data/Detection.h +++ b/src/data/Detection.h @@ -43,7 +43,7 @@ public: /// @brief Get number of detections. /// @return Number of detections - uint8_t get_nDetections(); + size_t get_nDetections(); /// @brief Generate JSON of the detections and metadata. /// @return JSON string. diff --git a/src/process/detection/Centroid.cpp b/src/process/detection/Centroid.cpp new file mode 100644 index 0000000..556ffcc --- /dev/null +++ b/src/process/detection/Centroid.cpp @@ -0,0 +1,75 @@ +#include "Centroid.h" +#include +#include +#include + +// constructor +Centroid::Centroid(int8_t _nDelay, int8_t _nDoppler, double _resolutionDoppler) +{ + // input + nDelay = _nDelay; + nDoppler = _nDoppler; + resolutionDoppler = _resolutionDoppler; +} + +Centroid::~Centroid() +{ +} + +Detection *Centroid::process(Detection *x) +{ + // store detections temporarily + std::vector delay, doppler, snr; + delay = x->get_delay(); + doppler = x->get_doppler(); + snr = x->get_snr(); + + // centroid data + int8_t delayMin, delayMax; + double dopplerMin, dopplerMax; + bool isCentroid; + std::vector delay2, doppler2, snr2; + + // loop over every detection + for (size_t i = 0; i < snr.size(); i++) + { + delayMin = delay[i] - nDelay; + delayMax = delay[i] + nDelay; + dopplerMin = doppler[i] - (nDoppler * resolutionDoppler); + dopplerMax = doppler[i] + (nDoppler * resolutionDoppler); + isCentroid = true; + + // find detections to keep + for (size_t j = 0; j < snr.size(); j++) + { + // skip same detection + if (j == i) + { + continue; + } + // search detections close by + if (delay[j] > delayMin && delay[j] < delayMax && + doppler[j] > dopplerMin && doppler[j] < dopplerMax) + { + // remove if SNR is lower + if (snr[i] < snr[j]) + { + isCentroid = false; + break; + } + } + } + // store centroided detections + if (isCentroid) + { + delay2.push_back(delay[i]); + doppler2.push_back(doppler[i]); + snr2.push_back(snr[i]); + } + } + + // create detection + Detection *detection = new Detection(delay2, doppler2, snr2); + + return detection; +} diff --git a/src/process/detection/Centroid.h b/src/process/detection/Centroid.h new file mode 100644 index 0000000..725fe3f --- /dev/null +++ b/src/process/detection/Centroid.h @@ -0,0 +1,47 @@ +/// @file Centroid.h +/// @class Centroid +/// @brief A class to remove duplicate target detections. +/// @details If detection SNR is larger than neighbours, then remove. +/// @author 30hours +/// @todo Still a bug where sometimes 2 consecutive range detections get through. + +#ifndef CENTROID_H +#define CENTROID_H + +#include +#include + +class Centroid +{ +private: + /// @brief Number of delay bins to check. + int8_t nDelay; + + /// @brief Number of Doppler bins to check. + int8_t nDoppler; + + /// @brief Doppler resolution to convert Hz to bins (Hz). + double resolutionDoppler; + + /// @brief Pointer to detection data to store result. + Detection *detection; + +public: + /// @brief Constructor. + /// @param nDelay Number of delay bins to check. + /// @param nDoppler Number of Doppler bins to check. + /// @param resolutionDoppler Doppler resolution to convert Hz to bins (Hz). + /// @return The object. + Centroid(int8_t nDelay, int8_t nDoppler, double resolutionDoppler); + + /// @brief Destructor. + /// @return Void. + ~Centroid(); + + /// @brief Implement the 1D CFAR detector. + /// @param x Detections from the 1D CFAR detector. + /// @return Centroided detections. + Detection *process(Detection *x); +}; + +#endif