Apollo 11.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 const auto& last_path_point = raw_trajectory.back().path_point();
402 double heading_angle = first_path_point.theta();
403 const Vec2d init_tracking_vector(
404 second_path_point.x() - first_path_point.x(),
405 second_path_point.y() - first_path_point.y());
406 double tracking_angle = init_tracking_vector.Angle();
407 if (first_path_point.x() == second_path_point.x() &&
408 first_path_point.y() == second_path_point.y() &&
409 first_path_point.x() == last_path_point.x() &&
410 first_path_point.y() == last_path_point.y()) {
411 *gear = injector_->vehicle_state()->vehicle_state().gear();
412 } else {
413 *gear =
414 std::abs(common::math::NormalizeAngle(tracking_angle - heading_angle)) <
415 (M_PI_2)
417 : canbus::Chassis::GEAR_REVERSE;
418 }
419 AINFO << "First trajectory segment gear: " << std::to_string(*gear);
420
421 // Set accumulated distance
422 Vec2d last_pos_vec(first_path_point.x(), first_path_point.y());
423 double distance_s = 0.0;
424 bool is_trajectory_last_point = false;
425
426 for (size_t i = 0; i < horizon - 1; ++i) {
427 const TrajectoryPoint& trajectory_point = raw_trajectory.at(i);
428 const TrajectoryPoint& next_trajectory_point = raw_trajectory.at(i + 1);
429 const TrajectoryPoint& last_trajectory_point = raw_trajectory.back();
430
431 // Check gear change
432 heading_angle = trajectory_point.path_point().theta();
433
435 if (next_trajectory_point.path_point().x() ==
436 trajectory_point.path_point().x() &&
437 next_trajectory_point.path_point().y() ==
438 trajectory_point.path_point().y() &&
439 last_trajectory_point.path_point().x() ==
440 trajectory_point.path_point().x() &&
441 last_trajectory_point.path_point().y() ==
442 trajectory_point.path_point().y()) {
443 AINFO << "Current trajectory point is same, set the gear with current gear!";
444 cur_gear = injector_->vehicle_state()->vehicle_state().gear();
445 } else {
446 const Vec2d tracking_vector(next_trajectory_point.path_point().x() -
447 trajectory_point.path_point().x(),
448 next_trajectory_point.path_point().y() -
449 trajectory_point.path_point().y());
450 tracking_angle = tracking_vector.Angle();
451 cur_gear = std::abs(common::math::NormalizeAngle(
452 tracking_angle - heading_angle)) < (M_PI_2)
454 : canbus::Chassis::GEAR_REVERSE;
455 }
456 AINFO << "cur_gear: " << std::to_string(cur_gear);
457
458 if (cur_gear != *gear) {
459 is_trajectory_last_point = true;
460 LoadTrajectoryPoint(trajectory_point, is_trajectory_last_point, *gear,
461 &last_pos_vec, &distance_s, trajectory);
462 partitioned_trajectories->emplace_back();
463 current_trajectory_gear = &(partitioned_trajectories->back());
464 current_trajectory_gear->second = cur_gear;
465 distance_s = 0.0;
466 is_trajectory_last_point = false;
467 }
468
469 trajectory = &(current_trajectory_gear->first);
470 gear = &(current_trajectory_gear->second);
471
472 LoadTrajectoryPoint(trajectory_point, is_trajectory_last_point, *gear,
473 &last_pos_vec, &distance_s, trajectory);
474 }
475 is_trajectory_last_point = true;
476 const TrajectoryPoint& last_trajectory_point = raw_trajectory.back();
477 LoadTrajectoryPoint(last_trajectory_point, is_trajectory_last_point, *gear,
478 &last_pos_vec, &distance_s, trajectory);
479}
480
481void OpenSpaceTrajectoryPartition::LoadTrajectoryPoint(
482 const TrajectoryPoint& trajectory_point,
483 const bool is_trajectory_last_point,
484 const canbus::Chassis::GearPosition& gear, Vec2d* last_pos_vec,
485 double* distance_s, DiscretizedTrajectory* current_trajectory) {
486 current_trajectory->emplace_back();
487 TrajectoryPoint* point = &(current_trajectory->back());
488 point->set_relative_time(trajectory_point.relative_time());
489 point->mutable_path_point()->set_x(trajectory_point.path_point().x());
490 point->mutable_path_point()->set_y(trajectory_point.path_point().y());
491 point->mutable_path_point()->set_theta(trajectory_point.path_point().theta());
492 point->set_v(trajectory_point.v());
493 point->mutable_path_point()->set_s(*distance_s);
494 Vec2d cur_pos_vec(trajectory_point.path_point().x(),
495 trajectory_point.path_point().y());
496 *distance_s += (gear == canbus::Chassis::GEAR_REVERSE ? -1.0 : 1.0) *
497 (cur_pos_vec.DistanceTo(*last_pos_vec));
498 *last_pos_vec = cur_pos_vec;
499 point->mutable_path_point()->set_kappa((is_trajectory_last_point ? -1 : 1) *
500 std::tan(trajectory_point.steer()) /
501 wheel_base_);
502 point->set_a(trajectory_point.a());
503}
504
505bool OpenSpaceTrajectoryPartition::CheckReachTrajectoryEnd(
506 const DiscretizedTrajectory& trajectory,
507 const canbus::Chassis::GearPosition& gear, const size_t trajectories_size,
508 size_t* current_trajectory_point_index) {
509 // Check if have reached endpoint of trajectory
510 const TrajectoryPoint& trajectory_end_point = trajectory.back();
511 const size_t trajectory_size = trajectory.size();
512 const PathPoint& path_end_point = trajectory_end_point.path_point();
513 const double path_end_point_x = path_end_point.x();
514 const double path_end_point_y = path_end_point.y();
515 const Vec2d tracking_vector(ego_x_ - path_end_point_x,
516 ego_y_ - path_end_point_y);
517 const double path_end_point_theta = path_end_point.theta();
518 const double included_angle =
519 NormalizeAngle(path_end_point_theta - tracking_vector.Angle());
520 const double distance_to_trajs_end =
521 std::sqrt((path_end_point_x - ego_x_) * (path_end_point_x - ego_x_) +
522 (path_end_point_y - ego_y_) * (path_end_point_y - ego_y_));
523 const double lateral_offset =
524 std::abs(distance_to_trajs_end * std::sin(included_angle));
525 const double longitudinal_offset =
526 std::abs(distance_to_trajs_end * std::cos(included_angle));
527 const double traj_end_point_moving_direction =
529 ? NormalizeAngle(path_end_point_theta + M_PI)
530 : path_end_point_theta;
531
532 const double heading_search_to_trajs_end = std::abs(NormalizeAngle(
533 traj_end_point_moving_direction - vehicle_moving_direction_));
534
535 // If close to the end point, start on the next trajectory
536 double end_point_iou_ratio = 0.0;
537 if (lateral_offset < lateral_offset_to_midpoint_ &&
538 longitudinal_offset < longitudinal_offset_to_midpoint_ &&
539 heading_search_to_trajs_end < heading_offset_to_midpoint_ &&
540 std::abs(ego_v_) < linear_velocity_threshold_on_ego_) {
541 // get vehicle box and path point box, compare with a threadhold in IOU
542 Box2d path_end_point_box({path_end_point_x, path_end_point_y},
543 path_end_point_theta, ego_length_, ego_width_);
544 Vec2d shift_vec{shift_distance_ * std::cos(path_end_point_theta),
545 shift_distance_ * std::sin(path_end_point_theta)};
546 path_end_point_box.Shift(shift_vec);
547 end_point_iou_ratio =
548 Polygon2d(ego_box_).ComputeIoU(Polygon2d(path_end_point_box));
549
550 if (end_point_iou_ratio > vehicle_box_iou_threshold_to_midpoint_) {
551 if (current_trajectory_index_ + 1 >= trajectories_size) {
552 current_trajectory_index_ = trajectories_size - 1;
553 *current_trajectory_point_index = trajectory_size - 1;
554 } else {
555 current_trajectory_index_ += 1;
556 *current_trajectory_point_index = 0;
557 }
558 AINFO << "Reach the end of a trajectory, switching to next one";
559 return true;
560 }
561 }
562
563 AINFO << "Vehicle did not reach end of a trajectory with conditions for "
564 "lateral distance_check: "
565 << (lateral_offset < lateral_offset_to_midpoint_)
566 << " and actual lateral distance: " << lateral_offset
567 << "; longitudinal distance_check: "
568 << (longitudinal_offset < longitudinal_offset_to_midpoint_)
569 << " and actual longitudinal distance: " << longitudinal_offset
570 << "; heading_check: "
571 << (heading_search_to_trajs_end < heading_offset_to_midpoint_)
572 << " with actual heading: " << heading_search_to_trajs_end
573 << "; velocity_check: "
574 << (std::abs(ego_v_) < linear_velocity_threshold_on_ego_)
575 << " with actual linear velocity: " << ego_v_ << "; iou_check: "
576 << (end_point_iou_ratio > vehicle_box_iou_threshold_to_midpoint_)
577 << " with actual iou: " << end_point_iou_ratio;
578 return false;
579}
580
581bool OpenSpaceTrajectoryPartition::UseFailSafeSearch(
582 const std::vector<TrajGearPair>& partitioned_trajectories,
583 const std::vector<std::string>& trajectories_encodings,
584 size_t* current_trajectory_index, size_t* current_trajectory_point_index) {
585 AERROR << "Trajectory partition fail, using failsafe search";
586 const size_t trajectories_size = partitioned_trajectories.size();
587 std::priority_queue<std::pair<std::pair<size_t, size_t>, double>,
588 std::vector<std::pair<std::pair<size_t, size_t>, double>>,
589 pair_comp_>
590 failsafe_closest_point_on_trajs;
591 for (size_t i = 0; i < trajectories_size; ++i) {
592 const auto& trajectory = partitioned_trajectories.at(i).first;
593 size_t trajectory_size = trajectory.size();
594 CHECK_GT(trajectory_size, 0U);
595 std::priority_queue<std::pair<size_t, double>,
596 std::vector<std::pair<size_t, double>>, comp_>
597 failsafe_closest_point;
598
599 for (size_t j = 0; j < trajectory_size; ++j) {
600 const TrajectoryPoint& trajectory_point = trajectory.at(j);
601 const PathPoint& path_point = trajectory_point.path_point();
602 const double path_point_x = path_point.x();
603 const double path_point_y = path_point.y();
604 const double path_point_theta = path_point.theta();
605 const Vec2d tracking_vector(path_point_x - ego_x_, path_point_y - ego_y_);
606 const double distance = tracking_vector.Length();
607 if (distance < distance_search_range_) {
608 // get vehicle box and path point box, compute IOU
609 Box2d path_point_box({path_point_x, path_point_y}, path_point_theta,
610 ego_length_, ego_width_);
611 Vec2d shift_vec{shift_distance_ * std::cos(path_point_theta),
612 shift_distance_ * std::sin(path_point_theta)};
613 path_point_box.Shift(shift_vec);
614 double iou_ratio =
615 Polygon2d(ego_box_).ComputeIoU(Polygon2d(path_point_box));
616 failsafe_closest_point.emplace(j, iou_ratio);
617 }
618 }
619 if (!failsafe_closest_point.empty()) {
620 size_t closest_point_index = failsafe_closest_point.top().first;
621 double max_iou_ratio = failsafe_closest_point.top().second;
622 failsafe_closest_point_on_trajs.emplace(
623 std::make_pair(i, closest_point_index), max_iou_ratio);
624 }
625 }
626 if (failsafe_closest_point_on_trajs.empty()) {
627 return false;
628 } else {
629 bool closest_and_not_repeated_traj_found = false;
630 while (!failsafe_closest_point_on_trajs.empty()) {
631 *current_trajectory_index =
632 failsafe_closest_point_on_trajs.top().first.first;
633 *current_trajectory_point_index =
634 failsafe_closest_point_on_trajs.top().first.second;
635 if (CheckTrajTraversed(
636 trajectories_encodings[*current_trajectory_index])) {
637 failsafe_closest_point_on_trajs.pop();
638 } else {
639 closest_and_not_repeated_traj_found = true;
640 UpdateTrajHistory(trajectories_encodings[*current_trajectory_index]);
641 return true;
642 }
643 }
644 if (!closest_and_not_repeated_traj_found) {
645 return false;
646 }
647
648 return true;
649 }
650}
651
652bool OpenSpaceTrajectoryPartition::InsertGearShiftTrajectory(
653 const bool flag_change_to_next, const size_t current_trajectory_index,
654 const std::vector<TrajGearPair>& partitioned_trajectories,
655 TrajGearPair* gear_switch_idle_time_trajectory) {
656 const auto* last_frame = injector_->frame_history()->Latest();
657 auto* current_gear_status =
659 if (last_frame) {
660 const auto& last_gear_status =
661 last_frame->open_space_info().gear_switch_states();
662 *(current_gear_status) = last_gear_status;
663 } else {
664 AERROR << "Lost last frame";
665 }
666 const auto& curr_gear =
667 partitioned_trajectories.at(current_trajectory_index).second;
668 if (flag_change_to_next || !current_gear_status->gear_shift_period_finished ||
669 curr_gear != ego_gear_) {
670 current_gear_status->gear_shift_period_finished = false;
671 if (current_gear_status->gear_shift_period_started) {
672 current_gear_status->gear_shift_start_time =
673 Clock::Instance()->NowInSeconds();
674 current_gear_status->gear_shift_position =
675 partitioned_trajectories.at(current_trajectory_index).second;
676 current_gear_status->gear_shift_period_started = false;
677 current_gear_status->gear_shift_period_time = 0.0;
678 }
679 if (current_gear_status->gear_shift_period_time >
680 config_.gear_shift_period_duration() &&
681 current_gear_status->gear_shift_position == ego_gear_) {
682 current_gear_status->gear_shift_period_finished = true;
683 current_gear_status->gear_shift_period_started = true;
684 AINFO << "finished gear shift";
685 } else {
686 double init_kappa = partitioned_trajectories.at(current_trajectory_index)
687 .first[0]
688 .path_point()
689 .kappa();
690 GenerateGearShiftTrajectory(current_gear_status->gear_shift_position,
691 init_kappa, gear_switch_idle_time_trajectory);
692 current_gear_status->gear_shift_period_time =
693 Clock::Instance()->NowInSeconds() -
694 current_gear_status->gear_shift_start_time;
695 return true;
696 }
697 }
698
699 return true;
700}
701
702void OpenSpaceTrajectoryPartition::GenerateGearShiftTrajectory(
703 const canbus::Chassis::GearPosition& gear_position, double init_kappa,
704 TrajGearPair* gear_switch_idle_time_trajectory) {
705 gear_switch_idle_time_trajectory->first.clear();
706 const double gear_shift_max_t = config_.gear_shift_max_t();
707 const double gear_shift_unit_t = config_.gear_shift_unit_t();
708 // TrajectoryPoint point;
709 for (double t = 0.0; t < gear_shift_max_t; t += gear_shift_unit_t) {
710 TrajectoryPoint point;
711 point.mutable_path_point()->set_x(frame_->vehicle_state().x());
712 point.mutable_path_point()->set_y(frame_->vehicle_state().y());
713 point.mutable_path_point()->set_theta(frame_->vehicle_state().heading());
714 point.mutable_path_point()->set_s(0.0);
715 point.mutable_path_point()->set_kappa(init_kappa);
716 point.set_relative_time(t);
717 point.set_v(0.0);
718 point.set_a(0.0);
719 gear_switch_idle_time_trajectory->first.emplace_back(point);
720 }
721 ADEBUG << "gear_switch_idle_time_trajectory"
722 << gear_switch_idle_time_trajectory->first.size();
723 gear_switch_idle_time_trajectory->second = gear_position;
724}
725
726void OpenSpaceTrajectoryPartition::GenerateStopTrajectory(
727 DiscretizedTrajectory* const trajectory_data,
728 double standstill_acceleration) {
729 double relative_time = 0.0;
730 // TODO(Jinyun) Move to conf
731 static constexpr int stop_trajectory_length = 10;
732 static constexpr double relative_stop_time = 0.1;
733 trajectory_data->clear();
734 static constexpr double vEpsilon = 0.00001;
735 standstill_acceleration =
736 frame_->vehicle_state().linear_velocity() >= -vEpsilon
737 ? standstill_acceleration
738 : -1.0 * standstill_acceleration;
739 for (size_t i = 0; i < stop_trajectory_length; i++) {
740 TrajectoryPoint point;
741 point.mutable_path_point()->set_x(frame_->vehicle_state().x());
742 point.mutable_path_point()->set_y(frame_->vehicle_state().y());
743 point.mutable_path_point()->set_theta(frame_->vehicle_state().heading());
744 point.mutable_path_point()->set_s(0.0);
745 point.mutable_path_point()->set_kappa(0.0);
746 point.set_relative_time(relative_time);
747 point.set_v(0.0);
748 point.set_a(standstill_acceleration);
749 trajectory_data->emplace_back(point);
750 relative_time += relative_stop_time;
751 }
752}
753
754void OpenSpaceTrajectoryPartition::AdjustRelativeTimeAndS(
755 const std::vector<TrajGearPair>& partitioned_trajectories,
756 const size_t current_trajectory_index,
757 const size_t closest_trajectory_point_index,
758 DiscretizedTrajectory* unpartitioned_trajectory_result,
759 TrajGearPair* current_partitioned_trajectory) {
760 const size_t partitioned_trajectories_size = partitioned_trajectories.size();
761 CHECK_GT(partitioned_trajectories_size, current_trajectory_index);
762
763 // Reassign relative time and relative s to have the closest point as origin
764 // point
765 *(current_partitioned_trajectory) =
766 partitioned_trajectories.at(current_trajectory_index);
767 auto trajectory = &(current_partitioned_trajectory->first);
768 double time_shift =
769 trajectory->at(closest_trajectory_point_index).relative_time();
770 double s_shift =
771 trajectory->at(closest_trajectory_point_index).path_point().s();
772 const size_t trajectory_size = trajectory->size();
773 for (size_t i = 0; i < trajectory_size; ++i) {
774 TrajectoryPoint* trajectory_point = &(trajectory->at(i));
775 trajectory_point->set_relative_time(trajectory_point->relative_time() -
776 time_shift);
777 trajectory_point->mutable_path_point()->set_s(
778 trajectory_point->path_point().s() - s_shift);
779 }
780
781 // Reassign relative t and s on stitched_trajectory_result for accurate next
782 // frame stitching
783 // size_t interpolated_pieces_num =
784 // config_.interpolated_pieces_num();
785 // if (FLAGS_use_iterative_anchoring_smoother) {
786 // interpolated_pieces_num = 1;
787 // }
788 const size_t unpartitioned_trajectory_size =
789 unpartitioned_trajectory_result->size();
790 // size_t index_estimate = 0;
791 // for (size_t i = 0; i < current_trajectory_index; ++i) {
792 // index_estimate += partitioned_trajectories.at(i).first.size();
793 // }
794 // index_estimate += closest_trajectory_point_index;
795 // index_estimate /= interpolated_pieces_num;
796 // if (index_estimate >= unpartitioned_trajectory_size) {
797 // index_estimate = unpartitioned_trajectory_size - 1;
798 // }
799 // time_shift =
800 // unpartitioned_trajectory_result->at(index_estimate).relative_time();
801 // s_shift =
802 // unpartitioned_trajectory_result->at(index_estimate).path_point().s();
803 for (size_t i = 0; i < unpartitioned_trajectory_size; ++i) {
804 TrajectoryPoint* trajectory_point =
805 &(unpartitioned_trajectory_result->at(i));
806 trajectory_point->set_relative_time(trajectory_point->relative_time() -
807 time_shift);
808 trajectory_point->mutable_path_point()->set_s(
809 trajectory_point->path_point().s() - s_shift);
810 }
811}
812
813} // namespace planning
814} // 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