Apollo 11.0
自动驾驶开放平台
distance_approach_problem_wrapper.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2018 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
21#include <future>
22
23#include "cyber/common/file.h"
28
29namespace apollo {
30namespace planning {
31
33
35public:
36 ObstacleContainer() = default;
37
38 bool VPresentationObstacle(const double* ROI_distance_approach_parking_boundary) {
39 obstacles_num_ = 4;
40 obstacles_edges_num_.resize(4, 1);
41 obstacles_edges_num_ << 2, 1, 2, 1;
42 size_t index = 0;
43 for (size_t i = 0; i < obstacles_num_; i++) {
44 std::vector<Vec2d> vertices_cw;
45 for (int j = 0; j < obstacles_edges_num_(i, 0) + 1; j++) {
46 Vec2d vertice
47 = Vec2d(ROI_distance_approach_parking_boundary[index],
48 ROI_distance_approach_parking_boundary[index + 1]);
49 index += 2;
50 vertices_cw.emplace_back(vertice);
51 }
52 obstacles_vertices_vec_.emplace_back(vertices_cw);
53 }
54 return true;
55 }
56
58 obstacles_A_ = Eigen::MatrixXd::Zero(obstacles_edges_num_.sum(), 2);
59 obstacles_b_ = Eigen::MatrixXd::Zero(obstacles_edges_num_.sum(), 1);
60 // vertices using H-representation
61 if (!ObsHRep(obstacles_num_, obstacles_edges_num_, obstacles_vertices_vec_, &obstacles_A_, &obstacles_b_)) {
62 AINFO << "Fail to present obstacle in hyperplane";
63 return false;
64 }
65 return true;
66 }
67
68 bool ObsHRep(
69 const size_t obstacles_num,
70 const Eigen::MatrixXi& obstacles_edges_num,
71 const std::vector<std::vector<Vec2d>>& obstacles_vertices_vec,
72 Eigen::MatrixXd* A_all,
73 Eigen::MatrixXd* b_all) {
74 if (obstacles_num != obstacles_vertices_vec.size()) {
75 AINFO << "obstacles_num != obstacles_vertices_vec.size()";
76 return false;
77 }
78
79 A_all->resize(obstacles_edges_num.sum(), 2);
80 b_all->resize(obstacles_edges_num.sum(), 1);
81
82 int counter = 0;
83 double kEpsilon = 1.0e-5;
84 // start building H representation
85 for (size_t i = 0; i < obstacles_num; ++i) {
86 size_t current_vertice_num = obstacles_edges_num(i, 0);
87 Eigen::MatrixXd A_i(current_vertice_num, 2);
88 Eigen::MatrixXd b_i(current_vertice_num, 1);
89
90 // take two subsequent vertices, and computer hyperplane
91 for (size_t j = 0; j < current_vertice_num; ++j) {
92 Vec2d v1 = obstacles_vertices_vec[i][j];
93 Vec2d v2 = obstacles_vertices_vec[i][j + 1];
94
95 Eigen::MatrixXd A_tmp(2, 1), b_tmp(1, 1), ab(2, 1);
96 // find hyperplane passing through v1 and v2
97 if (std::abs(v1.x() - v2.x()) < kEpsilon) {
98 if (v2.y() < v1.y()) {
99 A_tmp << 1, 0;
100 b_tmp << v1.x();
101 } else {
102 A_tmp << -1, 0;
103 b_tmp << -v1.x();
104 }
105 } else if (std::abs(v1.y() - v2.y()) < kEpsilon) {
106 if (v1.x() < v2.x()) {
107 A_tmp << 0, 1;
108 b_tmp << v1.y();
109 } else {
110 A_tmp << 0, -1;
111 b_tmp << -v1.y();
112 }
113 } else {
114 Eigen::MatrixXd tmp1(2, 2);
115 tmp1 << v1.x(), 1, v2.x(), 1;
116 Eigen::MatrixXd tmp2(2, 1);
117 tmp2 << v1.y(), v2.y();
118 ab = tmp1.inverse() * tmp2;
119 double a = ab(0, 0);
120 double b = ab(1, 0);
121
122 if (v1.x() < v2.x()) {
123 A_tmp << -a, 1;
124 b_tmp << b;
125 } else {
126 A_tmp << a, -1;
127 b_tmp << -b;
128 }
129 }
130
131 // store vertices
132 A_i.block(j, 0, 1, 2) = A_tmp.transpose();
133 b_i.block(j, 0, 1, 1) = b_tmp;
134 }
135
136 A_all->block(counter, 0, A_i.rows(), 2) = A_i;
137 b_all->block(counter, 0, b_i.rows(), 1) = b_i;
138 counter += static_cast<int>(current_vertice_num);
139 }
140 return true;
141 }
142
143 void AddObstacle(const double* ROI_distance_approach_parking_boundary) {
144 // the obstacles are hard coded into vertice sets of 3, 2, 3, 2
145 if (!(VPresentationObstacle(ROI_distance_approach_parking_boundary) && HPresentationObstacle())) {
146 AINFO << "obstacle presentation fails";
147 }
148 }
149
150 const std::vector<std::vector<Vec2d>>& GetObstacleVec() const {
151 return obstacles_vertices_vec_;
152 }
153 const Eigen::MatrixXd& GetAMatrix() const {
154 return obstacles_A_;
155 }
156 const Eigen::MatrixXd& GetbMatrix() const {
157 return obstacles_b_;
158 }
159 size_t GetObstaclesNum() const {
160 return obstacles_num_;
161 }
162 const Eigen::MatrixXi& GetObstaclesEdgesNum() const {
163 return obstacles_edges_num_;
164 }
165
166private:
167 size_t obstacles_num_ = 0;
168 Eigen::MatrixXi obstacles_edges_num_;
169 std::vector<std::vector<Vec2d>> obstacles_vertices_vec_;
170 Eigen::MatrixXd obstacles_A_;
171 Eigen::MatrixXd obstacles_b_;
172};
173
175public:
176 ResultContainer() = default;
178 x_ = std::move(result_.x);
179 y_ = std::move(result_.y);
180 phi_ = std::move(result_.phi);
181 v_ = std::move(result_.v);
182 a_ = std::move(result_.a);
183 steer_ = std::move(result_.steer);
184 }
185 std::vector<double>* GetX() {
186 return &x_;
187 }
188 std::vector<double>* GetY() {
189 return &y_;
190 }
191 std::vector<double>* GetPhi() {
192 return &phi_;
193 }
194 std::vector<double>* GetV() {
195 return &v_;
196 }
197 std::vector<double>* GetA() {
198 return &a_;
199 }
200 std::vector<double>* GetSteer() {
201 return &steer_;
202 }
204 return &result_;
205 }
206 Eigen::MatrixXd* PrepareStateResult() {
207 return &state_result_ds_;
208 }
209 Eigen::MatrixXd* PrepareControlResult() {
210 return &control_result_ds_;
211 }
212 Eigen::MatrixXd* PrepareTimeResult() {
213 return &time_result_ds_;
214 }
215 Eigen::MatrixXd* PrepareLResult() {
216 return &dual_l_result_ds_;
217 }
218 Eigen::MatrixXd* PrepareNResult() {
219 return &dual_n_result_ds_;
220 }
221 double* GetHybridTime() {
222 return &hybrid_time_;
223 }
224 double* GetDualTime() {
225 return &dual_time_;
226 }
227 double* GetIpoptTime() {
228 return &ipopt_time_;
229 }
230
231private:
232 HybridAStartResult result_;
233 std::vector<double> x_;
234 std::vector<double> y_;
235 std::vector<double> phi_;
236 std::vector<double> v_;
237 std::vector<double> a_;
238 std::vector<double> steer_;
239 Eigen::MatrixXd state_result_ds_;
240 Eigen::MatrixXd control_result_ds_;
241 Eigen::MatrixXd time_result_ds_;
242 Eigen::MatrixXd dual_l_result_ds_;
243 Eigen::MatrixXd dual_n_result_ds_;
244 double hybrid_time_;
245 double dual_time_;
246 double ipopt_time_;
247};
248
249extern "C" {
251 apollo::planning::PlannerOpenSpaceConfig planner_open_space_config_;
253 FLAGS_planner_open_space_config_filename, &planner_open_space_config_))
254 << "Failed to load open space config file " << FLAGS_planner_open_space_config_filename;
255 return new HybridAStar(planner_open_space_config_);
256}
263
264void AddObstacle(ObstacleContainer* obstacles_ptr, const double* ROI_distance_approach_parking_boundary) {
265 obstacles_ptr->AddObstacle(ROI_distance_approach_parking_boundary);
266}
267
268double InterpolateUsingLinearApproximation(const double p0, const double p1, const double w) {
269 return p0 * (1.0 - w) + p1 * w;
270}
271
272std::vector<double> VectorLinearInterpolation(const std::vector<double>& x, int extend_size) {
273 // interplation example:
274 // x: [x0, x1, x2], extend_size: 3
275 // output: [y0(x0), y1, y2, y3(x1), y4, y5, y6(x2)]
276 size_t origin_last = x.size() - 1;
277 std::vector<double> res(origin_last * extend_size + 1, 0.0);
278
279 for (size_t i = 0; i < origin_last * extend_size; ++i) {
280 size_t idx0 = i / extend_size;
281 size_t idx1 = idx0 + 1;
282 double w = static_cast<double>(i % extend_size) / static_cast<double>(extend_size);
283 res[i] = InterpolateUsingLinearApproximation(x[idx0], x[idx1], w);
284 }
285
286 res.back() = x.back();
287 return res;
288}
289
291 const apollo::planning::PlannerOpenSpaceConfig& planner_open_space_config,
292 const ObstacleContainer& obstacles,
293 double sx,
294 double sy,
295 double sphi,
296 double ex,
297 double ey,
298 double ephi,
299 const std::vector<double>& XYbounds,
300 HybridAStartResult* hybrid_a_star_result,
301 Eigen::MatrixXd* state_result_ds_,
302 Eigen::MatrixXd* control_result_ds_,
303 Eigen::MatrixXd* time_result_ds_,
304 Eigen::MatrixXd* dual_l_result_ds_,
305 Eigen::MatrixXd* dual_n_result_ds_,
306 double& dual_time,
307 double& ipopt_time) {
308 // load Warm Start result(horizon is the "N", not the size of step points)
309 size_t horizon_ = hybrid_a_star_result->x.size() - 1;
310 // nominal sampling time
311 float ts_ = planner_open_space_config.delta_t();
312
313 Eigen::VectorXd x;
314 Eigen::VectorXd y;
315 Eigen::VectorXd phi;
316 Eigen::VectorXd v;
317 Eigen::VectorXd steer;
318 Eigen::VectorXd a;
319
320 // TODO(Runxin): extend logics in future
321 if (horizon_ <= 10 && horizon_ > 2 && planner_open_space_config.enable_linear_interpolation()) {
322 // TODO(Runxin): extend this number
323 int extend_size = 5;
324 // modify state and control vectors sizes
325 horizon_ = extend_size * horizon_;
326 // modify delta t
327 ts_ = ts_ / static_cast<float>(extend_size);
328
329 std::vector<double> x_extend = VectorLinearInterpolation(hybrid_a_star_result->x, extend_size);
330 x = Eigen::Map<Eigen::VectorXd, Eigen::Unaligned>(x_extend.data(), horizon_ + 1);
331
332 std::vector<double> y_extend = VectorLinearInterpolation(hybrid_a_star_result->y, extend_size);
333 y = Eigen::Map<Eigen::VectorXd, Eigen::Unaligned>(y_extend.data(), horizon_ + 1);
334
335 std::vector<double> phi_extend = VectorLinearInterpolation(hybrid_a_star_result->phi, extend_size);
336 phi = Eigen::Map<Eigen::VectorXd, Eigen::Unaligned>(phi_extend.data(), horizon_ + 1);
337
338 std::vector<double> v_extend = VectorLinearInterpolation(hybrid_a_star_result->v, extend_size);
339 v = Eigen::Map<Eigen::VectorXd, Eigen::Unaligned>(v_extend.data(), horizon_ + 1);
340
341 steer = Eigen::VectorXd(horizon_);
342 a = Eigen::VectorXd(horizon_);
343 for (size_t i = 0; i < static_cast<size_t>(horizon_); ++i) {
344 steer[i] = hybrid_a_star_result->steer[i / extend_size];
345 a[i] = hybrid_a_star_result->a[i / extend_size];
346 }
347 ADEBUG << "hybrid A x: ";
348 for (size_t i = 0; i < hybrid_a_star_result->x.size(); ++i) {
349 ADEBUG << "i: " << i << ", val: " << hybrid_a_star_result->x[i];
350 }
351 ADEBUG << "interpolated x: \n" << x;
352
353 ADEBUG << "hybrid A steer: ";
354 for (size_t i = 0; i < hybrid_a_star_result->steer.size(); ++i) {
355 ADEBUG << "i: " << i << ", val: " << hybrid_a_star_result->steer[i];
356 }
357 ADEBUG << "interpolated steer: \n" << steer;
358 } else {
359 x = Eigen::Map<Eigen::VectorXd, Eigen::Unaligned>(hybrid_a_star_result->x.data(), horizon_ + 1);
360 y = Eigen::Map<Eigen::VectorXd, Eigen::Unaligned>(hybrid_a_star_result->y.data(), horizon_ + 1);
361 phi = Eigen::Map<Eigen::VectorXd, Eigen::Unaligned>(hybrid_a_star_result->phi.data(), horizon_ + 1);
362 v = Eigen::Map<Eigen::VectorXd, Eigen::Unaligned>(hybrid_a_star_result->v.data(), horizon_ + 1);
363 steer = Eigen::Map<Eigen::VectorXd, Eigen::Unaligned>(hybrid_a_star_result->steer.data(), horizon_);
364 a = Eigen::Map<Eigen::VectorXd, Eigen::Unaligned>(hybrid_a_star_result->a.data(), horizon_);
365 }
366
367 Eigen::MatrixXd xWS = Eigen::MatrixXd::Zero(4, horizon_ + 1);
368 Eigen::MatrixXd uWS = Eigen::MatrixXd::Zero(2, horizon_);
369 xWS.row(0) = x;
370 xWS.row(1) = y;
371 xWS.row(2) = phi;
372 xWS.row(3) = v;
373 uWS.row(0) = steer;
374 uWS.row(1) = a;
375
376 Eigen::MatrixXd x0(4, 1);
377 x0 << sx, sy, sphi, 0.0;
378
379 Eigen::MatrixXd xF(4, 1);
380 xF << ex, ey, ephi, 0.0;
381
382 Eigen::MatrixXd last_time_u(2, 1);
383 last_time_u << 0.0, 0.0;
384
385 common::VehicleParam vehicle_param_ = common::VehicleConfigHelper::GetConfig().vehicle_param();
386
387 // load vehicle configuration
388 Eigen::MatrixXd ego_(4, 1);
389 double front_to_center = vehicle_param_.front_edge_to_center();
390 double back_to_center = vehicle_param_.back_edge_to_center();
391 double left_to_center = vehicle_param_.left_edge_to_center();
392 double right_to_center = vehicle_param_.right_edge_to_center();
393 ego_ << front_to_center, right_to_center, back_to_center, left_to_center;
394
395 // result for distance approach problem
396 Eigen::MatrixXd l_warm_up;
397 Eigen::MatrixXd n_warm_up;
398 Eigen::MatrixXd s_warm_up = Eigen::MatrixXd::Zero(obstacles.GetObstaclesNum(), horizon_ + 1);
399
400 DualVariableWarmStartProblem* dual_variable_warm_start_ptr
401 = new DualVariableWarmStartProblem(planner_open_space_config);
402
403 const auto t1 = std::chrono::system_clock::now();
404 if (FLAGS_use_dual_variable_warm_start) {
405 bool dual_variable_warm_start_status = dual_variable_warm_start_ptr->Solve(
406 horizon_,
407 ts_,
408 ego_,
409 obstacles.GetObstaclesNum(),
410 obstacles.GetObstaclesEdgesNum(),
411 obstacles.GetAMatrix(),
412 obstacles.GetbMatrix(),
413 xWS,
414 &l_warm_up,
415 &n_warm_up,
416 &s_warm_up);
417
418 if (dual_variable_warm_start_status) {
419 AINFO << "Dual variable problem solved successfully!";
420 } else {
421 AERROR << "Dual variable problem solving failed";
422 return false;
423 }
424 } else {
425 l_warm_up = Eigen::MatrixXd::Zero(obstacles.GetObstaclesEdgesNum().sum(), horizon_ + 1);
426 n_warm_up = Eigen::MatrixXd::Zero(4 * obstacles.GetObstaclesNum(), horizon_ + 1);
427 }
428 const auto t2 = std::chrono::system_clock::now();
429 dual_time = std::chrono::duration<double>(t2 - t1).count() * 1000;
430
431 DistanceApproachProblem* distance_approach_ptr = new DistanceApproachProblem(planner_open_space_config);
432
433 bool status = distance_approach_ptr->Solve(
434 x0,
435 xF,
436 last_time_u,
437 horizon_,
438 ts_,
439 ego_,
440 xWS,
441 uWS,
442 l_warm_up,
443 n_warm_up,
444 s_warm_up,
445 XYbounds,
446 obstacles.GetObstaclesNum(),
447 obstacles.GetObstaclesEdgesNum(),
448 obstacles.GetAMatrix(),
449 obstacles.GetbMatrix(),
450 state_result_ds_,
451 control_result_ds_,
452 time_result_ds_,
453 dual_l_result_ds_,
454 dual_n_result_ds_);
455 const auto t3 = std::chrono::system_clock::now();
456 ipopt_time = std::chrono::duration<double>(t3 - t2).count() * 1000;
457
458 if (!status) {
459 AERROR << "Distance fail";
460 return false;
461 }
462 return true;
463}
464
466 HybridAStar* hybridA_ptr,
467 ObstacleContainer* obstacles_ptr,
468 ResultContainer* result_ptr,
469 double sx,
470 double sy,
471 double sphi,
472 double ex,
473 double ey,
474 double ephi,
475 double* XYbounds) {
476 apollo::planning::PlannerOpenSpaceConfig planner_open_space_config_;
478 FLAGS_planner_open_space_config_filename, &planner_open_space_config_))
479 << "Failed to load open space config file " << FLAGS_planner_open_space_config_filename;
480 AINFO << "FLAGS_planner_open_space_config_filename: " << FLAGS_planner_open_space_config_filename;
481
482 double hybrid_total = 0.0;
483 double dual_total = 0.0;
484 double ipopt_total = 0.0;
485
486 std::string flag_file_path = "/apollo/modules/planning/planning_component/conf/planning.conf";
487 google::SetCommandLineOption("flagfile", flag_file_path.c_str());
488
489 HybridAStartResult hybrid_astar_result;
490 std::vector<double> XYbounds_(XYbounds, XYbounds + 4);
491 std::vector<std::vector<common::math::Vec2d>> soft_boundary_vertices_vec;
492
493 const auto start_timestamp = std::chrono::system_clock::now();
494 if (!hybridA_ptr->Plan(
495 sx,
496 sy,
497 sphi,
498 ex,
499 ey,
500 ephi,
501 XYbounds_,
502 obstacles_ptr->GetObstacleVec(),
503 &hybrid_astar_result,
504 soft_boundary_vertices_vec,
505 false)) {
506 AINFO << "Hybrid A Star fails";
507 return false;
508 }
509 const auto end_timestamp = std::chrono::system_clock::now();
510 std::chrono::duration<double> time_diff = end_timestamp - start_timestamp;
511 hybrid_total = time_diff.count() * 1000;
512
513 if (FLAGS_enable_parallel_trajectory_smoothing) {
514 std::vector<HybridAStartResult> partition_trajectories;
515 if (!hybridA_ptr->TrajectoryPartition(hybrid_astar_result, &partition_trajectories)) {
516 AERROR << "TrajectoryPartition failed";
517 *(result_ptr->PrepareHybridAResult()) = hybrid_astar_result;
518 return false;
519 }
520 size_t size = partition_trajectories.size();
521 std::vector<Eigen::MatrixXd> state_result_ds_vec;
522 std::vector<Eigen::MatrixXd> control_result_ds_vec;
523 std::vector<Eigen::MatrixXd> time_result_ds_vec;
524 std::vector<Eigen::MatrixXd> dual_l_result_ds_vec;
525 std::vector<Eigen::MatrixXd> dual_n_result_ds_vec;
526 state_result_ds_vec.resize(size);
527 control_result_ds_vec.resize(size);
528 time_result_ds_vec.resize(size);
529 dual_l_result_ds_vec.resize(size);
530 dual_n_result_ds_vec.resize(size);
531 std::vector<std::future<bool>> results;
532
533 // In parallel
534 // TODO(Jinyun): fix memory issue
535 // for (size_t i = 0; i < size; ++i) {
536 // double piece_wise_sx = partition_trajectories[i].x.front();
537 // double piece_wise_sy = partition_trajectories[i].y.front();
538 // double piece_wise_sphi = partition_trajectories[i].phi.front();
539 // double piece_wise_ex = partition_trajectories[i].x.back();
540 // double piece_wise_ey = partition_trajectories[i].y.back();
541 // double piece_wise_ephi = partition_trajectories[i].phi.back();
542 // auto* ith_trajectories = &partition_trajectories[i];
543 // auto* ith_state_result = &state_result_ds_vec[i];
544 // auto* ith_control_result = &control_result_ds_vec[i];
545 // auto* ith_time_result = &time_result_ds_vec[i];
546 // auto* ith_dual_l_result = &dual_l_result_ds_vec[i];
547 // auto* ith_dual_n_result = &dual_n_result_ds_vec[i];
548 // results.push_back(
549 // cyber::Async(&DistanceSmoothing,
550 // std::ref(planner_open_space_config_),
551 // std::ref(*obstacles_ptr), piece_wise_sx,
552 // piece_wise_sy, piece_wise_sphi, piece_wise_ex,
553 // piece_wise_ey, piece_wise_ephi, std::ref(XYbounds_),
554 // ith_trajectories, ith_state_result,
555 // ith_control_result, ith_time_result,
556 // ith_dual_l_result, ith_dual_n_result));
557 // }
558 // for (auto& result : results) {
559 // if (!result.get()) {
560 // AERROR << "Failure in a piece of trajectory.";
561 // return false;
562 // }
563 // }
564
565 // In for loop
566 double dual_tmp = 0.0;
567 double ipopt_tmp = 0.0;
568 for (size_t i = 0; i < size; ++i) {
569 double piece_wise_sx = partition_trajectories[i].x.front();
570 double piece_wise_sy = partition_trajectories[i].y.front();
571 double piece_wise_sphi = partition_trajectories[i].phi.front();
572 double piece_wise_ex = partition_trajectories[i].x.back();
573 double piece_wise_ey = partition_trajectories[i].y.back();
574 double piece_wise_ephi = partition_trajectories[i].phi.back();
575
577 planner_open_space_config_,
578 *obstacles_ptr,
579 piece_wise_sx,
580 piece_wise_sy,
581 piece_wise_sphi,
582 piece_wise_ex,
583 piece_wise_ey,
584 piece_wise_ephi,
585 XYbounds_,
586 &partition_trajectories[i],
587 &state_result_ds_vec[i],
588 &control_result_ds_vec[i],
589 &time_result_ds_vec[i],
590 &dual_l_result_ds_vec[i],
591 &dual_n_result_ds_vec[i],
592 dual_tmp,
593 ipopt_tmp)) {
594 *(result_ptr->PrepareHybridAResult()) = hybrid_astar_result;
595 return false;
596 }
597 dual_total += dual_tmp;
598 ipopt_total += ipopt_tmp;
599 }
600
601 // Retrieve result in one single trajectory
602 size_t trajectory_point_size = 0;
603 for (size_t i = 0; i < size; ++i) {
604 if (state_result_ds_vec[i].cols() < 2) {
605 AERROR << "state horizon smaller than 2";
606 return false;
607 }
608 AINFO << "trajectory idx: "
609 << "idx range: " << trajectory_point_size << ", "
610 << trajectory_point_size + static_cast<size_t>(state_result_ds_vec[i].cols()) - 1;
611 trajectory_point_size += static_cast<size_t>(state_result_ds_vec[i].cols()) - 1;
612 }
613 ++trajectory_point_size;
614
615 const uint64_t state_dimension = state_result_ds_vec.front().rows();
616 Eigen::MatrixXd state_result_ds;
617 state_result_ds.resize(state_dimension, trajectory_point_size);
618 uint64_t k = 0;
619 for (size_t i = 0; i < size; ++i) {
620 // leave out the last repeated point so set column minus one
621 uint64_t state_col_num = state_result_ds_vec[i].cols() - 1;
622 for (uint64_t j = 0; j < state_col_num; ++j) {
623 state_result_ds.col(k) = state_result_ds_vec[i].col(j);
624 ++k;
625 }
626 }
627 state_result_ds.col(k) = state_result_ds_vec.back().col(state_result_ds_vec.back().cols() - 1);
628
629 const uint64_t control_dimension = control_result_ds_vec.front().rows();
630 Eigen::MatrixXd control_result_ds;
631 control_result_ds.resize(control_dimension, trajectory_point_size - 1);
632 k = 0;
633
634 for (size_t i = 0; i < size; ++i) {
635 uint64_t control_col_num = control_result_ds_vec[i].cols() - 1;
636 for (uint64_t j = 0; j < control_col_num; ++j) {
637 control_result_ds.col(k) = control_result_ds_vec[i].col(j);
638 ++k;
639 }
640 }
641
642 const uint64_t time_dimension = time_result_ds_vec.front().rows();
643 Eigen::MatrixXd time_result_ds;
644 time_result_ds.resize(time_dimension, trajectory_point_size - 1);
645 k = 0;
646 for (size_t i = 0; i < size; ++i) {
647 uint64_t time_col_num = time_result_ds_vec[i].cols() - 1;
648 for (uint64_t j = 0; j < time_col_num; ++j) {
649 time_result_ds.col(k) = time_result_ds_vec[i].col(j);
650 ++k;
651 }
652 }
653
654 *(result_ptr->PrepareHybridAResult()) = hybrid_astar_result;
655 *(result_ptr->PrepareStateResult()) = state_result_ds;
656 *(result_ptr->PrepareControlResult()) = control_result_ds;
657 *(result_ptr->PrepareTimeResult()) = time_result_ds;
658 *(result_ptr->GetHybridTime()) = hybrid_total;
659 *(result_ptr->GetDualTime()) = dual_total;
660 *(result_ptr->GetIpoptTime()) = ipopt_total;
661 } else {
662 Eigen::MatrixXd state_result_ds;
663 Eigen::MatrixXd control_result_ds;
664 Eigen::MatrixXd time_result_ds;
665 Eigen::MatrixXd dual_l_result_ds;
666 Eigen::MatrixXd dual_n_result_ds;
668 planner_open_space_config_,
669 *obstacles_ptr,
670 sx,
671 sy,
672 sphi,
673 ex,
674 ey,
675 ephi,
676 XYbounds_,
677 &hybrid_astar_result,
678 &state_result_ds,
679 &control_result_ds,
680 &time_result_ds,
681 &dual_l_result_ds,
682 &dual_n_result_ds,
683 dual_total,
684 ipopt_total)) {
685 AERROR << "DistanceSmoothing failed";
686 *(result_ptr->PrepareHybridAResult()) = hybrid_astar_result;
687 return false;
688 }
689 *(result_ptr->PrepareHybridAResult()) = hybrid_astar_result;
690 *(result_ptr->PrepareStateResult()) = state_result_ds;
691 *(result_ptr->PrepareControlResult()) = control_result_ds;
692 *(result_ptr->PrepareTimeResult()) = time_result_ds;
693 *(result_ptr->PrepareLResult()) = dual_l_result_ds;
694 *(result_ptr->PrepareNResult()) = dual_n_result_ds;
695 *(result_ptr->GetHybridTime()) = hybrid_total;
696 *(result_ptr->GetDualTime()) = dual_total;
697 *(result_ptr->GetIpoptTime()) = ipopt_total;
698 }
699 return true;
700}
701
703 ResultContainer* result_ptr,
704 ObstacleContainer* obstacles_ptr,
705 double* x,
706 double* y,
707 double* phi,
708 double* v,
709 double* a,
710 double* steer,
711 double* opt_x,
712 double* opt_y,
713 double* opt_phi,
714 double* opt_v,
715 double* opt_a,
716 double* opt_steer,
717 double* opt_time,
718 double* opt_dual_l,
719 double* opt_dual_n,
720 size_t* output_size,
721 double* hybrid_time,
722 double* dual_time,
723 double* ipopt_time) {
724 result_ptr->LoadHybridAResult();
725 size_t size = result_ptr->GetX()->size();
726 size_t size_by_distance = result_ptr->PrepareStateResult()->cols();
727 AERROR_IF(size != size_by_distance) << "sizes by hybrid A and distance approach not consistent";
728 for (size_t i = 0; i < size; ++i) {
729 x[i] = result_ptr->GetX()->at(i);
730 y[i] = result_ptr->GetY()->at(i);
731 phi[i] = result_ptr->GetPhi()->at(i);
732 v[i] = result_ptr->GetV()->at(i);
733 }
734 for (size_t i = 0; i + 1 < size; ++i) {
735 a[i] = result_ptr->GetA()->at(i);
736 steer[i] = result_ptr->GetSteer()->at(i);
737 }
738 output_size[0] = size;
739
740 size_t obstacles_edges_sum = obstacles_ptr->GetObstaclesEdgesNum().sum();
741 size_t obstacles_num_to_car = 4 * obstacles_ptr->GetObstaclesNum();
742 for (size_t i = 0; i < size_by_distance; ++i) {
743 opt_x[i] = (*(result_ptr->PrepareStateResult()))(0, i);
744 opt_y[i] = (*(result_ptr->PrepareStateResult()))(1, i);
745 opt_phi[i] = (*(result_ptr->PrepareStateResult()))(2, i);
746 opt_v[i] = (*(result_ptr->PrepareStateResult()))(3, i);
747 }
748
749 if (result_ptr->PrepareTimeResult() != 0) {
750 for (size_t i = 0; i + 1 < size_by_distance; ++i) {
751 opt_time[i] = (*(result_ptr->PrepareTimeResult()))(0, i);
752 }
753 }
754
755 if (result_ptr->PrepareLResult()->cols() != 0 && result_ptr->PrepareNResult() != 0) {
756 for (size_t i = 0; i + 1 < size_by_distance; ++i) {
757 for (size_t j = 0; j < obstacles_edges_sum; ++j) {
758 opt_dual_l[i * obstacles_edges_sum + j] = (*(result_ptr->PrepareLResult()))(j, i);
759 }
760 for (size_t k = 0; k < obstacles_num_to_car; ++k) {
761 opt_dual_n[i * obstacles_num_to_car + k] = (*(result_ptr->PrepareNResult()))(k, i);
762 }
763 }
764 }
765 for (size_t i = 0; i + 1 < size_by_distance; ++i) {
766 opt_a[i] = (*(result_ptr->PrepareControlResult()))(1, i);
767 opt_steer[i] = (*(result_ptr->PrepareControlResult()))(0, i);
768 }
769
770 hybrid_time[0] = *(result_ptr->GetHybridTime());
771 dual_time[0] = *(result_ptr->GetDualTime());
772 ipopt_time[0] = *(result_ptr->GetIpoptTime());
773}
774};
775
776} // namespace planning
777} // namespace apollo
static const VehicleConfig & GetConfig()
Get the current vehicle configuration.
Implements a class of 2-dimensional vectors.
Definition vec2d.h:42
double y() const
Getter for y component
Definition vec2d.h:57
double x() const
Getter for x component
Definition vec2d.h:54
bool Solve(const Eigen::MatrixXd &x0, const Eigen::MatrixXd &xF, const Eigen::MatrixXd &last_time_u, const size_t horizon, const double ts, const Eigen::MatrixXd &ego, const Eigen::MatrixXd &xWS, const Eigen::MatrixXd &uWS, const Eigen::MatrixXd &l_warm_up, const Eigen::MatrixXd &n_warm_up, const Eigen::MatrixXd &s_warm_up, const std::vector< double > &XYbounds, const size_t obstacles_num, const Eigen::MatrixXi &obstacles_edges_num, const Eigen::MatrixXd &obstacles_A, const Eigen::MatrixXd &obstacles_b, Eigen::MatrixXd *state_result, Eigen::MatrixXd *control_result, Eigen::MatrixXd *time_result, Eigen::MatrixXd *dual_l_result, Eigen::MatrixXd *dual_n_result)
bool Solve(const size_t horizon, const double ts, const Eigen::MatrixXd &ego, const size_t obstacles_num, const Eigen::MatrixXi &obstacles_edges_num, const Eigen::MatrixXd &obstacles_A, const Eigen::MatrixXd &obstacles_b, const Eigen::MatrixXd &xWS, Eigen::MatrixXd *l_warm_up, Eigen::MatrixXd *n_warm_up, Eigen::MatrixXd *s_warm_up)
bool TrajectoryPartition(const HybridAStartResult &result, std::vector< HybridAStartResult > *partitioned_result)
bool Plan(double sx, double sy, double sphi, double ex, double ey, double ephi, const std::vector< double > &XYbounds, const std::vector< std::vector< common::math::Vec2d > > &obstacles_vertices_vec, HybridAStartResult *result, const std::vector< std::vector< common::math::Vec2d > > &soft_boundary_vertices_vec={}, bool reeds_sheep_last_straight=false)
const std::vector< std::vector< Vec2d > > & GetObstacleVec() const
void AddObstacle(const double *ROI_distance_approach_parking_boundary)
bool VPresentationObstacle(const double *ROI_distance_approach_parking_boundary)
bool ObsHRep(const size_t obstacles_num, const Eigen::MatrixXi &obstacles_edges_num, const std::vector< std::vector< Vec2d > > &obstacles_vertices_vec, Eigen::MatrixXd *A_all, Eigen::MatrixXd *b_all)
Planning module main class.
#define ACHECK(cond)
Definition log.h:80
#define ADEBUG
Definition log.h:41
#define AERROR
Definition log.h:44
#define AERROR_IF(cond)
Definition log.h:74
#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
void AddObstacle(ObstacleContainer *obstacles_ptr, const double *ROI_distance_approach_parking_boundary)
ResultContainer * DistanceCreateResultPtr()
ObstacleContainer * DistanceCreateObstaclesPtr()
bool DistancePlan(HybridAStar *hybridA_ptr, ObstacleContainer *obstacles_ptr, ResultContainer *result_ptr, double sx, double sy, double sphi, double ex, double ey, double ephi, double *XYbounds)
void DistanceGetResult(ResultContainer *result_ptr, ObstacleContainer *obstacles_ptr, double *x, double *y, double *phi, double *v, double *a, double *steer, double *opt_x, double *opt_y, double *opt_phi, double *opt_v, double *opt_a, double *opt_steer, double *opt_time, double *opt_dual_l, double *opt_dual_n, size_t *output_size, double *hybrid_time, double *dual_time, double *ipopt_time)
bool DistanceSmoothing(const apollo::planning::PlannerOpenSpaceConfig &planner_open_space_config, const ObstacleContainer &obstacles, double sx, double sy, double sphi, double ex, double ey, double ephi, const std::vector< double > &XYbounds, HybridAStartResult *hybrid_a_star_result, Eigen::MatrixXd *state_result_ds_, Eigen::MatrixXd *control_result_ds_, Eigen::MatrixXd *time_result_ds_, Eigen::MatrixXd *dual_l_result_ds_, Eigen::MatrixXd *dual_n_result_ds_, double &dual_time, double &ipopt_time)
std::vector< double > VectorLinearInterpolation(const std::vector< double > &x, int extend_size)
class register implement
Definition arena_queue.h:37