test_motion_primitive_builder.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020, 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 <vector>
32 
35 
36 #include <gtest/gtest.h>
37 
38 namespace planner_cspace
39 {
40 namespace planner_3d
41 {
43 
44 bool compareVecs(const Vec& v1, const Vec& v2)
45 {
46  if (v1[0] != v2[0])
47  return v1[0] < v2[0];
48  if (v1[1] != v2[1])
49  return v1[1] < v2[1];
50  return v1[2] < v2[2];
51 }
52 
53 std::vector<Vec> buildExpectedPrimitives(const std::vector<std::vector<Vec>> original_primitives_vector,
54  const int quadrant)
55 {
56  std::vector<Vec> results;
57  for (const auto& original_primitives : original_primitives_vector)
58  {
59  for (const auto& original_primitive : original_primitives)
60  {
61  Vec primitive;
62  switch (quadrant)
63  {
64  case 0:
65  primitive = original_primitive;
66  break;
67  case 1:
68  primitive = Vec(original_primitive[1], -original_primitive[0], original_primitive[2]);
69  primitive.cycleUnsigned(16);
70  break;
71  case 2:
72  primitive = Vec(-original_primitive[0], -original_primitive[1], original_primitive[2]);
73  primitive.cycleUnsigned(16);
74  break;
75  case 3:
76  primitive = Vec(-original_primitive[1], original_primitive[0], original_primitive[2]);
77  primitive.cycleUnsigned(16);
78  break;
79  default:
80  break;
81  }
82  results.push_back(primitive);
83  const Vec opposite = Vec(-primitive[0], -primitive[1], primitive[2]);
84  results.push_back(opposite);
85  }
86  }
87  // In-place turns
88  for (int i = 1; i < 16; ++i)
89  {
90  results.push_back(Vec(0, 0, i));
91  }
92  std::sort(results.begin(), results.end(), &compareVecs);
93  return results;
94 }
95 
97 {
98  // clang-format off
99  const std::vector<Vec> expected_0deg_straight_primitives =
100  {
101  Vec(1, 0, 0),
102  Vec(2, 0, 0),
103  Vec(3, 0, 0),
104  Vec(4, 0, 0),
105  };
106  const std::vector<Vec> expected_0deg_rotation_1_primitives =
107  {
108  Vec(3, -2, 15),
109  Vec(3, -1, 15),
110  Vec(3, 1, 1),
111  Vec(3, 2, 1),
112  };
113  const std::vector<Vec> expected_0deg_rotation_2_primitives =
114  {
115  Vec(3, -2, 14),
116  Vec(3, -1, 14),
117  Vec(3, 1, 2),
118  Vec(3, 2, 2),
119  };
120  const std::vector<Vec> expected_0deg_rotation_3_primitives =
121  {
122  Vec(3, -2, 13),
123  Vec(3, -1, 13),
124  Vec(3, 1, 3),
125  Vec(3, 2, 3),
126  };
127  const std::vector<std::vector<Vec>> expected_0deg_primitives =
128  {
129  expected_0deg_straight_primitives,
130  expected_0deg_rotation_1_primitives,
131  expected_0deg_rotation_2_primitives,
132  expected_0deg_rotation_3_primitives,
133  };
134 
135  const std::vector<Vec> expected_23deg_straight_primitives =
136  {
137  Vec(2, 1, 0),
138  Vec(3, 1, 0),
139  Vec(3, 2, 0),
140  };
141  const std::vector<Vec> expected_23deg_rotation_1_primitives =
142  {
143  Vec(2, 3, 1),
144  Vec(3, 0, 15),
145  Vec(3, 2, 1),
146  Vec(4, 0, 15),
147  };
148  const std::vector<Vec> expected_23deg_rotation_2_primitives =
149  {
150  Vec(2, 3, 2),
151  Vec(3, 2, 2),
152  Vec(3, -1, 14),
153  Vec(3, 0, 14),
154  Vec(4, 0, 14),
155  };
156  const std::vector<Vec> expected_23deg_rotation_3_primitives =
157  {
158  Vec(1, 3, 3),
159  Vec(2, 3, 3),
160  Vec(3, -1, 13),
161  Vec(3, 0, 13),
162  Vec(4, 0, 13),
163  };
164  const std::vector<std::vector<Vec>> expected_23deg_primitives =
165  {
166  expected_23deg_straight_primitives,
167  expected_23deg_rotation_1_primitives,
168  expected_23deg_rotation_2_primitives,
169  expected_23deg_rotation_3_primitives,
170  };
171 
172  const std::vector<Vec> expected_45deg_straight_primitives =
173  {
174  Vec(1, 1, 0),
175  Vec(2, 2, 0),
176  Vec(3, 2, 0),
177  Vec(2, 3, 0),
178  };
179  const std::vector<Vec> expected_45deg_rotation_1_primitives =
180  {
181  Vec(1, 3, 1),
182  Vec(2, 3, 1),
183  Vec(3, 1, 15),
184  Vec(3, 2, 15),
185  };
186  const std::vector<Vec> expected_45deg_rotation_2_primitives =
187  {
188  Vec(0, 3, 2),
189  Vec(1, 3, 2),
190  Vec(2, 3, 2),
191  Vec(3, 0, 14),
192  Vec(3, 1, 14),
193  Vec(3, 2, 14),
194  };
195  const std::vector<Vec> expected_45deg_rotation_3_primitives =
196  {
197  Vec(0, 3, 3),
198  Vec(0, 4, 3),
199  Vec(1, 3, 3),
200  Vec(3, 0, 13),
201  Vec(3, 1, 13),
202  Vec(4, 0, 13),
203  };
204  const std::vector<std::vector<Vec>> expected_45deg_primitives =
205  {
206  expected_45deg_straight_primitives,
207  expected_45deg_rotation_1_primitives,
208  expected_45deg_rotation_2_primitives,
209  expected_45deg_rotation_3_primitives,
210  };
211 
212  const std::vector<Vec> expected_67deg_straight_primitives =
213  {
214  Vec(1, 2, 0),
215  Vec(1, 3, 0),
216  Vec(2, 3, 0),
217  };
218  const std::vector<Vec> expected_67deg_rotation_1_primitives =
219  {
220  Vec(0, 3, 1),
221  Vec(0, 4, 1),
222  Vec(2, 3, 15),
223  Vec(3, 2, 15),
224  };
225  const std::vector<Vec> expected_67deg_rotation_2_primitives =
226  {
227  Vec(0, 3, 2),
228  Vec(0, 4, 2),
229  Vec(-1, 3, 2),
230  Vec(2, 3, 14),
231  Vec(3, 2, 14),
232  };
233  const std::vector<Vec> expected_67deg_rotation_3_primitives =
234  {
235  Vec(0, 3, 3),
236  Vec(0, 4, 3),
237  Vec(1, -3, 3),
238  Vec(3, 1, 13),
239  Vec(3, 2, 13),
240  };
241  const std::vector<std::vector<Vec>> expected_67deg_primitives =
242  {
243  expected_67deg_straight_primitives,
244  expected_67deg_rotation_1_primitives,
245  expected_67deg_rotation_2_primitives,
246  expected_67deg_rotation_3_primitives,
247  };
248 
249  const std::vector<std::vector<std::vector<Vec>>> expected_original_primitives =
250  {
251  expected_0deg_primitives,
252  expected_23deg_primitives,
253  expected_45deg_primitives,
254  expected_67deg_primitives,
255  };
256  // clang-format on
257 
258  costmap_cspace_msgs::MapMetaData3D map_info;
259  map_info.linear_resolution = 0.1f;
260  map_info.angular_resolution = static_cast<float>(M_PI / 8);
261  map_info.angle = 16;
262 
263  CostCoeff cc;
264  cc.min_curve_radius_ = 0.1f;
265  cc.angle_resolution_aspect_ = 2.0f / tanf(map_info.angular_resolution);
266 
267  const int range = 4;
268  const std::vector<std::vector<MotionPrimitiveBuilder::Vec>> motion_primitives =
269  MotionPrimitiveBuilder::build(map_info, cc, range);
270 
271  EXPECT_EQ(map_info.angle, static_cast<unsigned int>(motion_primitives.size()));
272  for (size_t i = 0; i < motion_primitives.size(); ++i)
273  {
274  std::vector<Vec> current_primitives = motion_primitives[i];
275  std::sort(current_primitives.begin(), current_primitives.end(), &compareVecs);
276  const auto expected_primitives = buildExpectedPrimitives(expected_original_primitives[i % 4], i / 4);
277  ASSERT_EQ(expected_primitives.size(), current_primitives.size());
278  for (size_t j = 0; j < current_primitives.size(); ++j)
279  {
280  const Vec& expected_prim = expected_primitives[j];
281  const Vec& actual_prim = current_primitives[j];
282 
283  EXPECT_EQ(expected_prim, actual_prim)
284  << "Error at " << i << "," << j << "\n"
285  << " Expected: (" << expected_prim[0] << "," << expected_prim[1] << "," << expected_prim[2] << ")\n"
286  << " Actual: (" << actual_prim[0] << "," << actual_prim[1] << "," << actual_prim[2] << ")\n";
287  }
288  }
289 }
290 
291 } // namespace planner_3d
292 } // namespace planner_cspace
293 
294 int main(int argc, char** argv)
295 {
296  testing::InitGoogleTest(&argc, argv);
297 
298  return RUN_ALL_TESTS();
299 }
TEST(CostmapBBF, ForEach)
void cycleUnsigned(const int res, const ArgList &...rest)
Definition: cyclic_vec.h:289
bool compareVecs(const Vec &v1, const Vec &v2)
int main(int argc, char **argv)
std::vector< Vec > buildExpectedPrimitives(const std::vector< std::vector< Vec >> original_primitives_vector, const int quadrant)
static std::vector< std::vector< Vec > > build(const costmap_cspace_msgs::MapMetaData3D &map_info, const CostCoeff &cc, const int range)


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