LoopClosing.cc 104 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677
  1. /**
  2. * This file is part of ORB-SLAM3
  3. *
  4. * Copyright (C) 2017-2020 Carlos Campos, Richard Elvira, Juan J. Gómez Rodríguez, José M.M. Montiel and Juan D. Tardós, University of Zaragoza.
  5. * Copyright (C) 2014-2016 Raúl Mur-Artal, José M.M. Montiel and Juan D. Tardós, University of Zaragoza.
  6. *
  7. * ORB-SLAM3 is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
  8. * License as published by the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * ORB-SLAM3 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
  12. * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License along with ORB-SLAM3.
  16. * If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include "LoopClosing.h"
  19. #include "Sim3Solver.h"
  20. #include "Converter.h"
  21. #include "Optimizer.h"
  22. #include "ORBmatcher.h"
  23. #include "G2oTypes.h"
  24. #include<mutex>
  25. #include<thread>
  26. namespace ORB_SLAM3
  27. {
  28. LoopClosing::LoopClosing(Atlas *pAtlas, KeyFrameDatabase *pDB, ORBVocabulary *pVoc, const bool bFixScale):
  29. mbResetRequested(false), mbResetActiveMapRequested(false), mbFinishRequested(false), mbFinished(true), mpAtlas(pAtlas),
  30. mpKeyFrameDB(pDB), mpORBVocabulary(pVoc), mpMatchedKF(NULL), mLastLoopKFid(0), mbRunningGBA(false), mbFinishedGBA(true),
  31. mbStopGBA(false), mpThreadGBA(NULL), mbFixScale(bFixScale), mnFullBAIdx(0), mnLoopNumCoincidences(0), mnMergeNumCoincidences(0),
  32. mbLoopDetected(false), mbMergeDetected(false), mnLoopNumNotFound(0), mnMergeNumNotFound(0)
  33. {
  34. mnCovisibilityConsistencyTh = 3;
  35. mpLastCurrentKF = static_cast<KeyFrame*>(NULL);
  36. }
  37. void LoopClosing::SetTracker(Tracking *pTracker)
  38. {
  39. mpTracker=pTracker;
  40. }
  41. void LoopClosing::SetLocalMapper(LocalMapping *pLocalMapper)
  42. {
  43. mpLocalMapper=pLocalMapper;
  44. }
  45. void LoopClosing::Run()
  46. {
  47. mbFinished =false;
  48. while(1)
  49. {
  50. //NEW LOOP AND MERGE DETECTION ALGORITHM
  51. //----------------------------
  52. if(CheckNewKeyFrames())
  53. {
  54. if(mpLastCurrentKF)
  55. {
  56. mpLastCurrentKF->mvpLoopCandKFs.clear();
  57. mpLastCurrentKF->mvpMergeCandKFs.clear();
  58. }
  59. if(NewDetectCommonRegions())
  60. {
  61. if(mbMergeDetected)
  62. {
  63. if ((mpTracker->mSensor==System::IMU_MONOCULAR ||mpTracker->mSensor==System::IMU_STEREO) &&
  64. (!mpCurrentKF->GetMap()->isImuInitialized()))
  65. {
  66. cout << "IMU is not initilized, merge is aborted" << endl;
  67. }
  68. else
  69. {
  70. Verbose::PrintMess("*Merged detected", Verbose::VERBOSITY_NORMAL);
  71. Verbose::PrintMess("Number of KFs in the current map: " + to_string(mpCurrentKF->GetMap()->KeyFramesInMap()), Verbose::VERBOSITY_DEBUG);
  72. cv::Mat mTmw = mpMergeMatchedKF->GetPose();
  73. g2o::Sim3 gSmw2(Converter::toMatrix3d(mTmw.rowRange(0, 3).colRange(0, 3)),Converter::toVector3d(mTmw.rowRange(0, 3).col(3)),1.0);
  74. cv::Mat mTcw = mpCurrentKF->GetPose();
  75. g2o::Sim3 gScw1(Converter::toMatrix3d(mTcw.rowRange(0, 3).colRange(0, 3)),Converter::toVector3d(mTcw.rowRange(0, 3).col(3)),1.0);
  76. g2o::Sim3 gSw2c = mg2oMergeSlw.inverse();
  77. g2o::Sim3 gSw1m = mg2oMergeSlw;
  78. mSold_new = (gSw2c * gScw1);
  79. if(mpCurrentKF->GetMap()->IsInertial() && mpMergeMatchedKF->GetMap()->IsInertial())
  80. {
  81. if(mSold_new.scale()<0.90||mSold_new.scale()>1.1){
  82. mpMergeLastCurrentKF->SetErase();
  83. mpMergeMatchedKF->SetErase();
  84. mnMergeNumCoincidences = 0;
  85. mvpMergeMatchedMPs.clear();
  86. mvpMergeMPs.clear();
  87. mnMergeNumNotFound = 0;
  88. mbMergeDetected = false;
  89. Verbose::PrintMess("scale bad estimated. Abort merging", Verbose::VERBOSITY_NORMAL);
  90. continue;
  91. }
  92. // If inertial, force only yaw
  93. if ((mpTracker->mSensor==System::IMU_MONOCULAR ||mpTracker->mSensor==System::IMU_STEREO) &&
  94. mpCurrentKF->GetMap()->GetIniertialBA1()) // TODO, maybe with GetIniertialBA1
  95. {
  96. Eigen::Vector3d phi = LogSO3(mSold_new.rotation().toRotationMatrix());
  97. phi(0)=0;
  98. phi(1)=0;
  99. mSold_new = g2o::Sim3(ExpSO3(phi),mSold_new.translation(),1.0);
  100. }
  101. }
  102. // cout << "tw2w1: " << mSold_new.translation() << endl;
  103. // cout << "Rw2w1: " << mSold_new.rotation().toRotationMatrix() << endl;
  104. // cout << "Angle Rw2w1: " << 180*LogSO3(mSold_new.rotation().toRotationMatrix())/3.14 << endl;
  105. // cout << "scale w2w1: " << mSold_new.scale() << endl;
  106. mg2oMergeSmw = gSmw2 * gSw2c * gScw1;
  107. mg2oMergeScw = mg2oMergeSlw;
  108. // TODO UNCOMMENT
  109. if (mpTracker->mSensor==System::IMU_MONOCULAR ||mpTracker->mSensor==System::IMU_STEREO)
  110. MergeLocal2();
  111. else
  112. MergeLocal();
  113. }
  114. vdPR_CurrentTime.push_back(mpCurrentKF->mTimeStamp);
  115. vdPR_MatchedTime.push_back(mpMergeMatchedKF->mTimeStamp);
  116. vnPR_TypeRecogn.push_back(1);
  117. // Reset all variables
  118. mpMergeLastCurrentKF->SetErase();
  119. mpMergeMatchedKF->SetErase();
  120. mnMergeNumCoincidences = 0;
  121. mvpMergeMatchedMPs.clear();
  122. mvpMergeMPs.clear();
  123. mnMergeNumNotFound = 0;
  124. mbMergeDetected = false;
  125. if(mbLoopDetected)
  126. {
  127. // Reset Loop variables
  128. mpLoopLastCurrentKF->SetErase();
  129. mpLoopMatchedKF->SetErase();
  130. mnLoopNumCoincidences = 0;
  131. mvpLoopMatchedMPs.clear();
  132. mvpLoopMPs.clear();
  133. mnLoopNumNotFound = 0;
  134. mbLoopDetected = false;
  135. }
  136. }
  137. if(mbLoopDetected)
  138. {
  139. vdPR_CurrentTime.push_back(mpCurrentKF->mTimeStamp);
  140. vdPR_MatchedTime.push_back(mpLoopMatchedKF->mTimeStamp);
  141. vnPR_TypeRecogn.push_back(0);
  142. Verbose::PrintMess("*Loop detected", Verbose::VERBOSITY_NORMAL);
  143. mg2oLoopScw = mg2oLoopSlw; //*mvg2oSim3LoopTcw[nCurrentIndex];
  144. if(mpCurrentKF->GetMap()->IsInertial())
  145. {
  146. cv::Mat Twc = mpCurrentKF->GetPoseInverse();
  147. g2o::Sim3 g2oTwc(Converter::toMatrix3d(Twc.rowRange(0, 3).colRange(0, 3)),Converter::toVector3d(Twc.rowRange(0, 3).col(3)),1.0);
  148. g2o::Sim3 g2oSww_new = g2oTwc*mg2oLoopScw;
  149. Eigen::Vector3d phi = LogSO3(g2oSww_new.rotation().toRotationMatrix());
  150. //cout << "tw2w1: " << g2oSww_new.translation() << endl;
  151. //cout << "Rw2w1: " << g2oSww_new.rotation().toRotationMatrix() << endl;
  152. //cout << "Angle Rw2w1: " << 180*phi/3.14 << endl;
  153. //cout << "scale w2w1: " << g2oSww_new.scale() << endl;
  154. if (fabs(phi(0))<0.008f && fabs(phi(1))<0.008f && fabs(phi(2))<0.349f)
  155. {
  156. if(mpCurrentKF->GetMap()->IsInertial())
  157. {
  158. // If inertial, force only yaw
  159. if ((mpTracker->mSensor==System::IMU_MONOCULAR ||mpTracker->mSensor==System::IMU_STEREO) &&
  160. mpCurrentKF->GetMap()->GetIniertialBA2()) // TODO, maybe with GetIniertialBA1
  161. {
  162. phi(0)=0;
  163. phi(1)=0;
  164. g2oSww_new = g2o::Sim3(ExpSO3(phi),g2oSww_new.translation(),1.0);
  165. mg2oLoopScw = g2oTwc.inverse()*g2oSww_new;
  166. }
  167. }
  168. mvpLoopMapPoints = mvpLoopMPs;//*mvvpLoopMapPoints[nCurrentIndex];
  169. CorrectLoop();
  170. }
  171. else
  172. {
  173. cout << "BAD LOOP!!!" << endl;
  174. }
  175. }
  176. else
  177. {
  178. mvpLoopMapPoints = mvpLoopMPs;
  179. CorrectLoop();
  180. }
  181. // Reset all variables
  182. mpLoopLastCurrentKF->SetErase();
  183. mpLoopMatchedKF->SetErase();
  184. mnLoopNumCoincidences = 0;
  185. mvpLoopMatchedMPs.clear();
  186. mvpLoopMPs.clear();
  187. mnLoopNumNotFound = 0;
  188. mbLoopDetected = false;
  189. }
  190. }
  191. mpLastCurrentKF = mpCurrentKF;
  192. }
  193. ResetIfRequested();
  194. if(CheckFinish()){
  195. // cout << "LC: Finish requested" << endl;
  196. break;
  197. }
  198. usleep(5000);
  199. }
  200. //ofstream f_stats;
  201. //f_stats.open("PlaceRecognition_stats" + mpLocalMapper->strSequence + ".txt");
  202. //f_stats << "# current_timestamp, matched_timestamp, [0:Loop, 1:Merge]" << endl;
  203. //f_stats << fixed;
  204. //for(int i=0; i< vdPR_CurrentTime.size(); ++i)
  205. //{
  206. // f_stats << 1e9*vdPR_CurrentTime[i] << "," << 1e9*vdPR_MatchedTime[i] << "," << vnPR_TypeRecogn[i] << endl;
  207. //}
  208. //f_stats.close();
  209. SetFinish();
  210. }
  211. void LoopClosing::InsertKeyFrame(KeyFrame *pKF)
  212. {
  213. unique_lock<mutex> lock(mMutexLoopQueue);
  214. if(pKF->mnId!=0)
  215. mlpLoopKeyFrameQueue.push_back(pKF);
  216. }
  217. bool LoopClosing::CheckNewKeyFrames()
  218. {
  219. unique_lock<mutex> lock(mMutexLoopQueue);
  220. return(!mlpLoopKeyFrameQueue.empty());
  221. }
  222. bool LoopClosing::NewDetectCommonRegions()
  223. {
  224. {
  225. unique_lock<mutex> lock(mMutexLoopQueue);
  226. mpCurrentKF = mlpLoopKeyFrameQueue.front();
  227. mlpLoopKeyFrameQueue.pop_front();
  228. // Avoid that a keyframe can be erased while it is being process by this thread
  229. mpCurrentKF->SetNotErase();
  230. mpCurrentKF->mbCurrentPlaceRecognition = true;
  231. mpLastMap = mpCurrentKF->GetMap();
  232. }
  233. if(mpLastMap->IsInertial() && !mpLastMap->GetIniertialBA1())
  234. {
  235. mpKeyFrameDB->add(mpCurrentKF);
  236. mpCurrentKF->SetErase();
  237. return false;
  238. }
  239. if(mpTracker->mSensor == System::STEREO && mpLastMap->GetAllKeyFrames().size() < 5) //12
  240. {
  241. mpKeyFrameDB->add(mpCurrentKF);
  242. mpCurrentKF->SetErase();
  243. return false;
  244. }
  245. if(mpLastMap->GetAllKeyFrames().size() < 12)
  246. {
  247. mpKeyFrameDB->add(mpCurrentKF);
  248. mpCurrentKF->SetErase();
  249. return false;
  250. }
  251. //Check the last candidates with geometric validation
  252. // Loop candidates
  253. bool bLoopDetectedInKF = false;
  254. bool bCheckSpatial = false;
  255. if(mnLoopNumCoincidences > 0)
  256. {
  257. bCheckSpatial = true;
  258. // Find from the last KF candidates
  259. cv::Mat mTcl = mpCurrentKF->GetPose() * mpLoopLastCurrentKF->GetPoseInverse();
  260. g2o::Sim3 gScl(Converter::toMatrix3d(mTcl.rowRange(0, 3).colRange(0, 3)),Converter::toVector3d(mTcl.rowRange(0, 3).col(3)),1.0);
  261. g2o::Sim3 gScw = gScl * mg2oLoopSlw;
  262. int numProjMatches = 0;
  263. vector<MapPoint*> vpMatchedMPs;
  264. bool bCommonRegion = DetectAndReffineSim3FromLastKF(mpCurrentKF, mpLoopMatchedKF, gScw, numProjMatches, mvpLoopMPs, vpMatchedMPs);
  265. if(bCommonRegion)
  266. {
  267. bLoopDetectedInKF = true;
  268. mnLoopNumCoincidences++;
  269. mpLoopLastCurrentKF->SetErase();
  270. mpLoopLastCurrentKF = mpCurrentKF;
  271. mg2oLoopSlw = gScw;
  272. mvpLoopMatchedMPs = vpMatchedMPs;
  273. mbLoopDetected = mnLoopNumCoincidences >= 3;
  274. mnLoopNumNotFound = 0;
  275. if(!mbLoopDetected)
  276. {
  277. //f_succes_pr << mpCurrentKF->mNameFile << " " << "8"<< endl;
  278. //f_succes_pr << "% Number of spatial consensous: " << std::to_string(mnLoopNumCoincidences) << endl;
  279. cout << "PR: Loop detected with Reffine Sim3" << endl;
  280. }
  281. }
  282. else
  283. {
  284. bLoopDetectedInKF = false;
  285. /*f_succes_pr << mpCurrentKF->mNameFile << " " << "8"<< endl;
  286. f_succes_pr << "% Number of spatial consensous: " << std::to_string(mnLoopNumCoincidences) << endl;*/
  287. mnLoopNumNotFound++;
  288. if(mnLoopNumNotFound >= 2)
  289. {
  290. /*for(int i=0; i<mvpLoopLastKF.size(); ++i)
  291. {
  292. mvpLoopLastKF[i]->SetErase();
  293. mvpLoopCandidateKF[i]->SetErase();
  294. mvpLoopLastKF[i]->mbCurrentPlaceRecognition = true;
  295. }
  296. mvpLoopCandidateKF.clear();
  297. mvpLoopLastKF.clear();
  298. mvg2oSim3LoopTcw.clear();
  299. mvnLoopNumMatches.clear();
  300. mvvpLoopMapPoints.clear();
  301. mvvpLoopMatchedMapPoints.clear();*/
  302. mpLoopLastCurrentKF->SetErase();
  303. mpLoopMatchedKF->SetErase();
  304. //mg2oLoopScw;
  305. mnLoopNumCoincidences = 0;
  306. mvpLoopMatchedMPs.clear();
  307. mvpLoopMPs.clear();
  308. mnLoopNumNotFound = 0;
  309. }
  310. }
  311. }
  312. //Merge candidates
  313. bool bMergeDetectedInKF = false;
  314. if(mnMergeNumCoincidences > 0)
  315. {
  316. // Find from the last KF candidates
  317. cv::Mat mTcl = mpCurrentKF->GetPose() * mpMergeLastCurrentKF->GetPoseInverse();
  318. g2o::Sim3 gScl(Converter::toMatrix3d(mTcl.rowRange(0, 3).colRange(0, 3)),Converter::toVector3d(mTcl.rowRange(0, 3).col(3)),1.0);
  319. g2o::Sim3 gScw = gScl * mg2oMergeSlw;
  320. int numProjMatches = 0;
  321. vector<MapPoint*> vpMatchedMPs;
  322. bool bCommonRegion = DetectAndReffineSim3FromLastKF(mpCurrentKF, mpMergeMatchedKF, gScw, numProjMatches, mvpMergeMPs, vpMatchedMPs);
  323. if(bCommonRegion)
  324. {
  325. //cout << "BoW: Merge reffined Sim3 transformation suscelful" << endl;
  326. bMergeDetectedInKF = true;
  327. mnMergeNumCoincidences++;
  328. mpMergeLastCurrentKF->SetErase();
  329. mpMergeLastCurrentKF = mpCurrentKF;
  330. mg2oMergeSlw = gScw;
  331. mvpMergeMatchedMPs = vpMatchedMPs;
  332. mbMergeDetected = mnMergeNumCoincidences >= 3;
  333. }
  334. else
  335. {
  336. //cout << "BoW: Merge reffined Sim3 transformation failed" << endl;
  337. mbMergeDetected = false;
  338. bMergeDetectedInKF = false;
  339. mnMergeNumNotFound++;
  340. if(mnMergeNumNotFound >= 2)
  341. {
  342. /*cout << "+++++++Merge detected failed in KF" << endl;
  343. for(int i=0; i<mvpMergeLastKF.size(); ++i)
  344. {
  345. mvpMergeLastKF[i]->SetErase();
  346. mvpMergeCandidateKF[i]->SetErase();
  347. mvpMergeLastKF[i]->mbCurrentPlaceRecognition = true;
  348. }
  349. mvpMergeCandidateKF.clear();
  350. mvpMergeLastKF.clear();
  351. mvg2oSim3MergeTcw.clear();
  352. mvnMergeNumMatches.clear();
  353. mvvpMergeMapPoints.clear();
  354. mvvpMergeMatchedMapPoints.clear();*/
  355. mpMergeLastCurrentKF->SetErase();
  356. mpMergeMatchedKF->SetErase();
  357. mnMergeNumCoincidences = 0;
  358. mvpMergeMatchedMPs.clear();
  359. mvpMergeMPs.clear();
  360. mnMergeNumNotFound = 0;
  361. }
  362. }
  363. }
  364. if(mbMergeDetected || mbLoopDetected)
  365. {
  366. //f_time_pr << "Geo" << " " << timeGeoKF_ms.count() << endl;
  367. mpKeyFrameDB->add(mpCurrentKF);
  368. return true;
  369. }
  370. //-------------
  371. //TODO: This is only necessary if we use a minimun score for pick the best candidates
  372. const vector<KeyFrame*> vpConnectedKeyFrames = mpCurrentKF->GetVectorCovisibleKeyFrames();
  373. const DBoW2::BowVector &CurrentBowVec = mpCurrentKF->mBowVec;
  374. /*float minScore = 1;
  375. for(size_t i=0; i<vpConnectedKeyFrames.size(); i++)
  376. {
  377. KeyFrame* pKF = vpConnectedKeyFrames[i];
  378. if(pKF->isBad())
  379. continue;
  380. const DBoW2::BowVector &BowVec = pKF->mBowVec;
  381. float score = mpORBVocabulary->score(CurrentBowVec, BowVec);
  382. if(score<minScore)
  383. minScore = score;
  384. }*/
  385. //-------------
  386. // Extract candidates from the bag of words
  387. vector<KeyFrame*> vpMergeBowCand, vpLoopBowCand;
  388. //cout << "LC: bMergeDetectedInKF: " << bMergeDetectedInKF << " bLoopDetectedInKF: " << bLoopDetectedInKF << endl;
  389. if(!bMergeDetectedInKF || !bLoopDetectedInKF)
  390. {
  391. // Search in BoW
  392. mpKeyFrameDB->DetectNBestCandidates(mpCurrentKF, vpLoopBowCand, vpMergeBowCand,3);
  393. }
  394. // Check the BoW candidates if the geometric candidate list is empty
  395. //Loop candidates
  396. /*#ifdef COMPILEDWITHC11
  397. std::chrono::steady_clock::time_point timeStartGeoBoW = std::chrono::steady_clock::now();
  398. #else
  399. std::chrono::monotonic_clock::time_point timeStartGeoBoW = std::chrono::monotonic_clock::now();
  400. #endif*/
  401. if(!bLoopDetectedInKF && !vpLoopBowCand.empty())
  402. {
  403. mbLoopDetected = DetectCommonRegionsFromBoW(vpLoopBowCand, mpLoopMatchedKF, mpLoopLastCurrentKF, mg2oLoopSlw, mnLoopNumCoincidences, mvpLoopMPs, mvpLoopMatchedMPs);
  404. }
  405. // Merge candidates
  406. //cout << "LC: Find BoW candidates" << endl;
  407. if(!bMergeDetectedInKF && !vpMergeBowCand.empty())
  408. {
  409. mbMergeDetected = DetectCommonRegionsFromBoW(vpMergeBowCand, mpMergeMatchedKF, mpMergeLastCurrentKF, mg2oMergeSlw, mnMergeNumCoincidences, mvpMergeMPs, mvpMergeMatchedMPs);
  410. }
  411. //cout << "LC: add to KFDB" << endl;
  412. mpKeyFrameDB->add(mpCurrentKF);
  413. if(mbMergeDetected || mbLoopDetected)
  414. {
  415. return true;
  416. }
  417. //cout << "LC: erase KF" << endl;
  418. mpCurrentKF->SetErase();
  419. mpCurrentKF->mbCurrentPlaceRecognition = false;
  420. return false;
  421. }
  422. bool LoopClosing::DetectAndReffineSim3FromLastKF(KeyFrame* pCurrentKF, KeyFrame* pMatchedKF, g2o::Sim3 &gScw, int &nNumProjMatches,
  423. std::vector<MapPoint*> &vpMPs, std::vector<MapPoint*> &vpMatchedMPs)
  424. {
  425. set<MapPoint*> spAlreadyMatchedMPs;
  426. nNumProjMatches = FindMatchesByProjection(pCurrentKF, pMatchedKF, gScw, spAlreadyMatchedMPs, vpMPs, vpMatchedMPs);
  427. cout << "REFFINE-SIM3: Projection from last KF with " << nNumProjMatches << " matches" << endl;
  428. int nProjMatches = 30;
  429. int nProjOptMatches = 50;
  430. int nProjMatchesRep = 100;
  431. /*if(mpTracker->mSensor==System::IMU_MONOCULAR ||mpTracker->mSensor==System::IMU_STEREO)
  432. {
  433. nProjMatches = 50;
  434. nProjOptMatches = 50;
  435. nProjMatchesRep = 80;
  436. }*/
  437. if(nNumProjMatches >= nProjMatches)
  438. {
  439. cv::Mat mScw = Converter::toCvMat(gScw);
  440. cv::Mat mTwm = pMatchedKF->GetPoseInverse();
  441. g2o::Sim3 gSwm(Converter::toMatrix3d(mTwm.rowRange(0, 3).colRange(0, 3)),Converter::toVector3d(mTwm.rowRange(0, 3).col(3)),1.0);
  442. g2o::Sim3 gScm = gScw * gSwm;
  443. Eigen::Matrix<double, 7, 7> mHessian7x7;
  444. bool bFixedScale = mbFixScale; // TODO CHECK; Solo para el monocular inertial
  445. if(mpTracker->mSensor==System::IMU_MONOCULAR && !pCurrentKF->GetMap()->GetIniertialBA2())
  446. bFixedScale=false;
  447. int numOptMatches = Optimizer::OptimizeSim3(mpCurrentKF, pMatchedKF, vpMatchedMPs, gScm, 10, bFixedScale, mHessian7x7, true);
  448. cout << "REFFINE-SIM3: Optimize Sim3 from last KF with " << numOptMatches << " inliers" << endl;
  449. if(numOptMatches > nProjOptMatches)
  450. {
  451. g2o::Sim3 gScw_estimation(Converter::toMatrix3d(mScw.rowRange(0, 3).colRange(0, 3)),
  452. Converter::toVector3d(mScw.rowRange(0, 3).col(3)),1.0);
  453. vector<MapPoint*> vpMatchedMP;
  454. vpMatchedMP.resize(mpCurrentKF->GetMapPointMatches().size(), static_cast<MapPoint*>(NULL));
  455. nNumProjMatches = FindMatchesByProjection(pCurrentKF, pMatchedKF, gScw_estimation, spAlreadyMatchedMPs, vpMPs, vpMatchedMPs);
  456. //cout << "REFFINE-SIM3: Projection with optimize Sim3 from last KF with " << nNumProjMatches << " matches" << endl;
  457. if(nNumProjMatches >= nProjMatchesRep)
  458. {
  459. gScw = gScw_estimation;
  460. return true;
  461. }
  462. }
  463. }
  464. return false;
  465. }
  466. bool LoopClosing::DetectCommonRegionsFromBoW(std::vector<KeyFrame*> &vpBowCand, KeyFrame* &pMatchedKF2, KeyFrame* &pLastCurrentKF, g2o::Sim3 &g2oScw,
  467. int &nNumCoincidences, std::vector<MapPoint*> &vpMPs, std::vector<MapPoint*> &vpMatchedMPs)
  468. {
  469. int nBoWMatches = 20;
  470. int nBoWInliers = 15;
  471. int nSim3Inliers = 20;
  472. int nProjMatches = 50;
  473. int nProjOptMatches = 80;
  474. /*if(mpTracker->mSensor==System::IMU_MONOCULAR ||mpTracker->mSensor==System::IMU_STEREO)
  475. {
  476. nBoWMatches = 20;
  477. nBoWInliers = 15;
  478. nSim3Inliers = 30;
  479. nProjMatches = 50;
  480. nProjOptMatches = 70;
  481. }*/
  482. set<KeyFrame*> spConnectedKeyFrames = mpCurrentKF->GetConnectedKeyFrames();
  483. int nNumCovisibles = 5;
  484. ORBmatcher matcherBoW(0.9, true);
  485. ORBmatcher matcher(0.75, true);
  486. int nNumGuidedMatching = 0;
  487. // Varibles to select the best numbe
  488. KeyFrame* pBestMatchedKF;
  489. int nBestMatchesReproj = 0;
  490. int nBestNumCoindicendes = 0;
  491. g2o::Sim3 g2oBestScw;
  492. std::vector<MapPoint*> vpBestMapPoints;
  493. std::vector<MapPoint*> vpBestMatchedMapPoints;
  494. int numCandidates = vpBowCand.size();
  495. vector<int> vnStage(numCandidates, 0);
  496. vector<int> vnMatchesStage(numCandidates, 0);
  497. int index = 0;
  498. for(KeyFrame* pKFi : vpBowCand)
  499. {
  500. //cout << endl << "-------------------------------" << endl;
  501. if(!pKFi || pKFi->isBad())
  502. continue;
  503. // Current KF against KF with covisibles version
  504. std::vector<KeyFrame*> vpCovKFi = pKFi->GetBestCovisibilityKeyFrames(nNumCovisibles);
  505. vpCovKFi.push_back(vpCovKFi[0]);
  506. vpCovKFi[0] = pKFi;
  507. std::vector<std::vector<MapPoint*> > vvpMatchedMPs;
  508. vvpMatchedMPs.resize(vpCovKFi.size());
  509. std::set<MapPoint*> spMatchedMPi;
  510. int numBoWMatches = 0;
  511. KeyFrame* pMostBoWMatchesKF = pKFi;
  512. int nMostBoWNumMatches = 0;
  513. std::vector<MapPoint*> vpMatchedPoints = std::vector<MapPoint*>(mpCurrentKF->GetMapPointMatches().size(), static_cast<MapPoint*>(NULL));
  514. std::vector<KeyFrame*> vpKeyFrameMatchedMP = std::vector<KeyFrame*>(mpCurrentKF->GetMapPointMatches().size(), static_cast<KeyFrame*>(NULL));
  515. int nIndexMostBoWMatchesKF=0;
  516. for(int j=0; j<vpCovKFi.size(); ++j)
  517. {
  518. if(!vpCovKFi[j] || vpCovKFi[j]->isBad())
  519. continue;
  520. int num = matcherBoW.SearchByBoW(mpCurrentKF, vpCovKFi[j], vvpMatchedMPs[j]);
  521. //cout << "BoW: " << num << " putative matches with KF " << vpCovKFi[j]->mnId << endl;
  522. if (num > nMostBoWNumMatches)
  523. {
  524. nMostBoWNumMatches = num;
  525. nIndexMostBoWMatchesKF = j;
  526. }
  527. }
  528. bool bAbortByNearKF = false;
  529. for(int j=0; j<vpCovKFi.size(); ++j)
  530. {
  531. if(spConnectedKeyFrames.find(vpCovKFi[j]) != spConnectedKeyFrames.end())
  532. {
  533. bAbortByNearKF = true;
  534. //cout << "BoW: Candidate KF aborted by proximity" << endl;
  535. break;
  536. }
  537. //cout << "Matches: " << num << endl;
  538. for(int k=0; k < vvpMatchedMPs[j].size(); ++k)
  539. {
  540. MapPoint* pMPi_j = vvpMatchedMPs[j][k];
  541. if(!pMPi_j || pMPi_j->isBad())
  542. continue;
  543. if(spMatchedMPi.find(pMPi_j) == spMatchedMPi.end())
  544. {
  545. spMatchedMPi.insert(pMPi_j);
  546. numBoWMatches++;
  547. vpMatchedPoints[k]= pMPi_j;
  548. vpKeyFrameMatchedMP[k] = vpCovKFi[j];
  549. }
  550. }
  551. }
  552. //cout <<"BoW: " << numBoWMatches << " independent putative matches" << endl;
  553. if(!bAbortByNearKF && numBoWMatches >= nBoWMatches) // TODO pick a good threshold
  554. {
  555. /*cout << "-------------------------------" << endl;
  556. cout << "Geometric validation with " << numBoWMatches << endl;
  557. cout << "KFc: " << mpCurrentKF->mnId << "; KFm: " << pMostBoWMatchesKF->mnId << endl;*/
  558. // Geometric validation
  559. bool bFixedScale = mbFixScale;
  560. if(mpTracker->mSensor==System::IMU_MONOCULAR && !mpCurrentKF->GetMap()->GetIniertialBA2())
  561. bFixedScale=false;
  562. Sim3Solver solver = Sim3Solver(mpCurrentKF, pMostBoWMatchesKF, vpMatchedPoints, bFixedScale, vpKeyFrameMatchedMP);
  563. solver.SetRansacParameters(0.99, nBoWInliers, 300); // at least 15 inliers
  564. bool bNoMore = false;
  565. vector<bool> vbInliers;
  566. int nInliers;
  567. bool bConverge = false;
  568. cv::Mat mTcm;
  569. while(!bConverge && !bNoMore)
  570. {
  571. mTcm = solver.iterate(20,bNoMore, vbInliers, nInliers, bConverge);
  572. }
  573. //cout << "Num inliers: " << nInliers << endl;
  574. if(bConverge)
  575. {
  576. //cout <<"BoW: " << nInliers << " inliers in Sim3Solver" << endl;
  577. // Match by reprojection
  578. //int nNumCovisibles = 5;
  579. vpCovKFi.clear();
  580. vpCovKFi = pMostBoWMatchesKF->GetBestCovisibilityKeyFrames(nNumCovisibles);
  581. int nInitialCov = vpCovKFi.size();
  582. vpCovKFi.push_back(pMostBoWMatchesKF);
  583. set<KeyFrame*> spCheckKFs(vpCovKFi.begin(), vpCovKFi.end());
  584. set<MapPoint*> spMapPoints;
  585. vector<MapPoint*> vpMapPoints;
  586. vector<KeyFrame*> vpKeyFrames;
  587. for(KeyFrame* pCovKFi : vpCovKFi)
  588. {
  589. for(MapPoint* pCovMPij : pCovKFi->GetMapPointMatches())
  590. {
  591. if(!pCovMPij || pCovMPij->isBad())
  592. continue;
  593. if(spMapPoints.find(pCovMPij) == spMapPoints.end())
  594. {
  595. spMapPoints.insert(pCovMPij);
  596. vpMapPoints.push_back(pCovMPij);
  597. vpKeyFrames.push_back(pCovKFi);
  598. }
  599. }
  600. }
  601. //cout << "Point cloud: " << vpMapPoints.size() << endl;
  602. g2o::Sim3 gScm(Converter::toMatrix3d(solver.GetEstimatedRotation()),Converter::toVector3d(solver.GetEstimatedTranslation()),solver.GetEstimatedScale());
  603. g2o::Sim3 gSmw(Converter::toMatrix3d(pMostBoWMatchesKF->GetRotation()),Converter::toVector3d(pMostBoWMatchesKF->GetTranslation()),1.0);
  604. g2o::Sim3 gScw = gScm*gSmw; // Similarity matrix of current from the world position
  605. cv::Mat mScw = Converter::toCvMat(gScw);
  606. vector<MapPoint*> vpMatchedMP;
  607. vpMatchedMP.resize(mpCurrentKF->GetMapPointMatches().size(), static_cast<MapPoint*>(NULL));
  608. vector<KeyFrame*> vpMatchedKF;
  609. vpMatchedKF.resize(mpCurrentKF->GetMapPointMatches().size(), static_cast<KeyFrame*>(NULL));
  610. int numProjMatches = matcher.SearchByProjection(mpCurrentKF, mScw, vpMapPoints, vpKeyFrames, vpMatchedMP, vpMatchedKF, 8, 1.5);
  611. cout <<"BoW: " << numProjMatches << " matches between " << vpMapPoints.size() << " points with coarse Sim3" << endl;
  612. if(numProjMatches >= nProjMatches)
  613. {
  614. // Optimize Sim3 transformation with every matches
  615. Eigen::Matrix<double, 7, 7> mHessian7x7;
  616. bool bFixedScale = mbFixScale;
  617. if(mpTracker->mSensor==System::IMU_MONOCULAR && !mpCurrentKF->GetMap()->GetIniertialBA2())
  618. bFixedScale=false;
  619. int numOptMatches = Optimizer::OptimizeSim3(mpCurrentKF, pKFi, vpMatchedMP, gScm, 10, mbFixScale, mHessian7x7, true);
  620. //cout <<"BoW: " << numOptMatches << " inliers in the Sim3 optimization" << endl;
  621. //cout << "Inliers in Sim3 optimization: " << numOptMatches << endl;
  622. if(numOptMatches >= nSim3Inliers)
  623. {
  624. //cout <<"BoW: " << numOptMatches << " inliers in Sim3 optimization" << endl;
  625. g2o::Sim3 gSmw(Converter::toMatrix3d(pMostBoWMatchesKF->GetRotation()),Converter::toVector3d(pMostBoWMatchesKF->GetTranslation()),1.0);
  626. g2o::Sim3 gScw = gScm*gSmw; // Similarity matrix of current from the world position
  627. cv::Mat mScw = Converter::toCvMat(gScw);
  628. vector<MapPoint*> vpMatchedMP;
  629. vpMatchedMP.resize(mpCurrentKF->GetMapPointMatches().size(), static_cast<MapPoint*>(NULL));
  630. int numProjOptMatches = matcher.SearchByProjection(mpCurrentKF, mScw, vpMapPoints, vpMatchedMP, 5, 1.0);
  631. //cout <<"BoW: " << numProjOptMatches << " matches after of the Sim3 optimization" << endl;
  632. if(numProjOptMatches >= nProjOptMatches)
  633. {
  634. cout << "BoW: Current KF " << mpCurrentKF->mnId << "; candidate KF " << pKFi->mnId << endl;
  635. cout << "BoW: There are " << numProjOptMatches << " matches between them with the optimized Sim3" << endl;
  636. int max_x = -1, min_x = 1000000;
  637. int max_y = -1, min_y = 1000000;
  638. for(MapPoint* pMPi : vpMatchedMP)
  639. {
  640. if(!pMPi || pMPi->isBad())
  641. {
  642. continue;
  643. }
  644. tuple<size_t,size_t> indexes = pMPi->GetIndexInKeyFrame(pKFi);
  645. int index = get<0>(indexes);
  646. if(index >= 0)
  647. {
  648. int coord_x = pKFi->mvKeysUn[index].pt.x;
  649. if(coord_x < min_x)
  650. {
  651. min_x = coord_x;
  652. }
  653. if(coord_x > max_x)
  654. {
  655. max_x = coord_x;
  656. }
  657. int coord_y = pKFi->mvKeysUn[index].pt.y;
  658. if(coord_y < min_y)
  659. {
  660. min_y = coord_y;
  661. }
  662. if(coord_y > max_y)
  663. {
  664. max_y = coord_y;
  665. }
  666. }
  667. }
  668. //cout << "BoW: Coord in X -> " << min_x << ", " << max_x << "; and Y -> " << min_y << ", " << max_y << endl;
  669. //cout << "BoW: features area in X -> " << (max_x - min_x) << " and Y -> " << (max_y - min_y) << endl;
  670. int nNumKFs = 0;
  671. //vpMatchedMPs = vpMatchedMP;
  672. //vpMPs = vpMapPoints;
  673. // Check the Sim3 transformation with the current KeyFrame covisibles
  674. vector<KeyFrame*> vpCurrentCovKFs = mpCurrentKF->GetBestCovisibilityKeyFrames(nNumCovisibles);
  675. //cout << "---" << endl;
  676. //cout << "BoW: Geometrical validation" << endl;
  677. int j = 0;
  678. while(nNumKFs < 3 && j<vpCurrentCovKFs.size())
  679. //for(int j=0; j<vpCurrentCovKFs.size(); ++j)
  680. {
  681. KeyFrame* pKFj = vpCurrentCovKFs[j];
  682. cv::Mat mTjc = pKFj->GetPose() * mpCurrentKF->GetPoseInverse();
  683. g2o::Sim3 gSjc(Converter::toMatrix3d(mTjc.rowRange(0, 3).colRange(0, 3)),Converter::toVector3d(mTjc.rowRange(0, 3).col(3)),1.0);
  684. g2o::Sim3 gSjw = gSjc * gScw;
  685. int numProjMatches_j = 0;
  686. vector<MapPoint*> vpMatchedMPs_j;
  687. bool bValid = DetectCommonRegionsFromLastKF(pKFj,pMostBoWMatchesKF, gSjw,numProjMatches_j, vpMapPoints, vpMatchedMPs_j);
  688. if(bValid)
  689. {
  690. //cout << "BoW: KF " << pKFj->mnId << " has " << numProjMatches_j << " matches" << endl;
  691. cv::Mat Tc_w = mpCurrentKF->GetPose();
  692. cv::Mat Tw_cj = pKFj->GetPoseInverse();
  693. cv::Mat Tc_cj = Tc_w * Tw_cj;
  694. cv::Vec3d vector_dist = Tc_cj.rowRange(0, 3).col(3);
  695. cv::Mat Rc_cj = Tc_cj.rowRange(0, 3).colRange(0, 3);
  696. double dist = cv::norm(vector_dist);
  697. cout << "BoW: KF " << pKFi->mnId << " to KF " << pKFj->mnId << " is separated by " << dist << " meters" << endl;
  698. cout << "BoW: Rotation between KF -> " << Rc_cj << endl;
  699. vector<float> v_euler = Converter::toEuler(Rc_cj);
  700. v_euler[0] *= 180 /3.1415;
  701. v_euler[1] *= 180 /3.1415;
  702. v_euler[2] *= 180 /3.1415;
  703. cout << "BoW: Rotation in angles (x, y, z) -> (" << v_euler[0] << ", " << v_euler[1] << ", " << v_euler[2] << ")" << endl;
  704. nNumKFs++;
  705. /*if(numProjMatches_j > numProjOptMatches)
  706. {
  707. pLastCurrentKF = pKFj;
  708. g2oScw = gSjw;
  709. vpMatchedMPs = vpMatchedMPs_j;
  710. }*/
  711. }
  712. j++;
  713. }
  714. if(nNumKFs < 3)
  715. {
  716. vnStage[index] = 8;
  717. vnMatchesStage[index] = nNumKFs;
  718. }
  719. if(nBestMatchesReproj < numProjOptMatches)
  720. {
  721. nBestMatchesReproj = numProjOptMatches;
  722. nBestNumCoindicendes = nNumKFs;
  723. pBestMatchedKF = pMostBoWMatchesKF;
  724. g2oBestScw = gScw;
  725. vpBestMapPoints = vpMapPoints;
  726. vpBestMatchedMapPoints = vpMatchedMP;
  727. }
  728. }
  729. }
  730. }
  731. }
  732. }
  733. index++;
  734. }
  735. if(nBestMatchesReproj > 0)
  736. {
  737. pLastCurrentKF = mpCurrentKF;
  738. nNumCoincidences = nBestNumCoindicendes;
  739. pMatchedKF2 = pBestMatchedKF;
  740. pMatchedKF2->SetNotErase();
  741. g2oScw = g2oBestScw;
  742. vpMPs = vpBestMapPoints;
  743. vpMatchedMPs = vpBestMatchedMapPoints;
  744. return nNumCoincidences >= 3;
  745. }
  746. else
  747. {
  748. int maxStage = -1;
  749. int maxMatched;
  750. for(int i=0; i<vnStage.size(); ++i)
  751. {
  752. if(vnStage[i] > maxStage)
  753. {
  754. maxStage = vnStage[i];
  755. maxMatched = vnMatchesStage[i];
  756. }
  757. }
  758. // f_succes_pr << mpCurrentKF->mNameFile << " " << std::to_string(maxStage) << endl;
  759. // f_succes_pr << "% NumCand: " << std::to_string(numCandidates) << "; matches: " << std::to_string(maxMatched) << endl;
  760. }
  761. return false;
  762. }
  763. bool LoopClosing::DetectCommonRegionsFromLastKF(KeyFrame* pCurrentKF, KeyFrame* pMatchedKF, g2o::Sim3 &gScw, int &nNumProjMatches,
  764. std::vector<MapPoint*> &vpMPs, std::vector<MapPoint*> &vpMatchedMPs)
  765. {
  766. set<MapPoint*> spAlreadyMatchedMPs(vpMatchedMPs.begin(), vpMatchedMPs.end());
  767. nNumProjMatches = FindMatchesByProjection(pCurrentKF, pMatchedKF, gScw, spAlreadyMatchedMPs, vpMPs, vpMatchedMPs);
  768. //cout << "Projection from last KF with " << nNumProjMatches << " matches" << endl;
  769. int nProjMatches = 30;
  770. if(nNumProjMatches >= nProjMatches)
  771. {
  772. /*cout << "PR_From_LastKF: KF " << pCurrentKF->mnId << " has " << nNumProjMatches << " with KF " << pMatchedKF->mnId << endl;
  773. int max_x = -1, min_x = 1000000;
  774. int max_y = -1, min_y = 1000000;
  775. for(MapPoint* pMPi : vpMatchedMPs)
  776. {
  777. if(!pMPi || pMPi->isBad())
  778. {
  779. continue;
  780. }
  781. tuple<size_t,size_t> indexes = pMPi->GetIndexInKeyFrame(pMatchedKF);
  782. int index = get<0>(indexes);
  783. if(index >= 0)
  784. {
  785. int coord_x = pCurrentKF->mvKeysUn[index].pt.x;
  786. if(coord_x < min_x)
  787. {
  788. min_x = coord_x;
  789. }
  790. if(coord_x > max_x)
  791. {
  792. max_x = coord_x;
  793. }
  794. int coord_y = pCurrentKF->mvKeysUn[index].pt.y;
  795. if(coord_y < min_y)
  796. {
  797. min_y = coord_y;
  798. }
  799. if(coord_y > max_y)
  800. {
  801. max_y = coord_y;
  802. }
  803. }
  804. }*/
  805. //cout << "PR_From_LastKF: Coord in X -> " << min_x << ", " << max_x << "; and Y -> " << min_y << ", " << max_y << endl;
  806. //cout << "PR_From_LastKF: features area in X -> " << (max_x - min_x) << " and Y -> " << (max_y - min_y) << endl;
  807. return true;
  808. }
  809. return false;
  810. }
  811. int LoopClosing::FindMatchesByProjection(KeyFrame* pCurrentKF, KeyFrame* pMatchedKFw, g2o::Sim3 &g2oScw,
  812. set<MapPoint*> &spMatchedMPinOrigin, vector<MapPoint*> &vpMapPoints,
  813. vector<MapPoint*> &vpMatchedMapPoints)
  814. {
  815. int nNumCovisibles = 5;
  816. vector<KeyFrame*> vpCovKFm = pMatchedKFw->GetBestCovisibilityKeyFrames(nNumCovisibles);
  817. int nInitialCov = vpCovKFm.size();
  818. vpCovKFm.push_back(pMatchedKFw);
  819. set<KeyFrame*> spCheckKFs(vpCovKFm.begin(), vpCovKFm.end());
  820. set<KeyFrame*> spCurrentCovisbles = pCurrentKF->GetConnectedKeyFrames();
  821. for(int i=0; i<nInitialCov; ++i)
  822. {
  823. vector<KeyFrame*> vpKFs = vpCovKFm[i]->GetBestCovisibilityKeyFrames(nNumCovisibles);
  824. int nInserted = 0;
  825. int j = 0;
  826. while(j < vpKFs.size() && nInserted < nNumCovisibles)
  827. {
  828. if(spCheckKFs.find(vpKFs[j]) == spCheckKFs.end() && spCurrentCovisbles.find(vpKFs[j]) == spCurrentCovisbles.end())
  829. {
  830. spCheckKFs.insert(vpKFs[j]);
  831. ++nInserted;
  832. }
  833. ++j;
  834. }
  835. vpCovKFm.insert(vpCovKFm.end(), vpKFs.begin(), vpKFs.end());
  836. }
  837. set<MapPoint*> spMapPoints;
  838. vpMapPoints.clear();
  839. vpMatchedMapPoints.clear();
  840. for(KeyFrame* pKFi : vpCovKFm)
  841. {
  842. for(MapPoint* pMPij : pKFi->GetMapPointMatches())
  843. {
  844. if(!pMPij || pMPij->isBad())
  845. continue;
  846. if(spMapPoints.find(pMPij) == spMapPoints.end())
  847. {
  848. spMapPoints.insert(pMPij);
  849. vpMapPoints.push_back(pMPij);
  850. }
  851. }
  852. }
  853. //cout << "Point cloud: " << vpMapPoints.size() << endl;
  854. cv::Mat mScw = Converter::toCvMat(g2oScw);
  855. ORBmatcher matcher(0.9, true);
  856. vpMatchedMapPoints.resize(pCurrentKF->GetMapPointMatches().size(), static_cast<MapPoint*>(NULL));
  857. int num_matches = matcher.SearchByProjection(pCurrentKF, mScw, vpMapPoints, vpMatchedMapPoints, 3, 1.5);
  858. return num_matches;
  859. }
  860. void LoopClosing::CorrectLoop()
  861. {
  862. cout << "Loop detected!" << endl;
  863. // Send a stop signal to Local Mapping
  864. // Avoid new keyframes are inserted while correcting the loop
  865. mpLocalMapper->RequestStop();
  866. mpLocalMapper->EmptyQueue(); // Proccess keyframes in the queue
  867. // If a Global Bundle Adjustment is running, abort it
  868. cout << "Request GBA abort" << endl;
  869. if(isRunningGBA())
  870. {
  871. unique_lock<mutex> lock(mMutexGBA);
  872. mbStopGBA = true;
  873. mnFullBAIdx++;
  874. if(mpThreadGBA)
  875. {
  876. cout << "GBA running... Abort!" << endl;
  877. mpThreadGBA->detach();
  878. delete mpThreadGBA;
  879. }
  880. }
  881. // Wait until Local Mapping has effectively stopped
  882. while(!mpLocalMapper->isStopped())
  883. {
  884. usleep(1000);
  885. }
  886. // Ensure current keyframe is updated
  887. cout << "start updating connections" << endl;
  888. assert(mpCurrentKF->GetMap()->CheckEssentialGraph());
  889. mpCurrentKF->UpdateConnections();
  890. assert(mpCurrentKF->GetMap()->CheckEssentialGraph());
  891. // Retrive keyframes connected to the current keyframe and compute corrected Sim3 pose by propagation
  892. mvpCurrentConnectedKFs = mpCurrentKF->GetVectorCovisibleKeyFrames();
  893. mvpCurrentConnectedKFs.push_back(mpCurrentKF);
  894. KeyFrameAndPose CorrectedSim3, NonCorrectedSim3;
  895. CorrectedSim3[mpCurrentKF]=mg2oLoopScw;
  896. cv::Mat Twc = mpCurrentKF->GetPoseInverse();
  897. Map* pLoopMap = mpCurrentKF->GetMap();
  898. {
  899. // Get Map Mutex
  900. unique_lock<mutex> lock(pLoopMap->mMutexMapUpdate);
  901. const bool bImuInit = pLoopMap->isImuInitialized();
  902. for(vector<KeyFrame*>::iterator vit=mvpCurrentConnectedKFs.begin(), vend=mvpCurrentConnectedKFs.end(); vit!=vend; vit++)
  903. {
  904. KeyFrame* pKFi = *vit;
  905. cv::Mat Tiw = pKFi->GetPose();
  906. if(pKFi!=mpCurrentKF)
  907. {
  908. cv::Mat Tic = Tiw*Twc;
  909. cv::Mat Ric = Tic.rowRange(0,3).colRange(0,3);
  910. cv::Mat tic = Tic.rowRange(0,3).col(3);
  911. g2o::Sim3 g2oSic(Converter::toMatrix3d(Ric),Converter::toVector3d(tic),1.0);
  912. g2o::Sim3 g2oCorrectedSiw = g2oSic*mg2oLoopScw;
  913. //Pose corrected with the Sim3 of the loop closure
  914. CorrectedSim3[pKFi]=g2oCorrectedSiw;
  915. }
  916. cv::Mat Riw = Tiw.rowRange(0,3).colRange(0,3);
  917. cv::Mat tiw = Tiw.rowRange(0,3).col(3);
  918. g2o::Sim3 g2oSiw(Converter::toMatrix3d(Riw),Converter::toVector3d(tiw),1.0);
  919. //Pose without correction
  920. NonCorrectedSim3[pKFi]=g2oSiw;
  921. }
  922. // Correct all MapPoints obsrved by current keyframe and neighbors, so that they align with the other side of the loop
  923. cout << "LC: start correcting KeyFrames" << endl;
  924. cout << "LC: there are " << CorrectedSim3.size() << " KFs in the local window" << endl;
  925. for(KeyFrameAndPose::iterator mit=CorrectedSim3.begin(), mend=CorrectedSim3.end(); mit!=mend; mit++)
  926. {
  927. KeyFrame* pKFi = mit->first;
  928. g2o::Sim3 g2oCorrectedSiw = mit->second;
  929. g2o::Sim3 g2oCorrectedSwi = g2oCorrectedSiw.inverse();
  930. g2o::Sim3 g2oSiw =NonCorrectedSim3[pKFi];
  931. vector<MapPoint*> vpMPsi = pKFi->GetMapPointMatches();
  932. for(size_t iMP=0, endMPi = vpMPsi.size(); iMP<endMPi; iMP++)
  933. {
  934. MapPoint* pMPi = vpMPsi[iMP];
  935. if(!pMPi)
  936. continue;
  937. if(pMPi->isBad())
  938. continue;
  939. if(pMPi->mnCorrectedByKF==mpCurrentKF->mnId)
  940. continue;
  941. // Project with non-corrected pose and project back with corrected pose
  942. cv::Mat P3Dw = pMPi->GetWorldPos();
  943. Eigen::Matrix<double,3,1> eigP3Dw = Converter::toVector3d(P3Dw);
  944. Eigen::Matrix<double,3,1> eigCorrectedP3Dw = g2oCorrectedSwi.map(g2oSiw.map(eigP3Dw));
  945. cv::Mat cvCorrectedP3Dw = Converter::toCvMat(eigCorrectedP3Dw);
  946. pMPi->SetWorldPos(cvCorrectedP3Dw);
  947. pMPi->mnCorrectedByKF = mpCurrentKF->mnId;
  948. pMPi->mnCorrectedReference = pKFi->mnId;
  949. pMPi->UpdateNormalAndDepth();
  950. }
  951. // Update keyframe pose with corrected Sim3. First transform Sim3 to SE3 (scale translation)
  952. Eigen::Matrix3d eigR = g2oCorrectedSiw.rotation().toRotationMatrix();
  953. Eigen::Vector3d eigt = g2oCorrectedSiw.translation();
  954. double s = g2oCorrectedSiw.scale();
  955. // cout << "scale for loop-closing: " << s << endl;
  956. eigt *=(1./s); //[R t/s;0 1]
  957. cv::Mat correctedTiw = Converter::toCvSE3(eigR,eigt);
  958. pKFi->SetPose(correctedTiw);
  959. // Correct velocity according to orientation correction
  960. if(bImuInit)
  961. {
  962. Eigen::Matrix3d Rcor = eigR.transpose()*g2oSiw.rotation().toRotationMatrix();
  963. pKFi->SetVelocity(Converter::toCvMat(Rcor)*pKFi->GetVelocity());
  964. }
  965. // Make sure connections are updated
  966. pKFi->UpdateConnections();
  967. }
  968. // TODO Check this index increasement
  969. mpAtlas->GetCurrentMap()->IncreaseChangeIndex();
  970. cout << "LC: end correcting KeyFrames" << endl;
  971. // Start Loop Fusion
  972. // Update matched map points and replace if duplicated
  973. cout << "LC: start replacing duplicated" << endl;
  974. for(size_t i=0; i<mvpLoopMatchedMPs.size(); i++)
  975. {
  976. if(mvpLoopMatchedMPs[i])
  977. {
  978. MapPoint* pLoopMP = mvpLoopMatchedMPs[i];
  979. MapPoint* pCurMP = mpCurrentKF->GetMapPoint(i);
  980. if(pCurMP)
  981. pCurMP->Replace(pLoopMP);
  982. else
  983. {
  984. mpCurrentKF->AddMapPoint(pLoopMP,i);
  985. pLoopMP->AddObservation(mpCurrentKF,i);
  986. pLoopMP->ComputeDistinctiveDescriptors();
  987. }
  988. }
  989. }
  990. cout << "LC: end replacing duplicated" << endl;
  991. }
  992. // Project MapPoints observed in the neighborhood of the loop keyframe
  993. // into the current keyframe and neighbors using corrected poses.
  994. // Fuse duplications.
  995. //cout << "LC: start SearchAndFuse" << endl;
  996. SearchAndFuse(CorrectedSim3, mvpLoopMapPoints);
  997. //cout << "LC: end SearchAndFuse" << endl;
  998. // After the MapPoint fusion, new links in the covisibility graph will appear attaching both sides of the loop
  999. //cout << "LC: start updating covisibility graph" << endl;
  1000. map<KeyFrame*, set<KeyFrame*> > LoopConnections;
  1001. for(vector<KeyFrame*>::iterator vit=mvpCurrentConnectedKFs.begin(), vend=mvpCurrentConnectedKFs.end(); vit!=vend; vit++)
  1002. {
  1003. KeyFrame* pKFi = *vit;
  1004. vector<KeyFrame*> vpPreviousNeighbors = pKFi->GetVectorCovisibleKeyFrames();
  1005. // Update connections. Detect new links.
  1006. pKFi->UpdateConnections();
  1007. LoopConnections[pKFi]=pKFi->GetConnectedKeyFrames();
  1008. for(vector<KeyFrame*>::iterator vit_prev=vpPreviousNeighbors.begin(), vend_prev=vpPreviousNeighbors.end(); vit_prev!=vend_prev; vit_prev++)
  1009. {
  1010. LoopConnections[pKFi].erase(*vit_prev);
  1011. }
  1012. for(vector<KeyFrame*>::iterator vit2=mvpCurrentConnectedKFs.begin(), vend2=mvpCurrentConnectedKFs.end(); vit2!=vend2; vit2++)
  1013. {
  1014. LoopConnections[pKFi].erase(*vit2);
  1015. }
  1016. }
  1017. //cout << "LC: end updating covisibility graph" << endl;
  1018. // Optimize graph
  1019. //cout << "start opt essentialgraph" << endl;
  1020. bool bFixedScale = mbFixScale;
  1021. // TODO CHECK; Solo para el monocular inertial
  1022. if(mpTracker->mSensor==System::IMU_MONOCULAR && !mpCurrentKF->GetMap()->GetIniertialBA2())
  1023. bFixedScale=false;
  1024. //cout << "Optimize essential graph" << endl;
  1025. if(pLoopMap->IsInertial() && pLoopMap->isImuInitialized())
  1026. {
  1027. //cout << "With 4DoF" << endl;
  1028. Optimizer::OptimizeEssentialGraph4DoF(pLoopMap, mpLoopMatchedKF, mpCurrentKF, NonCorrectedSim3, CorrectedSim3, LoopConnections);
  1029. }
  1030. else
  1031. {
  1032. //cout << "With 7DoF" << endl;
  1033. Optimizer::OptimizeEssentialGraph(pLoopMap, mpLoopMatchedKF, mpCurrentKF, NonCorrectedSim3, CorrectedSim3, LoopConnections, bFixedScale);
  1034. }
  1035. //cout << "Optimize essential graph finished" << endl;
  1036. //usleep(5*1000*1000);
  1037. mpAtlas->InformNewBigChange();
  1038. // Add loop edge
  1039. mpLoopMatchedKF->AddLoopEdge(mpCurrentKF);
  1040. mpCurrentKF->AddLoopEdge(mpLoopMatchedKF);
  1041. // Launch a new thread to perform Global Bundle Adjustment (Only if few keyframes, if not it would take too much time)
  1042. if(!pLoopMap->isImuInitialized() || (pLoopMap->KeyFramesInMap()<200 && mpAtlas->CountMaps()==1))
  1043. {
  1044. mbRunningGBA = true;
  1045. mbFinishedGBA = false;
  1046. mbStopGBA = false;
  1047. mpThreadGBA = new thread(&LoopClosing::RunGlobalBundleAdjustment, this, pLoopMap, mpCurrentKF->mnId);
  1048. }
  1049. // Loop closed. Release Local Mapping.
  1050. mpLocalMapper->Release();
  1051. mLastLoopKFid = mpCurrentKF->mnId; //TODO old varible, it is not use in the new algorithm
  1052. }
  1053. void LoopClosing::MergeLocal()
  1054. {
  1055. Verbose::PrintMess("MERGE-VISUAL: Merge Visual detected!!!!", Verbose::VERBOSITY_NORMAL);
  1056. //mpTracker->SetStepByStep(true);
  1057. int numTemporalKFs = 15; //TODO (set by parameter): Temporal KFs in the local window if the map is inertial.
  1058. //Relationship to rebuild the essential graph, it is used two times, first in the local window and later in the rest of the map
  1059. KeyFrame* pNewChild;
  1060. KeyFrame* pNewParent;
  1061. vector<KeyFrame*> vpLocalCurrentWindowKFs;
  1062. vector<KeyFrame*> vpMergeConnectedKFs;
  1063. // Flag that is true only when we stopped a running BA, in this case we need relaunch at the end of the merge
  1064. bool bRelaunchBA = false;
  1065. Verbose::PrintMess("MERGE-VISUAL: Check Full Bundle Adjustment", Verbose::VERBOSITY_DEBUG);
  1066. // If a Global Bundle Adjustment is running, abort it
  1067. if(isRunningGBA())
  1068. {
  1069. unique_lock<mutex> lock(mMutexGBA);
  1070. mbStopGBA = true;
  1071. mnFullBAIdx++;
  1072. if(mpThreadGBA)
  1073. {
  1074. mpThreadGBA->detach();
  1075. delete mpThreadGBA;
  1076. }
  1077. bRelaunchBA = true;
  1078. }
  1079. Verbose::PrintMess("MERGE-VISUAL: Request Stop Local Mapping", Verbose::VERBOSITY_DEBUG);
  1080. mpLocalMapper->RequestStop();
  1081. // Wait until Local Mapping has effectively stopped
  1082. while(!mpLocalMapper->isStopped())
  1083. {
  1084. usleep(1000);
  1085. }
  1086. Verbose::PrintMess("MERGE-VISUAL: Local Map stopped", Verbose::VERBOSITY_DEBUG);
  1087. mpLocalMapper->EmptyQueue();
  1088. // Merge map will become in the new active map with the local window of KFs and MPs from the current map.
  1089. // Later, the elements of the current map will be transform to the new active map reference, in order to keep real time tracking
  1090. Map* pCurrentMap = mpCurrentKF->GetMap();
  1091. Map* pMergeMap = mpMergeMatchedKF->GetMap();
  1092. Verbose::PrintMess("MERGE-VISUAL: Initially there are " + to_string(pCurrentMap->KeyFramesInMap()) + " KFs and " + to_string(pCurrentMap->MapPointsInMap()) + " MPs in the active map ", Verbose::VERBOSITY_DEBUG);
  1093. Verbose::PrintMess("MERGE-VISUAL: Initially there are " + to_string(pMergeMap->KeyFramesInMap()) + " KFs and " + to_string(pMergeMap->MapPointsInMap()) + " MPs in the matched map ", Verbose::VERBOSITY_DEBUG);
  1094. //vector<KeyFrame*> vpMergeKFs = pMergeMap->GetAllKeyFrames();
  1095. ////
  1096. // Ensure current keyframe is updated
  1097. mpCurrentKF->UpdateConnections();
  1098. //Get the current KF and its neighbors(visual->covisibles; inertial->temporal+covisibles)
  1099. set<KeyFrame*> spLocalWindowKFs;
  1100. //Get MPs in the welding area from the current map
  1101. set<MapPoint*> spLocalWindowMPs;
  1102. if(pCurrentMap->IsInertial() && pMergeMap->IsInertial()) //TODO Check the correct initialization
  1103. {
  1104. KeyFrame* pKFi = mpCurrentKF;
  1105. int nInserted = 0;
  1106. while(pKFi && nInserted < numTemporalKFs)
  1107. {
  1108. spLocalWindowKFs.insert(pKFi);
  1109. pKFi = mpCurrentKF->mPrevKF;
  1110. nInserted++;
  1111. set<MapPoint*> spMPi = pKFi->GetMapPoints();
  1112. spLocalWindowMPs.insert(spMPi.begin(), spMPi.end());
  1113. }
  1114. pKFi = mpCurrentKF->mNextKF;
  1115. while(pKFi)
  1116. {
  1117. spLocalWindowKFs.insert(pKFi);
  1118. set<MapPoint*> spMPi = pKFi->GetMapPoints();
  1119. spLocalWindowMPs.insert(spMPi.begin(), spMPi.end());
  1120. }
  1121. }
  1122. else
  1123. {
  1124. spLocalWindowKFs.insert(mpCurrentKF);
  1125. }
  1126. vector<KeyFrame*> vpCovisibleKFs = mpCurrentKF->GetBestCovisibilityKeyFrames(numTemporalKFs);
  1127. spLocalWindowKFs.insert(vpCovisibleKFs.begin(), vpCovisibleKFs.end());
  1128. Verbose::PrintMess("MERGE-VISUAL: Initial number of KFs in local window from active map: " + to_string(spLocalWindowKFs.size()), Verbose::VERBOSITY_DEBUG);
  1129. const int nMaxTries = 3;
  1130. int nNumTries = 0;
  1131. while(spLocalWindowKFs.size() < numTemporalKFs && nNumTries < nMaxTries)
  1132. {
  1133. vector<KeyFrame*> vpNewCovKFs;
  1134. vpNewCovKFs.empty();
  1135. for(KeyFrame* pKFi : spLocalWindowKFs)
  1136. {
  1137. vector<KeyFrame*> vpKFiCov = pKFi->GetBestCovisibilityKeyFrames(numTemporalKFs/2);
  1138. for(KeyFrame* pKFcov : vpKFiCov)
  1139. {
  1140. if(pKFcov && !pKFcov->isBad() && spLocalWindowKFs.find(pKFcov) == spLocalWindowKFs.end())
  1141. {
  1142. vpNewCovKFs.push_back(pKFcov);
  1143. }
  1144. }
  1145. }
  1146. spLocalWindowKFs.insert(vpNewCovKFs.begin(), vpNewCovKFs.end());
  1147. nNumTries++;
  1148. }
  1149. Verbose::PrintMess("MERGE-VISUAL: Last number of KFs in local window from the active map: " + to_string(spLocalWindowKFs.size()), Verbose::VERBOSITY_DEBUG);
  1150. //TODO TEST
  1151. //vector<KeyFrame*> vpTestKFs = pCurrentMap->GetAllKeyFrames();
  1152. //spLocalWindowKFs.insert(vpTestKFs.begin(), vpTestKFs.end());
  1153. for(KeyFrame* pKFi : spLocalWindowKFs)
  1154. {
  1155. if(!pKFi || pKFi->isBad())
  1156. continue;
  1157. set<MapPoint*> spMPs = pKFi->GetMapPoints();
  1158. spLocalWindowMPs.insert(spMPs.begin(), spMPs.end());
  1159. }
  1160. Verbose::PrintMess("MERGE-VISUAL: Number of MPs in local window from active map: " + to_string(spLocalWindowMPs.size()), Verbose::VERBOSITY_DEBUG);
  1161. Verbose::PrintMess("MERGE-VISUAL: Number of MPs in the active map: " + to_string(pCurrentMap->GetAllMapPoints().size()), Verbose::VERBOSITY_DEBUG);
  1162. Verbose::PrintMess("-------", Verbose::VERBOSITY_DEBUG);
  1163. set<KeyFrame*> spMergeConnectedKFs;
  1164. if(pCurrentMap->IsInertial() && pMergeMap->IsInertial()) //TODO Check the correct initialization
  1165. {
  1166. KeyFrame* pKFi = mpMergeMatchedKF;
  1167. int nInserted = 0;
  1168. while(pKFi && nInserted < numTemporalKFs)
  1169. {
  1170. spMergeConnectedKFs.insert(pKFi);
  1171. pKFi = mpCurrentKF->mPrevKF;
  1172. nInserted++;
  1173. }
  1174. pKFi = mpMergeMatchedKF->mNextKF;
  1175. while(pKFi)
  1176. {
  1177. spMergeConnectedKFs.insert(pKFi);
  1178. }
  1179. }
  1180. else
  1181. {
  1182. spMergeConnectedKFs.insert(mpMergeMatchedKF);
  1183. }
  1184. vpCovisibleKFs = mpMergeMatchedKF->GetBestCovisibilityKeyFrames(numTemporalKFs);
  1185. spMergeConnectedKFs.insert(vpCovisibleKFs.begin(), vpCovisibleKFs.end());
  1186. Verbose::PrintMess("MERGE-VISUAL: Initial number of KFs in the local window from matched map: " + to_string(spMergeConnectedKFs.size()), Verbose::VERBOSITY_DEBUG);
  1187. nNumTries = 0;
  1188. while(spMergeConnectedKFs.size() < numTemporalKFs && nNumTries < nMaxTries)
  1189. {
  1190. vector<KeyFrame*> vpNewCovKFs;
  1191. for(KeyFrame* pKFi : spMergeConnectedKFs)
  1192. {
  1193. vector<KeyFrame*> vpKFiCov = pKFi->GetBestCovisibilityKeyFrames(numTemporalKFs/2);
  1194. for(KeyFrame* pKFcov : vpKFiCov)
  1195. {
  1196. if(pKFcov && !pKFcov->isBad() && spMergeConnectedKFs.find(pKFcov) == spMergeConnectedKFs.end())
  1197. {
  1198. vpNewCovKFs.push_back(pKFcov);
  1199. }
  1200. }
  1201. }
  1202. spMergeConnectedKFs.insert(vpNewCovKFs.begin(), vpNewCovKFs.end());
  1203. nNumTries++;
  1204. }
  1205. Verbose::PrintMess("MERGE-VISUAL: Last number of KFs in the localwindow from matched map: " + to_string(spMergeConnectedKFs.size()), Verbose::VERBOSITY_DEBUG);
  1206. set<MapPoint*> spMapPointMerge;
  1207. for(KeyFrame* pKFi : spMergeConnectedKFs)
  1208. {
  1209. set<MapPoint*> vpMPs = pKFi->GetMapPoints();
  1210. spMapPointMerge.insert(vpMPs.begin(),vpMPs.end());
  1211. }
  1212. vector<MapPoint*> vpCheckFuseMapPoint;
  1213. vpCheckFuseMapPoint.reserve(spMapPointMerge.size());
  1214. std::copy(spMapPointMerge.begin(), spMapPointMerge.end(), std::back_inserter(vpCheckFuseMapPoint));
  1215. //
  1216. cv::Mat Twc = mpCurrentKF->GetPoseInverse();
  1217. cv::Mat Rwc = Twc.rowRange(0,3).colRange(0,3);
  1218. cv::Mat twc = Twc.rowRange(0,3).col(3);
  1219. g2o::Sim3 g2oNonCorrectedSwc(Converter::toMatrix3d(Rwc),Converter::toVector3d(twc),1.0);
  1220. g2o::Sim3 g2oNonCorrectedScw = g2oNonCorrectedSwc.inverse();
  1221. g2o::Sim3 g2oCorrectedScw = mg2oMergeScw; //TODO Check the transformation
  1222. KeyFrameAndPose vCorrectedSim3, vNonCorrectedSim3;
  1223. vCorrectedSim3[mpCurrentKF]=g2oCorrectedScw;
  1224. vNonCorrectedSim3[mpCurrentKF]=g2oNonCorrectedScw;
  1225. //TODO Time test
  1226. #ifdef COMPILEDWITHC11
  1227. std::chrono::steady_clock::time_point timeStartTransfMerge = std::chrono::steady_clock::now();
  1228. #else
  1229. std::chrono::monotonic_clock::time_point timeStartTransfMerge = std::chrono::monotonic_clock::now();
  1230. #endif
  1231. for(KeyFrame* pKFi : spLocalWindowKFs)
  1232. {
  1233. if(!pKFi || pKFi->isBad())
  1234. {
  1235. Verbose::PrintMess("Bad KF in correction", Verbose::VERBOSITY_DEBUG);
  1236. continue;
  1237. }
  1238. if(pKFi->GetMap() != pCurrentMap)
  1239. Verbose::PrintMess("Other map KF, this should't happen", Verbose::VERBOSITY_DEBUG);
  1240. g2o::Sim3 g2oCorrectedSiw;
  1241. if(pKFi!=mpCurrentKF)
  1242. {
  1243. cv::Mat Tiw = pKFi->GetPose();
  1244. cv::Mat Riw = Tiw.rowRange(0,3).colRange(0,3);
  1245. cv::Mat tiw = Tiw.rowRange(0,3).col(3);
  1246. g2o::Sim3 g2oSiw(Converter::toMatrix3d(Riw),Converter::toVector3d(tiw),1.0);
  1247. //Pose without correction
  1248. vNonCorrectedSim3[pKFi]=g2oSiw;
  1249. cv::Mat Tic = Tiw*Twc;
  1250. cv::Mat Ric = Tic.rowRange(0,3).colRange(0,3);
  1251. cv::Mat tic = Tic.rowRange(0,3).col(3);
  1252. g2o::Sim3 g2oSic(Converter::toMatrix3d(Ric),Converter::toVector3d(tic),1.0);
  1253. g2oCorrectedSiw = g2oSic*mg2oMergeScw;
  1254. vCorrectedSim3[pKFi]=g2oCorrectedSiw;
  1255. }
  1256. else
  1257. {
  1258. g2oCorrectedSiw = g2oCorrectedScw;
  1259. }
  1260. pKFi->mTcwMerge = pKFi->GetPose();
  1261. // Update keyframe pose with corrected Sim3. First transform Sim3 to SE3 (scale translation)
  1262. Eigen::Matrix3d eigR = g2oCorrectedSiw.rotation().toRotationMatrix();
  1263. Eigen::Vector3d eigt = g2oCorrectedSiw.translation();
  1264. double s = g2oCorrectedSiw.scale();
  1265. pKFi->mfScale = s;
  1266. eigt *=(1./s); //[R t/s;0 1]
  1267. //cout << "R: " << mg2oMergeScw.rotation().toRotationMatrix() << endl;
  1268. //cout << "angle: " << 180*LogSO3(mg2oMergeScw.rotation().toRotationMatrix())/3.14 << endl;
  1269. //cout << "t: " << mg2oMergeScw.translation() << endl;
  1270. cv::Mat correctedTiw = Converter::toCvSE3(eigR,eigt);
  1271. pKFi->mTcwMerge = correctedTiw;
  1272. //pKFi->SetPose(correctedTiw);
  1273. // Make sure connections are updated
  1274. //pKFi->UpdateMap(pMergeMap);
  1275. //pMergeMap->AddKeyFrame(pKFi);
  1276. //pCurrentMap->EraseKeyFrame(pKFi);
  1277. //cout << "After -> Map current: " << pCurrentMap << "; New map: " << pKFi->GetMap() << endl;
  1278. if(pCurrentMap->isImuInitialized())
  1279. {
  1280. Eigen::Matrix3d Rcor = eigR.transpose()*vNonCorrectedSim3[pKFi].rotation().toRotationMatrix();
  1281. pKFi->mVwbMerge = Converter::toCvMat(Rcor)*pKFi->GetVelocity();
  1282. //pKFi->SetVelocity(Converter::toCvMat(Rcor)*pKFi->GetVelocity()); // TODO: should add here scale s
  1283. }
  1284. //TODO DEBUG to know which are the KFs that had been moved to the other map
  1285. //pKFi->mnOriginMapId = 5;
  1286. }
  1287. for(MapPoint* pMPi : spLocalWindowMPs)
  1288. {
  1289. if(!pMPi || pMPi->isBad())
  1290. continue;
  1291. KeyFrame* pKFref = pMPi->GetReferenceKeyFrame();
  1292. g2o::Sim3 g2oCorrectedSwi = vCorrectedSim3[pKFref].inverse();
  1293. g2o::Sim3 g2oNonCorrectedSiw = vNonCorrectedSim3[pKFref];
  1294. // Project with non-corrected pose and project back with corrected pose
  1295. cv::Mat P3Dw = pMPi->GetWorldPos();
  1296. Eigen::Matrix<double,3,1> eigP3Dw = Converter::toVector3d(P3Dw);
  1297. Eigen::Matrix<double,3,1> eigCorrectedP3Dw = g2oCorrectedSwi.map(g2oNonCorrectedSiw.map(eigP3Dw));
  1298. Eigen::Matrix3d eigR = g2oCorrectedSwi.rotation().toRotationMatrix();
  1299. Eigen::Matrix3d Rcor = eigR * g2oNonCorrectedSiw.rotation().toRotationMatrix();
  1300. cv::Mat cvCorrectedP3Dw = Converter::toCvMat(eigCorrectedP3Dw);
  1301. pMPi->mPosMerge = cvCorrectedP3Dw;
  1302. //cout << "Rcor: " << Rcor << endl;
  1303. //cout << "Normal: " << pMPi->GetNormal() << endl;
  1304. pMPi->mNormalVectorMerge = Converter::toCvMat(Rcor) * pMPi->GetNormal();
  1305. //pMPi->SetWorldPos(cvCorrectedP3Dw);
  1306. //pMPi->UpdateMap(pMergeMap);
  1307. //pMergeMap->AddMapPoint(pMPi);
  1308. //pCurrentMap->EraseMapPoint(pMPi);
  1309. //pMPi->UpdateNormalAndDepth();
  1310. }
  1311. #ifdef COMPILEDWITHC11
  1312. std::chrono::steady_clock::time_point timeFinishTransfMerge = std::chrono::steady_clock::now();
  1313. #else
  1314. std::chrono::monotonic_clock::time_point timeFinishTransfMerge = std::chrono::monotonic_clock::now();
  1315. #endif
  1316. std::chrono::duration<double,std::milli> timeTransfMerge = timeFinishTransfMerge - timeStartTransfMerge; // Time in milliseconds
  1317. Verbose::PrintMess("MERGE-VISUAL: TRANSF ms: " + to_string(timeTransfMerge.count()), Verbose::VERBOSITY_DEBUG);
  1318. //TODO Time test
  1319. #ifdef COMPILEDWITHC11
  1320. std::chrono::steady_clock::time_point timeStartCritMerge = std::chrono::steady_clock::now();
  1321. #else
  1322. std::chrono::monotonic_clock::time_point timeStartCritMerge = std::chrono::monotonic_clock::now();
  1323. #endif
  1324. {
  1325. unique_lock<mutex> currentLock(pCurrentMap->mMutexMapUpdate); // We update the current map with the Merge information
  1326. unique_lock<mutex> mergeLock(pMergeMap->mMutexMapUpdate); // We remove the Kfs and MPs in the merged area from the old map
  1327. for(KeyFrame* pKFi : spLocalWindowKFs)
  1328. {
  1329. if(!pKFi || pKFi->isBad())
  1330. {
  1331. //cout << "Bad KF in correction" << endl;
  1332. continue;
  1333. }
  1334. pKFi->mTcwBefMerge = pKFi->GetPose();
  1335. pKFi->mTwcBefMerge = pKFi->GetPoseInverse();
  1336. pKFi->SetPose(pKFi->mTcwMerge);
  1337. // Make sure connections are updated
  1338. pKFi->UpdateMap(pMergeMap);
  1339. pKFi->mnMergeCorrectedForKF = mpCurrentKF->mnId;
  1340. pMergeMap->AddKeyFrame(pKFi);
  1341. pCurrentMap->EraseKeyFrame(pKFi);
  1342. if(pCurrentMap->isImuInitialized())
  1343. {
  1344. pKFi->SetVelocity(pKFi->mVwbMerge);
  1345. }
  1346. }
  1347. for(MapPoint* pMPi : spLocalWindowMPs)
  1348. {
  1349. if(!pMPi || pMPi->isBad())
  1350. continue;
  1351. pMPi->SetWorldPos(pMPi->mPosMerge);
  1352. pMPi->SetNormalVector(pMPi->mNormalVectorMerge);
  1353. pMPi->UpdateMap(pMergeMap);
  1354. pMergeMap->AddMapPoint(pMPi);
  1355. pCurrentMap->EraseMapPoint(pMPi);
  1356. //pMPi->UpdateNormalAndDepth();
  1357. }
  1358. mpAtlas->ChangeMap(pMergeMap);
  1359. mpAtlas->SetMapBad(pCurrentMap);
  1360. pMergeMap->IncreaseChangeIndex();
  1361. //TODO for debug
  1362. pMergeMap->ChangeId(pCurrentMap->GetId());
  1363. }
  1364. #ifdef COMPILEDWITHC11
  1365. std::chrono::steady_clock::time_point timeFinishCritMerge = std::chrono::steady_clock::now();
  1366. #else
  1367. std::chrono::monotonic_clock::time_point timeFinishCritMerge = std::chrono::monotonic_clock::now();
  1368. #endif
  1369. std::chrono::duration<double,std::milli> timeCritMerge = timeFinishCritMerge - timeStartCritMerge; // Time in milliseconds
  1370. Verbose::PrintMess("MERGE-VISUAL: New current map: " + to_string(pMergeMap->GetId()), Verbose::VERBOSITY_DEBUG);
  1371. Verbose::PrintMess("MERGE-VISUAL: CRITICAL ms: " + to_string(timeCritMerge.count()), Verbose::VERBOSITY_DEBUG);
  1372. Verbose::PrintMess("MERGE-VISUAL: LOCAL MAPPING number of KFs: " + to_string(mpLocalMapper->KeyframesInQueue()), Verbose::VERBOSITY_DEBUG);
  1373. //Rebuild the essential graph in the local window
  1374. pCurrentMap->GetOriginKF()->SetFirstConnection(false);
  1375. pNewChild = mpCurrentKF->GetParent(); // Old parent, it will be the new child of this KF
  1376. pNewParent = mpCurrentKF; // Old child, now it will be the parent of its own parent(we need eliminate this KF from children list in its old parent)
  1377. mpCurrentKF->ChangeParent(mpMergeMatchedKF);
  1378. while(pNewChild /*&& spLocalWindowKFs.find(pNewChild) != spLocalWindowKFs.end()*/)
  1379. {
  1380. pNewChild->EraseChild(pNewParent); // We remove the relation between the old parent and the new for avoid loop
  1381. KeyFrame * pOldParent = pNewChild->GetParent();
  1382. pNewChild->ChangeParent(pNewParent);
  1383. //cout << "The new parent of KF " << pNewChild->mnId << " was " << pNewChild->GetParent()->mnId << endl;
  1384. pNewParent = pNewChild;
  1385. pNewChild = pOldParent;
  1386. }
  1387. //Update the connections between the local window
  1388. mpMergeMatchedKF->UpdateConnections();
  1389. //cout << "MERGE-VISUAL: Essential graph rebuilded" << endl;
  1390. //std::copy(spMapPointCurrent.begin(), spMapPointCurrent.end(), std::back_inserter(vpCheckFuseMapPoint));
  1391. vpMergeConnectedKFs = mpMergeMatchedKF->GetVectorCovisibleKeyFrames();
  1392. vpMergeConnectedKFs.push_back(mpMergeMatchedKF);
  1393. vpCheckFuseMapPoint.reserve(spMapPointMerge.size());
  1394. std::copy(spMapPointMerge.begin(), spMapPointMerge.end(), std::back_inserter(vpCheckFuseMapPoint));
  1395. //TODO Time test
  1396. #ifdef COMPILEDWITHC11
  1397. std::chrono::steady_clock::time_point timeStartFuseMerge = std::chrono::steady_clock::now();
  1398. #else
  1399. std::chrono::monotonic_clock::time_point timeStartFuseMerge = std::chrono::monotonic_clock::now();
  1400. #endif
  1401. // Project MapPoints observed in the neighborhood of the merge keyframe
  1402. // into the current keyframe and neighbors using corrected poses.
  1403. // Fuse duplications.
  1404. SearchAndFuse(vCorrectedSim3, vpCheckFuseMapPoint);
  1405. #ifdef COMPILEDWITHC11
  1406. std::chrono::steady_clock::time_point timeFinishFuseMerge = std::chrono::steady_clock::now();
  1407. #else
  1408. std::chrono::monotonic_clock::time_point timeFinishFuseMerge = std::chrono::monotonic_clock::now();
  1409. #endif
  1410. std::chrono::duration<double,std::milli> timeFuseMerge = timeFinishFuseMerge - timeStartFuseMerge; // Time in milliseconds
  1411. Verbose::PrintMess("MERGE-VISUAL: FUSE DUPLICATED ms: " + to_string(timeFuseMerge.count()), Verbose::VERBOSITY_DEBUG);
  1412. // Update connectivity
  1413. Verbose::PrintMess("MERGE-VISUAL: Init to update connections in the welding area", Verbose::VERBOSITY_DEBUG);
  1414. for(KeyFrame* pKFi : spLocalWindowKFs)
  1415. {
  1416. if(!pKFi || pKFi->isBad())
  1417. continue;
  1418. pKFi->UpdateConnections();
  1419. }
  1420. for(KeyFrame* pKFi : spMergeConnectedKFs)
  1421. {
  1422. if(!pKFi || pKFi->isBad())
  1423. continue;
  1424. pKFi->UpdateConnections();
  1425. }
  1426. //CheckObservations(spLocalWindowKFs, spMergeConnectedKFs);
  1427. Verbose::PrintMess("MERGE-VISUAL: Finish to update connections in the welding area", Verbose::VERBOSITY_DEBUG);
  1428. bool bStop = false;
  1429. Verbose::PrintMess("MERGE-VISUAL: Start local BA ", Verbose::VERBOSITY_DEBUG);
  1430. vpLocalCurrentWindowKFs.clear();
  1431. vpMergeConnectedKFs.clear();
  1432. std::copy(spLocalWindowKFs.begin(), spLocalWindowKFs.end(), std::back_inserter(vpLocalCurrentWindowKFs));
  1433. std::copy(spMergeConnectedKFs.begin(), spMergeConnectedKFs.end(), std::back_inserter(vpMergeConnectedKFs));
  1434. if (mpTracker->mSensor==System::IMU_MONOCULAR || mpTracker->mSensor==System::IMU_STEREO)
  1435. {
  1436. Verbose::PrintMess("MERGE-VISUAL: Visual-Inertial", Verbose::VERBOSITY_DEBUG);
  1437. Optimizer::MergeInertialBA(mpLocalMapper->GetCurrKF(),mpMergeMatchedKF,&bStop, mpCurrentKF->GetMap(),vCorrectedSim3);
  1438. }
  1439. else
  1440. {
  1441. Verbose::PrintMess("MERGE-VISUAL: Visual", Verbose::VERBOSITY_DEBUG);
  1442. Verbose::PrintMess("MERGE-VISUAL: Local current window->" + to_string(vpLocalCurrentWindowKFs.size()) + "; Local merge window->" + to_string(vpMergeConnectedKFs.size()), Verbose::VERBOSITY_DEBUG);
  1443. Optimizer::LocalBundleAdjustment(mpCurrentKF, vpLocalCurrentWindowKFs, vpMergeConnectedKFs,&bStop);
  1444. }
  1445. // Loop closed. Release Local Mapping.
  1446. mpLocalMapper->Release();
  1447. //return;
  1448. Verbose::PrintMess("MERGE-VISUAL: Finish the LBA", Verbose::VERBOSITY_DEBUG);
  1449. ////
  1450. //Update the non critical area from the current map to the merged map
  1451. vector<KeyFrame*> vpCurrentMapKFs = pCurrentMap->GetAllKeyFrames();
  1452. vector<MapPoint*> vpCurrentMapMPs = pCurrentMap->GetAllMapPoints();
  1453. if(vpCurrentMapKFs.size() == 0)
  1454. {
  1455. Verbose::PrintMess("MERGE-VISUAL: There are not KFs outside of the welding area", Verbose::VERBOSITY_DEBUG);
  1456. }
  1457. else
  1458. {
  1459. Verbose::PrintMess("MERGE-VISUAL: Calculate the new position of the elements outside of the window", Verbose::VERBOSITY_DEBUG);
  1460. //Apply the transformation
  1461. {
  1462. if(mpTracker->mSensor == System::MONOCULAR)
  1463. {
  1464. unique_lock<mutex> currentLock(pCurrentMap->mMutexMapUpdate); // We update the current map with the Merge information
  1465. for(KeyFrame* pKFi : vpCurrentMapKFs)
  1466. {
  1467. if(!pKFi || pKFi->isBad() || pKFi->GetMap() != pCurrentMap)
  1468. {
  1469. continue;
  1470. }
  1471. g2o::Sim3 g2oCorrectedSiw;
  1472. cv::Mat Tiw = pKFi->GetPose();
  1473. cv::Mat Riw = Tiw.rowRange(0,3).colRange(0,3);
  1474. cv::Mat tiw = Tiw.rowRange(0,3).col(3);
  1475. g2o::Sim3 g2oSiw(Converter::toMatrix3d(Riw),Converter::toVector3d(tiw),1.0);
  1476. //Pose without correction
  1477. vNonCorrectedSim3[pKFi]=g2oSiw;
  1478. cv::Mat Tic = Tiw*Twc;
  1479. cv::Mat Ric = Tic.rowRange(0,3).colRange(0,3);
  1480. cv::Mat tic = Tic.rowRange(0,3).col(3);
  1481. g2o::Sim3 g2oSim(Converter::toMatrix3d(Ric),Converter::toVector3d(tic),1.0);
  1482. g2oCorrectedSiw = g2oSim*mg2oMergeScw;
  1483. vCorrectedSim3[pKFi]=g2oCorrectedSiw;
  1484. // Update keyframe pose with corrected Sim3. First transform Sim3 to SE3 (scale translation)
  1485. Eigen::Matrix3d eigR = g2oCorrectedSiw.rotation().toRotationMatrix();
  1486. Eigen::Vector3d eigt = g2oCorrectedSiw.translation();
  1487. double s = g2oCorrectedSiw.scale();
  1488. pKFi->mfScale = s;
  1489. eigt *=(1./s); //[R t/s;0 1]
  1490. cv::Mat correctedTiw = Converter::toCvSE3(eigR,eigt);
  1491. pKFi->mTcwBefMerge = pKFi->GetPose();
  1492. pKFi->mTwcBefMerge = pKFi->GetPoseInverse();
  1493. pKFi->SetPose(correctedTiw);
  1494. if(pCurrentMap->isImuInitialized())
  1495. {
  1496. Eigen::Matrix3d Rcor = eigR.transpose()*vNonCorrectedSim3[pKFi].rotation().toRotationMatrix();
  1497. pKFi->SetVelocity(Converter::toCvMat(Rcor)*pKFi->GetVelocity()); // TODO: should add here scale s
  1498. }
  1499. }
  1500. for(MapPoint* pMPi : vpCurrentMapMPs)
  1501. {
  1502. if(!pMPi || pMPi->isBad()|| pMPi->GetMap() != pCurrentMap)
  1503. continue;
  1504. KeyFrame* pKFref = pMPi->GetReferenceKeyFrame();
  1505. g2o::Sim3 g2oCorrectedSwi = vCorrectedSim3[pKFref].inverse();
  1506. g2o::Sim3 g2oNonCorrectedSiw = vNonCorrectedSim3[pKFref];
  1507. // Project with non-corrected pose and project back with corrected pose
  1508. cv::Mat P3Dw = pMPi->GetWorldPos();
  1509. Eigen::Matrix<double,3,1> eigP3Dw = Converter::toVector3d(P3Dw);
  1510. Eigen::Matrix<double,3,1> eigCorrectedP3Dw = g2oCorrectedSwi.map(g2oNonCorrectedSiw.map(eigP3Dw));
  1511. cv::Mat cvCorrectedP3Dw = Converter::toCvMat(eigCorrectedP3Dw);
  1512. pMPi->SetWorldPos(cvCorrectedP3Dw);
  1513. pMPi->UpdateNormalAndDepth();
  1514. }
  1515. }
  1516. }
  1517. Verbose::PrintMess("MERGE-VISUAL: Apply transformation to all elements of the old map", Verbose::VERBOSITY_DEBUG);
  1518. mpLocalMapper->RequestStop();
  1519. // Wait until Local Mapping has effectively stopped
  1520. while(!mpLocalMapper->isStopped())
  1521. {
  1522. usleep(1000);
  1523. }
  1524. Verbose::PrintMess("MERGE-VISUAL: Local Map stopped", Verbose::VERBOSITY_DEBUG);
  1525. // Optimize graph (and update the loop position for each element form the begining to the end)
  1526. if(mpTracker->mSensor != System::MONOCULAR)
  1527. {
  1528. Optimizer::OptimizeEssentialGraph(mpCurrentKF, vpMergeConnectedKFs, vpLocalCurrentWindowKFs, vpCurrentMapKFs, vpCurrentMapMPs);
  1529. }
  1530. {
  1531. // Get Merge Map Mutex
  1532. unique_lock<mutex> currentLock(pCurrentMap->mMutexMapUpdate); // We update the current map with the Merge information
  1533. unique_lock<mutex> mergeLock(pMergeMap->mMutexMapUpdate); // We remove the Kfs and MPs in the merged area from the old map
  1534. Verbose::PrintMess("MERGE-VISUAL: There are " + to_string(pMergeMap->KeyFramesInMap()) + " KFs in the map", Verbose::VERBOSITY_DEBUG);
  1535. Verbose::PrintMess("MERGE-VISUAL: It will be inserted " + to_string(vpCurrentMapKFs.size()) + " KFs in the map", Verbose::VERBOSITY_DEBUG);
  1536. for(KeyFrame* pKFi : vpCurrentMapKFs)
  1537. {
  1538. if(!pKFi || pKFi->isBad() || pKFi->GetMap() != pCurrentMap)
  1539. {
  1540. continue;
  1541. }
  1542. // Make sure connections are updated
  1543. pKFi->UpdateMap(pMergeMap);
  1544. pMergeMap->AddKeyFrame(pKFi);
  1545. pCurrentMap->EraseKeyFrame(pKFi);
  1546. }
  1547. Verbose::PrintMess("MERGE-VISUAL: There are " + to_string(pMergeMap->MapPointsInMap()) + " MPs in the map", Verbose::VERBOSITY_DEBUG);
  1548. Verbose::PrintMess("MERGE-VISUAL: It will be inserted " + to_string(vpCurrentMapMPs.size()) + " MPs in the map", Verbose::VERBOSITY_DEBUG);
  1549. for(MapPoint* pMPi : vpCurrentMapMPs)
  1550. {
  1551. if(!pMPi || pMPi->isBad())
  1552. continue;
  1553. pMPi->UpdateMap(pMergeMap);
  1554. pMergeMap->AddMapPoint(pMPi);
  1555. pCurrentMap->EraseMapPoint(pMPi);
  1556. }
  1557. Verbose::PrintMess("MERGE-VISUAL: There are " + to_string(pMergeMap->MapPointsInMap()) + " MPs in the map", Verbose::VERBOSITY_DEBUG);
  1558. }
  1559. Verbose::PrintMess("MERGE-VISUAL: Optimaze the essential graph", Verbose::VERBOSITY_DEBUG);
  1560. }
  1561. mpLocalMapper->Release();
  1562. Verbose::PrintMess("MERGE-VISUAL: Finally there are " + to_string(pMergeMap->KeyFramesInMap()) + "KFs and " + to_string(pMergeMap->MapPointsInMap()) + " MPs in the complete map ", Verbose::VERBOSITY_DEBUG);
  1563. Verbose::PrintMess("MERGE-VISUAL:Completed!!!!!", Verbose::VERBOSITY_DEBUG);
  1564. if(bRelaunchBA && (!pCurrentMap->isImuInitialized() || (pCurrentMap->KeyFramesInMap()<200 && mpAtlas->CountMaps()==1)))
  1565. {
  1566. // Launch a new thread to perform Global Bundle Adjustment
  1567. Verbose::PrintMess("Relaunch Global BA", Verbose::VERBOSITY_DEBUG);
  1568. mbRunningGBA = true;
  1569. mbFinishedGBA = false;
  1570. mbStopGBA = false;
  1571. mpThreadGBA = new thread(&LoopClosing::RunGlobalBundleAdjustment,this, pMergeMap, mpCurrentKF->mnId);
  1572. }
  1573. mpMergeMatchedKF->AddMergeEdge(mpCurrentKF);
  1574. mpCurrentKF->AddMergeEdge(mpMergeMatchedKF);
  1575. pCurrentMap->IncreaseChangeIndex();
  1576. pMergeMap->IncreaseChangeIndex();
  1577. mpAtlas->RemoveBadMaps();
  1578. }
  1579. void LoopClosing::printReprojectionError(set<KeyFrame*> &spLocalWindowKFs, KeyFrame* mpCurrentKF, string &name)
  1580. {
  1581. string path_imgs = "./test_Reproj/";
  1582. for(KeyFrame* pKFi : spLocalWindowKFs)
  1583. {
  1584. //cout << "KF " << pKFi->mnId << endl;
  1585. cv::Mat img_i = cv::imread(pKFi->mNameFile, CV_LOAD_IMAGE_UNCHANGED);
  1586. //cout << "Image -> " << img_i.cols << ", " << img_i.rows << endl;
  1587. cv::cvtColor(img_i, img_i, CV_GRAY2BGR);
  1588. //cout << "Change of color in the image " << endl;
  1589. vector<MapPoint*> vpMPs = pKFi->GetMapPointMatches();
  1590. int num_points = 0;
  1591. for(int j=0; j<vpMPs.size(); ++j)
  1592. {
  1593. MapPoint* pMPij = vpMPs[j];
  1594. if(!pMPij || pMPij->isBad())
  1595. {
  1596. continue;
  1597. }
  1598. cv::KeyPoint point_img = pKFi->mvKeysUn[j];
  1599. cv::Point2f reproj_p;
  1600. float u, v;
  1601. bool bIsInImage = pKFi->ProjectPointUnDistort(pMPij, reproj_p, u, v);
  1602. if(bIsInImage){
  1603. //cout << "Reproj in the image" << endl;
  1604. cv::circle(img_i, point_img.pt, 1/*point_img.octave*/, cv::Scalar(0, 255, 0));
  1605. cv::line(img_i, point_img.pt, reproj_p, cv::Scalar(0, 0, 255));
  1606. num_points++;
  1607. }
  1608. else
  1609. {
  1610. //cout << "Reproj out of the image" << endl;
  1611. cv::circle(img_i, point_img.pt, point_img.octave, cv::Scalar(0, 0, 255));
  1612. }
  1613. }
  1614. //cout << "Image painted" << endl;
  1615. string filename_img = path_imgs + "KF" + to_string(mpCurrentKF->mnId) + "_" + to_string(pKFi->mnId) + name + "points" + to_string(num_points) + ".png";
  1616. cv::imwrite(filename_img, img_i);
  1617. }
  1618. }
  1619. void LoopClosing::MergeLocal2()
  1620. {
  1621. cout << "Merge detected!!!!" << endl;
  1622. int numTemporalKFs = 11; //TODO (set by parameter): Temporal KFs in the local window if the map is inertial.
  1623. //Relationship to rebuild the essential graph, it is used two times, first in the local window and later in the rest of the map
  1624. KeyFrame* pNewChild;
  1625. KeyFrame* pNewParent;
  1626. vector<KeyFrame*> vpLocalCurrentWindowKFs;
  1627. vector<KeyFrame*> vpMergeConnectedKFs;
  1628. KeyFrameAndPose CorrectedSim3, NonCorrectedSim3;
  1629. // NonCorrectedSim3[mpCurrentKF]=mg2oLoopScw;
  1630. // Flag that is true only when we stopped a running BA, in this case we need relaunch at the end of the merge
  1631. bool bRelaunchBA = false;
  1632. cout << "Check Full Bundle Adjustment" << endl;
  1633. // If a Global Bundle Adjustment is running, abort it
  1634. if(isRunningGBA())
  1635. {
  1636. unique_lock<mutex> lock(mMutexGBA);
  1637. mbStopGBA = true;
  1638. mnFullBAIdx++;
  1639. if(mpThreadGBA)
  1640. {
  1641. mpThreadGBA->detach();
  1642. delete mpThreadGBA;
  1643. }
  1644. bRelaunchBA = true;
  1645. }
  1646. cout << "Request Stop Local Mapping" << endl;
  1647. mpLocalMapper->RequestStop();
  1648. // Wait until Local Mapping has effectively stopped
  1649. while(!mpLocalMapper->isStopped())
  1650. {
  1651. usleep(1000);
  1652. }
  1653. cout << "Local Map stopped" << endl;
  1654. Map* pCurrentMap = mpCurrentKF->GetMap();
  1655. Map* pMergeMap = mpMergeMatchedKF->GetMap();
  1656. {
  1657. float s_on = mSold_new.scale();
  1658. cv::Mat R_on = Converter::toCvMat(mSold_new.rotation().toRotationMatrix());
  1659. cv::Mat t_on = Converter::toCvMat(mSold_new.translation());
  1660. unique_lock<mutex> lock(mpAtlas->GetCurrentMap()->mMutexMapUpdate);
  1661. cout << "KFs before empty: " << mpAtlas->GetCurrentMap()->KeyFramesInMap() << endl;
  1662. mpLocalMapper->EmptyQueue();
  1663. cout << "KFs after empty: " << mpAtlas->GetCurrentMap()->KeyFramesInMap() << endl;
  1664. std::chrono::steady_clock::time_point t2 = std::chrono::steady_clock::now();
  1665. cout << "updating active map to merge reference" << endl;
  1666. cout << "curr merge KF id: " << mpCurrentKF->mnId << endl;
  1667. cout << "curr tracking KF id: " << mpTracker->GetLastKeyFrame()->mnId << endl;
  1668. bool bScaleVel=false;
  1669. if(s_on!=1)
  1670. bScaleVel=true;
  1671. mpAtlas->GetCurrentMap()->ApplyScaledRotation(R_on,s_on,bScaleVel,t_on);
  1672. mpTracker->UpdateFrameIMU(s_on,mpCurrentKF->GetImuBias(),mpTracker->GetLastKeyFrame());
  1673. std::chrono::steady_clock::time_point t3 = std::chrono::steady_clock::now();
  1674. }
  1675. const int numKFnew=pCurrentMap->KeyFramesInMap();
  1676. if((mpTracker->mSensor==System::IMU_MONOCULAR || mpTracker->mSensor==System::IMU_STEREO)&& !pCurrentMap->GetIniertialBA2()){
  1677. // Map is not completly initialized
  1678. Eigen::Vector3d bg, ba;
  1679. bg << 0., 0., 0.;
  1680. ba << 0., 0., 0.;
  1681. Optimizer::InertialOptimization(pCurrentMap,bg,ba);
  1682. IMU::Bias b (ba[0],ba[1],ba[2],bg[0],bg[1],bg[2]);
  1683. unique_lock<mutex> lock(mpAtlas->GetCurrentMap()->mMutexMapUpdate);
  1684. mpTracker->UpdateFrameIMU(1.0f,b,mpTracker->GetLastKeyFrame());
  1685. // Set map initialized
  1686. pCurrentMap->SetIniertialBA2();
  1687. pCurrentMap->SetIniertialBA1();
  1688. pCurrentMap->SetImuInitialized();
  1689. }
  1690. cout << "MergeMap init ID: " << pMergeMap->GetInitKFid() << " CurrMap init ID: " << pCurrentMap->GetInitKFid() << endl;
  1691. // Load KFs and MPs from merge map
  1692. cout << "updating current map" << endl;
  1693. {
  1694. // Get Merge Map Mutex (This section stops tracking!!)
  1695. unique_lock<mutex> currentLock(pCurrentMap->mMutexMapUpdate); // We update the current map with the Merge information
  1696. unique_lock<mutex> mergeLock(pMergeMap->mMutexMapUpdate); // We remove the Kfs and MPs in the merged area from the old map
  1697. vector<KeyFrame*> vpMergeMapKFs = pMergeMap->GetAllKeyFrames();
  1698. vector<MapPoint*> vpMergeMapMPs = pMergeMap->GetAllMapPoints();
  1699. for(KeyFrame* pKFi : vpMergeMapKFs)
  1700. {
  1701. if(!pKFi || pKFi->isBad() || pKFi->GetMap() != pMergeMap)
  1702. {
  1703. continue;
  1704. }
  1705. // Make sure connections are updated
  1706. pKFi->UpdateMap(pCurrentMap);
  1707. pCurrentMap->AddKeyFrame(pKFi);
  1708. pMergeMap->EraseKeyFrame(pKFi);
  1709. }
  1710. for(MapPoint* pMPi : vpMergeMapMPs)
  1711. {
  1712. if(!pMPi || pMPi->isBad() || pMPi->GetMap() != pMergeMap)
  1713. continue;
  1714. pMPi->UpdateMap(pCurrentMap);
  1715. pCurrentMap->AddMapPoint(pMPi);
  1716. pMergeMap->EraseMapPoint(pMPi);
  1717. }
  1718. // Save non corrected poses (already merged maps)
  1719. vector<KeyFrame*> vpKFs = pCurrentMap->GetAllKeyFrames();
  1720. for(KeyFrame* pKFi : vpKFs)
  1721. {
  1722. cv::Mat Tiw=pKFi->GetPose();
  1723. cv::Mat Riw = Tiw.rowRange(0,3).colRange(0,3);
  1724. cv::Mat tiw = Tiw.rowRange(0,3).col(3);
  1725. g2o::Sim3 g2oSiw(Converter::toMatrix3d(Riw),Converter::toVector3d(tiw),1.0);
  1726. NonCorrectedSim3[pKFi]=g2oSiw;
  1727. }
  1728. }
  1729. cout << "MergeMap init ID: " << pMergeMap->GetInitKFid() << " CurrMap init ID: " << pCurrentMap->GetInitKFid() << endl;
  1730. cout << "end updating current map" << endl;
  1731. // Critical zone
  1732. bool good = pCurrentMap->CheckEssentialGraph();
  1733. /*if(!good)
  1734. cout << "BAD ESSENTIAL GRAPH!!" << endl;*/
  1735. cout << "Update essential graph" << endl;
  1736. // mpCurrentKF->UpdateConnections(); // to put at false mbFirstConnection
  1737. pMergeMap->GetOriginKF()->SetFirstConnection(false);
  1738. pNewChild = mpMergeMatchedKF->GetParent(); // Old parent, it will be the new child of this KF
  1739. pNewParent = mpMergeMatchedKF; // Old child, now it will be the parent of its own parent(we need eliminate this KF from children list in its old parent)
  1740. mpMergeMatchedKF->ChangeParent(mpCurrentKF);
  1741. while(pNewChild)
  1742. {
  1743. pNewChild->EraseChild(pNewParent); // We remove the relation between the old parent and the new for avoid loop
  1744. KeyFrame * pOldParent = pNewChild->GetParent();
  1745. pNewChild->ChangeParent(pNewParent);
  1746. pNewParent = pNewChild;
  1747. pNewChild = pOldParent;
  1748. }
  1749. cout << "MergeMap init ID: " << pMergeMap->GetInitKFid() << " CurrMap init ID: " << pCurrentMap->GetInitKFid() << endl;
  1750. cout << "end update essential graph" << endl;
  1751. good = pCurrentMap->CheckEssentialGraph();
  1752. if(!good)
  1753. cout << "BAD ESSENTIAL GRAPH 1!!" << endl;
  1754. cout << "Update relationship between KFs" << endl;
  1755. vector<MapPoint*> vpCheckFuseMapPoint; // MapPoint vector from current map to allow to fuse duplicated points with the old map (merge)
  1756. vector<KeyFrame*> vpCurrentConnectedKFs;
  1757. mvpMergeConnectedKFs.push_back(mpMergeMatchedKF);
  1758. vector<KeyFrame*> aux = mpMergeMatchedKF->GetVectorCovisibleKeyFrames();
  1759. mvpMergeConnectedKFs.insert(mvpMergeConnectedKFs.end(), aux.begin(), aux.end());
  1760. if (mvpMergeConnectedKFs.size()>6)
  1761. mvpMergeConnectedKFs.erase(mvpMergeConnectedKFs.begin()+6,mvpMergeConnectedKFs.end());
  1762. /*mvpMergeConnectedKFs = mpMergeMatchedKF->GetVectorCovisibleKeyFrames();
  1763. mvpMergeConnectedKFs.push_back(mpMergeMatchedKF);*/
  1764. mpCurrentKF->UpdateConnections();
  1765. vpCurrentConnectedKFs.push_back(mpCurrentKF);
  1766. /*vpCurrentConnectedKFs = mpCurrentKF->GetVectorCovisibleKeyFrames();
  1767. vpCurrentConnectedKFs.push_back(mpCurrentKF);*/
  1768. aux = mpCurrentKF->GetVectorCovisibleKeyFrames();
  1769. vpCurrentConnectedKFs.insert(vpCurrentConnectedKFs.end(), aux.begin(), aux.end());
  1770. if (vpCurrentConnectedKFs.size()>6)
  1771. vpCurrentConnectedKFs.erase(vpCurrentConnectedKFs.begin()+6,vpCurrentConnectedKFs.end());
  1772. set<MapPoint*> spMapPointMerge;
  1773. for(KeyFrame* pKFi : mvpMergeConnectedKFs)
  1774. {
  1775. set<MapPoint*> vpMPs = pKFi->GetMapPoints();
  1776. spMapPointMerge.insert(vpMPs.begin(),vpMPs.end());
  1777. if(spMapPointMerge.size()>1000)
  1778. break;
  1779. }
  1780. cout << "vpCurrentConnectedKFs.size() " << vpCurrentConnectedKFs.size() << endl;
  1781. cout << "mvpMergeConnectedKFs.size() " << mvpMergeConnectedKFs.size() << endl;
  1782. cout << "spMapPointMerge.size() " << spMapPointMerge.size() << endl;
  1783. vpCheckFuseMapPoint.reserve(spMapPointMerge.size());
  1784. std::copy(spMapPointMerge.begin(), spMapPointMerge.end(), std::back_inserter(vpCheckFuseMapPoint));
  1785. cout << "Finished to update relationship between KFs" << endl;
  1786. cout << "MergeMap init ID: " << pMergeMap->GetInitKFid() << " CurrMap init ID: " << pCurrentMap->GetInitKFid() << endl;
  1787. good = pCurrentMap->CheckEssentialGraph();
  1788. if(!good)
  1789. cout << "BAD ESSENTIAL GRAPH 2!!" << endl;
  1790. cout << "start SearchAndFuse" << endl;
  1791. SearchAndFuse(vpCurrentConnectedKFs, vpCheckFuseMapPoint);
  1792. cout << "end SearchAndFuse" << endl;
  1793. cout << "MergeMap init ID: " << pMergeMap->GetInitKFid() << " CurrMap init ID: " << pCurrentMap->GetInitKFid() << endl;
  1794. good = pCurrentMap->CheckEssentialGraph();
  1795. if(!good)
  1796. cout << "BAD ESSENTIAL GRAPH 3!!" << endl;
  1797. cout << "Init to update connections" << endl;
  1798. for(KeyFrame* pKFi : vpCurrentConnectedKFs)
  1799. {
  1800. if(!pKFi || pKFi->isBad())
  1801. continue;
  1802. pKFi->UpdateConnections();
  1803. }
  1804. for(KeyFrame* pKFi : mvpMergeConnectedKFs)
  1805. {
  1806. if(!pKFi || pKFi->isBad())
  1807. continue;
  1808. pKFi->UpdateConnections();
  1809. }
  1810. cout << "end update connections" << endl;
  1811. cout << "MergeMap init ID: " << pMergeMap->GetInitKFid() << " CurrMap init ID: " << pCurrentMap->GetInitKFid() << endl;
  1812. good = pCurrentMap->CheckEssentialGraph();
  1813. if(!good)
  1814. cout << "BAD ESSENTIAL GRAPH 4!!" << endl;
  1815. // TODO Check: If new map is too small, we suppose that not informaiton can be propagated from new to old map
  1816. if (numKFnew<10){
  1817. mpLocalMapper->Release();
  1818. return;
  1819. }
  1820. good = pCurrentMap->CheckEssentialGraph();
  1821. if(!good)
  1822. cout << "BAD ESSENTIAL GRAPH 5!!" << endl;
  1823. // Perform BA
  1824. bool bStopFlag=false;
  1825. KeyFrame* pCurrKF = mpTracker->GetLastKeyFrame();
  1826. cout << "start MergeInertialBA" << endl;
  1827. Optimizer::MergeInertialBA(pCurrKF, mpMergeMatchedKF, &bStopFlag, pCurrentMap,CorrectedSim3);
  1828. cout << "end MergeInertialBA" << endl;
  1829. good = pCurrentMap->CheckEssentialGraph();
  1830. if(!good)
  1831. cout << "BAD ESSENTIAL GRAPH 6!!" << endl;
  1832. // Release Local Mapping.
  1833. mpLocalMapper->Release();
  1834. return;
  1835. }
  1836. void LoopClosing::CheckObservations(set<KeyFrame*> &spKFsMap1, set<KeyFrame*> &spKFsMap2)
  1837. {
  1838. cout << "----------------------" << endl;
  1839. for(KeyFrame* pKFi1 : spKFsMap1)
  1840. {
  1841. map<KeyFrame*, int> mMatchedMP;
  1842. set<MapPoint*> spMPs = pKFi1->GetMapPoints();
  1843. for(MapPoint* pMPij : spMPs)
  1844. {
  1845. if(!pMPij || pMPij->isBad())
  1846. {
  1847. continue;
  1848. }
  1849. map<KeyFrame*, tuple<int,int>> mMPijObs = pMPij->GetObservations();
  1850. for(KeyFrame* pKFi2 : spKFsMap2)
  1851. {
  1852. if(mMPijObs.find(pKFi2) != mMPijObs.end())
  1853. {
  1854. if(mMatchedMP.find(pKFi2) != mMatchedMP.end())
  1855. {
  1856. mMatchedMP[pKFi2] = mMatchedMP[pKFi2] + 1;
  1857. }
  1858. else
  1859. {
  1860. mMatchedMP[pKFi2] = 1;
  1861. }
  1862. }
  1863. }
  1864. }
  1865. if(mMatchedMP.size() == 0)
  1866. {
  1867. cout << "CHECK-OBS: KF " << pKFi1->mnId << " has not any matched MP with the other map" << endl;
  1868. }
  1869. else
  1870. {
  1871. cout << "CHECK-OBS: KF " << pKFi1->mnId << " has matched MP with " << mMatchedMP.size() << " KF from the other map" << endl;
  1872. for(pair<KeyFrame*, int> matchedKF : mMatchedMP)
  1873. {
  1874. cout << " -KF: " << matchedKF.first->mnId << ", Number of matches: " << matchedKF.second << endl;
  1875. }
  1876. }
  1877. }
  1878. cout << "----------------------" << endl;
  1879. }
  1880. void LoopClosing::SearchAndFuse(const KeyFrameAndPose &CorrectedPosesMap, vector<MapPoint*> &vpMapPoints)
  1881. {
  1882. ORBmatcher matcher(0.8);
  1883. int total_replaces = 0;
  1884. cout << "FUSE: Initially there are " << vpMapPoints.size() << " MPs" << endl;
  1885. cout << "FUSE: Intially there are " << CorrectedPosesMap.size() << " KFs" << endl;
  1886. for(KeyFrameAndPose::const_iterator mit=CorrectedPosesMap.begin(), mend=CorrectedPosesMap.end(); mit!=mend;mit++)
  1887. {
  1888. int num_replaces = 0;
  1889. KeyFrame* pKFi = mit->first;
  1890. Map* pMap = pKFi->GetMap();
  1891. g2o::Sim3 g2oScw = mit->second;
  1892. cv::Mat cvScw = Converter::toCvMat(g2oScw);
  1893. vector<MapPoint*> vpReplacePoints(vpMapPoints.size(),static_cast<MapPoint*>(NULL));
  1894. int numFused = matcher.Fuse(pKFi,cvScw,vpMapPoints,4,vpReplacePoints);
  1895. // Get Map Mutex
  1896. unique_lock<mutex> lock(pMap->mMutexMapUpdate);
  1897. const int nLP = vpMapPoints.size();
  1898. for(int i=0; i<nLP;i++)
  1899. {
  1900. MapPoint* pRep = vpReplacePoints[i];
  1901. if(pRep)
  1902. {
  1903. num_replaces += 1;
  1904. pRep->Replace(vpMapPoints[i]);
  1905. }
  1906. }
  1907. total_replaces += num_replaces;
  1908. }
  1909. cout << "FUSE: " << total_replaces << " MPs had been fused" << endl;
  1910. }
  1911. void LoopClosing::SearchAndFuse(const vector<KeyFrame*> &vConectedKFs, vector<MapPoint*> &vpMapPoints)
  1912. {
  1913. ORBmatcher matcher(0.8);
  1914. int total_replaces = 0;
  1915. cout << "FUSE-POSE: Initially there are " << vpMapPoints.size() << " MPs" << endl;
  1916. cout << "FUSE-POSE: Intially there are " << vConectedKFs.size() << " KFs" << endl;
  1917. for(auto mit=vConectedKFs.begin(), mend=vConectedKFs.end(); mit!=mend;mit++)
  1918. {
  1919. int num_replaces = 0;
  1920. KeyFrame* pKF = (*mit);
  1921. Map* pMap = pKF->GetMap();
  1922. cv::Mat cvScw = pKF->GetPose();
  1923. vector<MapPoint*> vpReplacePoints(vpMapPoints.size(),static_cast<MapPoint*>(NULL));
  1924. matcher.Fuse(pKF,cvScw,vpMapPoints,4,vpReplacePoints);
  1925. // Get Map Mutex
  1926. unique_lock<mutex> lock(pMap->mMutexMapUpdate);
  1927. const int nLP = vpMapPoints.size();
  1928. for(int i=0; i<nLP;i++)
  1929. {
  1930. MapPoint* pRep = vpReplacePoints[i];
  1931. if(pRep)
  1932. {
  1933. num_replaces += 1;
  1934. pRep->Replace(vpMapPoints[i]);
  1935. }
  1936. }
  1937. cout << "FUSE-POSE: KF " << pKF->mnId << " ->" << num_replaces << " MPs fused" << endl;
  1938. total_replaces += num_replaces;
  1939. }
  1940. cout << "FUSE-POSE: " << total_replaces << " MPs had been fused" << endl;
  1941. }
  1942. void LoopClosing::RequestReset()
  1943. {
  1944. {
  1945. unique_lock<mutex> lock(mMutexReset);
  1946. mbResetRequested = true;
  1947. }
  1948. while(1)
  1949. {
  1950. {
  1951. unique_lock<mutex> lock2(mMutexReset);
  1952. if(!mbResetRequested)
  1953. break;
  1954. }
  1955. usleep(5000);
  1956. }
  1957. }
  1958. void LoopClosing::RequestResetActiveMap(Map *pMap)
  1959. {
  1960. {
  1961. unique_lock<mutex> lock(mMutexReset);
  1962. mbResetActiveMapRequested = true;
  1963. mpMapToReset = pMap;
  1964. }
  1965. while(1)
  1966. {
  1967. {
  1968. unique_lock<mutex> lock2(mMutexReset);
  1969. if(!mbResetActiveMapRequested)
  1970. break;
  1971. }
  1972. usleep(3000);
  1973. }
  1974. }
  1975. void LoopClosing::ResetIfRequested()
  1976. {
  1977. unique_lock<mutex> lock(mMutexReset);
  1978. if(mbResetRequested)
  1979. {
  1980. cout << "Loop closer reset requested..." << endl;
  1981. mlpLoopKeyFrameQueue.clear();
  1982. mLastLoopKFid=0; //TODO old variable, it is not use in the new algorithm
  1983. mbResetRequested=false;
  1984. mbResetActiveMapRequested = false;
  1985. }
  1986. else if(mbResetActiveMapRequested)
  1987. {
  1988. for (list<KeyFrame*>::const_iterator it=mlpLoopKeyFrameQueue.begin(); it != mlpLoopKeyFrameQueue.end();)
  1989. {
  1990. KeyFrame* pKFi = *it;
  1991. if(pKFi->GetMap() == mpMapToReset)
  1992. {
  1993. it = mlpLoopKeyFrameQueue.erase(it);
  1994. }
  1995. else
  1996. ++it;
  1997. }
  1998. mLastLoopKFid=mpAtlas->GetLastInitKFid(); //TODO old variable, it is not use in the new algorithm
  1999. mbResetActiveMapRequested=false;
  2000. }
  2001. }
  2002. void LoopClosing::RunGlobalBundleAdjustment(Map* pActiveMap, unsigned long nLoopKF)
  2003. {
  2004. Verbose::PrintMess("Starting Global Bundle Adjustment", Verbose::VERBOSITY_NORMAL);
  2005. const bool bImuInit = pActiveMap->isImuInitialized();
  2006. if(!bImuInit)
  2007. Optimizer::GlobalBundleAdjustemnt(pActiveMap,10,&mbStopGBA,nLoopKF,false);
  2008. else
  2009. Optimizer::FullInertialBA(pActiveMap,7,false,nLoopKF,&mbStopGBA);
  2010. int idx = mnFullBAIdx;
  2011. // Optimizer::GlobalBundleAdjustemnt(mpMap,10,&mbStopGBA,nLoopKF,false);
  2012. // Update all MapPoints and KeyFrames
  2013. // Local Mapping was active during BA, that means that there might be new keyframes
  2014. // not included in the Global BA and they are not consistent with the updated map.
  2015. // We need to propagate the correction through the spanning tree
  2016. {
  2017. unique_lock<mutex> lock(mMutexGBA);
  2018. if(idx!=mnFullBAIdx)
  2019. return;
  2020. if(!bImuInit && pActiveMap->isImuInitialized())
  2021. return;
  2022. if(!mbStopGBA)
  2023. {
  2024. Verbose::PrintMess("Global Bundle Adjustment finished", Verbose::VERBOSITY_NORMAL);
  2025. Verbose::PrintMess("Updating map ...", Verbose::VERBOSITY_NORMAL);
  2026. mpLocalMapper->RequestStop();
  2027. // Wait until Local Mapping has effectively stopped
  2028. while(!mpLocalMapper->isStopped() && !mpLocalMapper->isFinished())
  2029. {
  2030. usleep(1000);
  2031. }
  2032. // Get Map Mutex
  2033. unique_lock<mutex> lock(pActiveMap->mMutexMapUpdate);
  2034. // cout << "LC: Update Map Mutex adquired" << endl;
  2035. //pActiveMap->PrintEssentialGraph();
  2036. // Correct keyframes starting at map first keyframe
  2037. list<KeyFrame*> lpKFtoCheck(pActiveMap->mvpKeyFrameOrigins.begin(),pActiveMap->mvpKeyFrameOrigins.end());
  2038. while(!lpKFtoCheck.empty())
  2039. {
  2040. KeyFrame* pKF = lpKFtoCheck.front();
  2041. const set<KeyFrame*> sChilds = pKF->GetChilds();
  2042. //cout << "---Updating KF " << pKF->mnId << " with " << sChilds.size() << " childs" << endl;
  2043. //cout << " KF mnBAGlobalForKF: " << pKF->mnBAGlobalForKF << endl;
  2044. cv::Mat Twc = pKF->GetPoseInverse();
  2045. //cout << "Twc: " << Twc << endl;
  2046. //cout << "GBA: Correct KeyFrames" << endl;
  2047. for(set<KeyFrame*>::const_iterator sit=sChilds.begin();sit!=sChilds.end();sit++)
  2048. {
  2049. KeyFrame* pChild = *sit;
  2050. if(!pChild || pChild->isBad())
  2051. continue;
  2052. if(pChild->mnBAGlobalForKF!=nLoopKF)
  2053. {
  2054. //cout << "++++New child with flag " << pChild->mnBAGlobalForKF << "; LoopKF: " << nLoopKF << endl;
  2055. //cout << " child id: " << pChild->mnId << endl;
  2056. cv::Mat Tchildc = pChild->GetPose()*Twc;
  2057. //cout << "Child pose: " << Tchildc << endl;
  2058. //cout << "pKF->mTcwGBA: " << pKF->mTcwGBA << endl;
  2059. pChild->mTcwGBA = Tchildc*pKF->mTcwGBA;//*Tcorc*pKF->mTcwGBA;
  2060. cv::Mat Rcor = pChild->mTcwGBA.rowRange(0,3).colRange(0,3).t()*pChild->GetRotation();
  2061. if(!pChild->GetVelocity().empty()){
  2062. //cout << "Child velocity: " << pChild->GetVelocity() << endl;
  2063. pChild->mVwbGBA = Rcor*pChild->GetVelocity();
  2064. }
  2065. else
  2066. Verbose::PrintMess("Child velocity empty!! ", Verbose::VERBOSITY_NORMAL);
  2067. //cout << "Child bias: " << pChild->GetImuBias() << endl;
  2068. pChild->mBiasGBA = pChild->GetImuBias();
  2069. pChild->mnBAGlobalForKF=nLoopKF;
  2070. }
  2071. lpKFtoCheck.push_back(pChild);
  2072. }
  2073. //cout << "-------Update pose" << endl;
  2074. pKF->mTcwBefGBA = pKF->GetPose();
  2075. //cout << "pKF->mTcwBefGBA: " << pKF->mTcwBefGBA << endl;
  2076. pKF->SetPose(pKF->mTcwGBA);
  2077. /*cv::Mat Tco_cn = pKF->mTcwBefGBA * pKF->mTcwGBA.inv();
  2078. cv::Vec3d trasl = Tco_cn.rowRange(0,3).col(3);
  2079. double dist = cv::norm(trasl);
  2080. cout << "GBA: KF " << pKF->mnId << " had been moved " << dist << " meters" << endl;
  2081. double desvX = 0;
  2082. double desvY = 0;
  2083. double desvZ = 0;
  2084. if(pKF->mbHasHessian)
  2085. {
  2086. cv::Mat hessianInv = pKF->mHessianPose.inv();
  2087. double covX = hessianInv.at<double>(3,3);
  2088. desvX = std::sqrt(covX);
  2089. double covY = hessianInv.at<double>(4,4);
  2090. desvY = std::sqrt(covY);
  2091. double covZ = hessianInv.at<double>(5,5);
  2092. desvZ = std::sqrt(covZ);
  2093. pKF->mbHasHessian = false;
  2094. }
  2095. if(dist > 1)
  2096. {
  2097. cout << "--To much distance correction: It has " << pKF->GetConnectedKeyFrames().size() << " connected KFs" << endl;
  2098. cout << "--It has " << pKF->GetCovisiblesByWeight(80).size() << " connected KF with 80 common matches or more" << endl;
  2099. cout << "--It has " << pKF->GetCovisiblesByWeight(50).size() << " connected KF with 50 common matches or more" << endl;
  2100. cout << "--It has " << pKF->GetCovisiblesByWeight(20).size() << " connected KF with 20 common matches or more" << endl;
  2101. cout << "--STD in meters(x, y, z): " << desvX << ", " << desvY << ", " << desvZ << endl;
  2102. string strNameFile = pKF->mNameFile;
  2103. cv::Mat imLeft = cv::imread(strNameFile, CV_LOAD_IMAGE_UNCHANGED);
  2104. cv::cvtColor(imLeft, imLeft, CV_GRAY2BGR);
  2105. vector<MapPoint*> vpMapPointsKF = pKF->GetMapPointMatches();
  2106. int num_MPs = 0;
  2107. for(int i=0; i<vpMapPointsKF.size(); ++i)
  2108. {
  2109. if(!vpMapPointsKF[i] || vpMapPointsKF[i]->isBad())
  2110. {
  2111. continue;
  2112. }
  2113. num_MPs += 1;
  2114. string strNumOBs = to_string(vpMapPointsKF[i]->Observations());
  2115. cv::circle(imLeft, pKF->mvKeys[i].pt, 2, cv::Scalar(0, 255, 0));
  2116. cv::putText(imLeft, strNumOBs, pKF->mvKeys[i].pt, CV_FONT_HERSHEY_DUPLEX, 1, cv::Scalar(255, 0, 0));
  2117. }
  2118. cout << "--It has " << num_MPs << " MPs matched in the map" << endl;
  2119. string namefile = "./test_GBA/GBA_" + to_string(nLoopKF) + "_KF" + to_string(pKF->mnId) +"_D" + to_string(dist) +".png";
  2120. cv::imwrite(namefile, imLeft);
  2121. }*/
  2122. if(pKF->bImu)
  2123. {
  2124. //cout << "-------Update inertial values" << endl;
  2125. pKF->mVwbBefGBA = pKF->GetVelocity();
  2126. if (pKF->mVwbGBA.empty())
  2127. Verbose::PrintMess("pKF->mVwbGBA is empty", Verbose::VERBOSITY_NORMAL);
  2128. assert(!pKF->mVwbGBA.empty());
  2129. pKF->SetVelocity(pKF->mVwbGBA);
  2130. pKF->SetNewBias(pKF->mBiasGBA);
  2131. }
  2132. lpKFtoCheck.pop_front();
  2133. }
  2134. //cout << "GBA: Correct MapPoints" << endl;
  2135. // Correct MapPoints
  2136. const vector<MapPoint*> vpMPs = pActiveMap->GetAllMapPoints();
  2137. for(size_t i=0; i<vpMPs.size(); i++)
  2138. {
  2139. MapPoint* pMP = vpMPs[i];
  2140. if(pMP->isBad())
  2141. continue;
  2142. if(pMP->mnBAGlobalForKF==nLoopKF)
  2143. {
  2144. // If optimized by Global BA, just update
  2145. pMP->SetWorldPos(pMP->mPosGBA);
  2146. }
  2147. else
  2148. {
  2149. // Update according to the correction of its reference keyframe
  2150. KeyFrame* pRefKF = pMP->GetReferenceKeyFrame();
  2151. if(pRefKF->mnBAGlobalForKF!=nLoopKF)
  2152. continue;
  2153. if(pRefKF->mTcwBefGBA.empty())
  2154. continue;
  2155. // Map to non-corrected camera
  2156. cv::Mat Rcw = pRefKF->mTcwBefGBA.rowRange(0,3).colRange(0,3);
  2157. cv::Mat tcw = pRefKF->mTcwBefGBA.rowRange(0,3).col(3);
  2158. cv::Mat Xc = Rcw*pMP->GetWorldPos()+tcw;
  2159. // Backproject using corrected camera
  2160. cv::Mat Twc = pRefKF->GetPoseInverse();
  2161. cv::Mat Rwc = Twc.rowRange(0,3).colRange(0,3);
  2162. cv::Mat twc = Twc.rowRange(0,3).col(3);
  2163. pMP->SetWorldPos(Rwc*Xc+twc);
  2164. }
  2165. }
  2166. pActiveMap->InformNewBigChange();
  2167. pActiveMap->IncreaseChangeIndex();
  2168. // TODO Check this update
  2169. // mpTracker->UpdateFrameIMU(1.0f, mpTracker->GetLastKeyFrame()->GetImuBias(), mpTracker->GetLastKeyFrame());
  2170. mpLocalMapper->Release();
  2171. Verbose::PrintMess("Map updated!", Verbose::VERBOSITY_NORMAL);
  2172. }
  2173. mbFinishedGBA = true;
  2174. mbRunningGBA = false;
  2175. }
  2176. }
  2177. void LoopClosing::RequestFinish()
  2178. {
  2179. unique_lock<mutex> lock(mMutexFinish);
  2180. // cout << "LC: Finish requested" << endl;
  2181. mbFinishRequested = true;
  2182. }
  2183. bool LoopClosing::CheckFinish()
  2184. {
  2185. unique_lock<mutex> lock(mMutexFinish);
  2186. return mbFinishRequested;
  2187. }
  2188. void LoopClosing::SetFinish()
  2189. {
  2190. unique_lock<mutex> lock(mMutexFinish);
  2191. mbFinished = true;
  2192. }
  2193. bool LoopClosing::isFinished()
  2194. {
  2195. unique_lock<mutex> lock(mMutexFinish);
  2196. return mbFinished;
  2197. }
  2198. } //namespace ORB_SLAM