11#define DRONE_FLIGHT_HEIGHT 175
19 UpdateOrigin(origin, size);
28 for (uint32_t y{}; y < m_RoutemakerWidth; ++y) {
29 for (uint32_t x{}; x < m_RoutemakerWidth; ++x) {
30 NodePtr node{ GetNode(x, y) };
31 node->Parent = std::weak_ptr<Node<Cell2D>>();
32 node->GlobalGoal = std::numeric_limits<double>::infinity();
33 node->LocalGoal = std::numeric_limits<double>::infinity();
34 node->Visited =
false;
46 if (m_MapWidth < 250) {
48 }
else if (m_MapWidth < 500) {
50 }
else if (m_MapWidth < 1000) {
52 }
else if (m_MapWidth < 2000) {
58 m_RoutemakerWidth = m_MapWidth / m_RoutemakerRes;
66 m_HeightMap->UpdateOrigin(utmOrigin, size);
69 m_Nodes = std::vector<NodePtr>(m_RoutemakerWidth * m_RoutemakerWidth);
71 for (uint32_t y{ 0 }; y < m_RoutemakerWidth; ++y) {
72 for (uint32_t x{ 0 }; x < m_RoutemakerWidth; ++x) {
73 uint32_t xRel{ x * m_RoutemakerRes };
74 uint32_t yRel{ y * m_RoutemakerRes };
76 bool occupied{
false };
77 for (
int j{ 0 }; j < m_RoutemakerRes; ++j) {
78 for (
int i{ 0 }; i < m_RoutemakerRes; ++i) {
79 float heightCandidate;
80 if (m_HeightMap->GetHeight(
static_cast<int>(xRel) + i,
81 static_cast<int>(yRel) + j,
83 height = std::max(height, heightCandidate);
91 node.
Data = { x, y, occupied };
92 m_Nodes[x + y * m_RoutemakerWidth] =
93 std::make_shared<Node<Cell2D>>(node);
102 std::vector<Routemaker::NodePtr>
105 std::vector<NodePtr> neighbors;
107 uint32_t x{ node->Data.X };
108 uint32_t y{ node->Data.Y };
111 NodePtr neighbor{ GetNode(x - 1, y) };
112 if (!neighbor->Data.Occupied) {
113 neighbors.push_back(neighbor);
116 if (x < m_RoutemakerWidth - 1) {
117 NodePtr neighbor{ GetNode(x + 1, y) };
118 if (!neighbor->Data.Occupied) {
119 neighbors.push_back(neighbor);
123 NodePtr neighbor{ GetNode(x, y - 1) };
124 if (!neighbor->Data.Occupied) {
125 neighbors.push_back(neighbor);
129 if (y < m_RoutemakerWidth - 1) {
130 NodePtr neighbor{ GetNode(x, y + 1) };
131 if (!neighbor->Data.Occupied) {
132 neighbors.push_back(neighbor);
136 if ((x > 0) && (y > 0)) {
137 NodePtr neighbor{ GetNode(x - 1, y - 1) };
138 if (!neighbor->Data.Occupied) {
139 neighbors.push_back(neighbor);
143 if ((x < (m_RoutemakerWidth - 1)) && (y > 0)) {
144 NodePtr neighbor{ GetNode(x + 1, y - 1) };
145 if (!neighbor->Data.Occupied) {
146 neighbors.push_back(neighbor);
150 if ((x < (m_RoutemakerWidth - 1)) && (y < (m_RoutemakerWidth - 1))) {
151 NodePtr neighbor{ GetNode(x + 1, y + 1) };
152 if (!neighbor->Data.Occupied) {
153 neighbors.push_back(neighbor);
157 if ((x > 0) && (y < (m_RoutemakerWidth - 1))) {
158 NodePtr neighbor{ GetNode(x - 1, y + 1) };
159 if (!neighbor->Data.Occupied) {
160 neighbors.push_back(neighbor);
170 double x1{
static_cast<double>(a->Data.X) * m_RoutemakerRes };
171 double y1{
static_cast<double>(a->Data.Y) * m_RoutemakerRes };
172 double x2{
static_cast<double>(b->Data.X) * m_RoutemakerRes };
173 double y2{
static_cast<double>(b->Data.Y) * m_RoutemakerRes };
177 return std::sqrt(std::pow(x2 - x1, 2) + std::pow(y2 - y1, 2));
187 bool hasLineOfSight{
true };
189 std::list<NodePtr> nodes{ BresenhamLine(a, b) };
190 std::for_each(nodes.begin(), nodes.end(),
191 [&hasLineOfSight](
const NodePtr& n) {
192 if (n->Data.Occupied) {
195 hasLineOfSight = false;
199 return hasLineOfSight;
202 std::list<Routemaker::NodePtr>
203 Routemaker::BresenhamLine(
const NodePtr& a,
const NodePtr& b)
const
205 std::list<NodePtr> list;
207 auto x1{
static_cast<int32_t
>(a->Data.X) };
208 auto y1{
static_cast<int32_t
>(a->Data.Y) };
209 auto x2{
static_cast<int32_t
>(b->Data.X) };
210 auto y2{
static_cast<int32_t
>(b->Data.Y) };
212 bool isSteep{ std::abs(y2 - y1) > std::abs(x2 - x1) };
222 int32_t deltaX{ x2 - x1 };
223 int32_t deltaY{ std::abs(y2 - y1) };
224 int32_t error{}, yStep, y{ y1 };
232 for (int32_t x{ x1 }; x <= x2; ++x) {
234 list.push_back(GetNode(y, x));
236 list.push_back(GetNode(x, y));
240 if (2 * error >= deltaX) {
250 Routemaker::GetNode(uint32_t x, uint32_t y)
const
252 uint32_t index{ x + y * m_RoutemakerWidth };
253 return m_Nodes[index];
256 std::vector<Core::CartesianCoordinate>
274 asymmetricAPosition.
X /= m_RoutemakerRes;
275 asymmetricAPosition.Y /= m_RoutemakerRes;
276 asymmetricAPosition.Z /= m_RoutemakerRes;
278 asymmetricBPosition.X /= m_RoutemakerRes;
279 asymmetricBPosition.Y /= m_RoutemakerRes;
280 asymmetricBPosition.Z /= m_RoutemakerRes;
282 NodePtr start{ GetNode(
static_cast<uint32_t
>(asymmetricAPosition.X),
283 static_cast<uint32_t
>(asymmetricAPosition.Y)) };
284 NodePtr goal{ GetNode(
static_cast<uint32_t
>(asymmetricBPosition.X),
285 static_cast<uint32_t
>(asymmetricBPosition.Y)) };
287 SolveAStar(start, goal);
288 PostSmooth(start, goal);
293 std::vector<Core::CartesianCoordinate> route;
294 NodePtr current{ goal };
295 NodePtr parent{ goal->Parent.lock() };
296 while (current != start && parent !=
nullptr) {
299 (float)current->Data.
X * m_RoutemakerRes,
307 route.push_back(positionSymmetric);
309 parent = current->Parent.lock();
313 { (float)start->Data.X * m_RoutemakerRes,
316 route.push_back(positionSymmetric);
320 std::reverse(route.begin(), route.end());
static Core::CartesianCoordinate SymmetricToAsymmetric(Core::CartesianCoordinate symmetric)
Function used to convert a coordinate in a symmetric coordinate system to a coordinate in an asymmetr...
static Core::CartesianCoordinate AsymmetricToSymmetric(Core::CartesianCoordinate asymmetric)
Function used to convert a coordinate in an asymmetric cooridnate system to a coordinate in a symmetr...
std::shared_ptr< Node< Cell2D > > NodePtr
Helper alias to make code more readable.
Main class responsible for handling creation of routes between keyframes.
void UpdateOrigin(Core::UTMCoordinate UTMOrigin, int size)
Updates the origin coordinate and the size of the map.
double GetCost(NodePtr a, NodePtr b) override
Returns the cost between a and b.
std::vector< NodePtr > GetNeighbors(NodePtr node) override
Collects all neighbor nodes of node.
void ResetNodes() override
Resets all local and global goals and parent relationships of all nodes.
bool HasLineOfSight(NodePtr a, NodePtr b) override
Determines if there is a direct line of sight between node a and node b.
#define DRONE_FLIGHT_HEIGHT
A structure that represents a cartesian coordinate.
A structure representing an agent's position in cartesian space at a given point in time.
CartesianCoordinate Position
\ A structure that represents a coordinate in the Universal Transverse Mercator coordinate system
Represents a node in a Graph data structured made for path-finding.
T Data
Data stored in the the node.