6#define _USE_MATH_DEFINES
19#if defined (YARP_HAS_ZLIB)
31#define DEG2RAD M_PI/180.0
35#define RAD2DEG 180.0/M_PI
42 found = full_filename.find_last_of(
'/');
43 if (found != std::string::npos) {
44 return full_filename.substr(0, found) +
"/";
46 found = full_filename.find_last_of(
'\\');
47 if (found != std::string::npos) {
48 return full_filename.substr(0, found) +
"\\";
55 int start = full_filename.length() - 3;
56 return full_filename.substr(start, 3);
60bool MapGrid2D::isIdenticalTo(
const MapGrid2D& other)
const
77 for (
size_t y = 0; y <
m_height; y++) {
78 for (
size_t x = 0; x <
m_width; x++) {
84 for (
size_t y = 0; y <
m_height; y++) {
85 for (
size_t x = 0; x <
m_width; x++) {
103 m_occupied_thresh = 0.80;
104 m_free_thresh = 0.20;
105 for (
size_t y = 0; y <
m_height; y++)
107 for (
size_t x = 0; x <
m_width; x++)
110 m_map_flags.
safePixel(x, y) = MapGrid2D::map_flags::MAP_CELL_FREE;
113#if defined (YARP_HAS_ZLIB)
114 m_compressed_data_over_network =
true;
116 m_compressed_data_over_network =
false;
126 if (m_map_occupancy.
safePixel(cell.
x, cell.
y) != 0) {
129 if (m_map_flags.
safePixel(cell.
x, cell.
y) == MapGrid2D::map_flags::MAP_CELL_KEEP_OUT) {
132 if (m_map_flags.
safePixel(cell.
x, cell.
y) == MapGrid2D::map_flags::MAP_CELL_TEMPORARY_OBSTACLE) {
135 if (m_map_flags.
safePixel(cell.
x, cell.
y) == MapGrid2D::map_flags::MAP_CELL_ENLARGED_OBSTACLE) {
146 if (m_map_occupancy.
safePixel(cell.
x, cell.
y) == 0 && m_map_flags.
safePixel(cell.
x, cell.
y) == MapGrid2D::map_flags::MAP_CELL_FREE) {
157 if (m_map_flags.
safePixel(cell.
x, cell.
y) == MapGrid2D::map_flags::MAP_CELL_KEEP_OUT) {
170 if (m_map_flags.
safePixel(cell.
x, cell.
y) == MapGrid2D::map_flags::MAP_CELL_WALL) {
192 for (
size_t y = 0; y <
m_height; y++)
194 for (
size_t x = 0; x <
m_width; x++)
207 yError() <<
"The size of given image does not correspond to the current map. Use method setSize() first.";
210 for (
size_t y = 0; y <
m_height; y++)
212 for (
size_t x = 0; x <
m_width; x++)
224 for (
size_t y = 0; y <
m_height; y++)
226 for (
size_t x = 0; x <
m_width; x++)
228 if (this->m_map_flags.
safePixel(x, y) == MapGrid2D::map_flags::MAP_CELL_ENLARGED_OBSTACLE)
230 this->m_map_flags.
safePixel(x, y) = MapGrid2D::map_flags::MAP_CELL_FREE;
237 for (
size_t repeat = 0; repeat < repeat_num; repeat++)
240 std::vector<XYCell> list_of_cells;
241 for (
size_t y = 0; y <
m_height; y++)
243 for (
size_t x = 0; x <
m_width; x++)
252 list_of_cells.emplace_back(x, y);
258 for (
auto& list_of_cell : list_of_cells)
260 enlargeCell(list_of_cell);
266void MapGrid2D::enlargeCell(
XYCell cell)
270 size_t il = cell.
x > 1 ? cell.
x - 1 : 0;
272 size_t ju = cell.
y > 1 ? cell.
y - 1 : 0;
301bool MapGrid2D::loadROSParams(std::string ros_yaml_filename, std::string& pgm_occ_filename,
double& resolution,
double& orig_x,
double& orig_y,
double& orig_t )
303 std::string file_string;
305 file.open(ros_yaml_filename.c_str());
308 yError() <<
"failed to open file" << ros_yaml_filename;
313 while (getline(file, line))
315 if (line.find(
"origin") != std::string::npos)
317 std::replace(line.begin(), line.end(),
',',
' ');
318 std::replace(line.begin(), line.end(),
'[',
'(');
319 std::replace(line.begin(), line.end(),
']',
')');
326 file_string += (line +
'\n');
333 std::string debug_s = bbb.
toString();
335 if (bbb.
check(
"image:") ==
false) {
yError() <<
"missing image";
ret =
false; }
339 if (bbb.
check(
"resolution:") ==
false) {
yError() <<
"missing resolution";
ret =
false; }
342 if (bbb.
check(
"origin:") ==
false) {
yError() <<
"missing origin";
ret =
false; }
351 if (bbb.
check(
"occupied_thresh:"))
352 {m_occupied_thresh = bbb.
find(
"occupied_thresh:").
asFloat64();}
354 if (bbb.
check(
"free_thresh:"))
360bool MapGrid2D::loadMapYarpAndRos(std::string yarp_filename, std::string ros_yaml_filename)
367 yError() <<
"Unable to load map data" << yarp_filename;
370 std::string pgm_occ_filename;
375 bool b2 = loadROSParams(ros_yaml_filename, pgm_occ_filename, resolution, orig_x, orig_y, orig_t);
378 yError() <<
"Unable to ros params from" << ros_yaml_filename;
383 std::string pgm_occ_filename_with_path = path + pgm_occ_filename;
387 yError() <<
"Unable to load occupancy grid file:" << pgm_occ_filename_with_path;
399 for (
size_t y = 0; y <
m_height; y++)
401 for (
size_t x = 0; x <
m_width; x++)
408 for (
size_t y = 0; y <
m_height; y++)
410 for (
size_t x = 0; x <
m_width; x++)
418 yError() <<
"MapGrid2D::loadFromFile() Size of YARP map and ROS do not match";
425bool MapGrid2D::loadMapROSOnly(std::string ros_yaml_filename)
428 std::string pgm_occ_filename;
429 double resolution = 0;
433 bool b2 = loadROSParams(ros_yaml_filename, pgm_occ_filename, resolution, orig_x, orig_y, orig_t);
436 yError() <<
"Unable to ros params from" << ros_yaml_filename;
441 std::string pgm_occ_filename_with_path = path + pgm_occ_filename;
445 yError() <<
"Unable to load occupancy grid file:" << pgm_occ_filename;
455 for (
size_t y = 0; y <
m_height; y++)
457 for (
size_t x = 0; x <
m_width; x++)
464 for (
size_t y = 0; y < (
size_t)(m_map_occupancy.
height()); y++)
466 for (
size_t x = 0; x < (
size_t)(m_map_occupancy.
width()); x++)
473 else {
yError() <<
"Unreachable";}
479bool MapGrid2D::loadMapYarpOnly(std::string yarp_filename)
485 yError() <<
"Unable to load map" << yarp_filename;
496 for (
size_t y = 0; y <
m_height; y++)
498 for (
size_t x = 0; x <
m_width; x++)
505 for (
size_t y = 0; y < (
size_t)(m_map_flags.
height()); y++)
507 for (
size_t x = 0; x < (
size_t)(m_map_flags.
width()); x++)
528 m_occupied_thresh = 0.80;
529 m_free_thresh = 0.20;
533bool MapGrid2D::parseMapParameters(
const Property& mapfile)
538 if (mapfile.
check(
"resolution"))
542 if (mapfile.
check(
"origin"))
562 yError() <<
"Unable to open .map description file:" << map_file_with_path;
566 if (mapfile_prop.
check(
"MapName") ==
false)
568 yError() <<
"Unable to find 'MapName' parameter inside:" << map_file_with_path;
573 bool YarpMapDataFound =
false;
574 std::string ppm_flg_filename;
575 if (mapfile_prop.
check(
"YarpMapData") ==
false)
577 yWarning() <<
"Unable to find 'YarpMapData' parameter inside:" << map_file_with_path;
578 YarpMapDataFound =
false;
582 ppm_flg_filename = mapfile_prop.
find(
"YarpMapData").
asString();
583 YarpMapDataFound =
true;
586 bool RosMapDataFound =
false;
587 std::string yaml_filename;
588 if (mapfile_prop.
check(
"RosMapData") ==
false)
590 yWarning() <<
"Unable to find 'RosMapData' parameter inside:" << map_file_with_path;
591 RosMapDataFound =
false;
595 yaml_filename = mapfile_prop.
find(
"RosMapData").
asString();
596 RosMapDataFound =
true;
601 std::string yarp_flg_filename_with_path = mapfile_path + ppm_flg_filename;
602 std::string ros_yaml_filename_with_path = mapfile_path + yaml_filename;
603 if (YarpMapDataFound && RosMapDataFound)
606 yDebug() <<
"Opening files: "<< yarp_flg_filename_with_path <<
" and " << ros_yaml_filename_with_path;
607 return this->loadMapYarpAndRos(yarp_flg_filename_with_path, ros_yaml_filename_with_path) &&
608 this->parseMapParameters(mapfile_prop);
610 else if (!YarpMapDataFound && RosMapDataFound)
613 yDebug() <<
"Opening file:" << ros_yaml_filename_with_path;
614 return this->loadMapROSOnly(ros_yaml_filename_with_path) &&
615 this->parseMapParameters(mapfile_prop);
617 else if (YarpMapDataFound && !RosMapDataFound)
620 yDebug() <<
"Opening file:" << yarp_flg_filename_with_path;
621 return this->loadMapYarpOnly(yarp_flg_filename_with_path) &&
622 this->parseMapParameters(mapfile_prop);
626 yError() <<
"Critical error: unable to find neither 'RosMapData' nor 'YarpMapData' inside:" << map_file_with_path;
634 if (pixin.
r == 0 && pixin.
g == 0 && pixin.
b == 0) {
636 }
else if (pixin.
r == 205 && pixin.
g == 205 && pixin.
b == 205) {
638 }
else if (pixin.
r == 254 && pixin.
g == 254 && pixin.
b == 254) {
640 }
else if (pixin.
r == 255 && pixin.
g == 0 && pixin.
b == 0) {
649 if (cellin ==
MAP_CELL_WALL) { pixout_flg.
r = 0; pixout_flg.
g = 0; pixout_flg.
b = 0;}
650 else if (cellin ==
MAP_CELL_UNKNOWN) { pixout_flg.
r = 205; pixout_flg.
g = 205; pixout_flg.
b = 205; }
651 else if (cellin ==
MAP_CELL_FREE) { pixout_flg.
r = 254; pixout_flg.
g = 254; pixout_flg.
b = 254; }
652 else if (cellin ==
MAP_CELL_KEEP_OUT) { pixout_flg.
r = 255; pixout_flg.
g = 0; pixout_flg.
b = 0; }
658 pixout_flg.
r = 200; pixout_flg.
g = 0; pixout_flg.
b = 200;
673 else if (cellin != (
unsigned char)(-1) && cellin <=100)
675 return (254 - (cellin * 254 / 100));
695 else if (pixin != (
unsigned char)(-1))
697 auto occ = (
unsigned char)((254 - pixin) / 254.0);
711 for (
size_t j=0;j<
height();j++){
712 for (
size_t i=0;i<
width();i++){
726 for (
int j=
height()-1; j>0; j--){
727 for (
int i=
width()-1; i>0 ;i--){
741 for (
size_t i=0;i<
width();i++){
742 for (
size_t j=0;j<
height();j++){
756 for (
size_t i=
width()-1;i>0;i--){
757 for (
size_t j=0;j<
height();j++){
769 if (left > (
int)this->
width()) {
772 if (right > (
int)this->
width()) {
775 if (top > (
int)this->
height()) {
778 if (bottom > (
int)this->
height()) {
787 new_map_occupancy.
resize(right-left,bottom-top);
788 new_map_flags.
resize(right-left,bottom-top);
791 size_t original_height = m_map_occupancy.
height();
793 for (
int j = top, y = 0; j < bottom; j++, y++) {
794 for (
int i=left, x=0; i<right; i++, x++)
800 m_map_occupancy.
copy(new_map_occupancy);
801 m_map_flags.
copy(new_map_flags);
802 this->m_width=m_map_occupancy.
width();
803 this->m_height=m_map_occupancy.
height();
815 std::string yarp_filename = this->
getMapName() +
"_yarpflags.ppm";
816 std::string yaml_filename = this->
getMapName() +
"_grid.yaml";
817 std::string pgm_occ_filename = this->
getMapName() +
"_grid.pgm";
819 std::ofstream map_file;
820 map_file.open(map_file_with_path.c_str());
821 if (!map_file.is_open())
825 map_file <<
"MapName: "<< this->
getMapName() <<
'\n';
826 map_file <<
"YarpMapData: "<< yarp_filename <<
'\n';
827 map_file <<
"RosMapData: "<< yaml_filename <<
'\n';
830 std::ofstream yaml_file;
831 yaml_file.open(mapfile_path + yaml_filename.c_str());
832 if (!yaml_file.is_open())
836 yaml_file <<
"image: " << pgm_occ_filename <<
'\n';
839 yaml_file <<
"negate: 0" <<
'\n';
840 yaml_file <<
"occupied_thresh: " << m_occupied_thresh <<
'\n';
841 yaml_file <<
"free_thresh: " << m_free_thresh <<
'\n';
850 for (
size_t y = 0; y <
m_height; y++)
852 for (
size_t x = 0; x <
m_width; x++)
856 img_flg.
safePixel(x, y) = CellFlagDataToPixel(pix_flg);
857 img_occ.
safePixel(x, y) = CellOccupancyDataToPixel(pix_occ);
862 std::string ppm_flg_filename = yarp_filename;
892 char buff[255]; memset(buff, 0, 255);
896 m_compressed_data_over_network = connection.
expectInt8();
900 if (m_compressed_data_over_network)
902#if defined (YARP_HAS_ZLIB)
907 unsigned char* dataCompressed =
new unsigned char[sizeCompressed];
908 ok &= connection.
expectBlock((
char*)dataCompressed, sizeCompressed);
910 unsigned char* dataUncompressed = m_map_occupancy.
getRawImage();
911 int z_result = uncompress((Bytef*)dataUncompressed, (uLongf*)&sizeUncompressed, (
const Bytef*) dataCompressed, sizeCompressed);
913 delete[] dataCompressed;
918 unsigned char* dataCompressed =
new unsigned char[sizeCompressed];
919 ok &= connection.
expectBlock((
char*)dataCompressed, sizeCompressed);
921 unsigned char* dataUncompressed = m_map_flags.
getRawImage();
922 int z_result = uncompress((Bytef*)dataUncompressed, (uLongf*)&sizeUncompressed, (
const Bytef*)dataCompressed, sizeCompressed);
924 delete[] dataCompressed;
935 unsigned char* mem = m_map_occupancy.
getRawImage();
971 connection.
appendInt8(m_compressed_data_over_network);
973 if (m_compressed_data_over_network)
975#if defined (YARP_HAS_ZLIB)
978 unsigned char* dataUncompressed = m_map_occupancy.
getRawImage();
979 size_t sizeCompressed = compressBound(sizeUncompressed);
980 unsigned char* dataCompressed =
new unsigned char[sizeCompressed];
981 int z_result = compress((Bytef*)dataCompressed, (uLongf*)&sizeCompressed, (Bytef*)dataUncompressed, sizeUncompressed);
985 connection.
appendBlock((
char*)dataCompressed, sizeCompressed);
986 delete [] dataCompressed;
990 unsigned char* dataUncompressed = m_map_flags.
getRawImage();
991 size_t sizeCompressed = compressBound(sizeUncompressed);
992 unsigned char* dataCompressed =
new unsigned char[sizeCompressed];
993 int z_result = compress((Bytef*)dataCompressed, (uLongf*)&sizeCompressed, (Bytef*)dataUncompressed, sizeUncompressed);
997 connection.
appendBlock((
char*)dataCompressed, sizeCompressed);
998 delete[] dataCompressed;
1005 unsigned char* mem = m_map_occupancy.
getRawImage();
1030 yWarning() <<
"MapGrid2D::setOrigin() requested is not inside map!";
1045 yWarning() <<
"MapGrid2D::setOrigin() requested is not inside map!";
1060 if (resolution <= 0)
1062 yError() <<
"MapGrid2D::setResolution() invalid value:" << resolution;
1081 yError() <<
"MapGrid2D::setMapName() invalid map name";
1092 if (x <= 0 && y <= 0)
1094 yError() <<
"MapGrid2D::setSize() invalid size";
1099 yError() <<
"MapGrid2D::setSize() invalid map resolution.";
1110 if (x == 0 && y == 0)
1112 yError() <<
"MapGrid2D::setSize() invalid size";
1115 m_map_occupancy.
resize(x, y);
1116 m_map_flags.
resize(x, y);
1117 m_map_occupancy.
zero();
1140 yError() <<
"Invalid cell requested " << cell.
x <<
" " << cell.
y;
1151 yError() <<
"Invalid cell requested " << cell.
x <<
" " << cell.
y;
1162 yError() <<
"Invalid cell requested " << cell.
x <<
" " << cell.
y;
1180 yError() <<
"Invalid cell requested " << cell.
x <<
" " << cell.
y;
1183 if (m_map_occupancy.
safePixel(cell.
x, cell.
y)==255)
1189 occupancy = m_map_occupancy.
safePixel(cell.
x, cell.
y);
1199 yError() <<
"The size of given occupancy grid does not correspond to the current map. Use method setSize() first.";
1202 m_map_occupancy = image;
1208 image = m_map_occupancy;
1214 for (
size_t y = 0; y <
m_height; y++)
1216 for (
size_t x = 0; x <
m_width; x++)
1220 case MapGrid2D::map_flags::MAP_CELL_TEMPORARY_OBSTACLE:
1221 case MapGrid2D::map_flags::MAP_CELL_ENLARGED_OBSTACLE:
1231#if defined (YARP_HAS_ZLIB)
1232 m_compressed_data_over_network = val;
1235 yWarning() <<
"Zlib library not found, unable to set compression";
#define BOTTLE_TAG_FLOAT64
#define BOTTLE_TAG_STRING
static std::string extractExtensionFromFile(std::string full_filename)
static std::string extractPathFromFile(std::string full_filename)
contains the definition of a map type
bool isInsideMap(XYCell cell) const
Checks if a cell is inside the map.
MapGrid2DOrigin m_origin
pose of the map frame w.r.t. the bottom left corner of the map image
double m_resolution
meters/pixel
void setOrigin(double x_init, double y_init, double t_init)
void getSize_in_cells(size_t &x, size_t &y) const
Returns the size of the map in cells.
bool getMapFlag(XYCell cell, map_flags &flag) const
Get the flag of a specific cell of the map.
void clearMapTemporaryFlags()
Clear map temporary flags, such as: MAP_CELL_TEMPORARY_OBSTACLE, MAP_CELL_ENLARGED_OBSTACLE etc.
bool getMapImage(yarp::sig::ImageOf< yarp::sig::PixelRgb > &image) const
bool write(yarp::os::ConnectionWriter &connection) const override
Write vector to a connection.
bool read(yarp::os::ConnectionReader &connection) override
Read this object from a network connection.
size_t height() const
Retrieves the map height, expressed in cells.
bool setResolution(double resolution)
Sets the resolution of the map, i.e.
bool setOrigin(double x, double y, double theta)
Sets the origin of the map reference frame (according to ROS convention)
bool getOccupancyGrid(yarp::sig::ImageOf< yarp::sig::PixelMono > &image) const
std::string getMapName() const
Retrieves the map name.
bool setSize_in_cells(size_t x, size_t y)
Sets the size of the map in cells.
bool enable_map_compression_over_network(bool val)
void getOrigin(double &x, double &y, double &theta) const
Retrieves the origin of the map reference frame (according to ROS convention)
bool setMapImage(yarp::sig::ImageOf< yarp::sig::PixelRgb > &image)
bool setMapName(std::string map_name)
Sets the map name.
bool setMapFlag(XYCell cell, map_flags flag)
Set the flag of a specific cell of the map.
bool crop(int left, int top, int right, int bottom)
Modifies the map, cropping pixels at the boundaries.
bool isKeepOut(XYCell cell) const
Checks if a specific cell of the map is marked as keep-out.
bool isFree(XYCell cell) const
Checks if a specific cell of the map is free, i.e.
bool isNotFree(XYCell cell) const
Checks if a specific cell of the map contains is not free.
size_t width() const
Retrieves the map width, expressed in cells.
yarp::sig::PixelMono CellFlagData
void getSize_in_meters(double &x, double &y) const
Returns the size of the map in meters, according to the current map resolution.
bool enlargeObstacles(double size)
Performs the obstacle enlargement operation.
bool setOccupancyData(XYCell cell, double occupancy)
Set the occupancy data of a specific cell of the map.
bool loadFromFile(std::string map_filename)
Loads a yarp map file from disk.
bool setSize_in_meters(double x, double y)
Sets the size of the map in meters, according to the current map resolution.
yarp::sig::PixelMono CellOccupancyData
bool setOccupancyGrid(yarp::sig::ImageOf< yarp::sig::PixelMono > &image)
bool saveToFile(std::string map_filename) const
Store a yarp map file to disk.
bool getOccupancyData(XYCell cell, double &occupancy) const
Retrieves the occupancy data of a specific cell of the map.
bool isWall(XYCell cell) const
Checks if a specific cell of the map contains a wall.
@ MAP_CELL_TEMPORARY_OBSTACLE
@ MAP_CELL_ENLARGED_OBSTACLE
void getResolution(double &resolution) const
Retrieves the resolution of the map, i.e.
A simple collection of objects that can be described and transmitted in a portable way.
void fromString(const std::string &text)
Initializes bottle from a string.
Value & get(size_type index) const
Reads a Value v from a certain part of the list.
bool check(const std::string &key) const override
Check if there exists a property of the given name.
std::string toString() const override
Gives a human-readable textual representation of the bottle.
Value & find(const std::string &key) const override
Gets a value corresponding to a given keyword.
An interface for reading from a network connection.
virtual bool expectBlock(char *data, size_t len)=0
Read a block of data from the network connection.
virtual std::int32_t expectInt32()=0
Read a 32-bit integer from the network connection.
virtual bool convertTextMode()=0
Reads in a standard description in text mode, and converts it to a standard description in binary.
virtual bool isError() const =0
virtual std::int8_t expectInt8()=0
Read a 8-bit integer from the network connection.
virtual yarp::conf::float64_t expectFloat64()=0
Read a 64-bit floating point number from the network connection.
An interface for writing to a network connection.
virtual bool isError() const =0
virtual void appendInt8(std::int8_t data)=0
Send a representation of a 8-bit integer to the network connection.
virtual void appendExternalBlock(const char *data, size_t len)=0
Send a block of data to the network connection, without making a copy.
virtual bool convertTextMode()=0
Converts a standard description in binary into a textual description, if the connection is in text-mo...
virtual void appendInt32(std::int32_t data)=0
Send a representation of a 32-bit integer to the network connection.
virtual void appendFloat64(yarp::conf::float64_t data)=0
Send a representation of a 64-bit floating point number to the network connection.
virtual void appendBlock(const char *data, size_t len)=0
Send a block of data to the network connection.
void appendString(const std::string &str)
Send a string to the network connection.
A class for storing options and configuration information.
Value & find(const std::string &key) const override
Gets a value corresponding to a given keyword.
bool fromConfigFile(const std::string &fname, bool wipe=true)
Interprets a file as a list of properties.
bool check(const std::string &key) const override
Check if there exists a property of the given name.
virtual yarp::conf::float64_t asFloat64() const
Get 64-bit floating point value.
virtual Bottle * asList() const
Get list value.
virtual yarp::conf::float32_t asFloat32() const
Get 32-bit floating point value.
virtual std::string asString() const
Get string value.
T & safePixel(size_t x, size_t y)
T & pixel(size_t x, size_t y)
void setQuantum(size_t imgQuantum)
size_t width() const
Gets width of image in pixels.
unsigned char * getRawImage() const
Access to the internal image buffer.
bool copy(const Image &alt)
Copy operator.
size_t getRawImageSize() const
Access to the internal buffer size information (this is how much memory has been allocated for the im...
void resize(size_t imgWidth, size_t imgHeight)
Reallocate an image to be of a desired size, throwing away its current contents.
void zero()
Set all pixels to 0.
size_t height() const
Gets height of image in pixels.
For streams capable of holding different kinds of content, check what they actually have.
An interface to the operating system, including Port based communication.
bool read(ImageOf< PixelRgb > &dest, const std::string &src, image_fileformat format=FORMAT_ANY)
bool write(const ImageOf< PixelRgb > &src, const std::string &dest, image_fileformat format=FORMAT_PPM)
unsigned char PixelMono
Monochrome pixel type.