Apollo 10.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
35 public:
36 ObstacleContainer() = default;
37
39 const double* ROI_distance_approach_parking_boundary) {
40 obstacles_num_ = 4;
41 obstacles_edges_num_.resize(4, 1);
42 obstacles_edges_num_ << 2, 1, 2, 1;
43 size_t index = 0;
44 for (size_t i = 0; i < obstacles_num_; i++) {
45 std::vector<Vec2d> vertices_cw;
46 for (int j = 0; j < obstacles_edges_num_(i, 0) + 1; j++) {
47 Vec2d vertice =
48 Vec2d(ROI_distance_approach_parking_boundary[index],
49 ROI_distance_approach_parking_boundary[index + 1]);
50 index += 2;
51 vertices_cw.emplace_back(vertice);
52 }
53 obstacles_vertices_vec_.emplace_back(vertices_cw);
54 }
55 return true;
56 }
57
59 obstacles_A_ = Eigen::MatrixXd::Zero(obstacles_edges_num_.sum(), 2);
60 obstacles_b_ = Eigen::MatrixXd::Zero(obstacles_edges_num_.sum(), 1);
61 // vertices using H-representation
62 if (!ObsHRep(obstacles_num_, obstacles_edges_num_, obstacles_vertices_vec_,
63 &obstacles_A_, &obstacles_b_)) {
64 AINFO << "Fail to present obstacle in hyperplane";
65 return false;
66 }
67 return true;
68 }
69
70 bool ObsHRep(const size_t obstacles_num,
71 const Eigen::MatrixXi& obstacles_edges_num,
72 const std::vector<std::vector<Vec2d>>& obstacles_vertices_vec,
73 Eigen::MatrixXd* A_all, 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) &&
147 AINFO << "obstacle presentation fails";
148 }
149 }
150
151 const std::vector<std::vector<Vec2d>>& GetObstacleVec() const {
152 return obstacles_vertices_vec_;
153 }
154 const Eigen::MatrixXd& GetAMatrix() const { return obstacles_A_; }
155 const Eigen::MatrixXd& GetbMatrix() const { return obstacles_b_; }
156 size_t GetObstaclesNum() const { return obstacles_num_; }
157 const Eigen::MatrixXi& GetObstaclesEdgesNum() const {
158 return obstacles_edges_num_;
159 }
160
161 private:
162 size_t obstacles_num_ = 0;
163 Eigen::MatrixXi obstacles_edges_num_;
164 std::vector<std::vector<Vec2d>> obstacles_vertices_vec_;
165 Eigen::MatrixXd obstacles_A_;
166 Eigen::MatrixXd obstacles_b_;
167};
168
170 public:
171 ResultContainer() = default;
173 x_ = std::move(result_.x);
174 y_ = std::move(result_.y);
175 phi_ = std::move(result_.phi);
176 v_ = std::move(result_.v);
177 a_ = std::move(result_.a);
178 steer_ = std::move(result_.steer);
179 }
180 std::vector<double>* GetX() { return &x_; }
181 std::vector<double>* GetY() { return &y_; }
182 std::vector<double>* GetPhi() { return &phi_; }
183 std::vector<double>* GetV() { return &v_; }
184 std::vector<double>* GetA() { return &a_; }
185 std::vector<double>* GetSteer() { return &steer_; }
187 Eigen::MatrixXd* PrepareStateResult() { return &state_result_ds_; }
188 Eigen::MatrixXd* PrepareControlResult() { return &control_result_ds_; }
189 Eigen::MatrixXd* PrepareTimeResult() { return &time_result_ds_; }
190 Eigen::MatrixXd* PrepareLResult() { return &dual_l_result_ds_; }
191 Eigen::MatrixXd* PrepareNResult() { return &dual_n_result_ds_; }
192 double* GetHybridTime() { return &hybrid_time_; }
193 double* GetDualTime() { return &dual_time_; }
194 double* GetIpoptTime() { return &ipopt_time_; }
195
196 private:
197 HybridAStartResult result_;
198 std::vector<double> x_;
199 std::vector<double> y_;
200 std::vector<double> phi_;
201 std::vector<double> v_;
202 std::vector<double> a_;
203 std::vector<double> steer_;
204 Eigen::MatrixXd state_result_ds_;
205 Eigen::MatrixXd control_result_ds_;
206 Eigen::MatrixXd time_result_ds_;
207 Eigen::MatrixXd dual_l_result_ds_;
208 Eigen::MatrixXd dual_n_result_ds_;
209 double hybrid_time_;
210 double dual_time_;
211 double ipopt_time_;
212};
213
214extern "C" {
216 apollo::planning::PlannerOpenSpaceConfig planner_open_space_config_;
218 FLAGS_planner_open_space_config_filename, &planner_open_space_config_))
219 << "Failed to load open space config file "
220 << FLAGS_planner_open_space_config_filename;
221 return new HybridAStar(planner_open_space_config_);
222}
227
228void AddObstacle(ObstacleContainer* obstacles_ptr,
229 const double* ROI_distance_approach_parking_boundary) {
230 obstacles_ptr->AddObstacle(ROI_distance_approach_parking_boundary);
231}
232
233double InterpolateUsingLinearApproximation(const double p0, const double p1,
234 const double w) {
235 return p0 * (1.0 - w) + p1 * w;
236}
237
238std::vector<double> VectorLinearInterpolation(const std::vector<double>& x,
239 int extend_size) {
240 // interplation example:
241 // x: [x0, x1, x2], extend_size: 3
242 // output: [y0(x0), y1, y2, y3(x1), y4, y5, y6(x2)]
243 size_t origin_last = x.size() - 1;
244 std::vector<double> res(origin_last * extend_size + 1, 0.0);
245
246 for (size_t i = 0; i < origin_last * extend_size; ++i) {
247 size_t idx0 = i / extend_size;
248 size_t idx1 = idx0 + 1;
249 double w =
250 static_cast<double>(i % extend_size) / static_cast<double>(extend_size);
251 res[i] = InterpolateUsingLinearApproximation(x[idx0], x[idx1], w);
252 }
253
254 res.back() = x.back();
255 return res;
256}
257
259 const apollo::planning::PlannerOpenSpaceConfig& planner_open_space_config,
260 const ObstacleContainer& obstacles, double sx, double sy, double sphi,
261 double ex, double ey, double ephi, const std::vector<double>& XYbounds,
262 HybridAStartResult* hybrid_a_star_result, Eigen::MatrixXd* state_result_ds_,
263 Eigen::MatrixXd* control_result_ds_, Eigen::MatrixXd* time_result_ds_,
264 Eigen::MatrixXd* dual_l_result_ds_, Eigen::MatrixXd* dual_n_result_ds_,
265 double& dual_time, double& ipopt_time) {
266 // load Warm Start result(horizon is the "N", not the size of step points)
267 size_t horizon_ = hybrid_a_star_result->x.size() - 1;
268 // nominal sampling time
269 float ts_ = planner_open_space_config.delta_t();
270
271 Eigen::VectorXd x;
272 Eigen::VectorXd y;
273 Eigen::VectorXd phi;
274 Eigen::VectorXd v;
275 Eigen::VectorXd steer;
276 Eigen::VectorXd a;
277
278 // TODO(Runxin): extend logics in future
279 if (horizon_ <= 10 && horizon_ > 2 &&
280 planner_open_space_config.enable_linear_interpolation()) {
281 // TODO(Runxin): extend this number
282 int extend_size = 5;
283 // modify state and control vectors sizes
284 horizon_ = extend_size * horizon_;
285 // modify delta t
286 ts_ = ts_ / static_cast<float>(extend_size);
287
288 std::vector<double> x_extend =
289 VectorLinearInterpolation(hybrid_a_star_result->x, extend_size);
290 x = Eigen::Map<Eigen::VectorXd, Eigen::Unaligned>(x_extend.data(),
291 horizon_ + 1);
292
293 std::vector<double> y_extend =
294 VectorLinearInterpolation(hybrid_a_star_result->y, extend_size);
295 y = Eigen::Map<Eigen::VectorXd, Eigen::Unaligned>(y_extend.data(),
296 horizon_ + 1);
297
298 std::vector<double> phi_extend =
299 VectorLinearInterpolation(hybrid_a_star_result->phi, extend_size);
300 phi = Eigen::Map<Eigen::VectorXd, Eigen::Unaligned>(phi_extend.data(),
301 horizon_ + 1);
302
303 std::vector<double> v_extend =
304 VectorLinearInterpolation(hybrid_a_star_result->v, extend_size);
305 v = Eigen::Map<Eigen::VectorXd, Eigen::Unaligned>(v_extend.data(),
306 horizon_ + 1);
307
308 steer = Eigen::VectorXd(horizon_);
309 a = Eigen::VectorXd(horizon_);
310 for (size_t i = 0; i < static_cast<size_t>(horizon_); ++i) {
311 steer[i] = hybrid_a_star_result->steer[i / extend_size];
312 a[i] = hybrid_a_star_result->a[i / extend_size];
313 }
314 ADEBUG << "hybrid A x: ";
315 for (size_t i = 0; i < hybrid_a_star_result->x.size(); ++i) {
316 ADEBUG << "i: " << i << ", val: " << hybrid_a_star_result->x[i];
317 }
318 ADEBUG << "interpolated x: \n" << x;
319
320 ADEBUG << "hybrid A steer: ";
321 for (size_t i = 0; i < hybrid_a_star_result->steer.size(); ++i) {
322 ADEBUG << "i: " << i << ", val: " << hybrid_a_star_result->steer[i];
323 }
324 ADEBUG << "interpolated steer: \n" << steer;
325 } else {
326 x = Eigen::Map<Eigen::VectorXd, Eigen::Unaligned>(
327 hybrid_a_star_result->x.data(), horizon_ + 1);
328 y = Eigen::Map<Eigen::VectorXd, Eigen::Unaligned>(
329 hybrid_a_star_result->y.data(), horizon_ + 1);
330 phi = Eigen::Map<Eigen::VectorXd, Eigen::Unaligned>(
331 hybrid_a_star_result->phi.data(), horizon_ + 1);
332 v = Eigen::Map<Eigen::VectorXd, Eigen::Unaligned>(
333 hybrid_a_star_result->v.data(), horizon_ + 1);
334 steer = Eigen::Map<Eigen::VectorXd, Eigen::Unaligned>(
335 hybrid_a_star_result->steer.data(), horizon_);
336 a = Eigen::Map<Eigen::VectorXd, Eigen::Unaligned>(
337 hybrid_a_star_result->a.data(), horizon_);
338 }
339
340 Eigen::MatrixXd xWS = Eigen::MatrixXd::Zero(4, horizon_ + 1);
341 Eigen::MatrixXd uWS = Eigen::MatrixXd::Zero(2, horizon_);
342 xWS.row(0) = x;
343 xWS.row(1) = y;
344 xWS.row(2) = phi;
345 xWS.row(3) = v;
346 uWS.row(0) = steer;
347 uWS.row(1) = a;
348
349 Eigen::MatrixXd x0(4, 1);
350 x0 << sx, sy, sphi, 0.0;
351
352 Eigen::MatrixXd xF(4, 1);
353 xF << ex, ey, ephi, 0.0;
354
355 Eigen::MatrixXd last_time_u(2, 1);
356 last_time_u << 0.0, 0.0;
357
358 common::VehicleParam vehicle_param_ =
360
361 // load vehicle configuration
362 Eigen::MatrixXd ego_(4, 1);
363 double front_to_center = vehicle_param_.front_edge_to_center();
364 double back_to_center = vehicle_param_.back_edge_to_center();
365 double left_to_center = vehicle_param_.left_edge_to_center();
366 double right_to_center = vehicle_param_.right_edge_to_center();
367 ego_ << front_to_center, right_to_center, back_to_center, left_to_center;
368
369 // result for distance approach problem
370 Eigen::MatrixXd l_warm_up;
371 Eigen::MatrixXd n_warm_up;
372 Eigen::MatrixXd s_warm_up =
373 Eigen::MatrixXd::Zero(obstacles.GetObstaclesNum(), horizon_ + 1);
374
375 DualVariableWarmStartProblem* dual_variable_warm_start_ptr =
376 new DualVariableWarmStartProblem(planner_open_space_config);
377
378 const auto t1 = std::chrono::system_clock::now();
379 if (FLAGS_use_dual_variable_warm_start) {
380 bool dual_variable_warm_start_status = dual_variable_warm_start_ptr->Solve(
381 horizon_, ts_, ego_, obstacles.GetObstaclesNum(),
382 obstacles.GetObstaclesEdgesNum(), obstacles.GetAMatrix(),
383 obstacles.GetbMatrix(), xWS, &l_warm_up, &n_warm_up, &s_warm_up);
384
385 if (dual_variable_warm_start_status) {
386 AINFO << "Dual variable problem solved successfully!";
387 } else {
388 AERROR << "Dual variable problem solving failed";
389 return false;
390 }
391 } else {
392 l_warm_up = Eigen::MatrixXd::Zero(obstacles.GetObstaclesEdgesNum().sum(),
393 horizon_ + 1);
394 n_warm_up =
395 Eigen::MatrixXd::Zero(4 * obstacles.GetObstaclesNum(), horizon_ + 1);
396 }
397 const auto t2 = std::chrono::system_clock::now();
398 dual_time = std::chrono::duration<double>(t2 - t1).count() * 1000;
399
400 DistanceApproachProblem* distance_approach_ptr =
401 new DistanceApproachProblem(planner_open_space_config);
402
403 bool status = distance_approach_ptr->Solve(
404 x0, xF, last_time_u, horizon_, ts_, ego_, xWS, uWS, l_warm_up, n_warm_up,
405 s_warm_up, XYbounds, obstacles.GetObstaclesNum(),
406 obstacles.GetObstaclesEdgesNum(), obstacles.GetAMatrix(),
407 obstacles.GetbMatrix(), state_result_ds_, control_result_ds_,
408 time_result_ds_, dual_l_result_ds_, dual_n_result_ds_);
409 const auto t3 = std::chrono::system_clock::now();
410 ipopt_time = std::chrono::duration<double>(t3 - t2).count() * 1000;
411
412 if (!status) {
413 AERROR << "Distance fail";
414 return false;
415 }
416 return true;
417}
418
419bool DistancePlan(HybridAStar* hybridA_ptr, ObstacleContainer* obstacles_ptr,
420 ResultContainer* result_ptr, double sx, double sy,
421 double sphi, double ex, double ey, double ephi,
422 double* XYbounds) {
423 apollo::planning::PlannerOpenSpaceConfig planner_open_space_config_;
425 FLAGS_planner_open_space_config_filename, &planner_open_space_config_))
426 << "Failed to load open space config file "
427 << FLAGS_planner_open_space_config_filename;
428 AINFO << "FLAGS_planner_open_space_config_filename: "
429 << FLAGS_planner_open_space_config_filename;
430
431 double hybrid_total = 0.0;
432 double dual_total = 0.0;
433 double ipopt_total = 0.0;
434
435 std::string flag_file_path =
436 "modules/planning/planning_component/conf/planning.conf";
437 google::SetCommandLineOption("flagfile", flag_file_path.c_str());
438
439 HybridAStartResult hybrid_astar_result;
440 std::vector<double> XYbounds_(XYbounds, XYbounds + 4);
441 std::vector<std::vector<common::math::Vec2d>> soft_boundary_vertices_vec;
442
443 const auto start_timestamp = std::chrono::system_clock::now();
444 if (!hybridA_ptr->Plan(sx, sy, sphi, ex, ey, ephi, XYbounds_,
445 obstacles_ptr->GetObstacleVec(),
446 &hybrid_astar_result,
447 soft_boundary_vertices_vec, false)) {
448 AINFO << "Hybrid A Star fails";
449 return false;
450 }
451 const auto end_timestamp = std::chrono::system_clock::now();
452 std::chrono::duration<double> time_diff = end_timestamp - start_timestamp;
453 hybrid_total = time_diff.count() * 1000;
454
455 if (FLAGS_enable_parallel_trajectory_smoothing) {
456 std::vector<HybridAStartResult> partition_trajectories;
457 if (!hybridA_ptr->TrajectoryPartition(hybrid_astar_result,
458 &partition_trajectories)) {
459 AERROR << "TrajectoryPartition failed";
460 *(result_ptr->PrepareHybridAResult()) = hybrid_astar_result;
461 return false;
462 }
463 size_t size = partition_trajectories.size();
464 std::vector<Eigen::MatrixXd> state_result_ds_vec;
465 std::vector<Eigen::MatrixXd> control_result_ds_vec;
466 std::vector<Eigen::MatrixXd> time_result_ds_vec;
467 std::vector<Eigen::MatrixXd> dual_l_result_ds_vec;
468 std::vector<Eigen::MatrixXd> dual_n_result_ds_vec;
469 state_result_ds_vec.resize(size);
470 control_result_ds_vec.resize(size);
471 time_result_ds_vec.resize(size);
472 dual_l_result_ds_vec.resize(size);
473 dual_n_result_ds_vec.resize(size);
474 std::vector<std::future<bool>> results;
475
476 // In parallel
477 // TODO(Jinyun): fix memory issue
478 // for (size_t i = 0; i < size; ++i) {
479 // double piece_wise_sx = partition_trajectories[i].x.front();
480 // double piece_wise_sy = partition_trajectories[i].y.front();
481 // double piece_wise_sphi = partition_trajectories[i].phi.front();
482 // double piece_wise_ex = partition_trajectories[i].x.back();
483 // double piece_wise_ey = partition_trajectories[i].y.back();
484 // double piece_wise_ephi = partition_trajectories[i].phi.back();
485 // auto* ith_trajectories = &partition_trajectories[i];
486 // auto* ith_state_result = &state_result_ds_vec[i];
487 // auto* ith_control_result = &control_result_ds_vec[i];
488 // auto* ith_time_result = &time_result_ds_vec[i];
489 // auto* ith_dual_l_result = &dual_l_result_ds_vec[i];
490 // auto* ith_dual_n_result = &dual_n_result_ds_vec[i];
491 // results.push_back(
492 // cyber::Async(&DistanceSmoothing,
493 // std::ref(planner_open_space_config_),
494 // std::ref(*obstacles_ptr), piece_wise_sx,
495 // piece_wise_sy, piece_wise_sphi, piece_wise_ex,
496 // piece_wise_ey, piece_wise_ephi, std::ref(XYbounds_),
497 // ith_trajectories, ith_state_result,
498 // ith_control_result, ith_time_result,
499 // ith_dual_l_result, ith_dual_n_result));
500 // }
501 // for (auto& result : results) {
502 // if (!result.get()) {
503 // AERROR << "Failure in a piece of trajectory.";
504 // return false;
505 // }
506 // }
507
508 // In for loop
509 double dual_tmp = 0.0;
510 double ipopt_tmp = 0.0;
511 for (size_t i = 0; i < size; ++i) {
512 double piece_wise_sx = partition_trajectories[i].x.front();
513 double piece_wise_sy = partition_trajectories[i].y.front();
514 double piece_wise_sphi = partition_trajectories[i].phi.front();
515 double piece_wise_ex = partition_trajectories[i].x.back();
516 double piece_wise_ey = partition_trajectories[i].y.back();
517 double piece_wise_ephi = partition_trajectories[i].phi.back();
518
519 if (!DistanceSmoothing(planner_open_space_config_, *obstacles_ptr,
520 piece_wise_sx, piece_wise_sy, piece_wise_sphi,
521 piece_wise_ex, piece_wise_ey, piece_wise_ephi,
522 XYbounds_, &partition_trajectories[i],
523 &state_result_ds_vec[i], &control_result_ds_vec[i],
524 &time_result_ds_vec[i], &dual_l_result_ds_vec[i],
525 &dual_n_result_ds_vec[i], dual_tmp, ipopt_tmp)) {
526 *(result_ptr->PrepareHybridAResult()) = hybrid_astar_result;
527 return false;
528 }
529 dual_total += dual_tmp;
530 ipopt_total += ipopt_tmp;
531 }
532
533 // Retrieve result in one single trajectory
534 size_t trajectory_point_size = 0;
535 for (size_t i = 0; i < size; ++i) {
536 if (state_result_ds_vec[i].cols() < 2) {
537 AERROR << "state horizon smaller than 2";
538 return false;
539 }
540 AINFO << "trajectory idx: "
541 << "idx range: " << trajectory_point_size << ", "
542 << trajectory_point_size +
543 static_cast<size_t>(state_result_ds_vec[i].cols()) - 1;
544 trajectory_point_size +=
545 static_cast<size_t>(state_result_ds_vec[i].cols()) - 1;
546 }
547 ++trajectory_point_size;
548
549 const uint64_t state_dimension = state_result_ds_vec.front().rows();
550 Eigen::MatrixXd state_result_ds;
551 state_result_ds.resize(state_dimension, trajectory_point_size);
552 uint64_t k = 0;
553 for (size_t i = 0; i < size; ++i) {
554 // leave out the last repeated point so set column minus one
555 uint64_t state_col_num = state_result_ds_vec[i].cols() - 1;
556 for (uint64_t j = 0; j < state_col_num; ++j) {
557 state_result_ds.col(k) = state_result_ds_vec[i].col(j);
558 ++k;
559 }
560 }
561 state_result_ds.col(k) =
562 state_result_ds_vec.back().col(state_result_ds_vec.back().cols() - 1);
563
564 const uint64_t control_dimension = control_result_ds_vec.front().rows();
565 Eigen::MatrixXd control_result_ds;
566 control_result_ds.resize(control_dimension, trajectory_point_size - 1);
567 k = 0;
568
569 for (size_t i = 0; i < size; ++i) {
570 uint64_t control_col_num = control_result_ds_vec[i].cols() - 1;
571 for (uint64_t j = 0; j < control_col_num; ++j) {
572 control_result_ds.col(k) = control_result_ds_vec[i].col(j);
573 ++k;
574 }
575 }
576
577 const uint64_t time_dimension = time_result_ds_vec.front().rows();
578 Eigen::MatrixXd time_result_ds;
579 time_result_ds.resize(time_dimension, trajectory_point_size - 1);
580 k = 0;
581 for (size_t i = 0; i < size; ++i) {
582 uint64_t time_col_num = time_result_ds_vec[i].cols() - 1;
583 for (uint64_t j = 0; j < time_col_num; ++j) {
584 time_result_ds.col(k) = time_result_ds_vec[i].col(j);
585 ++k;
586 }
587 }
588
589 *(result_ptr->PrepareHybridAResult()) = hybrid_astar_result;
590 *(result_ptr->PrepareStateResult()) = state_result_ds;
591 *(result_ptr->PrepareControlResult()) = control_result_ds;
592 *(result_ptr->PrepareTimeResult()) = time_result_ds;
593 *(result_ptr->GetHybridTime()) = hybrid_total;
594 *(result_ptr->GetDualTime()) = dual_total;
595 *(result_ptr->GetIpoptTime()) = ipopt_total;
596 } else {
597 Eigen::MatrixXd state_result_ds;
598 Eigen::MatrixXd control_result_ds;
599 Eigen::MatrixXd time_result_ds;
600 Eigen::MatrixXd dual_l_result_ds;
601 Eigen::MatrixXd dual_n_result_ds;
602 if (!DistanceSmoothing(planner_open_space_config_, *obstacles_ptr, sx, sy,
603 sphi, ex, ey, ephi, XYbounds_, &hybrid_astar_result,
604 &state_result_ds, &control_result_ds,
605 &time_result_ds, &dual_l_result_ds,
606 &dual_n_result_ds, dual_total, ipopt_total)) {
607 AERROR << "DistanceSmoothing failed";
608 *(result_ptr->PrepareHybridAResult()) = hybrid_astar_result;
609 return false;
610 }
611 *(result_ptr->PrepareHybridAResult()) = hybrid_astar_result;
612 *(result_ptr->PrepareStateResult()) = state_result_ds;
613 *(result_ptr->PrepareControlResult()) = control_result_ds;
614 *(result_ptr->PrepareTimeResult()) = time_result_ds;
615 *(result_ptr->PrepareLResult()) = dual_l_result_ds;
616 *(result_ptr->PrepareNResult()) = dual_n_result_ds;
617 *(result_ptr->GetHybridTime()) = hybrid_total;
618 *(result_ptr->GetDualTime()) = dual_total;
619 *(result_ptr->GetIpoptTime()) = ipopt_total;
620 }
621 return true;
622}
623
625 ObstacleContainer* obstacles_ptr, double* x, double* y,
626 double* phi, double* v, double* a, double* steer,
627 double* opt_x, double* opt_y, double* opt_phi,
628 double* opt_v, double* opt_a, double* opt_steer,
629 double* opt_time, double* opt_dual_l, double* opt_dual_n,
630 size_t* output_size, double* hybrid_time,
631 double* dual_time, double* ipopt_time) {
632 result_ptr->LoadHybridAResult();
633 size_t size = result_ptr->GetX()->size();
634 size_t size_by_distance = result_ptr->PrepareStateResult()->cols();
635 AERROR_IF(size != size_by_distance)
636 << "sizes by hybrid A and distance approach not consistent";
637 for (size_t i = 0; i < size; ++i) {
638 x[i] = result_ptr->GetX()->at(i);
639 y[i] = result_ptr->GetY()->at(i);
640 phi[i] = result_ptr->GetPhi()->at(i);
641 v[i] = result_ptr->GetV()->at(i);
642 }
643 for (size_t i = 0; i + 1 < size; ++i) {
644 a[i] = result_ptr->GetA()->at(i);
645 steer[i] = result_ptr->GetSteer()->at(i);
646 }
647 output_size[0] = size;
648
649 size_t obstacles_edges_sum = obstacles_ptr->GetObstaclesEdgesNum().sum();
650 size_t obstacles_num_to_car = 4 * obstacles_ptr->GetObstaclesNum();
651 for (size_t i = 0; i < size_by_distance; ++i) {
652 opt_x[i] = (*(result_ptr->PrepareStateResult()))(0, i);
653 opt_y[i] = (*(result_ptr->PrepareStateResult()))(1, i);
654 opt_phi[i] = (*(result_ptr->PrepareStateResult()))(2, i);
655 opt_v[i] = (*(result_ptr->PrepareStateResult()))(3, i);
656 }
657
658 if (result_ptr->PrepareTimeResult() != 0) {
659 for (size_t i = 0; i + 1 < size_by_distance; ++i) {
660 opt_time[i] = (*(result_ptr->PrepareTimeResult()))(0, i);
661 }
662 }
663
664 if (result_ptr->PrepareLResult()->cols() != 0 &&
665 result_ptr->PrepareNResult() != 0) {
666 for (size_t i = 0; i + 1 < size_by_distance; ++i) {
667 for (size_t j = 0; j < obstacles_edges_sum; ++j) {
668 opt_dual_l[i * obstacles_edges_sum + j] =
669 (*(result_ptr->PrepareLResult()))(j, i);
670 }
671 for (size_t k = 0; k < obstacles_num_to_car; ++k) {
672 opt_dual_n[i * obstacles_num_to_car + k] =
673 (*(result_ptr->PrepareNResult()))(k, i);
674 }
675 }
676 }
677 for (size_t i = 0; i + 1 < size_by_distance; ++i) {
678 opt_a[i] = (*(result_ptr->PrepareControlResult()))(1, i);
679 opt_steer[i] = (*(result_ptr->PrepareControlResult()))(0, i);
680 }
681
682 hybrid_time[0] = *(result_ptr->GetHybridTime());
683 dual_time[0] = *(result_ptr->GetDualTime());
684 ipopt_time[0] = *(result_ptr->GetIpoptTime());
685}
686};
687
688} // namespace planning
689} // 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
optional VehicleParam vehicle_param