37 #ifndef NAV2_VOXEL_GRID__VOXEL_GRID_HPP_
38 #define NAV2_VOXEL_GRID__VOXEL_GRID_HPP_
47 #include "rclcpp/rclcpp.hpp"
55 namespace nav2_voxel_grid
74 VoxelGrid(
unsigned int size_x,
unsigned int size_y,
unsigned int size_z);
84 void resize(
unsigned int size_x,
unsigned int size_y,
unsigned int size_z);
87 uint32_t * getData() {
return data_;}
89 inline void markVoxel(
unsigned int x,
unsigned int y,
unsigned int z)
91 if (x >= size_x_ || y >= size_y_ || z >= size_z_) {
92 RCLCPP_DEBUG(logger,
"Error, voxel out of bounds.\n");
95 uint32_t full_mask = ((uint32_t)1 << z << 16) | (1 << z);
96 data_[y * size_x_ + x] |= full_mask;
99 inline bool markVoxelInMap(
100 unsigned int x,
unsigned int y,
unsigned int z,
101 unsigned int marked_threshold)
103 if (x >= size_x_ || y >= size_y_ || z >= size_z_) {
104 RCLCPP_DEBUG(logger,
"Error, voxel out of bounds.\n");
108 int index = y * size_x_ + x;
109 uint32_t * col = &data_[index];
110 uint32_t full_mask = ((uint32_t)1 << z << 16) | (1 << z);
113 unsigned int marked_bits = *col >> 16;
116 return !bitsBelowThreshold(marked_bits, marked_threshold);
119 inline void clearVoxel(
unsigned int x,
unsigned int y,
unsigned int z)
121 if (x >= size_x_ || y >= size_y_ || z >= size_z_) {
122 RCLCPP_DEBUG(logger,
"Error, voxel out of bounds.\n");
125 uint32_t full_mask = ((uint32_t)1 << z << 16) | (1 << z);
126 data_[y * size_x_ + x] &= ~(full_mask);
129 inline void clearVoxelColumn(
unsigned int index)
131 assert(index < size_x_ * size_y_);
135 inline void clearVoxelInMap(
unsigned int x,
unsigned int y,
unsigned int z)
137 if (x >= size_x_ || y >= size_y_ || z >= size_z_) {
138 RCLCPP_DEBUG(logger,
"Error, voxel out of bounds.\n");
141 int index = y * size_x_ + x;
142 uint32_t * col = &data_[index];
143 uint32_t full_mask = ((uint32_t)1 << z << 16) | (1 << z);
144 *col &= ~(full_mask);
146 unsigned int unknown_bits = uint16_t(*col >> 16) ^ uint16_t(*col);
147 unsigned int marked_bits = *col >> 16;
150 if (bitsBelowThreshold(unknown_bits, 1) && bitsBelowThreshold(marked_bits, 1)) {
155 inline bool bitsBelowThreshold(
unsigned int n,
unsigned int bit_threshold)
157 unsigned int bit_count;
158 for (bit_count = 0; n; ) {
160 if (bit_count > bit_threshold) {
168 static inline unsigned int numBits(
unsigned int n)
170 unsigned int bit_count;
171 for (bit_count = 0; n; ++bit_count) {
177 static VoxelStatus getVoxel(
178 unsigned int x,
unsigned int y,
unsigned int z,
179 unsigned int size_x,
unsigned int size_y,
unsigned int size_z,
const uint32_t * data)
181 if (x >= size_x || y >= size_y || z >= size_z) {
184 uint32_t full_mask = ((uint32_t)1 << z << 16) | (1 << z);
185 uint32_t result = data[y * size_x + x] & full_mask;
186 unsigned int bits = numBits(result);
199 double x0,
double y0,
double z0,
double x1,
double y1,
double z1,
200 unsigned int max_length = UINT_MAX);
202 double x0,
double y0,
double z0,
double x1,
double y1,
double z1,
203 unsigned int max_length = UINT_MAX,
unsigned int min_length = 0);
204 void clearVoxelLineInMap(
205 double x0,
double y0,
double z0,
double x1,
double y1,
double z1,
unsigned char * map_2d,
206 unsigned int unknown_threshold,
unsigned int mark_threshold,
207 unsigned char free_cost = 0,
unsigned char unknown_cost = 255,
208 unsigned int max_length = UINT_MAX,
unsigned int min_length = 0);
210 VoxelStatus getVoxel(
unsigned int x,
unsigned int y,
unsigned int z);
213 VoxelStatus getVoxelColumn(
214 unsigned int x,
unsigned int y,
215 unsigned int unknown_threshold = 0,
unsigned int marked_threshold = 0);
217 void printVoxelGrid();
218 void printColumnGrid();
219 unsigned int sizeX();
220 unsigned int sizeY();
221 unsigned int sizeZ();
223 template<
class ActionType>
224 inline void raytraceLine(
225 ActionType at,
double x0,
double y0,
double z0,
226 double x1,
double y1,
double z1,
unsigned int max_length = UINT_MAX,
227 unsigned int min_length = 0)
231 double dist = sqrt((x0 - x1) * (x0 - x1) + (y0 - y1) * (y0 - y1) + (z0 - z1) * (z0 - z1));
232 if ((
unsigned int)(dist) < min_length) {
235 double scale, min_x0, min_y0, min_z0;
237 scale = std::min(1.0, max_length / dist);
240 min_x0 = x0 + (x1 - x0) / dist * min_length;
241 min_y0 = y0 + (y1 - y0) / dist * min_length;
242 min_z0 = z0 + (z1 - z0) / dist * min_length;
252 int dx = int(x1) - int(min_x0);
253 int dy = int(y1) - int(min_y0);
254 int dz = int(z1) - int(min_z0);
256 unsigned int abs_dx = abs(dx);
257 unsigned int abs_dy = abs(dy);
258 unsigned int abs_dz = abs(dz);
260 int offset_dx = sign(dx);
261 int offset_dy = sign(dy) * size_x_;
262 int offset_dz = sign(dz);
264 unsigned int z_mask = ((1 << 16) | 1) << (
unsigned int)min_z0;
265 unsigned int offset = (
unsigned int)min_y0 * size_x_ + (
unsigned int)min_x0;
267 GridOffset grid_off(offset);
268 ZOffset z_off(z_mask);
271 if (abs_dx >= max(abs_dy, abs_dz)) {
272 int error_y = abs_dx / 2;
273 int error_z = abs_dx / 2;
276 at, grid_off, grid_off, z_off, abs_dx, abs_dy, abs_dz, error_y, error_z,
277 offset_dx, offset_dy, offset_dz, offset, z_mask, (
unsigned int)(scale * abs_dx));
282 if (abs_dy >= abs_dz) {
283 int error_x = abs_dy / 2;
284 int error_z = abs_dy / 2;
287 at, grid_off, grid_off, z_off, abs_dy, abs_dx, abs_dz, error_x, error_z,
288 offset_dy, offset_dx, offset_dz, offset, z_mask, (
unsigned int)(scale * abs_dy));
293 int error_x = abs_dz / 2;
294 int error_y = abs_dz / 2;
297 at, z_off, grid_off, grid_off, abs_dz, abs_dx, abs_dy, error_x, error_y, offset_dz,
298 offset_dx, offset_dy, offset, z_mask, (
unsigned int)(scale * abs_dz));
303 template<
class ActionType,
class OffA,
class OffB,
class OffC>
304 inline void bresenham3D(
305 ActionType at, OffA off_a, OffB off_b, OffC off_c,
306 unsigned int abs_da,
unsigned int abs_db,
unsigned int abs_dc,
307 int error_b,
int error_c,
int offset_a,
int offset_b,
int offset_c,
unsigned int & offset,
308 unsigned int & z_mask,
unsigned int max_length = UINT_MAX)
310 unsigned int end = std::min(max_length, abs_da);
311 for (
unsigned int i = 0; i < end; ++i) {
316 if ((
unsigned int)error_b >= abs_da) {
320 if ((
unsigned int)error_c >= abs_da) {
328 inline int sign(
int i)
330 return i > 0 ? 1 : -1;
333 inline unsigned int max(
unsigned int x,
unsigned int y)
335 return x > y ? x : y;
338 unsigned int size_x_, size_y_, size_z_;
340 unsigned char * costmap;
341 rclcpp::Logger logger;
348 explicit MarkVoxel(uint32_t * data)
350 inline void operator()(
unsigned int offset,
unsigned int z_mask)
352 data_[offset] |= z_mask;
362 explicit ClearVoxel(uint32_t * data)
364 inline void operator()(
unsigned int offset,
unsigned int z_mask)
366 data_[offset] &= ~(z_mask);
373 class ClearVoxelInMap
377 uint32_t * data,
unsigned char * costmap,
378 unsigned int unknown_clear_threshold,
unsigned int marked_clear_threshold,
379 unsigned char free_cost = 0,
unsigned char unknown_cost = 255)
380 : data_(data), costmap_(costmap),
381 unknown_clear_threshold_(unknown_clear_threshold), marked_clear_threshold_(
382 marked_clear_threshold),
383 free_cost_(free_cost), unknown_cost_(unknown_cost)
387 inline void operator()(
unsigned int offset,
unsigned int z_mask)
389 uint32_t * col = &data_[offset];
392 unsigned int unknown_bits = uint16_t(*col >> 16) ^ uint16_t(*col);
393 unsigned int marked_bits = *col >> 16;
396 if (bitsBelowThreshold(marked_bits, marked_clear_threshold_)) {
397 if (bitsBelowThreshold(unknown_bits, unknown_clear_threshold_)) {
398 costmap_[offset] = free_cost_;
400 costmap_[offset] = unknown_cost_;
406 inline bool bitsBelowThreshold(
unsigned int n,
unsigned int bit_threshold)
408 unsigned int bit_count;
409 for (bit_count = 0; n; ) {
411 if (bit_count > bit_threshold) {
420 unsigned char * costmap_;
421 unsigned int unknown_clear_threshold_, marked_clear_threshold_;
422 unsigned char free_cost_, unknown_cost_;
428 explicit GridOffset(
unsigned int & offset)
430 inline void operator()(
int offset_val)
432 offset_ += offset_val;
436 unsigned int & offset_;
442 explicit ZOffset(
unsigned int & z_mask)
444 inline void operator()(
int offset_val)
446 offset_val > 0 ? z_mask_ <<= 1 : z_mask_ >>= 1;
450 unsigned int & z_mask_;
void resize(unsigned int size_x, unsigned int size_y, unsigned int size_z)
Resizes a voxel grid to the desired size.
VoxelGrid(unsigned int size_x, unsigned int size_y, unsigned int size_z)
Constructor for a voxel grid.