Skip to content

Commit f4eeba7

Browse files
soblinsaka1-s
authored andcommitted
fix(intersection): additional fix for 8520 (autowarefoundation#8561)
Signed-off-by: Mamoru Sobue <mamoru.sobue@tier4.jp>
1 parent 2ae8bb8 commit f4eeba7

File tree

4 files changed

+75
-71
lines changed

4 files changed

+75
-71
lines changed

planning/behavior_velocity_planner/autoware_behavior_velocity_intersection_module/src/scene_intersection_prepare_data.cpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -934,6 +934,14 @@ std::vector<lanelet::ConstLineString3d> IntersectionModule::generateDetectionLan
934934
detection_lanelets.push_back(detection_lanelet);
935935
}
936936

937+
std::vector<lanelet::ConstLineString3d> detection_divisions;
938+
if (detection_lanelets.empty()) {
939+
// NOTE(soblin): due to the above filtering detection_lanelets may be empty or do not contain
940+
// conflicting_detection_lanelets
941+
// OK to return empty detction_divsions
942+
return detection_divisions;
943+
}
944+
937945
// (1) tsort detection_lanelets
938946
const auto [merged_detection_lanelets, originals] = util::mergeLaneletsByTopologicalSort(
939947
detection_lanelets, conflicting_detection_lanelets, routing_graph_ptr);
@@ -952,7 +960,6 @@ std::vector<lanelet::ConstLineString3d> IntersectionModule::generateDetectionLan
952960
}
953961

954962
// (3) discretize each merged lanelet
955-
std::vector<lanelet::ConstLineString3d> detection_divisions;
956963
for (const auto & [merged_lanelet, area] : merged_lanelet_with_area) {
957964
const double length = bg::length(merged_lanelet.centerline());
958965
const double width = area / length;

planning/behavior_velocity_planner/autoware_behavior_velocity_intersection_module/src/util.cpp

+53-44
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,13 @@
3232

3333
#include <algorithm>
3434
#include <cmath>
35+
#include <limits>
36+
#include <map>
37+
#include <memory>
38+
#include <queue>
3539
#include <set>
3640
#include <string>
3741
#include <unordered_map>
38-
#include <unordered_set>
3942
#include <vector>
4043

4144
namespace autoware::behavior_velocity_planner::util
@@ -212,42 +215,35 @@ std::optional<size_t> getFirstPointInsidePolygon(
212215
}
213216
return std::nullopt;
214217
}
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)
217222
{
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;
239234
}
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;
243241
}
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;
251247
}
252248

253249
std::pair<lanelet::ConstLanelets, std::vector<lanelet::ConstLanelets>>
@@ -269,13 +265,20 @@ mergeLaneletsByTopologicalSort(
269265
}
270266
std::set<size_t> terminal_inds;
271267
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+
}
273271
}
274272

275273
// create adjacency matrix
276274
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+
}
279282
// NOTE: this function aims to traverse the detection lanelet in the lane direction, so if lane B
280283
// follows lane A on the routing_graph, adj[A][B] = true
281284
for (const auto & lanelet : lanelets) {
@@ -290,27 +293,33 @@ mergeLaneletsByTopologicalSort(
290293

291294
std::unordered_map<size_t, std::vector<std::vector<size_t>>> branches;
292295
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);
294300
}
295301

296-
for (auto & [terminal_ind, paths] : branches) {
302+
for (auto it = branches.begin(); it != branches.end(); it++) {
303+
auto & paths = it->second;
297304
for (auto & path : paths) {
298305
std::reverse(path.begin(), path.end());
299306
}
300307
}
301308
lanelet::ConstLanelets merged;
302309
std::vector<lanelet::ConstLanelets> originals;
303310
for (const auto & [ind, sub_branches] : branches) {
304-
if (sub_branches.empty()) {
311+
if (sub_branches.size() == 0) {
305312
continue;
306313
}
307314
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();
309318
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]]);
311321
}
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));
314323
}
315324
}
316325
return {merged, originals};

planning/behavior_velocity_planner/autoware_behavior_velocity_intersection_module/src/util.hpp

+8-20
Original file line numberDiff line numberDiff line change
@@ -110,34 +110,22 @@ geometry_msgs::msg::Pose getObjectPoseWithVelocityDirection(
110110
* @brief this function sorts the set of lanelets topologically using topological sort and merges
111111
* the lanelets from each root to each end. each branch is merged and returned with the original
112112
* lanelets
113-
*
114-
* @param lanelets The set of input lanelets to be processed
115-
* @param terminal_lanelets The set of lanelets considered as terminal
116-
* @param routing_graph_ptr Pointer to the routing graph used for determining lanelet
117-
* connections
118-
*
119-
* @return A pair containing:
120-
* - First: A vector of merged lanelets, where each element represents a merged lanelet from
121-
* a branch
122-
* - Second: A vector of vectors, where each inner vector contains the original lanelets
123-
* that were merged to form the corresponding merged lanelet
113+
* @param[in] lanelets the set of lanelets
114+
* @param[in] routing_graph_ptr the routing graph
115+
* @return the pair of merged lanelets and their corresponding original lanelets
124116
*/
125117
std::pair<lanelet::ConstLanelets, std::vector<lanelet::ConstLanelets>>
126118
mergeLaneletsByTopologicalSort(
127119
const lanelet::ConstLanelets & lanelets, const lanelet::ConstLanelets & terminal_lanelets,
128120
const lanelet::routing::RoutingGraphPtr routing_graph_ptr);
129121

130122
/**
131-
* @brief Retrieves all paths from the given source to terminal nodes on the tree
132-
*
133-
* @param adjacency A 2D vector representing the adjacency matrix of the graph
134-
* @param src_ind The index of the current source node being processed
135-
*
136-
* @return A vector of vectors, where each inner vector represents a path from the source node to a
137-
* terminal node.
123+
* @brief this functions retrieves all the paths from the given source to terminal nodes on the tree
124+
@param[in] visited_inds visited node indices excluding src_ind so far
138125
*/
139-
std::vector<std::vector<size_t>> retrievePathsBackward(
140-
const std::vector<std::vector<bool>> & adjacency, size_t start_node);
126+
void retrievePathsBackward(
127+
const std::vector<std::vector<bool>> & adjacency, const size_t src_ind,
128+
const std::vector<size_t> & visited_inds, std::vector<std::vector<size_t>> & paths);
141129

142130
/**
143131
* @brief find the index of the first point where vehicle footprint intersects with the given

planning/behavior_velocity_planner/autoware_behavior_velocity_intersection_module/test/test_util.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,16 @@ TEST(TestUtil, retrievePathsBackward)
4242
};
4343
{
4444
const size_t src_ind = 6;
45-
auto paths =
46-
autoware::behavior_velocity_planner::util::retrievePathsBackward(adjacency, src_ind);
45+
std::vector<std::vector<size_t>> paths;
46+
autoware::behavior_velocity_planner::util::retrievePathsBackward(adjacency, src_ind, {}, paths);
4747
EXPECT_EQ(paths.size(), 1);
4848
EXPECT_EQ(paths.at(0).size(), 1);
4949
EXPECT_EQ(paths.at(0).at(0), 6);
5050
}
5151
{
5252
const size_t src_ind = 4;
53-
auto paths =
54-
autoware::behavior_velocity_planner::util::retrievePathsBackward(adjacency, src_ind);
53+
std::vector<std::vector<size_t>> paths;
54+
autoware::behavior_velocity_planner::util::retrievePathsBackward(adjacency, src_ind, {}, paths);
5555
EXPECT_EQ(paths.size(), 2);
5656
// 4 --> 6
5757
EXPECT_EQ(paths.at(0).size(), 2);
@@ -64,8 +64,8 @@ TEST(TestUtil, retrievePathsBackward)
6464
}
6565
{
6666
const size_t src_ind = 0;
67-
auto paths =
68-
autoware::behavior_velocity_planner::util::retrievePathsBackward(adjacency, src_ind);
67+
std::vector<std::vector<size_t>> paths;
68+
autoware::behavior_velocity_planner::util::retrievePathsBackward(adjacency, src_ind, {}, paths);
6969
EXPECT_EQ(paths.size(), 3);
7070
// 0 --> 1 --> 2 --> 4 --> 6
7171
EXPECT_EQ(paths.at(0).size(), 5);

0 commit comments

Comments
 (0)