ORBSLAM3轨迹对齐C++代码
时间: 2023-11-14 18:09:19 浏览: 96
ORBSLAM3是一个视觉SLAM系统,它可以在没有先验地图的情况下从单目、双目和RGB-D相机中提取出环境的三维信息。在ORBSLAM3中,轨迹对齐是一个重要的步骤,它可以将多个视觉SLAM系统的轨迹对齐到同一个坐标系中。以下是ORBSLAM3轨迹对齐的C++代码:
```c++
void Optimizer::BundleAdjustment(const vector<Frame>& vFrames, const vector<MapPoint*>& vpMapPoints, bool* pbStopFlag, const unsigned long nLoopKF, const bool bRobust)
{
// Create optimization problem
ceres::Problem problem;
ceres::LossFunction* loss_function = bRobust ? new ceres::HuberLoss(2.0) : NULL;
// Add pose blocks
for(size_t i=0; i<vFrames.size(); i++)
{
if(vFrames[i].isBad())
continue;
const cv::Mat Rcw = vFrames[i].GetRotation();
const cv::Mat tcw = vFrames[i].GetTranslation();
// Global pose optimization is disabled for the first and second frames
if(vFrames[i].mnId != 0 && vFrames[i].mnId != 1)
{
double angleAxis[3];
ceres::RotationMatrixToAngleAxis((const double*)Rcw.data, angleAxis);
problem.AddParameterBlock(angleAxis, 3, new ceres::EigenQuaternionParameterization());
problem.AddParameterBlock((double*)tcw.data, 3);
if(i==0)
{
problem.SetParameterBlockConstant(angleAxis);
problem.SetParameterBlockConstant((double*)tcw.data);
}
else
{
if(vFrames[i].mnId == nLoopKF)
{
ceres::LocalParameterization* quaternion_local_parameterization = new ceres::QuaternionParameterization;
problem.SetParameterization(angleAxis, quaternion_local_parameterization);
}
}
}
}
// Add point blocks
for(size_t i=0; i<vpMapPoints.size(); i++)
{
MapPoint* pMP = vpMapPoints[i];
if(pMP==NULL || pMP->isBad())
continue;
ceres::CostFunction* cost_function = ReprojectionError::Create(pMP->GetObservationList(), pMP->GetWorldPos());
vector<Frame*> vObservingFrames = pMP->GetObservingFrames();
for(size_t j=0; j<vObservingFrames.size(); j++)
{
Frame* pFrame = vObservingFrames[j];
if(pFrame->isBad())
continue;
ceres::LossFunction* frame_loss_function = vObservingFrames[j]->mnId == nLoopKF ? loss_function : NULL;
double angleAxis[3];
ceres::RotationMatrixToAngleAxis((const double*)(pFrame->GetRotation().data), angleAxis);
problem.AddResidualBlock(cost_function, frame_loss_function, angleAxis, (double*)(pFrame->GetTranslation().data), pMP->GetWorldPos());
}
}
// Set solver options
ceres::Solver::Options options;
options.linear_solver_type = ceres::DENSE_SCHUR;
options.max_num_iterations = 40;
options.num_threads = 4;
options.trust_region_strategy_type = ceres::DOGLEG;
options.minimizer_progress_to_stdout = false;
options.check_gradients = false;
options.gradient_check_relative_precision = 1e-4;
options.gradient_check_numeric_derivative_relative_step_size = 1e-5;
// Solve the optimization problem
ceres::Solver::Summary summary;
ceres::Solve(options, &problem, &summary);
if(pbStopFlag)
if(*pbStopFlag)
return;
// Update keyframe poses
for(size_t i=0; i<vFrames.size(); i++)
{
if(vFrames[i].isBad())
continue;
double angleAxis[3];
if(vFrames[i].mnId != 0 && vFrames[i].mnId != 1)
{
ceres::AngleAxisToQuaternion((const double*)vFrames[i].GetRotation().data, angleAxis);
Eigen::Quaterniond q = Eigen::Map<Eigen::Quaterniond>(angleAxis);
cv::Mat Rcw(q.toRotationMatrix());
cv::Mat tcw = cv::Mat(3,1,CV_64F,vFrames[i].GetTranslation().data);
vFrames[i].SetPose(Rcw,tcw);
}
}
// Update map points
for(size_t i=0; i<vpMapPoints.size(); i++)
{
MapPoint* pMP = vpMapPoints[i];
if(pMP==NULL || pMP->isBad())
continue;
pMP->UpdateNormalAndDepth();
}
}
```
该代码使用Ceres进行优化,将视觉SLAM系统的所有帧和地图点作为优化问题的参数,使用重投影误差作为代价函数,最小化重投影误差,从而优化相机位姿和地图点位置。该代码还包括了一些优化器参数和选项,如线性求解器类型、最大迭代次数、线程数等。
阅读全文