em_planner.cc 7.6 KB
Newer Older
D
Dong Li 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/******************************************************************************
 * 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.
 *****************************************************************************/

#include "modules/planning/planner/em/em_planner.h"

#include <fstream>
#include <utility>

D
Dong Li 已提交
22
#include "modules/common/adapters/adapter_manager.h"
D
Dong Li 已提交
23
#include "modules/common/log.h"
J
Jiangtao Hu 已提交
24
#include "modules/common/time/time.h"
D
Dong Li 已提交
25
#include "modules/common/util/string_tokenizer.h"
26
#include "modules/common/util/string_util.h"
27
#include "modules/common/vehicle_state/vehicle_state.h"
28 29
#include "modules/map/hdmap/hdmap.h"
#include "modules/map/hdmap/hdmap_common.h"
D
Dong Li 已提交
30
#include "modules/planning/common/data_center.h"
J
Jiangtao Hu 已提交
31
#include "modules/planning/common/frame.h"
32
#include "modules/planning/common/planning_data.h"
33
#include "modules/planning/common/planning_gflags.h"
D
Dong Li 已提交
34
#include "modules/planning/math/curve1d/quartic_polynomial_curve1d.h"
J
Jiangtao Hu 已提交
35
#include "modules/planning/optimizer/dp_poly_path/dp_poly_path_optimizer.h"
36 37
#include "modules/planning/optimizer/dp_st_speed/dp_st_speed_optimizer.h"
#include "modules/planning/optimizer/qp_spline_path/qp_spline_path_optimizer.h"
38
#include "modules/planning/optimizer/qp_spline_st_speed/qp_spline_st_speed_optimizer.h"
D
Dong Li 已提交
39 40 41 42

namespace apollo {
namespace planning {

43 44
using common::Status;
using common::adapter::AdapterManager;
J
Jiangtao Hu 已提交
45
using common::time::Clock;
46
using common::ErrorCode;
47
using common::SpeedPoint;
48 49
using common::TrajectoryPoint;
using common::VehicleState;
D
Dong Li 已提交
50

51
EMPlanner::EMPlanner() {}
J
Jiangtao Hu 已提交
52 53

void EMPlanner::RegisterOptimizers() {
54
  optimizer_factory_.Register(DP_POLY_PATH_OPTIMIZER, []() -> Optimizer* {
55
    return new DpPolyPathOptimizer(OptimizerType_Name(DP_POLY_PATH_OPTIMIZER));
56 57
  });
  optimizer_factory_.Register(DP_ST_SPEED_OPTIMIZER, []() -> Optimizer* {
58
    return new DpStSpeedOptimizer(OptimizerType_Name(DP_ST_SPEED_OPTIMIZER));
59 60
  });
  optimizer_factory_.Register(QP_SPLINE_PATH_OPTIMIZER, []() -> Optimizer* {
61 62
    return new QpSplinePathOptimizer(
        OptimizerType_Name(QP_SPLINE_PATH_OPTIMIZER));
63
  });
64
  optimizer_factory_.Register(QP_SPLINE_ST_SPEED_OPTIMIZER, []() -> Optimizer* {
65 66
    return new QpSplineStSpeedOptimizer(
        OptimizerType_Name(QP_SPLINE_ST_SPEED_OPTIMIZER));
67
  });
J
Jiangtao Hu 已提交
68 69 70
}

Status EMPlanner::Init(const PlanningConfig& config) {
J
Jiangtao Hu 已提交
71
  AINFO << "In EMPlanner::Init()";
J
Jiangtao Hu 已提交
72 73 74 75
  RegisterOptimizers();
  for (int i = 0; i < config.em_planner_config().optimizer_size(); ++i) {
    optimizers_.emplace_back(optimizer_factory_.CreateObject(
        config.em_planner_config().optimizer(i)));
76
    AINFO << "Created optimizer:" << optimizers_.back()->name();
J
Jiangtao Hu 已提交
77
  }
78 79
  for (auto& optimizer : optimizers_) {
    if (!optimizer->Init()) {
J
Jiangtao Hu 已提交
80
      std::string msg(common::util::StrCat("Init optimizer[", optimizer->name(),
D
Dong Li 已提交
81
                                           "] failed."));
J
Jiangtao Hu 已提交
82 83
      AERROR << msg;
      return Status(ErrorCode::PLANNING_ERROR, msg);
84 85
    }
  }
J
Jiangtao Hu 已提交
86 87 88
  return Status::OK();
}

89
Status EMPlanner::Plan(const TrajectoryPoint& start_point,
90
                       ADCTrajectory* trajectory_pb) {
J
Jiangtao Hu 已提交
91
  DataCenter* data_center = DataCenter::instance();
J
Jiangtao Hu 已提交
92
  Frame* frame = data_center->current_frame();
J
Jiangtao Hu 已提交
93

94 95 96 97
  if (data_center->last_frame()) {
    ADEBUG << "last frame:" << data_center->last_frame()->DebugString();
  }
  ADEBUG << "start point:" << start_point.DebugString();
98 99
  auto planning_data = frame->mutable_planning_data();
  planning_data->set_init_planning_point(start_point);
100

101 102
  std::shared_ptr<DecisionData> decision_data(new DecisionData());

103
  planning_data->set_decision_data(decision_data);
104
  for (auto& optimizer : optimizers_) {
J
Jiangtao Hu 已提交
105
    const double start_timestamp = apollo::common::time::ToSecond(Clock::Now());
106
    optimizer->Optimize(planning_data);
J
Jiangtao Hu 已提交
107 108 109
    const double end_timestamp = apollo::common::time::ToSecond(Clock::Now());
    const double time_diff_ms = (end_timestamp - start_timestamp) * 1000;

D
Dong Li 已提交
110 111
    ADEBUG << "after optimizer " << optimizer->name() << ":"
           << planning_data->DebugString();
112 113 114 115 116 117 118

    if (FLAGS_enable_record_debug) {
      // Save each path after path-optimizers .
      OptimizerType type;
      CHECK(OptimizerType_Parse(optimizer->name(), &type));
      if (type == DP_POLY_PATH_OPTIMIZER || type == QP_SPLINE_PATH_OPTIMIZER) {
        const auto& path_points =
119
            planning_data->path_data().discretized_path().points();
120 121 122
        auto* optimized_path =
            trajectory_pb->mutable_debug()->mutable_planning_data()->add_path();
        optimized_path->set_name(optimizer->name());
123 124
        optimized_path->mutable_path_point()->CopyFrom(
            {path_points.begin(), path_points.end()});
125
      }
J
Jiangtao Hu 已提交
126 127 128
      auto stats = trajectory_pb->mutable_latency_stats()->add_processor_stats();
      stats->set_name(optimizer->name());
      stats->set_time_ms(time_diff_ms);
129
    }
130
  }
131 132 133
  PublishableTrajectory computed_trajectory;
  if (!planning_data->aggregate(FLAGS_output_trajectory_time_resolution,
                                &computed_trajectory)) {
134 135 136
    std::string msg("Fail to aggregate planning trajectory.");
    AERROR << msg;
    return Status(ErrorCode::PLANNING_ERROR, msg);
137
  }
138
  frame->set_computed_trajectory(computed_trajectory);
139 140 141
  computed_trajectory.populate_trajectory_protobuf(trajectory_pb);

  // Add debug information.
142
  if (FLAGS_enable_record_debug) {
A
Aaron Xiao 已提交
143
    auto* reference_line =
144
        trajectory_pb->mutable_debug()->mutable_planning_data()->add_path();
A
Aaron Xiao 已提交
145
    reference_line->set_name("planning_reference_line");
146 147
    const auto& reference_points =
        planning_data->reference_line().reference_points();
148 149
    reference_line->mutable_path_point()->CopyFrom(
        {reference_points.begin(), reference_points.end()});
150
  }
151

J
Jiangtao Hu 已提交
152
  return Status::OK();
D
Dong Li 已提交
153 154 155 156
}

std::vector<SpeedPoint> EMPlanner::GenerateInitSpeedProfile(
    const double init_v, const double init_a) {
157
  // TODO(@lianglia-apollo): this is a dummy simple hot start, need refine later
D
Dong Li 已提交
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
  std::array<double, 3> start_state;

  // distance 0.0
  start_state[0] = 0.0;

  // start velocity
  start_state[1] = init_v;

  // start acceleration
  start_state[2] = init_a;

  std::array<double, 2> end_state;
  // end state velocity
  end_state[0] = 10.0;

  // end state acceleration
  end_state[1] = 0.0;

  // pre assume the curve time is 8 second, can be change later
  QuarticPolynomialCurve1d speed_curve(start_state, end_state,
                                       FLAGS_trajectory_time_length);

  // assume the time resolution is 0.1
181 182
  std::uint32_t num_time_steps =
      static_cast<std::uint32_t>(FLAGS_trajectory_time_length /
183
                                 FLAGS_trajectory_time_resolution) +
184
      1;
D
Dong Li 已提交
185 186 187
  std::vector<SpeedPoint> speed_profile;
  speed_profile.reserve(num_time_steps);

188
  for (std::uint32_t i = 0; i < num_time_steps; ++i) {
D
Dong Li 已提交
189 190 191 192
    double t = i * FLAGS_trajectory_time_resolution;
    double s = speed_curve.evaluate(0, t);
    double v = speed_curve.evaluate(1, t);
    double a = speed_curve.evaluate(2, t);
193 194
    double da = speed_curve.evaluate(3, t);
    SpeedPoint speed_point;
195 196
    speed_point.set_s(s);
    speed_point.set_t(t);
197 198 199 200
    speed_point.set_v(v);
    speed_point.set_a(a);
    speed_point.set_da(da);
    speed_profile.push_back(speed_point);
D
Dong Li 已提交
201 202 203
  }
  return std::move(speed_profile);
}
204

D
Dong Li 已提交
205
}  // namespace planning
206
}  // namespace apollo