35double GridSearch::EuclidDistance(
36 const double x1,
const double y1,
const double x2,
const double y2) {
37 return std::sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
40bool GridSearch::CheckConstraints(std::shared_ptr<Node2d> node) {
41 const double node_grid_x = node->GetGridX();
42 const double node_grid_y = node->GetGridY();
43 if (node_grid_x > max_grid_x_ ||
45 node_grid_y > max_grid_y_ ||
49 if (obstacles_linesegments_vec_.empty()) {
52 for (
const auto& obstacle_linesegments : obstacles_linesegments_vec_) {
53 for (
const common::math::LineSegment2d& linesegment :
54 obstacle_linesegments) {
55 if (linesegment.DistanceTo({node->GetGridX(), node->GetGridY()})
64std::vector<std::shared_ptr<Node2d>> GridSearch::GenerateNextNodes(
65 std::shared_ptr<Node2d> current_node) {
66 double current_node_x = current_node->GetGridX();
67 double current_node_y = current_node->GetGridY();
68 double current_node_path_cost = current_node->GetPathCost();
69 double diagonal_distance = std::sqrt(2.0);
70 std::vector<std::shared_ptr<Node2d>> next_nodes;
71 std::shared_ptr<Node2d> up =
72 std::make_shared<Node2d>(current_node_x, current_node_y + 1.0, XYbounds_);
73 up->SetPathCost(current_node_path_cost + 1.0);
74 std::shared_ptr<Node2d> up_right = std::make_shared<Node2d>(
75 current_node_x + 1.0, current_node_y + 1.0, XYbounds_);
76 up_right->SetPathCost(current_node_path_cost + diagonal_distance);
77 std::shared_ptr<Node2d> right =
78 std::make_shared<Node2d>(current_node_x + 1.0, current_node_y, XYbounds_);
79 right->SetPathCost(current_node_path_cost + 1.0);
80 std::shared_ptr<Node2d> down_right = std::make_shared<Node2d>(
81 current_node_x + 1.0, current_node_y - 1.0, XYbounds_);
82 down_right->SetPathCost(current_node_path_cost + diagonal_distance);
83 std::shared_ptr<Node2d> down =
84 std::make_shared<Node2d>(current_node_x, current_node_y - 1.0, XYbounds_);
85 down->SetPathCost(current_node_path_cost + 1.0);
86 std::shared_ptr<Node2d> down_left = std::make_shared<Node2d>(
87 current_node_x - 1.0, current_node_y - 1.0, XYbounds_);
88 down_left->SetPathCost(current_node_path_cost + diagonal_distance);
89 std::shared_ptr<Node2d> left =
90 std::make_shared<Node2d>(current_node_x - 1.0, current_node_y, XYbounds_);
91 left->SetPathCost(current_node_path_cost + 1.0);
92 std::shared_ptr<Node2d> up_left = std::make_shared<Node2d>(
93 current_node_x - 1.0, current_node_y + 1.0, XYbounds_);
94 up_left->SetPathCost(current_node_path_cost + diagonal_distance);
96 next_nodes.emplace_back(up);
97 next_nodes.emplace_back(up_right);
98 next_nodes.emplace_back(right);
99 next_nodes.emplace_back(down_right);
100 next_nodes.emplace_back(down);
101 next_nodes.emplace_back(down_left);
102 next_nodes.emplace_back(left);
103 next_nodes.emplace_back(up_left);
108 const double sx,
const double sy,
const double ex,
const double ey,
109 const std::vector<double>& XYbounds,
110 const std::vector<std::vector<common::math::LineSegment2d>>&
111 obstacles_linesegments_vec,
113 std::priority_queue<std::pair<std::string, double>,
114 std::vector<std::pair<std::string, double>>, cmp>
116 std::unordered_map<std::string, std::shared_ptr<Node2d>> open_set;
117 std::unordered_map<std::string, std::shared_ptr<Node2d>> close_set;
118 XYbounds_ = XYbounds;
119 std::shared_ptr<Node2d> start_node =
120 std::make_shared<Node2d>(sx, sy, xy_grid_resolution_, XYbounds_);
121 std::shared_ptr<Node2d> end_node =
122 std::make_shared<Node2d>(ex, ey, xy_grid_resolution_, XYbounds_);
123 std::shared_ptr<Node2d> final_node_ =
nullptr;
124 obstacles_linesegments_vec_ = obstacles_linesegments_vec;
125 open_set.emplace(start_node->GetIndex(), start_node);
126 open_pq.emplace(start_node->GetIndex(), start_node->GetCost());
129 size_t explored_node_num = 0;
130 while (!open_pq.empty()) {
131 std::string current_id = open_pq.top().first;
133 std::shared_ptr<Node2d> current_node = open_set[current_id];
135 if (*(current_node) == *(end_node)) {
136 final_node_ = current_node;
139 close_set.emplace(current_node->GetIndex(), current_node);
140 std::vector<std::shared_ptr<Node2d>> next_nodes =
141 std::move(GenerateNextNodes(current_node));
142 for (
auto& next_node : next_nodes) {
143 if (!CheckConstraints(next_node)) {
146 if (close_set.find(next_node->GetIndex()) != close_set.end()) {
149 if (open_set.find(next_node->GetIndex()) == open_set.end()) {
151 next_node->SetHeuristic(
152 EuclidDistance(next_node->GetGridX(), next_node->GetGridY(),
153 end_node->GetGridX(), end_node->GetGridY()));
154 next_node->SetPreNode(current_node);
155 open_set.emplace(next_node->GetIndex(), next_node);
156 open_pq.emplace(next_node->GetIndex(), next_node->GetCost());
161 if (final_node_ ==
nullptr) {
162 AERROR <<
"Grid A searching return null ptr(open_set ran out)";
165 LoadGridAStarResult(result);
166 ADEBUG <<
"explored node num is " << explored_node_num;
173 const std::vector<double>& XYbounds,
174 const std::vector<std::vector<common::math::LineSegment2d>>&
175 obstacles_linesegments_vec,
176 const std::vector<std::vector<common::math::LineSegment2d>>&
177 soft_boundary_linesegments_vec) {
178 std::priority_queue<std::pair<std::string, double>,
179 std::vector<std::pair<std::string, double>>, cmp>
181 std::unordered_map<std::string, std::shared_ptr<Node2d>> open_set;
182 dp_map_ =
decltype(dp_map_)();
183 XYbounds_ = XYbounds;
185 max_grid_y_ = std::round((XYbounds_[3] - XYbounds_[2]) / xy_grid_resolution_);
186 max_grid_x_ = std::round((XYbounds_[1] - XYbounds_[0]) / xy_grid_resolution_);
187 std::shared_ptr<Node2d> end_node =
188 std::make_shared<Node2d>(ex, ey, xy_grid_resolution_, XYbounds_);
189 obstacles_linesegments_vec_ = obstacles_linesegments_vec;
190 open_set.emplace(end_node->GetIndex(), end_node);
191 open_pq.emplace(end_node->GetIndex(), end_node->GetCost());
194 size_t explored_node_num = 0;
195 while (!open_pq.empty()) {
196 const std::string current_id = open_pq.top().first;
198 std::shared_ptr<Node2d> current_node = open_set[current_id];
199 dp_map_.emplace(current_node->GetIndex(), current_node);
200 std::vector<std::shared_ptr<Node2d>> next_nodes =
201 std::move(GenerateNextNodes(current_node));
202 for (
auto& next_node : next_nodes) {
203 if (!CheckConstraints(next_node)) {
206 if (dp_map_.find(next_node->GetIndex()) != dp_map_.end()) {
209 if (open_set.find(next_node->GetIndex()) == open_set.end()) {
211 next_node->SetPreNode(current_node);
212 open_set.emplace(next_node->GetIndex(), next_node);
213 open_pq.emplace(next_node->GetIndex(), next_node->GetCost());
215 if (open_set[next_node->GetIndex()]->GetCost() > next_node->GetCost()) {
216 open_set[next_node->GetIndex()]->SetCost(next_node->GetCost());
217 open_set[next_node->GetIndex()]->SetPreNode(current_node);
222 ADEBUG <<
"explored node num is " << explored_node_num;
228 if (dp_map_.find(index) != dp_map_.end()) {
229 return dp_map_[index]->GetCost() * xy_grid_resolution_;
231 return std::numeric_limits<double>::infinity();
236 (*result).path_cost = final_node_->GetPathCost() * xy_grid_resolution_;
237 std::shared_ptr<Node2d> current_node = final_node_;
238 std::vector<double> grid_a_x;
239 std::vector<double> grid_a_y;
240 while (current_node->GetPreNode() !=
nullptr) {
241 grid_a_x.push_back(current_node->GetGridX() * xy_grid_resolution_ +
243 grid_a_y.push_back(current_node->GetGridY() * xy_grid_resolution_ +
245 current_node = current_node->GetPreNode();
247 std::reverse(grid_a_x.begin(), grid_a_x.end());
248 std::reverse(grid_a_y.begin(), grid_a_y.end());
249 (*result).x = std::move(grid_a_x);
250 (*result).y = std::move(grid_a_y);
Implements a class of 2-dimensional vectors.
GridSearch(const PlannerOpenSpaceConfig &open_space_conf)
double CheckDpMap(const double sx, const double sy)
bool GenerateDpMap(const double ex, const double ey, const std::vector< double > &XYbounds, const std::vector< std::vector< common::math::LineSegment2d > > &obstacles_linesegments_vec, const std::vector< std::vector< common::math::LineSegment2d > > &soft_boundary_linesegments_vec={{}})
bool GenerateAStarPath(const double sx, const double sy, const double ex, const double ey, const std::vector< double > &XYbounds, const std::vector< std::vector< common::math::LineSegment2d > > &obstacles_linesegments_vec, GridAStartResult *result)
static std::string CalcIndex(const double x, const double y, const double xy_resolution, const std::vector< double > &XYbounds)
Planning module main class.
optional WarmStartConfig warm_start_config
optional double node_radius
optional double grid_a_star_xy_resolution