Called in the obstacle avoidance state to plan a path around obstacles blocking our path.
414 {
415
416 m_vPathCoordinates.clear();
417
418
419
421
422
423 m_stStartNode = nodes::AStarNode(nullptr, stStartCoordinate);
424
426
427 m_stGoalNode = nodes::AStarNode(nullptr, stRoundedGoal);
428
429
430
431
432
433
434
435
436
437 std::vector<nodes::AStarNode> vOpenList;
438 std::make_heap(vOpenList.begin(), vOpenList.end(), std::greater<nodes::AStarNode>());
439
440 std::unordered_map<std::string, double> umOpenListLookup;
441
442
443
444 std::vector<std::shared_ptr<nodes::AStarNode>> vClosedList;
445
446
447 std::unordered_map<std::string, double> umClosedList;
448
449
450 vOpenList.push_back(m_stStartNode);
451
453 umOpenListLookup.emplace(std::make_pair(szLocationString, 0.0));
454
455
456 while (!vOpenList.empty())
457 {
458
459 std::pop_heap(vOpenList.begin(), vOpenList.end(), std::greater<nodes::AStarNode>());
460 nodes::AStarNode stNextParent = vOpenList.back();
461
462 vOpenList.pop_back();
463
464
465 vClosedList.push_back(std::make_shared<nodes::AStarNode>(stNextParent));
466
467
468 std::vector<nodes::AStarNode> vSuccessors;
469
470
471 ushort usSuccessorTracker = 0;
472 for (int nEastingDirection = -1; nEastingDirection <= 1; nEastingDirection += 1)
473 {
474 for (int nNorthingDirection = -1; nNorthingDirection <= 1; nNorthingDirection += 1)
475 {
476 double dSuccessorEasting = stNextParent.stNodeLocation.dEasting + (nEastingDirection * constants::ASTAR_NODE_SIZE);
477 double dSuccessorNorthing = stNextParent.stNodeLocation.dNorthing + (nNorthingDirection * constants::ASTAR_NODE_SIZE);
478
479
480 usSuccessorTracker++;
481 if (usSuccessorTracker == 5)
482 {
483 continue;
484 }
485
486
488 {
489 continue;
490 }
491
492
493
495
496
497 stSuccessorCoordinate.dEasting = dSuccessorEasting;
498 stSuccessorCoordinate.dNorthing = dSuccessorNorthing;
500
501 nodes::AStarNode stNextSuccessor(vClosedList.back(), stSuccessorCoordinate);
502
503 vSuccessors.emplace_back(stNextSuccessor);
504 }
505 }
506
507
508 for (size_t i = 0; i < vSuccessors.size(); i++)
509 {
510
511 bool bAtGoal = false;
512 double dDeltaEasting;
513 double dDeltaNorthing;
514
515
516
518 bool bGeoSuccess = stDistanceToGoal.dDistanceMeters > 0.01;
519
520
521 if (bGeoSuccess)
522 {
523 bAtGoal = stDistanceToGoal.dDistanceMeters < constants::ASTAR_NODE_SIZE;
524 }
525
526 else
527 {
528 dDeltaEasting = std::abs(vSuccessors[i].stNodeLocation.dEasting - m_stGoalNode.stNodeLocation.dEasting);
529 dDeltaNorthing = std::abs(vSuccessors[i].stNodeLocation.dNorthing - m_stGoalNode.stNodeLocation.dNorthing);
530 bAtGoal = dDeltaEasting < constants::ASTAR_NODE_SIZE && dDeltaNorthing < constants::ASTAR_NODE_SIZE;
531 }
532
533
534 if (bAtGoal)
535 {
537 return m_vPathCoordinates;
538 }
539
540
542
543
544
545 vSuccessors[i].dKg = stNextParent.dKg + constants::ASTAR_NODE_SIZE;
546
547
548 if (bGeoSuccess)
549 {
550 vSuccessors[i].dKh = stDistanceToGoal.dDistanceMeters;
551 }
552
553 else
554 {
555 vSuccessors[i].dKh = std::sqrt(std::pow(dDeltaEasting, 2) + std::pow(dDeltaNorthing, 2));
556 }
557
558
559 vSuccessors[i].dKf = vSuccessors[i].dKg + vSuccessors[i].dKh;
560
561
562 if (umOpenListLookup.count(szSuccessorLookup))
563 {
564 if (umOpenListLookup[szSuccessorLookup] <= vSuccessors[i].dKf)
565 {
566 continue;
567 }
568 }
569
570
571 if (umClosedList.count(szSuccessorLookup))
572 {
573 if (umClosedList[szSuccessorLookup] <= vSuccessors[i].dKf)
574 {
575 continue;
576 }
577 }
578
579
580
581 umOpenListLookup.emplace(std::make_pair(szSuccessorLookup, vSuccessors[i].dKf));
582
583 vOpenList.push_back(vSuccessors[i]);
584 std::push_heap(vOpenList.begin(), vOpenList.end(), std::greater<nodes::AStarNode>());
585 }
586
587
589
590 umClosedList.emplace(std::make_pair(szParentLookup, stNextParent.dKf));
591 }
592
593
594 LOG_ERROR(logging::g_qSharedLogger,
595 "ASTAR Failed to find a path from UTM point ({}, {}) to UTM point ({}, {})",
596 m_stStartNode.stNodeLocation.dEasting,
597 m_stStartNode.stNodeLocation.dNorthing,
598 m_stGoalNode.stNodeLocation.dEasting,
599 m_stGoalNode.stNodeLocation.dNorthing);
600
601 return m_vPathCoordinates;
602 }
geoops::UTMCoordinate RoundUTMCoordinate(const geoops::UTMCoordinate &stCoordinateToRound)
Helper function used to round UTMCoordinates to the nearest constants::ASTAR_NODE_SIZE to avoid round...
Definition AStar.cpp:362
std::string UTMCoordinateToString(const geoops::UTMCoordinate &stToTranslate)
Helper function used to translate a UTMCoordinate's dEasting and dNorthing values into a string that ...
Definition AStar.cpp:300
void UpdateObstacleData(const std::vector< sl::ObjectData > &vObstacles, const bool &bClearObstacles=true)
This method clears any saved obstacles in AStar, takes in a vector of sl::ObjectData objects and tran...
Definition AStar.cpp:79
void ConstructPath(const nodes::AStarNode &stFinalNode)
Called when a goal node has been reached. Recursively builds a vector of UTMCoordinates by tracing th...
Definition AStar.cpp:379
bool ValidCoordinate(const double &dEasting, const double &dNorthing)
Helper function used to determine if a potential UTMCoordinate is valid. Returns False if there is an...
Definition AStar.cpp:320
geoops::UTMCoordinate FindNearestBoundaryPoint(const geoops::UTMCoordinate &stGoalCoordinate)
Helper function for the PlanAvoidancePath method. This method takes in a UTMCoordinate reference and ...
Definition AStar.cpp:180
GeoMeasurement CalculateGeoMeasurement(const GPSCoordinate &stCoord1, const GPSCoordinate &stCoord2)
The shortest path between two points on an ellipsoid at (lat1, lon1) and (lat2, lon2) is called the g...
Definition GeospatialOperations.hpp:445
This struct is used to store the distance, arc length, and relative bearing for a calculated geodesic...
Definition GeospatialOperations.hpp:82
This struct stores/contains information about a UTM coordinate.
Definition GeospatialOperations.hpp:244