5#include <unordered_map>
9#include "TinyRobotics/coordinates/Coordinate.h"
10#include "TinyRobotics/utils/AllocatorPSRAM.h"
12namespace tinyrobotics {
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
51template <
typename T = DistanceM>
54 using CostCallback = std::function<
float(
const Coordinate<T>&,
56 using ValidCallback = std::function<
bool(
const Coordinate<T>&,
void* ref)>;
72 std::string startStr = start.toCString();
73 std::string goalStr = goal.toCString();
74 TRLogger.debug(
"Finding path from %s to %s", startStr.c_str(),
76 using NodeMap = std::unordered_map<
81 bool found = aStarSearch(map, start, goal, &cameFrom,
nullptr);
83 return reconstructPath(cameFrom, start, goal);
85 return Path<Coordinate<T>>();
89
90
91
94 using NodeMap = std::unordered_map<
99 bool found = aStarSearch(map, start, goal, &cameFrom,
nullptr);
101 Path<Coordinate<T>> path = reconstructPath(cameFrom, start, goal);
102 if (path.size() >= 2) {
113 float estimatedTotalCost = 0;
114 bool operator>(
const NodeRecord& other)
const {
115 return estimatedTotalCost > other.estimatedTotalCost;
132 std::priority_queue<NodeRecord, std::vector<NodeRecord>,
133 std::greater<NodeRecord>>
139 openSet.push({start, 0.0f, cost_cb(start, goal, ref)});
140 costSoFar[start] = 0.0f;
141 if (cameFrom) cameFrom->clear();
142 while (!openSet.empty()) {
143 Coordinate<T> current = openSet.top().node;
144 if (current == goal) {
145 if (outCostSoFar) *outCostSoFar = costSoFar;
149 for (
const auto& neighbor : map.getNeighbors(current)) {
150 if (!valid_cb(neighbor, ref))
continue;
151 float newCost = costSoFar[current] + cost_cb(current, neighbor, ref);
152 if (!costSoFar.count(neighbor) || newCost < costSoFar[neighbor]) {
153 costSoFar[neighbor] = newCost;
154 float priority = newCost + cost_cb(neighbor, goal, ref);
155 openSet.push({neighbor, newCost, priority});
156 if (cameFrom) (*cameFrom)[neighbor] = current;
160 if (outCostSoFar) *outCostSoFar = costSoFar;
165 CostCallback cost_cb = defaultCost;
166 ValidCallback valid_cb = defaultValid;
171 return from.distance(to);
174 static bool defaultValid(
const Coordinate<T>& node,
void* ref) {
178 Path<Coordinate<T>> reconstructPath(
179 const std::unordered_map<
180 Coordinate<T>, Coordinate<T>, std::hash<Coordinate<T>>,
181 std::equal_to<Coordinate<T>>,
182 AllocatorPSRAM<std::pair<
const Coordinate<T>, Coordinate<T>>>>&
184 const Coordinate<T>& start,
const Coordinate<T>& goal) {
185 Path<Coordinate<T>> path;
187 while (current != start) {
188 path.addWaypoint(current);
189 auto it = cameFrom.find(current);
190 if (it == cameFrom.end())
break;
191 current = it->second;
193 path.addWaypoint(start);
Flexible A* pathfinding algorithm for any map implementing IMap<T> and using Coordinate<T> nodes.
Definition: AStar.h:52
Coordinate< T > nextStep(const IMapNeighbors< T > &map, const Coordinate< T > &start, const Coordinate< T > &goal)
Definition: AStar.h:92
void setValidCallback(ValidCallback cb)
provide a callback to determine if a node is valid (e.g., not an obstacle)
Definition: AStar.h:63
Path< Coordinate< T > > findPath(const IMapNeighbors< T > &map, const Coordinate< T > &start, const Coordinate< T > &goal)
Definition: AStar.h:70
void setReference(void *reference)
Definition: AStar.h:66
void setCostCallback(CostCallback cb)
Definition: AStar.h:61
Custom allocator that uses ESP32's PSRAM for memory allocation.
Definition: AllocatorPSRAM.h:21
A generic 3D coordinate class for robotics, navigation, and spatial calculations.
Definition: Coordinate.h:57