planning_test_base.cc 8.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/******************************************************************************
 * 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.
 *****************************************************************************/

17
#include "modules/planning/integration_tests/planning_test_base.h"
18

19 20 21
#include <cstdlib>

#include "google/protobuf/io/zero_copy_stream_impl.h"
D
Dong Li 已提交
22
#include "modules/common/log.h"
23
#include "modules/common/vehicle_state/vehicle_state_provider.h"
24
#include "modules/planning/common/planning_gflags.h"
D
Dong Li 已提交
25

26 27 28 29 30
namespace apollo {
namespace planning {

using common::adapter::AdapterManager;

31 32 33
DEFINE_string(test_data_dir, "", "the test data folder");
DEFINE_bool(test_update_golden_log, false,
            "true to update decision golden log file.");
34
DEFINE_string(test_routing_response_file, "garage_routing.pb.txt",
35
              "The routing file used in test");
36 37 38
DEFINE_string(test_localization_file, "garage_localization.pb.txt",
              "The localization test file");
DEFINE_string(test_chassis_file, "garage_chassis.pb.txt",
39
              "The chassis test file");
40
DEFINE_string(test_prediction_file, "", "The prediction module test file");
D
Dong Li 已提交
41
DEFINE_string(test_traffic_light_file, "", "The traffic light test file");
42

43 44 45
DEFINE_string(test_previous_planning_file, "",
              "The previous planning test file");

D
Dong Li 已提交
46
void PlanningTestBase::SetUpTestCase() {
47
  FLAGS_planning_config_file = "modules/planning/conf/planning_config.pb.txt";
S
siyangy 已提交
48 49
  FLAGS_planning_adapter_config_filename =
      "modules/planning/testdata/conf/adapter.conf";
50
  FLAGS_map_dir = "modules/planning/testdata";
51 52 53
  FLAGS_test_localization_file = "garage_localization.pb.txt";
  FLAGS_test_chassis_file = "garage_chassis.pb.txt";
  FLAGS_test_prediction_file = "garage_prediction.pb.txt";
54
  FLAGS_align_prediction_time = false;
55
  FLAGS_estimate_current_vehicle_state = false;
D
Dong Li 已提交
56
  FLAGS_enable_reference_line_provider_thread = false;
57
  FLAGS_enable_trajectory_check = true;
58
  FLAGS_planning_test_mode = true;
59
  FLAGS_enable_lag_prediction = false;
60 61
}

62
bool PlanningTestBase::SetUpAdapters() {
63
  if (!AdapterManager::Initialized()) {
S
siyangy 已提交
64
    AdapterManager::Init(FLAGS_planning_adapter_config_filename);
65
  }
66
  if (!AdapterManager::GetRoutingResponse()) {
67
    AERROR << "routing is not registered in adapter manager, check adapter "
68
              "config file."
S
siyangy 已提交
69
           << FLAGS_planning_adapter_config_filename;
70 71
    return false;
  }
72 73 74 75
  auto routing_response_file =
      FLAGS_test_data_dir + "/" + FLAGS_test_routing_response_file;
  if (!AdapterManager::FeedRoutingResponseFile(routing_response_file)) {
    AERROR << "failed to routing file: " << routing_response_file;
76 77
    return false;
  }
78 79 80 81 82
  AINFO << "Using Routing " << routing_response_file;
  auto localization_file =
      FLAGS_test_data_dir + "/" + FLAGS_test_localization_file;
  if (!AdapterManager::FeedLocalizationFile(localization_file)) {
    AERROR << "Failed to load localization file: " << localization_file;
83 84
    return false;
  }
85 86 87 88
  AINFO << "Using Localization file: " << localization_file;
  auto chassis_file = FLAGS_test_data_dir + "/" + FLAGS_test_chassis_file;
  if (!AdapterManager::FeedChassisFile(chassis_file)) {
    AERROR << "Failed to load chassis file: " << chassis_file;
89
    return false;
90
  }
91
  AINFO << "Using Chassis file: " << chassis_file;
D
Dong Li 已提交
92
  if (FLAGS_enable_prediction && !FLAGS_test_prediction_file.empty()) {
93 94
    auto prediction_file =
        FLAGS_test_data_dir + "/" + FLAGS_test_prediction_file;
D
Dong Li 已提交
95
    if (!AdapterManager::FeedPredictionFile(prediction_file)) {
96 97 98 99 100 101
      AERROR << "Failed to load prediction file: " << prediction_file;
      return false;
    }
    AINFO << "Using Prediction file: " << prediction_file;
  } else {
    AINFO << "Prediction is disabled";
102
  }
D
Dong Li 已提交
103 104 105 106 107 108 109 110 111 112 113
  if (FLAGS_enable_traffic_light && !FLAGS_test_traffic_light_file.empty()) {
    auto traffic_light_file =
        FLAGS_test_data_dir + "/" + FLAGS_test_traffic_light_file;
    if (!AdapterManager::FeedTrafficLightDetectionFile(traffic_light_file)) {
      AERROR << "Failed to load traffic light file: " << traffic_light_file;
      return false;
    }
    AINFO << "Using Traffic Light file: " << traffic_light_file;
  } else {
    AINFO << "Traffic Light is disabled";
  }
114 115 116
  return true;
}

117
void PlanningTestBase::SetUp() {
118
  planning_.Stop();
D
Dong Li 已提交
119
  CHECK(SetUpAdapters()) << "Failed to setup adapters";
120
  CHECK(planning_.Init().ok()) << "Failed to init planning module";
121 122 123 124 125 126 127
  if (!FLAGS_test_previous_planning_file.empty()) {
    const auto prev_planning_file =
        FLAGS_test_data_dir + "/" + FLAGS_test_previous_planning_file;
    ADCTrajectory prev_planning;
    CHECK(common::util::GetProtoFromFile(prev_planning_file, &prev_planning));
    planning_.SetLastPublishableTrajectory(prev_planning);
  }
128 129
}

130
void PlanningTestBase::TrimPlanning(ADCTrajectory* origin) {
D
Dong Li 已提交
131 132
  origin->clear_latency_stats();
  origin->clear_debug();
133 134 135 136
  origin->mutable_header()->clear_radar_timestamp();
  origin->mutable_header()->clear_lidar_timestamp();
  origin->mutable_header()->clear_timestamp_sec();
  origin->mutable_header()->clear_camera_timestamp();
137
  origin->mutable_header()->clear_sequence_num();
138 139 140 141 142 143
}

bool PlanningTestBase::RunPlanning(const std::string& test_case_name,
                                   int case_num) {
  const std::string golden_result_file = apollo::common::util::StrCat(
      "result_", test_case_name, "_", case_num, ".pb.txt");
144

145
  std::string full_golden_path = FLAGS_test_data_dir + "/" + golden_result_file;
146
  planning_.RunOnce();
147 148 149

  const ADCTrajectory* trajectory_pointer =
      AdapterManager::GetPlanning()->GetLatestPublished();
150

151
  if (!trajectory_pointer) {
152 153 154
    AERROR << " did not get latest adc trajectory";
    return false;
  }
155

156 157 158 159 160
  if (!IsValidTrajectory(*trajectory_pointer)) {
    AERROR << "Fail to pass trajectory check.";
    return false;
  }

161 162
  adc_trajectory_ = *trajectory_pointer;
  TrimPlanning(&adc_trajectory_);
163
  if (FLAGS_test_update_golden_log) {
164
    AINFO << "The golden file is regenerated:" << full_golden_path;
165
    common::util::SetProtoToASCIIFile(adc_trajectory_, full_golden_path);
166 167
  } else {
    ADCTrajectory golden_result;
168 169
    bool load_success =
        common::util::GetProtoFromASCIIFile(full_golden_path, &golden_result);
170
    TrimPlanning(&golden_result);
171
    if (!load_success ||
Z
Zhang Liangliang 已提交
172
        !common::util::IsProtoEqual(golden_result, adc_trajectory_)) {
173 174
      char tmp_fname[100] = "/tmp/XXXXXX";
      int fd = mkstemp(tmp_fname);
Z
Zhang Liangliang 已提交
175
      if (!common::util::SetProtoToASCIIFile(adc_trajectory_, fd)) {
176 177 178
        AERROR << "Failed to write to file " << tmp_fname;
      }
      AERROR << "found\ndiff " << tmp_fname << " " << full_golden_path;
D
Dong Li 已提交
179
      AERROR << "visualize diff\npython "
180 181
                "modules/tools/plot_trace/plot_planning_result.py "
             << tmp_fname << " " << full_golden_path;
182 183 184 185
      return false;
    }
  }
  return true;
186 187
}

188 189 190 191
bool PlanningTestBase::IsValidTrajectory(const ADCTrajectory& trajectory) {
  for (int i = 0; i < trajectory.trajectory_point_size(); ++i) {
    const auto& point = trajectory.trajectory_point(i);

192 193 194 195
    const double kMaxAccelThreshold =
        FLAGS_longitudinal_acceleration_upper_bound;
    const double kMinAccelThreshold =
        FLAGS_longitudinal_acceleration_lower_bound;
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
    if (point.a() > kMaxAccelThreshold || point.a() < kMinAccelThreshold) {
      AERROR << "Invalid trajectory point because accel out of range: "
             << point.DebugString();
      return false;
    }

    if (!point.has_path_point()) {
      AERROR << "Invalid trajectory point because NO path_point in "
                "trajectory_point: "
             << point.DebugString();
      return false;
    }

    if (i > 0) {
      const double kPathSEpsilon = 1e-3;
      const auto& last_point = trajectory.trajectory_point(i - 1);
      if (point.path_point().s() + kPathSEpsilon <
          last_point.path_point().s()) {
        AERROR << "Invalid trajectory point because s value error. last point: "
               << last_point.DebugString()
               << ", curr point: " << point.DebugString();
        return false;
      }
    }
  }
  return true;
}

224 225
}  // namespace planning
}  // namespace apollo