Merged pcl_integration branch to trunk

git-svn-id: http://rtabmap.googlecode.com/svn/trunk/rtabmap@1014 f169173b-cf89-36c8-b27e-44dbe73f0c83
This commit is contained in:
matlabbe
2013-12-11 00:12:44 +00:00
parent 97c70d394e
commit 8b8511e154
124 changed files with 21692 additions and 4458 deletions

View File

@@ -0,0 +1,361 @@
/**********************************************************************
*
* This source code is part of the Tree-based Network Optimizer (TORO)
*
* TORO Copyright (c) 2007 Giorgio Grisetti, Cyrill Stachniss,
* Slawomir Grzonka, and Wolfram Burgard
*
* TORO is licences under the Common Creative License,
* Attribution-NonCommercial-ShareAlike 3.0
*
* You are free:
* - to Share - to copy, distribute and transmit the work
* - to Remix - to adapt the work
*
* Under the following conditions:
*
* - Attribution. You must attribute the work in the manner specified
* by the author or licensor (but not in any way that suggests that
* they endorse you or your use of the work).
*
* - Noncommercial. You may not use this work for commercial purposes.
*
* - Share Alike. If you alter, transform, or build upon this work,
* you may distribute the resulting work only under the same or
* similar license to this one.
*
* Any of the above conditions can be waived if you get permission
* from the copyright holder. Nothing in this license impairs or
* restricts the author's moral rights.
*
* TORO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE.
**********************************************************************/
/** \file treeoptimizer3.cpp
*
* \brief Defines the core optimizer class for 3D graphs which is a
* subclass of TreePoseGraph3
*
**/
#include "treeoptimizer3.hh"
#include <fstream>
#include <sstream>
#include <string>
using namespace std;
namespace AISNavigation {
#define DEBUG(i) \
if (verboseLevel>i) cerr
TreeOptimizer3::TreeOptimizer3(){
restartOnDivergence=false;
sortedEdges=0;
mpl=-1;
edgeCompareMode=EVComparator<Edge*>::CompareLevel;
}
TreeOptimizer3::~TreeOptimizer3(){
}
void TreeOptimizer3::initializeTreeParameters(){
ParameterPropagator pp;
treeDepthVisit(pp,root);
}
void TreeOptimizer3::iterate(TreePoseGraph3::EdgeSet* eset, bool noPreconditioner){
TreePoseGraph3::EdgeSet* temp=sortedEdges;
if (eset){
sortedEdges=eset;
}
if (noPreconditioner)
propagateErrors(false);
else {
if (iteration==1)
computePreconditioner();
propagateErrors(true);
}
sortedEdges=temp;
onRestartBegin();
if (restartOnDivergence){
double mte, ate;
double mre, are;
error(&mre, &mte, &are, &ate);
maxTranslationalErrors.push_back(mte);
maxRotationalErrors.push_back(mre);
int interval=3;
if ((int)maxRotationalErrors.size()>=interval){
uint s=maxRotationalErrors.size();
double re0 = maxRotationalErrors[s-interval];
double re1 = maxRotationalErrors[s-1];
if ((re1-re0)>are || sqrt(re1)>0.99*M_PI){
double rg=rotGain;
if (sqrt(re1)>M_PI/4){
cerr << "RESTART!!!!! : Angular wraparound may be occourring" << endl;
cerr << " err=" << re0 << " -> " << re1 << endl;
cerr << "Restarting optimization and reducing the rotation factor" << endl;
cerr << rg << " -> ";
initializeOnTree();
initializeTreeParameters();
initializeOptimization();
error(&mre, &mte);
maxTranslationalErrors.push_back(mte);
maxRotationalErrors.push_back(mre);
rg*=0.1;
rotGain=rg;
cerr << rotGain << endl;
}
else {
cerr << "decreasing angular gain" << rotGain*0.1 << endl;
rotGain*=0.1;
}
}
}
}
onRestartDone();
}
void TreeOptimizer3::recomputeTransformations(Vertex*v, Vertex* top){
if (v==top)
return;
recomputeTransformations(v->parent, top);
v->transformation=v->parent->transformation*v->parameters;
}
void TreeOptimizer3::recomputeParameters(Vertex*v, Vertex* top){
while (v!=top){
v->parameters=v->parent->transformation.inv()*v->transformation;
v=v->parent;
}
}
TreeOptimizer3::Transformation TreeOptimizer3::getPose(Vertex*v, Vertex* top){
Transformation t(0.,0.,0.,0.,0.,0.);
if (v==top)
return v->transformation;
while (v!=top){
t=v->parameters*t;
v=v->parent;
}
return top->transformation*t;
}
TreeOptimizer3::Rotation TreeOptimizer3::getRotation(Vertex*v, Vertex* top){
Rotation r(0.,0.,0.);
if (v==top)
return v->transformation.rotation();
while (v!=top){
r=v->parameters.rotation()*r;
v=v->parent;
}
return top->transformation.rotation()*r;
}
double TreeOptimizer3::error(const Edge* e) const{
const Vertex* v1=e->v1;
const Vertex* v2=e->v2;
Transformation et=e->transformation;
Transformation t1=v1->transformation;
Transformation t2=v2->transformation;
Transformation t12=(t1*et)*t2.inv();
Pose p12=t12.toPoseType();
Pose ps=e->informationMatrix*p12;
double err=p12*ps;
DEBUG(100) << "e(" << v1->id << "," << v2->id << ")" << err << endl;
return err;
}
double TreeOptimizer3::traslationalError(const Edge* e) const{
const Vertex* v1=e->v1;
const Vertex* v2=e->v2;
Transformation et=e->transformation;
Transformation t1=v1->transformation;
Transformation t2=v2->transformation;
Translation t12=(t2.inv()*(t1*et)).translation();
return t12*t12;;
}
double TreeOptimizer3::rotationalError(const Edge* e) const{
const Vertex* v1=e->v1;
const Vertex* v2=e->v2;
Rotation er=e->transformation.rotation();
Rotation r1=v1->transformation.rotation();
Rotation r2=v2->transformation.rotation();
Rotation r12=r2.inverse()*(r1*er);
double r=r12.angle();
return r*r;
}
double TreeOptimizer3::loopError(const Edge* e) const{
double err=0;
const Vertex* v=e->v1;
while (v!=e->top){
err+=error(v->parentEdge);
v=v->parent;
}
v=e->v2;
while (v==e->top){
err+=error(v->parentEdge);
v=v->parent;
}
if (e->v2->parentEdge!=e && e->v1->parentEdge!=e)
err+=error(e);
return err;
}
double TreeOptimizer3::loopRotationalError(const Edge* e) const{
double err=0;
const Vertex* v=e->v1;
while (v!=e->top){
err+=rotationalError(v->parentEdge);
v=v->parent;
}
v=e->v2;
while (v!=e->top){
err+=rotationalError(v->parentEdge);
v=v->parent;
}
if (e->v2->parentEdge!=e && e->v1->parentEdge!=e)
err+=rotationalError(e);
return err;
}
double TreeOptimizer3::error(double* mre, double* mte, double* are, double* ate, TreePoseGraph3::EdgeSet* eset) const{
double globalRotError=0.;
double maxRotError=0;
double globalTrasError=0.;
double maxTrasError=0;
int c=0;
if (! eset){
for (TreePoseGraph3::EdgeMap::const_iterator it=edges.begin(); it!=edges.end(); it++){
double re=rotationalError(it->second);
globalRotError+=re;
maxRotError=maxRotError>re?maxRotError:re;
double te=traslationalError(it->second);
globalTrasError+=te;
maxTrasError=maxTrasError>te?maxTrasError:te;
c++;
}
} else {
for (TreePoseGraph3::EdgeSet::const_iterator it=eset->begin(); it!=eset->end(); it++){
const TreePoseGraph3::Edge* edge=*it;
double re=rotationalError(edge);
globalRotError+=re;
maxRotError=maxRotError>re?maxRotError:re;
double te=traslationalError(edge);
globalTrasError+=te;
maxTrasError=maxTrasError>te?maxTrasError:te;
c++;
}
}
if (mte)
*mte=maxTrasError;
if (mre)
*mre=maxRotError;
if (ate)
*ate=globalTrasError/c;
if (are)
*are=globalRotError/c;
return globalRotError+globalTrasError;
}
void TreeOptimizer3::initializeOptimization(EdgeCompareMode mode){
edgeCompareMode=mode;
// compute the size of the preconditioning matrix
int sz=maxIndex()+1;
DEBUG(1) << "Size= " << sz << endl;
M.resize(sz);
DEBUG(1) << "allocating M(" << sz << ")" << endl;
iteration=1;
// sorting edges
if (sortedEdges!=0){
delete sortedEdges;
sortedEdges=0;
}
sortedEdges=sortEdges();
mpl=maxPathLength();
rotGain=1.;
trasGain=1.;
}
void TreeOptimizer3::initializeOnlineIterations(){
int sz=maxIndex()+1;
DEBUG(1) << "Size= " << sz << endl;
M.resize(sz);
DEBUG(1) << "allocating M(" << sz << ")" << endl;
iteration=1;
maxRotationalErrors.clear();
maxTranslationalErrors.clear();
rotGain=1.;
trasGain=1.;
}
void TreeOptimizer3::initializeOnlineOptimization(EdgeCompareMode mode){
edgeCompareMode=mode;
// compute the size of the preconditioning matrix
clear();
Vertex* v0=addVertex(0,Pose(0,0,0,0,0,0));
root=v0;
v0->parameters=Transformation(v0->pose);
v0->parentEdge=0;
v0->parent=0;
v0->level=0;
v0->transformation=Transformation(TreePoseGraph3::Pose(0,0,0,0,0,0));
}
void TreeOptimizer3::onStepStart(Edge* e){
DEBUG(5) << "entering edge" << e << endl;
}
void TreeOptimizer3::onStepFinished(Edge* e){
DEBUG(5) << "exiting edge" << e << endl;
}
void TreeOptimizer3::onIterationStart(int iteration){
DEBUG(5) << "entering iteration " << iteration << endl;
}
void TreeOptimizer3::onIterationFinished(int iteration){
DEBUG(5) << "exiting iteration " << iteration << endl;
}
void TreeOptimizer3::onRestartBegin(){}
void TreeOptimizer3::onRestartDone(){}
bool TreeOptimizer3::isDone(){
return false;
}
}; //namespace AISNavigation