Browse Source

add testhdmap for test apollo hdmap. only compile ok.

yuchuli 10 tháng trước cách đây
mục cha
commit
32d57da293
100 tập tin đã thay đổi với 10239 bổ sung0 xóa
  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;
+}

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác