00001 
00002 #include "ptam/MapMaker.h"
00003 #include "ptam/MapPoint.h"
00004 #include "ptam/Bundle.h"
00005 #include "ptam/PatchFinder.h"
00006 #include "ptam/SmallMatrixOpts.h"
00007 #include "ptam/HomographyInit.h"
00008 
00009 #include <cvd/vector_image_ref.h>
00010 #include <cvd/vision.h>
00011 #include <cvd/image_interpolate.h>
00012 
00013 #include <TooN/SVD.h>
00014 #include <TooN/SymEigen.h>
00015 
00016 #include <gvars3/instances.h>
00017 #include <fstream>
00018 #include <algorithm>
00019 
00020 #include <ptam/Params.h>
00021 
00022 #ifdef WIN32
00023 #define WIN32_LEAN_AND_MEAN
00024 #include <windows.h>
00025 #endif
00026 
00027 using namespace CVD;
00028 using namespace std;
00029 using namespace GVars3;
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 MapMaker::MapMaker(Map& m, const ATANCamera &cam, ros::NodeHandle& nh)
00040 : mMap(m), mCamera(cam), octomap_interface(nh)
00041 {
00042   mbResetRequested = false;
00043   Reset();
00044   start(); 
00045   GUI.RegisterCommand("SaveMap", GUICommandCallBack, this);
00046   
00047 };
00048 
00049 
00050 void MapMaker::Reset()
00051 {
00052   
00053   mMap.Reset();
00054   mvFailureQueue.clear();
00055   while(!mqNewQueue.empty()) mqNewQueue.pop();
00056   mMap.vpKeyFrames.clear(); 
00057   mvpKeyFrameQueue.clear(); 
00058   mbBundleRunning = false;
00059   mbBundleConverged_Full = true;
00060   mbBundleConverged_Recent = true;
00061   mbResetDone = true;
00062   mbResetRequested = false;
00063   mbBundleAbortRequested = false;
00064 }
00065 
00066 
00067 
00068 #define CHECK_RESET if(mbResetRequested) {Reset(); continue;};
00069 
00070 void MapMaker::run()
00071 {
00072 
00073 #ifdef WIN32
00074   
00075   
00076   SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST);
00077 #endif
00078 
00079   
00080   const ptam::PtamParamsConfig& pPars = PtamParameters::varparams();
00081 
00082   while(!shouldStop())  
00083   {
00084     CHECK_RESET;
00085     sleep(1); 
00086     CHECK_RESET;
00087 
00088     
00089     while(!mvQueuedCommands.empty())
00090     {
00091       GUICommandHandler(mvQueuedCommands.begin()->sCommand, mvQueuedCommands.begin()->sParams);
00092       mvQueuedCommands.erase(mvQueuedCommands.begin());
00093     }
00094 
00095     if(!mMap.IsGood())  
00096       continue;
00097 
00098     
00099     
00100     
00101 
00102     CHECK_RESET;
00103     
00104     if(!mbBundleConverged_Recent && QueueSize() == 0)
00105       
00106       if (pPars.BundleMethod=="LOCAL" || pPars.BundleMethod=="LOCAL_GLOBAL")
00107         BundleAdjustRecent();
00108     
00109 
00110     CHECK_RESET;
00111     
00112     if(mbBundleConverged_Recent && QueueSize() == 0)
00113       ReFindNewlyMade();
00114 
00115     CHECK_RESET;
00116     
00117     if(mbBundleConverged_Recent && !mbBundleConverged_Full && QueueSize() == 0)
00118       
00119       if (pPars.BundleMethod=="GLOBAL" || pPars.BundleMethod=="LOCAL_GLOBAL")
00120         BundleAdjustAll();
00121 
00122     
00123 
00124     CHECK_RESET;
00125     
00126     if(mbBundleConverged_Recent && mbBundleConverged_Full && rand()%20 == 0 && QueueSize() == 0)
00127       ReFindFromFailureQueue();
00128 
00129     CHECK_RESET;
00130     HandleBadPoints();
00131 
00132     CHECK_RESET;
00133     
00134     if(QueueSize() > 0)
00135       AddKeyFrameFromTopOfQueue(); 
00136   }
00137 }
00138 
00139 
00140 
00141 void MapMaker::RequestReset()
00142 {
00143   mbResetDone = false;
00144   mbResetRequested = true;
00145 }
00146 
00147 bool MapMaker::ResetDone()
00148 {
00149   return mbResetDone;
00150 }
00151 
00152 
00153 
00154 void MapMaker::HandleBadPoints()
00155 {
00156   
00157   for(unsigned int i=0; i<mMap.vpPoints.size(); i++)
00158   {
00159     MapPoint &p = *mMap.vpPoints[i];
00160     if(p.nMEstimatorOutlierCount > 20 && p.nMEstimatorOutlierCount > p.nMEstimatorInlierCount)
00161       p.bBad = true;
00162   }
00163 
00164   
00165   
00166   for(unsigned int i=0; i<mMap.vpPoints.size(); i++)
00167     if(mMap.vpPoints[i]->bBad)
00168     {
00169       
00170       octomap_interface.deletePoint(mMap.vpPoints[i]);
00171       
00172       MapPoint::Ptr p = mMap.vpPoints[i];
00173       for(unsigned int j=0; j<mMap.vpKeyFrames.size(); j++)
00174       {
00175         KeyFrame &k = *mMap.vpKeyFrames[j];
00176         if(k.mMeasurements.count(p)){
00177           
00178 #ifdef KF_REPROJ
00179           
00180           for(unsigned int ibest=0;ibest<k.iBestPointsCount;ibest++){ 
00181             
00182             if(k.apCurrentBestPoints[ibest]==p) 
00183             {
00184               k.apCurrentBestPoints[ibest].reset();
00185               int mindist = 9999;
00186               int tempdist = 0;
00187               Vector<2> ptlev0 = LevelZeroPos(p->irCenter, p->nSourceLevel); 
00188               for(int iP = k.vpPoints.size()-1; iP>=0; iP--){ 
00189                 Vector<2> pt2lev0 = LevelZeroPos(k.vpPoints[iP]->irCenter, k.vpPoints[iP]->nSourceLevel);
00190                 tempdist = abs(ptlev0[0] - pt2lev0[0]) + abs(ptlev0[1] - pt2lev0[1]);   
00191                 if(tempdist < mindist && ! k.vpPoints[iP]->bBad){                                       
00192                   mindist = tempdist;
00193                   k.apCurrentBestPoints[ibest] = k.vpPoints[iP]; 
00194                 }
00195               }
00196             }
00197           }
00198 #endif
00199           
00200           k.mMeasurements.erase(p);
00201         }
00202       }
00203     }
00204   
00205   mMap.MoveBadPointsToTrash();
00206 }
00207 
00208 MapMaker::~MapMaker()
00209 {
00210   mbBundleAbortRequested = true;
00211   stop(); 
00212   cout << "Waiting for mapmaker to die.." << endl;
00213   join();
00214   cout << " .. mapmaker has died." << endl;
00215 }
00216 
00217 
00218 
00219 Vector<3> MapMaker::ReprojectPoint(SE3<> se3AfromB, const Vector<2> &v2A, const Vector<2> &v2B)
00220 {
00221   Matrix<3,4> PDash;
00222   PDash.slice<0,0,3,3>() = se3AfromB.get_rotation().get_matrix();
00223   PDash.slice<0,3,3,1>() = se3AfromB.get_translation().as_col();
00224 
00225   Matrix<4> A;
00226   A[0][0] = -1.0; A[0][1] =  0.0; A[0][2] = v2B[0]; A[0][3] = 0.0;
00227   A[1][0] =  0.0; A[1][1] = -1.0; A[1][2] = v2B[1]; A[1][3] = 0.0;
00228   A[2] = v2A[0] * PDash[2] - PDash[0];
00229   A[3] = v2A[1] * PDash[2] - PDash[1];
00230 
00231   SVD<4,4> svd(A);
00232   Vector<4> v4Smallest = svd.get_VT()[3];
00233   if(v4Smallest[3] == 0.0)
00234     v4Smallest[3] = 0.00001;
00235   return project(v4Smallest);
00236 }
00237 
00238 
00239 
00240 
00241 
00242 bool MapMaker::InitFromStereo(KeyFrame::Ptr kF,
00243                               KeyFrame::Ptr kS,
00244                               vector<pair<ImageRef, ImageRef> > &vTrailMatches,
00245                               SE3<> &se3TrackerPose)
00246 {
00247   
00248   
00249   const FixParams& pPars = PtamParameters::fixparams();
00250   mdWiggleScale=pPars.WiggleScale;
00251   
00252   
00253 
00254   mCamera.SetImageSize(kF->aLevels[0].im.size());
00255 
00256 
00257         if(vTrailMatches.size()<4)
00258         {
00259                 ROS_WARN_STREAM("Too few matches to init.");
00260                 return false;
00261         }
00262 
00265 
00266   
00267   
00268   
00269   
00270   
00271   
00272   
00273   
00274   
00275   
00276   
00277   
00278   
00279   
00280   
00281   
00282   
00283   
00284   
00285   
00286   
00287   
00288   
00289   
00290   
00291 
00293 
00294 
00295 
00296   vector<HomographyMatch> vMatches;
00297   for(unsigned int i=0; i<vTrailMatches.size(); i++)
00298   {
00299     HomographyMatch m;
00300     m.v2CamPlaneFirst = mCamera.UnProject(vTrailMatches[i].first);
00301     m.v2CamPlaneSecond = mCamera.UnProject(vTrailMatches[i].second);
00302     m.m2PixelProjectionJac = mCamera.GetProjectionDerivs();
00303     vMatches.push_back(m);
00304   }
00305 
00306 
00307   
00308   if(vMatches.size()<4)
00309     return false;
00310   
00311 
00312   SE3<> se3;
00313   bool bGood;
00314   HomographyInit HomographyInit;
00315 
00316   bGood = HomographyInit.Compute(vMatches, 5.0, se3);
00317 
00318   if(!bGood)
00319   {
00320     mMessageForUser << "  Could not init from stereo pair, try again." << endl;
00321     return false;
00322   }
00323 
00324   
00325   double dTransMagn = sqrt(se3.get_translation() * se3.get_translation());
00326   if(dTransMagn == 0)
00327   {
00328     mMessageForUser << "  Estimated zero baseline from stereo pair, try again." << endl;
00329     return false;
00330   }
00331   
00332   se3.get_translation() *= mdWiggleScale/dTransMagn;
00333 
00334 
00335   KeyFrame::Ptr pkFirst = kF;
00336   KeyFrame::Ptr pkSecond = kS;
00337 
00338   pkFirst->bFixed = true;
00339   pkFirst->se3CfromW = SE3<>();
00340 
00341   pkSecond->bFixed = false;
00342   pkSecond->se3CfromW = se3;
00343 
00344   
00345   PatchFinder finder;
00346 
00347   for(unsigned int i=0; i<vMatches.size(); i++)
00348   {
00349     MapPoint::Ptr p(new MapPoint());
00350 
00351     
00352     p->pPatchSourceKF = pkFirst;
00353     p->nSourceLevel = 0;
00354     p->v3Normal_NC = makeVector( 0,0,-1);
00355     p->irCenter = vTrailMatches[i].first;
00356     p->v3Center_NC = unproject(mCamera.UnProject(p->irCenter));
00357     p->v3OneDownFromCenter_NC = unproject(mCamera.UnProject(p->irCenter + ImageRef(0,1)));
00358     p->v3OneRightFromCenter_NC = unproject(mCamera.UnProject(p->irCenter + ImageRef(1,0)));
00359     normalize(p->v3Center_NC);
00360     normalize(p->v3OneDownFromCenter_NC);
00361     normalize(p->v3OneRightFromCenter_NC);
00362     p->RefreshPixelVectors();
00363 
00364     
00365     finder.MakeTemplateCoarseNoWarp(p);
00366     finder.MakeSubPixTemplate();
00367     finder.SetSubPixPos(vec(vTrailMatches[i].second));
00368     bool bGood = finder.IterateSubPixToConvergence(*pkSecond,10);
00369     if(!bGood)
00370     {
00371       continue;
00372     }
00373 
00374     
00375     Vector<2> v2SecondPos = finder.GetSubPixPos();
00376     p->v3WorldPos = ReprojectPoint(se3, mCamera.UnProject(v2SecondPos), vMatches[i].v2CamPlaneFirst);
00377     if(p->v3WorldPos[2] < 0.0)
00378     {
00379       continue;
00380     }
00381 
00382     
00383     p->pMMData = new MapMakerData();
00384     mMap.vpPoints.push_back(p);
00385 
00386     
00387     Measurement mFirst;
00388     mFirst.nLevel = 0;
00389     mFirst.Source = Measurement::SRC_ROOT;
00390     mFirst.v2RootPos = vec(vTrailMatches[i].first);
00391     mFirst.bSubPix = true;
00392     pkFirst->mMeasurements[p] = mFirst;
00393     p->pMMData->sMeasurementKFs.insert(pkFirst);
00394 
00395     Measurement mSecond;
00396     mSecond.nLevel = 0;
00397     mSecond.Source = Measurement::SRC_TRAIL;
00398     mSecond.v2RootPos = finder.GetSubPixPos();
00399     mSecond.bSubPix = true;
00400     pkSecond->mMeasurements[p] = mSecond;
00401     p->pMMData->sMeasurementKFs.insert(pkSecond);
00402     
00403 #ifdef KF_REPROJ
00404     pkFirst->AddKeyMapPoint(p);
00405     pkSecond->AddKeyMapPoint(p);
00406 #endif
00407     
00408   }
00409 
00410 
00411         if(mMap.vpPoints.size()<4)
00412         {
00413                 ROS_WARN_STREAM("Too few map points to init.");
00414                 return false;
00415         }
00416 
00417 
00418   mMap.vpKeyFrames.push_back(pkFirst);
00419   mMap.vpKeyFrames.push_back(pkSecond);
00420   pkFirst->MakeKeyFrame_Rest();
00421   pkSecond->MakeKeyFrame_Rest();
00422   
00423   
00424    BundleAdjustAll();
00425 
00426   
00427   
00428 
00429 
00430         if(!RefreshSceneDepth(pkFirst))
00431         {
00432                 ROS_WARN_STREAM("Something is seriously wrong with the first KF.");
00433                 return false;
00434         }
00435         if(!RefreshSceneDepth(pkSecond))
00436         {
00437                 ROS_WARN_STREAM("Something is seriously wrong with the second KF.");
00438                 return false;
00439         }
00440         mdWiggleScaleDepthNormalized = mdWiggleScale / pkFirst->dSceneDepthMean;
00441 
00442 
00443   
00444   const VarParams& pParams = PtamParameters::varparams();
00445   bool addedsome=false;
00446   addedsome |= AddSomeMapPoints(3);
00447   if(!pParams.NoLevelZeroMapPoints)
00448     addedsome |= AddSomeMapPoints(0);
00449   addedsome |= AddSomeMapPoints(1);
00450   addedsome |= AddSomeMapPoints(2);
00451   if(!addedsome)
00452         {
00453                 ROS_WARN_STREAM("Could not add any map points on any level - abort init.");
00454                 return false;
00455         }
00456   
00457 
00458   mbBundleConverged_Full = false;
00459   mbBundleConverged_Recent = false;
00460   
00461   double nloops=0;
00462   while(!mbBundleConverged_Full & (nloops<pParams.MaxStereoInitLoops))
00463   {
00464     BundleAdjustAll();
00465     if(mbResetRequested | (nloops>=pParams.MaxStereoInitLoops))
00466       return false;
00467     nloops++;
00468   }
00469 
00470   
00471   if(((pkFirst->dSceneDepthSigma+pkSecond->dSceneDepthSigma)/2.0>0.5) && pParams.CheckInitMapVar)
00472   {
00473     ROS_WARN_STREAM("Initial map rejected because of too large point variance. Point sigma: " << ((pkFirst->dSceneDepthSigma+pkSecond->dSceneDepthSigma)/2.0));
00474     return false;
00475   }
00476 
00477   
00478 
00479   
00480   ApplyGlobalTransformationToMap(CalcPlaneAligner());
00481   mMap.bGood = true;
00482   se3TrackerPose = pkSecond->se3CfromW;
00483 
00484   mMessageForUser << "  MapMaker: made initial map with " << mMap.vpPoints.size() << " points." << endl;
00485 
00486   
00487     octomap_interface.addKeyFrame(pkFirst);
00488     octomap_interface.addKeyFrame(pkSecond);
00489   
00490 
00491   return true;
00492 }
00493 
00494 
00495 
00496 
00497 
00498 
00499 void MapMaker::ThinCandidates(KeyFrame::Ptr k, int nLevel)
00500 {
00501   vector<Candidate> &vCSrc = k->aLevels[nLevel].vCandidates;
00502   vector<Candidate> vCGood;
00503   vector<ImageRef> irBusyLevelPos;
00504   
00505   
00506   for(meas_it it = k->mMeasurements.begin(); it!=k->mMeasurements.end(); it++)
00507   {
00508     if(!(it->second.nLevel == nLevel || it->second.nLevel == nLevel + 1))
00509       continue;
00510     irBusyLevelPos.push_back(ir_rounded(it->second.v2RootPos / LevelScale(nLevel)));
00511   }
00512 
00513   
00514   unsigned int nMinMagSquared = 10*10;
00515   for(unsigned int i=0; i<vCSrc.size(); i++)
00516   {
00517     ImageRef irC = vCSrc[i].irLevelPos;
00518     bool bGood = true;
00519     for(unsigned int j=0; j<irBusyLevelPos.size(); j++)
00520     {
00521       ImageRef irB = irBusyLevelPos[j];
00522       if((irB - irC).mag_squared() < nMinMagSquared)
00523       {
00524         bGood = false;
00525         break;
00526       }
00527     }
00528     if(bGood)
00529       vCGood.push_back(vCSrc[i]);
00530   }
00531   vCSrc = vCGood;
00532 }
00533 
00534 
00535 
00536 
00537 bool MapMaker::AddSomeMapPoints(int nLevel)
00538 {
00539   
00540   bool addedsome=false;
00541   
00542   KeyFrame::Ptr kSrc = (mMap.vpKeyFrames[mMap.vpKeyFrames.size() - 1]); 
00543   KeyFrame::Ptr kTarget = ClosestKeyFrame(kSrc);
00544   Level &l = kSrc->aLevels[nLevel];
00545 
00546   ThinCandidates(kSrc, nLevel);
00547   for(unsigned int i = 0; i<l.vCandidates.size(); i++)
00548     addedsome|=AddPointEpipolar(kSrc, kTarget, nLevel, i);
00549   return addedsome;
00550 };
00551 
00552 
00553 void MapMaker::ApplyGlobalTransformationToMap(SE3<> se3NewFromOld)
00554 {
00555   for(unsigned int i=0; i<mMap.vpKeyFrames.size(); i++)
00556     mMap.vpKeyFrames[i]->se3CfromW = mMap.vpKeyFrames[i]->se3CfromW * se3NewFromOld.inverse();
00557 
00558 
00559   for(unsigned int i=0; i<mMap.vpPoints.size(); i++)
00560   {
00561     mMap.vpPoints[i]->v3WorldPos =
00562         se3NewFromOld * mMap.vpPoints[i]->v3WorldPos;
00563     mMap.vpPoints[i]->RefreshPixelVectors();
00564   }
00565 }
00566 
00567 
00568 void MapMaker::ApplyGlobalScaleToMap(double dScale)
00569 {
00570   for(unsigned int i=0; i<mMap.vpKeyFrames.size(); i++)
00571     mMap.vpKeyFrames[i]->se3CfromW.get_translation() *= dScale;
00572 
00573   for(unsigned int i=0; i<mMap.vpPoints.size(); i++)
00574   {
00575     (*mMap.vpPoints[i]).v3WorldPos *= dScale;
00576     (*mMap.vpPoints[i]).v3PixelRight_W *= dScale;
00577     (*mMap.vpPoints[i]).v3PixelDown_W *= dScale;
00578     (*mMap.vpPoints[i]).RefreshPixelVectors();
00579   }
00580 }
00581 
00582 
00583 
00584 
00585 
00586 void MapMaker::AddKeyFrame(KeyFrame::Ptr k)
00587 {
00588   k->pSBI = NULL; 
00589   mvpKeyFrameQueue.push_back(k);
00590   if(mbBundleRunning)   
00591     mbBundleAbortRequested = true;
00592 }
00593 
00594 
00595 void MapMaker::AddKeyFrameFromTopOfQueue()
00596 {
00597   if(mvpKeyFrameQueue.size() == 0)
00598     return;
00599 
00600   KeyFrame::Ptr pK = mvpKeyFrameQueue[0];
00601   mvpKeyFrameQueue.erase(mvpKeyFrameQueue.begin());
00602 
00603   
00604 
00605   
00606   const ptam::PtamParamsConfig& pPars = PtamParameters::varparams();
00607   if (pPars.MaxKF>1)    
00608   {
00609     while (mMap.vpKeyFrames.size()>(unsigned int)pPars.MaxKF)
00610     {
00611       
00612       double dFarthestDist = 0;
00613       vector<KeyFrame::Ptr>::iterator itFarthest = mMap.vpKeyFrames.begin();
00614 
00615       for(vector<KeyFrame::Ptr>::iterator it = mMap.vpKeyFrames.begin();it!=mMap.vpKeyFrames.end();++it)
00616       {
00617         double dDist = KeyFrameLinearDist(pK, *it);
00618         if(dDist > dFarthestDist)
00619         {
00620           dFarthestDist = dDist;
00621           itFarthest = it;
00622         }
00623       }
00624 
00625       for (unsigned int i=0;i<mMap.vpPoints.size();i++)
00626         if (mMap.vpPoints[i]->pPatchSourceKF==*itFarthest)
00627           mMap.vpPoints[i]->bBad=true;
00628 
00629       if ((*itFarthest)->bFixed)        
00630       {
00631         mMap.vpKeyFrames.erase(itFarthest);
00632         mMap.vpKeyFrames[0]->bFixed=true;
00633       }
00634       else
00635         mMap.vpKeyFrames.erase(itFarthest);
00636     }
00637   }
00638   
00639 
00640   pK->MakeKeyFrame_Rest();
00641   
00642   
00643   
00644   mMap.vpKeyFrames.push_back(pK);
00645   
00646   for(meas_it it = pK->mMeasurements.begin();
00647       it!=pK->mMeasurements.end();
00648       it++)
00649   {
00650     it->first->pMMData->sMeasurementKFs.insert(pK);
00651     it->second.Source = Measurement::SRC_TRACKER;
00652   }
00653   
00654   ReFindInSingleKeyFrame(pK);
00655 
00656   bool addedsome=false;
00657   addedsome |= AddSomeMapPoints(3);       
00658   if(!pPars.NoLevelZeroMapPoints)
00659     addedsome |= AddSomeMapPoints(0);
00660   addedsome |= AddSomeMapPoints(1);
00661   addedsome |= AddSomeMapPoints(2);
00662 
00663   
00664   
00665   
00666   
00667 
00668   mbBundleConverged_Full = false;
00669   mbBundleConverged_Recent = false;
00670 
00671   
00672   octomap_interface.addKeyFrame(pK);
00673   
00674 }
00675 
00676 
00677 
00678 
00679 bool MapMaker::AddPointEpipolar(KeyFrame::Ptr kSrc,
00680                                 KeyFrame::Ptr kTarget,
00681                                 int nLevel,
00682                                 int nCandidate)
00683 {
00684   static Image<Vector<2> > imUnProj;
00685   static bool bMadeCache = false;
00686   if(!bMadeCache)
00687   {
00688     imUnProj.resize(kSrc->aLevels[0].im.size());
00689     ImageRef ir;
00690     do imUnProj[ir] = mCamera.UnProject(ir);
00691     while(ir.next(imUnProj.size()));
00692     bMadeCache = true;
00693   }
00694 
00695   int nLevelScale = LevelScale(nLevel);
00696   Candidate &candidate = kSrc->aLevels[nLevel].vCandidates[nCandidate];
00697   ImageRef irLevelPos = candidate.irLevelPos;
00698   Vector<2> v2RootPos = LevelZeroPos(irLevelPos, nLevel);
00699 
00700   Vector<3> v3Ray_SC = unproject(mCamera.UnProject(v2RootPos)); 
00701   normalize(v3Ray_SC);
00702   Vector<3> v3LineDirn_TC = kTarget->se3CfromW.get_rotation() * (kSrc->se3CfromW.get_rotation().inverse() * v3Ray_SC); 
00703 
00704   
00705   
00706   double dMean = kSrc->dSceneDepthMean;
00707   double dSigma = kSrc->dSceneDepthSigma;
00708   
00709   
00710   
00711   
00712   double dStartDepth = max(0.0, dMean - dSigma); 
00713   double dEndDepth = dMean + dSigma; 
00714   
00715   Vector<3> v3CamCenter_TC = kTarget->se3CfromW * kSrc->se3CfromW.inverse().get_translation(); 
00716   Vector<3> v3RayStart_TC = v3CamCenter_TC + dStartDepth * v3LineDirn_TC;                           
00717   Vector<3> v3RayEnd_TC = v3CamCenter_TC + dEndDepth * v3LineDirn_TC;                               
00718 
00719   
00721   
00722   
00723   
00724   
00725   
00726   
00728   
00729   if(v3RayEnd_TC[2] <= 0.0 )  return false;
00730   if(v3RayStart_TC[2] <= 0.0)
00731     v3RayStart_TC += v3LineDirn_TC * (0.001 - v3RayStart_TC[2] / v3LineDirn_TC[2]);
00732 
00733   Vector<2> v2A = project(v3RayStart_TC);
00734   Vector<2> v2B = project(v3RayEnd_TC);
00735   Vector<2> v2AlongProjectedLine = v2A-v2B;
00736 
00737   if(v2AlongProjectedLine * v2AlongProjectedLine < 0.00000001)
00738   {
00739     mMessageForUser << "v2AlongProjectedLine too small." << endl;
00740     return false;
00741   }
00742   normalize(v2AlongProjectedLine);
00743   Vector<2> v2Normal;
00744   v2Normal[0] = v2AlongProjectedLine[1];
00745   v2Normal[1] = -v2AlongProjectedLine[0];
00746 
00747   double dNormDist = v2A * v2Normal;
00748   if(fabs(dNormDist) > mCamera.LargestRadiusInImage() )
00749     return false;
00750 
00751   double dMinLen = min(v2AlongProjectedLine * v2A, v2AlongProjectedLine * v2B) - 0.05;
00752   double dMaxLen = max(v2AlongProjectedLine * v2A, v2AlongProjectedLine * v2B) + 0.05;
00753   if(dMinLen < -2.0)  dMinLen = -2.0;
00754   if(dMaxLen < -2.0)  dMaxLen = -2.0;
00755   if(dMinLen > 2.0)   dMinLen = 2.0;
00756   if(dMaxLen > 2.0)   dMaxLen = 2.0;
00757 
00758   
00759   PatchFinder Finder;
00760   Finder.MakeTemplateCoarseNoWarp(kSrc, nLevel, irLevelPos);
00761   if(Finder.TemplateBad())  return false;
00762 
00763   vector<Vector<2> > &vv2Corners = kTarget->aLevels[nLevel].vImplaneCorners;
00764   vector<ImageRef> &vIR = kTarget->aLevels[nLevel].vCorners;
00765   if(!kTarget->aLevels[nLevel].bImplaneCornersCached)
00766   {
00767     for(unsigned int i=0; i<vIR.size(); i++)   
00768       vv2Corners.push_back(imUnProj[ir(LevelZeroPos(vIR[i], nLevel))]);
00769     kTarget->aLevels[nLevel].bImplaneCornersCached = true;
00770   }
00771 
00772   int nBest = -1;
00773   int nBestZMSSD = Finder.mnMaxSSD + 1;
00774   double dMaxDistDiff = mCamera.OnePixelDist() * (4.0 + 1.0 * nLevelScale);
00775   double dMaxDistSq = dMaxDistDiff * dMaxDistDiff;
00776 
00777   for(unsigned int i=0; i<vv2Corners.size(); i++)   
00778   {
00779     Vector<2> v2Im = vv2Corners[i];
00780     double dDistDiff = dNormDist - v2Im * v2Normal;
00781     if(dDistDiff * dDistDiff > dMaxDistSq)      continue; 
00782     if(v2Im * v2AlongProjectedLine < dMinLen)   continue; 
00783     if(v2Im * v2AlongProjectedLine > dMaxLen)   continue; 
00784     int nZMSSD = Finder.ZMSSDAtPoint(kTarget->aLevels[nLevel].im, vIR[i]);
00785     if(nZMSSD < nBestZMSSD)
00786     {
00787       nBest = i;
00788       nBestZMSSD = nZMSSD;
00789     }
00790   }
00791 
00792   if(nBest == -1)   return false;   
00793 
00794   
00795   Finder.MakeSubPixTemplate();
00796   Finder.SetSubPixPos(LevelZeroPos(vIR[nBest], nLevel));
00797   bool bSubPixConverges = Finder.IterateSubPixToConvergence(*kTarget,10);
00798   if(!bSubPixConverges)
00799     return false;
00800 
00801   
00802   Vector<3> v3New;
00803   v3New = kTarget->se3CfromW.inverse() *
00804       ReprojectPoint(kSrc->se3CfromW * kTarget->se3CfromW.inverse(),
00805                      mCamera.UnProject(v2RootPos),
00806                      mCamera.UnProject(Finder.GetSubPixPos()));
00807 
00808   MapPoint::Ptr pNew(new MapPoint());
00809   pNew->v3WorldPos = v3New;
00810   pNew->pMMData = new MapMakerData();
00811 
00812   
00813   pNew->pPatchSourceKF = kSrc;
00814   pNew->nSourceLevel = nLevel;
00815   pNew->v3Normal_NC = makeVector( 0,0,-1);
00816   pNew->irCenter = irLevelPos;
00817   pNew->v3Center_NC = unproject(mCamera.UnProject(v2RootPos));
00818   pNew->v3OneRightFromCenter_NC = unproject(mCamera.UnProject(v2RootPos + vec(ImageRef(nLevelScale,0))));
00819   pNew->v3OneDownFromCenter_NC  = unproject(mCamera.UnProject(v2RootPos + vec(ImageRef(0,nLevelScale))));
00820 
00821   normalize(pNew->v3Center_NC);
00822   normalize(pNew->v3OneDownFromCenter_NC);
00823   normalize(pNew->v3OneRightFromCenter_NC);
00824 
00825   pNew->RefreshPixelVectors();
00826 
00827   mMap.vpPoints.push_back(pNew);
00828   mqNewQueue.push(pNew);
00829   Measurement m;
00830   m.Source = Measurement::SRC_ROOT;
00831   m.v2RootPos = v2RootPos;
00832   m.nLevel = nLevel;
00833   m.bSubPix = true;
00834   kSrc->mMeasurements[pNew] = m;
00835 
00836   m.Source = Measurement::SRC_EPIPOLAR;
00837   m.v2RootPos = Finder.GetSubPixPos();
00838   kTarget->mMeasurements[pNew] = m;
00839   pNew->pMMData->sMeasurementKFs.insert(kSrc);
00840   pNew->pMMData->sMeasurementKFs.insert(kTarget);
00841   
00842 #ifdef KF_REPROJ
00843   kSrc->AddKeyMapPoint(pNew);
00844   kTarget->AddKeyMapPoint(pNew);
00845 #endif
00846   
00847 
00848   return true;
00849 }
00850 
00851 double MapMaker::KeyFrameLinearDist(KeyFrame::Ptr k1, KeyFrame::Ptr k2)
00852 {
00853   Vector<3> v3KF1_CamPos = k1->se3CfromW.inverse().get_translation();
00854   Vector<3> v3KF2_CamPos = k2->se3CfromW.inverse().get_translation();
00855   Vector<3> v3Diff = v3KF2_CamPos - v3KF1_CamPos;
00856   double dDist = sqrt(v3Diff * v3Diff);
00857   return dDist;
00858 }
00859 
00860 vector<KeyFrame::Ptr> MapMaker::NClosestKeyFrames(KeyFrame::Ptr k, unsigned int N)
00861 {
00862   vector<pair<double, KeyFrame::Ptr > > vKFandScores;
00863   for(unsigned int i=0; i<mMap.vpKeyFrames.size(); i++)
00864   {
00865     if(mMap.vpKeyFrames[i] == k)
00866       continue;
00867     double dDist = KeyFrameLinearDist(k, mMap.vpKeyFrames[i]);
00868     vKFandScores.push_back(make_pair(dDist, mMap.vpKeyFrames[i]));
00869   }
00870   if(N > vKFandScores.size())
00871     N = vKFandScores.size();
00872   partial_sort(vKFandScores.begin(), vKFandScores.begin() + N, vKFandScores.end());
00873 
00874   vector<KeyFrame::Ptr> vResult;
00875   for(unsigned int i=0; i<N; i++)
00876     vResult.push_back(vKFandScores[i].second);
00877   return vResult;
00878 }
00879 
00880 KeyFrame::Ptr MapMaker::ClosestKeyFrame(KeyFrame::Ptr k)
00881 {
00882   double dClosestDist = 9999999999.9;
00883   int nClosest = -1;
00884   for(unsigned int i=0; i<mMap.vpKeyFrames.size(); i++)
00885   {
00886     if(mMap.vpKeyFrames[i] == k)
00887       continue;
00888     double dDist = KeyFrameLinearDist(k, mMap.vpKeyFrames[i]);
00889     if(dDist < dClosestDist)
00890     {
00891       dClosestDist = dDist;
00892       nClosest = i;
00893     }
00894   }
00895   assert(nClosest != -1);
00896   return mMap.vpKeyFrames[nClosest];
00897 }
00898 
00899 double MapMaker::DistToNearestKeyFrame(KeyFrame::Ptr kCurrent)
00900 {
00901   KeyFrame::Ptr pClosest = ClosestKeyFrame(kCurrent);
00902   double dDist = KeyFrameLinearDist(kCurrent, pClosest);
00903   return dDist;
00904 }
00905 
00906 bool MapMaker::NeedNewKeyFrame(KeyFrame::Ptr kCurrent)
00907 {
00908   KeyFrame::Ptr pClosest = ClosestKeyFrame(kCurrent);
00909   double dDist = KeyFrameLinearDist(kCurrent, pClosest);
00910 
00911   
00912   
00913   const ptam::PtamParamsConfig& pPars = PtamParameters::varparams();
00914 
00915   std::vector<double> medianpixdist;
00916   Vector<3> veccam2;
00917   Vector<2> cam2,cam1;
00918   for(std::map<MapPoint::Ptr, Measurement>::iterator it = kCurrent->mMeasurements.begin();it != kCurrent->mMeasurements.end(); it++)
00919   {
00920     veccam2 = pClosest->se3CfromW*it->first->v3WorldPos;        
00921     veccam2 = (kCurrent->se3CfromW*pClosest->se3CfromW.inverse()).get_rotation()*veccam2;       
00922     cam2 = mCamera.Project(makeVector(veccam2[0]/veccam2[2],veccam2[1]/veccam2[2]));
00923     cam1 = it->second.v2RootPos;
00924     medianpixdist.push_back(sqrt((cam2[0]-cam1[0])*(cam2[0]-cam1[0]) + (cam2[1]-cam1[1])*(cam2[1]-cam1[1])));
00925   }
00926   std::vector<double>::iterator first = medianpixdist.begin();
00927   std::vector<double>::iterator last = medianpixdist.end();
00928   std::vector<double>::iterator middle = first + std::floor((last - first) / 2);
00929   std::nth_element(first, middle, last); 
00930   double mediandist = *middle;
00931 
00932   dDist *= (1.0 / kCurrent->dSceneDepthMean);
00933 
00934   
00935   
00936   
00937   if(pPars.UseKFPixelDist & (mediandist>pPars.AutoInitPixel))
00938     return true;
00939 
00940   if(dDist > pPars.MaxKFDistWiggleMult * mdWiggleScaleDepthNormalized)
00941   {
00942     return true;
00943   }
00944   return false;
00945   
00946 }
00947 
00948 
00949 void MapMaker::BundleAdjustAll()
00950 {
00951   
00952   
00953   set<KeyFrame::Ptr> sAdj;
00954   set<KeyFrame::Ptr> sFixed;
00955   for(unsigned int i=0; i<mMap.vpKeyFrames.size(); i++)
00956     if(mMap.vpKeyFrames[i]->bFixed)
00957       sFixed.insert(mMap.vpKeyFrames[i]);
00958     else
00959       sAdj.insert(mMap.vpKeyFrames[i]);
00960 
00961   set<MapPoint::Ptr> sMapPoints;
00962   for(unsigned int i=0; i<mMap.vpPoints.size();i++)
00963     sMapPoints.insert(mMap.vpPoints[i]);
00964 
00965   BundleAdjust(sAdj, sFixed, sMapPoints, false);
00966 }
00967 
00968 
00969 
00970 void MapMaker::BundleAdjustRecent()
00971 {
00972   if(mMap.vpKeyFrames.size() < 8)
00973   { 
00974     mbBundleConverged_Recent = true;
00975     return;
00976   }
00977 
00978 
00979   
00980   
00981   set<KeyFrame::Ptr> sAdjustSet;
00982 
00983   
00984   unsigned char nloose = 4;
00985   
00986   const ptam::PtamParamsConfig& pPars = PtamParameters::varparams();
00987   if (pPars.MaxKF>1)    
00988     nloose=0;
00989 
00990   KeyFrame::Ptr pkfNewest = mMap.vpKeyFrames.back();
00991   sAdjustSet.insert(pkfNewest);
00992   vector<KeyFrame::Ptr> vClosest = NClosestKeyFrames(pkfNewest, 4);
00993   for(int i=0; i<nloose; i++)
00994     if(vClosest[i]->bFixed == false)
00995       sAdjustSet.insert(vClosest[i]);
00996   
00997 
00998   
00999   set<MapPoint::Ptr> sMapPoints;
01000   for(set<KeyFrame::Ptr>::iterator iter = sAdjustSet.begin();
01001       iter!=sAdjustSet.end();
01002       iter++)
01003   {
01004     map<MapPoint::Ptr,Measurement> &mKFMeas = (*iter)->mMeasurements;
01005     for(meas_it jiter = mKFMeas.begin(); jiter!= mKFMeas.end(); jiter++)
01006       sMapPoints.insert(jiter->first);
01007   };
01008 
01009   
01010   set<KeyFrame::Ptr> sFixedSet;
01011   for(vector<KeyFrame::Ptr>::iterator it = mMap.vpKeyFrames.begin(); it!=mMap.vpKeyFrames.end(); it++)
01012   {
01013     if(sAdjustSet.count(*it))
01014       continue;
01015     bool bInclude = false;
01016     for(meas_it jiter = (*it)->mMeasurements.begin(); jiter!= (*it)->mMeasurements.end(); jiter++)
01017       if(sMapPoints.count(jiter->first))
01018       {
01019         bInclude = true;
01020         break;
01021       }
01022     if(bInclude)
01023       sFixedSet.insert(*it);
01024   }
01025 
01026   BundleAdjust(sAdjustSet, sFixedSet, sMapPoints, true);
01027 }
01028 
01029 
01030 void MapMaker::BundleAdjust(set<KeyFrame::Ptr> sAdjustSet, set<KeyFrame::Ptr> sFixedSet, set<MapPoint::Ptr> sMapPoints, bool bRecent)
01031 {
01032   Bundle b(mCamera);   
01033   mbBundleRunning = true;
01034   mbBundleRunningIsRecent = bRecent;
01035 
01036   
01037   
01038   map<MapPoint::Ptr, int> mPoint_BundleID;
01039   map<int, MapPoint::Ptr> mBundleID_Point;
01040   map<KeyFrame::Ptr, int> mView_BundleID;
01041   map<int, KeyFrame::Ptr> mBundleID_View;
01042 
01043   
01044   for(set<KeyFrame::Ptr>::iterator it = sAdjustSet.begin(); it!= sAdjustSet.end(); it++)
01045   {
01046     int nBundleID = b.AddCamera((*it)->se3CfromW, (*it)->bFixed);
01047     mView_BundleID[*it] = nBundleID;
01048     mBundleID_View[nBundleID] = *it;
01049   }
01050   for(set<KeyFrame::Ptr>::iterator it = sFixedSet.begin(); it!= sFixedSet.end(); it++)
01051   {
01052     int nBundleID = b.AddCamera((*it)->se3CfromW, true);
01053     mView_BundleID[*it] = nBundleID;
01054     mBundleID_View[nBundleID] = *it;
01055   }
01056 
01057   
01058   for(set<MapPoint::Ptr>::iterator it = sMapPoints.begin(); it!=sMapPoints.end(); it++)
01059   {
01060     int nBundleID = b.AddPoint((*it)->v3WorldPos);
01061     mPoint_BundleID[*it] = nBundleID;
01062     mBundleID_Point[nBundleID] = *it;
01063 
01064     
01065     
01066     
01067     
01068     
01069     
01070     
01071   }
01072 
01073   
01074   for(unsigned int i=0; i<mMap.vpKeyFrames.size(); i++)
01075   {
01076     if(mView_BundleID.count(mMap.vpKeyFrames[i]) == 0)
01077       continue;
01078 
01079     int nKF_BundleID = mView_BundleID[mMap.vpKeyFrames[i]];
01080     for(meas_it it= mMap.vpKeyFrames[i]->mMeasurements.begin();
01081         it!= mMap.vpKeyFrames[i]->mMeasurements.end();
01082         it++)
01083     {
01084 
01085       if(mPoint_BundleID.count(it->first) == 0)
01086         continue;
01087       int nPoint_BundleID = mPoint_BundleID[it->first];
01088       b.AddMeas(nKF_BundleID, nPoint_BundleID, it->second.v2RootPos, LevelScale(it->second.nLevel) * LevelScale(it->second.nLevel));
01089     }
01090   }
01091 
01092   
01093   int nAccepted = b.Compute(&mbBundleAbortRequested);
01094 
01095   if(nAccepted < 0)
01096   {
01097     
01098     
01099     
01100     mMessageForUser << "!! MapMaker: Cholesky failure in bundle adjust. " << endl
01101         << "   The map is probably corrupt: Ditching the map. " << endl;
01102     mbResetRequested = true;
01103     return;
01104   }
01105 
01106   
01107   if(nAccepted > 0)
01108   {
01109     
01110     std::set<MapPoint::Ptr> mapPointsToUpdate; 
01111     for(map<MapPoint::Ptr,int>::iterator itr = mPoint_BundleID.begin();
01112         itr!=mPoint_BundleID.end();
01113         itr++){
01114       itr->first->v3WorldPos = b.GetPoint(itr->second);
01115       mapPointsToUpdate.insert(itr->first);
01116     }
01117     octomap_interface.updatePoints(mapPointsToUpdate);
01118     
01119 
01120     for(map<KeyFrame::Ptr,int>::iterator itr = mView_BundleID.begin();
01121         itr!=mView_BundleID.end();
01122         itr++)
01123       itr->first->se3CfromW = b.GetCamera(itr->second);
01124     if(bRecent)
01125       mbBundleConverged_Recent = false;
01126     mbBundleConverged_Full = false;
01127   };
01128 
01129   if(b.Converged())
01130   {
01131     mbBundleConverged_Recent = true;
01132     if(!bRecent)
01133       mbBundleConverged_Full = true;
01134   }
01135 
01136   mbBundleRunning = false;
01137   mbBundleAbortRequested = false;
01138 
01139   
01140   vector<pair<int,int> > vOutliers_PC_pair = b.GetOutlierMeasurements();
01141 
01142   for(unsigned int i=0; i<vOutliers_PC_pair.size(); i++)
01143   {
01144     MapPoint::Ptr pp = mBundleID_Point[vOutliers_PC_pair[i].first];
01145     KeyFrame::Ptr pk = mBundleID_View[vOutliers_PC_pair[i].second];
01146     Measurement &m = pk->mMeasurements[pp];
01147 
01148     if(pp->pMMData->GoodMeasCount() <= 2 || m.Source == Measurement::SRC_ROOT)   
01149       pp->bBad = true;
01150     else
01151     {
01152       
01153       if(m.Source == Measurement::SRC_TRACKER || m.Source == Measurement::SRC_EPIPOLAR)
01154         mvFailureQueue.push_back(pair<KeyFrame::Ptr,MapPoint::Ptr>(pk,pp));
01155       else
01156         pp->pMMData->sNeverRetryKFs.insert(pk);
01157       pk->mMeasurements.erase(pp);
01158       pp->pMMData->sMeasurementKFs.erase(pk);
01159       
01160       
01161       
01162       
01163       
01164       
01165       
01166     }
01167   }
01168 }
01169 
01170 
01171 
01172 
01173 
01174 
01175 bool MapMaker::ReFind_Common(KeyFrame::Ptr k, MapPoint::Ptr p)
01176 {
01177   
01178   
01179   if(p->pMMData->sMeasurementKFs.count(k)
01180       || p->pMMData->sNeverRetryKFs.count(k))
01181     return false;
01182 
01183   static PatchFinder Finder;
01184   Vector<3> v3Cam = k->se3CfromW * p->v3WorldPos;
01185   if(v3Cam[2] < 0.001)
01186   {
01187     p->pMMData->sNeverRetryKFs.insert(k);
01188     return false;
01189   }
01190   Vector<2> v2ImPlane = project(v3Cam);
01191   if(v2ImPlane* v2ImPlane > mCamera.LargestRadiusInImage() * mCamera.LargestRadiusInImage())
01192   {
01193     p->pMMData->sNeverRetryKFs.insert(k);
01194     return false;
01195   }
01196 
01197   Vector<2> v2Image = mCamera.Project(v2ImPlane);
01198   if(mCamera.Invalid())
01199   {
01200     p->pMMData->sNeverRetryKFs.insert(k);
01201     return false;
01202   }
01203 
01204   ImageRef irImageSize = k->aLevels[0].im.size();
01205   if(v2Image[0] < 0 || v2Image[1] < 0 || v2Image[0] > irImageSize[0] || v2Image[1] > irImageSize[1])
01206   {
01207     p->pMMData->sNeverRetryKFs.insert(k);
01208     return false;
01209   }
01210 
01211   Matrix<2> m2CamDerivs = mCamera.GetProjectionDerivs();
01212   Finder.MakeTemplateCoarse(p, k->se3CfromW, m2CamDerivs);
01213 
01214   if(Finder.TemplateBad())
01215   {
01216     p->pMMData->sNeverRetryKFs.insert(k);
01217     return false;
01218   }
01219   bool bFound = Finder.FindPatchCoarse(ir(v2Image), k, 4);  
01220   if(!bFound)
01221   {
01222     p->pMMData->sNeverRetryKFs.insert(k);
01223     return false;
01224   }
01225 
01226   
01227   Measurement m;
01228   m.nLevel = Finder.GetLevel();
01229   m.Source = Measurement::SRC_REFIND;
01230 
01231   if(Finder.GetLevel() > 0)
01232   {
01233     Finder.MakeSubPixTemplate();
01234     Finder.IterateSubPixToConvergence(*k,8);
01235     m.v2RootPos = Finder.GetSubPixPos();
01236     m.bSubPix = true;
01237   }
01238   else
01239   {
01240     m.v2RootPos = Finder.GetCoarsePosAsVector();
01241     m.bSubPix = false;
01242   };
01243 
01244   if(k->mMeasurements.count(p))
01245   {
01246     assert(0); 
01247   }
01248   k->mMeasurements[p] = m;
01249   p->pMMData->sMeasurementKFs.insert(k);
01250   
01251 #ifdef KF_REPROJ
01252   k->AddKeyMapPoint(p);
01253 #endif
01254   
01255   
01256   octomap_interface.updatePoint(p);
01257   
01258   return true;
01259 }
01260 
01261 
01262 
01263 int MapMaker::ReFindInSingleKeyFrame(KeyFrame::Ptr k)
01264 {
01265   vector<MapPoint::Ptr> vToFind;
01266   for(unsigned int i=0; i<mMap.vpPoints.size(); i++)
01267     vToFind.push_back(mMap.vpPoints[i]);
01268 
01269   int nFoundNow = 0;
01270   for(unsigned int i=0; i<vToFind.size(); i++)
01271     if(ReFind_Common(k,vToFind[i]))
01272       nFoundNow++;
01273 
01274   return nFoundNow;
01275 };
01276 
01277 
01278 
01279 
01280 void MapMaker::ReFindNewlyMade()
01281 {
01282   if(mqNewQueue.empty())
01283     return;
01284   int nFound = 0;
01285   int nBad = 0;
01286   while(!mqNewQueue.empty() && mvpKeyFrameQueue.size() == 0)
01287   {
01288     MapPoint::Ptr pNew = mqNewQueue.front();
01289     mqNewQueue.pop();
01290     if(pNew->bBad)
01291     {
01292       nBad++;
01293       continue;
01294     }
01295     for(unsigned int i=0; i<mMap.vpKeyFrames.size(); i++)
01296       if(ReFind_Common(mMap.vpKeyFrames[i], pNew))
01297         nFound++;
01298   }
01299 };
01300 
01301 
01302 void MapMaker::ReFindFromFailureQueue()
01303 {
01304   if(mvFailureQueue.size() == 0)
01305     return;
01306   sort(mvFailureQueue.begin(), mvFailureQueue.end());
01307   vector<pair<KeyFrame::Ptr, MapPoint::Ptr> >::iterator it;
01308   int nFound=0;
01309   for(it = mvFailureQueue.begin(); it!=mvFailureQueue.end(); it++)
01310     if(ReFind_Common(it->first, it->second))
01311       nFound++;
01312 
01313   mvFailureQueue.erase(mvFailureQueue.begin(), it);
01314 };
01315 
01316 
01317 bool MapMaker::IsDistanceToNearestKeyFrameExcessive(KeyFrame::Ptr kCurrent)
01318 {
01319   return DistToNearestKeyFrame(kCurrent) > mdWiggleScale * 10.0;
01320 }
01321 
01322 
01323 SE3<> MapMaker::CalcPlaneAligner()
01324 {
01325   unsigned int nPoints = mMap.vpPoints.size();
01326   if(nPoints < 10)
01327   {
01328     mMessageForUser << "  MapMaker: CalcPlane: too few points to calc plane." << endl;
01329     return SE3<>();
01330   };
01331   
01332   
01333   const ptam::PtamParamsConfig& pPars = PtamParameters::varparams();
01334   int nRansacs = pPars.PlaneAlignerRansacs;
01335   
01336   
01337   Vector<3> v3BestMean=makeVector(0,0,0);
01338   Vector<3> v3BestNormal=makeVector(0,0,0);
01339   double dBestDistSquared = 9999999999999999.9;
01340 
01341   for(int i=0; i<nRansacs; i++)
01342   {
01343     int nA = rand()%nPoints;
01344     int nB = nA;
01345     int nC = nA;
01346     while(nB == nA)
01347       nB = rand()%nPoints;
01348     while(nC == nA || nC==nB)
01349       nC = rand()%nPoints;
01350 
01351     Vector<3> v3Mean = 0.33333333 * (mMap.vpPoints[nA]->v3WorldPos +
01352         mMap.vpPoints[nB]->v3WorldPos +
01353         mMap.vpPoints[nC]->v3WorldPos);
01354 
01355     Vector<3> v3CA = mMap.vpPoints[nC]->v3WorldPos  - mMap.vpPoints[nA]->v3WorldPos;
01356     Vector<3> v3BA = mMap.vpPoints[nB]->v3WorldPos  - mMap.vpPoints[nA]->v3WorldPos;
01357     Vector<3> v3Normal = v3CA ^ v3BA;
01358     if(v3Normal * v3Normal  == 0)
01359       continue;
01360     normalize(v3Normal);
01361 
01362     double dSumError = 0.0;
01363     for(unsigned int i=0; i<nPoints; i++)
01364     {
01365       Vector<3> v3Diff = mMap.vpPoints[i]->v3WorldPos - v3Mean;
01366       double dDistSq = v3Diff * v3Diff;
01367       if(dDistSq == 0.0)
01368         continue;
01369       double dNormDist = fabs(v3Diff * v3Normal);
01370 
01371       if(dNormDist > 0.05)
01372         dNormDist = 0.05;
01373       dSumError += dNormDist;
01374     }
01375     if(dSumError < dBestDistSquared)
01376     {
01377       dBestDistSquared = dSumError;
01378       v3BestMean = v3Mean;
01379       v3BestNormal = v3Normal;
01380     }
01381   }
01382 
01383   
01384   vector<Vector<3> > vv3Inliers;
01385   for(unsigned int i=0; i<nPoints; i++)
01386   {
01387     Vector<3> v3Diff = mMap.vpPoints[i]->v3WorldPos - v3BestMean;
01388     double dDistSq = v3Diff * v3Diff;
01389     if(dDistSq == 0.0)
01390       continue;
01391     double dNormDist = fabs(v3Diff * v3BestNormal);
01392     if(dNormDist < 0.05)
01393       vv3Inliers.push_back(mMap.vpPoints[i]->v3WorldPos);
01394   }
01395 
01396   
01397   Vector<3> v3MeanOfInliers = Zeros;
01398   for(unsigned int i=0; i<vv3Inliers.size(); i++)
01399     v3MeanOfInliers+=vv3Inliers[i];
01400   v3MeanOfInliers *= (1.0 / vv3Inliers.size());
01401 
01402   Matrix<3> m3Cov = Zeros;
01403   for(unsigned int i=0; i<vv3Inliers.size(); i++)
01404   {
01405     Vector<3> v3Diff = vv3Inliers[i] - v3MeanOfInliers;
01406     m3Cov += v3Diff.as_col() * v3Diff.as_row();
01407   };
01408 
01409   
01410   SymEigen<3> sym(m3Cov);
01411   Vector<3> v3Normal = sym.get_evectors()[0];
01412 
01413   
01414   if(v3Normal[2] > 0)
01415     v3Normal *= -1.0;
01416 
01417   Matrix<3> m3Rot = Identity;
01418   m3Rot[2] = v3Normal;
01419   m3Rot[0] = m3Rot[0] - (v3Normal * (m3Rot[0] * v3Normal));
01420   normalize(m3Rot[0]);
01421   m3Rot[1] = m3Rot[2] ^ m3Rot[0];
01422 
01423   SE3<> se3Aligner;
01424   se3Aligner.get_rotation() = m3Rot;
01425   Vector<3> v3RMean = se3Aligner * v3MeanOfInliers;
01426   se3Aligner.get_translation() = -v3RMean;
01427 
01428   return se3Aligner;
01429 }
01430 
01431 
01432 
01433 
01434 bool MapMaker::RefreshSceneDepth(KeyFrame::Ptr pKF)
01435 {
01436   double dSumDepth = 0.0;
01437   double dSumDepthSquared = 0.0;
01438   int nMeas = 0;
01439   for(meas_it it = pKF->mMeasurements.begin(); it!=pKF->mMeasurements.end(); it++)
01440   {
01441     MapPoint &point = *it->first;
01442     Vector<3> v3PosK = pKF->se3CfromW * point.v3WorldPos;
01443     dSumDepth += v3PosK[2];
01444     dSumDepthSquared += v3PosK[2] * v3PosK[2];
01445     nMeas++;
01446   }
01447   
01448   
01449   
01450   if (nMeas<2)
01451     return false;
01452   pKF->dSceneDepthMean = dSumDepth / nMeas;
01453   pKF->dSceneDepthSigma = sqrt((dSumDepthSquared / nMeas) - (pKF->dSceneDepthMean) * (pKF->dSceneDepthMean));
01454   return true;
01455 }
01456 
01457 void MapMaker::GUICommandCallBack(void* ptr, string sCommand, string sParams)
01458 {
01459   Command c;
01460   c.sCommand = sCommand;
01461   c.sParams = sParams;
01462   ((MapMaker*) ptr)->mvQueuedCommands.push_back(c);
01463 }
01464 
01465 void MapMaker::GUICommandHandler(string sCommand, string sParams)  
01466 {
01467   if(sCommand=="SaveMap")
01468   {
01469     mMessageForUser << "  MapMaker: Saving the map.... " << endl;
01470     ofstream ofs("map.dump");
01471     for(unsigned int i=0; i<mMap.vpPoints.size(); i++)
01472     {
01473       ofs << mMap.vpPoints[i]->v3WorldPos << "  ";
01474       ofs << mMap.vpPoints[i]->nSourceLevel << endl;
01475     }
01476     ofs.close();
01477 
01478     for(unsigned int i=0; i<mMap.vpKeyFrames.size(); i++)
01479     {
01480       ostringstream ost1;
01481       ost1 << "keyframes/" << i << ".jpg";
01482       
01483 
01484       ostringstream ost2;
01485       ost2 << "keyframes/" << i << ".info";
01486       ofstream ofs2;
01487       ofs2.open(ost2.str().c_str());
01488       ofs2 << mMap.vpKeyFrames[i]->se3CfromW << endl;
01489       ofs2.close();
01490     }
01491     mMessageForUser << "  ... done saving map." << endl;
01492     return;
01493   }
01494 
01495   mMessageForUser << "! MapMaker::GUICommandHandler: unhandled command "<< sCommand << endl;
01496   exit(1);
01497 }; 
01498 
01499 
01500 
01501 
01502 
01503 
01504 
01505 
01506 
01507 
01508 
01509