dp_st_cost.cc 7.1 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
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
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_) {}

43
double DpStCost::GetObstacleCost(const StGraphPoint& st_graph_point) {
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
  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;
63

64 65
    const auto key =
        boundary.id() + "#" + std::to_string(st_graph_point.index_t());
66 67 68 69 70 71 72
    if (boundary_range_map_.find(key) == boundary_range_map_.end()) {
      boundary.GetBoundarySRange(t, &s_upper, &s_lower);
      boundary_range_map_[key] = std::make_pair(s_upper, s_lower);
    } else {
      s_upper = boundary_range_map_[key].first;
      s_lower = boundary_range_map_[key].second;
    }
73 74 75 76 77
    if (s < s_lower) {
      constexpr double kSafeTimeBuffer = 3.0;
      const double len = obstacle->obstacle()->Speed() * kSafeTimeBuffer;
      if (s + len < s_lower) {
        continue;
78
      } else {
79 80 81 82 83 84 85 86
        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 {
87
        cost += config_.obstacle_weight() * config_.default_obstacle_cost() *
88
                std::pow((kSafeDistance + s_upper - s), 2);
89
      }
90 91
    }
  }
92
  return cost * unit_t_;
93 94
}

95 96
double DpStCost::GetReferenceCost(const STPoint& point,
                                  const STPoint& reference_point) const {
97 98
  return config_.reference_weight() * (point.s() - reference_point.s()) *
         (point.s() - reference_point.s()) * unit_t_;
99 100
}

101 102
double DpStCost::GetSpeedCost(const STPoint& first, const STPoint& second,
                              const double speed_limit) const {
103
  double cost = 0.0;
104
  const double speed = (second.s() - first.s()) / unit_t_;
105
  if (speed < 0) {
106
    return kInf;
107 108
  }
  double det_speed = (speed - speed_limit) / speed_limit;
109
  if (det_speed > 0) {
110 111
    cost = config_.exceed_speed_penalty() * config_.default_speed_cost() *
           fabs(speed * speed) * unit_t_;
112
  } else if (det_speed < 0) {
113 114
    cost = config_.low_speed_penalty() * config_.default_speed_cost() *
           -det_speed * unit_t_;
115 116 117 118 119 120
  } else {
    cost = 0.0;
  }
  return cost;
}

121
double DpStCost::GetAccelCost(const double accel) const {
122
  const double accel_sq = accel * accel;
123 124 125 126
  double max_acc = config_.max_acceleration();
  double max_dec = config_.max_deceleration();
  double accel_penalty = config_.accel_penalty();
  double decel_penalty = config_.decel_penalty();
127 128
  double cost = 0.0;
  if (accel > 0.0) {
129
    cost = accel_penalty * accel_sq;
130
  } else {
131
    cost = decel_penalty * accel_sq;
132 133 134 135 136
  }
  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)));
137
  return cost * unit_t_;
138 139
}

140 141 142
double DpStCost::GetAccelCostByThreePoints(const STPoint& first,
                                           const STPoint& second,
                                           const STPoint& third) const {
143
  double accel = (first.s() + third.s() - 2 * second.s()) / (unit_t_ * unit_t_);
144
  return GetAccelCost(accel);
145 146
}

147 148 149
double DpStCost::GetAccelCostByTwoPoints(const double pre_speed,
                                         const STPoint& pre_point,
                                         const STPoint& curr_point) const {
150 151
  double current_speed = (curr_point.s() - pre_point.s()) / unit_t_;
  double accel = (current_speed - pre_speed) / unit_t_;
152
  return GetAccelCost(accel);
153 154
}

155
double DpStCost::JerkCost(const double jerk) const {
156 157
  double jerk_sq = jerk * jerk;
  double cost = 0.0;
158
  if (jerk > 0) {
159
    cost = config_.positive_jerk_coeff() * jerk_sq * unit_t_;
160
  } else {
161
    cost = config_.negative_jerk_coeff() * jerk_sq * unit_t_;
162 163 164 165
  }
  return cost;
}

166 167 168
double DpStCost::GetJerkCostByFourPoints(const STPoint& first,
                                         const STPoint& second,
                                         const STPoint& third,
K
kechxu 已提交
169 170
                                         const STPoint& fourth) const {
  double jerk = (fourth.s() - 3 * third.s() + 3 * second.s() - first.s()) /
171
                (unit_t_ * unit_t_ * unit_t_);
172
  return JerkCost(jerk);
173 174
}

175 176 177 178
double DpStCost::GetJerkCostByTwoPoints(const double pre_speed,
                                        const double pre_acc,
                                        const STPoint& pre_point,
                                        const STPoint& curr_point) const {
179 180 181
  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_;
182
  return JerkCost(jerk);
183 184
}

185 186 187 188
double DpStCost::GetJerkCostByThreePoints(const double first_speed,
                                          const STPoint& first,
                                          const STPoint& second,
                                          const STPoint& third) const {
189 190 191 192 193
  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_;
194
  return JerkCost(jerk);
195 196 197 198
}

}  // namespace planning
}  // namespace apollo