9 #define _USE_MATH_DEFINES
30 #define DEG2RAD M_PI/180.0
34 #define RAD2DEG 180.0/M_PI
41 found = full_filename.find_last_of(
'/');
42 if (found != string::npos)
return full_filename.substr(0, found)+
"/";
43 found = full_filename.find_last_of(
'\\');
44 if (found != string::npos)
return full_filename.substr(0, found)+
"\\";
50 int start = full_filename.length() - 3;
51 return full_filename.substr(start, 3);
57 if (m_map_name != other.
m_map_name)
return false;
58 if (m_origin != other.
m_origin)
return false;
60 if (m_width != other.
width())
return false;
61 if (m_height != other.
height())
return false;
62 for (
size_t y = 0; y < m_height; y++)
for (
size_t x = 0; x < m_width; x++)
63 if (m_map_occupancy.safePixel(x, y) != other.m_map_occupancy.
safePixel(x, y))
return false;
64 for (
size_t y = 0; y < m_height; y++)
for (
size_t x = 0; x < m_width; x++)
65 if (m_map_flags.safePixel(x, y) != other.m_map_flags.
safePixel(x, y))
return false;
74 m_map_occupancy.setQuantum(1);
75 m_map_flags.setQuantum(1);
76 m_map_occupancy.resize(m_width, m_height);
77 m_map_flags.resize(m_width, m_height);
78 m_occupied_thresh = 0.80;
80 for (
size_t y = 0; y < m_height; y++)
82 for (
size_t x = 0; x < m_width; x++)
84 m_map_occupancy.safePixel(x, y) = 0;
85 m_map_flags.safePixel(x, y) = MapGrid2D::map_flags::MAP_CELL_FREE;
94 if (isInsideMap(cell))
96 if (m_map_occupancy.safePixel(cell.
x, cell.
y) != 0)
return true;
97 if (m_map_flags.safePixel(cell.
x, cell.
y) == MapGrid2D::map_flags::MAP_CELL_KEEP_OUT)
return true;
98 if (m_map_flags.safePixel(cell.
x, cell.
y) == MapGrid2D::map_flags::MAP_CELL_TEMPORARY_OBSTACLE)
return true;
99 if (m_map_flags.safePixel(cell.
x, cell.
y) == MapGrid2D::map_flags::MAP_CELL_ENLARGED_OBSTACLE)
return true;
106 if (isInsideMap(cell))
108 if (m_map_occupancy.safePixel(cell.
x, cell.
y) == 0 &&
109 m_map_flags.safePixel(cell.
x, cell.
y) == MapGrid2D::map_flags::MAP_CELL_FREE)
117 if (isInsideMap(cell))
119 if (m_map_flags.safePixel(cell.
x, cell.
y) == MapGrid2D::map_flags::MAP_CELL_KEEP_OUT)
127 if (isInsideMap(cell))
131 if (m_map_flags.safePixel(cell.
x, cell.
y) == MapGrid2D::map_flags::MAP_CELL_WALL)
150 image.resize(m_width, m_height);
152 for (
size_t y = 0; y < m_height; y++)
154 for (
size_t x = 0; x < m_width; x++)
156 image.
safePixel(x, y) = CellDataToPixel(m_map_flags.safePixel(x, y));
164 if (image.width() != m_width ||
165 image.height() != m_height)
167 yError() <<
"The size of given iamge does not correspond to the current map. Use method setSize() first.";
170 for (
size_t y = 0; y < m_height; y++)
172 for (
size_t x = 0; x < m_width; x++)
174 m_map_flags.safePixel(x, y) = PixelToCellData(image.
safePixel(x, y));
184 for (
size_t y = 0; y < m_height; y++)
186 for (
size_t x = 0; x < m_width; x++)
188 if (this->m_map_flags.safePixel(x, y) == MapGrid2D::map_flags::MAP_CELL_ENLARGED_OBSTACLE)
190 this->m_map_flags.safePixel(x, y) = MapGrid2D::map_flags::MAP_CELL_FREE;
196 auto repeat_num = (size_t)(std::ceil(size/ m_resolution));
197 for (
size_t repeat = 0; repeat < repeat_num; repeat++)
200 std::vector<XYCell> list_of_cells;
201 for (
size_t y = 0; y < m_height; y++)
203 for (
size_t x = 0; x < m_width; x++)
206 if (this->m_map_flags.safePixel(x, y) == MAP_CELL_KEEP_OUT ||
207 this->m_map_flags.safePixel(x, y) == MAP_CELL_ENLARGED_OBSTACLE ||
208 this->m_map_flags.safePixel(x, y) == MAP_CELL_WALL ||
209 this->m_map_flags.safePixel(x, y) == MAP_CELL_UNKNOWN ||
210 this->m_map_flags.safePixel(x, y) == MAP_CELL_TEMPORARY_OBSTACLE)
212 list_of_cells.emplace_back(x, y);
218 for (
auto& list_of_cell : list_of_cells)
220 enlargeCell(list_of_cell);
226 void MapGrid2D::enlargeCell(
XYCell cell)
230 size_t il = cell.
x > 1 ? cell.
x - 1 : 0;
231 size_t ir = cell.
x + 1 < (m_width)-1 ? cell.
x + 1 : (m_width)-1;
232 size_t ju = cell.
y > 1 ? cell.
y - 1 : 0;
233 size_t jd = cell.
y + 1 < (m_height)-1 ? cell.
y + 1 : (m_height)-1;
235 if (m_map_flags.pixel(il, j) == MAP_CELL_FREE) m_map_flags.pixel(il, j) = MAP_CELL_ENLARGED_OBSTACLE;
236 if (m_map_flags.pixel(ir, j) == MAP_CELL_FREE) m_map_flags.pixel(ir, j) = MAP_CELL_ENLARGED_OBSTACLE;
237 if (m_map_flags.pixel(i, ju) == MAP_CELL_FREE) m_map_flags.pixel(i, ju) = MAP_CELL_ENLARGED_OBSTACLE;
238 if (m_map_flags.pixel(i, jd) == MAP_CELL_FREE) m_map_flags.pixel(i, jd) = MAP_CELL_ENLARGED_OBSTACLE;
239 if (m_map_flags.pixel(il, ju) == MAP_CELL_FREE) m_map_flags.pixel(il, ju) = MAP_CELL_ENLARGED_OBSTACLE;
240 if (m_map_flags.pixel(il, jd) == MAP_CELL_FREE) m_map_flags.pixel(il, jd) = MAP_CELL_ENLARGED_OBSTACLE;
241 if (m_map_flags.pixel(ir, ju) == MAP_CELL_FREE) m_map_flags.pixel(ir, ju) = MAP_CELL_ENLARGED_OBSTACLE;
242 if (m_map_flags.pixel(ir, jd) == MAP_CELL_FREE) m_map_flags.pixel(ir, jd) = MAP_CELL_ENLARGED_OBSTACLE;
245 bool MapGrid2D::loadROSParams(
string ros_yaml_filename,
string& pgm_occ_filename,
double& resolution,
double& orig_x,
double& orig_y,
double& orig_t )
247 std::string file_string;
249 file.open(ros_yaml_filename.c_str());
252 yError() <<
"failed to open file" << ros_yaml_filename;
257 while (getline(file, line))
259 if (line.find(
"origin") != std::string::npos)
261 std::replace(line.begin(), line.end(),
',',
' ');
262 std::replace(line.begin(), line.end(),
'[',
'(');
263 std::replace(line.begin(), line.end(),
']',
')');
270 file_string += (line +
'\n');
279 if (bbb.
check(
"image:") ==
false) {
yError() <<
"missing image";
ret =
false; }
283 if (bbb.
check(
"resolution:") ==
false) {
yError() <<
"missing resolution";
ret =
false; }
286 if (bbb.
check(
"origin:") ==
false) {
yError() <<
"missing origin";
ret =
false; }
295 if (bbb.
check(
"occupied_thresh:"))
296 {m_occupied_thresh = bbb.
find(
"occupied_thresh:").
asFloat64();}
298 if (bbb.
check(
"free_thresh:"))
304 bool MapGrid2D::loadMapYarpAndRos(
string yarp_filename,
string ros_yaml_filename)
311 yError() <<
"Unable to load map data" << yarp_filename;
314 string pgm_occ_filename;
319 bool b2 = loadROSParams(ros_yaml_filename, pgm_occ_filename, resolution, orig_x, orig_y, orig_t);
322 yError() <<
"Unable to ros params from" << ros_yaml_filename;
327 string pgm_occ_filename_with_path = path + pgm_occ_filename;
331 yError() <<
"Unable to load occupancy grid file:" << pgm_occ_filename_with_path;
335 if (yarp_img.width() == ros_img.width() && yarp_img.height() == ros_img.height())
338 setSize_in_cells(yarp_img.width(), yarp_img.height());
339 m_resolution = resolution;
340 m_origin.setOrigin(orig_x,orig_y,orig_t);
343 for (
size_t y = 0; y < m_height; y++)
345 for (
size_t x = 0; x < m_width; x++)
347 m_map_flags.safePixel(x, y) = PixelToCellData(yarp_img.
safePixel(x, y));
352 for (
size_t y = 0; y < m_height; y++)
354 for (
size_t x = 0; x < m_width; x++)
357 if (pix_occ.
r == 205 && pix_occ.
g == 205 && pix_occ.
b == 205)
360 m_map_occupancy.safePixel(x, y) = 255;
364 int color_avg = (pix_occ.
r + pix_occ.
g + pix_occ.
b) / 3;
365 auto occ = (
unsigned char)((254 - color_avg) / 254.0);
366 m_map_occupancy.safePixel(x, y) = occ * 100;
373 yError() <<
"MapGrid2D::loadFromFile() Size of YARP map and ROS do not match";
380 bool MapGrid2D::loadMapROSOnly(
string ros_yaml_filename)
383 string pgm_occ_filename;
384 double resolution = 0;
388 bool b2 = loadROSParams(ros_yaml_filename, pgm_occ_filename, resolution, orig_x, orig_y, orig_t);
391 yError() <<
"Unable to ros params from" << ros_yaml_filename;
396 string pgm_occ_filename_with_path = path + pgm_occ_filename;
400 yError() <<
"Unable to load occupancy grid file:" << pgm_occ_filename;
405 setSize_in_cells(ros_img.width(), ros_img.height());
406 m_resolution = resolution;
407 m_origin.setOrigin(orig_x, orig_y, orig_t);
410 for (
size_t y = 0; y < m_height; y++)
412 for (
size_t x = 0; x < m_width; x++)
415 if (pix_occ.
r == 205 && pix_occ.
g == 205 && pix_occ.
b == 205)
418 m_map_occupancy.safePixel(x, y) = 255;
422 int color_avg = (pix_occ.
r + pix_occ.
g + pix_occ.
b) / 3;
423 auto occ = (
unsigned char)((254 - color_avg) / 254.0);
424 m_map_occupancy.safePixel(x, y) = occ * 100;
430 for (
size_t y = 0; y < (size_t)(m_map_occupancy.height()); y++)
432 for (
size_t x = 0; x < (size_t)(m_map_occupancy.width()); x++)
435 if (pix_occ == 0) m_map_flags.safePixel(x, y) = MAP_CELL_FREE;
436 else if (pix_occ >= 200) m_map_flags.safePixel(x, y) = MAP_CELL_WALL;
437 else m_map_flags.safePixel(x, y) = MAP_CELL_UNKNOWN;
443 bool MapGrid2D::loadMapYarpOnly(
string yarp_filename)
449 yError() <<
"Unable to load map" << yarp_filename;
453 setSize_in_cells(yarp_img.width(), yarp_img.height());
460 for (
size_t y = 0; y < m_height; y++)
462 for (
size_t x = 0; x < m_width; x++)
464 m_map_flags.safePixel(x, y) = PixelToCellData(yarp_img.
safePixel(x, y));
469 for (
size_t y = 0; y < (size_t)(m_map_flags.height()); y++)
471 for (
size_t x = 0; x < (size_t)(m_map_flags.width()); x++)
475 if (pix_flg == MAP_CELL_FREE) m_map_occupancy.safePixel(x, y) = 0;
476 else if (pix_flg == MAP_CELL_KEEP_OUT) m_map_occupancy.safePixel(x, y) = 0;
477 else if (pix_flg == MAP_CELL_TEMPORARY_OBSTACLE) m_map_occupancy.safePixel(x, y) = 0;
478 else if (pix_flg == MAP_CELL_ENLARGED_OBSTACLE) m_map_occupancy.safePixel(x, y) = 0;
479 else if (pix_flg == MAP_CELL_WALL) m_map_occupancy.safePixel(x, y) = 100;
480 else if (pix_flg == MAP_CELL_UNKNOWN) m_map_occupancy.safePixel(x, y) = 255;
481 else m_map_occupancy.safePixel(x, y) = 255;
484 m_occupied_thresh = 0.80;
485 m_free_thresh = 0.20;
489 bool MapGrid2D::parseMapParameters(
const Property& mapfile)
494 if (mapfile.
check(
"resolution"))
498 if (mapfile.
check(
"origin"))
518 yError() <<
"Unable to open .map description file:" << map_file_with_path;
522 if (mapfile_prop.
check(
"MapName") ==
false)
524 yError() <<
"Unable to find 'MapName' parameter inside:" << map_file_with_path;
529 bool YarpMapDataFound =
false;
530 string ppm_flg_filename;
531 if (mapfile_prop.
check(
"YarpMapData") ==
false)
533 yWarning() <<
"Unable to find 'YarpMapData' parameter inside:" << map_file_with_path;
534 YarpMapDataFound =
false;
538 ppm_flg_filename = mapfile_prop.
find(
"YarpMapData").
asString();
539 YarpMapDataFound =
true;
542 bool RosMapDataFound =
false;
543 string yaml_filename;
544 if (mapfile_prop.
check(
"RosMapData") ==
false)
546 yWarning() <<
"Unable to find 'RosMapData' parameter inside:" << map_file_with_path;
547 RosMapDataFound =
false;
551 yaml_filename = mapfile_prop.
find(
"RosMapData").
asString();
552 RosMapDataFound =
true;
557 string yarp_flg_filename_with_path = mapfile_path + ppm_flg_filename;
558 string ros_yaml_filename_with_path = mapfile_path + yaml_filename;
559 if (YarpMapDataFound && RosMapDataFound)
562 yDebug() <<
"Opening files: "<< yarp_flg_filename_with_path <<
" and " << ros_yaml_filename_with_path;
563 return this->loadMapYarpAndRos(yarp_flg_filename_with_path, ros_yaml_filename_with_path) &&
564 this->parseMapParameters(mapfile_prop);
566 else if (!YarpMapDataFound && RosMapDataFound)
569 yDebug() <<
"Opening file:" << ros_yaml_filename_with_path;
570 return this->loadMapROSOnly(ros_yaml_filename_with_path) &&
571 this->parseMapParameters(mapfile_prop);
573 else if (YarpMapDataFound && !RosMapDataFound)
576 yDebug() <<
"Opening file:" << yarp_flg_filename_with_path;
577 return this->loadMapYarpOnly(yarp_flg_filename_with_path) &&
578 this->parseMapParameters(mapfile_prop);
582 yError() <<
"Critical error: unable to find neither 'RosMapData' nor 'YarpMapData' inside:" << map_file_with_path;
590 if (pixin.
r == 0 && pixin.
g == 0 && pixin.
b == 0)
return MAP_CELL_WALL;
591 else if (pixin.
r == 205 && pixin.
g == 205 && pixin.
b == 205)
return MAP_CELL_UNKNOWN;
592 else if (pixin.
r == 254 && pixin.
g == 254 && pixin.
b == 254)
return MAP_CELL_FREE;
593 else if (pixin.
r == 255 && pixin.
g == 0 && pixin.
b == 0)
return MAP_CELL_KEEP_OUT;
594 return MAP_CELL_UNKNOWN;
600 if (pixin == MAP_CELL_WALL) { pixout_flg.
r = 0; pixout_flg.
g = 0; pixout_flg.
b = 0;}
601 else if (pixin == MAP_CELL_UNKNOWN) { pixout_flg.
r = 205; pixout_flg.
g = 205; pixout_flg.
b = 205; }
602 else if (pixin == MAP_CELL_FREE) { pixout_flg.
r = 254; pixout_flg.
g = 254; pixout_flg.
b = 254; }
603 else if (pixin == MAP_CELL_KEEP_OUT) { pixout_flg.
r = 255; pixout_flg.
g = 0; pixout_flg.
b = 0; }
604 else if (pixin == MAP_CELL_ENLARGED_OBSTACLE) { pixout_flg.
r = 255; pixout_flg.
g = 200; pixout_flg.
b = 0; }
605 else if (pixin == MAP_CELL_TEMPORARY_OBSTACLE) { pixout_flg.
r = 100; pixout_flg.
g = 100; pixout_flg.
b = 200; }
609 pixout_flg.
r = 200; pixout_flg.
g = 0; pixout_flg.
b = 200;
618 for (
size_t j=0;j<height();j++){
619 for (
size_t i=0;i<width();i++){
633 for (
int j=height()-1; j>0; j--){
634 for (
int i=width()-1; i>0 ;i--){
648 for (
size_t i=0;i<width();i++){
649 for (
size_t j=0;j<height();j++){
663 for (
size_t i=width()-1;i>0;i--){
664 for (
size_t j=0;j<height();j++){
676 if (left > (
int)this->width())
return false;
677 if (right > (
int)this->width())
return false;
678 if (top > (
int)this->height())
return false;
679 if (bottom > (
int)this->height())
return false;
684 new_map_occupancy.setQuantum(1);
685 new_map_flags.setQuantum(1);
686 new_map_occupancy.resize(right-left,bottom-top);
687 new_map_flags.resize(right-left,bottom-top);
690 size_t original_height = m_map_occupancy.height();
692 for (
int j=top, y=0; j<bottom; j++, y++)
693 for (
int i=left, x=0; i<right; i++, x++)
695 new_map_occupancy.
safePixel(x,y) = m_map_occupancy.safePixel(i,j);
696 new_map_flags.
safePixel(x,y) = m_map_flags.safePixel(i,j);
698 m_map_occupancy.copy(new_map_occupancy);
699 m_map_flags.copy(new_map_flags);
700 this->m_width=m_map_occupancy.width();
701 this->m_height=m_map_occupancy.height();
702 yDebug() << m_origin.get_x() << m_origin.get_y();
703 double new_x0 = m_origin.get_x() +(left*m_resolution);
704 double new_y0 = m_origin.get_y() +(double(original_height)-double(bottom))*m_resolution;
705 m_origin.setOrigin(new_x0,new_y0, m_origin.get_theta());
711 std::string yarp_filename = this->getMapName() +
"_yarpflags.ppm";
712 std::string yaml_filename = this->getMapName() +
"_grid.yaml";
713 std::string pgm_occ_filename = this->getMapName() +
"_grid.pgm";
715 std::ofstream map_file;
716 map_file.open(map_file_with_path.c_str());
717 if (!map_file.is_open())
721 map_file <<
"MapName: "<< this->getMapName() << endl;
722 map_file <<
"YarpMapData: "<< yarp_filename << endl;
723 map_file <<
"RosMapData: "<< yaml_filename << endl;
726 std::ofstream yaml_file;
727 yaml_file.open(yaml_filename.c_str());
728 if (!yaml_file.is_open())
732 yaml_file <<
"image: " << pgm_occ_filename << endl;
733 yaml_file <<
"resolution: " << m_resolution << endl;
734 yaml_file <<
"origin: [ " << m_origin.get_x() <<
" " << m_origin.get_y() <<
" " << m_origin.get_theta() <<
" ]"<< endl;
735 yaml_file <<
"negate: 0" << endl;
736 yaml_file <<
"occupied_thresh: " << m_occupied_thresh << endl;
737 yaml_file <<
"free_thresh: " << m_free_thresh << endl;
744 img_flg.resize(m_width, m_height);
745 img_occ.resize(m_width, m_height);
746 for (
size_t y = 0; y < m_height; y++)
748 for (
size_t x = 0; x < m_width; x++)
753 if (pix_occ == 255) pix_occ_out = 205;
754 else pix_occ_out = 254-(pix_occ*254/100);
755 img_flg.
safePixel(x, y) = CellDataToPixel(pix);
761 std::string ppm_flg_filename = yarp_filename;
786 m_origin.setOrigin(x0,y0,theta0);
791 char buff[255]; memset(buff, 0, 255);
794 m_map_occupancy.resize(m_width, m_height);
795 m_map_flags.resize(m_width, m_height);
797 unsigned char *mem =
nullptr;
801 if (memsize != m_map_occupancy.getRawImageSize()) {
return false; }
802 mem = m_map_occupancy.getRawImage();
806 if (memsize != m_map_flags.getRawImageSize()) {
return false; }
807 mem = m_map_flags.getRawImage();
809 if (!ok)
return false;
833 unsigned char *mem =
nullptr;
835 mem = m_map_occupancy.getRawImage();
836 memsize = m_map_occupancy.getRawImageSize();
840 mem = m_map_flags.getRawImage();
841 memsize = m_map_flags.getRawImageSize();
856 yWarning() <<
"MapGrid2D::setOrigin() requested is not inside map!";
860 int xc = (int)(x/ m_resolution);
861 int yc = (int)(y / m_resolution);
863 XYCell orig(-xc, (m_height-1) + yc);
864 if (isInsideMap(orig))
866 m_origin.setOrigin(x,y, theta);
871 yWarning() <<
"MapGrid2D::setOrigin() requested is not inside map!";
872 m_origin.setOrigin(x, y, theta);
879 x = m_origin.get_x();
880 y = m_origin.get_y();
881 theta = m_origin.get_theta();
888 yError() <<
"MapGrid2D::setResolution() invalid value:" << resolution;
891 m_resolution = resolution;
897 resolution = m_resolution;
904 m_map_name = map_name;
907 yError() <<
"MapGrid2D::setMapName() invalid map name";
918 if (x <= 0 && y <= 0)
920 yError() <<
"MapGrid2D::setSize() invalid size";
923 if (m_resolution <= 0)
925 yError() <<
"MapGrid2D::setSize() invalid map resolution.";
928 auto w = (size_t)(x/m_resolution);
929 auto h = (size_t)(y/m_resolution);
930 setSize_in_cells(w,h);
936 if (x == 0 && y == 0)
938 yError() <<
"MapGrid2D::setSize() invalid size";
941 m_map_occupancy.resize(x, y);
942 m_map_flags.resize(x, y);
943 m_map_occupancy.zero();
952 x = m_width* m_resolution;
953 y = m_height* m_resolution;
964 if (isInsideMap(cell) ==
false)
966 yError() <<
"Invalid cell requested " << cell.
x <<
" " << cell.
y;
969 m_map_flags.safePixel(cell.
x, cell.
y) = flag;
975 if (isInsideMap(cell) ==
false)
977 yError() <<
"Invalid cell requested " << cell.
x <<
" " << cell.
y;
986 if (isInsideMap(cell) ==
false)
988 yError() <<
"Invalid cell requested " << cell.
x <<
" " << cell.
y;
997 if (isInsideMap(cell) ==
false)
999 yError() <<
"Invalid cell requested " << cell.
x <<
" " << cell.
y;
1002 if (m_map_occupancy.safePixel(cell.
x, cell.
y)==255)
1008 occupancy = m_map_occupancy.safePixel(cell.
x, cell.
y);
1015 if ((
size_t) image.width() != m_width ||
1016 (
size_t) image.height() != m_height)
1018 yError() <<
"The size of given occupancy grid does not correspond to the current map. Use method setSize() first.";
1021 m_map_occupancy = image;
1027 image = m_map_occupancy;