38 AINFO << config_.DebugString();
41 dual_variable_warm_start_.reset(
46 distance_approach_.reset(
50 iterative_anchoring_smoother_.reset(
58 const std::vector<std::vector<Vec2d>>& obstacles_vertices_vec =
60 const std::vector<double>& XYbounds = open_space_info.
ROI_xy_boundary();
61 const Eigen::MatrixXi& obstacles_edges_num =
63 const Eigen::MatrixXd& obstacles_A = open_space_info.
obstacles_A();
64 const Eigen::MatrixXd& obstacles_b = open_space_info.
obstacles_b();
70 for (
size_t i = 0; i < warm_start_trajectory.size(); i++) {
71 double x = warm_start_trajectory[i].path_point().x();
72 double y = warm_start_trajectory[i].path_point().y();
73 double theta = warm_start_trajectory[i].path_point().theta();
79 warm_start_trajectory[i].mutable_path_point()->set_x(x);
80 warm_start_trajectory[i].mutable_path_point()->set_y(y);
81 warm_start_trajectory[i].mutable_path_point()->set_theta(theta);
87 Eigen::MatrixXd state_result_ds;
88 Eigen::MatrixXd control_result_ds;
89 Eigen::MatrixXd time_result_ds;
90 Eigen::MatrixXd l_warm_up;
91 Eigen::MatrixXd n_warm_up;
92 Eigen::MatrixXd dual_l_result_ds;
93 Eigen::MatrixXd dual_n_result_ds;
95 if (FLAGS_enable_parallel_trajectory_smoothing) {
96 std::vector<DiscretizedTrajectory> partition_trajectories;
98 PartitionTrajectory(warm_start_trajectory, &partition_trajectories);
100 size_t size = partition_trajectories.size();
101 std::vector<Eigen::MatrixXd> xWS_vec;
102 std::vector<Eigen::MatrixXd> uWS_vec;
103 std::vector<Eigen::MatrixXd> state_result_ds_vec;
104 std::vector<Eigen::MatrixXd> control_result_ds_vec;
105 std::vector<Eigen::MatrixXd> time_result_ds_vec;
106 std::vector<Eigen::MatrixXd> l_warm_up_vec;
107 std::vector<Eigen::MatrixXd> n_warm_up_vec;
108 std::vector<Eigen::MatrixXd> dual_l_result_ds_vec;
109 std::vector<Eigen::MatrixXd> dual_n_result_ds_vec;
110 xWS_vec.resize(size);
111 uWS_vec.resize(size);
112 state_result_ds_vec.resize(size);
113 control_result_ds_vec.resize(size);
114 time_result_ds_vec.resize(size);
115 l_warm_up_vec.resize(size);
116 n_warm_up_vec.resize(size);
117 dual_l_result_ds_vec.resize(size);
118 dual_n_result_ds_vec.resize(size);
121 ADEBUG <<
"Trajectories size in smoother is " << size;
122 for (
size_t i = 0; i < size; ++i) {
123 LoadTrajectoryInEigen(partition_trajectories[i], xWS_vec[i],
125 Eigen::MatrixXd last_time_u(2, 1);
126 last_time_u << 0.0, 0.0;
130 const auto smoother_start_timestamp = std::chrono::system_clock::now();
131 if (FLAGS_use_iterative_anchoring_smoother) {
132 AINFO <<
"use iterative anchoring smoother";
133 if (!GenerateDecoupledTraj(
134 xWS_vec[i], last_time_u(1, 0), init_v, obstacles_vertices_vec,
135 &state_result_ds_vec[i], &control_result_ds_vec[i],
136 &time_result_ds_vec[i])) {
137 AERROR <<
"Smoother fail at " << i <<
"th trajectory";
138 AERROR << i <<
"th trajectory size is " << xWS_vec[i].cols();
140 ErrorCode::PLANNING_ERROR,
141 "iterative anchoring smoothing problem failed to solve");
144 const double start_system_timestamp =
145 std::chrono::duration<double>(
146 std::chrono::system_clock::now().time_since_epoch())
148 AINFO <<
"use distance approach parallel smoother";
149 if (!GenerateDistanceApproachTraj(
150 xWS_vec[i], uWS_vec[i], XYbounds, obstacles_edges_num,
151 obstacles_A, obstacles_b, obstacles_vertices_vec, last_time_u,
152 init_v, &state_result_ds_vec[i], &control_result_ds_vec[i],
153 &time_result_ds_vec[i], &l_warm_up_vec[i], &n_warm_up_vec[i],
154 &dual_l_result_ds_vec[i], &dual_n_result_ds_vec[i])) {
155 AERROR <<
"Smoother fail at " << i
156 <<
"th trajectory with index starts from 0";
157 AERROR << i <<
"th trajectory size is " << xWS_vec[i].cols();
158 AERROR <<
"State matrix: " << xWS_vec[i];
159 AERROR <<
"Control matrix: " << uWS_vec[i];
160 return Status(ErrorCode::PLANNING_ERROR,
161 "distance approach smoothing problem failed to solve");
163 const auto end_system_timestamp =
164 std::chrono::duration<double>(
165 std::chrono::system_clock::now().time_since_epoch())
167 const auto time_diff_ms =
168 (end_system_timestamp - start_system_timestamp) * 1000;
169 ADEBUG <<
"total planning time spend: " << time_diff_ms <<
" ms.";
170 ADEBUG << i <<
"th trajectory size is " << xWS_vec[i].cols();
171 ADEBUG <<
"average time spend: " << time_diff_ms / xWS_vec[i].cols()
173 ADEBUG <<
"average time spend after smooth: "
174 << time_diff_ms / state_result_ds_vec[i].cols()
176 ADEBUG << i <<
"th smoothed trajectory size is "
177 << state_result_ds_vec[i].cols();
179 const auto smoother_end_timestamp = std::chrono::system_clock::now();
180 std::chrono::duration<double> smoother_diff =
181 smoother_end_timestamp - smoother_start_timestamp;
182 AINFO <<
"Open space trajectory smoothing total time: "
183 << smoother_diff.count() * 1000.0 <<
" ms at the " << i
185 AINFO <<
"The " << i <<
"th trajectory pre-smoothing size is "
186 << xWS_vec[i].cols() <<
"; post-smoothing size is "
187 << state_result_ds_vec[i].cols();
191 CombineTrajectories(xWS_vec, uWS_vec, state_result_ds_vec,
192 control_result_ds_vec, time_result_ds_vec,
193 l_warm_up_vec, n_warm_up_vec, dual_l_result_ds_vec,
194 dual_n_result_ds_vec, &xWS, &uWS, &state_result_ds,
195 &control_result_ds, &time_result_ds, &l_warm_up,
196 &n_warm_up, &dual_l_result_ds, &dual_n_result_ds);
199 AINFO <<
"use distance approach smoother";
200 LoadTrajectoryInEigen(warm_start_trajectory, xWS, uWS);
202 Eigen::MatrixXd last_time_u(2, 1);
205 const double init_v = 0;
206 FLAGS_use_iterative_anchoring_smoother =
false;
207 if (!GenerateDistanceApproachTraj(
208 xWS, uWS, XYbounds, obstacles_edges_num, obstacles_A, obstacles_b,
209 obstacles_vertices_vec, last_time_u, init_v, &state_result_ds,
210 &control_result_ds, &time_result_ds, &l_warm_up, &n_warm_up,
211 &dual_l_result_ds, &dual_n_result_ds)) {
212 return Status(ErrorCode::PLANNING_ERROR,
213 "distance approach smoothing problem failed to solve");
218 if (FLAGS_enable_record_debug) {
219 open_space_debug_.Clear();
220 RecordDebugInfo(origin_point, origin_angle,
222 xWS, uWS, l_warm_up, n_warm_up, dual_l_result_ds,
223 dual_n_result_ds, state_result_ds, control_result_ds,
224 time_result_ds, XYbounds, obstacles_vertices_vec);
228 size_t state_size = state_result_ds.cols();
229 for (
size_t i = 0; i < state_size; ++i) {
231 origin_angle, origin_point,
232 &(state_result_ds(0, i)), &(state_result_ds(1, i)),
233 &(state_result_ds(2, i)));
236 LoadTrajectory(state_result_ds, control_result_ds, time_result_ds);
247void Optimizer::LoadTrajectoryInEigen(
249 size_t horizon = result.size() - 1;
250 xWS.resize(4, horizon + 1);
251 uWS.resize(2, horizon);
253 for (
size_t i = 0; i < horizon; i++) {
254 xWS(0, i) = result[i].path_point().x();
255 xWS(1, i) = result[i].path_point().y();
256 xWS(2, i) = result[i].path_point().theta();
257 xWS(3, i) = result[i].v();
258 uWS(0, i) = result[i].steer();
259 uWS(1, i) = result[i].a();
261 xWS(0, horizon) = result.back().path_point().x();
262 xWS(1, horizon) = result.back().path_point().y();
263 xWS(2, horizon) = result.back().path_point().theta();
264 xWS(3, horizon) = result.back().v();
267void Optimizer::CombineTrajectories(
268 const std::vector<Eigen::MatrixXd>& xWS_vec,
269 const std::vector<Eigen::MatrixXd>& uWS_vec,
270 const std::vector<Eigen::MatrixXd>& state_result_ds_vec,
271 const std::vector<Eigen::MatrixXd>& control_result_ds_vec,
272 const std::vector<Eigen::MatrixXd>& time_result_ds_vec,
273 const std::vector<Eigen::MatrixXd>& l_warm_up_vec,
274 const std::vector<Eigen::MatrixXd>& n_warm_up_vec,
275 const std::vector<Eigen::MatrixXd>& dual_l_result_ds_vec,
276 const std::vector<Eigen::MatrixXd>& dual_n_result_ds_vec,
277 Eigen::MatrixXd* xWS, Eigen::MatrixXd* uWS,
278 Eigen::MatrixXd* state_result_ds, Eigen::MatrixXd* control_result_ds,
279 Eigen::MatrixXd* time_result_ds, Eigen::MatrixXd* l_warm_up,
280 Eigen::MatrixXd* n_warm_up, Eigen::MatrixXd* dual_l_result_ds,
281 Eigen::MatrixXd* dual_n_result_ds) {
283 size_t warm_start_state_size = 0;
284 for (
const auto& warm_start_state : xWS_vec) {
285 warm_start_state_size += warm_start_state.cols();
287 warm_start_state_size -= xWS_vec.size() - 1;
289 size_t warm_start_control_size = 0;
290 for (
const auto& warm_start_control : uWS_vec) {
291 warm_start_control_size += warm_start_control.cols();
295 size_t smoothed_state_size = 0;
296 for (
const auto& smoothed_state : state_result_ds_vec) {
297 smoothed_state_size += smoothed_state.cols();
299 smoothed_state_size -= state_result_ds_vec.size() - 1;
301 size_t smoothed_control_size = 0;
302 for (
const auto& smoothed_control : control_result_ds_vec) {
303 smoothed_control_size += smoothed_control.cols();
306 size_t time_size = 0;
307 for (
const auto& smoothed_time : time_result_ds_vec) {
308 time_size += smoothed_time.cols();
311 size_t l_warm_start_size = 0;
312 for (
const auto& l_warm_start : l_warm_up_vec) {
313 l_warm_start_size += l_warm_start.cols();
316 size_t n_warm_start_size = 0;
317 for (
const auto& n_warm_start : n_warm_up_vec) {
318 n_warm_start_size += n_warm_start.cols();
321 size_t l_smoothed_size = 0;
322 for (
const auto& l_smoothed : dual_l_result_ds_vec) {
323 l_smoothed_size += l_smoothed.cols();
326 size_t n_smoothed_size = 0;
327 for (
const auto& n_smoothed : dual_n_result_ds_vec) {
328 n_smoothed_size += n_smoothed.cols();
331 Eigen::MatrixXd xWS_ =
332 Eigen::MatrixXd::Zero(xWS_vec[0].rows(), warm_start_state_size);
333 Eigen::MatrixXd uWS_ =
334 Eigen::MatrixXd::Zero(uWS_vec[0].rows(), warm_start_control_size);
335 Eigen::MatrixXd state_result_ds_ =
336 Eigen::MatrixXd::Zero(state_result_ds_vec[0].rows(), smoothed_state_size);
337 Eigen::MatrixXd control_result_ds_ = Eigen::MatrixXd::Zero(
338 control_result_ds_vec[0].rows(), smoothed_control_size);
339 Eigen::MatrixXd time_result_ds_ =
340 Eigen::MatrixXd::Zero(time_result_ds_vec[0].rows(), time_size);
341 Eigen::MatrixXd l_warm_up_ =
342 Eigen::MatrixXd::Zero(l_warm_up_vec[0].rows(), l_warm_start_size);
343 Eigen::MatrixXd n_warm_up_ =
344 Eigen::MatrixXd::Zero(n_warm_up_vec[0].rows(), n_warm_start_size);
345 Eigen::MatrixXd dual_l_result_ds_ =
346 Eigen::MatrixXd::Zero(dual_l_result_ds_vec[0].rows(), l_smoothed_size);
347 Eigen::MatrixXd dual_n_result_ds_ =
348 Eigen::MatrixXd::Zero(dual_n_result_ds_vec[0].rows(), n_smoothed_size);
350 size_t traj_size = xWS_vec.size();
352 uint64_t counter = 0;
353 for (
size_t i = 0; i < traj_size; ++i) {
355 uint64_t warm_start_state_cols = xWS_vec[i].cols() - 1;
356 for (
size_t j = 0; j < warm_start_state_cols; ++j) {
357 xWS_.col(counter) = xWS_vec[i].col(j);
361 xWS_.col(counter) = xWS_vec.back().col(xWS_vec.back().cols() - 1);
363 CHECK_EQ(counter, warm_start_state_size);
366 for (
size_t i = 0; i < traj_size; ++i) {
368 uint64_t warm_start_control_cols = uWS_vec[i].cols();
369 for (
size_t j = 0; j < warm_start_control_cols; ++j) {
370 uWS_.col(counter) = uWS_vec[i].col(j);
374 CHECK_EQ(counter, warm_start_control_size);
377 for (
size_t i = 0; i < traj_size; ++i) {
379 uint64_t smoothed_state_cols = state_result_ds_vec[i].cols() - 1;
380 for (
size_t j = 0; j < smoothed_state_cols; ++j) {
381 state_result_ds_.col(counter) = state_result_ds_vec[i].col(j);
385 state_result_ds_.col(counter) =
386 state_result_ds_vec.back().col(state_result_ds_vec.back().cols() - 1);
388 CHECK_EQ(counter, smoothed_state_size);
391 for (
size_t i = 0; i < traj_size; ++i) {
393 uint64_t smoothed_control_cols = control_result_ds_vec[i].cols();
394 for (
size_t j = 0; j < smoothed_control_cols; ++j) {
395 control_result_ds_.col(counter) = control_result_ds_vec[i].col(j);
399 CHECK_EQ(counter, smoothed_control_size);
402 for (
size_t i = 0; i < traj_size; ++i) {
404 uint64_t time_cols = time_result_ds_vec[i].cols();
405 for (
size_t j = 0; j < time_cols; ++j) {
406 time_result_ds_.col(counter) = time_result_ds_vec[i].col(j);
410 CHECK_EQ(counter, time_size);
413 for (
size_t i = 0; i < traj_size; ++i) {
415 uint64_t l_warm_up_cols = l_warm_up_vec[i].cols();
416 for (
size_t j = 0; j < l_warm_up_cols; ++j) {
417 l_warm_up_.col(counter) = l_warm_up_vec[i].col(j);
421 CHECK_EQ(counter, l_warm_start_size);
424 for (
size_t i = 0; i < traj_size; ++i) {
426 uint64_t n_warm_up_cols = n_warm_up_vec[i].cols();
427 for (
size_t j = 0; j < n_warm_up_cols; ++j) {
428 n_warm_up_.col(counter) = n_warm_up_vec[i].col(j);
432 CHECK_EQ(counter, n_warm_start_size);
435 for (
size_t i = 0; i < traj_size; ++i) {
437 uint64_t dual_l_result_ds_cols = dual_l_result_ds_vec[i].cols();
438 for (
size_t j = 0; j < dual_l_result_ds_cols; ++j) {
439 dual_l_result_ds_.col(counter) = dual_l_result_ds_vec[i].col(j);
443 CHECK_EQ(counter, l_smoothed_size);
446 for (
size_t i = 0; i < traj_size; ++i) {
448 uint64_t dual_n_result_ds_cols = dual_n_result_ds_vec[i].cols();
449 for (
size_t j = 0; j < dual_n_result_ds_cols; ++j) {
450 dual_n_result_ds_.col(counter) = dual_n_result_ds_vec[i].col(j);
454 CHECK_EQ(counter, n_smoothed_size);
456 *xWS = std::move(xWS_);
457 *uWS = std::move(uWS_);
458 *state_result_ds = std::move(state_result_ds_);
459 *control_result_ds = std::move(control_result_ds_);
460 *time_result_ds = std::move(time_result_ds_);
461 *l_warm_up = std::move(l_warm_up_);
462 *n_warm_up = std::move(n_warm_up_);
463 *dual_l_result_ds = std::move(dual_l_result_ds_);
464 *dual_n_result_ds = std::move(dual_n_result_ds_);
467bool Optimizer::GenerateDistanceApproachTraj(
468 const Eigen::MatrixXd& xWS,
const Eigen::MatrixXd& uWS,
469 const std::vector<double>& XYbounds,
470 const Eigen::MatrixXi& obstacles_edges_num,
471 const Eigen::MatrixXd& obstacles_A,
const Eigen::MatrixXd& obstacles_b,
472 const std::vector<std::vector<Vec2d>>& obstacles_vertices_vec,
473 const Eigen::MatrixXd& last_time_u,
const double init_v,
474 Eigen::MatrixXd* state_result_ds, Eigen::MatrixXd* control_result_ds,
475 Eigen::MatrixXd* time_result_ds, Eigen::MatrixXd* l_warm_up,
476 Eigen::MatrixXd* n_warm_up, Eigen::MatrixXd* dual_l_result_ds,
477 Eigen::MatrixXd* dual_n_result_ds) {
478 size_t horizon = xWS.cols() - 1;
479 Eigen::MatrixXd x0(4, 1);
480 x0 << xWS(0, 0), xWS(1, 0), xWS(2, 0), init_v;
482 Eigen::MatrixXd xF(4, 1);
483 xF << xWS(0, horizon), xWS(1, horizon), xWS(2, horizon), xWS(3, horizon);
486 const common::VehicleParam& vehicle_param_ =
489 double back_to_center = vehicle_param_.back_edge_to_center();
490 double left_to_center = vehicle_param_.left_edge_to_center();
491 double right_to_center = vehicle_param_.right_edge_to_center();
492 Eigen::MatrixXd ego(4, 1);
493 ego << front_to_center, right_to_center, back_to_center, left_to_center;
496 size_t obstacles_num = obstacles_vertices_vec.size();
499 double ts = FLAGS_open_space_delta_t;
502 Eigen::MatrixXd s_warm_up = Eigen::MatrixXd::Zero(obstacles_num, horizon + 1);
505 if (FLAGS_use_dual_variable_warm_start) {
506 if (dual_variable_warm_start_->Solve(
507 horizon, ts, ego, obstacles_num, obstacles_edges_num, obstacles_A,
508 obstacles_b, xWS, l_warm_up, n_warm_up, &s_warm_up)) {
509 ADEBUG <<
"Dual variable problem solved successfully!";
511 AERROR <<
"Dual variable problem failed to solve";
516 0.5 * Eigen::MatrixXd::Ones(obstacles_edges_num.sum(), horizon + 1);
517 *n_warm_up = 0.5 * Eigen::MatrixXd::Ones(4 * obstacles_num, horizon + 1);
521 if (distance_approach_->Solve(
522 x0, xF, last_time_u, horizon, ts, ego, xWS, uWS, *l_warm_up,
523 *n_warm_up, s_warm_up, XYbounds, obstacles_num, obstacles_edges_num,
524 obstacles_A, obstacles_b, state_result_ds, control_result_ds,
525 time_result_ds, dual_l_result_ds, dual_n_result_ds)) {
526 ADEBUG <<
"Distance approach problem solved successfully!";
528 AERROR <<
"Distance approach problem failed to solve";
529 if (FLAGS_enable_smoother_failsafe) {
530 UseWarmStartAsResult(xWS, uWS, *l_warm_up, *n_warm_up, state_result_ds,
531 control_result_ds, time_result_ds, dual_l_result_ds,
540bool Optimizer::GenerateDecoupledTraj(
541 const Eigen::MatrixXd& xWS,
const double init_a,
const double init_v,
542 const std::vector<std::vector<Vec2d>>& obstacles_vertices_vec,
543 Eigen::MatrixXd* state_result_dc, Eigen::MatrixXd* control_result_dc,
544 Eigen::MatrixXd* time_result_dc) {
545 DiscretizedTrajectory smoothed_trajectory;
546 if (!iterative_anchoring_smoother_->Smooth(
547 xWS, init_a, init_v, obstacles_vertices_vec, &smoothed_trajectory)) {
551 LoadResult(smoothed_trajectory, state_result_dc, control_result_dc,
556void Optimizer::UseWarmStartAsResult(
557 const Eigen::MatrixXd& xWS,
const Eigen::MatrixXd& uWS,
558 const Eigen::MatrixXd& l_warm_up,
const Eigen::MatrixXd& n_warm_up,
559 Eigen::MatrixXd* state_result_ds, Eigen::MatrixXd* control_result_ds,
560 Eigen::MatrixXd* time_result_ds, Eigen::MatrixXd* dual_l_result_ds,
561 Eigen::MatrixXd* dual_n_result_ds) {
562 AERROR <<
"Use warm start as trajectory output";
564 *state_result_ds = xWS;
565 *control_result_ds = uWS;
566 *dual_l_result_ds = l_warm_up;
567 *dual_n_result_ds = n_warm_up;
569 size_t time_result_horizon = xWS.cols() - 1;
570 *time_result_ds = Eigen::MatrixXd::Constant(
571 1, time_result_horizon, FLAGS_open_space_delta_t);
574void Optimizer::PartitionTrajectory(
575 const DiscretizedTrajectory& raw_trajectory,
576 std::vector<DiscretizedTrajectory>* partitioned_trajectories) {
577 size_t horizon = raw_trajectory.size();
579 partitioned_trajectories->clear();
580 partitioned_trajectories->emplace_back();
581 DiscretizedTrajectory* current_trajectory =
582 &(partitioned_trajectories->back());
585 const auto& first_path_point = raw_trajectory.front().path_point();
586 const auto& second_path_point = raw_trajectory[1].path_point();
587 double heading_angle = first_path_point.theta();
588 const Vec2d init_tracking_vector(
589 second_path_point.x() - first_path_point.x(),
590 second_path_point.y() - first_path_point.y());
591 double tracking_angle = init_tracking_vector.Angle();
596 : canbus::Chassis::GEAR_REVERSE;
599 Vec2d last_pos_vec(first_path_point.x(), first_path_point.y());
600 double distance_s = 0.0;
601 bool is_trajectory_last_point =
false;
603 for (
size_t i = 0; i < horizon - 1; ++i) {
604 current_trajectory->push_back(raw_trajectory.at(i));
605 const TrajectoryPoint& trajectory_point = raw_trajectory.at(i);
606 const TrajectoryPoint& next_trajectory_point = raw_trajectory.at(i + 1);
609 heading_angle = trajectory_point.path_point().theta();
610 const Vec2d tracking_vector(next_trajectory_point.path_point().x() -
611 trajectory_point.path_point().x(),
612 next_trajectory_point.path_point().y() -
613 trajectory_point.path_point().y());
614 tracking_angle = tracking_vector.Angle();
619 : canbus::Chassis::GEAR_REVERSE;
621 if (cur_gear != gear) {
623 partitioned_trajectories->emplace_back();
624 current_trajectory = &(partitioned_trajectories->back());
625 current_trajectory->push_back(raw_trajectory.at(i));
628 current_trajectory->push_back(raw_trajectory.back());
631void Optimizer::LoadTrajectory(
632 const Eigen::MatrixXd& state_result,
const Eigen::MatrixXd& control_result,
633 const Eigen::MatrixXd& time_result) {
634 optimized_trajectory_.clear();
638 size_t states_size = state_result.cols();
639 size_t times_size = time_result.cols();
640 size_t controls_size = control_result.cols();
641 CHECK_EQ(states_size, times_size + 1);
642 CHECK_EQ(states_size, controls_size + 1);
643 double relative_time = 0.0;
644 double relative_s = 0.0;
645 Vec2d last_path_point(state_result(0, 0), state_result(1, 0));
646 for (
size_t i = 0; i < states_size; ++i) {
647 TrajectoryPoint point;
648 point.mutable_path_point()->set_x(state_result(0, i));
649 point.mutable_path_point()->set_y(state_result(1, i));
650 point.mutable_path_point()->set_theta(state_result(2, i));
651 point.set_v(state_result(3, i));
652 Vec2d cur_path_point(state_result(0, i), state_result(1, i));
653 relative_s += cur_path_point.DistanceTo(last_path_point);
654 point.mutable_path_point()->set_s(relative_s);
656 if (i == controls_size) {
657 point.set_steer(0.0);
660 point.set_steer(control_result(0, i));
661 point.set_a(control_result(1, i));
665 point.set_relative_time(relative_time);
667 relative_time += time_result(0, i - 1);
668 point.set_relative_time(relative_time);
671 optimized_trajectory_.emplace_back(point);
672 last_path_point = cur_path_point;
676void Optimizer::LoadResult(
677 const DiscretizedTrajectory& discretized_trajectory,
678 Eigen::MatrixXd* state_result_dc, Eigen::MatrixXd* control_result_dc,
679 Eigen::MatrixXd* time_result_dc) {
680 const size_t points_size = discretized_trajectory.size();
681 CHECK_GT(points_size, 1U);
682 *state_result_dc = Eigen::MatrixXd::Zero(4, points_size);
683 *control_result_dc = Eigen::MatrixXd::Zero(2, points_size - 1);
684 *time_result_dc = Eigen::MatrixXd::Zero(1, points_size - 1);
686 auto& state_result = *state_result_dc;
687 for (
size_t i = 0; i < points_size; ++i) {
688 state_result(0, i) = discretized_trajectory[i].path_point().x();
689 state_result(1, i) = discretized_trajectory[i].path_point().y();
690 state_result(2, i) = discretized_trajectory[i].path_point().theta();
691 state_result(3, i) = discretized_trajectory[i].v();
694 auto& control_result = *control_result_dc;
695 auto& time_result = *time_result_dc;
696 const double wheel_base = common::VehicleConfigHelper::Instance()
700 for (
size_t i = 0; i + 1 < points_size; ++i) {
701 control_result(0, i) =
702 std::atan(discretized_trajectory[i].path_point().kappa() * wheel_base);
703 control_result(1, i) = discretized_trajectory[i].a();
704 time_result(0, i) = discretized_trajectory[i + 1].relative_time() -
705 discretized_trajectory[i].relative_time();
709void Optimizer::RecordDebugInfo(
710 const Vec2d& translate_origin,
const double rotate_angle,
711 const std::vector<double>& end_pose,
const Eigen::MatrixXd& xWS,
712 const Eigen::MatrixXd& uWS,
const Eigen::MatrixXd& l_warm_up,
713 const Eigen::MatrixXd& n_warm_up,
const Eigen::MatrixXd& dual_l_result_ds,
714 const Eigen::MatrixXd& dual_n_result_ds,
715 const Eigen::MatrixXd& state_result_ds,
716 const Eigen::MatrixXd& control_result_ds,
717 const Eigen::MatrixXd& time_result_ds,
718 const std::vector<double> XYbounds,
719 const std::vector<std::vector<Vec2d>>& obstacles_vertices_vec) {
721 common::TrajectoryPoint point;
722 point.mutable_path_point()->set_x(0.0);
723 point.mutable_path_point()->set_y(0.0);
724 point.mutable_path_point()->set_z(0.0);
725 point.mutable_path_point()->set_theta(0.0);
726 point.mutable_path_point()->set_s(0.0);
727 point.mutable_path_point()->set_kappa(0.0);
728 point.mutable_path_point()->set_dkappa(0.0);
729 point.mutable_path_point()->set_ddkappa(0.0);
732 point.set_relative_time(0.0);
734 open_space_debug_.mutable_trajectory_stitching_point()->CopyFrom(
738 auto roi_shift_point = open_space_debug_.mutable_roi_shift_point();
740 roi_shift_point->mutable_path_point()->set_x(translate_origin.x());
741 roi_shift_point->mutable_path_point()->set_y(translate_origin.y());
742 roi_shift_point->mutable_path_point()->set_theta(rotate_angle);
745 auto* end_point = open_space_debug_.mutable_end_point();
746 end_point->mutable_path_point()->set_x(end_pose[0]);
747 end_point->mutable_path_point()->set_y(end_pose[1]);
748 end_point->mutable_path_point()->set_theta(end_pose[2]);
749 end_point->set_v(end_pose[3]);
752 size_t horizon = xWS.cols() - 1;
753 auto* warm_start_trajectory =
754 open_space_debug_.mutable_warm_start_trajectory();
755 for (
size_t i = 0; i < horizon; ++i) {
756 auto* warm_start_point = warm_start_trajectory->add_vehicle_motion_point();
757 warm_start_point->mutable_trajectory_point()->mutable_path_point()->set_x(
759 warm_start_point->mutable_trajectory_point()->mutable_path_point()->set_y(
761 warm_start_point->mutable_trajectory_point()
762 ->mutable_path_point()
763 ->set_theta(xWS(2, i));
764 warm_start_point->mutable_trajectory_point()->set_v(xWS(3, i));
765 warm_start_point->set_steer(uWS(0, i));
766 warm_start_point->mutable_trajectory_point()->set_a(uWS(1, i));
768 auto* warm_start_point = warm_start_trajectory->add_vehicle_motion_point();
769 warm_start_point->mutable_trajectory_point()->mutable_path_point()->set_x(
771 warm_start_point->mutable_trajectory_point()->mutable_path_point()->set_y(
773 warm_start_point->mutable_trajectory_point()->mutable_path_point()->set_theta(
775 warm_start_point->mutable_trajectory_point()->set_v(xWS(3, horizon));
778 size_t l_warm_up_rows = l_warm_up.rows();
779 for (
size_t i = 0; i < horizon; ++i) {
780 for (
size_t j = 0; j < l_warm_up_rows; j++) {
781 open_space_debug_.add_warm_start_dual_lambda(l_warm_up(j, i));
784 size_t n_warm_up_rows = n_warm_up.rows();
785 for (
size_t i = 0; i < horizon; ++i) {
786 for (
size_t j = 0; j < n_warm_up_rows; j++) {
787 open_space_debug_.add_warm_start_dual_miu(n_warm_up(j, i));
792 size_t dual_l_result_ds_rows = dual_l_result_ds.rows();
793 for (
size_t i = 0; i < horizon; ++i) {
794 for (
size_t j = 0; j < dual_l_result_ds_rows; j++) {
795 open_space_debug_.add_optimized_dual_lambda(dual_l_result_ds(j, i));
798 size_t dual_n_result_ds_rows = dual_n_result_ds.rows();
799 for (
size_t i = 0; i < horizon; ++i) {
800 for (
size_t j = 0; j < dual_n_result_ds_rows; j++) {
801 open_space_debug_.add_optimized_dual_miu(dual_n_result_ds(j, i));
805 double relative_time = 0;
808 horizon = state_result_ds.cols() - 1;
809 auto* smoothed_trajectory = open_space_debug_.mutable_smoothed_trajectory();
810 for (
size_t i = 0; i < horizon; ++i) {
811 auto* smoothed_point = smoothed_trajectory->add_vehicle_motion_point();
812 smoothed_point->mutable_trajectory_point()->mutable_path_point()->set_x(
813 state_result_ds(0, i));
814 smoothed_point->mutable_trajectory_point()->mutable_path_point()->set_y(
815 state_result_ds(1, i));
816 smoothed_point->mutable_trajectory_point()->mutable_path_point()->set_theta(
817 state_result_ds(2, i));
818 smoothed_point->mutable_trajectory_point()->set_v(state_result_ds(3, i));
819 smoothed_point->set_steer(control_result_ds(0, i));
820 smoothed_point->mutable_trajectory_point()->set_a(control_result_ds(1, i));
821 relative_time += time_result_ds(0, i);
822 smoothed_point->mutable_trajectory_point()->set_relative_time(
825 auto* smoothed_point = smoothed_trajectory->add_vehicle_motion_point();
826 smoothed_point->mutable_trajectory_point()->mutable_path_point()->set_x(
827 state_result_ds(0, horizon));
828 smoothed_point->mutable_trajectory_point()->mutable_path_point()->set_y(
829 state_result_ds(1, horizon));
830 smoothed_point->mutable_trajectory_point()->mutable_path_point()->set_theta(
831 state_result_ds(2, horizon));
832 smoothed_point->mutable_trajectory_point()->set_v(
833 state_result_ds(3, horizon));
836 open_space_debug_.add_xy_boundary(XYbounds[0]);
837 open_space_debug_.add_xy_boundary(XYbounds[1]);
838 open_space_debug_.add_xy_boundary(XYbounds[2]);
839 open_space_debug_.add_xy_boundary(XYbounds[3]);
842 for (
const auto& obstacle_vertices : obstacles_vertices_vec) {
843 auto* obstacle_ptr = open_space_debug_.add_obstacles();
844 for (
const auto& vertex : obstacle_vertices) {
845 obstacle_ptr->add_vertices_x_coords(vertex.x());
846 obstacle_ptr->add_vertices_y_coords(vertex.y());
853 open_space_debug->MergeFrom(open_space_debug_);
A general class to denote the return status of an API call.
static Status OK()
generate a success status.
static const VehicleConfig & GetConfig()
Get the current vehicle configuration.
Implements a class of 2-dimensional vectors.
const std::vector< double > & ROI_xy_boundary() const
const std::vector< double > & open_space_end_pose() const
const common::math::Vec2d & origin_point() const
double origin_heading() const
const Eigen::MatrixXd & obstacles_A() const
const std::vector< std::vector< common::math::Vec2d > > & obstacles_vertices_vec() const
const Eigen::MatrixXd & obstacles_b() const
const Eigen::MatrixXi & obstacles_edges_num() const
const DiscretizedTrajectory & path_planning_trajectory_result() const
static void PathPointNormalizing(double rotate_angle, const common::math::Vec2d &translate_origin, double *x, double *y, double *phi)
static void PathPointDeNormalizing(double rotate_angle, const common::math::Vec2d &translate_origin, double *x, double *y, double *phi)
void UpdateDebugInfo(planning_internal::OpenSpaceDebug *open_space_debug)
Optimizer(const OpenSpaceTrajectoryOptimizerParkConfig &config)
common::Status Plan(const OpenSpaceInfo open_space_info)
Planning module main class.
double NormalizeAngle(const double angle)
Normalize angle to [-PI, PI).
optional VehicleParam vehicle_param
optional double front_edge_to_center
optional IterativeAnchoringConfig iterative_anchoring_smoother_config
optional DistanceApproachConfig distance_approach_config
optional DualVariableWarmStartConfig dual_variable_warm_start_config