48 inline double max3(
const double& a,
const double& b,
const double& c){
52 inline double min3(
const double& a,
const double& b,
const double& c){
59 TreeOptimizer3::Vertex*
n;
65 NodeInfo(TreeOptimizer3::Vertex* v=0,
double tw=0,
double rw=0,
int dir=0,
66 TreeOptimizer3::Transformation t=TreeOptimizer3::Transformation(0,0,0,0,0,0),
69 translationalWeight=tw;
86 void TreeOptimizer3::computePreconditioner(){
87 for (
uint i=0; i<M.size(); i++){
94 for (EdgeSet::iterator it=sortedEdges->begin(); it!=sortedEdges->end(); it++){
104 for (
int dir=0; dir<2; dir++){
105 Vertex* n = (dir==0)? e->v1 : e->v2;
108 double rW=
min3(W[0][0], W[1][1], W[2][2]);
109 double tW=
min3(W[3][3], W[4][4], W[5][5]);
112 gamma[0]=gamma[0]<rW?gamma[0]:rW;
113 gamma[1]=gamma[1]<tW?gamma[1]:tW;
121 for (
uint i=0; i<M.size(); i++){
122 cerr <<
"M[" << i <<
"]=" << M[i][0] <<
" " << M[i][1] << endl;
128 void TreeOptimizer3::propagateErrors(
bool usePreconditioner){
133 static NodeInfoVector path;
134 path.resize(edges.size()+1);
137 onIterationStart(iteration);
138 for (EdgeSet::iterator it=sortedEdges->begin(); it!=sortedEdges->end(); it++){
153 recomputeTransformations(v1,top);
154 recomputeTransformations(v2,top);
160 double totTW=0, totRW=0;
163 double tw=1./(double)l, rw=1./(
double)l;
164 if (usePreconditioner){
170 path[pc++]=
NodeInfo(aux,tw,rw,-1,aux->transformation, aux->parameters);
174 path[pc++]=
NodeInfo(top,0.,0.,0, top->transformation, top->parameters);
179 double tw=1./l, rw=1./l;
180 if (usePreconditioner){
186 path[pc--]=
NodeInfo(aux,tw,rw,1,aux->transformation, aux->parameters);
201 Rotation re=e->transformation.rotation();
204 double rotationFactor=(usePreconditioner)?
205 sqrt(
double(l))*
min3(e->informationMatrix[0][0],
206 e->informationMatrix[1][1],
207 e->informationMatrix[2][2])/
208 ( gamma[0]* (double)iteration ):
209 sqrt(
double(l))*rotGain/(double)iteration;
218 if (rotationFactor>1)
221 Rotation totalRotation = path[l].transformation.rotation() * rR * path[l].transformation.rotation().
inverse();
227 for (
int i= 1; i<=topIndex; i++){
228 cw+=path[i-1].rotationalWeight/totRW;
229 Rotation R=path[i].transformation.rotation();
230 Rotation B(axis, angle*cw*rotationFactor);
232 path[i].transformation.setRotation(R);
234 for (
int i= topIndex+1; i<=l; i++){
235 cw+=path[i].rotationalWeight/totRW;
236 Rotation R=path[i].transformation.rotation();
237 Rotation B(axis, angle*cw*rotationFactor);
239 path[i].transformation.setRotation(R);
243 for (
int i=0; i<topIndex; i++){
245 n->parameters.setRotation(path[i+1].transformation.rotation().inverse()*path[i].transformation.rotation());
247 for (
int i= topIndex+1; i<=l; i++){
249 n->parameters.setRotation(path[i-1].transformation.rotation().inverse()*path[i].transformation.rotation());
256 recomputeTransformations(v1,top);
257 recomputeTransformations(v2,top);
272 double translationFactor=(usePreconditioner)?
273 trasGain*l*
min3(e->informationMatrix[3][3],
274 e->informationMatrix[4][4],
275 e->informationMatrix[5][5])/( gamma[1]* (double)iteration):
276 trasGain*l/(double)iteration;
278 if (translationFactor>1)
284 for (
int i=topIndex-1; i>=0; i--){
286 lcum-=(usePreconditioner) ? path[i].translationalWeight/totTW : 1./(
double)l;
287 double fraction=lcum;
289 Translation T=n->transformation.translation()+offset;
290 n->transformation.setTranslation(T);
295 for (
int i=topIndex+1; i<=l; i++){
297 rcum+=(usePreconditioner) ? path[i].translationalWeight/totTW : 1./(
double)l;
298 double fraction=rcum;
300 Translation T=n->transformation.translation()+offset;
301 n->transformation.setTranslation(T);
303 assert(fabs(lcum+rcum)-1<1e-6);
305 recomputeParameters(v1, top);
306 recomputeParameters(v2, top);
313 Rotation newRotResidual=v2->transformation.rotation().
inverse()*(v1->transformation.rotation()*re);
315 double newRotResidualAngle=newRotResidual.
angle();
317 double rotResidualAngle=rR.
angle();
318 Translation newTransResidual=(v1->transformation*e->transformation).translation()-v2->transformation.translation();
320 cerr <<
"RotationalFraction: " << rotationFactor << endl;
321 cerr <<
"Rotational residual: " 322 <<
" axis " << rotResidualAxis.
x() <<
"\t" << rotResidualAxis.
y() <<
"\t" << rotResidualAxis.
z() <<
" --> " 323 <<
" -> " << newRotResidualAxis.
x() <<
"\t" << newRotResidualAxis.
y() <<
"\t" << newRotResidualAxis.
z() << endl;
324 cerr <<
" angle " << rotResidualAngle <<
"\t" << newRotResidualAngle << endl;
326 cerr <<
"Translational Fraction: " << translationFactor << endl;
327 cerr <<
"Translational Residual" << endl;
328 cerr <<
" " << tR.
x() <<
"\t" << tR.
y() <<
"\t" << tR.
z() << endl;
329 cerr <<
" " << newTransResidual.
x() <<
"\t" << newTransResidual.
y() <<
"\t" << newTransResidual.
z() << endl;
332 if (verboseLevel>101){
333 char filename [1000];
334 sprintf(filename,
"po-%02d-%03d-%03d-.dat", iteration, v1->id, v2->id);
335 recomputeAllTransformations();
336 saveGnuplot(filename);
339 onIterationFinished(iteration);
Vector3< T > axis() const
TreeOptimizer3::Vertex * n
double max3(const double &a, const double &b, const double &c)
NodeInfo(TreeOptimizer3::Vertex *v=0, double tw=0, double rw=0, int dir=0, TreeOptimizer3::Transformation t=TreeOptimizer3::Transformation(0, 0, 0, 0, 0, 0), TreeOptimizer3::Parameters p=TreeOptimizer3::Transformation(0, 0, 0, 0, 0, 0))
GLM_FUNC_DECL vecType< T, P > sqrt(vecType< T, P > const &x)
GLM_FUNC_DECL detail::tvec3< T, P > axis(detail::tquat< T, P > const &x)
GLM_FUNC_DECL genType e()
TreeOptimizer3::Transformation parameters
TreeOptimizer3::Transformation transformation
GLM_FUNC_DECL T angle(detail::tquat< T, P > const &x)
Defines the core optimizer class for 3D graphs which is a subclass of TreePoseGraph3.
Quaternion< T > inverse() const
std::vector< NodeInfo > NodeInfoVector
GLM_FUNC_DECL genType max(genType const &x, genType const &y)
double translationalWeight
GLM_FUNC_DECL genType zero()
double min3(const double &a, const double &b, const double &c)