Apollo 11.0
自动驾驶开放平台
lossless_map_creator.cc 文件参考
lossless_map_creator.cc 的引用(Include)关系图:

浏览源代码.

类型定义

typedef apollo::localization::msf::FeatureXYPlane::PointT PclPointT
 
typedef apollo::localization::msf::FeatureXYPlane::PointCloudT PclPointCloudT
 
typedef apollo::localization::msf::FeatureXYPlane::PointCloudPtrT PclPointCloudPtrT
 

函数

bool ParseCommandLine (int argc, char *argv[], boost::program_options::variables_map *vm)
 
void VarianceOnline (double *mean, double *var, unsigned int *N, double x)
 
int main (int argc, char **argv)
 

变量

const unsigned int CAR_SENSOR_LASER_NUMBER = 64
 

类型定义说明

◆ PclPointCloudPtrT

◆ PclPointCloudT

◆ PclPointT

函数说明

◆ main()

int main ( int  argc,
char **  argv 
)

在文件 lossless_map_creator.cc 第 110 行定义.

110 {
111 FeatureXYPlane plane_extractor;
112
113 boost::program_options::variables_map boost_args;
114 if (!ParseCommandLine(argc, argv, &boost_args)) {
115 AERROR << "Parse input command line failed.";
116 return -1;
117 }
118
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";
125 return -1;
126 }
127
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>();
131 // bool use_plane_fitting_ransac =
132 // boost_args["use_plane_fitting_ransac"].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)";
139 return -1;
140 }
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)";
146 return -1;
147 }
148
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.";
163 }
164
165 const size_t num_trials = pcd_folder_paths.size();
166
167 // load all poses
168 AINFO << "Pcd folders are as follows:";
169 for (size_t i = 0; i < num_trials; ++i) {
170 AINFO << pcd_folder_paths[i];
171 }
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]);
178 }
179
180 PyramidMapConfig conf("lossless_map");
181 PyramidMap map(&conf);
182 PyramidMapConfig& loss_less_config =
183 static_cast<PyramidMapConfig&>(map.GetMapConfig());
184 std::string map_folder_path = map_base_folder + "/lossless_map";
186 map.SetMapFolderPath(map_folder_path);
187 for (size_t i = 0; i < pcd_folder_paths.size(); ++i) {
188 map.AddDataset(pcd_folder_paths[i]);
189 }
190 if (strcasecmp(map_resolution_type.c_str(), "single") == 0) {
191 loss_less_config.SetSingleResolutions(single_resolution_map);
192 } else {
193 loss_less_config.SetMultiResolutions();
194 }
195
196 if (strcasecmp(coordinate_type.c_str(), "UTM") == 0) {
197 loss_less_config.coordinate_type_ = "UTM";
198 } else {
199 loss_less_config.coordinate_type_ = "LTM";
201 -1638400.0, -1638400.0, 1638400.0, 1638400.0);
202 }
203
204 // Output Config file
205 char file_buf[1024];
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);
209
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");
213
214 if (file) {
215 fprintf(file, "\n\nVeldoyne %uE\n", CAR_SENSOR_LASER_NUMBER);
216 fprintf(file, "Map coordinate type: %s\n",
217 loss_less_config.coordinate_type_.c_str());
218 // if (loss_less_config.coordinate_type_ == "LTM") {
219 // fprintf(file, "Map origin longitude: %lf\n",
220 // loss_less_config._origin_longitude); fprintf(file, "Map origin
221 // latitude: %lf\n", loss_less_config._origin_latitude);
222 // }
223 fprintf(file, "Map compression: %d\n",
224 loss_less_config.map_is_compression_);
225 fprintf(file, "Map resolution: ");
226 for (size_t i = 0; i < loss_less_config.map_resolutions_.size(); ++i) {
227 fprintf(file, "%lf, ", loss_less_config.map_resolutions_[i]);
228 }
229 fprintf(file, "\nMap size: %lf %lf %lf %lf\n",
230 loss_less_config.map_range_.GetMinX(),
231 loss_less_config.map_range_.GetMinY(),
232 loss_less_config.map_range_.GetMaxX(),
233 loss_less_config.map_range_.GetMaxY());
234 fprintf(file, "Map node size: %d x %d\n", loss_less_config.map_node_size_x_,
235 loss_less_config.map_node_size_y_);
236 fprintf(file, "Map row x col: \n");
237 for (size_t i = 0; i < loss_less_config.map_resolutions_.size(); ++i) {
238 fprintf(file, "%u x %u, ",
240 static_cast<unsigned int>(i)),
241 MapNodeIndex::GetMapIndexRangeEast(loss_less_config,
242 static_cast<unsigned int>(i)));
243 }
244 fprintf(file, "Map image max intensity: %lf\n",
245 loss_less_config.max_intensity_value_);
246 fprintf(file, "Map image max var: %lf\n",
247 loss_less_config.max_intensity_var_value_);
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());
251 }
252 fclose(file);
253 } else {
254 AERROR << "Can't open file: " << file_buf;
255 }
256
257 PyramidMapNodePool lossless_map_node_pool(25, 8);
258 lossless_map_node_pool.Initial(&loss_less_config);
259 map.InitMapNodeCaches(12, 24);
260 map.AttachMapNodePool(&lossless_map_node_pool);
261
262 for (unsigned int trial = 0; trial < num_trials; ++trial) {
263 for (unsigned int frame_idx = 0; frame_idx < ieout_poses[trial].size();
264 ++frame_idx) {
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
275 << ".";
276
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);
286 PyramidMapNode* map_node =
287 dynamic_cast<PyramidMapNode*>(map.GetMapNodeSafe(map_node_index));
288 map_node->GetCoordinate(pt3d_global, &col, &row);
289 PyramidMapMatrix& map_matrix =
290 dynamic_cast<PyramidMapMatrix&>(map_node->GetMapCellMatrix());
291 map_matrix.SetIntensitySafe(intensity, row, col);
292 }
293
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) {
298 PclPointT& pt = pcl_pc->at(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]);
303 }
304
305 plane_extractor.ExtractXYPlane(pcl_pc);
306 PclPointCloudPtrT& plane_pc = plane_extractor.GetXYPlaneCloud();
307
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);
320 PyramidMapNode* map_node =
321 dynamic_cast<PyramidMapNode*>(map.GetMapNodeSafe(map_node_index));
322 map_node->GetCoordinate(pt3d_global, &col, &row);
323 PyramidMapMatrix& map_matrix =
324 dynamic_cast<PyramidMapMatrix&>(map_node->GetMapCellMatrix());
325 map_matrix.SetIntensitySafe(intensity, row, col);
326 map_matrix.SetGroundAltitudeSafe(ground_altitude, row, col);
327 map_node->SetIsChanged(true);
328 }
329 }
330 }
331 }
332
333 // Compute the ground height offset
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);
346 PyramidMapNode* map_node =
347 dynamic_cast<PyramidMapNode*>(map.GetMapNodeSafe(map_node_index));
348 map_node->GetCoordinate(pt3d, &col, &row);
349 PyramidMapMatrix& map_matrix =
350 dynamic_cast<PyramidMapMatrix&>(map_node->GetMapCellMatrix());
351
352 if (use_plane_inliers_only) {
353 // Use the altitudes from layer 0 (layer 1 internally in the Map).
354 std::vector<unsigned int> layer_counts;
355 const unsigned int* ground_count =
356 map_matrix.GetGroundCountSafe(row, col);
357 if (!ground_count) {
358 AERROR << "No ground layer, skip.";
359 continue;
360 }
361 if (*ground_count > 0) {
362 // std::vector<float> layer_alts;
363 // map.GetAltSafe(pt3d, zone_id, resolution_id, &layer_alts);
364 const float* ground_altitude =
365 map_matrix.GetGroundAltitudeSafe(row, col);
366 if (!ground_altitude) {
367 AERROR << "No ground points, skip.";
368 continue;
369 }
370 // float alt = layer_alts[layer_id];
371 double height_diff = pt3d[2] - *ground_altitude;
372 VarianceOnline(&mean_height_diff, &var_height_diff,
373 &count_height_diff, height_diff);
374 }
375 } else {
376 // Use the altitudes from all layers
377 const unsigned int* count = map_matrix.GetCountSafe(row, col);
378 if (*count > 0) {
379 const float* alt = map_matrix.GetAltitudeSafe(row, col);
380 double height_diff = pt3d[2] - *alt;
381 VarianceOnline(&mean_height_diff, &var_height_diff,
382 &count_height_diff, height_diff);
383 }
384 }
385 }
386 }
387
388 map.GetMapConfig().map_ground_height_offset_ =
389 static_cast<float>(mean_height_diff);
390 std::string config_path = map.GetMapConfig().map_folder_path_ + "/config.xml";
391 map.GetMapConfig().Save(config_path);
392 ADEBUG << "Mean: " << mean_height_diff << ", Var: " << var_height_diff << ".";
393 return 0;
394}
void ExtractXYPlane(const PointCloudPtrT &cloud)
T GetMaxY() const
Get the max y of the rectangle.
Definition rect2d.h:88
T GetMaxX() const
Get the max x of the rectangle.
Definition rect2d.h:83
T GetMinX() const
Get the min x of the rectangle.
Definition rect2d.h:73
T GetMinY() const
Get the min y of the rectangle.
Definition rect2d.h:78
bool Save(const std::string &file_path)
Save the map option to a XML file.
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.
unsigned int map_node_size_x_
The map node size in pixels.
void SetSingleResolutions(float resolution=0.125)
Set single resolutions.
const BaseMapMatrix & GetMapCellMatrix() const
Get map cell matrix.
void SetIsChanged(bool is)
Set if the map node data has changed.
static unsigned int GetMapIndexRangeEast(const BaseMapConfig &option, unsigned int resolution_id)
Get the index range (maximum possible index + 1) in the east direction.
static MapNodeIndex GetMapNodeIndex(const BaseMapConfig &option, const Eigen::Vector3d &coordinate, unsigned int resolution_id, int zone_id)
Construct a map node index, given a global coordinate, eigen version.
static unsigned int GetMapIndexRangeNorth(const BaseMapConfig &option, unsigned int resolution_id)
Get the index range (maximum possible index + 1) in the north direction.
float max_intensity_value_
During the visualization (for example, Call the function get_image() of map node layer),...
float max_intensity_var_value_
During the visualization (for example, Call the function get_image() of map node layer),...
const unsigned int * GetGroundCountSafe(unsigned int row, unsigned int col, unsigned int level=0) const
Get a ground count value by check.
void SetGroundAltitudeSafe(float ground_altitude, unsigned int row, unsigned int col, unsigned int level=0)
Set an altitude ground value by check.
const float * GetAltitudeSafe(unsigned int row, unsigned int col, unsigned int level=0) const
Get an altitude value by check.
const unsigned int * GetCountSafe(unsigned int row, unsigned int col, unsigned int level=0) const
Get a count value by check.
const float * GetGroundAltitudeSafe(unsigned int row, unsigned int col, unsigned int level=0) const
Get an altitude ground value by check.
void SetIntensitySafe(float intensity, unsigned int row, unsigned int col, unsigned int level=0)
Set an intensity value by check.
bool GetCoordinate(const Eigen::Vector2d &coordinate, unsigned int level, unsigned int *x, unsigned int *y) const
Given the global coordinate, get the local 2D coordinate of the map cell matrix.
#define ADEBUG
Definition log.h:41
#define AERROR
Definition log.h:44
#define AINFO
Definition log.h:42
#define AWARN
Definition log.h:43
void VarianceOnline(double *mean, double *var, unsigned int *N, double x)
apollo::localization::msf::FeatureXYPlane::PointT PclPointT
apollo::localization::msf::FeatureXYPlane::PointCloudPtrT PclPointCloudPtrT
const unsigned int CAR_SENSOR_LASER_NUMBER
bool ParseCommandLine(int argc, char *argv[], boost::program_options::variables_map *vm)
apollo::localization::msf::FeatureXYPlane::PointCloudT PclPointCloudT
EigenVector< Eigen::Affine3d > EigenAffine3dVec
Definition eigen_defs.h:47
bool EnsureDirectory(const std::string &directory_path)
Check if a specified directory specified by directory_path exists.
Definition file.cc:285
void LoadPcds(const std::string &file_path, const unsigned int frame_index, const Eigen::Affine3d &pose, VelodyneFrame *velodyne_frame, bool is_global)
void LoadPcdPoses(const std::string &file_path, ::apollo::common::EigenAffine3dVec *poses, std::vector< double > *timestamps)
Load the PCD poses with their timestamps.
::apollo::common::EigenVector3dVec pt3ds
The 3D point cloud in this frame.
std::vector< unsigned char > intensities
The laser reflection values in this frames.
Eigen::Affine3d pose
The pose of the frame.

◆ ParseCommandLine()

bool ParseCommandLine ( int  argc,
char *  argv[],
boost::program_options::variables_map *  vm 
)

在文件 lossless_map_creator.cc 第 44 行定义.

45 {
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")
51 // ("use_plane_fitting_ransac",
52 // boost::program_options::value<bool>()->required(),
53 // "use plane fitting ransac")
54 ("pcd_folders",
55 boost::program_options::value<std::vector<std::string>>()
56 ->multitoken()
57 ->composing()
58 ->required(),
59 "pcd folders(repeated)")(
60 "pose_files",
61 boost::program_options::value<std::vector<std::string>>()
62 ->multitoken()
63 ->composing()
64 ->required(),
65 "pose files(repeated)")(
66 "map_folder",
67 boost::program_options::value<std::string>()->required(),
68 "map folder")(
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")(
76 "resolution",
77 boost::program_options::value<float>()->default_value(0.125),
78 "optional: resolution for single resolution generation, default: "
79 "0.125");
80 try {
81 boost::program_options::store(
82 boost::program_options::parse_command_line(argc, argv, desc), *vm);
83 if (vm->count("help")) {
84 AERROR << desc;
85 return false;
86 }
87 boost::program_options::notify(*vm);
88 } catch (std::exception& e) {
89 AERROR << "Error: " << e.what() << " " << desc;
90 return false;
91 } catch (...) {
92 AERROR << "Unknown error!";
93 return false;
94 }
95 return true;
96}

◆ VarianceOnline()

void VarianceOnline ( double *  mean,
double *  var,
unsigned int *  N,
double  x 
)

在文件 lossless_map_creator.cc 第 98 行定义.

98 {
99 ++(*N);
100 double value = (x - (*mean)) / (*N);
101 double v1 = x - (*mean);
102 (*mean) += value;
103 double v2 = x - (*mean);
104 (*var) = (((*N) - 1) * (*var) + v1 * v2) / (*N);
105}

变量说明

◆ CAR_SENSOR_LASER_NUMBER

const unsigned int CAR_SENSOR_LASER_NUMBER = 64

在文件 lossless_map_creator.cc 第 30 行定义.