From bba352ba78f67fa315b86aa5e492e0879a2e7aa7 Mon Sep 17 00:00:00 2001 From: 30hours Date: Tue, 21 Nov 2023 13:41:35 +0000 Subject: [PATCH] CfarDetector1D is mostly working at /api/detection --- .dockerignore | 1 + config/config.yml | 2 + config/radar4.yml | 2 + src/blah2.cpp | 25 +++++---- src/data/Detection.cpp | 21 ++++++++ src/data/Detection.h | 6 +++ src/process/detection/CfarDetector1D.cpp | 68 ++++++++++++------------ src/process/detection/CfarDetector1D.h | 12 ++++- 8 files changed, 91 insertions(+), 46 deletions(-) create mode 100644 .dockerignore diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..9a8a9e4 --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +save/ diff --git a/config/config.yml b/config/config.yml index e1806ee..f179557 100644 --- a/config/config.yml +++ b/config/config.yml @@ -24,6 +24,8 @@ process: pfa: 0.000001 nGuard: 10 nTrain: 20 + minDelay: 5 + minDoppler: 20 network: ip: 0.0.0.0 diff --git a/config/radar4.yml b/config/radar4.yml index b01bc03..1781861 100644 --- a/config/radar4.yml +++ b/config/radar4.yml @@ -24,6 +24,8 @@ process: pfa: 0.000001 nGuard: 10 nTrain: 20 + minDelay: 5 + minDoppler: 20 network: ip: 0.0.0.0 diff --git a/src/blah2.cpp b/src/blah2.cpp index ee47e83..09f4351 100644 --- a/src/blah2.cpp +++ b/src/blah2.cpp @@ -145,12 +145,14 @@ int main(int argc, char **argv) WienerHopf *filter = new WienerHopf(delayMinClutter, delayMaxClutter, nSamples); // setup process detection - double pfa; - int8_t nGuard, nTrain; + double pfa, minDoppler; + int8_t nGuard, nTrain, minDelay; tree["process"]["detection"]["pfa"] >> pfa; tree["process"]["detection"]["nGuard"] >> nGuard; tree["process"]["detection"]["nTrain"] >> nTrain; - CfarDetector1D *cfarDetector1D = new CfarDetector1D(pfa, nGuard, nTrain); + tree["process"]["detection"]["minDelay"] >> minDelay; + tree["process"]["detection"]["minDoppler"] >> minDoppler; + CfarDetector1D *cfarDetector1D = new CfarDetector1D(pfa, nGuard, nTrain, minDelay, minDoppler); // setup output data bool saveMap; @@ -217,7 +219,7 @@ int main(int argc, char **argv) timing_time.push_back(delta_t3); // detection process - // detection = cfarDetector1D->process(map); + detection = cfarDetector1D->process(map); uint64_t t4 = current_time_us(); double delta_t4 = (double)(t4-t3) / 1000; timing_name.push_back("detector"); @@ -238,13 +240,14 @@ int main(int argc, char **argv) } // output detection data - // detectionJson = detection->to_json(); - // for (int i = 0; i < (detectionJson.size() + MTU - 1) / MTU; i++) - // { - // subdata = detectionJson.substr(i * MTU, MTU); - // socket_detection.write_some(asio::buffer(subdata, subdata.size()), err); - // } - // delete detection; + detectionJson = detection->to_json(); + detectionJson = detection->delay_bin_to_km(detectionJson, fs); + for (int i = 0; i < (detectionJson.size() + MTU - 1) / MTU; i++) + { + subdata = detectionJson.substr(i * MTU, MTU); + socket_detection.write_some(asio::buffer(subdata, subdata.size()), err); + } + delete detection; // output radar data timer uint64_t t5 = current_time_us(); diff --git a/src/data/Detection.cpp b/src/data/Detection.cpp index ba5f774..a84d59b 100644 --- a/src/data/Detection.cpp +++ b/src/data/Detection.cpp @@ -64,6 +64,27 @@ std::string Detection::to_json() return strbuf.GetString(); } +std::string Detection::delay_bin_to_km(std::string json, uint32_t fs) +{ + rapidjson::Document document; + document.SetObject(); + rapidjson::Document::AllocatorType &allocator = document.GetAllocator(); + document.Parse(json.c_str()); + + document["delay"].Clear(); + for (int i = 0; i < delay.size(); i++) + { + document["delay"].PushBack(1.0*delay[i]*(299792458/(double)fs)/1000, allocator); + } + + rapidjson::StringBuffer strbuf; + rapidjson::Writer writer(strbuf); + writer.SetMaxDecimalPlaces(2); + document.Accept(writer); + + return strbuf.GetString(); +} + bool Detection::save(std::string _json, std::string filename) { using namespace rapidjson; diff --git a/src/data/Detection.h b/src/data/Detection.h index ac048b3..6c4a612 100644 --- a/src/data/Detection.h +++ b/src/data/Detection.h @@ -37,6 +37,12 @@ public: /// @return JSON string. std::string to_json(); + /// @brief Update JSON to convert delay bins to km. + /// @param json Input JSON string with delay field. + /// @param fs Sampling frequency (Hz). + /// @return JSON string. + std::string delay_bin_to_km(std::string json, uint32_t fs); + /// @brief Append the detections to a save file. /// @param json JSON string of detections and metadata. /// @param path Path of file to save. diff --git a/src/process/detection/CfarDetector1D.cpp b/src/process/detection/CfarDetector1D.cpp index eb046b0..6d09e46 100644 --- a/src/process/detection/CfarDetector1D.cpp +++ b/src/process/detection/CfarDetector1D.cpp @@ -1,15 +1,18 @@ #include "CfarDetector1D.h" +#include "Map.h" #include #include #include // constructor -CfarDetector1D::CfarDetector1D(double _pfa, int8_t _nGuard, int8_t _nTrain) +CfarDetector1D::CfarDetector1D(double _pfa, int8_t _nGuard, int8_t _nTrain, int8_t _minDelay, double _minDoppler) { // input pfa = _pfa; nGuard = _nGuard; nTrain = _nTrain; + minDelay = _minDelay; + minDoppler = _minDoppler; } CfarDetector1D::~CfarDetector1D() @@ -17,26 +20,12 @@ CfarDetector1D::~CfarDetector1D() } Detection *CfarDetector1D::process(Map> *x) -{ - std::vector> dataSnr; - std::vector> dataSquare; +{ + int32_t nDelayBins = x->get_nCols(); + int32_t nDopplerBins = x->get_nRows(); - // compute square of Map - for (int i = 0; i < x->data.size(); i++) - { - std::vector dataSnrRow; - std::vector dataSquareRow; - for (int j = 0; j < x->data[i].size(); j++) - { - dataSnrRow.push_back(10 * log10(std::abs(x->data[i][j])) - x->noisePower); - dataSquareRow.push_back(std::abs(x->data[i][j]) * std::abs(x->data[i][j])); - } - dataSnr.push_back(dataSnrRow); - dataSquare.push_back(dataSquareRow); - } - - int32_t nDelayBins = x->get_nRows(); - int32_t nDopplerBins = x->get_nCols(); + std::vector> mapRow; + std::vector mapRowSquare, mapRowSnr; // store detections temporarily std::vector delay; @@ -44,16 +33,28 @@ Detection *CfarDetector1D::process(Map> *x) std::vector snr; // loop over every cell - for (int iDelay = 0; iDelay < nDelayBins; iDelay++) - { - for (int iDoppler = 0; iDoppler < nDopplerBins; iDoppler++) + for (int i = 0; i < nDopplerBins; i++) + { + mapRow = x->get_row(i); + for (int j = 0; j < nDelayBins; j++) + { + mapRowSquare.push_back((double) std::abs(mapRow[j]*mapRow[j])); + mapRowSnr.push_back((double)20 * std::log10(std::abs(mapRow[j]))); + } + for (int j = 0; j < nDelayBins; j++) { - // get train cell indices std::vector iTrain; - for (int k = iDelay - nGuard - nTrain; k <= iDelay + nGuard + nTrain; ++k) + for (int k = j-nGuard-nTrain; k < j-nGuard; k++) { - if (k >= 1 && k <= nDelayBins) + if (k > 0 && k < nDelayBins) + { + iTrain.push_back(k); + } + } + for (int k = j+nGuard+1; k < j+nGuard+nTrain+1; k++) + { + if (k >= 0 && k < nDelayBins) { iTrain.push_back(k); } @@ -63,22 +64,23 @@ Detection *CfarDetector1D::process(Map> *x) int nCells = iTrain.size(); double alpha = nCells * (pow(pfa, -1.0 / nCells) - 1); double trainNoise = 0.0; - for (int k = 0; k < nCells; ++k) + for (int k = 0; k < nCells; k++) { - trainNoise += dataSquare[iDoppler][iTrain[k] - 1]; + trainNoise += mapRowSquare[iTrain[k]]; } trainNoise /= nCells; double threshold = alpha * trainNoise; // detection if over threshold - if (dataSquare[iDoppler][iDelay] > threshold) + if (mapRowSquare[j] > threshold) { - delay.push_back(iDelay + x->delay[0] - 1); - doppler.push_back(x->doppler[iDoppler]); - //snr.push_back(dataSnr[iDoppler][iDelay]); - snr.push_back(-1); + delay.push_back(j + x->delay[0] - 1); + doppler.push_back(x->doppler[i]); + snr.push_back(mapRowSnr[j]); } + iTrain.clear(); } + mapRowSquare.clear(); } // create detection diff --git a/src/process/detection/CfarDetector1D.h b/src/process/detection/CfarDetector1D.h index f22b88b..0064e97 100644 --- a/src/process/detection/CfarDetector1D.h +++ b/src/process/detection/CfarDetector1D.h @@ -3,7 +3,7 @@ /// @brief A class to implement a 1D CFAR detector. /// @details Converts an AmbiguityMap to DetectionData. 1D CFAR operates across delay, to minimise detections from the zero-Doppler line. /// @author 30hours -/// @todo SNR value is broken in process(), temp value -1. +/// @todo Actually implement the min delay and Doppler. #ifndef CFARDETECTOR1D_H #define CFARDETECTOR1D_H @@ -25,6 +25,12 @@ private: /// @brief Number of single-sided training cells. int8_t nTrain; + /// @brief Minimum delay to process detections (bins). + int8_t minDelay; + + /// @brief Minimum absolute Doppler to process detections (Hz). + double minDoppler; + /// @brief Pointer to detection data to store result. Detection *detection; @@ -33,8 +39,10 @@ public: /// @param pfa Probability of false alarm, numeric in [0,1]. /// @param nGuard Number of single-sided guard cells. /// @param nTrain Number of single-sided training cells. + /// @param minDelay Minimum delay to process detections (bins). + /// @param minDoppler Minimum absolute Doppler to process detections (Hz). /// @return The object. - CfarDetector1D(double pfa, int8_t nGuard, int8_t nTrain); + CfarDetector1D(double pfa, int8_t nGuard, int8_t nTrain, int8_t minDelay, double minDoppler); /// @brief Destructor. /// @return Void.