32
32
33
33
#include < algorithm>
34
34
#include < cmath>
35
+ #include < limits>
36
+ #include < map>
37
+ #include < memory>
38
+ #include < queue>
35
39
#include < set>
36
40
#include < string>
37
41
#include < unordered_map>
38
- #include < unordered_set>
39
42
#include < vector>
40
43
41
44
namespace autoware ::behavior_velocity_planner::util
@@ -212,42 +215,35 @@ std::optional<size_t> getFirstPointInsidePolygon(
212
215
}
213
216
return std::nullopt;
214
217
}
215
- std::vector<std::vector<size_t >> retrievePathsBackward (
216
- const std::vector<std::vector<bool >> & adjacency, size_t start_node)
218
+
219
+ void retrievePathsBackward (
220
+ const std::vector<std::vector<bool >> & adjacency, const size_t src_ind,
221
+ const std::vector<size_t > & visited_inds, std::vector<std::vector<size_t >> & paths)
217
222
{
218
- std::vector<std::vector<size_t >> paths;
219
- std::vector<size_t > current_path;
220
- std::unordered_set<size_t > visited;
221
-
222
- std::function<void (size_t )> retrieve_paths_backward_impl = [&](size_t src_ind) {
223
- current_path.push_back (src_ind);
224
- visited.insert (src_ind);
225
-
226
- bool is_terminal = true ;
227
- const auto & nexts = adjacency[src_ind];
228
-
229
- for (size_t next = 0 ; next < nexts.size (); ++next) {
230
- if (nexts[next]) {
231
- is_terminal = false ;
232
- if (visited.find (next) == visited.end ()) {
233
- retrieve_paths_backward_impl (next);
234
- } else {
235
- // Loop detected
236
- paths.push_back (current_path);
237
- }
238
- }
223
+ const auto & nexts = adjacency.at (src_ind);
224
+ const bool is_terminal = (std::find (nexts.begin (), nexts.end (), true ) == nexts.end ());
225
+ if (is_terminal) {
226
+ std::vector<size_t > path (visited_inds.begin (), visited_inds.end ());
227
+ path.push_back (src_ind);
228
+ paths.emplace_back (std::move (path));
229
+ return ;
230
+ }
231
+ for (size_t next = 0 ; next < nexts.size (); next++) {
232
+ if (!nexts.at (next)) {
233
+ continue ;
239
234
}
240
-
241
- if (is_terminal) {
242
- paths.push_back (current_path);
235
+ if (std::find (visited_inds.begin (), visited_inds.end (), next) != visited_inds.end ()) {
236
+ // loop detected
237
+ std::vector<size_t > path (visited_inds.begin (), visited_inds.end ());
238
+ path.push_back (src_ind);
239
+ paths.emplace_back (std::move (path));
240
+ continue ;
243
241
}
244
-
245
- current_path.pop_back ();
246
- visited.erase (src_ind);
247
- };
248
-
249
- retrieve_paths_backward_impl (start_node);
250
- return paths;
242
+ auto new_visited_inds = visited_inds;
243
+ new_visited_inds.push_back (src_ind);
244
+ retrievePathsBackward (adjacency, next, new_visited_inds, paths);
245
+ }
246
+ return ;
251
247
}
252
248
253
249
std::pair<lanelet::ConstLanelets, std::vector<lanelet::ConstLanelets>>
@@ -269,13 +265,20 @@ mergeLaneletsByTopologicalSort(
269
265
}
270
266
std::set<size_t > terminal_inds;
271
267
for (const auto & terminal_lanelet : terminal_lanelets) {
272
- terminal_inds.insert (Id2ind[terminal_lanelet.id ()]);
268
+ if (Id2ind.count (terminal_lanelet.id ()) > 0 ) {
269
+ terminal_inds.insert (Id2ind[terminal_lanelet.id ()]);
270
+ }
273
271
}
274
272
275
273
// create adjacency matrix
276
274
const auto n_node = lanelets.size ();
277
- std::vector<std::vector<bool >> adjacency (n_node, std::vector<bool >(n_node, false ));
278
-
275
+ std::vector<std::vector<bool >> adjacency (n_node);
276
+ for (size_t dst = 0 ; dst < n_node; ++dst) {
277
+ adjacency[dst].resize (n_node);
278
+ for (size_t src = 0 ; src < n_node; ++src) {
279
+ adjacency[dst][src] = false ;
280
+ }
281
+ }
279
282
// NOTE: this function aims to traverse the detection lanelet in the lane direction, so if lane B
280
283
// follows lane A on the routing_graph, adj[A][B] = true
281
284
for (const auto & lanelet : lanelets) {
@@ -290,27 +293,33 @@ mergeLaneletsByTopologicalSort(
290
293
291
294
std::unordered_map<size_t , std::vector<std::vector<size_t >>> branches;
292
295
for (const auto & terminal_ind : terminal_inds) {
293
- branches[terminal_ind] = retrievePathsBackward (adjacency, terminal_ind);
296
+ std::vector<std::vector<size_t >> paths;
297
+ std::vector<size_t > visited;
298
+ retrievePathsBackward (adjacency, terminal_ind, visited, paths);
299
+ branches[terminal_ind] = std::move (paths);
294
300
}
295
301
296
- for (auto & [terminal_ind, paths] : branches) {
302
+ for (auto it = branches.begin (); it != branches.end (); it++) {
303
+ auto & paths = it->second ;
297
304
for (auto & path : paths) {
298
305
std::reverse (path.begin (), path.end ());
299
306
}
300
307
}
301
308
lanelet::ConstLanelets merged;
302
309
std::vector<lanelet::ConstLanelets> originals;
303
310
for (const auto & [ind, sub_branches] : branches) {
304
- if (sub_branches.empty () ) {
311
+ if (sub_branches.size () == 0 ) {
305
312
continue ;
306
313
}
307
314
for (const auto & sub_inds : sub_branches) {
308
- lanelet::ConstLanelets to_merge;
315
+ lanelet::ConstLanelets to_be_merged;
316
+ originals.push_back (lanelet::ConstLanelets ({}));
317
+ auto & original = originals.back ();
309
318
for (const auto & sub_ind : sub_inds) {
310
- to_merge.push_back (Id2lanelet[ind2Id[sub_ind]]);
319
+ to_be_merged.push_back (Id2lanelet[ind2Id[sub_ind]]);
320
+ original.push_back (Id2lanelet[ind2Id[sub_ind]]);
311
321
}
312
- originals.push_back (to_merge);
313
- merged.push_back (lanelet::utils::combineLaneletsShape (to_merge));
322
+ merged.push_back (lanelet::utils::combineLaneletsShape (to_be_merged));
314
323
}
315
324
}
316
325
return {merged, originals};
0 commit comments