35 #include <pcl/common/transforms.h>
38 #include <laserProcessingClass.h>
39 #include <odomEstimationClass.h>
51 ,laserProcessing_(new LaserProcessingClass())
52 ,odomEstimation_(new OdomEstimationClass())
58 int sensor = Parameters::defaultOdomLOAMSensor();
59 double vertical_angle = 2.0;
60 float scan_period= Parameters::defaultOdomLOAMScanPeriod();
61 float max_dis = Parameters::defaultIcpRangeMax();
62 float min_dis = Parameters::defaultIcpRangeMin();
63 float map_resolution = Parameters::defaultOdomLOAMResolution();
64 linVar_ = Parameters::defaultOdomLOAMLinVar();
65 angVar_ = Parameters::defaultOdomLOAMAngVar();
78 lidar::Lidar lidar_param;
79 lidar_param.setScanPeriod(scan_period);
80 lidar_param.setVerticalAngle(vertical_angle);
81 lidar_param.setLines(sensor==2?64:sensor==1?32:16);
82 lidar_param.setMaxDistance(max_dis<=0?200:max_dis);
83 lidar_param.setMinDistance(min_dis);
85 laserProcessing_->init(lidar_param);
86 odomEstimation_->init(lidar_param, map_resolution);
93 delete laserProcessing_;
94 delete odomEstimation_;
102 lastPose_.setIdentity();
118 if(
data.laserScanRaw().isEmpty())
120 UERROR(
"LOAM works only with laser scans and the current input is empty. Aborting odometry update...");
123 else if(
data.laserScanRaw().is2d())
125 UERROR(
"LOAM version used works only with 3D laser scans from Velodyne. Aborting odometry update...");
129 cv::Mat covariance = cv::Mat::eye(6,6,CV_64FC1)*9999;
136 pcl::PointCloud<pcl::PointXYZI>::Ptr pointcloud_edge(
new pcl::PointCloud<pcl::PointXYZI>());
137 pcl::PointCloud<pcl::PointXYZI>::Ptr pointcloud_surf(
new pcl::PointCloud<pcl::PointXYZI>());
139 laserProcessing_->featureExtraction(laserCloudInPtr,pointcloud_edge,pointcloud_surf);
143 pcl::PointCloud<pcl::PointXYZI>::Ptr pointcloud_filtered(
new pcl::PointCloud<pcl::PointXYZI>());
144 *pointcloud_filtered+=*pointcloud_edge;
145 *pointcloud_filtered+=*pointcloud_surf;
149 odomEstimation_->initMapWithPoints(pointcloud_edge, pointcloud_surf);
151 odomEstimation_->updatePointsToMap(pointcloud_edge, pointcloud_surf);
159 covariance = cv::Mat::eye(6,6,CV_64FC1);
160 covariance(cv::Range(0,3), cv::Range(0,3)) *= linVar_;
161 covariance(cv::Range(3,6), cv::Range(3,6)) *= angVar_;
163 t = lastPose_.inverse() * pose;
166 const Transform & localTransform =
data.laserScanRaw().localTransform();
167 if(!
t.isNull() && !
t.isIdentity() && !localTransform.
isIdentity() && !localTransform.
isNull())
170 t = localTransform *
t * localTransform.
inverse();
176 if(covariance.cols == 6 && covariance.rows == 6 && covariance.type() == CV_64FC1)
178 info->reg.covariance = covariance;
183 pcl::PointCloud<pcl::PointXYZI>::Ptr localMap(
new pcl::PointCloud<pcl::PointXYZI>());
184 odomEstimation_->getMap(localMap);
185 info->localScanMapSize = localMap->size();
194 UWARN(
"FLOAM failed to register the latest scan, odometry should be reset.");
197 UINFO(
"Odom update time = %fs, lost=%s", timerTotal.
elapsed(), lost_?
"true":
"false");
200 UERROR(
"RTAB-Map is not built with FLOAM support! Select another odometry approach.");