system.cc3
bool System::MapChanged()//检查地图变化
{
static int n=0;
int curn = mpMap->GetLastBigChangeIdx();
if(n<curn)
{
n=curn;
return true;
}
else
return false;
}
void System::Reset()//系统重置
{
unique_lock<mutex> lock(mMutexReset);
mbReset = true;
}
void System::Shutdown()//关闭系统
{
mpLocalMapper->RequestFinish();//关闭地图
mpLoopCloser->RequestFinish();//关闭回环
if(mpViewer)//关闭观测
{
mpViewer->RequestFinish();
while(!mpViewer->isFinished())
usleep(5000);
}
// Wait until all thread have effectively stopped
while(!mpLocalMapper->isFinished() || !mpLoopCloser->isFinished() || mpLoopCloser->isRunningGBA())
{
usleep(5000);
}
if(mpViewer)
pangolin::BindToContext("ORB-SLAM2: Map Viewer");
}
void System::SaveTrajectoryTUM(const string &filename)//保存轨迹
{
cout << endl << "Saving camera trajectory to " << filename << " ..." << endl;
if(mSensor==MONOCULAR)
{
cerr << "ERROR: SaveTrajectoryTUM cannot be used for monocular." << endl;
return;
}
vector<KeyFrame*> vpKFs = mpMap->GetAllKeyFrames();
sort(vpKFs.begin(),vpKFs.end(),KeyFrame::lId);//给关键帧排序
// Transform all keyframes so that the first keyframe is at the origin.
//转换所有关键帧以至于这个第一帧处于起始位置
// After a loop closure the first keyframe might not be at the origin.
//在一次回环之后,第一帧或许不在起始位置了
cv::Mat Two = vpKFs[0]->GetPoseInverse();
ofstream f;
f.open(filename.c_str());
f << fixed;
// Frame pose is stored relative to its reference keyframe (which is optimized by BA and pose graph).
//帧的姿态是相对于它的参考关键帧储存的(这是由BA和姿态图优化)
// We need to get first the keyframe pose and then concatenate the relative transformation.
//我们需要首先得到参考帧位姿并且然后链接相应的转换
// Frames not localized (tracking failure) are not saved.
//追踪失败不被保存
// For each frame we have a reference keyframe (lRit), the timestamp (lT) and a flag
//对于每一帧我们有一个参考帧,这个时间标记和一个标志
// which is true when tracking failed (lbL).
//如果追踪失败了,ibl值为true
list<ORB_SLAM2::KeyFrame*>::iterator lRit = mpTracker->mlpReferences.begin();//当前帧
list<double>::iterator lT = mpTracker->mlFrameTimes.begin();//时间标记
list<bool>::iterator lbL = mpTracker->mlbLost.begin();//flag
for(list<cv::Mat>::iterator lit=mpTracker->mlRelativeFramePoses.begin(),
lend=mpTracker->mlRelativeFramePoses.end();lit!=lend;lit++, lRit++, lT++, lbL++)
{
if(*lbL)
continue;
KeyFrame* pKF = *lRit;
cv::Mat Trw = cv::Mat::eye(4,4,CV_32F);
// If the reference keyframe was culled, traverse the spanning tree to get a suitable keyframe.
//如果关键帧被剔除了,遍历生成树去得到一个适合的关键帧
while(pKF->isBad())
{
Trw = Trw*pKF->mTcp;
pKF = pKF->GetParent();
}
Trw = Trw*pKF->GetPose()*Two;
cv::Mat Tcw = (*lit)*Trw;
cv::Mat Rwc = Tcw.rowRange(0,3).colRange(0,3).t();
cv::Mat twc = -Rwc*Tcw.rowRange(0,3).col(3);
vector<float> q = Converter::toQuaternion(Rwc);
f << setprecision(6) << *lT << " " << setprecision(9) << twc.at<float>(0) << " " << twc.at<float>(1) << " " << twc.at<float>(2) << " " << q[0] << " " << q[1] << " " << q[2] << " " << q[3] << endl;
}
f.close();
cout << endl << "trajectory saved!" << endl;
}
void System::SaveKeyFrameTrajectoryTUM(const string &filename)//保存关键帧轨迹 ros_rgbd.cc调用的
{
cout << endl << "Saving keyframe trajectory to " << filename << " ..." << endl;
vector<KeyFrame*> vpKFs = mpMap->GetAllKeyFrames();//关键帧
sort(vpKFs.begin(),vpKFs.end(),KeyFrame::lId);//排序
// Transform all keyframes so that the first keyframe is at the origin.
// After a loop closure the first keyframe might not be at the origin.
//cv::Mat Two = vpKFs[0]->GetPoseInverse();
ofstream f;
f.open(filename.c_str());
f << fixed;
for(size_t i=0; i<vpKFs.size(); i++)
{
KeyFrame* pKF = vpKFs[i];
// pKF->SetPose(pKF->GetPose()*Two);
if(pKF->isBad())
continue;
//得到R,t
cv::Mat R = pKF->GetRotation().t();
vector<float> q = Converter::toQuaternion(R);
cv::Mat t = pKF->GetCameraCenter();
f << setprecision(6) << pKF->mTimeStamp << setprecision(7) << " " << t.at<float>(0) << " " << t.at<float>(1) << " " << t.at<float>(2)
<< " " << q[0] << " " << q[1] << " " << q[2] << " " << q[3] << endl;//保存
}
f.close();
cout << endl << "trajectory saved!" << endl;
}