dp_st_cost.cc 6.3 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
#include "modules/planning/math/double.h"
27 28 29 30

namespace apollo {
namespace planning {

31
DpStCost::DpStCost(const DpStSpeedConfig& dp_st_speed_config)
32 33 34 35 36
    : dp_st_speed_config_(dp_st_speed_config),
      unit_s_(dp_st_speed_config_.total_path_length() /
              dp_st_speed_config_.matrix_dimension_s()),
      unit_t_(dp_st_speed_config_.total_time() /
              dp_st_speed_config_.matrix_dimension_t()) {}
37

A
Aaron Xiao 已提交
38
// TODO(all): normalize cost with time
39
double DpStCost::GetObstacleCost(
40
    const STPoint& point,
41
    const std::vector<StBoundary>& st_graph_boundaries) const {
42
  double total_cost = 0.0;
43
  for (const StBoundary& boundary : st_graph_boundaries) {
44
    if (point.s() < 0 || boundary.IsPointInBoundary(point)) {
45
      total_cost = std::numeric_limits<double>::infinity();
46
      break;
47
    } else {
48
      const double distance = boundary.DistanceTo(point);
49
      total_cost += dp_st_speed_config_.default_obstacle_cost() *
50
                    std::exp(dp_st_speed_config_.obstacle_cost_factor() /
51 52 53
                             boundary.characteristic_length() * distance);
    }
  }
54
  return total_cost * unit_t_;
55 56
}

57 58
double DpStCost::GetReferenceCost(const STPoint& point,
                                  const STPoint& reference_point) const {
59
  return dp_st_speed_config_.reference_weight() *
60
         (point.s() - reference_point.s()) * (point.s() - reference_point.s()) *
61
         unit_t_;
62 63
}

64 65
double DpStCost::GetSpeedCost(const STPoint& first, const STPoint& second,
                              const double speed_limit) const {
66
  double cost = 0.0;
67
  const double speed = (second.s() - first.s()) / unit_t_;
68
  if (Double::Compare(speed, 0.0) < 0) {
69
    return std::numeric_limits<double>::infinity();
70 71
  }
  double det_speed = (speed - speed_limit) / speed_limit;
72
  if (Double::Compare(det_speed, 0.0) > 0) {
73 74 75
    cost = dp_st_speed_config_.exceed_speed_penalty() *
           dp_st_speed_config_.default_speed_cost() * fabs(speed * speed) *
           unit_t_;
76
  } else if (Double::Compare(det_speed, 0.0) < 0) {
77 78
    cost = dp_st_speed_config_.low_speed_penalty() *
           dp_st_speed_config_.default_speed_cost() * -det_speed * unit_t_;
79 80 81 82 83 84
  } else {
    cost = 0.0;
  }
  return cost;
}

85
double DpStCost::GetAccelCost(const double accel) const {
86
  const double accel_sq = accel * accel;
87 88 89 90
  double max_acc = dp_st_speed_config_.max_acceleration();
  double max_dec = dp_st_speed_config_.max_deceleration();
  double accel_penalty = dp_st_speed_config_.accel_penalty();
  double decel_penalty = dp_st_speed_config_.decel_penalty();
91 92
  double cost = 0.0;
  if (accel > 0.0) {
93
    cost = accel_penalty * accel_sq;
94
  } else {
95
    cost = decel_penalty * accel_sq;
96 97 98 99 100
  }
  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)));
101
  return cost * unit_t_;
102 103
}

104 105 106
double DpStCost::GetAccelCostByThreePoints(const STPoint& first,
                                           const STPoint& second,
                                           const STPoint& third) const {
107
  double accel = (first.s() + third.s() - 2 * second.s()) / (unit_t_ * unit_t_);
108
  return GetAccelCost(accel);
109 110
}

111 112 113
double DpStCost::GetAccelCostByTwoPoints(const double pre_speed,
                                         const STPoint& pre_point,
                                         const STPoint& curr_point) const {
114 115
  double current_speed = (curr_point.s() - pre_point.s()) / unit_t_;
  double accel = (current_speed - pre_speed) / unit_t_;
116
  return GetAccelCost(accel);
117 118
}

119
double DpStCost::JerkCost(const double jerk) const {
120 121
  double jerk_sq = jerk * jerk;
  double cost = 0.0;
122
  if (Double::Compare(jerk, 0.0) > 0) {
123
    cost = dp_st_speed_config_.positive_jerk_coeff() * jerk_sq * unit_t_;
124
  } else if (Double::Compare(jerk, 0.0) < 0) {
125
    cost = dp_st_speed_config_.negative_jerk_coeff() * jerk_sq * unit_t_;
126 127 128 129 130 131
  } else {
    cost = 0.0;
  }
  return cost;
}

132 133 134
double DpStCost::GetJerkCostByFourPoints(const STPoint& first,
                                         const STPoint& second,
                                         const STPoint& third,
K
kechxu 已提交
135 136
                                         const STPoint& fourth) const {
  double jerk = (fourth.s() - 3 * third.s() + 3 * second.s() - first.s()) /
137
                (unit_t_ * unit_t_ * unit_t_);
138
  return JerkCost(jerk);
139 140
}

141 142 143 144
double DpStCost::GetJerkCostByTwoPoints(const double pre_speed,
                                        const double pre_acc,
                                        const STPoint& pre_point,
                                        const STPoint& curr_point) const {
145 146 147
  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_;
148
  return JerkCost(jerk);
149 150
}

151 152 153 154
double DpStCost::GetJerkCostByThreePoints(const double first_speed,
                                          const STPoint& first,
                                          const STPoint& second,
                                          const STPoint& third) const {
155 156 157 158 159
  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_;
160
  return JerkCost(jerk);
161 162 163 164
}

}  // namespace planning
}  // namespace apollo