raycast_using_kdtree.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020, the mcl_3dl authors
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of the copyright holder nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #ifndef MCL_3DL_RAYCASTS_RAYCAST_USING_KDTREE_H
31 #define MCL_3DL_RAYCASTS_RAYCAST_USING_KDTREE_H
32 
33 #include <algorithm>
34 #include <cmath>
35 #include <vector>
36 
37 #include <mcl_3dl/chunked_kdtree.h>
38 #include <mcl_3dl/raycast.h>
39 #include <mcl_3dl/vec3.h>
40 
41 namespace mcl_3dl
42 {
43 template <typename POINT_TYPE>
44 class RaycastUsingKDTree : public Raycast<POINT_TYPE>
45 {
46  using typename Raycast<POINT_TYPE>::CastResult;
47 
48 public:
49  RaycastUsingKDTree(const float map_grid_size_x, const float map_grid_size_y, const float map_grid_size_z,
50  const float hit_tolerance)
51  : Raycast<POINT_TYPE>()
52  // FIXME(at-wat): remove NOLINT after clang-format or roslint supports it
53  , map_grid_min_(std::min({ map_grid_size_x, map_grid_size_y, map_grid_size_z })) // NOLINT(whitespace/braces)
54  , map_grid_max_(std::max({ map_grid_size_x, map_grid_size_y, map_grid_size_z })) // NOLINT(whitespace/braces)
55  , hit_tolerance_(hit_tolerance)
56  {
57  }
58 
59  void setRay(typename ChunkedKdtree<POINT_TYPE>::Ptr kdtree, const Vec3 ray_begin, const Vec3 ray_end) final
60  {
61  kdtree_ = kdtree;
62  length_ = std::floor(((ray_end - ray_begin).norm() + hit_tolerance_) / map_grid_min_);
63  inc_ = (ray_end - ray_begin).normalized() * map_grid_min_;
64  count_ = 1;
65  pos_ = ray_begin + inc_;
66  }
67 
68  bool getNextCastResult(CastResult& result) final
69  {
70  if (count_ >= length_)
71  {
72  return false;
73  }
74  bool collision(false);
75  float sin_ang(0.0);
76 
77  const POINT_TYPE* point = nullptr;
78  POINT_TYPE center;
79  center.x = pos_.x_;
80  center.y = pos_.y_;
81  center.z = pos_.z_;
82  std::vector<int> id(1);
83  std::vector<float> sqdist(1);
84  if (kdtree_->radiusSearch(center, std::sqrt(2.0) * map_grid_max_ / 2.0, id, sqdist, 1))
85  {
86  collision = true;
87  point = &(kdtree_->getInputCloud()->points[id[0]]);
88 
89  const float d0 = std::sqrt(sqdist[0]);
90  const Vec3 pos_prev = pos_ - (inc_ * 2.0);
91  POINT_TYPE center_prev;
92  center_prev.x = pos_prev.x_;
93  center_prev.y = pos_prev.y_;
94  center_prev.z = pos_prev.z_;
95  if (kdtree_->radiusSearch(center_prev, map_grid_min_ * 2 + std::sqrt(2.0) * map_grid_max_ / 2.0, id, sqdist, 1))
96  {
97  const float d1 = std::sqrt(sqdist[0]);
98  sin_ang = fabs(d1 - d0) / (map_grid_min_ * 2.0);
99  }
100  else
101  {
102  sin_ang = 1.0;
103  }
104  }
105  result = CastResult(pos_, collision, sin_ang, point);
106 
107  ++count_;
108  pos_ += inc_;
109  return true;
110  }
111 
112 private:
116  int length_;
117  int count_;
118  const float map_grid_min_;
119  const float map_grid_max_;
120  const float hit_tolerance_;
121 };
122 
123 } // namespace mcl_3dl
124 
125 #endif // MCL_3DL_RAYCASTS_RAYCAST_USING_KDTREE_H
float z_
Definition: vec3.h:42
RaycastUsingKDTree(const float map_grid_size_x, const float map_grid_size_y, const float map_grid_size_z, const float hit_tolerance)
std::shared_ptr< ChunkedKdtree > Ptr
ChunkedKdtree< POINT_TYPE >::Ptr kdtree_
void setRay(typename ChunkedKdtree< POINT_TYPE >::Ptr kdtree, const Vec3 ray_begin, const Vec3 ray_end) final
TFSIMD_FORCE_INLINE Vector3 normalized() const
bool getNextCastResult(CastResult &result) final
float y_
Definition: vec3.h:41
double min(double a, double b)
float x_
Definition: vec3.h:40


mcl_3dl
Author(s): Atsushi Watanabe
autogenerated on Wed May 12 2021 02:16:29