TinyRobotics
Loading...
Searching...
No Matches
PathMap.h
1#pragma once
2
3#include "TinyRobotics/maps/IMap.h"
4#include "TinyRobotics/maps/PathSegment.h"
5#include "TinyRobotics/utils/AllocatorPSRAM.h"
6
7namespace tinyrobotics {
8
9/**
10 * @brief Represents a graph of valid path segments (edges) between coordinates
11 * (nodes).
12 *
13 * PathMap is used for pathfinding algorithms (A*, Dijkstra, etc.) to find
14 * optimal paths between nodes. The map can contain both directed (one-way) and
15 * undirected (two-way) segments.
16 *
17 * Features:
18 * - Add segments (edges) between coordinates (nodes)
19 * - Query outgoing and incoming segments for a given node
20 * - Supports both directed and undirected graphs
21 *
22 * Typical usage: model a road network, robot navigation graph, or any scenario
23 * where movement is constrained to a set of valid connections.
24 *
25 * @tparam Coordinate The coordinate type (e.g., 2D or 3D point).
26 */
27template <typename CoordinateT = Coordinate<float>>
28class PathMap : public IMapNeighbors<typename std::remove_reference<
29 decltype(std::declval<CoordinateT>().x)>::type> {
30 public:
31 PathMap() = default;
32
33 void addSegment(const CoordinateT& from, const CoordinateT& to,
34 bool directed = false) {
35 auto distance = from.distance(to); // Example cost based on distance
36 PathSegment<CoordinateT> segment{from, to, distance,
37 directed}; // Default cost = 1.0
38 segments.push_back(segment);
39 }
40
41 void addSegment(PathSegment<CoordinateT> segment) {
42 segments.push_back(segment);
43 }
44
45 std::vector<PathSegment<CoordinateT>> getSegments(
46 const CoordinateT& from) const {
47 std::vector<PathSegment<CoordinateT>> result;
48 for (const auto& seg : segments) {
49 if (seg.from == from) {
50 result.push_back(seg);
51 }
52 }
53 for (const auto& seg : segments) {
54 if (seg.to == from && !seg.directed) {
55 PathSegment<CoordinateT> reverse_seg = seg;
56 std::swap(reverse_seg.from, reverse_seg.to);
57 result.push_back(reverse_seg);
58 }
59 }
60 return result;
61 }
62
63 // IMap interface: getNeighbors
64 std::vector<CoordinateT> getNeighbors(CoordinateT from) const override {
65 std::vector<CoordinateT> neighbors;
66 for (const auto& seg : segments) {
67 if (seg.from == from) {
68 neighbors.push_back(seg.to);
69 }
70 if (seg.to == from && !seg.directed) {
71 neighbors.push_back(seg.from);
72 }
73 }
74 return neighbors;
75 }
76
77 // IMap interface: isValid (always true for graph nodes in PathMap)
78 bool isValid(const Coordinate<float>& coord) const override {
79 // A node is valid if it appears in any segment
80 for (const auto& seg : segments) {
81 if (seg.from == coord || seg.to == coord) return true;
82 }
83 return false;
84 }
85
86 size_t size() const { return segments.size(); }
87
88 PathSegment<CoordinateT>& operator[](size_t index) { return segments[index]; }
89
90 size_t writeTo(Print& out) { return serializer.write(*this, out); }
91
92 size_t readFrom(Stream& in) { return serializer.read(*this, in); }
93
94 void clear() { segments.clear(); }
95
96 protected:
97 std::vector<PathSegment<CoordinateT>,
98 AllocatorPSRAM<PathSegment<CoordinateT>>>
99 segments;
100 PathMapSerializer<PathMap<CoordinateT>, CoordinateT> serializer;
101};
102
103} // namespace tinyrobotics
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
Abstract interface for neighbor queries in map-like data structures.
Definition: IMap.h:27
Represents a graph of valid path segments (edges) between coordinates (nodes).
Definition: PathMap.h:29
Represents a path segment (edge) between two coordinates in a graph.
Definition: PathSegment.h:26