path_planning.cpp
Go to the documentation of this file.
1 //=============================================================================
2 // Copyright (C) 2021-2024 Wageningen University - All Rights Reserved
3 // Author: Gonzalo Mier
4 // BSD-3 License
5 //=============================================================================
6 
7 #include <steering_functions/utilities/utilities.hpp>
9 
10 namespace f2c::pp {
11 
13  const F2CRoute& route, TurningBase& turn) {
14  F2CPath path;
15  for (size_t i = 0; i < route.sizeVectorSwaths(); ++i) {
16  auto prev_swaths = (i >0) ? route.getSwaths(i-1) : F2CSwaths();
18  prev_swaths, route.getConnection(i), route.getSwaths(i), turn);
19  path += planPath(robot, route.getSwaths(i), turn);
20  }
21  if (route.sizeConnections() > route.sizeVectorSwaths()) {
23  route.getLastSwaths(), route.getLastConnection(), F2CSwaths(), turn);
24  }
25  return path;
26 }
27 
29  const F2CSwaths& swaths, TurningBase& turn) {
30  F2CPath path;
31  if (swaths.size() > 1) {
32  for (size_t i = 0; i < swaths.size()-1; ++i) {
33  path.appendSwath(swaths[i], robot.getCruiseVel());
34  F2CPath turn_path = turn.createTurn(robot,
35  swaths[i].endPoint(), swaths[i].getOutAngle(),
36  swaths[i + 1].startPoint(), swaths[i + 1].getInAngle());
37  path += turn_path.discretize(0.1);
38  }
39  }
40  if (swaths.size() > 0) {
41  path.appendSwath(swaths.back(), robot.getCruiseVel());
42  }
43  return path;
44 }
45 
47  const F2CSwaths& s1,
48  const F2CMultiPoint& mp,
49  const F2CSwaths& s2,
50  TurningBase& turn) {
51  F2CPoint p1, p2;
52  double ang1, ang2;
53 
54  if (s1.size() > 0) {
55  p1 = s1.back().endPoint();
56  ang1 = s1.back().getOutAngle();
57  } else if (mp.size() > 0) {
58  p1 = mp[0];
59  ang1 = mp.getOutAngle(0);
60  } else {
61  return {};
62  }
63  if (s2.size() > 0) {
64  p2 = s2[0].startPoint();
65  ang2 = s2[0].getInAngle();
66  } else if (mp.size() > 0) {
67  p2 = mp.getLastPoint();
68  ang2 = mp.getInAngle(mp.size()-1);
69  } else {
70  return {};
71  }
72  return planPathForConnection(robot, p1, ang1, mp, p2, ang2, turn);
73 }
74 
76  const F2CPoint& p1, double ang1,
77  const F2CMultiPoint& mp,
78  const F2CPoint& p2, double ang2,
79  TurningBase& turn) {
80  auto v_con = simplifyConnection(robot,
81  p1, ang1, mp, p2, ang2);
82 
83  F2CPath path;
84  for (int i = 1; i < v_con.size(); ++i) {
85  path += turn.createTurn(robot,
86  v_con[i-1].first, v_con[i-1].second,
87  v_con[i].first, v_con[i].second);
88  }
89  return path;
90 }
91 
92 
93 
95  double x, y, ang, k;
96  end_of_clothoid(0.0, 0.0, 0.0, 0.0, robot.getMaxDiffCurv(), 1.0,
97  robot.getMaxCurv() / robot.getMaxDiffCurv(),
98  &x, &y, &ang, &k);
99  double xi = x - sin(ang) / robot.getMaxCurv();
100  double yi = y + cos(ang) / robot.getMaxCurv();
101  return sqrt(xi*xi + yi*yi);
102 }
103 
104 std::vector<std::pair<F2CPoint, double>> PathPlanning::simplifyConnection(
105  const F2CRobot& robot,
106  const F2CPoint& p1, double ang1,
107  const F2CMultiPoint& mp,
108  const F2CPoint& p2, double ang2) {
109  const double safe_dist = getSmoothTurningRadius(robot);
110  std::vector<std::pair<F2CPoint, double>> path;
111  path.emplace_back(p1, ang1);
112 
113  if (p1.distance(p2) < 6.0 * safe_dist || mp.size() < 2) {
114  path.emplace_back(p2, ang2);
115  return path;
116  }
117 
118  std::vector<F2CPoint> vp;
119  for (int i = 1; i < mp.size() - 1; ++i) {
120  double ang_in = (mp[i] - mp[i-1]).getAngleFromPoint();
121  double ang_out = (mp[i+1] - mp[i]).getAngleFromPoint();
122  if (fabs(ang_in - ang_out) > 0.1) {
123  vp.emplace_back(mp[i]);
124  }
125  }
126 
127  if (vp.size() < 2) {
128  path.emplace_back(p2, ang2);
129  return path;
130  }
131 
132  for (int i = 1; i < vp.size() - 1; ++i) {
133  double dist_in = vp[i].distance(vp[i-1]);
134  double dist_out = vp[i].distance(vp[i+1]);
135  if (dist_in == 0.0 || dist_out == 0.0) {
136  continue;
137  }
138  double d_in = min(0.5 * dist_in, safe_dist);
139  double d_out = min(0.5 * dist_out, safe_dist);
140  F2CPoint p_in = (vp[i-1] - vp[i]) * (d_in / dist_in) + vp[i];
141  F2CPoint p_out = (vp[i+1] - vp[i]) * (d_out / dist_out) + vp[i];
142  if (p_in.distance(path.back().first) > 3.0 * safe_dist &&
143  p_in.distance(p1) > 3.0 * safe_dist &&
144  p_in.distance(p2) > 3.0 * safe_dist) {
145  double ang_in = (vp[i ] - vp[i-1]).getAngleFromPoint();
146  path.emplace_back(p_in, ang_in);
147  }
148  if (p_out.distance(vp[i+1]) > 3.0 * safe_dist &&
149  p_out.distance(p1) > 3.0 * safe_dist &&
150  p_out.distance(p2) > 3.0 * safe_dist &&
151  p_out.distance(p_in) > 3.0 * safe_dist) {
152  double ang_out = (vp[i+1] - vp[i]).getAngleFromPoint();
153  path.emplace_back(p_out, ang_out);
154  }
155  }
156  path.emplace_back(p2, ang2);
157  return path;
158 }
159 
160 } // namespace f2c::pp
161 
f2c::pp::PathPlanning::simplifyConnection
static std::vector< std::pair< F2CPoint, double > > simplifyConnection(const F2CRobot &robot, const F2CPoint &p1, double ang1, const F2CMultiPoint &mp, const F2CPoint &p2, double ang2)
Definition: path_planning.cpp:104
f2c::types::Swaths::size
size_t size() const
Definition: Swaths.cpp:78
f2c::pp::PathPlanning::planPath
static F2CPath planPath(const F2CRobot &robot, const F2CRoute &route, TurningBase &turn)
Compute the coverage path using a route as a reference.
Definition: path_planning.cpp:12
5_route_planning.swaths
swaths
Definition: 5_route_planning.py:58
f2c::types::Path::discretize
Path & discretize(double step_size)
Definition: Path.cpp:434
f2c::pp::PathPlanning::getSmoothTurningRadius
static double getSmoothTurningRadius(const F2CRobot &robot)
Definition: path_planning.cpp:94
1_basic_types.p1
p1
Definition: 1_basic_types.py:11
f2c::pp
Path planning algorithms' namespace.
Definition: dubins_curves.h:14
2_objective_functions.path
path
Definition: 2_objective_functions.py:88
f2c::pp::PathPlanning::planPathForConnection
static F2CPath planPathForConnection(const F2CRobot &robot, const F2CSwaths &s1, const F2CMultiPoint &mp, const F2CSwaths &s2, TurningBase &turn)
Definition: path_planning.cpp:46
f2c::types::MultiPoint::getLastPoint
const Point getLastPoint() const
Definition: MultiPoint.cpp:70
f2c::types::MultiPoint::getOutAngle
double getOutAngle(size_t i) const
Definition: MultiPoint.cpp:118
2_objective_functions.robot
robot
Definition: 2_objective_functions.py:76
5_route_planning.route
route
Definition: 5_route_planning.py:29
1_basic_types.p2
p2
Definition: 1_basic_types.py:15
f2c::types::Swath::endPoint
Point endPoint() const
Definition: Swath.cpp:99
f2c::types::Path
Definition: Path.h:23
f2c::types::MultiPoint
Definition: MultiPoint.h:18
f2c::types::MultiPoint::getInAngle
double getInAngle(size_t i) const
Definition: MultiPoint.cpp:109
f2c::types::Swaths::back
Swath & back()
Definition: Swaths.cpp:62
F2CSwaths
f2c::types::Swaths F2CSwaths
Definition: types.h:51
f2c::types::Route
Definition: Route.h:23
f2c::pp::TurningBase
Base class for turn planners.
Definition: turning_base.h:22
f2c::types::Point
Definition: Point.h:21
f2c::types::Robot
Definition: Robot.h:25
path_planning.h
f2c::types::Geometry::distance
double distance(const Geometry< T2, R2 > &p) const
Compute shortest distance between this and another geometry.
Definition: Geometry_impl.hpp:139
f2c::types::MultiPoint::size
size_t size() const
Definition: MultiPoint.cpp:30
f2c::pp::TurningBase::createTurn
F2CPath createTurn(const F2CRobot &robot, const F2CPoint &start_pos, double start_angle, const F2CPoint &end_pos, double end_angle)
Create a turn that goes from one point with a certain angle to another point.
Definition: turning_base.cpp:30
f2c::types::Swath::getOutAngle
double getOutAngle() const
Definition: Swath.cpp:84
f2c::types::Swaths
Definition: Swaths.h:20


fields2cover
Author(s):
autogenerated on Fri Apr 25 2025 02:18:31