Autonomy Software C++ 24.5.1
Welcome to the Autonomy Software repository of the Mars Rover Design Team (MRDT) at Missouri University of Science and Technology (Missouri S&T)! API reference contains the source code and other resources for the development of the autonomy software for our Mars rover. The Autonomy Software project aims to compete in the University Rover Challenge (URC) by demonstrating advanced autonomous capabilities and robust navigation algorithms.
Loading...
Searching...
No Matches
PathPostProcessing.hpp
Go to the documentation of this file.
1
11#ifndef PATH_POST_PROCESSING_H
12#define PATH_POST_PROCESSING_H
13
14#include "../../util/GeospatialOperations.hpp"
15
17#include <vector>
18
20
21
30namespace pathplanners
31{
32
40 namespace postprocessing
41 {
42
51 std::vector<geoops::Waypoint> FitPathWithBSpline(const std::vector<geoops::Waypoint>& vRawPath)
52 {
53 // Create instance variables.
54 int nNumPoints = static_cast<int>(vRawPath.size()) / 8;
55
56 // Check if the path is empty or if the number of points is too small.
57 if (vRawPath.size() <= 3)
58 {
59 return vRawPath;
60 }
61
62 // Extract dX and dY coordinates.
63 std::vector<double> vX, vY;
64 for (const geoops::Waypoint& stWaypoint : vRawPath)
65 {
66 vX.push_back(stWaypoint.GetUTMCoordinate().dEasting);
67 vY.push_back(stWaypoint.GetUTMCoordinate().dNorthing);
68 }
69
70 // Create parameter values for each point. (cumulative distance)
71 std::vector<double> vT(vRawPath.size());
72 vT[0] = 0.0;
73 for (size_t siI = 1; siI < vRawPath.size(); siI++)
74 {
75 double dDist = std::sqrt(std::pow(vX[siI] - vX[siI - 1], 2) + std::pow(vY[siI] - vY[siI - 1], 2));
76 vT[siI] = vT[siI - 1] + dDist;
77 }
78
79 // Normalize parameter values to [0, 1].
80 double dMaxT = vT.back();
81 for (auto& dT1 : vT)
82 {
83 dT1 /= dMaxT;
84 }
85
86 // Fit cubic spline.
87 std::vector<geoops::Waypoint> vSplinePath;
88
89 // Keep the first point.
90 vSplinePath.push_back(vRawPath.front());
91
92 // Generate evenly spaced points along the spline.
93 for (int siI = 1; siI < nNumPoints - 1; siI++)
94 {
95 double dT = static_cast<double>(siI) / (nNumPoints - 1);
96
97 // Find the spline siSegment this parameter belongs to.
98 size_t siSegment = 0;
99 while (siSegment < vT.size() - 1 && vT[siSegment + 1] < dT)
100 {
101 siSegment++;
102 }
103
104 // Compute local parameter.
105 double dLocalT = (dT - vT[siSegment]) / (vT[siSegment + 1] - vT[siSegment]);
106
107 // Calculate indices for cubic interpolation.
108 int nI0 = std::max(0, static_cast<int>(siSegment) - 1);
109 int nI1 = siSegment;
110 int nI2 = std::min(static_cast<int>(vRawPath.size()) - 1, static_cast<int>(siSegment) + 1);
111 int nI3 = std::min(static_cast<int>(vRawPath.size()) - 1, static_cast<int>(siSegment) + 2);
112
113 // Catmull-Rom spline interpolation.
114 double dT1 = dLocalT;
115 double dT2 = dT1 * dT1;
116 double dT3 = dT2 * dT1;
117
118 double dH00 = 2 * dT3 - 3 * dT2 + 1;
119 double dH10 = dT3 - 2 * dT2 + dT1;
120 double dH01 = -2 * dT3 + 3 * dT2;
121 double dH11 = dT3 - dT2;
122
123 double dX = dH00 * vX[nI1] + dH10 * (vX[nI2] - vX[nI0]) + dH01 * vX[nI2] + dH11 * (vX[nI3] - vX[nI1]);
124 double dY = dH00 * vY[nI1] + dH10 * (vY[nI2] - vY[nI0]) + dH01 * vY[nI2] + dH11 * (vY[nI3] - vY[nI1]);
125
126 // Create waypoint.
127 geoops::UTMCoordinate stUTMResult(dX, dY, vRawPath[0].GetUTMCoordinate().nZone, vRawPath[0].GetUTMCoordinate().bWithinNorthernHemisphere);
128 vSplinePath.push_back(geoops::Waypoint(stUTMResult));
129 }
130
131 // Keep the last point.
132 vSplinePath.push_back(vRawPath.back());
133
134 return vSplinePath;
135 }
136
137
146 std::vector<geoops::Waypoint> FitPathWithBSpline(const std::vector<geoops::UTMCoordinate>& vRawPath)
147 {
148 // Convert UTM coordinates to Waypoints.
149 std::vector<geoops::Waypoint> vWaypoints;
150 for (const geoops::UTMCoordinate& stUTMCoordinate : vRawPath)
151 {
152 vWaypoints.emplace_back(geoops::Waypoint(stUTMCoordinate));
153 }
154
155 // Call the other function to fit the path.
156 return FitPathWithBSpline(vWaypoints);
157 }
158
159
168 std::vector<geoops::Waypoint> FitPathWithBSpline(const std::vector<geoops::GPSCoordinate>& vRawPath)
169 {
170 // Convert UTM coordinates to Waypoints.
171 std::vector<geoops::Waypoint> vWaypoints;
172 for (const geoops::GPSCoordinate& stUTMCoordinate : vRawPath)
173 {
174 vWaypoints.emplace_back(geoops::Waypoint(stUTMCoordinate));
175 }
176
177 // Call the other function to fit the path.
178 return FitPathWithBSpline(vWaypoints);
179 }
180 } // namespace postprocessing
181} // namespace pathplanners
182
183#endif
std::vector< geoops::Waypoint > FitPathWithBSpline(const std::vector< geoops::Waypoint > &vRawPath)
Fits a B-spline to the given path using cubic interpolation.
Definition PathPostProcessing.hpp:51
This namespace stores classes, functions, and structs that are used to implement different path plann...
Definition AStar.cpp:30
This struct stores/contains information about a GPS data.
Definition GeospatialOperations.hpp:99
This struct stores/contains information about a UTM coordinate.
Definition GeospatialOperations.hpp:195
This struct is used by the WaypointHandler class to store location, size, and type information about ...
Definition GeospatialOperations.hpp:392