GridMap2D.cpp
Go to the documentation of this file.
1 /*
2  * A simple 2D gridmap structure
3  *
4  * Copyright 2011 Armin Hornung, University of Freiburg
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  * * Neither the name of the University of Freiburg nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include "gridmap_2d/GridMap2D.h"
32 #include <ros/console.h>
33 
34 namespace gridmap_2d{
35 
37 : m_frameId("/map")
38 {
39 
40 }
41 
42 GridMap2D::GridMap2D(const nav_msgs::OccupancyGridConstPtr& gridMap, bool unknown_as_obstacle) {
43 
44  setMap(gridMap, unknown_as_obstacle);
45 
46 }
47 
49  : m_binaryMap(other.m_binaryMap.clone()),
50  m_distMap(other.m_distMap.clone()),
51  m_mapInfo(other.m_mapInfo),
52  m_frameId(other.m_frameId)
53 {
54 
55 }
56 
58 
59 }
60 
62  cv::distanceTransform(m_binaryMap, m_distMap, CV_DIST_L2, CV_DIST_MASK_PRECISE);
63  // distance map now contains distance in meters:
64  m_distMap = m_distMap * m_mapInfo.resolution;
65 }
66 
67 void GridMap2D::setMap(const nav_msgs::OccupancyGridConstPtr& grid_map, bool unknown_as_obstacle){
68  m_mapInfo = grid_map->info;
69  m_frameId = grid_map->header.frame_id;
70  // allocate map structs so that x/y in the world correspond to x/y in the image
71  // (=> cv::Mat is rotated by 90 deg, because it's row-major!)
72  m_binaryMap = cv::Mat(m_mapInfo.width, m_mapInfo.height, CV_8UC1);
73  m_distMap = cv::Mat(m_binaryMap.size(), CV_32FC1);
74 
75  std::vector<signed char>::const_iterator mapDataIter = grid_map->data.begin();
76 
77  //TODO check / param
78  unsigned char map_occ_thres = 70;
79 
80  // iterate over map, store in image
81  // (0,0) is lower left corner of OccupancyGrid
82  for(unsigned int j = 0; j < m_mapInfo.height; ++j){
83  for(unsigned int i = 0; i < m_mapInfo.width; ++i){
84  if (*mapDataIter > map_occ_thres
85  || (unknown_as_obstacle && *mapDataIter < 0))
86  {
87  m_binaryMap.at<uchar>(i,j) = OCCUPIED;
88  } else{
89  m_binaryMap.at<uchar>(i,j) = FREE;
90  }
91  ++mapDataIter;
92  }
93  }
94 
96 
97  ROS_INFO("GridMap2D created with %d x %d cells at %f resolution.", m_mapInfo.width, m_mapInfo.height, m_mapInfo.resolution);
98 }
99 
100 nav_msgs::OccupancyGrid GridMap2D::toOccupancyGridMsg() const{
101  nav_msgs::OccupancyGrid msg;
102  msg.header.frame_id = m_frameId;
103  msg.header.stamp = ros::Time::now();
104  msg.info = m_mapInfo;
105  msg.data.resize(msg.info.height*msg.info.width);
106 
107  // iterate over map, store in data
108  std::vector<signed char>::iterator mapDataIter = msg.data.begin();
109  // (0,0) is lower left corner of OccupancyGrid
110  for(unsigned int j = 0; j < m_mapInfo.height; ++j){
111  for(unsigned int i = 0; i < m_mapInfo.width; ++i){
112  if (m_binaryMap.at<uchar>(i,j) == OCCUPIED)
113  *mapDataIter = 100;
114  else
115  *mapDataIter = 0;
116 
117  ++mapDataIter;
118  }
119  }
120 
121  return msg;
122 }
123 
124 void GridMap2D::setMap(const cv::Mat& binaryMap){
125  m_binaryMap = binaryMap.clone();
126  m_distMap = cv::Mat(m_binaryMap.size(), CV_32FC1);
127 
128  cv::distanceTransform(m_binaryMap, m_distMap, CV_DIST_L2, CV_DIST_MASK_PRECISE);
129  // distance map now contains distance in meters:
130  m_distMap = m_distMap * m_mapInfo.resolution;
131 
132  ROS_INFO("GridMap2D copied from existing cv::Mat with %d x %d cells at %f resolution.", m_mapInfo.width, m_mapInfo.height, m_mapInfo.resolution);
133 
134 }
135 
136 void GridMap2D::inflateMap(double inflationRadius){
137  m_binaryMap = (m_distMap > inflationRadius );
138  // recompute distance map with new binary map:
139  cv::distanceTransform(m_binaryMap, m_distMap, CV_DIST_L2, CV_DIST_MASK_PRECISE);
140  m_distMap = m_distMap * m_mapInfo.resolution;
141 }
142 
143 // See costmap2D for mapToWorld / worldToMap implementations:
144 
145 void GridMap2D::mapToWorld(unsigned int mx, unsigned int my, double& wx, double& wy) const {
146  wx = m_mapInfo.origin.position.x + (mx+0.5) * m_mapInfo.resolution;
147  wy = m_mapInfo.origin.position.y + (my+0.5) * m_mapInfo.resolution;
148 }
149 
150 
151 
152 void GridMap2D::worldToMapNoBounds(double wx, double wy, unsigned int& mx, unsigned int& my) const {
153  mx = (int) ((wx - m_mapInfo.origin.position.x) / m_mapInfo.resolution);
154  my = (int) ((wy - m_mapInfo.origin.position.y) / m_mapInfo.resolution);
155 }
156 
157 bool GridMap2D::worldToMap(double wx, double wy, unsigned int& mx, unsigned int& my) const {
158  if(wx < m_mapInfo.origin.position.x || wy < m_mapInfo.origin.position.y)
159  return false;
160 
161  mx = (int) ((wx - m_mapInfo.origin.position.x) / m_mapInfo.resolution);
162  my = (int) ((wy - m_mapInfo.origin.position.y) / m_mapInfo.resolution);
163 
164  if(mx < m_mapInfo.width && my < m_mapInfo.height)
165  return true;
166 
167  return false;
168 }
169 
170 bool GridMap2D::inMapBounds(double wx, double wy) const{
171  unsigned mx, my;
172  return worldToMap(wx,wy,mx,my);
173 }
174 
175 float GridMap2D::distanceMapAt(double wx, double wy) const{
176  unsigned mx, my;
177 
178  if (worldToMap(wx, wy, mx, my))
179  return m_distMap.at<float>(mx, my);
180  else
181  return -1.0f;
182 }
183 
184 
185 uchar GridMap2D::binaryMapAt(double wx, double wy) const{
186  unsigned mx, my;
187 
188  if (worldToMap(wx, wy, mx, my))
189  return m_binaryMap.at<uchar>(mx, my);
190  else
191  return 0;
192 }
193 
194 float GridMap2D::distanceMapAtCell(unsigned int mx, unsigned int my) const{
195  return m_distMap.at<float>(mx, my);
196 }
197 
198 
199 uchar GridMap2D::binaryMapAtCell(unsigned int mx, unsigned int my) const{
200  return m_binaryMap.at<uchar>(mx, my);
201 }
202 
203 uchar& GridMap2D::binaryMapAtCell(unsigned int mx, unsigned int my){
204  return m_binaryMap.at<uchar>(mx, my);
205 }
206 
207 
208 bool GridMap2D::isOccupiedAtCell(unsigned int mx, unsigned int my) const{
209  return (m_binaryMap.at<uchar>(mx, my) < 255);
210 }
211 
212 
213 bool GridMap2D::isOccupiedAt(double wx, double wy) const{
214  unsigned mx, my;
215  if (worldToMap(wx, wy, mx, my))
216  return isOccupiedAtCell(mx, my);
217  else
218  return true;
219 }
220 
221 }
222 
223 
static const uchar OCCUPIED
char value for "free": 0
Definition: GridMap2D.h:135
nav_msgs::OccupancyGrid toOccupancyGridMsg() const
Converts back into a ROS nav_msgs::OccupancyGrid msg.
Definition: GridMap2D.cpp:100
bool isOccupiedAt(double wx, double wy) const
Definition: GridMap2D.cpp:213
void worldToMapNoBounds(double wx, double wy, unsigned int &mx, unsigned int &my) const
Definition: GridMap2D.cpp:152
void setMap(const nav_msgs::OccupancyGridConstPtr &grid_map, bool unknown_as_obstacle=false)
Initialize map from a ROS OccupancyGrid message.
Definition: GridMap2D.cpp:67
cv::Mat m_distMap
distance map (in meter)
Definition: GridMap2D.h:139
static const uchar FREE
char value for "free": 255
Definition: GridMap2D.h:134
void updateDistanceMap()
Recalculate the internal distance map. Required after manual changes to the grid map data...
Definition: GridMap2D.cpp:61
float distanceMapAtCell(unsigned int mx, unsigned int my) const
Returns distance (in m) at map cell <mx, my> in m; -1 if out of bounds!
Definition: GridMap2D.cpp:194
bool worldToMap(double wx, double wy, unsigned int &mx, unsigned int &my) const
Definition: GridMap2D.cpp:157
void mapToWorld(unsigned int mx, unsigned int my, double &wx, double &wy) const
Definition: GridMap2D.cpp:145
std::string m_frameId
"map" frame where ROS OccupancyGrid originated from
Definition: GridMap2D.h:141
#define ROS_INFO(...)
uchar binaryMapAt(double wx, double wy) const
Returns map value at world coordinates <wx, wy>; out of bounds will be returned as 0! ...
Definition: GridMap2D.cpp:185
uchar binaryMapAtCell(unsigned int mx, unsigned int my) const
Returns map value at map cell <mx, my>; out of bounds will be returned as 0!
Definition: GridMap2D.cpp:199
float distanceMapAt(double wx, double wy) const
Returns distance (in m) at world coordinates <wx,wy> in m; -1 if out of bounds!
Definition: GridMap2D.cpp:175
nav_msgs::MapMetaData m_mapInfo
Definition: GridMap2D.h:140
void inflateMap(double inflationRaduis)
Definition: GridMap2D.cpp:136
Stores a nav_msgs::OccupancyGrid in a convenient opencv cv::Mat as binary map (free: 255...
Definition: GridMap2D.h:49
const cv::Mat & binaryMap() const
Definition: GridMap2D.h:130
bool inMapBounds(double wx, double wy) const
check if a coordinate is covered by the map extent (same as worldToMap)
Definition: GridMap2D.cpp:170
static Time now()
cv::Mat m_binaryMap
binary occupancy map. 255: free, 0 occupied.
Definition: GridMap2D.h:138
bool isOccupiedAtCell(unsigned int mx, unsigned int my) const
Definition: GridMap2D.cpp:208


gridmap_2d
Author(s): Armin Hornung
autogenerated on Mon Jun 10 2019 13:38:21