32 const std::string& config_dir,
const std::string& name,
33 const std::shared_ptr<DependencyInjector>& injector) {
38 return Decider::LoadConfig<OpenSpaceFallBackDeciderConfig>(&config_);
41bool OpenSpaceFallbackDecider::QuardraticFormulaLowerSolution(
const double a,
47 const double kEpsilon = 1e-6;
49 if (std::abs(a) < kEpsilon) {
53 double tmp = b * b - 4 * a * c;
57 double sol1 = (-b + std::sqrt(tmp)) / (2.0 * a);
58 double sol2 = (-b - std::sqrt(tmp)) / (2.0 * a);
60 *sol = std::abs(std::min(sol1, sol2));
61 ADEBUG <<
"QuardraticFormulaLowerSolution finished with sol: " << *sol
62 <<
"sol1: " << sol1 <<
", sol2: " << sol2 <<
"a: " << a <<
"b: " << b
67Status OpenSpaceFallbackDecider::Process(
Frame* frame) {
68 std::vector<std::vector<common::math::Box2d>> predicted_bounding_rectangles;
69 size_t first_collision_index = 0;
70 size_t fallback_start_index = 0;
72 AINFO <<
"has got fallback decider, skip";
75 BuildPredictedEnvironment(frame->obstacles(), predicted_bounding_rectangles);
76 ADEBUG <<
"Numbers of obstsacles are: " << frame->obstacles().size();
77 ADEBUG <<
"Numbers of predicted bounding rectangles are: "
78 << predicted_bounding_rectangles[0].size()
79 <<
" and : " << predicted_bounding_rectangles.size();
80 if (!IsCollisionFreeTrajectory(
81 frame->open_space_info().chosen_partitioned_trajectory(),
82 predicted_bounding_rectangles, &fallback_start_index,
83 &first_collision_index)) {
90 frame->open_space_info().chosen_partitioned_trajectory();
93 const auto future_collision_point =
94 fallback_trajectory_pair_candidate.first[first_collision_index];
97 auto fallback_start_point =
98 fallback_trajectory_pair_candidate.first[fallback_start_index];
99 const auto& vehicle_state =
injector_->vehicle_state()->vehicle_state();
100 fallback_start_point.set_v(vehicle_state.linear_velocity());
103 future_collision_point;
106 double min_stop_distance =
107 0.5 * fallback_start_point.v() * fallback_start_point.v() / 4.0;
110 double stop_distance =
112 ? std::max(future_collision_point.path_point().s() -
113 fallback_start_point.path_point().s() - 1.0,
115 :
std::min(future_collision_point.path_point().s() -
116 fallback_start_point.path_point().s() + 1.0,
119 ADEBUG <<
"stop distance : " << stop_distance;
122 const double vehicle_max_acc = 4.0;
123 const double vehicle_max_dec = -4.0;
125 double stop_deceleration = 0.0;
127 if (fallback_trajectory_pair_candidate.second ==
130 std::min(fallback_start_point.v() * fallback_start_point.v() /
131 (2.0 * (stop_distance + 1e-6)),
133 stop_distance = std::min(-1 * min_stop_distance, stop_distance);
136 std::max(-fallback_start_point.v() * fallback_start_point.v() /
137 (2.0 * (stop_distance + 1e-6)),
139 stop_distance = std::max(min_stop_distance, stop_distance);
142 ADEBUG <<
"stop_deceleration: " << stop_deceleration;
145 size_t stop_index = fallback_start_index;
147 for (
size_t i = fallback_start_index;
148 i < fallback_trajectory_pair_candidate.first.NumOfPoints(); ++i) {
150 fallback_trajectory_pair_candidate.first[i].path_point().s()) >=
151 std::abs(fallback_start_point.path_point().s() + stop_distance)) {
157 ADEBUG <<
"stop index before is: " << stop_index
158 <<
"; fallback_start index before is: " << fallback_start_index;
160 for (
size_t i = 0; i < fallback_start_index; ++i) {
161 fallback_trajectory_pair_candidate.first[i].set_v(
162 fallback_start_point.v());
163 fallback_trajectory_pair_candidate.first[i].set_a(stop_deceleration);
170 if (fallback_start_index >= stop_index) {
172 AINFO <<
"Stop distance within safety buffer, stop now!";
173 fallback_start_point.set_v(0.0);
174 fallback_start_point.set_a(0.0);
175 fallback_trajectory_pair_candidate.first[stop_index].set_v(0.0);
176 fallback_trajectory_pair_candidate.first[stop_index].set_a(0.0);
179 fallback_trajectory_pair_candidate.first.erase(
180 fallback_trajectory_pair_candidate.first.begin() + stop_index + 1,
181 fallback_trajectory_pair_candidate.first.end());
184 for (
int i = 0; i < 20; ++i) {
185 common::TrajectoryPoint trajectory_point(
186 fallback_trajectory_pair_candidate.first[stop_index]);
187 trajectory_point.set_relative_time(
189 fallback_trajectory_pair_candidate.first[stop_index]
191 fallback_trajectory_pair_candidate.first.AppendTrajectoryPoint(
196 fallback_trajectory_pair_candidate;
201 ADEBUG <<
"before change, size : "
202 << fallback_trajectory_pair_candidate.first.size()
203 <<
", first index information : "
204 << fallback_trajectory_pair_candidate.first[0].DebugString()
205 <<
", second index information : "
206 << fallback_trajectory_pair_candidate.first[1].DebugString();
210 for (
size_t i = fallback_start_index; i <= stop_index; ++i) {
211 double new_relative_time = 0.0;
214 -2.0 * fallback_trajectory_pair_candidate.first[i].path_point().s();
216 if (QuardraticFormulaLowerSolution(stop_deceleration,
217 2.0 * fallback_start_point.v(), c,
218 &new_relative_time) &&
220 fallback_trajectory_pair_candidate.first[i].path_point().s()) <=
221 std::abs(stop_distance)) {
222 ADEBUG <<
"new_relative_time" << new_relative_time;
224 fallback_start_point.v() + stop_deceleration * new_relative_time;
226 if (std::abs(temp_v) < 1.0) {
227 fallback_trajectory_pair_candidate.first[i].set_v(temp_v);
229 fallback_trajectory_pair_candidate.first[i].set_v(
230 temp_v / std::abs(temp_v) * 1.0);
232 fallback_trajectory_pair_candidate.first[i].set_a(stop_deceleration);
234 fallback_trajectory_pair_candidate.first[i].set_relative_time(
238 fallback_trajectory_pair_candidate.first[i]
239 .mutable_path_point()
241 fallback_trajectory_pair_candidate.first[i - 1].path_point());
242 fallback_trajectory_pair_candidate.first[i].set_v(0.0);
243 fallback_trajectory_pair_candidate.first[i].set_a(0.0);
244 fallback_trajectory_pair_candidate.first[i].set_relative_time(
245 fallback_trajectory_pair_candidate.first[i - 1].relative_time() +
248 fallback_trajectory_pair_candidate.first[i].set_v(0.0);
249 fallback_trajectory_pair_candidate.first[i].set_a(0.0);
254 ADEBUG <<
"fallback start point after changes: "
255 << fallback_start_point.DebugString();
257 ADEBUG <<
"stop index: " << stop_index;
258 ADEBUG <<
"fallback start index: " << fallback_start_index;
261 fallback_trajectory_pair_candidate.first.erase(
262 fallback_trajectory_pair_candidate.first.begin() + stop_index + 1,
263 fallback_trajectory_pair_candidate.first.end());
266 for (
int i = 0; i < 20; ++i) {
267 common::TrajectoryPoint trajectory_point(
268 fallback_trajectory_pair_candidate.first[stop_index]);
269 trajectory_point.set_relative_time(
271 fallback_trajectory_pair_candidate.first[stop_index].relative_time());
272 fallback_trajectory_pair_candidate.first.AppendTrajectoryPoint(
277 fallback_trajectory_pair_candidate;
282 if (!IsCollisionFreeEgoBox()) {
283 double relative_time = 0.0;
285 static constexpr int stop_trajectory_length = 10;
286 static constexpr double relative_stop_time = 0.1;
287 auto fallback_tra_pair =
292 fallback_tra_pair->first.clear();
293 for (
size_t i = 0; i < stop_trajectory_length; i++) {
294 TrajectoryPoint point;
298 point.mutable_path_point()->set_s(0.0);
299 point.mutable_path_point()->set_kappa(0.0);
300 point.set_relative_time(relative_time);
303 fallback_tra_pair->first.emplace_back(point);
304 relative_time += relative_stop_time;
316void OpenSpaceFallbackDecider::BuildPredictedEnvironment(
317 const std::vector<const Obstacle*>& obstacles,
318 std::vector<std::vector<common::math::Box2d>>&
319 predicted_bounding_rectangles) {
320 predicted_bounding_rectangles.clear();
321 double relative_time = 0.0;
323 std::vector<Box2d> predicted_env;
324 for (
const Obstacle* obstacle : obstacles) {
325 if (!obstacle->IsVirtual()) {
326 TrajectoryPoint point = obstacle->GetPointAtTime(relative_time);
327 Box2d box = obstacle->GetBoundingBox(point);
328 predicted_env.push_back(std::move(box));
331 predicted_bounding_rectangles.emplace_back(std::move(predicted_env));
332 relative_time += FLAGS_trajectory_time_resolution;
336bool OpenSpaceFallbackDecider::IsCollisionFreeEgoBox() {
339 double x = vehicle_state.
x();
340 double y = vehicle_state.y();
341 double heading = vehicle_state.heading();
343 const auto& vehicle_config =
344 common::VehicleConfigHelper::Instance()->GetConfig();
345 double ego_length = vehicle_config.vehicle_param().length();
346 double ego_width = vehicle_config.vehicle_param().width();
347 Box2d ego_box({x, y}, heading, ego_length, ego_width);
348 Polygon2d ego_polygon = Polygon2d(ego_box);
350 for (
const Obstacle* obstacle :
frame_->obstacles()) {
351 if (obstacle->IsVirtual() || !obstacle->IsStatic() ||
352 obstacle->Perception().width() < 0.2 ||
353 obstacle->Perception().length() < 0.2) {
356 Polygon2d obstacle_polygon = obstacle->PerceptionPolygon();
357 if (ego_polygon.HasOverlap(obstacle_polygon)) {
364void OpenSpaceFallbackDecider::PathPointNormalizing(
365 double rotate_angle,
const Vec2d& translate_origin,
double* x,
double* y,
367 *x -= translate_origin.x();
368 *y -= translate_origin.y();
370 *x = (*x) * std::cos(-rotate_angle) - (*y) * std::sin(-rotate_angle);
371 *y = tmp_x * std::sin(-rotate_angle) + (*y) * std::cos(-rotate_angle);
375bool OpenSpaceFallbackDecider::IsCollisionFreeTrajectory(
377 const std::vector<std::vector<common::math::Box2d>>&
378 predicted_bounding_rectangles,
379 size_t* current_index,
size_t* first_collision_index) {
381 const auto& vehicle_config =
382 common::VehicleConfigHelper::Instance()->GetConfig();
383 double ego_length = vehicle_config.vehicle_param().length();
384 double ego_width = vehicle_config.vehicle_param().width();
385 auto trajectory_pb = trajectory_gear_pair.first;
386 const size_t point_size = trajectory_pb.NumOfPoints();
388 *current_index = trajectory_pb.QueryLowerBoundPoint(0.0);
390 for (
size_t i = *current_index; i < point_size; ++i) {
391 const auto& trajectory_point = trajectory_pb.TrajectoryPointAt(i);
392 double ego_theta = trajectory_point.path_point().theta();
394 {trajectory_point.path_point().x(), trajectory_point.path_point().y()},
395 ego_theta, ego_length, ego_width);
396 double shift_distance =
397 ego_length / 2.0 - vehicle_config.vehicle_param().back_edge_to_center();
398 Vec2d shift_vec{shift_distance * std::cos(ego_theta),
399 shift_distance * std::sin(ego_theta)};
400 ego_box.Shift(shift_vec);
401 size_t predicted_time_horizon = predicted_bounding_rectangles.size();
402 for (
size_t j = 0; j < predicted_time_horizon; j++) {
403 for (
const auto& obstacle_box : predicted_bounding_rectangles[j]) {
404 if (ego_box.HasOverlap(obstacle_box)) {
405 ADEBUG <<
"HasOverlap(obstacle_box) [" << i <<
"]";
407 Vec2d vehicle_vec({vehicle_state.x(), vehicle_state.y()});
409 if (std::abs(trajectory_point.relative_time() -
410 static_cast<double>(j) *
411 FLAGS_trajectory_time_resolution) <
413 trajectory_point.relative_time() > 0.0) {
414 ADEBUG <<
"first_collision_index: [" << i <<
"]";
415 *first_collision_index = i;
A general class to denote the return status of an API call.
static Status OK()
generate a success status.
Rectangular (undirected) bounding box in 2-D.
The class of polygon in 2-D.
Implements a class of 2-dimensional vectors.
const OpenSpaceInfo & open_space_info() const
const common::VehicleState & vehicle_state() const
OpenSpaceInfo * mutable_open_space_info()
bool Init(const std::string &config_dir, const std::string &name, const std::shared_ptr< DependencyInjector > &injector) override
bool fallback_flag() const
common::TrajectoryPoint * mutable_future_collision_point()
void set_stop_flag(const bool flag)
TrajGearPair * mutable_fallback_trajectory()
void set_fallback_flag(const bool flag)
std::shared_ptr< DependencyInjector > injector_
virtual bool Init(const std::string &config_dir, const std::string &name, const std::shared_ptr< DependencyInjector > &injector)
Planning module main class.
double NormalizeAngle(const double angle)
Normalize angle to [-PI, PI).
std::pair< DiscretizedTrajectory, canbus::Chassis::GearPosition > TrajGearPair
optional double open_space_fallback_collision_time_buffer
optional double open_space_prediction_time_period