| 496 | } |
| 497 | |
| 498 | void OctomapServer::insertScan( |
| 499 | const tf2::Vector3 & sensor_origin_tf, const PCLPointCloud & ground, |
| 500 | const PCLPointCloud & nonground) |
| 501 | { |
| 502 | const auto sensor_origin = octomap::pointTfToOctomap(sensor_origin_tf); |
| 503 | |
| 504 | if (!octree_->coordToKeyChecked(sensor_origin, update_bbox_min_) || |
| 505 | !octree_->coordToKeyChecked(sensor_origin, update_bbox_max_)) |
| 506 | { |
| 507 | RCLCPP_ERROR_STREAM(get_logger(), "Could not generate Key for origin " << sensor_origin); |
| 508 | } |
| 509 | |
| 510 | // instead of direct scan insertion, compute update to filter ground: |
| 511 | octomap::KeySet free_cells, occupied_cells; |
| 512 | // insert ground points only as free: |
| 513 | for (PCLPointCloud::const_iterator it = ground.begin(); it != ground.end(); ++it) { |
| 514 | octomap::point3d point(it->x, it->y, it->z); |
| 515 | // maxrange check |
| 516 | if ((max_range_ > 0.0) && ((point - sensor_origin).norm() > max_range_) ) { |
| 517 | point = sensor_origin + (point - sensor_origin).normalized() * max_range_; |
| 518 | } |
| 519 | |
| 520 | // only clear space (ground points) |
| 521 | if (octree_->computeRayKeys(sensor_origin, point, key_ray_)) { |
| 522 | free_cells.insert(key_ray_.begin(), key_ray_.end()); |
| 523 | } |
| 524 | |
| 525 | octomap::OcTreeKey end_key; |
| 526 | if (octree_->coordToKeyChecked(point, end_key)) { |
| 527 | updateMinKey(end_key, update_bbox_min_); |
| 528 | updateMaxKey(end_key, update_bbox_max_); |
| 529 | } else { |
| 530 | RCLCPP_ERROR_STREAM(get_logger(), "Could not generate Key for endpoint " << point); |
| 531 | } |
| 532 | } |
| 533 | |
| 534 | // all other points: free on ray, occupied on endpoint: |
| 535 | for (PCLPointCloud::const_iterator it = nonground.begin(); it != nonground.end(); ++it) { |
| 536 | octomap::point3d point(it->x, it->y, it->z); |
| 537 | // maxrange check |
| 538 | if ((max_range_ < 0.0) || ((point - sensor_origin).norm() <= max_range_) ) { |
| 539 | // free cells |
| 540 | if (octree_->computeRayKeys(sensor_origin, point, key_ray_)) { |
| 541 | free_cells.insert(key_ray_.begin(), key_ray_.end()); |
| 542 | } |
| 543 | // occupied endpoint |
| 544 | octomap::OcTreeKey key; |
| 545 | if (octree_->coordToKeyChecked(point, key)) { |
| 546 | occupied_cells.insert(key); |
| 547 | |
| 548 | updateMinKey(key, update_bbox_min_); |
| 549 | updateMaxKey(key, update_bbox_max_); |
| 550 | |
| 551 | #ifdef COLOR_OCTOMAP_SERVER // NB: Only read and interpret color if it's an occupied node |
| 552 | octree_->averageNodeColor(it->x, it->y, it->z, /*r=*/ it->r, /*g=*/ it->g, /*b=*/ it->b); |
| 553 | #endif |
| 554 | } |
| 555 | } else { // ray longer than maxrange |
nothing calls this directly
no outgoing calls
no test coverage detected