Apollo 10.0
自动驾驶开放平台
topo_node.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 *****************************************************************************/
16
18
19#include <algorithm>
20#include <cmath>
21#include <utility>
22
23#include "cyber/common/log.h"
26
27namespace apollo {
28namespace routing {
29
30namespace {
31
32const double MIN_INTERNAL_FOR_NODE = 0.01; // in meter
33const double kLenghtEpsilon = 1e-6; // in meter
34
35using apollo::common::util::FindPtrOrNull;
36using ::google::protobuf::RepeatedPtrField;
37
38void ConvertOutRange(const RepeatedPtrField<CurveRange>& range_vec,
39 double start_s, double end_s,
40 std::vector<NodeSRange>* out_range, int* prefer_index) {
41 out_range->clear();
42 for (const auto& c_range : range_vec) {
43 double s_s = c_range.start().s();
44 double e_s = c_range.end().s();
45 if (e_s < start_s || s_s > end_s || e_s < s_s) {
46 continue;
47 }
48 s_s = std::max(start_s, s_s);
49 e_s = std::min(end_s, e_s);
50 NodeSRange s_range(s_s, e_s);
51 out_range->push_back(std::move(s_range));
52 }
53 sort(out_range->begin(), out_range->end());
54 int max_index = -1;
55 double max_diff = 0.0;
56 for (size_t i = 0; i < out_range->size(); ++i) {
57 if (out_range->at(i).Length() > max_diff) {
58 max_index = static_cast<int>(i);
59 max_diff = out_range->at(i).Length();
60 }
61 }
62 *prefer_index = max_index;
63}
64
65} // namespace
66
67bool TopoNode::IsOutRangeEnough(const std::vector<NodeSRange>& range_vec,
68 double start_s, double end_s) {
69 if (!NodeSRange::IsEnoughForChangeLane(start_s, end_s)) {
70 return false;
71 }
72 int start_index = BinarySearchForSLarger(range_vec, start_s);
73 int end_index = BinarySearchForSSmaller(range_vec, end_s);
74
75 int index_diff = end_index - start_index;
76 if (start_index < 0 || end_index < 0) {
77 return false;
78 }
79 if (index_diff > 1) {
80 return true;
81 }
82
83 double pre_s_s = std::max(start_s, range_vec[start_index].StartS());
84 double suc_e_s = std::min(end_s, range_vec[end_index].EndS());
85
86 if (index_diff == 1) {
87 double dlt = range_vec[start_index].EndS() - pre_s_s;
88 dlt += suc_e_s - range_vec[end_index].StartS();
90 }
91 if (index_diff == 0) {
92 return NodeSRange::IsEnoughForChangeLane(pre_s_s, suc_e_s);
93 }
94 return false;
95}
96
98 : pb_node_(node), start_s_(0.0), end_s_(pb_node_.length()) {
99 ACHECK(pb_node_.length() > kLenghtEpsilon)
100 << "Node length is invalid in pb: " << pb_node_.DebugString();
101 Init();
102 origin_node_ = this;
103}
104
106 : TopoNode(topo_node->PbNode()) {
107 origin_node_ = topo_node;
108 start_s_ = range.StartS();
109 end_s_ = range.EndS();
110 Init();
111}
112
114
115void TopoNode::Init() {
116 if (!FindAnchorPoint()) {
117 AWARN << "Be attention!!! Find anchor point failed for lane: " << LaneId();
118 }
119 ConvertOutRange(pb_node_.left_out(), start_s_, end_s_,
120 &left_out_sorted_range_, &left_prefer_range_index_);
121
122 is_left_range_enough_ =
123 (left_prefer_range_index_ >= 0) &&
124 left_out_sorted_range_[left_prefer_range_index_].IsEnoughForChangeLane();
125
126 ConvertOutRange(pb_node_.right_out(), start_s_, end_s_,
127 &right_out_sorted_range_, &right_prefer_range_index_);
128 is_right_range_enough_ = (right_prefer_range_index_ >= 0) &&
129 right_out_sorted_range_[right_prefer_range_index_]
130 .IsEnoughForChangeLane();
131}
132
133bool TopoNode::FindAnchorPoint() {
134 double total_size = 0;
135 for (const auto& seg : CentralCurve().segment()) {
136 total_size += seg.line_segment().point_size();
137 }
138 double rate = (StartS() + EndS()) / 2.0 / Length();
139 int anchor_index = static_cast<int>(total_size * rate);
140 for (const auto& seg : CentralCurve().segment()) {
141 if (anchor_index < seg.line_segment().point_size()) {
142 SetAnchorPoint(seg.line_segment().point(anchor_index));
143 return true;
144 }
145 anchor_index -= seg.line_segment().point_size();
146 }
147 return false;
148}
149
150void TopoNode::SetAnchorPoint(const common::PointENU& anchor_point) {
151 anchor_point_ = anchor_point;
152}
153
154const Node& TopoNode::PbNode() const { return pb_node_; }
155
156double TopoNode::Length() const { return pb_node_.length(); }
157
158double TopoNode::Cost() const { return pb_node_.cost(); }
159
160bool TopoNode::IsVirtual() const { return pb_node_.is_virtual(); }
161
162const std::string& TopoNode::LaneId() const { return pb_node_.lane_id(); }
163
164const std::string& TopoNode::RoadId() const { return pb_node_.road_id(); }
165
167 return pb_node_.central_curve();
168}
169
170const common::PointENU& TopoNode::AnchorPoint() const { return anchor_point_; }
171
172const std::vector<NodeSRange>& TopoNode::LeftOutRange() const {
173 return left_out_sorted_range_;
174}
175
176const std::vector<NodeSRange>& TopoNode::RightOutRange() const {
177 return right_out_sorted_range_;
178}
179
180const std::unordered_set<const TopoEdge*>& TopoNode::InFromAllEdge() const {
181 return in_from_all_edge_set_;
182}
183
184const std::unordered_set<const TopoEdge*>& TopoNode::InFromLeftEdge() const {
185 return in_from_left_edge_set_;
186}
187
188const std::unordered_set<const TopoEdge*>& TopoNode::InFromRightEdge() const {
189 return in_from_right_edge_set_;
190}
191
192const std::unordered_set<const TopoEdge*>& TopoNode::InFromLeftOrRightEdge()
193 const {
194 return in_from_left_or_right_edge_set_;
195}
196
197const std::unordered_set<const TopoEdge*>& TopoNode::InFromPreEdge() const {
198 return in_from_pre_edge_set_;
199}
200
201const std::unordered_set<const TopoEdge*>& TopoNode::OutToAllEdge() const {
202 return out_to_all_edge_set_;
203}
204
205const std::unordered_set<const TopoEdge*>& TopoNode::OutToLeftEdge() const {
206 return out_to_left_edge_set_;
207}
208
209const std::unordered_set<const TopoEdge*>& TopoNode::OutToRightEdge() const {
210 return out_to_right_edge_set_;
211}
212
213const std::unordered_set<const TopoEdge*>& TopoNode::OutToLeftOrRightEdge()
214 const {
215 return out_to_left_or_right_edge_set_;
216}
217
218const std::unordered_set<const TopoEdge*>& TopoNode::OutToSucEdge() const {
219 return out_to_suc_edge_set_;
220}
221
222const TopoEdge* TopoNode::GetInEdgeFrom(const TopoNode* from_node) const {
223 return FindPtrOrNull(in_edge_map_, from_node);
224}
225
226const TopoEdge* TopoNode::GetOutEdgeTo(const TopoNode* to_node) const {
227 return FindPtrOrNull(out_edge_map_, to_node);
228}
229
230const TopoNode* TopoNode::OriginNode() const { return origin_node_; }
231
232double TopoNode::StartS() const { return start_s_; }
233
234double TopoNode::EndS() const { return end_s_; }
235
236bool TopoNode::IsSubNode() const { return OriginNode() != this; }
237
239 const TopoEdge* edge_for_type) const {
240 if (edge_for_type->Type() == TET_LEFT) {
241 return (is_left_range_enough_ &&
242 IsOutRangeEnough(left_out_sorted_range_, sub_node->StartS(),
243 sub_node->EndS()));
244 }
245 if (edge_for_type->Type() == TET_RIGHT) {
246 return (is_right_range_enough_ &&
247 IsOutRangeEnough(right_out_sorted_range_, sub_node->StartS(),
248 sub_node->EndS()));
249 }
250 if (edge_for_type->Type() == TET_FORWARD) {
251 return IsOutToSucEdgeValid() && sub_node->IsInFromPreEdgeValid();
252 }
253 return true;
254}
255
256void TopoNode::AddInEdge(const TopoEdge* edge) {
257 if (edge->ToNode() != this) {
258 return;
259 }
260 if (in_edge_map_.count(edge->FromNode()) != 0) {
261 return;
262 }
263 switch (edge->Type()) {
264 case TET_LEFT:
265 in_from_right_edge_set_.insert(edge);
266 in_from_left_or_right_edge_set_.insert(edge);
267 break;
268 case TET_RIGHT:
269 in_from_left_edge_set_.insert(edge);
270 in_from_left_or_right_edge_set_.insert(edge);
271 break;
272 default:
273 in_from_pre_edge_set_.insert(edge);
274 break;
275 }
276 in_from_all_edge_set_.insert(edge);
277 in_edge_map_[edge->FromNode()] = edge;
278}
279
281 if (edge->FromNode() != this) {
282 return;
283 }
284 if (out_edge_map_.count(edge->ToNode()) != 0) {
285 return;
286 }
287 switch (edge->Type()) {
288 case TET_LEFT:
289 out_to_left_edge_set_.insert(edge);
290 out_to_left_or_right_edge_set_.insert(edge);
291 break;
292 case TET_RIGHT:
293 out_to_right_edge_set_.insert(edge);
294 out_to_left_or_right_edge_set_.insert(edge);
295 break;
296 default:
297 out_to_suc_edge_set_.insert(edge);
298 break;
299 }
300 out_to_all_edge_set_.insert(edge);
301 out_edge_map_[edge->ToNode()] = edge;
302}
303
305 return std::fabs(StartS() - OriginNode()->StartS()) < MIN_INTERNAL_FOR_NODE;
306}
307
309 return std::fabs(EndS() - OriginNode()->EndS()) < MIN_INTERNAL_FOR_NODE;
310}
311
312TopoEdge::TopoEdge(const Edge& edge, const TopoNode* from_node,
313 const TopoNode* to_node)
314 : pb_edge_(edge), from_node_(from_node), to_node_(to_node) {}
315
317
318const Edge& TopoEdge::PbEdge() const { return pb_edge_; }
319
320double TopoEdge::Cost() const { return pb_edge_.cost(); }
321
322const TopoNode* TopoEdge::FromNode() const { return from_node_; }
323
324const TopoNode* TopoEdge::ToNode() const { return to_node_; }
325
326const std::string& TopoEdge::FromLaneId() const {
327 return pb_edge_.from_lane_id();
328}
329
330const std::string& TopoEdge::ToLaneId() const { return pb_edge_.to_lane_id(); }
331
333 if (pb_edge_.direction_type() == Edge::LEFT) {
334 return TET_LEFT;
335 }
336 if (pb_edge_.direction_type() == Edge::RIGHT) {
337 return TET_RIGHT;
338 }
339 return TET_FORWARD;
340}
341} // namespace routing
342} // namespace apollo
const TopoNode * topo_node
bool IsEnoughForChangeLane() const
Definition topo_range.cc:48
const TopoNode * ToNode() const
Definition topo_node.cc:324
const Edge & PbEdge() const
Definition topo_node.cc:318
const std::string & FromLaneId() const
Definition topo_node.cc:326
const TopoNode * FromNode() const
Definition topo_node.cc:322
TopoEdgeType Type() const
Definition topo_node.cc:332
TopoEdge(const Edge &edge, const TopoNode *from_node, const TopoNode *to_node)
Definition topo_node.cc:312
const std::string & ToLaneId() const
Definition topo_node.cc:330
const std::unordered_set< const TopoEdge * > & InFromAllEdge() const
Definition topo_node.cc:180
TopoNode(const Node &node)
Definition topo_node.cc:97
const TopoNode * OriginNode() const
Definition topo_node.cc:230
const std::unordered_set< const TopoEdge * > & OutToSucEdge() const
Definition topo_node.cc:218
const Node & PbNode() const
Definition topo_node.cc:154
const std::unordered_set< const TopoEdge * > & OutToRightEdge() const
Definition topo_node.cc:209
const std::vector< NodeSRange > & LeftOutRange() const
Definition topo_node.cc:172
bool IsOutToSucEdgeValid() const
Definition topo_node.cc:308
void AddOutEdge(const TopoEdge *edge)
Definition topo_node.cc:280
const std::string & LaneId() const
Definition topo_node.cc:162
const std::vector< NodeSRange > & RightOutRange() const
Definition topo_node.cc:176
bool IsInFromPreEdgeValid() const
Definition topo_node.cc:304
static bool IsOutRangeEnough(const std::vector< NodeSRange > &range_vec, double start_s, double end_s)
Definition topo_node.cc:67
const std::unordered_set< const TopoEdge * > & OutToLeftEdge() const
Definition topo_node.cc:205
void AddInEdge(const TopoEdge *edge)
Definition topo_node.cc:256
const TopoEdge * GetOutEdgeTo(const TopoNode *to_node) const
Definition topo_node.cc:226
const std::unordered_set< const TopoEdge * > & InFromRightEdge() const
Definition topo_node.cc:188
const hdmap::Curve & CentralCurve() const
Definition topo_node.cc:166
const std::unordered_set< const TopoEdge * > & OutToLeftOrRightEdge() const
Definition topo_node.cc:213
const std::unordered_set< const TopoEdge * > & InFromLeftEdge() const
Definition topo_node.cc:184
const std::unordered_set< const TopoEdge * > & InFromPreEdge() const
Definition topo_node.cc:197
const std::unordered_set< const TopoEdge * > & OutToAllEdge() const
Definition topo_node.cc:201
const std::string & RoadId() const
Definition topo_node.cc:164
const common::PointENU & AnchorPoint() const
Definition topo_node.cc:170
const TopoEdge * GetInEdgeFrom(const TopoNode *from_node) const
Definition topo_node.cc:222
const std::unordered_set< const TopoEdge * > & InFromLeftOrRightEdge() const
Definition topo_node.cc:192
bool IsOverlapEnough(const TopoNode *sub_node, const TopoEdge *edge_for_type) const
Definition topo_node.cc:238
#define ACHECK(cond)
Definition log.h:80
#define AWARN
Definition log.h:43
Some map util functions.
int BinarySearchForSSmaller(const std::vector< T > &sorted_vec, double value_s)
Definition range_utils.h:50
int BinarySearchForSLarger(const std::vector< T > &sorted_vec, double value_s)
Definition range_utils.h:25
class register implement
Definition arena_queue.h:37
optional string from_lane_id
optional double cost
optional DirectionType direction_type
optional string to_lane_id
repeated CurveRange left_out
optional bool is_virtual
optional string lane_id
repeated CurveRange right_out
optional double length
optional apollo::hdmap::Curve central_curve
optional double cost
optional string road_id