00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00044 #include "treeoptimizer3.hh"
00045 #include <fstream>
00046 #include <sstream>
00047 #include <string>
00048
00049 using namespace std;
00050
00051 #define DEBUG(i) \
00052 if (verboseLevel>i) cerr
00053
00054
00056 struct ParameterPropagator{
00057 void perform(TreePoseGraph3::Vertex* v){
00058 if (!v->parent){
00059 v->parameters=TreePoseGraph3::Transformation(0.,0.,0.,0.,0.,0.);
00060 return;
00061 }
00062 v->parameters=v->parent->transformation.inv()*v->transformation;
00063 }
00064 };
00065
00067 struct TransformationPropagator{
00068 void perform(TreePoseGraph3::Vertex* v){
00069 if (!v->parent){
00070 return;
00071 }
00072 v->transformation=v->parent->transformation*v->parameters;
00073 }
00074 };
00075
00076 TreeOptimizer3::TreeOptimizer3(){
00077 restartOnDivergence=false;
00078 sortedEdges=0;
00079 mpl=-1;
00080 edgeCompareMode=EVComparator<Edge*>::CompareLevel;
00081 }
00082
00083
00084 TreeOptimizer3::~TreeOptimizer3(){
00085 }
00086
00087 void TreeOptimizer3::initializeTreeParameters(){
00088 ParameterPropagator pp;
00089 treeDepthVisit(pp, root);
00090 }
00091
00092 void TreeOptimizer3::recomputeAllTransformations(){
00093 TransformationPropagator tp;
00094 treeDepthVisit(tp, root);
00095 }
00096
00097
00098 void TreeOptimizer3::iterate(TreePoseGraph3::EdgeSet* eset, bool noPreconditioner){
00099 TreePoseGraph3::EdgeSet* temp=sortedEdges;
00100 if (eset){
00101 sortedEdges=eset;
00102 }
00103
00104 if (noPreconditioner)
00105 propagateErrors();
00106 else {
00107 if (iteration==1)
00108 computePreconditioner();
00109 propagateErrorsPreconditioner();
00110 }
00111
00112 if (restartOnDivergence){
00113 double mte, ate;
00114 double mre, are;
00115 error(&mre, &mte, &are, &ate);
00116 maxTranslationalErrors.push_back(mte);
00117 maxRotationalErrors.push_back(mre);
00118 int interval=3;
00119 if ((int)maxRotationalErrors.size()>=interval){
00120 uint s=maxRotationalErrors.size();
00121 double re0 = maxRotationalErrors[s-interval];
00122 double re1 = maxRotationalErrors[s-1];
00123
00124 if ((re1-re0)>are || sqrt(re1)>0.99*M_PI){
00125 double rg=rotGain;
00126 if (sqrt(re1)>M_PI/4){
00127 cerr << "RESTART!!!!! : Angular wraparound may be occourring" << endl;
00128 cerr << " err=" << re0 << " -> " << re1 << endl;
00129 cerr << "Restarting optimization and reducing the rotation factor" << endl;
00130 cerr << rg << " -> ";
00131 initializeOnTree();
00132 initializeTreeParameters();
00133 initializeOptimization();
00134 error(&mre, &mte);
00135 maxTranslationalErrors.push_back(mte);
00136 maxRotationalErrors.push_back(mre);
00137 rg*=0.1;
00138 rotGain=rg;
00139 cerr << rotGain << endl;
00140 }
00141 else {
00142 cerr << "decreasing angular gain" << rotGain*0.1 << endl;
00143 rotGain*=0.1;
00144 }
00145 }
00146 }
00147 }
00148 sortedEdges=temp;
00149 }
00150
00151
00152 void TreeOptimizer3::recomputeTransformations(Vertex*v, Vertex* top){
00153 if (v==top)
00154 return;
00155 recomputeTransformations(v->parent, top);
00156 v->transformation=v->parent->transformation*v->parameters;
00157 }
00158
00159
00160 void TreeOptimizer3::recomputeParameters(Vertex*v, Vertex* top){
00161 while (v!=top){
00162 v->parameters=v->parent->transformation.inv()*v->transformation;
00163 v=v->parent;
00164 }
00165 }
00166
00167
00168 TreeOptimizer3::Transformation TreeOptimizer3::getPose(Vertex*v, Vertex* top){
00169 Transformation t(0.,0.,0.,0.,0.,0.);
00170 if (v==top)
00171 return v->transformation;
00172 while (v!=top){
00173 t=v->parameters*t;
00174 v=v->parent;
00175 }
00176 return top->transformation*t;
00177 }
00178
00179 TreeOptimizer3::Rotation TreeOptimizer3::getRotation(Vertex*v, Vertex* top){
00180 Rotation r(0.,0.,0.);
00181 if (v==top)
00182 return v->transformation.rotation();
00183 while (v!=top){
00184 r=v->parameters.rotation()*r;
00185 v=v->parent;
00186 }
00187 return top->transformation.rotation()*r;
00188 }
00189
00190
00191
00192 double TreeOptimizer3::error(const Edge* e) const{
00193 const Vertex* v1=e->v1;
00194 const Vertex* v2=e->v2;
00195
00196 Transformation et=e->transformation;
00197 Transformation t1=v1->transformation;
00198 Transformation t2=v2->transformation;
00199
00200 Transformation t12=(t1*et)*t2.inv();
00201 Pose p12=t12.toPoseType();
00202
00203 Pose ps=e->informationMatrix*p12;
00204 double err=p12*ps;
00205 DEBUG(100) << "e(" << v1->id << "," << v2->id << ")" << err << endl;
00206 return err;
00207
00208 }
00209
00210 double TreeOptimizer3::traslationalError(const Edge* e) const{
00211 const Vertex* v1=e->v1;
00212 const Vertex* v2=e->v2;
00213
00214 Transformation et=e->transformation;
00215 Transformation t1=v1->transformation;
00216 Transformation t2=v2->transformation;
00217
00218 Translation t12=(t2.inv()*(t1*et)).translation();
00219 return t12*t12;;
00220
00221 }
00222
00223 double TreeOptimizer3::rotationalError(const Edge* e) const{
00224 const Vertex* v1=e->v1;
00225 const Vertex* v2=e->v2;
00226
00227 Rotation er=e->transformation.rotation();
00228 Rotation r1=v1->transformation.rotation();
00229 Rotation r2=v2->transformation.rotation();
00230
00231 Rotation r12=r2.inverse()*(r1*er);
00232 double r=r12.angle();
00233 return r*r;
00234 }
00235
00236
00237 double TreeOptimizer3::error(double* mre, double* mte, double* are, double* ate, TreePoseGraph3::EdgeSet* eset) const{
00238 double globalRotError=0.;
00239 double maxRotError=0;
00240 double globalTrasError=0.;
00241 double maxTrasError=0;
00242
00243 int c=0;
00244 if (! eset){
00245 for (TreePoseGraph3::EdgeMap::const_iterator it=edges.begin(); it!=edges.end(); it++){
00246 double re=rotationalError(it->second);
00247 globalRotError+=re;
00248 maxRotError=maxRotError>re?maxRotError:re;
00249 double te=traslationalError(it->second);
00250 globalTrasError+=te;
00251 maxTrasError=maxTrasError>te?maxTrasError:te;
00252 c++;
00253 }
00254 } else {
00255 for (TreePoseGraph3::EdgeSet::const_iterator it=eset->begin(); it!=eset->end(); it++){
00256 const TreePoseGraph3::Edge* edge=*it;
00257 double re=rotationalError(edge);
00258 globalRotError+=re;
00259 maxRotError=maxRotError>re?maxRotError:re;
00260 double te=traslationalError(edge);
00261 globalTrasError+=te;
00262 maxTrasError=maxTrasError>te?maxTrasError:te;
00263 c++;
00264 }
00265 }
00266
00267 if (mte)
00268 *mte=maxTrasError;
00269 if (mre)
00270 *mre=maxRotError;
00271 if (ate)
00272 *ate=globalTrasError/c;
00273 if (are)
00274 *are=globalRotError/c;
00275 return globalRotError+globalTrasError;
00276 }
00277
00278
00279
00280 void TreeOptimizer3::initializeOptimization(EdgeCompareMode mode){
00281 edgeCompareMode=mode;
00282
00283 int sz=maxIndex()+1;
00284 DEBUG(1) << "Size= " << sz << endl;
00285 M.resize(sz);
00286
00287 DEBUG(1) << "allocating M(" << sz << ")" << endl;
00288 iteration=1;
00289
00290
00291 if (sortedEdges!=0){
00292 delete sortedEdges;
00293 sortedEdges=0;
00294 }
00295 sortedEdges=sortEdges();
00296 mpl=maxPathLength();
00297 rotGain=1.;
00298 trasGain=1.;
00299 }
00300
00301 void TreeOptimizer3::initializeOnlineIterations(){
00302 int sz=maxIndex()+1;
00303 DEBUG(1) << "Size= " << sz << endl;
00304 M.resize(sz);
00305 DEBUG(1) << "allocating M(" << sz << ")" << endl;
00306 iteration=1;
00307 maxRotationalErrors.clear();
00308 maxTranslationalErrors.clear();
00309 rotGain=1.;
00310 trasGain=1.;
00311 }
00312
00313 void TreeOptimizer3::initializeOnlineOptimization(EdgeCompareMode mode){
00314 edgeCompareMode=mode;
00315
00316 clear();
00317 Vertex* v0=addVertex(0,Pose(0,0,0,0,0,0));
00318 root=v0;
00319 v0->parameters=Transformation(v0->pose);
00320 v0->parentEdge=0;
00321 v0->parent=0;
00322 v0->level=0;
00323 v0->transformation=Transformation(TreePoseGraph3::Pose(0,0,0,0,0,0));
00324 }
00325
00326 void TreeOptimizer3::onStepStart(Edge* e){
00327 (void) e;
00328 }
00329
00330 void TreeOptimizer3::onStepFinished(Edge* e){
00331 (void) e;
00332 }
00333
00334 void TreeOptimizer3::onIterationStart(int iteration){
00335 (void) iteration;
00336 }
00337
00338 void TreeOptimizer3::onIterationFinished(int iteration){
00339 (void) iteration;
00340 }
00341
00342 bool TreeOptimizer3::isDone(){
00343 return false;
00344 }
00345
00346