Apollo 10.0
自动驾驶开放平台
lidar_locator_ndt.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2018 The Apollo Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
16
18
19#include <algorithm>
20#include <sstream>
21#include <string>
22#include <utility>
23#include <vector>
24
25#include "pcl/common/transforms.h"
26#include "pcl/io/pcd_io.h"
27
28#include "cyber/common/log.h"
31
32namespace apollo {
33namespace localization {
34namespace ndt {
35
37 : config_("map_ndt_v01"), map_(&config_), map_preload_node_pool_(30, 12) {
38 Eigen::Translation3d trans(0, 0, 0);
39 Eigen::Quaterniond quat(1, 0, 0, 0);
40 velodyne_extrinsic_ = trans * quat;
41 is_initialized_ = false;
42 is_map_loaded_ = false;
43 lidar_height_ = 1.7;
44 filter_x_ = 128;
45 filter_y_ = 128;
46}
47
49
50void LidarLocatorNdt::Init(const Eigen::Affine3d& init_location,
51 unsigned int resolution_id, int zone_id) {
52 location_ = init_location;
53 resolution_id_ = resolution_id;
54 zone_id_ = zone_id;
55 pre_input_location_ = location_;
56 pre_estimate_location_ = location_;
57 pre_imu_height_ = location_.translation()(2);
58 ndt_max_iterations_ = FLAGS_ndt_max_iterations;
59 ndt_target_resolution_ = FLAGS_ndt_target_resolution;
60 ndt_line_search_step_size_ = FLAGS_ndt_line_search_step_size;
61 ndt_transformation_epsilon_ = FLAGS_ndt_transformation_epsilon;
62
63 if (!is_map_loaded_) {
64 map_preload_node_pool_.Initial(&(map_.GetMapConfig()));
65 map_.InitMapNodeCaches(12, 24);
66 map_.AttachMapNodePool(&map_preload_node_pool_);
67 map_.LoadMapArea(location_.translation(), resolution_id_, zone_id_,
68 filter_x_, filter_y_);
69 AINFO << "Locator map pre-loading is done.";
70 is_map_loaded_ = true;
71 }
72
73 // set filter
74 filter_x_ =
75 static_cast<int>(static_cast<float>(FLAGS_ndt_filter_size_x) /
76 map_.GetMapConfig().map_resolutions_[resolution_id_]);
77 filter_y_ =
78 static_cast<int>(static_cast<float>(FLAGS_ndt_filter_size_y) /
79 map_.GetMapConfig().map_resolutions_[resolution_id_]);
80 AINFO << "Filter size: " << filter_x_ << ", " << filter_y_;
81
82 // set NDT
83 AINFO << "Init NDT." << std::endl;
84 reg_.SetMaximumIterations(ndt_max_iterations_);
85 reg_.SetResolution(static_cast<float>(ndt_target_resolution_));
86 reg_.SetStepSize(ndt_line_search_step_size_);
87 reg_.SetTransformationEpsilon(ndt_transformation_epsilon_);
88
89 is_initialized_ = true;
90}
91
92void LidarLocatorNdt::LoadMap(const Eigen::Affine3d& init_location,
93 unsigned int resolution_id, int zone_id) {
94 map_preload_node_pool_.Initial(&(map_.GetMapConfig()));
95 map_.InitMapNodeCaches(12, 24);
96 map_.AttachMapNodePool(&map_preload_node_pool_);
97 map_.LoadMapArea(location_.translation(), resolution_id, zone_id, filter_x_,
98 filter_y_);
99 AINFO << "Locator map pre-loading is done.";
100 is_map_loaded_ = true;
101}
102
103void LidarLocatorNdt::SetMapFolderPath(const std::string folder_path) {
104 if (!map_.SetMapFolderPath(folder_path)) {
105 AERROR << "Map folder is invalid!";
106 }
107}
108
109void LidarLocatorNdt::SetVelodyneExtrinsic(const Eigen::Affine3d& extrinsic) {
110 velodyne_extrinsic_ = extrinsic;
111}
112
114 lidar_height_ = height;
115 AINFO << "Set height: " << lidar_height_;
116}
117
118void LidarLocatorNdt::SetOnlineCloudResolution(const float& online_resolution) {
119 proj_reslution_ = online_resolution;
120 AINFO << "Proj resolution: " << proj_reslution_;
121}
122
123int LidarLocatorNdt::Update(unsigned int frame_idx, const Eigen::Affine3d& pose,
124 const LidarFrame& lidar_frame) {
125 // Increasement from INSPVA
126 Eigen::Vector3d trans_diff =
127 pose.translation() - pre_input_location_.translation();
128 Eigen::Vector3d trans_pre_local =
129 pre_estimate_location_.translation() + trans_diff;
130 Eigen::Quaterniond quatd(pose.linear());
131 Eigen::Translation3d transd(trans_pre_local);
132 Eigen::Affine3d center_pose = transd * quatd;
133
134 Eigen::Quaterniond pose_qbn(pose.linear());
135 AINFO << "original pose: " << std::setprecision(15) << pose.translation()[0]
136 << ", " << pose.translation()[1] << ", " << pose.translation()[2]
137 << ", " << pose_qbn.x() << ", " << pose_qbn.y() << ", " << pose_qbn.z()
138 << ", " << pose_qbn.w();
139
140 // Get lidar pose Twv = Twb * Tbv
141 Eigen::Affine3d transform = center_pose * velodyne_extrinsic_;
142 predict_location_ = center_pose;
143
144// Pre-load the map nodes
145#ifdef USE_PRELOAD_MAP_NODE
146 bool map_is_ready =
147 map_.LoadMapArea(center_pose.translation(), resolution_id_, zone_id_,
148 filter_x_, filter_y_);
149 map_.PreloadMapArea(center_pose.translation(), trans_diff, resolution_id_,
150 zone_id_);
151#endif
152
153 // Online pointcloud are projected into a ndt map node. (filtered)
154 double lt_x = pose.translation()[0];
155 double lt_y = pose.translation()[1];
156 double map_resolution = map_.GetMapConfig().map_resolutions_[resolution_id_];
157 lt_x -= (map_.GetMapConfig().map_node_size_x_ * map_resolution / 2.0);
158 lt_y -= (map_.GetMapConfig().map_node_size_y_ * map_resolution / 2.0);
159
160 // Start Ndt method
161 // Convert online points to pcl pointcloud
162 apollo::common::util::Timer online_filtered_timer;
163 online_filtered_timer.Start();
164 pcl::PointCloud<pcl::PointXYZ>::Ptr online_points(
165 new pcl::PointCloud<pcl::PointXYZ>());
166 for (unsigned int i = 0; i < lidar_frame.pt_xs.size(); ++i) {
167 pcl::PointXYZ p(lidar_frame.pt_xs[i], lidar_frame.pt_ys[i],
168 lidar_frame.pt_zs[i]);
169 online_points->push_back(p);
170 }
171
172 // Filter online points
173 AINFO << "Online point cloud leaf size: " << proj_reslution_;
174 pcl::PointCloud<pcl::PointXYZ>::Ptr online_points_filtered(
175 new pcl::PointCloud<pcl::PointXYZ>());
176 pcl::VoxelGrid<pcl::PointXYZ> sor;
177 sor.setInputCloud(online_points);
178 sor.setLeafSize(proj_reslution_, proj_reslution_, proj_reslution_);
179 sor.filter(*online_points_filtered);
180 AINFO << "Online Pointcloud size: " << online_points->size() << "/"
181 << online_points_filtered->size();
182 online_filtered_timer.End("online point calc end.");
183
184 // Obtain map pointcloud
186 map_timer.Start();
187 Eigen::Vector2d left_top_coord2d(lt_x, lt_y);
188 ComposeMapCells(left_top_coord2d, zone_id_, resolution_id_,
189 map_.GetMapConfig().map_resolutions_[resolution_id_],
190 transform.inverse());
191
192 // Convert map pointcloud to local corrdinate
193 pcl::PointCloud<pcl::PointXYZ>::Ptr pcl_map_point_cloud(
194 new pcl::PointCloud<pcl::PointXYZ>());
195 for (unsigned int i = 0; i < cell_map_.size(); ++i) {
196 Leaf& le = cell_map_[i];
197 float mean_0 = static_cast<float>(le.mean_(0));
198 float mean_1 = static_cast<float>(le.mean_(1));
199 float mean_2 = static_cast<float>(le.mean_(2));
200 pcl_map_point_cloud->push_back(pcl::PointXYZ(mean_0, mean_1, mean_2));
201 }
202 map_timer.End("Map create end.");
203 // Set left top corner for reg
204 reg_.SetLeftTopCorner(map_left_top_corner_);
205 // Ndt calculation
206 reg_.SetInputTarget(cell_map_, pcl_map_point_cloud);
207 reg_.SetInputSource(online_points_filtered);
208
210 ndt_timer.Start();
211 Eigen::Matrix3d inv_R = transform.inverse().linear();
212 Eigen::Matrix4d init_matrix = Eigen::Matrix4d::Identity();
213 init_matrix.block<3, 3>(0, 0) = inv_R.inverse();
214
215 pcl::PointCloud<pcl::PointXYZ>::Ptr output_cloud(
216 new pcl::PointCloud<pcl::PointXYZ>);
217 reg_.Align(output_cloud, init_matrix.cast<float>());
218 ndt_timer.End("Ndt Align End.");
219
220 fitness_score_ = reg_.GetFitnessScore();
221 bool has_converged = reg_.HasConverged();
222 int iteration = reg_.GetFinalNumIteration();
223 Eigen::Matrix4d ndt_pose = reg_.GetFinalTransformation().cast<double>();
224 AINFO << "Ndt summary:";
225 AINFO << "Fitness Score: " << fitness_score_;
226 AINFO << "Has_converged: " << has_converged;
227 AINFO << "Iteration: %d: " << iteration;
228 AINFO << "Relative Ndt pose: " << ndt_pose(0, 3) << ", " << ndt_pose(1, 3)
229 << ", " << ndt_pose(2, 3);
230
231 // Twv
232 Eigen::Affine3d lidar_location = Eigen::Affine3d::Identity();
233 lidar_location = transform.matrix() * init_matrix.inverse() * ndt_pose;
234
235 // Save results
236 location_ = lidar_location * velodyne_extrinsic_.inverse();
237 pre_input_location_ = pose;
238 pre_estimate_location_ = location_;
239 pre_imu_height_ = location_.translation()(2);
240
241 if (map_is_ready) {
242 return 0;
243 } else {
244 return -1;
245 }
246 return 0;
247}
248
249Eigen::Affine3d LidarLocatorNdt::GetPose() const { return location_; }
250
251Eigen::Vector3d LidarLocatorNdt::GetPredictLocation() const {
252 return predict_location_.translation();
253}
254
256 return location_covariance_;
257}
258
260 const Eigen::Vector2d& left_top_coord2d, int zone_id,
261 unsigned int resolution_id, float map_pixel_resolution,
262 const Eigen::Affine3d& inverse_transform) {
264 timer.Start();
265
266 unsigned int map_node_size_x = map_.GetMapConfig().map_node_size_x_;
267 unsigned int map_node_size_y = map_.GetMapConfig().map_node_size_y_;
268 unsigned int filter_size_x = filter_x_;
269 unsigned int filter_size_y = filter_y_;
270
271 // get the left top coordinate of input online pointcloud
272 Eigen::Vector2d coord2d = left_top_coord2d;
273 coord2d[0] -= map_pixel_resolution * static_cast<float>(filter_size_x / 2);
274 coord2d[1] -= map_pixel_resolution * static_cast<float>(filter_size_y / 2);
275
276 // get the node index of left top corner and global coordinate
278 map_.GetMapConfig(), coord2d, resolution_id, zone_id);
279 NdtMapNode* map_node_lt =
280 dynamic_cast<NdtMapNode*>(map_.GetMapNodeSafe(map_id));
281 assert(map_.IsMapNodeExist(map_id));
282 unsigned int map_coord_x = 0;
283 unsigned int map_coord_y = 0;
284 map_node_lt->GetCoordinate(coord2d, &map_coord_x, &map_coord_y);
285
286 std::vector<std::vector<int>> map_nodes_zones;
287
288 int top_left_start_x = static_cast<int>(map_coord_x);
289 int top_left_start_y = static_cast<int>(map_coord_y);
290 int top_left_end_x = static_cast<int>(map_node_size_x) - 1;
291 int top_left_end_y = static_cast<int>(map_node_size_y) - 1;
292 std::vector<int> node_zone;
293 node_zone.push_back(top_left_start_x);
294 node_zone.push_back(top_left_start_y);
295 node_zone.push_back(top_left_end_x);
296 node_zone.push_back(top_left_end_y);
297 map_nodes_zones.push_back(node_zone);
298
299 int top_center_start_x = 0;
300 int top_center_start_y = top_left_start_y;
301 int top_center_end_x = static_cast<int>(map_coord_x) - 1 +
302 2 * static_cast<int>(filter_size_x / 2);
303 top_center_end_x = top_center_end_x > static_cast<int>(map_node_size_x) - 1
304 ? static_cast<int>(map_node_size_x) - 1
305 : top_center_end_x;
306 int top_center_end_y = static_cast<int>(map_node_size_y) - 1;
307 node_zone.clear();
308 node_zone.push_back(top_center_start_x);
309 node_zone.push_back(top_center_start_y);
310 node_zone.push_back(top_center_end_x);
311 node_zone.push_back(top_center_end_y);
312 map_nodes_zones.push_back(node_zone);
313
314 int top_right_start_x = 0;
315 int top_right_start_y = top_left_start_y;
316 int top_right_end_x = 2 * static_cast<int>(filter_size_x / 2) -
317 (top_left_end_x - top_left_start_x + 1) - 1;
318 int top_right_end_y = static_cast<int>(map_node_size_y) - 1;
319 node_zone.clear();
320 node_zone.push_back(top_right_start_x);
321 node_zone.push_back(top_right_start_y);
322 node_zone.push_back(top_right_end_x);
323 node_zone.push_back(top_right_end_y);
324 map_nodes_zones.push_back(node_zone);
325
326 int middle_left_start_x = top_left_start_x;
327 int middle_left_start_y = 0;
328 int middle_left_end_x = top_left_end_x;
329 int middle_left_end_y = static_cast<int>(map_coord_y) - 1 +
330 2 * static_cast<int>(filter_size_y / 2);
331 middle_left_end_y = middle_left_end_y > static_cast<int>(map_node_size_y) - 1
332 ? static_cast<int>(map_node_size_y) - 1
333 : middle_left_end_y;
334 node_zone.clear();
335 node_zone.push_back(middle_left_start_x);
336 node_zone.push_back(middle_left_start_y);
337 node_zone.push_back(middle_left_end_x);
338 node_zone.push_back(middle_left_end_y);
339 map_nodes_zones.push_back(node_zone);
340
341 int middle_center_start_x = 0;
342 int middle_center_start_y = 0;
343 int middle_center_end_x = top_center_end_x;
344 int middle_center_end_y = middle_left_end_y;
345 node_zone.clear();
346 node_zone.push_back(middle_center_start_x);
347 node_zone.push_back(middle_center_start_y);
348 node_zone.push_back(middle_center_end_x);
349 node_zone.push_back(middle_center_end_y);
350 map_nodes_zones.push_back(node_zone);
351
352 int middle_right_start_x = 0;
353 int middle_right_start_y = 0;
354 int middle_right_end_x = top_right_end_x;
355 int middle_right_end_y = middle_center_end_y;
356 node_zone.clear();
357 node_zone.push_back(middle_right_start_x);
358 node_zone.push_back(middle_right_start_y);
359 node_zone.push_back(middle_right_end_x);
360 node_zone.push_back(middle_right_end_y);
361 map_nodes_zones.push_back(node_zone);
362
363 int bottom_left_start_x = top_left_start_x;
364 int bottom_left_start_y = 0;
365 int bottom_left_end_x = top_left_end_x;
366 int bottom_left_end_y = 2 * static_cast<int>(filter_size_y / 2) -
367 (top_left_end_y - top_left_start_y + 1) - 1;
368 node_zone.clear();
369 node_zone.push_back(bottom_left_start_x);
370 node_zone.push_back(bottom_left_start_y);
371 node_zone.push_back(bottom_left_end_x);
372 node_zone.push_back(bottom_left_end_y);
373 map_nodes_zones.push_back(node_zone);
374
375 int bottom_center_start_x = middle_center_start_x;
376 int bottom_center_start_y = bottom_left_start_y;
377 int bottom_center_end_x = middle_center_end_x;
378 int bottom_center_end_y = bottom_left_end_y;
379 node_zone.clear();
380 node_zone.push_back(bottom_center_start_x);
381 node_zone.push_back(bottom_center_start_y);
382 node_zone.push_back(bottom_center_end_x);
383 node_zone.push_back(bottom_center_end_y);
384 map_nodes_zones.push_back(node_zone);
385
386 int bottom_right_start_x = middle_right_start_x;
387 int bottom_right_start_y = bottom_left_start_y;
388 int bottom_right_end_x = middle_right_end_x;
389 int bottom_right_end_y = bottom_left_end_y;
390 node_zone.clear();
391 node_zone.push_back(bottom_right_start_x);
392 node_zone.push_back(bottom_right_start_y);
393 node_zone.push_back(bottom_right_end_x);
394 node_zone.push_back(bottom_right_end_y);
395 map_nodes_zones.push_back(node_zone);
396
397 std::vector<int> start_x_indices(3, 0);
398 std::vector<int> start_y_indices(3, 0);
399 start_x_indices[0] = 0;
400 start_x_indices[1] = top_left_end_x - top_left_start_x + 1;
401 start_x_indices[2] =
402 start_x_indices[1] + top_center_end_x - top_center_start_x + 1;
403 start_y_indices[0] = 0;
404 start_y_indices[1] = top_left_end_y - top_left_start_y + 1;
405 start_y_indices[2] =
406 start_y_indices[1] + middle_center_end_y - middle_center_start_y + 1;
407
408 std::vector<std::pair<int, int>> composed_map_indices;
409 for (int y = 0; y < 3; ++y) {
410 for (int x = 0; x < 3; ++x) {
411 composed_map_indices.push_back(
412 std::make_pair(start_x_indices[x], start_y_indices[y]));
413 }
414 }
415
416 Eigen::Vector2d coord2d_center =
417 map_node_lt->GetCoordinate(map_node_size_x / 2, map_node_size_y / 2);
418
419 cell_map_.clear();
420 Eigen::Affine3d transform = inverse_transform.inverse();
421 Eigen::Vector3d R_inv_t = -transform.translation();
422 // Calculate left top corner
423 map_left_top_corner_ = Eigen::Vector3d::Zero();
424 map_left_top_corner_.block<2, 1>(0, 0) = map_node_lt->GetLeftTopCorner();
425 map_left_top_corner_ += R_inv_t;
426
427 for (int y = 0; y < 3; ++y) {
428 for (int x = 0; x < 3; ++x) {
429 if (map_nodes_zones[y * 3 + x][2] - map_nodes_zones[y * 3 + x][0] >= 0 &&
430 map_nodes_zones[y * 3 + x][3] - map_nodes_zones[y * 3 + x][1] >= 0) {
431 // get map node
432 NdtMapNode* map_node_ptr = nullptr;
433 if (x == 0 && y == 0) {
434 map_node_ptr = map_node_lt;
435 } else {
436 Eigen::Vector2d coord2d_xy;
437 coord2d_xy[0] =
438 coord2d_center[0] + static_cast<double>(x * map_node_size_x) *
439 static_cast<double>(map_pixel_resolution);
440 coord2d_xy[1] =
441 coord2d_center[1] + static_cast<double>(y * map_node_size_y) *
442 static_cast<double>(map_pixel_resolution);
443
445 map_.GetMapConfig(), coord2d_xy, resolution_id, zone_id);
446 NdtMapNode* map_node_xy =
447 dynamic_cast<NdtMapNode*>(map_.GetMapNodeSafe(map_id));
448 assert(map_.IsMapNodeExist(map_id));
449 map_node_ptr = map_node_xy;
450 }
451
452 // get map matrix
453 NdtMapMatrix& map_cells =
454 dynamic_cast<NdtMapMatrix&>(map_node_ptr->GetMapCellMatrix());
455
456 // start obtain cells in MapNdtMatrix
457 const Eigen::Vector2d& left_top_corner =
458 map_node_ptr->GetLeftTopCorner();
459 double resolution = map_node_ptr->GetMapResolution();
460 double resolution_z = map_node_ptr->GetMapResolutionZ();
461 for (int map_y = map_nodes_zones[y * 3 + x][1];
462 map_y <= map_nodes_zones[y * 3 + x][3]; ++map_y) {
463 for (int map_x = map_nodes_zones[y * 3 + x][0];
464 map_x <= map_nodes_zones[y * 3 + x][2]; ++map_x) {
465 const NdtMapCells& cell_ndt = map_cells.GetMapCell(map_y, map_x);
466 if (cell_ndt.cells_.size() > 0) {
467 for (auto it = cell_ndt.cells_.begin();
468 it != cell_ndt.cells_.end(); ++it) {
469 unsigned int cell_count = it->second.count_;
470 if (cell_count >= 6) {
471 Leaf leaf;
472 leaf.nr_points_ = static_cast<int>(cell_count);
473
474 Eigen::Vector3d eigen_point(Eigen::Vector3d::Zero());
475 eigen_point(0) = left_top_corner[0] + map_x * resolution +
476 it->second.centroid_[0];
477 eigen_point(1) = left_top_corner[1] + map_y * resolution +
478 it->second.centroid_[1];
479 eigen_point(2) =
480 resolution_z * it->first + it->second.centroid_[2];
481 leaf.mean_ = (eigen_point + R_inv_t);
482 if (it->second.is_icov_available_ == 1) {
483 leaf.icov_ = it->second.centroid_icov_.cast<double>();
484 } else {
485 leaf.nr_points_ = -1;
486 }
487
488 cell_map_.push_back(leaf);
489 }
490 }
491 }
492 }
493 }
494 }
495 }
496 }
497
498 timer.End("Compose map cells.");
499}
500
501} // namespace ndt
502} // namespace localization
503} // namespace apollo
int64_t End(const std::string &msg)
Definition perf_util.cc:55
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.
unsigned int map_node_size_x_
The map node size in pixels.
void Initial(const BaseMapConfig *map_config, bool is_fixed_size=true)
Initialize the pool.
virtual bool GetCoordinate(const Eigen::Vector2d &coordinate, unsigned int *x, unsigned int *y) const
Given the global coordinate, get the local 2D coordinate of the map cell matrix.
const BaseMapMatrix & GetMapCellMatrix() const
Get map cell matrix.
const Eigen::Vector2d & GetLeftTopCorner() const
float GetMapResolution() const
Get the resolution of this map nodex.
bool SetMapFolderPath(const std::string folder_path)
Set the directory of the map.
Definition base_map.cc:106
BaseMapNode * GetMapNodeSafe(const MapNodeIndex &index)
Return the map node, if it's not in the cache, safely load it.
Definition base_map.cc:63
virtual void InitMapNodeCaches(int cacheL1_size, int cahceL2_size)
Definition base_map.cc:40
const BaseMapConfig & GetMapConfig() const
Get the map config.
Definition base_map.h:97
virtual bool LoadMapArea(const Eigen::Vector3d &seed_pt3d, unsigned int resolution_id, unsigned int zone_id, int filter_size_x, int filter_size_y)
Load map nodes for the location calculate of this frame.
Definition base_map.cc:394
virtual void PreloadMapArea(const Eigen::Vector3d &location, const Eigen::Vector3d &trans_diff, unsigned int resolution_id, unsigned int zone_id)
Preload map nodes for the next frame location calculation.
Definition base_map.cc:263
bool IsMapNodeExist(const MapNodeIndex &index)
Check if the map node in the cache.
Definition base_map.cc:99
void AttachMapNodePool(BaseMapNodePool *p_map_node_pool)
Attach map node pointer.
Definition base_map.cc:53
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.
std::unordered_map< int, NdtMapSingleCell > cells_
The multiple altitudes of the cell.
The data structure of ndt Map matrix.
const NdtMapCells & GetMapCell(unsigned int row, unsigned int col) const
Get a const map cell.
float GetMapResolutionZ() const
Get the resolution of this map nodex.
void SetVelodyneExtrinsic(const Eigen::Affine3d &extrinsic)
Set the extrinsic calibration.
void SetMapFolderPath(const std::string folder_path)
Set the map folder.
int Update(unsigned int frame_idx, const Eigen::Affine3d &pose, const LidarFrame &lidar_frame)
Update the histogram filter.
void Init(const Eigen::Affine3d &init_location, unsigned int resolution_id, int zone_id)
Initialize the locator.
void SetOnlineCloudResolution(const float &online_resolution)
Set online cloud resolution.
Eigen::Matrix3d GetLocationCovariance() const
Get the covariance of estimated location.
Eigen::Affine3d GetPose() const
Get the current optimal pose result.
void SetLidarHeight(double height)
Set the lidar height.
void ComposeMapCells(const Eigen::Vector2d &left_top_coord2d, int zone_id, unsigned int resolution_id, float map_pixel_resolution, const Eigen::Affine3d &inverse_transform)
Compose candidate map area.
void LoadMap(const Eigen::Affine3d &init_location, unsigned int resolution_id, int zone_id)
Load map data.
void SetStepSize(double step_size)
Set/change the newton line search maximum step length.
Definition ndt_solver.h:159
void SetResolution(float resolution)
Set/change the voxel grid resolution.
Definition ndt_solver.h:140
Eigen::Matrix4f GetFinalTransformation() const
Get the final transformation matrix estimated by the registration method.
Definition ndt_solver.h:182
double GetFitnessScore(double max_range=std::numeric_limits< double >::max())
Obtain the Euclidean fitness score.
bool HasConverged() const
Return the state of convergence after the last align run.
Definition ndt_solver.h:178
void SetMaximumIterations(int nr_iterations)
Set the maximum number of iterations the internal optimization should run for.
Definition ndt_solver.h:188
int GetFinalNumIteration() const
Get the number of iterations required to calculate alignment.
Definition ndt_solver.h:175
void SetInputTarget(const std::vector< Leaf > &cell_leaf, const PointCloudTargetConstPtr &cloud)
Provide a pointer to the input target.
Definition ndt_solver.h:113
void SetLeftTopCorner(const Eigen::Vector3d &left_top_corner)
Set left top corner of target point cloud.
Definition ndt_solver.h:226
void SetInputSource(const PointCloudTargetConstPtr &cloud)
Provide a pointer to the input target.
Definition ndt_solver.h:131
void Align(PointCloudSourcePtr output, const Eigen::Matrix4f &guess)
Call the registration algorithm which estimates the transformation and returns the transformed source...
void SetTransformationEpsilon(double epsilon)
Set the transformation epsilon (maximum allowable difference between two consecutive transformations.
Definition ndt_solver.h:194
The gflags used by localization module
#define AERROR
Definition log.h:44
#define AINFO
Definition log.h:42
class register implement
Definition arena_queue.h:37
Simple structure to hold a centroid, covarince and the number of points in a leaf.
int nr_points_
Number of points contained by voxel.
Eigen::Matrix3d icov_
Inverse of voxel covariance matrix.
Eigen::Vector3d mean_
3D voxel centroid.