RTAB-Map 0.23.10
Real-Time Appearance-Based Mapping
Loading...
Searching...
No Matches
LocalMapMaker.hpp
1/*
2Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions are met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in the
11 documentation and/or other materials provided with the distribution.
12 * Neither the name of the Universite de Sherbrooke nor the
13 names of its contributors may be used to endorse or promote products
14 derived from this software without specific prior written permission.
15
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifndef CORELIB_INCLUDE_RTABMAP_CORE_IMPL_LOCALMAP_HPP_
29#define CORELIB_INCLUDE_RTABMAP_CORE_IMPL_LOCALMAP_HPP_
30
31#include <rtabmap/core/util3d_mapping.h>
32#include <rtabmap/core/util3d_transforms.h>
34
35namespace rtabmap {
36
37template<typename PointT>
38typename pcl::PointCloud<PointT>::Ptr LocalGridMaker::segmentCloud(
39 const typename pcl::PointCloud<PointT>::Ptr & cloudIn,
40 const pcl::IndicesPtr & indicesIn,
41 const Transform & pose,
42 const cv::Point3f & viewPoint,
43 pcl::IndicesPtr & groundIndices,
44 pcl::IndicesPtr & obstaclesIndices,
45 pcl::IndicesPtr * flatObstacles) const
46{
47 groundIndices.reset(new std::vector<int>);
48 obstaclesIndices.reset(new std::vector<int>);
49 if(flatObstacles)
50 {
51 flatObstacles->reset(new std::vector<int>);
52 }
53
54 UASSERT(cloudIn.get());
55 UASSERT(indicesIn.get());
56 if(cloudIn->empty())
57 {
58 return cloudIn;
59 }
60
61 typename pcl::PointCloud<PointT>::Ptr cloud(new pcl::PointCloud<PointT>);
62 pcl::IndicesPtr indices(new std::vector<int>);
63
64 if(preVoxelFiltering_)
65 {
66 // voxelize to grid cell size
67 cloud = util3d::voxelize(cloudIn, indicesIn, cellSize_);
68
69 indices->resize(cloud->size());
70 for(unsigned int i=0; i<indices->size(); ++i)
71 {
72 indices->at(i) = i;
73 }
74 }
75 else
76 {
77 cloud = cloudIn;
78 if(indicesIn->empty() && cloud->is_dense)
79 {
80 indices->resize(cloud->size());
81 for(unsigned int i=0; i<indices->size(); ++i)
82 {
83 indices->at(i) = i;
84 }
85 }
86 else
87 {
88 indices = indicesIn;
89 }
90 }
91
92 if(cloud->empty())
93 {
94 return cloud;
95 }
96
97 // add pose rotation without yaw
98 float roll, pitch, yaw;
99 pose.getEulerAngles(roll, pitch, yaw);
100 UDEBUG("node.getPose()=%s projMapFrame_=%d", pose.prettyPrint().c_str(), projMapFrame_?1:0);
101 cloud = util3d::transformPointCloud(cloud, Transform(0,0, projMapFrame_?pose.z():0, roll, pitch, 0));
102
103 // filter footprint
104 if(footprintLength_ > 0.0f || footprintWidth_ > 0.0f || footprintHeight_ > 0.0f)
105 {
106 indices = util3d::cropBox(
107 cloud,
108 indices,
109 Eigen::Vector4f(
110 footprintLength_>0.0f?-footprintLength_/2.0f:std::numeric_limits<int>::min(),
111 footprintWidth_>0.0f&&footprintLength_>0.0f?-footprintWidth_/2.0f:std::numeric_limits<int>::min(),
112 0,
113 1),
114 Eigen::Vector4f(
115 footprintLength_>0.0f?footprintLength_/2.0f:std::numeric_limits<int>::max(),
116 footprintWidth_>0.0f&&footprintLength_>0.0f?footprintWidth_/2.0f:std::numeric_limits<int>::max(),
117 footprintHeight_>0.0f&&footprintLength_>0.0f&&footprintWidth_>0.0f?footprintHeight_:std::numeric_limits<int>::max(),
118 1),
120 true);
121 }
122
123 // filter ground/obstacles zone
124 if(minGroundHeight_ != 0.0f || maxObstacleHeight_ != 0.0f)
125 {
126 indices = util3d::passThrough(cloud, indices, "z",
127 minGroundHeight_!=0.0f?minGroundHeight_:std::numeric_limits<int>::min(),
128 maxObstacleHeight_>0.0f?maxObstacleHeight_:std::numeric_limits<int>::max());
129 UDEBUG("indices after max obstacles height filtering = %d", (int)indices->size());
130 }
131
132 if(indices->size())
133 {
134 if(normalsSegmentation_ && !groundIsObstacle_)
135 {
136 UDEBUG("normalKSearch=%d", normalKSearch_);
137 UDEBUG("maxGroundAngle=%f", maxGroundAngle_);
138 UDEBUG("Cluster radius=%f", clusterRadius_);
139 UDEBUG("flatObstaclesDetected=%d", flatObstaclesDetected_?1:0);
140 UDEBUG("maxGroundHeight=%f", maxGroundHeight_);
141 UDEBUG("groundNormalsUp=%f", groundNormalsUp_);
142 util3d::segmentObstaclesFromGround<PointT>(
143 cloud,
144 indices,
145 groundIndices,
146 obstaclesIndices,
147 normalKSearch_,
148 maxGroundAngle_,
149 clusterRadius_,
150 minClusterSize_,
151 flatObstaclesDetected_,
152 maxGroundHeight_,
153 flatObstacles,
154 Eigen::Vector4f(viewPoint.x, viewPoint.y, viewPoint.z+(projMapFrame_?pose.z():0), 1),
155 groundNormalsUp_);
156 UDEBUG("viewPoint=%f,%f,%f", viewPoint.x, viewPoint.y, viewPoint.z+(projMapFrame_?pose.z():0));
157 //UWARN("Saving ground.pcd and obstacles.pcd");
158 //pcl::io::savePCDFile("ground.pcd", *cloud, *groundIndices);
159 //pcl::io::savePCDFile("obstacles.pcd", *cloud, *obstaclesIndices);
160 }
161 else
162 {
163 UDEBUG("");
164 // passthrough filter
165 groundIndices = rtabmap::util3d::passThrough(cloud, indices, "z",
166 minGroundHeight_!=0.0f?minGroundHeight_:std::numeric_limits<int>::min(),
167 maxGroundHeight_!=0.0f?maxGroundHeight_:std::numeric_limits<int>::max());
168
169 pcl::IndicesPtr notObstacles = groundIndices;
170 if(indices->size())
171 {
172 notObstacles = util3d::extractIndices(cloud, indices, true);
173 notObstacles = util3d::concatenate(notObstacles, groundIndices);
174 }
175 obstaclesIndices = rtabmap::util3d::extractIndices(cloud, notObstacles, true);
176 }
177
178 UDEBUG("groundIndices=%d obstaclesIndices=%d", (int)groundIndices->size(), (int)obstaclesIndices->size());
179
180 // Do radius filtering after voxel filtering ( a lot faster)
181 if(noiseFilteringRadius_ > 0.0 && noiseFilteringMinNeighbors_ > 0)
182 {
183 UDEBUG("Radius filtering (%ld ground %ld obstacles, radius=%f k=%d)",
184 groundIndices->size(),
185 obstaclesIndices->size()+(flatObstacles?(*flatObstacles)->size():0),
186 noiseFilteringRadius_,
187 noiseFilteringMinNeighbors_);
188 if(groundIndices->size())
189 {
190 pcl::IndicesPtr farIndices;
191 if(rangeMax_!=0)
192 {
193 // Don't filter points farther than maximum range, in case we want to ray trace empty space
194 pcl::IndicesPtr closeIndices;
195 rtabmap::util3d::rangeSplitFiltering(cloud, groundIndices, rangeMax_, closeIndices, farIndices);
196 groundIndices = closeIndices;
197 }
198 groundIndices = rtabmap::util3d::radiusFiltering(cloud, groundIndices, noiseFilteringRadius_, noiseFilteringMinNeighbors_);
199 if(farIndices.get())
200 {
201 groundIndices = rtabmap::util3d::concatenate(groundIndices, farIndices);
202 }
203 }
204 if(obstaclesIndices->size())
205 {
206 pcl::IndicesPtr farIndices;
207 if(rangeMax_!=0)
208 {
209 // Don't filter points farther than maximum range, in case we want to ray trace empty space
210 pcl::IndicesPtr closeIndices;
211 rtabmap::util3d::rangeSplitFiltering(cloud, obstaclesIndices, rangeMax_, closeIndices, farIndices);
212 obstaclesIndices = closeIndices;
213 }
214 obstaclesIndices = rtabmap::util3d::radiusFiltering(cloud, obstaclesIndices, noiseFilteringRadius_, noiseFilteringMinNeighbors_);
215 if(farIndices.get())
216 {
217 obstaclesIndices = rtabmap::util3d::concatenate(obstaclesIndices, farIndices);
218 }
219 }
220 if(flatObstacles && (*flatObstacles)->size())
221 {
222 pcl::IndicesPtr farIndices;
223 if(rangeMax_!=0)
224 {
225 // Don't filter points farther than maximum range, in case we want to ray trace empty space
226 pcl::IndicesPtr closeIndices;
227 rtabmap::util3d::rangeSplitFiltering(cloud, *flatObstacles, rangeMax_, closeIndices, farIndices);
228 *flatObstacles = closeIndices;
229 }
230 *flatObstacles = rtabmap::util3d::radiusFiltering(cloud, *flatObstacles, noiseFilteringRadius_, noiseFilteringMinNeighbors_);
231 if(farIndices.get())
232 {
233 *flatObstacles = rtabmap::util3d::concatenate(*flatObstacles, farIndices);
234 }
235 }
236 UDEBUG("Radius filtering end (%ld ground %ld obstacles)",
237 groundIndices->size(),
238 obstaclesIndices->size()+(flatObstacles?(*flatObstacles)->size():0));
239
240 if(groundIndices->empty() && obstaclesIndices->empty())
241 {
242 UWARN("Cloud (with %d points) is empty after noise "
243 "filtering. Occupancy grid cannot be "
244 "created.",
245 (int)cloud->size());
246
247 }
248 }
249 }
250 return cloud;
251}
252
253}
254
255
256#endif /* CORELIB_INCLUDE_RTABMAP_CORE_IMPL_LOCALMAP_HPP_ */
ULogger class and convenient macros.
#define UDEBUG(...)
Definition ULogger.h:59
#define UASSERT(condition)
Definition ULogger.h:66
#define UWARN(...)
Definition ULogger.h:61
pcl::PointCloud< PointT >::Ptr segmentCloud(const typename pcl::PointCloud< PointT >::Ptr &cloud, const pcl::IndicesPtr &indices, const Transform &pose, const cv::Point3f &viewPoint, pcl::IndicesPtr &groundIndices, pcl::IndicesPtr &obstaclesIndices, pcl::IndicesPtr *flatObstacles=0) const
Segments a point cloud into ground and obstacle indices.
Represents a 3D rigid body transformation (rotation + translation).
Definition Transform.h:53
std::string prettyPrint() const
Returns a string representation of the transform.
static Transform getIdentity()
Returns identity transform.
void getEulerAngles(float &roll, float &pitch, float &yaw) const
Extracts Euler angles (roll, pitch, yaw).
float & z()
Translation z.
Definition Transform.h:151
pcl::IndicesPtr RTABMAP_CORE_EXPORT cropBox(const pcl::PCLPointCloud2::Ptr &cloud, const pcl::IndicesPtr &indices, const Eigen::Vector4f &min, const Eigen::Vector4f &max, const Transform &transform=Transform::getIdentity(), bool negative=false)
Performs crop box filtering on a point cloud of type pcl::PCLPointCloud2 and returns filtered indices...
pcl::IndicesPtr RTABMAP_CORE_EXPORT extractIndices(const pcl::PointCloud< pcl::PointXYZ >::Ptr &cloud, const pcl::IndicesPtr &indices, bool negative)
Extract indices from point cloud of type pcl::PointXYZ.
pcl::IndicesPtr RTABMAP_CORE_EXPORT passThrough(const pcl::PointCloud< pcl::PointXYZ >::Ptr &cloud, const pcl::IndicesPtr &indices, const std::string &axis, float min, float max, bool negative=false)
Performs pass-through filtering on a point cloud of type pcl::PointXYZ and returns filtered indices.
void RTABMAP_CORE_EXPORT rangeSplitFiltering(const pcl::PointCloud< pcl::PointXYZ >::Ptr &cloud, const pcl::IndicesPtr &indices, float range, pcl::IndicesPtr &closeIndices, pcl::IndicesPtr &farIndices)
Splits a point cloud of type pcl::PointXYZ.
pcl::IndicesPtr RTABMAP_CORE_EXPORT radiusFiltering(const pcl::PointCloud< pcl::PointXYZ >::Ptr &cloud, float radiusSearch, int minNeighborsInRadius)
Radius filtering for point cloud of type pcl::PointXYZ.
pcl::PointCloud< pcl::PointXYZ >::Ptr RTABMAP_CORE_EXPORT transformPointCloud(const pcl::PointCloud< pcl::PointXYZ >::Ptr &cloud, const Transform &transform)
Transforms pcl::PointXYZ point cloud type.
pcl::PointCloud< pcl::PointXYZ >::Ptr RTABMAP_CORE_EXPORT voxelize(const pcl::PointCloud< pcl::PointXYZ >::Ptr &cloud, const pcl::IndicesPtr &indices, float voxelSize)
Performs voxel grid downsampling on a point cloud of type pcl::PointXYZ on provided indices.
pcl::IndicesPtr RTABMAP_CORE_EXPORT concatenate(const std::vector< pcl::IndicesPtr > &indices)
Concatenates multiple sets of indices into a single index vector.