Program Listing for File OptimizationThread.cpp¶
↰ Return to documentation for file (lib/SlamSystem/OptimizationThread.cpp)
#include "OptimizationThread.h"
#include "DataStructures/Frame.h"
#include "GlobalMapping/KeyFrameGraph.h"
#include <g3log/g3log.hpp>
#include "SlamSystem.h"
#include "MappingThread.h"
namespace lsd_slam {
using active_object::ActiveIdle;
const auto optimizationDt = std::chrono::milliseconds(2000);
OptimizationThread::OptimizationThread( SlamSystem &system, bool threaded )
: //_haveUnmergedOptimizationOffset( false ),
_system( system ),
_thread( threaded ? ActiveIdle::createActiveIdle( std::bind( &OptimizationThread::idleImpl, this ), optimizationDt ) : NULL )
{
LOG(INFO) << "Started optimization thread";
}
OptimizationThread::~OptimizationThread()
{
if( _thread ) delete _thread.release();
LOG(INFO) << "Exited optimization thread";
}
//===== Callbacks for ActiveObject ======
void OptimizationThread::idleImpl( void )
{
LOG(DEBUG) << "Running short optimization";
while(optimizationIteration(5, 0.02)) { ; } //_system.mapThread()->doMergeOptimizationUpdate(); }
}
void OptimizationThread::newConstraintImpl( void )
{
LOG(DEBUG) << "Running short optimization";
_system.keyFrameGraph()->addElementsFromBuffer();
while(optimizationIteration(5, 0.02)) { ; } //_system._mapThread->doMergeOptimizationUpdate(); }
}
void OptimizationThread::finalOptimizationImpl( void )
{
LOG(INFO) << "Running final optimization!";
optimizationIteration(50, 0.001);
_system.mapThread()->doMergeOptimizationUpdate();
finalOptimizationComplete.notify();
}
//=== Actual meat ====
bool OptimizationThread::optimizationIteration(int itsPerTry, float minChange)
{
Timer timer;
// std::lock_guard< std::mutex > lock(g2oGraphAccessMutex);
// Do the optimization. This can take quite some time!
int its = _system.keyFrameGraph()->optimize(itsPerTry);
// save the optimization result.
_system.poseConsistencyMutex.lock_shared();
_system.keyFrameGraph()->keyframesAllMutex.lock_shared();
float maxChange = 0;
float sumChange = 0;
float sum = 0;
for(size_t i=0;i<_system.keyFrameGraph()->keyframesAll.size(); i++)
{
// set edge error sum to zero
_system.keyFrameGraph()->keyframesAll[i]->frame()->edgeErrorSum = 0;
_system.keyFrameGraph()->keyframesAll[i]->frame()->edgesNum = 0;
if(!_system.keyFrameGraph()->keyframesAll[i]->frame()->pose->isInGraph) continue;
// get change from last optimization
Sim3 a = _system.keyFrameGraph()->keyframesAll[i]->frame()->pose->graphVertex->estimate();
Sim3 b = _system.keyFrameGraph()->keyframesAll[i]->frame()->getCamToWorld();
Sophus::Vector7f diff = (a*b.inverse()).log().cast<float>();
for(int j=0;j<7;j++)
{
float d = fabsf((float)(diff[j]));
if(d > maxChange) maxChange = d;
sumChange += d;
}
sum +=7;
// set change
_system.keyFrameGraph()->keyframesAll[i]->frame()->pose->setPoseGraphOptResult(
_system.keyFrameGraph()->keyframesAll[i]->frame()->pose->graphVertex->estimate());
// add error
for(auto edge : _system.keyFrameGraph()->keyframesAll[i]->frame()->pose->graphVertex->edges())
{
_system.keyFrameGraph()->keyframesAll[i]->frame()->edgeErrorSum += ((EdgeSim3*)(edge))->chi2();
_system.keyFrameGraph()->keyframesAll[i]->frame()->edgesNum++;
}
}
_system.keyFrameGraph()->keyframesAllMutex.unlock_shared();
_system.poseConsistencyMutex.unlock_shared();
LOGF_IF(DEBUG, Conf().print.optimizationInfo,
"did %d optimization iterations. Max Pose Parameter Change: %f; avgChange: %f. %s\n",
its, maxChange, sumChange / sum,
maxChange > minChange && its == itsPerTry ? "continue optimizing":"Waiting for addition to graph.");
perf.update( timer );
return maxChange > minChange && its == itsPerTry;
}
// void OptimizationThread::optimizeGraph( void )
// {
// std::unique_lock<std::mutex> g2oLock(g2oGraphAccessMutex);
// keyFrameGraph()->optimize(1000);
// g2oLock.unlock();
// mergeOptimizationOffset();
// }
}