34 if (!x1 && !x2 && !y1 && !y2) {
42 x2=
min(x2,static_cast<int>(size_x)-1);
43 y2=
min(y2,static_cast<int>(size_y)-1);
46 int robot_size_units=
round(100*robot_size / resolution);
51 m_voronoi_diagram.setSize(x_min,x_max, y_min,y_max, resolution);
54 m_voronoi_diagram.fill(0);
57 voroni_free_threshold= 1.0f - threshold;
59 int basis_x[2],basis_y[2];
63 for (
int x=x1;
x<=x2;
x++) {
64 for (
int y=y1;
y<=y2;
y++)
66 const int Clearance = computeClearance(
x,
y,basis_x,basis_y,&nBasis);
68 if (Clearance > robot_size_units )
69 setVoroniClearance(
x,
y,Clearance );
77 for (
int x=x1;
x<=x2;
x++) {
78 for (
int y=y1;
y<=y2;
y++) {
79 if ( getVoroniClearance(
x,
y) )
82 for (
int xx=
x-1;xx<=(
x+1);xx++)
83 for (
int yy=
y-1;yy<=(
y+1);yy++)
84 if (getVoroniClearance(xx,yy)) nDiag++;
88 setVoroniClearance(
x,
y,0);
101 int filter_dist =
round(filter_distance / resolution);
102 int min_clear_near, max_clear_near;
106 m_basis_map.setSize(x_min,x_max, y_min,y_max, resolution);
112 std::vector<int> temp_x,temp_y, temp_clear, temp_borrar;
118 if ( 0!=(clear_xy=getVoroniClearance(
x,
y)) )
121 int nVecinosVoroni = 0;
122 min_clear_near = max_clear_near = clear_xy;
124 for (
int xx=
x-2;xx<=(
x+2);xx++)
125 for (
int yy=
y-2;yy<=(
y+2);yy++)
127 if ( 0!=(
clear = getVoroniClearance(xx,yy)) )
130 min_clear_near =
min( min_clear_near ,
clear );
131 max_clear_near = max( max_clear_near ,
clear );
136 if (nVecinosVoroni>=3 && min_clear_near==clear_xy && max_clear_near!=clear_xy )
139 temp_x.push_back(
x );
140 temp_y.push_back(
y );
141 temp_clear.push_back( clear_xy );
142 temp_borrar.push_back( 0 );
150 std::vector<int> basis1_x,basis1_y, basis2_x,basis2_y;
151 for (
unsigned i=0;i<temp_x.size();i++)
157 computeClearance(temp_x[i],temp_y[i],basis_x,basis_y,&nBasis);
161 basis1_x.push_back(basis_x[0]);
162 basis1_y.push_back(basis_y[0]);
164 basis2_x.push_back(basis_x[1]);
165 basis2_y.push_back(basis_y[1]);
170 for (
unsigned i=0;i<(((temp_x.size()))-1);i++) {
171 if (!temp_borrar[i]) {
172 for (
unsigned int j=i+1;j<temp_x.size();j++) {
178 ax = basis1_x[i]-basis1_x[j];
179 ay = basis1_y[i]-basis1_y[j];
180 bool i1j1= (sqrt(1.0f*ax*ax+ay*ay)<filter_dist);
183 ax = basis1_x[i]-basis2_x[j];
184 ay = basis1_y[i]-basis2_y[j];
185 bool i1j2= (sqrt(1.0f*ax*ax+ay*ay)<filter_dist);
188 ax = basis2_x[i]-basis1_x[j];
189 ay = basis2_y[i]-basis1_y[j];
190 bool i2j1= (sqrt(1.0f*ax*ax+ay*ay)<filter_dist);
193 ax = basis2_x[i]-basis2_x[j];
194 ay = basis2_y[i]-basis2_y[j];
195 bool i2j2= (sqrt(1.0f*ax*ax+ay*ay)<filter_dist);
199 if ( (i1j1 && i2j2) || (i1j2 && i2j1) )
201 if ( temp_clear[i]<temp_clear[j] )
203 else temp_borrar[i]=1;
213 CriticalPointsList.clearance.clear();
214 CriticalPointsList.x.clear();
215 CriticalPointsList.y.clear();
216 CriticalPointsList.x_basis1.clear();
217 CriticalPointsList.y_basis1.clear();
218 CriticalPointsList.x_basis2.clear();
219 CriticalPointsList.y_basis2.clear();
221 for (
unsigned i=0;i<temp_x.size();i++)
225 CriticalPointsList.x.push_back( temp_x[i] );
226 CriticalPointsList.y.push_back( temp_y[i] );
227 CriticalPointsList.clearance.push_back( temp_clear[i] );
230 setBasisCell( temp_x[i],temp_y[i] ,1);
251 static const cellType thresholdCellValue = p2l(0.5f);
254 if ( static_cast<unsigned>(cx)>=size_x || static_cast<unsigned>(cy)>=size_y )
257 if ( map[cx+cy*size_y]<thresholdCellValue )
264 static int ultimo_cx = -10, ultimo_cy = -10;
265 int estimated_min_free_circle;
266 static int ultimo_free_circle;
268 if ( abs(ultimo_cx-cx)<=1 && abs(ultimo_cy-cy)<=1)
269 estimated_min_free_circle = max(1,ultimo_free_circle - 3);
271 estimated_min_free_circle = 1;
277 #define N_CIRCULOS 100 278 static bool tabla_construida =
false;
281 static int circs_x[32000],circs_y[32000];
283 if (!tabla_construida)
285 tabla_construida=
true;
286 int indice_absoluto = 0;
291 float AA = (2.0f*
M_PIf / nPasos);
292 int ult_x=0,
x,ult_y=0,
y;
295 circ_PrimeraEntrada[i] = indice_absoluto;
302 if ((
x!=ult_x ||
y!=ult_y) && !(
x==i &&
y==0) )
304 circs_x[indice_absoluto]=
x;
305 circs_y[indice_absoluto++]=
y;
315 nEntradasCirculo[i]=nEntradas;
327 int vueltas_extra = 2;
329 for (tam_circ=estimated_min_free_circle;tam_circ<
N_CIRCULOS && (!(*nBasis) || vueltas_extra );tam_circ++)
331 int nEnts = nEntradasCirculo[tam_circ];
332 bool dentro_obs =
false;
333 int idx = circ_PrimeraEntrada[tam_circ];
335 for (
int j=0;j<nEnts && (*nBasis)<2;j++,idx++)
337 int xx = cx+circs_x[idx];
338 int yy = cy+circs_y[idx];
340 if (xx>=0 && xx<static_cast<int>(size_x) && yy>=0 && yy<static_cast<int>(size_y))
343 if ( map[xx+yy*size_y]<thresholdCellValue )
356 int ax = basis_x[0] - xx;
357 int ay = basis_y[0] - yy;
358 pasa = sqrt(1.0f*ax*ax+ay*ay)>(1.75f*tam_circ);
363 basis_x[*nBasis] = cx+circs_x[idx];
364 basis_y[*nBasis] = cy+circs_y[idx];
377 if (*nBasis==1) vueltas_extra--;
378 else vueltas_extra=0;
383 ultimo_free_circle = tam_circ;
390 int dx, dy, dir_predilecta,dir;
393 dx = cx - basis_x[0];
394 dy = cy - basis_y[0];
396 if (dx>0) dir_predilecta=4;
397 else dir_predilecta=3;
399 if (dy>0) dir_predilecta=1;
400 else dir_predilecta=6;
402 vec = GetNeighborhood( basis_x[0], basis_y[0] );
404 if (!(vec & (1<<dir_predilecta))) dir = dir_predilecta;
405 else if (!(vec & (1<<1))) dir = 1;
406 else if (!(vec & (1<<3))) dir = 3;
407 else if (!(vec & (1<<4))) dir = 4;
408 else if (!(vec & (1<<6))) dir = 6;
411 vec = GetNeighborhood(basis_x[0]+direccion_vecino_x[dir],basis_y[0]+direccion_vecino_y[dir]);
412 if (vec!=0x00 && vec!=0xFF)
414 basis_x[0]+=direccion_vecino_x[dir];
415 basis_y[0]+=direccion_vecino_y[dir];
420 dx = cx - basis_x[1];
421 dy = cy - basis_y[1];
423 if (dx>0) dir_predilecta=4;
424 else dir_predilecta=3;
426 if (dy>0) dir_predilecta=1;
427 else dir_predilecta=6;
429 vec = GetNeighborhood( basis_x[1], basis_y[1] );
431 if (!(vec & (1<<dir_predilecta))) dir = dir_predilecta;
432 else if (!(vec & (1<<1))) dir = 1;
433 else if (!(vec & (1<<3))) dir = 3;
434 else if (!(vec & (1<<4))) dir = 4;
435 else if (!(vec & (1<<6))) dir = 6;
438 vec = GetNeighborhood(basis_x[1]+direccion_vecino_x[dir],basis_y[1]+direccion_vecino_y[dir]);
439 if (vec!=0x00 && vec!=0xFF)
441 basis_x[1]+=direccion_vecino_x[dir];
442 basis_y[1]+=direccion_vecino_y[dir];
465 if (getCell(cx-1,cy-1)<=voroni_free_threshold)
res |= (1<<0);
466 if (getCell( cx ,cy-1)<=voroni_free_threshold)
res |= (1<<1);
467 if (getCell(cx+1,cy-1)<=voroni_free_threshold)
res |= (1<<2);
468 if (getCell(cx-1, cy )<=voroni_free_threshold)
res |= (1<<3);
469 if (getCell(cx+1, cy )<=voroni_free_threshold)
res |= (1<<4);
470 if (getCell(cx-1,cy+1)<=voroni_free_threshold)
res |= (1<<5);
471 if (getCell( cx ,cy+1)<=voroni_free_threshold)
res |= (1<<6);
472 if (getCell(cx+1,cy+1)<=voroni_free_threshold)
res |= (1<<7);
520 int xx1 = max(0,x2idx(
x-maxSearchDistance));
521 int xx2 =
min(static_cast<unsigned>( size_x-1),static_cast<unsigned>( x2idx(
x+maxSearchDistance)) );
522 int yy1 = max(0,y2idx(
y-maxSearchDistance));
523 int yy2 =
min(static_cast<unsigned>( size_y-1),static_cast<unsigned>( y2idx(
y+maxSearchDistance)));
529 float clearance_sq =
square(maxSearchDistance);
530 cellType thresholdCellValue = p2l(0.5f);
533 bool atLeastOneFree =
false;
534 for (xx=cx-1;!atLeastOneFree && xx<=cx+1;xx++)
535 for (yy=cy-1;!atLeastOneFree && yy<=cy+1;yy++)
536 if (getCell(xx,yy)>0.505f)
537 atLeastOneFree =
true;
543 for (xx=xx1;xx<=xx2;xx++)
544 for (yy=yy1;yy<=yy2;yy++)
545 if (map[xx+yy*size_x]<thresholdCellValue)
548 return sqrt(clearance_sq);
#define ASSERT_EQUAL_(__A, __B)
void findCriticalPoints(float filter_distance)
Builds a list with the critical points from Voronoi diagram, which must must be built before calling ...
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
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.
void clear()
Clear the contents of this container.
T square(const T x)
Inline function for the square of a number.
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.
int round(const T value)
Returns the closer integer (int) to x.
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...
int16_t cellType
The type of the map cells: