Apollo 10.0
自动驾驶开放平台
open_space_trajectory_partition.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2019 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
22#include <algorithm>
23#include <memory>
24#include <queue>
25
26#include "absl/strings/str_cat.h"
27
28#include "cyber/time/clock.h"
32
33namespace apollo {
34namespace planning {
35
45
47 const std::string& config_dir, const std::string& name,
48 const std::shared_ptr<DependencyInjector>& injector) {
49 if (!Task::Init(config_dir, name, injector)) {
50 return false;
51 }
52 // Load the config this task.
53 bool res = Task::LoadConfig<OpenSpaceTrajectoryPartitionConfig>(&config_);
54 heading_search_range_ = config_.heading_search_range();
55 heading_track_range_ = config_.heading_track_range();
56 distance_search_range_ = config_.distance_search_range();
57 heading_offset_to_midpoint_ = config_.heading_offset_to_midpoint();
58 lateral_offset_to_midpoint_ = config_.lateral_offset_to_midpoint();
59 longitudinal_offset_to_midpoint_ = config_.longitudinal_offset_to_midpoint();
60 vehicle_box_iou_threshold_to_midpoint_ =
62 linear_velocity_threshold_on_ego_ =
64 vehicle_param_ =
65 common::VehicleConfigHelper::Instance()->GetConfig().vehicle_param();
66 ego_length_ = vehicle_param_.length();
67 ego_width_ = vehicle_param_.width();
68 shift_distance_ = ego_length_ / 2.0 - vehicle_param_.back_edge_to_center();
69 wheel_base_ = vehicle_param_.wheel_base();
70 AINFO << config_.DebugString();
71 return res;
72}
73
75 auto* current_gear_status =
77 current_gear_status->gear_switching_flag = false;
78 current_gear_status->gear_shift_period_finished = true;
79 current_gear_status->gear_shift_period_started = true;
80 current_gear_status->gear_shift_period_time = 0.0;
81 current_gear_status->gear_shift_start_time = 0.0;
82 current_gear_status->gear_shift_position = canbus::Chassis::GEAR_DRIVE;
83}
84
85Status OpenSpaceTrajectoryPartition::Process() {
86 const auto& open_space_info = frame_->open_space_info();
87 auto open_space_info_ptr = frame_->mutable_open_space_info();
88 const auto& stitched_trajectory_result =
89 open_space_info.stitched_trajectory_result();
90
91 auto* interpolated_trajectory_result_ptr =
92 open_space_info_ptr->mutable_interpolated_trajectory_result();
93
94 InterpolateTrajectory(stitched_trajectory_result,
95 interpolated_trajectory_result_ptr);
96
97 auto* partitioned_trajectories =
98 open_space_info_ptr->mutable_partitioned_trajectories();
99
100 PartitionTrajectory(*interpolated_trajectory_result_ptr,
101 partitioned_trajectories);
102
103 const auto& open_space_status =
104 injector_->planning_context()->planning_status().open_space();
105 if (!open_space_status.position_init() &&
107 auto* open_space_status = injector_->planning_context()
108 ->mutable_planning_status()
109 ->mutable_open_space();
110 open_space_status->set_position_init(true);
111 auto* chosen_partitioned_trajectory =
112 open_space_info_ptr->mutable_chosen_partitioned_trajectory();
113 auto* mutable_trajectory =
114 open_space_info_ptr->mutable_stitched_trajectory_result();
115 AdjustRelativeTimeAndS(open_space_info.partitioned_trajectories(), 0, 0,
116 mutable_trajectory, chosen_partitioned_trajectory);
117 current_trajectory_index_ = 0;
118 fail_search_fallback_ = false;
119 last_index_ = -1;
120 return Status::OK();
121 }
122
123 // Choose the one to follow based on the closest partitioned trajectory
124 size_t trajectories_size = partitioned_trajectories->size();
125 // may get stop trajecotry;
126 current_trajectory_index_ =
127 std::min<size_t>(trajectories_size - 1, current_trajectory_index_);
128 size_t current_trajectory_point_index = 0;
129 bool flag_change_to_next = false;
130
131 // Vehicle related information used to choose closest point
132 UpdateVehicleInfo();
133
134 const auto& gear =
135 partitioned_trajectories->at(current_trajectory_index_).second;
136 const auto& cur_trajectory =
137 partitioned_trajectories->at(current_trajectory_index_).first;
138 size_t trajectory_size = cur_trajectory.size();
139 CHECK_GT(trajectory_size, 0U);
140 flag_change_to_next = CheckReachTrajectoryEnd(
141 cur_trajectory, gear, trajectories_size, &current_trajectory_point_index);
142 AINFO << "current_trajectory_index_" << current_trajectory_index_ << ","
143 << current_trajectory_point_index << "time index" << last_index_
144 << "flag_change_to_next" << flag_change_to_next;
145 auto* chosen_partitioned_trajectory =
146 open_space_info_ptr->mutable_chosen_partitioned_trajectory();
147
148 auto chosen_trajectory = &(chosen_partitioned_trajectory->first);
149 if (config_.use_gear_shift_trajectory()) {
150 if (InsertGearShiftTrajectory(flag_change_to_next,
151 current_trajectory_index_,
152 open_space_info.partitioned_trajectories(),
153 chosen_partitioned_trajectory) &&
154 chosen_partitioned_trajectory->first.size() != 0) {
155 chosen_trajectory = &(chosen_partitioned_trajectory->first);
156 ADEBUG << "After InsertGearShiftTrajectory [" << chosen_trajectory->size()
157 << "]";
158 last_index_ = -1;
159 return Status::OK();
160 }
161 }
162 // Choose the closest point to track
163 std::priority_queue<std::pair<size_t, double>,
164 std::vector<std::pair<size_t, double>>, comp_>
165 closest_point;
166 AINFO << "ego:" << std::fixed << ego_x_ << "," << ego_y_ << ","
167 << vehicle_moving_direction_;
168 for (size_t j = 0; j < trajectory_size; ++j) {
169 const TrajectoryPoint& trajectory_point = cur_trajectory.at(j);
170 const PathPoint& path_point = trajectory_point.path_point();
171 const double path_point_x = path_point.x();
172 const double path_point_y = path_point.y();
173 const double path_point_theta = path_point.theta();
174 const Vec2d tracking_vector(path_point_x - ego_x_, path_point_y - ego_y_);
175 const double distance = tracking_vector.Length();
176 // const double tracking_direction = tracking_vector.Angle();
177 const double traj_point_moving_direction =
179 ? NormalizeAngle(path_point_theta + M_PI)
180 : path_point_theta;
181 // const double head_track_difference = std::abs(
182 // NormalizeAngle(tracking_direction - vehicle_moving_direction_));
183 const double heading_search_difference = std::abs(NormalizeAngle(
184 traj_point_moving_direction - vehicle_moving_direction_));
185 // AINFO << "XY" << std::fixed << path_point_x << "," << path_point_y << ","
186 // << path_point_theta << "," << distance << ","
187 // << heading_search_difference << "ego heading"
188 // << vehicle_moving_direction_;
189 if (distance < distance_search_range_ &&
190 heading_search_difference < heading_search_range_) {
191 // get vehicle box and path point box, compute IOU
192 Box2d path_point_box({path_point_x, path_point_y}, path_point_theta,
193 ego_length_, ego_width_);
194 Vec2d shift_vec{shift_distance_ * std::cos(path_point_theta),
195 shift_distance_ * std::sin(path_point_theta)};
196 path_point_box.Shift(shift_vec);
197 double iou_ratio =
198 Polygon2d(ego_box_).ComputeIoU(Polygon2d(path_point_box));
199 closest_point.emplace(j, iou_ratio);
200 }
201 }
202
203 if (closest_point.empty() || fail_search_fallback_) {
204 fail_search_fallback_ = true;
206 auto fallback_tra_pair =
208 GenerateStopTrajectory(&fallback_tra_pair->first, -4.0);
209 fallback_tra_pair->second = frame_->local_view().chassis->gear_location();
210 const std::string msg =
211 "Fail to find nearest trajectory point to follow stop to fallback "
212 "replan";
213 AERROR << msg;
214 return Status::OK();
215 }
216 current_trajectory_point_index = closest_point.top().first;
217 if (!flag_change_to_next) {
218 double veh_rel_time;
219 size_t time_match_index;
220 double now_time = Clock::Instance()->NowInSeconds();
221 auto& traj = partitioned_trajectories->at(current_trajectory_index_).first;
222 if (last_index_ != -1) {
223 veh_rel_time = traj[last_index_].relative_time() + now_time - last_time_;
224 AINFO << std::fixed << now_time << "," << last_time_;
225 time_match_index = traj.QueryLowerBoundPoint(veh_rel_time);
226 } else {
227 time_match_index = current_trajectory_point_index;
228 last_index_ = time_match_index;
229 last_time_ = now_time;
230 }
231
232 AINFO << "time_match_index" << time_match_index << "pos match index"
233 << current_trajectory_point_index;
234 AINFO << "TRAJ CLOSEST" << std::fixed
235 << traj.at(current_trajectory_point_index).path_point().x() << ","
236 << traj.at(current_trajectory_point_index).path_point().y();
237 if (std::abs(traj[time_match_index].path_point().s() -
238 traj.at(current_trajectory_point_index).path_point().s()) <
239 config_.speed_replan_distance()) {
240 current_trajectory_point_index = time_match_index;
241 } else {
242 AINFO << "reset speed because matched point too far";
243 last_index_ = current_trajectory_point_index;
244 last_time_ = now_time;
245 }
246 } else {
247 last_index_ = -1;
248 }
249 auto* mutable_trajectory =
250 open_space_info_ptr->mutable_stitched_trajectory_result();
251 AdjustRelativeTimeAndS(open_space_info.partitioned_trajectories(),
252 current_trajectory_index_,
253 current_trajectory_point_index, mutable_trajectory,
254 chosen_partitioned_trajectory);
255 return Status::OK();
256}
257
258void OpenSpaceTrajectoryPartition::InterpolateTrajectory(
259 const DiscretizedTrajectory& stitched_trajectory_result,
260 DiscretizedTrajectory* interpolated_trajectory) {
261 if (FLAGS_use_iterative_anchoring_smoother) {
262 *interpolated_trajectory = stitched_trajectory_result;
263 return;
264 }
265 interpolated_trajectory->clear();
266 size_t interpolated_pieces_num = config_.interpolated_pieces_num();
267 CHECK_GT(stitched_trajectory_result.size(), 0U);
268 CHECK_GT(interpolated_pieces_num, 0U);
269 size_t trajectory_to_be_partitioned_intervals_num =
270 stitched_trajectory_result.size() - 1;
271 size_t interpolated_points_num = interpolated_pieces_num - 1;
272 for (size_t i = 0; i < trajectory_to_be_partitioned_intervals_num; ++i) {
273 double relative_time_interval =
274 (stitched_trajectory_result.at(i + 1).relative_time() -
275 stitched_trajectory_result.at(i).relative_time()) /
276 static_cast<double>(interpolated_pieces_num);
277 interpolated_trajectory->push_back(stitched_trajectory_result.at(i));
278 for (size_t j = 0; j < interpolated_points_num; ++j) {
279 double relative_time =
280 stitched_trajectory_result.at(i).relative_time() +
281 (static_cast<double>(j) + 1.0) * relative_time_interval;
282 interpolated_trajectory->emplace_back(
284 stitched_trajectory_result.at(i),
285 stitched_trajectory_result.at(i + 1), relative_time));
286 }
287 }
288 interpolated_trajectory->push_back(stitched_trajectory_result.back());
289}
290
291void OpenSpaceTrajectoryPartition::UpdateVehicleInfo() {
292 const common::VehicleState& vehicle_state = frame_->vehicle_state();
293 ego_theta_ = vehicle_state.heading();
294 ego_x_ = vehicle_state.x();
295 ego_y_ = vehicle_state.y();
296 ego_v_ = vehicle_state.linear_velocity();
297 ego_gear_ = vehicle_state.gear();
298 Box2d box({ego_x_, ego_y_}, ego_theta_, ego_length_, ego_width_);
299 ego_box_ = std::move(box);
300 Vec2d ego_shift_vec{shift_distance_ * std::cos(ego_theta_),
301 shift_distance_ * std::sin(ego_theta_)};
302 ego_box_.Shift(ego_shift_vec);
303 vehicle_moving_direction_ =
304 vehicle_state.gear() == canbus::Chassis::GEAR_REVERSE
305 ? NormalizeAngle(ego_theta_ + M_PI)
306 : ego_theta_;
307}
308
309bool OpenSpaceTrajectoryPartition::EncodeTrajectory(
310 const DiscretizedTrajectory& trajectory, std::string* const encoding) {
311 if (trajectory.empty()) {
312 AERROR << "Fail to encode trajectory because it is empty";
313 return false;
314 }
315 static constexpr double encoding_origin_x = 58700.0;
316 static constexpr double encoding_origin_y = 4141000.0;
317 const auto& init_path_point = trajectory.front().path_point();
318 const auto& last_path_point = trajectory.back().path_point();
319
320 const int init_point_x =
321 static_cast<int>((init_path_point.x() - encoding_origin_x) * 1000.0);
322 const int init_point_y =
323 static_cast<int>((init_path_point.y() - encoding_origin_y) * 1000.0);
324 const int init_point_heading =
325 static_cast<int>(init_path_point.theta() * 10000.0);
326 const int last_point_x =
327 static_cast<int>((last_path_point.x() - encoding_origin_x) * 1000.0);
328 const int last_point_y =
329 static_cast<int>((last_path_point.y() - encoding_origin_y) * 1000.0);
330 const int last_point_heading =
331 static_cast<int>(last_path_point.theta() * 10000.0);
332
333 *encoding = absl::StrCat(
334 // init point
335 init_point_x, "_", init_point_y, "_", init_point_heading, "/",
336 // last point
337 last_point_x, "_", last_point_y, "_", last_point_heading);
338 return true;
339}
340
341bool OpenSpaceTrajectoryPartition::CheckTrajTraversed(
342 const std::string& trajectory_encoding_to_check) {
343 const auto& open_space_status =
344 injector_->planning_context()->planning_status().open_space();
345 const int index_history_size =
346 open_space_status.partitioned_trajectories_index_history_size();
347
348 if (index_history_size <= 1) {
349 return false;
350 }
351 for (int i = 0; i < index_history_size - 1; i++) {
352 const auto& index_history =
353 open_space_status.partitioned_trajectories_index_history(i);
354 if (index_history == trajectory_encoding_to_check) {
355 return true;
356 }
357 }
358 return false;
359}
360
361void OpenSpaceTrajectoryPartition::UpdateTrajHistory(
362 const std::string& chosen_trajectory_encoding) {
363 auto* open_space_status = injector_->planning_context()
364 ->mutable_planning_status()
365 ->mutable_open_space();
366
367 const auto& trajectory_history =
368 injector_->planning_context()
369 ->planning_status()
370 .open_space()
371 .partitioned_trajectories_index_history();
372 if (trajectory_history.empty()) {
373 open_space_status->add_partitioned_trajectories_index_history(
374 chosen_trajectory_encoding);
375 return;
376 }
377 if (*(trajectory_history.rbegin()) == chosen_trajectory_encoding) {
378 return;
379 }
380 open_space_status->add_partitioned_trajectories_index_history(
381 chosen_trajectory_encoding);
382}
383
384void OpenSpaceTrajectoryPartition::PartitionTrajectory(
385 const DiscretizedTrajectory& raw_trajectory,
386 std::vector<TrajGearPair>* partitioned_trajectories) {
387 CHECK_NOTNULL(partitioned_trajectories);
388
389 size_t horizon = raw_trajectory.size();
390
391 partitioned_trajectories->clear();
392 partitioned_trajectories->emplace_back();
393 TrajGearPair* current_trajectory_gear = &(partitioned_trajectories->back());
394
395 auto* trajectory = &(current_trajectory_gear->first);
396 auto* gear = &(current_trajectory_gear->second);
397
398 // Decide initial gear
399 const auto& first_path_point = raw_trajectory.front().path_point();
400 const auto& second_path_point = raw_trajectory[1].path_point();
401 double heading_angle = first_path_point.theta();
402 const Vec2d init_tracking_vector(
403 second_path_point.x() - first_path_point.x(),
404 second_path_point.y() - first_path_point.y());
405 double tracking_angle = init_tracking_vector.Angle();
406 *gear =
407 std::abs(common::math::NormalizeAngle(tracking_angle - heading_angle)) <
408 (M_PI_2)
410 : canbus::Chassis::GEAR_REVERSE;
411
412 // Set accumulated distance
413 Vec2d last_pos_vec(first_path_point.x(), first_path_point.y());
414 double distance_s = 0.0;
415 bool is_trajectory_last_point = false;
416
417 for (size_t i = 0; i < horizon - 1; ++i) {
418 const TrajectoryPoint& trajectory_point = raw_trajectory.at(i);
419 const TrajectoryPoint& next_trajectory_point = raw_trajectory.at(i + 1);
420
421 // Check gear change
422 heading_angle = trajectory_point.path_point().theta();
423 const Vec2d tracking_vector(next_trajectory_point.path_point().x() -
424 trajectory_point.path_point().x(),
425 next_trajectory_point.path_point().y() -
426 trajectory_point.path_point().y());
427 tracking_angle = tracking_vector.Angle();
428 auto cur_gear =
429 std::abs(common::math::NormalizeAngle(tracking_angle - heading_angle)) <
430 (M_PI_2)
432 : canbus::Chassis::GEAR_REVERSE;
433
434 if (cur_gear != *gear) {
435 is_trajectory_last_point = true;
436 LoadTrajectoryPoint(trajectory_point, is_trajectory_last_point, *gear,
437 &last_pos_vec, &distance_s, trajectory);
438 partitioned_trajectories->emplace_back();
439 current_trajectory_gear = &(partitioned_trajectories->back());
440 current_trajectory_gear->second = cur_gear;
441 distance_s = 0.0;
442 is_trajectory_last_point = false;
443 }
444
445 trajectory = &(current_trajectory_gear->first);
446 gear = &(current_trajectory_gear->second);
447
448 LoadTrajectoryPoint(trajectory_point, is_trajectory_last_point, *gear,
449 &last_pos_vec, &distance_s, trajectory);
450 }
451 is_trajectory_last_point = true;
452 const TrajectoryPoint& last_trajectory_point = raw_trajectory.back();
453 LoadTrajectoryPoint(last_trajectory_point, is_trajectory_last_point, *gear,
454 &last_pos_vec, &distance_s, trajectory);
455}
456
457void OpenSpaceTrajectoryPartition::LoadTrajectoryPoint(
458 const TrajectoryPoint& trajectory_point,
459 const bool is_trajectory_last_point,
460 const canbus::Chassis::GearPosition& gear, Vec2d* last_pos_vec,
461 double* distance_s, DiscretizedTrajectory* current_trajectory) {
462 current_trajectory->emplace_back();
463 TrajectoryPoint* point = &(current_trajectory->back());
464 point->set_relative_time(trajectory_point.relative_time());
465 point->mutable_path_point()->set_x(trajectory_point.path_point().x());
466 point->mutable_path_point()->set_y(trajectory_point.path_point().y());
467 point->mutable_path_point()->set_theta(trajectory_point.path_point().theta());
468 point->set_v(trajectory_point.v());
469 point->mutable_path_point()->set_s(*distance_s);
470 Vec2d cur_pos_vec(trajectory_point.path_point().x(),
471 trajectory_point.path_point().y());
472 *distance_s += (gear == canbus::Chassis::GEAR_REVERSE ? -1.0 : 1.0) *
473 (cur_pos_vec.DistanceTo(*last_pos_vec));
474 *last_pos_vec = cur_pos_vec;
475 point->mutable_path_point()->set_kappa((is_trajectory_last_point ? -1 : 1) *
476 std::tan(trajectory_point.steer()) /
477 wheel_base_);
478 point->set_a(trajectory_point.a());
479}
480
481bool OpenSpaceTrajectoryPartition::CheckReachTrajectoryEnd(
482 const DiscretizedTrajectory& trajectory,
483 const canbus::Chassis::GearPosition& gear, const size_t trajectories_size,
484 size_t* current_trajectory_point_index) {
485 // Check if have reached endpoint of trajectory
486 const TrajectoryPoint& trajectory_end_point = trajectory.back();
487 const size_t trajectory_size = trajectory.size();
488 const PathPoint& path_end_point = trajectory_end_point.path_point();
489 const double path_end_point_x = path_end_point.x();
490 const double path_end_point_y = path_end_point.y();
491 const Vec2d tracking_vector(ego_x_ - path_end_point_x,
492 ego_y_ - path_end_point_y);
493 const double path_end_point_theta = path_end_point.theta();
494 const double included_angle =
495 NormalizeAngle(path_end_point_theta - tracking_vector.Angle());
496 const double distance_to_trajs_end =
497 std::sqrt((path_end_point_x - ego_x_) * (path_end_point_x - ego_x_) +
498 (path_end_point_y - ego_y_) * (path_end_point_y - ego_y_));
499 const double lateral_offset =
500 std::abs(distance_to_trajs_end * std::sin(included_angle));
501 const double longitudinal_offset =
502 std::abs(distance_to_trajs_end * std::cos(included_angle));
503 const double traj_end_point_moving_direction =
505 ? NormalizeAngle(path_end_point_theta + M_PI)
506 : path_end_point_theta;
507
508 const double heading_search_to_trajs_end = std::abs(NormalizeAngle(
509 traj_end_point_moving_direction - vehicle_moving_direction_));
510
511 // If close to the end point, start on the next trajectory
512 double end_point_iou_ratio = 0.0;
513 if (lateral_offset < lateral_offset_to_midpoint_ &&
514 longitudinal_offset < longitudinal_offset_to_midpoint_ &&
515 heading_search_to_trajs_end < heading_offset_to_midpoint_ &&
516 std::abs(ego_v_) < linear_velocity_threshold_on_ego_) {
517 // get vehicle box and path point box, compare with a threadhold in IOU
518 Box2d path_end_point_box({path_end_point_x, path_end_point_y},
519 path_end_point_theta, ego_length_, ego_width_);
520 Vec2d shift_vec{shift_distance_ * std::cos(path_end_point_theta),
521 shift_distance_ * std::sin(path_end_point_theta)};
522 path_end_point_box.Shift(shift_vec);
523 end_point_iou_ratio =
524 Polygon2d(ego_box_).ComputeIoU(Polygon2d(path_end_point_box));
525
526 if (end_point_iou_ratio > vehicle_box_iou_threshold_to_midpoint_) {
527 if (current_trajectory_index_ + 1 >= trajectories_size) {
528 current_trajectory_index_ = trajectories_size - 1;
529 *current_trajectory_point_index = trajectory_size - 1;
530 } else {
531 current_trajectory_index_ += 1;
532 *current_trajectory_point_index = 0;
533 }
534 AINFO << "Reach the end of a trajectory, switching to next one";
535 return true;
536 }
537 }
538
539 AINFO << "Vehicle did not reach end of a trajectory with conditions for "
540 "lateral distance_check: "
541 << (lateral_offset < lateral_offset_to_midpoint_)
542 << " and actual lateral distance: " << lateral_offset
543 << "; longitudinal distance_check: "
544 << (longitudinal_offset < longitudinal_offset_to_midpoint_)
545 << " and actual longitudinal distance: " << longitudinal_offset
546 << "; heading_check: "
547 << (heading_search_to_trajs_end < heading_offset_to_midpoint_)
548 << " with actual heading: " << heading_search_to_trajs_end
549 << "; velocity_check: "
550 << (std::abs(ego_v_) < linear_velocity_threshold_on_ego_)
551 << " with actual linear velocity: " << ego_v_ << "; iou_check: "
552 << (end_point_iou_ratio > vehicle_box_iou_threshold_to_midpoint_)
553 << " with actual iou: " << end_point_iou_ratio;
554 return false;
555}
556
557bool OpenSpaceTrajectoryPartition::UseFailSafeSearch(
558 const std::vector<TrajGearPair>& partitioned_trajectories,
559 const std::vector<std::string>& trajectories_encodings,
560 size_t* current_trajectory_index, size_t* current_trajectory_point_index) {
561 AERROR << "Trajectory partition fail, using failsafe search";
562 const size_t trajectories_size = partitioned_trajectories.size();
563 std::priority_queue<std::pair<std::pair<size_t, size_t>, double>,
564 std::vector<std::pair<std::pair<size_t, size_t>, double>>,
565 pair_comp_>
566 failsafe_closest_point_on_trajs;
567 for (size_t i = 0; i < trajectories_size; ++i) {
568 const auto& trajectory = partitioned_trajectories.at(i).first;
569 size_t trajectory_size = trajectory.size();
570 CHECK_GT(trajectory_size, 0U);
571 std::priority_queue<std::pair<size_t, double>,
572 std::vector<std::pair<size_t, double>>, comp_>
573 failsafe_closest_point;
574
575 for (size_t j = 0; j < trajectory_size; ++j) {
576 const TrajectoryPoint& trajectory_point = trajectory.at(j);
577 const PathPoint& path_point = trajectory_point.path_point();
578 const double path_point_x = path_point.x();
579 const double path_point_y = path_point.y();
580 const double path_point_theta = path_point.theta();
581 const Vec2d tracking_vector(path_point_x - ego_x_, path_point_y - ego_y_);
582 const double distance = tracking_vector.Length();
583 if (distance < distance_search_range_) {
584 // get vehicle box and path point box, compute IOU
585 Box2d path_point_box({path_point_x, path_point_y}, path_point_theta,
586 ego_length_, ego_width_);
587 Vec2d shift_vec{shift_distance_ * std::cos(path_point_theta),
588 shift_distance_ * std::sin(path_point_theta)};
589 path_point_box.Shift(shift_vec);
590 double iou_ratio =
591 Polygon2d(ego_box_).ComputeIoU(Polygon2d(path_point_box));
592 failsafe_closest_point.emplace(j, iou_ratio);
593 }
594 }
595 if (!failsafe_closest_point.empty()) {
596 size_t closest_point_index = failsafe_closest_point.top().first;
597 double max_iou_ratio = failsafe_closest_point.top().second;
598 failsafe_closest_point_on_trajs.emplace(
599 std::make_pair(i, closest_point_index), max_iou_ratio);
600 }
601 }
602 if (failsafe_closest_point_on_trajs.empty()) {
603 return false;
604 } else {
605 bool closest_and_not_repeated_traj_found = false;
606 while (!failsafe_closest_point_on_trajs.empty()) {
607 *current_trajectory_index =
608 failsafe_closest_point_on_trajs.top().first.first;
609 *current_trajectory_point_index =
610 failsafe_closest_point_on_trajs.top().first.second;
611 if (CheckTrajTraversed(
612 trajectories_encodings[*current_trajectory_index])) {
613 failsafe_closest_point_on_trajs.pop();
614 } else {
615 closest_and_not_repeated_traj_found = true;
616 UpdateTrajHistory(trajectories_encodings[*current_trajectory_index]);
617 return true;
618 }
619 }
620 if (!closest_and_not_repeated_traj_found) {
621 return false;
622 }
623
624 return true;
625 }
626}
627
628bool OpenSpaceTrajectoryPartition::InsertGearShiftTrajectory(
629 const bool flag_change_to_next, const size_t current_trajectory_index,
630 const std::vector<TrajGearPair>& partitioned_trajectories,
631 TrajGearPair* gear_switch_idle_time_trajectory) {
632 const auto* last_frame = injector_->frame_history()->Latest();
633 auto* current_gear_status =
635 if (last_frame) {
636 const auto& last_gear_status =
637 last_frame->open_space_info().gear_switch_states();
638 *(current_gear_status) = last_gear_status;
639 } else {
640 AERROR << "Lost last frame";
641 }
642 const auto& curr_gear =
643 partitioned_trajectories.at(current_trajectory_index).second;
644 if (flag_change_to_next || !current_gear_status->gear_shift_period_finished ||
645 curr_gear != ego_gear_) {
646 current_gear_status->gear_shift_period_finished = false;
647 if (current_gear_status->gear_shift_period_started) {
648 current_gear_status->gear_shift_start_time =
649 Clock::Instance()->NowInSeconds();
650 current_gear_status->gear_shift_position =
651 partitioned_trajectories.at(current_trajectory_index).second;
652 current_gear_status->gear_shift_period_started = false;
653 current_gear_status->gear_shift_period_time = 0.0;
654 }
655 if (current_gear_status->gear_shift_period_time >
656 config_.gear_shift_period_duration() &&
657 current_gear_status->gear_shift_position == ego_gear_) {
658 current_gear_status->gear_shift_period_finished = true;
659 current_gear_status->gear_shift_period_started = true;
660 AINFO << "finished gear shift";
661 } else {
662 double init_kappa = partitioned_trajectories.at(current_trajectory_index)
663 .first[0]
664 .path_point()
665 .kappa();
666 GenerateGearShiftTrajectory(current_gear_status->gear_shift_position,
667 init_kappa, gear_switch_idle_time_trajectory);
668 current_gear_status->gear_shift_period_time =
669 Clock::Instance()->NowInSeconds() -
670 current_gear_status->gear_shift_start_time;
671 return true;
672 }
673 }
674
675 return true;
676}
677
678void OpenSpaceTrajectoryPartition::GenerateGearShiftTrajectory(
679 const canbus::Chassis::GearPosition& gear_position, double init_kappa,
680 TrajGearPair* gear_switch_idle_time_trajectory) {
681 gear_switch_idle_time_trajectory->first.clear();
682 const double gear_shift_max_t = config_.gear_shift_max_t();
683 const double gear_shift_unit_t = config_.gear_shift_unit_t();
684 // TrajectoryPoint point;
685 for (double t = 0.0; t < gear_shift_max_t; t += gear_shift_unit_t) {
686 TrajectoryPoint point;
687 point.mutable_path_point()->set_x(frame_->vehicle_state().x());
688 point.mutable_path_point()->set_y(frame_->vehicle_state().y());
689 point.mutable_path_point()->set_theta(frame_->vehicle_state().heading());
690 point.mutable_path_point()->set_s(0.0);
691 point.mutable_path_point()->set_kappa(init_kappa);
692 point.set_relative_time(t);
693 point.set_v(0.0);
694 point.set_a(0.0);
695 gear_switch_idle_time_trajectory->first.emplace_back(point);
696 }
697 ADEBUG << "gear_switch_idle_time_trajectory"
698 << gear_switch_idle_time_trajectory->first.size();
699 gear_switch_idle_time_trajectory->second = gear_position;
700}
701
702void OpenSpaceTrajectoryPartition::GenerateStopTrajectory(
703 DiscretizedTrajectory* const trajectory_data,
704 double standstill_acceleration) {
705 double relative_time = 0.0;
706 // TODO(Jinyun) Move to conf
707 static constexpr int stop_trajectory_length = 10;
708 static constexpr double relative_stop_time = 0.1;
709 trajectory_data->clear();
710 static constexpr double vEpsilon = 0.00001;
711 standstill_acceleration =
712 frame_->vehicle_state().linear_velocity() >= -vEpsilon
713 ? standstill_acceleration
714 : -1.0 * standstill_acceleration;
715 for (size_t i = 0; i < stop_trajectory_length; i++) {
716 TrajectoryPoint point;
717 point.mutable_path_point()->set_x(frame_->vehicle_state().x());
718 point.mutable_path_point()->set_y(frame_->vehicle_state().y());
719 point.mutable_path_point()->set_theta(frame_->vehicle_state().heading());
720 point.mutable_path_point()->set_s(0.0);
721 point.mutable_path_point()->set_kappa(0.0);
722 point.set_relative_time(relative_time);
723 point.set_v(0.0);
724 point.set_a(standstill_acceleration);
725 trajectory_data->emplace_back(point);
726 relative_time += relative_stop_time;
727 }
728}
729
730void OpenSpaceTrajectoryPartition::AdjustRelativeTimeAndS(
731 const std::vector<TrajGearPair>& partitioned_trajectories,
732 const size_t current_trajectory_index,
733 const size_t closest_trajectory_point_index,
734 DiscretizedTrajectory* unpartitioned_trajectory_result,
735 TrajGearPair* current_partitioned_trajectory) {
736 const size_t partitioned_trajectories_size = partitioned_trajectories.size();
737 CHECK_GT(partitioned_trajectories_size, current_trajectory_index);
738
739 // Reassign relative time and relative s to have the closest point as origin
740 // point
741 *(current_partitioned_trajectory) =
742 partitioned_trajectories.at(current_trajectory_index);
743 auto trajectory = &(current_partitioned_trajectory->first);
744 double time_shift =
745 trajectory->at(closest_trajectory_point_index).relative_time();
746 double s_shift =
747 trajectory->at(closest_trajectory_point_index).path_point().s();
748 const size_t trajectory_size = trajectory->size();
749 for (size_t i = 0; i < trajectory_size; ++i) {
750 TrajectoryPoint* trajectory_point = &(trajectory->at(i));
751 trajectory_point->set_relative_time(trajectory_point->relative_time() -
752 time_shift);
753 trajectory_point->mutable_path_point()->set_s(
754 trajectory_point->path_point().s() - s_shift);
755 }
756
757 // Reassign relative t and s on stitched_trajectory_result for accurate next
758 // frame stitching
759 // size_t interpolated_pieces_num =
760 // config_.interpolated_pieces_num();
761 // if (FLAGS_use_iterative_anchoring_smoother) {
762 // interpolated_pieces_num = 1;
763 // }
764 const size_t unpartitioned_trajectory_size =
765 unpartitioned_trajectory_result->size();
766 // size_t index_estimate = 0;
767 // for (size_t i = 0; i < current_trajectory_index; ++i) {
768 // index_estimate += partitioned_trajectories.at(i).first.size();
769 // }
770 // index_estimate += closest_trajectory_point_index;
771 // index_estimate /= interpolated_pieces_num;
772 // if (index_estimate >= unpartitioned_trajectory_size) {
773 // index_estimate = unpartitioned_trajectory_size - 1;
774 // }
775 // time_shift =
776 // unpartitioned_trajectory_result->at(index_estimate).relative_time();
777 // s_shift =
778 // unpartitioned_trajectory_result->at(index_estimate).path_point().s();
779 for (size_t i = 0; i < unpartitioned_trajectory_size; ++i) {
780 TrajectoryPoint* trajectory_point =
781 &(unpartitioned_trajectory_result->at(i));
782 trajectory_point->set_relative_time(trajectory_point->relative_time() -
783 time_shift);
784 trajectory_point->mutable_path_point()->set_s(
785 trajectory_point->path_point().s() - s_shift);
786 }
787}
788
789} // namespace planning
790} // 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
Rectangular (undirected) bounding box in 2-D.
Definition box2d.h:52
The class of polygon in 2-D.
Definition polygon2d.h:42
Implements a class of 2-dimensional vectors.
Definition vec2d.h:42
a singleton clock that can be used to get the current timestamp.
Definition clock.h:39
const OpenSpaceInfo & open_space_info() const
Definition frame.h:167
const LocalView & local_view() const
Definition frame.h:163
const common::VehicleState & vehicle_state() const
Definition frame.cc:83
OpenSpaceInfo * mutable_open_space_info()
Definition frame.h:169
GearSwitchStates * mutable_gear_switch_states()
TrajGearPair * mutable_fallback_trajectory()
void set_fallback_flag(const bool flag)
const DiscretizedTrajectory & stitched_trajectory_result() const
bool Init(const std::string &config_dir, const std::string &name, const std::shared_ptr< DependencyInjector > &injector) override
std::shared_ptr< DependencyInjector > injector_
Definition task.h:59
virtual bool Init(const std::string &config_dir, const std::string &name, const std::shared_ptr< DependencyInjector > &injector)
Definition task.cc:40
Planning module main class.
#define ADEBUG
Definition log.h:41
#define AERROR
Definition log.h:44
#define AINFO
Definition log.h:42
SLPoint InterpolateUsingLinearApproximation(const SLPoint &p0, const SLPoint &p1, const double w)
float tan(Angle16 a)
Definition angle.cc:47
double NormalizeAngle(const double angle)
Normalize angle to [-PI, PI).
Definition math_utils.cc:53
std::pair< DiscretizedTrajectory, canbus::Chassis::GearPosition > TrajGearPair
class register implement
Definition arena_queue.h:37
Definition future.h:29
Define the Polygon2d class.
std::shared_ptr< canbus::Chassis > chassis
Definition local_view.h:42