Apollo 11.0
自动驾驶开放平台
dp_road_graph.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
22
23#include "modules/common_msgs/basic_msgs/error_code.pb.h"
24#include "modules/common_msgs/planning_msgs/planning_internal.pb.h"
25#include "modules/planning/planning_base/proto/planning_status.pb.h"
26
27#include "cyber/common/log.h"
28#include "cyber/task/task.h"
37
38namespace apollo {
39namespace planning {
40
41DpRoadGraph::DpRoadGraph(const DpPolyPathConfig &config,
42 const ReferenceLineInfo &reference_line_info,
43 const SpeedData &speed_data)
44 : config_(config),
45 reference_line_info_(reference_line_info),
46 reference_line_(reference_line_info.reference_line()),
47 speed_data_(speed_data) {}
48
50 const std::vector<const Obstacle *> &obstacles,
51 PathData *const path_data) {
52 CHECK_NOTNULL(path_data);
53
54 init_point_ = init_point;
55 if (!reference_line_.XYToSL(init_point_.path_point(), &init_sl_point_)) {
56 AERROR << "Fail to create init_sl_point from : "
57 << init_point.DebugString();
58 return false;
59 }
60 init_frenet_frame_point_ =
61 reference_line_.GetFrenetPoint(init_point_.path_point());
62
63 waypoint_sampler_->Init(&reference_line_info_, init_sl_point_,
64 init_frenet_frame_point_);
65 waypoint_sampler_->SetDebugLogger(planning_debug_);
66
67 std::vector<DpRoadGraphNode> min_cost_path;
68 if (!GenerateMinCostPath(obstacles, &min_cost_path)) {
69 AERROR << "Fail to generate graph!";
70 return false;
71 }
72 std::vector<common::FrenetFramePoint> frenet_path;
73 double accumulated_s = min_cost_path.front().sl_point.s();
74 const double path_resolution = config_.path_resolution();
75
76 for (size_t i = 1; i < min_cost_path.size(); ++i) {
77 const auto &prev_node = min_cost_path[i - 1];
78 const auto &cur_node = min_cost_path[i];
79
80 const double path_length = cur_node.sl_point.s() - prev_node.sl_point.s();
81 double current_s = 0.0;
82 const auto &curve = cur_node.min_cost_curve;
83 while (current_s + path_resolution / 2.0 < path_length) {
84 const double l = curve.Evaluate(0, current_s);
85 const double dl = curve.Evaluate(1, current_s);
86 const double ddl = curve.Evaluate(2, current_s);
87 common::FrenetFramePoint frenet_frame_point;
88 frenet_frame_point.set_s(accumulated_s + current_s);
89 frenet_frame_point.set_l(l);
90 frenet_frame_point.set_dl(dl);
91 frenet_frame_point.set_ddl(ddl);
92 frenet_path.push_back(std::move(frenet_frame_point));
93 current_s += path_resolution;
94 }
95 if (i == min_cost_path.size() - 1) {
96 accumulated_s += current_s;
97 } else {
98 accumulated_s += path_length;
99 }
100 }
101 path_data->SetReferenceLine(&reference_line_);
102 path_data->SetFrenetPath(FrenetFramePath(std::move(frenet_path)));
103 return true;
104}
105
106bool DpRoadGraph::GenerateMinCostPath(
107 const std::vector<const Obstacle *> &obstacles,
108 std::vector<DpRoadGraphNode> *min_cost_path) {
109 ACHECK(min_cost_path != nullptr);
110
111 std::vector<std::vector<common::SLPoint>> path_waypoints;
112 if (!waypoint_sampler_->SamplePathWaypoints(init_point_, &path_waypoints) ||
113 path_waypoints.size() < 1) {
114 AERROR << "Fail to sample path waypoints! reference_line_length = "
115 << reference_line_.Length();
116 return false;
117 }
118 const auto &vehicle_config =
119 common::VehicleConfigHelper::Instance()->GetConfig();
120
121 TrajectoryCost trajectory_cost(
122 config_, reference_line_, reference_line_info_.IsChangeLanePath(),
123 obstacles, vehicle_config.vehicle_param(), speed_data_, init_sl_point_,
124 reference_line_info_.AdcSlBoundary());
125
126 std::list<std::list<DpRoadGraphNode>> graph_nodes;
127
128 // find one point from first row
129 const auto &first_row = path_waypoints.front();
130 size_t nearest_i = 0;
131 for (size_t i = 1; i < first_row.size(); ++i) {
132 if (std::fabs(first_row[i].l() - init_sl_point_.l()) <
133 std::fabs(first_row[nearest_i].l() - init_sl_point_.l())) {
134 nearest_i = i;
135 }
136 }
137 graph_nodes.emplace_back();
138 graph_nodes.back().emplace_back(first_row[nearest_i], nullptr,
139 ComparableCost());
140 auto &front = graph_nodes.front().front();
141 size_t total_level = path_waypoints.size();
142
143 for (size_t level = 1; level < path_waypoints.size(); ++level) {
144 const auto &prev_dp_nodes = graph_nodes.back();
145 const auto &level_points = path_waypoints[level];
146
147 graph_nodes.emplace_back();
148 std::vector<std::future<void>> results;
149
150 for (size_t i = 0; i < level_points.size(); ++i) {
151 const auto &cur_point = level_points[i];
152
153 graph_nodes.back().emplace_back(cur_point, nullptr);
154
155 auto msg = std::make_shared<RoadGraphMessage>(
156 prev_dp_nodes, level, total_level, &trajectory_cost, &front,
157 &(graph_nodes.back().back()));
158
159 if (FLAGS_enable_multi_thread_in_dp_poly_path) {
160 results.emplace_back(cyber::Async(&DpRoadGraph::UpdateNode, this, msg));
161 } else {
162 UpdateNode(msg);
163 }
164 }
165 if (FLAGS_enable_multi_thread_in_dp_poly_path) {
166 for (auto &result : results) {
167 result.get();
168 }
169 }
170 }
171
172 // find best path
173 DpRoadGraphNode fake_head;
174 for (const auto &cur_dp_node : graph_nodes.back()) {
175 fake_head.UpdateCost(&cur_dp_node, cur_dp_node.min_cost_curve,
176 cur_dp_node.min_cost);
177 }
178
179 const auto *min_cost_node = &fake_head;
180 while (min_cost_node->min_cost_prev_node) {
181 min_cost_node = min_cost_node->min_cost_prev_node;
182 min_cost_path->push_back(*min_cost_node);
183 }
184 if (min_cost_node != &graph_nodes.front().front()) {
185 return false;
186 }
187
188 std::reverse(min_cost_path->begin(), min_cost_path->end());
189
190 for (const auto &node : *min_cost_path) {
191 ADEBUG << "min_cost_path: " << node.sl_point.ShortDebugString();
192 planning_debug_->mutable_planning_data()
193 ->mutable_dp_poly_graph()
194 ->add_min_cost_point()
195 ->CopyFrom(node.sl_point);
196 }
197 return true;
198}
199
200void DpRoadGraph::UpdateNode(const std::shared_ptr<RoadGraphMessage> &msg) {
201 CHECK_NOTNULL(msg);
202 CHECK_NOTNULL(msg->trajectory_cost);
203 CHECK_NOTNULL(msg->front);
204 CHECK_NOTNULL(msg->cur_node);
205 for (const auto &prev_dp_node : msg->prev_nodes) {
206 const auto &prev_sl_point = prev_dp_node.sl_point;
207 const auto &cur_point = msg->cur_node->sl_point;
208 double init_dl = 0.0;
209 double init_ddl = 0.0;
210 if (msg->level == 1) {
211 init_dl = init_frenet_frame_point_.dl();
212 init_ddl = init_frenet_frame_point_.ddl();
213 }
214 QuinticPolynomialCurve1d curve(prev_sl_point.l(), init_dl, init_ddl,
215 cur_point.l(), 0.0, 0.0,
216 cur_point.s() - prev_sl_point.s());
217
218 if (!IsValidCurve(curve)) {
219 continue;
220 }
221 const auto cost =
222 msg->trajectory_cost->Calculate(curve, prev_sl_point.s(), cur_point.s(),
223 msg->level, msg->total_level) +
224 prev_dp_node.min_cost;
225
226 msg->cur_node->UpdateCost(&prev_dp_node, curve, cost);
227 }
228
229 // try to connect the current point with the first point directly
230 if (reference_line_info_.IsChangeLanePath() && msg->level >= 2) {
231 const double init_dl = init_frenet_frame_point_.dl();
232 const double init_ddl = init_frenet_frame_point_.ddl();
233 QuinticPolynomialCurve1d curve(
234 init_sl_point_.l(), init_dl, init_ddl, msg->cur_node->sl_point.l(), 0.0,
235 0.0, msg->cur_node->sl_point.s() - init_sl_point_.s());
236 if (!IsValidCurve(curve)) {
237 return;
238 }
239 const auto cost = msg->trajectory_cost->Calculate(
240 curve, init_sl_point_.s(), msg->cur_node->sl_point.s(), msg->level,
241 msg->total_level);
242 msg->cur_node->UpdateCost(msg->front, curve, cost);
243 }
244}
245
246bool DpRoadGraph::IsValidCurve(const QuinticPolynomialCurve1d &curve) const {
247 static constexpr double kMaxLateralDistance = 20.0;
248 for (double s = 0.0; s < curve.ParamLength(); s += 2.0) {
249 const double l = curve.Evaluate(0, s);
250 if (std::fabs(l) > kMaxLateralDistance) {
251 return false;
252 }
253 }
254 return true;
255}
256
257void DpRoadGraph::GetCurveCost(TrajectoryCost trajectory_cost,
258 const QuinticPolynomialCurve1d &curve,
259 const double start_s, const double end_s,
260 const uint32_t curr_level,
261 const uint32_t total_level,
262 ComparableCost *cost) {
263 *cost =
264 trajectory_cost.Calculate(curve, start_s, end_s, curr_level, total_level);
265}
266
267} // namespace planning
268} // namespace apollo
bool FindPathTunnel(const common::TrajectoryPoint &init_point, const std::vector< const Obstacle * > &obstacles, PathData *const path_data)
DpRoadGraph(const DpPolyPathConfig &config, const ReferenceLineInfo &reference_line_info, const SpeedData &speed_data)
void SetReferenceLine(const ReferenceLine *reference_line)
Definition path_data.cc:107
bool SetFrenetPath(FrenetFramePath frenet_path)
Definition path_data.cc:58
ReferenceLineInfo holds all data for one reference line.
const SLBoundary & AdcSlBoundary() const
bool IsChangeLanePath() const
Check if the current reference line is a change lane reference line, i.e., ADC's current position is ...
bool XYToSL(const common::math::Vec2d &xy_point, common::SLPoint *const sl_point, double warm_start_s=-1.0) const
Transvert Cartesian coordinates to Frenet.
common::FrenetFramePoint GetFrenetPoint(const common::PathPoint &path_point) const
Planning module main class.
#define ACHECK(cond)
Definition log.h:80
#define ADEBUG
Definition log.h:41
#define AERROR
Definition log.h:44
Some util functions.
class register implement
Definition arena_queue.h:37