|
@@ -753,464 +753,465 @@ void Estimator::Estimate(std::list<LidarFrame>& lidarFrameList,
|
|
|
const Eigen::Vector3d& gravity)
|
|
|
{
|
|
|
|
|
|
- int num_corner_map = 0;
|
|
|
- int num_surf_map = 0;
|
|
|
-
|
|
|
- static uint32_t frame_count = 0;
|
|
|
- int windowSize = lidarFrameList.size();
|
|
|
- Eigen::Matrix4d transformTobeMapped = Eigen::Matrix4d::Identity();
|
|
|
- Eigen::Matrix3d exRbl = exTlb.topLeftCorner(3, 3).transpose();
|
|
|
- Eigen::Vector3d exPbl = -1.0 * exRbl * exTlb.topRightCorner(3, 1);
|
|
|
-
|
|
|
- // store point to line features
|
|
|
- std::vector<std::vector<FeatureLine>> vLineFeatures(windowSize);
|
|
|
- for (auto &v : vLineFeatures)
|
|
|
+ int num_corner_map = 0;
|
|
|
+ int num_surf_map = 0;
|
|
|
+
|
|
|
+ static uint32_t frame_count = 0;
|
|
|
+ int windowSize = lidarFrameList.size();
|
|
|
+ Eigen::Matrix4d transformTobeMapped = Eigen::Matrix4d::Identity();
|
|
|
+ Eigen::Matrix3d exRbl = exTlb.topLeftCorner(3, 3).transpose();
|
|
|
+ Eigen::Vector3d exPbl = -1.0 * exRbl * exTlb.topRightCorner(3, 1);
|
|
|
+
|
|
|
+ // store point to line features
|
|
|
+ std::vector<std::vector<FeatureLine>> vLineFeatures(windowSize);
|
|
|
+ for (auto &v : vLineFeatures)
|
|
|
+ {
|
|
|
+ v.reserve(2000);
|
|
|
+ }
|
|
|
+
|
|
|
+ // store point to plan features
|
|
|
+ std::vector<std::vector<FeaturePlanVec>> vPlanFeatures(windowSize);
|
|
|
+ for (auto &v : vPlanFeatures)
|
|
|
+ {
|
|
|
+ v.reserve(2000);
|
|
|
+ }
|
|
|
+
|
|
|
+ std::vector<std::vector<FeatureNon>> vNonFeatures(windowSize);
|
|
|
+ for (auto &v : vNonFeatures)
|
|
|
+ {
|
|
|
+ v.reserve(2000);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (windowSize == SLIDEWINDOWSIZE)
|
|
|
+ {
|
|
|
+ plan_weight_tan = 0.0003;
|
|
|
+ thres_dist = 1.0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ plan_weight_tan = 0.0;
|
|
|
+ thres_dist = 25.0;
|
|
|
+ }
|
|
|
+
|
|
|
+ // excute optimize process
|
|
|
+ const int max_iters = 5;
|
|
|
+ for (int iterOpt = 0; iterOpt < max_iters; ++iterOpt)
|
|
|
+ {
|
|
|
+ //用freamelist中每帧的P和V赋值优化参数初值,
|
|
|
+ vector2double(lidarFrameList);
|
|
|
+
|
|
|
+ //create huber loss function
|
|
|
+ ceres::LossFunction *loss_function = NULL;
|
|
|
+ loss_function = new ceres::HuberLoss(0.1 / IMUIntegrator::lidar_m);
|
|
|
+ if (windowSize == SLIDEWINDOWSIZE)
|
|
|
{
|
|
|
- v.reserve(2000);
|
|
|
+ loss_function = NULL;
|
|
|
}
|
|
|
-
|
|
|
- // store point to plan features
|
|
|
- std::vector<std::vector<FeaturePlanVec>> vPlanFeatures(windowSize);
|
|
|
- for (auto &v : vPlanFeatures)
|
|
|
+ else
|
|
|
{
|
|
|
- v.reserve(2000);
|
|
|
+ loss_function = new ceres::HuberLoss(0.1 / IMUIntegrator::lidar_m);
|
|
|
}
|
|
|
|
|
|
- std::vector<std::vector<FeatureNon>> vNonFeatures(windowSize);
|
|
|
- for (auto &v : vNonFeatures)
|
|
|
+ ceres::Problem::Options problem_options;
|
|
|
+ ceres::Problem problem(problem_options);
|
|
|
+
|
|
|
+ //添加每帧数据的位姿优化变量
|
|
|
+ for (int i = 0; i < windowSize; ++i)
|
|
|
{
|
|
|
- v.reserve(2000);
|
|
|
+ //三维P和朝向(旋转向量)
|
|
|
+ problem.AddParameterBlock(para_PR[i], 6);
|
|
|
}
|
|
|
-
|
|
|
- if (windowSize == SLIDEWINDOWSIZE)
|
|
|
+ //添加每帧数据的速度优化变量
|
|
|
+ for (int i = 0; i < windowSize; ++i)
|
|
|
{
|
|
|
- plan_weight_tan = 0.0003;
|
|
|
- thres_dist = 1.0;
|
|
|
+ //三维的V,三维的bg,三维的ba
|
|
|
+ problem.AddParameterBlock(para_VBias[i], 9);
|
|
|
}
|
|
|
- else
|
|
|
+
|
|
|
+ // add IMU CostFunction
|
|
|
+ for (int f = 1; f < windowSize; ++f)
|
|
|
{
|
|
|
- plan_weight_tan = 0.0;
|
|
|
- thres_dist = 25.0;
|
|
|
+ auto frame_curr = lidarFrameList.begin();
|
|
|
+ std::advance(frame_curr, f);
|
|
|
+ problem.AddResidualBlock(Cost_NavState_PRV_Bias::Create(frame_curr->imuIntegrator,
|
|
|
+ const_cast<Eigen::Vector3d &>(gravity),
|
|
|
+ Eigen::LLT<Eigen::Matrix<double, 15, 15>>
|
|
|
+ (frame_curr->imuIntegrator.GetCovariance().inverse())
|
|
|
+ .matrixL().transpose()),
|
|
|
+ nullptr,
|
|
|
+ para_PR[f - 1],
|
|
|
+ para_VBias[f - 1],
|
|
|
+ para_PR[f],
|
|
|
+ para_VBias[f]);
|
|
|
}
|
|
|
|
|
|
- // excute optimize process
|
|
|
- const int max_iters = 5;
|
|
|
- for (int iterOpt = 0; iterOpt < max_iters; ++iterOpt)
|
|
|
+ if (last_marginalization_info)
|
|
|
{
|
|
|
- //用freamelist中每帧的P和V赋值优化参数初值,
|
|
|
- vector2double(lidarFrameList);
|
|
|
+ // construct new marginlization_factor
|
|
|
+ auto *marginalization_factor = new MarginalizationFactor(last_marginalization_info);
|
|
|
+ problem.AddResidualBlock(marginalization_factor, nullptr,
|
|
|
+ last_marginalization_parameter_blocks);
|
|
|
+ }
|
|
|
|
|
|
- //create huber loss function
|
|
|
- ceres::LossFunction *loss_function = NULL;
|
|
|
- loss_function = new ceres::HuberLoss(0.1 / IMUIntegrator::lidar_m);
|
|
|
- if (windowSize == SLIDEWINDOWSIZE)
|
|
|
- {
|
|
|
- loss_function = NULL;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- loss_function = new ceres::HuberLoss(0.1 / IMUIntegrator::lidar_m);
|
|
|
- }
|
|
|
+ Eigen::Quaterniond q_before_opti = lidarFrameList.back().Q;
|
|
|
+ Eigen::Vector3d t_before_opti = lidarFrameList.back().P;
|
|
|
|
|
|
- ceres::Problem::Options problem_options;
|
|
|
- ceres::Problem problem(problem_options);
|
|
|
+ std::vector<std::vector<ceres::CostFunction *>> edgesLine(windowSize);
|
|
|
+ std::vector<std::vector<ceres::CostFunction *>> edgesPlan(windowSize);
|
|
|
+ std::vector<std::vector<ceres::CostFunction *>> edgesNon(windowSize);
|
|
|
+ std::thread threads[3];
|
|
|
+ //添加2帧点云与local地图匹配约束
|
|
|
|
|
|
- //添加每帧数据的位姿优化变量
|
|
|
- for (int i = 0; i < windowSize; ++i)
|
|
|
- {
|
|
|
- //三维P和朝向(旋转向量)
|
|
|
- problem.AddParameterBlock(para_PR[i], 6);
|
|
|
- }
|
|
|
- //添加每帧数据的速度优化变量
|
|
|
- for (int i = 0; i < windowSize; ++i)
|
|
|
- {
|
|
|
- //三维的V,三维的bg,三维的ba
|
|
|
- problem.AddParameterBlock(para_VBias[i], 9);
|
|
|
- }
|
|
|
+ for (int f = 0; f < windowSize; ++f)
|
|
|
+ {
|
|
|
|
|
|
- // add IMU CostFunction
|
|
|
- for (int f = 1; f < windowSize; ++f)
|
|
|
- {
|
|
|
- auto frame_curr = lidarFrameList.begin();
|
|
|
- std::advance(frame_curr, f);
|
|
|
- problem.AddResidualBlock(Cost_NavState_PRV_Bias::Create(frame_curr->imuIntegrator,
|
|
|
- const_cast<Eigen::Vector3d &>(gravity),
|
|
|
- Eigen::LLT<Eigen::Matrix<double, 15, 15>>
|
|
|
- (frame_curr->imuIntegrator.GetCovariance().inverse())
|
|
|
- .matrixL().transpose()),
|
|
|
- nullptr,
|
|
|
- para_PR[f - 1],
|
|
|
- para_VBias[f - 1],
|
|
|
- para_PR[f],
|
|
|
- para_VBias[f]);
|
|
|
- }
|
|
|
+ auto frame_curr = lidarFrameList.begin();
|
|
|
+ std::advance(frame_curr, f);
|
|
|
+ transformTobeMapped = Eigen::Matrix4d::Identity();
|
|
|
+ transformTobeMapped.topLeftCorner(3, 3) = frame_curr->Q * exRbl;
|
|
|
+ transformTobeMapped.topRightCorner(3, 1) = frame_curr->Q * exPbl + frame_curr->P;
|
|
|
+
|
|
|
+ threads[0] = std::thread(&Estimator::processPointToLine, this,
|
|
|
+ std::ref(edgesLine[f]),
|
|
|
+ std::ref(vLineFeatures[f]),
|
|
|
+ std::ref(laserCloudCornerStack[f]),
|
|
|
+ std::ref(exTlb),
|
|
|
+ std::ref(transformTobeMapped));
|
|
|
+
|
|
|
+
|
|
|
+ threads[1] = std::thread(&Estimator::processPointToPlanVec, this,
|
|
|
+ std::ref(edgesPlan[f]),
|
|
|
+ std::ref(vPlanFeatures[f]),
|
|
|
+ std::ref(laserCloudSurfStack[f]),
|
|
|
+ std::ref(exTlb),
|
|
|
+ std::ref(transformTobeMapped));
|
|
|
+
|
|
|
+
|
|
|
+ threads[2] = std::thread(&Estimator::processNonFeatureICP, this,
|
|
|
+ std::ref(edgesNon[f]),
|
|
|
+ std::ref(vNonFeatures[f]),
|
|
|
+ std::ref(laserCloudNonFeatureStack[f]),
|
|
|
+ std::ref(exTlb),
|
|
|
+ std::ref(transformTobeMapped));
|
|
|
+
|
|
|
+ threads[0].join();
|
|
|
+ threads[1].join();
|
|
|
+ threads[2].join();
|
|
|
+ }
|
|
|
|
|
|
- if (last_marginalization_info)
|
|
|
- {
|
|
|
- // construct new marginlization_factor
|
|
|
- auto *marginalization_factor = new MarginalizationFactor(last_marginalization_info);
|
|
|
- problem.AddResidualBlock(marginalization_factor, nullptr,
|
|
|
- last_marginalization_parameter_blocks);
|
|
|
- }
|
|
|
|
|
|
- Eigen::Quaterniond q_before_opti = lidarFrameList.back().Q;
|
|
|
- Eigen::Vector3d t_before_opti = lidarFrameList.back().P;
|
|
|
-
|
|
|
- std::vector<std::vector<ceres::CostFunction *>> edgesLine(windowSize);
|
|
|
- std::vector<std::vector<ceres::CostFunction *>> edgesPlan(windowSize);
|
|
|
- std::vector<std::vector<ceres::CostFunction *>> edgesNon(windowSize);
|
|
|
- std::thread threads[3];
|
|
|
- //添加2帧点云与local地图匹配约束
|
|
|
-
|
|
|
- for (int f = 0; f < windowSize; ++f)
|
|
|
- {
|
|
|
-
|
|
|
- auto frame_curr = lidarFrameList.begin();
|
|
|
- std::advance(frame_curr, f);
|
|
|
- transformTobeMapped = Eigen::Matrix4d::Identity();
|
|
|
- transformTobeMapped.topLeftCorner(3, 3) = frame_curr->Q * exRbl;
|
|
|
- transformTobeMapped.topRightCorner(3, 1) = frame_curr->Q * exPbl + frame_curr->P;
|
|
|
-
|
|
|
- threads[0] = std::thread(&Estimator::processPointToLine, this,
|
|
|
- std::ref(edgesLine[f]),
|
|
|
- std::ref(vLineFeatures[f]),
|
|
|
- std::ref(laserCloudCornerStack[f]),
|
|
|
- std::ref(exTlb),
|
|
|
- std::ref(transformTobeMapped));
|
|
|
-
|
|
|
-
|
|
|
- threads[1] = std::thread(&Estimator::processPointToPlanVec, this,
|
|
|
- std::ref(edgesPlan[f]),
|
|
|
- std::ref(vPlanFeatures[f]),
|
|
|
- std::ref(laserCloudSurfStack[f]),
|
|
|
- std::ref(exTlb),
|
|
|
- std::ref(transformTobeMapped));
|
|
|
-
|
|
|
-
|
|
|
- threads[2] = std::thread(&Estimator::processNonFeatureICP, this,
|
|
|
- std::ref(edgesNon[f]),
|
|
|
- std::ref(vNonFeatures[f]),
|
|
|
- std::ref(laserCloudNonFeatureStack[f]),
|
|
|
- std::ref(exTlb),
|
|
|
- std::ref(transformTobeMapped));
|
|
|
-
|
|
|
- threads[0].join();
|
|
|
- threads[1].join();
|
|
|
- threads[2].join();
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- int cntSurf = 0;
|
|
|
- int cntCorner = 0;
|
|
|
- int cntNon = 0;
|
|
|
- if (windowSize == SLIDEWINDOWSIZE)
|
|
|
+ int cntSurf = 0;
|
|
|
+ int cntCorner = 0;
|
|
|
+ int cntNon = 0;
|
|
|
+ if (windowSize == SLIDEWINDOWSIZE)
|
|
|
+ {
|
|
|
+ thres_dist = 1.0;
|
|
|
+ if (iterOpt == 0)
|
|
|
+ {
|
|
|
+ for (int f = 0; f < windowSize; ++f)
|
|
|
{
|
|
|
- thres_dist = 1.0;
|
|
|
- if (iterOpt == 0)
|
|
|
+ int cntFtu = 0;
|
|
|
+ for (auto &e : edgesLine[f])
|
|
|
+ {
|
|
|
+ if (std::fabs(vLineFeatures[f][cntFtu].error) > 1e-5)
|
|
|
{
|
|
|
- for (int f = 0; f < windowSize; ++f)
|
|
|
- {
|
|
|
- int cntFtu = 0;
|
|
|
- for (auto &e : edgesLine[f])
|
|
|
- {
|
|
|
- if (std::fabs(vLineFeatures[f][cntFtu].error) > 1e-5)
|
|
|
- {
|
|
|
- problem.AddResidualBlock(e, loss_function, para_PR[f]);
|
|
|
- vLineFeatures[f][cntFtu].valid = true;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- vLineFeatures[f][cntFtu].valid = false;
|
|
|
- }
|
|
|
- cntFtu++;
|
|
|
- cntCorner++;
|
|
|
- }
|
|
|
-
|
|
|
- cntFtu = 0;
|
|
|
- for (auto &e : edgesPlan[f])
|
|
|
- {
|
|
|
- if (std::fabs(vPlanFeatures[f][cntFtu].error) > 1e-5)
|
|
|
- {
|
|
|
- problem.AddResidualBlock(e, loss_function, para_PR[f]);
|
|
|
- vPlanFeatures[f][cntFtu].valid = true;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- vPlanFeatures[f][cntFtu].valid = false;
|
|
|
- }
|
|
|
- cntFtu++;
|
|
|
- cntSurf++;
|
|
|
- }
|
|
|
-
|
|
|
- cntFtu = 0;
|
|
|
- for (auto &e : edgesNon[f])
|
|
|
- {
|
|
|
- if (std::fabs(vNonFeatures[f][cntFtu].error) > 1e-5)
|
|
|
- {
|
|
|
- problem.AddResidualBlock(e, loss_function, para_PR[f]);
|
|
|
- vNonFeatures[f][cntFtu].valid = true;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- vNonFeatures[f][cntFtu].valid = false;
|
|
|
- }
|
|
|
- cntFtu++;
|
|
|
- cntNon++;
|
|
|
- }
|
|
|
- }
|
|
|
+ problem.AddResidualBlock(e, loss_function, para_PR[f]);
|
|
|
+ vLineFeatures[f][cntFtu].valid = true;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- for (int f = 0; f < windowSize; ++f)
|
|
|
- {
|
|
|
- int cntFtu = 0;
|
|
|
- for (auto &e : edgesLine[f])
|
|
|
- {
|
|
|
- if (vLineFeatures[f][cntFtu].valid)
|
|
|
- {
|
|
|
- problem.AddResidualBlock(e, loss_function, para_PR[f]);
|
|
|
- }
|
|
|
- cntFtu++;
|
|
|
- cntCorner++;
|
|
|
- }
|
|
|
- cntFtu = 0;
|
|
|
- for (auto &e : edgesPlan[f])
|
|
|
- {
|
|
|
- if (vPlanFeatures[f][cntFtu].valid)
|
|
|
- {
|
|
|
- problem.AddResidualBlock(e, loss_function, para_PR[f]);
|
|
|
- }
|
|
|
- cntFtu++;
|
|
|
- cntSurf++;
|
|
|
- }
|
|
|
-
|
|
|
- cntFtu = 0;
|
|
|
- for (auto &e : edgesNon[f])
|
|
|
- {
|
|
|
- if (vNonFeatures[f][cntFtu].valid)
|
|
|
- {
|
|
|
- problem.AddResidualBlock(e, loss_function, para_PR[f]);
|
|
|
- }
|
|
|
- cntFtu++;
|
|
|
- cntNon++;
|
|
|
- }
|
|
|
- }
|
|
|
+ vLineFeatures[f][cntFtu].valid = false;
|
|
|
}
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- if (iterOpt == 0)
|
|
|
+ cntFtu++;
|
|
|
+ cntCorner++;
|
|
|
+ }
|
|
|
+
|
|
|
+ cntFtu = 0;
|
|
|
+ for (auto &e : edgesPlan[f])
|
|
|
{
|
|
|
- thres_dist = 10.0;
|
|
|
+ if (std::fabs(vPlanFeatures[f][cntFtu].error) > 1e-5)
|
|
|
+ {
|
|
|
+ problem.AddResidualBlock(e, loss_function, para_PR[f]);
|
|
|
+ vPlanFeatures[f][cntFtu].valid = true;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ vPlanFeatures[f][cntFtu].valid = false;
|
|
|
+ }
|
|
|
+ cntFtu++;
|
|
|
+ cntSurf++;
|
|
|
}
|
|
|
- else
|
|
|
+
|
|
|
+ cntFtu = 0;
|
|
|
+ for (auto &e : edgesNon[f])
|
|
|
{
|
|
|
- thres_dist = 1.0;
|
|
|
+ if (std::fabs(vNonFeatures[f][cntFtu].error) > 1e-5)
|
|
|
+ {
|
|
|
+ problem.AddResidualBlock(e, loss_function, para_PR[f]);
|
|
|
+ vNonFeatures[f][cntFtu].valid = true;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ vNonFeatures[f][cntFtu].valid = false;
|
|
|
+ }
|
|
|
+ cntFtu++;
|
|
|
+ cntNon++;
|
|
|
}
|
|
|
- for (int f = 0; f < windowSize; ++f)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ for (int f = 0; f < windowSize; ++f)
|
|
|
+ {
|
|
|
+ int cntFtu = 0;
|
|
|
+ for (auto &e : edgesLine[f])
|
|
|
{
|
|
|
- int cntFtu = 0;
|
|
|
- for (auto &e : edgesLine[f])
|
|
|
+ if (vLineFeatures[f][cntFtu].valid)
|
|
|
{
|
|
|
- if (std::fabs(vLineFeatures[f][cntFtu].error) > 1e-5)
|
|
|
- {
|
|
|
- problem.AddResidualBlock(e, loss_function, para_PR[f]);
|
|
|
- vLineFeatures[f][cntFtu].valid = true;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- vLineFeatures[f][cntFtu].valid = false;
|
|
|
- }
|
|
|
- cntFtu++;
|
|
|
- cntCorner++;
|
|
|
+ problem.AddResidualBlock(e, loss_function, para_PR[f]);
|
|
|
}
|
|
|
- cntFtu = 0;
|
|
|
- for (auto &e : edgesPlan[f])
|
|
|
+ cntFtu++;
|
|
|
+ cntCorner++;
|
|
|
+ }
|
|
|
+ cntFtu = 0;
|
|
|
+ for (auto &e : edgesPlan[f])
|
|
|
+ {
|
|
|
+ if (vPlanFeatures[f][cntFtu].valid)
|
|
|
{
|
|
|
- if (std::fabs(vPlanFeatures[f][cntFtu].error) > 1e-5)
|
|
|
- {
|
|
|
- problem.AddResidualBlock(e, loss_function, para_PR[f]);
|
|
|
- vPlanFeatures[f][cntFtu].valid = true;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- vPlanFeatures[f][cntFtu].valid = false;
|
|
|
- }
|
|
|
- cntFtu++;
|
|
|
- cntSurf++;
|
|
|
+ problem.AddResidualBlock(e, loss_function, para_PR[f]);
|
|
|
}
|
|
|
+ cntFtu++;
|
|
|
+ cntSurf++;
|
|
|
+ }
|
|
|
|
|
|
- cntFtu = 0;
|
|
|
- for (auto &e : edgesNon[f])
|
|
|
+ cntFtu = 0;
|
|
|
+ for (auto &e : edgesNon[f])
|
|
|
+ {
|
|
|
+ if (vNonFeatures[f][cntFtu].valid)
|
|
|
{
|
|
|
- if (std::fabs(vNonFeatures[f][cntFtu].error) > 1e-5)
|
|
|
- {
|
|
|
- problem.AddResidualBlock(e, loss_function, para_PR[f]);
|
|
|
- vNonFeatures[f][cntFtu].valid = true;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- vNonFeatures[f][cntFtu].valid = false;
|
|
|
- }
|
|
|
- cntFtu++;
|
|
|
- cntNon++;
|
|
|
+ problem.AddResidualBlock(e, loss_function, para_PR[f]);
|
|
|
}
|
|
|
+ cntFtu++;
|
|
|
+ cntNon++;
|
|
|
}
|
|
|
}
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (iterOpt == 0)
|
|
|
+ {
|
|
|
+ thres_dist = 10.0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ thres_dist = 1.0;
|
|
|
+ }
|
|
|
+ for (int f = 0; f < windowSize; ++f)
|
|
|
+ {
|
|
|
+ int cntFtu = 0;
|
|
|
+ for (auto &e : edgesLine[f])
|
|
|
+ {
|
|
|
+ if (std::fabs(vLineFeatures[f][cntFtu].error) > 1e-5)
|
|
|
+ {
|
|
|
+ problem.AddResidualBlock(e, loss_function, para_PR[f]);
|
|
|
+ vLineFeatures[f][cntFtu].valid = true;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ vLineFeatures[f][cntFtu].valid = false;
|
|
|
+ }
|
|
|
+ cntFtu++;
|
|
|
+ cntCorner++;
|
|
|
+ }
|
|
|
+ cntFtu = 0;
|
|
|
+ for (auto &e : edgesPlan[f])
|
|
|
+ {
|
|
|
+ if (std::fabs(vPlanFeatures[f][cntFtu].error) > 1e-5)
|
|
|
+ {
|
|
|
+ problem.AddResidualBlock(e, loss_function, para_PR[f]);
|
|
|
+ vPlanFeatures[f][cntFtu].valid = true;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ vPlanFeatures[f][cntFtu].valid = false;
|
|
|
+ }
|
|
|
+ cntFtu++;
|
|
|
+ cntSurf++;
|
|
|
+ }
|
|
|
|
|
|
- ceres::Solver::Options options;
|
|
|
- options.linear_solver_type = ceres::DENSE_SCHUR;
|
|
|
- options.trust_region_strategy_type = ceres::DOGLEG;
|
|
|
- options.max_num_iterations = 10;
|
|
|
- options.minimizer_progress_to_stdout = false;
|
|
|
- options.num_threads = 6;
|
|
|
- ceres::Solver::Summary summary;
|
|
|
+ cntFtu = 0;
|
|
|
+ for (auto &e : edgesNon[f])
|
|
|
+ {
|
|
|
+ if (std::fabs(vNonFeatures[f][cntFtu].error) > 1e-5)
|
|
|
+ {
|
|
|
+ problem.AddResidualBlock(e, loss_function, para_PR[f]);
|
|
|
+ vNonFeatures[f][cntFtu].valid = true;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ vNonFeatures[f][cntFtu].valid = false;
|
|
|
+ }
|
|
|
+ cntFtu++;
|
|
|
+ cntNon++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- ceres::Solve(options, &problem, &summary);
|
|
|
+ ceres::Solver::Options options;
|
|
|
+ options.linear_solver_type = ceres::DENSE_SCHUR;
|
|
|
+ options.trust_region_strategy_type = ceres::DOGLEG;
|
|
|
+ options.max_num_iterations = 10;
|
|
|
+ options.minimizer_progress_to_stdout = false;
|
|
|
+ options.num_threads = 6;
|
|
|
+ ceres::Solver::Summary summary;
|
|
|
|
|
|
- //将优化的结果赋值到lidarFrameList的每一帧数据
|
|
|
- double2vector(lidarFrameList);
|
|
|
+ ceres::Solve(options, &problem, &summary);
|
|
|
+ final_cost_ = summary.final_cost;
|
|
|
|
|
|
- Eigen::Quaterniond q_after_opti = lidarFrameList.back().Q;
|
|
|
- Eigen::Vector3d t_after_opti = lidarFrameList.back().P;
|
|
|
- Eigen::Vector3d V_after_opti = lidarFrameList.back().V;
|
|
|
- double deltaR = (q_before_opti.angularDistance(q_after_opti)) * 180.0 / M_PI;
|
|
|
- double deltaT = (t_before_opti - t_after_opti).norm();
|
|
|
+ //将优化的结果赋值到lidarFrameList的每一帧数据
|
|
|
+ double2vector(lidarFrameList);
|
|
|
|
|
|
- if (deltaR < 0.05 && deltaT < 0.05 || (iterOpt + 1) == max_iters)
|
|
|
+ Eigen::Quaterniond q_after_opti = lidarFrameList.back().Q;
|
|
|
+ Eigen::Vector3d t_after_opti = lidarFrameList.back().P;
|
|
|
+ Eigen::Vector3d V_after_opti = lidarFrameList.back().V;
|
|
|
+ double deltaR = (q_before_opti.angularDistance(q_after_opti)) * 180.0 / M_PI;
|
|
|
+ double deltaT = (t_before_opti - t_after_opti).norm();
|
|
|
+
|
|
|
+ if (deltaR < 0.05 && deltaT < 0.05 || (iterOpt + 1) == max_iters)
|
|
|
+ {
|
|
|
+ //printf("Frame: %d\n", frame_count++);
|
|
|
+ if (windowSize != SLIDEWINDOWSIZE) break; //此处表示IMU未初始化,
|
|
|
+ // apply marginalization
|
|
|
+ auto *marginalization_info = new MarginalizationInfo();
|
|
|
+ if (last_marginalization_info)
|
|
|
+ {
|
|
|
+ std::vector<int> drop_set;
|
|
|
+ for (int i = 0; i < static_cast<int>(last_marginalization_parameter_blocks.size()); i++)
|
|
|
{
|
|
|
- //printf("Frame: %d\n", frame_count++);
|
|
|
- if (windowSize != SLIDEWINDOWSIZE) break; //此处表示IMU未初始化,
|
|
|
- // apply marginalization
|
|
|
- auto *marginalization_info = new MarginalizationInfo();
|
|
|
- if (last_marginalization_info)
|
|
|
- {
|
|
|
- std::vector<int> drop_set;
|
|
|
- for (int i = 0; i < static_cast<int>(last_marginalization_parameter_blocks.size()); i++)
|
|
|
- {
|
|
|
- if (last_marginalization_parameter_blocks[i] == para_PR[0] ||
|
|
|
- last_marginalization_parameter_blocks[i] == para_VBias[0])
|
|
|
- drop_set.push_back(i);
|
|
|
- }
|
|
|
+ if (last_marginalization_parameter_blocks[i] == para_PR[0] ||
|
|
|
+ last_marginalization_parameter_blocks[i] == para_VBias[0])
|
|
|
+ drop_set.push_back(i);
|
|
|
+ }
|
|
|
|
|
|
- auto *marginalization_factor = new MarginalizationFactor(last_marginalization_info);
|
|
|
- auto *residual_block_info = new ResidualBlockInfo(marginalization_factor, nullptr,
|
|
|
- last_marginalization_parameter_blocks,
|
|
|
- drop_set);
|
|
|
- marginalization_info->addResidualBlockInfo(residual_block_info);
|
|
|
- }
|
|
|
+ auto *marginalization_factor = new MarginalizationFactor(last_marginalization_info);
|
|
|
+ auto *residual_block_info = new ResidualBlockInfo(marginalization_factor, nullptr,
|
|
|
+ last_marginalization_parameter_blocks,
|
|
|
+ drop_set);
|
|
|
+ marginalization_info->addResidualBlockInfo(residual_block_info);
|
|
|
+ }
|
|
|
|
|
|
- auto frame_curr = lidarFrameList.begin();
|
|
|
- std::advance(frame_curr, 1);
|
|
|
- ceres::CostFunction *IMU_Cost = Cost_NavState_PRV_Bias::Create(frame_curr->imuIntegrator,
|
|
|
- const_cast<Eigen::Vector3d &>(gravity),
|
|
|
- Eigen::LLT<Eigen::Matrix<double, 15, 15>>
|
|
|
- (frame_curr->imuIntegrator.GetCovariance().inverse())
|
|
|
- .matrixL().transpose());
|
|
|
- auto *residual_block_info = new ResidualBlockInfo(IMU_Cost, nullptr,
|
|
|
- std::vector<double *>{para_PR[0], para_VBias[0], para_PR[1], para_VBias[1]},
|
|
|
- std::vector<int>{0, 1});
|
|
|
- marginalization_info->addResidualBlockInfo(residual_block_info);
|
|
|
-
|
|
|
- int f = 0;
|
|
|
- transformTobeMapped = Eigen::Matrix4d::Identity();
|
|
|
- transformTobeMapped.topLeftCorner(3, 3) = frame_curr->Q * exRbl;
|
|
|
- transformTobeMapped.topRightCorner(3, 1) = frame_curr->Q * exPbl + frame_curr->P;
|
|
|
- edgesLine[f].clear();
|
|
|
- edgesPlan[f].clear();
|
|
|
- edgesNon[f].clear();
|
|
|
- threads[0] = std::thread(&Estimator::processPointToLine, this,
|
|
|
- std::ref(edgesLine[f]),
|
|
|
- std::ref(vLineFeatures[f]),
|
|
|
- std::ref(laserCloudCornerStack[f]),
|
|
|
- std::ref(exTlb),
|
|
|
- std::ref(transformTobeMapped));
|
|
|
-
|
|
|
- threads[1] = std::thread(&Estimator::processPointToPlanVec, this,
|
|
|
- std::ref(edgesPlan[f]),
|
|
|
- std::ref(vPlanFeatures[f]),
|
|
|
- std::ref(laserCloudSurfStack[f]),
|
|
|
- std::ref(exTlb),
|
|
|
- std::ref(transformTobeMapped));
|
|
|
-
|
|
|
- threads[2] = std::thread(&Estimator::processNonFeatureICP, this,
|
|
|
- std::ref(edgesNon[f]),
|
|
|
- std::ref(vNonFeatures[f]),
|
|
|
- std::ref(laserCloudNonFeatureStack[f]),
|
|
|
- std::ref(exTlb),
|
|
|
- std::ref(transformTobeMapped));
|
|
|
-
|
|
|
- threads[0].join();
|
|
|
- threads[1].join();
|
|
|
- threads[2].join();
|
|
|
- int cntFtu = 0;
|
|
|
- for (auto &e : edgesLine[f])
|
|
|
- {
|
|
|
- if (vLineFeatures[f][cntFtu].valid)
|
|
|
- {
|
|
|
- auto *residual_block_info = new ResidualBlockInfo(e, nullptr,
|
|
|
- std::vector<double *>{para_PR[0]},
|
|
|
- std::vector<int>{0});
|
|
|
- marginalization_info->addResidualBlockInfo(residual_block_info);
|
|
|
- }
|
|
|
- cntFtu++;
|
|
|
- }
|
|
|
- cntFtu = 0;
|
|
|
- for (auto &e : edgesPlan[f])
|
|
|
- {
|
|
|
- if (vPlanFeatures[f][cntFtu].valid)
|
|
|
- {
|
|
|
- auto *residual_block_info = new ResidualBlockInfo(e, nullptr,
|
|
|
- std::vector<double *>{para_PR[0]},
|
|
|
- std::vector<int>{0});
|
|
|
- marginalization_info->addResidualBlockInfo(residual_block_info);
|
|
|
- }
|
|
|
- cntFtu++;
|
|
|
- }
|
|
|
+ auto frame_curr = lidarFrameList.begin();
|
|
|
+ std::advance(frame_curr, 1);
|
|
|
+ ceres::CostFunction *IMU_Cost = Cost_NavState_PRV_Bias::Create(frame_curr->imuIntegrator,
|
|
|
+ const_cast<Eigen::Vector3d &>(gravity),
|
|
|
+ Eigen::LLT<Eigen::Matrix<double, 15, 15>>
|
|
|
+ (frame_curr->imuIntegrator.GetCovariance().inverse())
|
|
|
+ .matrixL().transpose());
|
|
|
+ auto *residual_block_info = new ResidualBlockInfo(IMU_Cost, nullptr,
|
|
|
+ std::vector<double *>{para_PR[0], para_VBias[0], para_PR[1], para_VBias[1]},
|
|
|
+ std::vector<int>{0, 1});
|
|
|
+ marginalization_info->addResidualBlockInfo(residual_block_info);
|
|
|
+
|
|
|
+ int f = 0;
|
|
|
+ transformTobeMapped = Eigen::Matrix4d::Identity();
|
|
|
+ transformTobeMapped.topLeftCorner(3, 3) = frame_curr->Q * exRbl;
|
|
|
+ transformTobeMapped.topRightCorner(3, 1) = frame_curr->Q * exPbl + frame_curr->P;
|
|
|
+ edgesLine[f].clear();
|
|
|
+ edgesPlan[f].clear();
|
|
|
+ edgesNon[f].clear();
|
|
|
+ threads[0] = std::thread(&Estimator::processPointToLine, this,
|
|
|
+ std::ref(edgesLine[f]),
|
|
|
+ std::ref(vLineFeatures[f]),
|
|
|
+ std::ref(laserCloudCornerStack[f]),
|
|
|
+ std::ref(exTlb),
|
|
|
+ std::ref(transformTobeMapped));
|
|
|
+
|
|
|
+ threads[1] = std::thread(&Estimator::processPointToPlanVec, this,
|
|
|
+ std::ref(edgesPlan[f]),
|
|
|
+ std::ref(vPlanFeatures[f]),
|
|
|
+ std::ref(laserCloudSurfStack[f]),
|
|
|
+ std::ref(exTlb),
|
|
|
+ std::ref(transformTobeMapped));
|
|
|
+
|
|
|
+ threads[2] = std::thread(&Estimator::processNonFeatureICP, this,
|
|
|
+ std::ref(edgesNon[f]),
|
|
|
+ std::ref(vNonFeatures[f]),
|
|
|
+ std::ref(laserCloudNonFeatureStack[f]),
|
|
|
+ std::ref(exTlb),
|
|
|
+ std::ref(transformTobeMapped));
|
|
|
+
|
|
|
+ threads[0].join();
|
|
|
+ threads[1].join();
|
|
|
+ threads[2].join();
|
|
|
+ int cntFtu = 0;
|
|
|
+ for (auto &e : edgesLine[f])
|
|
|
+ {
|
|
|
+ if (vLineFeatures[f][cntFtu].valid)
|
|
|
+ {
|
|
|
+ auto *residual_block_info = new ResidualBlockInfo(e, nullptr,
|
|
|
+ std::vector<double *>{para_PR[0]},
|
|
|
+ std::vector<int>{0});
|
|
|
+ marginalization_info->addResidualBlockInfo(residual_block_info);
|
|
|
+ }
|
|
|
+ cntFtu++;
|
|
|
+ }
|
|
|
+ cntFtu = 0;
|
|
|
+ for (auto &e : edgesPlan[f])
|
|
|
+ {
|
|
|
+ if (vPlanFeatures[f][cntFtu].valid)
|
|
|
+ {
|
|
|
+ auto *residual_block_info = new ResidualBlockInfo(e, nullptr,
|
|
|
+ std::vector<double *>{para_PR[0]},
|
|
|
+ std::vector<int>{0});
|
|
|
+ marginalization_info->addResidualBlockInfo(residual_block_info);
|
|
|
+ }
|
|
|
+ cntFtu++;
|
|
|
+ }
|
|
|
|
|
|
- cntFtu = 0;
|
|
|
- for (auto &e : edgesNon[f])
|
|
|
- {
|
|
|
- if (vNonFeatures[f][cntFtu].valid)
|
|
|
- {
|
|
|
- auto *residual_block_info = new ResidualBlockInfo(e, nullptr,
|
|
|
- std::vector<double *>{para_PR[0]},
|
|
|
- std::vector<int>{0});
|
|
|
- marginalization_info->addResidualBlockInfo(residual_block_info);
|
|
|
- }
|
|
|
- cntFtu++;
|
|
|
- }
|
|
|
+ cntFtu = 0;
|
|
|
+ for (auto &e : edgesNon[f])
|
|
|
+ {
|
|
|
+ if (vNonFeatures[f][cntFtu].valid)
|
|
|
+ {
|
|
|
+ auto *residual_block_info = new ResidualBlockInfo(e, nullptr,
|
|
|
+ std::vector<double *>{para_PR[0]},
|
|
|
+ std::vector<int>{0});
|
|
|
+ marginalization_info->addResidualBlockInfo(residual_block_info);
|
|
|
+ }
|
|
|
+ cntFtu++;
|
|
|
+ }
|
|
|
|
|
|
- marginalization_info->preMarginalize();
|
|
|
- marginalization_info->marginalize();
|
|
|
+ marginalization_info->preMarginalize();
|
|
|
+ marginalization_info->marginalize();
|
|
|
|
|
|
- std::unordered_map<long, double *> addr_shift;
|
|
|
- for (int i = 1; i < SLIDEWINDOWSIZE; i++)
|
|
|
- {
|
|
|
- addr_shift[reinterpret_cast<long>(para_PR[i])] = para_PR[i - 1];
|
|
|
- addr_shift[reinterpret_cast<long>(para_VBias[i])] = para_VBias[i - 1];
|
|
|
- }
|
|
|
- std::vector<double *> parameter_blocks = marginalization_info->getParameterBlocks(addr_shift);
|
|
|
+ std::unordered_map<long, double *> addr_shift;
|
|
|
+ for (int i = 1; i < SLIDEWINDOWSIZE; i++)
|
|
|
+ {
|
|
|
+ addr_shift[reinterpret_cast<long>(para_PR[i])] = para_PR[i - 1];
|
|
|
+ addr_shift[reinterpret_cast<long>(para_VBias[i])] = para_VBias[i - 1];
|
|
|
+ }
|
|
|
+ std::vector<double *> parameter_blocks = marginalization_info->getParameterBlocks(addr_shift);
|
|
|
|
|
|
- delete last_marginalization_info;
|
|
|
- last_marginalization_info = marginalization_info;
|
|
|
- last_marginalization_parameter_blocks = parameter_blocks;
|
|
|
- break;
|
|
|
- }
|
|
|
+ delete last_marginalization_info;
|
|
|
+ last_marginalization_info = marginalization_info;
|
|
|
+ last_marginalization_parameter_blocks = parameter_blocks;
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
- if (windowSize != SLIDEWINDOWSIZE)
|
|
|
- {
|
|
|
- for (int f = 0; f < windowSize; ++f)
|
|
|
- {
|
|
|
- edgesLine[f].clear();
|
|
|
- edgesPlan[f].clear();
|
|
|
- edgesNon[f].clear();
|
|
|
- vLineFeatures[f].clear();
|
|
|
- vPlanFeatures[f].clear();
|
|
|
- vNonFeatures[f].clear();
|
|
|
- }
|
|
|
- }
|
|
|
+ if (windowSize != SLIDEWINDOWSIZE)
|
|
|
+ {
|
|
|
+ for (int f = 0; f < windowSize; ++f)
|
|
|
+ {
|
|
|
+ edgesLine[f].clear();
|
|
|
+ edgesPlan[f].clear();
|
|
|
+ edgesNon[f].clear();
|
|
|
+ vLineFeatures[f].clear();
|
|
|
+ vPlanFeatures[f].clear();
|
|
|
+ vNonFeatures[f].clear();
|
|
|
+ }
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
}
|
|
|
void Estimator::MapIncrementLocal(const pcl::PointCloud<PointType>::Ptr& laserCloudCornerStack,
|