TinyRobotics
Loading...
Searching...
No Matches
Dijkstra.h
1#pragma once
2#include <functional>
3#include <limits>
4#include <queue>
5#include <unordered_map>
6#include <vector>
7
8#include "TinyRobotics/coordinates/Coordinate.h"
9#include "TinyRobotics/planning/Path.h"
10#include "TinyRobotics/utils/Common.h"
11
12namespace tinyrobotics {
13
14/**
15 * @class Dijkstra
16 * @ingroup planning
17 * @brief Generic Dijkstra shortest path algorithm for graphs/maps with
18 * callback-based cost and validity.
19 *
20 * @tparam MapType Must provide:
21 * - std::vector<Node> getNeighbors(const Node& node) const
22 */
23template <typename T = DistanceM>
24class Dijkstra {
25 public:
26 using CostCallback = std::function<float(const Coordinate<T>&,
27 const Coordinate<T>&, void* ref)>;
28 using ValidCallback = std::function<bool(const Coordinate<T>&, void* ref)>;
29
30 Dijkstra() = default;
31
32 /// provide a callback to determine the cost of moving from one node to
33 /// another
34 void setCostCallback(CostCallback cb) { cost_cb = cb; }
35 /// provide a callback to determine if a node is valid (e.g., not an obstacle)
36 void setValidCallback(ValidCallback cb) { valid_cb = cb; }
37 /// provide reference for callbacks (e.g., to access map data or other
38 /// context)
39 void setReference(void* reference) { ref = reference; }
40
41 /**
42 * @brief Finds the shortest path from start to goal.
43 * @param start The starting node.
44 * @param goal The goal node.
45 * @return Vector of nodes representing the path (empty if no path found).
46 */
48 const Coordinate<T>& goal) {
49 using Pair = std::pair<float, Coordinate<T>>;
50 std::priority_queue<Pair, std::vector<Pair>, std::greater<Pair>> open;
51 std::unordered_map<Coordinate<T>, float> cost_so_far;
52 std::unordered_map<Coordinate<T>, Coordinate<T>> came_from;
53
54 open.emplace(0.0f, start);
55 cost_so_far[start] = 0.0f;
56 came_from[start] = start;
57
58 while (!open.empty()) {
59 Coordinate<T> current = open.top().second;
60 open.pop();
61
62 if (current == goal) break;
63
64 for (const Coordinate<T>& next : map.getNeighbors(current)) {
65 if (!valid_cb(next, ref)) continue;
66 float new_cost = cost_so_far[current] + cost_cb(current, next, ref);
67 if (!cost_so_far.count(next) || new_cost < cost_so_far[next]) {
68 cost_so_far[next] = new_cost;
69 came_from[next] = current;
70 open.emplace(new_cost, next);
71 }
72 }
73 }
74
75 // Reconstruct path
76 Path<Coordinate<T>> path;
77 if (!came_from.count(goal)) return path;
78 for (Coordinate<T> at = goal; at != start; at = came_from[at]) {
79 path.addWaypoint(at);
80 }
81 path.addWaypoint(start);
82 path.reverse();
83 return path;
84 }
85
86 protected:
87 CostCallback cost_cb = defaultCost;
88 ValidCallback valid_cb = defaultValid;
89 void* ref = this;
90
91 static float defaultCost(const Coordinate<T>& from, const Coordinate<T>& to,
92 void* ref) {
93 return from.distance(to);
94 }
95
96 static bool defaultValid(const Coordinate<T>& node, void* ref) {
97 return true; // By default, all nodes are valid
98 }
99};
100
101} // namespace tinyrobotics
A generic 3D coordinate class for robotics, navigation, and spatial calculations.
Definition: Coordinate.h:57
Generic Dijkstra shortest path algorithm for graphs/maps with callback-based cost and validity.
Definition: Dijkstra.h:24
void setValidCallback(ValidCallback cb)
provide a callback to determine if a node is valid (e.g., not an obstacle)
Definition: Dijkstra.h:36
Path< Coordinate< T > > findPath(const IMapNeighbors< T > &map, const Coordinate< T > &start, const Coordinate< T > &goal)
Finds the shortest path from start to goal.
Definition: Dijkstra.h:47
void setReference(void *reference)
Definition: Dijkstra.h:39
void setCostCallback(CostCallback cb)
Definition: Dijkstra.h:34