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  const std::vector<Vec> expected_0deg_straight_primitives =
99  {
100  Vec(1, 0, 0),
101  Vec(2, 0, 0),
102  Vec(3, 0, 0),
103  Vec(4, 0, 0),
104  };
105  const std::vector<Vec> expected_0deg_rotation_1_primitives =
106  {
107  Vec(3, -2, 15),
108  Vec(3, -1, 15),
109  Vec(3, 1, 1),
110  Vec(3, 2, 1),
111  };
112  const std::vector<Vec> expected_0deg_rotation_2_primitives =
113  {
114  Vec(3, -2, 14),
115  Vec(3, -1, 14),
116  Vec(3, 1, 2),
117  Vec(3, 2, 2),
118  };
119  const std::vector<Vec> expected_0deg_rotation_3_primitives =
120  {
121  Vec(3, -2, 13),
122  Vec(3, -1, 13),
123  Vec(3, 1, 3),
124  Vec(3, 2, 3),
125  };
126  const std::vector<std::vector<Vec>> expected_0deg_primitives =
127  {
128  expected_0deg_straight_primitives,
129  expected_0deg_rotation_1_primitives,
130  expected_0deg_rotation_2_primitives,
131  expected_0deg_rotation_3_primitives,
132  };
133 
134  const std::vector<Vec> expected_23deg_straight_primitives =
135  {
136  Vec(2, 1, 0),
137  Vec(3, 1, 0),
138  Vec(3, 2, 0),
139  };
140  const std::vector<Vec> expected_23deg_rotation_1_primitives =
141  {
142  Vec(2, 3, 1),
143  Vec(3, 0, 15),
144  Vec(3, 2, 1),
145  Vec(4, 0, 15),
146  };
147  const std::vector<Vec> expected_23deg_rotation_2_primitives =
148  {
149  Vec(2, 3, 2),
150  Vec(3, 2, 2),
151  Vec(3, -1, 14),
152  Vec(3, 0, 14),
153  Vec(4, 0, 14),
154  };
155  const std::vector<Vec> expected_23deg_rotation_3_primitives =
156  {
157  Vec(1, 3, 3),
158  Vec(2, 3, 3),
159  Vec(3, -1, 13),
160  Vec(3, 0, 13),
161  Vec(4, 0, 13),
162  };
163  const std::vector<std::vector<Vec>> expected_23deg_primitives =
164  {
165  expected_23deg_straight_primitives,
166  expected_23deg_rotation_1_primitives,
167  expected_23deg_rotation_2_primitives,
168  expected_23deg_rotation_3_primitives,
169  };
170 
171  const std::vector<Vec> expected_45deg_straight_primitives =
172  {
173  Vec(1, 1, 0),
174  Vec(2, 2, 0),
175  Vec(3, 2, 0),
176  Vec(2, 3, 0),
177  };
178  const std::vector<Vec> expected_45deg_rotation_1_primitives =
179  {
180  Vec(1, 3, 1),
181  Vec(2, 3, 1),
182  Vec(3, 1, 15),
183  Vec(3, 2, 15),
184  };
185  const std::vector<Vec> expected_45deg_rotation_2_primitives =
186  {
187  Vec(0, 3, 2),
188  Vec(1, 3, 2),
189  Vec(2, 3, 2),
190  Vec(3, 0, 14),
191  Vec(3, 1, 14),
192  Vec(3, 2, 14),
193  };
194  const std::vector<Vec> expected_45deg_rotation_3_primitives =
195  {
196  Vec(0, 3, 3),
197  Vec(0, 4, 3),
198  Vec(1, 3, 3),
199  Vec(3, 0, 13),
200  Vec(3, 1, 13),
201  Vec(4, 0, 13),
202  };
203  const std::vector<std::vector<Vec>> expected_45deg_primitives =
204  {
205  expected_45deg_straight_primitives,
206  expected_45deg_rotation_1_primitives,
207  expected_45deg_rotation_2_primitives,
208  expected_45deg_rotation_3_primitives,
209  };
210 
211  const std::vector<Vec> expected_67deg_straight_primitives =
212  {
213  Vec(1, 2, 0),
214  Vec(1, 3, 0),
215  Vec(2, 3, 0),
216  };
217  const std::vector<Vec> expected_67deg_rotation_1_primitives =
218  {
219  Vec(0, 3, 1),
220  Vec(0, 4, 1),
221  Vec(2, 3, 15),
222  Vec(3, 2, 15),
223  };
224  const std::vector<Vec> expected_67deg_rotation_2_primitives =
225  {
226  Vec(0, 3, 2),
227  Vec(0, 4, 2),
228  Vec(-1, 3, 2),
229  Vec(2, 3, 14),
230  Vec(3, 2, 14),
231  };
232  const std::vector<Vec> expected_67deg_rotation_3_primitives =
233  {
234  Vec(0, 3, 3),
235  Vec(0, 4, 3),
236  Vec(1, -3, 3),
237  Vec(3, 1, 13),
238  Vec(3, 2, 13),
239  };
240  const std::vector<std::vector<Vec>> expected_67deg_primitives =
241  {
242  expected_67deg_straight_primitives,
243  expected_67deg_rotation_1_primitives,
244  expected_67deg_rotation_2_primitives,
245  expected_67deg_rotation_3_primitives,
246  };
247 
248  const std::vector<std::vector<std::vector<Vec>>> expected_original_primitives =
249  {
250  expected_0deg_primitives,
251  expected_23deg_primitives,
252  expected_45deg_primitives,
253  expected_67deg_primitives,
254  };
255 
256  costmap_cspace_msgs::MapMetaData3D map_info;
257  map_info.linear_resolution = 0.1f;
258  map_info.angular_resolution = static_cast<float>(M_PI / 8);
259  map_info.angle = 16;
260 
261  CostCoeff cc;
262  cc.min_curve_radius_ = 0.1f;
263  cc.angle_resolution_aspect_ = 2.0f / tanf(map_info.angular_resolution);
264 
265  const int range = 4;
266  const std::vector<std::vector<MotionPrimitiveBuilder::Vec>> motion_primitives =
267  MotionPrimitiveBuilder::build(map_info, cc, range);
268 
269  EXPECT_EQ(map_info.angle, static_cast<unsigned int>(motion_primitives.size()));
270  for (size_t i = 0; i < motion_primitives.size(); ++i)
271  {
272  std::vector<Vec> current_primitives = motion_primitives[i];
273  std::sort(current_primitives.begin(), current_primitives.end(), &compareVecs);
274  const auto expected_primitives = buildExpectedPrimitives(expected_original_primitives[i % 4], i / 4);
275  ASSERT_EQ(expected_primitives.size(), current_primitives.size());
276  for (size_t j = 0; j < current_primitives.size(); ++j)
277  {
278  const Vec& expected_prim = expected_primitives[j];
279  const Vec& actual_prim = current_primitives[j];
280 
281  EXPECT_EQ(expected_prim, actual_prim)
282  << "Error at " << i << "," << j << "\n"
283  << " Expected: (" << expected_prim[0] << "," << expected_prim[1] << "," << expected_prim[2] << ")\n"
284  << " Actual: (" << actual_prim[0] << "," << actual_prim[1] << "," << actual_prim[2] << ")\n";
285  }
286  }
287 }
288 
289 } // namespace planner_3d
290 } // namespace planner_cspace
291 
292 int main(int argc, char** argv)
293 {
294  testing::InitGoogleTest(&argc, argv);
295 
296  return RUN_ALL_TESTS();
297 }
TEST(CostmapBBF, ForEach)
bool compareVecs(const Vec &v1, const Vec &v2)
int main(int argc, char **argv)
void cycleUnsigned(const int res, const ArgList &... rest)
Definition: cyclic_vec.h:289
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 Mon Jul 3 2023 02:39:06