25 float threshold,
float robot_size,
int x1,
int x2,
int y1,
int y2)
28 if (!x1 && !x2 && !y1 && !y2)
38 x2 = min(x2, static_cast<int>(size_x) - 1);
39 y2 = min(y2, static_cast<int>(size_y) - 1);
42 int robot_size_units =
round(100 * robot_size / resolution);
47 m_voronoi_diagram.setSize(
48 x_min, x_max, y_min, y_max, resolution);
51 m_voronoi_diagram.fill(0);
54 voroni_free_threshold = 1.0f - threshold;
56 int basis_x[2], basis_y[2];
60 for (
int x = x1; x <= x2; x++)
62 for (
int y = y1; y <= y2; y++)
65 computeClearance(x, y, basis_x, basis_y, &nBasis);
67 if (Clearance > robot_size_units)
68 setVoroniClearance(x, y, Clearance);
76 for (
int x = x1; x <= x2; x++)
78 for (
int y = y1; y <= y2; y++)
80 if (getVoroniClearance(x, y))
83 for (
int xx = x - 1; xx <= (x + 1); xx++)
84 for (
int yy = y - 1; yy <= (y + 1); yy++)
85 if (getVoroniClearance(xx, yy)) nDiag++;
88 if (nDiag > 3) setVoroniClearance(x, y, 0);
101 int filter_dist =
round(filter_distance / resolution);
102 int min_clear_near, max_clear_near;
106 x_min, x_max, y_min, y_max,
113 std::vector<int> temp_x, temp_y, temp_clear, temp_borrar;
117 for (
int x = 1; x < (static_cast<int>(size_x) - 1); x++)
119 for (
int y = 1; y < (static_cast<int>(size_y) - 1); y++)
121 if (0 != (clear_xy = getVoroniClearance(x, y)))
124 int nVecinosVoroni = 0;
125 min_clear_near = max_clear_near = clear_xy;
127 for (
int xx = x - 2; xx <= (x + 2); xx++)
128 for (
int yy = y - 2; yy <= (y + 2); yy++)
130 if (0 != (
clear = getVoroniClearance(xx, yy)))
133 min_clear_near = min(min_clear_near,
clear);
134 max_clear_near = max(max_clear_near,
clear);
139 if (nVecinosVoroni >= 3 && min_clear_near == clear_xy &&
140 max_clear_near != clear_xy)
145 temp_clear.push_back(clear_xy);
146 temp_borrar.push_back(0);
154 std::vector<int> basis1_x, basis1_y, basis2_x, basis2_y;
155 for (
unsigned i = 0; i < temp_x.size(); i++)
161 computeClearance(temp_x[i], temp_y[i], basis_x, basis_y, &nBasis);
165 basis1_x.push_back(basis_x[0]);
166 basis1_y.push_back(basis_y[0]);
168 basis2_x.push_back(basis_x[1]);
169 basis2_y.push_back(basis_y[1]);
174 for (
unsigned i = 0; i < (((temp_x.size())) - 1); i++)
178 for (
unsigned int j = i + 1; j < temp_x.size(); j++)
185 ax = basis1_x[i] - basis1_x[j];
186 ay = basis1_y[i] - basis1_y[j];
187 bool i1j1 = (sqrt(1.0f * ax * ax + ay * ay) < filter_dist);
190 ax = basis1_x[i] - basis2_x[j];
191 ay = basis1_y[i] - basis2_y[j];
192 bool i1j2 = (sqrt(1.0f * ax * ax + ay * ay) < filter_dist);
195 ax = basis2_x[i] - basis1_x[j];
196 ay = basis2_y[i] - basis1_y[j];
197 bool i2j1 = (sqrt(1.0f * ax * ax + ay * ay) < filter_dist);
200 ax = basis2_x[i] - basis2_x[j];
201 ay = basis2_y[i] - basis2_y[j];
202 bool i2j2 = (sqrt(1.0f * ax * ax + ay * ay) < filter_dist);
205 if ((i1j1 && i2j2) || (i1j2 && i2j1))
207 if (temp_clear[i] < temp_clear[j])
219 CriticalPointsList.clearance.clear();
220 CriticalPointsList.x.clear();
221 CriticalPointsList.y.clear();
222 CriticalPointsList.x_basis1.clear();
223 CriticalPointsList.y_basis1.clear();
224 CriticalPointsList.x_basis2.clear();
225 CriticalPointsList.y_basis2.clear();
227 for (
unsigned i = 0; i < temp_x.size(); i++)
231 CriticalPointsList.x.push_back(temp_x[i]);
232 CriticalPointsList.y.push_back(temp_y[i]);
233 CriticalPointsList.clearance.push_back(temp_clear[i]);
236 setBasisCell(temp_x[i], temp_y[i], 1);
256 int cx,
int cy,
int* basis_x,
int* basis_y,
int* nBasis,
257 bool GetContourPoint)
const 259 static const cellType thresholdCellValue = p2l(0.5f);
262 if (static_cast<unsigned>(cx) >= size_x ||
263 static_cast<unsigned>(cy) >= size_y)
266 if (map[cx + cy * size_y] < thresholdCellValue)
return 0;
272 static int ultimo_cx = -10, ultimo_cy = -10;
273 int estimated_min_free_circle;
274 static int ultimo_free_circle;
276 if (std::abs(ultimo_cx - cx) <= 1 && std::abs(ultimo_cy - cy) <= 1)
277 estimated_min_free_circle = max(1, ultimo_free_circle - 3);
279 estimated_min_free_circle = 1;
285 #define N_CIRCULOS 100 286 static bool tabla_construida =
false;
289 static int circs_x[32000], circs_y[32000];
291 if (!tabla_construida)
293 tabla_construida =
true;
294 int indice_absoluto = 0;
301 float AA = (2.0f *
M_PIf / nPasos);
302 int ult_x = 0, x, ult_y = 0, y;
305 circ_PrimeraEntrada[i] = indice_absoluto;
312 if ((x != ult_x || y != ult_y) && !(x == i && y == 0))
314 circs_x[indice_absoluto] = x;
315 circs_y[indice_absoluto++] = y;
325 nEntradasCirculo[i] = nEntradas;
334 int vueltas_extra = 2;
336 for (tam_circ = estimated_min_free_circle;
337 tam_circ <
N_CIRCULOS && (!(*nBasis) || vueltas_extra); tam_circ++)
339 int nEnts = nEntradasCirculo[tam_circ];
340 bool dentro_obs =
false;
341 int idx = circ_PrimeraEntrada[tam_circ];
343 for (
int j = 0; j < nEnts && (*nBasis) < 2; j++, idx++)
345 int xx = cx + circs_x[idx];
346 int yy = cy + circs_y[idx];
348 if (xx >= 0 && xx < static_cast<int>(size_x) && yy >= 0 &&
349 yy < static_cast<int>(size_y))
352 if (map[xx + yy * size_y] < thresholdCellValue)
365 int ax = basis_x[0] - xx;
366 int ay = basis_y[0] - yy;
367 pasa = sqrt(1.0f * ax * ax + ay * ay) >
373 basis_x[*nBasis] = cx + circs_x[idx];
374 basis_y[*nBasis] = cy + circs_y[idx];
395 ultimo_free_circle = tam_circ;
402 int dx, dy, dir_predilecta,
dir;
405 dx = cx - basis_x[0];
406 dy = cy - basis_y[0];
407 if (std::abs(dx) > std::abs(dy))
417 vec = GetNeighborhood(basis_x[0], basis_y[0]);
419 if (!(vec & (1 << dir_predilecta)))
420 dir = dir_predilecta;
421 else if (!(vec & (1 << 1)))
423 else if (!(vec & (1 << 3)))
425 else if (!(vec & (1 << 4)))
427 else if (!(vec & (1 << 6)))
431 vec = GetNeighborhood(
432 basis_x[0] + direccion_vecino_x[
dir],
433 basis_y[0] + direccion_vecino_y[
dir]);
434 if (vec != 0x00 && vec != 0xFF)
436 basis_x[0] += direccion_vecino_x[
dir];
437 basis_y[0] += direccion_vecino_y[
dir];
442 dx = cx - basis_x[1];
443 dy = cy - basis_y[1];
444 if (std::abs(dx) > std::abs(dy))
454 vec = GetNeighborhood(basis_x[1], basis_y[1]);
456 if (!(vec & (1 << dir_predilecta)))
457 dir = dir_predilecta;
458 else if (!(vec & (1 << 1)))
460 else if (!(vec & (1 << 3)))
462 else if (!(vec & (1 << 4)))
464 else if (!(vec & (1 << 6)))
468 vec = GetNeighborhood(
469 basis_x[1] + direccion_vecino_x[
dir],
470 basis_y[1] + direccion_vecino_y[
dir]);
471 if (vec != 0x00 && vec != 0xFF)
473 basis_x[1] += direccion_vecino_x[
dir];
474 basis_y[1] += direccion_vecino_y[
dir];
479 return tam_circ * 100;
495 unsigned char res = 0;
497 if (getCell(cx - 1, cy - 1) <= voroni_free_threshold) res |= (1 << 0);
498 if (getCell(cx, cy - 1) <= voroni_free_threshold) res |= (1 << 1);
499 if (getCell(cx + 1, cy - 1) <= voroni_free_threshold) res |= (1 << 2);
500 if (getCell(cx - 1, cy) <= voroni_free_threshold) res |= (1 << 3);
501 if (getCell(cx + 1, cy) <= voroni_free_threshold) res |= (1 << 4);
502 if (getCell(cx - 1, cy + 1) <= voroni_free_threshold) res |= (1 << 5);
503 if (getCell(cx, cy + 1) <= voroni_free_threshold) res |= (1 << 6);
504 if (getCell(cx + 1, cy + 1) <= voroni_free_threshold) res |= (1 << 7);
562 float x,
float y,
float maxSearchDistance)
const 564 int xx1 = max(0, x2idx(x - maxSearchDistance));
566 min(static_cast<unsigned>(size_x - 1),
567 static_cast<unsigned>(x2idx(x + maxSearchDistance)));
568 int yy1 = max(0, y2idx(y - maxSearchDistance));
570 min(static_cast<unsigned>(size_y - 1),
571 static_cast<unsigned>(y2idx(y + maxSearchDistance)));
577 float clearance_sq =
square(maxSearchDistance);
578 cellType thresholdCellValue = p2l(0.5f);
581 bool atLeastOneFree =
false;
582 for (xx = cx - 1; !atLeastOneFree && xx <= cx + 1; xx++)
583 for (yy = cy - 1; !atLeastOneFree && yy <= cy + 1; yy++)
584 if (getCell(xx, yy) > 0.505f) atLeastOneFree =
true;
586 if (!atLeastOneFree)
return 0;
588 for (xx = xx1; xx <= xx2; xx++)
589 for (yy = yy1; yy <= yy2; yy++)
590 if (map[xx + yy * size_x] < thresholdCellValue)
592 min(clearance_sq,
square(resolution) *
595 return sqrt(clearance_sq);
void findCriticalPoints(float filter_distance)
Builds a list with the critical points from Voronoi diagram, which must must be built before calling ...
void buildVoronoiDiagram(float threshold, float robot_size, int x1=0, int x2=0, int y1=0, int y2=0)
Build the Voronoi diagram of the grid map.
#define ASSERT_EQUAL_(__A, __B)
Assert comparing two values, reporting their actual values upon failure.
This namespace contains representation of robot actions and observations.
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
return_t square(const num_t x)
Inline function for the square of a number.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
int direction2idx(int dx, int dy)
Returns the index [0,7] of the given movement, or -1 if invalid one.
unsigned char GetNeighborhood(int cx, int cy) const
Returns a byte with the occupancy of the 8 sorrounding cells.
OccGridCellTraits::cellType cellType
The type of the map cells:
int computeClearance(int cx, int cy, int *basis_x, int *basis_y, int *nBasis, bool GetContourPoint=false) const
Compute the clearance of a given cell, and returns its two first basis (closest obstacle) points...
void clear()
Clear the contents of this container.
int round(const T value)
Returns the closer integer (int) to x.