only use scale value for rotation-only solving, not the transformed clusters. This gives the more expected results

This commit is contained in:
Stefan Tröger 2013-12-22 12:11:01 +01:00
parent 66f9afbef3
commit 0a750b1bc5
3 changed files with 45 additions and 30 deletions

View File

@ -21,6 +21,7 @@
#define DCM_KERNEL_IMP_H #define DCM_KERNEL_IMP_H
#include "../kernel.hpp" #include "../kernel.hpp"
#include <Base/Console.h>
#include <boost/math/special_functions.hpp> #include <boost/math/special_functions.hpp>
#include <Eigen/QR> #include <Eigen/QR>
@ -62,8 +63,6 @@ void Dogleg<Kernel>::calculateStep(const Eigen::MatrixBase<Derived>& g, const Ei
const typename Kernel::Vector h_gn = jacobi.fullPivLu().solve(-residual); const typename Kernel::Vector h_gn = jacobi.fullPivLu().solve(-residual);
const double eigen_error = (jacobi*h_gn + residual).norm(); const double eigen_error = (jacobi*h_gn + residual).norm();
#ifdef USE_LOGGING #ifdef USE_LOGGING
BOOST_LOG(log)<< "Gauss Newton error: "<<eigen_error;
if(!boost::math::isfinite(h_gn.norm())) { if(!boost::math::isfinite(h_gn.norm())) {
BOOST_LOG(log)<< "Unnormal gauss-newton detected: "<<h_gn.norm(); BOOST_LOG(log)<< "Unnormal gauss-newton detected: "<<h_gn.norm();
} }
@ -81,9 +80,6 @@ void Dogleg<Kernel>::calculateStep(const Eigen::MatrixBase<Derived>& g, const Ei
// compute the dogleg step // compute the dogleg step
if(h_gn.norm() <= delta) { if(h_gn.norm() <= delta) {
h_dl = h_gn; h_dl = h_gn;
#ifdef USE_LOGGING
BOOST_LOG(log)<< "Gauss Newton Step: "<<eigen_error;
#endif
} }
else if((alpha*h_sd).norm() >= delta) { else if((alpha*h_sd).norm() >= delta) {
//h_dl = alpha*h_sd; //h_dl = alpha*h_sd;
@ -94,8 +90,6 @@ void Dogleg<Kernel>::calculateStep(const Eigen::MatrixBase<Derived>& g, const Ei
BOOST_LOG(log)<< "Unnormal dogleg descent detected: "<<h_dl.norm(); BOOST_LOG(log)<< "Unnormal dogleg descent detected: "<<h_dl.norm();
} }
BOOST_LOG(log)<< "Steepest Descend step";
#endif #endif
} }
else { else {
@ -131,8 +125,6 @@ void Dogleg<Kernel>::calculateStep(const Eigen::MatrixBase<Derived>& g, const Ei
BOOST_LOG(log)<< "Unnormal dogleg beta detected: "<<beta; BOOST_LOG(log)<< "Unnormal dogleg beta detected: "<<beta;
} }
BOOST_LOG(log)<< "Dogleg Step";
#endif #endif
} }
}; };
@ -436,6 +428,7 @@ void Kernel<Scalar, Nonlinear>::MappedEquationSystem::setAccess(AccessType t) {
new(&Parameter) VectorMap(&m_parameter(m_param_trans_offset),num,DynStride(1,1)); new(&Parameter) VectorMap(&m_parameter(m_param_trans_offset),num,DynStride(1,1));
new(&Residual) VectorMap(&m_residual(m_eqn_trans_offset), eq_num, DynStride(1,1)); new(&Residual) VectorMap(&m_residual(m_eqn_trans_offset), eq_num, DynStride(1,1));
} }
m_access = t; m_access = t;
}; };
@ -443,11 +436,11 @@ template<typename Scalar, template<class> class Nonlinear>
bool Kernel<Scalar, Nonlinear>::MappedEquationSystem::hasAccessType(AccessType t) { bool Kernel<Scalar, Nonlinear>::MappedEquationSystem::hasAccessType(AccessType t) {
if(t==rotation) if(t==rotation)
return (m_param_rot_offset>0); return (m_param_rot_offset>0 && m_eqn_rot_offset>0);
else if(t==general) else if(t==general)
return (m_param_trans_offset<m_params); return (m_param_trans_offset<m_params && m_eqn_trans_offset<m_eqns);
else else
return (m_params>0); return (m_params>0 && m_eqns>0);
}; };
template<typename Scalar, template<class> class Nonlinear> template<typename Scalar, template<class> class Nonlinear>

View File

@ -107,12 +107,12 @@ SystemSolver<Sys>::Rescaler::Rescaler(boost::shared_ptr<Cluster> c, Mes& m) : cl
template<typename Sys> template<typename Sys>
void SystemSolver<Sys>::Rescaler::operator()() { void SystemSolver<Sys>::Rescaler::operator()() {
mes.Scaling = scaleClusters(); mes.Scaling = scaleClusters(calculateScale());
rescales++; rescales++;
}; };
template<typename Sys> template<typename Sys>
typename SystemSolver<Sys>::Scalar SystemSolver<Sys>::Rescaler::scaleClusters() { typename SystemSolver<Sys>::Scalar SystemSolver<Sys>::Rescaler::calculateScale() {
typedef typename Cluster::cluster_iterator citer; typedef typename Cluster::cluster_iterator citer;
std::pair<citer, citer> cit = cluster->clusters(); std::pair<citer, citer> cit = cluster->clusters();
@ -134,6 +134,12 @@ typename SystemSolver<Sys>::Scalar SystemSolver<Sys>::Rescaler::scaleClusters()
sc = (s>sc) ? s : sc; sc = (s>sc) ? s : sc;
} }
return sc;
}
template<typename Sys>
typename SystemSolver<Sys>::Scalar SystemSolver<Sys>::Rescaler::scaleClusters(Scalar sc) {
//if no scaling-value returned we can use 1 //if no scaling-value returned we can use 1
sc = (Kernel::isSame(sc,0, 1e-10)) ? 1. : sc; sc = (Kernel::isSame(sc,0, 1e-10)) ? 1. : sc;
@ -362,15 +368,28 @@ void SystemSolver<Sys>::solveCluster(boost::shared_ptr<Cluster> cluster, Sys& sy
//cool, lets do uncylic. first all rotational constraints with rotational parameters //cool, lets do uncylic. first all rotational constraints with rotational parameters
mes.setAccess(rotation); mes.setAccess(rotation);
//solve can be done without catching exceptions, because this only fails if the system is //rotations need to be calculated in a scaled manner. thats because the normales used for
//unsolvable. We need the rescaler here two as unscaled rotations may be unprecise if the //rotation calculation are always 1, no matter how big the part is. This can lead to problems
//parts are big (as ne the normals are always 1) and then distances may not be possible //when for example two rotated faces have a precision error on the parallel normals but a distance
//to solve correctly with only translations //at the outer edges is far bigger than the precision as the distance from normal origin to outer edge
//is bigger 1. that would lead to unsolvable translation-only systems.
//solve need to catch exceptions to reset the mes scaling on failure
Rescaler re(cluster, mes); Rescaler re(cluster, mes);
re(); mes.Scaling = 1./(re.calculateScale()*SKALEFAKTOR);
try {
sys.kernel().solve(mes, re); sys.kernel().solve(mes, re);
mes.Scaling = 1.;
}
catch(...) {
mes.Scaling = 1.;
throw;
}
//now let's see if we have to go on with the translations //now let's see if we have to go on with the translations
if(mes.hasAccessType(general)) {
mes.setAccess(general); mes.setAccess(general);
mes.recalculate(); mes.recalculate();
@ -392,6 +411,8 @@ void SystemSolver<Sys>::solveCluster(boost::shared_ptr<Cluster> cluster, Sys& sy
done = false; done = false;
} }
} }
};
//}; //};
//not done already? try it the hard way! //not done already? try it the hard way!

View File

@ -84,7 +84,8 @@ struct SystemSolver : public Job<Sys> {
void operator()(); void operator()();
Scalar scaleClusters(); Scalar calculateScale();
Scalar scaleClusters(Scalar sc);
void collectPseudoPoints(boost::shared_ptr<Cluster> parent, void collectPseudoPoints(boost::shared_ptr<Cluster> parent,
LocalVertex cluster, LocalVertex cluster,
std::vector<typename Kernel::Vector3, std::vector<typename Kernel::Vector3,