Sfoglia il codice sorgente

add testhdmap for test apollo hdmap. only compile ok.

yuchuli 1 mese fa
parent
commit
32d57da293
100 ha cambiato i file con 10239 aggiunte e 0 eliminazioni
  1. 3 0
      src/test/testhdmap/Readme.md
  2. 7 0
      src/test/testhdmap/apolloprotomake.sh
  3. 75 0
      src/test/testhdmap/cyber/base/macros.h
  4. 42 0
      src/test/testhdmap/cyber/binary.cc
  5. 31 0
      src/test/testhdmap/cyber/binary.h
  6. 530 0
      src/test/testhdmap/cyber/common/file.cc
  7. 273 0
      src/test/testhdmap/cyber/common/file.h
  8. 145 0
      src/test/testhdmap/cyber/common/log.h
  9. 75 0
      src/test/testhdmap/cyber/common/macros.h
  10. 49 0
      src/test/testhdmap/cyber/common/types.h
  11. 8 0
      src/test/testhdmap/main.cpp
  12. 88 0
      src/test/testhdmap/modules/common/configs/config_gflags.cc
  13. 58 0
      src/test/testhdmap/modules/common/configs/config_gflags.h
  14. 155 0
      src/test/testhdmap/modules/common/math/aabox2d.cc
  15. 228 0
      src/test/testhdmap/modules/common/math/aabox2d.h
  16. 471 0
      src/test/testhdmap/modules/common/math/aaboxkdtree2d.h
  17. 426 0
      src/test/testhdmap/modules/common/math/box2d.cc
  18. 299 0
      src/test/testhdmap/modules/common/math/box2d.h
  19. 229 0
      src/test/testhdmap/modules/common/math/line_segment2d.cc
  20. 227 0
      src/test/testhdmap/modules/common/math/line_segment2d.h
  21. 115 0
      src/test/testhdmap/modules/common/math/linear_interpolation.cc
  22. 86 0
      src/test/testhdmap/modules/common/math/linear_interpolation.h
  23. 108 0
      src/test/testhdmap/modules/common/math/math_utils.cc
  24. 224 0
      src/test/testhdmap/modules/common/math/math_utils.h
  25. 640 0
      src/test/testhdmap/modules/common/math/polygon2d.cc
  26. 341 0
      src/test/testhdmap/modules/common/math/polygon2d.h
  27. 131 0
      src/test/testhdmap/modules/common/math/vec2d.cc
  28. 135 0
      src/test/testhdmap/modules/common/math/vec2d.h
  29. 130 0
      src/test/testhdmap/modules/common/status/status.h
  30. 46 0
      src/test/testhdmap/modules/common/util/future.h
  31. 70 0
      src/test/testhdmap/modules/common/util/string_util.cc
  32. 53 0
      src/test/testhdmap/modules/common/util/string_util.h
  33. 51 0
      src/test/testhdmap/modules/common/util/util.cc
  34. 166 0
      src/test/testhdmap/modules/common/util/util.h
  35. BIN
      src/test/testhdmap/modules/common_msgs/.DS_Store
  36. 7 0
      src/test/testhdmap/modules/common_msgs/BUILD
  37. 36 0
      src/test/testhdmap/modules/common_msgs/README.md
  38. 32 0
      src/test/testhdmap/modules/common_msgs/audio_msgs/BUILD
  39. 31 0
      src/test/testhdmap/modules/common_msgs/audio_msgs/audio.proto
  40. 41 0
      src/test/testhdmap/modules/common_msgs/audio_msgs/audio_common.proto
  41. 34 0
      src/test/testhdmap/modules/common_msgs/audio_msgs/audio_event.proto
  42. 59 0
      src/test/testhdmap/modules/common_msgs/basic_msgs/BUILD
  43. 14 0
      src/test/testhdmap/modules/common_msgs/basic_msgs/direction.proto
  44. 21 0
      src/test/testhdmap/modules/common_msgs/basic_msgs/drive_event.proto
  45. 17 0
      src/test/testhdmap/modules/common_msgs/basic_msgs/drive_state.proto
  46. 78 0
      src/test/testhdmap/modules/common_msgs/basic_msgs/error_code.proto
  47. 62 0
      src/test/testhdmap/modules/common_msgs/basic_msgs/geometry.proto
  48. 33 0
      src/test/testhdmap/modules/common_msgs/basic_msgs/header.proto
  49. 106 0
      src/test/testhdmap/modules/common_msgs/basic_msgs/pnc_point.proto
  50. 9 0
      src/test/testhdmap/modules/common_msgs/basic_msgs/vehicle_id.proto
  51. 18 0
      src/test/testhdmap/modules/common_msgs/basic_msgs/vehicle_signal.proto
  52. 29 0
      src/test/testhdmap/modules/common_msgs/chassis_msgs/BUILD
  53. 259 0
      src/test/testhdmap/modules/common_msgs/chassis_msgs/chassis.proto
  54. 982 0
      src/test/testhdmap/modules/common_msgs/chassis_msgs/chassis_detail.proto
  55. 14 0
      src/test/testhdmap/modules/common_msgs/common-msgs.BUILD
  56. 17 0
      src/test/testhdmap/modules/common_msgs/config_msgs/BUILD
  57. 101 0
      src/test/testhdmap/modules/common_msgs/config_msgs/vehicle_config.proto
  58. 38 0
      src/test/testhdmap/modules/common_msgs/control_msgs/BUILD
  59. 278 0
      src/test/testhdmap/modules/common_msgs/control_msgs/control_cmd.proto
  60. 11 0
      src/test/testhdmap/modules/common_msgs/control_msgs/input_debug.proto
  61. 18 0
      src/test/testhdmap/modules/common_msgs/control_msgs/pad_msg.proto
  62. 27 0
      src/test/testhdmap/modules/common_msgs/cyberfile.xml
  63. 53 0
      src/test/testhdmap/modules/common_msgs/dreamview_msgs/BUILD
  64. 76 0
      src/test/testhdmap/modules/common_msgs/dreamview_msgs/chart.proto
  65. 56 0
      src/test/testhdmap/modules/common_msgs/dreamview_msgs/hmi_config.proto
  66. 130 0
      src/test/testhdmap/modules/common_msgs/dreamview_msgs/hmi_mode.proto
  67. 129 0
      src/test/testhdmap/modules/common_msgs/dreamview_msgs/hmi_status.proto
  68. 303 0
      src/test/testhdmap/modules/common_msgs/dreamview_msgs/simulation_world.proto
  69. 12 0
      src/test/testhdmap/modules/common_msgs/drivers_msgs/BUILD
  70. 55 0
      src/test/testhdmap/modules/common_msgs/drivers_msgs/can_card_parameter.proto
  71. 89 0
      src/test/testhdmap/modules/common_msgs/external_command_msgs/BUILD
  72. 36 0
      src/test/testhdmap/modules/common_msgs/external_command_msgs/action_command.proto
  73. 17 0
      src/test/testhdmap/modules/common_msgs/external_command_msgs/chassis_command.proto
  74. 32 0
      src/test/testhdmap/modules/common_msgs/external_command_msgs/command_status.proto
  75. 24 0
      src/test/testhdmap/modules/common_msgs/external_command_msgs/free_space_command.proto
  76. 26 0
      src/test/testhdmap/modules/common_msgs/external_command_msgs/geometry.proto
  77. 27 0
      src/test/testhdmap/modules/common_msgs/external_command_msgs/lane_follow_command.proto
  78. 13 0
      src/test/testhdmap/modules/common_msgs/external_command_msgs/lane_segment.proto
  79. 43 0
      src/test/testhdmap/modules/common_msgs/external_command_msgs/path_follow_command.proto
  80. 22 0
      src/test/testhdmap/modules/common_msgs/external_command_msgs/speed_command.proto
  81. 27 0
      src/test/testhdmap/modules/common_msgs/external_command_msgs/valet_parking_command.proto
  82. 16 0
      src/test/testhdmap/modules/common_msgs/guardian_msgs/BUILD
  83. 10 0
      src/test/testhdmap/modules/common_msgs/guardian_msgs/guardian.proto
  84. 50 0
      src/test/testhdmap/modules/common_msgs/localization_msgs/BUILD
  85. 13 0
      src/test/testhdmap/modules/common_msgs/localization_msgs/gps.proto
  86. 13 0
      src/test/testhdmap/modules/common_msgs/localization_msgs/imu.proto
  87. 81 0
      src/test/testhdmap/modules/common_msgs/localization_msgs/localization.proto
  88. 175 0
      src/test/testhdmap/modules/common_msgs/localization_msgs/localization_status.proto
  89. 65 0
      src/test/testhdmap/modules/common_msgs/localization_msgs/pose.proto
  90. 165 0
      src/test/testhdmap/modules/common_msgs/map_msgs/BUILD
  91. 58 0
      src/test/testhdmap/modules/common_msgs/map_msgs/map.proto
  92. 14 0
      src/test/testhdmap/modules/common_msgs/map_msgs/map_clear_area.proto
  93. 15 0
      src/test/testhdmap/modules/common_msgs/map_msgs/map_crosswalk.proto
  94. 31 0
      src/test/testhdmap/modules/common_msgs/map_msgs/map_geometry.proto
  95. 8 0
      src/test/testhdmap/modules/common_msgs/map_msgs/map_id.proto
  96. 24 0
      src/test/testhdmap/modules/common_msgs/map_msgs/map_junction.proto
  97. 109 0
      src/test/testhdmap/modules/common_msgs/map_msgs/map_lane.proto
  98. 71 0
      src/test/testhdmap/modules/common_msgs/map_msgs/map_overlap.proto
  99. 26 0
      src/test/testhdmap/modules/common_msgs/map_msgs/map_parking_space.proto
  100. 38 0
      src/test/testhdmap/modules/common_msgs/map_msgs/map_pnc_junction.proto

+ 3 - 0
src/test/testhdmap/Readme.md

@@ -0,0 +1,3 @@
+测试apollo hdmap的工程,
+使用apolloprotomake生成必要的pb文件。
+proj的问题没有解决,暂时忽略。

+ 7 - 0
src/test/testhdmap/apolloprotomake.sh

@@ -0,0 +1,7 @@
+ protoc ./modules/common_msgs/basic_msgs/*.proto  -I=./ --cpp_out=./
+ protoc ./modules/common_msgs/localization_msgs/*.proto  -I=./ --cpp_out=./
+ protoc ./modules/common_msgs/map_msgs/*.proto  -I=./ --cpp_out=./
+ protoc ./modules/common_msgs/perception_msgs/*.proto  -I=./ --cpp_out=./
+ protoc ./modules/common_msgs/planning_msgs/*.proto  -I=./ --cpp_out=./ 
+
+ 

+ 75 - 0
src/test/testhdmap/cyber/base/macros.h

@@ -0,0 +1,75 @@
+/******************************************************************************
+ * Copyright 2018 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.
+ *****************************************************************************/
+
+#ifndef CYBER_BASE_MACROS_H_
+#define CYBER_BASE_MACROS_H_
+
+#include <cstdlib>
+#include <new>
+
+#if __GNUC__ >= 3
+#define cyber_likely(x) (__builtin_expect((x), 1))
+#define cyber_unlikely(x) (__builtin_expect((x), 0))
+#else
+#define cyber_likely(x) (x)
+#define cyber_unlikely(x) (x)
+#endif
+
+#define CACHELINE_SIZE 64
+
+#define DEFINE_TYPE_TRAIT(name, func)                     \
+  template <typename T>                                   \
+  struct name {                                           \
+    template <typename Class>                             \
+    static constexpr bool Test(decltype(&Class::func)*) { \
+      return true;                                        \
+    }                                                     \
+    template <typename>                                   \
+    static constexpr bool Test(...) {                     \
+      return false;                                       \
+    }                                                     \
+                                                          \
+    static constexpr bool value = Test<T>(nullptr);       \
+  };                                                      \
+                                                          \
+  template <typename T>                                   \
+  constexpr bool name<T>::value;
+
+inline void cpu_relax() {
+#if defined(__aarch64__)
+  asm volatile("yield" ::: "memory");
+#else
+  asm volatile("rep; nop" ::: "memory");
+#endif
+}
+
+inline void* CheckedMalloc(size_t size) {
+  void* ptr = std::malloc(size);
+  if (!ptr) {
+    throw std::bad_alloc();
+  }
+  return ptr;
+}
+
+inline void* CheckedCalloc(size_t num, size_t size) {
+  void* ptr = std::calloc(num, size);
+  if (!ptr) {
+    throw std::bad_alloc();
+  }
+  return ptr;
+}
+
+#endif  // CYBER_BASE_MACROS_H_

+ 42 - 0
src/test/testhdmap/cyber/binary.cc

@@ -0,0 +1,42 @@
+/******************************************************************************
+ * Copyright 2018 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 "cyber/binary.h"
+
+#include <mutex>
+#include <string>
+
+namespace {
+std::mutex m;
+std::string binary_name; // NOLINT
+}  // namespace
+
+namespace apollo {
+namespace cyber {
+namespace binary {
+
+std::string GetName() {
+  std::lock_guard<std::mutex> lock(m);
+  return binary_name;
+}
+void SetName(const std::string& name) {
+  std::lock_guard<std::mutex> lock(m);
+  binary_name = name;
+}
+
+}  // namespace binary
+}  // namespace cyber
+}  // namespace apollo

+ 31 - 0
src/test/testhdmap/cyber/binary.h

@@ -0,0 +1,31 @@
+/******************************************************************************
+ * Copyright 2018 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.
+ *****************************************************************************/
+
+#ifndef CYBER_BINARY_H_
+#define CYBER_BINARY_H_
+
+#include <string>
+
+namespace apollo {
+namespace cyber {
+namespace binary {
+std::string GetName();
+void SetName(const std::string& name);
+}  // namespace binary
+}  // namespace cyber
+}  // namespace apollo
+
+#endif  // CYBER_BINARY_H_

+ 530 - 0
src/test/testhdmap/cyber/common/file.cc

@@ -0,0 +1,530 @@
+/******************************************************************************
+ * Copyright 2018 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 "cyber/common/file.h"
+
+#include <dirent.h>
+#include <fcntl.h>
+#include <glob.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <cerrno>
+#include <cstddef>
+#include <fstream>
+#include <string>
+
+#include "google/protobuf/util/json_util.h"
+#include "nlohmann/json.hpp"
+
+namespace apollo {
+namespace cyber {
+namespace common {
+
+using std::istreambuf_iterator;
+using std::string;
+using std::vector;
+
+bool SetProtoToASCIIFile(const google::protobuf::Message &message,
+                         int file_descriptor) {
+  using google::protobuf::TextFormat;
+  using google::protobuf::io::FileOutputStream;
+  using google::protobuf::io::ZeroCopyOutputStream;
+  if (file_descriptor < 0) {
+    AERROR << "Invalid file descriptor.";
+    return false;
+  }
+  ZeroCopyOutputStream *output = new FileOutputStream(file_descriptor);
+  bool success = TextFormat::Print(message, output);
+  delete output;
+  close(file_descriptor);
+  return success;
+}
+
+bool SetProtoToASCIIFile(const google::protobuf::Message &message,
+                         const std::string &file_name) {
+  int fd = open(file_name.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU);
+  if (fd < 0) {
+    AERROR << "Unable to open file " << file_name << " to write.";
+    return false;
+  }
+  return SetProtoToASCIIFile(message, fd);
+}
+
+bool GetProtoFromASCIIFile(const std::string &file_name,
+                           google::protobuf::Message *message) {
+  using google::protobuf::TextFormat;
+  using google::protobuf::io::FileInputStream;
+  using google::protobuf::io::ZeroCopyInputStream;
+  int file_descriptor = open(file_name.c_str(), O_RDONLY);
+  if (file_descriptor < 0) {
+    AERROR << "Failed to open file " << file_name << " in text mode.";
+    // Failed to open;
+    return false;
+  }
+
+  ZeroCopyInputStream *input = new FileInputStream(file_descriptor);
+  bool success = TextFormat::Parse(input, message);
+  if (!success) {
+    AERROR << "Failed to parse file " << file_name << " as text proto.";
+  }
+  delete input;
+  close(file_descriptor);
+  return success;
+}
+
+bool SetProtoToBinaryFile(const google::protobuf::Message &message,
+                          const std::string &file_name) {
+  std::fstream output(file_name,
+                      std::ios::out | std::ios::trunc | std::ios::binary);
+  return message.SerializeToOstream(&output);
+}
+
+bool GetProtoFromBinaryFile(const std::string &file_name,
+                            google::protobuf::Message *message) {
+  std::fstream input(file_name, std::ios::in | std::ios::binary);
+  if (!input.good()) {
+    AERROR << "Failed to open file " << file_name << " in binary mode.";
+    return false;
+  }
+  if (!message->ParseFromIstream(&input)) {
+    AERROR << "Failed to parse file " << file_name << " as binary proto.";
+    return false;
+  }
+  return true;
+}
+
+bool GetProtoFromFile(const std::string &file_name,
+                      google::protobuf::Message *message) {
+  if (!PathExists(file_name)) {
+    AERROR << "File [" << file_name << "] does not exist! ";
+    return false;
+  }
+  // Try the binary parser first if it's much likely a binary proto.
+  static const std::string kBinExt = ".bin";
+  if (std::equal(kBinExt.rbegin(), kBinExt.rend(), file_name.rbegin())) {
+    return GetProtoFromBinaryFile(file_name, message) ||
+           GetProtoFromASCIIFile(file_name, message);
+  }
+
+  return GetProtoFromASCIIFile(file_name, message) ||
+         GetProtoFromBinaryFile(file_name, message);
+}
+
+bool GetProtoFromJsonFile(const std::string &file_name,
+                          google::protobuf::Message *message) {
+  using google::protobuf::util::JsonParseOptions;
+  using google::protobuf::util::JsonStringToMessage;
+  std::ifstream ifs(file_name);
+  if (!ifs.is_open()) {
+    AERROR << "Failed to open file " << file_name;
+    return false;
+  }
+  nlohmann::json Json;
+  ifs >> Json;
+  ifs.close();
+  JsonParseOptions options;
+  options.ignore_unknown_fields = true;
+  google::protobuf::util::Status dump_status;
+  return (JsonStringToMessage(Json.dump(), message, options).ok());
+}
+
+bool GetContent(const std::string &file_name, std::string *content) {
+  std::ifstream fin(file_name);
+  if (!fin) {
+    return false;
+  }
+
+  std::stringstream str_stream;
+  str_stream << fin.rdbuf();
+  *content = str_stream.str();
+  return true;
+}
+
+std::string GetAbsolutePath(const std::string &prefix,
+                            const std::string &relative_path) {
+  if (relative_path.empty()) {
+    return prefix;
+  }
+  // If prefix is empty or relative_path is already absolute.
+  if (prefix.empty() || relative_path.front() == '/') {
+    return relative_path;
+  }
+
+  if (prefix.back() == '/') {
+    return prefix + relative_path;
+  }
+  return prefix + "/" + relative_path;
+}
+
+bool PathExists(const std::string &path) {
+  struct stat info;
+  return stat(path.c_str(), &info) == 0;
+}
+
+bool PathIsAbsolute(const std::string &path) {
+  if (path.empty()) {
+    return false;
+  }
+  return path.front() == '/';
+}
+
+bool DirectoryExists(const std::string &directory_path) {
+  struct stat info;
+  return stat(directory_path.c_str(), &info) == 0 && (info.st_mode & S_IFDIR);
+}
+
+std::vector<std::string> Glob(const std::string &pattern) {
+  glob_t globs = {};
+  std::vector<std::string> results;
+  if (glob(pattern.c_str(), GLOB_TILDE, nullptr, &globs) == 0) {
+    for (size_t i = 0; i < globs.gl_pathc; ++i) {
+      results.emplace_back(globs.gl_pathv[i]);
+    }
+  }
+  globfree(&globs);
+  return results;
+}
+
+bool CopyFile(const std::string &from, const std::string &to) {
+  std::ifstream src(from, std::ios::binary);
+  if (!src) {
+    AWARN << "Source path could not be normally opened: " << from;
+    std::string command = "cp -r " + from + " " + to;
+    ADEBUG << command;
+    const int ret = std::system(command.c_str());
+    if (ret == 0) {
+      ADEBUG << "Copy success, command returns " << ret;
+      return true;
+    } else {
+      ADEBUG << "Copy error, command returns " << ret;
+      return false;
+    }
+  }
+
+  std::ofstream dst(to, std::ios::binary);
+  if (!dst) {
+    AERROR << "Target path is not writable: " << to;
+    return false;
+  }
+
+  dst << src.rdbuf();
+  return true;
+}
+
+bool CopyDir(const std::string &from, const std::string &to) {
+  DIR *directory = opendir(from.c_str());
+  if (directory == nullptr) {
+    AERROR << "Cannot open directory " << from;
+    return false;
+  }
+
+  bool ret = true;
+  if (EnsureDirectory(to)) {
+    struct dirent *entry;
+    while ((entry = readdir(directory)) != nullptr) {
+      // skip directory_path/. and directory_path/..
+      if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..")) {
+        continue;
+      }
+      const std::string sub_path_from = from + "/" + entry->d_name;
+      const std::string sub_path_to = to + "/" + entry->d_name;
+      if (entry->d_type == DT_DIR) {
+        ret &= CopyDir(sub_path_from, sub_path_to);
+      } else {
+        ret &= CopyFile(sub_path_from, sub_path_to);
+      }
+    }
+  } else {
+    AERROR << "Cannot create target directory " << to;
+    ret = false;
+  }
+  closedir(directory);
+  return ret;
+}
+
+bool Copy(const std::string &from, const std::string &to) {
+  return DirectoryExists(from) ? CopyDir(from, to) : CopyFile(from, to);
+}
+
+bool EnsureDirectory(const std::string &directory_path) {
+  std::string path = directory_path;
+  for (size_t i = 1; i < directory_path.size(); ++i) {
+    if (directory_path[i] == '/') {
+      // Whenever a '/' is encountered, create a temporary view from
+      // the start of the path to the character right before this.
+      path[i] = 0;
+
+      if (mkdir(path.c_str(), S_IRWXU) != 0) {
+        if (errno != EEXIST) {
+          return false;
+        }
+      }
+
+      // Revert the temporary view back to the original.
+      path[i] = '/';
+    }
+  }
+
+  // Make the final (full) directory.
+  if (mkdir(path.c_str(), S_IRWXU) != 0) {
+    if (errno != EEXIST) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+bool RemoveAllFiles(const std::string &directory_path) {
+  DIR *directory = opendir(directory_path.c_str());
+  if (directory == nullptr) {
+    AERROR << "Cannot open directory " << directory_path;
+    return false;
+  }
+
+  struct dirent *file;
+  while ((file = readdir(directory)) != nullptr) {
+    // skip directory_path/. and directory_path/..
+    if (!strcmp(file->d_name, ".") || !strcmp(file->d_name, "..")) {
+      continue;
+    }
+    // build the path for each file in the folder
+    std::string file_path = directory_path + "/" + file->d_name;
+    if (unlink(file_path.c_str()) < 0) {
+      AERROR << "Fail to remove file " << file_path << ": " << strerror(errno);
+      closedir(directory);
+      return false;
+    }
+  }
+  closedir(directory);
+  return true;
+}
+
+std::vector<std::string> ListSubPaths(const std::string &directory_path,
+                                      const unsigned char d_type) {
+  std::vector<std::string> result;
+  DIR *directory = opendir(directory_path.c_str());
+  if (directory == nullptr) {
+    AERROR << "Cannot open directory " << directory_path;
+    return result;
+  }
+
+  struct dirent *entry;
+  while ((entry = readdir(directory)) != nullptr) {
+    // Skip "." and "..".
+    if (entry->d_type == d_type && strcmp(entry->d_name, ".") != 0 &&
+        strcmp(entry->d_name, "..") != 0) {
+      result.emplace_back(entry->d_name);
+    }
+  }
+  closedir(directory);
+  return result;
+}
+
+size_t FindPathByPattern(const std::string &base_path, const std::string &patt,
+                         const unsigned char d_type, const bool recursive,
+                         std::vector<std::string> *result_list) {
+  DIR *directory = opendir(base_path.c_str());
+  size_t result_cnt = 0;
+  if (directory == nullptr) {
+    AWARN << "cannot open directory " << base_path;
+    return result_cnt;
+  }
+  struct dirent *entry;
+  for (entry = readdir(directory); entry != nullptr;
+       entry = readdir(directory)) {
+    std::string entry_path = base_path + "/" + std::string(entry->d_name);
+    // skip `.` and `..`
+    if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
+      // TODO(liangjinping): support regex or glob or other pattern mode
+      if ((patt == "" || strcmp(entry->d_name, patt.c_str()) == 0) &&
+          entry->d_type == d_type) {
+        // found
+        result_list->emplace_back(entry_path);
+        ++result_cnt;
+      }
+      if (recursive && (entry->d_type == DT_DIR)) {
+        result_cnt +=
+            FindPathByPattern(entry_path, patt, d_type, recursive, result_list);
+      }
+    }
+  }
+  closedir(directory);
+  return result_cnt;
+}
+
+std::string GetDirName(const std::string &path) {
+  std::string::size_type end = path.rfind('/');
+  if (end == std::string::npos) {
+    // not found, return current dir
+    return ".";
+  }
+  return path.substr(0, end);
+}
+
+std::string GetFileName(const std::string &path, const bool remove_extension) {
+  std::string::size_type start = path.rfind('/');
+  if (start == std::string::npos) {
+    start = 0;
+  } else {
+    // Move to the next char after '/'.
+    ++start;
+  }
+
+  std::string::size_type end = std::string::npos;
+  if (remove_extension) {
+    end = path.rfind('.');
+    // The last '.' is found before last '/', ignore.
+    if (end != std::string::npos && end < start) {
+      end = std::string::npos;
+    }
+  }
+  const auto len = (end != std::string::npos) ? end - start : end;
+  return path.substr(start, len);
+}
+
+bool GetFilePathWithEnv(const std::string &path, const std::string &env_var,
+                        std::string *file_path) {
+  if (path.empty()) {
+    return false;
+  }
+  if (PathIsAbsolute(path)) {
+    // an absolute path
+    *file_path = path;
+    return PathExists(path);
+  }
+
+  bool relative_path_exists = false;
+  if (PathExists(path)) {
+    // relative path exists
+    *file_path = path;
+    relative_path_exists = true;
+  }
+  if (path.front() == '.') {
+    // relative path but not exist.
+    return relative_path_exists;
+  }
+
+  const char *var = std::getenv(env_var.c_str());
+  if (var == nullptr) {
+    AWARN << "GetFilePathWithEnv: env " << env_var << " not found.";
+    return relative_path_exists;
+  }
+  std::string env_path = std::string(var);
+
+  // search by environment variable
+  size_t begin = 0;
+  size_t index;
+  do {
+    index = env_path.find(':', begin);
+    auto p = env_path.substr(begin, index - begin);
+    if (p.empty()) {
+      continue;
+    }
+    if (p.back() != '/') {
+      p += '/' + path;
+    } else {
+      p += path;
+    }
+    if (PathExists(p)) {
+      *file_path = p;
+      return true;
+    }
+    begin = index + 1;
+  } while (index != std::string::npos);
+  return relative_path_exists;
+}
+
+std::string GetCurrentPath() {
+  char tmp[PATH_MAX];
+  return getcwd(tmp, sizeof(tmp)) ? std::string(tmp) : std::string("");
+}
+
+bool GetType(const string &filename, FileType *type) {
+  struct stat stat_buf;
+  if (lstat(filename.c_str(), &stat_buf) != 0) {
+    return false;
+  }
+  if (S_ISDIR(stat_buf.st_mode) != 0) {
+    *type = TYPE_DIR;
+  } else if (S_ISREG(stat_buf.st_mode) != 0) {
+    *type = TYPE_FILE;
+  } else {
+    AWARN << "failed to get type: " << filename;
+    return false;
+  }
+  return true;
+}
+
+bool DeleteFile(const string &filename) {
+  if (!PathExists(filename)) {
+    return true;
+  }
+  FileType type;
+  if (!GetType(filename, &type)) {
+    return false;
+  }
+  if (type == TYPE_FILE) {
+    if (remove(filename.c_str()) != 0) {
+      AERROR << "failed to remove file: " << filename;
+      return false;
+    }
+    return true;
+  }
+  DIR *dir = opendir(filename.c_str());
+  if (dir == nullptr) {
+    AWARN << "failed to opendir: " << filename;
+    return false;
+  }
+  dirent *dir_info = nullptr;
+  while ((dir_info = readdir(dir)) != nullptr) {
+    if (strcmp(dir_info->d_name, ".") == 0 ||
+        strcmp(dir_info->d_name, "..") == 0) {
+      continue;
+    }
+    string temp_file = filename + "/" + string(dir_info->d_name);
+    FileType temp_type;
+    if (!GetType(temp_file, &temp_type)) {
+      AWARN << "failed to get file type: " << temp_file;
+      closedir(dir);
+      return false;
+    }
+    if (type == TYPE_DIR) {
+      DeleteFile(temp_file);
+    }
+    remove(temp_file.c_str());
+  }
+  closedir(dir);
+  remove(filename.c_str());
+  return true;
+}
+
+bool CreateDir(const string &dir) {
+  int ret = mkdir(dir.c_str(), S_IRWXU | S_IRWXG | S_IRWXO);
+  if (ret != 0) {
+    AWARN << "failed to create dir. [dir: " << dir
+          << "] [err: " << strerror(errno) << "]";
+    return false;
+  }
+  return true;
+}
+
+}  // namespace common
+}  // namespace cyber
+}  // namespace apollo

+ 273 - 0
src/test/testhdmap/cyber/common/file.h

@@ -0,0 +1,273 @@
+/******************************************************************************
+ * Copyright 2018 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
+ */
+
+#ifndef CYBER_COMMON_FILE_H_
+#define CYBER_COMMON_FILE_H_
+
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <cstdio>
+#include <fstream>
+#include <string>
+#include <vector>
+
+#include "google/protobuf/io/zero_copy_stream_impl.h"
+#include "google/protobuf/text_format.h"
+
+#include "cyber/common/log.h"
+
+/**
+ * @namespace apollo::common::util
+ * @brief apollo::common::util
+ */
+namespace apollo {
+namespace cyber {
+namespace common {
+
+// file type: file or directory
+enum FileType { TYPE_FILE, TYPE_DIR };
+
+bool SetProtoToASCIIFile(const google::protobuf::Message &message,
+                         int file_descriptor);
+/**
+ * @brief Sets the content of the file specified by the file_name to be the
+ *        ascii representation of the input protobuf.
+ * @param message The proto to output to the specified file.
+ * @param file_name The name of the target file to set the content.
+ * @return If the action is successful.
+ */
+bool SetProtoToASCIIFile(const google::protobuf::Message &message,
+                         const std::string &file_name);
+
+/**
+ * @brief Parses the content of the file specified by the file_name as ascii
+ *        representation of protobufs, and merges the parsed content to the
+ *        proto.
+ * @param file_name The name of the file to parse whose content.
+ * @param message The proto to carry the parsed content in the specified file.
+ * @return If the action is successful.
+ */
+bool GetProtoFromASCIIFile(const std::string &file_name,
+                           google::protobuf::Message *message);
+
+/**
+ * @brief Sets the content of the file specified by the file_name to be the
+ *        binary representation of the input protobuf.
+ * @param message The proto to output to the specified file.
+ * @param file_name The name of the target file to set the content.
+ * @return If the action is successful.
+ */
+bool SetProtoToBinaryFile(const google::protobuf::Message &message,
+                          const std::string &file_name);
+
+/**
+ * @brief Parses the content of the file specified by the file_name as binary
+ *        representation of protobufs, and merges the parsed content to the
+ *        proto.
+ * @param file_name The name of the file to parse whose content.
+ * @param message The proto to carry the parsed content in the specified file.
+ * @return If the action is successful.
+ */
+bool GetProtoFromBinaryFile(const std::string &file_name,
+                            google::protobuf::Message *message);
+
+/**
+ * @brief Parses the content of the file specified by the file_name as a
+ *        representation of protobufs, and merges the parsed content to the
+ *        proto.
+ * @param file_name The name of the file to parse whose content.
+ * @param message The proto to carry the parsed content in the specified file.
+ * @return If the action is successful.
+ */
+bool GetProtoFromFile(const std::string &file_name,
+                      google::protobuf::Message *message);
+
+/**
+ * @brief Parses the content of the json file specified by the file_name as
+ * ascii representation of protobufs, and merges the parsed content to the
+ *        proto.
+ * @param file_name The name of the file to parse whose content.
+ * @param message The proto to carry the parsed content in the specified file.
+ * @return If the action is successful.
+ */
+bool GetProtoFromJsonFile(const std::string &file_name,
+                          google::protobuf::Message *message);
+
+/**
+ * @brief Get file content as string.
+ * @param file_name The name of the file to read content.
+ * @param content The file content.
+ * @return If the action is successful.
+ */
+bool GetContent(const std::string &file_name, std::string *content);
+
+/**
+ * @brief Get absolute path by concatenating prefix and relative_path.
+ * @return The absolute path.
+ */
+std::string GetAbsolutePath(const std::string &prefix,
+                            const std::string &relative_path);
+
+/**
+ * @brief Check if the path exists.
+ * @param path a file name, such as /a/b/c.txt
+ * @return If the path exists.
+ */
+bool PathExists(const std::string &path);
+
+bool PathIsAbsolute(const std::string &path);
+
+/**
+ * @brief Check if the directory specified by directory_path exists
+ *        and is indeed a directory.
+ * @param directory_path Directory path.
+ * @return If the directory specified by directory_path exists
+ *         and is indeed a directory.
+ */
+bool DirectoryExists(const std::string &directory_path);
+
+/**
+ * @brief Expand path pattern to matched paths.
+ * @param pattern Path pattern, which may contain wildcards [?*].
+ * @return Matched path list.
+ */
+std::vector<std::string> Glob(const std::string &pattern);
+
+/**
+ * @brief Copy a file.
+ * @param from The file path to copy from.
+ * @param to The file path to copy to.
+ * @return If the action is successful.
+ */
+bool CopyFile(const std::string &from, const std::string &to);
+
+/**
+ * @brief Copy a directory.
+ * @param from The path to copy from.
+ * @param to The path to copy to.
+ * @return If the action is successful.
+ */
+bool CopyDir(const std::string &from, const std::string &to);
+
+/**
+ * @brief Copy a file or directory.
+ * @param from The path to copy from.
+ * @param to The path to copy to.
+ * @return If the action is successful.
+ */
+bool Copy(const std::string &from, const std::string &to);
+
+/**
+ * @brief Check if a specified directory specified by directory_path exists.
+ *        If not, recursively create the directory (and its parents).
+ * @param directory_path Directory path.
+ * @return If the directory does exist or its creation is successful.
+ */
+bool EnsureDirectory(const std::string &directory_path);
+
+/**
+ * @brief Remove all the files under a specified directory. Note that
+ *        sub-directories are NOT affected.
+ * @param directory_path Directory path.
+ * @return If the action is successful.
+ */
+bool RemoveAllFiles(const std::string &directory_path);
+
+/**
+ * @brief List sub-paths.
+ * @param directory_path Directory path.
+ * @param d_type Sub-path type, DT_DIR for directory, or DT_REG for file.
+ * @return A vector of sub-paths, without the directory_path prefix.
+ */
+std::vector<std::string> ListSubPaths(const std::string &directory_path,
+                                      const unsigned char d_type = DT_DIR);
+
+/**
+ * @brief Find path with pattern
+ * @param base_path search root
+ * @param patt pattern to compare with entry->d_name for filter
+ * @param d_type entry type for filter
+ * @param recursive search directory recursively
+ * @param result_list a vector reference for storing the search result
+ * @return the result count
+ */
+size_t FindPathByPattern(const std::string &base_path, const std::string &patt,
+                         const unsigned char d_type, const bool recursive,
+                         std::vector<std::string> *result_list);
+
+/**
+ * @brief get directory name of path
+ * @param path
+ * @return dirname of path
+ */
+std::string GetDirName(const std::string &path);
+
+std::string GetFileName(const std::string &path,
+                        const bool remove_extension = false);
+
+/**
+ * @brief get file path, judgement priority:
+ * 1. absolute path.
+ * 2. relative path starts with '.'.
+ * 3. add environment variable prefix before the path.
+ * 4. a common relative path.
+ *
+ * @param path input file path string.
+ * @param env_var environment var string.
+ * @param file_path the output file path.
+ *
+ * @return if no valid path found, return false.
+ */
+bool GetFilePathWithEnv(const std::string &path, const std::string &env_var,
+                        std::string *file_path);
+
+std::string GetCurrentPath();
+
+// delete file including file or directory
+bool DeleteFile(const std::string &filename);
+
+bool GetType(const std::string &filename, FileType *type);
+
+bool CreateDir(const std::string &dir);
+
+template <typename T>
+bool LoadConfig(const std::string &relative_path, T *config) {
+  CHECK_NOTNULL(config);
+  // todo: get config base relative path
+  std::string actual_config_path;
+  if (!GetFilePathWithEnv(relative_path, "APOLLO_CONF_PATH",
+                          &actual_config_path)) {
+    AERROR << "conf file [" << relative_path
+           << "] is not found in APOLLO_CONF_PATH";
+    return false;
+  }
+  AINFO << "load conf file: " << actual_config_path;
+  return GetProtoFromFile(actual_config_path, config);
+}
+
+}  // namespace common
+}  // namespace cyber
+}  // namespace apollo
+
+#endif  // CYBER_COMMON_FILE_H_

+ 145 - 0
src/test/testhdmap/cyber/common/log.h

@@ -0,0 +1,145 @@
+/******************************************************************************
+ * Copyright 2018 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.
+ *****************************************************************************/
+
+/**
+ * @log
+ */
+
+#ifndef CYBER_COMMON_LOG_H_
+#define CYBER_COMMON_LOG_H_
+
+#include <cstdarg>
+#include <string>
+
+#include "glog/logging.h"
+#include "glog/raw_logging.h"
+
+#include "cyber/binary.h"
+
+#define LEFT_BRACKET "["
+#define RIGHT_BRACKET "]"
+
+#ifndef MODULE_NAME
+#define MODULE_NAME apollo::cyber::binary::GetName().c_str()
+#endif
+
+#define ADEBUG_MODULE(module) \
+  VLOG(4) << LEFT_BRACKET << module << RIGHT_BRACKET << "[DEBUG] "
+#define ADEBUG ADEBUG_MODULE(MODULE_NAME)
+#define AINFO ALOG_MODULE(MODULE_NAME, INFO)
+#define AWARN ALOG_MODULE(MODULE_NAME, WARN)
+#define AERROR ALOG_MODULE(MODULE_NAME, ERROR)
+#define AFATAL ALOG_MODULE(MODULE_NAME, FATAL)
+
+#ifndef ALOG_MODULE_STREAM
+#define ALOG_MODULE_STREAM(log_severity) ALOG_MODULE_STREAM_##log_severity
+#endif
+
+#ifndef ALOG_MODULE
+#define ALOG_MODULE(module, log_severity) \
+  ALOG_MODULE_STREAM(log_severity)(module)
+#endif
+
+#define ALOG_MODULE_STREAM_INFO(module)                         \
+  google::LogMessage(__FILE__, __LINE__, google::INFO).stream() \
+      << LEFT_BRACKET << module << RIGHT_BRACKET
+
+#define ALOG_MODULE_STREAM_WARN(module)                            \
+  google::LogMessage(__FILE__, __LINE__, google::WARNING).stream() \
+      << LEFT_BRACKET << module << RIGHT_BRACKET
+
+#define ALOG_MODULE_STREAM_ERROR(module)                         \
+  google::LogMessage(__FILE__, __LINE__, google::ERROR).stream() \
+      << LEFT_BRACKET << module << RIGHT_BRACKET
+
+#define ALOG_MODULE_STREAM_FATAL(module)                         \
+  google::LogMessage(__FILE__, __LINE__, google::FATAL).stream() \
+      << LEFT_BRACKET << module << RIGHT_BRACKET
+
+#define AINFO_IF(cond) ALOG_IF(INFO, cond, MODULE_NAME)
+#define AWARN_IF(cond) ALOG_IF(WARN, cond, MODULE_NAME)
+#define AERROR_IF(cond) ALOG_IF(ERROR, cond, MODULE_NAME)
+#define AFATAL_IF(cond) ALOG_IF(FATAL, cond, MODULE_NAME)
+#define ALOG_IF(severity, cond, module) \
+  !(cond) ? (void)0                     \
+          : google::LogMessageVoidify() & ALOG_MODULE(module, severity)
+
+#define ACHECK(cond) CHECK(cond) << LEFT_BRACKET << MODULE_NAME << RIGHT_BRACKET
+
+#define AINFO_EVERY(freq) \
+  LOG_EVERY_N(INFO, freq) << LEFT_BRACKET << MODULE_NAME << RIGHT_BRACKET
+#define AWARN_EVERY(freq) \
+  LOG_EVERY_N(WARNING, freq) << LEFT_BRACKET << MODULE_NAME << RIGHT_BRACKET
+#define AERROR_EVERY(freq) \
+  LOG_EVERY_N(ERROR, freq) << LEFT_BRACKET << MODULE_NAME << RIGHT_BRACKET
+
+#if !defined(RETURN_IF_NULL)
+#define RETURN_IF_NULL(ptr)          \
+  if (ptr == nullptr) {              \
+    AWARN << #ptr << " is nullptr."; \
+    return;                          \
+  }
+#endif
+
+#if !defined(RETURN_VAL_IF_NULL)
+#define RETURN_VAL_IF_NULL(ptr, val) \
+  if (ptr == nullptr) {              \
+    AWARN << #ptr << " is nullptr."; \
+    return val;                      \
+  }
+#endif
+
+#if !defined(RETURN_IF)
+#define RETURN_IF(condition)           \
+  if (condition) {                     \
+    AWARN << #condition << " is met."; \
+    return;                            \
+  }
+#endif
+
+#if !defined(RETURN_VAL_IF)
+#define RETURN_VAL_IF(condition, val)  \
+  if (condition) {                     \
+    AWARN << #condition << " is met."; \
+    return val;                        \
+  }
+#endif
+
+#if !defined(_RETURN_VAL_IF_NULL2__)
+#define _RETURN_VAL_IF_NULL2__
+#define RETURN_VAL_IF_NULL2(ptr, val) \
+  if (ptr == nullptr) {               \
+    return (val);                     \
+  }
+#endif
+
+#if !defined(_RETURN_VAL_IF2__)
+#define _RETURN_VAL_IF2__
+#define RETURN_VAL_IF2(condition, val) \
+  if (condition) {                     \
+    return (val);                      \
+  }
+#endif
+
+#if !defined(_RETURN_IF2__)
+#define _RETURN_IF2__
+#define RETURN_IF2(condition) \
+  if (condition) {            \
+    return;                   \
+  }
+#endif
+
+#endif  // CYBER_COMMON_LOG_H_

+ 75 - 0
src/test/testhdmap/cyber/common/macros.h

@@ -0,0 +1,75 @@
+/******************************************************************************
+ * Copyright 2018 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.
+ *****************************************************************************/
+
+#ifndef CYBER_COMMON_MACROS_H_
+#define CYBER_COMMON_MACROS_H_
+
+#include <iostream>
+#include <memory>
+#include <mutex>
+#include <type_traits>
+#include <utility>
+
+#include "cyber/base/macros.h"
+
+DEFINE_TYPE_TRAIT(HasShutdown, Shutdown)
+
+template <typename T>
+typename std::enable_if<HasShutdown<T>::value>::type CallShutdown(T *instance) {
+  instance->Shutdown();
+}
+
+template <typename T>
+typename std::enable_if<!HasShutdown<T>::value>::type CallShutdown(
+    T *instance) {
+  (void)instance;
+}
+
+// There must be many copy-paste versions of these macros which are same
+// things, undefine them to avoid conflict.
+#undef UNUSED
+#undef DISALLOW_COPY_AND_ASSIGN
+
+#define UNUSED(param) (void)param
+
+#define DISALLOW_COPY_AND_ASSIGN(classname) \
+  classname(const classname &) = delete;    \
+  classname &operator=(const classname &) = delete;
+
+#define DECLARE_SINGLETON(classname)                                      \
+ public:                                                                  \
+  static classname *Instance(bool create_if_needed = true) {              \
+    static classname *instance = nullptr;                                 \
+    if (!instance && create_if_needed) {                                  \
+      static std::once_flag flag;                                         \
+      std::call_once(flag,                                                \
+                     [&] { instance = new (std::nothrow) classname(); }); \
+    }                                                                     \
+    return instance;                                                      \
+  }                                                                       \
+                                                                          \
+  static void CleanUp() {                                                 \
+    auto instance = Instance(false);                                      \
+    if (instance != nullptr) {                                            \
+      CallShutdown(instance);                                             \
+    }                                                                     \
+  }                                                                       \
+                                                                          \
+ private:                                                                 \
+  classname();                                                            \
+  DISALLOW_COPY_AND_ASSIGN(classname)
+
+#endif  // CYBER_COMMON_MACROS_H_

+ 49 - 0
src/test/testhdmap/cyber/common/types.h

@@ -0,0 +1,49 @@
+/******************************************************************************
+ * Copyright 2018 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.
+ *****************************************************************************/
+
+#ifndef CYBER_COMMON_TYPES_H_
+#define CYBER_COMMON_TYPES_H_
+
+#include <cstdint>
+
+namespace apollo {
+namespace cyber {
+
+class NullType {};
+
+// Return code definition for cyber internal function return.
+enum ReturnCode {
+  SUCC = 0,
+  FAIL = 1,
+};
+
+/**
+ * @brief Describe relation between nodes, writers/readers...
+ */
+enum Relation : std::uint8_t {
+  NO_RELATION = 0,
+  DIFF_HOST,  // different host
+  DIFF_PROC,  // same host, but different process
+  SAME_PROC,  // same process
+};
+
+static const char SRV_CHANNEL_REQ_SUFFIX[] = "__SRV__REQUEST";
+static const char SRV_CHANNEL_RES_SUFFIX[] = "__SRV__RESPONSE";
+
+}  // namespace cyber
+}  // namespace apollo
+
+#endif  // CYBER_COMMON_TYPES_H_

+ 8 - 0
src/test/testhdmap/main.cpp

@@ -0,0 +1,8 @@
+#include <QCoreApplication>
+
+int main(int argc, char *argv[])
+{
+    QCoreApplication a(argc, argv);
+
+    return a.exec();
+}

+ 88 - 0
src/test/testhdmap/modules/common/configs/config_gflags.cc

@@ -0,0 +1,88 @@
+/******************************************************************************
+ * 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/common/configs/config_gflags.h"
+
+DEFINE_string(map_dir, "/apollo/modules/map/data/sunnyvale_loop",
+              "Directory which contains a group of related maps.");
+DEFINE_int32(local_utm_zone_id, 10, "UTM zone id.");
+
+DEFINE_string(test_base_map_filename, "",
+              "If not empty, use this test base map files.");
+
+DEFINE_string(base_map_filename, "base_map.bin|base_map.xml|base_map.txt",
+              "Base map files in the map_dir, search in order.");
+DEFINE_string(sim_map_filename, "sim_map.bin|sim_map.txt",
+              "Simulation map files in the map_dir, search in order.");
+DEFINE_string(routing_map_filename, "routing_map.bin|routing_map.txt",
+              "Routing map files in the map_dir, search in order.");
+DEFINE_string(end_way_point_filename, "default_end_way_point.txt",
+              "End way point of the map, will be sent in RoutingRequest.");
+DEFINE_string(default_routing_filename, "default_cycle_routing.txt",
+              "Default cycle routing of the map, will be sent in Task to Task "
+              "Manager Module.");
+DEFINE_string(park_go_routing_filename, "park_go_routing.txt",
+              "Park go routing of the map, support for dreamview contest.");
+DEFINE_string(speed_control_filename, "speed_control.pb.txt",
+              "The speed control region in a map.");
+
+DEFINE_string(vehicle_config_path,
+              "/apollo/modules/common/data/vehicle_param.pb.txt",
+              "the file path of vehicle config file");
+
+DEFINE_string(
+    vehicle_model_config_filename,
+    "/apollo/modules/common/vehicle_model/conf/vehicle_model_config.pb.txt",
+    "the file path of vehicle model config file");
+
+DEFINE_bool(use_cyber_time, false,
+            "Whether Clock::Now() gets time from system_clock::now() or from "
+            "Cyber.");
+
+DEFINE_string(localization_tf2_frame_id, "world", "the tf2 transform frame id");
+DEFINE_string(localization_tf2_child_frame_id, "localization",
+              "the tf2 transform child frame id");
+
+DEFINE_bool(use_navigation_mode, false,
+            "Use relative position in navigation mode");
+DEFINE_string(
+    navigation_mode_end_way_point_file,
+    "modules/dreamview/conf/navigation_mode_default_end_way_point.txt",
+    "end_way_point file used if navigation mode is set.");
+
+DEFINE_double(half_vehicle_width, 1.05, "half vehicle width");
+
+DEFINE_double(look_forward_time_sec, 8.0,
+              "look forward time times adc speed to calculate this distance "
+              "when creating reference line from routing");
+
+DEFINE_bool(use_sim_time, false, "Use bag time in mock time mode.");
+
+DEFINE_bool(reverse_heading_vehicle_state, false,
+            "test flag for reverse driving.");
+
+DEFINE_bool(state_transform_to_com_reverse, false,
+            "Enable vehicle states coordinate transformation from center of "
+            "rear-axis to center of mass, during reverse driving");
+DEFINE_bool(state_transform_to_com_drive, true,
+            "Enable vehicle states coordinate transformation from center of "
+            "rear-axis to center of mass, during forward driving");
+DEFINE_bool(multithread_run, false,
+            "multi-thread run flag mainly used by simulation");
+
+// localization
+DEFINE_bool(enable_map_reference_unify, true,
+            "enable IMU data convert to map reference");

+ 58 - 0
src/test/testhdmap/modules/common/configs/config_gflags.h

@@ -0,0 +1,58 @@
+/******************************************************************************
+ * 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.
+ *****************************************************************************/
+
+#pragma once
+
+#include "gflags/gflags.h"
+
+// The directory which contains a group of related maps, such as base_map,
+// sim_map, routing_topo_grapth, etc.
+DECLARE_string(map_dir);
+DECLARE_int32(local_utm_zone_id);
+
+DECLARE_string(test_base_map_filename);
+DECLARE_string(base_map_filename);
+DECLARE_string(sim_map_filename);
+DECLARE_string(routing_map_filename);
+DECLARE_string(end_way_point_filename);
+DECLARE_string(default_routing_filename);
+DECLARE_string(park_go_routing_filename);
+DECLARE_string(speed_control_filename);
+
+DECLARE_double(look_forward_time_sec);
+
+DECLARE_string(vehicle_config_path);
+DECLARE_string(vehicle_model_config_filename);
+
+DECLARE_bool(use_cyber_time);
+
+DECLARE_string(localization_tf2_frame_id);
+DECLARE_string(localization_tf2_child_frame_id);
+DECLARE_bool(use_navigation_mode);
+DECLARE_string(navigation_mode_end_way_point_file);
+
+DECLARE_double(half_vehicle_width);
+
+DECLARE_bool(use_sim_time);
+
+DECLARE_bool(reverse_heading_vehicle_state);
+
+DECLARE_bool(state_transform_to_com_reverse);
+DECLARE_bool(state_transform_to_com_drive);
+DECLARE_bool(multithread_run);
+
+// localizaiton
+DECLARE_bool(enable_map_reference_unify);

+ 155 - 0
src/test/testhdmap/modules/common/math/aabox2d.cc

@@ -0,0 +1,155 @@
+/******************************************************************************
+ * 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/common/math/aabox2d.h"
+
+#include <algorithm>
+#include <cmath>
+
+#include "absl/strings/str_cat.h"
+#include "cyber/common/log.h"
+
+#include "modules/common/math/math_utils.h"
+
+namespace apollo {
+namespace common {
+namespace math {
+
+AABox2d::AABox2d(const Vec2d &center, const double length, const double width)
+    : center_(center),
+      length_(length),
+      width_(width),
+      half_length_(length / 2.0),
+      half_width_(width / 2.0) {
+  CHECK_GT(length_, -kMathEpsilon);
+  CHECK_GT(width_, -kMathEpsilon);
+}
+
+AABox2d::AABox2d(const Vec2d &one_corner, const Vec2d &opposite_corner)
+    : AABox2d((one_corner + opposite_corner) / 2.0,
+              std::abs(one_corner.x() - opposite_corner.x()),
+              std::abs(one_corner.y() - opposite_corner.y())) {}
+
+AABox2d::AABox2d(const std::vector<Vec2d> &points) {
+  ACHECK(!points.empty());
+  double min_x = points[0].x();
+  double max_x = points[0].x();
+  double min_y = points[0].y();
+  double max_y = points[0].y();
+  for (const auto &point : points) {
+    min_x = std::min(min_x, point.x());
+    max_x = std::max(max_x, point.x());
+    min_y = std::min(min_y, point.y());
+    max_y = std::max(max_y, point.y());
+  }
+
+  center_ = {(min_x + max_x) / 2.0, (min_y + max_y) / 2.0};
+  length_ = max_x - min_x;
+  width_ = max_y - min_y;
+  half_length_ = length_ / 2.0;
+  half_width_ = width_ / 2.0;
+}
+
+void AABox2d::GetAllCorners(std::vector<Vec2d> *const corners) const {
+  CHECK_NOTNULL(corners)->clear();
+  corners->reserve(4);
+  corners->emplace_back(center_.x() + half_length_, center_.y() - half_width_);
+  corners->emplace_back(center_.x() + half_length_, center_.y() + half_width_);
+  corners->emplace_back(center_.x() - half_length_, center_.y() + half_width_);
+  corners->emplace_back(center_.x() - half_length_, center_.y() - half_width_);
+}
+
+bool AABox2d::IsPointIn(const Vec2d &point) const {
+  return std::abs(point.x() - center_.x()) <= half_length_ + kMathEpsilon &&
+         std::abs(point.y() - center_.y()) <= half_width_ + kMathEpsilon;
+}
+
+bool AABox2d::IsPointOnBoundary(const Vec2d &point) const {
+  const double dx = std::abs(point.x() - center_.x());
+  const double dy = std::abs(point.y() - center_.y());
+  return (std::abs(dx - half_length_) <= kMathEpsilon &&
+          dy <= half_width_ + kMathEpsilon) ||
+         (std::abs(dy - half_width_) <= kMathEpsilon &&
+          dx <= half_length_ + kMathEpsilon);
+}
+
+double AABox2d::DistanceTo(const Vec2d &point) const {
+  const double dx = std::abs(point.x() - center_.x()) - half_length_;
+  const double dy = std::abs(point.y() - center_.y()) - half_width_;
+  if (dx <= 0.0) {
+    return std::max(0.0, dy);
+  }
+  if (dy <= 0.0) {
+    return dx;
+  }
+  return hypot(dx, dy);
+}
+
+double AABox2d::DistanceTo(const AABox2d &box) const {
+  const double dx =
+      std::abs(box.center_x() - center_.x()) - box.half_length() - half_length_;
+  const double dy =
+      std::abs(box.center_y() - center_.y()) - box.half_width() - half_width_;
+  if (dx <= 0.0) {
+    return std::max(0.0, dy);
+  }
+  if (dy <= 0.0) {
+    return dx;
+  }
+  return hypot(dx, dy);
+}
+
+bool AABox2d::HasOverlap(const AABox2d &box) const {
+  return std::abs(box.center_x() - center_.x()) <=
+             box.half_length() + half_length_ &&
+         std::abs(box.center_y() - center_.y()) <=
+             box.half_width() + half_width_;
+}
+
+void AABox2d::Shift(const Vec2d &shift_vec) { center_ += shift_vec; }
+
+void AABox2d::MergeFrom(const AABox2d &other_box) {
+  const double x1 = std::min(min_x(), other_box.min_x());
+  const double x2 = std::max(max_x(), other_box.max_x());
+  const double y1 = std::min(min_y(), other_box.min_y());
+  const double y2 = std::max(max_y(), other_box.max_y());
+  center_ = Vec2d((x1 + x2) / 2.0, (y1 + y2) / 2.0);
+  length_ = x2 - x1;
+  width_ = y2 - y1;
+  half_length_ = length_ / 2.0;
+  half_width_ = width_ / 2.0;
+}
+
+void AABox2d::MergeFrom(const Vec2d &other_point) {
+  const double x1 = std::min(min_x(), other_point.x());
+  const double x2 = std::max(max_x(), other_point.x());
+  const double y1 = std::min(min_y(), other_point.y());
+  const double y2 = std::max(max_y(), other_point.y());
+  center_ = Vec2d((x1 + x2) / 2.0, (y1 + y2) / 2.0);
+  length_ = x2 - x1;
+  width_ = y2 - y1;
+  half_length_ = length_ / 2.0;
+  half_width_ = width_ / 2.0;
+}
+
+std::string AABox2d::DebugString() const {
+  return absl::StrCat("aabox2d ( center = ", center_.DebugString(),
+                      "  length = ", length_, "  width = ", width_, " )");
+}
+
+}  // namespace math
+}  // namespace common
+}  // namespace apollo

+ 228 - 0
src/test/testhdmap/modules/common/math/aabox2d.h

@@ -0,0 +1,228 @@
+/******************************************************************************
+ * 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
+ * @brief Defines the AABox2d class.
+ */
+
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include "modules/common/math/vec2d.h"
+
+/**
+ * @namespace apollo::common::math
+ * @brief apollo::common::math
+ */
+namespace apollo {
+namespace common {
+namespace math {
+
+/**
+ * @class AABox2d
+ * @brief Implements a class of (undirected) axes-aligned bounding boxes in 2-D.
+ * This class is referential-agnostic.
+ */
+class AABox2d {
+ public:
+  /**
+   * @brief Default constructor.
+   * Creates an axes-aligned box with zero length and width at the origin.
+   */
+  AABox2d() = default;
+  /**
+   * @brief Parameterized constructor.
+   * Creates an axes-aligned box with given center, length, and width.
+   * @param center The center of the box
+   * @param length The size of the box along the x-axis
+   * @param width The size of the box along the y-axis
+   */
+  AABox2d(const Vec2d &center, const double length, const double width);
+  /**
+   * @brief Parameterized constructor.
+   * Creates an axes-aligned box from two opposite corners.
+   * @param one_corner One corner of the box
+   * @param opposite_corner The opposite corner to the first one
+   */
+  AABox2d(const Vec2d &one_corner, const Vec2d &opposite_corner);
+  /**
+   * @brief Parameterized constructor.
+   * Creates an axes-aligned box containing all points in a given vector.
+   * @param points Vector of points to be included inside the box.
+   */
+  explicit AABox2d(const std::vector<Vec2d> &points);
+
+  /**
+   * @brief Getter of center_
+   * @return Center of the box
+   */
+  const Vec2d &center() const { return center_; }
+
+  /**
+   * @brief Getter of x-component of center_
+   * @return x-component of the center of the box
+   */
+  double center_x() const { return center_.x(); }
+
+  /**
+   * @brief Getter of y-component of center_
+   * @return y-component of the center of the box
+   */
+  double center_y() const { return center_.y(); }
+
+  /**
+   * @brief Getter of length_
+   * @return The length of the box
+   */
+  double length() const { return length_; }
+
+  /**
+   * @brief Getter of width_
+   * @return The width of the box
+   */
+  double width() const { return width_; }
+
+  /**
+   * @brief Getter of half_length_
+   * @return Half of the length of the box
+   */
+  double half_length() const { return half_length_; }
+
+  /**
+   * @brief Getter of half_width_
+   * @return Half of the width of the box
+   */
+  double half_width() const { return half_width_; }
+
+  /**
+   * @brief Getter of length_*width_
+   * @return The area of the box
+   */
+  double area() const { return length_ * width_; }
+
+  /**
+   * @brief Returns the minimum x-coordinate of the box
+   *
+   * @return x-coordinate
+   */
+  double min_x() const { return center_.x() - half_length_; }
+
+  /**
+   * @brief Returns the maximum x-coordinate of the box
+   *
+   * @return x-coordinate
+   */
+  double max_x() const { return center_.x() + half_length_; }
+
+  /**
+   * @brief Returns the minimum y-coordinate of the box
+   *
+   * @return y-coordinate
+   */
+  double min_y() const { return center_.y() - half_width_; }
+
+  /**
+   * @brief Returns the maximum y-coordinate of the box
+   *
+   * @return y-coordinate
+   */
+  double max_y() const { return center_.y() + half_width_; }
+
+  /**
+   * @brief Gets all corners in counter clockwise order.
+   *
+   * @param corners Output where the corners are written
+   */
+  void GetAllCorners(std::vector<Vec2d> *const corners) const;
+
+  /**
+   * @brief Determines whether a given point is in the box.
+   *
+   * @param point The point we wish to test for containment in the box
+   */
+  bool IsPointIn(const Vec2d &point) const;
+
+  /**
+   * @brief Determines whether a given point is on the boundary of the box.
+   *
+   * @param point The point we wish to test for boundary membership
+   */
+  bool IsPointOnBoundary(const Vec2d &point) const;
+
+  /**
+   * @brief Determines the distance between a point and the box.
+   *
+   * @param point The point whose distance to the box we wish to determine.
+   */
+  double DistanceTo(const Vec2d &point) const;
+
+  /**
+   * @brief Determines the distance between two boxes.
+   *
+   * @param box Another box.
+   */
+  double DistanceTo(const AABox2d &box) const;
+
+  /**
+   * @brief Determines whether two boxes overlap.
+   *
+   * @param box Another box
+   */
+  bool HasOverlap(const AABox2d &box) const;
+
+  /**
+   * @brief Shift the center of AABox by the input vector.
+   *
+   * @param shift_vec The vector by which we wish to shift the box
+   */
+  void Shift(const Vec2d &shift_vec);
+
+  /**
+   * @brief Changes box to include another given box, as well as the current
+   * one.
+   *
+   * @param other_box Another box
+   */
+  void MergeFrom(const AABox2d &other_box);
+
+  /**
+   * @brief Changes box to include a given point, as well as the current box.
+   *
+   * @param other_point Another point
+   */
+  void MergeFrom(const Vec2d &other_point);
+
+  /**
+   * @brief Gets a human-readable debug string
+   *
+   * @return A string
+   */
+  std::string DebugString() const;
+
+ private:
+  Vec2d center_;
+  double length_ = 0.0;
+  double width_ = 0.0;
+  double half_length_ = 0.0;
+  double half_width_ = 0.0;
+};
+
+}  // namespace math
+}  // namespace common
+}  // namespace apollo

+ 471 - 0
src/test/testhdmap/modules/common/math/aaboxkdtree2d.h

@@ -0,0 +1,471 @@
+/******************************************************************************
+ * 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
+ * @brief Defines the templated AABoxKDTree2dNode class.
+ */
+
+#pragma once
+
+#include <algorithm>
+#include <limits>
+#include <memory>
+#include <vector>
+
+#include "cyber/common/log.h"
+
+#include "modules/common/math/aabox2d.h"
+#include "modules/common/math/math_utils.h"
+
+/**
+ * @namespace apollo::common::math
+ * @brief The math namespace deals with a number of useful mathematical objects.
+ */
+namespace apollo {
+namespace common {
+namespace math {
+
+/**
+ * @class AABoxKDTreeParams
+ * @brief Contains parameters of axis-aligned bounding box.
+ */
+struct AABoxKDTreeParams {
+  /// The maximum depth of the kdtree.
+  int max_depth = -1;
+  /// The maximum number of items in one leaf node.
+  int max_leaf_size = -1;
+  /// The maximum dimension size of leaf node.
+  double max_leaf_dimension = -1.0;
+};
+
+/**
+ * @class AABoxKDTree2dNode
+ * @brief The class of KD-tree node of axis-aligned bounding box.
+ */
+template <class ObjectType>
+class AABoxKDTree2dNode {
+ public:
+  using ObjectPtr = const ObjectType *;
+  /**
+   * @brief Constructor which takes a vector of objects,
+   *        parameters and depth of the node.
+   * @param objects Objects to build the KD-tree node.
+   * @param params Parameters to build the KD-tree.
+   * @param depth Depth of the KD-tree node.
+   */
+  AABoxKDTree2dNode(const std::vector<ObjectPtr> &objects,
+                    const AABoxKDTreeParams &params, int depth)
+      : depth_(depth) {
+    ACHECK(!objects.empty());
+
+    ComputeBoundary(objects);
+    ComputePartition();
+
+    if (SplitToSubNodes(objects, params)) {
+      std::vector<ObjectPtr> left_subnode_objects;
+      std::vector<ObjectPtr> right_subnode_objects;
+      PartitionObjects(objects, &left_subnode_objects, &right_subnode_objects);
+
+      // Split to sub-nodes.
+      if (!left_subnode_objects.empty()) {
+        left_subnode_.reset(new AABoxKDTree2dNode<ObjectType>(
+            left_subnode_objects, params, depth + 1));
+      }
+      if (!right_subnode_objects.empty()) {
+        right_subnode_.reset(new AABoxKDTree2dNode<ObjectType>(
+            right_subnode_objects, params, depth + 1));
+      }
+    } else {
+      InitObjects(objects);
+    }
+  }
+
+  /**
+   * @brief Get the nearest object to a target point by the KD-tree
+   *        rooted at this node.
+   * @param point The target point. Search it's nearest object.
+   * @return The nearest object to the target point.
+   */
+  ObjectPtr GetNearestObject(const Vec2d &point) const {
+    ObjectPtr nearest_object = nullptr;
+    double min_distance_sqr = std::numeric_limits<double>::infinity();
+    GetNearestObjectInternal(point, &min_distance_sqr, &nearest_object);
+    return nearest_object;
+  }
+
+  /**
+   * @brief Get objects within a distance to a point by the KD-tree
+   *        rooted at this node.
+   * @param point The center point of the range to search objects.
+   * @param distance The radius of the range to search objects.
+   * @return All objects within the specified distance to the specified point.
+   */
+  std::vector<ObjectPtr> GetObjects(const Vec2d &point,
+                                    const double distance) const {
+    std::vector<ObjectPtr> result_objects;
+    GetObjectsInternal(point, distance, Square(distance), &result_objects);
+    return result_objects;
+  }
+
+  /**
+   * @brief Get the axis-aligned bounding box of the objects.
+   * @return The axis-aligned bounding box of the objects.
+   */
+  AABox2d GetBoundingBox() const {
+    return AABox2d({min_x_, min_y_}, {max_x_, max_y_});
+  }
+
+ private:
+  void InitObjects(const std::vector<ObjectPtr> &objects) {
+    num_objects_ = static_cast<int>(objects.size());
+    objects_sorted_by_min_ = objects;
+    objects_sorted_by_max_ = objects;
+    std::sort(objects_sorted_by_min_.begin(), objects_sorted_by_min_.end(),
+              [&](ObjectPtr obj1, ObjectPtr obj2) {
+                return partition_ == PARTITION_X
+                           ? obj1->aabox().min_x() < obj2->aabox().min_x()
+                           : obj1->aabox().min_y() < obj2->aabox().min_y();
+              });
+    std::sort(objects_sorted_by_max_.begin(), objects_sorted_by_max_.end(),
+              [&](ObjectPtr obj1, ObjectPtr obj2) {
+                return partition_ == PARTITION_X
+                           ? obj1->aabox().max_x() > obj2->aabox().max_x()
+                           : obj1->aabox().max_y() > obj2->aabox().max_y();
+              });
+    objects_sorted_by_min_bound_.reserve(num_objects_);
+    for (ObjectPtr object : objects_sorted_by_min_) {
+      objects_sorted_by_min_bound_.push_back(partition_ == PARTITION_X
+                                                 ? object->aabox().min_x()
+                                                 : object->aabox().min_y());
+    }
+    objects_sorted_by_max_bound_.reserve(num_objects_);
+    for (ObjectPtr object : objects_sorted_by_max_) {
+      objects_sorted_by_max_bound_.push_back(partition_ == PARTITION_X
+                                                 ? object->aabox().max_x()
+                                                 : object->aabox().max_y());
+    }
+  }
+
+  bool SplitToSubNodes(const std::vector<ObjectPtr> &objects,
+                       const AABoxKDTreeParams &params) {
+    if (params.max_depth >= 0 && depth_ >= params.max_depth) {
+      return false;
+    }
+    if (static_cast<int>(objects.size()) <= std::max(1, params.max_leaf_size)) {
+      return false;
+    }
+    if (params.max_leaf_dimension >= 0.0 &&
+        std::max(max_x_ - min_x_, max_y_ - min_y_) <=
+            params.max_leaf_dimension) {
+      return false;
+    }
+    return true;
+  }
+
+  double LowerDistanceSquareToPoint(const Vec2d &point) const {
+    double dx = 0.0;
+    if (point.x() < min_x_) {
+      dx = min_x_ - point.x();
+    } else if (point.x() > max_x_) {
+      dx = point.x() - max_x_;
+    }
+    double dy = 0.0;
+    if (point.y() < min_y_) {
+      dy = min_y_ - point.y();
+    } else if (point.y() > max_y_) {
+      dy = point.y() - max_y_;
+    }
+    return dx * dx + dy * dy;
+  }
+
+  double UpperDistanceSquareToPoint(const Vec2d &point) const {
+    const double dx =
+        (point.x() > mid_x_ ? (point.x() - min_x_) : (point.x() - max_x_));
+    const double dy =
+        (point.y() > mid_y_ ? (point.y() - min_y_) : (point.y() - max_y_));
+    return dx * dx + dy * dy;
+  }
+
+  void GetAllObjects(std::vector<ObjectPtr> *const result_objects) const {
+    result_objects->insert(result_objects->end(),
+                           objects_sorted_by_min_.begin(),
+                           objects_sorted_by_min_.end());
+    if (left_subnode_ != nullptr) {
+      left_subnode_->GetAllObjects(result_objects);
+    }
+    if (right_subnode_ != nullptr) {
+      right_subnode_->GetAllObjects(result_objects);
+    }
+  }
+
+  void GetObjectsInternal(const Vec2d &point, const double distance,
+                          const double distance_sqr,
+                          std::vector<ObjectPtr> *const result_objects) const {
+    if (LowerDistanceSquareToPoint(point) > distance_sqr) {
+      return;
+    }
+    if (UpperDistanceSquareToPoint(point) <= distance_sqr) {
+      GetAllObjects(result_objects);
+      return;
+    }
+    const double pvalue = (partition_ == PARTITION_X ? point.x() : point.y());
+    if (pvalue < partition_position_) {
+      const double limit = pvalue + distance;
+      for (int i = 0; i < num_objects_; ++i) {
+        if (objects_sorted_by_min_bound_[i] > limit) {
+          break;
+        }
+        ObjectPtr object = objects_sorted_by_min_[i];
+        if (object->DistanceSquareTo(point) <= distance_sqr) {
+          result_objects->push_back(object);
+        }
+      }
+    } else {
+      const double limit = pvalue - distance;
+      for (int i = 0; i < num_objects_; ++i) {
+        if (objects_sorted_by_max_bound_[i] < limit) {
+          break;
+        }
+        ObjectPtr object = objects_sorted_by_max_[i];
+        if (object->DistanceSquareTo(point) <= distance_sqr) {
+          result_objects->push_back(object);
+        }
+      }
+    }
+    if (left_subnode_ != nullptr) {
+      left_subnode_->GetObjectsInternal(point, distance, distance_sqr,
+                                        result_objects);
+    }
+    if (right_subnode_ != nullptr) {
+      right_subnode_->GetObjectsInternal(point, distance, distance_sqr,
+                                         result_objects);
+    }
+  }
+
+  void GetNearestObjectInternal(const Vec2d &point,
+                                double *const min_distance_sqr,
+                                ObjectPtr *const nearest_object) const {
+    if (LowerDistanceSquareToPoint(point) >= *min_distance_sqr - kMathEpsilon) {
+      return;
+    }
+    const double pvalue = (partition_ == PARTITION_X ? point.x() : point.y());
+    const bool search_left_first = (pvalue < partition_position_);
+    if (search_left_first) {
+      if (left_subnode_ != nullptr) {
+        left_subnode_->GetNearestObjectInternal(point, min_distance_sqr,
+                                                nearest_object);
+      }
+    } else {
+      if (right_subnode_ != nullptr) {
+        right_subnode_->GetNearestObjectInternal(point, min_distance_sqr,
+                                                 nearest_object);
+      }
+    }
+    if (*min_distance_sqr <= kMathEpsilon) {
+      return;
+    }
+
+    if (search_left_first) {
+      for (int i = 0; i < num_objects_; ++i) {
+        const double bound = objects_sorted_by_min_bound_[i];
+        if (bound > pvalue && Square(bound - pvalue) > *min_distance_sqr) {
+          break;
+        }
+        ObjectPtr object = objects_sorted_by_min_[i];
+        const double distance_sqr = object->DistanceSquareTo(point);
+        if (distance_sqr < *min_distance_sqr) {
+          *min_distance_sqr = distance_sqr;
+          *nearest_object = object;
+        }
+      }
+    } else {
+      for (int i = 0; i < num_objects_; ++i) {
+        const double bound = objects_sorted_by_max_bound_[i];
+        if (bound < pvalue && Square(bound - pvalue) > *min_distance_sqr) {
+          break;
+        }
+        ObjectPtr object = objects_sorted_by_max_[i];
+        const double distance_sqr = object->DistanceSquareTo(point);
+        if (distance_sqr < *min_distance_sqr) {
+          *min_distance_sqr = distance_sqr;
+          *nearest_object = object;
+        }
+      }
+    }
+    if (*min_distance_sqr <= kMathEpsilon) {
+      return;
+    }
+    if (search_left_first) {
+      if (right_subnode_ != nullptr) {
+        right_subnode_->GetNearestObjectInternal(point, min_distance_sqr,
+                                                 nearest_object);
+      }
+    } else {
+      if (left_subnode_ != nullptr) {
+        left_subnode_->GetNearestObjectInternal(point, min_distance_sqr,
+                                                nearest_object);
+      }
+    }
+  }
+
+  void ComputeBoundary(const std::vector<ObjectPtr> &objects) {
+    min_x_ = std::numeric_limits<double>::infinity();
+    min_y_ = std::numeric_limits<double>::infinity();
+    max_x_ = -std::numeric_limits<double>::infinity();
+    max_y_ = -std::numeric_limits<double>::infinity();
+    for (ObjectPtr object : objects) {
+      min_x_ = std::fmin(min_x_, object->aabox().min_x());
+      max_x_ = std::fmax(max_x_, object->aabox().max_x());
+      min_y_ = std::fmin(min_y_, object->aabox().min_y());
+      max_y_ = std::fmax(max_y_, object->aabox().max_y());
+    }
+    mid_x_ = (min_x_ + max_x_) / 2.0;
+    mid_y_ = (min_y_ + max_y_) / 2.0;
+    ACHECK(!std::isinf(max_x_) && !std::isinf(max_y_) && !std::isinf(min_x_) &&
+           !std::isinf(min_y_))
+        << "the provided object box size is infinity";
+  }
+
+  void ComputePartition() {
+    if (max_x_ - min_x_ >= max_y_ - min_y_) {
+      partition_ = PARTITION_X;
+      partition_position_ = (min_x_ + max_x_) / 2.0;
+    } else {
+      partition_ = PARTITION_Y;
+      partition_position_ = (min_y_ + max_y_) / 2.0;
+    }
+  }
+
+  void PartitionObjects(const std::vector<ObjectPtr> &objects,
+                        std::vector<ObjectPtr> *const left_subnode_objects,
+                        std::vector<ObjectPtr> *const right_subnode_objects) {
+    left_subnode_objects->clear();
+    right_subnode_objects->clear();
+    std::vector<ObjectPtr> other_objects;
+    if (partition_ == PARTITION_X) {
+      for (ObjectPtr object : objects) {
+        if (object->aabox().max_x() <= partition_position_) {
+          left_subnode_objects->push_back(object);
+        } else if (object->aabox().min_x() >= partition_position_) {
+          right_subnode_objects->push_back(object);
+        } else {
+          other_objects.push_back(object);
+        }
+      }
+    } else {
+      for (ObjectPtr object : objects) {
+        if (object->aabox().max_y() <= partition_position_) {
+          left_subnode_objects->push_back(object);
+        } else if (object->aabox().min_y() >= partition_position_) {
+          right_subnode_objects->push_back(object);
+        } else {
+          other_objects.push_back(object);
+        }
+      }
+    }
+    InitObjects(other_objects);
+  }
+
+ private:
+  int num_objects_ = 0;
+  std::vector<ObjectPtr> objects_sorted_by_min_;
+  std::vector<ObjectPtr> objects_sorted_by_max_;
+  std::vector<double> objects_sorted_by_min_bound_;
+  std::vector<double> objects_sorted_by_max_bound_;
+  int depth_ = 0;
+
+  // Boundary
+  double min_x_ = 0.0;
+  double max_x_ = 0.0;
+  double min_y_ = 0.0;
+  double max_y_ = 0.0;
+  double mid_x_ = 0.0;
+  double mid_y_ = 0.0;
+
+  enum Partition {
+    PARTITION_X = 1,
+    PARTITION_Y = 2,
+  };
+  Partition partition_ = PARTITION_X;
+  double partition_position_ = 0.0;
+
+  std::unique_ptr<AABoxKDTree2dNode<ObjectType>> left_subnode_ = nullptr;
+  std::unique_ptr<AABoxKDTree2dNode<ObjectType>> right_subnode_ = nullptr;
+};
+
+/**
+ * @class AABoxKDTree2d
+ * @brief The class of KD-tree of Aligned Axis Bounding Box(AABox).
+ */
+template <class ObjectType>
+class AABoxKDTree2d {
+ public:
+  using ObjectPtr = const ObjectType *;
+
+  /**
+   * @brief Constructor which takes a vector of objects and parameters.
+   * @param params Parameters to build the KD-tree.
+   */
+  AABoxKDTree2d(const std::vector<ObjectType> &objects,
+                const AABoxKDTreeParams &params) {
+    if (!objects.empty()) {
+      std::vector<ObjectPtr> object_ptrs;
+      for (const auto &object : objects) {
+        object_ptrs.push_back(&object);
+      }
+      root_.reset(new AABoxKDTree2dNode<ObjectType>(object_ptrs, params, 0));
+    }
+  }
+
+  /**
+   * @brief Get the nearest object to a target point.
+   * @param point The target point. Search it's nearest object.
+   * @return The nearest object to the target point.
+   */
+  ObjectPtr GetNearestObject(const Vec2d &point) const {
+    return root_ == nullptr ? nullptr : root_->GetNearestObject(point);
+  }
+
+  /**
+   * @brief Get objects within a distance to a point.
+   * @param point The center point of the range to search objects.
+   * @param distance The radius of the range to search objects.
+   * @return All objects within the specified distance to the specified point.
+   */
+  std::vector<ObjectPtr> GetObjects(const Vec2d &point,
+                                    const double distance) const {
+    if (root_ == nullptr) {
+      return {};
+    }
+    return root_->GetObjects(point, distance);
+  }
+
+  /**
+   * @brief Get the axis-aligned bounding box of the objects.
+   * @return The axis-aligned bounding box of the objects.
+   */
+  AABox2d GetBoundingBox() const {
+    return root_ == nullptr ? AABox2d() : root_->GetBoundingBox();
+  }
+
+ private:
+  std::unique_ptr<AABoxKDTree2dNode<ObjectType>> root_ = nullptr;
+};
+
+}  // namespace math
+}  // namespace common
+}  // namespace apollo

+ 426 - 0
src/test/testhdmap/modules/common/math/box2d.cc

@@ -0,0 +1,426 @@
+/******************************************************************************
+ * 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/common/math/box2d.h"
+
+#include <algorithm>
+#include <cmath>
+#include <utility>
+
+#include "absl/strings/str_cat.h"
+
+#include "cyber/common/log.h"
+#include "modules/common/math/math_utils.h"
+#include "modules/common/math/polygon2d.h"
+
+namespace apollo {
+namespace common {
+namespace math {
+namespace {
+
+double PtSegDistance(double query_x, double query_y, double start_x,
+                     double start_y, double end_x, double end_y,
+                     double length) {
+  const double x0 = query_x - start_x;
+  const double y0 = query_y - start_y;
+  const double dx = end_x - start_x;
+  const double dy = end_y - start_y;
+  const double proj = x0 * dx + y0 * dy;
+  if (proj <= 0.0) {
+    return hypot(x0, y0);
+  }
+  if (proj >= length * length) {
+    return hypot(x0 - dx, y0 - dy);
+  }
+  return std::abs(x0 * dy - y0 * dx) / length;
+}
+
+}  // namespace
+
+Box2d::Box2d(const Vec2d &center, const double heading, const double length,
+             const double width)
+    : center_(center),
+      length_(length),
+      width_(width),
+      half_length_(length / 2.0),
+      half_width_(width / 2.0),
+      heading_(heading),
+      cos_heading_(cos(heading)),
+      sin_heading_(sin(heading)) {
+  CHECK_GT(length_, -kMathEpsilon);
+  CHECK_GT(width_, -kMathEpsilon);
+  InitCorners();
+}
+
+Box2d::Box2d(const Vec2d &point, double heading, double front_length,
+             double back_length, double width)
+    : length_(front_length + back_length),
+      width_(width),
+      half_length_(length_ / 2.0),
+      half_width_(width / 2.0),
+      heading_(heading),
+      cos_heading_(cos(heading)),
+      sin_heading_(sin(heading)) {
+  CHECK_GT(length_, -kMathEpsilon);
+  CHECK_GT(width_, -kMathEpsilon);
+  double delta_length = (front_length - back_length) / 2.0;
+  center_ = Vec2d(point.x() + cos_heading_ * delta_length,
+                  point.y() + sin_heading_ * delta_length);
+  InitCorners();
+}
+
+Box2d::Box2d(const LineSegment2d &axis, const double width)
+    : center_(axis.center()),
+      length_(axis.length()),
+      width_(width),
+      half_length_(axis.length() / 2.0),
+      half_width_(width / 2.0),
+      heading_(axis.heading()),
+      cos_heading_(axis.cos_heading()),
+      sin_heading_(axis.sin_heading()) {
+  CHECK_GT(length_, -kMathEpsilon);
+  CHECK_GT(width_, -kMathEpsilon);
+  InitCorners();
+}
+
+void Box2d::InitCorners() {
+  const double dx1 = cos_heading_ * half_length_;
+  const double dy1 = sin_heading_ * half_length_;
+  const double dx2 = sin_heading_ * half_width_;
+  const double dy2 = -cos_heading_ * half_width_;
+  corners_.clear();
+  corners_.emplace_back(center_.x() + dx1 + dx2, center_.y() + dy1 + dy2);
+  corners_.emplace_back(center_.x() + dx1 - dx2, center_.y() + dy1 - dy2);
+  corners_.emplace_back(center_.x() - dx1 - dx2, center_.y() - dy1 - dy2);
+  corners_.emplace_back(center_.x() - dx1 + dx2, center_.y() - dy1 + dy2);
+
+  for (auto &corner : corners_) {
+    max_x_ = std::fmax(corner.x(), max_x_);
+    min_x_ = std::fmin(corner.x(), min_x_);
+    max_y_ = std::fmax(corner.y(), max_y_);
+    min_y_ = std::fmin(corner.y(), min_y_);
+  }
+}
+
+Box2d::Box2d(const AABox2d &aabox)
+    : center_(aabox.center()),
+      length_(aabox.length()),
+      width_(aabox.width()),
+      half_length_(aabox.half_length()),
+      half_width_(aabox.half_width()),
+      heading_(0.0),
+      cos_heading_(1.0),
+      sin_heading_(0.0) {
+  CHECK_GT(length_, -kMathEpsilon);
+  CHECK_GT(width_, -kMathEpsilon);
+}
+
+Box2d Box2d::CreateAABox(const Vec2d &one_corner,
+                         const Vec2d &opposite_corner) {
+  const double x1 = std::min(one_corner.x(), opposite_corner.x());
+  const double x2 = std::max(one_corner.x(), opposite_corner.x());
+  const double y1 = std::min(one_corner.y(), opposite_corner.y());
+  const double y2 = std::max(one_corner.y(), opposite_corner.y());
+  return Box2d({(x1 + x2) / 2.0, (y1 + y2) / 2.0}, 0.0, x2 - x1, y2 - y1);
+}
+
+void Box2d::GetAllCorners(std::vector<Vec2d> *const corners) const {
+  if (corners == nullptr) {
+    return;
+  }
+  *corners = corners_;
+}
+
+const std::vector<Vec2d> &Box2d::GetAllCorners() const { return corners_; }
+
+bool Box2d::IsPointIn(const Vec2d &point) const {
+  const double x0 = point.x() - center_.x();
+  const double y0 = point.y() - center_.y();
+  const double dx = std::abs(x0 * cos_heading_ + y0 * sin_heading_);
+  const double dy = std::abs(-x0 * sin_heading_ + y0 * cos_heading_);
+  return dx <= half_length_ + kMathEpsilon && dy <= half_width_ + kMathEpsilon;
+}
+
+bool Box2d::IsPointOnBoundary(const Vec2d &point) const {
+  const double x0 = point.x() - center_.x();
+  const double y0 = point.y() - center_.y();
+  const double dx = std::abs(x0 * cos_heading_ + y0 * sin_heading_);
+  const double dy = std::abs(x0 * sin_heading_ - y0 * cos_heading_);
+  return (std::abs(dx - half_length_) <= kMathEpsilon &&
+          dy <= half_width_ + kMathEpsilon) ||
+         (std::abs(dy - half_width_) <= kMathEpsilon &&
+          dx <= half_length_ + kMathEpsilon);
+}
+
+double Box2d::DistanceTo(const Vec2d &point) const {
+  const double x0 = point.x() - center_.x();
+  const double y0 = point.y() - center_.y();
+  const double dx =
+      std::abs(x0 * cos_heading_ + y0 * sin_heading_) - half_length_;
+  const double dy =
+      std::abs(x0 * sin_heading_ - y0 * cos_heading_) - half_width_;
+  if (dx <= 0.0) {
+    return std::max(0.0, dy);
+  }
+  if (dy <= 0.0) {
+    return dx;
+  }
+  return hypot(dx, dy);
+}
+
+bool Box2d::HasOverlap(const LineSegment2d &line_segment) const {
+  if (line_segment.length() <= kMathEpsilon) {
+    return IsPointIn(line_segment.start());
+  }
+  if (std::fmax(line_segment.start().x(), line_segment.end().x()) < min_x() ||
+      std::fmin(line_segment.start().x(), line_segment.end().x()) > max_x() ||
+      std::fmax(line_segment.start().y(), line_segment.end().y()) < min_y() ||
+      std::fmin(line_segment.start().y(), line_segment.end().y()) > max_y()) {
+    return false;
+  }
+  // Construct coordinate system with origin point as left_bottom corner of
+  // Box2d, y axis along direction of heading.
+  Vec2d x_axis(sin_heading_, -cos_heading_);
+  Vec2d y_axis(cos_heading_, sin_heading_);
+  // corners_[2] is the left bottom point of the box.
+  Vec2d start_v = line_segment.start() - corners_[2];
+  // "start_point" is the start point of "line_segment" mapped in the new
+  // coordinate system.
+  Vec2d start_point(start_v.InnerProd(x_axis), start_v.InnerProd(y_axis));
+  // Check if "start_point" is inside the box.
+  if (is_inside_rectangle(start_point)) {
+    return true;
+  }
+  // Check if "end_point" is inside the box.
+  Vec2d end_v = line_segment.end() - corners_[2];
+  Vec2d end_point(end_v.InnerProd(x_axis), end_v.InnerProd(y_axis));
+  if (is_inside_rectangle(end_point)) {
+    return true;
+  }
+  // Exclude the case when the 2 points of "line_segment" are at the same side
+  // of rectangle.
+  if ((start_point.x() < 0.0) && (end_point.x() < 0.0)) {
+    return false;
+  }
+  if ((start_point.y() < 0.0) && (end_point.y() < 0.0)) {
+    return false;
+  }
+  if ((start_point.x() > width_) && (end_point.x() > width_)) {
+    return false;
+  }
+  if ((start_point.y() > length_) && (end_point.y() > length_)) {
+    return false;
+  }
+  // Check if "line_segment" intersects with box.
+  Vec2d line_direction = line_segment.end() - line_segment.start();
+  Vec2d normal_vec(line_direction.y(), -line_direction.x());
+  Vec2d p1 = center_ - line_segment.start();
+  Vec2d diagonal_vec = center_ - corners_[0];
+  // if project_p1 < projection of diagonal, "line_segment" intersects with box.
+  double project_p1 = fabs(p1.InnerProd(normal_vec));
+  if (fabs(diagonal_vec.InnerProd(normal_vec)) >= project_p1) {
+    return true;
+  }
+  diagonal_vec = center_ - corners_[1];
+  if (fabs(diagonal_vec.InnerProd(normal_vec)) >= project_p1) {
+    return true;
+  }
+  return false;
+}
+
+double Box2d::DistanceTo(const LineSegment2d &line_segment) const {
+  if (line_segment.length() <= kMathEpsilon) {
+    return DistanceTo(line_segment.start());
+  }
+  const double ref_x1 = line_segment.start().x() - center_.x();
+  const double ref_y1 = line_segment.start().y() - center_.y();
+  double x1 = ref_x1 * cos_heading_ + ref_y1 * sin_heading_;
+  double y1 = ref_x1 * sin_heading_ - ref_y1 * cos_heading_;
+  double box_x = half_length_;
+  double box_y = half_width_;
+  int gx1 = (x1 >= box_x ? 1 : (x1 <= -box_x ? -1 : 0));
+  int gy1 = (y1 >= box_y ? 1 : (y1 <= -box_y ? -1 : 0));
+  if (gx1 == 0 && gy1 == 0) {
+    return 0.0;
+  }
+  const double ref_x2 = line_segment.end().x() - center_.x();
+  const double ref_y2 = line_segment.end().y() - center_.y();
+  double x2 = ref_x2 * cos_heading_ + ref_y2 * sin_heading_;
+  double y2 = ref_x2 * sin_heading_ - ref_y2 * cos_heading_;
+  int gx2 = (x2 >= box_x ? 1 : (x2 <= -box_x ? -1 : 0));
+  int gy2 = (y2 >= box_y ? 1 : (y2 <= -box_y ? -1 : 0));
+  if (gx2 == 0 && gy2 == 0) {
+    return 0.0;
+  }
+  if (gx1 < 0 || (gx1 == 0 && gx2 < 0)) {
+    x1 = -x1;
+    gx1 = -gx1;
+    x2 = -x2;
+    gx2 = -gx2;
+  }
+  if (gy1 < 0 || (gy1 == 0 && gy2 < 0)) {
+    y1 = -y1;
+    gy1 = -gy1;
+    y2 = -y2;
+    gy2 = -gy2;
+  }
+  if (gx1 < gy1 || (gx1 == gy1 && gx2 < gy2)) {
+    std::swap(x1, y1);
+    std::swap(gx1, gy1);
+    std::swap(x2, y2);
+    std::swap(gx2, gy2);
+    std::swap(box_x, box_y);
+  }
+  if (gx1 == 1 && gy1 == 1) {
+    switch (gx2 * 3 + gy2) {
+      case 4:
+        return PtSegDistance(box_x, box_y, x1, y1, x2, y2,
+                             line_segment.length());
+      case 3:
+        return (x1 > x2) ? (x2 - box_x)
+                         : PtSegDistance(box_x, box_y, x1, y1, x2, y2,
+                                         line_segment.length());
+      case 2:
+        return (x1 > x2) ? PtSegDistance(box_x, -box_y, x1, y1, x2, y2,
+                                         line_segment.length())
+                         : PtSegDistance(box_x, box_y, x1, y1, x2, y2,
+                                         line_segment.length());
+      case -1:
+        return CrossProd({x1, y1}, {x2, y2}, {box_x, -box_y}) >= 0.0
+                   ? 0.0
+                   : PtSegDistance(box_x, -box_y, x1, y1, x2, y2,
+                                   line_segment.length());
+      case -4:
+        return CrossProd({x1, y1}, {x2, y2}, {box_x, -box_y}) <= 0.0
+                   ? PtSegDistance(box_x, -box_y, x1, y1, x2, y2,
+                                   line_segment.length())
+                   : (CrossProd({x1, y1}, {x2, y2}, {-box_x, box_y}) <= 0.0
+                          ? 0.0
+                          : PtSegDistance(-box_x, box_y, x1, y1, x2, y2,
+                                          line_segment.length()));
+    }
+  } else {
+    switch (gx2 * 3 + gy2) {
+      case 4:
+        return (x1 < x2) ? (x1 - box_x)
+                         : PtSegDistance(box_x, box_y, x1, y1, x2, y2,
+                                         line_segment.length());
+      case 3:
+        return std::min(x1, x2) - box_x;
+      case 1:
+      case -2:
+        return CrossProd({x1, y1}, {x2, y2}, {box_x, box_y}) <= 0.0
+                   ? 0.0
+                   : PtSegDistance(box_x, box_y, x1, y1, x2, y2,
+                                   line_segment.length());
+      case -3:
+        return 0.0;
+    }
+  }
+  ACHECK(0) << "unimplemented state: " << gx1 << " " << gy1 << " " << gx2 << " "
+            << gy2;
+  return 0.0;
+}
+
+double Box2d::DistanceTo(const Box2d &box) const {
+  return Polygon2d(box).DistanceTo(*this);
+}
+
+bool Box2d::HasOverlap(const Box2d &box) const {
+  if (box.max_x() < min_x() || box.min_x() > max_x() || box.max_y() < min_y() ||
+      box.min_y() > max_y()) {
+    return false;
+  }
+
+  const double shift_x = box.center_x() - center_.x();
+  const double shift_y = box.center_y() - center_.y();
+
+  const double dx1 = cos_heading_ * half_length_;
+  const double dy1 = sin_heading_ * half_length_;
+  const double dx2 = sin_heading_ * half_width_;
+  const double dy2 = -cos_heading_ * half_width_;
+  const double dx3 = box.cos_heading() * box.half_length();
+  const double dy3 = box.sin_heading() * box.half_length();
+  const double dx4 = box.sin_heading() * box.half_width();
+  const double dy4 = -box.cos_heading() * box.half_width();
+
+  return std::abs(shift_x * cos_heading_ + shift_y * sin_heading_) <=
+             std::abs(dx3 * cos_heading_ + dy3 * sin_heading_) +
+                 std::abs(dx4 * cos_heading_ + dy4 * sin_heading_) +
+                 half_length_ &&
+         std::abs(shift_x * sin_heading_ - shift_y * cos_heading_) <=
+             std::abs(dx3 * sin_heading_ - dy3 * cos_heading_) +
+                 std::abs(dx4 * sin_heading_ - dy4 * cos_heading_) +
+                 half_width_ &&
+         std::abs(shift_x * box.cos_heading() + shift_y * box.sin_heading()) <=
+             std::abs(dx1 * box.cos_heading() + dy1 * box.sin_heading()) +
+                 std::abs(dx2 * box.cos_heading() + dy2 * box.sin_heading()) +
+                 box.half_length() &&
+         std::abs(shift_x * box.sin_heading() - shift_y * box.cos_heading()) <=
+             std::abs(dx1 * box.sin_heading() - dy1 * box.cos_heading()) +
+                 std::abs(dx2 * box.sin_heading() - dy2 * box.cos_heading()) +
+                 box.half_width();
+}
+
+AABox2d Box2d::GetAABox() const {
+  const double dx1 = std::abs(cos_heading_ * half_length_);
+  const double dy1 = std::abs(sin_heading_ * half_length_);
+  const double dx2 = std::abs(sin_heading_ * half_width_);
+  const double dy2 = std::abs(cos_heading_ * half_width_);
+  return AABox2d(center_, (dx1 + dx2) * 2.0, (dy1 + dy2) * 2.0);
+}
+
+void Box2d::RotateFromCenter(const double rotate_angle) {
+  heading_ = NormalizeAngle(heading_ + rotate_angle);
+  cos_heading_ = std::cos(heading_);
+  sin_heading_ = std::sin(heading_);
+  InitCorners();
+}
+
+void Box2d::Shift(const Vec2d &shift_vec) {
+  center_ += shift_vec;
+  for (size_t i = 0; i < 4; ++i) {
+    corners_[i] += shift_vec;
+  }
+  for (auto &corner : corners_) {
+    max_x_ = std::fmax(corner.x(), max_x_);
+    min_x_ = std::fmin(corner.x(), min_x_);
+    max_y_ = std::fmax(corner.y(), max_y_);
+    min_y_ = std::fmin(corner.y(), min_y_);
+  }
+}
+
+void Box2d::LongitudinalExtend(const double extension_length) {
+  length_ += extension_length;
+  half_length_ += extension_length / 2.0;
+  InitCorners();
+}
+
+void Box2d::LateralExtend(const double extension_length) {
+  width_ += extension_length;
+  half_width_ += extension_length / 2.0;
+  InitCorners();
+}
+
+std::string Box2d::DebugString() const {
+  return absl::StrCat("box2d ( center = ", center_.DebugString(),
+                      "  heading = ", heading_, "  length = ", length_,
+                      "  width = ", width_, " )");
+}
+
+}  // namespace math
+}  // namespace common
+}  // namespace apollo

+ 299 - 0
src/test/testhdmap/modules/common/math/box2d.h

@@ -0,0 +1,299 @@
+/******************************************************************************
+ * 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
+ * @brief The class of Box2d. Here, the x/y axes are respectively Forward/Left,
+ *        as opposed to what happens in euler_angles_zxy.h (Right/Forward).
+ */
+
+#pragma once
+
+#include <limits>
+#include <string>
+#include <vector>
+
+#include "modules/common/math/aabox2d.h"
+#include "modules/common/math/line_segment2d.h"
+#include "modules/common/math/vec2d.h"
+
+/**
+ * @namespace apollo::common::math
+ * @brief apollo::common::math
+ */
+namespace apollo {
+namespace common {
+namespace math {
+
+/**
+ * @class Box2d
+ * @brief Rectangular (undirected) bounding box in 2-D.
+ *
+ * This class is referential-agnostic, although our convention on the use of
+ * the word "heading" in this project (permanently set to be 0 at East)
+ * forces us to assume that the X/Y frame here is East/North.
+ * For disambiguation, we call the axis of the rectangle parallel to the
+ * heading direction the "heading-axis". The size of the heading-axis is
+ * called "length", and the size of the axis perpendicular to it "width".
+ */
+class Box2d {
+ public:
+  Box2d() = default;
+  /**
+   * @brief Constructor which takes the center, heading, length and width.
+   * @param center The center of the rectangular bounding box.
+   * @param heading The angle between the x-axis and the heading-axis,
+   *        measured counter-clockwise.
+   * @param length The size of the heading-axis.
+   * @param width The size of the axis perpendicular to the heading-axis.
+   */
+  Box2d(const Vec2d &center, const double heading, const double length,
+        const double width);
+
+  /**
+   * @brief Constructor which takes the point on the axis, front length, back
+   * length, heading, and width.
+   * @param center The center of the rectangular bounding box.
+   * @param heading The angle between the x-axis and the heading-axis,
+   *        measured counter-clockwise.
+   * @param front_length The length from the start point to the given point.
+   * @param back_length The length from the end point to the given point.
+   * @param width The size of the axis perpendicular to the heading-axis.
+   */
+  Box2d(const Vec2d &point, double heading, double front_length,
+        double back_length, double width);
+
+  /**
+   * @brief Constructor which takes the heading-axis and the width of the box
+   * @param axis The heading-axis
+   * @param width The width of the box, which is taken perpendicularly
+   * to the heading direction.
+   */
+  Box2d(const LineSegment2d &axis, const double width);
+
+  /**
+   * @brief Constructor which takes an AABox2d (axes-aligned box).
+   * @param aabox The input AABox2d.
+   */
+  explicit Box2d(const AABox2d &aabox);
+
+  /**
+   * @brief Creates an axes-aligned Box2d from two opposite corners
+   * @param one_corner One of the corners
+   * @param opposite_corner The opposite corner to the first one
+   * @return An axes-aligned Box2d
+   */
+  static Box2d CreateAABox(const Vec2d &one_corner,
+                           const Vec2d &opposite_corner);
+
+  /**
+   * @brief Getter of the center of the box
+   * @return The center of the box
+   */
+  const Vec2d &center() const { return center_; }
+
+  /**
+   * @brief Getter of the x-coordinate of the center of the box
+   * @return The x-coordinate of the center of the box
+   */
+  double center_x() const { return center_.x(); }
+
+  /**
+   * @brief Getter of the y-coordinate of the center of the box
+   * @return The y-coordinate of the center of the box
+   */
+  double center_y() const { return center_.y(); }
+
+  /**
+   * @brief Getter of the length
+   * @return The length of the heading-axis
+   */
+  double length() const { return length_; }
+
+  /**
+   * @brief Getter of the width
+   * @return The width of the box taken perpendicularly to the heading
+   */
+  double width() const { return width_; }
+
+  /**
+   * @brief Getter of half the length
+   * @return Half the length of the heading-axis
+   */
+  double half_length() const { return half_length_; }
+
+  /**
+   * @brief Getter of half the width
+   * @return Half the width of the box taken perpendicularly to the heading
+   */
+  double half_width() const { return half_width_; }
+
+  /**
+   * @brief Getter of the heading
+   * @return The counter-clockwise angle between the x-axis and the heading-axis
+   */
+  double heading() const { return heading_; }
+
+  /**
+   * @brief Getter of the cosine of the heading
+   * @return The cosine of the heading
+   */
+  double cos_heading() const { return cos_heading_; }
+
+  /**
+   * @brief Getter of the sine of the heading
+   * @return The sine of the heading
+   */
+  double sin_heading() const { return sin_heading_; }
+
+  /**
+   * @brief Getter of the area of the box
+   * @return The product of its length and width
+   */
+  double area() const { return length_ * width_; }
+
+  /**
+   * @brief Getter of the size of the diagonal of the box
+   * @return The diagonal size of the box
+   */
+  double diagonal() const { return std::hypot(length_, width_); }
+
+  /**
+   * @brief Getter of the corners of the box
+   * @param corners The vector where the corners are listed
+   */
+  void GetAllCorners(std::vector<Vec2d> *const corners) const;
+
+  /**
+   * @brief Getter of the corners of the box
+   * @param corners The vector where the corners are listed
+   */
+  const std::vector<Vec2d> &GetAllCorners() const;
+
+  /**
+   * @brief Tests points for membership in the box
+   * @param point A point that we wish to test for membership in the box
+   * @return True iff the point is contained in the box
+   */
+  bool IsPointIn(const Vec2d &point) const;
+
+  /**
+   * @brief Tests points for membership in the boundary of the box
+   * @param point A point that we wish to test for membership in the boundary
+   * @return True iff the point is a boundary point of the box
+   */
+  bool IsPointOnBoundary(const Vec2d &point) const;
+
+  /**
+   * @brief Determines the distance between the box and a given point
+   * @param point The point whose distance to the box we wish to compute
+   * @return A distance
+   */
+  double DistanceTo(const Vec2d &point) const;
+
+  /**
+   * @brief Determines the distance between the box and a given line segment
+   * @param line_segment The line segment whose distance to the box we compute
+   * @return A distance
+   */
+  double DistanceTo(const LineSegment2d &line_segment) const;
+
+  /**
+   * @brief Determines the distance between two boxes
+   * @param box The box whose distance to this box we want to compute
+   * @return A distance
+   */
+  double DistanceTo(const Box2d &box) const;
+
+  /**
+   * @brief Determines whether this box overlaps a given line segment
+   * @param line_segment The line-segment
+   * @return True if they overlap
+   */
+  bool HasOverlap(const LineSegment2d &line_segment) const;
+
+  /**
+   * @brief Determines whether these two boxes overlap
+   * @param line_segment The other box
+   * @return True if they overlap
+   */
+  bool HasOverlap(const Box2d &box) const;
+
+  /**
+   * @brief Gets the smallest axes-aligned box containing the current one
+   * @return An axes-aligned box
+   */
+  AABox2d GetAABox() const;
+
+  /**
+   * @brief Rotate from center.
+   * @param rotate_angle Angle to rotate.
+   */
+  void RotateFromCenter(const double rotate_angle);
+
+  /**
+   * @brief Shifts this box by a given vector
+   * @param shift_vec The vector determining the shift
+   */
+  void Shift(const Vec2d &shift_vec);
+
+  /**
+   * @brief Extend the box longitudinally
+   * @param extension_length the length to extend
+   */
+  void LongitudinalExtend(const double extension_length);
+
+  void LateralExtend(const double extension_length);
+
+  /**
+   * @brief Gets a human-readable description of the box
+   * @return A debug-string
+   */
+  std::string DebugString() const;
+
+  void InitCorners();
+
+  double max_x() const { return max_x_; }
+  double min_x() const { return min_x_; }
+  double max_y() const { return max_y_; }
+  double min_y() const { return min_y_; }
+
+ private:
+  inline bool is_inside_rectangle(const Vec2d &point) const {
+    return (point.x() >= 0.0 && point.x() <= width_ && point.y() >= 0.0 &&
+            point.y() <= length_);
+  }
+
+  Vec2d center_;
+  double length_ = 0.0;
+  double width_ = 0.0;
+  double half_length_ = 0.0;
+  double half_width_ = 0.0;
+  double heading_ = 0.0;
+  double cos_heading_ = 1.0;
+  double sin_heading_ = 0.0;
+
+  std::vector<Vec2d> corners_;
+
+  double max_x_ = std::numeric_limits<double>::lowest();
+  double min_x_ = std::numeric_limits<double>::max();
+  double max_y_ = std::numeric_limits<double>::lowest();
+  double min_y_ = std::numeric_limits<double>::max();
+};
+
+}  // namespace math
+}  // namespace common
+}  // namespace apollo

+ 229 - 0
src/test/testhdmap/modules/common/math/line_segment2d.cc

@@ -0,0 +1,229 @@
+/******************************************************************************
+ * 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/common/math/line_segment2d.h"
+
+#include <algorithm>
+#include <cmath>
+#include <utility>
+
+#include "absl/strings/str_cat.h"
+#include "cyber/common/log.h"
+
+#include "modules/common/math/math_utils.h"
+
+namespace apollo {
+namespace common {
+namespace math {
+namespace {
+
+bool IsWithin(double val, double bound1, double bound2) {
+  if (bound1 > bound2) {
+    std::swap(bound1, bound2);
+  }
+  return val >= bound1 - kMathEpsilon && val <= bound2 + kMathEpsilon;
+}
+
+}  // namespace
+
+LineSegment2d::LineSegment2d() { unit_direction_ = Vec2d(1, 0); }
+
+LineSegment2d::LineSegment2d(const Vec2d &start, const Vec2d &end)
+    : start_(start), end_(end) {
+  const double dx = end_.x() - start_.x();
+  const double dy = end_.y() - start_.y();
+  length_ = hypot(dx, dy);
+  unit_direction_ =
+      (length_ <= kMathEpsilon ? Vec2d(0, 0)
+                               : Vec2d(dx / length_, dy / length_));
+  heading_ = unit_direction_.Angle();
+}
+
+Vec2d LineSegment2d::rotate(const double angle) {
+  Vec2d diff_vec = end_ - start_;
+  diff_vec.SelfRotate(angle);
+  return start_ + diff_vec;
+}
+
+double LineSegment2d::length() const { return length_; }
+
+double LineSegment2d::length_sqr() const { return length_ * length_; }
+
+double LineSegment2d::DistanceTo(const Vec2d &point) const {
+  if (length_ <= kMathEpsilon) {
+    return point.DistanceTo(start_);
+  }
+  const double x0 = point.x() - start_.x();
+  const double y0 = point.y() - start_.y();
+  const double proj = x0 * unit_direction_.x() + y0 * unit_direction_.y();
+  if (proj <= 0.0) {
+    return hypot(x0, y0);
+  }
+  if (proj >= length_) {
+    return point.DistanceTo(end_);
+  }
+  return std::abs(x0 * unit_direction_.y() - y0 * unit_direction_.x());
+}
+
+double LineSegment2d::DistanceTo(const Vec2d &point,
+                                 Vec2d *const nearest_pt) const {
+  CHECK_NOTNULL(nearest_pt);
+  if (length_ <= kMathEpsilon) {
+    *nearest_pt = start_;
+    return point.DistanceTo(start_);
+  }
+  const double x0 = point.x() - start_.x();
+  const double y0 = point.y() - start_.y();
+  const double proj = x0 * unit_direction_.x() + y0 * unit_direction_.y();
+  if (proj < 0.0) {
+    *nearest_pt = start_;
+    return hypot(x0, y0);
+  }
+  if (proj > length_) {
+    *nearest_pt = end_;
+    return point.DistanceTo(end_);
+  }
+  *nearest_pt = start_ + unit_direction_ * proj;
+  return std::abs(x0 * unit_direction_.y() - y0 * unit_direction_.x());
+}
+
+double LineSegment2d::DistanceSquareTo(const Vec2d &point) const {
+  if (length_ <= kMathEpsilon) {
+    return point.DistanceSquareTo(start_);
+  }
+  const double x0 = point.x() - start_.x();
+  const double y0 = point.y() - start_.y();
+  const double proj = x0 * unit_direction_.x() + y0 * unit_direction_.y();
+  if (proj <= 0.0) {
+    return Square(x0) + Square(y0);
+  }
+  if (proj >= length_) {
+    return point.DistanceSquareTo(end_);
+  }
+  return Square(x0 * unit_direction_.y() - y0 * unit_direction_.x());
+}
+
+double LineSegment2d::DistanceSquareTo(const Vec2d &point,
+                                       Vec2d *const nearest_pt) const {
+  CHECK_NOTNULL(nearest_pt);
+  if (length_ <= kMathEpsilon) {
+    *nearest_pt = start_;
+    return point.DistanceSquareTo(start_);
+  }
+  const double x0 = point.x() - start_.x();
+  const double y0 = point.y() - start_.y();
+  const double proj = x0 * unit_direction_.x() + y0 * unit_direction_.y();
+  if (proj <= 0.0) {
+    *nearest_pt = start_;
+    return Square(x0) + Square(y0);
+  }
+  if (proj >= length_) {
+    *nearest_pt = end_;
+    return point.DistanceSquareTo(end_);
+  }
+  *nearest_pt = start_ + unit_direction_ * proj;
+  return Square(x0 * unit_direction_.y() - y0 * unit_direction_.x());
+}
+
+bool LineSegment2d::IsPointIn(const Vec2d &point) const {
+  if (length_ <= kMathEpsilon) {
+    return std::abs(point.x() - start_.x()) <= kMathEpsilon &&
+           std::abs(point.y() - start_.y()) <= kMathEpsilon;
+  }
+  const double prod = CrossProd(point, start_, end_);
+  if (std::abs(prod) > kMathEpsilon) {
+    return false;
+  }
+  return IsWithin(point.x(), start_.x(), end_.x()) &&
+         IsWithin(point.y(), start_.y(), end_.y());
+}
+
+double LineSegment2d::ProjectOntoUnit(const Vec2d &point) const {
+  return unit_direction_.InnerProd(point - start_);
+}
+
+double LineSegment2d::ProductOntoUnit(const Vec2d &point) const {
+  return unit_direction_.CrossProd(point - start_);
+}
+
+bool LineSegment2d::HasIntersect(const LineSegment2d &other_segment) const {
+  Vec2d point;
+  return GetIntersect(other_segment, &point);
+}
+
+bool LineSegment2d::GetIntersect(const LineSegment2d &other_segment,
+                                 Vec2d *const point) const {
+  CHECK_NOTNULL(point);
+  if (IsPointIn(other_segment.start())) {
+    *point = other_segment.start();
+    return true;
+  }
+  if (IsPointIn(other_segment.end())) {
+    *point = other_segment.end();
+    return true;
+  }
+  if (other_segment.IsPointIn(start_)) {
+    *point = start_;
+    return true;
+  }
+  if (other_segment.IsPointIn(end_)) {
+    *point = end_;
+    return true;
+  }
+  if (length_ <= kMathEpsilon || other_segment.length() <= kMathEpsilon) {
+    return false;
+  }
+  const double cc1 = CrossProd(start_, end_, other_segment.start());
+  const double cc2 = CrossProd(start_, end_, other_segment.end());
+  if (cc1 * cc2 >= -kMathEpsilon) {
+    return false;
+  }
+  const double cc3 =
+      CrossProd(other_segment.start(), other_segment.end(), start_);
+  const double cc4 =
+      CrossProd(other_segment.start(), other_segment.end(), end_);
+  if (cc3 * cc4 >= -kMathEpsilon) {
+    return false;
+  }
+  const double ratio = cc4 / (cc4 - cc3);
+  *point = Vec2d(start_.x() * ratio + end_.x() * (1.0 - ratio),
+                 start_.y() * ratio + end_.y() * (1.0 - ratio));
+  return true;
+}
+
+// return distance with perpendicular foot point.
+double LineSegment2d::GetPerpendicularFoot(const Vec2d &point,
+                                           Vec2d *const foot_point) const {
+  CHECK_NOTNULL(foot_point);
+  if (length_ <= kMathEpsilon) {
+    *foot_point = start_;
+    return point.DistanceTo(start_);
+  }
+  const double x0 = point.x() - start_.x();
+  const double y0 = point.y() - start_.y();
+  const double proj = x0 * unit_direction_.x() + y0 * unit_direction_.y();
+  *foot_point = start_ + unit_direction_ * proj;
+  return std::abs(x0 * unit_direction_.y() - y0 * unit_direction_.x());
+}
+
+std::string LineSegment2d::DebugString() const {
+  return absl::StrCat("segment2d ( start = ", start_.DebugString(),
+                      "  end = ", end_.DebugString(), " )");
+}
+
+}  // namespace math
+}  // namespace common
+}  // namespace apollo

+ 227 - 0
src/test/testhdmap/modules/common/math/line_segment2d.h

@@ -0,0 +1,227 @@
+/******************************************************************************
+ * 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
+ * @brief Define the LineSegment2d class.
+ */
+
+#pragma once
+
+#include <string>
+
+#include "modules/common/math/vec2d.h"
+
+/**
+ * @namespace apollo::common::math
+ * @brief apollo::common::math
+ */
+namespace apollo {
+namespace common {
+namespace math {
+
+/**
+ * @class LineSegment2d
+ * @brief Line segment in 2-D.
+ */
+class LineSegment2d {
+ public:
+  /**
+   * @brief Empty constructor.
+   */
+  LineSegment2d();
+
+  /**
+   * @brief Constructor with start point and end point.
+   * @param start The start point of the line segment.
+   * @param end The end point of the line segment.
+   */
+  LineSegment2d(const Vec2d &start, const Vec2d &end);
+
+  /**
+   * @brief Get the start point.
+   * @return The start point of the line segment.
+   */
+  const Vec2d &start() const { return start_; }
+
+  /**
+   * @brief Get the end point.
+   * @return The end point of the line segment.
+   */
+  const Vec2d &end() const { return end_; }
+
+  /**
+   * @brief Get the unit direction from the start point to the end point.
+   * @return The start point of the line segment.
+   */
+  const Vec2d &unit_direction() const { return unit_direction_; }
+
+  /**
+   * @brief Get the center of the line segment.
+   * @return The center of the line segment.
+   */
+  Vec2d center() const { return (start_ + end_) / 2.0; }
+
+  /** @brief Get a new line-segment with the same start point, but rotated
+   * counterclock-wise by the given amount.
+   * @return The rotated line-segment's end-point.
+   */
+  Vec2d rotate(const double angle);
+
+  /**
+   * @brief Get the heading of the line segment.
+   * @return The heading, which is the angle between unit direction and x-axis.
+   */
+  double heading() const { return heading_; }
+
+  /**
+   * @brief Get the cosine of the heading.
+   * @return The cosine of the heading.
+   */
+  double cos_heading() const { return unit_direction_.x(); }
+
+  /**
+   * @brief Get the sine of the heading.
+   * @return The sine of the heading.
+   */
+  double sin_heading() const { return unit_direction_.y(); }
+
+  /**
+   * @brief Get the length of the line segment.
+   * @return The length of the line segment.
+   */
+  double length() const;
+
+  /**
+   * @brief Get the square of length of the line segment.
+   * @return The square of length of the line segment.
+   */
+  double length_sqr() const;
+
+  /**
+   * @brief Compute the shortest distance from a point on the line segment
+   *        to a point in 2-D.
+   * @param point The point to compute the distance to.
+   * @return The shortest distance from points on the line segment to point.
+   */
+  double DistanceTo(const Vec2d &point) const;
+
+  /**
+   * @brief Compute the shortest distance from a point on the line segment
+   *        to a point in 2-D, and get the nearest point on the line segment.
+   * @param point The point to compute the distance to.
+   * @param nearest_pt The nearest point on the line segment
+   *        to the input point.
+   * @return The shortest distance from points on the line segment
+   *         to the input point.
+   */
+  double DistanceTo(const Vec2d &point, Vec2d *const nearest_pt) const;
+
+  /**
+   * @brief Compute the square of the shortest distance from a point
+   *        on the line segment to a point in 2-D.
+   * @param point The point to compute the squared of the distance to.
+   * @return The square of the shortest distance from points
+   *         on the line segment to the input point.
+   */
+  double DistanceSquareTo(const Vec2d &point) const;
+
+  /**
+   * @brief Compute the square of the shortest distance from a point
+   *        on the line segment to a point in 2-D,
+   *        and get the nearest point on the line segment.
+   * @param point The point to compute the squared of the distance to.
+   * @param nearest_pt The nearest point on the line segment
+   *        to the input point.
+   * @return The shortest distance from points on the line segment
+   *         to the input point.
+   */
+  double DistanceSquareTo(const Vec2d &point, Vec2d *const nearest_pt) const;
+
+  /**
+   * @brief Check if a point is within the line segment.
+   * @param point The point to check if it is within the line segment.
+   * @return Whether the input point is within the line segment or not.
+   */
+  bool IsPointIn(const Vec2d &point) const;
+
+  /**
+   * @brief Check if the line segment has an intersect
+   *        with another line segment in 2-D.
+   * @param other_segment The line segment to check if it has an intersect.
+   * @return Whether the line segment has an intersect
+   *         with the input other_segment.
+   */
+  bool HasIntersect(const LineSegment2d &other_segment) const;
+
+  /**
+   * @brief Compute the intersect with another line segment in 2-D if any.
+   * @param other_segment The line segment to compute the intersect.
+   * @param point the computed intersect between the line segment and
+   *        the input other_segment.
+   * @return Whether the line segment has an intersect
+   *         with the input other_segment.
+   */
+  bool GetIntersect(const LineSegment2d &other_segment,
+                    Vec2d *const point) const;
+
+  /**
+   * @brief Compute the projection of a vector onto the line segment.
+   * @param point The end of the vector (starting from the start point of the
+   *        line segment) to compute the projection onto the line segment.
+   * @return The projection of the vector, which is from the start point of
+   *         the line segment to the input point, onto the unit direction.
+   */
+  double ProjectOntoUnit(const Vec2d &point) const;
+
+  /**
+   * @brief Compute the cross product of a vector onto the line segment.
+   * @param point The end of the vector (starting from the start point of the
+   *        line segment) to compute the cross product onto the line segment.
+   * @return The cross product of the unit direction and
+   *         the vector, which is from the start point of
+   *         the line segment to the input point.
+   */
+  double ProductOntoUnit(const Vec2d &point) const;
+
+  /**
+   * @brief Compute perpendicular foot of a point in 2-D on the straight line
+   *        expanded from the line segment.
+   * @param point The point to compute the perpendicular foot from.
+   * @param foot_point The computed perpendicular foot from the input point to
+   *        the straight line expanded from the line segment.
+   * @return The distance from the input point to the perpendicular foot.
+   */
+  double GetPerpendicularFoot(const Vec2d &point,
+                              Vec2d *const foot_point) const;
+
+  /**
+   * @brief Get the debug string including the essential information.
+   * @return Information of the line segment for debugging.
+   */
+  std::string DebugString() const;
+
+ private:
+  Vec2d start_;
+  Vec2d end_;
+  Vec2d unit_direction_;
+  double heading_ = 0.0;
+  double length_ = 0.0;
+};
+
+}  // namespace math
+}  // namespace common
+}  // namespace apollo

+ 115 - 0
src/test/testhdmap/modules/common/math/linear_interpolation.cc

@@ -0,0 +1,115 @@
+/******************************************************************************
+ * 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/common/math/linear_interpolation.h"
+
+#include <cmath>
+
+#include "cyber/common/log.h"
+#include "modules/common/math/math_utils.h"
+
+namespace apollo {
+namespace common {
+namespace math {
+
+double slerp(const double a0, const double t0, const double a1, const double t1,
+             const double t) {
+  if (std::abs(t1 - t0) <= kMathEpsilon) {
+    ADEBUG << "input time difference is too small";
+    return NormalizeAngle(a0);
+  }
+  const double a0_n = NormalizeAngle(a0);
+  const double a1_n = NormalizeAngle(a1);
+  double d = a1_n - a0_n;
+  if (d > M_PI) {
+    d = d - 2 * M_PI;
+  } else if (d < -M_PI) {
+    d = d + 2 * M_PI;
+  }
+
+  const double r = (t - t0) / (t1 - t0);
+  const double a = a0_n + d * r;
+  return NormalizeAngle(a);
+}
+
+SLPoint InterpolateUsingLinearApproximation(const SLPoint &p0,
+                                            const SLPoint &p1, const double w) {
+  CHECK_GE(w, 0.0);
+
+  SLPoint p;
+  p.set_s((1 - w) * p0.s() + w * p1.s());
+  p.set_l((1 - w) * p0.l() + w * p1.l());
+  return p;
+}
+
+PathPoint InterpolateUsingLinearApproximation(const PathPoint &p0,
+                                              const PathPoint &p1,
+                                              const double s) {
+  double s0 = p0.s();
+  double s1 = p1.s();
+
+  PathPoint path_point;
+  double weight = (s - s0) / (s1 - s0);
+  double x = (1 - weight) * p0.x() + weight * p1.x();
+  double y = (1 - weight) * p0.y() + weight * p1.y();
+  double theta = slerp(p0.theta(), p0.s(), p1.theta(), p1.s(), s);
+  double kappa = (1 - weight) * p0.kappa() + weight * p1.kappa();
+  double dkappa = (1 - weight) * p0.dkappa() + weight * p1.dkappa();
+  double ddkappa = (1 - weight) * p0.ddkappa() + weight * p1.ddkappa();
+  path_point.set_x(x);
+  path_point.set_y(y);
+  path_point.set_theta(theta);
+  path_point.set_kappa(kappa);
+  path_point.set_dkappa(dkappa);
+  path_point.set_ddkappa(ddkappa);
+  path_point.set_s(s);
+  return path_point;
+}
+
+TrajectoryPoint InterpolateUsingLinearApproximation(const TrajectoryPoint &tp0,
+                                                    const TrajectoryPoint &tp1,
+                                                    const double t) {
+  if (!tp0.has_path_point() || !tp1.has_path_point()) {
+    TrajectoryPoint p;
+    p.mutable_path_point()->CopyFrom(PathPoint());
+    return p;
+  }
+  const PathPoint pp0 = tp0.path_point();
+  const PathPoint pp1 = tp1.path_point();
+  double t0 = tp0.relative_time();
+  double t1 = tp1.relative_time();
+
+  TrajectoryPoint tp;
+  tp.set_v(lerp(tp0.v(), t0, tp1.v(), t1, t));
+  tp.set_a(lerp(tp0.a(), t0, tp1.a(), t1, t));
+  tp.set_relative_time(t);
+  tp.set_steer(slerp(tp0.steer(), t0, tp1.steer(), t1, t));
+
+  PathPoint *path_point = tp.mutable_path_point();
+  path_point->set_x(lerp(pp0.x(), t0, pp1.x(), t1, t));
+  path_point->set_y(lerp(pp0.y(), t0, pp1.y(), t1, t));
+  path_point->set_theta(slerp(pp0.theta(), t0, pp1.theta(), t1, t));
+  path_point->set_kappa(lerp(pp0.kappa(), t0, pp1.kappa(), t1, t));
+  path_point->set_dkappa(lerp(pp0.dkappa(), t0, pp1.dkappa(), t1, t));
+  path_point->set_ddkappa(lerp(pp0.ddkappa(), t0, pp1.ddkappa(), t1, t));
+  path_point->set_s(lerp(pp0.s(), t0, pp1.s(), t1, t));
+
+  return tp;
+}
+
+}  // namespace math
+}  // namespace common
+}  // namespace apollo

+ 86 - 0
src/test/testhdmap/modules/common/math/linear_interpolation.h

@@ -0,0 +1,86 @@
+/******************************************************************************
+ * 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
+ * @brief Linear interpolation functions.
+ */
+
+#pragma once
+
+#include <cmath>
+
+#include "cyber/common/log.h"
+#include "modules/common_msgs/basic_msgs/pnc_point.pb.h"
+
+/**
+ * @namespace apollo::common::math
+ * @brief apollo::common::math
+ */
+namespace apollo {
+namespace common {
+namespace math {
+
+/**
+ * @brief Linear interpolation between two points of type T.
+ * @param x0 The coordinate of the first point.
+ * @param t0 The interpolation parameter of the first point.
+ * @param x1 The coordinate of the second point.
+ * @param t1 The interpolation parameter of the second point.
+ * @param t The interpolation parameter for interpolation.
+ * @param x The coordinate of the interpolated point.
+ * @return Interpolated point.
+ */
+template <typename T>
+T lerp(const T &x0, const double t0, const T &x1, const double t1,
+       const double t) {
+  if (std::abs(t1 - t0) <= 1.0e-6) {
+    AERROR << "input time difference is too small";
+    return x0;
+  }
+  const double r = (t - t0) / (t1 - t0);
+  const T x = x0 + r * (x1 - x0);
+  return x;
+}
+
+/**
+ * @brief Spherical linear interpolation between two angles.
+ *        The two angles are within range [-M_PI, M_PI).
+ * @param a0 The value of the first angle.
+ * @param t0 The interpolation parameter of the first angle.
+ * @param a1 The value of the second angle.
+ * @param t1 The interpolation parameter of the second angle.
+ * @param t The interpolation parameter for interpolation.
+ * @param a The value of the spherically interpolated angle.
+ * @return Interpolated angle.
+ */
+double slerp(const double a0, const double t0, const double a1, const double t1,
+             const double t);
+
+SLPoint InterpolateUsingLinearApproximation(const SLPoint &p0,
+                                            const SLPoint &p1, const double w);
+
+PathPoint InterpolateUsingLinearApproximation(const PathPoint &p0,
+                                              const PathPoint &p1,
+                                              const double s);
+
+TrajectoryPoint InterpolateUsingLinearApproximation(const TrajectoryPoint &tp0,
+                                                    const TrajectoryPoint &tp1,
+                                                    const double t);
+
+}  // namespace math
+}  // namespace common
+}  // namespace apollo

+ 108 - 0
src/test/testhdmap/modules/common/math/math_utils.cc

@@ -0,0 +1,108 @@
+/******************************************************************************
+ * 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/common/math/math_utils.h"
+
+#include <cmath>
+#include <utility>
+
+namespace apollo {
+namespace common {
+namespace math {
+
+double Sqr(const double x) { return x * x; }
+
+double CrossProd(const Vec2d& start_point, const Vec2d& end_point_1,
+                 const Vec2d& end_point_2) {
+  return (end_point_1 - start_point).CrossProd(end_point_2 - start_point);
+}
+
+double InnerProd(const Vec2d& start_point, const Vec2d& end_point_1,
+                 const Vec2d& end_point_2) {
+  return (end_point_1 - start_point).InnerProd(end_point_2 - start_point);
+}
+
+double CrossProd(const double x0, const double y0, const double x1,
+                 const double y1) {
+  return x0 * y1 - x1 * y0;
+}
+
+double InnerProd(const double x0, const double y0, const double x1,
+                 const double y1) {
+  return x0 * x1 + y0 * y1;
+}
+
+double WrapAngle(const double angle) {
+  const double new_angle = std::fmod(angle, M_PI * 2.0);
+  return new_angle < 0 ? new_angle + M_PI * 2.0 : new_angle;
+}
+
+double NormalizeAngle(const double angle) {
+  double a = std::fmod(angle + M_PI, 2.0 * M_PI);
+  if (a < 0.0) {
+    a += (2.0 * M_PI);
+  }
+  return a - M_PI;
+}
+
+double AngleDiff(const double from, const double to) {
+  return NormalizeAngle(to - from);
+}
+
+int RandomInt(const int s, const int t, unsigned int rand_seed) {
+  if (s >= t) {
+    return s;
+  }
+  return s + rand_r(&rand_seed) % (t - s + 1);
+}
+
+double RandomDouble(const double s, const double t, unsigned int rand_seed) {
+  return s + (t - s) / 16383.0 * (rand_r(&rand_seed) & 16383);
+}
+
+// Gaussian
+double Gaussian(const double u, const double std, const double x) {
+  return (1.0 / std::sqrt(2 * M_PI * std * std)) *
+         std::exp(-(x - u) * (x - u) / (2 * std * std));
+}
+
+Eigen::Vector2d RotateVector2d(const Eigen::Vector2d& v_in,
+                               const double theta) {
+  const double cos_theta = std::cos(theta);
+  const double sin_theta = std::sin(theta);
+
+  auto x = cos_theta * v_in.x() - sin_theta * v_in.y();
+  auto y = sin_theta * v_in.x() + cos_theta * v_in.y();
+
+  return {x, y};
+}
+
+std::pair<double, double> Cartesian2Polar(double x, double y) {
+  double r = std::sqrt(x * x + y * y);
+  double theta = std::atan2(y, x);
+  return std::make_pair(r, theta);
+}
+
+double check_negative(double input_data) {
+  if (std::signbit(input_data)) {
+    input_data = -input_data;
+  }
+  return input_data;
+}
+
+}  // namespace math
+}  // namespace common
+}  // namespace apollo

+ 224 - 0
src/test/testhdmap/modules/common/math/math_utils.h

@@ -0,0 +1,224 @@
+/******************************************************************************
+ * 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
+ * @brief Math-related util functions.
+ */
+
+#pragma once
+
+#include <cmath>
+#include <limits>
+#include <type_traits>
+#include <utility>
+
+#include "Eigen/Dense"
+
+#include "modules/common/math/vec2d.h"
+
+/**
+ * @namespace apollo::common::math
+ * @brief apollo::common::math
+ */
+namespace apollo {
+namespace common {
+namespace math {
+
+double Sqr(const double x);
+
+/**
+ * @brief Cross product between two 2-D vectors from the common start point,
+ *        and end at two other points.
+ * @param start_point The common start point of two vectors in 2-D.
+ * @param end_point_1 The end point of the first vector.
+ * @param end_point_2 The end point of the second vector.
+ *
+ * @return The cross product result.
+ */
+double CrossProd(const Vec2d &start_point, const Vec2d &end_point_1,
+                 const Vec2d &end_point_2);
+
+/**
+ * @brief Inner product between two 2-D vectors from the common start point,
+ *        and end at two other points.
+ * @param start_point The common start point of two vectors in 2-D.
+ * @param end_point_1 The end point of the first vector.
+ * @param end_point_2 The end point of the second vector.
+ *
+ * @return The inner product result.
+ */
+double InnerProd(const Vec2d &start_point, const Vec2d &end_point_1,
+                 const Vec2d &end_point_2);
+
+/**
+ * @brief Cross product between two vectors.
+ *        One vector is formed by 1st and 2nd parameters of the function.
+ *        The other vector is formed by 3rd and 4th parameters of the function.
+ * @param x0 The x coordinate of the first vector.
+ * @param y0 The y coordinate of the first vector.
+ * @param x1 The x coordinate of the second vector.
+ * @param y1 The y coordinate of the second vector.
+ *
+ * @return The cross product result.
+ */
+double CrossProd(const double x0, const double y0, const double x1,
+                 const double y1);
+
+/**
+ * @brief Inner product between two vectors.
+ *        One vector is formed by 1st and 2nd parameters of the function.
+ *        The other vector is formed by 3rd and 4th parameters of the function.
+ * @param x0 The x coordinate of the first vector.
+ * @param y0 The y coordinate of the first vector.
+ * @param x1 The x coordinate of the second vector.
+ * @param y1 The y coordinate of the second vector.
+ *
+ * @return The inner product result.
+ */
+double InnerProd(const double x0, const double y0, const double x1,
+                 const double y1);
+
+/**
+ * @brief Wrap angle to [0, 2 * PI).
+ * @param angle the original value of the angle.
+ * @return The wrapped value of the angle.
+ */
+double WrapAngle(const double angle);
+
+/**
+ * @brief Normalize angle to [-PI, PI).
+ * @param angle the original value of the angle.
+ * @return The normalized value of the angle.
+ */
+double NormalizeAngle(const double angle);
+
+/**
+ * @brief Calculate the difference between angle from and to
+ * @param from the start angle
+ * @param from the end angle
+ * @return The difference between from and to. The range is between [-PI, PI).
+ */
+double AngleDiff(const double from, const double to);
+
+/**
+ * @brief Get a random integer between two integer values by a random seed.
+ * @param s The lower bound of the random integer.
+ * @param t The upper bound of the random integer.
+ * @param random_seed The random seed.
+ * @return A random integer between s and t based on the input random_seed.
+ */
+int RandomInt(const int s, const int t, unsigned int rand_seed = 1);
+
+/**
+ * @brief Get a random double between two integer values by a random seed.
+ * @param s The lower bound of the random double.
+ * @param t The upper bound of the random double.
+ * @param random_seed The random seed.
+ * @return A random double between s and t based on the input random_seed.
+ */
+double RandomDouble(const double s, const double t, unsigned int rand_seed = 1);
+
+/**
+ * @brief Compute squared value.
+ * @param value The target value to get its squared value.
+ * @return Squared value of the input value.
+ */
+template <typename T>
+inline T Square(const T value) {
+  return value * value;
+}
+
+/**
+ * @brief Clamp a value between two bounds.
+ *        If the value goes beyond the bounds, return one of the bounds,
+ *        otherwise, return the original value.
+ * @param value The original value to be clamped.
+ * @param bound1 One bound to clamp the value.
+ * @param bound2 The other bound to clamp the value.
+ * @return The clamped value.
+ */
+template <typename T>
+T Clamp(const T value, T bound1, T bound2) {
+  if (bound1 > bound2) {
+    std::swap(bound1, bound2);
+  }
+
+  if (value < bound1) {
+    return bound1;
+  } else if (value > bound2) {
+    return bound2;
+  }
+  return value;
+}
+
+// Gaussian
+double Gaussian(const double u, const double std, const double x);
+
+inline double Sigmoid(const double x) { return 1.0 / (1.0 + std::exp(-x)); }
+
+// Rotate a 2d vector counter-clockwise by theta
+Eigen::Vector2d RotateVector2d(const Eigen::Vector2d &v_in, const double theta);
+
+inline std::pair<double, double> RFUToFLU(const double x, const double y) {
+  return std::make_pair(y, -x);
+}
+
+inline std::pair<double, double> FLUToRFU(const double x, const double y) {
+  return std::make_pair(-y, x);
+}
+
+inline void L2Norm(int feat_dim, float *feat_data) {
+  if (feat_dim == 0) {
+    return;
+  }
+  // feature normalization
+  float l2norm = 0.0f;
+  for (int i = 0; i < feat_dim; ++i) {
+    l2norm += feat_data[i] * feat_data[i];
+  }
+  if (l2norm == 0) {
+    float val = 1.f / std::sqrt(static_cast<float>(feat_dim));
+    for (int i = 0; i < feat_dim; ++i) {
+      feat_data[i] = val;
+    }
+  } else {
+    l2norm = std::sqrt(l2norm);
+    for (int i = 0; i < feat_dim; ++i) {
+      feat_data[i] /= l2norm;
+    }
+  }
+}
+
+// Cartesian coordinates to Polar coordinates
+std::pair<double, double> Cartesian2Polar(double x, double y);
+
+template <class T>
+typename std::enable_if<!std::numeric_limits<T>::is_integer, bool>::type
+almost_equal(T x, T y, int ulp) {
+  // the machine epsilon has to be scaled to the magnitude of the values used
+  // and multiplied by the desired precision in ULPs (units in the last place)
+  // unless the result is subnormal
+  return std::fabs(x - y) <=
+             std::numeric_limits<T>::epsilon() * std::fabs(x + y) * ulp ||
+         std::fabs(x - y) < std::numeric_limits<T>::min();
+}
+
+double check_negative(double input_data);
+
+}  // namespace math
+}  // namespace common
+}  // namespace apollo

+ 640 - 0
src/test/testhdmap/modules/common/math/polygon2d.cc

@@ -0,0 +1,640 @@
+/******************************************************************************
+ * 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/common/math/polygon2d.h"
+
+#include <algorithm>
+#include <cmath>
+#include <limits>
+#include <utility>
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/str_join.h"
+
+#include "cyber/common/log.h"
+#include "modules/common/math/math_utils.h"
+#include "modules/common/util/string_util.h"
+
+namespace apollo {
+namespace common {
+namespace math {
+
+Polygon2d::Polygon2d(const Box2d &box) {
+  box.GetAllCorners(&points_);
+  BuildFromPoints();
+}
+
+Polygon2d::Polygon2d(std::vector<Vec2d> points) : points_(std::move(points)) {
+  BuildFromPoints();
+}
+
+double Polygon2d::DistanceTo(const Vec2d &point) const {
+  CHECK_GE(points_.size(), 3U);
+  if (IsPointIn(point)) {
+    return 0.0;
+  }
+  double distance = std::numeric_limits<double>::infinity();
+  for (int i = 0; i < num_points_; ++i) {
+    distance = std::min(distance, line_segments_[i].DistanceTo(point));
+  }
+  return distance;
+}
+
+double Polygon2d::DistanceSquareTo(const Vec2d &point) const {
+  CHECK_GE(points_.size(), 3U);
+  if (IsPointIn(point)) {
+    return 0.0;
+  }
+  double distance_sqr = std::numeric_limits<double>::infinity();
+  for (int i = 0; i < num_points_; ++i) {
+    distance_sqr =
+        std::min(distance_sqr, line_segments_[i].DistanceSquareTo(point));
+  }
+  return distance_sqr;
+}
+
+double Polygon2d::DistanceTo(const LineSegment2d &line_segment) const {
+  if (line_segment.length() <= kMathEpsilon) {
+    return DistanceTo(line_segment.start());
+  }
+  CHECK_GE(points_.size(), 3U);
+  if (IsPointIn(line_segment.center())) {
+    return 0.0;
+  }
+  if (std::any_of(line_segments_.begin(), line_segments_.end(),
+                  [&](const LineSegment2d &poly_seg) {
+                    return poly_seg.HasIntersect(line_segment);
+                  })) {
+    return 0.0;
+  }
+
+  double distance = std::min(DistanceTo(line_segment.start()),
+                             DistanceTo(line_segment.end()));
+  for (int i = 0; i < num_points_; ++i) {
+    distance = std::min(distance, line_segment.DistanceTo(points_[i]));
+  }
+  return distance;
+}
+
+double Polygon2d::DistanceTo(const Box2d &box) const {
+  CHECK_GE(points_.size(), 3U);
+  return DistanceTo(Polygon2d(box));
+}
+
+double Polygon2d::DistanceTo(const Polygon2d &polygon) const {
+  CHECK_GE(points_.size(), 3U);
+  CHECK_GE(polygon.num_points(), 3);
+
+  if (IsPointIn(polygon.points()[0])) {
+    return 0.0;
+  }
+  if (polygon.IsPointIn(points_[0])) {
+    return 0.0;
+  }
+  double distance = std::numeric_limits<double>::infinity();
+  for (int i = 0; i < num_points_; ++i) {
+    distance = std::min(distance, polygon.DistanceTo(line_segments_[i]));
+  }
+  return distance;
+}
+
+double Polygon2d::DistanceToBoundary(const Vec2d &point) const {
+  double distance = std::numeric_limits<double>::infinity();
+  for (int i = 0; i < num_points_; ++i) {
+    distance = std::min(distance, line_segments_[i].DistanceTo(point));
+  }
+  return distance;
+}
+
+bool Polygon2d::IsPointOnBoundary(const Vec2d &point) const {
+  CHECK_GE(points_.size(), 3U);
+  return std::any_of(
+      line_segments_.begin(), line_segments_.end(),
+      [&](const LineSegment2d &poly_seg) { return poly_seg.IsPointIn(point); });
+}
+
+bool Polygon2d::IsPointIn(const Vec2d &point) const {
+  CHECK_GE(points_.size(), 3U);
+  if (IsPointOnBoundary(point)) {
+    return true;
+  }
+  int j = num_points_ - 1;
+  int c = 0;
+  for (int i = 0; i < num_points_; ++i) {
+    if ((points_[i].y() > point.y()) != (points_[j].y() > point.y())) {
+      const double side = CrossProd(point, points_[i], points_[j]);
+      if (points_[i].y() < points_[j].y() ? side > 0.0 : side < 0.0) {
+        ++c;
+      }
+    }
+    j = i;
+  }
+  return c & 1;
+}
+
+bool Polygon2d::HasOverlap(const Polygon2d &polygon) const {
+  CHECK_GE(points_.size(), 3U);
+  CHECK_GE(polygon.num_points(), 3);
+  if (polygon.max_x() < min_x() || polygon.min_x() > max_x() ||
+      polygon.max_y() < min_y() || polygon.min_y() > max_y()) {
+    return false;
+  }
+
+  if (IsPointIn(polygon.points()[0])) {
+    return true;
+  }
+
+  if (polygon.IsPointIn(points_[0])) {
+    return true;
+  }
+
+  for (int i = 0; i < polygon.num_points(); ++i) {
+    if (HasOverlap(polygon.line_segments()[i])) {
+      return true;
+    }
+  }
+  return false;
+}
+
+bool Polygon2d::Contains(const LineSegment2d &line_segment) const {
+  if (line_segment.length() <= kMathEpsilon) {
+    return IsPointIn(line_segment.start());
+  }
+  CHECK_GE(points_.size(), 3U);
+  if (!IsPointIn(line_segment.start())) {
+    return false;
+  }
+  if (!IsPointIn(line_segment.end())) {
+    return false;
+  }
+  if (!is_convex_) {
+    std::vector<LineSegment2d> overlaps = GetAllOverlaps(line_segment);
+    double total_length = 0;
+    for (const auto &overlap_seg : overlaps) {
+      total_length += overlap_seg.length();
+    }
+    return total_length >= line_segment.length() - kMathEpsilon;
+  }
+  return true;
+}
+
+bool Polygon2d::Contains(const Polygon2d &polygon) const {
+  CHECK_GE(points_.size(), 3U);
+  if (area_ < polygon.area() - kMathEpsilon) {
+    return false;
+  }
+  if (!IsPointIn(polygon.points()[0])) {
+    return false;
+  }
+  const auto &line_segments = polygon.line_segments();
+  return std::all_of(line_segments.begin(), line_segments.end(),
+                     [&](const LineSegment2d &line_segment) {
+                       return Contains(line_segment);
+                     });
+}
+
+int Polygon2d::Next(int at) const { return at >= num_points_ - 1 ? 0 : at + 1; }
+
+int Polygon2d::Prev(int at) const { return at == 0 ? num_points_ - 1 : at - 1; }
+
+void Polygon2d::BuildFromPoints() {
+  num_points_ = static_cast<int>(points_.size());
+  CHECK_GE(num_points_, 3);
+
+  // Make sure the points are in ccw order.
+  area_ = 0.0;
+  for (int i = 1; i < num_points_; ++i) {
+    area_ += CrossProd(points_[0], points_[i - 1], points_[i]);
+  }
+  if (area_ < 0) {
+    area_ = -area_;
+    std::reverse(points_.begin(), points_.end());
+  }
+  area_ /= 2.0;
+  CHECK_GT(area_, kMathEpsilon);
+
+  // Construct line_segments.
+  line_segments_.reserve(num_points_);
+  for (int i = 0; i < num_points_; ++i) {
+    line_segments_.emplace_back(points_[i], points_[Next(i)]);
+  }
+
+  // Check convexity.
+  is_convex_ = true;
+  for (int i = 0; i < num_points_; ++i) {
+    if (CrossProd(points_[Prev(i)], points_[i], points_[Next(i)]) <=
+        -kMathEpsilon) {
+      is_convex_ = false;
+      break;
+    }
+  }
+
+  // Compute aabox.
+  min_x_ = points_[0].x();
+  max_x_ = points_[0].x();
+  min_y_ = points_[0].y();
+  max_y_ = points_[0].y();
+  for (const auto &point : points_) {
+    min_x_ = std::min(min_x_, point.x());
+    max_x_ = std::max(max_x_, point.x());
+    min_y_ = std::min(min_y_, point.y());
+    max_y_ = std::max(max_y_, point.y());
+  }
+}
+
+bool Polygon2d::ComputeConvexHull(const std::vector<Vec2d> &points,
+                                  Polygon2d *const polygon) {
+  CHECK_NOTNULL(polygon);
+  const int n = static_cast<int>(points.size());
+  if (n < 3) {
+    return false;
+  }
+  std::vector<int> sorted_indices(n);
+  for (int i = 0; i < n; ++i) {
+    sorted_indices[i] = i;
+  }
+  std::sort(sorted_indices.begin(), sorted_indices.end(),
+            [&](const int idx1, const int idx2) {
+              const Vec2d &pt1 = points[idx1];
+              const Vec2d &pt2 = points[idx2];
+              const double dx = pt1.x() - pt2.x();
+              if (std::abs(dx) > kMathEpsilon) {
+                return dx < 0.0;
+              }
+              return pt1.y() < pt2.y();
+            });
+  int count = 0;
+  std::vector<int> results;
+  results.reserve(n);
+  int last_count = 1;
+  for (int i = 0; i < n + n; ++i) {
+    if (i == n) {
+      last_count = count;
+    }
+    const int idx = sorted_indices[(i < n) ? i : (n + n - 1 - i)];
+    const Vec2d &pt = points[idx];
+    while (count > last_count &&
+           CrossProd(points[results[count - 2]], points[results[count - 1]],
+                     pt) <= kMathEpsilon) {
+      results.pop_back();
+      --count;
+    }
+    results.push_back(idx);
+    ++count;
+  }
+  --count;
+  if (count < 3) {
+    return false;
+  }
+  std::vector<Vec2d> result_points;
+  result_points.reserve(count);
+  for (int i = 0; i < count; ++i) {
+    result_points.push_back(points[results[i]]);
+  }
+  *polygon = Polygon2d(result_points);
+  return true;
+}
+
+bool Polygon2d::ClipConvexHull(const LineSegment2d &line_segment,
+                               std::vector<Vec2d> *const points) {
+  if (line_segment.length() <= kMathEpsilon) {
+    return true;
+  }
+  CHECK_NOTNULL(points);
+  const size_t n = points->size();
+  if (n < 3) {
+    return false;
+  }
+  std::vector<double> prod(n);
+  std::vector<int> side(n);
+  for (size_t i = 0; i < n; ++i) {
+    prod[i] = CrossProd(line_segment.start(), line_segment.end(), (*points)[i]);
+    if (std::abs(prod[i]) <= kMathEpsilon) {
+      side[i] = 0;
+    } else {
+      side[i] = ((prod[i] < 0) ? -1 : 1);
+    }
+  }
+
+  std::vector<Vec2d> new_points;
+  for (size_t i = 0; i < n; ++i) {
+    if (side[i] >= 0) {
+      new_points.push_back((*points)[i]);
+    }
+    const size_t j = ((i == n - 1) ? 0 : (i + 1));
+    if (side[i] * side[j] < 0) {
+      const double ratio = prod[j] / (prod[j] - prod[i]);
+      new_points.emplace_back(
+          (*points)[i].x() * ratio + (*points)[j].x() * (1.0 - ratio),
+          (*points)[i].y() * ratio + (*points)[j].y() * (1.0 - ratio));
+    }
+  }
+
+  points->swap(new_points);
+  return points->size() >= 3U;
+}
+
+bool Polygon2d::ComputeOverlap(const Polygon2d &other_polygon,
+                               Polygon2d *const overlap_polygon) const {
+  CHECK_GE(points_.size(), 3U);
+  CHECK_NOTNULL(overlap_polygon);
+  ACHECK(is_convex_ && other_polygon.is_convex());
+  std::vector<Vec2d> points = other_polygon.points();
+  for (int i = 0; i < num_points_; ++i) {
+    if (!ClipConvexHull(line_segments_[i], &points)) {
+      return false;
+    }
+  }
+  return ComputeConvexHull(points, overlap_polygon);
+}
+
+double Polygon2d::ComputeIoU(const Polygon2d &other_polygon) const {
+  Polygon2d overlap_polygon;
+  if (!ComputeOverlap(other_polygon, &overlap_polygon)) {
+    return 0.0;
+  }
+  double intersection_area = overlap_polygon.area();
+  double union_area = area_ + other_polygon.area() - overlap_polygon.area();
+  return intersection_area / union_area;
+}
+
+bool Polygon2d::HasOverlap(const LineSegment2d &line_segment) const {
+  CHECK_GE(points_.size(), 3U);
+  if ((line_segment.start().x() < min_x_ && line_segment.end().x() < min_x_) ||
+      (line_segment.start().x() > max_x_ && line_segment.end().x() > max_x_) ||
+      (line_segment.start().y() < min_y_ && line_segment.end().y() < min_y_) ||
+      (line_segment.start().y() > max_y_ && line_segment.end().y() > max_y_)) {
+    return false;
+  }
+
+  if (std::any_of(line_segments_.begin(), line_segments_.end(),
+    [&](const LineSegment2d &poly_seg) {
+      return poly_seg.HasIntersect(line_segment);
+    })) {
+      return true;
+    }
+  return false;
+}
+
+bool Polygon2d::GetOverlap(const LineSegment2d &line_segment,
+                           Vec2d *const first, Vec2d *const last) const {
+  CHECK_GE(points_.size(), 3U);
+  CHECK_NOTNULL(first);
+  CHECK_NOTNULL(last);
+
+  if (line_segment.length() <= kMathEpsilon) {
+    if (!IsPointIn(line_segment.start())) {
+      return false;
+    }
+    *first = line_segment.start();
+    *last = line_segment.start();
+    return true;
+  }
+
+  double min_proj = line_segment.length();
+  double max_proj = 0;
+  if (IsPointIn(line_segment.start())) {
+    *first = line_segment.start();
+    min_proj = 0.0;
+  }
+  if (IsPointIn(line_segment.end())) {
+    *last = line_segment.end();
+    max_proj = line_segment.length();
+  }
+  for (const auto &poly_seg : line_segments_) {
+    Vec2d pt;
+    if (poly_seg.GetIntersect(line_segment, &pt)) {
+      const double proj = line_segment.ProjectOntoUnit(pt);
+      if (proj < min_proj) {
+        min_proj = proj;
+        *first = pt;
+      }
+      if (proj > max_proj) {
+        max_proj = proj;
+        *last = pt;
+      }
+    }
+  }
+  return min_proj <= max_proj + kMathEpsilon;
+}
+
+void Polygon2d::GetAllVertices(std::vector<Vec2d> *const vertices) const {
+  if (vertices == nullptr) {
+    return;
+  }
+  *vertices = points_;
+}
+
+std::vector<Vec2d> Polygon2d::GetAllVertices() const { return points_; }
+
+std::vector<LineSegment2d> Polygon2d::GetAllOverlaps(
+    const LineSegment2d &line_segment) const {
+  CHECK_GE(points_.size(), 3U);
+
+  if (line_segment.length() <= kMathEpsilon) {
+    std::vector<LineSegment2d> overlaps;
+    if (IsPointIn(line_segment.start())) {
+      overlaps.push_back(line_segment);
+    }
+    return overlaps;
+  }
+  std::vector<double> projections;
+  if (IsPointIn(line_segment.start())) {
+    projections.push_back(0.0);
+  }
+  if (IsPointIn(line_segment.end())) {
+    projections.push_back(line_segment.length());
+  }
+  for (const auto &poly_seg : line_segments_) {
+    Vec2d pt;
+    if (poly_seg.GetIntersect(line_segment, &pt)) {
+      projections.push_back(line_segment.ProjectOntoUnit(pt));
+    }
+  }
+  std::sort(projections.begin(), projections.end());
+  std::vector<std::pair<double, double>> overlaps;
+  for (size_t i = 0; i + 1 < projections.size(); ++i) {
+    const double start_proj = projections[i];
+    const double end_proj = projections[i + 1];
+    if (end_proj - start_proj <= kMathEpsilon) {
+      continue;
+    }
+    const Vec2d reference_point =
+        line_segment.start() +
+        (start_proj + end_proj) / 2.0 * line_segment.unit_direction();
+    if (!IsPointIn(reference_point)) {
+      continue;
+    }
+    if (overlaps.empty() ||
+        start_proj > overlaps.back().second + kMathEpsilon) {
+      overlaps.emplace_back(start_proj, end_proj);
+    } else {
+      overlaps.back().second = end_proj;
+    }
+  }
+  std::vector<LineSegment2d> overlap_line_segments;
+  for (const auto &overlap : overlaps) {
+    overlap_line_segments.emplace_back(
+        line_segment.start() + overlap.first * line_segment.unit_direction(),
+        line_segment.start() + overlap.second * line_segment.unit_direction());
+  }
+  return overlap_line_segments;
+}
+
+void Polygon2d::ExtremePoints(const double heading, Vec2d *const first,
+                              Vec2d *const last) const {
+  CHECK_GE(points_.size(), 3U);
+  CHECK_NOTNULL(first);
+  CHECK_NOTNULL(last);
+
+  const Vec2d direction_vec = Vec2d::CreateUnitVec2d(heading);
+  double min_proj = std::numeric_limits<double>::infinity();
+  double max_proj = -std::numeric_limits<double>::infinity();
+  for (const auto &pt : points_) {
+    const double proj = pt.InnerProd(direction_vec);
+    if (proj < min_proj) {
+      min_proj = proj;
+      *first = pt;
+    }
+    if (proj > max_proj) {
+      max_proj = proj;
+      *last = pt;
+    }
+  }
+}
+
+AABox2d Polygon2d::AABoundingBox() const {
+  return AABox2d({min_x_, min_y_}, {max_x_, max_y_});
+}
+
+Box2d Polygon2d::BoundingBoxWithHeading(const double heading) const {
+  CHECK_GE(points_.size(), 3U);
+  const Vec2d direction_vec = Vec2d::CreateUnitVec2d(heading);
+  Vec2d px1;
+  Vec2d px2;
+  Vec2d py1;
+  Vec2d py2;
+  ExtremePoints(heading, &px1, &px2);
+  ExtremePoints(heading - M_PI_2, &py1, &py2);
+  const double x1 = px1.InnerProd(direction_vec);
+  const double x2 = px2.InnerProd(direction_vec);
+  const double y1 = py1.CrossProd(direction_vec);
+  const double y2 = py2.CrossProd(direction_vec);
+  return Box2d(
+      (x1 + x2) / 2.0 * direction_vec +
+          (y1 + y2) / 2.0 * Vec2d(direction_vec.y(), -direction_vec.x()),
+      heading, x2 - x1, y2 - y1);
+}
+
+Box2d Polygon2d::MinAreaBoundingBox() const {
+  CHECK_GE(points_.size(), 3U);
+  if (!is_convex_) {
+    Polygon2d convex_polygon;
+    ComputeConvexHull(points_, &convex_polygon);
+    ACHECK(convex_polygon.is_convex());
+    return convex_polygon.MinAreaBoundingBox();
+  }
+  double min_area = std::numeric_limits<double>::infinity();
+  double min_area_at_heading = 0.0;
+  int left_most = 0;
+  int right_most = 0;
+  int top_most = 0;
+  for (int i = 0; i < num_points_; ++i) {
+    const auto &line_segment = line_segments_[i];
+    double proj = 0.0;
+    double min_proj = line_segment.ProjectOntoUnit(points_[left_most]);
+    while ((proj = line_segment.ProjectOntoUnit(points_[Prev(left_most)])) <
+           min_proj) {
+      min_proj = proj;
+      left_most = Prev(left_most);
+    }
+    while ((proj = line_segment.ProjectOntoUnit(points_[Next(left_most)])) <
+           min_proj) {
+      min_proj = proj;
+      left_most = Next(left_most);
+    }
+    double max_proj = line_segment.ProjectOntoUnit(points_[right_most]);
+    while ((proj = line_segment.ProjectOntoUnit(points_[Prev(right_most)])) >
+           max_proj) {
+      max_proj = proj;
+      right_most = Prev(right_most);
+    }
+    while ((proj = line_segment.ProjectOntoUnit(points_[Next(right_most)])) >
+           max_proj) {
+      max_proj = proj;
+      right_most = Next(right_most);
+    }
+    double prod = 0.0;
+    double max_prod = line_segment.ProductOntoUnit(points_[top_most]);
+    while ((prod = line_segment.ProductOntoUnit(points_[Prev(top_most)])) >
+           max_prod) {
+      max_prod = prod;
+      top_most = Prev(top_most);
+    }
+    while ((prod = line_segment.ProductOntoUnit(points_[Next(top_most)])) >
+           max_prod) {
+      max_prod = prod;
+      top_most = Next(top_most);
+    }
+    const double area = max_prod * (max_proj - min_proj);
+    if (area < min_area) {
+      min_area = area;
+      min_area_at_heading = line_segment.heading();
+    }
+  }
+  return BoundingBoxWithHeading(min_area_at_heading);
+}
+
+Polygon2d Polygon2d::ExpandByDistance(const double distance) const {
+  if (!is_convex_) {
+    Polygon2d convex_polygon;
+    ComputeConvexHull(points_, &convex_polygon);
+    ACHECK(convex_polygon.is_convex());
+    return convex_polygon.ExpandByDistance(distance);
+  }
+  const double kMinAngle = 0.1;
+  std::vector<Vec2d> points;
+  for (int i = 0; i < num_points_; ++i) {
+    const double start_angle = line_segments_[Prev(i)].heading() - M_PI_2;
+    const double end_angle = line_segments_[i].heading() - M_PI_2;
+    const double diff = WrapAngle(end_angle - start_angle);
+    if (diff <= kMathEpsilon) {
+      points.push_back(points_[i] +
+                       Vec2d::CreateUnitVec2d(start_angle) * distance);
+    } else {
+      const int count = static_cast<int>(diff / kMinAngle) + 1;
+      for (int k = 0; k <= count; ++k) {
+        const double angle = start_angle + diff * static_cast<double>(k) /
+                                               static_cast<double>(count);
+        points.push_back(points_[i] + Vec2d::CreateUnitVec2d(angle) * distance);
+      }
+    }
+  }
+  Polygon2d new_polygon;
+  ACHECK(ComputeConvexHull(points, &new_polygon));
+  return new_polygon;
+}
+
+std::string Polygon2d::DebugString() const {
+  return absl::StrCat("polygon2d (  num_points = ", num_points_, "  points = (",
+                      absl::StrJoin(points_, " ", util::DebugStringFormatter()),
+                      " )  ", is_convex_ ? "convex" : "non-convex",
+                      "  area = ", area_, " )");
+}
+
+}  // namespace math
+}  // namespace common
+}  // namespace apollo

+ 341 - 0
src/test/testhdmap/modules/common/math/polygon2d.h

@@ -0,0 +1,341 @@
+/******************************************************************************
+ * 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
+ * @brief Define the Polygon2d class.
+ */
+
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include "modules/common/math/box2d.h"
+#include "modules/common/math/line_segment2d.h"
+#include "modules/common/math/vec2d.h"
+
+/**
+ * @namespace apollo::common::math
+ * @brief apollo::common::math
+ */
+namespace apollo {
+namespace common {
+namespace math {
+
+/**
+ * @class Polygon2d
+ * @brief The class of polygon in 2-D.
+ */
+class Polygon2d {
+ public:
+  /**
+   * @brief Empty constructor.
+   */
+  Polygon2d() = default;
+
+  /**
+   * @brief Constructor which takes a box.
+   * @param box The box to construct the polygon.
+   */
+  explicit Polygon2d(const Box2d &box);
+
+  /**
+   * @brief Constructor which takes a vector of points as its vertices.
+   * @param points The points to construct the polygon.
+   */
+  explicit Polygon2d(std::vector<Vec2d> points);
+
+  /**
+   * @brief Get the vertices of the polygon.
+   * @return The vertices of the polygon.
+   */
+  const std::vector<Vec2d> &points() const { return points_; }
+
+  /**
+   * @brief Get the edges of the polygon.
+   * @return The edges of the polygon.
+   */
+  const std::vector<LineSegment2d> &line_segments() const {
+    return line_segments_;
+  }
+
+  /**
+   * @brief Get the number of vertices of the polygon.
+   * @return The number of vertices of the polygon.
+   */
+  int num_points() const { return num_points_; }
+
+  /**
+   * @brief Check if the polygon is convex.
+   * @return Whether the polygon is convex or not.
+   */
+  bool is_convex() const { return is_convex_; }
+
+  /**
+   * @brief Get the area of the polygon.
+   * @return The area of the polygon.
+   */
+  double area() const { return area_; }
+
+  /**
+   * @brief Compute the distance from a point to the boundary of the polygon.
+   *        This distance is equal to the minimal distance from the point
+   *        to the edges of the polygon.
+   * @param point The point to compute whose distance to the polygon.
+   * @return The distance from the point to the polygon's boundary.
+   */
+  double DistanceToBoundary(const Vec2d &point) const;
+
+  /**
+   * @brief Compute the distance from a point to the polygon. If the point is
+   *        within the polygon, return 0. Otherwise, this distance is
+   *        the minimal distance from the point to the edges of the polygon.
+   * @param point The point to compute whose distance to the polygon.
+   * @return The distance from the point to the polygon.
+   */
+  double DistanceTo(const Vec2d &point) const;
+
+  /**
+   * @brief Compute the distance from a line segment to the polygon.
+   *        If the line segment is within the polygon, or it has intersect with
+   *        the polygon, return 0. Otherwise, this distance is
+   *        the minimal distance between the distances from the two ends
+   *        of the line segment to the polygon.
+   * @param line_segment The line segment to compute whose distance to
+   *        the polygon.
+   * @return The distance from the line segment to the polygon.
+   */
+  double DistanceTo(const LineSegment2d &line_segment) const;
+
+  /**
+   * @brief Compute the distance from a box to the polygon.
+   *        If the box is within the polygon, or it has overlap with
+   *        the polygon, return 0. Otherwise, this distance is
+   *        the minimal distance among the distances from the edges
+   *        of the box to the polygon.
+   * @param box The box to compute whose distance to the polygon.
+   * @return The distance from the box to the polygon.
+   */
+  double DistanceTo(const Box2d &box) const;
+
+  /**
+   * @brief Compute the distance from another polygon to the polygon.
+   *        If the other polygon is within this polygon, or it has overlap with
+   *        this polygon, return 0. Otherwise, this distance is
+   *        the minimal distance among the distances from the edges
+   *        of the other polygon to this polygon.
+   * @param polygon The polygon to compute whose distance to this polygon.
+   * @return The distance from the other polygon to this polygon.
+   */
+  double DistanceTo(const Polygon2d &polygon) const;
+
+  /**
+   * @brief Compute the square of distance from a point to the polygon.
+   *        If the point is within the polygon, return 0. Otherwise,
+   *        this square of distance is the minimal square of distance from
+   *        the point to the edges of the polygon.
+   * @param point The point to compute whose square of distance to the polygon.
+   * @return The square of distance from the point to the polygon.
+   */
+  double DistanceSquareTo(const Vec2d &point) const;
+
+  /**
+   * @brief Check if a point is within the polygon.
+   * @param point The target point. To check if it is within the polygon.
+   * @return Whether a point is within the polygon or not.
+   */
+  bool IsPointIn(const Vec2d &point) const;
+
+  /**
+   * @brief Check if a point is on the boundary of the polygon.
+   * @param point The target point. To check if it is on the boundary
+   *        of the polygon.
+   * @return Whether a point is on the boundary of the polygon or not.
+   */
+  bool IsPointOnBoundary(const Vec2d &point) const;
+
+  /**
+   * @brief Check if the polygon contains a line segment.
+   * @param line_segment The target line segment. To check if the polygon
+   *        contains it.
+   * @return Whether the polygon contains the line segment or not.
+   */
+  bool Contains(const LineSegment2d &line_segment) const;
+
+  /**
+   * @brief Check if the polygon contains another polygon.
+   * @param polygon The target polygon. To check if this polygon contains it.
+   * @return Whether this polygon contains another polygon or not.
+   */
+  bool Contains(const Polygon2d &polygon) const;
+
+  /**
+   * @brief Compute the convex hull of a group of points.
+   * @param points The target points. To compute the convex hull of them.
+   * @param polygon The convex hull of the points.
+   * @return If successfully compute the convex hull.
+   */
+  static bool ComputeConvexHull(const std::vector<Vec2d> &points,
+                                Polygon2d *const polygon);
+
+  /**
+   * @brief Check if a line segment has overlap with this polygon.
+   * @param line_segment The target line segment. To check if it has
+   *        overlap with this polygon.
+   * @return Whether the target line segment has overlap with this
+   *         polygon or not.
+   */
+  bool HasOverlap(const LineSegment2d &line_segment) const;
+
+  /**
+   * @brief Get the overlap of a line segment and this polygon. If they have
+   *        overlap, output the two ends of the overlapped line segment.
+   * @param line_segment The target line segment. To get its overlap with
+   *         this polygon.
+   * @param first First end of the overlapped line segment.
+   * @param second Second end of the overlapped line segment.
+   * @return If the target line segment has overlap with this polygon.
+   */
+  bool GetOverlap(const LineSegment2d &line_segment, Vec2d *const first,
+                  Vec2d *const last) const;
+
+  /**
+   * @brief Get all vertices of the polygon
+   * @param All vertices of the polygon
+   */
+  void GetAllVertices(std::vector<Vec2d> *const vertices) const;
+
+  /**
+   * @brief Get all vertices of the polygon
+   */
+  std::vector<Vec2d> GetAllVertices() const;
+
+  /**
+   * @brief Get all overlapped line segments of a line segment and this polygon.
+   *        There are possibly multiple overlapped line segments if this
+   *        polygon is not convex.
+   * @param line_segment The target line segment. To get its all overlapped
+   *        line segments with this polygon.
+   * @return A group of overlapped line segments.
+   */
+  std::vector<LineSegment2d> GetAllOverlaps(
+      const LineSegment2d &line_segment) const;
+
+  /**
+   * @brief Check if this polygon has overlap with another polygon.
+   * @param polygon The target polygon. To check if it has overlap
+   *        with this polygon.
+   * @return If this polygon has overlap with another polygon.
+   */
+  bool HasOverlap(const Polygon2d &polygon) const;
+
+  // Only compute overlaps between two convex polygons.
+  /**
+   * @brief Compute the overlap of this polygon and the other polygon if any.
+   *        Note: this function only works for computing overlap between
+   *        two convex polygons.
+   * @param other_polygon The target polygon. To compute its overlap with
+   *        this polygon.
+   * @param overlap_polygon The overlapped polygon.
+   * @param If there is an overlapped polygon.
+   */
+  bool ComputeOverlap(const Polygon2d &other_polygon,
+                      Polygon2d *const overlap_polygon) const;
+
+  // Only compute intersection over union ratio between two convex polygons.
+  /**
+   * @brief Compute intersection over union ratio of this polygon and the other
+   * polygon. Note: this function only works for computing overlap
+   * between two convex polygons.
+   * @param other_polygon The target polygon. To compute its overlap with
+   *        this polygon.
+   * @return A value between 0.0 and 1.0, meaning no intersection to fully
+   * overlaping
+   */
+  double ComputeIoU(const Polygon2d &other_polygon) const;
+
+  /**
+   * @brief Get the axis-aligned bound box of the polygon.
+   * @return The axis-aligned bound box of the polygon.
+   */
+  AABox2d AABoundingBox() const;
+
+  /**
+   * @brief Get the bound box according to a heading.
+   * @param heading The specified heading of the bounding box.
+   * @return The bound box according to the specified heading.
+   */
+  Box2d BoundingBoxWithHeading(const double heading) const;
+
+  /**
+   * @brief Get the bounding box with the minimal area.
+   * @return The bounding box with the minimal area.
+   */
+  Box2d MinAreaBoundingBox() const;
+
+  /**
+   * @brief Get the extreme points along a heading direction.
+   * @param heading The specified heading.
+   * @param first The point on the boundary of this polygon with the minimal
+   *        projection onto the heading direction.
+   * @param last The point on the boundary of this polygon with the maximal
+   *        projection onto the heading direction.
+   */
+  void ExtremePoints(const double heading, Vec2d *const first,
+                     Vec2d *const last) const;
+
+  /**
+   * @brief Expand this polygon by a distance.
+   * @param distance The specified distance. To expand this polygon by it.
+   * @return The polygon after expansion.
+   */
+  Polygon2d ExpandByDistance(const double distance) const;
+
+  /**
+   * @brief Get a string containing essential information about the polygon
+   *        for debugging purpose.
+   * @return Essential information about the polygon for debugging purpose.
+   */
+  std::string DebugString() const;
+
+  double min_x() const { return min_x_; }
+  double max_x() const { return max_x_; }
+  double min_y() const { return min_y_; }
+  double max_y() const { return max_y_; }
+
+ protected:
+  void BuildFromPoints();
+  int Next(int at) const;
+  int Prev(int at) const;
+
+  static bool ClipConvexHull(const LineSegment2d &line_segment,
+                             std::vector<Vec2d> *const points);
+
+  std::vector<Vec2d> points_;
+  int num_points_ = 0;
+  std::vector<LineSegment2d> line_segments_;
+  bool is_convex_ = false;
+  double area_ = 0.0;
+  double min_x_ = 0.0;
+  double max_x_ = 0.0;
+  double min_y_ = 0.0;
+  double max_y_ = 0.0;
+};
+
+}  // namespace math
+}  // namespace common
+}  // namespace apollo

+ 131 - 0
src/test/testhdmap/modules/common/math/vec2d.cc

@@ -0,0 +1,131 @@
+/******************************************************************************
+ * 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/common/math/vec2d.h"
+
+#include <cmath>
+
+#include "absl/strings/str_cat.h"
+
+#include "cyber/common/log.h"
+
+namespace apollo {
+namespace common {
+namespace math {
+
+Vec2d Vec2d::CreateUnitVec2d(const double angle) {
+  return Vec2d(std::cos(angle), std::sin(angle));
+}
+
+double Vec2d::Length() const { return std::hypot(x_, y_); }
+
+double Vec2d::LengthSquare() const { return x_ * x_ + y_ * y_; }
+
+double Vec2d::Angle() const { return std::atan2(y_, x_); }
+
+void Vec2d::Normalize() {
+  const double l = Length();
+  if (l > kMathEpsilon) {
+    x_ /= l;
+    y_ /= l;
+  }
+}
+
+double Vec2d::DistanceTo(const Vec2d &other) const {
+  return std::hypot(x_ - other.x_, y_ - other.y_);
+}
+
+double Vec2d::DistanceSquareTo(const Vec2d &other) const {
+  const double dx = x_ - other.x_;
+  const double dy = y_ - other.y_;
+  return dx * dx + dy * dy;
+}
+
+double Vec2d::CrossProd(const Vec2d &other) const {
+  return x_ * other.y() - y_ * other.x();
+}
+
+double Vec2d::InnerProd(const Vec2d &other) const {
+  return x_ * other.x() + y_ * other.y();
+}
+
+Vec2d Vec2d::rotate(const double angle) const {
+  return Vec2d(x_ * cos(angle) - y_ * sin(angle),
+               x_ * sin(angle) + y_ * cos(angle));
+}
+
+void Vec2d::SelfRotate(const double angle) {
+  double tmp_x = x_;
+  x_ = x_ * cos(angle) - y_ * sin(angle);
+  y_ = tmp_x * sin(angle) + y_ * cos(angle);
+}
+
+Vec2d Vec2d::operator+(const Vec2d &other) const {
+  return Vec2d(x_ + other.x(), y_ + other.y());
+}
+
+Vec2d Vec2d::operator-(const Vec2d &other) const {
+  return Vec2d(x_ - other.x(), y_ - other.y());
+}
+
+Vec2d Vec2d::operator*(const double ratio) const {
+  return Vec2d(x_ * ratio, y_ * ratio);
+}
+
+Vec2d Vec2d::operator/(const double ratio) const {
+  CHECK_GT(std::abs(ratio), kMathEpsilon);
+  return Vec2d(x_ / ratio, y_ / ratio);
+}
+
+Vec2d &Vec2d::operator+=(const Vec2d &other) {
+  x_ += other.x();
+  y_ += other.y();
+  return *this;
+}
+
+Vec2d &Vec2d::operator-=(const Vec2d &other) {
+  x_ -= other.x();
+  y_ -= other.y();
+  return *this;
+}
+
+Vec2d &Vec2d::operator*=(const double ratio) {
+  x_ *= ratio;
+  y_ *= ratio;
+  return *this;
+}
+
+Vec2d &Vec2d::operator/=(const double ratio) {
+  CHECK_GT(std::abs(ratio), kMathEpsilon);
+  x_ /= ratio;
+  y_ /= ratio;
+  return *this;
+}
+
+bool Vec2d::operator==(const Vec2d &other) const {
+  return (std::abs(x_ - other.x()) < kMathEpsilon &&
+          std::abs(y_ - other.y()) < kMathEpsilon);
+}
+
+Vec2d operator*(const double ratio, const Vec2d &vec) { return vec * ratio; }
+
+std::string Vec2d::DebugString() const {
+  return absl::StrCat("vec2d ( x = ", x_, "  y = ", y_, " )");
+}
+
+}  // namespace math
+}  // namespace common
+}  // namespace apollo

+ 135 - 0
src/test/testhdmap/modules/common/math/vec2d.h

@@ -0,0 +1,135 @@
+/******************************************************************************
+ * 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
+ * @brief Defines the Vec2d class.
+ */
+
+#pragma once
+
+#include <cmath>
+#include <string>
+
+/**
+ * @namespace apollo::common::math
+ * @brief apollo::common::math
+ */
+namespace apollo {
+namespace common {
+namespace math {
+
+constexpr double kMathEpsilon = 1e-10;
+
+/**
+ * @class Vec2d
+ *
+ * @brief Implements a class of 2-dimensional vectors.
+ */
+class Vec2d {
+ public:
+  //! Constructor which takes x- and y-coordinates.
+  constexpr Vec2d(const double x, const double y) noexcept : x_(x), y_(y) {}
+
+  //! Constructor returning the zero vector.
+  constexpr Vec2d() noexcept : Vec2d(0, 0) {}
+
+  //! Creates a unit-vector with a given angle to the positive x semi-axis
+  static Vec2d CreateUnitVec2d(const double angle);
+
+  //! Getter for x component
+  double x() const { return x_; }
+
+  //! Getter for y component
+  double y() const { return y_; }
+
+  //! Setter for x component
+  void set_x(const double x) { x_ = x; }
+
+  //! Setter for y component
+  void set_y(const double y) { y_ = y; }
+
+  //! Gets the length of the vector
+  double Length() const;
+
+  //! Gets the squared length of the vector
+  double LengthSquare() const;
+
+  //! Gets the angle between the vector and the positive x semi-axis
+  double Angle() const;
+
+  //! Returns the unit vector that is co-linear with this vector
+  void Normalize();
+
+  //! Returns the distance to the given vector
+  double DistanceTo(const Vec2d &other) const;
+
+  //! Returns the squared distance to the given vector
+  double DistanceSquareTo(const Vec2d &other) const;
+
+  //! Returns the "cross" product between these two Vec2d (non-standard).
+  double CrossProd(const Vec2d &other) const;
+
+  //! Returns the inner product between these two Vec2d.
+  double InnerProd(const Vec2d &other) const;
+
+  //! rotate the vector by angle.
+  Vec2d rotate(const double angle) const;
+
+  //! rotate the vector itself by angle.
+  void SelfRotate(const double angle);
+
+  //! Sums two Vec2d
+  Vec2d operator+(const Vec2d &other) const;
+
+  //! Subtracts two Vec2d
+  Vec2d operator-(const Vec2d &other) const;
+
+  //! Multiplies Vec2d by a scalar
+  Vec2d operator*(const double ratio) const;
+
+  //! Divides Vec2d by a scalar
+  Vec2d operator/(const double ratio) const;
+
+  //! Sums another Vec2d to the current one
+  Vec2d &operator+=(const Vec2d &other);
+
+  //! Subtracts another Vec2d to the current one
+  Vec2d &operator-=(const Vec2d &other);
+
+  //! Multiplies this Vec2d by a scalar
+  Vec2d &operator*=(const double ratio);
+
+  //! Divides this Vec2d by a scalar
+  Vec2d &operator/=(const double ratio);
+
+  //! Compares two Vec2d
+  bool operator==(const Vec2d &other) const;
+
+  //! Returns a human-readable string representing this object
+  std::string DebugString() const;
+
+ protected:
+  double x_ = 0.0;
+  double y_ = 0.0;
+};
+
+//! Multiplies the given Vec2d by a given scalar
+Vec2d operator*(const double ratio, const Vec2d &vec);
+
+}  // namespace math
+}  // namespace common
+}  // namespace apollo

+ 130 - 0
src/test/testhdmap/modules/common/status/status.h

@@ -0,0 +1,130 @@
+/******************************************************************************
+ * 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
+ */
+
+#pragma once
+
+#include <string>
+
+#include "google/protobuf/descriptor.h"
+#include "modules/common_msgs/basic_msgs/error_code.pb.h"
+#include "modules/common/util/future.h"
+
+/**
+ * @namespace apollo::common
+ * @brief apollo::common
+ */
+namespace apollo {
+namespace common {
+
+/**
+ * @class Status
+ *
+ * @brief A general class to denote the return status of an API call. It
+ * can either be an OK status for success, or a failure status with error
+ * message and error code enum.
+ */
+class Status {
+ public:
+  /**
+   * @brief Create a status with the specified error code and msg as a
+   * human-readable string containing more detailed information.
+   * @param code the error code.
+   * @param msg the message associated with the error.
+   */
+  explicit Status(ErrorCode code = ErrorCode::OK, std::string_view msg = "")
+      : code_(code), msg_(msg.data()) {}
+
+  ~Status() = default;
+
+  /**
+   * @brief generate a success status.
+   * @returns a success status
+   */
+  static Status OK() { return Status(); }
+
+  /**
+   * @brief check whether the return status is OK.
+   * @returns true if the code is ErrorCode::OK
+   *          false otherwise
+   */
+  bool ok() const { return code_ == ErrorCode::OK; }
+
+  /**
+   * @brief get the error code
+   * @returns the error code
+   */
+  ErrorCode code() const { return code_; }
+
+  /**
+   * @brief defines the logic of testing if two Status are equal
+   */
+  bool operator==(const Status &rh) const {
+    return (this->code_ == rh.code_) && (this->msg_ == rh.msg_);
+  }
+
+  /**
+   * @brief defines the logic of testing if two Status are unequal
+   */
+  bool operator!=(const Status &rh) const { return !(*this == rh); }
+
+  /**
+   * @brief returns the error message of the status, empty if the status is OK.
+   * @returns the error message
+   */
+  const std::string &error_message() const { return msg_; }
+
+  /**
+   * @brief returns a string representation in a readable format.
+   * @returns the string "OK" if success.
+   *          the internal error message otherwise.
+   */
+  std::string ToString() const {
+    if (ok()) {
+      return "OK";
+    }
+    return ErrorCode_Name(code_) + ": " + msg_;
+  }
+
+  /**
+   * @brief save the error_code and error message to protobuf
+   * @param the Status protobuf that will store the message.
+   */
+  void Save(StatusPb *status_pb) {
+    if (!status_pb) {
+      return;
+    }
+    status_pb->set_error_code(code_);
+    if (!msg_.empty()) {
+      status_pb->set_msg(msg_);
+    }
+  }
+
+ private:
+  ErrorCode code_;
+  std::string msg_;
+};
+
+inline std::ostream &operator<<(std::ostream &os, const Status &s) {
+  os << s.ToString();
+  return os;
+}
+
+}  // namespace common
+}  // namespace apollo

+ 46 - 0
src/test/testhdmap/modules/common/util/future.h

@@ -0,0 +1,46 @@
+/******************************************************************************
+ * Copyright 2019 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.
+ *****************************************************************************/
+
+#pragma once
+
+#if __cplusplus == 201103L || __cplusplus == 201402L
+#  include "absl/types/optional.h"
+#  include "absl/strings/string_view.h"
+#endif
+
+#if __cplusplus == 201103L
+#  include "absl/memory/memory.h"
+#  include "absl/utility/utility.h"
+#endif
+
+namespace std {
+// Drop-in replacement for code compliant with future C++ versions.
+
+#if __cplusplus == 201103L || __cplusplus == 201402L
+
+// Borrow from C++ 17 (201703L)
+using absl::optional;
+using absl::string_view;
+
+#endif
+
+#if __cplusplus == 201103L
+// Borrow from C++ 14.
+using absl::make_integer_sequence;
+using absl::make_unique;
+#endif
+
+}  // namespace std

+ 70 - 0
src/test/testhdmap/modules/common/util/string_util.cc

@@ -0,0 +1,70 @@
+/******************************************************************************
+ * 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/common/util/string_util.h"
+
+#include <cmath>
+#include <vector>
+
+#include "absl/strings/str_cat.h"
+
+namespace apollo {
+namespace common {
+namespace util {
+namespace {
+
+static const char kBase64Array[] =
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+std::string Base64Piece(const char in0, const char in1, const char in2) {
+  const int triplet = in0 << 16 | in1 << 8 | in2;
+  std::string out(4, '=');
+  out[0] = kBase64Array[(triplet >> 18) & 0x3f];
+  out[1] = kBase64Array[(triplet >> 12) & 0x3f];
+  if (in1) {
+    out[2] = kBase64Array[(triplet >> 6) & 0x3f];
+  }
+  if (in2) {
+    out[3] = kBase64Array[triplet & 0x3f];
+  }
+  return out;
+}
+
+}  // namespace
+
+std::string EncodeBase64(std::string_view in) {
+  std::string out;
+  if (in.empty()) {
+    return out;
+  }
+
+  const size_t in_size = in.length();
+  out.reserve(((in_size - 1) / 3 + 1) * 4);
+  for (size_t i = 0; i + 2 < in_size; i += 3) {
+    absl::StrAppend(&out, Base64Piece(in[i], in[i + 1], in[i + 2]));
+  }
+  if (in_size % 3 == 1) {
+    absl::StrAppend(&out, Base64Piece(in[in_size - 1], 0, 0));
+  }
+  if (in_size % 3 == 2) {
+    absl::StrAppend(&out, Base64Piece(in[in_size - 2], in[in_size - 1], 0));
+  }
+  return out;
+}
+
+}  // namespace util
+}  // namespace common
+}  // namespace apollo

+ 53 - 0
src/test/testhdmap/modules/common/util/string_util.h

@@ -0,0 +1,53 @@
+/******************************************************************************
+ * 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
+ * @brief Some string util functions.
+ */
+
+#pragma once
+
+#include <string>
+
+#include "absl/strings/str_format.h"
+#include "modules/common/util/future.h"
+
+#define FORMAT_TIMESTAMP(timestamp) \
+  std::fixed << std::setprecision(9) << timestamp
+
+/**
+ * @namespace apollo::common::util
+ * @brief apollo::common::util
+ */
+namespace apollo {
+namespace common {
+namespace util {
+
+using absl::StrFormat;
+
+struct DebugStringFormatter {
+  template <class T>
+  void operator()(std::string* out, const T& t) const {
+    out->append(t.DebugString());
+  }
+};
+
+std::string EncodeBase64(std::string_view in);
+
+}  // namespace util
+}  // namespace common
+}  // namespace apollo

+ 51 - 0
src/test/testhdmap/modules/common/util/util.cc

@@ -0,0 +1,51 @@
+/******************************************************************************
+ * 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/common/util/util.h"
+
+#include <cmath>
+#include <vector>
+
+namespace apollo {
+namespace common {
+namespace util {
+
+PointENU operator+(const PointENU enu, const math::Vec2d& xy) {
+  PointENU point;
+  point.set_x(enu.x() + xy.x());
+  point.set_y(enu.y() + xy.y());
+  point.set_z(enu.z());
+  return point;
+}
+
+PathPoint GetWeightedAverageOfTwoPathPoints(const PathPoint& p1,
+                                            const PathPoint& p2,
+                                            const double w1, const double w2) {
+  PathPoint p;
+  p.set_x(p1.x() * w1 + p2.x() * w2);
+  p.set_y(p1.y() * w1 + p2.y() * w2);
+  p.set_z(p1.z() * w1 + p2.z() * w2);
+  p.set_theta(p1.theta() * w1 + p2.theta() * w2);
+  p.set_kappa(p1.kappa() * w1 + p2.kappa() * w2);
+  p.set_dkappa(p1.dkappa() * w1 + p2.dkappa() * w2);
+  p.set_ddkappa(p1.ddkappa() * w1 + p2.ddkappa() * w2);
+  p.set_s(p1.s() * w1 + p2.s() * w2);
+  return p;
+}
+
+}  // namespace util
+}  // namespace common
+}  // namespace apollo

+ 166 - 0
src/test/testhdmap/modules/common/util/util.h

@@ -0,0 +1,166 @@
+/******************************************************************************
+ * 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
+ * @brief Some util functions.
+ */
+
+#pragma once
+
+#include <algorithm>
+#include <iostream>
+#include <limits>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "cyber/common/log.h"
+#include "cyber/common/types.h"
+#include "modules/common/configs/config_gflags.h"
+#include "modules/common/math/vec2d.h"
+#include "modules/common_msgs/basic_msgs/geometry.pb.h"
+#include "modules/common_msgs/basic_msgs/pnc_point.pb.h"
+
+/**
+ * @namespace apollo::common::util
+ * @brief apollo::common::util
+ */
+namespace apollo {
+namespace common {
+namespace util {
+template <typename ProtoA, typename ProtoB>
+bool IsProtoEqual(const ProtoA& a, const ProtoB& b) {
+  return a.GetTypeName() == b.GetTypeName() &&
+         a.SerializeAsString() == b.SerializeAsString();
+  // Test shows that the above method is 5 times faster than the
+  // API: google::protobuf::util::MessageDifferencer::Equals(a, b);
+}
+
+struct PairHash {
+  template <typename T, typename U>
+  size_t operator()(const std::pair<T, U>& pair) const {
+    return std::hash<T>()(pair.first) ^ std::hash<U>()(pair.second);
+  }
+};
+
+template <typename T>
+bool WithinBound(T start, T end, T value) {
+  return value >= start && value <= end;
+}
+
+PointENU operator+(const PointENU enu, const math::Vec2d& xy);
+
+/**
+ * uniformly slice a segment [start, end] to num + 1 pieces
+ * the result sliced will contain the n + 1 points that slices the provided
+ * segment. `start` and `end` will be the first and last element in `sliced`.
+ */
+template <typename T>
+void uniform_slice(const T start, const T end, uint32_t num,
+                   std::vector<T>* sliced) {
+  if (!sliced || num == 0) {
+    return;
+  }
+  const T delta = (end - start) / num;
+  sliced->resize(num + 1);
+  T s = start;
+  for (uint32_t i = 0; i < num; ++i, s += delta) {
+    sliced->at(i) = s;
+  }
+  sliced->at(num) = end;
+}
+
+/**
+ * calculate the distance beteween Point u and Point v, which are all have
+ * member function x() and y() in XY dimension.
+ * @param u one point that has member function x() and y().
+ * @param b one point that has member function x() and y().
+ * @return sqrt((u.x-v.x)^2 + (u.y-v.y)^2), i.e., the Euclid distance on XY
+ * dimension.
+ */
+template <typename U, typename V>
+double DistanceXY(const U& u, const V& v) {
+  return std::hypot(u.x() - v.x(), u.y() - v.y());
+}
+
+/**
+ * Check if two points u and v are the same point on XY dimension.
+ * @param u one point that has member function x() and y().
+ * @param v one point that has member function x() and y().
+ * @return sqrt((u.x-v.x)^2 + (u.y-v.y)^2) < epsilon, i.e., the Euclid distance
+ * on XY dimension.
+ */
+template <typename U, typename V>
+bool SamePointXY(const U& u, const V& v) {
+  static constexpr double kMathEpsilonSqr = 1e-8 * 1e-8;
+  return (u.x() - v.x()) * (u.x() - v.x()) < kMathEpsilonSqr &&
+         (u.y() - v.y()) * (u.y() - v.y()) < kMathEpsilonSqr;
+}
+
+PathPoint GetWeightedAverageOfTwoPathPoints(const PathPoint& p1,
+                                            const PathPoint& p2,
+                                            const double w1, const double w2);
+
+// Test whether two float or double numbers are equal.
+// ulp: units in the last place.
+template <typename T>
+typename std::enable_if<!std::numeric_limits<T>::is_integer, bool>::type
+IsFloatEqual(T x, T y, int ulp = 2) {
+  // the machine epsilon has to be scaled to the magnitude of the values used
+  // and multiplied by the desired precision in ULPs (units in the last place)
+  return std::fabs(x - y) <
+             std::numeric_limits<T>::epsilon() * std::fabs(x + y) * ulp
+         // unless the result is subnormal
+         || std::fabs(x - y) < std::numeric_limits<T>::min();
+}
+}  // namespace util
+}  // namespace common
+}  // namespace apollo
+
+template <typename T>
+class FunctionInfo {
+ public:
+  typedef int (T::*Function)();
+  Function function_;
+  std::string fun_name_;
+};
+
+template <typename T, size_t count>
+bool ExcuteAllFunctions(T* obj, FunctionInfo<T> fun_list[]) {
+  for (size_t i = 0; i < count; i++) {
+    if ((obj->*(fun_list[i].function_))() != apollo::cyber::SUCC) {
+      AERROR << fun_list[i].fun_name_ << " failed.";
+      return false;
+    }
+  }
+  return true;
+}
+
+#define EXEC_ALL_FUNS(type, obj, list) \
+  ExcuteAllFunctions<type, sizeof(list) / sizeof(FunctionInfo<type>)>(obj, list)
+
+template <typename A, typename B>
+std::ostream& operator<<(std::ostream& os, std::pair<A, B>& p) {
+  return os << "first: " << p.first << ", second: " << p.second;
+}
+
+#define UNIQUE_LOCK_MULTITHREAD(mutex_type)                         \
+  std::unique_ptr<std::unique_lock<std::mutex>> lock_ptr = nullptr; \
+  if (FLAGS_multithread_run) {                                      \
+    lock_ptr.reset(new std::unique_lock<std::mutex>(mutex_type));   \
+  }

BIN
src/test/testhdmap/modules/common_msgs/.DS_Store


+ 7 - 0
src/test/testhdmap/modules/common_msgs/BUILD

@@ -0,0 +1,7 @@
+load("//tools:apollo_package.bzl", "apollo_package")
+
+package(
+    default_visibility = ["//visibility:public"],
+)
+
+apollo_package()

+ 36 - 0
src/test/testhdmap/modules/common_msgs/README.md

@@ -0,0 +1,36 @@
+# common-msgs
+
+## Introduction
+This package includes all the message definitions that need to be transmitted in the channel.
+
+## Directory Structure
+```shell
+modules/common_msgs/
+├── audio_msgs              // Message definitions of audio
+├── basic_msgs              // Common message definitions
+├── BUILD
+├── chassis_msgs            // Message definitions of chassis 
+├── config_msgs             // Message definitions of config in multiple modules
+├── control_msgs            // Message definitions of control 
+├── cyberfile.xml
+├── dreamview_msgs          // Message definitions of dreamview
+├── drivers_msgs            // Message definitions of drivers component
+├── external_command_msgs   // Message definitions of external_command   
+├── guardian_msgs           // Message definitions of guardian_msgs 
+├── localization_msgs       // Message definitions of localization
+├── map_msgs                // Message definitions of map
+├── monitor_msgs            // Message definitions of monitor
+├── perception_msgs         // Message definitions of perception
+├── planning_msgs           // Message definitions of planning
+├── prediction_msgs         // Message definitions of prediction
+├── README.md
+├── routing_msgs            // Message definitions of routing
+├── sensor_msgs             // Message definitions of multiple sensors
+├── simulation_msgs         // Message definitions for simulation
+├── storytelling_msgs       // Message definitions of storytelling
+├── task_manager_msgs       // Message definitions of task-manager
+├── transform_msgs          // Message definitions of transform
+└── v2x_msgs                // Message definitions of v2x
+```
+
+

+ 32 - 0
src/test/testhdmap/modules/common_msgs/audio_msgs/BUILD

@@ -0,0 +1,32 @@
+## Auto generated by `proto_build_generator.py`
+load("//tools/proto:proto.bzl", "proto_library")
+load("//tools:apollo_package.bzl", "apollo_package")
+
+package(default_visibility = ["//visibility:public"])
+
+proto_library(
+    name = "audio_common_proto",
+    srcs = ["audio_common.proto"],
+)
+
+proto_library(
+    name = "audio_event_proto",
+    srcs = ["audio_event.proto"],
+    deps = [
+        ":audio_common_proto",
+        "//modules/common_msgs/basic_msgs:header_proto",
+        "//modules/common_msgs/localization_msgs:pose_proto",
+    ],
+)
+
+proto_library(
+    name = "audio_proto",
+    srcs = ["audio.proto"],
+    deps = [
+        ":audio_common_proto",
+        "//modules/common_msgs/basic_msgs:geometry_proto",
+        "//modules/common_msgs/basic_msgs:header_proto",
+    ],
+)
+
+apollo_package()

+ 31 - 0
src/test/testhdmap/modules/common_msgs/audio_msgs/audio.proto

@@ -0,0 +1,31 @@
+/******************************************************************************
+ * Copyright 2020 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.
+ *****************************************************************************/
+
+syntax = "proto2";
+
+package apollo.audio;
+
+import "modules/common_msgs/audio_msgs/audio_common.proto";
+import "modules/common_msgs/basic_msgs/geometry.proto";
+import "modules/common_msgs/basic_msgs/header.proto";
+
+message AudioDetection {
+  optional apollo.common.Header header = 1;
+  optional bool is_siren = 2;
+  optional apollo.audio.MovingResult moving_result = 3 [default = UNKNOWN];
+  optional apollo.common.Point3D position = 4;
+  optional double source_degree = 5;
+}

+ 41 - 0
src/test/testhdmap/modules/common_msgs/audio_msgs/audio_common.proto

@@ -0,0 +1,41 @@
+/******************************************************************************
+ * Copyright 2020 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.
+ *****************************************************************************/
+
+syntax = "proto2";
+
+package apollo.audio;
+
+enum MovingResult {
+  UNKNOWN = 0;
+  APPROACHING = 1;
+  DEPARTING = 2;
+  STATIONARY = 3;
+}
+
+enum AudioType {
+  UNKNOWN_TYPE = 0;
+  POLICE = 1;
+  AMBULANCE = 2;
+  FIRETRUCK = 3;
+}
+
+enum AudioDirection {
+  UNKNOWN_DIRECTION = 0;
+  FRONT = 1;
+  LEFT = 2;
+  BACK = 3;
+  RIGHT = 4;
+}

+ 34 - 0
src/test/testhdmap/modules/common_msgs/audio_msgs/audio_event.proto

@@ -0,0 +1,34 @@
+/******************************************************************************
+ * Copyright 2020 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.
+ *****************************************************************************/
+
+syntax = "proto2";
+
+package apollo.audio;
+
+import "modules/common_msgs/audio_msgs/audio_common.proto";
+import "modules/common_msgs/basic_msgs/header.proto";
+import "modules/common_msgs/localization_msgs/pose.proto";
+
+message AudioEvent {
+  optional apollo.common.Header header = 1;
+  optional int32 id = 2;  // obstacle ID.
+  optional apollo.audio.MovingResult moving_result = 3 [default = UNKNOWN];
+  optional apollo.audio.AudioType audio_type = 4 [default = UNKNOWN_TYPE];
+  optional bool siren_is_on = 5;
+  optional apollo.audio.AudioDirection audio_direction = 6
+      [default = UNKNOWN_DIRECTION];
+  optional apollo.localization.Pose pose = 7;
+}

+ 59 - 0
src/test/testhdmap/modules/common_msgs/basic_msgs/BUILD

@@ -0,0 +1,59 @@
+## Auto generated by `proto_build_generator.py`
+load("//tools/proto:proto.bzl", "proto_library")
+load("//tools:apollo_package.bzl", "apollo_package")
+
+package(default_visibility = ["//visibility:public"])
+
+proto_library(
+    name = "drive_event_proto",
+    srcs = ["drive_event.proto"],
+    deps = [
+        ":header_proto",
+        "//modules/common_msgs/localization_msgs:pose_proto",
+    ],
+)
+
+proto_library(
+    name = "vehicle_signal_proto",
+    srcs = ["vehicle_signal.proto"],
+)
+
+proto_library(
+    name = "error_code_proto",
+    srcs = ["error_code.proto"],
+)
+
+proto_library(
+    name = "drive_state_proto",
+    srcs = ["drive_state.proto"],
+)
+
+proto_library(
+    name = "header_proto",
+    srcs = ["header.proto"],
+    deps = [
+        ":error_code_proto",
+    ],
+)
+
+proto_library(
+    name = "direction_proto",
+    srcs = ["direction.proto"],
+)
+
+proto_library(
+    name = "pnc_point_proto",
+    srcs = ["pnc_point.proto"],
+)
+
+proto_library(
+    name = "geometry_proto",
+    srcs = ["geometry.proto"],
+)
+
+proto_library(
+    name = "vehicle_id_proto",
+    srcs = ["vehicle_id.proto"],
+)
+
+apollo_package()

+ 14 - 0
src/test/testhdmap/modules/common_msgs/basic_msgs/direction.proto

@@ -0,0 +1,14 @@
+syntax = "proto2";
+
+package apollo.common;
+
+enum Direction {
+  EAST = 0;
+  WEST = 1;
+  SOUTH = 2;
+  NORTH = 3;
+  NORTHEAST = 4;
+  SOUTHEAST = 5;
+  SOUTHWEST = 6;
+  NORTHWEST = 7;
+};

+ 21 - 0
src/test/testhdmap/modules/common_msgs/basic_msgs/drive_event.proto

@@ -0,0 +1,21 @@
+syntax = "proto2";
+
+package apollo.common;
+
+import "modules/common_msgs/basic_msgs/header.proto";
+import "modules/common_msgs/localization_msgs/pose.proto";
+
+message DriveEvent {
+  enum Type {
+    CRITICAL = 0;
+    PROBLEM = 1;
+    DESIRED = 2;
+    OUT_OF_SCOPE = 3;
+  }
+
+  optional apollo.common.Header header = 1;
+  optional string event = 2;
+  optional apollo.localization.Pose location = 3;
+  repeated Type type = 4;
+  optional bool is_reportable = 5;
+}

+ 17 - 0
src/test/testhdmap/modules/common_msgs/basic_msgs/drive_state.proto

@@ -0,0 +1,17 @@
+syntax = "proto2";
+
+package apollo.common;
+
+// This is the engage advice that published by critical runtime modules.
+message EngageAdvice {
+  enum Advice {
+    UNKNOWN = 0;
+    DISALLOW_ENGAGE = 1;
+    READY_TO_ENGAGE = 2;
+    KEEP_ENGAGED = 3;
+    PREPARE_DISENGAGE = 4;
+  }
+
+  optional Advice advice = 1 [default = DISALLOW_ENGAGE];
+  optional string reason = 2;
+}

+ 78 - 0
src/test/testhdmap/modules/common_msgs/basic_msgs/error_code.proto

@@ -0,0 +1,78 @@
+syntax = "proto2";
+
+package apollo.common;
+
+// Error codes enum for API's categorized by modules.
+enum ErrorCode {
+  // No error, returns on success.
+  OK = 0;
+
+  // Control module error codes start from here.
+  CONTROL_ERROR = 1000;
+  CONTROL_INIT_ERROR = 1001;
+  CONTROL_COMPUTE_ERROR = 1002;
+  CONTROL_ESTOP_ERROR = 1003;
+  PERFECT_CONTROL_ERROR = 1004;
+
+  // Canbus module error codes start from here.
+  CANBUS_ERROR = 2000;
+  CAN_CLIENT_ERROR_BASE = 2100;
+  CAN_CLIENT_ERROR_OPEN_DEVICE_FAILED = 2101;
+  CAN_CLIENT_ERROR_FRAME_NUM = 2102;
+  CAN_CLIENT_ERROR_SEND_FAILED = 2103;
+  CAN_CLIENT_ERROR_RECV_FAILED = 2104;
+
+  // Localization module error codes start from here.
+  LOCALIZATION_ERROR = 3000;
+  LOCALIZATION_ERROR_MSG = 3100;
+  LOCALIZATION_ERROR_LIDAR = 3200;
+  LOCALIZATION_ERROR_INTEG = 3300;
+  LOCALIZATION_ERROR_GNSS = 3400;
+
+  // Perception module error codes start from here.
+  PERCEPTION_ERROR = 4000;
+  PERCEPTION_ERROR_TF = 4001;
+  PERCEPTION_ERROR_PROCESS = 4002;
+  PERCEPTION_FATAL = 4003;
+  PERCEPTION_ERROR_NONE = 4004;
+  PERCEPTION_ERROR_UNKNOWN = 4005;
+
+  // Prediction module error codes start from here.
+  PREDICTION_ERROR = 5000;
+
+  // Planning module error codes start from here
+  PLANNING_ERROR = 6000;
+  PLANNING_ERROR_NOT_READY = 6001;
+
+  // HDMap module error codes start from here
+  HDMAP_DATA_ERROR = 7000;
+
+  // Routing module error codes
+  ROUTING_ERROR = 8000;
+  ROUTING_ERROR_REQUEST = 8001;
+  ROUTING_ERROR_RESPONSE = 8002;
+  ROUTING_ERROR_NOT_READY = 8003;
+
+  // Indicates an input has been exhausted.
+  END_OF_INPUT = 9000;
+
+  // HTTP request error codes.
+  HTTP_LOGIC_ERROR = 10000;
+  HTTP_RUNTIME_ERROR = 10001;
+
+  // Relative Map error codes.
+  RELATIVE_MAP_ERROR = 11000;  // general relative map error code
+  RELATIVE_MAP_NOT_READY = 11001;
+
+  // Driver error codes.
+  DRIVER_ERROR_GNSS = 12000;
+  DRIVER_ERROR_VELODYNE = 13000;
+
+  // Storytelling error codes.
+  STORYTELLING_ERROR = 14000;
+}
+
+message StatusPb {
+  optional ErrorCode error_code = 1 [default = OK];
+  optional string msg = 2;
+}

+ 62 - 0
src/test/testhdmap/modules/common_msgs/basic_msgs/geometry.proto

@@ -0,0 +1,62 @@
+syntax = "proto2";
+
+package apollo.common;
+
+// A point in the map reference frame. The map defines an origin, whose
+// coordinate is (0, 0, 0).
+// Most modules, including localization, perception, and prediction, generate
+// results based on the map reference frame.
+// Currently, the map uses Universal Transverse Mercator (UTM) projection. See
+// the link below for the definition of map origin.
+//   https://en.wikipedia.org/wiki/Universal_Transverse_Mercator_coordinate_system
+// The z field of PointENU can be omitted. If so, it is a 2D location and we do
+// not care its height.
+message PointENU {
+  optional double x = 1 [default = nan];  // East from the origin, in meters.
+  optional double y = 2 [default = nan];  // North from the origin, in meters.
+  optional double z = 3 [default = 0.0];  // Up from the WGS-84 ellipsoid, in
+                                          // meters.
+}
+
+// A point in the global reference frame. Similar to PointENU, PointLLH allows
+// omitting the height field for representing a 2D location.
+message PointLLH {
+  // Longitude in degrees, ranging from -180 to 180.
+  optional double lon = 1 [default = nan];
+  // Latitude in degrees, ranging from -90 to 90.
+  optional double lat = 2 [default = nan];
+  // WGS-84 ellipsoid height in meters.
+  optional double height = 3 [default = 0.0];
+}
+
+// A general 2D point. Its meaning and units depend on context, and must be
+// explained in comments.
+message Point2D {
+  optional double x = 1 [default = nan];
+  optional double y = 2 [default = nan];
+}
+
+// A general 3D point. Its meaning and units depend on context, and must be
+// explained in comments.
+message Point3D {
+  optional double x = 1 [default = nan];
+  optional double y = 2 [default = nan];
+  optional double z = 3 [default = nan];
+}
+
+// A unit quaternion that represents a spatial rotation. See the link below for
+// details.
+//   https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation
+// The scalar part qw can be omitted. In this case, qw should be calculated by
+//   qw = sqrt(1 - qx * qx - qy * qy - qz * qz).
+message Quaternion {
+  optional double qx = 1 [default = nan];
+  optional double qy = 2 [default = nan];
+  optional double qz = 3 [default = nan];
+  optional double qw = 4 [default = nan];
+}
+
+// A general polygon, points are counter clockwise
+message Polygon {
+  repeated Point3D point = 1;
+}

+ 33 - 0
src/test/testhdmap/modules/common_msgs/basic_msgs/header.proto

@@ -0,0 +1,33 @@
+syntax = "proto2";
+
+package apollo.common;
+
+import "modules/common_msgs/basic_msgs/error_code.proto";
+
+message Header {
+  // Message publishing time in seconds.
+  optional double timestamp_sec = 1;
+
+  // Module name.
+  optional string module_name = 2;
+
+  // Sequence number for each message. Each module maintains its own counter for
+  // sequence_num, always starting from 1 on boot.
+  optional uint32 sequence_num = 3;
+
+  // Lidar Sensor timestamp for nano-second.
+  optional uint64 lidar_timestamp = 4;
+
+  // Camera Sensor timestamp for nano-second.
+  optional uint64 camera_timestamp = 5;
+
+  // Radar Sensor timestamp for nano-second.
+  optional uint64 radar_timestamp = 6;
+
+  // data version
+  optional uint32 version = 7 [default = 1];
+
+  optional StatusPb status = 8;
+
+  optional string frame_id = 9;
+}

+ 106 - 0
src/test/testhdmap/modules/common_msgs/basic_msgs/pnc_point.proto

@@ -0,0 +1,106 @@
+syntax = "proto2";
+
+// Defined Point types that are commonly used in PnC (Planning and Control)
+// modules.
+
+package apollo.common;
+
+message SLPoint {
+  optional double s = 1;
+  optional double l = 2;
+}
+
+message FrenetFramePoint {
+  optional double s = 1;
+  optional double l = 2;
+  optional double dl = 3;
+  optional double ddl = 4;
+}
+
+message SpeedPoint {
+  optional double s = 1;
+  optional double t = 2;
+  // speed (m/s)
+  optional double v = 3;
+  // acceleration (m/s^2)
+  optional double a = 4;
+  // jerk (m/s^3)
+  optional double da = 5;
+}
+
+message PathPoint {
+  // coordinates
+  optional double x = 1;
+  optional double y = 2;
+  optional double z = 3;
+
+  // direction on the x-y plane
+  optional double theta = 4;
+  // curvature on the x-y planning
+  optional double kappa = 5;
+  // accumulated distance from beginning of the path
+  optional double s = 6;
+
+  // derivative of kappa w.r.t s.
+  optional double dkappa = 7;
+  // derivative of derivative of kappa w.r.t s.
+  optional double ddkappa = 8;
+  // The lane ID where the path point is on
+  optional string lane_id = 9;
+
+  // derivative of x and y w.r.t parametric parameter t in CosThetareferenceline
+  optional double x_derivative = 10;
+  optional double y_derivative = 11;
+}
+
+message Path {
+  optional string name = 1;
+  repeated PathPoint path_point = 2;
+}
+
+message TrajectoryPoint {
+  // path point
+  optional PathPoint path_point = 1;
+  // linear velocity
+  optional double v = 2;  // in [m/s]
+  // linear acceleration
+  optional double a = 3;
+  // relative time from beginning of the trajectory
+  optional double relative_time = 4;
+  // longitudinal jerk
+  optional double da = 5;
+  // The angle between vehicle front wheel and vehicle longitudinal axis
+  optional double steer = 6;
+
+  // Gaussian probability information
+  optional GaussianInfo gaussian_info = 7;
+}
+
+message Trajectory {
+  optional string name = 1;
+  repeated TrajectoryPoint trajectory_point = 2;
+}
+
+message VehicleMotionPoint {
+  // trajectory point
+  optional TrajectoryPoint trajectory_point = 1;
+  // The angle between vehicle front wheel and vehicle longitudinal axis
+  optional double steer = 2;
+}
+
+message VehicleMotion {
+  optional string name = 1;
+  repeated VehicleMotionPoint vehicle_motion_point = 2;
+}
+
+message GaussianInfo {
+  // Information of gaussian distribution
+  optional double sigma_x = 1;
+  optional double sigma_y = 2;
+  optional double correlation = 3;
+  // Information of representative uncertainty area
+  optional double area_probability = 4;
+  optional double ellipse_a = 5;
+  optional double ellipse_b = 6;
+  optional double theta_a = 7;
+}

+ 9 - 0
src/test/testhdmap/modules/common_msgs/basic_msgs/vehicle_id.proto

@@ -0,0 +1,9 @@
+syntax = "proto2";
+
+package apollo.common;
+
+message VehicleID {
+  optional string vin = 1;
+  optional string plate = 2;
+  optional string other_unique_id = 3;
+}

+ 18 - 0
src/test/testhdmap/modules/common_msgs/basic_msgs/vehicle_signal.proto

@@ -0,0 +1,18 @@
+syntax = "proto2";
+
+package apollo.common;
+
+message VehicleSignal {
+  enum TurnSignal {
+    TURN_NONE = 0;
+    TURN_LEFT = 1;
+    TURN_RIGHT = 2;
+    TURN_HAZARD_WARNING = 3;
+  };
+  optional TurnSignal turn_signal = 1;
+  // lights enable command
+  optional bool high_beam = 2;
+  optional bool low_beam = 3;
+  optional bool horn = 4;
+  optional bool emergency_light = 5;
+}

+ 29 - 0
src/test/testhdmap/modules/common_msgs/chassis_msgs/BUILD

@@ -0,0 +1,29 @@
+## Auto generated by `proto_build_generator.py`
+load("//tools/proto:proto.bzl", "proto_library")
+load("//tools:apollo_package.bzl", "apollo_package")
+
+package(default_visibility = ["//visibility:public"])
+
+proto_library(
+    name = "chassis_detail_proto",
+    srcs = ["chassis_detail.proto"],
+    deps = [
+        ":chassis_proto",
+        "//modules/common_msgs/basic_msgs:vehicle_id_proto",
+    ],
+)
+
+proto_library(
+    name = "chassis_proto",
+    srcs = ["chassis.proto"],
+    deps = [
+        "//modules/common_msgs/basic_msgs:drive_state_proto",
+        "//modules/common_msgs/basic_msgs:geometry_proto",
+        "//modules/common_msgs/basic_msgs:header_proto",
+        "//modules/common_msgs/basic_msgs:vehicle_id_proto",
+        "//modules/common_msgs/basic_msgs:vehicle_signal_proto",
+        "@com_google_protobuf//:any_proto",
+    ],
+)
+
+apollo_package()

+ 259 - 0
src/test/testhdmap/modules/common_msgs/chassis_msgs/chassis.proto

@@ -0,0 +1,259 @@
+syntax = "proto2";
+
+package apollo.canbus;
+
+import "google/protobuf/any.proto";
+import "modules/common_msgs/basic_msgs/drive_state.proto";
+import "modules/common_msgs/basic_msgs/geometry.proto";
+import "modules/common_msgs/basic_msgs/header.proto";
+import "modules/common_msgs/basic_msgs/vehicle_id.proto";
+import "modules/common_msgs/basic_msgs/vehicle_signal.proto";
+
+
+// next id :31
+message Chassis {
+  enum DrivingMode {
+    COMPLETE_MANUAL = 0;  // human drive
+    COMPLETE_AUTO_DRIVE = 1;
+    AUTO_STEER_ONLY = 2;  // only steer
+    AUTO_SPEED_ONLY = 3;  // include throttle and brake
+
+    // security mode when manual intervention happens, only response status
+    EMERGENCY_MODE = 4;
+  }
+
+  enum ErrorCode {
+    NO_ERROR = 0;
+
+    CMD_NOT_IN_PERIOD = 1;  // control cmd not in period
+
+    // car chassis report error, like steer, brake, throttle, gear fault
+    CHASSIS_ERROR = 2;
+
+    // classify the types of the car chassis errors
+    CHASSIS_ERROR_ON_STEER = 6;
+    CHASSIS_ERROR_ON_BRAKE = 7;
+    CHASSIS_ERROR_ON_THROTTLE = 8;
+    CHASSIS_ERROR_ON_GEAR = 9;
+
+    MANUAL_INTERVENTION = 3;  // human manual intervention
+
+    // receive car chassis can frame not in period
+    CHASSIS_CAN_NOT_IN_PERIOD = 4;
+
+    UNKNOWN_ERROR = 5;
+  }
+
+  enum GearPosition {
+    GEAR_NEUTRAL = 0;
+    GEAR_DRIVE = 1;
+    GEAR_REVERSE = 2;
+    GEAR_PARKING = 3;
+    GEAR_LOW = 4;
+    GEAR_INVALID = 5;
+    GEAR_NONE = 6;
+  }
+
+  enum BumperEvent {
+    BUMPER_INVALID = 0;
+    BUMPER_NORMAL = 1;
+    BUMPER_PRESSED = 2;
+  }
+
+  optional bool engine_started = 3;
+
+  // Engine speed in RPM.
+  optional float engine_rpm = 4 [default = nan];
+
+  // Vehicle Speed in meters per second.
+  optional float speed_mps = 5 [default = nan];
+
+  // Vehicle odometer in meters.
+  optional float odometer_m = 6 [default = nan];
+
+  // Fuel range in meters.
+  optional int32 fuel_range_m = 7;
+
+  // Real throttle location in [%], ranging from 0 to 100.
+  optional float throttle_percentage = 8 [default = nan];
+
+  // Real brake location in [%], ranging from 0 to 100.
+  optional float brake_percentage = 9 [default = nan];
+
+  // Real steering location in [%], ranging from -100 to 100.
+  // steering_angle / max_steering_angle
+  // Clockwise: negative
+  // CountClockwise: positive
+  optional float steering_percentage = 11 [default = nan];
+
+  // Applied steering torque in [Nm].
+  optional float steering_torque_nm = 12 [default = nan];
+
+  // Parking brake status.
+  optional bool parking_brake = 13;
+
+  // Light signals.
+  optional bool high_beam_signal = 14 [deprecated = true];
+  optional bool low_beam_signal = 15 [deprecated = true];
+  optional bool left_turn_signal = 16 [deprecated = true];
+  optional bool right_turn_signal = 17 [deprecated = true];
+  optional bool horn = 18 [deprecated = true];
+
+  optional bool wiper = 19;
+  optional bool disengage_status = 20 [deprecated = true];
+  optional DrivingMode driving_mode = 21 [default = COMPLETE_MANUAL];
+  optional ErrorCode error_code = 22 [default = NO_ERROR];
+  optional GearPosition gear_location = 23;
+
+  // timestamp for steering module
+  optional double steering_timestamp = 24;  // In seconds, with 1e-6 accuracy
+
+  // chassis also needs it own sending timestamp
+  optional apollo.common.Header header = 25;
+
+  optional int32 chassis_error_mask = 26 [default = 0];
+
+  optional apollo.common.VehicleSignal signal = 27;
+
+  // Only available for Lincoln now
+  optional ChassisGPS chassis_gps = 28;
+
+  optional apollo.common.EngageAdvice engage_advice = 29;
+
+  optional WheelSpeed wheel_speed = 30;
+
+  optional Surround surround = 31;
+
+  // Vehicle registration information
+  optional License license = 32 [deprecated = true];
+
+  // Real gear location.
+  // optional int32 gear_location = 10 [deprecated = true]; deprecated use enum
+  // replace this [id 23]
+
+  optional apollo.common.VehicleID vehicle_id = 33;
+
+  optional int32 battery_soc_percentage = 34 [default = -1];
+
+  // Real send throttle location in [%], ranging from 0 to 100.
+  optional float throttle_percentage_cmd = 35 [default = nan];
+
+  // Real send brake location in [%], ranging from 0 to 100.
+  optional float brake_percentage_cmd = 36 [default = nan];
+
+  // Real send steering location in [%], ranging from -100 to 100.
+  // steering_angle / max_steering_angle
+  // Clockwise: negative
+  // CountClockwise: positive
+  optional float steering_percentage_cmd = 37 [default = nan];
+
+  optional BumperEvent front_bumper_event = 38;
+
+  optional BumperEvent back_bumper_event = 39;
+
+  optional CheckResponse check_response = 40;
+
+  // Custom chassis operation command defined by user for extensibility.
+  optional google.protobuf.Any custom_status = 41;
+}
+
+message ChassisGPS {
+  optional double latitude = 1;
+  optional double longitude = 2;
+  optional bool gps_valid = 3;
+
+  optional int32 year = 4;
+  optional int32 month = 5;
+  optional int32 day = 6;
+  optional int32 hours = 7;
+  optional int32 minutes = 8;
+  optional int32 seconds = 9;
+  optional double compass_direction = 10;
+  optional double pdop = 11;
+  optional bool is_gps_fault = 12;
+  optional bool is_inferred = 13;
+
+  optional double altitude = 14;
+  optional double heading = 15;
+  optional double hdop = 16;
+  optional double vdop = 17;
+  optional GpsQuality quality = 18;
+  optional int32 num_satellites = 19;
+  optional double gps_speed = 20;
+}
+
+enum GpsQuality {
+  FIX_NO = 0;
+  FIX_2D = 1;
+  FIX_3D = 2;
+  FIX_INVALID = 3;
+}
+
+message WheelSpeed {
+  enum WheelSpeedType {
+    FORWARD = 0;
+    BACKWARD = 1;
+    STANDSTILL = 2;
+    INVALID = 3;
+  }
+  optional bool is_wheel_spd_rr_valid = 1 [default = false];
+  optional WheelSpeedType wheel_direction_rr = 2 [default = INVALID];
+  optional double wheel_spd_rr = 3 [default = 0.0];
+  optional bool is_wheel_spd_rl_valid = 4 [default = false];
+  optional WheelSpeedType wheel_direction_rl = 5 [default = INVALID];
+  optional double wheel_spd_rl = 6 [default = 0.0];
+  optional bool is_wheel_spd_fr_valid = 7 [default = false];
+  optional WheelSpeedType wheel_direction_fr = 8 [default = INVALID];
+  optional double wheel_spd_fr = 9 [default = 0.0];
+  optional bool is_wheel_spd_fl_valid = 10 [default = false];
+  optional WheelSpeedType wheel_direction_fl = 11 [default = INVALID];
+  optional double wheel_spd_fl = 12 [default = 0.0];
+}
+
+message Sonar {
+  optional double range = 1;                       // Meter
+  optional apollo.common.Point3D translation = 2;  // Meter
+  optional apollo.common.Quaternion rotation = 3;
+}
+
+message Surround {
+  optional bool cross_traffic_alert_left = 1;
+  optional bool cross_traffic_alert_left_enabled = 2;
+  optional bool blind_spot_left_alert = 3;
+  optional bool blind_spot_left_alert_enabled = 4;
+  optional bool cross_traffic_alert_right = 5;
+  optional bool cross_traffic_alert_right_enabled = 6;
+  optional bool blind_spot_right_alert = 7;
+  optional bool blind_spot_right_alert_enabled = 8;
+  optional double sonar00 = 9;
+  optional double sonar01 = 10;
+  optional double sonar02 = 11;
+  optional double sonar03 = 12;
+  optional double sonar04 = 13;
+  optional double sonar05 = 14;
+  optional double sonar06 = 15;
+  optional double sonar07 = 16;
+  optional double sonar08 = 17;
+  optional double sonar09 = 18;
+  optional double sonar10 = 19;
+  optional double sonar11 = 20;
+  optional bool sonar_enabled = 21;
+  optional bool sonar_fault = 22;
+  repeated double sonar_range = 23;
+  repeated Sonar sonar = 24;
+}
+
+message License {
+  optional string vin = 1 [deprecated = true];
+}
+
+// CheckResponseSignal
+message CheckResponse {
+  optional bool is_eps_online = 1 [default = false];
+  optional bool is_epb_online = 2 [default = false];
+  optional bool is_esp_online = 3 [default = false];
+  optional bool is_vtog_online = 4 [default = false];
+  optional bool is_scu_online = 5 [default = false];
+  optional bool is_switch_online = 6 [default = false];
+  optional bool is_vcu_online = 7 [default = false];
+}

+ 982 - 0
src/test/testhdmap/modules/common_msgs/chassis_msgs/chassis_detail.proto

@@ -0,0 +1,982 @@
+syntax = "proto2";
+
+package apollo.canbus;
+
+import "modules/common_msgs/basic_msgs/vehicle_id.proto";
+import "modules/common_msgs/chassis_msgs/chassis.proto";
+
+
+message ChassisDetail {
+  enum Type {
+    QIRUI_EQ_15 = 0;
+    CHANGAN_RUICHENG = 1;
+  }
+  optional Type car_type = 1;               // car type
+  optional BasicInfo basic = 2;             // basic info
+  optional Safety safety = 3;               // safety
+  optional Gear gear = 4;                   // gear
+  optional Ems ems = 5;                     // engine manager system
+  optional Esp esp = 6;                     // Electronic Stability Program
+  optional Gas gas = 7;                     // gas pedal
+  optional Epb epb = 8;                     // Electronic parking brake
+  optional Brake brake = 9;                 // brake pedal
+  optional Deceleration deceleration = 10;  // deceleration
+  optional VehicleSpd vehicle_spd = 11;     // vehicle speed
+  optional Eps eps = 12;                    // Electronic Power Steering
+  optional Light light = 13;                // Light
+  optional Battery battery = 14;            // Battery info
+  optional CheckResponseSignal check_response = 15;
+  optional License license = 16 [deprecated = true];  // License info
+  optional Surround surround = 17;                    // Surround information
+  // Reserve fields for other vehicles
+  optional apollo.common.VehicleID vehicle_id = 101;
+}
+
+// CheckResponseSignal
+message CheckResponseSignal {
+  optional bool is_eps_online = 1 [default = false];   // byd:0x34C qirui:0x505
+  optional bool is_epb_online = 2 [default = false];   // byd:0x218
+  optional bool is_esp_online = 3 [default = false];   // byd:0x122 qirui:0x451
+  optional bool is_vtog_online = 4 [default = false];  // byd:0x242
+  optional bool is_scu_online = 5 [default = false];   // byd:0x35C
+  optional bool is_switch_online = 6 [default = false];  // byd:0x133
+  optional bool is_vcu_online = 7 [default = false];     //  qirui:0x400
+}
+
+// Battery
+message Battery {
+  optional double battery_percent = 1;  // unit:%, battery percentage left
+  // lincoln fuellevel 72
+  optional double fuel_level = 2;
+}
+
+// light
+message Light {
+  enum TurnLightType {
+    TURN_LIGHT_OFF = 0;
+    TURN_LEFT_ON = 1;
+    TURN_RIGHT_ON = 2;
+    TURN_LIGHT_ON = 3;
+  }
+  enum BeamLampType {
+    BEAM_OFF = 0;
+    HIGH_BEAM_ON = 1;
+    LOW_BEAM_ON = 2;
+  }
+  enum LincolnLampType {
+    BEAM_NULL = 0;
+    BEAM_FLASH_TO_PASS = 1;
+    BEAM_HIGH = 2;
+    BEAM_INVALID = 3;
+  }
+  enum LincolnWiperType {
+    WIPER_OFF = 0;
+    WIPER_AUTO_OFF = 1;
+    WIPER_OFF_MOVING = 2;
+    WIPER_MANUAL_OFF = 3;
+    WIPER_MANUAL_ON = 4;
+    WIPER_MANUAL_LOW = 5;
+    WIPER_MANUAL_HIGH = 6;
+    WIPER_MIST_FLICK = 7;
+    WIPER_WASH = 8;
+    WIPER_AUTO_LOW = 9;
+    WIPER_AUTO_HIGH = 10;
+    WIPER_COURTESY_WIPE = 11;
+    WIPER_AUTO_ADJUST = 12;
+    WIPER_RESERVED = 13;
+    WIPER_STALLED = 14;
+    WIPER_NO_DATA = 15;
+  }
+  enum LincolnAmbientType {
+    AMBIENT_DARK = 0;
+    AMBIENT_LIGHT = 1;
+    AMBIENT_TWILIGHT = 2;
+    AMBIENT_TUNNEL_ON = 3;
+    AMBIENT_TUNNEL_OFF = 4;
+    AMBIENT_INVALID = 5;
+    AMBIENT_NO_DATA = 7;
+  }
+
+  optional TurnLightType turn_light_type = 1;
+  optional BeamLampType beam_lamp_type = 2;
+  optional bool is_brake_lamp_on = 3;
+  // byd switch 133
+  optional bool is_auto_light = 4;
+  optional int32 wiper_gear = 5;
+  optional int32 lotion_gear = 6;
+  optional bool is_horn_on = 7;
+
+  // lincoln misc 69
+  optional LincolnLampType lincoln_lamp_type = 8;
+  optional LincolnWiperType lincoln_wiper = 9;
+  optional LincolnAmbientType lincoln_ambient = 10;
+}
+
+// Electrical Power Steering
+message Eps {
+  enum Type {
+    NOT_AVAILABLE = 0;
+    READY = 1;
+    ACTIVE = 2;
+    INVALID = 3;
+  }
+  // changan: eps 2a0
+  optional bool is_eps_fail = 1;
+  // eps 2a0
+  optional Type eps_control_state = 2;       // for changan to control steering
+  optional double eps_driver_hand_torq = 3;  // unit:Nm
+
+  optional bool is_steering_angle_valid = 4;
+  optional double steering_angle = 5;      // unit:degree
+  optional double steering_angle_spd = 6;  // unit:degree/s
+
+  // byd sas 11f
+  optional bool is_trimming_status = 7;
+  optional bool is_calibration_status = 8;
+  optional bool is_failure_status = 9;
+  optional int32 allow_enter_autonomous_mode = 10;
+  optional int32 current_driving_mode = 11;
+
+  // lincoln steering 65
+  optional double steering_angle_cmd = 12;
+  optional double vehicle_speed = 13;
+  optional double epas_torque = 14;
+  optional bool steering_enabled = 15;
+  optional bool driver_override = 16;
+  optional bool driver_activity = 17;
+  optional bool watchdog_fault = 18;
+  optional bool channel_1_fault = 19;
+  optional bool channel_2_fault = 20;
+  optional bool calibration_fault = 21;
+  optional bool connector_fault = 22;
+
+  optional double timestamp_65 = 23;
+
+  // lincoln version 7f
+  optional int32 major_version = 24;
+  optional int32 minor_version = 25;
+  optional int32 build_number = 26;
+}
+
+message VehicleSpd {
+  // esp 277
+  optional bool is_vehicle_standstill = 1;
+
+  // esp 218
+  optional bool is_vehicle_spd_valid = 2;
+  optional double vehicle_spd = 3 [default = 0];  // unit:m/s
+  // esp 208
+  optional bool is_wheel_spd_rr_valid = 4;
+  optional WheelSpeed.WheelSpeedType wheel_direction_rr = 5;
+  optional double wheel_spd_rr = 6;
+  optional bool is_wheel_spd_rl_valid = 7;
+  optional WheelSpeed.WheelSpeedType wheel_direction_rl = 8;
+  optional double wheel_spd_rl = 9;
+  optional bool is_wheel_spd_fr_valid = 10;
+  optional WheelSpeed.WheelSpeedType wheel_direction_fr = 11;
+  optional double wheel_spd_fr = 12;
+  optional bool is_wheel_spd_fl_valid = 13;
+  optional WheelSpeed.WheelSpeedType wheel_direction_fl = 14;
+  optional double wheel_spd_fl = 15;
+
+  // byd esp 222
+  optional bool is_yaw_rate_valid = 16;
+  optional double yaw_rate = 17;
+  optional double yaw_rate_offset = 18;
+
+  // byd esp 223
+  optional bool is_ax_valid = 19;
+  optional double ax = 20;
+  optional double ax_offset = 21;
+  optional bool is_ay_valid = 22;
+  optional double ay = 23;
+  optional double ay_offset = 24;
+
+  // lincoln accel 6b
+  optional double lat_acc = 25;
+  optional double long_acc = 26;
+  optional double vert_acc = 27;
+
+  // lincoln gyro 6c
+  optional double roll_rate = 28;
+
+  // lincoln brakeinfo 74
+  optional double acc_est = 29;
+
+  // lincoln wheelspeed 6a
+  optional double timestamp_sec = 30;
+}
+
+message Deceleration {
+  // esp 277
+  optional bool is_deceleration_available =
+      1;  // for changan to send deceleration value
+  optional bool is_deceleration_active =
+      2;  // for changan to send deceleration value
+
+  optional double deceleration = 3 [default = 0];
+
+  optional double is_evb_fail = 4;
+  optional double evb_pressure = 5 [default = 0];  // mpa, 0~25.5
+
+  optional double brake_pressure = 6 [default = 0];
+  optional double brake_pressure_spd = 7 [default = 0];
+}
+
+message Brake {
+  enum HSAStatusType {
+    HSA_INACTIVE = 0;
+    HSA_FINDING_GRADIENT = 1;
+    HSA_ACTIVE_PRESSED = 2;
+    HSA_ACTIVE_RELEASED = 3;
+    HSA_FAST_RELEASE = 4;
+    HSA_SLOW_RELEASE = 5;
+    HSA_FAILED = 6;
+    HSA_UNDEFINED = 7;
+  }
+  enum HSAModeType {
+    HSA_OFF = 0;
+    HSA_AUTO = 1;
+    HSA_MANUAL = 2;
+    HSA_MODE_UNDEFINED = 3;
+  }
+  // ems 255
+  optional bool is_brake_pedal_pressed = 1
+      [default = false];  // only manual brake
+  // esp 277
+  optional bool is_brake_force_exist =
+      2;  // no matter auto mode brake or manual brake
+  optional bool is_brake_over_heat = 3;
+
+  optional bool is_hand_brake_on = 4;  // hand brake
+  optional double brake_pedal_position = 5;
+
+  // byd vtog 342
+  optional bool is_brake_valid = 6;
+
+  // lincoln brake 61
+  optional double brake_input = 7;
+  optional double brake_cmd = 8;
+  optional double brake_output = 9;
+  optional bool boo_input = 10;
+  optional bool boo_cmd = 11;
+  optional bool boo_output = 12;
+  optional bool watchdog_applying_brakes = 13;
+  optional int32 watchdog_source = 14;
+  optional bool brake_enabled = 15;
+  optional bool driver_override = 16;
+  optional bool driver_activity = 17;
+  optional bool watchdog_fault = 18;
+  optional bool channel_1_fault = 19;
+  optional bool channel_2_fault = 20;
+  optional bool boo_fault = 21;
+  optional bool connector_fault = 22;
+
+  // lincoln brakeinfo 74
+  optional double brake_torque_req = 23;
+  optional HSAStatusType hsa_status = 24;
+  optional double brake_torque_act = 25;
+  optional HSAModeType hsa_mode = 26;
+  optional double wheel_torque_act = 27;
+
+  // lincoln version 7f
+  optional int32 major_version = 28;
+  optional int32 minor_version = 29;
+  optional int32 build_number = 30;
+}
+
+// Electrical Parking Brake
+message Epb {
+  enum PBrakeType {
+    PBRAKE_OFF = 0;
+    PBRAKE_TRANSITION = 1;
+    PBRAKE_ON = 2;
+    PBRAKE_FAULT = 3;
+  }
+  // epb 256
+  optional bool is_epb_error = 1;
+  optional bool is_epb_released = 2;
+
+  // byd epb 218
+  optional int32 epb_status = 3;
+
+  // lincoln brakeinfo 74
+  optional PBrakeType parking_brake_status = 4;
+}
+
+message Gas {
+  // ems 255
+  optional bool is_gas_pedal_error = 1;
+  // ems 26a
+  optional bool is_gas_pedal_pressed_more = 2;  // more than auto mode gas torq
+  optional double gas_pedal_position = 3 [default = 0];  // manual gas
+  // byd vtog 342
+  optional bool is_gas_valid = 4 [default = false];
+
+  // lincoln throttle 63
+  optional double throttle_input = 5;
+  optional double throttle_cmd = 6;
+  optional double throttle_output = 7;
+  optional int32 watchdog_source = 8;
+  optional bool throttle_enabled = 9;
+  optional bool driver_override = 10;
+  optional bool driver_activity = 11;
+  optional bool watchdog_fault = 12;
+  optional bool channel_1_fault = 13;
+  optional bool channel_2_fault = 14;
+  optional bool connector_fault = 15;
+
+  // lincoln throttleinfo 75
+  optional double accelerator_pedal = 16;
+  optional double accelerator_pedal_rate = 17;
+
+  // lincoln version 7f
+  optional int32 major_version = 18;
+  optional int32 minor_version = 19;
+  optional int32 build_number = 20;
+}
+
+// Electronic Stability Program
+message Esp {
+  // esp 277
+  optional bool is_esp_acc_error = 1;  // for changan to control car
+
+  // esp 218
+  optional bool is_esp_on = 2;
+  optional bool is_esp_active = 3;
+  optional bool is_abs_error = 4;
+  optional bool is_abs_active = 5;
+  optional bool is_tcsvdc_fail = 6;
+
+  // lincoln brakeinfo 74
+  optional bool is_abs_enabled = 7;
+  optional bool is_stab_active = 8;
+  optional bool is_stab_enabled = 9;
+  optional bool is_trac_active = 10;
+  optional bool is_trac_enabled = 11;
+}
+
+// Engine Manager System
+message Ems {
+  enum Type {
+    STOP = 0;
+    CRANK = 1;
+    RUNNING = 2;
+    INVALID = 3;
+  }
+  // ems 26a
+  optional bool is_engine_acc_available = 1;  // for changan to control car
+  optional bool is_engine_acc_error = 2;      // for changan to control car
+
+  // ems 265
+  optional Type engine_state = 3;
+  optional double max_engine_torq_percent =
+      4;  // for engine torq control, unit:%
+  optional double min_engine_torq_percent =
+      5;  // for engine torq control, unit:%
+  optional int32 base_engine_torq_constant =
+      6;  // for engine torq control, unit:Nm
+
+  // ems 255
+  optional bool is_engine_speed_error = 7;
+  optional double engine_speed = 8;
+
+  // byd vtog 241
+  optional int32 engine_torque = 9;
+  // byd vtog 242
+  optional bool is_over_engine_torque = 10;
+
+  // lincoln mkz throttleinfo 75
+  optional double engine_rpm = 11;
+}
+
+message Gear {
+  // tcu 268
+  optional bool is_shift_position_valid = 1;
+  // chanan: tcu 268
+  optional Chassis.GearPosition gear_state = 2;
+  // lincoln gear 67
+  optional bool driver_override = 3;
+  optional Chassis.GearPosition gear_cmd = 4;
+  optional bool canbus_fault = 5;
+}
+
+message Safety {
+  // ip 270
+  optional bool is_driver_car_door_close = 1;
+  // sas 50
+  optional bool is_driver_buckled = 2;
+
+  // byd sws 4a8
+  optional int32 emergency_button = 3;
+
+  // qirui:403
+  // when car chassis error, like system fault, or warning report
+  optional bool has_error = 4 [default = false];
+  optional bool is_motor_invertor_fault = 5;
+  optional bool is_system_fault = 6;
+  optional bool is_power_battery_fault = 7;
+  optional bool is_motor_invertor_over_temperature = 8;
+  optional bool is_small_battery_charge_discharge_fault = 9;
+  optional int32 driving_mode = 10;
+
+  // lincoln misc 69
+  optional bool is_passenger_door_open = 11;
+  optional bool is_rearleft_door_open = 12;
+  optional bool is_rearright_door_open = 13;
+  optional bool is_hood_open = 14;
+  optional bool is_trunk_open = 15;
+  optional bool is_passenger_detected = 16;
+  optional bool is_passenger_airbag_enabled = 17;
+  optional bool is_passenger_buckled = 18;
+
+  // lincoln tirepressure 71
+  optional int32 front_left_tire_press = 19;
+  optional int32 front_right_tire_press = 20;
+  optional int32 rear_left_tire_press = 21;
+  optional int32 rear_right_tire_press = 22;
+  optional Chassis.DrivingMode car_driving_mode = 23;
+}
+
+message BasicInfo {
+  enum Type {
+    OFF = 0;
+    ACC = 1;
+    ON = 2;
+    START = 3;
+    INVALID = 4;
+  }
+
+  optional bool is_auto_mode = 1;
+  optional Type power_state = 2;
+  optional bool is_air_bag_deployed = 3;
+  optional double odo_meter = 4;  // odo meter, unit:km
+  optional double drive_range =
+      5;  // the meter left when drive continuously, unit:km
+  optional bool is_system_error = 6;
+  optional bool is_human_interrupt = 7;  // human interrupt
+
+  // lincoln misc 69
+  optional bool acc_on_button = 8;  // acc on button pressed
+  optional bool acc_off_button = 9;
+  optional bool acc_res_button = 10;
+  optional bool acc_cancel_button = 11;
+  optional bool acc_on_off_button = 12;
+  optional bool acc_res_cancel_button = 13;
+  optional bool acc_inc_spd_button = 14;
+  optional bool acc_dec_spd_button = 15;
+  optional bool acc_inc_gap_button = 16;
+  optional bool acc_dec_gap_button = 17;
+  optional bool lka_button = 18;
+  optional bool canbus_fault = 19;
+
+  // lincoln gps 6d
+  optional double latitude = 20;
+  optional double longitude = 21;
+  optional bool gps_valid = 22;
+
+  // lincoln gps 6e
+  optional int32 year = 23;
+  optional int32 month = 24;
+  optional int32 day = 25;
+  optional int32 hours = 26;
+  optional int32 minutes = 27;
+  optional int32 seconds = 28;
+  optional double compass_direction = 29;
+  optional double pdop = 30;
+  optional bool is_gps_fault = 31;
+  optional bool is_inferred = 32;
+
+  // lincoln gps 6f
+  optional double altitude = 33;
+  optional double heading = 34;
+  optional double hdop = 35;
+  optional double vdop = 36;
+  optional GpsQuality quality = 37;
+  optional int32 num_satellites = 38;
+  optional double gps_speed = 39;
+}
+
+// Gem vehicle starts from here
+// TODO(QiL) : Re-factor needed here
+
+message Global_rpt_6a {
+  // Report Message
+  enum Pacmod_statusType {
+    PACMOD_STATUS_CONTROL_DISABLED = 0;
+    PACMOD_STATUS_CONTROL_ENABLED = 1;
+  }
+  enum Override_statusType {
+    OVERRIDE_STATUS_NOT_OVERRIDDEN = 0;
+    OVERRIDE_STATUS_OVERRIDDEN = 1;
+  }
+  enum Brk_can_timeoutType {
+    BRK_CAN_TIMEOUT_NO_ACTIVE_CAN_TIMEOUT = 0;
+    BRK_CAN_TIMEOUT_ACTIVE_CAN_TIMEOUT = 1;
+  }
+  // [] [0|1]
+  optional Pacmod_statusType pacmod_status = 1;
+  // [] [0|1]
+  optional Override_statusType override_status = 2;
+  // [] [0|1]
+  optional bool veh_can_timeout = 3;
+  // [] [0|1]
+  optional bool str_can_timeout = 4;
+  // [] [0|1]
+  optional Brk_can_timeoutType brk_can_timeout = 5;
+  // [] [0|1]
+  optional bool usr_can_timeout = 6;
+  // [] [0|65535]
+  optional int32 usr_can_read_errors = 7;
+}
+
+message Brake_cmd_6b {
+  // Report Message
+  // [%] [0|1]
+  optional double brake_cmd = 1;
+}
+
+message Brake_rpt_6c {
+  // Report Message
+  enum Brake_on_offType {
+    BRAKE_ON_OFF_OFF = 0;
+    BRAKE_ON_OFF_ON = 1;
+  }
+  // [%] [0|1]
+  optional double manual_input = 1;
+  // [%] [0|1]
+  optional double commanded_value = 2;
+  // [%] [0|1]
+  optional double output_value = 3;
+  // [] [0|1]
+  optional Brake_on_offType brake_on_off = 4;
+}
+
+message Steering_cmd_6d {
+  // Report Message
+  // [radians] [-2147483.648|2147483.647]
+  optional double position_value = 1;
+  // [rad/s] [0|65.535]
+  optional double speed_limit = 2;
+}
+
+message Steering_rpt_1_6e {
+  // Report Message
+  // [rad/s] [-32.768|32.767]
+  optional double manual_input = 1;
+  // [rad/s] [-32.768|32.767]
+  optional double commanded_value = 2;
+  // [rad/s] [-32.768|32.767]
+  optional double output_value = 3;
+}
+
+message Wheel_speed_rpt_7a {
+  // Report Message
+  // [rad/s] [-32768|32767]
+  optional int32 wheel_spd_rear_right = 1;
+  // [rad/s] [-32768|32767]
+  optional int32 wheel_spd_rear_left = 2;
+  // [rad/s] [-32768|32767]
+  optional int32 wheel_spd_front_right = 3;
+  // [rad/s] [-32768|32767]
+  optional int32 wheel_spd_front_left = 4;
+}
+
+message Date_time_rpt_83 {
+  // Report Message
+  // [sec] [0|60]
+  optional int32 time_second = 1;
+  // [min] [0|60]
+  optional int32 time_minute = 2;
+  // [hr] [0|23]
+  optional int32 time_hour = 3;
+  // [dy] [1|31]
+  optional int32 date_day = 4;
+  // [mon] [1|12]
+  optional int32 date_month = 5;
+  // [yr] [2000|2255]
+  optional int32 date_year = 6;
+}
+
+message Brake_motor_rpt_1_70 {
+  // Report Message
+  // [amps] [0|4294967.295]
+  optional double motor_current = 1;
+  // [radians] [-2147483.648|2147483.647]
+  optional double shaft_position = 2;
+}
+
+message Headlight_rpt_77 {
+  // Report Message
+  enum Output_valueType {
+    OUTPUT_VALUE_HEADLIGHTS_OFF = 0;
+    OUTPUT_VALUE_LOW_BEAMS = 1;
+    OUTPUT_VALUE_HIGH_BEAMS = 2;
+  }
+  enum Manual_inputType {
+    MANUAL_INPUT_HEADLIGHTS_OFF = 0;
+    MANUAL_INPUT_LOW_BEAMS = 1;
+    MANUAL_INPUT_HIGH_BEAMS = 2;
+  }
+  enum Commanded_valueType {
+    COMMANDED_VALUE_HEADLIGHTS_OFF = 0;
+    COMMANDED_VALUE_LOW_BEAMS = 1;
+    COMMANDED_VALUE_HIGH_BEAMS = 2;
+  }
+  // [] [0|2]
+  optional Output_valueType output_value = 1;
+  // [] [0|2]
+  optional Manual_inputType manual_input = 2;
+  // [] [0|2]
+  optional Commanded_valueType commanded_value = 3;
+}
+
+message Accel_rpt_68 {
+  // Report Message
+  // [%] [0|1]
+  optional double manual_input = 1;
+  // [%] [0|1]
+  optional double commanded_value = 2;
+  // [%] [0|1]
+  optional double output_value = 3;
+}
+
+message Steering_motor_rpt_3_75 {
+  // Report Message
+  // [N-m] [-2147483.648|2147483.647]
+  optional double torque_output = 1;
+  // [N-m] [-2147483.648|2147483.647]
+  optional double torque_input = 2;
+}
+
+message Turn_cmd_63 {
+  // Report Message
+  enum Turn_signal_cmdType {
+    TURN_SIGNAL_CMD_RIGHT = 0;
+    TURN_SIGNAL_CMD_NONE = 1;
+    TURN_SIGNAL_CMD_LEFT = 2;
+    TURN_SIGNAL_CMD_HAZARD = 3;
+  }
+  // [] [0|3]
+  optional Turn_signal_cmdType turn_signal_cmd = 1;
+}
+
+message Turn_rpt_64 {
+  // Report Message
+  enum Manual_inputType {
+    MANUAL_INPUT_RIGHT = 0;
+    MANUAL_INPUT_NONE = 1;
+    MANUAL_INPUT_LEFT = 2;
+    MANUAL_INPUT_HAZARD = 3;
+  }
+  enum Commanded_valueType {
+    COMMANDED_VALUE_RIGHT = 0;
+    COMMANDED_VALUE_NONE = 1;
+    COMMANDED_VALUE_LEFT = 2;
+    COMMANDED_VALUE_HAZARD = 3;
+  }
+  enum Output_valueType {
+    OUTPUT_VALUE_RIGHT = 0;
+    OUTPUT_VALUE_NONE = 1;
+    OUTPUT_VALUE_LEFT = 2;
+    OUTPUT_VALUE_HAZARD = 3;
+  }
+  // [] [0|3]
+  optional Manual_inputType manual_input = 1;
+  // [] [0|3]
+  optional Commanded_valueType commanded_value = 2;
+  // [] [0|3]
+  optional Output_valueType output_value = 3;
+}
+
+message Shift_cmd_65 {
+  // Report Message
+  enum Shift_cmdType {
+    SHIFT_CMD_PARK = 0;
+    SHIFT_CMD_REVERSE = 1;
+    SHIFT_CMD_NEUTRAL = 2;
+    SHIFT_CMD_FORWARD = 3;
+    SHIFT_CMD_LOW = 4;
+  }
+  // FORWARD_is_also_LOW_on_vehicles_with_LOW/HIGH,_PARK_and_HIGH_only_available_on_certain_Vehicles
+  // [] [0|4]
+  optional Shift_cmdType shift_cmd = 1;
+}
+
+message Shift_rpt_66 {
+  // Report Message
+  enum Manual_inputType {
+    MANUAL_INPUT_PARK = 0;
+    MANUAL_INPUT_REVERSE = 1;
+    MANUAL_INPUT_NEUTRAL = 2;
+    MANUAL_INPUT_FORWARD = 3;
+    MANUAL_INPUT_HIGH = 4;
+  }
+  enum Commanded_valueType {
+    COMMANDED_VALUE_PARK = 0;
+    COMMANDED_VALUE_REVERSE = 1;
+    COMMANDED_VALUE_NEUTRAL = 2;
+    COMMANDED_VALUE_FORWARD = 3;
+    COMMANDED_VALUE_HIGH = 4;
+  }
+  enum Output_valueType {
+    OUTPUT_VALUE_PARK = 0;
+    OUTPUT_VALUE_REVERSE = 1;
+    OUTPUT_VALUE_NEUTRAL = 2;
+    OUTPUT_VALUE_FORWARD = 3;
+    OUTPUT_VALUE_HIGH = 4;
+  }
+  // [] [0|4]
+  optional Manual_inputType manual_input = 1;
+  // [] [0|4]
+  optional Commanded_valueType commanded_value = 2;
+  // [] [0|4]
+  optional Output_valueType output_value = 3;
+}
+
+message Accel_cmd_67 {
+  // Report Message
+  // [%] [0|1]
+  optional double accel_cmd = 1;
+}
+
+message Lat_lon_heading_rpt_82 {
+  // Report Message
+  // [deg] [-327.68|327.67]
+  optional double heading = 1;
+  // [sec] [-128|127]
+  optional int32 longitude_seconds = 2;
+  // [min] [-128|127]
+  optional int32 longitude_minutes = 3;
+  // [deg] [-128|127]
+  optional int32 longitude_degrees = 4;
+  // [sec] [-128|127]
+  optional int32 latitude_seconds = 5;
+  // [min] [-128|127]
+  optional int32 latitude_minutes = 6;
+  // [deg] [-128|127]
+  optional int32 latitude_degrees = 7;
+}
+
+message Global_cmd_69 {
+  // Report Message
+  enum Pacmod_enableType {
+    PACMOD_ENABLE_CONTROL_DISABLED = 0;
+    PACMOD_ENABLE_CONTROL_ENABLED = 1;
+  }
+  enum Clear_overrideType {
+    CLEAR_OVERRIDE_DON_T_CLEAR_ACTIVE_OVERRIDES = 0;
+    CLEAR_OVERRIDE_CLEAR_ACTIVE_OVERRIDES = 1;
+  }
+  enum Ignore_overrideType {
+    IGNORE_OVERRIDE_DON_T_IGNORE_USER_OVERRIDES = 0;
+    IGNORE_OVERRIDE_IGNORE_USER_OVERRIDES = 1;
+  }
+  // [] [0|1]
+  optional Pacmod_enableType pacmod_enable = 1;
+  // [] [0|1]
+  optional Clear_overrideType clear_override = 2;
+  // [] [0|1]
+  optional Ignore_overrideType ignore_override = 3;
+}
+
+message Parking_brake_status_rpt_80 {
+  // Report Message
+  enum Parking_brake_enabledType {
+    PARKING_BRAKE_ENABLED_OFF = 0;
+    PARKING_BRAKE_ENABLED_ON = 1;
+  }
+  // [] [0|1]
+  optional Parking_brake_enabledType parking_brake_enabled = 1;
+}
+
+message Yaw_rate_rpt_81 {
+  // Report Message
+  // [rad/s] [-327.68|327.67]
+  optional double yaw_rate = 1;
+}
+
+message Horn_rpt_79 {
+  // Report Message
+  enum Output_valueType {
+    OUTPUT_VALUE_OFF = 0;
+    OUTPUT_VALUE_ON = 1;
+  }
+  enum Commanded_valueType {
+    COMMANDED_VALUE_OFF = 0;
+    COMMANDED_VALUE_ON = 1;
+  }
+  enum Manual_inputType {
+    MANUAL_INPUT_OFF = 0;
+    MANUAL_INPUT_ON = 1;
+  }
+  // [] [0|1]
+  optional Output_valueType output_value = 1;
+  // [] [0|1]
+  optional Commanded_valueType commanded_value = 2;
+  // [] [0|1]
+  optional Manual_inputType manual_input = 3;
+}
+
+message Horn_cmd_78 {
+  // Report Message
+  enum Horn_cmdType {
+    HORN_CMD_OFF = 0;
+    HORN_CMD_ON = 1;
+  }
+  // [] [0|1]
+  optional Horn_cmdType horn_cmd = 1;
+}
+
+message Wiper_rpt_91 {
+  // Report Message
+  enum Output_valueType {
+    OUTPUT_VALUE_WIPERS_OFF = 0;
+    OUTPUT_VALUE_INTERMITTENT_1 = 1;
+    OUTPUT_VALUE_INTERMITTENT_2 = 2;
+    OUTPUT_VALUE_INTERMITTENT_3 = 3;
+    OUTPUT_VALUE_INTERMITTENT_4 = 4;
+    OUTPUT_VALUE_INTERMITTENT_5 = 5;
+    OUTPUT_VALUE_LOW = 6;
+    OUTPUT_VALUE_HIGH = 7;
+  }
+  enum Commanded_valueType {
+    COMMANDED_VALUE_WIPERS_OFF = 0;
+    COMMANDED_VALUE_INTERMITTENT_1 = 1;
+    COMMANDED_VALUE_INTERMITTENT_2 = 2;
+    COMMANDED_VALUE_INTERMITTENT_3 = 3;
+    COMMANDED_VALUE_INTERMITTENT_4 = 4;
+    COMMANDED_VALUE_INTERMITTENT_5 = 5;
+    COMMANDED_VALUE_LOW = 6;
+    COMMANDED_VALUE_HIGH = 7;
+  }
+  enum Manual_inputType {
+    MANUAL_INPUT_WIPERS_OFF = 0;
+    MANUAL_INPUT_INTERMITTENT_1 = 1;
+    MANUAL_INPUT_INTERMITTENT_2 = 2;
+    MANUAL_INPUT_INTERMITTENT_3 = 3;
+    MANUAL_INPUT_INTERMITTENT_4 = 4;
+    MANUAL_INPUT_INTERMITTENT_5 = 5;
+    MANUAL_INPUT_LOW = 6;
+    MANUAL_INPUT_HIGH = 7;
+  }
+  // [] [0|7]
+  optional Output_valueType output_value = 1;
+  // [] [0|7]
+  optional Commanded_valueType commanded_value = 2;
+  // [] [0|7]
+  optional Manual_inputType manual_input = 3;
+}
+
+message Vehicle_speed_rpt_6f {
+  // Report Message
+  enum Vehicle_speed_validType {
+    VEHICLE_SPEED_VALID_INVALID = 0;
+    VEHICLE_SPEED_VALID_VALID = 1;
+  }
+  // [m/s] [-327.68|327.67]
+  optional double vehicle_speed = 1;
+  // [] [0|1]
+  optional Vehicle_speed_validType vehicle_speed_valid = 2;
+}
+
+message Headlight_cmd_76 {
+  // Report Message
+  enum Headlight_cmdType {
+    HEADLIGHT_CMD_HEADLIGHTS_OFF = 0;
+    HEADLIGHT_CMD_LOW_BEAMS = 1;
+    HEADLIGHT_CMD_HIGH_BEAMS = 2;
+  }
+  // [] [0|2]
+  optional Headlight_cmdType headlight_cmd = 1;
+}
+
+message Steering_motor_rpt_2_74 {
+  // Report Message
+  // [deg C] [-32808|32727]
+  optional int32 encoder_temperature = 1;
+  // [deg C] [-32808|32727]
+  optional int32 motor_temperature = 2;
+  // [rev/s] [-2147483.648|2147483.647]
+  optional double angular_speed = 3;
+}
+
+message Brake_motor_rpt_2_71 {
+  // Report Message
+  // [deg C] [-32808|32727]
+  optional int32 encoder_temperature = 1;
+  // [deg C] [-32808|32727]
+  optional int32 motor_temperature = 2;
+  // [rev/s] [0|4294967.295]
+  optional double angular_speed = 3;
+}
+
+message Steering_motor_rpt_1_73 {
+  // Report Message
+  // [amps] [0|4294967.295]
+  optional double motor_current = 1;
+  // [amps] [-2147483.648|2147483.647]
+  optional double shaft_position = 2;
+}
+
+message Wiper_cmd_90 {
+  // Report Message
+  enum Wiper_cmdType {
+    WIPER_CMD_WIPERS_OFF = 0;
+    WIPER_CMD_INTERMITTENT_1 = 1;
+    WIPER_CMD_INTERMITTENT_2 = 2;
+    WIPER_CMD_INTERMITTENT_3 = 3;
+    WIPER_CMD_INTERMITTENT_4 = 4;
+    WIPER_CMD_INTERMITTENT_5 = 5;
+    WIPER_CMD_LOW = 6;
+    WIPER_CMD_HIGH = 7;
+  }
+  // [] [0|7]
+  optional Wiper_cmdType wiper_cmd = 1;
+}
+
+message Brake_motor_rpt_3_72 {
+  // Report Message
+  // [N-m] [-2147483.648|2147483.647]
+  optional double torque_output = 1;
+  // [N-m] [-2147483.648|2147483.647]
+  optional double torque_input = 2;
+}
+
+message Gem {
+  optional Global_rpt_6a global_rpt_6a = 1;                // report message
+  optional Brake_cmd_6b brake_cmd_6b = 2;                  // report message
+  optional Brake_rpt_6c brake_rpt_6c = 3;                  // report message
+  optional Steering_cmd_6d steering_cmd_6d = 4;            // report message
+  optional Steering_rpt_1_6e steering_rpt_1_6e = 5;        // report message
+  optional Wheel_speed_rpt_7a wheel_speed_rpt_7a = 6;      // report message
+  optional Date_time_rpt_83 date_time_rpt_83 = 7;          // report message
+  optional Brake_motor_rpt_1_70 brake_motor_rpt_1_70 = 8;  // report message
+  optional Headlight_rpt_77 headlight_rpt_77 = 9;          // report message
+  optional Accel_rpt_68 accel_rpt_68 = 10;                 // report message
+  optional Steering_motor_rpt_3_75 steering_motor_rpt_3_75 =
+      11;                                   // report message
+  optional Turn_cmd_63 turn_cmd_63 = 12;    // report message
+  optional Turn_rpt_64 turn_rpt_64 = 13;    // report message
+  optional Shift_cmd_65 shift_cmd_65 = 14;  // report message
+  optional Shift_rpt_66 shift_rpt_66 = 15;  // report message
+  optional Accel_cmd_67 accel_cmd_67 = 16;  // report message
+  optional Lat_lon_heading_rpt_82 lat_lon_heading_rpt_82 =
+      17;                                     // report message
+  optional Global_cmd_69 global_cmd_69 = 18;  // report message
+  optional Parking_brake_status_rpt_80 parking_brake_status_rpt_80 =
+      19;                                                   // report message
+  optional Yaw_rate_rpt_81 yaw_rate_rpt_81 = 20;            // report message
+  optional Horn_rpt_79 horn_rpt_79 = 21;                    // report message
+  optional Horn_cmd_78 horn_cmd_78 = 22;                    // report message
+  optional Wiper_rpt_91 wiper_rpt_91 = 23;                  // report message
+  optional Vehicle_speed_rpt_6f vehicle_speed_rpt_6f = 24;  // report message
+  optional Headlight_cmd_76 headlight_cmd_76 = 25;          // report message
+  optional Steering_motor_rpt_2_74 steering_motor_rpt_2_74 =
+      26;                                                   // report message
+  optional Brake_motor_rpt_2_71 brake_motor_rpt_2_71 = 27;  // report message
+  optional Steering_motor_rpt_1_73 steering_motor_rpt_1_73 =
+      28;                                                   // report message
+  optional Wiper_cmd_90 wiper_cmd_90 = 29;                  // report message
+  optional Brake_motor_rpt_3_72 brake_motor_rpt_3_72 = 30;  // report message
+}

+ 14 - 0
src/test/testhdmap/modules/common_msgs/common-msgs.BUILD

@@ -0,0 +1,14 @@
+load("@rules_cc//cc:defs.bzl", "cc_library")
+  
+cc_library(
+    name = "common-msgs",
+    includes = ["include"],
+    hdrs = glob(
+        [
+            "include/**/*.h",
+        ],
+    ),
+    include_prefix = "modules/common_msgs",
+    strip_include_prefix = "include",
+    visibility = ["//visibility:public"],
+)

+ 17 - 0
src/test/testhdmap/modules/common_msgs/config_msgs/BUILD

@@ -0,0 +1,17 @@
+## Auto generated by `proto_build_generator.py`
+load("//tools/proto:proto.bzl", "proto_library")
+load("//tools:apollo_package.bzl", "apollo_package")
+
+package(default_visibility = ["//visibility:public"])
+
+proto_library(
+    name = "vehicle_config_proto",
+    srcs = ["vehicle_config.proto"],
+    deps = [
+        "//modules/common_msgs/basic_msgs:geometry_proto",
+        "//modules/common_msgs/basic_msgs:header_proto",
+        "//modules/common_msgs/basic_msgs:vehicle_id_proto",
+    ],
+)
+
+apollo_package()

+ 101 - 0
src/test/testhdmap/modules/common_msgs/config_msgs/vehicle_config.proto

@@ -0,0 +1,101 @@
+syntax = "proto2";
+
+package apollo.common;
+
+import "modules/common_msgs/basic_msgs/header.proto";
+import "modules/common_msgs/basic_msgs/geometry.proto";
+import "modules/common_msgs/basic_msgs/vehicle_id.proto";
+
+message Transform {
+  optional bytes source_frame = 1;  // Also known as "frame_id."
+
+  optional bytes target_frame = 2;  // Also known as "child_frame_id."
+
+  // Position of target in the source frame.
+  optional Point3D translation = 3;
+
+  // Activate rotation from the source frame to the target frame.
+  optional Quaternion rotation = 4;
+}
+
+message Extrinsics {
+  repeated Transform tansforms = 1;
+}
+
+// Vehicle parameters shared among several modules.
+// By default, all are measured with the SI units (meters, meters per second,
+// etc.).
+
+enum VehicleBrand {
+  LINCOLN_MKZ = 0;
+  GEM = 1;
+  LEXUS = 2;
+  TRANSIT = 3;
+  GE3 = 4;
+  WEY = 5;
+  ZHONGYUN = 6;
+  CH = 7;
+  DKIT = 8;
+  NEOLIX = 9;
+}
+
+message LatencyParam {
+  // latency parameters, in second (s)
+  optional double dead_time = 1;
+  optional double rise_time = 2;
+  optional double peak_time = 3;
+  optional double settling_time = 4;
+}
+
+message VehicleParam {
+  optional VehicleBrand brand = 1;
+  // Car center point is car reference point, i.e., center of rear axle.
+  optional VehicleID vehicle_id = 2;
+  optional double front_edge_to_center = 3 [default = nan];
+  optional double back_edge_to_center = 4 [default = nan];
+  optional double left_edge_to_center = 5 [default = nan];
+  optional double right_edge_to_center = 6 [default = nan];
+
+  optional double length = 7 [default = nan];
+  optional double width = 8 [default = nan];
+  optional double height = 9 [default = nan];
+
+  optional double min_turn_radius = 10 [default = nan];
+  optional double max_acceleration = 11 [default = nan];
+  optional double max_deceleration = 12 [default = nan];
+
+  // The following items are used to compute trajectory constraints in
+  // planning/control/canbus,
+  // vehicle max steer angle
+  optional double max_steer_angle = 13 [default = nan];
+  // vehicle max steer rate; how fast can the steering wheel turn.
+  optional double max_steer_angle_rate = 14 [default = nan];
+  // vehicle min steer rate;
+  optional double min_steer_angle_rate = 15 [default = nan];
+  // ratio between the turn of steering wheel and the turn of wheels
+  optional double steer_ratio = 16 [default = nan];
+  // the distance between the front and back wheels
+  optional double wheel_base = 17 [default = nan];
+  // Tire effective rolling radius (vertical distance between the wheel center
+  // and the ground).
+  optional double wheel_rolling_radius = 18 [default = nan];
+
+  // minimum differentiable vehicle speed, in m/s
+  optional float max_abs_speed_when_stopped = 19 [default = nan];
+
+  // minimum value get from chassis.brake, in percentage
+  optional double brake_deadzone = 20 [default = nan];
+  // minimum value get from chassis.throttle, in percentage
+  optional double throttle_deadzone = 21 [default = nan];
+
+  // vehicle latency parameters
+  optional LatencyParam steering_latency_param = 22;
+  optional LatencyParam throttle_latency_param = 23;
+  optional LatencyParam brake_latency_param = 24;
+}
+
+message VehicleConfig {
+  optional apollo.common.Header header = 1;
+  optional VehicleParam vehicle_param = 2;
+  optional Extrinsics extrinsics = 3;
+}

+ 38 - 0
src/test/testhdmap/modules/common_msgs/control_msgs/BUILD

@@ -0,0 +1,38 @@
+## Auto generated by `proto_build_generator.py`
+load("//tools/proto:proto.bzl", "proto_library")
+load("//tools:apollo_package.bzl", "apollo_package")
+
+package(default_visibility = ["//visibility:public"])
+
+proto_library(
+    name = "control_cmd_proto",
+    srcs = ["control_cmd.proto"],
+    deps = [
+        ":input_debug_proto",
+        ":control_pad_msg_proto",
+        "//modules/common_msgs/basic_msgs:drive_state_proto",
+        "//modules/common_msgs/basic_msgs:header_proto",
+        "//modules/common_msgs/basic_msgs:pnc_point_proto",
+        "//modules/common_msgs/basic_msgs:vehicle_signal_proto",
+        "//modules/common_msgs/chassis_msgs:chassis_proto",
+        "@com_google_protobuf//:any_proto"
+    ],
+)
+
+proto_library(
+    name = "control_pad_msg_proto",
+    srcs = ["pad_msg.proto"],
+    deps = [
+        "//modules/common_msgs/basic_msgs:header_proto",
+    ],
+)
+
+proto_library(
+    name = "input_debug_proto",
+    srcs = ["input_debug.proto"],
+    deps = [
+        "//modules/common_msgs/basic_msgs:header_proto",
+    ],
+)
+
+apollo_package()

+ 278 - 0
src/test/testhdmap/modules/common_msgs/control_msgs/control_cmd.proto

@@ -0,0 +1,278 @@
+syntax = "proto2";
+package apollo.control;
+
+import "google/protobuf/any.proto";
+import "modules/common_msgs/basic_msgs/drive_state.proto";
+import "modules/common_msgs/basic_msgs/header.proto";
+import "modules/common_msgs/basic_msgs/pnc_point.proto";
+import "modules/common_msgs/basic_msgs/vehicle_signal.proto";
+import "modules/common_msgs/chassis_msgs/chassis.proto";
+import "modules/common_msgs/control_msgs/input_debug.proto";
+import "modules/common_msgs/control_msgs/pad_msg.proto";
+
+enum TurnSignal {
+  TURN_NONE = 0;
+  TURN_LEFT = 1;
+  TURN_RIGHT = 2;
+}
+
+message LatencyStats {
+  optional double total_time_ms = 1;
+  repeated double controller_time_ms = 2;
+  optional bool total_time_exceeded = 3;
+}
+
+// next id : 27
+message ControlCommand {
+  optional apollo.common.Header header = 1;
+  // target throttle in percentage [0, 100]
+  optional double throttle = 3;
+
+  // target brake in percentage [0, 100]
+  optional double brake = 4;
+
+  // target non-directional steering rate, in percentage of full scale per
+  // second [0, 100]
+  optional double steering_rate = 6;
+
+  // target steering angle, in percentage of full scale [-100, 100]
+  optional double steering_target = 7;
+
+  // parking brake engage. true: engaged
+  optional bool parking_brake = 8;
+
+  // target speed, in m/s
+  optional double speed = 9;
+
+  // target acceleration in m`s^-2
+  optional double acceleration = 10;
+
+  // model reset
+  optional bool reset_model = 16 [deprecated = true];
+  // engine on/off, true: engine on
+  optional bool engine_on_off = 17;
+  // completion percentage of trajectory planned in last cycle
+  optional double trajectory_fraction = 18;
+  optional apollo.canbus.Chassis.DrivingMode driving_mode = 19
+      [deprecated = true];
+  optional apollo.canbus.Chassis.GearPosition gear_location = 20;
+
+  optional Debug debug = 22;
+  optional apollo.common.VehicleSignal signal = 23;
+  optional LatencyStats latency_stats = 24;
+  optional PadMessage pad_msg = 25;
+  optional apollo.common.EngageAdvice engage_advice = 26;
+  optional bool is_in_safe_mode = 27 [default = false];
+
+  // deprecated fields
+  optional bool left_turn = 13 [deprecated = true];
+  optional bool right_turn = 14 [deprecated = true];
+  optional bool high_beam = 11 [deprecated = true];
+  optional bool low_beam = 12 [deprecated = true];
+  optional bool horn = 15 [deprecated = true];
+  optional TurnSignal turnsignal = 21 [deprecated = true];
+}
+
+message SimpleLongitudinalDebug {
+  optional double station_reference = 1;
+  optional double station_error = 2;
+  optional double station_error_limited = 3;
+  optional double preview_station_error = 4;
+  optional double speed_reference = 5;
+  optional double speed_error = 6;
+  optional double speed_controller_input_limited = 7;
+  optional double preview_speed_reference = 8;
+  optional double preview_speed_error = 9;
+  optional double preview_acceleration_reference = 10;
+  optional double acceleration_cmd_closeloop = 11;
+  optional double acceleration_cmd = 12;
+  optional double acceleration_lookup = 13;
+  optional double speed_lookup = 14;
+  optional double calibration_value = 15;
+  optional double throttle_cmd = 16;
+  optional double brake_cmd = 17;
+  optional bool is_full_stop = 18;
+  optional double slope_offset_compensation = 19;
+  optional double current_station = 20;
+  optional double path_remain = 21;
+  optional int32 pid_saturation_status = 22;
+  optional int32 leadlag_saturation_status = 23;
+  optional double speed_offset = 24;
+  optional double current_speed = 25;
+  optional double acceleration_reference = 26;
+  optional double current_acceleration = 27;
+  optional double acceleration_error = 28;
+  optional double jerk_reference = 29;
+  optional double current_jerk = 30;
+  optional double jerk_error = 31;
+  optional apollo.common.TrajectoryPoint current_matched_point = 32;
+  optional apollo.common.TrajectoryPoint current_reference_point = 33;
+  optional apollo.common.TrajectoryPoint preview_reference_point = 34;
+  optional double acceleration_lookup_limit = 35;
+  optional double vehicle_pitch = 36;
+  optional bool is_epb_brake = 37;
+  optional double current_steer_interval = 38;
+  optional bool is_wait_steer = 39;
+  optional bool is_stop_reason_by_destination = 40;
+  optional bool is_stop_reason_by_prdestrian = 41;
+  optional bool is_full_stop_soft = 42;
+}
+
+message SimpleLateralDebug {
+  optional double lateral_error = 1;
+  optional double ref_heading = 2;
+  optional double heading = 3;
+  optional double heading_error = 4;
+  optional double heading_error_rate = 5;
+  optional double lateral_error_rate = 6;
+  optional double curvature = 7;
+  optional double steer_angle = 8;
+  optional double steer_angle_feedforward = 9;
+  optional double steer_angle_lateral_contribution = 10;
+  optional double steer_angle_lateral_rate_contribution = 11;
+  optional double steer_angle_heading_contribution = 12;
+  optional double steer_angle_heading_rate_contribution = 13;
+  optional double steer_angle_feedback = 14;
+  optional double steering_position = 15;
+  optional double ref_speed = 16;
+  optional double steer_angle_limited = 17;
+
+  // time derivative of lateral error rate, in m/s^2
+  optional double lateral_acceleration = 18;
+  // second time derivative of lateral error rate, in m/s^3
+  optional double lateral_jerk = 19;
+
+  optional double ref_heading_rate = 20;
+  optional double heading_rate = 21;
+
+  // heading_acceleration, as known as yaw acceleration, is the time derivative
+  // of heading rate,  in rad/s^2
+  optional double ref_heading_acceleration = 22;
+  optional double heading_acceleration = 23;
+  optional double heading_error_acceleration = 24;
+
+  // heading_jerk, as known as yaw jerk, is the second time derivative of
+  // heading rate, in rad/s^3
+  optional double ref_heading_jerk = 25;
+  optional double heading_jerk = 26;
+  optional double heading_error_jerk = 27;
+
+  // modified lateral_error and heading_error with look-ahead or look-back
+  // station, as the feedback term for control usage
+  optional double lateral_error_feedback = 28;
+  optional double heading_error_feedback = 29;
+
+  // current planning target point
+  optional apollo.common.TrajectoryPoint current_target_point = 30;
+
+  // Augmented feedback control term in addition to LQR control
+  optional double steer_angle_feedback_augment = 31;
+
+  // Mrac control status and feedback states for steer control
+  optional MracDebug steer_mrac_debug = 32;
+  optional bool steer_mrac_enable_status = 33;
+}
+
+message SimpleMPCDebug {
+  optional double lateral_error = 1;
+  optional double ref_heading = 2;
+  optional double heading = 3;
+  optional double heading_error = 4;
+  optional double heading_error_rate = 5;
+  optional double lateral_error_rate = 6;
+  optional double curvature = 7;
+  optional double steer_angle = 8;
+  optional double steer_angle_feedforward = 9;
+  optional double steer_angle_lateral_contribution = 10;
+  optional double steer_angle_lateral_rate_contribution = 11;
+  optional double steer_angle_heading_contribution = 12;
+  optional double steer_angle_heading_rate_contribution = 13;
+  optional double steer_angle_feedback = 14;
+  optional double steering_position = 15;
+  optional double ref_speed = 16;
+  optional double steer_angle_limited = 17;
+  optional double station_reference = 18;
+  optional double station_error = 19;
+  optional double speed_reference = 20;
+  optional double speed_error = 21;
+  optional double acceleration_reference = 22;
+  optional bool is_full_stop = 23;
+  optional double station_feedback = 24;
+  optional double speed_feedback = 25;
+  optional double acceleration_cmd_closeloop = 26;
+  optional double acceleration_cmd = 27;
+  optional double acceleration_lookup = 28;
+  optional double speed_lookup = 29;
+  optional double calibration_value = 30;
+  optional double steer_unconstrained_control_diff = 31;
+  optional double steer_angle_feedforward_compensation = 32;
+  repeated double matrix_q_updated = 33;  // matrix_q_updated_ size = 6
+  repeated double matrix_r_updated = 34;  // matrix_r_updated_ size = 2
+
+  // time derivative of lateral error rate, in m/s^2
+  optional double lateral_acceleration = 35;
+  // second time derivative of lateral error rate, in m/s^3
+  optional double lateral_jerk = 36;
+
+  optional double ref_heading_rate = 37;
+  optional double heading_rate = 38;
+
+  // heading_acceleration, as known as yaw acceleration, is the time derivative
+  // of heading rate,  in rad/s^2
+  optional double ref_heading_acceleration = 39;
+  optional double heading_acceleration = 40;
+  optional double heading_error_acceleration = 41;
+
+  // heading_jerk, as known as yaw jerk, is the second time derivative of
+  // heading rate, in rad/s^3
+  optional double ref_heading_jerk = 42;
+  optional double heading_jerk = 43;
+  optional double heading_error_jerk = 44;
+
+  optional double acceleration_feedback = 45;
+  optional double acceleration_error = 46;
+  optional double jerk_reference = 47;
+  optional double jerk_feedback = 48;
+  optional double jerk_error = 49;
+
+  // modified lateral_error and heading_error with look-ahead or look-back
+  // station, as the feedback term for control usage
+  optional double lateral_error_feedback = 50;
+  optional double heading_error_feedback = 51;
+  // Augmented feedback control term in addition to MPC control
+  optional double steer_angle_feedback_augment = 52;
+  optional apollo.common.TrajectoryPoint current_matched_point = 53;
+  optional apollo.common.TrajectoryPoint current_reference_point = 54;
+  optional apollo.common.TrajectoryPoint preview_reference_point = 55;
+  optional double preview_station_error = 56;
+  optional double preview_speed_reference = 57;
+  optional double preview_speed_error = 58;
+  optional double preview_acceleration_reference = 59;
+  optional double vehicle_pitch = 60;
+  optional double slope_offset_compensation = 61;
+  optional double path_remain = 62;
+  optional double acceleration_lookup_offset = 63;
+  optional double acceleration_vrf = 64;
+}
+
+message MracDebug {
+  optional int32 mrac_model_order = 1;
+  repeated double mrac_reference_state = 2;
+  repeated double mrac_state_error = 3;
+  optional MracAdaptiveGain mrac_adaptive_gain = 4;
+  optional int32 mrac_reference_saturation_status = 5;
+  optional int32 mrac_control_saturation_status = 6;
+}
+
+message MracAdaptiveGain {
+  repeated double state_adaptive_gain = 1;
+  repeated double input_adaptive_gain = 2;
+  repeated double nonlinear_adaptive_gain = 3;
+}
+
+message Debug {
+  optional SimpleLongitudinalDebug simple_lon_debug = 1;
+  optional SimpleLateralDebug simple_lat_debug = 2;
+  optional InputDebug input_debug = 3;
+  optional SimpleMPCDebug simple_mpc_debug = 4;
+}

+ 11 - 0
src/test/testhdmap/modules/common_msgs/control_msgs/input_debug.proto

@@ -0,0 +1,11 @@
+syntax = "proto2";
+package apollo.control;
+
+import "modules/common_msgs/basic_msgs/header.proto";
+
+message InputDebug {
+  optional apollo.common.Header localization_header = 1;
+  optional apollo.common.Header canbus_header = 2;
+  optional apollo.common.Header trajectory_header = 3;
+  optional apollo.common.Header latest_replan_trajectory_header = 4;
+}

+ 18 - 0
src/test/testhdmap/modules/common_msgs/control_msgs/pad_msg.proto

@@ -0,0 +1,18 @@
+syntax = "proto2";
+package apollo.control;
+
+import "modules/common_msgs/basic_msgs/header.proto";
+
+enum DrivingAction {
+  START = 1;
+  RESET = 2;
+  VIN_REQ = 3;
+};
+
+message PadMessage {
+  // control mode, set mode according to low level definition
+  optional apollo.common.Header header = 1;
+
+  // action in the driving_mode
+  optional DrivingAction action = 2;
+}

+ 27 - 0
src/test/testhdmap/modules/common_msgs/cyberfile.xml

@@ -0,0 +1,27 @@
+<package format="2">
+  <name>common-msgs</name>
+  <version>local</version>
+  <description>
+    This module contains code that is not specific to any module but is useful for the functioning of Apollo.
+  </description>
+
+  <maintainer email="apollo-support@baidu.com">Apollo</maintainer>
+  <license>Apache License 2.0</license>
+  <url type="website">https://www.apollo.auto/</url>
+  <url type="repository">https://github.com/ApolloAuto/apollo</url>
+  <url type="bugtracker">https://github.com/ApolloAuto/apollo/issues</url>
+
+  <type>module</type>
+  <src_path url="https://github.com/ApolloAuto/apollo">//modules/common_msgs</src_path>
+
+  <depend expose="False">3rd-rules-python</depend>
+  <depend expose="False">3rd-grpc</depend>
+  <depend expose="False">3rd-gpus</depend>
+  <depend expose="False">3rd-rules-proto</depend>
+  <depend expose="False">3rd-py</depend>
+  <depend>bazel-extend-tools</depend>
+  <depend expose="False">3rd-bazel-skylib</depend>
+
+  <depend lib_names="protobuf" repo_name="com_google_protobuf">3rd-protobuf</depend>
+
+</package>

+ 53 - 0
src/test/testhdmap/modules/common_msgs/dreamview_msgs/BUILD

@@ -0,0 +1,53 @@
+## Auto generated by `proto_build_generator.py`
+load("//tools/proto:proto.bzl", "proto_library")
+load("//tools:apollo_package.bzl", "apollo_package")
+
+package(default_visibility = ["//visibility:public"])
+
+proto_library(
+    name = "chart_proto",
+    srcs = ["chart.proto"],
+    deps = [
+        "//modules/common_msgs/basic_msgs:geometry_proto",
+    ],
+)
+
+proto_library(
+    name = "hmi_status_proto",
+    srcs = ["hmi_status.proto"],
+    deps = [
+        "//modules/common_msgs/basic_msgs:geometry_proto",
+        "//modules/common_msgs/basic_msgs:header_proto",
+        "//modules/common_msgs/monitor_msgs:system_status_proto",
+    ],
+)
+
+proto_library(
+    name = "hmi_mode_proto",
+    srcs = ["hmi_mode.proto"],
+    deps = [
+        "//modules/common_msgs/dreamview_msgs:hmi_status_proto"
+    ],
+)
+
+proto_library(
+    name = "hmi_config_proto",
+    srcs = ["hmi_config.proto"],
+)
+
+proto_library(
+    name = "simulation_world_proto",
+    srcs = ["simulation_world.proto"],
+    deps = [
+        "//modules/common_msgs/chassis_msgs:chassis_proto",
+        "//modules/common_msgs/monitor_msgs:monitor_log_proto",
+        "//modules/common_msgs/basic_msgs:pnc_point_proto",
+        "//modules/common_msgs/perception_msgs:perception_obstacle_proto",
+        "//modules/common_msgs/planning_msgs:planning_internal_proto",
+        "//modules/common_msgs/prediction_msgs:feature_proto",
+        "//modules/common_msgs/routing_msgs:routing_geometry_proto",
+        "//modules/common_msgs/config_msgs:vehicle_config_proto",
+    ],
+)
+
+apollo_package()

+ 76 - 0
src/test/testhdmap/modules/common_msgs/dreamview_msgs/chart.proto

@@ -0,0 +1,76 @@
+syntax = "proto2";
+
+package apollo.dreamview;
+
+import "modules/common_msgs/basic_msgs/geometry.proto";
+
+message Options {
+  message Axis {
+    optional double min = 1;
+    optional double max = 2;
+    optional string label_string = 3;
+
+    // size of the axis of your graph which is then divided into measuring
+    // grades
+    optional double window_size = 4;
+    // size of the smaller measuring grades in the axis found between two larger
+    // measuring grades
+    optional double step_size = 5;
+    // midpoint taken within the dataset. If it is not specified, we will
+    // calculate it for you.
+    optional double mid_value = 6;
+  }
+
+  optional bool legend_display = 1 [default = true];
+  optional Axis x = 2;
+  optional Axis y = 3;
+
+  // This is the aspect ratio (width/height) of the entire chart.
+  optional double aspect_ratio = 4;
+
+  // Same window size for x-Axis and y-Axis. It is
+  // effective only if x/y window_size is NOT set.
+  optional bool sync_xy_window_size = 5 [default = false];
+}
+
+message Line {
+  optional string label = 1;
+  optional bool hide_label_in_legend = 2 [default = false];
+  repeated apollo.common.Point2D point = 3;
+
+  // If the 'color' property is undefined, a random one will be assigned.
+  // See http://www.chartjs.org/docs/latest/charts/line.html
+  // for all supported properties from chart.js
+  map<string, string> properties = 4;
+}
+
+message Polygon {
+  optional string label = 1;
+  optional bool hide_label_in_legend = 2 [default = false];
+  repeated apollo.common.Point2D point = 3;
+
+  // If the 'color' property is undefined, a random one will be assigned.
+  // See http://www.chartjs.org/docs/latest/charts/line.html
+  // for all supported properties from chart.js
+  map<string, string> properties = 4;
+}
+
+message Car {
+  optional string label = 1;
+  optional bool hide_label_in_legend = 2 [default = false];
+
+  optional double x = 3;
+  optional double y = 4;
+  optional double heading = 5;
+  optional string color = 6;
+}
+
+message Chart {
+  optional string title = 1;
+  optional Options options = 2;
+
+  // data sets
+  repeated Line line = 3;
+  repeated Polygon polygon = 4;
+  repeated Car car = 5;
+}

+ 56 - 0
src/test/testhdmap/modules/common_msgs/dreamview_msgs/hmi_config.proto

@@ -0,0 +1,56 @@
+syntax = "proto2";
+
+package apollo.dreamview;
+
+enum HMIAction {
+  // Simple HMI action without any parameter.
+  NONE = 0;
+  SETUP_MODE = 1;       // Setup current mode.
+  RESET_MODE = 2;       // Reset current mode.
+  ENTER_AUTO_MODE = 3;  // Enter into auto driving mode.
+  DISENGAGE = 4;        // Disengage from auto driving mode.
+
+  // HMI action with a value string parameter.
+  CHANGE_MODE = 5;     // value = mode_name
+  CHANGE_MAP = 6;      // value = map_name
+  CHANGE_VEHICLE = 7;  // value = vehicle_name
+  START_MODULE = 8;    // value = module_name
+  STOP_MODULE = 9;     // value = module_name
+  CHANGE_SCENARIO = 10;     // value = scenario_id
+  CHANGE_SCENARIO_SET = 11;      // value = scenario_set_id
+  LOAD_SCENARIOS = 12; // 加载全部scenarios
+  DELETE_SCENARIO_SET = 13; // value = scenario_set_id
+  LOAD_DYNAMIC_MODELS = 14; // 加载全部动力学模型
+  CHANGE_DYNAMIC_MODEL = 15; // 切换动力学模型 value = dynamic_model_name
+  DELETE_DYNAMIC_MODEL = 16; // 删除动力学模型 value = dynamic_model_name
+  CHANGE_RECORD = 17; //value = record_id
+  DELETE_RECORD = 18; //value = record_id
+  LOAD_RECORDS = 19;     // Load all records
+  STOP_RECORD = 20; //value = module_name
+  CHANGE_OPERATION = 21; //value = operation_name
+  DELETE_VEHICLE_CONF = 22; // Delete the parameters of a vehicle.
+  DELETE_V2X_CONF = 23; // Delete the parameters of a v2x.
+  DELETE_MAP = 24; // Delete map that value = map_name
+  LOAD_RTK_RECORDS = 25; // Load all rtk records
+  CHANGE_RTK_RECORD = 26; // change rtk records
+  LOAD_RECORD = 27;     // Load record
+}
+
+message HMIConfig {
+  map<string, string> modes = 1;     // {mode_name: mode_path}
+  map<string, string> maps = 2;      // {map_name: map_path}
+  map<string, string> vehicles = 3;  // {vehicle_name: vehicle_path}
+}
+
+message VehicleData {
+  // Upon switching vehicle, we need to copy source data to the dest path to
+  // make it in effect.
+  message DataFile {
+    // Source path is a path relative to the vehicle data directory.
+    optional string source_path = 1;
+    // Dest path is where the data file could become in effect.
+    optional string dest_path = 2;
+  }
+  repeated DataFile data_files = 1;
+}
+

+ 130 - 0
src/test/testhdmap/modules/common_msgs/dreamview_msgs/hmi_mode.proto

@@ -0,0 +1,130 @@
+syntax = "proto2";
+
+package apollo.dreamview;
+
+// This proto defines a mode showing in Dreamview, including how you will
+// display them and monitor their status.
+
+import "modules/common_msgs/dreamview_msgs/hmi_status.proto";
+
+// For ProcessMonitor.
+message ProcessMonitorConfig {
+  repeated string command_keywords = 1;
+}
+
+// For ModuleMonitor
+message ModuleMonitorConfig {
+  repeated string node_name = 1;
+}
+
+// For ChannelMonitor.
+message ChannelMonitorConfig {
+  optional string name = 1;
+  optional double delay_fatal = 2 [default = 3.0];  // In seconds.
+
+  // The fields will be checked to make sure they are existing
+  // Specify in the format of "a.b.c"
+  repeated string mandatory_fields = 3;
+
+  // Minimum and maximum frequency allowed for this channel
+  optional double min_frequency_allowed = 4 [default = 0.0];
+  optional double max_frequency_allowed = 5 [default = 1000.0];
+}
+
+// For ResourceMonitor.
+message ResourceMonitorConfig {
+  message DiskSpace {
+    // Path to monitor space. Support wildcards like ? and *.
+    // If the path does't exist, raise UNKNWON which will be ignored.
+    optional string path = 1;
+    optional int32 insufficient_space_warning = 2;  // In GB.
+    optional int32 insufficient_space_error = 3;
+  }
+
+  message CPUUsage {
+    optional float high_cpu_usage_warning = 1;
+    optional float high_cpu_usage_error = 2;
+    // The process's dag path, if not set it will check the system's overall CPU
+    // usage
+    optional string process_dag_path = 3;
+  }
+
+  message MemoryUsage {
+    optional int32 high_memory_usage_warning = 1;
+    optional int32 high_memory_usage_error = 2;
+    // The process's dag path, if not set it will check the system's overall
+    // memory usage
+    optional string process_dag_path = 3;
+  }
+
+  message DiskLoad {
+    optional int32 high_disk_load_warning = 1;
+    optional int32 high_disk_load_error = 2;
+    // Disk device name, such as sda, sdb and etc
+    optional string device_name = 3;
+  }
+
+  repeated DiskSpace disk_spaces = 1;
+  repeated CPUUsage cpu_usages = 2;
+  repeated MemoryUsage memory_usages = 3;
+  repeated DiskLoad disk_load_usages = 4;
+}
+
+// A monitored component will be listed on HMI which only shows its status but
+// user cannot operate.
+// The whole config will generate SystemStatus.components[i].summary by Monitor
+// module, which is generally the most severe one of process, channel or
+// resource status.
+message MonitoredComponent {
+  // Generate SystemStatus.components[i].process_status.
+  // OK if the process is running.
+  // FATAL if the process is down.
+  optional ProcessMonitorConfig process = 1;
+
+  // Generate SystemStatus.components[i].channel_status.
+  // OK if delay is not notable.
+  // FATAL if delay is larger than fatal_delay.
+  optional ChannelMonitorConfig channel = 2;
+
+  // Generate SystemStatus.components[i].resource_status.
+  // OK if all requirements are met.
+  // WARN/ERROR/FATAL if any requirement is below expectation.
+  optional ResourceMonitorConfig resource = 3;
+
+  // Whether to trigger safe-mode if the component is down.
+  optional bool required_for_safety = 4 [default = true];
+
+  // Generate SystemStatus.components[i].module_status.
+  // OK if the module is running.
+  // FATAL if the module is down.
+  optional ModuleMonitorConfig module = 5;
+}
+
+// A module which can be started and stopped by HMI.
+message Module {
+  optional string start_command = 1;
+  optional string stop_command = 2;
+
+  // We use the config in ProcessMonitor to check if the module is running.
+  optional ProcessMonitorConfig process_monitor_config = 3;
+  // Whether to trigger safe-mode if the module is down.
+  optional bool required_for_safety = 4 [default = true];
+}
+
+// A CyberModule will be translated to a regular Module upon loading.
+message CyberModule {
+  repeated string dag_files = 1;
+  optional bool required_for_safety = 2 [default = true];
+  optional string process_group = 3;
+}
+
+message HMIMode {
+  map<string, CyberModule> cyber_modules = 1;
+  map<string, Module> modules = 2;
+  map<string, MonitoredComponent> monitored_components = 3;
+  map<string, ProcessMonitorConfig> other_components = 4;
+  repeated HMIModeOperation operations = 5;
+  optional HMIModeOperation default_operation = 6;
+  optional string layout = 7;
+  map<string, MonitoredComponent> global_components = 8;
+}

+ 129 - 0
src/test/testhdmap/modules/common_msgs/dreamview_msgs/hmi_status.proto

@@ -0,0 +1,129 @@
+syntax = "proto2";
+
+package apollo.dreamview;
+
+import "modules/common_msgs/basic_msgs/header.proto";
+import "modules/common_msgs/monitor_msgs/system_status.proto";
+import "modules/common_msgs/basic_msgs/geometry.proto";
+
+
+message ScenarioInfo {
+  optional string scenario_id = 1;
+  optional string scenario_name = 2;
+  optional string map_name = 3;
+  optional apollo.common.Point2D start_point = 4;
+  optional apollo.common.Point2D end_point = 5;
+}
+
+message ScenarioSet {
+  // id is key
+  optional string scenario_set_name = 1;
+  repeated ScenarioInfo scenarios = 2;
+}
+
+enum PlayRecordStatus{
+  // action:play continue
+  RUNNING = 0;
+  // action: pause
+  PAUSED = 1;
+  // action: default kill
+  CLOSED = 2;
+}
+
+message RecordStatus{
+  optional string current_record_id = 1 [default = ""];
+  optional PlayRecordStatus play_record_status = 2 [default = CLOSED];
+  optional double curr_time_s = 4 [default = 0];
+}
+
+enum HMIModeOperation {
+  // None
+  None = 0;
+  // 仿真调试
+  SIM_DEBUG = 1;
+  // 自由仿真
+  Sim_Control = 2;
+  // 实车自动驾驶
+  Auto_Drive=3;
+  // 循迹
+  TRACE=4;
+  // 场景仿真
+  Scenario_Sim = 5;
+  // 播包
+  Record = 6;
+  // 循迹
+  Waypoint_Follow=7;
+}
+
+enum LoadRecordStatus {
+  NOT_LOAD = 1;
+  LOADING = 2;
+  LOADED = 3;
+}
+
+message LoadRecordInfo{
+  optional LoadRecordStatus load_record_status = 1 [default = NOT_LOAD];
+  optional double total_time_s = 2 [default = 0];
+  optional string record_file_path = 3 [default = ""];
+  // Compatible with dv download scenario use plugin,only dv use it.
+  optional int32 download_status = 4 [default = 0];
+}
+
+message HMIStatus {
+  optional apollo.common.Header header = 1;
+
+  repeated string modes = 2;
+  optional string current_mode = 3;
+
+  repeated string maps = 4;
+  optional string current_map = 5;
+
+  repeated string vehicles = 6;
+  optional string current_vehicle = 7;
+
+  // {module_name: is_running_or_not}
+  map<string, bool> modules = 8;
+  // {component_name: status}
+  map<string, apollo.monitor.ComponentStatus> monitored_components = 9;
+
+  optional string docker_image = 10;
+  optional int32 utm_zone_id = 11;  // FLAGS_local_utm_zone_id
+
+  // Message which will be read aloud to drivers and passengers through
+  // Dreamview.
+  optional string passenger_msg = 12;
+  // {component_name: status}
+  map<string, apollo.monitor.ComponentStatus> other_components = 13;
+  map<string, ScenarioSet> scenario_set = 15;
+  optional string current_scenario_set_id = 16 [default = ""];
+  optional string current_scenario_id = 17 [default = ""];
+  repeated string dynamic_models = 18;
+  optional string current_dynamic_model = 19;
+  // for dreamview(1.0 version)
+  optional string current_record_id = 20 [default = ""];
+  // for dv1.0: map value no used,is also equals to empty object
+  // for dv2.0: map value equals to loadrecordinfo object which includes
+  // record total time(s),load record status and record file path
+  map<string, LoadRecordInfo> records = 21;
+  optional sint32 current_vehicle_type = 22;
+  optional string current_camera_sensor_channel = 23;
+  optional string current_point_cloud_channel = 24;
+
+  // dv2.0: add operation concept
+  // operations is related to hmiMode
+  repeated HMIModeOperation operations = 25;
+  optional HMIModeOperation current_operation = 26;
+  optional string current_layout = 27;
+  optional RecordStatus current_record_status = 28;
+  // Mark global component status.
+  map<string, apollo.monitor.Component> global_components = 29;
+  // Mark the expected number of modules to be opened
+  optional uint32 expected_modules = 30 [default = 0];
+
+  // {module_name: Used to identify whether the user clicks on the module}
+  map<string, bool> modules_lock = 31;
+  // Used to identify whether the backend triggers automatic shutdown.
+  optional bool backend_shutdown = 32 [default = false];
+  repeated string rtk_records = 33;
+  optional string current_rtk_record_id = 34 [default = ""];
+}

+ 303 - 0
src/test/testhdmap/modules/common_msgs/dreamview_msgs/simulation_world.proto

@@ -0,0 +1,303 @@
+syntax = "proto2";
+
+package apollo.dreamview;
+
+import "modules/common_msgs/chassis_msgs/chassis.proto";
+import "modules/common_msgs/monitor_msgs/monitor_log.proto";
+import "modules/common_msgs/basic_msgs/pnc_point.proto";
+import "modules/common_msgs/perception_msgs/perception_obstacle.proto";
+import "modules/common_msgs/planning_msgs/planning_internal.proto";
+import "modules/common_msgs/prediction_msgs/feature.proto";
+import "modules/common_msgs/routing_msgs/geometry.proto";
+import "modules/common_msgs/config_msgs/vehicle_config.proto";
+
+// Next-id: 4
+message PolygonPoint {
+  optional double x = 1;
+  optional double y = 2;
+  optional double z = 3 [default = 0.0];
+
+  // Gaussian probability information
+  optional apollo.common.GaussianInfo gaussian_info = 4;
+}
+
+// Next-id: 3
+message Prediction {
+  optional double probability = 1;
+  repeated PolygonPoint predicted_trajectory = 2;
+}
+
+// Next-id: 13
+message Decision {
+  enum Type {
+    IGNORE = 0;    // Ignore the object
+    STOP = 1;      // Stop at a distance from the object
+    NUDGE = 2;     // Go around the object
+    YIELD = 3;     // Go after the object
+    OVERTAKE = 4;  // Go before the object
+    FOLLOW = 5;    // Follow the object in the same lane
+    SIDEPASS = 6;  // Pass the object in neighboring lane
+  }
+  optional Type type = 1 [default = IGNORE];
+
+  // Shape Info
+  // Can be used for corners of nudge region
+  repeated PolygonPoint polygon_point = 2;
+
+  // Position Info
+  // Can be used for stop fence
+  optional double heading = 3;
+  optional double latitude = 4;
+  optional double longitude = 5;
+  optional double position_x = 6;
+  optional double position_y = 7;
+  optional double length = 8 [default = 2.8];
+  optional double width = 9 [default = 1.4];
+  optional double height = 10 [default = 1.8];
+
+  enum StopReasonCode {
+    STOP_REASON_HEAD_VEHICLE = 1;
+    STOP_REASON_DESTINATION = 2;
+    STOP_REASON_PEDESTRIAN = 3;
+    STOP_REASON_OBSTACLE = 4;
+    STOP_REASON_SIGNAL = 100;
+    STOP_REASON_STOP_SIGN = 101;
+    STOP_REASON_YIELD_SIGN = 102;
+    STOP_REASON_CLEAR_ZONE = 103;
+    STOP_REASON_CROSSWALK = 104;
+    STOP_REASON_EMERGENCY = 105;
+    STOP_REASON_NOT_READY = 106;
+    STOP_REASON_PULL_OVER = 107;
+  }
+  optional StopReasonCode stopReason = 11;
+  optional apollo.routing.ChangeLaneType change_lane_type = 12;
+}
+
+// Next-id: 41
+message Object {
+  // ID
+  optional string id = 1;  // primary identifier for each object
+
+  // Shape Info
+  repeated PolygonPoint polygon_point = 2;  // corners of an object
+
+  // Position Info
+  optional double heading = 3;
+  optional double latitude = 4;
+  optional double longitude = 5;
+  optional double position_x = 6;
+  optional double position_y = 7;
+  optional double length = 8 [default = 2.8];
+  optional double width = 9 [default = 1.4];
+  optional double height = 10 [default = 1.8];
+
+  // Motion Info
+  // For objects with motion info such as ADC.
+  optional double speed = 11;               // in m/s, can be negative
+  optional double speed_acceleration = 12;  // in m/s^2
+  optional double speed_jerk = 13;
+  optional double spin = 14;
+  optional double spin_acceleration = 15;
+  optional double spin_jerk = 16;
+  optional double speed_heading = 17;
+  optional double kappa = 18;
+  optional double dkappa = 35;
+
+  // Signal Info
+  // For objects with signals set and current signal such as Traffic Light,
+  // Stop Sign, and Vehicle Signal.
+  repeated string signal_set = 19;
+  optional string current_signal = 20;
+
+  // Time Info
+  optional double timestamp_sec = 21;
+
+  // Decision Info
+  repeated Decision decision = 22;
+  optional bool yielded_obstacle = 32 [default = false];
+
+  // Chassis Info
+  // For ADC
+  optional double throttle_percentage = 23;
+  optional double brake_percentage = 24;
+  optional double steering_percentage = 25;
+  optional double steering_angle = 26;
+  optional double steering_ratio = 27;
+  optional int32 battery_percentage = 38;
+  optional apollo.canbus.Chassis.GearPosition gear_location = 39;
+  enum DisengageType {
+    DISENGAGE_NONE = 0;
+    DISENGAGE_UNKNOWN = 1;
+    DISENGAGE_MANUAL = 2;
+    DISENGAGE_EMERGENCY = 3;
+    DISENGAGE_AUTO_STEER_ONLY = 4;
+    DISENGAGE_AUTO_SPEED_ONLY = 5;
+    DISENGAGE_CHASSIS_ERROR = 6;
+  };
+
+  optional DisengageType disengage_type = 28;
+
+  enum Type {
+    UNKNOWN = 0;
+    UNKNOWN_MOVABLE = 1;
+    UNKNOWN_UNMOVABLE = 2;
+    PEDESTRIAN = 3;  // pedestrian, usually determined by moving behavior.
+    BICYCLE = 4;     // bike, motor bike.
+    VEHICLE = 5;     // passenger car or truck.
+    VIRTUAL = 6;     // virtual object created by decision module.
+    CIPV = 7;        // closest in-path vehicle determined by perception module.
+  };
+
+  optional Type type = 29;  // obstacle type
+  // obstacle sub-type
+  optional apollo.perception.PerceptionObstacle.SubType sub_type = 34;
+  repeated Prediction prediction = 30;
+
+  // perception confidence level. Range: [0,1]
+  optional double confidence = 31 [default = 1];
+  optional apollo.prediction.ObstaclePriority obstacle_priority = 33;
+  optional apollo.prediction.ObstacleInteractiveTag interactive_tag = 40;
+
+  // v2x for perception obstacle
+  optional apollo.perception.PerceptionObstacle.Source source = 36
+      [default = HOST_VEHICLE];  // source type
+  // v2x use case info
+  optional apollo.perception.V2XInformation v2x_info = 37;
+}
+
+message DelaysInMs {
+  optional double chassis = 1;
+  optional double localization = 3;
+  optional double perception_obstacle = 4;
+  optional double planning = 5;
+  optional double prediction = 7;
+  optional double traffic_light = 8;
+  optional double control = 9;
+}
+
+message RoutePath {
+  repeated PolygonPoint point = 1;
+}
+
+message Latency {
+  optional double timestamp_sec = 1;
+  optional double total_time_ms = 2;
+}
+
+message MapElementIds {
+  repeated string lane = 1;
+  repeated string crosswalk = 2;
+  repeated string junction = 3;
+  repeated string signal = 4;
+  repeated string stop_sign = 5;
+  repeated string yield = 6;
+  repeated string overlap = 7;
+  repeated string road = 8;
+  repeated string clear_area = 9;
+  repeated string parking_space = 10;
+  repeated string speed_bump = 11;
+  repeated string pnc_junction = 12;
+}
+
+message ControlData {
+  optional double timestamp_sec = 1;
+  optional double station_error = 2;
+  optional double lateral_error = 3;
+  optional double heading_error = 4;
+  optional apollo.common.TrajectoryPoint current_target_point = 5;
+}
+
+message Notification {
+  optional double timestamp_sec = 1;
+  optional apollo.common.monitor.MonitorMessageItem item = 2;
+}
+
+message SensorMeasurements {
+  repeated Object sensor_measurement = 1;
+}
+
+// Next-id: 31
+message SimulationWorld {
+  // Timestamp in milliseconds
+  optional double timestamp = 1;
+
+  // Sequence number
+  optional uint32 sequence_num = 2;
+
+  // Objects in the world and the associated predictions/decisions
+  repeated Object object = 3;
+
+  // Autonomous driving cars
+  optional Object auto_driving_car = 4;
+
+  // Planning signal
+  optional Object traffic_signal = 5;
+
+  // Routing paths
+  repeated RoutePath route_path = 6;
+  // Timestamp of latest routing
+  optional double routing_time = 7;
+
+  // Planned trajectory
+  repeated Object planning_trajectory = 8;
+
+  // Main decision
+  optional Object main_stop = 9 [deprecated = true];
+  optional Object main_decision = 10;
+
+  // Speed limit
+  optional double speed_limit = 11;
+
+  // Module delays
+  optional DelaysInMs delay = 12;
+
+  // Notification
+  optional apollo.common.monitor.MonitorMessage monitor = 13
+      [deprecated = true];
+  repeated Notification notification = 14;
+
+  // Engage advice from planning
+  optional string engage_advice = 15;
+
+  // Module latency
+  map<string, Latency> latency = 16;
+
+  optional MapElementIds map_element_ids = 17;
+  optional uint64 map_hash = 18;
+  optional double map_radius = 19;
+
+  // Planning data
+  optional apollo.planning_internal.PlanningData planning_data = 20;
+
+  // GPS
+  optional Object gps = 21;
+
+  // Lane Markers from perception
+  optional apollo.perception.LaneMarkers lane_marker = 22;
+
+  // Control data
+  optional ControlData control_data = 23;
+
+  // Relative Map
+  repeated apollo.common.Path navigation_path = 24;
+
+  // RSS info
+  optional bool is_rss_safe = 25 [default = true];
+
+  // Shadow localization
+  optional Object shadow_localization = 26;
+
+  // Perception detected signals
+  repeated Object perceived_signal = 27;
+
+  // A map from a story name to whether it is on
+  map<string, bool> stories = 28;
+
+  // A map from a sensor_id to a group of sensor_measurements
+  map<string, SensorMeasurements> sensor_measurements = 29;
+
+  optional bool is_siren_on = 30 [default = false];
+
+  // vehicle param
+  optional apollo.common.VehicleParam vehicle_param = 31;
+}

+ 12 - 0
src/test/testhdmap/modules/common_msgs/drivers_msgs/BUILD

@@ -0,0 +1,12 @@
+## Auto generated by `proto_build_generator.py`
+load("//tools/proto:proto.bzl", "proto_library")
+load("//tools:apollo_package.bzl", "apollo_package")
+
+package(default_visibility = ["//visibility:public"])
+
+proto_library(
+    name = "can_card_parameter_proto",
+    srcs = ["can_card_parameter.proto"],
+)
+
+apollo_package()

+ 55 - 0
src/test/testhdmap/modules/common_msgs/drivers_msgs/can_card_parameter.proto

@@ -0,0 +1,55 @@
+syntax = "proto2";
+
+package apollo.drivers.canbus;
+
+message CANCardParameter {
+  enum CANCardBrand {
+    FAKE_CAN = 0;
+    ESD_CAN = 1;
+    SOCKET_CAN_RAW = 2;
+    HERMES_CAN = 3;
+  }
+
+  enum CANCardType {
+    PCI_CARD = 0;
+    USB_CARD = 1;
+  }
+
+  enum CANChannelId {
+    CHANNEL_ID_ZERO = 0;
+    CHANNEL_ID_ONE = 1;
+    CHANNEL_ID_TWO = 2;
+    CHANNEL_ID_THREE = 3;
+    CHANNEL_ID_FOUR = 4;
+    CHANNEL_ID_FIVE = 5;
+    CHANNEL_ID_SIX = 6;
+    CHANNEL_ID_SEVEN = 7;
+  }
+
+  enum CANInterface {
+    NATIVE = 0;
+    VIRTUAL = 1;
+    SLCAN = 2;
+  }
+
+  enum HERMES_BAUDRATE {
+    BCAN_BAUDRATE_1M = 0;
+    BCAN_BAUDRATE_500K = 1;
+    BCAN_BAUDRATE_250K = 2;
+    BCAN_BAUDRATE_150K = 3;
+    BCAN_BAUDRATE_NUM = 4;
+  }
+
+  // CAN卡驱动类型配置 | 根据所用的CAN卡硬件型号或驱动类型配置
+  optional CANCardBrand brand = 1;
+  // CAN卡硬件接口类型配置 | 根据所用的CAN卡硬件接口类型或驱动类型配置
+  optional CANCardType type = 2;
+  // CAN卡端口号配置 | 根据所连接的CAN卡端口号配置
+  optional CANChannelId channel_id = 3;
+  // CAN卡软件接口配置 | 默认配置为NATIVE
+  optional CANInterface interface = 4;
+  // CAN卡端口数量配置 | 默认数量为4,最多支持8个,默认可不配置
+  optional uint32 num_ports = 5 [default = 4];
+  // HERMES CAN卡波特率配置 | 只针对选择HERMES CAN卡时设置波特率,默认不配置
+  optional HERMES_BAUDRATE hermes_baudrate = 6 [default = BCAN_BAUDRATE_500K];
+}

+ 89 - 0
src/test/testhdmap/modules/common_msgs/external_command_msgs/BUILD

@@ -0,0 +1,89 @@
+## Auto generated by `proto_build_generator.py`
+load("//tools/proto:proto.bzl", "proto_library")
+load("//tools:apollo_package.bzl", "apollo_package")
+
+package(default_visibility = ["//visibility:public"])
+
+proto_library(
+    name = "valet_parking_command_proto",
+    srcs = ["valet_parking_command.proto"],
+    deps = [
+        ":external_geometry_proto",
+        ":lane_segment_proto",
+        "//modules/common_msgs/basic_msgs:header_proto",
+    ],
+)
+
+proto_library(
+    name = "lane_follow_command_proto",
+    srcs = ["lane_follow_command.proto"],
+    deps = [
+        ":external_geometry_proto",
+        ":lane_segment_proto",
+        "//modules/common_msgs/basic_msgs:header_proto",
+    ],
+)
+
+proto_library(
+    name = "path_follow_command_proto",
+    srcs = ["path_follow_command.proto"],
+    deps = [
+        ":external_geometry_proto",
+        "//modules/common_msgs/basic_msgs:header_proto",
+    ],
+)
+
+proto_library(
+    name = "command_status_proto",
+    srcs = ["command_status.proto"],
+    deps = [
+        "//modules/common_msgs/basic_msgs:header_proto",
+    ],
+)
+
+proto_library(
+    name = "chassis_command_proto",
+    srcs = ["chassis_command.proto"],
+    deps = [
+        "@com_google_protobuf//:any_proto",
+        "//modules/common_msgs/basic_msgs:header_proto",
+        "//modules/common_msgs/basic_msgs:vehicle_signal_proto",
+    ],
+)
+
+proto_library(
+    name = "free_space_command_proto",
+    srcs = ["free_space_command.proto"],
+    deps = [
+        ":external_geometry_proto",
+        "//modules/common_msgs/basic_msgs:header_proto",
+    ],
+)
+
+proto_library(
+    name = "speed_command_proto",
+    srcs = ["speed_command.proto"],
+    deps = [
+        "//modules/common_msgs/basic_msgs:header_proto",
+    ],
+)
+
+proto_library(
+    name = "action_command_proto",
+    srcs = ["action_command.proto"],
+    deps = [
+        "//modules/common_msgs/basic_msgs:header_proto",
+    ],
+)
+
+proto_library(
+    name = "lane_segment_proto",
+    srcs = ["lane_segment.proto"],
+)
+
+proto_library(
+    name = "external_geometry_proto",
+    srcs = ["geometry.proto"],
+)
+
+apollo_package()

+ 36 - 0
src/test/testhdmap/modules/common_msgs/external_command_msgs/action_command.proto

@@ -0,0 +1,36 @@
+syntax = "proto2";
+
+package apollo.external_command;
+
+import "modules/common_msgs/basic_msgs/header.proto";
+
+enum ActionCommandType {
+  // Follow the current lane.
+  FOLLOW = 1;
+  // Change to the laft lane.
+  CHANGE_LEFT = 2;
+  // Change to the right lane.
+  CHANGE_RIGHT = 3;
+  // Pull over and stop driving.
+  PULL_OVER = 4;
+  // Stop driving smoothly in emergency case.
+  STOP = 5;
+  // Start driving after paused.
+  START = 6;
+  // Clear the input planning command to cancel planning.
+  CLEAR_PLANNING = 7;
+  // Switch to manual drive mode.
+  SWITCH_TO_MANUAL = 50;
+  // Switch to auto drive mode.
+  SWITCH_TO_AUTO = 51;
+  // Varify vin code of vehicle.
+  VIN_REQ = 52;
+}
+
+message ActionCommand {
+  optional apollo.common.Header header = 1;
+  // Unique identification for command.
+  optional int64 command_id = 2 [default = -1];
+  // The action command.
+  required ActionCommandType command = 3;
+}

+ 17 - 0
src/test/testhdmap/modules/common_msgs/external_command_msgs/chassis_command.proto

@@ -0,0 +1,17 @@
+syntax = "proto2";
+
+package apollo.external_command;
+
+import "google/protobuf/any.proto";
+import "modules/common_msgs/basic_msgs/header.proto";
+import "modules/common_msgs/basic_msgs/vehicle_signal.proto";
+
+message ChassisCommand {
+  optional apollo.common.Header header = 1;
+  // Unique identification for command.
+  optional int64 command_id = 2 [default = -1];
+  // The basic vehicle signals which can also be controlled by apollo system.
+  optional apollo.common.VehicleSignal basic_signal = 3;
+  // Custom chassis operation command defined by user for extensibility.
+  optional google.protobuf.Any custom_operation = 4;
+}

+ 32 - 0
src/test/testhdmap/modules/common_msgs/external_command_msgs/command_status.proto

@@ -0,0 +1,32 @@
+syntax = "proto2";
+
+package apollo.external_command;
+
+import "modules/common_msgs/basic_msgs/header.proto";
+
+enum CommandStatusType {
+  // Command is being executed without error.
+  RUNNING = 1;
+  // Command is finished.
+  FINISHED = 2;
+  // Command's execution has error.
+  ERROR = 3;
+  // Cannot get the status of command.
+  UNKNOWN = 4;
+}
+
+message CommandStatusRequest {
+  optional apollo.common.Header header = 1;
+  // Unique identification for command.
+  optional int64 command_id = 2 [default = -1];
+}
+
+message CommandStatus {
+  optional apollo.common.Header header = 1;
+  // Unique identification for command.
+  optional int64 command_id = 2 [default = -1];
+  // The status of command execution.
+  required CommandStatusType status = 3;
+  // The message for the status.
+  optional string message = 4;
+}

+ 24 - 0
src/test/testhdmap/modules/common_msgs/external_command_msgs/free_space_command.proto

@@ -0,0 +1,24 @@
+syntax = "proto2";
+
+package apollo.external_command;
+
+import "modules/common_msgs/basic_msgs/header.proto";
+import "modules/common_msgs/external_command_msgs/geometry.proto";
+
+message FreeSpaceCommand {
+  optional apollo.common.Header header = 1;
+  // Unique identification for command.
+  optional int64 command_id = 2 [default = -1];
+  // Pose of the parking spot.
+  required Pose parking_spot_pose = 3;
+  // Region where openspace trajectory will be searched. Junction containing
+  // "non_drivable_roi" should be contained by "drivable_roi"
+  // polygon points should be clockwise if outer polygon can drive. 
+  // otherwise polygon points should be counter-clockwise if inner polygon can drive
+  repeated RoiPolygon non_drivable_roi = 4;
+  required RoiPolygon drivable_roi = 5;
+  // Expected speed when executing this command. If "target_speed" > maximum
+  // speed of the vehicle, use maximum speed of the vehicle instead. If it is
+  // not given, the default target speed of system will be used.
+  optional double target_speed = 6;
+}

+ 26 - 0
src/test/testhdmap/modules/common_msgs/external_command_msgs/geometry.proto

@@ -0,0 +1,26 @@
+syntax = "proto2";
+
+package apollo.external_command;
+
+message Point {
+  // x coordinate.
+  required double x = 1;
+  // y coordinate.
+  required double y = 2;
+}
+
+message Pose {
+  // x coordinate.
+  required double x = 1;
+  // y coordinate.
+  required double y = 2;
+  // Rotation around z axis in Cartesian coordinate system.
+  optional double heading = 3;
+}
+
+// Region of interest in form of polygon.
+// If the points of polygon is in anticlockwise, ROI is drivable area; otherwise if
+// they are in clockwise, ROI is prohibited driving area.
+message RoiPolygon {
+  repeated Point point = 1;
+}

+ 27 - 0
src/test/testhdmap/modules/common_msgs/external_command_msgs/lane_follow_command.proto

@@ -0,0 +1,27 @@
+syntax = "proto2";
+
+package apollo.external_command;
+
+import "modules/common_msgs/basic_msgs/header.proto";
+import "modules/common_msgs/external_command_msgs/geometry.proto";
+import "modules/common_msgs/external_command_msgs/lane_segment.proto";
+
+message LaneFollowCommand {
+  optional apollo.common.Header header = 1;
+  // Unique identification for command.
+  optional int64 command_id = 2 [default = -1];
+  // If the start pose is set as the first point of "way_point".
+  optional bool is_start_pose_set = 3 [default = false];
+  // The points between "start_pose" and "end_pose".
+  repeated Pose way_point = 4;
+  // End pose of the lane follow command, must be given.
+  required Pose end_pose = 5;
+  // The lane segments which should not be passed by.
+  repeated LaneSegment blacklisted_lane = 6;
+  // The road which should not be passed by.
+  repeated string blacklisted_road = 7;
+  // Expected speed when executing this command. If "target_speed" > maximum
+  // speed of the vehicle, use maximum speed of the vehicle instead. If it is
+  // not given, the default target speed of system will be used.
+  optional double target_speed = 8;
+}

+ 13 - 0
src/test/testhdmap/modules/common_msgs/external_command_msgs/lane_segment.proto

@@ -0,0 +1,13 @@
+
+syntax = "proto2";
+
+package apollo.external_command;
+
+message LaneSegment {
+  // lane id which this LaneSegment belongs to.
+  optional string id = 1;
+  // Start s of this LaneSegment on the lane.
+  optional double start_s = 2;
+  // End s of this LaneSegment on the lane.
+  optional double end_s = 3;
+}

+ 43 - 0
src/test/testhdmap/modules/common_msgs/external_command_msgs/path_follow_command.proto

@@ -0,0 +1,43 @@
+syntax = "proto2";
+
+package apollo.external_command;
+
+import "modules/common_msgs/basic_msgs/header.proto";
+import "modules/common_msgs/external_command_msgs/geometry.proto";
+
+// PathBoundary with left and right boundary.
+message PathBoundary {
+  // Left boundary of the path, each boundary point mapped to the path point.
+  repeated Point left_boundary = 1;
+  // Right boundary of the path, each boundary point mapped to the path point.
+  repeated Point right_boundary = 2;
+}
+
+// Path boundary generated with the distance from center to left and right
+// boundary given.
+message BoundaryWithWidth {
+  // Distance from the path center to left boundary.
+  required double left_path_width = 1;
+  // Distance from the path center to right boundary.
+  required double right_path_width = 2;
+}
+
+message PathFollowCommand {
+  optional apollo.common.Header header = 1;
+  // Unique identification for command.
+  optional int64 command_id = 2 [default = -1];
+  // Path point to be followed, a valid path should contain >= 2 points. No lane
+  // on the map is followed for this command.
+  repeated Point way_point = 3;
+  oneof boundary {
+    // PathBoundary with left and right boundary.
+    PathBoundary path_boundary = 4;
+    // Path boundary generated with the distance from center to left and right
+    // boundary given.
+    BoundaryWithWidth boundary_with_width = 5;
+  }
+  // Expected speed when executing this command. If "target_speed" > maximum
+  // speed of the vehicle, use maximum speed of the vehicle instead. If it is
+  // not given, the default target speed of system will be used.
+  optional double target_speed = 6;
+}

+ 22 - 0
src/test/testhdmap/modules/common_msgs/external_command_msgs/speed_command.proto

@@ -0,0 +1,22 @@
+syntax = "proto2";
+
+package apollo.external_command;
+
+import "modules/common_msgs/basic_msgs/header.proto";
+
+message SpeedCommand {
+  optional apollo.common.Header header = 1;
+  // Unique identification for command.
+  optional int64 command_id = 2 [default = -1];
+  oneof linear_speed {
+    // Replace the target speed of current motion command with this new target
+    // speed.
+    double target_speed = 3;
+    // Multiple the target speed in current motion command with the factor. The
+    // factor should be in range [0, 1.0].
+    double target_speed_factor = 4;
+    // Restore the target speed with the initial value(The default configured
+    // target speed or set in motion command).
+    bool is_restore_target_speed = 5;
+  }
+}

+ 27 - 0
src/test/testhdmap/modules/common_msgs/external_command_msgs/valet_parking_command.proto

@@ -0,0 +1,27 @@
+syntax = "proto2";
+
+package apollo.external_command;
+
+import "modules/common_msgs/basic_msgs/header.proto";
+import "modules/common_msgs/external_command_msgs/geometry.proto";
+import "modules/common_msgs/external_command_msgs/lane_segment.proto";
+
+message ValetParkingCommand {
+  optional apollo.common.Header header = 1;
+  // Unique identification for command.
+  optional int64 command_id = 2 [default = -1];
+  // If the start pose is set as the first point of "way_point".
+  optional bool is_start_pose_set = 3 [default = false];
+  // The points between "start_pose" and "end_pose".
+  repeated Pose way_point = 4;
+  // The lane segments which should not be passed by.
+  repeated LaneSegment blacklisted_lane = 5;
+  // The road which should not be passed by.
+  repeated string blacklisted_road = 6;
+  // The id of the parking spot on the map.
+  required string parking_spot_id = 7;
+  // Expected speed when executing this command. If "target_speed" > maximum
+  // speed of the vehicle, use maximum speed of the vehicle instead. If it is
+  // not given, the default target speed of system will be used.
+  optional double target_speed = 8;
+}

+ 16 - 0
src/test/testhdmap/modules/common_msgs/guardian_msgs/BUILD

@@ -0,0 +1,16 @@
+## Auto generated by `proto_build_generator.py`
+load("//tools/proto:proto.bzl", "proto_library")
+load("//tools:apollo_package.bzl", "apollo_package")
+
+package(default_visibility = ["//visibility:public"])
+
+proto_library(
+    name = "guardian_proto",
+    srcs = ["guardian.proto"],
+    deps = [
+        "//modules/common_msgs/basic_msgs:header_proto",
+        "//modules/common_msgs/control_msgs:control_cmd_proto",
+    ],
+)
+
+apollo_package()

+ 10 - 0
src/test/testhdmap/modules/common_msgs/guardian_msgs/guardian.proto

@@ -0,0 +1,10 @@
+syntax = "proto2";
+package apollo.guardian;
+
+import "modules/common_msgs/basic_msgs/header.proto";
+import "modules/common_msgs/control_msgs/control_cmd.proto";
+
+message GuardianCommand {
+  optional apollo.common.Header header = 1;
+  optional apollo.control.ControlCommand control_command = 2;
+}

+ 50 - 0
src/test/testhdmap/modules/common_msgs/localization_msgs/BUILD

@@ -0,0 +1,50 @@
+## Auto generated by `proto_build_generator.py`
+load("//tools/proto:proto.bzl", "proto_library")
+load("//tools:apollo_package.bzl", "apollo_package")
+
+package(default_visibility = ["//visibility:public"])
+
+proto_library(
+    name = "pose_proto",
+    srcs = ["pose.proto"],
+    deps = [
+        "//modules/common_msgs/basic_msgs:geometry_proto",
+    ],
+)
+
+proto_library(
+    name = "imu_proto",
+    srcs = ["imu.proto"],
+    deps = [
+        ":pose_proto",
+        "//modules/common_msgs/basic_msgs:header_proto",
+    ],
+)
+
+proto_library(
+    name = "localization_proto",
+    srcs = ["localization.proto"],
+    deps = [
+        ":localization_status_proto",
+        ":pose_proto",
+        "//modules/common_msgs/basic_msgs:geometry_proto",
+        "//modules/common_msgs/basic_msgs:header_proto",
+        "//modules/common_msgs/basic_msgs:pnc_point_proto",
+    ],
+)
+
+proto_library(
+    name = "localization_status_proto",
+    srcs = ["localization_status.proto"],
+)
+
+proto_library(
+    name = "gps_proto",
+    srcs = ["gps.proto"],
+    deps = [
+        ":pose_proto",
+        "//modules/common_msgs/basic_msgs:header_proto",
+    ],
+)
+
+apollo_package()

+ 13 - 0
src/test/testhdmap/modules/common_msgs/localization_msgs/gps.proto

@@ -0,0 +1,13 @@
+syntax = "proto2";
+
+package apollo.localization;
+
+import "modules/common_msgs/basic_msgs/header.proto";
+import "modules/common_msgs/localization_msgs/pose.proto";
+
+message Gps {
+  optional apollo.common.Header header = 1;
+
+  // Localization message: from GPS or localization
+  optional apollo.localization.Pose localization = 2;
+}

+ 13 - 0
src/test/testhdmap/modules/common_msgs/localization_msgs/imu.proto

@@ -0,0 +1,13 @@
+syntax = "proto2";
+
+package apollo.localization;
+
+import "modules/common_msgs/basic_msgs/header.proto";
+import "modules/common_msgs/localization_msgs/pose.proto";
+
+message CorrectedImu {
+  optional apollo.common.Header header = 1;
+
+  // Inertial Measurement Unit(IMU)
+  optional apollo.localization.Pose imu = 3;
+}

+ 81 - 0
src/test/testhdmap/modules/common_msgs/localization_msgs/localization.proto

@@ -0,0 +1,81 @@
+/******************************************************************************
+ * 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.
+ *****************************************************************************/
+
+syntax = "proto2";
+
+package apollo.localization;
+
+import "modules/common_msgs/basic_msgs/header.proto";
+import "modules/common_msgs/basic_msgs/geometry.proto";
+import "modules/common_msgs/basic_msgs/pnc_point.proto";
+import "modules/common_msgs/localization_msgs/localization_status.proto";
+import "modules/common_msgs/localization_msgs/pose.proto";
+
+message Uncertainty {
+  // Standard deviation of position, east/north/up in meters.
+  optional apollo.common.Point3D position_std_dev = 1;
+
+  // Standard deviation of quaternion qx/qy/qz, unitless.
+  optional apollo.common.Point3D orientation_std_dev = 2;
+
+  // Standard deviation of linear velocity, east/north/up in meters per second.
+  optional apollo.common.Point3D linear_velocity_std_dev = 3;
+
+  // Standard deviation of linear acceleration, right/forward/up in meters per
+  // square second.
+  optional apollo.common.Point3D linear_acceleration_std_dev = 4;
+
+  // Standard deviation of angular velocity, right/forward/up in radians per
+  // second.
+  optional apollo.common.Point3D angular_velocity_std_dev = 5;
+
+  // TODO: Define covariance items when needed.
+}
+
+message LocalizationEstimate {
+  optional apollo.common.Header header = 1;
+  optional apollo.localization.Pose pose = 2;
+  optional Uncertainty uncertainty = 3;
+
+  // The time of pose measurement, seconds since 1970-1-1 (UNIX time).
+  optional double measurement_time = 4;  // In seconds.
+
+  // Future trajectory actually driven by the drivers
+  repeated apollo.common.TrajectoryPoint trajectory_point = 5;
+
+  // msf status
+  optional MsfStatus msf_status = 6;
+  // msf quality
+  optional MsfSensorMsgStatus sensor_status = 7;
+}
+
+enum MeasureState {
+  OK = 0;
+  WARNNING = 1;
+  ERROR = 2;
+  CRITICAL_ERROR = 3;
+  FATAL_ERROR = 4;
+}
+
+message LocalizationStatus {
+  optional apollo.common.Header header = 1;
+  optional MeasureState fusion_status = 2;
+  optional MeasureState gnss_status = 3 [deprecated = true];
+  optional MeasureState lidar_status = 4 [deprecated = true];
+  // The time of pose measurement, seconds since 1970-1-1 (UNIX time).
+  optional double measurement_time = 5;  // In seconds.
+  optional string state_message = 6;
+}

+ 175 - 0
src/test/testhdmap/modules/common_msgs/localization_msgs/localization_status.proto

@@ -0,0 +1,175 @@
+/******************************************************************************
+ * Copyright 2018 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.
+ *****************************************************************************/
+
+syntax = "proto2";
+
+package apollo.localization;
+
+// LiDAR-based loclaization module status
+enum LocalLidarStatus {
+  MSF_LOCAL_LIDAR_NORMAL = 0;       // Localization result satisfy threshold
+  MSF_LOCAL_LIDAR_MAP_MISSING = 1;  // Can't find localization map (config.xml)
+  MSF_LOCAL_LIDAR_EXTRINSICS_MISSING = 2;  // Missing extrinsic parameters
+  MSF_LOCAL_LIDAR_MAP_LOADING_FAILED = 3;  // Fail to load localization map
+  MSF_LOCAL_LIDAR_NO_OUTPUT =
+      4;  // No output (comparing to timestamp of imu msg)
+  MSF_LOCAL_LIDAR_OUT_OF_MAP =
+      5;  // Coverage of online pointcloud and map is lower than threshold
+  MSF_LOCAL_LIDAR_NOT_GOOD = 6;  // Localization result do not meet threshold
+  MSF_LOCAL_LIDAR_UNDEFINED_STATUS = 7;  // others
+}
+
+enum LocalLidarQuality {
+  MSF_LOCAL_LIDAR_VERY_GOOD = 0;
+  MSF_LOCAL_LIDAR_GOOD = 1;
+  MSF_LOCAL_LIDAR_NOT_BAD = 2;
+  MSF_LOCAL_LIDAR_BAD = 3;
+}
+
+// LiDAR-based localization result check (the difference between lidar and sins
+// result)
+enum LocalLidarConsistency {
+  MSF_LOCAL_LIDAR_CONSISTENCY_00 =
+      0;  // The difference is less than threshold 1
+  MSF_LOCAL_LIDAR_CONSISTENCY_01 =
+      1;  // The difference is bigger than threshold 1 but less than threshold 2
+  MSF_LOCAL_LIDAR_CONSISTENCY_02 =
+      2;  // The difference is bigger than threshold 2
+  MSF_LOCAL_LIDAR_CONSISTENCY_03 = 3;  // others
+}
+
+// GNSS-based localization result check (the difference between GNSS and sins
+// result)
+enum GnssConsistency {
+  MSF_GNSS_CONSISTENCY_00 = 0;  // The difference is less than threshold 1
+  MSF_GNSS_CONSISTENCY_01 =
+      1;  // The difference is bigger than threshold 1 but less than threshold 2
+  MSF_GNSS_CONSISTENCY_02 = 2;  // The difference is bigger than threshold 2
+  MSF_GNSS_CONSISTENCY_03 = 3;  // others
+}
+
+enum GnssPositionType {
+  NONE = 0;         // No solution
+  FIXEDPOS = 1;     // Position has been fixed by the FIX POSITION command or by
+                    // position averaging
+  FIXEDHEIGHT = 2;  // Position has been fixed by the FIX HEIGHT, or FIX AUTO,
+                    // command or by position averaging
+  FLOATCONV = 4;    // Solution from floating point carrier phase anbiguities
+  WIDELANE = 5;     // Solution from wide-lane ambiguities
+  NARROWLANE = 6;   // Solution from narrow-lane ambiguities
+  DOPPLER_VELOCITY = 8;  // Velocity computed using instantaneous Doppler
+  SINGLE = 16;           // Single point position
+  PSRDIFF = 17;          // Pseudorange differential solution
+  WAAS = 18;             // Solution calculated using corrections from an SBAS
+  PROPOGATED = 19;  // Propagated by a Kalman filter without new observations
+  OMNISTAR = 20;    // OmniSTAR VBS position
+  L1_FLOAT = 32;    // Floating L1 albiguity solution
+  IONOFREE_FLOAT = 33;  // Floating ionospheric free ambiguity solution
+  NARROW_FLOAT = 34;    // Floating narrow-lane anbiguity solution
+  L1_INT = 48;          // Integer L1 ambiguity solution
+  WIDE_INT = 49;        // Integer wide-lane ambiguity solution
+  NARROW_INT = 50;      // Integer narrow-lane ambiguity solution
+  RTK_DIRECT_INS = 51;  // RTK status where RTK filter is directly initialized
+                        // from the INS filter
+  INS_SBAS = 52;        // INS calculated position corrected for the antenna
+  INS_PSRSP =
+      53;  // INS pseudorange single point solution - no DGPS corrections
+  INS_PSRDIFF = 54;         // INS pseudorange differential solution
+  INS_RTKFLOAT = 55;        // INS RTK float point ambiguities solution
+  INS_RTKFIXED = 56;        // INS RTK fixed ambiguities solution
+  INS_OMNISTAR = 57;        // INS OmniSTAR VBS solution
+  INS_OMNISTAR_HP = 58;     // INS OmniSTAR high precision solution
+  INS_OMNISTAR_XP = 59;     // INS OmniSTAR extra precision solution
+  OMNISTAR_HP = 64;         // OmniSTAR high precision
+  OMNISTAR_XP = 65;         // OmniSTAR extra precision
+  PPP_CONVERGING = 68;      // Precise Point Position(PPP) solution converging
+  PPP = 69;                 // Precise Point Position(PPP)solution
+  INS_PPP_Converging = 73;  // INS NovAtel CORRECT Precise Point Position(PPP)
+                            // solution converging
+  INS_PPP = 74;   // INS NovAtel CORRECT Precise Point Position(PPP) solution
+  MSG_LOSS = 91;  // Gnss position message loss
+}
+
+// IMU msg status
+enum ImuMsgDelayStatus {
+  IMU_DELAY_NORMAL = 0;
+  IMU_DELAY_1 = 1;
+  IMU_DELAY_2 = 2;
+  IMU_DELAY_3 = 3;
+  IMU_DELAY_ABNORMAL = 4;
+}
+
+enum ImuMsgMissingStatus {
+  IMU_MISSING_NORMAL = 0;
+  IMU_MISSING_1 = 1;
+  IMU_MISSING_2 = 2;
+  IMU_MISSING_3 = 3;
+  IMU_MISSING_4 = 4;
+  IMU_MISSING_5 = 5;
+  IMU_MISSING_ABNORMAL = 6;
+}
+
+enum ImuMsgDataStatus {
+  IMU_DATA_NORMAL = 0;
+  IMU_DATA_ABNORMAL = 1;
+  IMU_DATA_OTHER = 2;
+}
+
+// The running status of localization module
+enum MsfRunningStatus {
+  MSF_SOL_LIDAR_GNSS = 0;
+  MSF_SOL_X_GNSS = 1;
+  MSF_SOL_LIDAR_X = 2;
+  MSF_SOL_LIDAR_XX = 3;
+  MSF_SOL_LIDAR_XXX = 4;
+  MSF_SOL_X_X = 5;
+  MSF_SOL_X_XX = 6;
+  MSF_SOL_X_XXX = 7;
+  MSF_SSOL_LIDAR_GNSS = 8;
+  MSF_SSOL_X_GNSS = 9;
+  MSF_SSOL_LIDAR_X = 10;
+  MSF_SSOL_LIDAR_XX = 11;
+  MSF_SSOL_LIDAR_XXX = 12;
+  MSF_SSOL_X_X = 13;
+  MSF_SSOL_X_XX = 14;
+  MSF_SSOL_X_XXX = 15;
+  MSF_NOSOL_LIDAR_GNSS = 16;
+  MSF_NOSOL_X_GNSS = 17;
+  MSF_NOSOL_LIDAR_X = 18;
+  MSF_NOSOL_LIDAR_XX = 19;
+  MSF_NOSOL_LIDAR_XXX = 20;
+  MSF_NOSOL_X_X = 21;
+  MSF_NOSOL_X_XX = 22;
+  MSF_NOSOL_X_XXX = 23;
+  MSF_RUNNING_INIT = 24;
+}
+
+// The status of sensor msg
+message MsfSensorMsgStatus {
+  optional ImuMsgDelayStatus imu_delay_status = 1;
+  optional ImuMsgMissingStatus imu_missing_status = 2;
+  optional ImuMsgDataStatus imu_data_status = 3;
+}
+
+// The status of msf localization module
+message MsfStatus {
+  optional LocalLidarConsistency local_lidar_consistency = 1;
+  optional GnssConsistency gnss_consistency = 2;
+  optional LocalLidarStatus local_lidar_status = 3;
+  optional LocalLidarQuality local_lidar_quality = 4;
+  optional GnssPositionType gnsspos_position_type = 5;
+  optional MsfRunningStatus msf_running_status = 6;
+}

+ 65 - 0
src/test/testhdmap/modules/common_msgs/localization_msgs/pose.proto

@@ -0,0 +1,65 @@
+/******************************************************************************
+ * 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.
+ *****************************************************************************/
+
+syntax = "proto2";
+
+package apollo.localization;
+
+import "modules/common_msgs/basic_msgs/geometry.proto";
+
+message Pose {
+  // Position of the vehicle reference point (VRP) in the map reference frame.
+  // The VRP is the center of rear axle.
+  optional apollo.common.PointENU position = 1;
+
+  // A quaternion that represents the rotation from the IMU coordinate
+  // (Right/Forward/Up) to the
+  // world coordinate (East/North/Up).
+  optional apollo.common.Quaternion orientation = 2;
+
+  // Linear velocity of the VRP in the map reference frame.
+  // East/north/up in meters per second.
+  optional apollo.common.Point3D linear_velocity = 3;
+
+  // Linear acceleration of the VRP in the map reference frame.
+  // East/north/up in meters per square second.
+  optional apollo.common.Point3D linear_acceleration = 4;
+
+  // Angular velocity of the vehicle in the map reference frame.
+  // Around east/north/up axes in radians per second.
+  optional apollo.common.Point3D angular_velocity = 5;
+
+  // Heading
+  // The heading is zero when the car is facing East and positive when facing
+  // North.
+  optional double heading = 6;
+
+  // Linear acceleration of the VRP in the vehicle reference frame.
+  // Right/forward/up in meters per square second.
+  optional apollo.common.Point3D linear_acceleration_vrf = 7;
+
+  // Angular velocity of the VRP in the vehicle reference frame.
+  // Around right/forward/up axes in radians per second.
+  optional apollo.common.Point3D angular_velocity_vrf = 8;
+
+  // Roll/pitch/yaw that represents a rotation with intrinsic sequence z-x-y.
+  // in world coordinate (East/North/Up)
+  // The roll, in (-pi/2, pi/2), corresponds to a rotation around the y-axis.
+  // The pitch, in [-pi, pi), corresponds to a rotation around the x-axis.
+  // The yaw, in [-pi, pi), corresponds to a rotation around the z-axis.
+  // The direction of rotation follows the right-hand rule.
+  optional apollo.common.Point3D euler_angles = 9;
+}

+ 165 - 0
src/test/testhdmap/modules/common_msgs/map_msgs/BUILD

@@ -0,0 +1,165 @@
+## Auto generated by `proto_build_generator.py`
+load("//tools/proto:proto.bzl", "proto_library")
+load("//tools:apollo_package.bzl", "apollo_package")
+
+package(default_visibility = ["//visibility:public"])
+
+proto_library(
+    name = "map_road_proto",
+    srcs = ["map_road.proto"],
+    deps = [
+        ":map_geometry_proto",
+        ":map_id_proto",
+    ],
+)
+
+proto_library(
+    name = "map_overlap_proto",
+    srcs = ["map_overlap.proto"],
+    deps = [
+        ":map_geometry_proto",
+        ":map_id_proto",
+    ],
+)
+
+proto_library(
+    name = "map_lane_proto",
+    srcs = ["map_lane.proto"],
+    deps = [
+        ":map_geometry_proto",
+        ":map_id_proto",
+    ],
+)
+
+proto_library(
+    name = "map_stop_sign_proto",
+    srcs = ["map_stop_sign.proto"],
+    deps = [
+        ":map_geometry_proto",
+        ":map_id_proto",
+    ],
+)
+
+proto_library(
+    name = "map_id_proto",
+    srcs = ["map_id.proto"],
+)
+
+proto_library(
+    name = "map_junction_proto",
+    srcs = ["map_junction.proto"],
+    deps = [
+        ":map_geometry_proto",
+        ":map_id_proto",
+    ],
+)
+
+proto_library(
+    name = "map_rsu_proto",
+    srcs = ["map_rsu.proto"],
+    deps = [
+        ":map_id_proto",
+    ],
+)
+
+proto_library(
+    name = "map_geometry_proto",
+    srcs = ["map_geometry.proto"],
+    deps = [
+        "//modules/common_msgs/basic_msgs:geometry_proto",
+    ],
+)
+
+proto_library(
+    name = "map_yield_sign_proto",
+    srcs = ["map_yield_sign.proto"],
+    deps = [
+        ":map_geometry_proto",
+        ":map_id_proto",
+    ],
+)
+
+proto_library(
+    name = "map_proto",
+    srcs = ["map.proto"],
+    deps = [
+        ":map_clear_area_proto",
+        ":map_crosswalk_proto",
+        ":map_junction_proto",
+        ":map_lane_proto",
+        ":map_overlap_proto",
+        ":map_parking_space_proto",
+        ":map_pnc_junction_proto",
+        ":map_road_proto",
+        ":map_rsu_proto",
+        ":map_signal_proto",
+        ":map_speed_bump_proto",
+        ":map_stop_sign_proto",
+        ":map_yield_sign_proto",
+    ],
+)
+
+proto_library(
+    name = "map_clear_area_proto",
+    srcs = ["map_clear_area.proto"],
+    deps = [
+        ":map_geometry_proto",
+        ":map_id_proto",
+    ],
+)
+
+proto_library(
+    name = "map_parking_space_proto",
+    srcs = ["map_parking_space.proto"],
+    deps = [
+        ":map_geometry_proto",
+        ":map_id_proto",
+    ],
+)
+
+proto_library(
+    name = "map_pnc_junction_proto",
+    srcs = ["map_pnc_junction.proto"],
+    deps = [
+        ":map_geometry_proto",
+        ":map_id_proto",
+    ],
+)
+
+proto_library(
+    name = "map_crosswalk_proto",
+    srcs = ["map_crosswalk.proto"],
+    deps = [
+        ":map_geometry_proto",
+        ":map_id_proto",
+    ],
+)
+
+proto_library(
+    name = "map_speed_bump_proto",
+    srcs = ["map_speed_bump.proto"],
+    deps = [
+        ":map_geometry_proto",
+        ":map_id_proto",
+    ],
+)
+
+proto_library(
+    name = "map_speed_control_proto",
+    srcs = ["map_speed_control.proto"],
+    deps = [
+        ":map_geometry_proto",
+    ],
+)
+
+proto_library(
+    name = "map_signal_proto",
+    srcs = ["map_signal.proto"],
+    deps = [
+        ":map_geometry_proto",
+        ":map_id_proto",
+        "//modules/common_msgs/basic_msgs:geometry_proto",
+    ],
+)
+
+apollo_package()

+ 58 - 0
src/test/testhdmap/modules/common_msgs/map_msgs/map.proto

@@ -0,0 +1,58 @@
+syntax = "proto2";
+
+package apollo.hdmap;
+
+import "modules/common_msgs/map_msgs/map_clear_area.proto";
+import "modules/common_msgs/map_msgs/map_crosswalk.proto";
+import "modules/common_msgs/map_msgs/map_junction.proto";
+import "modules/common_msgs/map_msgs/map_lane.proto";
+import "modules/common_msgs/map_msgs/map_overlap.proto";
+import "modules/common_msgs/map_msgs/map_parking_space.proto";
+import "modules/common_msgs/map_msgs/map_pnc_junction.proto";
+import "modules/common_msgs/map_msgs/map_road.proto";
+import "modules/common_msgs/map_msgs/map_rsu.proto";
+import "modules/common_msgs/map_msgs/map_signal.proto";
+import "modules/common_msgs/map_msgs/map_speed_bump.proto";
+import "modules/common_msgs/map_msgs/map_stop_sign.proto";
+import "modules/common_msgs/map_msgs/map_yield_sign.proto";
+
+// This message defines how we project the ellipsoidal Earth surface to a plane.
+message Projection {
+  // PROJ.4 setting:
+  // "+proj=tmerc +lat_0={origin.lat} +lon_0={origin.lon} +k={scale_factor}
+  // +ellps=WGS84 +no_defs"
+  optional string proj = 1;
+}
+
+message Header {
+  optional bytes version = 1;
+  optional bytes date = 2;
+  optional Projection projection = 3;
+  optional bytes district = 4;
+  optional bytes generation = 5;
+  optional bytes rev_major = 6;
+  optional bytes rev_minor = 7;
+  optional double left = 8;
+  optional double top = 9;
+  optional double right = 10;
+  optional double bottom = 11;
+  optional bytes vendor = 12;
+}
+
+message Map {
+  optional Header header = 1;
+
+  repeated Crosswalk crosswalk = 2;
+  repeated Junction junction = 3;
+  repeated Lane lane = 4;
+  repeated StopSign stop_sign = 5;
+  repeated Signal signal = 6;
+  repeated YieldSign yield = 7;
+  repeated Overlap overlap = 8;
+  repeated ClearArea clear_area = 9;
+  repeated SpeedBump speed_bump = 10;
+  repeated Road road = 11;
+  repeated ParkingSpace parking_space = 12;
+  repeated PNCJunction pnc_junction = 13;
+  repeated RSU rsu = 14;
+}

+ 14 - 0
src/test/testhdmap/modules/common_msgs/map_msgs/map_clear_area.proto

@@ -0,0 +1,14 @@
+syntax = "proto2";
+
+package apollo.hdmap;
+
+import "modules/common_msgs/map_msgs/map_geometry.proto";
+import "modules/common_msgs/map_msgs/map_id.proto";
+
+// A clear area means in which stopping car is prohibited
+
+message ClearArea {
+  optional Id id = 1;
+  repeated Id overlap_id = 2;
+  optional Polygon polygon = 3;
+}

+ 15 - 0
src/test/testhdmap/modules/common_msgs/map_msgs/map_crosswalk.proto

@@ -0,0 +1,15 @@
+syntax = "proto2";
+
+package apollo.hdmap;
+
+import "modules/common_msgs/map_msgs/map_geometry.proto";
+import "modules/common_msgs/map_msgs/map_id.proto";
+
+// Crosswalk is a place designated for pedestrians to cross a road.
+message Crosswalk {
+  optional Id id = 1;
+
+  optional Polygon polygon = 2;
+
+  repeated Id overlap_id = 3;
+}

+ 31 - 0
src/test/testhdmap/modules/common_msgs/map_msgs/map_geometry.proto

@@ -0,0 +1,31 @@
+syntax = "proto2";
+
+import "modules/common_msgs/basic_msgs/geometry.proto";
+
+package apollo.hdmap;
+
+// Polygon, not necessary convex.
+message Polygon {
+  repeated apollo.common.PointENU point = 1;
+}
+
+// Straight line segment.
+message LineSegment {
+  repeated apollo.common.PointENU point = 1;
+}
+
+// Generalization of a line.
+message CurveSegment {
+  oneof curve_type {
+    LineSegment line_segment = 1;
+  }
+  optional double s = 6;  // start position (s-coordinate)
+  optional apollo.common.PointENU start_position = 7;
+  optional double heading = 8;  // start orientation
+  optional double length = 9;
+}
+
+// An object similar to a line but that need not be straight.
+message Curve {
+  repeated CurveSegment segment = 1;
+}

+ 8 - 0
src/test/testhdmap/modules/common_msgs/map_msgs/map_id.proto

@@ -0,0 +1,8 @@
+syntax = "proto2";
+
+package apollo.hdmap;
+
+// Global unique ids for all objects (include lanes, junctions, overlaps, etc).
+message Id {
+  optional string id = 1;
+}

+ 24 - 0
src/test/testhdmap/modules/common_msgs/map_msgs/map_junction.proto

@@ -0,0 +1,24 @@
+syntax = "proto2";
+
+package apollo.hdmap;
+
+import "modules/common_msgs/map_msgs/map_geometry.proto";
+import "modules/common_msgs/map_msgs/map_id.proto";
+
+// A junction is the junction at-grade of two or more roads crossing.
+message Junction {
+  optional Id id = 1;
+
+  optional Polygon polygon = 2;
+
+  repeated Id overlap_id = 3;
+  enum Type {
+    UNKNOWN = 0;
+    IN_ROAD = 1;
+    CROSS_ROAD = 2;
+    FORK_ROAD = 3;
+    MAIN_SIDE = 4;
+    DEAD_END = 5;
+  };
+  optional Type type = 4;
+}

+ 109 - 0
src/test/testhdmap/modules/common_msgs/map_msgs/map_lane.proto

@@ -0,0 +1,109 @@
+syntax = "proto2";
+
+package apollo.hdmap;
+
+import "modules/common_msgs/map_msgs/map_geometry.proto";
+import "modules/common_msgs/map_msgs/map_id.proto";
+
+message LaneBoundaryType {
+  enum Type {
+    UNKNOWN = 0;
+    DOTTED_YELLOW = 1;
+    DOTTED_WHITE = 2;
+    SOLID_YELLOW = 3;
+    SOLID_WHITE = 4;
+    DOUBLE_YELLOW = 5;
+    CURB = 6;
+  };
+  // Offset relative to the starting point of boundary
+  optional double s = 1;
+  // support multiple types
+  repeated Type types = 2;
+}
+
+message LaneBoundary {
+  optional Curve curve = 1;
+
+  optional double length = 2;
+  // indicate whether the lane boundary exists in real world
+  optional bool virtual = 3;
+  // in ascending order of s
+  repeated LaneBoundaryType boundary_type = 4;
+}
+
+// Association between central point to closest boundary.
+message LaneSampleAssociation {
+  optional double s = 1;
+  optional double width = 2;
+}
+
+// A lane is part of a roadway, that is designated for use by a single line of
+// vehicles.
+// Most public roads (include highways) have more than two lanes.
+message Lane {
+  optional Id id = 1;
+
+  // Central lane as reference trajectory, not necessary to be the geometry
+  // central.
+  optional Curve central_curve = 2;
+
+  // Lane boundary curve.
+  optional LaneBoundary left_boundary = 3;
+  optional LaneBoundary right_boundary = 4;
+
+  // in meters.
+  optional double length = 5;
+
+  // Speed limit of the lane, in meters per second.
+  optional double speed_limit = 6;
+
+  repeated Id overlap_id = 7;
+
+  // All lanes can be driving into (or from).
+  repeated Id predecessor_id = 8;
+  repeated Id successor_id = 9;
+
+  // Neighbor lanes on the same direction.
+  repeated Id left_neighbor_forward_lane_id = 10;
+  repeated Id right_neighbor_forward_lane_id = 11;
+
+  enum LaneType {
+    NONE = 1;
+    CITY_DRIVING = 2;
+    BIKING = 3;
+    SIDEWALK = 4;
+    PARKING = 5;
+    SHOULDER = 6;
+  };
+  optional LaneType type = 12;
+
+  enum LaneTurn {
+    NO_TURN = 1;
+    LEFT_TURN = 2;
+    RIGHT_TURN = 3;
+    U_TURN = 4;
+  };
+  optional LaneTurn turn = 13;
+
+  repeated Id left_neighbor_reverse_lane_id = 14;
+  repeated Id right_neighbor_reverse_lane_id = 15;
+
+  optional Id junction_id = 16;
+
+  // Association between central point to closest boundary.
+  repeated LaneSampleAssociation left_sample = 17;
+  repeated LaneSampleAssociation right_sample = 18;
+
+  enum LaneDirection {
+    FORWARD = 1;
+    BACKWARD = 2;
+    BIDIRECTION = 3;
+  }
+  optional LaneDirection direction = 19;
+
+  // Association between central point to closest road boundary.
+  repeated LaneSampleAssociation left_road_sample = 20;
+  repeated LaneSampleAssociation right_road_sample = 21;
+
+  repeated Id self_reverse_lane_id = 22;
+}

+ 71 - 0
src/test/testhdmap/modules/common_msgs/map_msgs/map_overlap.proto

@@ -0,0 +1,71 @@
+syntax = "proto2";
+
+package apollo.hdmap;
+
+import "modules/common_msgs/map_msgs/map_geometry.proto";
+import "modules/common_msgs/map_msgs/map_id.proto";
+
+message LaneOverlapInfo {
+  optional double start_s = 1;  // position (s-coordinate)
+  optional double end_s = 2;    // position (s-coordinate)
+  optional bool is_merge = 3;
+
+  optional Id region_overlap_id = 4;
+}
+
+message SignalOverlapInfo {}
+
+message StopSignOverlapInfo {}
+
+message CrosswalkOverlapInfo {
+  optional Id region_overlap_id = 1;
+}
+
+message JunctionOverlapInfo {}
+
+message YieldOverlapInfo {}
+
+message ClearAreaOverlapInfo {}
+
+message SpeedBumpOverlapInfo {}
+
+message ParkingSpaceOverlapInfo {}
+
+message PNCJunctionOverlapInfo {}
+
+message RSUOverlapInfo {}
+
+message RegionOverlapInfo {
+  optional Id id = 1;
+  repeated Polygon polygon = 2;
+}
+
+// Information about one object in the overlap.
+message ObjectOverlapInfo {
+  optional Id id = 1;
+
+  oneof overlap_info {
+    LaneOverlapInfo lane_overlap_info = 3;
+    SignalOverlapInfo signal_overlap_info = 4;
+    StopSignOverlapInfo stop_sign_overlap_info = 5;
+    CrosswalkOverlapInfo crosswalk_overlap_info = 6;
+    JunctionOverlapInfo junction_overlap_info = 7;
+    YieldOverlapInfo yield_sign_overlap_info = 8;
+    ClearAreaOverlapInfo clear_area_overlap_info = 9;
+    SpeedBumpOverlapInfo speed_bump_overlap_info = 10;
+    ParkingSpaceOverlapInfo parking_space_overlap_info = 11;
+    PNCJunctionOverlapInfo pnc_junction_overlap_info = 12;
+    RSUOverlapInfo rsu_overlap_info = 13;
+  }
+}
+
+// Here, the "overlap" includes any pair of objects on the map
+// (e.g. lanes, junctions, and crosswalks).
+message Overlap {
+  optional Id id = 1;
+
+  // Information about one overlap, include all overlapped objects.
+  repeated ObjectOverlapInfo object = 2;
+
+  repeated RegionOverlapInfo region_overlap = 3;
+}

+ 26 - 0
src/test/testhdmap/modules/common_msgs/map_msgs/map_parking_space.proto

@@ -0,0 +1,26 @@
+syntax = "proto2";
+
+package apollo.hdmap;
+
+import "modules/common_msgs/map_msgs/map_geometry.proto";
+import "modules/common_msgs/map_msgs/map_id.proto";
+
+// ParkingSpace is a place designated to park a car.
+message ParkingSpace {
+  optional Id id = 1;
+
+  optional Polygon polygon = 2;
+
+  repeated Id overlap_id = 3;
+
+  optional double heading = 4;
+}
+
+// ParkingLot is a place for parking cars.
+message ParkingLot {
+  optional Id id = 1;
+
+  optional Polygon polygon = 2;
+
+  repeated Id overlap_id = 3;
+}

+ 38 - 0
src/test/testhdmap/modules/common_msgs/map_msgs/map_pnc_junction.proto

@@ -0,0 +1,38 @@
+syntax = "proto2";
+
+package apollo.hdmap;
+
+import "modules/common_msgs/map_msgs/map_geometry.proto";
+import "modules/common_msgs/map_msgs/map_id.proto";
+
+message Passage {
+  optional Id id = 1;
+
+  repeated Id signal_id = 2;
+  repeated Id yield_id = 3;
+  repeated Id stop_sign_id = 4;
+  repeated Id lane_id = 5;
+
+  enum Type {
+    UNKNOWN = 0;
+    ENTRANCE = 1;
+    EXIT = 2;
+  };
+  optional Type type = 6;
+};
+
+message PassageGroup {
+  optional Id id = 1;
+
+  repeated Passage passage = 2;
+};
+
+message PNCJunction {
+  optional Id id = 1;
+
+  optional Polygon polygon = 2;
+
+  repeated Id overlap_id = 3;
+
+  repeated PassageGroup passage_group = 4;
+}

Some files were not shown because too many files changed in this diff