motion_cache.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018-2019, the neonavigation 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 #include <algorithm>
31 #include <cmath>
32 #include <unordered_map>
33 #include <vector>
34 
37 
38 namespace planner_cspace
39 {
40 namespace planner_3d
41 {
43  const float linear_resolution,
44  const float angular_resolution,
45  const int range,
46  const std::function<void(CyclicVecInt<3, 2>, size_t&, size_t&)> gm_addr)
47 {
48  const int angle = std::lround(M_PI * 2 / angular_resolution);
49 
50  CyclicVecInt<3, 2> max_range(0, 0, 0);
51  page_size_ = angle;
52  cache_.resize(angle);
53  for (int syaw = 0; syaw < angle; syaw++)
54  {
55  const float yaw = syaw * angular_resolution;
57  for (d[0] = -range; d[0] <= range; d[0]++)
58  {
59  for (d[1] = -range; d[1] <= range; d[1]++)
60  {
61  if (d[0] == 0 && d[1] == 0)
62  continue;
63  if (d.sqlen() > range * range)
64  continue;
65  for (d[2] = 0; d[2] < angle; d[2]++)
66  {
67  Page page;
68  const float yaw_e = d[2] * angular_resolution;
69  const float diff_val[3] =
70  {
71  d[0] * linear_resolution,
72  d[1] * linear_resolution,
73  d[2] * angular_resolution
74  };
75  std::unordered_map<CyclicVecInt<3, 2>, bool, CyclicVecInt<3, 2>> registered;
76  registered[d] = true;
77 
78  CyclicVecFloat<3, 2> motion(diff_val[0], diff_val[1], diff_val[2]);
79  motion.rotate(-syaw * angular_resolution);
80  const float cos_v = cosf(motion[2]);
81  const float sin_v = sinf(motion[2]);
82 
83  const float inter = 1.0 / d.len();
84 
85  if (std::abs(sin_v) < 0.1)
86  {
87  for (float i = 0; i < 1.0; i += inter)
88  {
89  const float x = diff_val[0] * i;
90  const float y = diff_val[1] * i;
91 
93  x / linear_resolution, y / linear_resolution, yaw / angular_resolution);
94  pos.cycleUnsigned(angle);
95  if (registered.find(pos) == registered.end())
96  {
97  page.motion_.push_back(pos);
98  for (int i = 0; i < 3; ++i)
99  max_range[i] = std::max(max_range[i], std::abs(pos[i]));
100  registered[pos] = true;
101  }
102  }
103  page.distance_ = d.len();
104  cache_[syaw][d] = page;
105  continue;
106  }
107 
108  float distf = 0.0;
109  const float r1 = motion[1] + motion[0] * cos_v / sin_v;
110  const float r2 = std::copysign(
111  std::sqrt(std::pow(motion[0], 2) + std::pow(motion[0] * cos_v / sin_v, 2)),
112  motion[0] * sin_v);
113 
114  float dyaw = yaw_e - yaw;
115  if (dyaw < -M_PI)
116  dyaw += 2 * M_PI;
117  else if (dyaw > M_PI)
118  dyaw -= 2 * M_PI;
119 
120  const float cx = d[0] * linear_resolution + r2 * cosf(yaw_e + M_PI / 2);
121  const float cy = d[1] * linear_resolution + r2 * sinf(yaw_e + M_PI / 2);
122  const float cx_s = r1 * cosf(yaw + M_PI / 2);
123  const float cy_s = r1 * sinf(yaw + M_PI / 2);
124 
125  CyclicVecFloat<3, 2> posf_prev(0, 0, 0);
126 
127  for (float i = 0; i < 1.0; i += inter)
128  {
129  const float r = r1 * (1.0 - i) + r2 * i;
130  const float cx2 = cx_s * (1.0 - i) + cx * i;
131  const float cy2 = cy_s * (1.0 - i) + cy * i;
132  const float cyaw = yaw + i * dyaw;
133 
134  const float posf_raw[3] =
135  {
136  (cx2 - r * cosf(cyaw + M_PI / 2)) / linear_resolution,
137  (cy2 - r * sinf(cyaw + M_PI / 2)) / linear_resolution,
138  cyaw / angular_resolution
139  };
140  const CyclicVecFloat<3, 2> posf(posf_raw[0], posf_raw[1], posf_raw[2]);
141  CyclicVecInt<3, 2> pos(posf_raw[0], posf_raw[1], posf_raw[2]);
142  pos.cycleUnsigned(angle);
143  if (registered.find(pos) == registered.end())
144  {
145  page.motion_.push_back(pos);
146  registered[pos] = true;
147  }
148  distf += (posf - posf_prev).len();
149  posf_prev = posf;
150  }
151  distf += (CyclicVecFloat<3, 2>(d) - posf_prev).len();
152  page.distance_ = distf;
153  cache_[syaw][d] = page;
154  }
155  }
156  }
157  // Sort to improve cache hit rate
158  for (auto& cache : cache_[syaw])
159  {
160  auto comp = [this, &gm_addr](const CyclicVecInt<3, 2> a, const CyclicVecInt<3, 2> b)
161  {
162  size_t a_baddr, a_addr;
163  size_t b_baddr, b_addr;
164  gm_addr(a, a_baddr, a_addr);
165  gm_addr(b, b_baddr, b_addr);
166  if (a_baddr == b_baddr)
167  {
168  return (a_addr < b_addr);
169  }
170  return (a_baddr < b_baddr);
171  };
172  std::sort(cache.second.motion_.begin(), cache.second.motion_.end(), comp);
173  }
174  }
175  max_range_ = max_range;
176 }
177 } // namespace planner_3d
178 } // namespace planner_cspace
d
void cycleUnsigned(const int res, const ArgList &...rest)
Definition: cyclic_vec.h:289
TFSIMD_FORCE_INLINE const tfScalar & y() const
std::vector< CyclicVecInt< 3, 2 > > motion_
Definition: motion_cache.h:51
TFSIMD_FORCE_INLINE tfScalar angle(const Quaternion &q1, const Quaternion &q2)
void reset(const float linear_resolution, const float angular_resolution, const int range, const std::function< void(CyclicVecInt< 3, 2 >, size_t &, size_t &)> gm_addr)
void rotate(const float ang)
Definition: cyclic_vec.h:268
TFSIMD_FORCE_INLINE const tfScalar & x() const


planner_cspace
Author(s): Atsushi Watanabe
autogenerated on Wed May 12 2021 02:20:42