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;
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 (abs(ultimo_cx - cx) <= 1 && 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 (abs(dx) > 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 (abs(dx) > 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)
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.
T square(const T x)
Inline function for the square of a number.
#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...
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.