CircularPathSmoothing.cpp
Go to the documentation of this file.
2 
3 #include <algorithm>
4 #include <cmath>
5 #include <cstddef>
6 #include <cstdlib>
7 #include <type_traits>
8 
11 
12 namespace
13 {
14  template <typename T>
15  constexpr T
16  deg2rad(T deg)
17  {
18  static_assert(std::is_floating_point<T>::value);
19  constexpr T c = M_PI / 180;
20  return deg * c;
21  }
22 } // namespace
23 
25 {
26  // TODO move to Simox
27  float
28  getAngleBetweenVectors(const Eigen::Vector2f& v1, const Eigen::Vector2f& v2)
29  {
30  // Returns an angle between 0 and 180 degree (the minimum angle between the two vectors)
31  const Eigen::Vector2f v1_vec_normed = v1.normalized();
32  const Eigen::Vector2f v2_vec_normed = v2.normalized();
33  const float dot_product_vec =
34  v1_vec_normed(0) * v2_vec_normed(0) + v1_vec_normed(1) * v2_vec_normed(1);
35  float yaw = acos(dot_product_vec);
36  return yaw;
37  }
38 
41  {
42  Points points;
43 
44  points.push_back(p.front());
45 
46  // omit start and end
47  for (size_t i = 1; i < (p.size() - 1); i++)
48  {
49  const Eigen::Vector2f& prev = p.at(i - 1);
50  const Eigen::Vector2f& at = p.at(i);
51  const Eigen::Vector2f& next = p.at(i + 1);
52 
53  // the largest radius for smoothing
54  const float maxRadius = std::min((prev - at).norm(), (next - at).norm());
55  const float radius = std::min(maxRadius, 300.F);
56 
57  const Eigen::Vector2f vIn = (prev - at).normalized();
58  const Eigen::Vector2f vOut = (next - at).normalized();
59 
60  // the angle between the lines
61  const float phi = getAngleBetweenVectors(vIn, vOut);
62  const float l = radius / std::tan(phi / 2);
63 
64  points.emplace_back(at + Eigen::Vector2f(prev - at).normalized() * l);
65  points.emplace_back(at + Eigen::Vector2f(next - at).normalized() * l);
66  }
67 
68  points.push_back(p.back());
69 
70  return points;
71  }
72 
75  {
77  const auto& p = trajectory.points();
78 
79  points.push_back(p.front());
80 
81  // omit start and end
82  for (size_t i = 1; i < (p.size() - 1); i++)
83  {
84  const Eigen::Vector2f& prev =
85  navigation::conv::to2D(p.at(i - 1).waypoint.pose.translation());
86  const Eigen::Vector2f& at = navigation::conv::to2D(p.at(i).waypoint.pose.translation());
87  const Eigen::Vector2f& next =
88  navigation::conv::to2D(p.at(i + 1).waypoint.pose.translation());
89 
90  // the largest radius for smoothing
91  const float maxRadius = std::min((prev - at).norm(), (next - at).norm());
92  const float radius = std::min(maxRadius, 300.F);
93 
94  const Eigen::Vector2f vIn = (prev - at).normalized();
95  const Eigen::Vector2f vOut = (next - at).normalized();
96 
97  // the angle between the lines
98  const float phi = getAngleBetweenVectors(vIn, vOut);
99 
100  // decide whether it is necessary to smooth the path
101  if (std::abs(phi) < deg2rad(10.F))
102  {
103  points.push_back(p.at(i));
104  }
105  else
106  {
107  const float l = radius / std::tan(phi / 2);
108 
109  const Eigen::Vector2f prePos = at + Eigen::Vector2f(prev - at).normalized() * l;
110  const Eigen::Vector2f postPos = at + Eigen::Vector2f(next - at).normalized() * l;
111 
112  const auto tpProj = [&](const Eigen::Vector2f& pos) -> core::GlobalTrajectoryPoint
113  {
114  const auto proj =
115  trajectory.getProjection(navigation::conv::to3D(pos),
117 
118  return proj.projection;
119  };
120 
121  points.push_back(tpProj(prePos));
122  points.push_back(tpProj(postPos));
123  }
124  }
125 
126  points.push_back(p.back());
127 
128  return points;
129  }
130 } // namespace armarx::navigation::algorithm
armarx::navigation::core::GlobalTrajectory
Definition: Trajectory.h:70
armarx::navigation::core::VelocityInterpolation::LinearInterpolation
@ LinearInterpolation
armarx::navigation::algorithm::getAngleBetweenVectors
float getAngleBetweenVectors(const Eigen::Vector2f &v1, const Eigen::Vector2f &v2)
Definition: CircularPathSmoothing.cpp:28
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:46
armarx::navigation::core::GlobalTrajectoryPoints
std::vector< GlobalTrajectoryPoint > GlobalTrajectoryPoints
Definition: Trajectory.h:43
armarx::navigation::core::GlobalTrajectoryPoint
Definition: Trajectory.h:37
CircularPathSmoothing.h
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:855
armarx::abs
std::vector< T > abs(const std::vector< T > &v)
Definition: VectorHelpers.h:281
armarx::navigation::algorithm::CircularPathSmoothing::Points
std::vector< Point > Points
Definition: CircularPathSmoothing.h:41
armarx::navigation::core::Projection::projection
GlobalTrajectoryPoint projection
Definition: Trajectory.h:47
M_PI
#define M_PI
Definition: MathTools.h:17
armarx::navigation::algorithm
This file is part of ArmarX.
Definition: AStarPlanner.cpp:32
armarx::navigation::algorithm::CircularPathSmoothing::smooth
Points smooth(const Points &p)
circular path smoothing
Definition: CircularPathSmoothing.cpp:40
armarx::navigation::conv::to2D
std::vector< Eigen::Vector2f > to2D(const std::vector< Eigen::Vector3f > &v)
Definition: eigen.cpp:29
F
Definition: ExportDialogControllerTest.cpp:18
armarx::navigation::conv::to3D
std::vector< Eigen::Vector3f > to3D(const std::vector< Eigen::Vector2f > &v)
Definition: eigen.cpp:14
armarx::navigation::core::GlobalTrajectory::getProjection
Projection getProjection(const Position &point, const VelocityInterpolation &velocityInterpolation) const
Definition: Trajectory.cpp:245
eigen.h
T
float T
Definition: UnscentedKalmanFilterTest.cpp:38
min
T min(T t1, T t2)
Definition: gdiam.h:44
Trajectory.h
armarx::navigation::core::GlobalTrajectory::points
const std::vector< GlobalTrajectoryPoint > & points() const
Definition: Trajectory.cpp:734
norm
double norm(const Point &a)
Definition: point.hpp:102