227 {
228 Clear();
229 AINFO <<
"Start A* search algorithm.";
230
231 std::priority_queue<SearchNode> open_set_detail;
232
233 SearchNode src_search_node(src_node);
234 src_search_node.f = HeuristicCost(src_node, dest_node);
235 open_set_detail.push(src_search_node);
236
237 open_set_.insert(src_node);
238 g_score_[src_node] = 0.0;
239 enter_s_[src_node] = src_node->StartS();
240
241 SearchNode current_node;
242 std::unordered_set<const TopoEdge*> next_edge_set;
243 std::unordered_set<const TopoEdge*> sub_edge_set;
244 while (!open_set_detail.empty()) {
245 current_node = open_set_detail.top();
246 const auto* from_node = current_node.topo_node;
247 if (current_node.topo_node == dest_node) {
248 if (!Reconstruct(came_from_, from_node, result_nodes)) {
249 AERROR <<
"Failed to reconstruct route.";
250 return false;
251 }
252 return true;
253 }
254 open_set_.erase(from_node);
255 open_set_detail.pop();
256
257 if (closed_set_.count(from_node) != 0) {
258
259 continue;
260 }
261 closed_set_.emplace(from_node);
262
263
264
265 const auto& neighbor_edges =
266 (GetResidualS(from_node) > FLAGS_min_length_for_lane_change &&
267 change_lane_enabled_)
268 ? from_node->OutToAllEdge()
269 : from_node->OutToSucEdge();
270 double tentative_g_score = 0.0;
271 next_edge_set.clear();
272 for (const auto* edge : neighbor_edges) {
273 sub_edge_set.clear();
274 sub_graph->GetSubInEdgesIntoSubGraph(edge, &sub_edge_set);
275 next_edge_set.insert(sub_edge_set.begin(), sub_edge_set.end());
276 }
277
278 for (const auto* edge : next_edge_set) {
279 const auto* to_node = edge->ToNode();
280 if (closed_set_.count(to_node) == 1) {
281 continue;
282 }
283 if (GetResidualS(edge, to_node) < FLAGS_min_length_for_lane_change) {
284 continue;
285 }
286 tentative_g_score =
287 g_score_[current_node.topo_node] + GetCostToNeighbor(edge);
289 tentative_g_score -=
290 (edge->FromNode()->Cost() + edge->ToNode()->Cost()) / 2;
291 }
292 double f = tentative_g_score + HeuristicCost(to_node, dest_node);
293 if (open_set_.count(to_node) != 0 &&
f >= g_score_[to_node]) {
294 continue;
295 }
296
298 enter_s_[to_node] = to_node->StartS();
299 } else {
300
301 double to_node_enter_s =
302 (enter_s_[from_node] + FLAGS_min_length_for_lane_change) /
303 from_node->Length() * to_node->Length();
304
305 to_node_enter_s = std::min(to_node_enter_s, to_node->Length());
306
307 if (to_node_enter_s > to_node->EndS() && to_node == dest_node) {
308 continue;
309 }
310 enter_s_[to_node] = to_node_enter_s;
311 }
312
313 g_score_[to_node] =
f;
314 SearchNode next_node(to_node);
316 open_set_detail.push(next_node);
317 came_from_[to_node] = from_node;
318 if (open_set_.count(to_node) == 0) {
319 open_set_.insert(to_node);
320 }
321 }
322 }
323 AERROR <<
"Failed to find goal lane with id: " << dest_node->LaneId();
324 return false;
325}