TI-radar AWR1843 C674x DSP core  1
clusteringDBscan.c
Go to the documentation of this file.
1 
39 /* C674x mathlib */
40 #include <ti/mathlib/mathlib.h>
41 #include <string.h>
42 #include <stdint.h>
43 
44 #include "dss_data_path.h"
45 #include "clusteringDBscan.h"
46 
47 
48 
49 
50 
80  DSS_DataPathObj *obj,
81  uint16_t numDetetectedObj,
83  trackingInputReport_t *trackingInput)
84 {
85  uint16_t *neighLast;
86  uint16_t *neighCurrent;
87  uint16_t neighCount;
88  uint16_t newCount;
89  uint16_t point, member;
90  uint16_t numPoints;
91  uint16_t clusterId;
92  uint16_t ind;
93 
94  float epsilon,epsilon2, weight;
95  int32_t epsilon2fixed;
96  int32_t epsilonfixed;
97  int32_t vFactorfixed;
98 
99  MmwDemo_detectedObjActual * detObj2D = obj->detObj2D;
100 
101  numPoints = numDetetectedObj;
102  clusterId = 0;
103  epsilon = inst->epsilon;
104  epsilon2 = epsilon*epsilon;
105  weight = inst->weight;
106 
107  epsilon2fixed = _spint(epsilon2 * (float)(inst->fixedPointScale * inst->fixedPointScale));
108  epsilonfixed = _spint(epsilon * inst->fixedPointScale);
109  vFactorfixed = (int32_t)(inst->vFactor * inst->fixedPointScale);
110 
111  memset(inst->visited, POINT_UNKNOWN, numPoints*sizeof(char));
112 
113  // scan through all the points to find its neighbors
114  for(point = 0; point < numPoints; point++)
115  {
116  if(inst->visited[point] != POINT_VISITED)
117  {
118  inst->visited[point] = POINT_VISITED;
119 
120  neighCurrent = neighLast = inst->neighbors;
121  // scope is the local copy of visit
122  memcpy(inst->scope, inst->visited, numPoints*sizeof(char));
123 
125  detObj2D, point, neighLast, numPoints, epsilon2fixed, epsilonfixed, weight,
126  vFactorfixed,inst->scope, &newCount, inst->dBScanNeighbourLim);
127 
128  /* The cluster consists of the point itself and its neighbours. */
129  if(neighCount < inst->minPointsInCluster - 1)
130  {
131  // This point is Noise
132  output->IndexArray[point] = 0;
133  }
134  else
135  {
136  // This point belongs to a New Cluster
137  clusterId++; // New cluster ID
138  output->IndexArray[point] = clusterId; // This point belong to this cluster
139 
140  // tag all the neighbors as visited in scope so that it will not be found again when searching neighbor's neighbor.
141  for (ind = 0; ind < newCount; ind ++)
142  {
143  member = neighLast[ind];
144  inst->scope[member] = POINT_VISITED;
145  }
146  neighLast += newCount;
147 
148  while (neighCurrent != neighLast) // neigh shall be at least minPoints in front of neighborhood pointer
149  {
150  // Explore the neighborhood
151  member = *neighCurrent++; // Take point from the neighborhood
152  output->IndexArray[member] = clusterId; // All points from the neighborhood also belong to this cluster
153  inst->visited[member] = POINT_VISITED;
154 
156  detObj2D, member, neighLast, numPoints,
157  epsilon2fixed, epsilonfixed, weight,
158  vFactorfixed, inst->scope, &newCount,
159  inst->dBScanNeighbourLim);
160 
161  if(neighCount >= inst->minPointsInCluster)
162  {
163  int32_t speed = (int32_t) detObj2D[point].speed;
164 
165  /* Check if the new point's velocity is the same velocity as the
166  * clusterOriginator. */
167  if (_abs(detObj2D[member].speed - speed) < vFactorfixed)
168  {
169  for (ind = 0; ind < newCount; ind ++)
170  {
171  member = neighLast[ind];
172  inst->scope[member] = POINT_VISITED;
173  }
174  neighLast += newCount; /* Member is a core point, and its neighborhood is added to the cluster */
175  }
176  }
177  }
178 
179  if (clusterId >= inst->maxClusters)
180  {
182  }
183 
184  /* calculate the clustering center and edge information. */
186  detObj2D, inst->neighbors, neighLast,
187  (clusteringDBscanReport_t *)&output->report[clusterId - 1],
188  &trackingInput[clusterId - 1], obj);
189  }
190  }
191  }
192  output->numCluster = clusterId;
193 
194  return DBSCAN_OK;
195 }
196 
197 
198 
248  MmwDemo_detectedObjActual * restrict detObj2D,
249  uint16_t point,
250  uint16_t *restrict neigh,
251  uint16_t numPoints,
252  int32_t epsilon2,
253  int32_t epsilon,
254  float weight,
255  int32_t vFactor,
256  char * restrict visited,
257  uint16_t * restrict newCount,
258  uint16_t dBScanNeighbourLim)
259 {
260  int32_t a,b,c;
261  uint16_t i;
262  int32_t sum, epsilon2WithSpeed, itemp;
263  uint32_t newCounttmp = 0;
264 
265  _nassert((uint32_t)detObj2D % 8 == 0);
266  int16_t x = detObj2D[point].x;
267  int16_t y = detObj2D[point].y;
268  int16_t speed = detObj2D[point].speed;
269  uint16_t range = detObj2D[point].range;
270 
271  itemp = vFactor;
272  if (_abs(speed) < vFactor)
273  {
274  itemp = _abs(speed);
275  }
276 
277  epsilon2WithSpeed = (int32_t)(itemp*itemp*weight + epsilon2);
278 
279  for(i = 0; i < numPoints; i++)
280  {
281  if (visited[i] == POINT_VISITED)
282  {
283  continue;
284  }
285 
286  if (_abs(detObj2D[i].speed - speed) > itemp)
287  {
288  continue;
289  }
290 
291  if (_abs(detObj2D[i].range - range) > epsilon)
292  {
293  continue;
294  }
295 
296  a = detObj2D[i].x - x;
297  b = detObj2D[i].y - y;
298  c = detObj2D[i].speed - speed;
299 
300  sum = (a*a) + (b*b) + (int32_t)(weight*(float)(c*c));
301 
302  if (sum < epsilon2WithSpeed)
303  {
304  /* Mark this point as a neighbour in the list of
305  * neighbours. Also increment the number of neighbours
306  * for this point. */
307  *neigh = i;
308 
309  neigh++;
310 
311  newCounttmp++;
312  }
313  }
314 
315  *newCount = (uint16_t) newCounttmp;
316  return newCounttmp;
317 }
318 
356  uint16_t clusterOriginator,
357  MmwDemo_detectedObjActual * restrict detObj2D,
358  uint16_t * restrict neighStart,
359  uint16_t * restrict neighLast,
360  clusteringDBscanReport_t * restrict report,
361  trackingInputReport_t * restrict trackingInput,
362  DSS_DataPathObj *obj)
363 {
364  int16_t ind, length, member, strongestMember;
365  float sumx, sumy, sumVel, xCenter, yCenter, xSize, ySize, avgVel, temp;
366  float lengthInv;
367  uint16_t strongestPeakVal;
368  length = (neighLast - neighStart);
369  float maxSizeflt;
370  sumx = detObj2D[clusterOriginator].x;
371  sumy = detObj2D[clusterOriginator].y;
372  sumVel = detObj2D[clusterOriginator].speed;
373 
374  for (ind = 0; ind < length; ind++)
375  {
376  member = neighStart[ind];
377  sumx += (float)(detObj2D[member].x);
378  sumy += (float)(detObj2D[member].y);
379  sumVel += (float)(detObj2D[member].speed);
380  }
381 
382  lengthInv = recipsp((float)(length + 1));
383  xCenter = sumx * lengthInv;
384  yCenter = sumy * lengthInv;
385  avgVel = sumVel * lengthInv;
386  xSize = 0;
387  ySize = 0;
388 
389  strongestPeakVal = detObj2D[clusterOriginator].peakVal;
390  strongestMember = clusterOriginator;
391 
392  temp = ( ((float)detObj2D[strongestMember].x) - xCenter);
393  temp = ((temp > 0)? (temp): (-temp)); //abs
394  xSize =(xSize > temp)? (xSize):(temp); //max
395  temp = ( ((float)detObj2D[strongestMember].y) - yCenter);
396  temp = ((temp > 0)? (temp): (-temp)); //abs
397  ySize = ((ySize > temp)? (ySize):(temp));//max
398 
399  for (ind = 0; ind < length; ind++)
400  {
401  member = neighStart[ind];
402  temp = ( ((float)detObj2D[member].x) - xCenter);
403  temp = ((temp > 0)? (temp): (-temp)); //abs
404  xSize =(xSize > temp)? (xSize):(temp); //max
405  temp = ( ((float)detObj2D[member].y) - yCenter);
406  temp = ((temp > 0)? (temp): (-temp)); //abs
407  ySize = ((ySize > temp)? (ySize):(temp));//max
408 
409  if(detObj2D[member].peakVal > strongestPeakVal)
410  {
411  strongestPeakVal = detObj2D[member].peakVal;
412  strongestMember = member;
413  }
414  }
415 
416  /* If the size is absurd, due to the fact that the cluster has only
417  * one point, put in a more reasonable number. */
418  if ((xSize == 0) || (ySize == 0))
419  {
420  uint32_t oneQFormat = (1 << obj->xyzOutputQFormat);
421  xSize = (uint16_t) (3.0f * obj->rangeResolution * oneQFormat);
422  ySize = (uint16_t) (3.0f * obj->rangeResolution * oneQFormat);
423  }
424  /* The clusterOriginator is also added to the number of points in
425  * the cluster */
426  report->numPoints = length + 1;
427  report->xCenter = (int16_t)(xCenter);
428  report->yCenter = (int16_t)(yCenter);
429  report->xSize = (int16_t)(xSize);
430  report->ySize = (int16_t)(ySize);
431  report->avgVel = (int16_t)(avgVel);
432 
433  /* Populate the inputs to the Kalman filter, if necessary. */
434 
435 }
436 
clusteringDBscan.h
DBscan clustering module.
clusteringDBscanInstance::visited
char * visited
Definition: dss_data_path.h:323
clusteringDBscanInstance::minPointsInCluster
uint16_t minPointsInCluster
Definition: dss_data_path.h:313
clusteringDBscanInstance
error code for clusteringDBscan.
Definition: dss_data_path.h:308
clusteringDBscanInstance::scope
char * scope
Definition: dss_data_path.h:324
clusteringDBscanInstance::neighbors
uint16_t * neighbors
Definition: dss_data_path.h:325
trackingInputReport
Input to tracking from the clustering output.
Definition: dss_data_path.h:358
clusteringDBscanInstance::dBScanNeighbourLim
uint16_t dBScanNeighbourLim
Definition: dss_data_path.h:318
DSS_DataPathObj_t::rangeResolution
float rangeResolution
range resolution in meters
Definition: dss_data_path.h:679
clusteringDBscan_findNeighbors2Fixed
uint16_t clusteringDBscan_findNeighbors2Fixed(MmwDemo_detectedObjActual *restrict detObj2D, uint16_t point, uint16_t *restrict neigh, uint16_t numPoints, int32_t epsilon2, int32_t epsilon, float weight, int32_t vFactor, char *restrict visited, uint16_t *restrict newCount, uint16_t dBScanNeighbourLim)
Definition: clusteringDBscan.c:247
clusteringDBscanInstance::fixedPointScale
uint16_t fixedPointScale
Definition: dss_data_path.h:319
DSS_DataPathObj_t::detObj2D
MmwDemo_detectedObjActual * detObj2D
Detected objects after second pass in Range direction. These objects are send out as point clouds.
Definition: dss_data_path.h:707
DBSCAN_ERROR_CLUSTER_LIMIT_REACHED
Definition: dss_data_path.h:302
clusteringDBscanOutput::IndexArray
uint16_t * IndexArray
Definition: dss_data_path.h:369
clusteringDBscanOutput::report
clusteringDBscanReport_t * report
Definition: dss_data_path.h:371
clusteringDBscanReport
Structure for each cluster information report .
Definition: dss_data_path.h:347
MmwDemo_detectedObjActual_t
Detected object estimated parameters.
Definition: dss_data_path.h:153
DSS_DataPathObj_t::xyzOutputQFormat
uint8_t xyzOutputQFormat
Q format of the output x/y/z coordinates.
Definition: dss_data_path.h:576
clusteringDBscanInstance::weight
float weight
Definition: dss_data_path.h:311
clusteringDBscanOutput
Structure of clustering output.
Definition: dss_data_path.h:367
clusteringDBscanRun
int32_t clusteringDBscanRun(clusteringDBscanInstance_t *inst, DSS_DataPathObj *obj, uint16_t numDetetectedObj, clusteringDBscanOutput_t *output, trackingInputReport_t *trackingInput)
Definition: clusteringDBscan.c:79
clusteringDBscanOutput::numCluster
uint16_t numCluster
Definition: dss_data_path.h:370
DSS_DataPathObj_t
Millimeter Wave Demo Data Path Information.
Definition: dss_data_path.h:444
DBSCAN_OK
Definition: dss_data_path.h:299
clusteringDBscanInstance::vFactor
float vFactor
Definition: dss_data_path.h:312
POINT_VISITED
#define POINT_VISITED
Definition: clusteringDBscan.h:46
clusteringDBscanInstance::epsilon
float epsilon
Definition: dss_data_path.h:310
clusteringDBscanInstance::maxClusters
uint16_t maxClusters
Definition: dss_data_path.h:314
clusteringDBscan_calcInfoFixed
void clusteringDBscan_calcInfoFixed(uint16_t clusterOriginator, MmwDemo_detectedObjActual *restrict detObj2D, uint16_t *restrict neighStart, uint16_t *restrict neighLast, clusteringDBscanReport_t *restrict report, trackingInputReport_t *restrict trackingInput, DSS_DataPathObj *obj)
Definition: clusteringDBscan.c:355
POINT_UNKNOWN
#define POINT_UNKNOWN
#defines for the state of the detected points w.r.t to the clustering algorithms.
Definition: clusteringDBscan.h:45
dss_data_path.h
This is the data path processing header.