20#include <unordered_set>
28using apollo::common::util::ContainsKey;
31 static constexpr double kEpsilon = 1e-6;
32 return std::fabs(value_1 - value_2) < kEpsilon;
36 const std::vector<NodeWithRange>& node_vec) {
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();
46 return node_vec[result_idx];
49bool ResultGenerator::ExtractBasicPassages(
50 const std::vector<NodeWithRange>& nodes,
51 std::vector<PassageInfo>*
const passages) {
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) {
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();
65 auto change_lane_type =
LEFT;
67 change_lane_type =
RIGHT;
69 passages->emplace_back(nodes_of_passage, change_lane_type);
70 nodes_of_passage.clear();
72 nodes_of_passage.push_back(nodes.at(i));
74 passages->emplace_back(nodes_of_passage,
FORWARD);
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 &&
85 *reachable_node = to_node;
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 &&
99 *reachable_node = from_node;
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());
113 auto& front_node = curr_passage->nodes.front();
116 if (!range_manager.Find(front_node.GetTopoNode())) {
117 if (
IsCloseEnough(prev_passage.nodes.front().StartS(), 0.0)) {
118 front_node.SetStartS(0.0);
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);
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();
138 if (ContainsKey(node_set_of_curr_passage, pred_node)) {
142 NodeWithRange reachable_node(pred_node, 0, 1);
143 if (IsReachableToWithChangeLane(pred_node, prev_passage,
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();
149 pred_set.emplace_back(pred_node, black_s_end, pred_node->Length());
152 pred_set.emplace_back(pred_node, 0.0, pred_node->Length());
156 if (pred_set.empty()) {
157 allowed_to_explore =
false;
159 allowed_to_explore =
true;
161 curr_passage->nodes.insert(curr_passage->nodes.begin(), node_to_insert);
162 node_set_of_curr_passage.emplace(node_to_insert.GetTopoNode());
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());
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())) {
178 next_passage.nodes.back().FullLength())) {
179 back_node.SetEndS(back_node.FullLength());
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 <<
"]";
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();
203 if (ContainsKey(node_set_of_curr_passage, succ_node)) {
207 NodeWithRange reachable_node(succ_node, 0, 1.0);
208 if (IsReachableFromWithChangeLane(succ_node, next_passage,
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();
214 succ_set.emplace_back(succ_node, 0.0, black_s_start);
218 reachable_node.FullLength())) {
219 succ_set.emplace_back(succ_node, 0.0, succ_node->Length());
221 double push_end_s = reachable_node.EndS() /
222 reachable_node.FullLength() *
224 succ_set.emplace_back(succ_node, 0.0, push_end_s);
229 if (succ_set.empty()) {
230 allowed_to_explore =
false;
232 allowed_to_explore =
true;
234 curr_passage->nodes.push_back(node_to_insert);
235 node_set_of_curr_passage.emplace(node_to_insert.GetTopoNode());
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)));
248 ExtendBackward(range_manager, passages->at(i - 1), &(passages->at(i)));
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)));
256 ExtendBackward(range_manager, passages->at(i - 1), &(passages->at(i)));
262 const std::vector<NodeWithRange>::const_iterator begin,
263 const std::vector<NodeWithRange>::const_iterator end,
265 for (
auto it = begin; it != end; ++it) {
267 seg->set_id(it->LaneId());
268 seg->set_start_s(it->StartS());
269 seg->set_end_s(it->EndS());
279 double distance = nodes.at(0).EndS() - nodes.at(0).StartS();
280 for (
size_t i = 1; i < nodes.size(); ++i) {
282 nodes.at(i - 1).GetTopoNode()->GetOutEdgeTo(nodes.at(i).GetTopoNode());
283 if (edge ==
nullptr || edge->Type() !=
TET_FORWARD) {
286 distance += nodes.at(i).EndS() - nodes.at(i).StartS();
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() <<
")";
305 const std::vector<NodeWithRange>& nodes,
312 result->set_map_version(map_version);
314 result->mutable_routing_request()->CopyFrom(request);
319 const std::vector<NodeWithRange>& nodes,
322 std::vector<PassageInfo> passages;
323 if (!ExtractBasicPassages(nodes, &passages)) {
326 ExtendPassages(range_manager, &passages);
328 CreateRoadSegments(passages, result);
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();
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)
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;
359 if (start_index.first == end_index.first) {
360 passage->set_change_lane_type(
FORWARD);
361 passage->set_can_exit(
true);
363 passage->set_change_lane_type(passages[i].change_lane_type);
364 passage->set_can_exit(i == end_index.first);
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)) ||
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;
390 if (in_change_lane) {
391 ADEBUG <<
"start_index(" << start_index.first <<
", "
392 << start_index.second <<
") end_index(" << i <<
", " << j - 1
394 AddRoadSegment(passages, start_index, {i, j - 1}, result);
396 ADEBUG <<
"start_index(" << i <<
", " << j <<
") end_index(" << i
398 AddRoadSegment(passages, {i, j}, {i, j}, result);
399 in_change_lane =
false;
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},
bool GeneratePassageRegion(const std::string &map_version, const routing::RoutingRequest &request, const std::vector< NodeWithRange > &nodes, const TopoRangeManager &range_manager, routing::RoutingResponse *const result)
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)