Skip to content

Commit 37fb6a8

Browse files
committed
add voxel search patterns
1 parent b1d84b0 commit 37fb6a8

File tree

1 file changed

+68
-21
lines changed

1 file changed

+68
-21
lines changed

include/small_gicp/ann/incremental_voxelmap.hpp

+68-21
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ struct IncrementalVoxelMap {
4141

4242
/// @brief Constructor.
4343
/// @param leaf_size Voxel size
44-
explicit IncrementalVoxelMap(double leaf_size) : inv_leaf_size(1.0 / leaf_size), lru_horizon(100), lru_clear_cycle(10), lru_counter(0) {}
44+
explicit IncrementalVoxelMap(double leaf_size) : inv_leaf_size(1.0 / leaf_size), lru_horizon(100), lru_clear_cycle(10), lru_counter(0) { set_search_offsets(1); }
4545

4646
/// @brief Number of points in the voxelmap.
4747
size_t size() const { return flat_voxels.size(); }
@@ -95,18 +95,24 @@ struct IncrementalVoxelMap {
9595
/// @param sq_dist Squared distance to the nearest neighbor
9696
/// @return Number of found points (0 or 1)
9797
size_t nearest_neighbor_search(const Eigen::Vector4d& pt, size_t* index, double* sq_dist) const {
98-
const Eigen::Vector3i coord = fast_floor(pt * inv_leaf_size).template head<3>();
99-
const auto found = voxels.find(coord);
100-
if (found == voxels.end()) {
101-
return 0;
102-
}
98+
const Eigen::Vector3i center = fast_floor(pt * inv_leaf_size).template head<3>();
99+
size_t voxel_index = 0;
100+
const auto index_transform = [&](size_t i) { return calc_index(voxel_index, i); };
101+
KnnResult<1, decltype(index_transform)> result(index, sq_dist, -1, index_transform);
102+
103+
for (const auto& offset : search_offsets) {
104+
const Eigen::Vector3i coord = center + offset;
105+
const auto found = voxels.find(coord);
106+
if (found == voxels.end()) {
107+
continue;
108+
}
103109

104-
const size_t voxel_index = found->second;
105-
const auto& voxel = flat_voxels[voxel_index]->second;
110+
voxel_index = found->second;
111+
const auto& voxel = flat_voxels[voxel_index]->second;
112+
113+
traits::Traits<VoxelContents>::knn_search(voxel, pt, result);
114+
}
106115

107-
const auto index_transform = [=](size_t i) { return calc_index(voxel_index, i); };
108-
KnnResult<1, decltype(index_transform)> result(index, sq_dist, -1, index_transform);
109-
traits::Traits<VoxelContents>::knn_search(voxel, pt, result);
110116
return result.num_found();
111117
}
112118

@@ -117,18 +123,25 @@ struct IncrementalVoxelMap {
117123
/// @param k_sq_dists Squared distances to nearest neighbors
118124
/// @return Number of found points
119125
size_t knn_search(const Eigen::Vector4d& pt, size_t k, size_t* k_indices, double* k_sq_dists) const {
120-
const Eigen::Vector3i coord = fast_floor(pt * inv_leaf_size).template head<3>();
121-
const auto found = voxels.find(coord);
122-
if (found == voxels.end()) {
123-
return 0;
124-
}
126+
const Eigen::Vector3i center = fast_floor(pt * inv_leaf_size).template head<3>();
125127

126-
const size_t voxel_index = found->second;
127-
const auto& voxel = flat_voxels[voxel_index]->second;
128-
129-
const auto index_transform = [=](size_t i) { return calc_index(voxel_index, i); };
128+
size_t voxel_index = 0;
129+
const auto index_transform = [&](size_t i) { return calc_index(voxel_index, i); };
130130
KnnResult<-1, decltype(index_transform)> result(k_indices, k_sq_dists, k, index_transform);
131-
traits::Traits<VoxelContents>::knn_search(voxel, pt, result);
131+
132+
for (const auto& offset : search_offsets) {
133+
const Eigen::Vector3i coord = center + offset;
134+
const auto found = voxels.find(coord);
135+
if (found == voxels.end()) {
136+
continue;
137+
}
138+
139+
voxel_index = found->second;
140+
const auto& voxel = flat_voxels[voxel_index]->second;
141+
142+
traits::Traits<VoxelContents>::knn_search(voxel, pt, result);
143+
}
144+
132145
return result.num_found();
133146
}
134147

@@ -137,6 +150,38 @@ struct IncrementalVoxelMap {
137150
inline size_t voxel_id(const size_t i) const { return i >> point_id_bits; } ///< Extract the point ID from a global index.
138151
inline size_t point_id(const size_t i) const { return i & ((1ull << point_id_bits) - 1); } ///< Extract the voxel ID from a global index.
139152

153+
/// @brief Set the pattern of the search offsets. (Must be 1, 7, or 27)
154+
void set_search_offsets(int num_offsets) {
155+
switch (num_offsets) {
156+
default:
157+
std::cerr << "warning: unsupported search_offsets=" << num_offsets << " (supported values: 1, 7, 27)" << std::endl;
158+
std::cerr << " : using default search_offsets=1" << std::endl;
159+
[[fallthrough]];
160+
case 1:
161+
search_offsets = {Eigen::Vector3i(0, 0, 0)};
162+
break;
163+
case 7:
164+
search_offsets = {
165+
Eigen::Vector3i(0, 0, 0),
166+
Eigen::Vector3i(1, 0, 0),
167+
Eigen::Vector3i(0, 1, 0),
168+
Eigen::Vector3i(0, 0, 1),
169+
Eigen::Vector3i(-1, 0, 0),
170+
Eigen::Vector3i(0, -1, 0),
171+
Eigen::Vector3i(0, 0, -1)};
172+
break;
173+
case 27:
174+
for (int i = -1; i <= 1; i++) {
175+
for (int j = -1; j <= 1; j++) {
176+
for (int k = -1; k <= 1; k++) {
177+
search_offsets.emplace_back(i, j, k);
178+
}
179+
}
180+
}
181+
break;
182+
}
183+
}
184+
140185
public:
141186
static_assert(sizeof(size_t) == 8, "size_t must be 64-bit");
142187
static constexpr int point_id_bits = 32; ///< Use the first 32 bits for point id
@@ -147,6 +192,8 @@ struct IncrementalVoxelMap {
147192
size_t lru_clear_cycle; ///< LRU clear cycle. Voxel deletion is performed every lru_clear_cycle steps.
148193
size_t lru_counter; ///< LRU counter. Incremented every step.
149194

195+
std::vector<Eigen::Vector3i> search_offsets; ///< Voxel search offsets.
196+
150197
typename VoxelContents::Setting voxel_setting; ///< Voxel setting.
151198
std::vector<std::shared_ptr<std::pair<VoxelInfo, VoxelContents>>> flat_voxels; ///< Voxel contents.
152199
std::unordered_map<Eigen::Vector3i, size_t, XORVector3iHash> voxels; ///< Voxel index map.

0 commit comments

Comments
 (0)