37 use_esdf_ = warm_start_conf.
use_esdf();
40double GridSearch::EuclidDistance(
const double x1,
const double y1,
const double x2,
const double y2) {
41 return std::sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
44bool GridSearch::CheckConstraints(std::shared_ptr<Node2d> node) {
45 const double node_grid_x = node->GetGridX();
46 const double node_grid_y = node->GetGridY();
47 if (node_grid_x > max_grid_x_ || node_grid_x < 0 || node_grid_y > max_grid_y_ || node_grid_y < 0) {
50 if (obstacles_linesegments_vec_.empty()) {
53 for (
const auto& obstacle_linesegments : obstacles_linesegments_vec_) {
54 for (
const common::math::LineSegment2d& linesegment : obstacle_linesegments) {
55 if (linesegment.DistanceTo({node->GetGridX(), node->GetGridY()}) < node_radius_) {
66void GridSearch::AddSoftCost(
const std::vector<std::vector<common::math::LineSegment2d>>& soft_boundary) {
67 for (
const auto& soft_boundary_linesegments : soft_boundary) {
68 for (
const common::math::LineSegment2d& linesegment : soft_boundary_linesegments) {
69 int max = linesegment.length() / xy_grid_resolution_;
70 Vec2d unit = linesegment.unit_direction();
71 Vec2d node = linesegment.start();
72 for (
double i = 0; i < max; i++) {
73 std::unordered_set<std::string> close_set;
74 node += unit * xy_grid_resolution_;
75 int grid_x =
static_cast<int>((node.x() - XYbounds_[0]) / xy_grid_resolution_);
76 int grid_y =
static_cast<int>((node.y() - XYbounds_[2]) / xy_grid_resolution_);
77 Vec2d origin_index = {grid_x, grid_y};
78 ExtendNode(grid_x, grid_y, origin_index, close_set);
80 node = linesegment.end();
81 int grid_x =
static_cast<int>((node.x() - XYbounds_[0]) / xy_grid_resolution_);
82 int grid_y =
static_cast<int>((node.y() - XYbounds_[2]) / xy_grid_resolution_);
83 Vec2d origin_index = {grid_x, grid_y};
84 std::unordered_set<std::string> close_set;
85 ExtendNode(grid_x, grid_y, origin_index, close_set);
90void GridSearch::ExtendNode(
94 std::unordered_set<std::string>& close_set) {
96 double min_dist = (node - origin_index).Length() * xy_grid_resolution_;
100 if (min_dist > esdf_range_ || x > max_grid_x_ || x < 0 || y > max_grid_y_ || y < 0) {
105 std::string index = absl::StrCat(x,
"_", y);
106 if (close_set.find(index) == close_set.end() && dp_map_.find(index) != dp_map_.end()
107 && dp_map_[index]->GetDistanceToObstacle() > min_dist) {
108 dp_map_[index]->SetDistanceToObstacle(min_dist);
109 close_set.insert(index);
110 for (
int i = 0; i < 4; i++) {
111 int new_x = x + dx_[i];
112 int new_y = y + dy_[i];
113 ExtendNode(new_x, new_y, origin_index, close_set);
120std::vector<std::shared_ptr<Node2d>> GridSearch::GenerateNextNodes(std::shared_ptr<Node2d> current_node) {
121 double current_node_x = current_node->GetGridX();
122 double current_node_y = current_node->GetGridY();
123 double current_node_path_cost = current_node->GetPathCost();
124 double diagonal_distance = std::sqrt(2.0);
125 std::vector<std::shared_ptr<Node2d>> next_nodes;
126 std::shared_ptr<Node2d> up = std::make_shared<Node2d>(current_node_x, current_node_y + 1.0, XYbounds_);
127 up->SetPathCost(current_node_path_cost + 1.0);
128 std::shared_ptr<Node2d> up_right = std::make_shared<Node2d>(current_node_x + 1.0, current_node_y + 1.0, XYbounds_);
129 up_right->SetPathCost(current_node_path_cost + diagonal_distance);
130 std::shared_ptr<Node2d> right = std::make_shared<Node2d>(current_node_x + 1.0, current_node_y, XYbounds_);
131 right->SetPathCost(current_node_path_cost + 1.0);
132 std::shared_ptr<Node2d> down_right
133 = std::make_shared<Node2d>(current_node_x + 1.0, current_node_y - 1.0, XYbounds_);
134 down_right->SetPathCost(current_node_path_cost + diagonal_distance);
135 std::shared_ptr<Node2d> down = std::make_shared<Node2d>(current_node_x, current_node_y - 1.0, XYbounds_);
136 down->SetPathCost(current_node_path_cost + 1.0);
137 std::shared_ptr<Node2d> down_left = std::make_shared<Node2d>(current_node_x - 1.0, current_node_y - 1.0, XYbounds_);
138 down_left->SetPathCost(current_node_path_cost + diagonal_distance);
139 std::shared_ptr<Node2d> left = std::make_shared<Node2d>(current_node_x - 1.0, current_node_y, XYbounds_);
140 left->SetPathCost(current_node_path_cost + 1.0);
141 std::shared_ptr<Node2d> up_left = std::make_shared<Node2d>(current_node_x - 1.0, current_node_y + 1.0, XYbounds_);
142 up_left->SetPathCost(current_node_path_cost + diagonal_distance);
144 next_nodes.emplace_back(up);
145 next_nodes.emplace_back(up_right);
146 next_nodes.emplace_back(right);
147 next_nodes.emplace_back(down_right);
148 next_nodes.emplace_back(down);
149 next_nodes.emplace_back(down_left);
150 next_nodes.emplace_back(left);
151 next_nodes.emplace_back(up_left);
160 const std::vector<double>& XYbounds,
161 const std::vector<std::vector<common::math::LineSegment2d>>& obstacles_linesegments_vec,
163 std::priority_queue<std::pair<std::string, double>, std::vector<std::pair<std::string, double>>, cmp> open_pq;
164 std::unordered_map<std::string, std::shared_ptr<Node2d>> open_set;
165 std::unordered_map<std::string, std::shared_ptr<Node2d>> close_set;
166 XYbounds_ = XYbounds;
167 std::shared_ptr<Node2d> start_node = std::make_shared<Node2d>(sx, sy, xy_grid_resolution_, XYbounds_);
168 std::shared_ptr<Node2d> end_node = std::make_shared<Node2d>(ex, ey, xy_grid_resolution_, XYbounds_);
169 std::shared_ptr<Node2d> final_node_ =
nullptr;
170 obstacles_linesegments_vec_ = obstacles_linesegments_vec;
171 open_set.emplace(start_node->GetIndex(), start_node);
172 open_pq.emplace(start_node->GetIndex(), start_node->GetCost());
175 size_t explored_node_num = 0;
176 while (!open_pq.empty()) {
177 std::string current_id = open_pq.top().first;
179 std::shared_ptr<Node2d> current_node = open_set[current_id];
181 if (*(current_node) == *(end_node)) {
182 final_node_ = current_node;
185 close_set.emplace(current_node->GetIndex(), current_node);
186 std::vector<std::shared_ptr<Node2d>> next_nodes = std::move(GenerateNextNodes(current_node));
187 for (
auto& next_node : next_nodes) {
188 if (!CheckConstraints(next_node)) {
191 if (close_set.find(next_node->GetIndex()) != close_set.end()) {
194 if (open_set.find(next_node->GetIndex()) == open_set.end()) {
196 next_node->SetHeuristic(EuclidDistance(
197 next_node->GetGridX(), next_node->GetGridY(), end_node->GetGridX(), end_node->GetGridY()));
198 next_node->SetPreNode(current_node);
199 open_set.emplace(next_node->GetIndex(), next_node);
200 open_pq.emplace(next_node->GetIndex(), next_node->GetCost());
205 if (final_node_ ==
nullptr) {
206 AERROR <<
"Grid A searching return null ptr(open_set ran out)";
209 LoadGridAStarResult(result);
210 ADEBUG <<
"explored node num is " << explored_node_num;
217 const std::vector<double>& XYbounds,
218 const std::vector<std::vector<common::math::LineSegment2d>>& obstacles_linesegments_vec,
219 const std::vector<std::vector<common::math::LineSegment2d>>& soft_boundary_linesegments_vec) {
220 std::priority_queue<std::pair<std::string, double>, std::vector<std::pair<std::string, double>>, cmp> open_pq;
221 std::unordered_map<std::string, std::shared_ptr<Node2d>> open_set;
222 dp_map_ =
decltype(dp_map_)();
223 XYbounds_ = XYbounds;
225 max_grid_y_ = std::round((XYbounds_[3] - XYbounds_[2]) / xy_grid_resolution_);
226 max_grid_x_ = std::round((XYbounds_[1] - XYbounds_[0]) / xy_grid_resolution_);
227 std::shared_ptr<Node2d> end_node = std::make_shared<Node2d>(ex, ey, xy_grid_resolution_, XYbounds_);
228 obstacles_linesegments_vec_ = obstacles_linesegments_vec;
229 open_set.emplace(end_node->GetIndex(), end_node);
230 open_pq.emplace(end_node->GetIndex(), end_node->GetCost());
233 size_t explored_node_num = 0;
234 while (!open_pq.empty()) {
235 const std::string current_id = open_pq.top().first;
237 std::shared_ptr<Node2d> current_node = open_set[current_id];
238 dp_map_.emplace(current_node->GetIndex(), current_node);
239 std::vector<std::shared_ptr<Node2d>> next_nodes = std::move(GenerateNextNodes(current_node));
240 for (
auto& next_node : next_nodes) {
241 if (!CheckConstraints(next_node)) {
244 if (dp_map_.find(next_node->GetIndex()) != dp_map_.end()) {
247 if (open_set.find(next_node->GetIndex()) == open_set.end()) {
249 next_node->SetPreNode(current_node);
250 open_set.emplace(next_node->GetIndex(), next_node);
251 open_pq.emplace(next_node->GetIndex(), next_node->GetCost());
253 if (open_set[next_node->GetIndex()]->GetCost() > next_node->GetCost()) {
254 open_set[next_node->GetIndex()]->SetCost(next_node->GetCost());
255 open_set[next_node->GetIndex()]->SetPreNode(current_node);
261 AddSoftCost(soft_boundary_linesegments_vec);
263 ADEBUG <<
"explored node num is " << explored_node_num;
269 if (dp_map_.find(index) != dp_map_.end()) {
270 return dp_map_[index]->GetCost() * xy_grid_resolution_;
272 return std::numeric_limits<double>::infinity();
278 if (dp_map_.find(index) != dp_map_.end()) {
279 return dp_map_[index]->GetDistanceToObstacle();
286 (*result).path_cost = final_node_->GetPathCost() * xy_grid_resolution_;
287 std::shared_ptr<Node2d> current_node = final_node_;
288 std::vector<double> grid_a_x;
289 std::vector<double> grid_a_y;
290 while (current_node->GetPreNode() !=
nullptr) {
291 grid_a_x.push_back(current_node->GetGridX() * xy_grid_resolution_ + XYbounds_[0]);
292 grid_a_y.push_back(current_node->GetGridY() * xy_grid_resolution_ + XYbounds_[2]);
293 current_node = current_node->GetPreNode();
295 std::reverse(grid_a_x.begin(), grid_a_x.end());
296 std::reverse(grid_a_y.begin(), grid_a_y.end());
297 (*result).x = std::move(grid_a_x);
298 (*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)
double GetObstacleDistance(const double x, const double y)
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
optional double esdf_range