21#include <boost/filesystem.hpp>
23#include "absl/strings/str_cat.h"
29namespace localization {
32 : map_config_(), resolution_id_(0), zone_id_(0), visual_engine_() {}
37 const std::string &map_folder,
const std::string &map_visual_folder,
38 const std::string &pcd_folder,
const std::string &pcd_timestamp_file,
39 const std::string &gnss_loc_file,
const std::string &lidar_loc_file,
40 const std::string &fusion_loc_file,
const std::string &extrinsic_file) {
41 map_folder_ = map_folder;
42 map_visual_folder_ = map_visual_folder;
43 pcd_folder_ = pcd_folder;
44 pcd_timestamp_file_ = pcd_timestamp_file;
45 gnss_loc_file_ = gnss_loc_file;
46 lidar_loc_file_ = lidar_loc_file;
47 fusion_loc_file_ = fusion_loc_file;
48 extrinsic_file_ = extrinsic_file;
50 pcd_timestamps_.clear();
53 fusion_poses_.clear();
58 const std::string config_file = map_folder_ +
"/config.xml";
60 bool success = map_config_.
Load(config_file);
62 AERROR <<
"Load map config failed.";
65 AINFO <<
"Load map config succeed.";
69 AERROR <<
"Load velodyne extrinsic failed.";
72 AERROR <<
"Load velodyne extrinsic succeed.";
74 success = PCDTimestampFileHandler();
76 AERROR <<
"Handle pcd timestamp file failed.";
79 AINFO <<
"Handle pcd timestamp file succeed.";
81 success = LidarLocFileHandler(pcd_timestamps_);
83 AERROR <<
"Handle lidar localization file failed.";
86 AINFO <<
"Handle lidar localization file succeed.";
88 success = GnssLocFileHandler(pcd_timestamps_);
90 AERROR <<
"Handle gnss localization file failed.";
93 AINFO <<
"Handle gnss localization file succeed.";
95 success = FusionLocFileHandler(pcd_timestamps_);
97 AERROR <<
"Handle fusion localization file failed.";
100 AINFO <<
"Handle fusion localization file succeed.";
105 AERROR <<
"Get zone id failed.";
108 AINFO <<
"Get zone id succeed.";
116 success = visual_engine_.
Init(map_folder_, map_visual_folder_, map_param,
117 resolution_id_, zone_id_, velodyne_extrinsic_,
120 AERROR <<
"Visualization engine init failed.";
123 AINFO <<
"Visualization engine init succeed.";
129 for (
unsigned int idx = 0; idx < pcd_timestamps_.size(); ++idx) {
134 AINFO <<
"Frame id: " << idx + 1;
135 auto pose_found_iter = lidar_poses_.find(idx);
136 auto std_found_iter = lidar_stds_.find(idx);
137 if (pose_found_iter != lidar_poses_.end() &&
138 std_found_iter != lidar_stds_.end()) {
139 AINFO <<
"Find lidar pose.";
140 const Eigen::Affine3d &lidar_pose = pose_found_iter->second;
141 const Eigen::Vector3d &lidar_std = std_found_iter->second;
142 lidar_loc_info.
set(Eigen::Translation3d(lidar_pose.translation()),
143 Eigen::Quaterniond(lidar_pose.linear()), lidar_std,
144 "Lidar.", pcd_timestamps_[idx], idx + 1);
147 pose_found_iter = gnss_poses_.find(idx);
148 std_found_iter = gnss_stds_.find(idx);
149 if (pose_found_iter != gnss_poses_.end() &&
150 std_found_iter != gnss_stds_.end()) {
151 AINFO <<
"Find gnss pose.";
152 const Eigen::Affine3d &gnss_pose = pose_found_iter->second;
153 const Eigen::Vector3d &gnss_std = std_found_iter->second;
154 gnss_loc_info.
set(Eigen::Translation3d(gnss_pose.translation()), gnss_std,
155 "GNSS.", pcd_timestamps_[idx], idx + 1);
158 pose_found_iter = fusion_poses_.find(idx);
159 std_found_iter = fusion_stds_.find(idx);
160 if (pose_found_iter != fusion_poses_.end() &&
161 std_found_iter != fusion_stds_.end()) {
162 AINFO <<
"Find fusion pose.";
163 const Eigen::Affine3d &fusion_pose = pose_found_iter->second;
164 const Eigen::Vector3d &fusion_std = std_found_iter->second;
165 fusion_loc_info.
set(Eigen::Translation3d(fusion_pose.translation()),
166 Eigen::Quaterniond(fusion_pose.linear()), fusion_std,
167 "Fusion.", pcd_timestamps_[idx], idx + 1);
170 std::string pcd_file_path = absl::StrCat(pcd_folder_,
"/", idx + 1,
".pcd");
172 std::vector<unsigned char> intensities;
174 pcd_file_path, idx, lidar_loc_info.
pose, &pt3ds, &intensities,
false);
177 lidar_loc_info, gnss_loc_info, fusion_loc_info};
178 visual_engine_.
Visualize(std::move(loc_infos), pt3ds);
182bool OfflineLocalVisualizer::PCDTimestampFileHandler() {
183 pcd_timestamps_.clear();
185 FILE *file = fopen(pcd_timestamp_file_.c_str(),
"r");
187 AERROR <<
"Can't open file to read: " << pcd_timestamp_file_;
193 while (fscanf(file,
"%u %lf\n", &index, ×tamp) == 2) {
194 pcd_timestamps_.push_back(timestamp);
201bool OfflineLocalVisualizer::LidarLocFileHandler(
202 const std::vector<double> &pcd_timestamps) {
205 std::vector<double> timestamps;
209 &lidar_poses_, &lidar_stds_);
214bool OfflineLocalVisualizer::GnssLocFileHandler(
215 const std::vector<double> &pcd_timestamps) {
218 std::vector<double> timestamps;
222 &gnss_poses_, &gnss_stds_);
227bool OfflineLocalVisualizer::FusionLocFileHandler(
228 const std::vector<double> &pcd_timestamps) {
231 std::vector<double> timestamps;
235 &fusion_poses_, &fusion_stds_);
240 const ::apollo::common::EigenAffine3dVec &in_poses,
241 const ::apollo::common::EigenVector3dVec &in_stds,
242 const std::vector<double> &in_timestamps,
243 const std::vector<double> &ref_timestamps,
244 std::map<unsigned int, Eigen::Affine3d> *out_poses,
245 std::map<unsigned int, Eigen::Vector3d> *out_stds) {
246 unsigned int index = 0;
247 for (
size_t i = 0; i < ref_timestamps.size(); ++i) {
248 double ref_timestamp = ref_timestamps[i];
249 while (index < in_timestamps.size() &&
250 in_timestamps.at(index) < ref_timestamp) {
254 if (index >= in_timestamps.size()) {
255 AERROR <<
"[ERROR] No more poses. Exit now.";
259 double cur_timestamp = in_timestamps[index];
260 double pre_timestamp = in_timestamps[index - 1];
261 DCHECK_NE(cur_timestamp, pre_timestamp);
264 (cur_timestamp - ref_timestamp) / (cur_timestamp - pre_timestamp);
268 Eigen::Affine3d pre_pose = in_poses[index - 1];
269 Eigen::Affine3d cur_pose = in_poses[index];
270 Eigen::Quaterniond pre_quatd(pre_pose.linear());
271 Eigen::Translation3d pre_transd(pre_pose.translation());
272 Eigen::Quaterniond cur_quatd(cur_pose.linear());
273 Eigen::Translation3d cur_transd(cur_pose.translation());
275 Eigen::Quaterniond res_quatd = pre_quatd.slerp(1 - t, cur_quatd);
277 Eigen::Translation3d re_transd;
278 re_transd.x() = pre_transd.x() * t + cur_transd.x() * (1 - t);
279 re_transd.y() = pre_transd.y() * t + cur_transd.y() * (1 - t);
280 re_transd.z() = pre_transd.z() * t + cur_transd.z() * (1 - t);
281 (*out_poses)[
static_cast<unsigned int>(i)] = re_transd * res_quatd;
283 Eigen::Vector3d pre_std = in_stds[index - 1];
284 Eigen::Vector3d cur_std = in_stds[index];
286 std[0] = pre_std[0] * t + cur_std[0] * (1 - t);
287 std[1] = pre_std[1] * t + cur_std[1] * (1 - t);
288 std[2] = pre_std[2] * t + cur_std[2] * (1 - t);
289 (*out_stds)[
static_cast<unsigned int>(i)] =
std;
295 const std::string &map_folder,
const unsigned int resolution_id,
298 snprintf(buf,
sizeof(buf),
"/%03u", resolution_id);
299 std::string folder_north = map_folder +
"/map" + buf +
"/north";
300 std::string folder_south = map_folder +
"/map" + buf +
"/south";
301 boost::filesystem::directory_iterator directory_end;
302 boost::filesystem::directory_iterator iter_north(folder_north);
303 if (iter_north == directory_end) {
304 boost::filesystem::directory_iterator iter_south(folder_south);
305 if (iter_south == directory_end) {
308 std::string zone_id_full_path = (*iter_south).path().string();
309 std::size_t pos = zone_id_full_path.find_last_of(
"/");
310 std::string zone_id_str =
311 zone_id_full_path.substr(pos + 1, zone_id_full_path.length());
313 *zone_id = -(std::stoi(zone_id_str));
314 AINFO <<
"Find zone id: " << *zone_id;
317 std::string zone_id_full_path = (*iter_north).path().string();
318 std::size_t pos = zone_id_full_path.find_last_of(
"/");
319 std::string zone_id_str =
320 zone_id_full_path.substr(pos + 1, zone_id_full_path.length());
322 *zone_id = (std::stoi(zone_id_str));
323 AINFO <<
"Find zone id: " << *zone_id;
bool Init(const std::string &map_folder, const std::string &map_visual_folder, const std::string &pcd_folder, const std::string &pcd_timestamp_file, const std::string &gnss_loc_file, const std::string &lidar_loc_file, const std::string &fusion_loc_file, const std::string &extrinsic_file)
bool GetZoneIdFromMapFolder(const std::string &map_folder, const unsigned int resolution_id, int *zone_id)
~OfflineLocalVisualizer()
static void PoseAndStdInterpolationByTime(const ::apollo::common::EigenAffine3dVec &in_poses, const ::apollo::common::EigenVector3dVec &in_stds, const std::vector< double > &in_timestamps, const std::vector< double > &ref_timestamps, std::map< unsigned int, Eigen::Affine3d > *out_poses, std::map< unsigned int, Eigen::Vector3d > *out_stds)
T GetMaxY() const
Get the max y of the rectangle.
T GetMaxX() const
Get the max x of the rectangle.
T GetMinX() const
Get the min x of the rectangle.
T GetMinY() const
Get the min y of the rectangle.
bool Init(const std::string &map_folder, const std::string &map_visual_folder, const VisualMapParam &map_param, const unsigned int resolution_id, const int zone_id, const Eigen::Affine3d &extrinsic, const unsigned int loc_info_num=1)
void Visualize(::apollo::common::EigenVector< LocalizatonInfo > &&loc_infos, const ::apollo::common::EigenVector3dVec &cloud)
unsigned int map_node_size_y_
The map node size in pixels.
std::vector< float > map_resolutions_
The pixel resolutions in the map in meters.
Rect2D< double > map_range_
The minimum and maximum UTM range in the map.
bool Load(const std::string &file_path)
Load the map option from a XML file.
unsigned int map_node_size_x_
The map node size in pixels.
std::string map_version_
The version of map.
EigenVector< Eigen::Affine3d > EigenAffine3dVec
std::vector< EigenType, Eigen::aligned_allocator< EigenType > > EigenVector
EigenVector< Eigen::Vector3d > EigenVector3dVec
void LoadPcds(const std::string &file_path, const unsigned int frame_index, const Eigen::Affine3d &pose, VelodyneFrame *velodyne_frame, bool is_global)
bool LoadExtrinsic(const std::string &file_path, Eigen::Affine3d *extrinsic)
Load the velodyne extrinsic from a YAML file.
void LoadPosesAndStds(const std::string &file_path, ::apollo::common::EigenAffine3dVec *poses, ::apollo::common::EigenVector3dVec *stds, std::vector< double > *timestamps)
Load poses and stds their timestamps.
The offline tool for localization visualization.
The data structure to store info of a localization
void set(const Eigen::Translation3d &location, const Eigen::Quaterniond &attitude, const Eigen::Vector3d &std_var, const std::string &description, const double timestamp, const unsigned int frame_id)
The data structure to store parameters of a map
void set(const std::vector< float > &map_resolutions, const unsigned int map_node_size_x, const unsigned int map_node_size_y, const double map_min_x, const double map_min_y, const double map_max_x, const double map_max_y)
The utilities of velodyne.