Apollo 11.0
自动驾驶开放平台
gridded_path_time_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 <algorithm>
24#include <limits>
25#include <string>
26
27#include "modules/common_msgs/basic_msgs/pnc_point.pb.h"
28
29#include "cyber/common/log.h"
30#include "cyber/task/task.h"
35
36namespace apollo {
37namespace planning {
38
43
44namespace {
45
46static constexpr double kDoubleEpsilon = 1.0e-6;
47
48// Continuous-time collision check using linear interpolation as closed-loop
49// dynamics
50bool CheckOverlapOnDpStGraph(const std::vector<const STBoundary*>& boundaries,
51 const StGraphPoint& p1, const StGraphPoint& p2) {
52 if (FLAGS_use_st_drivable_boundary) {
53 return false;
54 }
55 for (const auto* boundary : boundaries) {
56 if (boundary->boundary_type() == STBoundary::BoundaryType::KEEP_CLEAR) {
57 continue;
58 }
59 // Check collision between a polygon and a line segment
60 if (boundary->HasOverlap({p1.point(), p2.point()})) {
61 return true;
62 }
63 }
64 return false;
65}
66} // namespace
67
69 const StGraphData& st_graph_data, const DpStSpeedOptimizerConfig& dp_config,
70 const std::vector<const Obstacle*>& obstacles,
71 const common::TrajectoryPoint& init_point)
72 : st_graph_data_(st_graph_data),
73 gridded_path_time_graph_config_(dp_config),
74 obstacles_(obstacles),
75 init_point_(init_point),
76 dp_st_cost_(dp_config, st_graph_data_.total_time_by_conf(),
77 st_graph_data_.path_length(), obstacles,
78 st_graph_data_.st_drivable_boundary(), init_point_) {
79 total_length_t_ = st_graph_data_.total_time_by_conf();
80 unit_t_ = gridded_path_time_graph_config_.unit_t();
81 total_length_s_ = st_graph_data_.path_length();
82 dense_unit_s_ = gridded_path_time_graph_config_.dense_unit_s();
83 sparse_unit_s_ = gridded_path_time_graph_config_.sparse_unit_s();
84 dense_dimension_s_ = gridded_path_time_graph_config_.dense_dimension_s();
85 // Safety approach preventing unreachable acceleration/deceleration
86 max_acceleration_ =
87 std::min(std::abs(vehicle_param_.max_acceleration()),
88 std::abs(gridded_path_time_graph_config_.max_acceleration()));
89 max_deceleration_ =
90 -1.0 *
91 std::min(std::abs(vehicle_param_.max_deceleration()),
92 std::abs(gridded_path_time_graph_config_.max_deceleration()));
93}
94
96 static constexpr double kBounadryEpsilon = 1e-2;
97 for (const auto& boundary : st_graph_data_.st_boundaries()) {
98 // KeepClear obstacles not considered in Dp St decision
99 if (boundary->boundary_type() == STBoundary::BoundaryType::KEEP_CLEAR) {
100 continue;
101 }
102 // If init point in collision with obstacle, return speed fallback
103 if (boundary->IsPointInBoundary({0.0, 0.0}) ||
104 (std::fabs(boundary->min_t()) < kBounadryEpsilon &&
105 std::fabs(boundary->min_s()) < kBounadryEpsilon)) {
106 dimension_t_ = static_cast<uint32_t>(std::ceil(
107 total_length_t_ / static_cast<double>(unit_t_))) +
108 1;
109 std::vector<SpeedPoint> speed_profile;
110 double t = 0.0;
111 for (uint32_t i = 0; i < dimension_t_; ++i, t += unit_t_) {
112 speed_profile.push_back(PointFactory::ToSpeedPoint(0, t));
113 }
114 *speed_data = SpeedData(speed_profile);
115 return Status::OK();
116 }
117 }
118
119 if (!InitCostTable().ok()) {
120 const std::string msg = "Initialize cost table failed.";
121 AERROR << msg;
122 return Status(ErrorCode::PLANNING_ERROR, msg);
123 }
124
125 if (!InitSpeedLimitLookUp().ok()) {
126 const std::string msg = "Initialize speed limit lookup table failed.";
127 AERROR << msg;
128 return Status(ErrorCode::PLANNING_ERROR, msg);
129 }
130
131 if (!CalculateTotalCost().ok()) {
132 const std::string msg = "Calculate total cost failed.";
133 AERROR << msg;
134 return Status(ErrorCode::PLANNING_ERROR, msg);
135 }
136
137 if (!RetrieveSpeedProfile(speed_data).ok()) {
138 const std::string msg = "Retrieve best speed profile failed.";
139 AERROR << msg;
140 return Status(ErrorCode::PLANNING_ERROR, msg);
141 }
142 return Status::OK();
143}
144
145Status GriddedPathTimeGraph::InitCostTable() {
146 // Time dimension is homogeneous while Spatial dimension has two resolutions,
147 // dense and sparse with dense resolution coming first in the spatial horizon
148
149 // Sanity check for numerical stability
150 if (unit_t_ < kDoubleEpsilon) {
151 const std::string msg = "unit_t is smaller than the kDoubleEpsilon.";
152 AERROR << msg;
153 return Status(ErrorCode::PLANNING_ERROR, msg);
154 }
155
156 // Sanity check on s dimension setting
157 if (dense_dimension_s_ < 1) {
158 const std::string msg = "dense_dimension_s is at least 1.";
159 AERROR << msg;
160 return Status(ErrorCode::PLANNING_ERROR, msg);
161 }
162
163 dimension_t_ = static_cast<uint32_t>(std::ceil(
164 total_length_t_ / static_cast<double>(unit_t_))) +
165 1;
166
167 double sparse_length_s =
168 total_length_s_ -
169 static_cast<double>(dense_dimension_s_ - 1) * dense_unit_s_;
170 sparse_dimension_s_ =
171 sparse_length_s > std::numeric_limits<double>::epsilon()
172 ? static_cast<uint32_t>(std::ceil(sparse_length_s / sparse_unit_s_))
173 : 0;
174 dense_dimension_s_ =
175 sparse_length_s > std::numeric_limits<double>::epsilon()
176 ? dense_dimension_s_
177 : static_cast<uint32_t>(std::ceil(total_length_s_ / dense_unit_s_)) +
178 1;
179 dimension_s_ = dense_dimension_s_ + sparse_dimension_s_;
180 PrintCurves debug;
181 // Sanity Check
182 if (dimension_t_ < 1 || dimension_s_ < 1) {
183 const std::string msg = "Dp st cost table size incorrect.";
184 AERROR << msg;
185 return Status(ErrorCode::PLANNING_ERROR, msg);
186 }
187
188 cost_table_ = std::vector<std::vector<StGraphPoint>>(
189 dimension_t_, std::vector<StGraphPoint>(dimension_s_, StGraphPoint()));
190
191 double curr_t = 0.0;
192 for (uint32_t i = 0; i < cost_table_.size(); ++i, curr_t += unit_t_) {
193 auto& cost_table_i = cost_table_[i];
194 double curr_s = 0.0;
195 for (uint32_t j = 0; j < dense_dimension_s_; ++j, curr_s += dense_unit_s_) {
196 cost_table_i[j].Init(i, j, STPoint(curr_s, curr_t));
197 debug.AddPoint("dp_node_points", curr_t, curr_s);
198 }
199 curr_s = static_cast<double>(dense_dimension_s_ - 1) * dense_unit_s_ +
200 sparse_unit_s_;
201 for (uint32_t j = dense_dimension_s_; j < cost_table_i.size();
202 ++j, curr_s += sparse_unit_s_) {
203 cost_table_i[j].Init(i, j, STPoint(curr_s, curr_t));
204 debug.AddPoint("dp_node_points", curr_t, curr_s);
205 }
206 }
207
208 const auto& cost_table_0 = cost_table_[0];
209 spatial_distance_by_index_ = std::vector<double>(cost_table_0.size(), 0.0);
210 for (uint32_t i = 0; i < cost_table_0.size(); ++i) {
211 spatial_distance_by_index_[i] = cost_table_0[i].point().s();
212 }
213 return Status::OK();
214}
215
216Status GriddedPathTimeGraph::InitSpeedLimitLookUp() {
217 speed_limit_by_index_.clear();
218
219 speed_limit_by_index_.resize(dimension_s_);
220 const auto& speed_limit = st_graph_data_.speed_limit();
221
222 for (uint32_t i = 0; i < dimension_s_; ++i) {
223 speed_limit_by_index_[i] =
224 speed_limit.GetSpeedLimitByS(cost_table_[0][i].point().s());
225 }
226 return Status::OK();
227}
228
229Status GriddedPathTimeGraph::CalculateTotalCost() {
230 // col and row are for STGraph
231 // t corresponding to col
232 // s corresponding to row
233 size_t next_highest_row = 0;
234 size_t next_lowest_row = 0;
235
236 for (size_t c = 0; c < cost_table_.size(); ++c) {
237 size_t highest_row = 0;
238 size_t lowest_row = cost_table_.back().size() - 1;
239
240 int count = static_cast<int>(next_highest_row) -
241 static_cast<int>(next_lowest_row) + 1;
242 if (count > 0) {
243 std::vector<std::future<void>> results;
244 for (size_t r = next_lowest_row; r <= next_highest_row; ++r) {
245 auto msg = std::make_shared<StGraphMessage>(c, r);
246 if (gridded_path_time_graph_config_
247 .enable_multi_thread_in_dp_st_graph()) {
248 results.push_back(
249 cyber::Async(&GriddedPathTimeGraph::CalculateCostAt, this, msg));
250 } else {
251 CalculateCostAt(msg);
252 }
253 }
254 if (gridded_path_time_graph_config_
255 .enable_multi_thread_in_dp_st_graph()) {
256 for (auto& result : results) {
257 result.get();
258 }
259 }
260 }
261
262 for (size_t r = next_lowest_row; r <= next_highest_row; ++r) {
263 const auto& cost_cr = cost_table_[c][r];
264 if (cost_cr.total_cost() < std::numeric_limits<double>::infinity()) {
265 size_t h_r = 0;
266 size_t l_r = 0;
267 GetRowRange(cost_cr, &h_r, &l_r);
268 highest_row = std::max(highest_row, h_r);
269 lowest_row = std::min(lowest_row, l_r);
270 }
271 }
272 next_highest_row = highest_row;
273 next_lowest_row = lowest_row;
274 }
275
276 return Status::OK();
277}
278
279void GriddedPathTimeGraph::GetRowRange(const StGraphPoint& point,
280 size_t* next_highest_row,
281 size_t* next_lowest_row) {
282 double v0 = 0.0;
283 // TODO(all): Record speed information in StGraphPoint and deprecate this.
284 // A scaling parameter for DP range search due to the lack of accurate
285 // information of the current velocity (set to 1 by default since we use
286 // past 1 second's average v as approximation)
287 double acc_coeff = 0.5;
288 if (!point.pre_point()) {
289 v0 = init_point_.v();
290 } else {
291 v0 = point.GetOptimalSpeed();
292 }
293
294 const auto max_s_size = dimension_s_ - 1;
295 const double t_squared = unit_t_ * unit_t_;
296 const double s_upper_bound = v0 * unit_t_ +
297 acc_coeff * max_acceleration_ * t_squared +
298 point.point().s();
299 const auto next_highest_itr =
300 std::lower_bound(spatial_distance_by_index_.begin(),
301 spatial_distance_by_index_.end(), s_upper_bound);
302 if (next_highest_itr == spatial_distance_by_index_.end()) {
303 *next_highest_row = max_s_size;
304 } else {
305 *next_highest_row =
306 std::distance(spatial_distance_by_index_.begin(), next_highest_itr);
307 }
308
309 const double s_lower_bound =
310 std::fmax(0.0, v0 * unit_t_ + acc_coeff * max_deceleration_ * t_squared) +
311 point.point().s();
312 const auto next_lowest_itr =
313 std::lower_bound(spatial_distance_by_index_.begin(),
314 spatial_distance_by_index_.end(), s_lower_bound);
315 if (next_lowest_itr == spatial_distance_by_index_.end()) {
316 *next_lowest_row = max_s_size;
317 } else {
318 *next_lowest_row =
319 std::distance(spatial_distance_by_index_.begin(), next_lowest_itr);
320 }
321}
322
323void GriddedPathTimeGraph::CalculateCostAt(
324 const std::shared_ptr<StGraphMessage>& msg) {
325 const uint32_t c = msg->c;
326 const uint32_t r = msg->r;
327 auto& cost_cr = cost_table_[c][r];
328
329 cost_cr.SetObstacleCost(dp_st_cost_.GetObstacleCost(cost_cr));
330 if (cost_cr.obstacle_cost() > std::numeric_limits<double>::max()) {
331 return;
332 }
333
334 cost_cr.SetSpatialPotentialCost(dp_st_cost_.GetSpatialPotentialCost(cost_cr));
335
336 const auto& cost_init = cost_table_[0][0];
337 if (c == 0) {
338 DCHECK_EQ(r, 0U) << "Incorrect. Row should be 0 with col = 0. row: " << r;
339 cost_cr.SetTotalCost(0.0);
340 cost_cr.SetOptimalSpeed(init_point_.v());
341 return;
342 }
343
344 const double speed_limit = speed_limit_by_index_[r];
345 const double cruise_speed = st_graph_data_.cruise_speed();
346 // The mininal s to model as constant acceleration formula
347 // default: 0.25 * 7 = 1.75 m
348 const double min_s_consider_speed = dense_unit_s_ * dimension_t_;
349
350 if (c == 1) {
351 const double acc =
352 2 * (cost_cr.point().s() / unit_t_ - init_point_.v()) / unit_t_;
353 if (acc < max_deceleration_ || acc > max_acceleration_) {
354 return;
355 }
356
357 if (init_point_.v() + acc * unit_t_ < -kDoubleEpsilon &&
358 cost_cr.point().s() > min_s_consider_speed) {
359 return;
360 }
361
362 if (CheckOverlapOnDpStGraph(st_graph_data_.st_boundaries(), cost_cr,
363 cost_init)) {
364 return;
365 }
366 cost_cr.SetTotalCost(
367 cost_cr.obstacle_cost() + cost_cr.spatial_potential_cost() +
368 cost_init.total_cost() +
369 CalculateEdgeCostForSecondCol(r, speed_limit, cruise_speed));
370 cost_cr.SetPrePoint(cost_init);
371 cost_cr.SetOptimalSpeed(init_point_.v() + acc * unit_t_);
372 return;
373 }
374
375 static constexpr double kSpeedRangeBuffer = 0.20;
376 const double pre_lowest_s =
377 cost_cr.point().s() -
378 FLAGS_planning_upper_speed_limit * (1 + kSpeedRangeBuffer) * unit_t_;
379 const auto pre_lowest_itr =
380 std::lower_bound(spatial_distance_by_index_.begin(),
381 spatial_distance_by_index_.end(), pre_lowest_s);
382 uint32_t r_low = 0;
383 if (pre_lowest_itr == spatial_distance_by_index_.end()) {
384 r_low = dimension_s_ - 1;
385 } else {
386 r_low = static_cast<uint32_t>(
387 std::distance(spatial_distance_by_index_.begin(), pre_lowest_itr));
388 }
389 const uint32_t r_pre_size = r - r_low + 1;
390 const auto& pre_col = cost_table_[c - 1];
391 double curr_speed_limit = speed_limit;
392
393 if (c == 2) {
394 for (uint32_t i = 0; i < r_pre_size; ++i) {
395 uint32_t r_pre = r - i;
396 if (std::isinf(pre_col[r_pre].total_cost()) ||
397 pre_col[r_pre].pre_point() == nullptr) {
398 continue;
399 }
400 // TODO(Jiaxuan): Calculate accurate acceleration by recording speed
401 // data in ST point.
402 // Use curr_v = (point.s - pre_point.s) / unit_t as current v
403 // Use pre_v = (pre_point.s - prepre_point.s) / unit_t as previous v
404 // Current acc estimate: curr_a = (curr_v - pre_v) / unit_t
405 // = (point.s + prepre_point.s - 2 * pre_point.s) / (unit_t * unit_t)
406 const double curr_a =
407 2 *
408 ((cost_cr.point().s() - pre_col[r_pre].point().s()) / unit_t_ -
409 pre_col[r_pre].GetOptimalSpeed()) /
410 unit_t_;
411 if (curr_a < max_deceleration_ || curr_a > max_acceleration_) {
412 continue;
413 }
414
415 if (pre_col[r_pre].GetOptimalSpeed() + curr_a * unit_t_ <
417 cost_cr.point().s() > min_s_consider_speed) {
418 continue;
419 }
420
421 // Filter out continuous-time node connection which is in collision with
422 // obstacle
423 if (CheckOverlapOnDpStGraph(st_graph_data_.st_boundaries(), cost_cr,
424 pre_col[r_pre])) {
425 continue;
426 }
427 curr_speed_limit =
428 std::fmin(curr_speed_limit, speed_limit_by_index_[r_pre]);
429 const double cost = cost_cr.obstacle_cost() +
430 cost_cr.spatial_potential_cost() +
431 pre_col[r_pre].total_cost() +
432 CalculateEdgeCostForThirdCol(
433 r, r_pre, curr_speed_limit, cruise_speed);
434
435 if (cost < cost_cr.total_cost()) {
436 cost_cr.SetTotalCost(cost);
437 cost_cr.SetPrePoint(pre_col[r_pre]);
438 cost_cr.SetOptimalSpeed(pre_col[r_pre].GetOptimalSpeed() +
439 curr_a * unit_t_);
440 }
441 }
442 return;
443 }
444
445 for (uint32_t i = 0; i < r_pre_size; ++i) {
446 uint32_t r_pre = r - i;
447 if (std::isinf(pre_col[r_pre].total_cost()) ||
448 pre_col[r_pre].pre_point() == nullptr) {
449 continue;
450 }
451 // Use curr_v = (point.s - pre_point.s) / unit_t as current v
452 // Use pre_v = (pre_point.s - prepre_point.s) / unit_t as previous v
453 // Current acc estimate: curr_a = (curr_v - pre_v) / unit_t
454 // = (point.s + prepre_point.s - 2 * pre_point.s) / (unit_t * unit_t)
455 const double curr_a =
456 2 *
457 ((cost_cr.point().s() - pre_col[r_pre].point().s()) / unit_t_ -
458 pre_col[r_pre].GetOptimalSpeed()) /
459 unit_t_;
460 if (curr_a > max_acceleration_ || curr_a < max_deceleration_) {
461 continue;
462 }
463
464 if (pre_col[r_pre].GetOptimalSpeed() + curr_a * unit_t_ < -kDoubleEpsilon &&
465 cost_cr.point().s() > min_s_consider_speed) {
466 continue;
467 }
468
469 if (CheckOverlapOnDpStGraph(st_graph_data_.st_boundaries(), cost_cr,
470 pre_col[r_pre])) {
471 continue;
472 }
473
474 uint32_t r_prepre = pre_col[r_pre].pre_point()->index_s();
475 const StGraphPoint& prepre_graph_point = cost_table_[c - 2][r_prepre];
476 if (std::isinf(prepre_graph_point.total_cost())) {
477 continue;
478 }
479
480 if (!prepre_graph_point.pre_point()) {
481 continue;
482 }
483 const STPoint& triple_pre_point = prepre_graph_point.pre_point()->point();
484 const STPoint& prepre_point = prepre_graph_point.point();
485 const STPoint& pre_point = pre_col[r_pre].point();
486 const STPoint& curr_point = cost_cr.point();
487 curr_speed_limit =
488 std::fmin(curr_speed_limit, speed_limit_by_index_[r_pre]);
489 double cost = cost_cr.obstacle_cost() + cost_cr.spatial_potential_cost() +
490 pre_col[r_pre].total_cost() +
491 CalculateEdgeCost(triple_pre_point, prepre_point, pre_point,
492 curr_point, curr_speed_limit, cruise_speed);
493
494 if (cost < cost_cr.total_cost()) {
495 cost_cr.SetTotalCost(cost);
496 cost_cr.SetPrePoint(pre_col[r_pre]);
497 cost_cr.SetOptimalSpeed(pre_col[r_pre].GetOptimalSpeed() +
498 curr_a * unit_t_);
499 }
500 }
501}
502
503Status GriddedPathTimeGraph::RetrieveSpeedProfile(SpeedData* const speed_data) {
504 double min_cost = std::numeric_limits<double>::infinity();
505 const StGraphPoint* best_end_point = nullptr;
506 PrintPoints debug("dp_node_edge");
507 for (const auto& points_vec : cost_table_) {
508 for (const auto& pt : points_vec) {
509 debug.AddPoint(pt.point().t(), pt.point().s());
510 }
511 }
512 // for debug plot
513 // debug.PrintToLog();
514 for (const StGraphPoint& cur_point : cost_table_.back()) {
515 if (!std::isinf(cur_point.total_cost()) &&
516 cur_point.total_cost() < min_cost) {
517 best_end_point = &cur_point;
518 min_cost = cur_point.total_cost();
519 }
520 }
521
522 for (const auto& row : cost_table_) {
523 const StGraphPoint& cur_point = row.back();
524 if (!std::isinf(cur_point.total_cost()) &&
525 cur_point.total_cost() < min_cost) {
526 best_end_point = &cur_point;
527 min_cost = cur_point.total_cost();
528 }
529 }
530
531 if (best_end_point == nullptr) {
532 const std::string msg = "Fail to find the best feasible trajectory.";
533 AERROR << msg;
534 return Status(ErrorCode::PLANNING_ERROR, msg);
535 }
536
537 std::vector<SpeedPoint> speed_profile;
538 const StGraphPoint* cur_point = best_end_point;
539 PrintPoints debug_res("dp_result");
540 while (cur_point != nullptr) {
541 ADEBUG << "Time: " << cur_point->point().t();
542 ADEBUG << "S: " << cur_point->point().s();
543 ADEBUG << "V: " << cur_point->GetOptimalSpeed();
544 SpeedPoint speed_point;
545 debug_res.AddPoint(cur_point->point().t(), cur_point->point().s());
546 speed_point.set_s(cur_point->point().s());
547 speed_point.set_t(cur_point->point().t());
548 speed_profile.push_back(speed_point);
549 cur_point = cur_point->pre_point();
550 }
551 // for debug plot
552 // debug_res.PrintToLog();
553 std::reverse(speed_profile.begin(), speed_profile.end());
554
555 static constexpr double kEpsilon = std::numeric_limits<double>::epsilon();
556 if (speed_profile.front().t() > kEpsilon ||
557 speed_profile.front().s() > kEpsilon) {
558 const std::string msg = "Fail to retrieve speed profile.";
559 AERROR << msg;
560 return Status(ErrorCode::PLANNING_ERROR, msg);
561 }
562
563 for (size_t i = 0; i + 1 < speed_profile.size(); ++i) {
564 const double v = (speed_profile[i + 1].s() - speed_profile[i].s()) /
565 (speed_profile[i + 1].t() - speed_profile[i].t() + 1e-3);
566 speed_profile[i].set_v(v);
567 }
568
569 *speed_data = SpeedData(speed_profile);
570 return Status::OK();
571}
572
573double GriddedPathTimeGraph::CalculateEdgeCost(
574 const STPoint& first, const STPoint& second, const STPoint& third,
575 const STPoint& forth, const double speed_limit, const double cruise_speed) {
576 return dp_st_cost_.GetSpeedCost(third, forth, speed_limit, cruise_speed) +
577 dp_st_cost_.GetAccelCostByThreePoints(second, third, forth) +
578 dp_st_cost_.GetJerkCostByFourPoints(first, second, third, forth);
579}
580
581double GriddedPathTimeGraph::CalculateEdgeCostForSecondCol(
582 const uint32_t row, const double speed_limit, const double cruise_speed) {
583 double init_speed = init_point_.v();
584 double init_acc = init_point_.a();
585 const STPoint& pre_point = cost_table_[0][0].point();
586 const STPoint& curr_point = cost_table_[1][row].point();
587 return dp_st_cost_.GetSpeedCost(pre_point, curr_point, speed_limit,
588 cruise_speed) +
589 dp_st_cost_.GetAccelCostByTwoPoints(init_speed, pre_point,
590 curr_point) +
591 dp_st_cost_.GetJerkCostByTwoPoints(init_speed, init_acc, pre_point,
592 curr_point);
593}
594
595double GriddedPathTimeGraph::CalculateEdgeCostForThirdCol(
596 const uint32_t curr_row, const uint32_t pre_row, const double speed_limit,
597 const double cruise_speed) {
598 double init_speed = init_point_.v();
599 const STPoint& first = cost_table_[0][0].point();
600 const STPoint& second = cost_table_[1][pre_row].point();
601 const STPoint& third = cost_table_[2][curr_row].point();
602 return dp_st_cost_.GetSpeedCost(second, third, speed_limit, cruise_speed) +
603 dp_st_cost_.GetAccelCostByThreePoints(first, second, third) +
604 dp_st_cost_.GetJerkCostByThreePoints(init_speed, first, second, third);
605}
606
607} // namespace planning
608} // namespace apollo
A general class to denote the return status of an API call.
Definition status.h:43
static Status OK()
generate a success status.
Definition status.h:60
static SpeedPoint ToSpeedPoint(const double s, const double t, const double v=0, const double a=0, const double da=0)
double GetSpatialPotentialCost(const StGraphPoint &point)
double GetAccelCostByTwoPoints(const double pre_speed, const STPoint &first, const STPoint &second)
double GetJerkCostByThreePoints(const double first_speed, const STPoint &first_point, const STPoint &second_point, const STPoint &third_point)
double GetJerkCostByTwoPoints(const double pre_speed, const double pre_acc, const STPoint &pre_point, const STPoint &curr_point)
double GetSpeedCost(const STPoint &first, const STPoint &second, const double speed_limit, const double cruise_speed) const
double GetJerkCostByFourPoints(const STPoint &first, const STPoint &second, const STPoint &third, const STPoint &fourth)
double GetAccelCostByThreePoints(const STPoint &first, const STPoint &second, const STPoint &third)
double GetObstacleCost(const StGraphPoint &point)
common::Status Search(SpeedData *const speed_data)
GriddedPathTimeGraph(const StGraphData &st_graph_data, const DpStSpeedOptimizerConfig &dp_config, const std::vector< const Obstacle * > &obstacles, const common::TrajectoryPoint &init_point)
const SpeedLimit & speed_limit() const
const std::vector< const STBoundary * > & st_boundaries() const
Planning module main class.
#define ADEBUG
Definition log.h:41
#define AERROR
Definition log.h:44
const double kDoubleEpsilon
class register implement
Definition arena_queue.h:37
Defines the Vec2d class.