Apollo 10.0
自动驾驶开放平台
navigator.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 "cyber/common/file.h"
23
24namespace apollo {
25namespace routing {
26
27namespace {
28
30
31bool ShowRequestInfo(const routing::RoutingRequest& request,
32 const TopoGraph* graph) {
33 for (const auto& wp : request.waypoint()) {
34 const auto* node = graph->GetNode(wp.id());
35 if (node == nullptr) {
36 AERROR << "Way node is not found in topo graph! ID: " << wp.id();
37 return false;
38 }
39 AINFO << "Way point:\tlane id: " << wp.id() << " s: " << wp.s()
40 << " x: " << wp.pose().x() << " y: " << wp.pose().y()
41 << " length: " << node->Length();
42 }
43
44 for (const auto& bl : request.blacklisted_lane()) {
45 const auto* node = graph->GetNode(bl.id());
46 if (node == nullptr) {
47 AERROR << "Black list node is not found in topo graph! ID: " << bl.id();
48 return false;
49 }
50 AINFO << "Black point:\tlane id: " << bl.id()
51 << " start_s: " << bl.start_s() << " end_s: " << bl.end_s()
52 << " length: " << node->Length();
53 }
54
55 return true;
56}
57
58bool GetWayNodes(const routing::RoutingRequest& request,
59 const TopoGraph* graph,
60 std::vector<const TopoNode*>* const way_nodes,
61 std::vector<double>* const way_s) {
62 for (const auto& point : request.waypoint()) {
63 const auto* cur_node = graph->GetNode(point.id());
64 if (cur_node == nullptr) {
65 AERROR << "Cannot find way point in graph! Id: " << point.id();
66 return false;
67 }
68 way_nodes->push_back(cur_node);
69 way_s->push_back(point.s());
70 }
71 return true;
72}
73
74void SetErrorCode(const common::ErrorCode& error_code_id,
75 const std::string& error_string,
76 common::StatusPb* const error_code) {
77 error_code->set_error_code(error_code_id);
78 error_code->set_msg(error_string);
79 if (error_code_id == common::ErrorCode::OK) {
80 ADEBUG << error_string.c_str();
81 } else {
82 AERROR << error_string.c_str();
83 }
84}
85
86void PrintDebugData(const std::vector<NodeWithRange>& nodes) {
87 AINFO << "Route lane id\tis virtual\tstart s\tend s";
88 for (const auto& node : nodes) {
89 AINFO << node.GetTopoNode()->LaneId() << "\t"
90 << node.GetTopoNode()->IsVirtual() << "\t" << node.StartS() << "\t"
91 << node.EndS();
92 }
93}
94
95} // namespace
96
97Navigator::Navigator(const std::string& topo_file_path) {
98 Graph graph;
99 if (!cyber::common::GetProtoFromFile(topo_file_path, &graph)) {
100 AERROR << "Failed to read topology graph from " << topo_file_path;
101 return;
102 }
103
104 graph_.reset(new TopoGraph());
105 if (!graph_->LoadGraph(graph)) {
106 AINFO << "Failed to init navigator graph failed! File path: "
107 << topo_file_path;
108 return;
109 }
110 black_list_generator_.reset(new BlackListRangeGenerator);
111 result_generator_.reset(new ResultGenerator);
112 is_ready_ = true;
113 AINFO << "The navigator is ready.";
114}
115
117
118bool Navigator::IsReady() const { return is_ready_; }
119
120void Navigator::Clear() { topo_range_manager_.Clear(); }
121
122bool Navigator::Init(const routing::RoutingRequest& request,
123 const TopoGraph* graph,
124 std::vector<const TopoNode*>* const way_nodes,
125 std::vector<double>* const way_s) {
126 Clear();
127 if (!GetWayNodes(request, graph_.get(), way_nodes, way_s)) {
128 AERROR << "Failed to find search terminal point in graph!";
129 return false;
130 }
131 black_list_generator_->GenerateBlackMapFromRequest(request, graph_.get(),
132 &topo_range_manager_);
133 return true;
134}
135
136bool Navigator::MergeRoute(
137 const std::vector<NodeWithRange>& node_vec,
138 std::vector<NodeWithRange>* const result_node_vec) const {
139 for (const auto& node : node_vec) {
140 if (result_node_vec->empty() ||
141 result_node_vec->back().GetTopoNode() != node.GetTopoNode()) {
142 result_node_vec->push_back(node);
143 } else {
144 if (result_node_vec->back().EndS() < node.StartS()) {
145 AERROR << "Result route is not continuous.";
146 return false;
147 }
148 result_node_vec->back().SetEndS(node.EndS());
149 }
150 }
151 return true;
152}
153
154bool Navigator::SearchRouteByStrategy(
155 const TopoGraph* graph, const std::vector<const TopoNode*>& way_nodes,
156 const std::vector<double>& way_s,
157 std::vector<NodeWithRange>* const result_nodes) const {
158 std::unique_ptr<Strategy> strategy_ptr;
159 strategy_ptr.reset(new AStarStrategy(FLAGS_enable_change_lane_in_result));
160
161 result_nodes->clear();
162 std::vector<NodeWithRange> node_vec;
163 for (size_t i = 1; i < way_nodes.size(); ++i) {
164 const auto* way_start = way_nodes[i - 1];
165 const auto* way_end = way_nodes[i];
166 double way_start_s = way_s[i - 1];
167 double way_end_s = way_s[i];
168
169 TopoRangeManager full_range_manager = topo_range_manager_;
170 black_list_generator_->AddBlackMapFromTerminal(
171 way_start, way_end, way_start_s, way_end_s, &full_range_manager);
172
173 SubTopoGraph sub_graph(full_range_manager.RangeMap());
174 const auto* start = sub_graph.GetSubNodeWithS(way_start, way_start_s);
175 if (start == nullptr) {
176 AERROR << "Sub graph node is nullptr, origin node id: "
177 << way_start->LaneId() << ", s:" << way_start_s;
178 return false;
179 }
180 const auto* end = sub_graph.GetSubNodeWithS(way_end, way_end_s);
181 if (end == nullptr) {
182 AERROR << "Sub graph node is nullptr, origin node id: "
183 << way_end->LaneId() << ", s:" << way_end_s;
184 return false;
185 }
186
187 std::vector<NodeWithRange> cur_result_nodes;
188 if (!strategy_ptr->Search(graph, &sub_graph, start, end,
189 &cur_result_nodes)) {
190 AERROR << "Failed to search route with waypoint from " << start->LaneId()
191 << " to " << end->LaneId();
192 return false;
193 }
194
195 node_vec.insert(node_vec.end(), cur_result_nodes.begin(),
196 cur_result_nodes.end());
197 }
198
199 if (!MergeRoute(node_vec, result_nodes)) {
200 AERROR << "Failed to merge route.";
201 return false;
202 }
203 return true;
204}
205
207 routing::RoutingResponse* const response) {
208 if (!ShowRequestInfo(request, graph_.get())) {
209 SetErrorCode(ErrorCode::ROUTING_ERROR_REQUEST,
210 "Error encountered when reading request point!",
211 response->mutable_status());
212 return false;
213 }
214
215 if (!IsReady()) {
216 SetErrorCode(ErrorCode::ROUTING_ERROR_NOT_READY, "Navigator is not ready!",
217 response->mutable_status());
218 return false;
219 }
220 std::vector<const TopoNode*> way_nodes;
221 std::vector<double> way_s;
222 if (!Init(request, graph_.get(), &way_nodes, &way_s)) {
223 SetErrorCode(ErrorCode::ROUTING_ERROR_NOT_READY,
224 "Failed to initialize navigator!", response->mutable_status());
225 return false;
226 }
227
228 std::vector<NodeWithRange> result_nodes;
229 if (!SearchRouteByStrategy(graph_.get(), way_nodes, way_s, &result_nodes)) {
230 SetErrorCode(ErrorCode::ROUTING_ERROR_RESPONSE,
231 "Failed to find route with request!",
232 response->mutable_status());
233 return false;
234 }
235 if (result_nodes.empty()) {
236 SetErrorCode(ErrorCode::ROUTING_ERROR_RESPONSE, "Failed to result nodes!",
237 response->mutable_status());
238 return false;
239 }
240 result_nodes.front().SetStartS(request.waypoint().begin()->s());
241 result_nodes.back().SetEndS(request.waypoint().rbegin()->s());
242
243 if (!result_generator_->GeneratePassageRegion(
244 graph_->MapVersion(), request, result_nodes, topo_range_manager_,
245 response)) {
246 SetErrorCode(ErrorCode::ROUTING_ERROR_RESPONSE,
247 "Failed to generate passage regions based on result lanes",
248 response->mutable_status());
249 return false;
250 }
251 SetErrorCode(ErrorCode::OK, "Success!", response->mutable_status());
252
253 PrintDebugData(result_nodes);
254 return true;
255}
256
257} // namespace routing
258} // namespace apollo
bool SearchRoute(const routing::RoutingRequest &request, routing::RoutingResponse *const response)
Definition navigator.cc:206
Navigator(const std::string &topo_file_path)
Definition navigator.cc:97
#define ADEBUG
Definition log.h:41
#define AERROR
Definition log.h:44
#define AINFO
Definition log.h:42
bool GetProtoFromFile(const std::string &file_name, google::protobuf::Message *message)
Parses the content of the file specified by the file_name as a representation of protobufs,...
Definition file.cc:132
class register implement
Definition arena_queue.h:37
repeated apollo::routing::LaneWaypoint waypoint
Definition routing.proto:14