16 #include <Eigen/Dense> 29 GridMap::GridMap(
const std::vector<std::string>& layers) {
34 startIndex_.setZero();
38 for (
auto& layer : layers_) {
39 data_.insert(std::pair<std::string, Matrix>(layer,
Matrix()));
46 assert(length(0) > 0.0);
47 assert(length(1) > 0.0);
48 assert(resolution > 0.0);
51 size(0) =
static_cast<int>(round(length(0) / resolution));
52 size(1) =
static_cast<int>(round(length(1) / resolution));
81 for (
const auto& layer :
layers_) {
82 if (!other.
exists(layer)) {
94 assert(
size_(0) == data.rows());
95 assert(
size_(1) == data.cols());
99 data_.at(layer) = data;
102 data_.insert(std::pair<std::string, Matrix>(layer, data));
113 return data_.at(layer);
114 }
catch (
const std::out_of_range& exception) {
115 throw std::out_of_range(
"GridMap::get(...) : No map layer '" + layer +
"' available.");
121 return data_.at(layer);
122 }
catch (
const std::out_of_range& exception) {
123 throw std::out_of_range(
"GridMap::get(...) : No map layer of type '" + layer +
"' available.");
136 const auto dataIterator =
data_.find(layer);
137 if (dataIterator ==
data_.end()) {
140 data_.erase(dataIterator);
142 const auto layerIterator = std::find(
layers_.begin(),
layers_.end(), layer);
143 if (layerIterator ==
layers_.end()) {
163 return at(layer, index);
165 throw std::out_of_range(
"GridMap::atPosition(...) : Position is out of range.");
170 bool skipNextSwitchCase =
false;
171 switch (interpolationMethod) {
178 skipNextSwitchCase =
true;
183 if (!skipNextSwitchCase) {
205 return at(layer, index);
207 throw std::out_of_range(
"GridMap::atPosition(...) : Position is out of range.");
211 throw std::runtime_error(
212 "GridMap::atPosition(...) : Specified " 213 "interpolation method not implemented.");
219 return data_.at(layer)(index(0), index(1));
220 }
catch (
const std::out_of_range& exception) {
221 throw std::out_of_range(
"GridMap::at(...) : No map layer '" + layer +
"' available.");
227 return data_.at(layer)(index(0), index(1));
228 }
catch (
const std::out_of_range& exception) {
229 throw std::out_of_range(
"GridMap::at(...) : No map layer '" + layer +
"' available.");
246 return isfinite(value);
258 if (layers.empty()) {
261 for (
const auto& layer : layers) {
270 const auto value =
at(layer, index);
276 position.head(2) = position2d;
277 position.z() = value;
282 Eigen::Vector3d temp{
at(layerPrefix +
"x", index),
at(layerPrefix +
"y", index),
at(layerPrefix +
"z", index)};
293 return getSubmap(position, length, index, isSuccess);
304 SubmapGeometry submapInformation(*
this, position, length, isSuccess);
312 std::vector<BufferRegion> bufferRegions;
315 cout <<
"Cannot access submap of this size." << endl;
320 for (
const auto& data :
data_) {
321 for (
const auto& bufferRegion : bufferRegions) {
322 Index index = bufferRegion.getStartIndex();
323 Size size = bufferRegion.getSize();
326 submap.
data_[data.first].topLeftCorner(size(0), size(1)) = data.second.block(index(0), index(1), size(0), size(1));
328 submap.
data_[data.first].topRightCorner(size(0), size(1)) = data.second.block(index(0), index(1), size(0), size(1));
330 submap.
data_[data.first].bottomLeftCorner(size(0), size(1)) = data.second.block(index(0), index(1), size(0), size(1));
332 submap.
data_[data.first].bottomRightCorner(size(0), size(1)) = data.second.block(index(0), index(1), size(0), size(1));
342 const double sampleRatio)
const {
344 if (!
exists(heightLayerName)) {
345 throw std::out_of_range(
"GridMap::getTransformedMap(...) : No map layer '" + heightLayerName +
"' available.");
349 std::vector<Position3> positionSamples;
353 const double sampleLength =
resolution_ * sampleRatio;
356 const double halfLengthX =
length_.x() * 0.5;
357 const double halfLengthY =
length_.y() * 0.5;
363 std::vector<Position3> newEdges;
365 newEdges.push_back(transform * topLeftCorner);
366 newEdges.push_back(transform * topRightCorner);
367 newEdges.push_back(transform * bottomLeftCorner);
368 newEdges.push_back(transform * bottomRightCorner);
372 for (
const auto& newEdge : newEdges) {
373 newCenter += newEdge;
379 for (
const auto& newEdge : newEdges) {
380 Position3 positionCenterToEdge = newEdge - newCenter;
381 maxLengthFromCenter.x() = std::fmax(std::fabs(positionCenterToEdge.x()), maxLengthFromCenter.x());
382 maxLengthFromCenter.y() = std::fmax(std::fabs(positionCenterToEdge.y()), maxLengthFromCenter.y());
384 Length newLength = 2.0 * maxLengthFromCenter;
396 if (!
getPosition3(heightLayerName, *iterator, center)) {
401 positionSamples.clear();
403 if (sampleRatio > 0.0) {
404 positionSamples.reserve(5);
405 positionSamples.push_back(center);
406 positionSamples.push_back(
Position3(center.x() - sampleLength, center.y(), center.z()));
407 positionSamples.push_back(
Position3(center.x() + sampleLength, center.y(), center.z()));
408 positionSamples.push_back(
Position3(center.x(), center.y() - sampleLength, center.z()));
409 positionSamples.push_back(
Position3(center.x(), center.y() + sampleLength, center.z()));
411 positionSamples.push_back(center);
415 for (
const auto& position : positionSamples) {
416 const Position3 transformedPosition = transform * position;
419 if (!newMap.
getIndex(
Position(transformedPosition.x(), transformedPosition.y()), newIndex)) {
425 const auto newExistingValue = newMap.
at(heightLayerName, newIndex);
426 if (!std::isnan(newExistingValue) && newExistingValue > transformedPosition.z()) {
431 for (
const auto& layer :
layers_) {
432 const auto currentValueInOldGrid =
at(layer, *iterator);
433 auto& newValue = newMap.
at(layer, newIndex);
434 if (layer == heightLayerName) {
435 newValue = transformedPosition.z();
438 newValue = currentValueInOldGrid;
459 for (
int i = 0; i < indexShift.size(); i++) {
460 if (indexShift(i) != 0) {
461 if (abs(indexShift(i)) >=
getSize()(i)) {
467 int sign = (indexShift(i) > 0 ? 1 : -1);
468 int startIndex =
startIndex_(i) - (sign < 0 ? 1 : 0);
469 int endIndex = startIndex - sign + indexShift(i);
470 int nCells = abs(indexShift(i));
471 int index = (sign > 0 ? startIndex : endIndex);
474 if (index + nCells <=
getSize()(i)) {
485 int firstIndex = index;
486 int firstNCells =
getSize()(i) - firstIndex;
496 int secondNCells = nCells - firstNCells;
512 position_ += alignedPositionShift;
515 return (indexShift.any() != 0);
519 std::vector<BufferRegion> newRegions;
520 return move(position, newRegions);
525 if (copyAllLayers) layers = other.
getLayers();
531 for (
const auto& layer : layers) {
538 if (
isValid(*iterator) && !overwriteData)
continue;
542 if (!other.
isInside(position))
continue;
544 for (
const auto& layer : layers) {
545 if (!other.
isValid(index, layer))
continue;
546 at(layer, *iterator) = other.
at(layer, index);
561 bool resizeMap =
false;
564 if (topLeftCornerOther.x() > topLeftCorner.x()) {
565 extendedMapPosition.x() += (topLeftCornerOther.x() - topLeftCorner.x()) / 2.0;
566 extendedMapLength.x() += topLeftCornerOther.x() - topLeftCorner.x();
569 if (topLeftCornerOther.y() > topLeftCorner.y()) {
570 extendedMapPosition.y() += (topLeftCornerOther.y() - topLeftCorner.y()) / 2.0;
571 extendedMapLength.y() += topLeftCornerOther.y() - topLeftCorner.y();
574 if (bottomRightCornerOther.x() < bottomRightCorner.x()) {
575 extendedMapPosition.x() -= (bottomRightCorner.x() - bottomRightCornerOther.x()) / 2.0;
576 extendedMapLength.x() += bottomRightCorner.x() - bottomRightCornerOther.x();
579 if (bottomRightCornerOther.y() < bottomRightCorner.y()) {
580 extendedMapPosition.y() -= (bottomRightCorner.y() - bottomRightCornerOther.y()) / 2.0;
581 extendedMapLength.y() += bottomRightCorner.y() - bottomRightCornerOther.y();
610 if (
isValid(*iterator))
continue;
614 if (!mapCopy.
isInside(position))
continue;
616 for (
const auto& layer :
layers_) {
617 at(layer, *iterator) = mapCopy.
at(layer, index);
675 std::vector<BufferRegion> bufferRegions;
677 throw std::out_of_range(
"Cannot access submap of this size.");
680 for (
auto& data :
data_) {
681 auto tempData(data.second);
682 for (
const auto& bufferRegion : bufferRegions) {
683 Index index = bufferRegion.getStartIndex();
684 Size size = bufferRegion.getSize();
687 tempData.topLeftCorner(size(0), size(1)) = data.second.block(index(0), index(1), size(0), size(1));
689 tempData.topRightCorner(size(0), size(1)) = data.second.block(index(0), index(1), size(0), size(1));
691 tempData.bottomLeftCorner(size(0), size(1)) = data.second.block(index(0), index(1), size(0), size(1));
693 tempData.bottomRightCorner(size(0), size(1)) = data.second.block(index(0), index(1), size(0), size(1));
696 data.second = tempData;
714 const double halfLengthX =
length_.x() * 0.5;
715 const double halfLengthY =
length_.y() * 0.5;
722 const double maxX = topRightCorner.x();
723 const double minX = bottomRightCorner.x();
724 const double maxY = bottomLeftCorner.y();
725 const double minY = bottomRightCorner.y();
729 positionInMap.x() = std::fmin(positionInMap.x(), maxX - std::numeric_limits<double>::epsilon());
730 positionInMap.y() = std::fmin(positionInMap.y(), maxY - std::numeric_limits<double>::epsilon());
732 positionInMap.x() = std::fmax(positionInMap.x(), minX + std::numeric_limits<double>::epsilon());
733 positionInMap.y() = std::fmax(positionInMap.y(), minY + std::numeric_limits<double>::epsilon());
735 return positionInMap;
740 data_.at(layer).setConstant(NAN);
741 }
catch (
const std::out_of_range& exception) {
742 throw std::out_of_range(
"GridMap::clear(...) : No map layer '" + layer +
"' available.");
753 for (
auto& data :
data_) {
754 data.second.setConstant(NAN);
760 data_.at(layer).block(index, 0, nRows,
getSize()(1)).setConstant(NAN);
766 data_.at(layer).block(0, index,
getSize()(0), nCols).setConstant(NAN);
779 if (position.x() >= point.x()) {
780 indices[1] = indices[0] +
Index(-1, 0);
783 indices[1] = indices[0] +
Index(+1, 0);
786 if (position.y() >= point.y()) {
787 indices[2] = indices[0] +
Index(0, -1);
801 indices[2] = indices[0] +
Index(0, +1);
814 indices[3].x() = indices[1].x();
815 indices[3].y() = indices[2].y();
818 const size_t bufferSize = mapSize(0) * mapSize(1);
820 const size_t endIndexLin = startIndexLin + bufferSize;
824 for (
size_t i = 0; i < 4; ++i) {
826 if ((indexLin < startIndexLin) || (indexLin > endIndexLin))
return false;
827 f[i] = layerMat(indexLin);
834 value = f[0] * positionRedFlip.x() * positionRedFlip.y() + f[1] * positionRed.x() * positionRedFlip.y() +
835 f[2] * positionRedFlip.x() * positionRed.y() + f[3] * positionRed.x() * positionRed.y();
841 for (
auto& data :
data_) {
850 double interpolatedValue = 0.0;
855 if (!std::isfinite(interpolatedValue)) {
858 value = interpolatedValue;
866 double interpolatedValue = 0.0;
871 if (!std::isfinite(interpolatedValue)) {
874 value = interpolatedValue;
const Length & getLength() const
double getResolution() const
void setGeometry(const Length &length, const double resolution, const Position &position=Position::Zero())
Time getTimestamp() const
bool atPositionBicubicConvolutionInterpolated(const std::string &layer, const Position &position, float &value) const
Size size_
Size of the buffer (rows and cols of the data structure).
void setPosition(const Position &position)
float & atPosition(const std::string &layer, const Position &position)
const Index & getStartIndex() const
void clear(const std::string &layer)
bool getPosition(const Index &index, Position &position) const
void wrapIndexToRange(Index &index, const Size &bufferSize)
bool getBufferRegionsForSubmap(std::vector< BufferRegion > &submapBufferRegions, const Index &submapIndex, const Size &submapBufferSize, const Size &bufferSize, const Index &bufferStartIndex=Index::Zero())
void setBasicLayers(const std::vector< std::string > &basicLayers)
const Position & getPosition() const
const std::string & getFrameId() const
double resolution_
Map resolution in xy plane [m/cell].
GridMap getTransformedMap(const Eigen::Isometry3d &transform, const std::string &heightLayerName, const std::string &newFrameId, const double sampleRatio=0.0) const
std::vector< std::string > basicLayers_
std::unordered_map< std::string, Matrix > data_
Grid map data stored as layers of matrices.
Position getClosestPositionInMap(const Position &position) const
grid_map::DataType DataType
bool getVector(const std::string &layerPrefix, const Index &index, Eigen::Vector3d &vector) const
std::string frameId_
Frame id of the grid map.
const Matrix & operator[](const std::string &layer) const
bool atPositionBicubicInterpolated(const std::string &layer, const Position &position, float &value) const
bool move(const Position &position, std::vector< BufferRegion > &newRegions)
void convertToDefaultStartIndex()
bool getIndexFromPosition(Index &index, const Position &position, const Length &mapLength, const Position &mapPosition, const double &resolution, const Size &bufferSize, const Index &bufferStartIndex=Index::Zero())
bool addDataFrom(const GridMap &other, bool extendMap, bool overwriteData, bool copyAllLayers, std::vector< std::string > layers=std::vector< std::string >())
GridMap getSubmap(const Position &position, const Length &length, bool &isSuccess) const
bool isValid(const Index &index) const
const Length & getLength() const
Eigen::Vector3d Position3
bool exists(const std::string &layer) const
bool extendToInclude(const GridMap &other)
bool checkIfPositionWithinMap(const Position &position, const Length &mapLength, const Position &mapPosition)
double getResolution() const
const std::vector< std::string > & getLayers() const
bool getPositionShiftFromIndexShift(Vector &positionShift, const Index &indexShift, const double &resolution)
std::vector< std::string > layers_
Names of the data layers.
bool isInside(const Position &position) const
bool isDefaultStartIndex() const
const Matrix & get(const std::string &layer) const
const Position & getPosition() const
void setStartIndex(const Index &startIndex)
Position position_
Map position in the grid map frame [m].
float & at(const std::string &layer, const Index &index)
bool hasSameLayers(const grid_map::GridMap &other) const
Time timestamp_
Timestamp of the grid map (nanoseconds).
bool hasBasicLayers() const
Index startIndex_
Circular buffer start indeces.
void add(const std::string &layer, const double value=NAN)
size_t getLinearIndexFromIndex(const Index &index, const Size &bufferSize, const bool rowMajor=false)
bool evaluateBicubicConvolutionInterpolation(const GridMap &gridMap, const std::string &layer, const Position &queriedPosition, double *interpolatedValue)
bool atPositionLinearInterpolated(const std::string &layer, const Position &position, float &value) const
bool getPositionFromIndex(Position &position, const Index &index, const Length &mapLength, const Position &mapPosition, const double &resolution, const Size &bufferSize, const Index &bufferStartIndex=Index::Zero())
void clearCols(unsigned int index, unsigned int nCols)
void clearRows(unsigned int index, unsigned int nRows)
Length length_
Side length of the map in x- and y-direction [m].
bool getIndexShiftFromPositionShift(Index &indexShift, const Vector &positionShift, const double &resolution)
void setFrameId(const std::string &frameId)
const Index & getStartIndex() const
void setTimestamp(const Time timestamp)
bool erase(const std::string &layer)
bool getIndex(const Position &position, Index &index) const
bool getPosition3(const std::string &layer, const Index &index, Position3 &position) const
bool evaluateBicubicInterpolation(const GridMap &gridMap, const std::string &layer, const Position &queriedPosition, double *interpolatedValue)
void resize(const Index &bufferSize)
const std::vector< std::string > & getBasicLayers() const
const Size & getSize() const