Apollo 10.0
自动驾驶开放平台
junction_analyzer.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2018 The Apollo Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
16
17#include <algorithm>
18#include <limits>
19#include <queue>
20#include <unordered_set>
21#include <utility>
22
25
26namespace apollo {
27namespace prediction {
28
32using ConstLaneInfoPtr = std::shared_ptr<const LaneInfo>;
33
34void JunctionAnalyzer::Init(const std::string& junction_id) {
35 if (junction_info_ptr_ != nullptr &&
36 junction_info_ptr_->id().id() == junction_id) {
37 return;
38 }
39 Clear();
40 junction_info_ptr_ = PredictionMap::JunctionById(junction_id);
41 SetAllJunctionExits();
42}
43
45 // Clear all data
46 junction_info_ptr_ = nullptr;
47 junction_exits_.clear();
48 junction_features_.clear();
49}
50
51void JunctionAnalyzer::SetAllJunctionExits() {
52 CHECK_NOTNULL(junction_info_ptr_);
53 // Go through everything that the junction overlaps with.
54 for (const auto& overlap_id : junction_info_ptr_->junction().overlap_id()) {
55 auto overlap_info_ptr = PredictionMap::OverlapById(overlap_id.id());
56 if (overlap_info_ptr == nullptr) {
57 continue;
58 }
59 // Find the lane-segments that are overlapping, yet also extends out of
60 // the junction area. Those are the junction-exit-lanes.
61 for (const auto& object : overlap_info_ptr->overlap().object()) {
62 if (object.has_lane_overlap_info()) {
63 const std::string& lane_id = object.id().id();
64 auto lane_info_ptr = PredictionMap::LaneById(lane_id);
65 double s = object.lane_overlap_info().end_s();
66 if (s + FLAGS_junction_exit_lane_threshold <
67 lane_info_ptr->total_length()) {
68 JunctionExit junction_exit;
69 PointENU position = lane_info_ptr->GetSmoothPoint(s);
70 junction_exit.set_exit_lane_id(lane_id);
71 junction_exit.mutable_exit_position()->set_x(position.x());
72 junction_exit.mutable_exit_position()->set_y(position.y());
73 junction_exit.set_exit_heading(lane_info_ptr->Heading(s));
74 junction_exit.set_exit_width(lane_info_ptr->GetWidth(s));
75 // add junction_exit to hashtable
76 junction_exits_[lane_id] = junction_exit;
77 }
78 }
79 }
80 }
81}
82
83std::vector<JunctionExit> JunctionAnalyzer::GetJunctionExits(
84 const std::string& start_lane_id) {
85 // TODO(hongyi) make this a gflag
86 int max_search_level = 6;
87
88 std::vector<JunctionExit> junction_exits;
89 std::queue<std::pair<ConstLaneInfoPtr, int>> lane_info_queue;
90 lane_info_queue.emplace(PredictionMap::LaneById(start_lane_id), 0);
91 std::unordered_set<std::string> visited_exit_lanes;
92 // Perform a BFS to find all exit lanes that can be connected through
93 // this start_lane_id.
94 while (!lane_info_queue.empty()) {
95 ConstLaneInfoPtr curr_lane = lane_info_queue.front().first;
96 int level = lane_info_queue.front().second;
97 lane_info_queue.pop();
98 const std::string& curr_lane_id = curr_lane->id().id();
99 // Stop if this is already an exit lane.
100 if (IsExitLane(curr_lane_id) &&
101 visited_exit_lanes.find(curr_lane_id) == visited_exit_lanes.end()) {
102 junction_exits.push_back(junction_exits_[curr_lane_id]);
103 visited_exit_lanes.insert(curr_lane_id);
104 continue;
105 }
106 // Stop if reached max-search-level.
107 if (level >= max_search_level) {
108 continue;
109 }
110 for (const auto& succ_lane_id : curr_lane->lane().successor_id()) {
111 ConstLaneInfoPtr succ_lane_ptr =
112 PredictionMap::LaneById(succ_lane_id.id());
113 lane_info_queue.emplace(succ_lane_ptr, level + 1);
114 }
115 }
116 return junction_exits;
117}
118
120 const std::string& start_lane_id) {
121 if (junction_features_.find(start_lane_id) != junction_features_.end()) {
122 return junction_features_[start_lane_id];
123 }
124 JunctionFeature junction_feature;
125 junction_feature.set_junction_id(GetJunctionId());
126 junction_feature.set_junction_range(ComputeJunctionRange());
127 // Find all junction-exit-lanes that are successors of the start_lane_id.
128 std::vector<JunctionExit> junction_exits = GetJunctionExits(start_lane_id);
129
130 for (const auto& junction_exit : junction_exits) {
131 junction_feature.add_junction_exit()->CopyFrom(junction_exit);
132 }
133 junction_feature.mutable_enter_lane()->set_lane_id(start_lane_id);
134 junction_feature.add_start_lane_id(start_lane_id);
135 junction_features_[start_lane_id] = junction_feature;
136 return junction_features_[start_lane_id];
137}
138
140 const std::vector<std::string>& start_lane_ids) {
141 JunctionFeature merged_junction_feature;
142 bool initialized = false;
143 std::unordered_map<std::string, JunctionExit> junction_exits_map;
144 for (const std::string& start_lane_id : start_lane_ids) {
145 JunctionFeature junction_feature = GetJunctionFeature(start_lane_id);
146 if (!initialized) {
147 merged_junction_feature.set_junction_id(junction_feature.junction_id());
148 merged_junction_feature.set_junction_range(
149 junction_feature.junction_range());
150 initialized = true;
151 }
152 for (const JunctionExit& junction_exit : junction_feature.junction_exit()) {
153 if (junction_exits_map.find(junction_exit.exit_lane_id()) ==
154 junction_exits_map.end()) {
155 junction_exits_map[junction_exit.exit_lane_id()] = junction_exit;
156 }
157 }
158 }
159 for (const auto& exit : junction_exits_map) {
160 merged_junction_feature.add_start_lane_id(exit.first);
161 merged_junction_feature.add_junction_exit()->CopyFrom(exit.second);
162 }
163 return merged_junction_feature;
164}
165
166bool JunctionAnalyzer::IsExitLane(const std::string& lane_id) {
167 return junction_exits_.find(lane_id) != junction_exits_.end();
168}
169
171 CHECK_NOTNULL(junction_info_ptr_);
172 return junction_info_ptr_->id().id();
173}
174
176 CHECK_NOTNULL(junction_info_ptr_);
177 if (!junction_info_ptr_->junction().has_polygon() ||
178 junction_info_ptr_->junction().polygon().point_size() < 3) {
179 AERROR << "Junction [" << GetJunctionId()
180 << "] has not enough polygon points to compute range";
181 return FLAGS_defualt_junction_range;
182 }
183 double x_min = std::numeric_limits<double>::infinity();
184 double x_max = -std::numeric_limits<double>::infinity();
185 double y_min = std::numeric_limits<double>::infinity();
186 double y_max = -std::numeric_limits<double>::infinity();
187 for (const auto& point : junction_info_ptr_->junction().polygon().point()) {
188 x_min = std::min(x_min, point.x());
189 x_max = std::max(x_max, point.x());
190 y_min = std::min(y_min, point.y());
191 y_max = std::max(y_max, point.y());
192 }
193 double dx = std::abs(x_max - x_min);
194 double dy = std::abs(y_max - y_min);
195 double range = std::sqrt(dx * dx + dy * dy);
196 return range;
197}
198
199} // namespace prediction
200} // namespace apollo
const std::string & GetJunctionId()
Get junction ID
double ComputeJunctionRange()
Compute junction range
void Clear()
Clear all stored data
const JunctionFeature & GetJunctionFeature(const std::string &start_lane_id)
Get junction feature starting from start_lane_id
void Init(const std::string &junction_id)
Initialize by junction ID, if junction id differs from prev cycle
static std::shared_ptr< const hdmap::JunctionInfo > JunctionById(const std::string &id)
Get a shared pointer to a junction by junction ID.
static std::shared_ptr< const hdmap::LaneInfo > LaneById(const std::string &id)
Get a shared pointer to a lane by lane ID.
static std::shared_ptr< const hdmap::OverlapInfo > OverlapById(const std::string &id)
Get a shared pointer to an overlap by overlap ID.
#define AERROR
Definition log.h:44
std::shared_ptr< const LaneInfo > ConstLaneInfoPtr
class register implement
Definition arena_queue.h:37
repeated JunctionExit junction_exit
Definition feature.proto:53