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
GeoPlanner.h
Go to the documentation of this file.
1
10#ifndef GEOPLANNER_H
11#define GEOPLANNER_H
12
13#include "../../handlers/LiDARHandler.h"
14#include "../../util/GeospatialOperations.hpp"
15#include "../../util/logging/PathTracer.hpp"
16
18#include <OpenMS/DATASTRUCTURES/KDTree.h>
19#include <RoveComm/RoveComm.h>
20#include <RoveComm/RoveCommManifest.h>
21#include <mutex>
22#include <queue>
23#include <unordered_map>
24#include <unordered_set>
25#include <vector>
26
28
29
38namespace pathplanners
39{
40
41
49 {
50 public:
51 double dEasting;
52 double dNorthing;
53 };
54
55
63 {
64 public:
65 using result_type = double;
66
67 inline result_type operator()(const LiDARHandler::PointRow& v, size_t idx) const { return (idx == 0) ? v.dEasting : v.dNorthing; }
68
69 inline result_type operator()(const KDQueryPoint& v, size_t idx) const { return (idx == 0) ? v.dEasting : v.dNorthing; }
70 };
71
72 // KD-Tree typedef for 2D PointRows using our accessor.
73 using KDTree2D = KDTree::KDTree<2, LiDARHandler::PointRow, PointKDAccessor>;
74
75
86 {
87 public:
89 // Declare class methods.
91
92 GeoPlanner(double dTileSize = 50.0);
94 std::vector<geoops::Waypoint> PlanPath(LiDARHandler* pLiDARHandler,
95 const geoops::UTMCoordinate& stStart,
96 const geoops::UTMCoordinate& stEnd,
97 double dSearchRadius = 2.0,
98 double dMaxSearchTimeSeconds = 240.0,
99 bool bPlotPath = false);
100 void ClearGeoCache();
101
103 // Setters.
105 void SetTileSize(double dTileSize);
106 void SetMinTravScore(double dMinTravScore);
107 void SetBetaBias(double dBetaBias);
108
110 // Getters.
112 double GetTileSize() const;
113 double GetMinTravScore() const;
114 double GetBetaBias() const;
115
116 private:
118 // Declare private class structs.
120
121 /*
122 * AStar's algorithm related structs.
123 */
124
125
133 {
134 public:
135 int nID = -1; // The unique identifier for the LiDAR point. (node)
136 double dEasting = 0.0; // The easting coordinate of the point.
137 double dNorthing = 0.0; // The northing coordinate of the point.
138 double dAltitude = 0.0; // The altitude of the point.
139 int nZone = 0; // The UTM zone of the point.
140 bool bInNorthernHemisphere = true; // Whether the point is in the northern hemisphere.
141 double dGCost = std::numeric_limits<double>::infinity(); // The cost from the start node to this node.
142 double dHCost = 0.0; // The heuristic cost from this node to the end node.
143 };
144
145
153 {
154 public:
155 bool operator()(const PlannerState& stLeftHandSide, const PlannerState& stRightHandSide) const
156 {
157 // Tiebreaker: Compare based on cost, lower cost means higher priority. We want to keep the right-hand side if it has a lower cost.
158 return (stLeftHandSide.dGCost + stLeftHandSide.dHCost) > (stRightHandSide.dGCost + stRightHandSide.dHCost);
159 }
160 };
161
162 /*
163 * Implicit graph representation with tiles.
164 */
165
166
176 struct TileKey
177 {
178 public:
179 int nX; // X coordinate of the tile.
180 int nY; // Y coordinate of the tile.
181
182
192 bool operator==(const TileKey& stOther) const { return nX == stOther.nX && nY == stOther.nY; }
193 };
194
195
204 {
205 public:
206 size_t operator()(const TileKey& stKey) const noexcept
207 {
208 // Combine the X and Y ints into one size_t hash.
209 return (std::hash<int>()(stKey.nX) << 16) ^ std::hash<int>()(stKey.nY);
210 }
211 };
212
213
223 {
224 public:
225 bool operator()(const TileKey& stLeftHandSide, const TileKey& stRightHandSide) const noexcept
226 {
227 // Check if both X and Y coordinates are equal.
228 return (stLeftHandSide.nX == stRightHandSide.nX) && (stLeftHandSide.nY == stRightHandSide.nY);
229 }
230 };
231
233 // Declare private methods.
235
236 bool InitializeSearch(const geoops::UTMCoordinate& stStart, const geoops::UTMCoordinate& stEnd);
237 void SearchAStar();
238 std::vector<geoops::Waypoint> ReconstructPath() const;
239 void CheckAndLoadTile(const PlannerState& stCurrentState);
241 void PlotPathAndTerrain(const std::vector<geoops::Waypoint>& vPath) const;
242 double EuclideanDistance(double dEasting1, double dNorthing1, double dAltitude1, double dEasting2, double dNorthing2, double dAltitude2) const;
243
244
251 const std::function<void(const rovecomm::RoveCommPacket<float>&, const sockaddr_in&)> MinTravScore =
252 [this](const rovecomm::RoveCommPacket<float>& stPacket, const sockaddr_in& stdAddr)
253 {
254 // Not using this.
255 (void) stdAddr;
256
257 // Set minimum travel score from incoming packet.
258 if (stPacket.vData.size() > 0)
259 {
260 // Set minimum travel score.
261 m_dMinTravScore = static_cast<double>(stPacket.vData[0]);
262 // Clear the tile cache.
263 this->ClearGeoCache();
264
265 // Submit logger message.
266 LOG_NOTICE(logging::g_qSharedLogger,
267 "Incoming Packet: Setting GeoPlanner minimum travel score to {}. The tile cache has also been cleared.",
268 this->m_dMinTravScore);
269 }
270 };
271
272
279 const std::function<void(const rovecomm::RoveCommPacket<float>&, const sockaddr_in&)> BetaBias =
280 [this](const rovecomm::RoveCommPacket<float>& stPacket, const sockaddr_in& stdAddr)
281 {
282 // Not using this.
283 (void) stdAddr;
284
285 // Set minimum travel score from incoming packet.
286 if (stPacket.vData.size() > 0)
287 {
288 m_dBeta = static_cast<double>(stPacket.vData[0]);
289 // Submit logger message.
290 LOG_NOTICE(logging::g_qSharedLogger, "Incoming Packet: Setting GeoPlanner beta bias to {}", this->m_dBeta);
291 }
292 };
293
295 // Private member variables.
297
298 int m_nStartID, m_nEndID; // Unique identifiers for the start and end points.
299 double m_dBeta; // Bias factor for travel scores.
300 double m_dMinTravScore; // Minimum travel score threshold for path planning.
301 double m_dTileSize; // Size of the grid tiles in meters.
302 double m_dSearchRadius; // Search radius for finding neighbors.
303 double m_dMaxSearchTimeSeconds; // The maximum time to spend searching for a path in seconds.
304 LiDARHandler* m_pLiDARHandler; // Pointer to the LiDARHandler instance for fetching geospatial data.
305 std::unique_ptr<logging::graphing::PathTracer> m_pPathTracer; // Path tracer for 3D visualization.
306 std::unique_ptr<KDTree2D> m_pKDTree; // KD-tree for fast spatial queries over loaded tiles.
307 std::mutex m_muPathGenMutex; // Mutex to protect path planning operations.
308
309 // AStar's algorithm related variables.
310
311 /*
312 * The core of AStar's algorithm is a priority queue (min-heap) that stores the open set of nodes to be evaluated.
313 * The priority queue is ordered by the estimated total cost (f = g + h) of reaching the goal from the start node
314 * through each node. We also maintain a map to track the best path to each node (predecessors) and a set of
315 * nodes that have already been evaluated (closedSet).
316 */
317 std::priority_queue<PlannerState, std::vector<PlannerState>, PlannerStateCompare> m_pqOpenSetNextBest; // Priority queue (min-heap) to be evaled.
318 std::unordered_map<int, int> m_umPredecessors; // Maps point IDs to their predecessor's ID.
319 std::unordered_set<int> m_usClosedSet; // Set of point IDs that have been evaluated.
320 std::unordered_map<int, PlannerState> m_umAllStates; // Maps point IDs to their corresponding PlannerState.
321
322 // Implicit graph representation with tiles.
323 std::unordered_map<TileKey, std::vector<LiDARHandler::PointRow>, TileKeyHash, TileKeyEqual> m_umTileMapCache; // Maps tile keys to LiDAR points.
324 // KD-tree insertion bookkeeping to avoid duplicate inserts and to batch optimizations.
325 std::unordered_set<TileKey, TileKeyHash, TileKeyEqual> m_usKDTreeInsertedTiles; // Tracks which tiles' points have been inserted
326 };
327} // namespace pathplanners
328
329#endif // GEOPLANNER_H
Definition LiDARHandler.h:31
This class implements a geospatial path planner that uses AStar's algorithm with a bias towards trave...
Definition GeoPlanner.h:86
std::vector< geoops::Waypoint > ReconstructPath() const
Plan a path from the start to the end UTM coordinates using A* algorithm.
Definition GeoPlanner.cpp:469
void CheckAndLoadTile(const PlannerState &stCurrentState)
Check if the tile containing the current state is loaded, and if not, load it.
Definition GeoPlanner.cpp:527
double GetMinTravScore() const
Get the minimum traversal score for path planning.
Definition GeoPlanner.cpp:241
void SetTileSize(double dTileSize)
Set the size of each tile in meters.
Definition GeoPlanner.cpp:189
const std::function< void(const rovecomm::RoveCommPacket< float > &, const sockaddr_in &)> MinTravScore
Callback function used to set the minimum travel score for path planning.
Definition GeoPlanner.h:251
void PlotPathAndTerrain(const std::vector< geoops::Waypoint > &vPath) const
Plot the given path and the terrain points that the path goes through.
Definition GeoPlanner.cpp:656
void SetMinTravScore(double dMinTravScore)
Set the minimum traversal score for path planning.
Definition GeoPlanner.cpp:202
double GetBetaBias() const
Get the beta bias for travel scores in path planning.
Definition GeoPlanner.cpp:254
~GeoPlanner()
Destroy the Geo Planner:: Geo Planner object.
Definition GeoPlanner.cpp:71
bool InitializeSearch(const geoops::UTMCoordinate &stStart, const geoops::UTMCoordinate &stEnd)
Initialize the search by caching the start and end tiles and setting up initial states.
Definition GeoPlanner.cpp:270
std::vector< geoops::Waypoint > PlanPath(LiDARHandler *pLiDARHandler, const geoops::UTMCoordinate &stStart, const geoops::UTMCoordinate &stEnd, double dSearchRadius=2.0, double dMaxSearchTimeSeconds=240.0, bool bPlotPath=false)
Plan a path from the start to the end UTM coordinates using A* algorithm.
Definition GeoPlanner.cpp:91
double EuclideanDistance(double dEasting1, double dNorthing1, double dAltitude1, double dEasting2, double dNorthing2, double dAltitude2) const
Calculate the distance between two UTM coordinates.
Definition GeoPlanner.cpp:762
void SearchAStar()
Perform the A* search algorithm to find the optimal path.
Definition GeoPlanner.cpp:320
void SetBetaBias(double dBetaBias)
Set the beta bias for travel scores in path planning.
Definition GeoPlanner.cpp:215
double GetTileSize() const
Get the size of each tile in meters.
Definition GeoPlanner.cpp:228
const std::function< void(const rovecomm::RoveCommPacket< float > &, const sockaddr_in &)> BetaBias
Callback function used to set the beta bias for travel scores in path planning.
Definition GeoPlanner.h:279
PlannerState FindClosestLiDARPoint(const geoops::UTMCoordinate &stCoordinate)
Find the closest LiDAR point to the given UTM coordinate.
Definition GeoPlanner.cpp:617
void ClearGeoCache()
Clear all cached tiles and KD-Tree data.
Definition GeoPlanner.cpp:172
uint32_t v
This namespace stores classes, functions, and structs that are used to implement different path plann...
Definition AStar.cpp:30
Definition LiDARHandler.h:38
This struct stores/contains information about a UTM coordinate.
Definition GeospatialOperations.hpp:210
This struct is used to compare two PlannerState objects based on their cost.
Definition GeoPlanner.h:153
This struct represents the state of a node in the path planning algorithm.
Definition GeoPlanner.h:133
This struct is used to compare two TileKey objects for equality. After the hashbuckets narrow down ca...
Definition GeoPlanner.h:223
This struct is used to hash TileKey objects for use in unordered maps. It combines the X and Y coordi...
Definition GeoPlanner.h:204
This struct represents a tile key in the implicit graph representation. We divide the plan into a reg...
Definition GeoPlanner.h:177
bool operator==(const TileKey &stOther) const
Overridden operator equals for TileKey struct.
Definition GeoPlanner.h:192
Small POD used for KDTree searches (2D point)
Definition GeoPlanner.h:49
Accessor for KDTree that exposes easting/northing for both PointRow and KDQueryPoint.
Definition GeoPlanner.h:63