dp_st_cost.cc 6.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

/**
18
 * @file dp_st_cost.cc
19 20
 **/

D
Dong Li 已提交
21
#include "modules/planning/tasks/dp_st_speed/dp_st_cost.h"
22

23 24
#include <limits>

25
#include "modules/planning/common/speed/st_point.h"
26 27 28

namespace apollo {
namespace planning {
29 30
namespace {
constexpr double kInf = std::numeric_limits<double>::infinity();
31
}
32

33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
DpStCost::DpStCost(const DpStSpeedConfig& config,
                   const std::vector<const PathObstacle*>& obstacles,
                   const common::TrajectoryPoint& init_point)
    : config_(config),
      obstacles_(obstacles),
      init_point_(init_point),
      unit_s_(config_.total_path_length() / config_.matrix_dimension_s()),
      unit_t_(config_.total_time() / config_.matrix_dimension_t()),
      unit_v_(unit_s_ / unit_t_) {}

double DpStCost::GetObstacleCost(const StGraphPoint& st_graph_point) const {
  const double s = st_graph_point.point().s();
  const double t = st_graph_point.point().t();

  double cost = 0.0;
  for (const auto* obstacle : obstacles_) {
    auto boundary = obstacle->st_boundary();
    const double kIgnoreDistance = 200.0;
    if (boundary.min_s() > kIgnoreDistance) {
      continue;
    }
    if (t < boundary.min_t() || t > boundary.max_t()) {
      continue;
    }
    if (obstacle->IsBlockingObstacle() &&
        boundary.IsPointInBoundary(STPoint(s, t))) {
      return kInf;
    }
    double s_upper = 0.0;
    double s_lower = 0.0;
    boundary.GetBoundarySRange(t, &s_upper, &s_lower);
    if (s < s_lower) {
      constexpr double kSafeTimeBuffer = 3.0;
      const double len = obstacle->obstacle()->Speed() * kSafeTimeBuffer;
      if (s + len < s_lower) {
        continue;
69
      } else {
70 71 72 73 74 75 76 77 78 79
        cost += config_.obstacle_weight() * config_.default_obstacle_cost() *
                std::pow((len - s_lower + s), 2);
      }
    } else if (s > s_upper) {
      const double kSafeDistance = 20.0;  // or calculated from velocity
      if (s > s_upper + kSafeDistance) {
        continue;
      } else {
        cost += config_.obstacle_weight() *
                std::pow((kSafeDistance + s_upper - s), 2);
80
      }
81 82
    }
  }
83
  return cost * unit_t_;
84 85
}

86 87
double DpStCost::GetReferenceCost(const STPoint& point,
                                  const STPoint& reference_point) const {
88 89
  return config_.reference_weight() * (point.s() - reference_point.s()) *
         (point.s() - reference_point.s()) * unit_t_;
90 91
}

92 93
double DpStCost::GetSpeedCost(const STPoint& first, const STPoint& second,
                              const double speed_limit) const {
94
  double cost = 0.0;
95
  const double speed = (second.s() - first.s()) / unit_t_;
96
  if (speed < 0) {
97
    return kInf;
98 99
  }
  double det_speed = (speed - speed_limit) / speed_limit;
100
  if (det_speed > 0) {
101 102
    cost = config_.exceed_speed_penalty() * config_.default_speed_cost() *
           fabs(speed * speed) * unit_t_;
103
  } else if (det_speed < 0) {
104 105
    cost = config_.low_speed_penalty() * config_.default_speed_cost() *
           -det_speed * unit_t_;
106 107 108 109 110 111
  } else {
    cost = 0.0;
  }
  return cost;
}

112
double DpStCost::GetAccelCost(const double accel) const {
113
  const double accel_sq = accel * accel;
114 115 116 117
  double max_acc = config_.max_acceleration();
  double max_dec = config_.max_deceleration();
  double accel_penalty = config_.accel_penalty();
  double decel_penalty = config_.decel_penalty();
118 119
  double cost = 0.0;
  if (accel > 0.0) {
120
    cost = accel_penalty * accel_sq;
121
  } else {
122
    cost = decel_penalty * accel_sq;
123 124 125 126 127
  }
  cost += accel_sq * decel_penalty * decel_penalty /
              (1 + std::exp(1.0 * (accel - max_dec))) +
          accel_sq * accel_penalty * accel_penalty /
              (1 + std::exp(-1.0 * (accel - max_acc)));
128
  return cost * unit_t_;
129 130
}

131 132 133
double DpStCost::GetAccelCostByThreePoints(const STPoint& first,
                                           const STPoint& second,
                                           const STPoint& third) const {
134
  double accel = (first.s() + third.s() - 2 * second.s()) / (unit_t_ * unit_t_);
135
  return GetAccelCost(accel);
136 137
}

138 139 140
double DpStCost::GetAccelCostByTwoPoints(const double pre_speed,
                                         const STPoint& pre_point,
                                         const STPoint& curr_point) const {
141 142
  double current_speed = (curr_point.s() - pre_point.s()) / unit_t_;
  double accel = (current_speed - pre_speed) / unit_t_;
143
  return GetAccelCost(accel);
144 145
}

146
double DpStCost::JerkCost(const double jerk) const {
147 148
  double jerk_sq = jerk * jerk;
  double cost = 0.0;
149
  if (jerk > 0) {
150
    cost = config_.positive_jerk_coeff() * jerk_sq * unit_t_;
151
  } else {
152
    cost = config_.negative_jerk_coeff() * jerk_sq * unit_t_;
153 154 155 156
  }
  return cost;
}

157 158 159
double DpStCost::GetJerkCostByFourPoints(const STPoint& first,
                                         const STPoint& second,
                                         const STPoint& third,
K
kechxu 已提交
160 161
                                         const STPoint& fourth) const {
  double jerk = (fourth.s() - 3 * third.s() + 3 * second.s() - first.s()) /
162
                (unit_t_ * unit_t_ * unit_t_);
163
  return JerkCost(jerk);
164 165
}

166 167 168 169
double DpStCost::GetJerkCostByTwoPoints(const double pre_speed,
                                        const double pre_acc,
                                        const STPoint& pre_point,
                                        const STPoint& curr_point) const {
170 171 172
  const double curr_speed = (curr_point.s() - pre_point.s()) / unit_t_;
  const double curr_accel = (curr_speed - pre_speed) / unit_t_;
  const double jerk = (curr_accel - pre_acc) / unit_t_;
173
  return JerkCost(jerk);
174 175
}

176 177 178 179
double DpStCost::GetJerkCostByThreePoints(const double first_speed,
                                          const STPoint& first,
                                          const STPoint& second,
                                          const STPoint& third) const {
180 181 182 183 184
  const double pre_speed = (second.s() - first.s()) / unit_t_;
  const double pre_acc = (pre_speed - first_speed) / unit_t_;
  const double curr_speed = (third.s() - second.s()) / unit_t_;
  const double curr_acc = (curr_speed - pre_speed) / unit_t_;
  const double jerk = (curr_acc - pre_acc) / unit_t_;
185
  return JerkCost(jerk);
186 187 188 189
}

}  // namespace planning
}  // namespace apollo