45 boost::program_options::variables_map* vm) {
46 boost::program_options::options_description desc(
"Allowd options");
47 desc.add_options()(
"help",
"product help message")(
48 "use_plane_inliers_only",
49 boost::program_options::value<bool>()->required(),
50 "use plane inliers only")
55 boost::program_options::value<std::vector<std::string>>()
59 "pcd folders(repeated)")(
61 boost::program_options::value<std::vector<std::string>>()
65 "pose files(repeated)")(
67 boost::program_options::value<std::string>()->required(),
69 "zone_id", boost::program_options::value<int>()->required(),
70 "zone id")(
"coordinate_type",
71 boost::program_options::value<std::string>()->required(),
72 "coordinate type: UTM or LTM")(
73 "map_resolution_type",
74 boost::program_options::value<std::string>()->required(),
75 "map resolution type: single or multi")(
77 boost::program_options::value<float>()->default_value(0.125),
78 "optional: resolution for single resolution generation, default: "
81 boost::program_options::store(
82 boost::program_options::parse_command_line(argc, argv, desc), *vm);
83 if (vm->count(
"help")) {
87 boost::program_options::notify(*vm);
88 }
catch (std::exception& e) {
89 AERROR <<
"Error: " << e.what() <<
" " << desc;
92 AERROR <<
"Unknown error!";
110int main(
int argc,
char** argv) {
113 boost::program_options::variables_map boost_args;
115 AERROR <<
"Parse input command line failed.";
119 const std::vector<std::string> pcd_folder_paths =
120 boost_args[
"pcd_folders"].as<std::vector<std::string>>();
121 const std::vector<std::string> pose_files =
122 boost_args[
"pose_files"].as<std::vector<std::string>>();
123 if (pcd_folder_paths.size() != pose_files.size()) {
124 AERROR <<
"The count of pcd folders is not equal pose files";
128 const std::string map_base_folder =
129 boost_args[
"map_folder"].as<std::string>();
130 bool use_plane_inliers_only = boost_args[
"use_plane_inliers_only"].as<
bool>();
133 const int zone_id = boost_args[
"zone_id"].as<
int>();
134 const std::string coordinate_type =
135 boost_args[
"coordinate_type"].as<std::string>();
136 if (strcasecmp(coordinate_type.c_str(),
"UTM") != 0 &&
137 strcasecmp(coordinate_type.c_str(),
"LTM") != 0) {
138 AERROR <<
"Coordinate type invalid. (UTM or LTM)";
141 const std::string map_resolution_type =
142 boost_args[
"map_resolution_type"].as<std::string>();
143 if (strcasecmp(map_resolution_type.c_str(),
"single") != 0 &&
144 strcasecmp(map_resolution_type.c_str(),
"multi") != 0) {
145 AERROR <<
"Map resolution type invalid. (single or multi)";
149 float single_resolution_map = boost_args[
"resolution"].as<
float>();
150 if (fabs(single_resolution_map - 0.03125) > 1e-8 &&
151 fabs(single_resolution_map - 0.0625) > 1e-8 &&
152 fabs(single_resolution_map - 0.125) < 1e-8 &&
153 fabs(single_resolution_map - 0.25) < 1e-8 &&
154 fabs(single_resolution_map - 0.5) < 1e-8 &&
155 fabs(single_resolution_map - 1.0) < 1e-8 &&
156 fabs(single_resolution_map - 2.0) < 1e-8 &&
157 fabs(single_resolution_map - 4.0) < 1e-8 &&
158 fabs(single_resolution_map - 8.0) < 1e-8 &&
159 fabs(single_resolution_map - 16.0) < 1e-8) {
160 AWARN <<
"Map resolution can only be: 0.03125, "
161 <<
"0.0625, 0.125, 0.25, 0.5, 1.0, 2.0, "
162 <<
"4.0, 8.0 or 16.0.";
165 const size_t num_trials = pcd_folder_paths.size();
168 AINFO <<
"Pcd folders are as follows:";
169 for (
size_t i = 0; i < num_trials; ++i) {
170 AINFO << pcd_folder_paths[i];
172 std::vector<EigenAffine3dVec> ieout_poses(num_trials);
173 std::vector<std::vector<double>> time_stamps(num_trials);
174 std::vector<std::vector<unsigned int>> pcd_indices(num_trials);
175 for (
size_t i = 0; i < pose_files.size(); ++i) {
177 pose_files[i], &ieout_poses[i], &time_stamps[i], &pcd_indices[i]);
184 std::string map_folder_path = map_base_folder +
"/lossless_map";
187 for (
size_t i = 0; i < pcd_folder_paths.size(); ++i) {
190 if (strcasecmp(map_resolution_type.c_str(),
"single") == 0) {
196 if (strcasecmp(coordinate_type.c_str(),
"UTM") == 0) {
201 -1638400.0, -1638400.0, 1638400.0, 1638400.0);
206 snprintf(file_buf,
sizeof(file_buf),
"%s/lossless_map/config.xml",
207 map_base_folder.c_str());
208 loss_less_config.
Save(file_buf);
210 snprintf(file_buf,
sizeof(file_buf),
"%s/lossless_map/config.txt",
211 map_base_folder.c_str());
212 FILE* file = fopen(file_buf,
"a");
216 fprintf(file,
"Map coordinate type: %s\n",
223 fprintf(file,
"Map compression: %d\n",
225 fprintf(file,
"Map resolution: ");
229 fprintf(file,
"\nMap size: %lf %lf %lf %lf\n",
234 fprintf(file,
"Map node size: %d x %d\n", loss_less_config.
map_node_size_x_,
236 fprintf(file,
"Map row x col: \n");
238 fprintf(file,
"%u x %u, ",
240 static_cast<unsigned int>(i)),
242 static_cast<unsigned int>(i)));
244 fprintf(file,
"Map image max intensity: %lf\n",
246 fprintf(file,
"Map image max var: %lf\n",
248 fprintf(file,
"PCD folders: \n");
249 for (
unsigned int trial = 0; trial < num_trials; ++trial) {
250 fprintf(file,
"%s\n", pcd_folder_paths[trial].c_str());
254 AERROR <<
"Can't open file: " << file_buf;
258 lossless_map_node_pool.
Initial(&loss_less_config);
262 for (
unsigned int trial = 0; trial < num_trials; ++trial) {
263 for (
unsigned int frame_idx = 0; frame_idx < ieout_poses[trial].size();
265 unsigned int trial_frame_idx = frame_idx;
266 const EigenAffine3dVec& poses = ieout_poses[trial];
268 std::string pcd_file_path = absl::StrCat(
269 pcd_folder_paths[trial],
"/", pcd_indices[trial][frame_idx],
".pcd");
270 const Eigen::Affine3d& pcd_pose = poses[trial_frame_idx];
272 pcd_file_path, trial_frame_idx, pcd_pose, &velodyne_frame,
false);
273 AINFO <<
"Loaded " << velodyne_frame.
pt3ds.size()
274 <<
"3D Points at Trial: " << trial <<
" Frame: " << trial_frame_idx
277 unsigned int resolution_id = 0;
278 unsigned int row = 0;
279 unsigned int col = 0;
280 for (
size_t i = 0; i < velodyne_frame.
pt3ds.size(); ++i) {
281 Eigen::Vector3d& pt3d_local = velodyne_frame.
pt3ds[i];
282 unsigned char intensity = velodyne_frame.
intensities[i];
283 Eigen::Vector3d pt3d_global = velodyne_frame.
pose * pt3d_local;
285 loss_less_config, pt3d_global, resolution_id, zone_id);
294 if (use_plane_inliers_only) {
296 pcl_pc->resize(velodyne_frame.
pt3ds.size());
297 for (
size_t i = 0; i < velodyne_frame.
pt3ds.size(); ++i) {
299 pt.x =
static_cast<float>(velodyne_frame.
pt3ds[i][0]);
300 pt.y =
static_cast<float>(velodyne_frame.
pt3ds[i][1]);
301 pt.z =
static_cast<float>(velodyne_frame.
pt3ds[i][2]);
302 pt.intensity =
static_cast<float>(velodyne_frame.
intensities[i]);
308 for (
unsigned int k = 0; k < plane_pc->size(); ++k) {
309 const PclPointT& plane_pt = plane_pc->at(k);
310 Eigen::Vector3d pt3d_local_double;
311 pt3d_local_double[0] = plane_pt.x;
312 pt3d_local_double[1] = plane_pt.y;
313 pt3d_local_double[2] = plane_pt.z;
314 unsigned char intensity =
315 static_cast<unsigned char>(plane_pt.intensity);
316 Eigen::Vector3d pt3d_global = velodyne_frame.
pose * pt3d_local_double;
317 float ground_altitude =
static_cast<float>(pt3d_global[2]);
319 loss_less_config, pt3d_global, resolution_id, zone_id);
334 double mean_height_diff = 0;
335 double var_height_diff = 0;
336 unsigned int count_height_diff = 0;
337 for (
unsigned int trial = 0; trial < num_trials; ++trial) {
338 for (
unsigned int i = 0; i < ieout_poses[trial].size(); ++i) {
339 const Eigen::Affine3d& ieout_pose = ieout_poses[trial][i];
340 const Eigen::Vector3d& pt3d = ieout_pose.translation();
341 unsigned int resolution_id = 0;
342 unsigned int row = 0;
343 unsigned int col = 0;
345 loss_less_config, pt3d, resolution_id, zone_id);
352 if (use_plane_inliers_only) {
354 std::vector<unsigned int> layer_counts;
355 const unsigned int* ground_count =
358 AERROR <<
"No ground layer, skip.";
361 if (*ground_count > 0) {
364 const float* ground_altitude =
366 if (!ground_altitude) {
367 AERROR <<
"No ground points, skip.";
371 double height_diff = pt3d[2] - *ground_altitude;
373 &count_height_diff, height_diff);
377 const unsigned int* count = map_matrix.
GetCountSafe(row, col);
380 double height_diff = pt3d[2] - *alt;
382 &count_height_diff, height_diff);
389 static_cast<float>(mean_height_diff);
392 ADEBUG <<
"Mean: " << mean_height_diff <<
", Var: " << var_height_diff <<
".";