37bool HeadingIsAtLeft(
const std::vector<double>& heading1,
38 const std::vector<double>& heading2,
const size_t idx) {
39 if (idx >= heading1.size() || idx >= heading2.size()) {
46 }
else if (angle < 0.0) {
49 return HeadingIsAtLeft(heading1, heading2, idx + 1);
52int ConvertTurnTypeToDegree(
const Lane& lane) {
54 if (!lane.has_turn()) {
59 switch (lane.turn()) {
73bool IsAtLeft(std::shared_ptr<const LaneInfo> lane1,
74 std::shared_ptr<const LaneInfo> lane2) {
75 if (lane1->lane().has_turn() && lane2->lane().has_turn() &&
76 lane1->lane().turn() != lane2->lane().turn()) {
77 int degree_to_left_1 = ConvertTurnTypeToDegree(lane1->lane());
78 int degree_to_left_2 = ConvertTurnTypeToDegree(lane2->lane());
79 return degree_to_left_1 > degree_to_left_2;
81 return HeadingIsAtLeft(lane1->headings(), lane2->headings(), 0);
87 const bool consider_divide,
88 std::shared_ptr<const LaneInfo> lane_info_ptr)
91 consider_divide_(consider_divide),
92 lane_info_ptr_(lane_info_ptr) {}
96 if (length_ < 0.0 || lane_info_ptr_ ==
nullptr) {
97 const auto error_msg = absl::StrCat(
98 "Invalid road graph settings. Road graph length = ", length_);
100 return Status(ErrorCode::PREDICTION_ERROR, error_msg);
102 if (lane_graph_ptr ==
nullptr) {
103 const auto error_msg =
"Invalid input lane graph.";
105 return Status(ErrorCode::PREDICTION_ERROR, error_msg);
109 std::list<LaneSegment> lane_segments;
110 double accumulated_s = 0.0;
111 ConstructLaneSequence(accumulated_s, start_s_, lane_info_ptr_,
112 FLAGS_road_graph_max_search_horizon, consider_divide_,
113 &lane_segments, lane_graph_ptr);
120 if (length_ < 0.0 || lane_info_ptr_ ==
nullptr) {
121 const auto error_msg = absl::StrCat(
122 "Invalid road graph settings. Road graph length = ", length_);
124 return Status(ErrorCode::PREDICTION_ERROR, error_msg);
126 if (lane_graph_ptr ==
nullptr) {
127 const auto error_msg =
"Invalid input lane graph.";
129 return Status(ErrorCode::PREDICTION_ERROR, error_msg);
133 std::list<LaneSegment> lane_segments;
135 ConstructLaneSequence(
true, 0.0, start_s_, lane_info_ptr_,
136 FLAGS_road_graph_max_search_horizon, consider_divide_,
137 &lane_segments, &lane_graph_successor);
138 lane_segments.clear();
140 length_ = length_ / 2.0;
141 ConstructLaneSequence(
false, 0.0, start_s_, lane_info_ptr_,
142 FLAGS_road_graph_max_search_horizon, consider_divide_,
143 &lane_segments, &lane_graph_predecessor);
145 CombineLaneGraphs(lane_graph_predecessor, lane_graph_successor);
153 for (
const auto& lane_sequence_pre : lane_graph_predecessor.lane_sequence()) {
154 const auto& ending_lane_segment = lane_sequence_pre.lane_segment(
155 lane_sequence_pre.lane_segment_size() - 1);
156 for (
const auto& lane_sequence_suc : lane_graph_successor.lane_sequence()) {
157 if (lane_sequence_suc.lane_segment(0).lane_id() ==
158 ending_lane_segment.lane_id()) {
159 LaneSequence* lane_sequence = final_lane_graph.add_lane_sequence();
160 for (
const auto& it : lane_sequence_pre.lane_segment()) {
161 *(lane_sequence->add_lane_segment()) = it;
164 ->mutable_lane_segment(lane_sequence->lane_segment_size() - 1)
165 ->set_end_s(lane_sequence_suc.lane_segment(0).end_s());
167 ->mutable_lane_segment(lane_sequence->lane_segment_size() - 1)
168 ->set_adc_s(lane_sequence_suc.lane_segment(0).start_s());
169 lane_sequence->set_adc_lane_segment_idx(
170 lane_sequence->lane_segment_size() - 1);
171 for (
int i = 1; i < lane_sequence_suc.lane_segment_size(); ++i) {
172 *(lane_sequence->add_lane_segment()) =
179 return final_lane_graph;
184 if (!lane_graph.IsInitialized()) {
188 for (
const auto& lane_sequence : lane_graph.
lane_sequence()) {
189 for (
const auto& lane_segment : lane_sequence.
lane_segment()) {
190 if (lane_segment.has_lane_id() &&
191 lane_segment.lane_id() == lane_info_ptr->id().id()) {
199void RoadGraph::ConstructLaneSequence(
200 const double accumulated_s,
const double curr_lane_seg_s,
201 std::shared_ptr<const LaneInfo> lane_info_ptr,
202 const int graph_search_horizon,
const bool consider_lane_split,
203 std::list<LaneSegment>*
const lane_segments,
205 ConstructLaneSequence(
true, accumulated_s, curr_lane_seg_s, lane_info_ptr,
206 graph_search_horizon, consider_lane_split,
207 lane_segments, lane_graph_ptr);
210void RoadGraph::ConstructLaneSequence(
211 const bool search_forward_direction,
const double accumulated_s,
212 const double curr_lane_seg_s, std::shared_ptr<const LaneInfo> lane_info_ptr,
213 const int graph_search_horizon,
const bool consider_lane_split,
214 std::list<LaneSegment>*
const lane_segments,
215 LaneGraph*
const lane_graph_ptr)
const {
217 if (lane_info_ptr ==
nullptr) {
218 AERROR <<
"Invalid lane.";
221 if (graph_search_horizon < 0) {
222 AERROR <<
"The lane search has already reached the limits";
223 AERROR <<
"Possible map error found!";
229 curr_lane_seg_s >= 0.0 ? curr_lane_seg_s : lane_info_ptr->total_length();
230 LaneSegment lane_segment;
231 lane_segment.set_adc_s(curr_s);
232 lane_segment.set_lane_id(lane_info_ptr->id().id());
233 lane_segment.set_lane_turn_type(
235 lane_segment.set_total_length(lane_info_ptr->total_length());
236 if (search_forward_direction) {
237 lane_segment.set_start_s(curr_s);
238 lane_segment.set_end_s(std::fmin(curr_s + length_ - accumulated_s,
239 lane_info_ptr->total_length()));
241 lane_segment.set_start_s(
242 std::fmax(0.0, curr_s - (length_ - accumulated_s)));
243 lane_segment.set_end_s(curr_s);
245 if (search_forward_direction) {
246 lane_segments->push_back(std::move(lane_segment));
248 lane_segments->push_front(std::move(lane_segment));
253 if (search_forward_direction) {
254 if (lane_segments->back().end_s() < lane_info_ptr->total_length() ||
255 lane_info_ptr->lane().successor_id().empty()) {
256 LaneSequence* sequence = lane_graph_ptr->add_lane_sequence();
257 for (
const auto& it : *lane_segments) {
258 *(sequence->add_lane_segment()) = it;
260 lane_segments->pop_back();
264 if (lane_segments->front().start_s() > 0.0 ||
265 lane_info_ptr->lane().predecessor_id().empty()) {
266 LaneSequence* sequence = lane_graph_ptr->add_lane_sequence();
267 for (
const auto& it : *lane_segments) {
268 *(sequence->add_lane_segment()) = it;
270 lane_segments->pop_front();
276 double new_accumulated_s = 0.0;
277 double new_lane_seg_s = 0.0;
278 std::vector<std::shared_ptr<const hdmap::LaneInfo>> candidate_lanes;
279 std::set<std::string> set_lane_ids;
280 if (search_forward_direction) {
281 new_accumulated_s = accumulated_s + lane_info_ptr->total_length() - curr_s;
283 for (
const auto& successor_lane_id : lane_info_ptr->lane().successor_id()) {
284 set_lane_ids.insert(successor_lane_id.id());
286 for (
const auto& unique_id : set_lane_ids) {
290 std::sort(candidate_lanes.begin(), candidate_lanes.end(), IsAtLeft);
292 if (!consider_lane_split) {
297 new_accumulated_s = accumulated_s + curr_s;
298 new_lane_seg_s = -0.1;
300 for (
const auto& predecessor_lane_id :
301 lane_info_ptr->lane().predecessor_id()) {
302 set_lane_ids.insert(predecessor_lane_id.id());
304 for (
const auto& unique_id : set_lane_ids) {
308 bool consider_further_lane_split =
309 !search_forward_direction ||
310 (FLAGS_prediction_offline_mode ==
312 (FLAGS_prediction_offline_mode ==
314 (consider_lane_split && candidate_lanes.size() == 1);
316 for (
const auto& candidate_lane : candidate_lanes) {
317 ConstructLaneSequence(search_forward_direction, new_accumulated_s,
318 new_lane_seg_s, candidate_lane,
319 graph_search_horizon - 1, consider_further_lane_split,
320 lane_segments, lane_graph_ptr);
322 if (search_forward_direction) {
323 lane_segments->pop_back();
325 lane_segments->pop_front();
A general class to denote the return status of an API call.
static const int kDumpDataForLearning
static const int kDumpFeatureProto
static int LaneTurnType(const std::string &lane_id)
Get lane turn type.
static std::shared_ptr< const hdmap::LaneInfo > LaneWithSmallestAverageCurvature(const std::vector< std::shared_ptr< const hdmap::LaneInfo > > &lane_infos)
Get the pointer to the lane with the smallest average curvature
static std::shared_ptr< const hdmap::LaneInfo > LaneById(const std::string &id)
Get a shared pointer to a lane by lane ID.
bool IsOnLaneGraph(std::shared_ptr< const hdmap::LaneInfo > lane_info_ptr, const LaneGraph &lane_graph)
Check if a lane with an s is on the lane graph
common::Status BuildLaneGraph(LaneGraph *const lane_graph)
Build the lane graph.
common::Status BuildLaneGraphBidirection(LaneGraph *const lane_graph_ptr)
RoadGraph(const double start_s, const double length, const bool consider_divide, std::shared_ptr< const hdmap::LaneInfo > lane_info_ptr)
Constructor
double NormalizeAngle(const double angle)
Normalize angle to [-PI, PI).
Holds all global constants for the prediction module.
repeated LaneSequence lane_sequence
repeated LaneSegment lane_segment