CfarDetector1D is mostly working at /api/detection

This commit is contained in:
30hours 2023-11-21 13:41:35 +00:00
parent bd3eb5278a
commit bba352ba78
8 changed files with 91 additions and 46 deletions

1
.dockerignore Normal file
View file

@ -0,0 +1 @@
save/

View file

@ -24,6 +24,8 @@ process:
pfa: 0.000001 pfa: 0.000001
nGuard: 10 nGuard: 10
nTrain: 20 nTrain: 20
minDelay: 5
minDoppler: 20
network: network:
ip: 0.0.0.0 ip: 0.0.0.0

View file

@ -24,6 +24,8 @@ process:
pfa: 0.000001 pfa: 0.000001
nGuard: 10 nGuard: 10
nTrain: 20 nTrain: 20
minDelay: 5
minDoppler: 20
network: network:
ip: 0.0.0.0 ip: 0.0.0.0

View file

@ -145,12 +145,14 @@ int main(int argc, char **argv)
WienerHopf *filter = new WienerHopf(delayMinClutter, delayMaxClutter, nSamples); WienerHopf *filter = new WienerHopf(delayMinClutter, delayMaxClutter, nSamples);
// setup process detection // setup process detection
double pfa; double pfa, minDoppler;
int8_t nGuard, nTrain; int8_t nGuard, nTrain, minDelay;
tree["process"]["detection"]["pfa"] >> pfa; tree["process"]["detection"]["pfa"] >> pfa;
tree["process"]["detection"]["nGuard"] >> nGuard; tree["process"]["detection"]["nGuard"] >> nGuard;
tree["process"]["detection"]["nTrain"] >> nTrain; 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 // setup output data
bool saveMap; bool saveMap;
@ -217,7 +219,7 @@ int main(int argc, char **argv)
timing_time.push_back(delta_t3); timing_time.push_back(delta_t3);
// detection process // detection process
// detection = cfarDetector1D->process(map); detection = cfarDetector1D->process(map);
uint64_t t4 = current_time_us(); uint64_t t4 = current_time_us();
double delta_t4 = (double)(t4-t3) / 1000; double delta_t4 = (double)(t4-t3) / 1000;
timing_name.push_back("detector"); timing_name.push_back("detector");
@ -238,13 +240,14 @@ int main(int argc, char **argv)
} }
// output detection data // output detection data
// detectionJson = detection->to_json(); detectionJson = detection->to_json();
// for (int i = 0; i < (detectionJson.size() + MTU - 1) / MTU; i++) 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); subdata = detectionJson.substr(i * MTU, MTU);
// } socket_detection.write_some(asio::buffer(subdata, subdata.size()), err);
// delete detection; }
delete detection;
// output radar data timer // output radar data timer
uint64_t t5 = current_time_us(); uint64_t t5 = current_time_us();

View file

@ -64,6 +64,27 @@ std::string Detection::to_json()
return strbuf.GetString(); 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<rapidjson::StringBuffer> writer(strbuf);
writer.SetMaxDecimalPlaces(2);
document.Accept(writer);
return strbuf.GetString();
}
bool Detection::save(std::string _json, std::string filename) bool Detection::save(std::string _json, std::string filename)
{ {
using namespace rapidjson; using namespace rapidjson;

View file

@ -37,6 +37,12 @@ public:
/// @return JSON string. /// @return JSON string.
std::string to_json(); 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. /// @brief Append the detections to a save file.
/// @param json JSON string of detections and metadata. /// @param json JSON string of detections and metadata.
/// @param path Path of file to save. /// @param path Path of file to save.

View file

@ -1,15 +1,18 @@
#include "CfarDetector1D.h" #include "CfarDetector1D.h"
#include "Map.h"
#include <iostream> #include <iostream>
#include <vector> #include <vector>
#include <cmath> #include <cmath>
// constructor // 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 // input
pfa = _pfa; pfa = _pfa;
nGuard = _nGuard; nGuard = _nGuard;
nTrain = _nTrain; nTrain = _nTrain;
minDelay = _minDelay;
minDoppler = _minDoppler;
} }
CfarDetector1D::~CfarDetector1D() CfarDetector1D::~CfarDetector1D()
@ -18,25 +21,11 @@ CfarDetector1D::~CfarDetector1D()
Detection *CfarDetector1D::process(Map<std::complex<double>> *x) Detection *CfarDetector1D::process(Map<std::complex<double>> *x)
{ {
std::vector<std::vector<double>> dataSnr; int32_t nDelayBins = x->get_nCols();
std::vector<std::vector<double>> dataSquare; int32_t nDopplerBins = x->get_nRows();
// compute square of Map std::vector<std::complex<double>> mapRow;
for (int i = 0; i < x->data.size(); i++) std::vector<double> mapRowSquare, mapRowSnr;
{
std::vector<double> dataSnrRow;
std::vector<double> 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();
// store detections temporarily // store detections temporarily
std::vector<double> delay; std::vector<double> delay;
@ -44,16 +33,28 @@ Detection *CfarDetector1D::process(Map<std::complex<double>> *x)
std::vector<double> snr; std::vector<double> snr;
// loop over every cell // loop over every cell
for (int iDelay = 0; iDelay < nDelayBins; iDelay++) for (int i = 0; i < nDopplerBins; i++)
{ {
for (int iDoppler = 0; iDoppler < nDopplerBins; iDoppler++) 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 // get train cell indices
std::vector<int> iTrain; std::vector<int> 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); iTrain.push_back(k);
} }
@ -63,22 +64,23 @@ Detection *CfarDetector1D::process(Map<std::complex<double>> *x)
int nCells = iTrain.size(); int nCells = iTrain.size();
double alpha = nCells * (pow(pfa, -1.0 / nCells) - 1); double alpha = nCells * (pow(pfa, -1.0 / nCells) - 1);
double trainNoise = 0.0; 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; trainNoise /= nCells;
double threshold = alpha * trainNoise; double threshold = alpha * trainNoise;
// detection if over threshold // detection if over threshold
if (dataSquare[iDoppler][iDelay] > threshold) if (mapRowSquare[j] > threshold)
{ {
delay.push_back(iDelay + x->delay[0] - 1); delay.push_back(j + x->delay[0] - 1);
doppler.push_back(x->doppler[iDoppler]); doppler.push_back(x->doppler[i]);
//snr.push_back(dataSnr[iDoppler][iDelay]); snr.push_back(mapRowSnr[j]);
snr.push_back(-1);
} }
iTrain.clear();
} }
mapRowSquare.clear();
} }
// create detection // create detection

View file

@ -3,7 +3,7 @@
/// @brief A class to implement a 1D CFAR detector. /// @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. /// @details Converts an AmbiguityMap to DetectionData. 1D CFAR operates across delay, to minimise detections from the zero-Doppler line.
/// @author 30hours /// @author 30hours
/// @todo SNR value is broken in process(), temp value -1. /// @todo Actually implement the min delay and Doppler.
#ifndef CFARDETECTOR1D_H #ifndef CFARDETECTOR1D_H
#define CFARDETECTOR1D_H #define CFARDETECTOR1D_H
@ -25,6 +25,12 @@ private:
/// @brief Number of single-sided training cells. /// @brief Number of single-sided training cells.
int8_t nTrain; 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. /// @brief Pointer to detection data to store result.
Detection *detection; Detection *detection;
@ -33,8 +39,10 @@ public:
/// @param pfa Probability of false alarm, numeric in [0,1]. /// @param pfa Probability of false alarm, numeric in [0,1].
/// @param nGuard Number of single-sided guard cells. /// @param nGuard Number of single-sided guard cells.
/// @param nTrain Number of single-sided training 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. /// @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. /// @brief Destructor.
/// @return Void. /// @return Void.