dp_road_graph.cc 7.3 KB
Newer Older
Y
Yifei Jiang 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/******************************************************************************
 * 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.
 *****************************************************************************/

/**
 * @file dp_road_graph.h
 **/

D
Dong Li 已提交
21
#include "modules/planning/tasks/dp_poly_path/dp_road_graph.h"
22 23

#include <algorithm>
J
jiangyifei 已提交
24
#include <limits>
A
Aaron Xiao 已提交
25
#include <string>
26
#include <unordered_map>
J
jiangyifei 已提交
27
#include <utility>
Y
Yifei Jiang 已提交
28

29
#include "modules/common/proto/error_code.pb.h"
30
#include "modules/common/proto/pnc_point.pb.h"
31 32 33 34

#include "modules/common/configs/vehicle_config_helper.h"
#include "modules/common/log.h"
#include "modules/common/util/util.h"
Y
Yifei Jiang 已提交
35
#include "modules/planning/common/path/frenet_frame_path.h"
D
Dong Li 已提交
36
#include "modules/planning/common/planning_gflags.h"
Y
Yifei Jiang 已提交
37 38
#include "modules/planning/math/curve1d/quintic_polynomial_curve1d.h"
#include "modules/planning/math/double.h"
D
Dong Li 已提交
39
#include "modules/planning/tasks/dp_poly_path/trajectory_cost.h"
Y
Yifei Jiang 已提交
40 41 42 43

namespace apollo {
namespace planning {

44 45 46
using apollo::common::ErrorCode;
using apollo::common::Status;

Y
Yajia Zhang 已提交
47
DPRoadGraph::DPRoadGraph(const DpPolyPathConfig &config,
48
                         const ReferenceLine &reference_line,
49
                         const SpeedData &speed_data)
50 51 52
    : config_(config),
      reference_line_(reference_line),
      speed_data_(speed_data) {}
Y
Yifei Jiang 已提交
53

54
bool DPRoadGraph::FindPathTunnel(const common::TrajectoryPoint &init_point,
D
Dong Li 已提交
55
                                 PathData *const path_data) {
Y
Yifei Jiang 已提交
56
  CHECK_NOTNULL(path_data);
57
  init_point_ = init_point;
58
  if (!reference_line_.XYToSL(
59 60
          {init_point_.path_point().x(), init_point_.path_point().y()},
          &init_sl_point_)) {
61 62
    AERROR << "Fail to create init_sl_point from : "
           << init_point.DebugString();
D
Dong Li 已提交
63
    return false;
Y
Yifei Jiang 已提交
64
  }
Y
Yajia Zhang 已提交
65
  std::vector<DPRoadGraphNode> min_cost_path;
66
  if (!GenerateMinCostPath(&min_cost_path)) {
D
Dong Li 已提交
67 68
    AERROR << "Fail to generate graph!";
    return false;
Y
Yifei Jiang 已提交
69
  }
D
Dong Li 已提交
70
  std::vector<common::FrenetFramePoint> frenet_path;
Z
zhuweicheng 已提交
71 72
  double accumulated_s = init_sl_point_.s();
  const double path_resolution = config_.path_resolution();
Y
Yajia Zhang 已提交
73 74

  for (std::size_t i = 1; i < min_cost_path.size(); ++i) {
75 76
    const auto &prev_node = min_cost_path[i - 1];
    const auto &cur_node = min_cost_path[i];
Y
Yajia Zhang 已提交
77

78
    const double path_length = cur_node.sl_point.s() - prev_node.sl_point.s();
79
    double current_s = 0.0;
80
    const auto &curve = cur_node.min_cost_curve;
81 82 83 84
    while (Double::Compare(current_s, path_length) < 0.0) {
      const double l = curve.Evaluate(0, current_s);
      const double dl = curve.Evaluate(1, current_s);
      const double ddl = curve.Evaluate(2, current_s);
D
Dong Li 已提交
85
      common::FrenetFramePoint frenet_frame_point;
Y
Yifei Jiang 已提交
86 87 88 89
      frenet_frame_point.set_s(accumulated_s + current_s);
      frenet_frame_point.set_l(l);
      frenet_frame_point.set_dl(dl);
      frenet_frame_point.set_ddl(ddl);
90
      frenet_path.push_back(std::move(frenet_frame_point));
91
      current_s += path_resolution;
Y
Yifei Jiang 已提交
92
    }
93
    accumulated_s += path_length;
Y
Yifei Jiang 已提交
94
  }
95
  FrenetFramePath tunnel(frenet_path);
96 97
  path_data->SetReferenceLine(&reference_line_);
  path_data->SetFrenetPath(tunnel);
D
Dong Li 已提交
98
  return true;
Y
Yifei Jiang 已提交
99 100
}

101 102
bool DPRoadGraph::GenerateMinCostPath(
    std::vector<DPRoadGraphNode> *min_cost_path) {
Y
Yajia Zhang 已提交
103 104
  CHECK(min_cost_path != nullptr);

Y
Yajia Zhang 已提交
105
  std::vector<std::vector<common::SLPoint>> path_waypoints;
106
  if (!SamplePathWaypoints(init_point_, &path_waypoints)) {
Y
Yajia Zhang 已提交
107
    AERROR << "Fail to sample path waypoints!";
108
    return false;
Y
Yifei Jiang 已提交
109
  }
D
Dong Li 已提交
110
  path_waypoints.insert(path_waypoints.begin(),
111
                        std::vector<common::SLPoint>{init_sl_point_});
Y
Yajia Zhang 已提交
112

Y
Yajia Zhang 已提交
113
  const auto &vehicle_config =
114
      common::VehicleConfigHelper::instance()->GetConfig();
Y
Yajia Zhang 已提交
115

116
  TrajectoryCost trajectory_cost(config_, reference_line_,
Y
Yajia Zhang 已提交
117
                                 vehicle_config.vehicle_param(), speed_data_);
Y
Yajia Zhang 已提交
118 119

  std::vector<std::vector<DPRoadGraphNode>> graph_nodes(path_waypoints.size());
120
  graph_nodes[0].emplace_back(init_sl_point_, nullptr, 0.0);
Y
Yajia Zhang 已提交
121 122 123 124

  for (std::size_t level = 1; level < path_waypoints.size(); ++level) {
    const auto &prev_dp_nodes = graph_nodes[level - 1];
    const auto &level_points = path_waypoints[level];
A
Aaron Xiao 已提交
125
    for (const auto &cur_point : level_points) {
126
      graph_nodes[level].emplace_back(cur_point, nullptr);
127
      auto &cur_node = graph_nodes[level].back();
A
Aaron Xiao 已提交
128
      for (const auto &prev_dp_node : prev_dp_nodes) {
129
        const auto &prev_sl_point = prev_dp_node.sl_point;
Y
Yajia Zhang 已提交
130 131 132
        QuinticPolynomialCurve1d curve(prev_sl_point.l(), 0.0, 0.0,
                                       cur_point.l(), 0.0, 0.0,
                                       cur_point.s() - prev_sl_point.s());
133
        const double cost =
A
Aaron Xiao 已提交
134
            trajectory_cost.Calculate(curve, prev_sl_point.s(), cur_point.s()) +
135
            prev_dp_node.min_cost;
Y
Yajia Zhang 已提交
136
        cur_node.UpdateCost(&prev_dp_node, curve, cost);
D
Dong Li 已提交
137 138 139
      }
    }
  }
Y
Yifei Jiang 已提交
140

141
  // find best path
Y
Yajia Zhang 已提交
142
  DPRoadGraphNode fake_head;
A
Aaron Xiao 已提交
143
  for (const auto &cur_dp_node : graph_nodes.back()) {
Y
Yajia Zhang 已提交
144
    fake_head.UpdateCost(&cur_dp_node, cur_dp_node.min_cost_curve,
D
Dong Li 已提交
145
                         cur_dp_node.min_cost);
Y
Yifei Jiang 已提交
146
  }
Y
Yajia Zhang 已提交
147

148 149 150 151 152 153
  const auto *min_cost_node = &fake_head;
  while (min_cost_node->min_cost_prev_node) {
    min_cost_node = min_cost_node->min_cost_prev_node;
    min_cost_path->push_back(*min_cost_node);
  }
  std::reverse(min_cost_path->begin(), min_cost_path->end());
Y
Yifei Jiang 已提交
154 155 156
  return true;
}

Y
Yajia Zhang 已提交
157
bool DPRoadGraph::SamplePathWaypoints(
158 159
    const common::TrajectoryPoint &init_point,
    std::vector<std::vector<common::SLPoint>> *const points) {
Y
Yajia Zhang 已提交
160 161 162
  CHECK(points != nullptr);

  common::math::Vec2d init_cartesian_point(init_point.path_point().x(),
D
Dong Li 已提交
163
                                           init_point.path_point().y());
Y
Yajia Zhang 已提交
164
  common::SLPoint init_sl_point;
165
  if (!reference_line_.XYToSL(init_cartesian_point, &init_sl_point)) {
166
    AERROR << "Failed to get sl point from point "
Y
Yajia Zhang 已提交
167
           << init_cartesian_point.DebugString();
168 169
    return false;
  }
Y
Yajia Zhang 已提交
170

171
  const double reference_line_length =
172
      reference_line_.map_path().accumulated_s().back();
Y
Yajia Zhang 已提交
173

174 175 176 177 178
  double level_distance =
      std::fmax(config_.step_length_min(),
                std::fmin(init_point.v(), config_.step_length_max()));

  double accumulated_s = init_sl_point.s();
Y
Yajia Zhang 已提交
179
  for (std::size_t i = 0;
180 181 182 183 184 185 186 187
       i < config_.sample_level() && accumulated_s < reference_line_length;
       ++i) {
    std::vector<common::SLPoint> level_points;
    accumulated_s += level_distance;
    double s = std::fmin(accumulated_s, reference_line_length);

    int32_t num =
        static_cast<int32_t>(config_.sample_points_num_each_level() / 2);
Y
Yajia Zhang 已提交
188

189 190 191
    for (int32_t j = -num; j < num + 1; ++j) {
      double l = config_.lateral_sample_offset() * j;
      auto sl = common::util::MakeSLPoint(s, l);
A
Aaron Xiao 已提交
192
      if (reference_line_.IsOnRoad(sl)) {
193 194 195 196 197 198 199 200 201 202
        level_points.push_back(sl);
      }
    }
    if (!level_points.empty()) {
      points->push_back(level_points);
    }
  }
  return true;
}

Y
Yifei Jiang 已提交
203 204
}  // namespace planning
}  // namespace apollo