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);
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 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 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.
int16_t cellType
The type of the map cells:
int round(const T value)
Returns the closer integer (int) to x.
#define ASSERT_EQUAL_(__A, __B)
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...
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values,...
void clear()
Clear the contents of this container.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.