diff --git a/src/ceres_wrapper/ceres_manager.cpp b/src/ceres_wrapper/ceres_manager.cpp
index f996584d4963da450daf0dda49ad89721824de7e..8d6f178c40197778c3aecc4bf02d07ddd61dd05f 100644
--- a/src/ceres_wrapper/ceres_manager.cpp
+++ b/src/ceres_wrapper/ceres_manager.cpp
@@ -257,7 +257,7 @@ void CeresManager::update()
         {
             case ADD:
             {
-                //std::cout << "adding constraint" << std::endl;
+                std::cout << "adding constraint" << std::endl;
                 addConstraint(wolf_problem_->getConstraintNotificationList().front().constraint_ptr_,wolf_problem_->getConstraintNotificationList().front().id_);
                 //std::cout << "added" << std::endl;
                 break;
@@ -268,9 +268,9 @@ void CeresManager::update()
         wolf_problem_->getConstraintNotificationList().pop_front();
     }
     //std::cout << "all constraints added" << std::endl;
-	//std::cout << "ceres residual blocks:   " << ceres_problem_->NumResidualBlocks() << std::endl;
-    //std::cout << "wrapper residual blocks: " << id_2_residual_idx_.size() << std::endl;
-    //std::cout << "parameter blocks: " << ceres_problem_->NumParameterBlocks() << std::endl;
+	std::cout << "ceres residual blocks:   " << ceres_problem_->NumResidualBlocks() << std::endl;
+    std::cout << "wrapper residual blocks: " << id_2_residual_idx_.size() << std::endl;
+    std::cout << "parameter blocks: " << ceres_problem_->NumParameterBlocks() << std::endl;
 
 	assert(ceres_problem_->NumResidualBlocks() == id_2_residual_idx_.size() && "ceres residuals different from wrapper residuals");
 }
@@ -300,18 +300,18 @@ void CeresManager::removeConstraint(const unsigned int& _corr_id)
 
 void CeresManager::addStateBlock(StateBlockPtr _st_ptr)
 {
-//    std::cout << "Adding State Block " << _st_ptr->getPtr() << std::endl;
-//    std::cout << " size: " <<  _st_ptr->getSize() << std::endl;
-//    std::cout << " vector: " <<  _st_ptr->getVector().transpose() << std::endl;
+    std::cout << "Adding State Block " << _st_ptr->getPtr() << std::endl;
+    std::cout << " size: " <<  _st_ptr->getSize() << std::endl;
+    std::cout << " vector: " <<  _st_ptr->getVector().transpose() << std::endl;
 
     if (_st_ptr->hasLocalParametrization())
     {
-        //std::cout << "Local Parametrization to be added:" << _st_ptr->getLocalParametrizationPtr() << std::endl;
+        std::cout << "Local Parametrization to be added:" << _st_ptr->getLocalParametrizationPtr() << std::endl;
         ceres_problem_->AddParameterBlock(_st_ptr->getPtr(), _st_ptr->getSize(), new LocalParametrizationWrapper(_st_ptr->getLocalParametrizationPtr()));
     }
     else
     {
-        //std::cout << "No Local Parametrization to be added" << std::endl;
+        std::cout << "No Local Parametrization to be added" << std::endl;
         ceres_problem_->AddParameterBlock(_st_ptr->getPtr(), _st_ptr->getSize(), nullptr);
     }
     if (_st_ptr->isFixed())
diff --git a/src/constraint_AHP.h b/src/constraint_AHP.h
index f74eaf2e9a413a9c43baf13843de6af6319ea569..5b27da72e10d2ea3fbd9ebedb8f92f42297146c5 100644
--- a/src/constraint_AHP.h
+++ b/src/constraint_AHP.h
@@ -28,7 +28,7 @@ class ConstraintAHP : public ConstraintSparse<2, 3, 4, 3, 4, 4>
 
     public:
 
-        ConstraintAHP(FeatureBasePtr _ftr_ptr, FrameBasePtr _current_frame_ptr, std::shared_ptr<LandmarkAHP> _landmark_ptr,
+        ConstraintAHP(FeatureBasePtr _ftr_ptr, FrameBasePtr _current_frame_ptr, LandmarkAHP::Ptr _landmark_ptr,
                         bool _apply_loss_function = false, ConstraintStatus _status = CTR_ACTIVE) :
                 ConstraintSparse<2, 3, 4, 3, 4, 4>(CTR_AHP, _landmark_ptr, _apply_loss_function, _status,
                                              _current_frame_ptr->getPPtr(), _current_frame_ptr->getOPtr(), _landmark_ptr->getAnchorFrame()->getPPtr()
@@ -39,6 +39,8 @@ class ConstraintAHP : public ConstraintSparse<2, 3, 4, 3, 4, 4>
         {
             setType("AHP");
 
+            frame_other_ptr_ = _landmark_ptr->getAnchorFrame();
+
             K_ = (std::static_pointer_cast<SensorCamera>(_ftr_ptr->getCapturePtr()->getSensorPtr()))->getIntrinsicMatrix();
             distortion_ = (std::static_pointer_cast<SensorCamera>(_ftr_ptr->getCapturePtr()->getSensorPtr()))->getDistortionVector();
         }
@@ -52,6 +54,7 @@ class ConstraintAHP : public ConstraintSparse<2, 3, 4, 3, 4, 4>
         void expectation(const T* const _current_frame_p, const T* const _current_frame_o, const T* const _anchor_frame_p,
                                     const T* const _anchor_frame_o, const T* const _lmk_hmg, T* _expectation) const
         {
+            // Maps over the input pointers
             Eigen::Matrix<T, 3, 3> K = K_.cast<T>();
             Eigen::Map<const Eigen::Matrix<T, 4, 1> > landmark_hmg_c0(_lmk_hmg);
 
@@ -80,72 +83,77 @@ class ConstraintAHP : public ConstraintSparse<2, 3, 4, 3, 4, 4>
             T_R0_C0 = trc * qrc;
             T_R1_C1 = T_R0_C0;
 
+            // hmg point in C1 frame (current frame)
             Eigen::Matrix<T,4,1> landmark_hmg_c1;
             landmark_hmg_c1 = T_R1_C1.inverse(Eigen::Affine) * T_W_R1.inverse(Eigen::Affine) * T_W_R0 * T_R0_C0 * landmark_hmg_c0;
-//            std::cout << "\nlandmark_hmg_c1:\n" << landmark_hmg_c1(0) << "\t" << landmark_hmg_c1(1) << "\t" << landmark_hmg_c1(2) << "\t" << landmark_hmg_c1(3) << std::endl;
+            //            std::cout << "\nlandmark_hmg_c1:\n" << landmark_hmg_c1(0) << "\t" << landmark_hmg_c1(1) << "\t" << landmark_hmg_c1(2) << "\t" << landmark_hmg_c1(3) << std::endl;
 
 
-            Eigen::Matrix<T,3,1> v_normalized;
-            v_normalized = landmark_hmg_c1.head(3);// /landmark_hmg_c1(3);
-//            T inverse_dist_c1 = landmark_hmg_c1(3); // inverse distance
+            // lmk direction vector
+            Eigen::Matrix<T,3,1> v_dir = landmark_hmg_c1.head(3);
 
-//            std::cout << "\nv_normalized:\n" << v_normalized(0) << "\t" << v_normalized(1) << "\t"
-//                      << v_normalized(2) << "\t" << landmark_hmg_c1(3) << std::endl;
+//            std::cout << "\nv_normalized:\n" << v_dir(0) << "\t" << v_dir(1) << "\t"
+//                      << v_dir(2) << "\t" << landmark_hmg_c1(3) << std::endl;
 
-            Eigen::Matrix<T,2,1> v;
-            v = v_normalized.head(2)/v_normalized(2);
-//            std::cout << "\nv:\n" << v(0) << "\t" << v(1) << std::endl;
+            // projected point in canonical sensor
+            Eigen::Matrix<T,2,1> point_undistorted;
+            point_undistorted = v_dir.head(2)/v_dir(2);
+            //            std::cout << "\nv:\n" << point_undistorted(0) << "\t" << point_undistorted(1) << std::endl;
 
-            Eigen::Matrix<T,2,1> distored_point;
             Eigen::Matrix<T,Eigen::Dynamic,1> distortion_vector = distortion_.cast<T>();
-//            std::cout << "\ndistortion_vector:\n" << distortion_vector(0) << "\t" << distortion_vector(1) << std::endl;
-
-            Eigen::Matrix<T,2,1> distored_point_pinhole;
-            distored_point_pinhole = pinhole::distortPoint(distortion_vector, v);
-
-//            T r2 = v.squaredNorm(); // this is the norm squared: r2 = ||u||^2
-//
-//            T s = (T)1.0;
-//            T r2i = (T)1.0;
-//            for (int i = 0; i < distortion_vector.size() ; i++) { //   here we are doing:
-//                r2i = r2i * r2;                                   //   r2i = r^(2*(i+1))
-//                s = s + (distortion_vector(i) * r2i);             //   s = 1 + d_0 * r^2 + d_1 * r^4 + d_2 * r^6 + ...
-//            }
-//            if (s < (T)0.6) s = (T)1.0;
-//            distored_point(0) = s * v(0);
-//            distored_point(1) = s * v(1);
-//            std::cout << "\ndistored_point:\n" << distored_point(0) << "\t" << distored_point(1) << std::endl;
-//            std::cout << "\ndistored_point_pinhole:\n" << distored_point_pinhole(0) << "\t" << distored_point_pinhole(1) << std::endl;
-
-//            std::cout << "K: " << K << std::endl;
+            //            std::cout << "\ndistortion_vector:\n" << distortion_vector(0) << "\t" << distortion_vector(1) << std::endl;
+
+            // distort point
+            Eigen::Matrix<T,2,1> point_distorted = pinhole::distortPoint(distortion_vector, point_undistorted);
 
+            // pixellize
             Eigen::Map<Eigen::Matrix<T, 2, 1> > expectation(_expectation);
-            expectation(0) = K(0,0)*distored_point_pinhole(0)+K(0,2);
-            expectation(1) = K(1,1)*distored_point_pinhole(1)+K(1,2);
+            expectation(0) = K(0,0) * point_distorted(0) + K(0,2);
+            expectation(1) = K(1,1) * point_distorted(1) + K(1,2);
 
-//            std::cout << "constraint n[" << id() << "] _expectation: " << _expectation(0) << "\t" << _expectation(1) << std::endl;
+            //            std::cout << "constraint n[" << id() << "] _expectation: " << _expectation(0) << "\t" << _expectation(1) << std::endl;
 
-//            return u;
+        }
+
+        Eigen::VectorXs expectation() const
+        {
+            Eigen::VectorXs exp(2);
+            FrameBasePtr frm_current    = getFeaturePtr()->getCapturePtr()->getFramePtr();
+            FrameBasePtr frm_anchor     = getFrameOtherPtr();
+            LandmarkBasePtr lmk         = getLandmarkOtherPtr();
+            const Scalar * const frame_current_pos  = frm_current->getPPtr()->getVector().data();
+            const Scalar * const frame_current_ori  = frm_current->getOPtr()->getVector().data();
+            const Scalar * const frame_anchor_pos   = frm_anchor->getPPtr()->getVector().data();
+            const Scalar * const frame_anchor_ori   = frm_anchor->getOPtr()->getVector().data();
+            const Scalar * const lmk_pos_hmg        = lmk->getPPtr()->getVector().data();
+            expectation(frame_current_pos,
+                        frame_current_ori,
+                        frame_anchor_pos,
+                        frame_anchor_ori,
+                        lmk_pos_hmg,
+                        exp.data());
+            return exp;
         }
 
         template<typename T>
         bool operator ()(const T* const _current_frame_p, const T* const _current_frame_o, const T* const _anchor_frame_p,
                          const T* const _anchor_frame_o, const T* const _lmk_hmg, T* _residuals) const
         {
-
-            Eigen::Matrix<T, Eigen::Dynamic, 1> u(2) ;
+//            std::cout << "operator: " << id() << std::endl;
+            Eigen::Matrix<T, Eigen::Dynamic, 1> expected(2) ;
             expectation(_current_frame_p, _current_frame_o,  _anchor_frame_p,
-                          _anchor_frame_o,  _lmk_hmg, u.data()) ;
-            // ==================================================
+                          _anchor_frame_o,  _lmk_hmg, expected.data()) ;
+
+            Eigen::Matrix<T, 2, 1> measured = getMeasurement().cast<T>();
 
-            //    std::cout << "\nCONSTRAINT INFO" << std::endl;
+            Eigen::Map<Eigen::Matrix<T, 2, 1> > residuals(_residuals);
 
-            Eigen::Matrix<T, 2, 1> feature_pos = getMeasurement().cast<T>();
+            residuals = getMeasurementSquareRootInformation().cast<T>() * (expected - measured);
 
-            Eigen::Map<Eigen::Matrix<T, 2, 1> > residualsmap(_residuals);
-//            std::cout << "SquareRootInformation: " << getMeasurementSquareRootInformation() << std::endl;
-            residualsmap = getMeasurementSquareRootInformation().cast<T>() * (u - feature_pos);
-//            std::cout << "\nRESIDUALS:\n" << residualsmap[0] << "\t" << residualsmap[1] << std::endl;
+            // debug info:
+            Eigen::Map<const Eigen::Matrix< T, 4, 1> > landmark(_lmk_hmg);
+//            std::cout << "\nLANDMARK  L" <<  getLandmarkOtherPtr()->id() << ":\n\t" << landmark[0] << "\n\t" << landmark[1] << "\n\t" << landmark[2] << "\n\t" << landmark[3] << std::endl;
+//            std::cout << "\nRESIDUALS c" <<  id() << ":\n\t" << residuals[0] << "\n\t" << residuals[1] << std::endl;
 
             return true;
         }
@@ -157,6 +165,19 @@ class ConstraintAHP : public ConstraintSparse<2, 3, 4, 3, 4, 4>
             return JAC_AUTO;
         }
 
+        static ConstraintAHP::Ptr create(FeatureBasePtr _ftr_ptr, FrameBasePtr _frm_current_ptr, LandmarkAHP::Ptr _lmk_ahp_ptr)
+        {
+            // construct constraint
+            Ptr ctr_ahp = std::make_shared<ConstraintAHP>(_ftr_ptr, _frm_current_ptr, _lmk_ahp_ptr);
+
+            // link it to wolf tree
+//            _ftr_ptr->addConstraint(ctr_ahp);
+            ctr_ahp->setFrameOtherPtr(_lmk_ahp_ptr->getAnchorFrame());
+            _lmk_ahp_ptr->getAnchorFrame()->addConstrainedBy(ctr_ahp);
+            _lmk_ahp_ptr->addConstrainedBy(ctr_ahp);
+            return  ctr_ahp;
+        }
+
 
 };
 
diff --git a/src/constraint_base.cpp b/src/constraint_base.cpp
index 04cc5475b5cd64ef68d5135bcfad500f584fc0eb..cf0cf4862229000de839ce108a0e18d6c95eddfb 100644
--- a/src/constraint_base.cpp
+++ b/src/constraint_base.cpp
@@ -133,7 +133,7 @@ void ConstraintBase::remove()
             default:
                 break;
         }
-        std::cout << "Removed          c" << id() << std::endl;
+        std::cout << "Removed             c" << id() << std::endl;
     }
 }
 
diff --git a/src/constraint_base.h b/src/constraint_base.h
index ea6992127479804d5dd7278cb805b48d3d5836f5..e01a3c6879ebdb7e39c84dee531085532b66174a 100644
--- a/src/constraint_base.h
+++ b/src/constraint_base.h
@@ -119,17 +119,17 @@ class ConstraintBase : public NodeBase, public std::enable_shared_from_this<Cons
 
         /** \brief Returns a pointer to the frame constrained to
          **/
-        FrameBasePtr getFrameOtherPtr();
+        FrameBasePtr getFrameOtherPtr() const;
         void setFrameOtherPtr(FrameBasePtr _frm_o){frame_other_ptr_ = _frm_o;}
 
         /** \brief Returns a pointer to the feature constrained to
          **/
-        FeatureBasePtr getFeatureOtherPtr();
+        FeatureBasePtr getFeatureOtherPtr() const;
         void setFeatureOtherPtr(FeatureBasePtr _ftr_o){feature_other_ptr_ = _ftr_o;}
 
         /** \brief Returns a pointer to the landmark constrained to
          **/
-        LandmarkBasePtr getLandmarkOtherPtr();
+        LandmarkBasePtr getLandmarkOtherPtr() const;
         void setLandmarkOtherPtr(LandmarkBasePtr _lmk_o){landmark_other_ptr_ = _lmk_o;}
 
         ProblemPtr getProblem();
@@ -209,17 +209,17 @@ inline void ConstraintBase::setApplyLossFunction(const bool _apply)
     }
 }
 
-inline FrameBasePtr ConstraintBase::getFrameOtherPtr()
+inline FrameBasePtr ConstraintBase::getFrameOtherPtr() const
 {
     return frame_other_ptr_.lock();
 }
 
-inline FeatureBasePtr ConstraintBase::getFeatureOtherPtr()
+inline FeatureBasePtr ConstraintBase::getFeatureOtherPtr() const
 {
     return feature_other_ptr_.lock();
 }
 
-inline LandmarkBasePtr ConstraintBase::getLandmarkOtherPtr()
+inline LandmarkBasePtr ConstraintBase::getLandmarkOtherPtr() const
 {
     return landmark_other_ptr_.lock();
 }
diff --git a/src/constraint_odom_3D.h b/src/constraint_odom_3D.h
index 7c07105da7bbbe56c43dc9ee7d7ad0c66757cb63..7dd7ea6e37d43f99302565b8f38f406c92539ad6 100644
--- a/src/constraint_odom_3D.h
+++ b/src/constraint_odom_3D.h
@@ -31,6 +31,16 @@ class ConstraintOdom3D : public ConstraintSparse<6,3,4,3,4>
                                  const T* const _q2,
                                  T* _residuals) const;
 
+        template<typename T>
+                bool expectation(const T* const _p1,
+                                 const T* const _q1,
+                                 const T* const _p2,
+                                 const T* const _q2,
+                                 T* _expectation_dp,
+                                 T* _expectation_dq) const;
+
+        Eigen::VectorXs expectation() const;
+
     private:
         template<typename T>
         void printRes(const Eigen::Matrix<T, 6, 1>& r) const;
@@ -75,6 +85,54 @@ inline ConstraintOdom3D::~ConstraintOdom3D()
     //
 }
 
+template<typename T>
+inline bool wolf::ConstraintOdom3D::expectation(const T* const _p1, const T* const _q1, const T* const _p2,
+                                                const T* const _q2, T* _expectation_dp, T* _expectation_dq) const
+{
+    Eigen::Map<const Eigen::Matrix<T,3,1> > p1(_p1);
+    Eigen::Map<const Eigen::Quaternion<T> > q1(_q1);
+//    Eigen::Map<const Eigen::Matrix<T,4,1> > q1_v(_q1);
+    Eigen::Map<const Eigen::Matrix<T,3,1> > p2(_p2);
+    Eigen::Map<const Eigen::Quaternion<T> > q2(_q2);
+//    Eigen::Map<const Eigen::Matrix<T,4,1> > q2_v(_q2);
+    Eigen::Map<Eigen::Matrix<T,3,1> > expectation_dp(_expectation_dp);
+//    Eigen::Map<Eigen::Matrix<T,4,1> > expectation_dq_v(_expectation_dq);
+    Eigen::Map<Eigen::Quaternion<T> > expectation_dq(_expectation_dq);
+
+
+    // std::cout << "p1: " << p1(0) << std::endl << p1(1) << std::endl << p1(2) << std::endl;
+    // std::cout << "q1: " << q1_v(0) << std::endl << q1_v(1) << std::endl << q1_v(2) << std::endl << q1_v(3) << std::endl;
+    // std::cout << "p2: " << p2(0) << std::endl << p2(1) << std::endl << p2(2) << std::endl;
+    // std::cout << "q2: " << q2_v(0) << std::endl << q2_v(1) << std::endl << q2_v(2) << std::endl << q2_v(3) << std::endl;
+
+    // estimate motion increment, dp, dq;
+    expectation_dp = q1.conjugate() * (p2 - p1);
+    expectation_dq =  q1.conjugate() * q2;
+
+    std::cout << "exp_p: " << expectation_dp(0) << std::endl << expectation_dp(1) << std::endl << expectation_dp(2) << std::endl;
+//    std::cout << "exp_q: " << expectation(3) << std::endl << expectation(4) << std::endl << expectation(5) << std::endl << expectation(6) << std::endl;
+
+    return true;
+}
+
+inline Eigen::VectorXs wolf::ConstraintOdom3D::expectation() const
+{
+    Eigen::VectorXs exp(7);
+    FrameBasePtr frm_current = getFeaturePtr()->getFramePtr();
+    FrameBasePtr frm_origin = getFrameOtherPtr();
+    const Scalar * const frame_current_pos  = frm_current->getPPtr()->getVector().data();
+    const Scalar * const frame_current_ori  = frm_current->getOPtr()->getVector().data();
+    const Scalar * const frame_origin_pos   = frm_origin->getPPtr()->getVector().data();
+    const Scalar * const frame_origin_ori   = frm_origin->getOPtr()->getVector().data();
+    expectation(frame_current_pos,
+                frame_current_ori,
+                frame_origin_pos,
+                frame_origin_ori,
+                exp.data(),
+                exp.data()+3);
+    return exp;
+}
+
 template<typename T>
 inline bool wolf::ConstraintOdom3D::operator ()(const T* const _p1, const T* const _q1, const T* const _p2,
                                                 const T* const _q2, T* _residuals) const
@@ -112,22 +170,27 @@ inline bool wolf::ConstraintOdom3D::operator ()(const T* const _p1, const T* con
      */
 
     // MAPS
-    Eigen::Map<const Eigen::Matrix<T,3,1> > p1(_p1);
-    Eigen::Map<const Eigen::Quaternion<T> > q1(_q1);
-    Eigen::Map<const Eigen::Matrix<T,4,1> > q1_v(_q1);
-    Eigen::Map<const Eigen::Matrix<T,3,1> > p2(_p2);
-    Eigen::Map<const Eigen::Quaternion<T> > q2(_q2);
-    Eigen::Map<const Eigen::Matrix<T,4,1> > q2_v(_q2);
+//    Eigen::Map<const Eigen::Matrix<T,3,1> > p1(_p1);
+//    Eigen::Map<const Eigen::Quaternion<T> > q1(_q1);
+//    Eigen::Map<const Eigen::Matrix<T,4,1> > q1_v(_q1);
+//    Eigen::Map<const Eigen::Matrix<T,3,1> > p2(_p2);
+//    Eigen::Map<const Eigen::Quaternion<T> > q2(_q2);
+//    Eigen::Map<const Eigen::Matrix<T,4,1> > q2_v(_q2);
     Eigen::Map<Eigen::Matrix<T,6,1> > residuals(_residuals);
+//
+//    // std::cout << "p1: " << p1(0) << std::endl << p1(1) << std::endl << p1(2) << std::endl;
+//    // std::cout << "q1: " << q1_v(0) << std::endl << q1_v(1) << std::endl << q1_v(2) << std::endl << q1_v(3) << std::endl;
+//    // std::cout << "p2: " << p2(0) << std::endl << p2(1) << std::endl << p2(2) << std::endl;
+//    // std::cout << "q2: " << q2_v(0) << std::endl << q2_v(1) << std::endl << q2_v(2) << std::endl << q2_v(3) << std::endl;
+//
+//    // estimate motion increment, dp, dq;
+//    Eigen::Matrix<T,3,1> dp = q1.conjugate() * (p2 - p1);
+//    Eigen::Quaternion<T> dq = q1.conjugate() * q2;
+
+    Eigen::Matrix<T, Eigen::Dynamic, 1> expected(7) ;
+    expectation(_p1, _q1, _p2, _q2, expected.data(), expected.data()+3);
 
-    // std::cout << "p1: " << p1(0) << std::endl << p1(1) << std::endl << p1(2) << std::endl;
-    // std::cout << "q1: " << q1_v(0) << std::endl << q1_v(1) << std::endl << q1_v(2) << std::endl << q1_v(3) << std::endl;
-    // std::cout << "p2: " << p2(0) << std::endl << p2(1) << std::endl << p2(2) << std::endl;
-    // std::cout << "q2: " << q2_v(0) << std::endl << q2_v(1) << std::endl << q2_v(2) << std::endl << q2_v(3) << std::endl;
 
-    // estimate motion increment, dp, dq;
-    Eigen::Matrix<T,3,1> dp = q1.conjugate() * (p2 - p1);
-    Eigen::Quaternion<T> dq = q1.conjugate() * q2;
     // std::cout << "dp: " << dp(0) << std::endl << dp(1) << std::endl<< dp(2) << std::endl;
     // std::cout << "dq: " << dq.x() << std::endl << dq.y() << std::endl << dq.z() << std::endl << dq.w() << std::endl;
 
@@ -140,6 +203,19 @@ inline bool wolf::ConstraintOdom3D::operator ()(const T* const _p1, const T* con
 
     // residual
     // residuals.head<3>() = dq.conjugate() * (dp_m - dp); // see note below
+//    residuals.head(3) = dp_m - dp; // being a residual, rotating it has no implications, so we skip the product by dq.conj
+//    residuals.tail(3) = q2v(dq.conjugate() * dq_m);
+
+    Eigen::Matrix<T,3,1> dp = expected.head(3);
+    Eigen::Quaternion<T> dq;// = expected.tail(4);
+    dq.x() = expected(3);
+    dq.y() = expected(4);
+    dq.z() = expected(5);
+    dq.w() = expected(6);
+
+    std::cout << "operator dp: " << dp(0) << std::endl << dp(1) << std::endl << dp(2) << std::endl;
+    std::cout << "operator dq: " << dq.x() << std::endl << dq.y() << std::endl << dq.z() << std::endl << dq.w() << std::endl;
+
     residuals.head(3) = dp_m - dp; // being a residual, rotating it has no implications, so we skip the product by dq.conj
     residuals.tail(3) = q2v(dq.conjugate() * dq_m);
 
diff --git a/src/examples/CMakeLists.txt b/src/examples/CMakeLists.txt
index 4804687231cd80de6bbbf188da6fe517c63c9076..9877404f2a42fe199c43af103c365e9e44eca83d 100644
--- a/src/examples/CMakeLists.txt
+++ b/src/examples/CMakeLists.txt
@@ -10,6 +10,9 @@ ADD_EXECUTABLE(test_sh_ptr test_sh_ptr.cpp)
 
 ADD_EXECUTABLE(test_wolf_root test_wolf_root.cpp)
 
+ADD_EXECUTABLE(test_kf_callback test_kf_callback.cpp)
+TARGET_LINK_LIBRARIES(test_kf_callback ${PROJECT_NAME})
+
 ADD_EXECUTABLE(test_wolf_logging test_wolf_logging.cpp)
 TARGET_LINK_LIBRARIES(test_wolf_logging ${PROJECT_NAME})
 
@@ -146,6 +149,10 @@ IF(OpenCV_FOUND)
     TARGET_LINK_LIBRARIES(test_ROI_ORB ${PROJECT_NAME})
 ENDIF(OpenCV_FOUND)
 
+# Simple AHP test
+ADD_EXECUTABLE(test_simple_AHP test_simple_AHP.cpp)
+TARGET_LINK_LIBRARIES(test_simple_AHP ${PROJECT_NAME})
+
 # Processor Tracker Feature test
 ADD_EXECUTABLE(test_processor_tracker_feature test_processor_tracker_feature.cpp)
 TARGET_LINK_LIBRARIES(test_processor_tracker_feature ${PROJECT_NAME})
diff --git a/src/examples/camera_params_ueye_sim.yaml b/src/examples/camera_params_ueye_sim.yaml
index 61016aec6d9fe03e7bfca52029b2e35f6477cfd6..789aa54b2147d279a3303657b6b82dbbfb744177 100644
--- a/src/examples/camera_params_ueye_sim.yaml
+++ b/src/examples/camera_params_ueye_sim.yaml
@@ -4,7 +4,7 @@ camera_name: camera
 camera_matrix:
   rows: 3
   cols: 3
-  data: [392.796383, 0, 350.175772, 0, 392.779002, 255.209917, 0, 0, 1]
+  data: [320, 0, 320, 0, 320, 240, 0, 0, 1]
 distortion_model: plumb_bob
 distortion_coefficients:
   rows: 1
diff --git a/src/examples/odom_3D.yaml b/src/examples/odom_3D.yaml
index c05a9f7b08c6e085d585206d9ccf50f6bb20f11c..6f2ba202f2ea861eea637898f5b340134fa9c352 100644
--- a/src/examples/odom_3D.yaml
+++ b/src/examples/odom_3D.yaml
@@ -1,9 +1,9 @@
 sensor type: "ODOM 3D"              # This must match the KEY used in the SensorFactory. Otherwise it is an error.
 sensor name: "Main odometer"        # This is ignored. The name provided to the SensorFactory prevails
 motion variances: 
-    disp_to_disp:   0.2  # m^2   / m
-    disp_to_rot:    0.2  # rad^2 / m
-    rot_to_rot:     0.1  # rad^2 / rad
-    min_disp_var:   0.1  # m^2
-    min_rot_var:    0.1  # rad^2
+    disp_to_disp:   0.002  # m^2   / m
+    disp_to_rot:    0.002  # rad^2 / m
+    rot_to_rot:     0.001  # rad^2 / rad
+    min_disp_var:   0.001  # m^2
+    min_rot_var:    0.001  # rad^2
     
\ No newline at end of file
diff --git a/src/examples/processor_image_ORB.yaml b/src/examples/processor_image_ORB.yaml
index 178d444c1508a3b968adb0fa52bcbc822718c787..bff6d5394cc544efa7da802d457da44717a4ae94 100644
--- a/src/examples/processor_image_ORB.yaml
+++ b/src/examples/processor_image_ORB.yaml
@@ -25,11 +25,11 @@ active search:
     separation: 5
 
 algorithm:
-    maximum new features: 10
+    maximum new features: 40
     minimum features for new keyframe: 40
     minimum response for new features: 80 #0.0005
     time tolerance: 0.01
-    distance: 10
+    distance: 20
     
 draw: # Used to control drawing options
     primary draw: true
diff --git a/src/examples/test_constraint_AHP.cpp b/src/examples/test_constraint_AHP.cpp
index f7a38da43de0a17c6ae927906785f8d77d169d47..40c6130960f6c8a673ce81a7a6db094ea2ce1762 100644
--- a/src/examples/test_constraint_AHP.cpp
+++ b/src/examples/test_constraint_AHP.cpp
@@ -16,8 +16,7 @@ int main()
 
     //=====================================================
     // Environment variable for configuration files
-//    GET_WOLF_ROOT
-    std::string wolf_root("/home/jtarraso/dev/wolf");
+    std::string wolf_root = _WOLF_ROOT_DIR;
     std::cout << wolf_root << std::endl;
     //=====================================================
 
diff --git a/src/examples/test_image.cpp b/src/examples/test_image.cpp
index 58fd4cb882195a55e1d342ff71735d39d87164aa..6072dd720f5e774a6cf2f944a54ac76bc4b7dc64 100644
--- a/src/examples/test_image.cpp
+++ b/src/examples/test_image.cpp
@@ -66,11 +66,7 @@ int main(int argc, char** argv)
 
     TimeStamp t = 1;
 
-    char const* tmp = std::getenv( "WOLF_ROOT" );
-    if ( tmp == nullptr )
-        throw std::runtime_error("WOLF_ROOT environment not loaded.");
-
-    std::string wolf_root( tmp );
+    std::string wolf_root = _WOLF_ROOT_DIR;
     std::cout << "Wolf root: " << wolf_root << std::endl;
 
     ProblemPtr wolf_problem_ = Problem::create(FRM_PO_3D);
diff --git a/src/examples/test_kf_callback.cpp b/src/examples/test_kf_callback.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..73dd8ee480699b55d0aa585e8df214b637f79243
--- /dev/null
+++ b/src/examples/test_kf_callback.cpp
@@ -0,0 +1,68 @@
+/*
+ * test_kf_callback.cpp
+ *
+ *  Created on: Nov 6, 2016
+ *      Author: jsola
+ */
+
+
+
+#include "../sensor_odom_2D.h"
+#include "../processor_odom_2D.h"
+#include "../processor_tracker_feature_dummy.h"
+#include "../capture_void.h"
+
+int main()
+{
+    using namespace wolf;
+    using namespace Eigen;
+    using namespace std;
+
+    ProblemPtr problem = Problem::create(FRM_PO_2D);
+
+    SensorBasePtr sen_odo    = problem->installSensor("ODOM 2D", "main odometer", (Vector3s()<<0,0,0).finished(),"");
+    ProcessorBasePtr prc_odo = problem->installProcessor("ODOM 2D", "odometry integrator", "main odometer", "");
+    prc_odo->setTimeTolerance(0.1);
+
+    SensorBasePtr sen_ftr    = problem->installSensor("ODOM 2D", "other odometer", (Vector3s()<<0,0,0).finished(),"");
+    shared_ptr<ProcessorTrackerFeatureDummy> prc_ftr = make_shared<ProcessorTrackerFeatureDummy>(7, 4);
+    prc_ftr->setName("tracker");
+    sen_ftr->addProcessor(prc_ftr);
+    prc_ftr->setTimeTolerance(0.1);
+
+    cout << "Motion sensor    : " << problem->getProcessorMotionPtr()->getSensorPtr()->getName() << endl;
+    cout << "Motion processor : " << problem->getProcessorMotionPtr()->getName() << endl;
+
+    TimeStamp t(0);
+    Vector3s x; x << 0,0,0;
+//    problem->setOrigin(x, (Matrix3s::Identity()), t);
+    problem->getProcessorMotionPtr()->setOrigin(x, t);
+
+    cout << "x(0) = " << problem->getCurrentState().transpose() << endl;
+
+    Vector2s odo_data;  odo_data << .1, (M_PI / 2);
+
+    problem->print(2, false, true, false); // print(level, constr_by, metric, state_blocks)
+
+    Scalar dt = 1;
+    for (auto i = 0; i < 4; i++)
+    {
+        t += dt;
+        cout << "=======================\n>> TIME: " << t.get() << endl;
+
+        cout << "Tracker----------------" << endl;
+        sen_ftr->addCapture(make_shared<CaptureVoid>(t, sen_ftr));
+        problem->print(2, false, true, false); // print(level, constr_by, metric, state_blocks)
+
+        cout << "Motion-----------------" << endl;
+        sen_odo->addCapture(make_shared<CaptureMotion>(t, sen_odo, odo_data));
+        cout << "x(" << t.get() << ") = " << problem->getCurrentState().transpose() << endl;
+        problem->print(2, false, true, false); // print(level, constr_by, metric, state_blocks)
+
+    }
+
+    problem->print();
+
+
+    return 0;
+}
diff --git a/src/examples/test_local_param.cpp b/src/examples/test_local_param.cpp
index 408ab004112a88b1f7dc0434b4171c9181dea91d..6176ed0de964dc21b251624ce258a8c6edd1099b 100644
--- a/src/examples/test_local_param.cpp
+++ b/src/examples/test_local_param.cpp
@@ -14,10 +14,10 @@
 #include <iostream>
 
 #define JAC_NUMERIC(T, _x0, _J, dx) \
-{    Eigen::VectorXs dv(3); \
-    Eigen::Map<const Eigen::VectorXs> _dv (dv.data(), 3); \
-    Eigen::VectorXs xo(3); \
-    Eigen::Map<Eigen::VectorXs> _xo (xo.data(), 4); \
+{    VectorXs dv(3); \
+    Map<const VectorXs> _dv (dv.data(), 3); \
+    VectorXs xo(3); \
+    Map<VectorXs> _xo (xo.data(), 4); \
     for (int i = 0; i< 3; i++) {\
         dv.setZero();\
         dv(i) = dx;\
@@ -34,6 +34,14 @@ int main(){
     using namespace std;
     using namespace wolf;
 
+    cout << endl << endl;
+    cout << "=========== Test Local Parametrization ==========" << endl;
+    cout << "----   Quaternion and Homogeneous 3D vector  ----" << endl << endl;
+
+    // test result
+    bool all_tests_passed = true;
+    bool pass;
+
     // Storage
     VectorXs x(22);
     MatrixXs M(1,12); // matrix dimensions do not matter, just storage size.
@@ -49,73 +57,93 @@ int main(){
     da /= 10.0;
     Map<VectorXs> qo(&x(7),4);
     Map<MatrixXs> J(&M(0,0),4,3);
+    MatrixXs J_num(4,3);
 
+    cout << "\n--------------- QUATERNION plus() --------------- " << endl;
     cout << "Initial values:" << endl;
     cout << "q  = " << q.transpose() << "   with norm = " << q.norm() << "\nda = " << da.transpose() << endl;
-    cout << "qo = " << qo.transpose() << "   with norm = " << qo.norm() << endl;
 
-    LocalParametrizationQuaternion<DQ_GLOBAL> Qpar;
+    LocalParametrizationQuaternion<DQ_GLOBAL> Qpar_glob;
     LocalParametrizationQuaternion<DQ_LOCAL> Qpar_loc;
-    bool pass;
 
-    cout << "\nGLOBAL D_QUAT plus()" << endl;
+    // Global --------------------
+    cout << "\n----  DQ_GLOBAL: qo = Exp(da) * q  ----" << endl;
+    cout << "Results:" << endl;
     Map<const VectorXs> q_m(q.data(),4);
     Map<const VectorXs> da_m(da.data(),3);
-    Qpar.plus(q_m,da_m,qo);
+    Qpar_glob.plus(q_m,da_m,qo);
     cout << "qo = " << qo.transpose() << "   with norm = " << qo.norm() << endl;
+    pass = (q_m.norm()-qo.norm()) < 1e-9;
+    all_tests_passed = all_tests_passed && pass;
+    cout << "-------------------- Norm test " << (pass ? "PASSED" : "FAILED") << endl;
 
-    Qpar.computeJacobian(q_m,J);
-    cout << " J = \n" << J << endl << endl;
+    Qpar_glob.computeJacobian(q_m,J);
+    cout << " J = \n" << J << endl;
 
-    MatrixXs J_num(4,3);
-    JAC_NUMERIC(Qpar, q_m, J_num, 1e-9)
-    cout << " J_num = \n" << J_num;
+    JAC_NUMERIC(Qpar_glob, q_m, J_num, 1e-9)
+    cout << " J_num = \n" << J_num << endl;
 
     pass = (J-J_num).isMuchSmallerThan(1,1e-6);
-    std::cout << "Jacobians test " << (pass ? "PASSED" : "FAIL") << std::endl;
+    all_tests_passed = all_tests_passed && pass;
+    cout << "-------------------- Jacobians test " << (pass ? "PASSED" : "FAILED") << endl;
 
-    cout << "\nLOCAL D_QUAT plus()" << endl;
+    // Local -------------------------
+    cout << "\n----  DQ_LOCAL: qo = q * Exp(da)  ----" << endl;
+    cout << "Results:" << endl;
     Qpar_loc.plus(q_m,da_m,qo);
     cout << "qo = " << qo.transpose() << "   with norm = " << qo.norm() << endl;
+    pass = (q_m.norm()-qo.norm()) < 1e-9;
+    all_tests_passed = all_tests_passed && pass;
+    cout << "-------------------- Norm test " << (pass ? "PASSED" : "FAILED") << endl;
 
     Qpar_loc.computeJacobian(q_m,J);
-    cout << " J = " << J << endl;
+    cout << " J = \n" << J << endl;
 
     JAC_NUMERIC(Qpar_loc, q_m, J_num, 1e-9)
     cout << " J_num = \n" << J_num << endl;
 
     pass = (J-J_num).isMuchSmallerThan(1,1e-6);
-    std::cout << "Jacobians test " << (pass ? "PASSED" : "FAIL") << std::endl;
+    all_tests_passed = all_tests_passed && pass;
+    cout << "-------------------- Jacobians test " << (pass ? "PASSED" : "FAILED") << endl;
 
 
     // HOMOGENEOUS ----------------------------------------
-    cout << "\nHOMOGENEOUS plus()" << endl;
+    cout << "\n--------------- HOMOGENEOUS plus() --------------- " << endl;
     Map<VectorXs> h(&x(11),4);
     h.setRandom();
     Map<VectorXs> d(&x(15),3);
     d << .1,.2,.3;
-    Map<VectorXs> h_out(&x(18),4);
+    Map<VectorXs> ho(&x(18),4);
 
     cout << "Initial values:" << endl;
     cout << "h  = " << h.transpose() << "   with norm: " << h.norm() << endl;
     cout << "d  = " << d.transpose() << endl;
 
     LocalParametrizationHomogeneous Hpar;
-    Map<const VectorXs> h_const(h.data(),4);
-    Map<const VectorXs> d_const(d.data(),3);
+    Map<const VectorXs> h_m(h.data(),4);
+    Map<const VectorXs> d_m(d.data(),3);
 
-    Hpar.plus(h_const,d_const,h_out);
-    cout << "\nh_out = " << h_out.transpose() << "   with norm: " << h_out.norm() << endl;
+    cout << "\nResults:" << endl;
+    Hpar.plus(h_m,d_m,ho);
+    cout << "ho = " << ho.transpose() << "   with norm: " << ho.norm() << endl;
+    pass = (h_m.norm()-ho.norm()) < 1e-9;
+    all_tests_passed = all_tests_passed && pass;
+    cout << "-------------------- Norm test " << (pass ? "PASSED" : "FAILED") << endl;
 
-    Hpar.computeJacobian(h_const,J);
-    cout << " J = " << J << "\n" << endl;
+    Hpar.computeJacobian(h_m,J);
+    cout << " J = \n" << J << endl;
 
-    JAC_NUMERIC(Hpar, q_m, J_num, 1e-9)
+    JAC_NUMERIC(Hpar, h_m, J_num, 1e-9)
     cout << " J_num = \n" << J_num << endl;
 
     pass = (J-J_num).isMuchSmallerThan(1,1e-6);
-    std::cout << "Jacobians test " << (pass ? "PASSED" : "FAIL") << std::endl;
+    all_tests_passed = all_tests_passed && pass;
+    cout << "-------------------- Jacobians test " << (pass ? "PASSED" : "FAILED") << endl;
 
+    cout << endl << "---------------- " << (all_tests_passed ? "All tests PASSED " : "Some tests FAILED") << " --------------" << endl;
+    cout         << "=================================================" << endl;
 
+    if (!all_tests_passed)
+        return -1;
     return 0;
 }
diff --git a/src/examples/test_map_yaml.cpp b/src/examples/test_map_yaml.cpp
index c76b99e0741c1f8d1d4bb5c16e5e0d3ec3418546..8a899872d03325519f878db820bf7a40ecf62d02 100644
--- a/src/examples/test_map_yaml.cpp
+++ b/src/examples/test_map_yaml.cpp
@@ -71,22 +71,19 @@ int main()
 
     std::string filename;
 
-    char* w = std::getenv("WOLF_ROOT");
-    if (w == NULL)
-        throw std::runtime_error("Environment variable WOLF_ROOT not found");
-    std::string WOLF_ROOT       = w;
-    std::string WOLF_CONFIG     = WOLF_ROOT + "/src/examples";
-    std::cout << "\nWolf directory for configuration files: " << WOLF_CONFIG << std::endl;
+    std::string wolf_root       = _WOLF_ROOT_DIR;
+    std::string wolf_config     = wolf_root + "/src/examples";
+    std::cout << "\nWolf directory for configuration files: " << wolf_config << std::endl;
 
     ProblemPtr problem = Problem::create(FRM_PO_2D);
-    filename = WOLF_CONFIG + "/map_polyline_example.yaml";
+    filename = wolf_config + "/map_polyline_example.yaml";
     std::cout << "Reading map from file: " << filename << std::endl;
     problem->loadMap(filename);
 
     std::cout << "Printing map..." << std::endl;
     print(*(problem->getMapPtr()));
 
-    filename = WOLF_CONFIG + "/map_polyline_example_write.yaml";
+    filename = wolf_config + "/map_polyline_example_write.yaml";
     std::cout << "Writing map to file: " << filename << std::endl;
     std::string thisfile = __FILE__;
     problem->getMapPtr()->save(filename, "Example generated by test file " + thisfile);
diff --git a/src/examples/test_processor_image_landmark.cpp b/src/examples/test_processor_image_landmark.cpp
index 67948941cbe89f56d2519bbd63d5c35244f7f6c7..2d7ce8adb470377da468bf8f033b7ce0310b17b3 100644
--- a/src/examples/test_processor_image_landmark.cpp
+++ b/src/examples/test_processor_image_landmark.cpp
@@ -37,7 +37,7 @@ int main(int argc, char** argv)
     {
 //        filename = "/home/jtarraso/Videos/House_interior.mp4";
 //        filename = "/home/jtarraso/Vídeos/gray1.mp4";
-        filename = "/home/jtarraso/test_video/output2.mpg";
+        filename = "/home/jtarraso/test_video/output6.mpg";
         capture.open(filename);
     }
     else if (std::string(argv[1]) == "0")
@@ -125,7 +125,7 @@ int main(int argc, char** argv)
     // running CAPTURES preallocated
     CaptureImage::Ptr image_ptr;
     Vector6s data(Vector6s::Zero()); // will integrate this data repeatedly
-    CaptureMotion::Ptr cap_odo = std::make_shared<CaptureMotion>(TimeStamp(0), sen_odo_ptr, data);
+    CaptureMotion::Ptr cap_odo = std::make_shared<CaptureMotion>(TimeStamp(t), sen_odo_ptr, data);
     //=====================================================
 
 
@@ -197,13 +197,13 @@ int main(int argc, char** argv)
 
         sen_odo_ptr->addCapture(cap_odo);
 
-//        wolf_problem_ptr_->print(2);
+        wolf_problem_ptr_->print(2);
 
 
 
         // Image ------------------------------------------------
 
-        clock_t t1 = clock();
+//        clock_t t1 = clock();
 
         // Preferred method with factory objects:
         image_ptr = std::make_shared<CaptureImage>(t, camera_ptr, frame[f % buffer_size]);
@@ -212,26 +212,47 @@ int main(int argc, char** argv)
         //image_ptr->process();
         camera_ptr->addCapture(image_ptr);
 
-        std::cout << "Time: " << ((double) clock() - t1) / CLOCKS_PER_SEC << "s" << std::endl;
+//        std::cout << "Time: " << ((double) clock() - t1) / CLOCKS_PER_SEC << "s" << std::endl;
 
         ceres::Solver::Summary summary = ceres_manager.solve();
         std::cout << summary.BriefReport() << std::endl;
 
+        wolf_problem_ptr_->print(2);
+
+//        CaptureMotion::Ptr cap = wolf_problem_ptr_->getProcessorMotionPtr()->getOriginPtr();
+//        if(cap)
+//        {
+//            FeatureBasePtr ftr = cap->getFeatureList().front();
+//            if(ftr)
+//            {
+//                ConstraintBasePtr ctr = ftr->getConstraintList().front();
+//                if(ctr)
+//                {
+//                    ConstraintOdom3D::Ptr ctr_odom = std::static_pointer_cast<ConstraintOdom3D>(ctr);
+//                    if(ctr_odom)
+//                    {
+//                        std::cout << "ctr_odom3D expectation: " << ctr_odom->expectation().transpose() << std::endl;
+//                        std::cout << "odom3D measurement: " << cap->getFeatureList().front()->getMeasurement().transpose() << std::endl;
+//                    }
+//                }
+//            }
+//        }
+
 
 //        std::cout << "Last key frame pose: "
 //                << wolf_problem_ptr_->getLastKeyFramePtr()->getPPtr()->getVector().transpose() << std::endl;
 //        std::cout << "Last key frame orientation: "
 //                << wolf_problem_ptr_->getLastKeyFramePtr()->getOPtr()->getVector().transpose() << std::endl;
 
-        cv::waitKey(20);
+        cv::waitKey(0);
 
-        std::cout << "END OF ITERATION\n=================================" << std::endl;
+        std::cout << "=================================================================================================" << std::endl;
 
         f++;
         capture >> frame[f % buffer_size];
     }
 
-    wolf_problem_ptr_->print();
+    // wolf_problem_ptr_->print(2);
     wolf_problem_ptr_.reset();
 
     return 0;
diff --git a/src/examples/test_processor_odom_3D.cpp b/src/examples/test_processor_odom_3D.cpp
index 6f6d7c9dd4c3dee7d3e062d23e1ce4bdb456baa0..a2fa0d85d52a846004d5f90eff073bfc5b54dc28 100644
--- a/src/examples/test_processor_odom_3D.cpp
+++ b/src/examples/test_processor_odom_3D.cpp
@@ -33,7 +33,6 @@ int main (int argc, char** argv)
 
     std::string wolf_root = _WOLF_ROOT_DIR;
 
-
     TimeStamp tf;
     if (argc == 1)
         tf = 1.0;
diff --git a/src/examples/test_simple_AHP.cpp b/src/examples/test_simple_AHP.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..959319e125c7ab0a31e9cbcdcb7cfca2dcb86820
--- /dev/null
+++ b/src/examples/test_simple_AHP.cpp
@@ -0,0 +1,279 @@
+/**
+ * \file test_simple_AHP.cpp
+ *
+ *  Created on: 2 nov. 2016
+ *      \author: jtarraso
+ */
+
+#include "wolf.h"
+#include "frame_base.h"
+#include "sensor_camera.h"
+#include "pinholeTools.h"
+#include "rotations.h"
+#include "capture_image.h"
+#include "landmark_AHP.h"
+#include "constraint_AHP.h"
+#include "ceres_wrapper/ceres_manager.h"
+
+/**
+ * This test simulates the following situation:
+ *   - A kf at the origin, we use it as anchor: kf1
+ *   - A kf at the origin, we use it to project lmks onto the anchor frame: kf2
+ *   - A kf at 1m to the right of the origin, kf3
+ *   - A kf at 1m to the left of the origin, kf4
+ *   - A lmk at 1m distance in front of the anchor: L1
+ *     - we use this lmk to project it onto kf2, kf3 and kf4 and obtain measured pixels p0, p1 and p2
+ *   - A lmk initialized at kf1, with measurement p0, at a distance of 2m: L2
+ *     - we project the pixels p3 and p4: we observe that they do not match p1 and p2
+ *     - we use the measurements p1 and p2 to solve the optimization problem on L2: L2 should converge to L1.
+ *   - This is a sketch of the situation:
+ *     - X, Y are the axes in world frame
+ *     - x, z are the axes in anchor camera frame. We have that X=z, Y=-x.
+ *     - Axes Z and y are perpendicular to the drawing; they have no effect.
+ *
+ *                X,z
+ *                 ^
+ *                 |
+ *              L2 * 2
+ *                .|.
+ *               . | .
+ *              .  |  .
+ *             .   |   .
+ *            . L1 * 1  .
+ *           .   . | .   .
+ *          .  .   |   .  .
+ *      p4 . .     |     . . p3
+ *        .. p2    |    p1 ..
+ *  Y <--+---------+---------+
+ * -x   +1         0        -1
+ *      kf4      kf1        kf3
+ *               kf2
+ *
+ *      camera: (uo,vo) = (320,240)
+ *              (au,av) = (320,320)
+ *
+ *      projection geometry:
+ *
+ *     1:1  2:1  1:0  2:1  1:1
+ *      0   160  320  480  640
+ *      +----+----+----+----+
+ *                |
+ *                |
+ *                | 320
+ *                |
+ *                *
+ *
+ *
+ *      projected pixels:
+ *      p0 = (320,240) // at optical axis or relation 1:0
+ *      p1 = ( 0 ,240) // at 45 deg or relation 1:1
+ *      p2 = (640,240) // at 45 deg or relation 1:1
+ *      p3 = (160,240) // at a relation 2:1
+ *      p4 = (480,240) // at a relation 2:1
+ *
+ */
+int main(int argc, char** argv)
+{
+    using namespace wolf;
+    using namespace Eigen;
+
+    /* 1. crear 2 kf, fixed
+     * 2. crear 1 sensor
+     * 3. crear 1 lmk1
+     * 4. projectar lmk sobre sensor a fk1
+     * 5. projectar lmk sobre sensor a kf4
+     * 6. // esborrar lmk lmk_ptr->remove() no cal
+     * 7. crear nous kf
+     * 8. crear captures
+     * 9. crear features amb les mesures de 4 i 5
+     * 10. crear lmk2 des de kf3
+     * 11. crear constraint des del kf4 a lmk2, amb ancora al kf3
+     * 12. solve
+     * 13. lmk1 == lmk2 ?
+     */
+
+    // ============================================================================================================
+    /* 1 */
+    ProblemPtr problem = Problem::create(FRM_PO_3D);
+    // One anchor frame to define the lmk, and a copy to make a constraint
+    FrameBasePtr kf_1 = problem->createFrame(KEY_FRAME,(Vector7s()<<0,0,0,0,0,0,1).finished(), TimeStamp(0));
+    FrameBasePtr kf_2 = problem->createFrame(KEY_FRAME,(Vector7s()<<0,0,0,0,0,0,1).finished(), TimeStamp(0));
+    // and two other frames to observe the lmk
+    FrameBasePtr kf_3 = problem->createFrame(KEY_FRAME,(Vector7s()<<0,-1,0,0,0,0,1).finished(), TimeStamp(0));
+    FrameBasePtr kf_4 = problem->createFrame(KEY_FRAME,(Vector7s()<<0,+1,0,0,0,0,1).finished(), TimeStamp(0));
+
+    kf_1->fix();
+    kf_2->fix();
+    kf_3->fix();
+    kf_4->fix();
+    // ============================================================================================================
+
+    // ============================================================================================================
+    /* 2 */
+    std::string wolf_root = _WOLF_ROOT_DIR;
+    SensorBasePtr sensor_ptr = problem->installSensor("CAMERA", "PinHole", (Vector7s()<<0,0,0,-0.5,0.5,-0.5,0.5).finished(), wolf_root + "/src/examples/camera_params_ueye_sim.yaml");
+    SensorCamera::Ptr camera = std::static_pointer_cast<SensorCamera>(sensor_ptr);
+    // ============================================================================================================
+
+    // ============================================================================================================
+    /* 3 */
+    Eigen::Vector3s lmk_dir = {0,0,1}; // in the optical axis of the anchor camera at kf1
+    std::cout << std::endl << "lmk: " << lmk_dir.transpose() << std::endl;
+    lmk_dir.normalize();
+    Eigen::Vector4s lmk_hmg_c;
+    Scalar distance = 1.0; // from anchor at kf1
+    lmk_hmg_c = {lmk_dir(0),lmk_dir(1),lmk_dir(2),(1/distance)};
+//    std::cout << "lmk hmg in C frame: " << lmk_hmg_c.transpose() << std::endl;
+    // ============================================================================================================
+
+
+    // Captures------------------
+    cv::Mat cv_image;
+    cv_image.zeros(2,2,0);
+    CaptureImage::Ptr image_0 = std::make_shared<CaptureImage>(TimeStamp(0), camera, cv_image);
+    CaptureImage::Ptr image_1 = std::make_shared<CaptureImage>(TimeStamp(1), camera, cv_image);
+    CaptureImage::Ptr image_2 = std::make_shared<CaptureImage>(TimeStamp(2), camera, cv_image);
+    kf_2->addCapture(image_0);
+    kf_3->addCapture(image_1);
+    kf_4->addCapture(image_2);
+
+    // Features-----------------
+    cv::Mat desc;
+
+    cv::KeyPoint kp_0;
+    std::shared_ptr<FeaturePointImage> feat_0 = std::make_shared<FeaturePointImage>(kp_0, desc, Eigen::Matrix2s::Identity());
+    image_0->addFeature(feat_0);
+
+    cv::KeyPoint kp_1;
+    std::shared_ptr<FeaturePointImage> feat_1 = std::make_shared<FeaturePointImage>(kp_1, desc, Eigen::Matrix2s::Identity());
+    image_1->addFeature(feat_1);
+
+    cv::KeyPoint kp_2;
+    std::shared_ptr<FeaturePointImage> feat_2 = std::make_shared<FeaturePointImage>(kp_2, desc, Eigen::Matrix2s::Identity());
+    image_2->addFeature(feat_2);
+
+    // Landmark--------------------
+    std::shared_ptr<LandmarkAHP> lmk_1 = std::make_shared<LandmarkAHP>(lmk_hmg_c, kf_1, camera, desc);
+    problem->addLandmark(lmk_1);
+    lmk_1->setStatus(LANDMARK_FIXED);
+    std::cout << "Landmark 1: " << lmk_1->point().transpose() << std::endl;
+
+    // Constraints------------------
+    ConstraintAHP::Ptr ctr_0 = ConstraintAHP::create(feat_0, kf_2, lmk_1 );
+    feat_0->addConstraint(ctr_0);
+    ConstraintAHP::Ptr ctr_1 = ConstraintAHP::create(feat_1, kf_3, lmk_1 );
+    feat_1->addConstraint(ctr_1);
+    ConstraintAHP::Ptr ctr_2 = ConstraintAHP::create(feat_2, kf_4, lmk_1 );
+    feat_2->addConstraint(ctr_2);
+
+    // Projections----------------------------
+    Eigen::VectorXs pix_0 = ctr_0->expectation();
+    kp_0 = cv::KeyPoint(pix_0(0), pix_0(1), 0);
+    feat_0->setKeypoint(kp_0);
+
+    Eigen::VectorXs pix_1 = ctr_1->expectation();
+    kp_1 = cv::KeyPoint(pix_1(0), pix_1(1), 0);
+    feat_1->setKeypoint(kp_1);
+
+    Eigen::VectorXs pix_2 = ctr_2->expectation();
+    kp_2 = cv::KeyPoint(pix_2(0), pix_2(1), 0);
+    feat_2->setKeypoint(kp_2);
+
+    std::cout << "pixel 0: " << pix_0.transpose() << std::endl;
+    std::cout << "pixel 1: " << pix_1.transpose() << std::endl;
+    std::cout << "pixel 2: " << pix_2.transpose() << std::endl;
+    //
+    //======== up to here the initial projections ==============
+
+    std::cout << "\n";
+
+    //======== now we want to estimate a new lmk ===============
+    //
+    // Features -----------------
+    std::shared_ptr<FeaturePointImage> feat_3 = std::make_shared<FeaturePointImage>(kp_1, desc, Eigen::Matrix2s::Identity());
+    image_1->addFeature(feat_3);
+
+    std::shared_ptr<FeaturePointImage> feat_4 = std::make_shared<FeaturePointImage>(kp_2, desc, Eigen::Matrix2s::Identity());
+    image_2->addFeature(feat_4);
+
+
+    // New landmark with measured pixels from kf2 (anchor) kf3 and kf4 (measurements)
+    Scalar unknown_distance = 2; // the real distance is 1
+    Matrix3s K = camera->getIntrinsicMatrix();
+    Vector3s pix_0_hmg;
+    pix_0_hmg << pix_0, 1;
+    Eigen::Vector3s dir_0 = K.inverse() * pix_0_hmg;
+    Eigen::Vector4s pnt_hmg_0;
+    pnt_hmg_0 << dir_0, 1/unknown_distance;
+    LandmarkAHP::Ptr lmk_2( std::make_shared<LandmarkAHP>(pnt_hmg_0, kf_2, camera, desc) );
+    problem->addLandmark(lmk_2);
+    std::cout << "Landmark 2: " << lmk_2->point().transpose() << std::endl;
+
+    // New constraints from kf3 and kf4
+    ConstraintAHP::Ptr ctr_3 = ConstraintAHP::create(feat_3, kf_3, lmk_2 );
+    feat_3->addConstraint(ctr_3);
+    ConstraintAHP::Ptr ctr_4 = ConstraintAHP::create(feat_4, kf_4, lmk_2 );
+    feat_4->addConstraint(ctr_4);
+
+    Eigen::Vector2s pix_3 = ctr_3->expectation();
+    Eigen::Vector2s pix_4 = ctr_4->expectation();
+
+    std::cout << "pix 3: " << pix_3.transpose() << std::endl;
+    std::cout << "pix 4: " << pix_4.transpose() << std::endl;
+
+    // Wolf tree status ----------------------
+    problem->print(3);
+//    problem->check();
+
+
+
+
+
+
+    // ========== solve ==================================================================================================
+    /* 12 */
+    // Ceres wrapper
+    ceres::Solver::Options ceres_options;
+    ceres_options.minimizer_type = ceres::TRUST_REGION; //ceres::TRUST_REGION;LINE_SEARCH
+    ceres_options.max_line_search_step_contraction = 1e-3;
+    //    ceres_options.minimizer_progress_to_stdout = false;
+    //    ceres_options.line_search_direction_type = ceres::LBFGS;
+    //    ceres_options.max_num_iterations = 100;
+    google::InitGoogleLogging(argv[0]);
+
+    CeresManager ceres_manager(problem, ceres_options);
+
+
+    ceres::Solver::Summary summary = ceres_manager.solve();
+    std::cout << summary.FullReport() << std::endl;
+
+    // Test of convergence over the lmk params
+    bool pass = (lmk_2->point() - lmk_1->point()).isMuchSmallerThan(1,Constants::EPS);
+
+    std::cout << "Landmark 2 below should have converged to Landmark 1:" << std::endl;
+    std::cout << "Landmark 1: " << lmk_1->point().transpose() << std::endl;
+    std::cout << "Landmark 2: " << lmk_2->point().transpose() << std::endl;
+    std::cout << "Landmark convergence test " << (pass ? "PASSED" : "FAILED") << std::endl;
+    std::cout << std::endl;
+
+    if (!pass)
+        return -1;
+    return 0;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/examples/test_wolf_factories.cpp b/src/examples/test_wolf_factories.cpp
index 8878f39dc32d6ab149bebbb266cf9a0deb2530dd..c34616753a174a249f54cb5dbf75825ac4e8b843 100644
--- a/src/examples/test_wolf_factories.cpp
+++ b/src/examples/test_wolf_factories.cpp
@@ -36,21 +36,11 @@ int main(void)
     using std::static_pointer_cast;
 
 
-    /**=============================================================================================
-     * Get wolf root directory from the environment variable WOLF_ROOT
-     * To make this work, you need to set the environment variable WOLF_ROOT:
-     *  - To run from terminal, edit your ~/.bashrc, or ~/.bash_profile and add this line:
-     *        export WOLF_ROOT="/path/to/wolf"
-     *  - To run from eclipse, open the 'run configuration' of this executable, tab 'Environment'
-     *    and add variable WOLF_ROOT set to /path/to/wolf
-     */
-    char* w = std::getenv("WOLF_ROOT");
-    if (w == NULL)
-        throw std::runtime_error("Environment variable WOLF_ROOT not found");
-
-    std::string WOLF_ROOT       = w;
-    std::string WOLF_CONFIG     = WOLF_ROOT + "/src/examples";
-    std::cout << "\nwolf directory for configuration files: " << WOLF_CONFIG << std::endl;
+
+    //==============================================================================================
+    std::string wolf_root       = _WOLF_ROOT_DIR;
+    std::string wolf_config     = wolf_root + "/src/examples";
+    std::cout << "\nwolf directory for configuration files: " << wolf_config << std::endl;
     //==============================================================================================
 
     cout << "\n====== Registering creators in the Wolf Factories =======" << endl;
@@ -59,7 +49,7 @@ int main(void)
             "There is only one attempt per class, and it is successful!\n"
             "We do this by registering in the class\'s .cpp file.\n"
             "\n"
-            "- See \'" << WOLF_ROOT << "/src/examples/test_wolf_factories.cpp\'\n"
+            "- See \'" << wolf_root << "/src/examples/test_wolf_factories.cpp\'\n"
             "  for the way to install sensors and processors to wolf::Problem." << endl;
 
     // Start creating the problem
@@ -68,13 +58,13 @@ int main(void)
 
     // define some useful parameters
     Eigen::VectorXs pq_3d(7), po_2d(3), p_3d(3);
-    shared_ptr<IntrinsicsOdom2D> intr_odom2d_ptr;
+    shared_ptr<IntrinsicsOdom2D> intr_odom2d_ptr = nullptr;
 
     cout << "\n================== Intrinsics Factory ===================" << endl;
 
     // Use params factory for camera intrinsics
-    IntrinsicsBasePtr intr_cam_ptr = IntrinsicsFactory::get().create("CAMERA", WOLF_CONFIG + "/camera.yaml");
-    ProcessorParamsBasePtr params_ptr = ProcessorParamsFactory::get().create("IMAGE", WOLF_CONFIG + "/processor_image_ORB.yaml");
+    IntrinsicsBasePtr intr_cam_ptr = IntrinsicsFactory::get().create("CAMERA", wolf_config + "/camera_params_ueye_sim.yaml");
+    ProcessorParamsBasePtr params_ptr = ProcessorParamsFactory::get().create("IMAGE FEATURE", wolf_config + "/processor_image_ORB.yaml");
 
     cout << "CAMERA with intrinsics      : " << (static_pointer_cast<IntrinsicsCamera>(intr_cam_ptr))->pinhole_model.transpose() << endl;
 //    cout << "Processor IMAGE image width : " << (static_pointer_cast<ProcessorParamsImage>(params_ptr))->image.width << endl;
@@ -83,13 +73,13 @@ int main(void)
 
     // Install sensors
     problem->installSensor("CAMERA",     "front left camera",    pq_3d,  intr_cam_ptr);
-    problem->installSensor("CAMERA",     "front right camera",   pq_3d,  WOLF_CONFIG + "/camera.yaml");
+    problem->installSensor("CAMERA",     "front right camera",   pq_3d,  wolf_config + "/camera_params_ueye_sim.yaml");
     problem->installSensor("ODOM 2D",    "main odometer",        po_2d,  intr_odom2d_ptr);
     problem->installSensor("GPS FIX",    "GPS fix",              p_3d);
     problem->installSensor("IMU",        "inertial",             pq_3d);
-    problem->installSensor("GPS",        "GPS raw",              p_3d);
+//    problem->installSensor("GPS",        "GPS raw",              p_3d);
     problem->installSensor("ODOM 2D",    "aux odometer",         po_2d,  intr_odom2d_ptr);
-    problem->installSensor("CAMERA", "rear camera", pq_3d, WOLF_ROOT + "/src/examples/camera.yaml");
+    problem->installSensor("CAMERA", "rear camera", pq_3d, wolf_root + "/src/examples/camera_params_ueye_sim.yaml");
 
     // print available sensors
     for (auto sen : problem->getHardwarePtr()->getSensorList())
@@ -103,9 +93,9 @@ int main(void)
 
     // Install processors and bind them to sensors -- by sensor name!
     problem->installProcessor("ODOM 2D", "main odometry",    "main odometer");
-    problem->installProcessor("ODOM 3D", "sec. odometry",    "aux odometer");
+    problem->installProcessor("ODOM 2D", "sec. odometry",    "aux odometer");
     problem->installProcessor("IMU",     "pre-integrated",   "inertial");
-    problem->installProcessor("IMAGE",   "ORB",              "front left camera", WOLF_CONFIG + "/processor_image_ORB.yaml");
+    problem->installProcessor("IMAGE FEATURE",   "ORB",              "front left camera", wolf_config + "/processor_image_ORB.yaml");
 //    problem->createProcessor("GPS",     "GPS pseudoranges", "GPS raw");
 
     // print installed processors
diff --git a/src/examples/test_yaml.cpp b/src/examples/test_yaml.cpp
index 2b9dac224ad71cc0bdbf41d5800b49226547db25..5b4f9f553fb4f0bb86a91a3947a4511270f59100 100644
--- a/src/examples/test_yaml.cpp
+++ b/src/examples/test_yaml.cpp
@@ -21,21 +21,9 @@
 int main()
 {
 
-    /**=============================================================================================
-     * Get wolf root directory from the environment variable WOLF_ROOT
-     * To make this work, you need to set the environment variable WOLF_ROOT:
-     *  - To run from terminal, edit your ~/.bashrc, or ~/.bash_profile and add this line:
-     *        export WOLF_ROOT="/path/to/wolf"
-     *  - To run from eclipse, open the 'run configuration' of this executable, tab 'Environment'
-     *    and add variable WOLF_ROOT set to /path/to/wolf
-     */
-    std::string WOLF_ROOT;
-    char* w = std::getenv("WOLF_ROOT");
-    if (w != NULL)
-        WOLF_ROOT = w;
-    else
-        throw std::runtime_error("Environment variable WOLF_ROOT not found");
-    std::cout << "\nwolf root directory: " << WOLF_ROOT << std::endl;
+    //=============================================================================================
+    std::string wolf_root       = _WOLF_ROOT_DIR;
+    std::cout << "\nwolf root directory: " << wolf_root << std::endl;
     //=============================================================================================
 
     using namespace Eigen;
@@ -45,7 +33,7 @@ int main()
 
     // Camera parameters
 
-    YAML::Node camera_config = YAML::LoadFile(WOLF_ROOT + "/src/examples/camera.yaml");
+    YAML::Node camera_config = YAML::LoadFile(wolf_root + "/src/examples/camera.yaml");
 
     if (camera_config["sensor type"])
     {
@@ -87,7 +75,7 @@ int main()
 
     ProcessorParamsImage p;
 
-    Node params = YAML::LoadFile(WOLF_ROOT + "/src/examples/processor_image_ORB.yaml");
+    Node params = YAML::LoadFile(wolf_root + "/src/examples/processor_image_ORB.yaml");
 
     if (params["processor type"])
     {
diff --git a/src/feature_point_image.cpp b/src/feature_point_image.cpp
index aa1d9e81ab564dcd50dc580808fc9fd49e4a41bf..9bef25d2b5d101e0505c75b717ab0360933bd558 100644
--- a/src/feature_point_image.cpp
+++ b/src/feature_point_image.cpp
@@ -6,6 +6,8 @@ namespace wolf {
 FeaturePointImage::FeaturePointImage(const Eigen::Vector2s & _measurement) :
     FeatureBase("POINT IMAGE", _measurement,Eigen::MatrixXs::Zero(0,0)), is_known_(false)
 {
+    keypoint_.pt.x = float(measurement_(0));
+    keypoint_.pt.y = float(measurement_(1));
     //
 }
 
diff --git a/src/feature_point_image.h b/src/feature_point_image.h
index 4c7a451de27e50567f0e2ca539723e62a99181a5..6a7486a7e16992802d193e6ecaa3ddf8066f7278 100644
--- a/src/feature_point_image.h
+++ b/src/feature_point_image.h
@@ -66,6 +66,8 @@ class FeaturePointImage : public FeatureBase
         void setKeypoint(const cv::KeyPoint& _kp)
         {
             keypoint_ = _kp;
+            measurement_(0) = _kp.pt.x;
+            measurement_(1) = _kp.pt.y;
         }
 
         const cv::Mat& getDescriptor() const;
diff --git a/src/landmark_AHP.cpp b/src/landmark_AHP.cpp
index c66dd056f00991ebb71c91007efadbb76b25c056..d0ae0765fa4db43bd3cb59975c1ee27df98de7d2 100644
--- a/src/landmark_AHP.cpp
+++ b/src/landmark_AHP.cpp
@@ -35,12 +35,26 @@ YAML::Node LandmarkAHP::saveToYaml() const
     return node;
 }
 
-Eigen::Vector3s LandmarkAHP::getPoint3D() const
+Eigen::Vector3s LandmarkAHP::getPointInAnchorSensor() const
 {
     Eigen::Map<const Eigen::Vector4s> hmg_point(getPPtr()->getVector().data());
     return hmg_point.head<3>()/hmg_point(3);
 }
 
+Eigen::Vector3s LandmarkAHP::point() const
+{
+    using namespace Eigen;
+    Transform<Scalar,3,Affine> T_w_r
+        = Translation<Scalar,3>(getAnchorFrame()->getPPtr()->getVector())
+        * Quaternions(getAnchorFrame()->getOPtr()->getVector().data());
+    Transform<Scalar,3,Affine> T_r_c
+        = Translation<Scalar,3>(getAnchorSensor()->getPPtr()->getVector())
+        * Quaternions(getAnchorSensor()->getOPtr()->getVector().data());
+    Vector4s point_hmg_c = getPPtr()->getVector();
+    Vector4s point_hmg = T_w_r * T_r_c * point_hmg_c;
+    return point_hmg.head<3>()/point_hmg(3);
+}
+
 wolf::LandmarkBasePtr LandmarkAHP::create(const YAML::Node& _node)
 {
     unsigned int        id          = _node["id"]           .as< unsigned int     >();
diff --git a/src/landmark_AHP.h b/src/landmark_AHP.h
index c9d02c651018a9995d203953cb9112afb4f564c3..7c85e1bc7545a7015c6ad7426d60b9932f5a10d3 100644
--- a/src/landmark_AHP.h
+++ b/src/landmark_AHP.h
@@ -38,7 +38,8 @@ class LandmarkAHP : public LandmarkBase
         void setAnchorFrame  (FrameBasePtr  _anchor_frame );
         void setAnchorSensor (SensorBasePtr _anchor_sensor);
         void setAnchor       (FrameBasePtr  _anchor_frame , SensorBasePtr _anchor_sensor);
-        Eigen::Vector3s getPoint3D() const;
+        Eigen::Vector3s getPointInAnchorSensor() const;
+        Eigen::Vector3s point() const;
 
         YAML::Node saveToYaml() const;
 
diff --git a/src/local_parametrization_homogeneous.cpp b/src/local_parametrization_homogeneous.cpp
index 431f77a23e10c8c1f301029e7b8552a8e761a656..987c9e45612d47072f30ef9d8e4d4f30b3c18a84 100644
--- a/src/local_parametrization_homogeneous.cpp
+++ b/src/local_parametrization_homogeneous.cpp
@@ -31,22 +31,27 @@ bool LocalParametrizationHomogeneous::plus(const Eigen::Map<const Eigen::VectorX
 
     using namespace Eigen;
 
-    double norm_delta = _delta.norm();
-    if (norm_delta > Constants::EPS)
+    double angle = _delta.norm();
+    Quaternions dq;
+    if (angle > Constants::EPS_SMALL)
     {
         // compute rotation axis -- this guarantees unity norm
-        Vector3s axis = _delta / norm_delta;
+        Vector3s axis = _delta.normalized();
 
-        // express delta as a quaternion -- this is exp(delta)
-        Quaternions dq(AngleAxis<Scalar>(norm_delta, axis));
+        // express delta as a quaternion using the angle-axis helper
+        dq = AngleAxis<Scalar>(angle, axis);
 
-        // result as a homogeneous point -- we use the quaternion product for keeping in the 4-sphere
-        _h_plus_delta = (dq * Map<const Quaternions>(_h.data())).coeffs();
     }
-    else
+    else // Consider small angle approx
     {
-        _h_plus_delta = _h;
+        dq.w() = 1;
+        dq.vec() = _delta/2;
+        dq.normalize();
     }
+
+    // result as a homogeneous point -- we use the quaternion product for keeping in the 4-sphere
+    _h_plus_delta = (dq * Map<const Quaternions>(_h.data())).coeffs();
+
     return true;
 }
 
@@ -56,11 +61,11 @@ bool LocalParametrizationHomogeneous::computeJacobian(const Eigen::Map<const Eig
     assert(_h.size() == global_size_ && "Wrong size of input quaternion.");
     assert(_jacobian.rows() == global_size_ && _jacobian.cols() == local_size_ && "Wrong size of Jacobian matrix.");
 
-    _jacobian << -_h(0), -_h(1), -_h(2),
-                  _h(3),  _h(2), -_h(1),
-                 -_h(2),  _h(3),  _h(0),
-                  _h(1), -_h(0),  _h(3);
-    _jacobian /= 2;
+    Eigen::Vector4s hh = _h/2;
+    _jacobian <<  hh(3),  hh(2), -hh(1),
+                 -hh(2),  hh(3),  hh(0),
+                  hh(1), -hh(0),  hh(3),
+                 -hh(0), -hh(1), -hh(2) ;
     return true;
 }
 
diff --git a/src/local_parametrization_quaternion.cpp b/src/local_parametrization_quaternion.cpp
index 1e7faeb3b96838b512398db17d611556847c70b6..08b8ea1431cdced786eace58221af8d8b7f2850f 100644
--- a/src/local_parametrization_quaternion.cpp
+++ b/src/local_parametrization_quaternion.cpp
@@ -1,5 +1,5 @@
 #include "local_parametrization_quaternion.h"
-
+#include <iostream>
 namespace wolf {
 
 template <>
@@ -17,23 +17,27 @@ bool LocalParametrizationQuaternion<wolf::DQ_LOCAL>::plus(const Eigen::Map<const
     using namespace Eigen;
 
     double angle = _delta_theta.norm();
+    Quaternions dq;
     if (angle > Constants::EPS_SMALL)
     {
         // compute rotation axis -- this guarantees unity norm
         Vector3s axis = _delta_theta / angle;
 
         // express delta_theta as a quaternion using the angle-axis helper
-        Quaternions dq(AngleAxis<Scalar>(angle, axis));
-
-        // result as a quaternion
-        // the delta is in local reference: q * dq
-        _q_plus_delta_theta = (Map<const Quaternions>(_q.data()) * dq).coeffs();
+        dq = AngleAxis<Scalar>(angle, axis);
 
     }
-    else // Consider null rotation
+    else // Consider small angle approx
     {
-        _q_plus_delta_theta = _q;
+        dq.w() = 1;
+        dq.vec() = _delta_theta/2;
+        dq.normalize();
     }
+
+    // result as a quaternion
+    // the delta is in global reference: dq * q
+    _q_plus_delta_theta = (Map<const Quaternions>(_q.data()) * dq).coeffs();
+
     return true;
 }
 
@@ -52,22 +56,27 @@ bool LocalParametrizationQuaternion<wolf::DQ_GLOBAL>::plus(const Eigen::Map<cons
     using namespace Eigen;
 
     double angle = _delta_theta.norm();
+    Quaternions dq;
     if (angle > Constants::EPS_SMALL)
     {
         // compute rotation axis -- this guarantees unity norm
         Vector3s axis = _delta_theta / angle;
 
         // express delta_theta as a quaternion using the angle-axis helper
-        Quaternions dq(AngleAxis<Scalar>(angle, axis));
+        dq = AngleAxis<Scalar>(angle, axis);
 
-        // result as a quaternion
-        // the delta is in global reference: dq * q
-        _q_plus_delta_theta = (dq * Map<const Quaternions>(_q.data())).coeffs();
     }
-    else // Consider null rotation
+    else // Consider small angle approx
     {
-        _q_plus_delta_theta = _q;
+        dq.w() = 1;
+        dq.vec() = _delta_theta/2;
+        dq.normalize();
     }
+
+    // result as a quaternion
+    // the delta is in global reference: dq * q
+    _q_plus_delta_theta = (dq * Map<const Quaternions>(_q.data())).coeffs();
+
     return true;
 }
 
@@ -78,12 +87,11 @@ bool LocalParametrizationQuaternion<wolf::DQ_LOCAL>::computeJacobian(const Eigen
     assert(_q.size() == global_size_ && "Wrong size of input quaternion.");
     assert(_jacobian.rows() == global_size_ && _jacobian.cols() == local_size_ && "Wrong size of Jacobian matrix.");
 
-    using namespace Eigen;
-    _jacobian << -_q(0), -_q(1), -_q(2),
-                  _q(3), -_q(2),  _q(1),
-                  _q(2),  _q(3), -_q(0),
-                 -_q(1),  _q(0),  _q(3);
-    _jacobian /= 2;
+    Eigen::Vector4s qq = _q/2;
+    _jacobian <<  qq(3), -qq(2),  qq(1),
+                  qq(2),  qq(3), -qq(0),
+                 -qq(1),  qq(0),  qq(3),
+                 -qq(0), -qq(1), -qq(2) ;
 
     return true;
 }
@@ -95,12 +103,11 @@ bool LocalParametrizationQuaternion<wolf::DQ_GLOBAL>::computeJacobian(const Eige
     assert(_q.size() == global_size_ && "Wrong size of input quaternion.");
     assert(_jacobian.rows() == global_size_ && _jacobian.cols() == local_size_ && "Wrong size of Jacobian matrix.");
 
-    using namespace Eigen;
-    _jacobian << -_q(0), -_q(1), -_q(2),
-                  _q(3),  _q(2), -_q(1),
-                 -_q(2),  _q(3),  _q(0),
-                  _q(1), -_q(0),  _q(3);
-    _jacobian /= 2;
+    Eigen::Vector4s qq = _q/2;
+    _jacobian <<  qq(3),  qq(2), -qq(1),
+                 -qq(2),  qq(3),  qq(0),
+                  qq(1), -qq(0),  qq(3),
+                 -qq(0), -qq(1), -qq(2);
 
     return true;
 }
diff --git a/src/problem.cpp b/src/problem.cpp
index 4d6f338ded1ff6e262593d93116319622e51aa72..c1104595ccda1ad9b732afe5edf19110e42d6d01 100644
--- a/src/problem.cpp
+++ b/src/problem.cpp
@@ -556,197 +556,335 @@ void Problem::saveMap(const std::string& _filename_dot_yaml, const std::string&
     getMapPtr()->save(_filename_dot_yaml, _map_name);
 }
 
-void Problem::print(int level)
+void Problem::print(int depth, bool constr_by, bool metric, bool state_blocks)
 {
     std::cout << std::endl;
     std::cout << "P: wolf tree status ---------------------" << std::endl;
-    std::cout << "H" << std::endl;
-    for (auto S : getHardwarePtr()->getSensorList() )
+    std::cout << "Hardware" << std::endl;
+    if (depth >= 1)
     {
-        std::cout << "  S" << S->id() << std::endl;
-        for (auto p : S->getProcessorList() )
+        for (auto S : getHardwarePtr()->getSensorList())
         {
-            if (p->isMotion())
+            std::cout << "  S" << S->id() << std::endl;
+            if (state_blocks)
             {
-                std::cout << "    pm" << p->id() << std::endl;
-                ProcessorMotion::Ptr pm = std::static_pointer_cast<ProcessorMotion>(p);
-                if (pm->getOriginPtr())
-                    std::cout << "      o: C" << pm->getOriginPtr()->id() << std::endl;
-                if (pm->getLastPtr())
-                    std::cout << "      l: C" << pm->getLastPtr()->id() << std::endl;
-                if (pm->getIncomingPtr())
-                    std::cout << "      i: C" << pm->getIncomingPtr()->id() << std::endl;
+                std::cout << "    sb:";
+                for (auto sb : S->getStateBlockVec())
+                    if (sb != nullptr)
+                        std::cout << " " << (sb->isFixed() ? "Fix" : "Est");
+                std::cout << std::endl;
             }
-            else
+            if (depth >= 2)
             {
-                try
+                for (auto p : S->getProcessorList())
                 {
-                    std::cout << "    pt" << p->id() << std::endl;
-                    ProcessorTracker::Ptr pt = std::static_pointer_cast<ProcessorTracker>(p);
-                    if (pt->getOriginPtr())
-                        std::cout << "      o: C" << pt->getOriginPtr()->id() << std::endl;
-                    if (pt->getLastPtr())
-                        std::cout << "      l: C" << pt->getLastPtr()->id() << std::endl;
-                    if (pt->getIncomingPtr())
-                        std::cout << "      i: C" << pt->getIncomingPtr()->id() << std::endl;
-                }
-                catch (std::runtime_error& e)
-                {
-                    std::cout << "Unknown processor type!" << std::endl;
-                }
+                    if (p->isMotion())
+                    {
+                        std::cout << "    pm" << p->id() << std::endl;
+                        if (depth >= 2)
+                        {
+                            ProcessorMotion::Ptr pm = std::static_pointer_cast<ProcessorMotion>(p);
+                            if (pm->getOriginPtr())
+                                std::cout << "      o: C" << pm->getOriginPtr()->id() << " - F"
+                                        << pm->getOriginPtr()->getFramePtr()->id() << std::endl;
+                            if (pm->getLastPtr())
+                                std::cout << "      l: C" << pm->getLastPtr()->id() << " - F"
+                                        << pm->getLastPtr()->getFramePtr()->id() << std::endl;
+                            if (pm->getIncomingPtr())
+                                std::cout << "      i: C" << pm->getIncomingPtr()->id() << std::endl;
+                        }
+                    }
+                    else
+                    {
+                        try
+                        {
+                            std::cout << "    pt" << p->id() << std::endl;
+                            if (depth >= 2)
+                            {
+                                ProcessorTracker::Ptr pt = std::static_pointer_cast<ProcessorTracker>(p);
+                                if (pt->getOriginPtr())
+                                    std::cout << "      o: C" << pt->getOriginPtr()->id() << " - F"
+                                            << pt->getOriginPtr()->getFramePtr()->id() << std::endl;
+                                if (pt->getLastPtr())
+                                    std::cout << "      l: C" << pt->getLastPtr()->id() << " - F"
+                                            << pt->getLastPtr()->getFramePtr()->id() << std::endl;
+                                if (pt->getIncomingPtr())
+                                    std::cout << "      i: C" << pt->getIncomingPtr()->id() << std::endl;
+                            }
+                        }
+                        catch (std::runtime_error& e)
+                        {
+                            std::cout << "Unknown processor type!" << std::endl;
+                        }
 
+                    }
+                }
             }
+            else
+                std::cout << "    " << S->getProcessorList().size() << "p" << std::endl;
         }
     }
-    std::cout << "T" << std::endl;
-    for (auto F : getTrajectoryPtr()->getFrameList() )
+    else
+        std::cout << "  " << getHardwarePtr()->getSensorList().size() << "S" << std::endl;
+    std::cout << "Trajectory" << std::endl;
+    if (depth >= 1)
     {
-        std::cout << (F->isKey() ?  "  KF" : "  F") << F->id();
-        if (level > 0)
-        {
-            std::cout << "  <-- ";
-            for (auto cby : F->getConstrainedByList())
-                std::cout << "c" << cby->id() << " \t";
-        }
-        std::cout << std::endl;
-        if (level > 1)
+        for (auto F : getTrajectoryPtr()->getFrameList())
         {
-            std::cout << (F->isFixed() ?  "    Fixed" : "    Estim") << ", ts=" << std::setprecision(5) << F->getTimeStamp().get();
-            std::cout << ",\t x = ( " << std::setprecision(2) << F->getState().transpose() << ")";
+            std::cout << (F->isKey() ? "  KF" : "  F") << F->id();
+            if (constr_by)
+            {
+                std::cout << "  <-- ";
+                for (auto cby : F->getConstrainedByList())
+                    std::cout << "c" << cby->id() << " \t";
+            }
             std::cout << std::endl;
-        }
-        for (auto C : F->getCaptureList() )
-        {
-            std::cout << "    C" << C->id() << " -> S" << C->getSensorPtr()->id() << std::endl;
-            for (auto f : C->getFeatureList() )
+            if (metric)
             {
-                std::cout << "      f" << f->id();
-                if (level > 0)
-                    {
-                    std::cout<< "  <--\t";
-                    for (auto cby : f->getConstrainedByList())
-                        std::cout << "c" << cby->id() << " \t";
-                    }
+                std::cout << (F->isFixed() ? "    Fixed" : "    Estim") << ", ts=" << std::setprecision(5)
+                        << F->getTimeStamp().get();
+                std::cout << ",\t x = ( " << std::setprecision(2) << F->getState().transpose() << ")";
+                std::cout << std::endl;
+            }
+            if (state_blocks)
+            {
+                std::cout << "    sb:";
+                for (auto sb : F->getStateBlockVec())
+                    if (sb != nullptr)
+                        std::cout << " " << (sb->isFixed() ? "Fix" : "Est");
                 std::cout << std::endl;
-                if (level > 1)
-                    std::cout << "        m = ( " << std::setprecision(3) << f->getMeasurement().transpose() << ")" << std::endl;
-                for (auto c : f->getConstraintList() )
+            }
+            if (depth >= 2)
+            {
+                for (auto C : F->getCaptureList())
                 {
-                    std::cout << "        c" << c->id();
-                    switch (c->getCategory())
+                    std::cout << "    C" << C->id() << " -> S" << C->getSensorPtr()->id() << std::endl;
+                    if (depth >= 3)
                     {
-                        case CTR_ABSOLUTE:
-                            std::cout << " --> A" << std::endl;
-                            break;
-                        case CTR_FRAME:
-                            std::cout << " --> F" << c->getFrameOtherPtr()->id() << std::endl;
-                            break;
-                        case CTR_FEATURE:
-                            std::cout << " --> f" << c->getFeatureOtherPtr()->id() << std::endl;
-                            break;
-                        case CTR_LANDMARK:
-                            std::cout << " --> L" << c->getLandmarkOtherPtr()->id() << std::endl;
-                            break;
+                        for (auto f : C->getFeatureList())
+                        {
+                            std::cout << "      f" << f->id();
+                            if (constr_by)
+                            {
+                                std::cout << "  <--\t";
+                                for (auto cby : f->getConstrainedByList())
+                                    std::cout << "c" << cby->id() << " \t";
+                            }
+                            std::cout << std::endl;
+                            if (metric)
+                                std::cout << "        m = ( " << std::setprecision(3) << f->getMeasurement().transpose()
+                                        << ")" << std::endl;
+                            if (depth >= 4)
+                            {
+                                for (auto c : f->getConstraintList())
+                                {
+                                    std::cout << "        c" << c->id() << " -->";
+                                    if (c->getCategory() == CTR_ABSOLUTE)
+                                        std::cout << " A";
+                                    if (c->getFrameOtherPtr() != nullptr)
+                                        std::cout << " F" << c->getFrameOtherPtr()->id();
+                                    if (c->getFeatureOtherPtr() != nullptr)
+                                        std::cout << " f" << c->getFeatureOtherPtr()->id();
+                                    if (c->getLandmarkOtherPtr() != nullptr)
+                                        std::cout << " L" << c->getLandmarkOtherPtr()->id();
+                                    std::cout << std::endl;
+                                }
+                            }
+                            else
+                                std::cout << "        " << f->getConstraintList().size() << "c" << std::endl;
+                        }
                     }
+                    else
+                        std::cout << "      " << C->getFeatureList().size() << "f" << std::endl;
                 }
             }
+            else
+                std::cout << "    " << F->getCaptureList().size() << "C" << std::endl;
         }
     }
-    std::cout << "M" << std::endl;
-    for (auto L : getMapPtr()->getLandmarkList() )
+    else
+        std::cout << "  " << getTrajectoryPtr()->getFrameList().size() << "F" << std::endl;
+    std::cout << "Map" << std::endl;
+    if (depth >= 1)
     {
-        std::cout << "  L" << L->id();
-        if (level > 0)
+        for (auto L : getMapPtr()->getLandmarkList())
+        {
+            std::cout << "  L" << L->id();
+            if (constr_by)
             {
-            std::cout << "\t<-- ";
-            for (auto cby : L->getConstrainedByList())
-                std::cout << "c" << cby->id() << " \t";
+                std::cout << "\t<-- ";
+                for (auto cby : L->getConstrainedByList())
+                    std::cout << "c" << cby->id() << " \t";
             }
-        std::cout << std::endl;
+            std::cout << std::endl;
+            if (state_blocks)
+            {
+                std::cout << "    sb:";
+                for (auto sb : L->getStateBlockVec())
+                    if (sb != nullptr)
+                        std::cout << " " << (sb->isFixed() ? "Fix" : "Est");
+                std::cout << std::endl;
+            }
+        }
     }
+    else
+        std::cout << "  " << getMapPtr()->getLandmarkList().size() << "L" << std::endl;
     std::cout << "-----------------------------------------" << std::endl;
     std::cout << std::endl;
 }
 
-bool Problem::check()
+bool Problem::check(int verbose_level)
 {
     bool is_consistent = true;
     std::cout << std::endl;
     std::cout << "Wolf tree integrity ---------------------" << std::endl;
     auto P_raw = this;
-    std::cout << "P @ " << P_raw << std::endl;
     auto H = hardware_ptr_;
-    std::cout << "H @ " << H.get() << std::endl;
+    if (verbose_level > 0)
+    {
+        std::cout << "P @ " << P_raw << std::endl;
+        std::cout << "H @ " << H.get() << std::endl;
+    }
     is_consistent = is_consistent && (H->getProblem().get() == P_raw);
-    for (auto S : H->getSensorList() )
+    for (auto S : H->getSensorList())
     {
-        std::cout << "  S" << S->id() << " @ " << S.get() << std::endl;
-        std::cout << "    -> P @ " << S->getProblem().get() << std::endl;
-        std::cout << "    -> H @ " << S->getHardwarePtr().get() << std::endl;
+        if (verbose_level > 0)
+        {
+            std::cout << "  S" << S->id() << " @ " << S.get() << std::endl;
+            std::cout << "    -> P @ " << S->getProblem().get() << std::endl;
+            std::cout << "    -> H @ " << S->getHardwarePtr().get() << std::endl;
+        }
         is_consistent = is_consistent && (S->getProblem().get() == P_raw);
         is_consistent = is_consistent && (S->getHardwarePtr() == H);
-        for (auto p : S->getProcessorList() )
+        for (auto p : S->getProcessorList())
         {
-            std::cout << "    p" << p->id() << " @ " << p.get() << " -> S" << p->getSensorPtr()->id() << std::endl;
-            std::cout << "      -> P  @ " << p->getProblem().get() << std::endl;
-            std::cout << "      -> S" << p->getSensorPtr()->id() << " @ " << p->getSensorPtr().get() << std::endl;
+            if (verbose_level > 0)
+            {
+                std::cout << "    p" << p->id() << " @ " << p.get() << " -> S" << p->getSensorPtr()->id() << std::endl;
+                std::cout << "      -> P  @ " << p->getProblem().get() << std::endl;
+                std::cout << "      -> S" << p->getSensorPtr()->id() << " @ " << p->getSensorPtr().get() << std::endl;
+            }
             is_consistent = is_consistent && (p->getProblem().get() == P_raw);
             is_consistent = is_consistent && (p->getSensorPtr() == S);
         }
     }
     auto T = trajectory_ptr_;
-    std::cout << "T @ " << T.get() << std::endl;
+    if (verbose_level > 0)
+    {
+        std::cout << "T @ " << T.get() << std::endl;
+    }
     is_consistent = is_consistent && (T->getProblem().get() == P_raw);
-    for (auto F : T->getFrameList() )
+    for (auto F : T->getFrameList())
     {
-        std::cout << (F->isKey() ?  "  KF" : "  F") << F->id() << " @ " << F.get() << std::endl;
-        std::cout << "    -> P @ " << F->getProblem().get() << std::endl;
-        std::cout << "    -> T @ " << F->getTrajectoryPtr().get() << std::endl;
-        is_consistent = is_consistent && (F->getProblem().get() == P_raw);
-        is_consistent = is_consistent && (F->getTrajectoryPtr() == T);
-        for (auto c : F->getConstrainedByList())
+        if (verbose_level > 0)
         {
-            std::cout << "    <- c" << c->id() << " -> F" << c->getFrameOtherPtr()->id() << std::endl;
+            std::cout << (F->isKey() ? "  KF" : "  F") << F->id() << " @ " << F.get() << std::endl;
+            std::cout << "    -> P @ " << F->getProblem().get() << std::endl;
+            std::cout << "    -> T @ " << F->getTrajectoryPtr().get() << std::endl;
+            for (auto c : F->getConstrainedByList())
+            {
+                std::cout << "    <- c" << c->id() << " -> F" << c->getFrameOtherPtr()->id() << std::endl;
+            }
         }
-        for (auto C : F->getCaptureList() )
+        is_consistent = is_consistent && (F->getProblem().get() == P_raw);
+        is_consistent = is_consistent && (F->getTrajectoryPtr() == T);
+        for (auto C : F->getCaptureList())
         {
-            std::cout << "    C" << C->id() << " @" << C.get() << " -> S" << C->getSensorPtr()->id() << std::endl;
-            std::cout << "      -> P  @ " << C->getProblem().get() << std::endl;
-            std::cout << "      -> F" << C->getFramePtr()->id() << " @ " << C->getFramePtr().get() << std::endl;
+            if (verbose_level > 0)
+            {
+                std::cout << "    C" << C->id() << " @" << C.get() << " -> S" << C->getSensorPtr()->id() << std::endl;
+                std::cout << "      -> P  @ " << C->getProblem().get() << std::endl;
+                std::cout << "      -> F" << C->getFramePtr()->id() << " @ " << C->getFramePtr().get() << std::endl;
+            }
             is_consistent = is_consistent && (C->getProblem().get() == P_raw);
             is_consistent = is_consistent && (C->getFramePtr() == F);
-            for (auto f : C->getFeatureList() )
+            for (auto f : C->getFeatureList())
             {
-                std::cout << "      f" << f->id() << " @" << f.get() << std::endl;
-                std::cout << "        -> P  @ " << f->getProblem().get() << std::endl;
-                std::cout << "        -> C" << f->getCapturePtr()->id() << " @ " << f->getCapturePtr().get() << std::endl;
+                if (verbose_level > 0)
+                {
+                    std::cout << "      f" << f->id() << " @" << f.get() << std::endl;
+                    std::cout << "        -> P  @ " << f->getProblem().get() << std::endl;
+                    std::cout << "        -> C" << f->getCapturePtr()->id() << " @ " << f->getCapturePtr().get()
+                            << std::endl;
+                }
                 is_consistent = is_consistent && (f->getProblem().get() == P_raw);
                 is_consistent = is_consistent && (f->getCapturePtr() == C);
 
-                for (auto c : f->getConstrainedByList())
+                if (verbose_level > 0)
                 {
-                    std::cout << "     <- c" << c->id() << " -> f" << c->getFeatureOtherPtr()->id() << std::endl;
+                    for (auto c : f->getConstrainedByList())
+                    {
+                        std::cout << "     <- c" << c->id() << " -> f" << c->getFeatureOtherPtr()->id() << std::endl;
+                    }
                 }
-                for (auto c : f->getConstraintList() )
+                for (auto c : f->getConstraintList())
                 {
-                    std::cout << "        c" << c->id() << " @" << C.get();
+                    if (verbose_level > 0)
+                        std::cout << "        c" << c->id() << " @" << C.get();
                     switch (c->getCategory())
                     {
                         case CTR_ABSOLUTE:
-                            std::cout << " --> A" << std::endl;
+                            if (verbose_level > 0)
+                                std::cout << " --> A" << std::endl;
                             break;
                         case CTR_FRAME:
-                            std::cout << " --> F" << c->getFrameOtherPtr()->id() << std::endl;
+                        {
+                            auto Fo = c->getFrameOtherPtr();
+                            if (verbose_level > 0)
+                                std::cout << " --> F" << Fo->id() << " <- ";
+                            bool found = false;
+                            for (auto cby : Fo->getConstrainedByList())
+                            {
+                                if (verbose_level > 0)
+                                    std::cout << " c" << cby->id();
+                                found = found || (c == cby);
+                            }
+                            if (verbose_level > 0)
+                                std::cout << std::endl;
+                            is_consistent = is_consistent && found;
                             break;
+                        }
                         case CTR_FEATURE:
-                            std::cout << " --> f" << c->getFeatureOtherPtr()->id() << std::endl;
+                        {
+                            auto fo = c->getFeatureOtherPtr();
+                            if (verbose_level > 0)
+                                std::cout << " --> f" << fo->id() << " <- ";
+                            bool found = false;
+                            for (auto cby : fo->getConstrainedByList())
+                            {
+                                if (verbose_level > 0)
+                                    std::cout << " c" << cby->id();
+                                found = found || (c == cby);
+                            }
+                            if (verbose_level > 0)
+                                std::cout << std::endl;
+                            is_consistent = is_consistent && found;
                             break;
+                        }
                         case CTR_LANDMARK:
-                            std::cout << " --> L" << c->getLandmarkOtherPtr()->id() << std::endl;
+                        {
+                            auto Lo = c->getLandmarkOtherPtr();
+                            if (verbose_level > 0)
+                                std::cout << " --> L" << Lo->id() << " <- ";
+                            bool found = false;
+                            for (auto cby : Lo->getConstrainedByList())
+                            {
+                                if (verbose_level > 0)
+                                    std::cout << " c" << cby->id();
+                                found = found || (c == cby);
+                            }
+                            if (verbose_level > 0)
+                                std::cout << std::endl;
+                            is_consistent = is_consistent && found;
                             break;
+                        }
+                    }
+                    if (verbose_level > 0)
+                    {
+                        std::cout << "          -> P  @ " << c->getProblem().get() << std::endl;
+                        std::cout << "          -> f" << c->getFeaturePtr()->id() << " @ " << c->getFeaturePtr().get()
+                                << std::endl;
                     }
-                    std::cout << "          -> P  @ " << c->getProblem().get() << std::endl;
-                    std::cout << "          -> f" << c->getFeaturePtr()->id() << " @ " << c->getFeaturePtr().get() << std::endl;
                     is_consistent = is_consistent && (c->getProblem().get() == P_raw);
                     is_consistent = is_consistent && (c->getFeaturePtr() == f);
                 }
@@ -754,24 +892,28 @@ bool Problem::check()
         }
     }
     auto M = map_ptr_;
-    std::cout << "M @ " << M.get() << std::endl;
+    if (verbose_level > 0)
+        std::cout << "M @ " << M.get() << std::endl;
     is_consistent = is_consistent && (M->getProblem().get() == P_raw);
-    for (auto L : M->getLandmarkList() )
+    for (auto L : M->getLandmarkList())
     {
-        std::cout << "  L" << L->id() << " @" << L.get() << std::endl;
+        if (verbose_level > 0)
+            std::cout << "  L" << L->id() << " @" << L.get() << std::endl;
         is_consistent = is_consistent && (L->getProblem().get() == P_raw);
         is_consistent = is_consistent && (L->getMapPtr() == M);
-        for (auto c : L->getConstrainedByList())
+        bool found = false;
+        for (auto cby : L->getConstrainedByList())
         {
-            std::cout << "      <- c" << c->id() << " -> L" << c->getLandmarkOtherPtr()->id() << std::endl;
+            if (verbose_level > 0)
+                std::cout << "      <- c" << cby->id() << " -> L" << cby->getLandmarkOtherPtr()->id() << std::endl;
+            found = found || (cby->getLandmarkOtherPtr() && L == cby->getLandmarkOtherPtr());
         }
+        is_consistent = is_consistent && found;
     }
 
-//    std::cout << std::endl;
-    std::cout << "--------------------------- Wolf tree " << (is_consistent ? " OK" : "NOK") << std::endl;
+    std::cout << "--------------------------- Wolf tree " << (is_consistent ? " OK" : "Not OK !!") << std::endl;
     std::cout << std::endl;
 
-
     return is_consistent;
 }
 
diff --git a/src/problem.h b/src/problem.h
index 62b8bef241e096e885f9295262227e161c59c23f..21f88aaa03d69b9209b50a3a2d27371e37b212c6 100644
--- a/src/problem.h
+++ b/src/problem.h
@@ -245,10 +245,13 @@ class Problem : public std::enable_shared_from_this<Problem>
         // Print and check ---------------------------------------
         /**
          * \brief print wolf tree
-         * \param level : 0: Basic links; 1: with Constrained_by; with 2: Metrics; default: 1.
+         * \param depth :        levels to show ( 0: H, T, M : 1: H:S:p, T:F, M:L ; 2: T:F:C ; 3: T:F:C:f ; 4: T:F:C:f:c )
+         * \param constr_by:     show constraints pointing to F, f and L.
+         * \param metric :       show metric info (status, time stamps, state vectors, measurements)
+         * \param state_blocks : show state blocks
          */
-        void print(int level = 1);
-        bool check();
+        void print(int depth = 4, bool constr_by = false, bool metric = true, bool state_blocks = false);
+        bool check(int verbose_level = 0);
 
 };
 
diff --git a/src/processor_base.cpp b/src/processor_base.cpp
index 886d959c00935812b87c005774a896e6bb738076..89849f3d7c706320f808b43f5b77ab04bc998fbe 100644
--- a/src/processor_base.cpp
+++ b/src/processor_base.cpp
@@ -12,6 +12,7 @@ ProcessorBase::ProcessorBase(const std::string& _type, const Scalar& _time_toler
         processor_id_(++processor_id_count_),
         time_tolerance_(_time_tolerance)
 {
+    setType(_type);
     std::cout << "constructed    +p" << id() << std::endl;
 
     //
diff --git a/src/processor_base.h b/src/processor_base.h
index fc8405c3a2260adb65f4869561da8f2b80fe081e..af502ae8640eaaaea81549f1631c3a43cdc68bf7 100644
--- a/src/processor_base.h
+++ b/src/processor_base.h
@@ -67,6 +67,8 @@ class ProcessorBase : public NodeBase, public std::enable_shared_from_this<Proce
 
         ProblemPtr getProblem();
 
+        void setTimeTolerance(Scalar _time_tolerance);
+
     private:
         static unsigned int processor_id_count_;
 
@@ -117,6 +119,11 @@ inline const SensorBasePtr ProcessorBase::getSensorPtr() const
     return sensor_ptr_.lock();
 }
 
+inline void ProcessorBase::setTimeTolerance(Scalar _time_tolerance)
+{
+    time_tolerance_ = _time_tolerance;
+}
+
 } // namespace wolf
 
 #endif
diff --git a/src/processor_image_feature.cpp b/src/processor_image_feature.cpp
index 1c03d30179b86441fd301bc83080274c2565e279..8b4de59670ef39ab6cf7967faa52cdec3e9cf237 100644
--- a/src/processor_image_feature.cpp
+++ b/src/processor_image_feature.cpp
@@ -160,7 +160,7 @@ unsigned int ProcessorImageFeature::trackFeatures(const FeatureBaseList& _featur
             tracker_roi_.pop_back();
         }
     }
-    std::cout << "TrackFeatures - Number of Features tracked: " << _feature_list_out.size() << std::endl;
+//    std::cout << "TrackFeatures - Number of Features tracked: " << _feature_list_out.size() << std::endl;
     return _feature_list_out.size();
 }
 
diff --git a/src/processor_image_landmark.cpp b/src/processor_image_landmark.cpp
index c6e9bb2446e2379a8c14eb56fe4fd44c89867b39..5b1d6c4da5f7ad3ee467af0a1a1e7181c34a00ea 100644
--- a/src/processor_image_landmark.cpp
+++ b/src/processor_image_landmark.cpp
@@ -111,7 +111,6 @@ unsigned int ProcessorImageLandmark::findLandmarks(const LandmarkBaseList& _land
                                                           FeatureBaseList& _feature_list_out,
                                                           LandmarkMatchMap& _feature_landmark_correspondences)
 {
-    WOLF_DEBUG_HERE
 
     unsigned int roi_width = params_.matcher.roi_width;
     unsigned int roi_heigth = params_.matcher.roi_height;
@@ -190,14 +189,13 @@ unsigned int ProcessorImageLandmark::findLandmarks(const LandmarkBaseList& _land
 
         lmk_nbr++;
     }
-    std::cout << "\tNumber of Features tracked: " << _feature_list_out.size() << std::endl;
+//    std::cout << "\tNumber of Features tracked: " << _feature_list_out.size() << std::endl;
     landmarks_tracked_ = _feature_list_out.size();
     return _feature_list_out.size();
 }
 
 bool ProcessorImageLandmark::voteForKeyFrame()
 {
-    WOLF_DEBUG_HERE
 
     return false;
 //    return landmarks_tracked_ < params_.algorithm.min_features_for_keyframe;
@@ -205,7 +203,6 @@ bool ProcessorImageLandmark::voteForKeyFrame()
 
 unsigned int ProcessorImageLandmark::detectNewFeatures(const unsigned int& _max_features)
 {
-    WOLF_DEBUG_HERE
 
     cv::Rect roi;
     std::vector<cv::KeyPoint> new_keypoints;
@@ -253,7 +250,6 @@ unsigned int ProcessorImageLandmark::detectNewFeatures(const unsigned int& _max_
 
 LandmarkBasePtr ProcessorImageLandmark::createLandmark(FeatureBasePtr _feature_ptr)
 {
-    WOLF_DEBUG_HERE
 
     std::shared_ptr<FeaturePointImage> feat_point_image_ptr = std::static_pointer_cast<FeaturePointImage>( _feature_ptr);
     FrameBasePtr anchor_frame = getLastPtr()->getFramePtr();
@@ -284,7 +280,6 @@ LandmarkBasePtr ProcessorImageLandmark::createLandmark(FeatureBasePtr _feature_p
 
 ConstraintBasePtr ProcessorImageLandmark::createConstraint(FeatureBasePtr _feature_ptr, LandmarkBasePtr _landmark_ptr)
 {
-    WOLF_DEBUG_HERE
 
     if ((std::static_pointer_cast<LandmarkAHP>(_landmark_ptr))->getAnchorFrame() == last_ptr_->getFramePtr())
     {
@@ -439,7 +434,7 @@ void ProcessorImageLandmark::drawFeaturesFromLandmarks(cv::Mat _image)
         //candidate - cyan
         cv::Point2f point = (std::static_pointer_cast<FeaturePointImage>(feature_point))->getKeypoint().pt;
         cv::circle(_image, point, 2, cv::Scalar(255.0, 255.0, 0.0), -1, 8, 0);
-        std::cout << "feature of landmark [" << (feature_point)->landmarkId() << "] in: " << point << std::endl;
+//        std::cout << "feature of landmark [" << (feature_point)->landmarkId() << "] in: " << point << std::endl;
 
         cv::Point2f point2 = point;
         point2.x = point2.x - 16;
@@ -503,7 +498,7 @@ void ProcessorImageLandmark::drawLandmarks(cv::Mat _image)
     cv::putText(_image, std::to_string(counter), label_for_landmark_point2,
                 cv:: FONT_HERSHEY_SIMPLEX, 0.4, cv::Scalar(255.0, 0.0, 255.0));
 
-    std::cout << "\t\tTotal landmarks: " << counter << std::endl;
+//    std::cout << "\t\tTotal landmarks: " << counter << std::endl;
 
     cv::imshow("Feature tracker", _image);
 }
diff --git a/src/processor_motion.cpp b/src/processor_motion.cpp
index f7317b31d15f2f3007e146d550524eb7b3f35fbc..cdf5bf891f95c291f4e859a475efee143b6e492b 100644
--- a/src/processor_motion.cpp
+++ b/src/processor_motion.cpp
@@ -20,26 +20,41 @@ ProcessorMotion::~ProcessorMotion()
 
 void ProcessorMotion::process(CaptureBasePtr _incoming_ptr)
 {
-    WOLF_DEBUG_HERE
+
+    /* Status:
+     * KF --- KF --- F ----
+     *        o      l      i
+     */
 
     incoming_ptr_ = std::static_pointer_cast<CaptureMotion>(_incoming_ptr);
 
+    /* Status:
+     * KF --- KF --- F ---- *
+     *        o      l      i
+     */
+
     preProcess();
     integrate();
 
     if (voteForKeyFrame() && permittedKeyFrame())
     {
+        WOLF_DEBUG_HERE
         // key_capture
         CaptureMotion::Ptr key_capture_ptr = last_ptr_;
         FrameBasePtr key_frame_ptr = key_capture_ptr->getFramePtr();
-        if (key_frame_ptr == nullptr) {WOLF_DEBUG_HERE; std::runtime_error("bad pointer");}
 
-        // Set the frame as key
+        // Set the frame of key_capture as key
         key_frame_ptr->setState(getCurrentState());
         key_frame_ptr->setTimeStamp(getBuffer().get().back().ts_);
         key_frame_ptr->setKey();
 
-        // create motion feature and add it to the capture
+        /* Status:
+         * KF --- KF --- KF ---
+         *        o      l      i
+         */
+
+
+        // create motion feature and add it to the key_capture
         FeatureBasePtr key_feature_ptr = std::make_shared<FeatureBase>(
                 "MOTION",
                 key_capture_ptr->getBuffer().get().back().delta_integr_,
@@ -54,19 +69,27 @@ void ProcessorMotion::process(CaptureBasePtr _incoming_ptr)
         origin_ptr_->getFramePtr() -> addConstrainedBy(ctr_ptr);
 
         // new last capture
-        last_ptr_ = std::make_shared<CaptureMotion>(key_frame_ptr->getTimeStamp(), getSensorPtr(),
+        last_ptr_ = std::make_shared<CaptureMotion>(key_frame_ptr->getTimeStamp(),
+                                                    getSensorPtr(),
                                                     Eigen::VectorXs::Zero(data_size_),
-                                                    Eigen::MatrixXs::Zero(data_size_, data_size_), key_frame_ptr);
+                                                    Eigen::MatrixXs::Zero(data_size_, data_size_),
+                                                    key_frame_ptr);
 
         // create a new last frame
         FrameBasePtr new_frame_ptr = getProblem()->createFrame(NON_KEY_FRAME, key_frame_ptr->getState(), last_ptr_->getTimeStamp());
         new_frame_ptr->addCapture(last_ptr_); // Add Capture to the new Frame
 
-        // reset processor origin
+        // reset processor origin to the new keyframe's capture
         origin_ptr_ = key_capture_ptr;
         getBuffer().get().push_back(Motion( {key_frame_ptr->getTimeStamp(), deltaZero(), deltaZero(),
                                              Eigen::MatrixXs::Zero(delta_cov_size_, delta_cov_size_),
                                              Eigen::MatrixXs::Zero(delta_cov_size_, delta_cov_size_)}));
+
+        /* Status:
+         * KF --- KF --- KF --- F ----
+         *               o      l      i
+         */
+
         delta_integrated_ = deltaZero();
         delta_integrated_cov_.setZero();
 
@@ -74,12 +97,13 @@ void ProcessorMotion::process(CaptureBasePtr _incoming_ptr)
         resetDerived();
         getProblem()->keyFrameCallback(key_frame_ptr, shared_from_this(), time_tolerance_);
 
-        //// debug cout
-        //Eigen::VectorXs interpolated_state(3);
-        //xPlusDelta(origin_ptr_->getFramePtr()->getState(), key_capture_ptr->getBufferPtr()->get().back().delta_integr_, interpolated_state);
-        //std::cout << "\tinterpolated state: " << interpolated_state.transpose() << std::endl;
     }
+
+
     postProcess();
+
+    // clear incoming just in case
+    incoming_ptr_ = nullptr; // This line is not really needed, but it makes things clearer.
 }
 
 CaptureMotion::Ptr ProcessorMotion::findCaptureContainingTimeStamp(const TimeStamp& _ts) const
@@ -113,12 +137,16 @@ CaptureMotion::Ptr ProcessorMotion::findCaptureContainingTimeStamp(const TimeSta
 
 void ProcessorMotion::setOrigin(FrameBasePtr _origin_frame)
 {
-    WOLF_DEBUG_HERE
 
     assert(_origin_frame->getTrajectoryPtr() != nullptr
             && "ProcessorMotion::setOrigin: origin frame must be in the trajectory.");
     assert(_origin_frame->isKey() && "ProcessorMotion::setOrigin: origin frame must be KEY FRAME.");
 
+    /* Status:
+     * * --- * ---
+     * o     l     i
+     */
+
     // make (empty) origin Capture
     origin_ptr_ = std::make_shared<CaptureMotion>(_origin_frame->getTimeStamp(), getSensorPtr(),
                                                   Eigen::VectorXs::Zero(data_size_),
@@ -126,18 +154,28 @@ void ProcessorMotion::setOrigin(FrameBasePtr _origin_frame)
     // Add origin capture to origin frame
     _origin_frame->addCapture(origin_ptr_);
 
+    /* Status:
+     * KF --- * ---
+     * o      l     i
+     */
+
     // make (emtpy) last Capture
     last_ptr_ = std::make_shared<CaptureMotion>(_origin_frame->getTimeStamp(),
                                                 getSensorPtr(),
                                                 Eigen::VectorXs::Zero(data_size_),
                                                 Eigen::MatrixXs::Zero(data_size_, data_size_),
                                                 _origin_frame);
-    // Make frame at last Capture
+    // Make non-key-frame at last Capture
     //    makeFrame(last_ptr_, _origin_frame->getState(), NON_KEY_FRAME);
     FrameBasePtr new_frame_ptr = getProblem()->createFrame(NON_KEY_FRAME,
                                                            _origin_frame->getState(),
                                                            last_ptr_->getTimeStamp());
-    new_frame_ptr->addCapture(last_ptr_); // Add last Capture to the new Frame
+    new_frame_ptr->addCapture(last_ptr_);
+
+    /* Status:
+     * KF --- F ---
+     * o      l     i
+     */
 
     // Reset deltas
     delta_ = deltaZero();
@@ -155,19 +193,22 @@ void ProcessorMotion::setOrigin(FrameBasePtr _origin_frame)
 
 bool ProcessorMotion::keyFrameCallback(FrameBasePtr _keyframe_ptr, const Scalar& _time_tol_other)
 {
-    WOLF_DEBUG_HERE
 
-    Scalar time_tol = std::min(time_tolerance_, _time_tol_other);
-    std::cout << "  Time tol this  " << time_tolerance_ << std::endl;
-    std::cout << "  Time tol other " << _time_tol_other << std::endl;
-    std::cout << "  Time tol eff   " << time_tol << std::endl;
-
-    std::cout << "  Time stamp input F " << _keyframe_ptr->getTimeStamp().get() << std::endl;
-    std::cout << "  Time stamp orig  F " << getOriginPtr()->getFramePtr()->getTimeStamp().get() << std::endl;
-    std::cout << "  Time stamp orig  C " << getOriginPtr()->getTimeStamp().get() << std::endl;
-    std::cout << "  Time stamp last  F " << getLastPtr()->getFramePtr()->getTimeStamp().get() << std::endl;
-    std::cout << "  Time stamp last  C " << getLastPtr()->getTimeStamp().get() << std::endl;
+    //    Scalar time_tol = std::min(time_tolerance_, _time_tol_other);
+    //    std::cout << "  Time tol this  " << time_tolerance_ << std::endl;
+    //    std::cout << "  Time tol other " << _time_tol_other << std::endl;
+    //    std::cout << "  Time tol eff   " << time_tol << std::endl;
+    //
+    //    std::cout << "  Time stamp input F " << _keyframe_ptr->getTimeStamp().get() << std::endl;
+    //    std::cout << "  Time stamp orig  F " << getOriginPtr()->getFramePtr()->getTimeStamp().get() << std::endl;
+    //    std::cout << "  Time stamp orig  C " << getOriginPtr()->getTimeStamp().get() << std::endl;
+    //    std::cout << "  Time stamp last  F " << getLastPtr()->getFramePtr()->getTimeStamp().get() << std::endl;
+    //    std::cout << "  Time stamp last  C " << getLastPtr()->getTimeStamp().get() << std::endl;
 
+    WOLF_DEBUG_HERE
+    std::cout << "PM: KF" << _keyframe_ptr->id() << " callback received at ts= " << _keyframe_ptr->getTimeStamp().get() << std::endl;
+    std::cout << "    while last ts= " << last_ptr_->getTimeStamp().get() << std::endl;
+    std::cout << "    while last's frame ts= " << last_ptr_->getFramePtr()->getTimeStamp().get() << std::endl;
 
     assert(_keyframe_ptr->getTrajectoryPtr() != nullptr
             && "ProcessorMotion::keyFrameCallback: key frame must be in the trajectory.");
@@ -226,7 +267,7 @@ bool ProcessorMotion::keyFrameCallback(FrameBasePtr _keyframe_ptr, const Scalar&
     // modify feature and constraint (if they exist)
     if (!capture_ptr->getFeatureList().empty())
     {
-        FeatureBasePtr feature_ptr = capture_ptr->getFeatureList().front();
+        FeatureBasePtr feature_ptr = capture_ptr->getFeatureList().back(); // there is only one feature!
 
         // modify feature
         feature_ptr->setMeasurement(capture_ptr->getBuffer().get().back().delta_integr_);
@@ -236,14 +277,18 @@ bool ProcessorMotion::keyFrameCallback(FrameBasePtr _keyframe_ptr, const Scalar&
                         Eigen::MatrixXs::Identity(delta_size_, delta_size_) * 1e-8);
 
         // modify constraint
-        if (!feature_ptr->getConstraintList().empty())
-        {
-            auto ctr = feature_ptr->getConstraintList().front();
-            feature_ptr->getConstraintList().remove(ctr);
+        // Instead of modifying, we remove one ctr, and create a new one.
+
+        // get the constraint to be removed later
+        auto ctr_to_remove = feature_ptr->getConstraintList().back(); // there is only one constraint!
+
+        // create and append new constraint
+        auto new_ctr = feature_ptr->addConstraint(createConstraint(feature_ptr, _keyframe_ptr));
+        _keyframe_ptr->addConstrainedBy(new_ctr);
+
+        // remove old constraint now (otherwise c->remove() gets propagated to f, C, F, etc.)
+        ctr_to_remove->remove();
 
-            //            feature_ptr->getConstraintList().front()->remove(); // XXX What happens here?
-            feature_ptr->addConstraint(createConstraint(feature_ptr, _keyframe_ptr));
-        }
     }
 
     return true;
@@ -251,7 +296,6 @@ bool ProcessorMotion::keyFrameCallback(FrameBasePtr _keyframe_ptr, const Scalar&
 
 void ProcessorMotion::integrate()
 {
-    WOLF_DEBUG_HERE
 
     // Set dt
     updateDt();
@@ -269,11 +313,15 @@ void ProcessorMotion::integrate()
     // then push it into buffer
     getBuffer().get().push_back(Motion( {incoming_ptr_->getTimeStamp(), delta_, delta_integrated_, delta_cov_,
                                          delta_integrated_cov_}));
+
+    // Update state and time stamps
+    last_ptr_->getFramePtr()->setState(getCurrentState());
+    last_ptr_->setTimeStamp(incoming_ptr_->getTimeStamp());
+    last_ptr_->getFramePtr()->setTimeStamp(last_ptr_->getTimeStamp());
 }
 
 void ProcessorMotion::reintegrate(CaptureMotion::Ptr _capture_ptr)
 {
-    WOLF_DEBUG_HERE
 
     // start with empty motion
     _capture_ptr->getBuffer().get().push_front(motionZero(_capture_ptr->getOriginFramePtr()->getTimeStamp()));
diff --git a/src/processor_motion.h b/src/processor_motion.h
index 35a3de7b5d96130f5c7e1ceffd76f80391377eb1..95eed1f740b41c16a6dec2ff8fa63a0b1c72e6d5 100644
--- a/src/processor_motion.h
+++ b/src/processor_motion.h
@@ -369,7 +369,6 @@ inline void ProcessorMotion::resetDerived()
 
 inline bool ProcessorMotion::voteForKeyFrame()
 {
-    WOLF_DEBUG_HERE
 
     return false;
 }
diff --git a/src/processor_odom_2D.cpp b/src/processor_odom_2D.cpp
index 24ec3019102ee3a6f6fd897b96d79ca273fea7b6..283c340f0c136ea0f9fbd060ef6e30c43c8f7c33 100644
--- a/src/processor_odom_2D.cpp
+++ b/src/processor_odom_2D.cpp
@@ -4,8 +4,24 @@ namespace wolf
 
 ProcessorBasePtr ProcessorOdom2D::create(const std::string& _unique_name, const ProcessorParamsBasePtr _params, const SensorBasePtr)
 {
-    std::shared_ptr<ProcessorParamsOdom2D> params = std::static_pointer_cast<ProcessorParamsOdom2D>(_params);
-    std::shared_ptr<ProcessorOdom2D> prc_ptr = std::make_shared<ProcessorOdom2D>(params->dist_traveled_th_, params->cov_det_th_, params->elapsed_time_th_);
+    Scalar dist_traveled_th ;
+    Scalar cov_det_th       ;
+    Scalar elapsed_time_th  ;
+    if (_params)
+    {
+        std::shared_ptr<ProcessorParamsOdom2D> params = std::static_pointer_cast<ProcessorParamsOdom2D>(_params);
+        dist_traveled_th = params->dist_traveled_th_;
+        cov_det_th       = params->cov_det_th_;
+        elapsed_time_th  = params->elapsed_time_th_;
+    }
+    else
+    {
+        std::cout << __FILE__ << ":" << __FUNCTION__ << "() : No parameters provided. Using dummy set." << std::endl;
+        dist_traveled_th = 1;
+        cov_det_th       = 1;
+        elapsed_time_th  = 1;
+    }
+    std::shared_ptr<ProcessorOdom2D> prc_ptr = std::make_shared<ProcessorOdom2D>(dist_traveled_th, cov_det_th, elapsed_time_th);
     prc_ptr->setName(_unique_name);
     return prc_ptr;
 }
diff --git a/src/processor_odom_2D.h b/src/processor_odom_2D.h
index 21f52a3c4e904a7eb59c23ad2032189ed83f1c54..105bd97e5a7cbd004d5c53730962d3736a9543c9 100644
--- a/src/processor_odom_2D.h
+++ b/src/processor_odom_2D.h
@@ -105,8 +105,11 @@ inline void ProcessorOdom2D::data2delta(const Eigen::VectorXs& _data, const Eige
 
     delta_cov_ = J * _data_cov * J.transpose();
 
-    //std::cout << "data cov:" << std::endl << _data_cov << std::endl;
-    //std::cout << "delta cov:" << std::endl << _delta_cov << std::endl;
+    //WOLF_DEBUG_HERE
+    //std::cout << "data      :" << _data.transpose() << std::endl;
+    //std::cout << "data cov  :" << std::endl << _data_cov << std::endl;
+    //std::cout << "delta     :" << delta_.transpose() << std::endl;
+    //std::cout << "delta cov :" << std::endl << delta_cov << std::endl;
 }
 
 inline void ProcessorOdom2D::xPlusDelta(const Eigen::VectorXs& _x, const Eigen::VectorXs& _delta, const Scalar _Dt, Eigen::VectorXs& _x_plus_delta)
@@ -230,21 +233,21 @@ inline Motion ProcessorOdom2D::interpolate(const Motion& _motion_ref, Motion& _m
 inline bool ProcessorOdom2D::voteForKeyFrame()
 {
     //std::cout << "ProcessorOdom2D::voteForKeyFrame: traveled distance " << getBufferPtr()->get().back().delta_integr_.norm() << std::endl;
-    if (getBuffer().get().back().delta_integr_.norm() > dist_traveled_th_)
+    if (getBuffer().get().back().delta_integr_.head<2>().norm() > dist_traveled_th_)
     {
-        std::cout << "ProcessorOdom2D:: " << this->id() << "VOTE FOR KEY FRAME traveled distance "
-                << getBuffer().get().back().delta_integr_.norm() << std::endl;
+        std::cout << "ProcessorOdom2D:: " << id() << " -  VOTE FOR KEY FRAME traveled distance "
+                << getBuffer().get().back().delta_integr_.head<2>().norm() << std::endl;
         return true;
     }
     if (getBuffer().get().back().delta_integr_cov_.determinant() > cov_det_th_)
     {
-        std::cout << "ProcessorOdom2D::  " << this->id() << "VOTE FOR KEY FRAME covariance det "
+        std::cout << "ProcessorOdom2D:: " << id() << " - VOTE FOR KEY FRAME covariance det "
                 << getBuffer().get().back().delta_integr_cov_.determinant() << std::endl;
         return true;
     }
     if (getBuffer().get().back().ts_.get() - origin_ptr_->getFramePtr()->getTimeStamp().get() > elapsed_time_th_)
     {
-        std::cout << "ProcessorOdom2D::  " << this->id() << "VOTE FOR KEY FRAME elapsed time "
+        std::cout << "ProcessorOdom2D:: " << id() << " - VOTE FOR KEY FRAME elapsed time "
                 << getBuffer().get().back().ts_.get() - origin_ptr_->getFramePtr()->getTimeStamp().get()
                 << std::endl;
         return true;
diff --git a/src/processor_odom_3D.h b/src/processor_odom_3D.h
index 39bf8bcfac8b60e70b29cf27632e1b1a16fb974a..5f799e854aacf2d665f8c643cc547eb6f93717f6 100644
--- a/src/processor_odom_3D.h
+++ b/src/processor_odom_3D.h
@@ -213,7 +213,16 @@ inline Motion ProcessorOdom3D::interpolate(const Motion& _motion_ref,
 
 inline bool ProcessorOdom3D::voteForKeyFrame()
 {
-    return true;
+    if (getBuffer().get().size() > 3)
+    {
+        std::cout << "PM::vote" << std::endl;
+        return true;
+    }
+    else
+    {
+        std::cout << "PM::do not vote" << std::endl;
+        return false;
+    }
 }
 
 inline ConstraintBasePtr ProcessorOdom3D::createConstraint(FeatureBasePtr _feature_motion,
diff --git a/src/processor_tracker.cpp b/src/processor_tracker.cpp
index 1cf3d933ad4f66b3cb01d339b9129fd659cbd8e5..12b841fe90d0aff9dd40c9994c0e9cebca231b29 100644
--- a/src/processor_tracker.cpp
+++ b/src/processor_tracker.cpp
@@ -28,7 +28,6 @@ ProcessorTracker::~ProcessorTracker()
 
 void ProcessorTracker::process(CaptureBasePtr const _incoming_ptr)
 {
-    WOLF_DEBUG_HERE
 
     using std::abs;
 
@@ -41,7 +40,11 @@ void ProcessorTracker::process(CaptureBasePtr const _incoming_ptr)
     if (origin_ptr_ == nullptr && last_ptr_ == nullptr)
     {
         std::cout << "FIRST TIME" << std::endl;
-        //std::cout << "Features in origin: " << 0 << "; in last: " << 0 << std::endl;
+
+        /* Status:
+         *  * ---- * ---- * ----        KF: keyframes; F: frame
+         *  o      l      i             captures: origin, last, incoming
+         */
 
         // advance
         advance();
@@ -50,30 +53,56 @@ void ProcessorTracker::process(CaptureBasePtr const _incoming_ptr)
         last_ptr_ = incoming_ptr_;
         incoming_ptr_ = nullptr;
 
+        /* Status:
+         *  * ---- * ----           KF: keyframes; F: frame
+         *  o      l      i         captures: origin, last, incoming
+         */
+
         // keyframe creation on last
         FrameBasePtr closest_key_frm = getProblem()->getTrajectoryPtr()->closestKeyFrameToTimeStamp(last_ptr_->getTimeStamp());
         if (closest_key_frm && abs(closest_key_frm->getTimeStamp() - last_ptr_->getTimeStamp()) <= time_tolerance_)
         {
-            std::cout << "Setting key-frame to last_" << std::endl;
+            WOLF_DEBUG_HERE
             closest_key_frm->addCapture(last_ptr_);
             closest_key_frm->setKey();
+            std::cout << "Last appended to existing F, set KF" << closest_key_frm->id() << std::endl;
+
+            /* Status:
+             *  * ---- KF ---       KF: keyframes; F: frame
+             *  o      l      i     captures: origin, last, incoming
+             */
+
         }
         else
         {
+            WOLF_DEBUG_HERE
             //makeFrame(last_ptr_, KEY_FRAME);
             //makeFrame(last_ptr_, getProblem()->getStateAtTimeStamp(last_ptr_->getTimeStamp()), KEY_FRAME);
 
-            std::cout << "Making key-frame with last_" << std::endl;
             FrameBasePtr new_frame_ptr = getProblem()->createFrame(KEY_FRAME,
                                                                    getProblem()->getStateAtTimeStamp(last_ptr_->getTimeStamp()),
                                                                    last_ptr_->getTimeStamp());
             new_frame_ptr->addCapture(last_ptr_); // Add incoming Capture to the new Frame
+            std::cout << "Last appended to new KF" << new_frame_ptr->id() << std::endl;
+
+            getProblem()->keyFrameCallback(new_frame_ptr, shared_from_this(), time_tolerance_);
+
+            /* Status:
+             *  * ---- KF ---       KF: keyframes; F: frame
+             *  o      l      i     captures: origin, last, incoming
+             */
 
         }
 
         // Detect new Features, initialize Landmarks, create Constraints, ...
         processNew(max_new_features_);
 
+        /* Status:
+         *  * ---- KF ---       KF: keyframes; F: frame
+         *  o      l      i     captures: origin, last, incoming
+         *         n            new features
+         */
+
 
         // Establish constraints from last
         establishConstraints();
@@ -85,23 +114,49 @@ void ProcessorTracker::process(CaptureBasePtr const _incoming_ptr)
     {
         std::cout << "SECOND TIME or after KEY FRAME CALLBACK" << std::endl;
 
+        /* Status:
+         *  * ---- KF ---       KF: keyframes; F: frame
+         *  o      l      i     captures: origin, last, incoming
+         *         n            new features
+         */
+
         // First we track the known Features
         processKnown();
 
+        /* Status:
+         *  * ---- KF ---       KF: keyframes; F: frame
+         *  o      l      i     captures: origin, last, incoming
+         *         k      k     known features
+         */
+
         // Create a new non-key Frame in the Trajectory with the incoming Capture
         FrameBasePtr closest_key_frm = getProblem()->getTrajectoryPtr()->closestKeyFrameToTimeStamp(incoming_ptr_->getTimeStamp());
         if (closest_key_frm && abs(closest_key_frm->getTimeStamp() - incoming_ptr_->getTimeStamp()) <= time_tolerance_)
         {
             // Just append the Capture to the existing keyframe
             closest_key_frm->addCapture(incoming_ptr_);
-            std::cout << "Appended to frame" << closest_key_frm->id() << std::endl;
-      }
+            std::cout << "Incoming appended to F" << closest_key_frm->id() << std::endl;
+
+            /* Status:
+             *  * ---- KF --- KF    KF: keyframes; F: frame
+             *  o      l      i     captures: origin, last, incoming
+             *         k      k     known features
+             */
+
+        }
         else
         {
             // Create a frame to hold what will become the last Capture
             FrameBasePtr new_frame_ptr = getProblem()->createFrame(NON_KEY_FRAME, incoming_ptr_->getTimeStamp());
             new_frame_ptr->addCapture(incoming_ptr_); // Add incoming Capture to the new Frame
-            std::cout << "Made frame" << new_frame_ptr->id() << std::endl;
+            std::cout << "Incoming in new F" << new_frame_ptr->id() << std::endl;
+
+            /* Status:
+             *  * ---- KF --- F     KF: keyframes; F: frame
+             *  o      l      i     captures: origin, last, incoming
+             *         k      k     known features
+             */
+
         }
 
         // Reset the derived Tracker
@@ -112,6 +167,14 @@ void ProcessorTracker::process(CaptureBasePtr const _incoming_ptr)
         last_ptr_       = incoming_ptr_;
         incoming_ptr_   = nullptr; // This line is not really needed, but it makes things clearer.
 
+        std::cout << "origin <-- last <-- incoming" << std::endl;
+
+        /* Status:
+         *  KF -- F/KF --       KF: keyframes; F: frame
+         *  o      l      i     captures: origin, last, incoming
+         *  k      k            known features
+         */
+
     }
     // OTHER TIMES
     else
@@ -120,16 +183,16 @@ void ProcessorTracker::process(CaptureBasePtr const _incoming_ptr)
 
         // 1. First we track the known Features and create new constraints as needed
 
-        /**
-         * KF --- KF --- F           KF: keyframes; F: frame
+        /* Status:
+         * KF --- KF --- F ----      KF: keyframes; F: frame
          *        o      l      i    captures: origin, last, incoming
          *        k      k           known features
          */
 
         processKnown();
 
-        /**
-         * KF --- KF --- F           KF: keyframes; F: frame
+        /* Status:
+         * KF --- KF --- F ----      KF: keyframes; F: frame
          *        o      l      i    captures: origin, last, incoming
          *        k      k      k    known features
          */
@@ -150,13 +213,12 @@ void ProcessorTracker::process(CaptureBasePtr const _incoming_ptr)
 
         if ( !( (voteForKeyFrame() && permittedKeyFrame() ) || closest_key_frm_to_last ) )
         {
-            WOLF_DEBUG_HERE
 
             // 2.a. We did not create a KeyFrame:
 
-            /**
-             * KF --- KF --- F ---- *    frames
-             *        o      l      i    captures: incoming
+            /* Status:
+             * KF --- KF --- F ---- *
+             *        o      l      i
              *        k      k      k    known features
              */
 
@@ -164,13 +226,15 @@ void ProcessorTracker::process(CaptureBasePtr const _incoming_ptr)
             advance();
 
             // Advance this
-            last_ptr_->getFramePtr()->addCapture(incoming_ptr_); // Add incoming Capture to the tracker's Frame
+            last_ptr_->getFramePtr()->addCapture(incoming_ptr_); // Add incoming Capture to the tracker's last Frame
             last_ptr_->remove();
             incoming_ptr_->getFramePtr()->setTimeStamp(incoming_ptr_->getTimeStamp());
             last_ptr_ = incoming_ptr_; // Incoming Capture takes the place of last Capture
             incoming_ptr_ = nullptr; // This line is not really needed, but it makes things clearer.
 
-            /**
+            std::cout << "last <-- incoming" << std::endl;
+
+            /* Status:
              * KF --- KF ---------- F
              *        o      -      l    - : deleted capture
              *        k      -      k    - : deleted features
@@ -178,11 +242,10 @@ void ProcessorTracker::process(CaptureBasePtr const _incoming_ptr)
         }
         else
         {
-            WOLF_DEBUG_HERE
 
             // 2.b. We create a KF
 
-            /**
+            /* Status:
              * KF --- KF --- F ---- *    frames
              *        o      l      i    captures: incoming
              *        k      k      k    known features
@@ -191,7 +254,7 @@ void ProcessorTracker::process(CaptureBasePtr const _incoming_ptr)
             // Detect new Features, initialize Landmarks, create Constraints, ...
             processNew(max_new_features_);
 
-            /**
+            /* Status:
              * After keyframe vote and re-processing last and incoming
              * KF --- KF --- F ---- *
              *        o      l      i
@@ -199,28 +262,27 @@ void ProcessorTracker::process(CaptureBasePtr const _incoming_ptr)
              *               n      n    new features
              */
 
-            // Create a new non-key Frame in the Trajectory with the incoming Capture
             FrameBasePtr key_frm = getProblem()->getTrajectoryPtr()->closestKeyFrameToTimeStamp(incoming_ptr_->getTimeStamp());
             if ( abs(key_frm->getTimeStamp() - incoming_ptr_->getTimeStamp() ) < time_tolerance_)
             {
-                WOLF_DEBUG_HERE
                 // Append incoming to existing key-frame
                 key_frm->addCapture(incoming_ptr_); // TODO I think it should be last_ptr_ not incoming!
-                std::cout << "Adhered to existing KF" << key_frm->id() << std::endl;
+                std::cout << "Incoming adhered to existing KF" << key_frm->id() << std::endl;
             }
             else
             {
-                WOLF_DEBUG_HERE
+                // Create a new non-key Frame in the Trajectory with the incoming Capture
                 // Make a non-key-frame to hold incoming
                 FrameBasePtr new_frame_ptr = getProblem()->createFrame(NON_KEY_FRAME, incoming_ptr_->getTimeStamp());
                 new_frame_ptr->addCapture(incoming_ptr_); // Add incoming Capture to the new Frame
+                std::cout << "Incoming adhered to new F" << key_frm->id() << std::endl;
 
                 // Make the last Capture's Frame a KeyFrame
                 setKeyFrame(last_ptr_);
-                std::cout << "Adhered to new created KF" << key_frm->id() << std::endl;
+                std::cout << "Set KEY to last F" << key_frm->id() << std::endl;
             }
 
-            /**
+            /* Status:
              * KF --- KF --- KF --- F
              *        o      l      i
              *        k      k      k
@@ -239,7 +301,9 @@ void ProcessorTracker::process(CaptureBasePtr const _incoming_ptr)
             last_ptr_ = incoming_ptr_;
             incoming_ptr_ = nullptr; // This line is not really needed, but it makes things clearer.
 
-            /**
+            std::cout << "origin <-- last <-- incoming" << std::endl;
+
+            /* Status:
              * KF --- KF --- KF --- F
              *               o      l
              *               k      k
@@ -256,34 +320,14 @@ void ProcessorTracker::process(CaptureBasePtr const _incoming_ptr)
 bool ProcessorTracker::keyFrameCallback(FrameBasePtr _keyframe_ptr, const Scalar& _time_tol_other)
 {
     WOLF_DEBUG_HERE
+    std::cout << "PT: KF" << _keyframe_ptr->id() << " callback received at ts= " << _keyframe_ptr->getTimeStamp().get() << std::endl;
+    std::cout << "    while last ts= " << last_ptr_->getTimeStamp().get() << std::endl;
+    std::cout << "    while last's frame ts= " << last_ptr_->getFramePtr()->getTimeStamp().get() << std::endl;
 
     assert((last_ptr_ == nullptr || last_ptr_->getFramePtr() != nullptr) && "ProcessorTracker::keyFrameCallback: last_ptr_ must have a frame always");
 
-    //======================
-    // Start Debug info
     Scalar time_tol = std::min(time_tolerance_, _time_tol_other);
-    std::cout << "  Time tol this  " << time_tolerance_ << std::endl;
-    std::cout << "  Time tol other " << _time_tol_other << std::endl;
-    std::cout << "  Time tol eff   " << time_tol << std::endl;
-
-    if (_keyframe_ptr == nullptr) {WOLF_DEBUG_HERE; std::runtime_error("bad pointer");}
-
-    std::cout << "  Time stamp input F " << _keyframe_ptr->getTimeStamp().get() << std::endl;
-    if (getOriginPtr()){
-        if (getOriginPtr() == nullptr) {WOLF_DEBUG_HERE; std::runtime_error("bad pointer");}
-        if (getOriginPtr()->getFramePtr() == nullptr) {WOLF_DEBUG_HERE; std::runtime_error("bad pointer");}
-        std::cout << "  Time stamp orig  F " << getOriginPtr()->getFramePtr()->getTimeStamp().get() << std::endl;
-        std::cout << "  Time stamp orig  C " << getOriginPtr()->getTimeStamp().get() << std::endl;
-    }
-    if (getLastPtr())
-    {
-        if (getLastPtr() == nullptr) {WOLF_DEBUG_HERE; std::runtime_error("bad pointer");}
-        if (getLastPtr()->getFramePtr() == nullptr) {WOLF_DEBUG_HERE; std::runtime_error("bad pointer");}
-        std::cout << "  Time stamp last  F " << getLastPtr()->getFramePtr()->getTimeStamp().get() << std::endl;
-        std::cout << "  Time stamp last  C " << getLastPtr()->getTimeStamp().get() << std::endl;
-    }
-    // End Debug info
-    //======================
+
 
     // Nothing to do if:
     //   - there is no last
@@ -291,7 +335,6 @@ bool ProcessorTracker::keyFrameCallback(FrameBasePtr _keyframe_ptr, const Scalar
     //   - last frame is too far in time from keyframe
     if (last_ptr_ == nullptr || last_ptr_->getFramePtr()->isKey() || std::abs(last_ptr_->getTimeStamp() - _keyframe_ptr->getTimeStamp()) > time_tol)
     {
-        WOLF_DEBUG_HERE
         return false;
     }
 
@@ -317,7 +360,6 @@ bool ProcessorTracker::keyFrameCallback(FrameBasePtr _keyframe_ptr, const Scalar
 
 void ProcessorTracker::setKeyFrame(CaptureBasePtr _capture_ptr)
 {
-    WOLF_DEBUG_HERE
 
     assert(_capture_ptr != nullptr && _capture_ptr->getFramePtr() != nullptr && "ProcessorTracker::setKeyFrame: null capture or capture without frame");
     if (!_capture_ptr->getFramePtr()->isKey())
diff --git a/src/processor_tracker_feature.cpp b/src/processor_tracker_feature.cpp
index 0a733c3feff3f5183a7151d8b9a465fb261ea8cf..a9342814d436e0e2e2c9c02b86f626dc4d85efbe 100644
--- a/src/processor_tracker_feature.cpp
+++ b/src/processor_tracker_feature.cpp
@@ -21,7 +21,6 @@ ProcessorTrackerFeature::~ProcessorTrackerFeature()
 
 unsigned int ProcessorTrackerFeature::processKnown()
 {
-    WOLF_DEBUG_HERE
 
 //    std::cout << "ProcessorTrackerFeature::processKnown()" << std::endl;
 
@@ -73,7 +72,6 @@ unsigned int ProcessorTrackerFeature::processNew(const unsigned int& _max_new_fe
      * At the end, all new Features are appended to the lists of known Features in
      * the last and incoming Captures.
      */
-    WOLF_DEBUG_HERE
 
 
     // Populate the last Capture with new Features. The result is in new_features_last_.
diff --git a/src/processor_tracker_feature.h b/src/processor_tracker_feature.h
index fe50cc42008d896960e0929a4129bdd2ca1bae4e..1e76748b157a9ba618988938b5745014acfe0ae8 100644
--- a/src/processor_tracker_feature.h
+++ b/src/processor_tracker_feature.h
@@ -172,7 +172,6 @@ namespace wolf {
 
 inline void ProcessorTrackerFeature::establishConstraints()
 {
-    WOLF_DEBUG_HERE
 
     for (auto match : matches_origin_from_last_)
     {
@@ -184,7 +183,6 @@ inline void ProcessorTrackerFeature::establishConstraints()
 
 inline void ProcessorTrackerFeature::advance()
 {
-    WOLF_DEBUG_HERE
 
     //    std::cout << "ProcessorTrackerFeature::advance()" << std::endl;
 
@@ -206,7 +204,6 @@ inline void ProcessorTrackerFeature::advance()
 
 inline void ProcessorTrackerFeature::reset()
 {
-    WOLF_DEBUG_HERE
 
     //    std::cout << "ProcessorTrackerFeature::reset()" << std::endl;
 
diff --git a/src/processor_tracker_feature_corner.cpp b/src/processor_tracker_feature_corner.cpp
index de4d2bb4e02d91b85cfee67e09cf5e7d9fb23a7f..c130221f67aec245c615a6d21f2ac3ac30f20a9f 100644
--- a/src/processor_tracker_feature_corner.cpp
+++ b/src/processor_tracker_feature_corner.cpp
@@ -111,9 +111,9 @@ ConstraintBasePtr ProcessorTrackerFeatureCorner::createConstraint(FeatureBasePtr
         _feature_other_ptr->addConstraint(std::make_shared<ConstraintCorner2D>(_feature_other_ptr, landmark_ptr));
     }
 
-    std::cout << "creating constraint: last feature " << _feature_ptr->getMeasurement()
-              << " with origin feature " << _feature_other_ptr->getMeasurement() << std::endl
-              << " corresponding to landmark " << landmark_ptr->nodeId() << std::endl;
+//    std::cout << "creating constraint: last feature " << _feature_ptr->getMeasurement()
+//              << " with origin feature " << _feature_other_ptr->getMeasurement() << std::endl
+//              << " corresponding to landmark " << landmark_ptr->nodeId() << std::endl;
     return std::make_shared<ConstraintCorner2D>(_feature_ptr, landmark_ptr);
 }
 
diff --git a/src/processor_tracker_feature_dummy.cpp b/src/processor_tracker_feature_dummy.cpp
index f245f831fabb0af8f058adee79e447153d9a8a1e..d8b5de1a0a23d253bc3d02e82ed4b1612c9e4fa5 100644
--- a/src/processor_tracker_feature_dummy.cpp
+++ b/src/processor_tracker_feature_dummy.cpp
@@ -39,7 +39,6 @@ unsigned int ProcessorTrackerFeatureDummy::trackFeatures(const FeatureBaseList&
 
 bool ProcessorTrackerFeatureDummy::voteForKeyFrame()
 {
-    WOLF_DEBUG_HERE
     std::cout << "N features: " << incoming_ptr_->getFeatureList().size() << std::endl;
     bool vote = incoming_ptr_->getFeatureList().size() < min_feat_for_keyframe_;
     std::cout << (vote ? "Vote ": "Not vote ") << "for KF" << std::endl;
@@ -57,8 +56,9 @@ unsigned int ProcessorTrackerFeatureDummy::detectNewFeatures(const unsigned int&
         n_feature_++;
         new_features_last_.push_back(
                 std::make_shared<FeatureBase>("POINT IMAGE", n_feature_* Eigen::Vector1s::Ones(), Eigen::MatrixXs::Ones(1, 1)));
-        std::cout << "feature " << new_features_last_.back()->getMeasurement() << " detected!" << std::endl;
+        //std::cout << "feature " << new_features_last_.back()->getMeasurement() << " detected!" << std::endl;
     }
+    std::cout << new_features_last_.size() << " features detected!" << std::endl;
 
     return new_features_last_.size();
 }
diff --git a/src/processor_tracker_feature_dummy.h b/src/processor_tracker_feature_dummy.h
index 3cab6acd9ed241c58c00c3df15b71c95b8fd9390..a62695b3355ee51e5b54c684c8af20b7ee34138d 100644
--- a/src/processor_tracker_feature_dummy.h
+++ b/src/processor_tracker_feature_dummy.h
@@ -100,8 +100,8 @@ inline bool ProcessorTrackerFeatureDummy::correctFeatureDrift(const FeatureBaseP
 inline ConstraintBasePtr ProcessorTrackerFeatureDummy::createConstraint(FeatureBasePtr _feature_ptr,
                                                                       FeatureBasePtr _feature_other_ptr)
 {
-    std::cout << "creating constraint: last feature " << _feature_ptr->getMeasurement()
-              << " with origin feature " << _feature_other_ptr->getMeasurement() << std::endl;
+//    std::cout << "creating constraint: last feature " << _feature_ptr->getMeasurement()
+//              << " with origin feature " << _feature_other_ptr->getMeasurement() << std::endl;
     return std::make_shared<ConstraintEpipolar>(_feature_ptr, _feature_other_ptr);
 }
 
diff --git a/src/processor_tracker_landmark.cpp b/src/processor_tracker_landmark.cpp
index 1897f16f7966871c016f2c052d29ade8dfc8bf8a..8a55a508f2bd2b83d11a9427f018a42a38ba5878 100644
--- a/src/processor_tracker_landmark.cpp
+++ b/src/processor_tracker_landmark.cpp
@@ -30,7 +30,6 @@ ProcessorTrackerLandmark::~ProcessorTrackerLandmark()
 
 unsigned int ProcessorTrackerLandmark::processNew(const unsigned int& _max_features)
 {
-    WOLF_DEBUG_HERE
     //std::cout << "\tlast correspondences: " << matches_landmark_from_last_.size() << std::endl;
     //std::cout << "\tlast features: " << (last_ptr_ == nullptr ? 0 : last_ptr_->getFeatureList().size()) << std::endl;
     //std::cout << "\tlast new features: " << new_features_last_.size() << std::endl;
@@ -64,11 +63,11 @@ unsigned int ProcessorTrackerLandmark::processNew(const unsigned int& _max_featu
 
     // Append all new Features to the Capture's list of Features
     last_ptr_->addFeatureList(new_features_last_);
-    std::cout << "\tnew last features added " << std::endl;
+//    std::cout << "\tnew last features added " << std::endl;
 
     // Append new landmarks to the map
     getProblem()->addLandmarkList(new_landmarks);
-    std::cout << "\tnew landmarks added: " << getProblem()->getMapPtr()->getLandmarkList().size() << std::endl;
+//    std::cout << "\tnew landmarks added: " << getProblem()->getMapPtr()->getLandmarkList().size() << std::endl;
 
     //std::cout << "end of processNew:" << std::endl;
     //std::cout << "\tlast correspondences: " << matches_landmark_from_last_.size() << std::endl;
@@ -84,24 +83,22 @@ unsigned int ProcessorTrackerLandmark::processNew(const unsigned int& _max_featu
 
 void ProcessorTrackerLandmark::createNewLandmarks(LandmarkBaseList& _new_landmarks)
 {
-    WOLF_DEBUG_HERE
 
     for (auto new_feature_ptr : new_features_last_)
     {
         // create new landmark
         LandmarkBasePtr new_lmk_ptr = createLandmark(new_feature_ptr);
-        std::cout << "\tnew_landmark: " << new_lmk_ptr->id() << std::endl;
+//        std::cout << "\tnew_landmark: " << new_lmk_ptr->id() << std::endl;
         _new_landmarks.push_back(new_lmk_ptr);
         // create new correspondence
         matches_landmark_from_last_[new_feature_ptr] = std::make_shared<LandmarkMatch>(new_lmk_ptr, 1); // max score
     }
-    std::cout << "\tnew_landmarks: " << _new_landmarks.size() << std::endl;
-    std::cout << "\tlast correspondences: " << matches_landmark_from_last_.size() << std::endl;
+//    std::cout << "\tnew_landmarks: " << _new_landmarks.size() << std::endl;
+//    std::cout << "\tlast correspondences: " << matches_landmark_from_last_.size() << std::endl;
 }
 
 unsigned int ProcessorTrackerLandmark::processKnown()
 {
-    WOLF_DEBUG_HERE
 
     //std::cout << "ProcessorTrackerLandmark::processKnown:" << std::endl;
     //std::cout << "\tlast correspondences: " << matches_landmark_from_last_.size() << std::endl;
@@ -131,7 +128,6 @@ unsigned int ProcessorTrackerLandmark::processKnown()
 
 void ProcessorTrackerLandmark::establishConstraints()
 {
-    WOLF_DEBUG_HERE
 
     //std::cout << "\tfeatures:" << last_ptr_->getFeatureList().size() << std::endl;
     //std::cout << "\tcorrespondences: " << matches_landmark_from_last_.size() << std::endl;
diff --git a/src/processor_tracker_landmark.h b/src/processor_tracker_landmark.h
index 5b39952fbe2604d6a17b57443fe9e34d5a855955..915ec82f73e3b8426e065c6d9e1215d29c77fca8 100644
--- a/src/processor_tracker_landmark.h
+++ b/src/processor_tracker_landmark.h
@@ -174,7 +174,6 @@ namespace wolf
 {
 inline void ProcessorTrackerLandmark::advance()
 {
-    WOLF_DEBUG_HERE
 
     for ( auto match : matches_landmark_from_last_)
     {
@@ -191,7 +190,6 @@ inline void ProcessorTrackerLandmark::advance()
 
 inline void ProcessorTrackerLandmark::reset()
 {
-    WOLF_DEBUG_HERE
 
     //std::cout << "ProcessorTrackerLandmark::reset" << std::endl;
     for ( auto match : matches_landmark_from_last_)
diff --git a/src/sensor_odom_2D.cpp b/src/sensor_odom_2D.cpp
index 82689b6aad7b5b78a7ea46814cf6d9528461c064..972a468d843a535845741d23c8c947cc81c6114f 100644
--- a/src/sensor_odom_2D.cpp
+++ b/src/sensor_odom_2D.cpp
@@ -35,8 +35,14 @@ SensorBasePtr SensorOdom2D::create(const std::string& _unique_name, const Eigen:
     StateBlockPtr pos_ptr = std::make_shared<StateBlock>(_extrinsics_po.head(2), true);
     StateBlockPtr ori_ptr = std::make_shared<StateBlock>(_extrinsics_po.tail(1), true);
     // cast intrinsics into derived type
-    std::shared_ptr<IntrinsicsOdom2D> params = std::static_pointer_cast<IntrinsicsOdom2D>(_intrinsics);
-    std::shared_ptr<SensorOdom2D> odo = std::make_shared<SensorOdom2D>(pos_ptr, ori_ptr, params->k_disp_to_disp, params->k_rot_to_rot);
+    std::shared_ptr<SensorOdom2D> odo;
+    if (_intrinsics)
+    {
+        std::shared_ptr<IntrinsicsOdom2D> params = std::static_pointer_cast<IntrinsicsOdom2D>(_intrinsics);
+        odo = std::make_shared<SensorOdom2D>(pos_ptr, ori_ptr, params->k_disp_to_disp, params->k_rot_to_rot);
+    }
+    else
+        odo = std::make_shared<SensorOdom2D>(pos_ptr, ori_ptr, 1, 1);
     odo->setName(_unique_name);
     return odo;
 }
diff --git a/src/trajectory_base.cpp b/src/trajectory_base.cpp
index f537b27848ec4a8b4505c8a7f92fc590b853312c..6a6e544cad3953f9a379abe012131d6b4b5f0edf 100644
--- a/src/trajectory_base.cpp
+++ b/src/trajectory_base.cpp
@@ -54,7 +54,7 @@ void TrajectoryBase::sortFrame(FrameBasePtr _frame_ptr)
 FrameBaseIter TrajectoryBase::computeFrameOrder(FrameBasePtr _frame_ptr)
 {
     for (auto frm_rit = getFrameList().rbegin(); frm_rit != getFrameList().rend(); frm_rit++)
-        if ((*frm_rit)!= _frame_ptr && (*frm_rit)->isKey() && (*frm_rit)->getTimeStamp() < _frame_ptr->getTimeStamp())
+        if ((*frm_rit)!= _frame_ptr && (*frm_rit)->isKey() && (*frm_rit)->getTimeStamp() <= _frame_ptr->getTimeStamp())
             return frm_rit.base();
     return getFrameList().begin();
 }
diff --git a/src/yaml/sensor_camera_yaml.cpp b/src/yaml/sensor_camera_yaml.cpp
index 7d1e5980131cc584e517fc05c14656fdd0f48b54..a2feb6fe4a68d55fb9c2074e46c21566f9700f0d 100644
--- a/src/yaml/sensor_camera_yaml.cpp
+++ b/src/yaml/sensor_camera_yaml.cpp
@@ -62,9 +62,9 @@ static IntrinsicsBasePtr createIntrinsicsCamera(const std::string & _filename_do
         //=========================================
         // ===== this part for debugging only =====
         //=========================================
-        std::cout << "\n--- Parameters Parsed from YAML file ---" << std::endl;
-        std::cout << "sensor type: " << sensor_type << std::endl;
-        std::cout << "sensor name: " << sensor_name << std::endl;
+//        std::cout << "\n--- Parameters Parsed from YAML file ---" << std::endl;
+//        std::cout << "sensor type: " << sensor_type << std::endl;
+//        std::cout << "sensor name: " << sensor_name << std::endl;
 
 //        // extrinsics discarded in this creator
 //        Vector3d pos            = camera_config["extrinsic"]["position"].as<Vector3d>();
@@ -74,10 +74,10 @@ static IntrinsicsBasePtr createIntrinsicsCamera(const std::string & _filename_do
 //        std::cout << "\tposition    : " << pos.transpose() << std::endl;
 //        std::cout << "\torientation : " << ori.transpose() << std::endl;
 
-        std::cout << "sensor intrinsics: " << std::endl;
-        std::cout << "\timage size  : " << width << "x" << height << std::endl;
-        std::cout << "\tintrinsic   : " << intrinsic.transpose() << std::endl;
-        std::cout << "\tdistoriton  : " << distortion.transpose() << std::endl;
+//        std::cout << "sensor intrinsics: " << std::endl;
+//        std::cout << "\timage size  : " << width << "x" << height << std::endl;
+//        std::cout << "\tintrinsic   : " << intrinsic.transpose() << std::endl;
+//        std::cout << "\tdistoriton  : " << distortion.transpose() << std::endl;
         //=========================================
         //=========================================
 
diff --git a/src/yaml/sensor_odom_3D_yaml.cpp b/src/yaml/sensor_odom_3D_yaml.cpp
index e2b281948647c3c2a66a730bf817dc6a2ac100cc..136b29b639e1868ed21aef9644d223eb73277951 100644
--- a/src/yaml/sensor_odom_3D_yaml.cpp
+++ b/src/yaml/sensor_odom_3D_yaml.cpp
@@ -45,9 +45,9 @@ static IntrinsicsBasePtr createIntrinsicsOdom3D(const std::string & _filename_do
         //=========================================
         // ===== this part for debugging only =====
         //=========================================
-        std::cout << "\n--- Parameters Parsed from YAML file ---" << std::endl;
-        std::cout << "sensor type: " << sensor_type << std::endl;
-        std::cout << "sensor name: " << sensor_name << std::endl;
+//        std::cout << "\n--- Parameters Parsed from YAML file ---" << std::endl;
+//        std::cout << "sensor type: " << sensor_type << std::endl;
+//        std::cout << "sensor name: " << sensor_name << std::endl;
 
         //=========================================
         //=========================================