Apollo 10.0
自动驾驶开放平台
result_generator.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2017 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 *****************************************************************************/
17
18#include <algorithm>
19#include <cmath>
20#include <unordered_set>
21
22#include "cyber/common/log.h"
24
25namespace apollo {
26namespace routing {
27
28using apollo::common::util::ContainsKey;
29
30bool IsCloseEnough(double value_1, double value_2) {
31 static constexpr double kEpsilon = 1e-6;
32 return std::fabs(value_1 - value_2) < kEpsilon;
33}
34
36 const std::vector<NodeWithRange>& node_vec) {
37 ACHECK(!node_vec.empty());
38 size_t result_idx = 0;
39 double result_range_length = 0.0;
40 for (size_t i = 0; i < node_vec.size(); ++i) {
41 if (node_vec[i].Length() > result_range_length) {
42 result_range_length = node_vec[i].Length();
43 result_idx = i;
44 }
45 }
46 return node_vec[result_idx];
47}
48
49bool ResultGenerator::ExtractBasicPassages(
50 const std::vector<NodeWithRange>& nodes,
51 std::vector<PassageInfo>* const passages) {
52 ACHECK(!nodes.empty());
53 passages->clear();
54 std::vector<NodeWithRange> nodes_of_passage;
55 nodes_of_passage.push_back(nodes.at(0));
56 for (size_t i = 1; i < nodes.size(); ++i) {
57 auto edge =
58 nodes.at(i - 1).GetTopoNode()->GetOutEdgeTo(nodes.at(i).GetTopoNode());
59 if (edge == nullptr) {
60 AERROR << "Get null pointer to edge from " << nodes.at(i - 1).LaneId()
61 << " to " << nodes.at(i).LaneId();
62 return false;
63 }
64 if (edge->Type() == TET_LEFT || edge->Type() == TET_RIGHT) {
65 auto change_lane_type = LEFT;
66 if (edge->Type() == TET_RIGHT) {
67 change_lane_type = RIGHT;
68 }
69 passages->emplace_back(nodes_of_passage, change_lane_type);
70 nodes_of_passage.clear();
71 }
72 nodes_of_passage.push_back(nodes.at(i));
73 }
74 passages->emplace_back(nodes_of_passage, FORWARD);
75 return true;
76}
77
78bool ResultGenerator::IsReachableFromWithChangeLane(
79 const TopoNode* from_node, const PassageInfo& to_nodes,
80 NodeWithRange* reachable_node) {
81 for (const auto& to_node : to_nodes.nodes) {
82 auto edge = to_node.GetTopoNode()->GetInEdgeFrom(from_node);
83 if (edge != nullptr &&
84 (edge->Type() == TET_LEFT || edge->Type() == TET_RIGHT)) {
85 *reachable_node = to_node;
86 return true;
87 }
88 }
89 return false;
90}
91
92bool ResultGenerator::IsReachableToWithChangeLane(
93 const TopoNode* to_node, const PassageInfo& from_nodes,
94 NodeWithRange* reachable_node) {
95 for (const auto& from_node : from_nodes.nodes) {
96 auto edge = from_node.GetTopoNode()->GetOutEdgeTo(to_node);
97 if (edge != nullptr &&
98 (edge->Type() == TET_LEFT || edge->Type() == TET_RIGHT)) {
99 *reachable_node = from_node;
100 return true;
101 }
102 }
103 return false;
104}
105
106void ResultGenerator::ExtendBackward(const TopoRangeManager& range_manager,
107 const PassageInfo& prev_passage,
108 PassageInfo* const curr_passage) {
109 std::unordered_set<const TopoNode*> node_set_of_curr_passage;
110 for (const auto& node : curr_passage->nodes) {
111 node_set_of_curr_passage.insert(node.GetTopoNode());
112 }
113 auto& front_node = curr_passage->nodes.front();
114 // if front node starts at middle
115 if (!IsCloseEnough(front_node.StartS(), 0.0)) {
116 if (!range_manager.Find(front_node.GetTopoNode())) {
117 if (IsCloseEnough(prev_passage.nodes.front().StartS(), 0.0)) {
118 front_node.SetStartS(0.0);
119 } else {
120 double temp_s = prev_passage.nodes.front().StartS() /
121 prev_passage.nodes.front().FullLength() *
122 front_node.FullLength();
123 front_node.SetStartS(temp_s);
124 }
125 } else {
126 return;
127 }
128 }
129
130 bool allowed_to_explore = true;
131 while (allowed_to_explore) {
132 std::vector<NodeWithRange> pred_set;
133 for (const auto& edge :
134 curr_passage->nodes.front().GetTopoNode()->InFromPreEdge()) {
135 const auto& pred_node = edge->FromNode();
136
137 // if pred node has been inserted
138 if (ContainsKey(node_set_of_curr_passage, pred_node)) {
139 continue;
140 }
141 // if pred node is reachable from prev passage
142 NodeWithRange reachable_node(pred_node, 0, 1);
143 if (IsReachableToWithChangeLane(pred_node, prev_passage,
144 &reachable_node)) {
145 const auto* pred_range = range_manager.Find(pred_node);
146 if (pred_range != nullptr && !pred_range->empty()) {
147 double black_s_end = pred_range->back().EndS();
148 if (!IsCloseEnough(black_s_end, pred_node->Length())) {
149 pred_set.emplace_back(pred_node, black_s_end, pred_node->Length());
150 }
151 } else {
152 pred_set.emplace_back(pred_node, 0.0, pred_node->Length());
153 }
154 }
155 }
156 if (pred_set.empty()) {
157 allowed_to_explore = false;
158 } else {
159 allowed_to_explore = true;
160 const auto& node_to_insert = GetLargestRange(pred_set);
161 curr_passage->nodes.insert(curr_passage->nodes.begin(), node_to_insert);
162 node_set_of_curr_passage.emplace(node_to_insert.GetTopoNode());
163 }
164 }
165}
166
167void ResultGenerator::ExtendForward(const TopoRangeManager& range_manager,
168 const PassageInfo& next_passage,
169 PassageInfo* const curr_passage) {
170 std::unordered_set<const TopoNode*> node_set_of_curr_passage;
171 for (const auto& node : curr_passage->nodes) {
172 node_set_of_curr_passage.insert(node.GetTopoNode());
173 }
174 auto& back_node = curr_passage->nodes.back();
175 if (!IsCloseEnough(back_node.EndS(), back_node.FullLength())) {
176 if (!range_manager.Find(back_node.GetTopoNode())) {
177 if (IsCloseEnough(next_passage.nodes.back().EndS(),
178 next_passage.nodes.back().FullLength())) {
179 back_node.SetEndS(back_node.FullLength());
180 } else {
181 double adjusted_end_s = next_passage.nodes.back().EndS() /
182 next_passage.nodes.back().FullLength() *
183 back_node.FullLength();
184 if (adjusted_end_s > back_node.StartS()) {
185 adjusted_end_s = std::min(adjusted_end_s, back_node.FullLength());
186 back_node.SetEndS(adjusted_end_s);
187 ADEBUG << "ExtendForward: orig_end_s[" << back_node.EndS()
188 << "] adjusted_end_s[" << adjusted_end_s << "]";
189 }
190 }
191 } else {
192 return;
193 }
194 }
195
196 bool allowed_to_explore = true;
197 while (allowed_to_explore) {
198 std::vector<NodeWithRange> succ_set;
199 for (const auto& edge :
200 curr_passage->nodes.back().GetTopoNode()->OutToSucEdge()) {
201 const auto& succ_node = edge->ToNode();
202 // if succ node has been inserted
203 if (ContainsKey(node_set_of_curr_passage, succ_node)) {
204 continue;
205 }
206 // if next passage is reachable from succ node
207 NodeWithRange reachable_node(succ_node, 0, 1.0);
208 if (IsReachableFromWithChangeLane(succ_node, next_passage,
209 &reachable_node)) {
210 const auto* succ_range = range_manager.Find(succ_node);
211 if (succ_range != nullptr && !succ_range->empty()) {
212 double black_s_start = succ_range->front().StartS();
213 if (!IsCloseEnough(black_s_start, 0.0)) {
214 succ_set.emplace_back(succ_node, 0.0, black_s_start);
215 }
216 } else {
217 if (IsCloseEnough(reachable_node.EndS(),
218 reachable_node.FullLength())) {
219 succ_set.emplace_back(succ_node, 0.0, succ_node->Length());
220 } else {
221 double push_end_s = reachable_node.EndS() /
222 reachable_node.FullLength() *
223 succ_node->Length();
224 succ_set.emplace_back(succ_node, 0.0, push_end_s);
225 }
226 }
227 }
228 }
229 if (succ_set.empty()) {
230 allowed_to_explore = false;
231 } else {
232 allowed_to_explore = true;
233 const auto& node_to_insert = GetLargestRange(succ_set);
234 curr_passage->nodes.push_back(node_to_insert);
235 node_set_of_curr_passage.emplace(node_to_insert.GetTopoNode());
236 }
237 }
238}
239
240void ResultGenerator::ExtendPassages(const TopoRangeManager& range_manager,
241 std::vector<PassageInfo>* const passages) {
242 int passage_num = static_cast<int>(passages->size());
243 for (int i = 0; i < passage_num; ++i) {
244 if (i < passage_num - 1) {
245 ExtendForward(range_manager, passages->at(i + 1), &(passages->at(i)));
246 }
247 if (i > 0) {
248 ExtendBackward(range_manager, passages->at(i - 1), &(passages->at(i)));
249 }
250 }
251 for (int i = passage_num - 1; i >= 0; --i) {
252 if (i < passage_num - 1) {
253 ExtendForward(range_manager, passages->at(i + 1), &(passages->at(i)));
254 }
255 if (i > 0) {
256 ExtendBackward(range_manager, passages->at(i - 1), &(passages->at(i)));
257 }
258 }
259}
260
262 const std::vector<NodeWithRange>::const_iterator begin,
263 const std::vector<NodeWithRange>::const_iterator end,
264 Passage* const passage) {
265 for (auto it = begin; it != end; ++it) {
266 LaneSegment* seg = passage->add_segment();
267 seg->set_id(it->LaneId());
268 seg->set_start_s(it->StartS());
269 seg->set_end_s(it->EndS());
270 }
271}
272
273void LaneNodesToPassageRegion(const std::vector<NodeWithRange>& nodes,
274 Passage* const passage) {
275 return LaneNodesToPassageRegion(nodes.begin(), nodes.end(), passage);
276}
277
278double CalculateDistance(const std::vector<NodeWithRange>& nodes) {
279 double distance = nodes.at(0).EndS() - nodes.at(0).StartS();
280 for (size_t i = 1; i < nodes.size(); ++i) {
281 auto edge =
282 nodes.at(i - 1).GetTopoNode()->GetOutEdgeTo(nodes.at(i).GetTopoNode());
283 if (edge == nullptr || edge->Type() != TET_FORWARD) {
284 continue;
285 }
286 distance += nodes.at(i).EndS() - nodes.at(i).StartS();
287 }
288 return distance;
289}
290
291void PrintDebugInfo(const std::string& road_id,
292 const std::vector<std::vector<NodeWithRange>>& nodes) {
293 AINFO << "road id: " << road_id;
294 for (size_t j = 0; j < nodes.size(); ++j) {
295 AINFO << "\tPassage " << j;
296 for (const auto& node : nodes[j]) {
297 AINFO << "\t\t" << node.LaneId() << " (" << node.StartS() << ", "
298 << node.EndS() << ")";
299 }
300 }
301}
302
304 const std::string& map_version, const routing::RoutingRequest& request,
305 const std::vector<NodeWithRange>& nodes,
306 const TopoRangeManager& range_manager,
307 routing::RoutingResponse* const result) {
308 if (!GeneratePassageRegion(nodes, range_manager, result)) {
309 return false;
310 }
311
312 result->set_map_version(map_version);
313 result->mutable_measurement()->set_distance(CalculateDistance(nodes));
314 result->mutable_routing_request()->CopyFrom(request);
315 return true;
316}
317
319 const std::vector<NodeWithRange>& nodes,
320 const TopoRangeManager& range_manager,
321 routing::RoutingResponse* const result) {
322 std::vector<PassageInfo> passages;
323 if (!ExtractBasicPassages(nodes, &passages)) {
324 return false;
325 }
326 ExtendPassages(range_manager, &passages);
327
328 CreateRoadSegments(passages, result);
329
330 return true;
331}
332
333void ResultGenerator::AddRoadSegment(
334 const std::vector<PassageInfo>& passages,
335 const std::pair<std::size_t, std::size_t>& start_index,
336 const std::pair<std::size_t, std::size_t>& end_index,
337 routing::RoutingResponse* result) {
338 auto* road = result->add_road();
339
340 road->set_id(passages[start_index.first].nodes[start_index.second].RoadId());
341 for (std::size_t i = start_index.first;
342 i <= end_index.first && i < passages.size(); ++i) {
343 auto* passage = road->add_passage();
344 const size_t node_start_index =
345 (i == start_index.first ? std::max((std::size_t)0, start_index.second)
346 : 0);
347 const auto node_begin_iter = passages[i].nodes.cbegin() + node_start_index;
348 ADEBUG << "start node: " << node_begin_iter->LaneId() << ": "
349 << node_begin_iter->StartS() << "; " << node_begin_iter->EndS();
350 const size_t node_end_index =
351 (i == end_index.first
352 ? std::min(end_index.second, passages[i].nodes.size() - 1)
353 : passages[i].nodes.size() - 1);
354 const auto node_last_iter = passages[i].nodes.cbegin() + node_end_index;
355 ADEBUG << "last node: " << node_last_iter->LaneId() << ": "
356 << node_last_iter->StartS() << "; " << node_last_iter->EndS();
357 auto node_end_iter = node_last_iter + 1;
358 LaneNodesToPassageRegion(node_begin_iter, node_end_iter, passage);
359 if (start_index.first == end_index.first) {
360 passage->set_change_lane_type(FORWARD);
361 passage->set_can_exit(true);
362 } else {
363 passage->set_change_lane_type(passages[i].change_lane_type);
364 passage->set_can_exit(i == end_index.first);
365 }
366 }
367}
368
369void ResultGenerator::CreateRoadSegments(
370 const std::vector<PassageInfo>& passages,
371 routing::RoutingResponse* result) {
372 ACHECK(!passages.empty()) << "passages empty";
373 NodeWithRange fake_node_range(passages.front().nodes.front());
374 bool in_change_lane = false;
375 std::pair<std::size_t, std::size_t> start_index(0, 0);
376 for (std::size_t i = 0; i < passages.size(); ++i) {
377 const auto& curr_nodes = passages[i].nodes;
378 for (std::size_t j = 0; j < curr_nodes.size(); ++j) {
379 if ((i + 1 < passages.size() &&
380 IsReachableToWithChangeLane(curr_nodes[j].GetTopoNode(),
381 passages[i + 1], &fake_node_range)) ||
382 (i > 0 &&
383 IsReachableFromWithChangeLane(curr_nodes[j].GetTopoNode(),
384 passages[i - 1], &fake_node_range))) {
385 if (!in_change_lane) {
386 start_index = {i, j};
387 in_change_lane = true;
388 }
389 } else {
390 if (in_change_lane) {
391 ADEBUG << "start_index(" << start_index.first << ", "
392 << start_index.second << ") end_index(" << i << ", " << j - 1
393 << ")";
394 AddRoadSegment(passages, start_index, {i, j - 1}, result);
395 }
396 ADEBUG << "start_index(" << i << ", " << j << ") end_index(" << i
397 << ", " << j << ")";
398 AddRoadSegment(passages, {i, j}, {i, j}, result);
399 in_change_lane = false;
400 }
401 }
402 }
403 if (in_change_lane) {
404 ADEBUG << "start_index(" << start_index.first << ", " << start_index.second
405 << ") end_index(" << passages.size() - 1 << ", "
406 << passages.back().nodes.size() - 1 << ")";
407 AddRoadSegment(passages, start_index,
408 {passages.size() - 1, passages.back().nodes.size() - 1},
409 result);
410 }
411}
412
413} // namespace routing
414} // namespace apollo
bool GeneratePassageRegion(const std::string &map_version, const routing::RoutingRequest &request, const std::vector< NodeWithRange > &nodes, const TopoRangeManager &range_manager, routing::RoutingResponse *const result)
#define ACHECK(cond)
Definition log.h:80
#define ADEBUG
Definition log.h:41
#define AERROR
Definition log.h:44
#define AINFO
Definition log.h:42
Some map util functions.
void PrintDebugInfo(const std::string &road_id, const std::vector< std::vector< NodeWithRange > > &nodes)
const NodeWithRange & GetLargestRange(const std::vector< NodeWithRange > &node_vec)
bool IsCloseEnough(double value_1, double value_2)
double CalculateDistance(const std::vector< NodeWithRange > &nodes)
void LaneNodesToPassageRegion(const std::vector< NodeWithRange >::const_iterator begin, const std::vector< NodeWithRange >::const_iterator end, Passage *const passage)
class register implement
Definition arena_queue.h:37