38 #include <opencv2/photo.hpp>
39 #include <grid_map_core/iterators/GridMapIterator.hpp>
40 #include <pcl/io/pcd_io.h>
46 minMapSize_(
Parameters::defaultGridGlobalMinSize())
59 return toImage(
"elevation", xMin, yMin, cellSize);
64 return toImage(
"colors", xMin, yMin, cellSize);
67 cv::Mat
GridMap::toImage(
const std::string & layer,
float & xMin,
float & yMin,
float & cellSize)
const
74 if(layer.compare(
"elevation") == 0)
76 image = cv::Mat::zeros(
gridMap_.getSize()(1),
gridMap_.getSize()(0), CV_32FC1);
79 const float&
value =
data(index(0), index(1));
83 image.at<
float>(image.rows-1-imageIndex(1), image.cols-1-imageIndex(0)) =
value;
87 else if(layer.compare(
"colors") == 0)
89 image = cv::Mat::zeros(
gridMap_.getSize()(1),
gridMap_.getSize()(0), CV_8UC3);
92 const float&
value =
data(index(0), index(1));
96 const int * ptr = (
const int *)&
value;
97 cv::Vec3b & color = image.at<cv::Vec3b>(image.rows-1-imageIndex(1), image.cols-1-imageIndex(0));
98 color[0] = (
unsigned char)(*ptr & 0xFF);
99 color[1] = (
unsigned char)((*ptr >> 8) & 0xFF);
100 color[2] = (
unsigned char)((*ptr >> 16) & 0xFF);
106 UFATAL(
"Unknown layer \"%s\"", layer.c_str());
111 cellSize =
gridMap_.getResolution();
121 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(
new pcl::PointCloud<pcl::PointXYZRGB>);
124 const grid_map::Matrix& dataElevation =
gridMap_[
"elevation"];
125 const grid_map::Matrix& dataColors =
gridMap_[
"colors"];
127 cloud->width =
gridMap_.getSize()(0);
128 cloud->height =
gridMap_.getSize()(1);
129 cloud->resize(cloud->width * cloud->height);
130 cloud->is_dense =
false;
134 float cellSize =
gridMap_.getResolution();
139 const float&
value = dataElevation(index(0), index(1));
140 const int* color = (
const int*)&dataColors(index(0), index(1));
142 pcl::PointXYZRGB & pt = cloud->at(cloud->width-1-imageIndex(0), imageIndex(1));
145 pt.x = xMin + (cloud->width-1-imageIndex(0)) * cellSize;
146 pt.y = yMin + (cloud->height-1-imageIndex(1)) * cellSize;
148 pt.b = (
unsigned char)(*color & 0xFF);
149 pt.g = (
unsigned char)((*color >> 8) & 0xFF);
150 pt.r = (
unsigned char)((*color >> 16) & 0xFF);
154 pt.x = pt.y = pt.z = std::numeric_limits<float>::quiet_NaN();
163 pcl::PolygonMesh::Ptr mesh(
new pcl::PolygonMesh);
173 pcl::toPCLPointCloud2(*cloud, mesh->cloud);
190 std::map<int, cv::Mat> occupiedLocalMaps;
199 undefinedSize =
false;
202 for(std::list<std::pair<int, Transform> >::const_iterator
iter = newPoses.begin();
iter!=newPoses.end(); ++
iter)
206 float x =
iter->second.x();
207 float y =
iter->second.y();
212 undefinedSize =
false;
230 UDEBUG(
"Updating from cache");
231 for(std::list<std::pair<int, Transform> >::const_iterator
iter = newPoses.begin();
iter!=newPoses.end(); ++
iter)
237 if(!localGrid.
is3D())
239 UWARN(
"It seems the local occupancy grids are not 3d, cannot update GridMap! (ground type=%d, obstacles type=%d, empty type=%d)",
260 const float * vi = localGrid.
groundCells.ptr<
float>(0,
i);
261 float * vo = occupied.ptr<
float>(0,
i);
281 else if(maxX < vo[0])
286 else if(maxY < vo[1])
301 float * vo = occupied.ptr<
float>(0,
i+localGrid.
groundCells.cols);
321 else if(maxX < vo[0])
326 else if(maxY < vo[1])
330 uInsert(occupiedLocalMaps, std::make_pair(
iter->first, occupied));
335 if(minX != maxX && minY != maxY)
338 float xMin = minX-margin;
340 float yMin = minY-margin;
342 float xMax = maxX+margin;
343 float yMax = maxY+margin;
348 UERROR(
"Large map size!! map min=(%f, %f) max=(%f,%f). "
349 "There's maybe an error with the poses provided! The map will not be created!",
350 xMin, yMin, xMax, yMax);
359 grid_map::Length
length = grid_map::Length(xMax - xMin, yMax - yMin);
360 grid_map::Position
position = grid_map::Position((xMax+xMin)/2.0
f, (yMax+yMin)/2.0
f);
369 gridMap_.setBasicLayers({
"elevation"});
374 newMapSize.width ==
gridMap_.getSize()[0] &&
375 newMapSize.height ==
gridMap_.getSize()[1])
402 UDEBUG(
"deltaX=%d, deltaY=%d", deltaX, deltaY);
403 newMapSize.width = (xMax - xMin) /
cellSize_+0.5
f;
404 newMapSize.height = (yMax - yMin) /
cellSize_+0.5
f;
405 UDEBUG(
"%d/%d -> %d/%d",
gridMap_.getSize()[0],
gridMap_.getSize()[1], newMapSize.width, newMapSize.height);
407 UASSERT(newMapSize.width >=
gridMap_.getSize()[0]+deltaX && newMapSize.height >=
gridMap_.getSize()[1]+deltaY);
408 UASSERT(deltaX>=0 && deltaY>=0);
410 grid_map::Length
length = grid_map::Length(xMax - xMin, yMax - yMin);
411 grid_map::Position
position = grid_map::Position((xMax+xMin)/2.0
f, (yMax+yMin)/2.0
f);
413 grid_map::GridMap tmpExtendedMap;
416 UDEBUG(
"%d/%d -> %d/%d",
gridMap_.getSize()[0],
gridMap_.getSize()[1], tmpExtendedMap.getSize()[0], tmpExtendedMap.getSize()[1]);
418 UDEBUG(
"extendToInclude (%f,%f,%f,%f) -> (%f,%f,%f,%f)",
421 tmpExtendedMap.getLength()[0], tmpExtendedMap.getLength()[1],
422 tmpExtendedMap.getPosition()[0], tmpExtendedMap.getPosition()[1]);
423 if(!
gridMap_.extendToInclude(tmpExtendedMap))
425 UERROR(
"Failed to update size of the grid map");
433 UDEBUG(
"first pose= %d last pose=%d", newPoses.begin()->first, newPoses.rbegin()->first);
435 grid_map::Matrix& gridMapData =
gridMap_[
"elevation"];
436 grid_map::Matrix& gridMapNodeIds =
gridMap_[
"node_ids"];
437 grid_map::Matrix& gridMapColors =
gridMap_[
"colors"];
438 for(std::list<std::pair<int, Transform> >::const_iterator kter = newPoses.begin(); kter!=newPoses.end(); ++kter)
440 std::map<int, cv::Mat>::iterator
iter = occupiedLocalMaps.find(kter->first);
441 if(
iter!=occupiedLocalMaps.end())
445 for(
int i=0;
i<
iter->second.cols; ++
i)
447 float * ptf =
iter->second.
ptr<
float>(0,
i);
448 grid_map::Position
position(ptf[0], ptf[1]);
455 gridMapData(index(0), index(1)) = ptf[2];
456 gridMapNodeIds(index(0), index(1)) = kter->first;
457 gridMapColors(index(0), index(1)) = ptf[3];
461 if ((gridMapData(index(0), index(1)) < ptf[2] && (gridMapNodeIds(index(0), index(1)) <= kter->first || kter->first == -1)) ||
462 gridMapNodeIds(index(0), index(1)) < kter->first)
464 gridMapData(index(0), index(1)) = ptf[2];
465 gridMapNodeIds(index(0), index(1)) = kter->first;
466 gridMapColors(index(0), index(1)) = ptf[3];
472 UERROR(
"Outside map!? (%d) (%f,%f) -> (%d,%d)",
i, ptf[0], ptf[1], index[0], index[1]);
482 UDEBUG(
"Occupancy Grid update time = %f s",
timer.ticks());