26 m_lidarCloudSurfMap = pcl::PointCloud<pcl::PointXYZ>::Ptr(
new pcl::PointCloud<pcl::PointXYZ>());
31 m_kdTreeEdgeMap = pcl::KdTreeFLANN<pcl::PointXYZ>::Ptr(
new pcl::KdTreeFLANN<pcl::PointXYZ>());
32 m_kdTreeSurfMap = pcl::KdTreeFLANN<pcl::PointXYZ>::Ptr(
new pcl::KdTreeFLANN<pcl::PointXYZ>());
34 m_odom = Eigen::Isometry3d::Identity();
41 const pcl::PointCloud<pcl::PointXYZ>::Ptr & edges,
42 const pcl::PointCloud<pcl::PointXYZ>::Ptr & surfaces)
52 const pcl::PointCloud<pcl::PointXYZ>::Ptr & edges,
53 const pcl::PointCloud<pcl::PointXYZ>::Ptr & surfaces)
70 pcl::PointCloud<pcl::PointXYZ>::Ptr downsampledEdgeCloud(
new pcl::PointCloud<pcl::PointXYZ>());
71 pcl::PointCloud<pcl::PointXYZ>::Ptr downsampledSurfCloud(
new pcl::PointCloud<pcl::PointXYZ>());
84 ceres::LossFunction *loss_function =
new ceres::HuberLoss(0.1);
86 ceres::Problem::Options problem_options;
87 ceres::Problem problem(problem_options);
92 ceres::Solver::Options options;
94 options.linear_solver_type = ceres::SPARSE_NORMAL_CHOLESKY;
95 options.max_num_iterations = 4;
96 options.minimizer_progress_to_stdout =
false;
97 options.check_gradients =
false;
98 options.gradient_check_relative_precision = 1e-4;
99 ceres::Solver::Summary summary;
100 ceres::Solve(options, &problem, &summary);
103 printf(
"[ updatePointsToMap ] not enough points in map to associate\n");
104 printf(
"[ updatePointsToMap ] corners: %li [ minimum required: > 10]\n",
m_lidarCloudCornerMap->points.size());
105 printf(
"[ updatePointsToMap ] surfaces: %li [ minimum required: > 50]\n",
m_lidarCloudSurfMap->points.size());
109 m_odom = Eigen::Isometry3d::Identity();
117 const std::shared_ptr<pcl::PointXYZ> & pointIn,
118 std::shared_ptr<pcl::PointXYZ> & pointOut)
120 Eigen::Vector3d pointCurrent(pointIn->x, pointIn->y, pointIn->z);
123 pointOut->x = point_w.x();
124 pointOut->y = point_w.y();
125 pointOut->z = point_w.z();
129 const pcl::PointCloud<pcl::PointXYZ>::Ptr & edgesIn,
130 pcl::PointCloud<pcl::PointXYZ>::Ptr & edgesOut,
131 const pcl::PointCloud<pcl::PointXYZ>::Ptr & surfacesIn,
132 pcl::PointCloud<pcl::PointXYZ>::Ptr & surfacesOut)
141 const pcl::PointCloud<pcl::PointXYZ>::Ptr & points,
142 const pcl::PointCloud<pcl::PointXYZ>::Ptr & map,
143 ceres::Problem & problem,
144 ceres::LossFunction *loss_function)
147 auto pointTemp = std::make_shared<pcl::PointXYZ>();
148 auto pointToAdd = std::make_shared<pcl::PointXYZ>();
149 for (
int i = 0; i < (int)points->points.size(); i++)
151 pointTemp.reset(
new pcl::PointXYZ());
152 pointToAdd.reset(
new pcl::PointXYZ(points->points[i]));
157 std::vector<int> pointSearchInd(k);
158 std::vector<float> pointSearchSqDis(k);
160 if (
m_kdTreeEdgeMap->nearestKSearch(*pointTemp, k, pointSearchInd, pointSearchSqDis) > 0) {
162 if (pointSearchSqDis[k - 1] < 1.0)
164 std::vector<Eigen::Vector3d> nearCorners;
165 Eigen::Vector3d center(0, 0, 0);
167 for (
int j = 0; j < k; j++)
170 map->points[pointSearchInd[j]].x,
171 map->points[pointSearchInd[j]].y,
172 map->points[pointSearchInd[j]].z);
173 center = center + tmp;
174 nearCorners.push_back(tmp);
177 center = center / (float)k;
178 Eigen::Matrix3d covMat = Eigen::Matrix3d::Zero();
180 for (
int j = 0; j < k; j++)
182 Eigen::Matrix<double, 3, 1> tmpZeroMean = nearCorners[j] - center;
183 covMat = covMat + tmpZeroMean * tmpZeroMean.transpose();
186 Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> saes(covMat);
187 Eigen::Vector3d unit_direction = saes.eigenvectors().col(2);
188 Eigen::Vector3d curr_point(points->points[i].x, points->points[i].y, points->points[i].z);
190 if (saes.eigenvalues()[2] > 3 * saes.eigenvalues()[1])
192 Eigen::Vector3d point_on_line = center;
193 Eigen::Vector3d point_a, point_b;
194 point_a = 0.1 * unit_direction + point_on_line;
195 point_b = -0.1 * unit_direction + point_on_line;
196 ceres::CostFunction* cost_function =
198 problem.AddResidualBlock(cost_function, loss_function,
m_parameters);
206 printf(
"not enough correct corner points: %i\n", corner_num);
212 const pcl::PointCloud<pcl::PointXYZ>::Ptr & points,
213 const pcl::PointCloud<pcl::PointXYZ>::Ptr & map,
214 ceres::Problem & problem,
215 ceres::LossFunction * lossFunction)
219 auto pointTemp = std::make_shared<pcl::PointXYZ>();
220 auto pointToAdd = std::make_shared<pcl::PointXYZ>();
221 for (
int i = 0; i < (int)points->points.size(); i++)
223 pointTemp.reset(
new pcl::PointXYZ());
224 pointToAdd.reset(
new pcl::PointXYZ(points->points[i]));
227 std::vector<int> pointSearchInd;
228 std::vector<float> pointSearchSqDis;
230 if (
m_kdTreeSurfMap->nearestKSearch(*pointTemp, k, pointSearchInd, pointSearchSqDis) > 0) {
231 if (pointSearchSqDis[k - 1] < 1.0)
233 Eigen::Matrix<double, k, 3> matA0;
234 Eigen::Matrix<double, k, 1> matB0 = -1 * Eigen::Matrix<double, k, 1>::Ones();
236 for (
int j = 0; j < k; j++)
238 matA0(j, 0) = map->points[pointSearchInd[j]].x;
239 matA0(j, 1) = map->points[pointSearchInd[j]].y;
240 matA0(j, 2) = map->points[pointSearchInd[j]].z;
243 Eigen::Vector3d norm = matA0.colPivHouseholderQr().solve(matB0);
244 double negative_OA_dot_norm = 1 / norm.norm();
247 bool planeValid =
true;
248 for (
int j = 0; j < k; j++)
253 norm(0) * map->points[pointSearchInd[j]].x +
254 norm(1) * map->points[pointSearchInd[j]].y +
255 norm(2) * map->points[pointSearchInd[j]].z + negative_OA_dot_norm) > 0.2)
261 Eigen::Vector3d curr_point(points->points[i].x, points->points[i].y, points->points[i].z);
264 ceres::CostFunction *cost_function =
266 problem.AddResidualBlock(cost_function, lossFunction,
m_parameters);
273 printf(
"not enough correct surface points: %i\n", surf_num);
278 const pcl::PointCloud<pcl::PointXYZ>::Ptr & downsampledEdgeCloud,
279 const pcl::PointCloud<pcl::PointXYZ>::Ptr & downsampledSurfCloud)
282 auto pointTemp = std::make_shared<pcl::PointXYZ>();
283 auto pointToAdd = std::make_shared<pcl::PointXYZ>();
284 for (i = 0; i < (int)downsampledEdgeCloud->points.size(); i++) {
285 pointTemp.reset(
new pcl::PointXYZ());
286 pointToAdd.reset(
new pcl::PointXYZ(downsampledEdgeCloud->points[i]));
291 for (i = 0; i < (int)downsampledSurfCloud->points.size(); i++) {
292 pointTemp.reset(
new pcl::PointXYZ());
293 pointToAdd.reset(
new pcl::PointXYZ(downsampledSurfCloud->points[i]));
310 pcl::PointCloud<pcl::PointXYZ>::Ptr tmpCorner(
new pcl::PointCloud<pcl::PointXYZ>());
311 pcl::PointCloud<pcl::PointXYZ>::Ptr tmpSurf(
new pcl::PointCloud<pcl::PointXYZ>());
327 pcl::PointCloud<pcl::PointXYZ>::Ptr & lidarCloudMap)