지금까지 파악한 상황은 이렇다.
1. map을 저장하는 함수는 src/System.cc의 line 1403 void System::SaveATlas(int type) 이다.
void System::SaveAtlas(int type){
if(!mStrSaveAtlasToFile.empty()) // 내가 알아야할 변수1. mStrSaveAtlasToFile
// 아마도 이건 yaml 파일에 내가 적은 System.SaveAtlasToFile = "Map" 이거 일거다.
{
//clock_t start = clock();
// Save the current session
mpAtlas->PreSave(); // 아래쪽을 보면 mpAtlas가 반복해서 나오는 것을 알 수 있다.
string pathSaveFileName = "./";
pathSaveFileName = pathSaveFileName.append(mStrSaveAtlasToFile);
pathSaveFileName = pathSaveFileName.append(".osa");
string strVocabularyChecksum = CalculateCheckSum(mStrVocabularyFilePath,TEXT_FILE);
std::size_t found = mStrVocabularyFilePath.find_last_of("/\\");
string strVocabularyName = mStrVocabularyFilePath.substr(found+1);
if(type == TEXT_FILE) // File text
{
cout << "Starting to write the save text file " << endl;
std::remove(pathSaveFileName.c_str());
std::ofstream ofs(pathSaveFileName, std::ios::binary);
boost::archive::text_oarchive oa(ofs);
oa << strVocabularyName;
oa << strVocabularyChecksum;
oa << mpAtlas; // 특히 이 부분에서 map data 중에 map point일 거 같다.
// 사실, 이 map point도 3가지 종류의 데이터가 있다.
cout << "End to write the save text file" << endl;
}
else if(type == BINARY_FILE) // File binary
{
cout << "Starting to write the save binary file" << endl;
std::remove(pathSaveFileName.c_str());
std::ofstream ofs(pathSaveFileName, std::ios::binary); http://www.gisdeveloper.co.kr/?p=3847
boost::archive::binary_oarchive oa(ofs); https://www.boost.org/doc/libs/1_46_1/libs/serialization/doc/archives.html 참고할 것
oa << strVocabularyName;
oa << strVocabularyChecksum;
oa << mpAtlas;
cout << "End to write save binary file" << endl;
}
}
}
함수 내에서 사전에 정의된(내가 알아야하는) 변수는 다음과 같다.
mStrSaveATlasToFIle
mpAtlas->PreSave();
type
이 mpAtlas가 map point와 연관이 있는 것으로 추측한다. 근데, 이 map point는 사실 세가지 종류로 구성된다. 우선 우리가 상식적으로 생각하는 3D Points, 그리고 representative orb descriptor, 그리고 viewing distance가 있다.
2. 이 PreSave(); 가 src/Atlas.cc에서 line 302에 정의되어있다.
void Atlas::PreSave()
{
if(mpCurrentMap){
if(!mspMaps.empty() && mnLastInitKFidMap < mpCurrentMap->GetMaxKFid())
mnLastInitKFidMap = mpCurrentMap->GetMaxKFid()+1; //The init KF is the next of current maximum
}
struct compFunctor
{
inline bool operator()(Map* elem1 ,Map* elem2)
{
return elem1->GetId() < elem2->GetId();
}
};
std::copy(mspMaps.begin(), mspMaps.end(), std::back_inserter(mvpBackupMaps));
sort(mvpBackupMaps.begin(), mvpBackupMaps.end(), compFunctor());
std::set<GeometricCamera*> spCams(mvpCameras.begin(), mvpCameras.end());
for(Map* pMi : mvpBackupMaps)
{
if(!pMi || pMi->IsBad())
continue;
if(pMi->GetAllKeyFrames().size() == 0) {
// Empty map, erase before of save it.
SetMapBad(pMi);
continue;
}
pMi->PreSave(spCams);
}
RemoveBadMaps();
}
코드를 이해하기 보다, 그래서 이게 map points, 그 중에도 3D Points를 담고있는지만 확인하는 수준으로 공부하자.
3. 실제로 함수가 실행되는 위치(가장 중요).
대부분 복잡한 일을 수행하는 코드에서는 함수가 선언되는 위치와 실행되는 위치가 다르다. 따라서 위에서 type과 같이 단순히 숫자로 input을 받아버리는 경우, 이것의 중요성, 의미를 파악하고 실제 행동을 보기 위해서는 함수가 실행되는 부분을 봐야할 필요가 있다.
SaveAtlas가 System.cc에서 조회되는 갯수는 총 9번. 이 중에 윗부분에서 mStrSaveAtlasToFile로 조회되는 것이 3번, 그리고 중간에서 실제로 실행되며 3번 조회되고고, 아래에서 선언될 때 3번 나온다.
중간에 실행되는 코드를 보자.
src/System.cc line 552에서 Shutdown()함수의 마지막 단에서 함수가 호출된다. 여기서 아예 SaveAtlas(FileType::BINARY_FILE); 임을 확인할 수 있다.
void System::Shutdown()
{
{
unique_lock<mutex> lock(mMutexReset);
mbShutDown = true;
}
cout << "Shutdown" << endl;
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())
{
if(!mpLocalMapper->isFinished())
cout << "mpLocalMapper is not finished" << endl;
if(!mpLoopCloser->isFinished())
cout << "mpLoopCloser is not finished" << endl;
if(mpLoopCloser->isRunningGBA()){
cout << "mpLoopCloser is running GBA" << endl;
cout << "break anyway..." << endl;
break;
}
usleep(5000);
}
if(!mStrSaveAtlasToFile.empty())
{
Verbose::PrintMess("Atlas saving to file " + mStrSaveAtlasToFile, Verbose::VERBOSITY_NORMAL);
SaveAtlas(FileType::BINARY_FILE);
}
https://github.com/UZ-SLAMLab/ORB_SLAM3/issues/443
마지막 참고