55#include < Eigen/Geometry>
66#include < boost/multi_array.hpp>
77#include < gtest/gtest_prod.h>
8+ #include < mpl_collision/map_util.h>
89
910namespace mapper {
1011
12+ // Create a derived class to be able to directly access elements of the map
13+ // declared in MapUtil
14+ class VoxelMap : public MPL ::VoxelMapUtil {
15+ public:
16+ VoxelMap () = default ;
17+ signed char & operator [](int index) { return map_[index]; }
18+ };
19+
1120template <typename T>
1221using AlignedVector = std::vector<T, Eigen::aligned_allocator<T>>;
1322
1423using vec_Vec3d = AlignedVector<Eigen::Vector3d>;
1524using vec_Vec3i = AlignedVector<Eigen::Vector3i>;
1625
26+ /* *
27+ * @brief The VoxelMapper class contains two maps denoted as map_ and
28+ * inflated_map_ where inflated_map_ is the inflated versions of map_. These two
29+ * objects are instances of the mapper::VoxelMap class which is derived from
30+ * MapUtil. Naturally, the maps share the same origin, dimensions and resolution
31+ * IMPORTANT note: They use axis-aligned voxels
32+ */
1733class VoxelMapper {
1834 // Making test class and tests friends of VoxelMapper class to be able to
1935 // access private methods and members
@@ -23,94 +39,86 @@ class VoxelMapper {
2339 public:
2440 /* *
2541 * @brief Simple constructor
26- * @param origin the origin of the map (float), should be the left-most corner
27- * @param dim the range of map in x-y-z axes (float)
28- * @param res voxel resolution
29- * @param val set default map value
30- * @param decay_times_to_empty number of times of decay for an occupied voxel
31- * to be decayed into empty cell, 0 means no decay
42+ * @param origin The origin of the map (float), should be the most negative
43+ * corner
44+ * @param dim The range of map in x-y-z axes (float in world units)
45+ * @param res Voxel resolution in world units
46+ * @param default_val The default map value
47+ * @param decay_times_to_empty Number of times of decay for an occupied voxel
48+ * to be decayed into empty cell. 0 means no decay
3249 */
3350 VoxelMapper (const Eigen::Vector3d& origin,
3451 const Eigen::Vector3d& dim,
3552 double res,
36- int8_t val = 0 ,
53+ int8_t default_val = 0 ,
3754 int decay_times_to_empty = 0 );
3855
39- // / set the map with some predefined values
56+ /* *
57+ * @brief Set the map with some predefined values
58+ * @param ori Origin position in world units (most negative corner)
59+ * @param dim Number of cells in each dimension
60+ * @param map Vector of cell values
61+ * @param res Map resolution
62+ */
4063 void setMap (const Eigen::Vector3d &ori, const Eigen::Vector3i &dim,
4164 const std::vector<signed char > &map, double res);
42- // / Set all voxels as unknown
43- void setMapUnknown ();
44- // / Set all voxels as free
45- void setMapFree ();
46-
47- // / Get the occupied voxels
48- vec_Vec3d getCloud ();
49- // / Get the inflated occupied voxels
50- vec_Vec3d getInflatedCloud ();
5165
5266 /* *
53- * @brief Get the occupied voxels within a local range
54- * @param pos the center of the local point cloud
55- * @param dim the range of the local point cloud
56- *
57- * Assume the map is in a fixed frame
67+ * @brief Set the inflated map with some predefined values
68+ * @param ori Origin position in world units (most negative corner)
69+ * @param dim Number of cells in each dimension
70+ * @param map Vector of cell values
71+ * @param res Map resolution
5872 */
59- vec_Vec3d getLocalCloud (const Eigen::Vector3d& pos,
60- const Eigen::Vector3d& ori,
61- const Eigen::Vector3d& dim);
73+ void setInflatedMap (const Eigen::Vector3d &ori, const Eigen::Vector3i &dim,
74+ const std::vector<signed char > &map, double res);
6275
6376 /* *
64- * @brief crop a local voxel map from the global voxel map
65- * @param ori the origin of the local voxel map
66- * @param dim the range of the local voxel map
67- *
68- * Assume the map is in a fixed frame
77+ * @brief Set all voxels as unknown in both the map and inflated map
6978 */
70- planning_ros_msgs::VoxelMap getInflatedLocalMap (const Eigen::Vector3d& ori,
71- const Eigen::Vector3d& dim);
79+ void setMapUnknown ();
7280
7381 /* *
74- * @brief Decay the occupied voxels within a local range
75- * @param pos the center of the local point cloud
76- * @param max_decay_range maximum range of the local region to decay
77- *
78- * Assume the map is in a fixed frame
82+ * @brief Set all voxels as free in both the map and the inflated map
7983 */
80- void decayLocalCloud ( const Eigen::Vector3d& pos, double max_decay_range );
84+ void setMapFree ( );
8185
8286 /* *
83- * @brief Get the inflated occupied voxels within a local range (local voxel
84- * map is a subset of global voxel map)
85- * @param pos the center of the local point cloud
86- * @param dim the range of the local point cloud
87- *
88- * Assume the map is in a fixed frame
87+ * @brief Get the Map object
88+ * @return planning_ros_msgs::VoxelMap
8989 */
90- vec_Vec3d getInflatedLocalCloud (const Eigen::Vector3d& pos,
91- const Eigen::Vector3d& ori,
92- const Eigen::Vector3d& dim);
93-
94- // / Get the map
9590 planning_ros_msgs::VoxelMap getMap ();
96- // / Get the inflated map
91+
92+ /* *
93+ * @brief Get the Inflated Map object
94+ * @return planning_ros_msgs::VoxelMap
95+ */
9796 planning_ros_msgs::VoxelMap getInflatedMap ();
9897
9998 /* *
100- * @brief Get the 2D slice of inflated point cloud
101- * @param h the height (z-axis value) to get the slice
102- * @param hh the thickness of the slice, zero means one-voxel thick
99+ * @brief Crop a local voxel map from the global inflated voxel map
100+ * @param ori The origin of the local voxel map (most negative corner)
101+ * @param dim the range of the local voxel map in world units
102+ */
103+ planning_ros_msgs::VoxelMap getInflatedLocalMap (const Eigen::Vector3d& ori,
104+ const Eigen::Vector3d& dim);
105+
106+ /* *
107+ * @brief Get a 2D slice of the inflated map
108+ * @param h The height (z-axis value) to get the slice
109+ * @param hh The thickness of the slice, zero means one-voxel thick. Thickness
110+ * refers to how much space (in either direction) along the z-axis is going to
111+ * be considered for the 2D slice.
103112 */
104113 planning_ros_msgs::VoxelMap getInflatedOccMap (double h, double hh = 0 );
105114
106115 /* *
107- * @brief Add point cloud to global map
108- * @param pts point cloud in the sensor frame
109- * @param TF transform from the sensor frame to the map frame
110- * @param ns inflated voxel neighbors
111- * @param ray_trace if do ray trace, default disabled
112- *
113- * return the new added occupied cells
116+ * @brief Add point cloud to map and inflated map
117+ * @param pts Point cloud in the sensor frame
118+ * @param TF Transformation representing the pose of the sensor frame with
119+ * respect to the map frame
120+ * @param ns Relative neighboring voxels to consider for the inflated map
121+ * @param ray_trace If do ray trace, default disabled
114122 */
115123 void addCloud (const vec_Vec3d& pts,
116124 const Eigen::Affine3d& TF,
@@ -119,89 +127,110 @@ class VoxelMapper {
119127 double max_range = 10 );
120128
121129 /* *
122- * @brief Add point cloud
123- * @param pts point cloud in the sensor frame
124- * @param TF transform from the sensor frame to the map frame
125- * @param ns inflated voxel neighbors
126- * @param ray_trace if do ray trace, default disabled
127- * @param uh upper bound in world z axis
128- * @param lh lower bound in world z axis
129- *
130- * return the new added occupied cells
131- */
132- void addCloud2D (const vec_Vec3d& pts,
133- const Eigen::Affine3d& TF,
134- const vec_Vec3i& ns,
135- bool ray_trace,
136- double uh,
137- double lh,
138- double max_range);
139-
140- // / Free voxels
130+ * @brief Get a vector of points that are located at the center of occupied
131+ * voxels in the map
132+ */
133+ vec_Vec3d getCloud ();
134+
135+ /* *
136+ * @brief Get a vector of points that are located at the center of occupied
137+ * voxels in the inflated map
138+ */
139+ vec_Vec3d getInflatedCloud ();
140+
141+ /* *
142+ * @brief Get a vector of points that are located at the center of occupied
143+ * voxels in the map within a local range
144+ * @param ori The origin of the local cloud in world units (most negative
145+ * corner)
146+ * @param dim the range of the local point cloud in world units
147+ */
148+ vec_Vec3d getLocalCloud (const Eigen::Vector3d& ori,
149+ const Eigen::Vector3d& dim);
150+
151+ /* *
152+ * @brief Get a vector of points that are located at the center of occupied
153+ * voxels in the inflated map within a local range
154+ * @param ori The origin of the local cloud in world units (most negative
155+ * corner)
156+ * @param dim the range of the local point cloud in world units
157+ */
158+ vec_Vec3d getInflatedLocalCloud (const Eigen::Vector3d& ori,
159+ const Eigen::Vector3d& dim);
160+
161+ /* *
162+ * @brief Decay the occupied voxels in the map and the inflated map within a
163+ * local range
164+ * @param pos The center of the local point cloud
165+ * @param max_decay_range Maximum range of the local region to decay
166+ */
167+ void decayLocalCloud (const Eigen::Vector3d& pos, double max_decay_range);
168+
169+ /* *
170+ * @brief Free the voxel in which the provided point is located in as well as
171+ * the voxel's neighbors. Any voxel in the inflated map (be it a neighbor or
172+ * not) will not be freed if the corresponding voxel in the map is free.
173+ * @param pt Point in world units
174+ * @param ns Relative neighboring voxels
175+ */
141176 void freeVoxels (const Eigen::Vector3d& pt, const vec_Vec3i& ns);
142- // / Set corresponding voxels as free
177+
178+ /* *
179+ * @brief This method takes a point cloud and performs ray tracing with every
180+ * point to free the corresponding voxels if they are previously unknown. This
181+ * is performed both for the map and the inflated map.
182+ * @param pts Vector of points to perform ray tracing with
183+ * @param tf The pose of the frame that the points are relative to
184+ */
143185 void freeCloud (const vec_Vec3d& pts, const Eigen::Affine3d& tf);
144- // /// Decay the voxel value to unknown with growing time
145- // void decay();
146186
147187 private:
148- // / Initialize a space for the map
149- bool allocate (const Eigen::Vector3d& new_dim_d,
150- const Eigen::Vector3d& new_ori_d);
151- // / Raytrace from p1 to p2
152- vec_Vec3i rayTrace (const Eigen::Vector3d& pt1, const Eigen::Vector3d& pt2);
153- // / Convert the float point into the int coordinate
154- Eigen::Vector3i floatToInt (const Eigen::Vector3d& pt);
155- // / Convert the int coordinate into the float point
156- Eigen::Vector3d intToFloat (const Eigen::Vector3i& pn);
157- // / Check if the coordinate is outside or not
158- bool isOutSide (const Eigen::Vector3i& pn);
159-
160- // / Map dimension: number of voxels in each axis
161- Eigen::Vector3i dim_;
162- // / Map origin coordinate
163- Eigen::Vector3i origin_;
164- // / Map origin point
165- Eigen::Vector3d origin_d_;
166-
167- Eigen::Affine3d lidar_rot_;
168-
169- // / Map resolution
170- double res_;
171- // / Map object, it is a 3D array
172- boost::multi_array<int8_t , 3 > map_;
173- // / Inflated map object, it is a 3D array
174- boost::multi_array<int8_t , 3 > inflated_map_;
175-
176- planning_ros_msgs::VoxelMap voxel_map;
177-
178- // / Value free
179- // Now replaced with parameter value from VoxelMap.msg
180- int8_t val_free = voxel_map.val_free;
181- // / Value occupied
182- // Now replaced with parameter value from VoxelMap.msg
183- int8_t val_occ = voxel_map.val_occ;
184-
185- // / Value unknown
186- // Now replaced with parameter value from VoxelMap.msg
187- int8_t val_unknown = voxel_map.val_unknown;
188- // / Value even
189- // Now replaced with parameter value from VoxelMap.msg
190- int8_t val_even = voxel_map.val_even;
191- // / Value decay (voxels will disappear if unobserved for (val_occ - val_even)
192- // / / val_decay times)
193- int decay_times_to_empty;
194- int8_t val_decay;
195-
196- // be careful of overflow (should always be within -128 and 128 range)
197- // Add val_add to the voxel whenever a point lies in it.
198- // Now replaced with parameter value from VoxelMap.msg
199- int8_t val_add =
200- voxel_map.val_add; // should always be less than 27 to avoid overflow
201- // (should always be within -128 and 128 range)
202- // / Default map value
203- // Now replaced with parameter value from VoxelMap.msg
204- int8_t val_default = voxel_map.val_default;
188+ /* *
189+ * @brief Initialize a space for the map. If this method is called after
190+ * initialization, then it can rellocate the map and retain the value of any
191+ * overlapping voxels
192+ * @param new_dim_d New dimensions in world units
193+ * @param new_ori_d New origin in world units
194+ * @return Boolean value where true means that the reallocation occurred
195+ */
196+ bool allocate (const Eigen::Vector3d& new_ori_d,
197+ const Eigen::Vector3d& new_dim_d);
198+
199+ mapper::VoxelMap map_; // Map object
200+ mapper::VoxelMap inflated_map_; // Inflated map object
201+ Eigen::Vector3d origin_d_; // Origin for both maps,most negative corner
202+ Eigen::Vector3i dim_; // Number of voxels along each axis
203+ double res_; // Resolution used for both maps
204+
205+ // Possible voxel values taken from VoxelMap.msg
206+ int8_t val_free_ = planning_ros_msgs::VoxelMap::val_free;
207+ int8_t val_occ_ = planning_ros_msgs::VoxelMap::val_occ;
208+ int8_t val_unknown_ = planning_ros_msgs::VoxelMap::val_unknown;
209+ int8_t val_even_ = planning_ros_msgs::VoxelMap::val_even;
210+ int8_t val_default_ = planning_ros_msgs::VoxelMap::val_default;
211+
212+ // Be careful of overflow (should always be within -128 and 128 range)
213+ // Add val_add to the voxel whenever a point lies in it. Should always be less
214+ // than 27 to avoid overflow (should always be within -128 and 128 range)
215+ int8_t val_add_ = planning_ros_msgs::VoxelMap::val_add;
216+
217+ // Value decay (voxels will disappear if unobserved for
218+ // ((val_occ - val_even) / val_decay times)
219+ int8_t val_decay_;
205220};
206221
222+ inline void VoxelMapper::setMap (const Eigen::Vector3d &ori,
223+ const Eigen::Vector3i &dim,
224+ const std::vector<signed char > &map,
225+ double res) {
226+ map_.setMap (ori, dim, map, res);
227+ }
228+
229+ inline void VoxelMapper::setInflatedMap (const Eigen::Vector3d &ori,
230+ const Eigen::Vector3i &dim,
231+ const std::vector<signed char > &map,
232+ double res) {
233+ inflated_map_.setMap (ori, dim, map, res);
234+ }
235+
207236} // namespace mapper
0 commit comments