#ifndef LIDARFACTOR_H #define LIDARFACTOR_H #include #include #include #include #include #include #include "utils/math_tools.h" //To do: LidarKeyframeFactor.h struct LidarEdgeFactor { EIGEN_MAKE_ALIGNED_OPERATOR_NEW LidarEdgeFactor(Eigen::Vector3d curr_point_, Eigen::Vector3d last_point_a_, Eigen::Vector3d last_point_b_, Eigen::Quaterniond qlb_, Eigen::Vector3d tlb_, double s_): curr_point(curr_point_), last_point_a(last_point_a_), last_point_b(last_point_b_) { qlb = qlb_; tlb = tlb_; s = s_; } template bool operator()(const T *t, const T *q, T *residual) const { Eigen::Matrix cp{T(curr_point.x()), T(curr_point.y()), T(curr_point.z())}; Eigen::Matrix lpa{T(last_point_a.x()), T(last_point_a.y()), T(last_point_a.z())}; Eigen::Matrix lpb{T(last_point_b.x()), T(last_point_b.y()), T(last_point_b.z())}; Eigen::Quaternion q_last_curr{q[0], q[1], q[2], q[3]}; Eigen::Matrix t_last_curr{t[0], t[1], t[2]}; Eigen::Quaternion q_l_b{T(qlb.w()), T(qlb.x()), T(qlb.y()), T(qlb.z())}; Eigen::Matrix t_l_b{T(tlb.x()), T(tlb.y()), T(tlb.z())}; Eigen::Matrix lp; lp = q_last_curr * cp + t_last_curr; Eigen::Matrix nu = (lp - lpa).cross(lp - lpb); Eigen::Matrix de = lpa - lpb; residual[0] = nu.norm() / de.norm(); residual[0] *= T(s); return true; } static ceres::CostFunction *Create(const Eigen::Vector3d curr_point_, const Eigen::Vector3d last_point_a_, const Eigen::Vector3d last_point_b_, Eigen::Quaterniond qlb_, Eigen::Vector3d tlb_, double s_) { return (new ceres::AutoDiffCostFunction(new LidarEdgeFactor(curr_point_, last_point_a_, last_point_b_, qlb_, tlb_, s_))); } Eigen::Vector3d curr_point, last_point_a, last_point_b; Eigen::Quaterniond qlb; Eigen::Vector3d tlb; double s; }; struct LidarPlaneNormFactor { LidarPlaneNormFactor(Eigen::Vector3d curr_point_, Eigen::Vector3d plane_unit_norm_, Eigen::Quaterniond qlb_, Eigen::Vector3d tlb_, double negative_OA_dot_norm_, double score_): curr_point(curr_point_), plane_unit_norm(plane_unit_norm_), qlb(qlb_), tlb(tlb_), negative_OA_dot_norm(negative_OA_dot_norm_), score(score_) {} template bool operator()(const T *t, const T *q, T *residual) const { Eigen::Quaternion q_w_curr{q[0], q[1], q[2], q[3]}; Eigen::Matrix t_w_curr{t[0], t[1], t[2]}; Eigen::Matrix cp{T(curr_point.x()), T(curr_point.y()), T(curr_point.z())}; Eigen::Matrix point_w; Eigen::Quaternion q_l_b{T(qlb.w()), T(qlb.x()), T(qlb.y()), T(qlb.z())}; Eigen::Matrix t_l_b{T(tlb.x()), T(tlb.y()), T(tlb.z())}; point_w = q_l_b.inverse() * (cp - t_l_b); point_w = q_w_curr * point_w + t_w_curr; Eigen::Matrix norm(T(plane_unit_norm.x()), T(plane_unit_norm.y()), T(plane_unit_norm.z())); residual[0] = T(score) * (norm.dot(point_w) + T(negative_OA_dot_norm)); return true; } static ceres::CostFunction *Create(const Eigen::Vector3d curr_point_, const Eigen::Vector3d plane_unit_norm_, const Eigen::Quaterniond qlb_, const Eigen::Vector3d tlb_, const double negative_OA_dot_norm_, const double score_) { return (new ceres::AutoDiffCostFunction(new LidarPlaneNormFactor(curr_point_, plane_unit_norm_, qlb_, tlb_, negative_OA_dot_norm_, score_))); } Eigen::Vector3d curr_point; Eigen::Vector3d plane_unit_norm; Eigen::Quaterniond qlb; Eigen::Vector3d tlb; double negative_OA_dot_norm, score; }; struct LidarPlaneNormIncreFactor { LidarPlaneNormIncreFactor(Eigen::Vector3d curr_point_, Eigen::Vector3d plane_unit_norm_, double negative_OA_dot_norm_): curr_point(curr_point_), plane_unit_norm(plane_unit_norm_), negative_OA_dot_norm(negative_OA_dot_norm_) {} template bool operator()(const T *q, const T *t, T *residual) const { Eigen::Quaternion q_inc{q[0], q[1], q[2], q[3]}; Eigen::Matrix t_inc{t[0], t[1], t[2]}; Eigen::Matrix cp{T(curr_point.x()), T(curr_point.y()), T(curr_point.z())}; Eigen::Matrix point_w; point_w = q_inc * cp + t_inc; Eigen::Matrix norm(T(plane_unit_norm.x()), T(plane_unit_norm.y()), T(plane_unit_norm.z())); residual[0] = norm.dot(point_w) + T(negative_OA_dot_norm); return true; } static ceres::CostFunction *Create(const Eigen::Vector3d curr_point_, const Eigen::Vector3d plane_unit_norm_, const double negative_OA_dot_norm_) { return (new ceres::AutoDiffCostFunction(new LidarPlaneNormIncreFactor(curr_point_, plane_unit_norm_, negative_OA_dot_norm_))); } Eigen::Vector3d curr_point; Eigen::Vector3d plane_unit_norm; double negative_OA_dot_norm; }; #endif // LIDARFACTOR_H