test_path2d.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018, 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 <cstddef>
32 #include <string>
33 
34 #include <gtest/gtest.h>
35 
38 
39 namespace
40 {
41 double getRemainedDistance(const trajectory_tracker::Path2D& path, const Eigen::Vector2d& p)
42 {
43  const auto nearest = path.findNearest(path.begin(), path.end(), p);
44  const Eigen::Vector2d pos_on_line =
45  trajectory_tracker::projection2d((nearest - 1)->pos_, nearest->pos_, p);
46  return path.remainedDistance(path.begin(), nearest, path.end(), pos_on_line);
47 }
48 } // namespace
49 
50 TEST(Path2D, RemainedDistance)
51 {
53  for (double x = 0.0; x < 10.0 - 1e-3; x += 0.2)
54  path_full.push_back(trajectory_tracker::Pose2D(Eigen::Vector2d(x, 0), 0, 1));
55  path_full.push_back(trajectory_tracker::Pose2D(Eigen::Vector2d(10.0, 0), 0, 1));
56 
57  // Single pose path means orientation control mode. More than two poses should be line following.
58  for (size_t l = 2; l < path_full.size(); ++l)
59  {
61  path.resize(l);
62  std::copy(path_full.end() - l, path_full.end(), path.begin());
63 
64  std::string err_msg = "failed for " + std::to_string(l) + " pose(s) path";
65 
66  ASSERT_NEAR(getRemainedDistance(path, Eigen::Vector2d(0, 0)), 10.0, 1e-2) << err_msg;
67 
68  ASSERT_NEAR(getRemainedDistance(path, Eigen::Vector2d(8.25, 0)), 1.75, 1e-2) << err_msg;
69  ASSERT_NEAR(getRemainedDistance(path, Eigen::Vector2d(10.25, 0)), -0.25, 1e-2) << err_msg;
70 
71  ASSERT_NEAR(getRemainedDistance(path, Eigen::Vector2d(8.25, 0.1)), 1.75, 1e-2) << err_msg;
72  ASSERT_NEAR(getRemainedDistance(path, Eigen::Vector2d(8.25, -0.1)), 1.75, 1e-2) << err_msg;
73  ASSERT_NEAR(getRemainedDistance(path, Eigen::Vector2d(10.25, 0.1)), -0.25, 1e-2) << err_msg;
74  ASSERT_NEAR(getRemainedDistance(path, Eigen::Vector2d(10.25, -0.1)), -0.25, 1e-2) << err_msg;
75  }
76 }
77 
78 TEST(Path2D, Curvature)
79 {
80  for (float c = 1.0; c < 4.0; c += 0.4)
81  {
83  for (double a = 0; a < 1.57; a += 0.1)
84  path.push_back(trajectory_tracker::Pose2D(Eigen::Vector2d(std::cos(a), std::sin(a)) * c, 0, 1));
85 
86  ASSERT_NEAR(path.getCurvature(path.begin(), path.end(), path[0].pos_, 10.0), 1.0 / c, 1e-2);
87  }
88 }
89 
90 TEST(Path2D, LocalGoalWithoutSwitchBack)
91 {
92  for (int yaw_i = -1; yaw_i <= 1; ++yaw_i)
93  {
94  const double yaw_diff = yaw_i * 0.1;
95 
97  Eigen::Vector2d p(0, 0);
98  double yaw(0);
99  for (int i = 0; i < 10; ++i)
100  {
101  p -= Eigen::Vector2d(std::cos(yaw), std::sin(yaw)) * 0.1;
102  yaw += yaw_diff;
103  path.push_back(trajectory_tracker::Pose2D(p, yaw, 1));
104  }
105  ASSERT_EQ(path.findLocalGoal(path.begin(), path.end(), true), path.end());
106  ASSERT_EQ(path.findLocalGoal(path.begin(), path.end(), false), path.end());
107  }
108 }
109 
110 TEST(Path2D, LocalGoalWithSwitchBack)
111 {
112  for (int yaw_i = -1; yaw_i <= 1; ++yaw_i)
113  {
114  const double yaw_diff = yaw_i * 0.1;
115 
117  Eigen::Vector2d p(0, 0);
118  double yaw(0);
119  for (int i = 0; i < 5; ++i)
120  {
121  p -= Eigen::Vector2d(std::cos(yaw), std::sin(yaw)) * 0.1;
122  yaw += yaw_diff;
123  path.push_back(trajectory_tracker::Pose2D(p, yaw, 1));
124  }
125  for (int i = 0; i < 5; ++i)
126  {
127  p += Eigen::Vector2d(std::cos(yaw), std::sin(yaw)) * 0.1;
128  yaw += yaw_diff;
129  path.push_back(trajectory_tracker::Pose2D(p, yaw, 1));
130  }
131  const auto it_local_goal = path.findLocalGoal(path.begin(), path.end(), true);
132  ASSERT_EQ(it_local_goal, path.begin() + 5);
133  ASSERT_EQ(path.findLocalGoal(it_local_goal, path.end(), true), path.end());
134 
135  // no switch back motion under (allow_switchback == false)
136  ASSERT_EQ(path.findLocalGoal(path.begin(), path.end(), false), path.end());
137  }
138 }
139 
140 int main(int argc, char** argv)
141 {
142  testing::InitGoogleTest(&argc, argv);
143 
144  return RUN_ALL_TESTS();
145 }
double remainedDistance(const ConstIterator &begin, const ConstIterator &nearest, const ConstIterator &end, const Eigen::Vector2d &target_on_line) const
Definition: path2d.h:140
int main(int argc, char **argv)
TEST(Path2D, RemainedDistance)
Definition: test_path2d.cpp:50
ConstIterator findLocalGoal(const ConstIterator &begin, const ConstIterator &end, const bool allow_backward_motion) const
Definition: path2d.h:89
float getCurvature(const ConstIterator &begin, const ConstIterator &end, const Eigen::Vector2d &target_on_line, const float max_search_range) const
Definition: path2d.h:174
TFSIMD_FORCE_INLINE const tfScalar & x() const
Eigen::Vector2d projection2d(const Eigen::Vector2d &a, const Eigen::Vector2d &b, const Eigen::Vector2d &c)
Definition: eigen_line.h:78
ConstIterator findNearest(const ConstIterator &begin, const ConstIterator &end, const Eigen::Vector2d &target, const float max_search_range=0) const
Definition: path2d.h:111


trajectory_tracker
Author(s): Atsushi Watanabe
autogenerated on Tue Jul 9 2019 05:00:09