37 #ifndef NAV2_VOXEL_GRID__VOXEL_GRID_HPP_
38 #define NAV2_VOXEL_GRID__VOXEL_GRID_HPP_
48 #include <rclcpp/logger.hpp>
49 #include <rclcpp/logging.hpp>
57 namespace nav2_voxel_grid
76 VoxelGrid(
unsigned int size_x,
unsigned int size_y,
unsigned int size_z);
86 void resize(
unsigned int size_x,
unsigned int size_y,
unsigned int size_z);
89 uint32_t * getData() {
return data_;}
91 inline void markVoxel(
unsigned int x,
unsigned int y,
unsigned int z)
93 if (x >= size_x_ || y >= size_y_ || z >= size_z_) {
94 RCLCPP_DEBUG(logger,
"Error, voxel out of bounds.\n");
97 uint32_t full_mask = ((uint32_t)1 << z << 16) | (1 << z);
98 data_[y * size_x_ + x] |= full_mask;
101 inline bool markVoxelInMap(
102 unsigned int x,
unsigned int y,
unsigned int z,
103 unsigned int marked_threshold)
105 if (x >= size_x_ || y >= size_y_ || z >= size_z_) {
106 RCLCPP_DEBUG(logger,
"Error, voxel out of bounds.\n");
110 int index = y * size_x_ + x;
111 uint32_t * col = &data_[index];
112 uint32_t full_mask = ((uint32_t)1 << z << 16) | (1 << z);
115 unsigned int marked_bits = *col >> 16;
118 return !bitsBelowThreshold(marked_bits, marked_threshold);
121 inline void clearVoxel(
unsigned int x,
unsigned int y,
unsigned int z)
123 if (x >= size_x_ || y >= size_y_ || z >= size_z_) {
124 RCLCPP_DEBUG(logger,
"Error, voxel out of bounds.\n");
127 uint32_t full_mask = ((uint32_t)1 << z << 16) | (1 << z);
128 data_[y * size_x_ + x] &= ~(full_mask);
131 inline void clearVoxelColumn(
unsigned int index)
133 assert(index < size_x_ * size_y_);
137 inline void clearVoxelInMap(
unsigned int x,
unsigned int y,
unsigned int z)
139 if (x >= size_x_ || y >= size_y_ || z >= size_z_) {
140 RCLCPP_DEBUG(logger,
"Error, voxel out of bounds.\n");
143 int index = y * size_x_ + x;
144 uint32_t * col = &data_[index];
145 uint32_t full_mask = ((uint32_t)1 << z << 16) | (1 << z);
146 *col &= ~(full_mask);
148 unsigned int unknown_bits = uint16_t(*col >> 16) ^ uint16_t(*col);
149 unsigned int marked_bits = *col >> 16;
152 if (bitsBelowThreshold(unknown_bits, 1) && bitsBelowThreshold(marked_bits, 1)) {
157 inline bool bitsBelowThreshold(
unsigned int n,
unsigned int bit_threshold)
159 unsigned int bit_count;
160 for (bit_count = 0; n; ) {
162 if (bit_count > bit_threshold) {
170 static inline unsigned int numBits(
unsigned int n)
172 unsigned int bit_count;
173 for (bit_count = 0; n; ++bit_count) {
179 static VoxelStatus getVoxel(
180 unsigned int x,
unsigned int y,
unsigned int z,
181 unsigned int size_x,
unsigned int size_y,
unsigned int size_z,
const uint32_t * data)
183 if (x >= size_x || y >= size_y || z >= size_z) {
186 uint32_t full_mask = ((uint32_t)1 << z << 16) | (1 << z);
187 uint32_t result = data[y * size_x + x] & full_mask;
188 unsigned int bits = numBits(result);
201 double x0,
double y0,
double z0,
double x1,
double y1,
double z1,
202 unsigned int max_length = UINT_MAX);
204 double x0,
double y0,
double z0,
double x1,
double y1,
double z1,
205 unsigned int max_length = UINT_MAX,
unsigned int min_length = 0);
206 void clearVoxelLineInMap(
207 double x0,
double y0,
double z0,
double x1,
double y1,
double z1,
unsigned char * map_2d,
208 unsigned int unknown_threshold,
unsigned int mark_threshold,
209 unsigned char free_cost = 0,
unsigned char unknown_cost = 255,
210 unsigned int max_length = UINT_MAX,
unsigned int min_length = 0);
212 VoxelStatus getVoxel(
unsigned int x,
unsigned int y,
unsigned int z);
215 VoxelStatus getVoxelColumn(
216 unsigned int x,
unsigned int y,
217 unsigned int unknown_threshold = 0,
unsigned int marked_threshold = 0);
219 void printVoxelGrid();
220 void printColumnGrid();
221 unsigned int sizeX();
222 unsigned int sizeY();
223 unsigned int sizeZ();
225 template<
class ActionType>
226 inline void raytraceLine(
227 ActionType at,
double x0,
double y0,
double z0,
228 double x1,
double y1,
double z1,
unsigned int max_length = UINT_MAX,
229 unsigned int min_length = 0)
233 double dist = sqrt((x0 - x1) * (x0 - x1) + (y0 - y1) * (y0 - y1) + (z0 - z1) * (z0 - z1));
234 if ((
unsigned int)(dist) < min_length) {
237 double scale, min_x0, min_y0, min_z0;
239 scale = std::min(1.0, max_length / dist);
242 min_x0 = x0 + (x1 - x0) / dist * min_length;
243 min_y0 = y0 + (y1 - y0) / dist * min_length;
244 min_z0 = z0 + (z1 - z0) / dist * min_length;
254 int dx = int(x1) - int(min_x0);
255 int dy = int(y1) - int(min_y0);
256 int dz = int(z1) - int(min_z0);
258 unsigned int abs_dx = abs(dx);
259 unsigned int abs_dy = abs(dy);
260 unsigned int abs_dz = abs(dz);
262 int offset_dx = sign(dx);
263 int offset_dy = sign(dy) * size_x_;
264 int offset_dz = sign(dz);
266 unsigned int z_mask = ((1 << 16) | 1) << (
unsigned int)min_z0;
267 unsigned int offset = (
unsigned int)min_y0 * size_x_ + (
unsigned int)min_x0;
269 GridOffset grid_off(offset);
270 ZOffset z_off(z_mask);
273 if (abs_dx >= max(abs_dy, abs_dz)) {
274 int error_y = abs_dx / 2;
275 int error_z = abs_dx / 2;
278 at, grid_off, grid_off, z_off, abs_dx, abs_dy, abs_dz, error_y, error_z,
279 offset_dx, offset_dy, offset_dz, offset, z_mask, (
unsigned int)(scale * abs_dx));
284 if (abs_dy >= abs_dz) {
285 int error_x = abs_dy / 2;
286 int error_z = abs_dy / 2;
289 at, grid_off, grid_off, z_off, abs_dy, abs_dx, abs_dz, error_x, error_z,
290 offset_dy, offset_dx, offset_dz, offset, z_mask, (
unsigned int)(scale * abs_dy));
295 int error_x = abs_dz / 2;
296 int error_y = abs_dz / 2;
299 at, z_off, grid_off, grid_off, abs_dz, abs_dx, abs_dy, error_x, error_y, offset_dz,
300 offset_dx, offset_dy, offset, z_mask, (
unsigned int)(scale * abs_dz));
305 template<
class ActionType,
class OffA,
class OffB,
class OffC>
306 inline void bresenham3D(
307 ActionType at, OffA off_a, OffB off_b, OffC off_c,
308 unsigned int abs_da,
unsigned int abs_db,
unsigned int abs_dc,
309 int error_b,
int error_c,
int offset_a,
int offset_b,
int offset_c,
unsigned int & offset,
310 unsigned int & z_mask,
unsigned int max_length = UINT_MAX)
312 unsigned int end = std::min(max_length, abs_da);
313 for (
unsigned int i = 0; i < end; ++i) {
318 if ((
unsigned int)error_b >= abs_da) {
322 if ((
unsigned int)error_c >= abs_da) {
330 inline int sign(
int i)
332 return i > 0 ? 1 : -1;
335 inline unsigned int max(
unsigned int x,
unsigned int y)
337 return x > y ? x : y;
340 unsigned int size_x_, size_y_, size_z_;
342 unsigned char * costmap;
343 rclcpp::Logger logger;
350 explicit MarkVoxel(uint32_t * data)
352 inline void operator()(
unsigned int offset,
unsigned int z_mask)
354 data_[offset] |= z_mask;
364 explicit ClearVoxel(uint32_t * data)
366 inline void operator()(
unsigned int offset,
unsigned int z_mask)
368 data_[offset] &= ~(z_mask);
375 class ClearVoxelInMap
379 uint32_t * data,
unsigned char * costmap,
380 unsigned int unknown_clear_threshold,
unsigned int marked_clear_threshold,
381 unsigned char free_cost = 0,
unsigned char unknown_cost = 255)
382 : data_(data), costmap_(costmap),
383 unknown_clear_threshold_(unknown_clear_threshold), marked_clear_threshold_(
384 marked_clear_threshold),
385 free_cost_(free_cost), unknown_cost_(unknown_cost)
389 inline void operator()(
unsigned int offset,
unsigned int z_mask)
391 uint32_t * col = &data_[offset];
394 unsigned int unknown_bits = uint16_t(*col >> 16) ^ uint16_t(*col);
395 unsigned int marked_bits = *col >> 16;
398 if (bitsBelowThreshold(marked_bits, marked_clear_threshold_)) {
399 if (bitsBelowThreshold(unknown_bits, unknown_clear_threshold_)) {
400 costmap_[offset] = free_cost_;
402 costmap_[offset] = unknown_cost_;
408 inline bool bitsBelowThreshold(
unsigned int n,
unsigned int bit_threshold)
410 unsigned int bit_count;
411 for (bit_count = 0; n; ) {
413 if (bit_count > bit_threshold) {
422 unsigned char * costmap_;
423 unsigned int unknown_clear_threshold_, marked_clear_threshold_;
424 unsigned char free_cost_, unknown_cost_;
430 explicit GridOffset(
unsigned int & offset)
432 inline void operator()(
int offset_val)
434 offset_ += offset_val;
438 unsigned int & offset_;
444 explicit ZOffset(
unsigned int & z_mask)
446 inline void operator()(
int offset_val)
448 offset_val > 0 ? z_mask_ <<= 1 : z_mask_ >>= 1;
452 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.