diff --git a/src/IMU_tools.h b/src/IMU_tools.h
index 4f6ecda67b6695723b11ddecc56403da57a931a0..6d231223554ec4ea5e196cb7220a40e0eb42c001 100644
--- a/src/IMU_tools.h
+++ b/src/IMU_tools.h
@@ -34,10 +34,10 @@
  *   - between: Db = D2 (-) D1, so that D2 = D1 (+) Db
  *   - composeOverState: x2 = x1 (+) D
  *   - betweenStates: D = x2 (-) x1, so that x2 = x1 (+) D
- *   - lift: got from Delta manifold to tangent space (equivalent to log() in rotations)
- *   - retract: go from tangent space to delta manifold (equivalent to exp() in rotations)
- *   - plus: D2 = D1 (+) retract(d)
- *   - diff: d = lift( D2 (-) D1 )
+ *   - log: got from Delta manifold to tangent space (equivalent to log() in rotations)
+ *   - exp_IMU: go from tangent space to delta manifold (equivalent to exp() in rotations)
+ *   - plus: D2 = D1 (+) exp_IMU(d)
+ *   - diff: d = log_IMU( D2 (-) D1 )
  *   - body2delta: construct a delta from body magnitudes of linAcc and angVel
  */
 
@@ -345,7 +345,7 @@ inline Matrix<typename D1::Scalar, 10, 1> betweenStates(const MatrixBase<D1>& x1
 }
 
 template<typename Derived>
-Matrix<typename Derived::Scalar, 9, 1> lift(const MatrixBase<Derived>& delta_in)
+Matrix<typename Derived::Scalar, 9, 1> log_IMU(const MatrixBase<Derived>& delta_in)
 {
     MatrixSizeCheck<10, 1>::check(delta_in);
 
@@ -366,7 +366,7 @@ Matrix<typename Derived::Scalar, 9, 1> lift(const MatrixBase<Derived>& delta_in)
 }
 
 template<typename Derived>
-Matrix<typename Derived::Scalar, 10, 1> retract(const MatrixBase<Derived>& d_in)
+Matrix<typename Derived::Scalar, 10, 1> exp_IMU(const MatrixBase<Derived>& d_in)
 {
     MatrixSizeCheck<9, 1>::check(d_in);
 
diff --git a/src/three_D_tools.h b/src/SE3.h
similarity index 70%
rename from src/three_D_tools.h
rename to src/SE3.h
index 73ec2d413475ccd8ca82a4b9db14f84787d38509..cecd71757360a0bee2d36d50bbf225eda914e606 100644
--- a/src/three_D_tools.h
+++ b/src/SE3.h
@@ -1,12 +1,12 @@
 /*
- * three_D_tools.h
+ * SE3.h
  *
  *  Created on: Mar 15, 2018
  *      Author: jsola
  */
 
-#ifndef THREE_D_TOOLS_H_
-#define THREE_D_TOOLS_H_
+#ifndef SE3_H_
+#define SE3_H_
 
 
 #include "wolf.h"
@@ -27,10 +27,11 @@
  *   - identity:    I  = Delta at the origin, with Dp = [0,0,0]; Dq = [0,0,0,1], so that D (+) I = I (+) D = D
  *   - inverse:     so that D (+) D.inv = D.inv (+) D = I
  *   - between:     Db = D2 (-) D1 := D1.inv (+) D2, so that D2 = D1 (+) Db
- *   - lift:        go from Delta manifold to tangent space (equivalent to log() in rotations)
- *   - retract:     go from tangent space to delta manifold (equivalent to exp() in rotations)
- *   - plus:        D2 = D1 (+) retract(d)
- *   - diff:        d  = lift( D2 (-) D1 )
+ *   - log_SE3:     go from Delta manifold to tangent space (equivalent to log() in rotations)
+ *   - exp_SE3:     go from tangent space to delta manifold (equivalent to exp() in rotations)
+ *   - plus:        D2 = D1 * exp_SE3(d)
+ *   - minus:       d  = log_SE3( D1.inv() * D2 )
+ *   - interpolate: dd = D1 * exp ( log( D1.inv() * D2 ) * t ) = D1 (+) ( (D2 (-) D1) * t)
  */
 
 
@@ -220,7 +221,7 @@ inline Matrix<typename D1::Scalar, 7, 1> between(const MatrixBase<D1>& d1,
 }
 
 template<typename Derived>
-Matrix<typename Derived::Scalar, 6, 1> lift(const MatrixBase<Derived>& delta_in)
+Matrix<typename Derived::Scalar, 6, 1> log_SE3(const MatrixBase<Derived>& delta_in)
 {
     MatrixSizeCheck<7, 1>::check(delta_in);
 
@@ -231,25 +232,32 @@ Matrix<typename Derived::Scalar, 6, 1> lift(const MatrixBase<Derived>& delta_in)
     Map<Matrix<typename Derived::Scalar, 3, 1> >         dp_ret ( & ret(0) );
     Map<Matrix<typename Derived::Scalar, 3, 1> >         do_ret ( & ret(3) );
 
-    dp_ret = dp_in;
-    do_ret = log_q(dq_in);
+    Matrix<typename Derived::Scalar, 3, 3> V_inv;
+
+    do_ret  = log_q(dq_in);
+    V_inv   = jac_SO3_left_inv(do_ret);
+    dp_ret  = V_inv * dp_in;
 
     return ret;
 }
 
 template<typename Derived>
-Matrix<typename Derived::Scalar, 7, 1> retract(const MatrixBase<Derived>& d_in)
+Matrix<typename Derived::Scalar, 7, 1> exp_SE3(const MatrixBase<Derived>& d_in)
 {
     MatrixSizeCheck<6, 1>::check(d_in);
 
     Matrix<typename Derived::Scalar, 7, 1> ret;
 
+    Matrix<typename Derived::Scalar, 3, 3> V;
+
+    V = jac_SO3_left(d_in.template tail<3>());
+
     Map<const Matrix<typename Derived::Scalar, 3, 1> >   dp_in  ( & d_in(0) );
     Map<const Matrix<typename Derived::Scalar, 3, 1> >   do_in  ( & d_in(3) );
     Map<Matrix<typename Derived::Scalar, 3, 1> >         dp     ( &  ret(0) );
     Map<Quaternion<typename Derived::Scalar> >           dq     ( &  ret(3) );
 
-    dp = dp_in;
+    dp = V * dp_in;
     dq = exp_q(do_in);
 
     return ret;
@@ -292,21 +300,21 @@ inline Matrix<typename D1::Scalar, 7, 1> plus(const MatrixBase<D1>& d1,
 }
 
 template<typename D1, typename D2, typename D4, typename D5, typename D7, typename D8>
-inline void diff(const MatrixBase<D1>& dp1, const QuaternionBase<D2>& dq1,
-                 const MatrixBase<D4>& dp2, const QuaternionBase<D5>& dq2,
-                 MatrixBase<D7>& diff_p, MatrixBase<D8>& diff_o )
+inline void minus(const MatrixBase<D1>& dp1, const QuaternionBase<D2>& dq1,
+                  const MatrixBase<D4>& dp2, const QuaternionBase<D5>& dq2,
+                  MatrixBase<D7>& diff_p, MatrixBase<D8>& diff_o )
 {
-        diff_p = dp2 - dp1;
-        diff_o = log_q(dq1.conjugate() * dq2);
+    diff_p = dp2 - dp1;
+    diff_o = log_q(dq1.conjugate() * dq2);
 }
 
 template<typename D1, typename D2, typename D4, typename D5, typename D6, typename D7, typename D8, typename D9>
-inline void diff(const MatrixBase<D1>& dp1, const QuaternionBase<D2>& dq1,
-                 const MatrixBase<D4>& dp2, const QuaternionBase<D5>& dq2,
-                 MatrixBase<D6>& diff_p, MatrixBase<D7>& diff_o,
-                 MatrixBase<D8>& J_do_dq1, MatrixBase<D9>& J_do_dq2)
+inline void minus(const MatrixBase<D1>& dp1, const QuaternionBase<D2>& dq1,
+                  const MatrixBase<D4>& dp2, const QuaternionBase<D5>& dq2,
+                  MatrixBase<D6>& diff_p, MatrixBase<D7>& diff_o,
+                  MatrixBase<D8>& J_do_dq1, MatrixBase<D9>& J_do_dq2)
 {
-    diff(dp1, dq1, dp2, dq2, diff_p, diff_o);
+    minus(dp1, dq1, dp2, dq2, diff_p, diff_o);
 
     J_do_dq1    = - jac_SO3_left_inv(diff_o);
     J_do_dq2    =   jac_SO3_right_inv(diff_o);
@@ -314,9 +322,9 @@ inline void diff(const MatrixBase<D1>& dp1, const QuaternionBase<D2>& dq1,
 
 
 template<typename D1, typename D2, typename D3>
-inline void diff(const MatrixBase<D1>& d1,
-                 const MatrixBase<D2>& d2,
-                 MatrixBase<D3>& err)
+inline void minus(const MatrixBase<D1>& d1,
+                  const MatrixBase<D2>& d2,
+                  MatrixBase<D3>& err)
 {
     Map<const Matrix<typename D1::Scalar, 3, 1> >   dp1    ( & d1(0) );
     Map<const Quaternion<typename D1::Scalar> >     dq1    ( & d1(3) );
@@ -325,15 +333,15 @@ inline void diff(const MatrixBase<D1>& d1,
     Map<Matrix<typename D3::Scalar, 3, 1> >         diff_p ( & err(0) );
     Map<Matrix<typename D3::Scalar, 3, 1> >         diff_o ( & err(3) );
 
-    diff(dp1, dq1, dp2, dq2, diff_p, diff_o);
+    minus(dp1, dq1, dp2, dq2, diff_p, diff_o);
 }
 
 template<typename D1, typename D2, typename D3, typename D4, typename D5>
-inline void diff(const MatrixBase<D1>& d1,
-                 const MatrixBase<D2>& d2,
-                 MatrixBase<D3>& dif,
-                 MatrixBase<D4>& J_diff_d1,
-                 MatrixBase<D5>& J_diff_d2)
+inline void minus(const MatrixBase<D1>& d1,
+                  const MatrixBase<D2>& d2,
+                  MatrixBase<D3>& dif,
+                  MatrixBase<D4>& J_diff_d1,
+                  MatrixBase<D5>& J_diff_d2)
 {
     Map<const Matrix<typename D1::Scalar, 3, 1> >   dp1    ( & d1(0) );
     Map<const Quaternion<typename D1::Scalar> >     dq1    ( & d1(3) );
@@ -347,9 +355,9 @@ inline void diff(const MatrixBase<D1>& d1,
 
     Matrix<typename D4::Scalar, 3, 3> J_do_dq1, J_do_dq2;
 
-    diff(dp1, dq1, dv1, dp2, dq2, dv2, diff_p, diff_o, diff_v, J_do_dq1, J_do_dq2);
+    minus(dp1, dq1, dv1, dp2, dq2, dv2, diff_p, diff_o, diff_v, J_do_dq1, J_do_dq2);
 
-    /* d = diff(d1, d2) is
+    /* d = minus(d1, d2) is
      *   dp = dp2 - dp1
      *   do = Log(dq1.conj * dq2)
      *   dv = dv2 - dv1
@@ -367,17 +375,111 @@ inline void diff(const MatrixBase<D1>& d1,
 }
 
 template<typename D1, typename D2>
-inline Matrix<typename D1::Scalar, 6, 1> diff(const MatrixBase<D1>& d1,
-                                              const MatrixBase<D2>& d2)
+inline Matrix<typename D1::Scalar, 6, 1> minus(const MatrixBase<D1>& d1,
+                                               const MatrixBase<D2>& d2)
 {
     Matrix<typename D1::Scalar, 6, 1> ret;
-    diff(d1, d2, ret);
+    minus(d1, d2, ret);
     return ret;
 }
 
+template<typename D1, typename D2, typename D3>
+inline void interpolate(const MatrixBase<D1>& d1,
+                        const MatrixBase<D2>& d2,
+                        const typename D1::Scalar& t,
+                        MatrixBase<D3>& ret)
+{
+    Matrix<typename D1::Scalar, 7, 1> dd = between(d1, d2);
+
+    Matrix<typename D1::Scalar, 6, 1> tau = t * log_SE3(dd);
+
+    ret = compose(d1, exp_SE3(tau));
+}
+
+template<typename D1, typename D2>
+inline void toSE3(const MatrixBase<D1>& pose,
+                        MatrixBase<D2>& SE3)
+{
+    MatrixSizeCheck<4,4>::check(SE3);
+
+    typedef typename D1::Scalar T;
+
+    SE3.template block<3,1>(0,3) = pose.template head<3>();
+    SE3.template block<3,3>(0,0) = q2R(pose.template tail<4>());
+    SE3.template block<1,3>(3,0).setZero();
+    SE3(3,3) = (T)1.0;
+}
+
+template<typename D1, typename D2>
+inline Matrix<typename D1::Scalar, 6, 6> Q_helper(const MatrixBase<D1>& v, const MatrixBase<D1>& w)
+{
+    typedef typename D1::Scalar T;
+
+    Matrix<T, 3, 3> V   = skew(v);
+    Matrix<T, 3, 3> W   = skew(w);
+    Matrix<T, 3, 3> VW  = V * W;
+    Matrix<T, 3, 3> WV  = VW.transpose();       // Note on this change wrt. Barfoot: it happens that V*W = (W*V).transpose() !!!
+    Matrix<T, 3, 3> WVW = WV * W;
+    Matrix<T, 3, 3> VWW = VW * W;
+
+    T th_2      = w.squaredNorm();
+
+    T A(T(0.5)), B, C, D;
+
+    // Small angle approximation
+    if (th_2 <= T(1e-8))
+    {
+        B =  Scalar(1./6.)  + Scalar(1./120.)  * th_2;
+        C = -Scalar(1./24.) + Scalar(1./720.)  * th_2;
+        D = -Scalar(1./60.);
+    }
+    else
+    {
+        T th        = sqrt(th_2);
+        T th_3      = th_2*th;
+        T th_4      = th_2*th_2;
+        T th_5      = th_3*th_2;
+        T sin_th    = sin(th);
+        T cos_th    = cos(th);
+        B           = (th-sin_th)/th_3;
+        C           = (T(1.0) - th_2/T(2.0) - cos_th)/th_4;
+        D           = (th - sin_th - th_3/T(6.0))/th_5;
+    }
+    Matrix<T, 3, 3> Q;
+    Q.noalias() =
+            + A * V
+            + B * (WV + VW + WVW)
+            - C * (VWW - VWW.transpose() - Scalar(3) * WVW)           // Note on this change wrt. Barfoot: it happens that V*W*W = -(W*W*V).transpose() !!!
+            - D * WVW * W;                                            // Note on this change wrt. Barfoot: it happens that W*V*W*W = W*W*V*W !!!
+
+    return Q;
+}
+
+template<typename D1>
+inline Matrix<typename D1::Scalar, 6, 6> jac_SE3_left(const MatrixBase<D1>& tangent)
+{
+    typedef typename D1::Scalar T;
+    Map<Matrix<T, 3, 1>> v(tangent.data() + 0); // linear
+    Map<Matrix<T, 3, 1>> w(tangent.data() + 3); // angular
+
+    Matrix<T, 3, 3> Jl(jac_SO3_left(w));
+    Matrix<T, 3, 3> Q = Q_helper(v,w);
+
+    Matrix<T, 6, 6> Jl_SE3;
+    Jl_SE3.topLeftCorner(3,3)     = Jl;
+    Jl_SE3.bottomRightCorner(3,3) = Jl;
+    Jl_SE3.topRightCorner(3,3)    = Q;
+    Jl_SE3.bottomLeftCorner(3,3)  .setZero();
+}
+
+template<typename D1>
+inline Matrix<typename D1::Scalar, 6, 6> jac_SE3_right(const MatrixBase<D1>& tangent)
+{
+    return jac_SE3_left(-tangent);
+}
 
 } // namespace three_d
 } // namespace wolf
 
 
-#endif /* THREE_D_TOOLS_H_ */
+#endif /* SE3_H_ */
diff --git a/src/ceres_wrapper/ceres_manager.h b/src/ceres_wrapper/ceres_manager.h
index efd9861bf380710ea027a06570f08910107a397a..8852bc06d3a0fe24fa2b760aa3766cb2e24cbf66 100644
--- a/src/ceres_wrapper/ceres_manager.h
+++ b/src/ceres_wrapper/ceres_manager.h
@@ -53,13 +53,13 @@ class CeresManager : public SolverManager
 
         virtual void computeCovariances(const StateBlockList& st_list) override;
 
-        virtual bool hasConverged();
+        virtual bool hasConverged() override;
 
-        virtual SizeStd iterations();
+        virtual SizeStd iterations() override;
 
-        virtual Scalar initialCost();
+        virtual Scalar initialCost() override;
 
-        virtual Scalar finalCost();
+        virtual Scalar finalCost() override;
 
         ceres::Solver::Options& getSolverOptions();
 
diff --git a/src/processor_motion.cpp b/src/processor_motion.cpp
index 08deb800317224f415bbb0b589f24967c4ad2716..0abab214309a12779c0d916ac559ca4afbbd1339 100644
--- a/src/processor_motion.cpp
+++ b/src/processor_motion.cpp
@@ -26,7 +26,7 @@ ProcessorMotion::ProcessorMotion(const std::string& _type,
         delta_cov_(_delta_cov_size, _delta_cov_size),
         delta_integrated_(_delta_size),
         delta_integrated_cov_(_delta_cov_size, _delta_cov_size),
-        calib_(_calib_size),
+        calib_preint_(_calib_size),
         jacobian_delta_preint_(delta_cov_size_, delta_cov_size_),
         jacobian_delta_(delta_cov_size_, delta_cov_size_),
         jacobian_calib_(delta_size_, calib_size_)
@@ -248,7 +248,7 @@ void ProcessorMotion::process(CaptureBasePtr _incoming_ptr)
         getProblem()->keyFrameCallback(key_frame_ptr, shared_from_this(), params_motion_->time_tolerance);
     }
 
-    resetDerived(); // TODO see where to put this
+    resetDerived();
 
     // clear incoming just in case
     incoming_ptr_ = nullptr; // This line is not really needed, but it makes things clearer.
@@ -274,7 +274,7 @@ bool ProcessorMotion::getState(const TimeStamp& _ts, Eigen::VectorXs& _x)
         CaptureBasePtr cap_orig   = capture_motion->getOriginFramePtr()->getCaptureOf(getSensorPtr());
         VectorXs calib            = cap_orig->getCalibration();
 
-        // Get delta and correct it with new bias
+        // Get delta and correct it with new calibration params
         VectorXs calib_preint     = capture_motion->getBuffer().getCalibrationPreint();
         Motion   motion           = capture_motion->getBuffer().getMotion(_ts);
         
@@ -296,35 +296,6 @@ bool ProcessorMotion::getState(const TimeStamp& _ts, Eigen::VectorXs& _x)
     return true;
 }
 
-//CaptureMotionPtr ProcessorMotion::findCaptureContainingTimeStamp(const TimeStamp& _ts) const
-//{
-//    //std::cout << "ProcessorMotion::findCaptureContainingTimeStamp: ts = " << _ts.getSeconds() << "." << _ts.getNanoSeconds() << std::endl;
-//    CaptureMotionPtr capture_ptr = last_ptr_;
-//    while (capture_ptr != nullptr)
-//    {
-//        // capture containing motion previous than the ts found:
-//        if (capture_ptr->getBuffer().get().front().ts_ < _ts)
-//            return capture_ptr;
-//        else
-//        {
-//            // go to the previous motion capture
-//            if (capture_ptr == last_ptr_)
-//                capture_ptr = origin_ptr_;
-//            else if (capture_ptr->getOriginFramePtr() == nullptr)
-//                return nullptr;
-//            else
-//            {
-//                CaptureBasePtr capture_base_ptr = capture_ptr->getOriginFramePtr()->getCaptureOf(getSensorPtr());
-//                if (capture_base_ptr == nullptr)
-//                    return nullptr;
-//                else
-//                    capture_ptr = std::static_pointer_cast<CaptureMotion>(capture_base_ptr);
-//            }
-//        }
-//    }
-//    return capture_ptr;
-//}
-
 FrameBasePtr ProcessorMotion::setOrigin(const Eigen::VectorXs& _x_origin, const TimeStamp& _ts_origin)
 {
     FrameBasePtr key_frame_ptr = getProblem()->emplaceFrame(KEY_FRAME, _x_origin, _ts_origin);
@@ -387,12 +358,12 @@ void ProcessorMotion::integrateOneStep()
     assert(dt_ >= 0 && "Time interval _dt is negative!");
 
     // get vector of parameters to calibrate
-    calib_ = getBuffer().getCalibrationPreint();
+    calib_preint_ = getBuffer().getCalibrationPreint();
 
     // get data and convert it to delta, and obtain also the delta covariance
     computeCurrentDelta(incoming_ptr_->getData(),
                         incoming_ptr_->getDataCovariance(),
-                        calib_,
+                        calib_preint_,
                         dt_,
                         delta_,
                         delta_cov_,
@@ -408,11 +379,14 @@ void ProcessorMotion::integrateOneStep()
 
     // integrate Jacobian wrt calib
     if ( hasCalibration() )
-        jacobian_calib_ = jacobian_delta_preint_ * getBuffer().get().back().jacobian_calib_ + jacobian_delta_ * jacobian_delta_calib_;
+        jacobian_calib_.noalias()
+            = jacobian_delta_preint_ * getBuffer().get().back().jacobian_calib_
+            + jacobian_delta_ * jacobian_delta_calib_;
 
     // Integrate covariance
-    delta_integrated_cov_ = jacobian_delta_preint_ * getBuffer().get().back().delta_integr_cov_ * jacobian_delta_preint_.transpose()
-                          + jacobian_delta_        * delta_cov_                                 * jacobian_delta_.transpose();
+    delta_integrated_cov_.noalias()
+            = jacobian_delta_preint_ * getBuffer().get().back().delta_integr_cov_ * jacobian_delta_preint_.transpose()
+            + jacobian_delta_        * delta_cov_                                 * jacobian_delta_.transpose();
 
     // push all into buffer
     getBuffer().get().emplace_back(incoming_ptr_->getTimeStamp(),
@@ -501,8 +475,53 @@ Motion ProcessorMotion::interpolate(const Motion& _ref, Motion& _second, TimeSta
     else
     {
         // _ts is closest to _second
-        Motion interpolated             ( _second );
+        Motion interpolated                 ( _second );
+        interpolated.ts_                    = _ts;
+        _second.data_                       . setZero();
+        _second.data_cov_                   . setZero();
+        _second.delta_                      = deltaZero();
+        _second.delta_cov_                  . setZero();
+        _second.jacobian_delta_integr_      . setIdentity();
+        _second.jacobian_delta_             . setZero();
+
+        return interpolated;
+    }
+
+}
+
+Motion ProcessorMotion::interpolate(const Motion& _ref1, const Motion& _ref2, const TimeStamp& _ts, Motion& _second)
+{
+    // Check time bounds
+    assert(_ref1.ts_ <= _ref2.ts_ && "Interpolation bounds not causal.");
+    assert(_ts >= _ref1.ts_       && "Interpolation time is before the _ref1 motion.");
+    assert(_ts <= _ref2.ts_       && "Interpolation time is after  the _ref2 motion.");
+
+    // Fraction of the time interval
+    Scalar tau    = (_ts - _ref1.ts_) / (_ref2.ts_ - _ref1.ts_);
+
+    if (tau < 0.5)
+    {
+        // _ts is closest to _ref1
+        Motion interpolated                 ( _ref1 );
+        interpolated.ts_                    = _ts;
+        interpolated.data_                  . setZero();
+        interpolated.data_cov_              . setZero();
+        interpolated.delta_                 = deltaZero();
+        interpolated.delta_cov_             . setZero();
+        interpolated.jacobian_delta_integr_ . setIdentity();
+        interpolated.jacobian_delta_        . setZero();
+
+        _second = _ref2;
+
+        return interpolated;
+    }
+    else
+    {
+        // _ts is closest to _ref2
+        Motion interpolated                 ( _ref2 );
         interpolated.ts_                    = _ts;
+
+        _second                             = _ref2;
         _second.data_                       . setZero();
         _second.data_cov_                   . setZero();
         _second.delta_                      = deltaZero();
@@ -518,7 +537,7 @@ Motion ProcessorMotion::interpolate(const Motion& _ref, Motion& _second, TimeSta
 CaptureMotionPtr ProcessorMotion::findCaptureContainingTimeStamp(const TimeStamp& _ts) const
 {
     // We need to search in previous keyframes for the capture containing a motion buffer with the queried time stamp
-    // Note: since the buffer goes from a FK through the past until the previous KF, we need to:
+    // Note: since the buffer goes from a KF in the past until the next KF, we need to:
     //  1. See that the KF contains a CaptureMotion
     //  2. See that the TS is smaller than the KF's TS
     //  3. See that the TS is bigger than the KF's first Motion in the CaptureMotion's buffer
@@ -533,7 +552,7 @@ CaptureMotionPtr ProcessorMotion::findCaptureContainingTimeStamp(const TimeStamp
         capture = frame->getCaptureOf(getSensorPtr());
         if (capture != nullptr)
         {
-            // We found a Capture belonging to this processor's Sensor ==> it is a CaptureMotion
+            // Rule 1 satisfied! We found a Capture belonging to this processor's Sensor ==> it is a CaptureMotion
             capture_motion = std::static_pointer_cast<CaptureMotion>(capture);
             if (_ts >= capture_motion->getBuffer().get().front().ts_)
                 // Found time stamp satisfying rule 3 above !! ==> break for loop
diff --git a/src/processor_motion.h b/src/processor_motion.h
index 4e20cab461bfb9cb5555f3091b1abd5d086d6573..e399bddcce6562e265d540c9e5699cd8e7f64193 100644
--- a/src/processor_motion.h
+++ b/src/processor_motion.h
@@ -372,6 +372,24 @@ class ProcessorMotion : public ProcessorBase
          */
         virtual Motion interpolate(const Motion& _ref, Motion& _second, TimeStamp& _ts);
 
+        /** \brief Interpolate motion to an intermediate time-stamp
+         *
+         * @param _ref1   The first motion reference
+         * @param _ref2   The second motion reference.
+         * @param _ts     The intermediate time stamp: it must be bounded by  `_ref.ts_ <= _ts <= _second.ts_`.
+         * @param _second The second part motion after interpolation, so that return (+) second = ref2.
+         * @return        The interpolated motion (see documentation below).
+         *
+         * This function interpolates a motion between two existing motions.
+         *
+         * In this base implementation, we just provide the closest motion provided (ref1 or ref2),
+         * the second motion being the complementary part,
+         * so really no interpolation takes place and just the current data and delta are updated.
+         *
+         * Should you require finer interpolation, you must overload this method in your derived class.
+         */
+        virtual Motion interpolate(const Motion& _ref1, const Motion& _ref2, const TimeStamp& _ts, Motion& _second);
+
         /** \brief create a CaptureMotion and add it to a Frame
          * \param _ts time stamp
          * \param _sensor Sensor that produced the Capture
@@ -399,6 +417,10 @@ class ProcessorMotion : public ProcessorBase
          * \param _capture_motion: the parent capture
          */
         FeatureBasePtr emplaceFeature(CaptureMotionPtr _capture_own);
+
+        /** \brief create a feature corresponding to given capture
+         * \param _capture_motion: the parent capture
+         */
         virtual FeatureBasePtr createFeature(CaptureMotionPtr _capture_own) = 0;
 
         /** \brief create a constraint and link it in the wolf tree
@@ -435,7 +457,7 @@ class ProcessorMotion : public ProcessorBase
         SizeEigen data_size_;        ///< the size of the incoming data
         SizeEigen delta_size_;       ///< the size of the deltas
         SizeEigen delta_cov_size_;   ///< the size of the delta covariances matrix
-        SizeEigen calib_size_;       ///< size of the extra parameters (TBD in derived classes)
+        SizeEigen calib_size_;       ///< the size of the calibration parameters (TBD in derived classes)
         CaptureMotionPtr origin_ptr_;
         CaptureMotionPtr last_ptr_;
         CaptureMotionPtr incoming_ptr_;
@@ -449,7 +471,7 @@ class ProcessorMotion : public ProcessorBase
         Eigen::MatrixXs delta_cov_;             ///< current delta covariance
         Eigen::VectorXs delta_integrated_;      ///< integrated delta
         Eigen::MatrixXs delta_integrated_cov_;  ///< integrated delta covariance
-        Eigen::VectorXs calib_;                 ///< calibration vector
+        Eigen::VectorXs calib_preint_;          ///< calibration vector used during pre-integration
         Eigen::MatrixXs jacobian_delta_preint_; ///< jacobian of delta composition w.r.t previous delta integrated
         Eigen::MatrixXs jacobian_delta_;        ///< jacobian of delta composition w.r.t current delta
         Eigen::MatrixXs jacobian_calib_;        ///< jacobian of delta preintegration wrt calibration params
diff --git a/src/processor_odom_2D.cpp b/src/processor_odom_2D.cpp
index fb1f567761e1a8d35b15aa019a78524fd47bfd16..19818dffcc1aee098c316f1b13bf603703333c39 100644
--- a/src/processor_odom_2D.cpp
+++ b/src/processor_odom_2D.cpp
@@ -5,10 +5,6 @@ namespace wolf
 ProcessorOdom2D::ProcessorOdom2D(ProcessorParamsOdom2DPtr _params) :
                 ProcessorMotion("ODOM 2D", 3, 3, 3, 2, 0, _params),
                 params_odom_2D_(_params)
-//                dist_traveled_th_(_params.dist_traveled_th_),
-//                theta_traveled_th_(_params.theta_traveled_th_),
-//                cov_det_th_(_params->cov_det_th)//,
-//                elapsed_time_th_(_params.elapsed_time_th_)
 {
     unmeasured_perturbation_cov_ = _params->unmeasured_perturbation_std * _params->unmeasured_perturbation_std * Matrix3s::Identity();
 }
@@ -21,16 +17,17 @@ void ProcessorOdom2D::computeCurrentDelta(const Eigen::VectorXs& _data, const Ei
                                           const Eigen::VectorXs& _calib, const Scalar _dt, Eigen::VectorXs& _delta,
                                           Eigen::MatrixXs& _delta_cov, Eigen::MatrixXs& _jacobian_calib)
 {
-    //std::cout << "ProcessorOdom2d::data2delta" << std::endl;
     assert(_data.size() == data_size_ && "Wrong _data vector size");
     assert(_data_cov.rows() == data_size_ && "Wrong _data_cov size");
     assert(_data_cov.cols() == data_size_ && "Wrong _data_cov size");
+
     // data  is [dtheta, dr]
     // delta is [dx, dy, dtheta]
     // motion model is 1/2 turn + straight + 1/2 turn
     _delta(0) = cos(_data(1) / 2) * _data(0);
     _delta(1) = sin(_data(1) / 2) * _data(0);
     _delta(2) = _data(1);
+
     // Fill delta covariance
     Eigen::MatrixXs J(delta_cov_size_, data_size_);
     J(0, 0) = cos(_data(1) / 2);
@@ -39,35 +36,29 @@ void ProcessorOdom2D::computeCurrentDelta(const Eigen::VectorXs& _data, const Ei
     J(0, 1) = -_data(0) * sin(_data(1) / 2) / 2;
     J(1, 1) = _data(0) * cos(_data(1) / 2) / 2;
     J(2, 1) = 1;
+
     // Since input data is size 2, and delta is size 3, the noise model must be given by:
     // 1. Covariance of the input data:  J*Q*J.tr
-    // 2. Fix variance term to be added: var*Id
+    // 2. Fixed variance term to be added: var*Id
     _delta_cov = J * _data_cov * J.transpose() + unmeasured_perturbation_cov_;
-    //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;
-    // jacobian_delta_calib_ not used in this class yet. In any case, set to zero with:
-    //    jacobian_delta_calib_.setZero();
 }
 
 void ProcessorOdom2D::deltaPlusDelta(const Eigen::VectorXs& _delta1, const Eigen::VectorXs& _delta2, const Scalar _Dt2,
                                      Eigen::VectorXs& _delta1_plus_delta2)
 {
-    // This is just a frame composition in 2D
-    //std::cout << "ProcessorOdom2d::deltaPlusDelta" << std::endl;
     assert(_delta1.size() == delta_size_ && "Wrong _delta1 vector size");
     assert(_delta2.size() == delta_size_ && "Wrong _delta2 vector size");
     assert(_delta1_plus_delta2.size() == delta_size_ && "Wrong _delta1_plus_delta2 vector size");
-    _delta1_plus_delta2.head<2>() = _delta1.head<2>() + Eigen::Rotation2Ds(_delta1(2)).matrix() * _delta2.head<2>();
-    _delta1_plus_delta2(2) = pi2pi(_delta1(2) + _delta2(2));
+
+    // This is just a frame composition in 2D
+    _delta1_plus_delta2.head<2>()   = _delta1.head<2>() + Eigen::Rotation2Ds(_delta1(2)).matrix() * _delta2.head<2>();
+    _delta1_plus_delta2(2)          = pi2pi(_delta1(2) + _delta2(2));
 }
 
 void ProcessorOdom2D::deltaPlusDelta(const Eigen::VectorXs& _delta1, const Eigen::VectorXs& _delta2, const Scalar _Dt2,
                                      Eigen::VectorXs& _delta1_plus_delta2, Eigen::MatrixXs& _jacobian1,
                                      Eigen::MatrixXs& _jacobian2)
 {
-    //std::cout << "ProcessorOdom2d::deltaPlusDelta jacobians" << std::endl;
     assert(_delta1.size() == delta_size_ && "Wrong _delta1 vector size");
     assert(_delta2.size() == delta_size_ && "Wrong _delta2 vector size");
     assert(_delta1_plus_delta2.size() == delta_size_ && "Wrong _delta1_plus_delta2 vector size");
@@ -75,12 +66,16 @@ void ProcessorOdom2D::deltaPlusDelta(const Eigen::VectorXs& _delta1, const Eigen
     assert(_jacobian1.cols() == delta_cov_size_ && "Wrong _jacobian1 size");
     assert(_jacobian2.rows() == delta_cov_size_ && "Wrong _jacobian2 size");
     assert(_jacobian2.cols() == delta_cov_size_ && "Wrong _jacobian2 size");
+
+    // This is just a frame composition in 2D
     _delta1_plus_delta2.head<2>() = _delta1.head<2>() + Eigen::Rotation2Ds(_delta1(2)).matrix() * _delta2.head<2>();
     _delta1_plus_delta2(2) = pi2pi(_delta1(2) + _delta2(2));
+
     // Jac wrt delta_integrated
     _jacobian1 = Eigen::MatrixXs::Identity(delta_cov_size_, delta_cov_size_);
     _jacobian1(0, 2) = -sin(_delta1(2)) * _delta2(0) - cos(_delta1(2)) * _delta2(1);
     _jacobian1(1, 2) = cos(_delta1(2)) * _delta2(0) - sin(_delta1(2)) * _delta2(1);
+
     // jac wrt delta
     _jacobian2 = Eigen::MatrixXs::Identity(delta_cov_size_, delta_cov_size_);
     _jacobian2.topLeftCorner<2, 2>() = Eigen::Rotation2Ds(_delta1(2)).matrix();
@@ -89,10 +84,10 @@ void ProcessorOdom2D::deltaPlusDelta(const Eigen::VectorXs& _delta1, const Eigen
 void ProcessorOdom2D::statePlusDelta(const Eigen::VectorXs& _x, const Eigen::VectorXs& _delta, const Scalar _Dt,
                                      Eigen::VectorXs& _x_plus_delta)
 {
-    // This is just a frame composition in 2D
-    //std::cout << "ProcessorOdom2d::statePlusDelta" << std::endl;
     assert(_x.size() == x_size_ && "Wrong _x vector size");
     assert(_x_plus_delta.size() == x_size_ && "Wrong _x_plus_delta vector size");
+
+    // This is just a frame composition in 2D
     _x_plus_delta.head<2>() = _x.head<2>() + Eigen::Rotation2Ds(_x(2)).matrix() * _delta.head<2>();
     _x_plus_delta(2) = pi2pi(_x(2) + _delta(2));
 }
diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt
index bac392115b91c812e8b079493ebe85b95ae3a8d2..cd99f0476dfe9eacbf0b7b63566f9306def8e554 100644
--- a/src/test/CMakeLists.txt
+++ b/src/test/CMakeLists.txt
@@ -94,7 +94,9 @@ target_link_libraries(gtest_processor_motion ${PROJECT_NAME})
   
 # Rotation test
 wolf_add_gtest(gtest_rotation gtest_rotation.cpp)
-#target_link_libraries(gtest_rotation ${PROJECT_NAME})
+
+# SE3 test
+wolf_add_gtest(gtest_SE3 gtest_SE3.cpp)
 
 # SensorBase test
 wolf_add_gtest(gtest_sensor_base gtest_sensor_base.cpp)
diff --git a/src/test/gtest_IMU_tools.cpp b/src/test/gtest_IMU_tools.cpp
index 14957c9791a4754c254319b90f1d93c4e7763225..9f0f8c398e1f7b51690228f5ff3f75be4e66b01d 100644
--- a/src/test/gtest_IMU_tools.cpp
+++ b/src/test/gtest_IMU_tools.cpp
@@ -129,7 +129,7 @@ TEST(IMU_tools, lift_retract)
     VectorXs d_min(9); d_min << 0, 1, 2, .3, .4, .5, 6, 7, 8; // use angles in the ball theta < pi
 
     // transform to delta
-    VectorXs delta = retract(d_min);
+    VectorXs delta = exp_IMU(d_min);
 
     // expected delta
     Vector3s dp = d_min.head(3);
@@ -139,11 +139,11 @@ TEST(IMU_tools, lift_retract)
     ASSERT_MATRIX_APPROX(delta, delta_true, 1e-10);
 
     // transform to a new tangent -- should be the original tangent
-    VectorXs d_from_delta = lift(delta);
+    VectorXs d_from_delta = log_IMU(delta);
     ASSERT_MATRIX_APPROX(d_from_delta, d_min, 1e-10);
 
     // transform to a new delta -- should be the previous delta
-    VectorXs delta_from_d = retract(d_from_delta);
+    VectorXs delta_from_d = exp_IMU(d_from_delta);
     ASSERT_MATRIX_APPROX(delta_from_d, delta, 1e-10);
 }
 
diff --git a/src/test/gtest_SE3.cpp b/src/test/gtest_SE3.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b734385b4a997e78d8b0de73573bbbe331009715
--- /dev/null
+++ b/src/test/gtest_SE3.cpp
@@ -0,0 +1,236 @@
+/**
+ * \file gtest_SE3.cpp
+ *
+ *  Created on: Feb 2, 2019
+ *      \author: jsola
+ */
+
+
+#include "../SE3.h"
+#include "utils_gtest.h"
+
+
+
+using namespace Eigen;
+using namespace wolf;
+using namespace three_D;
+
+TEST(SE3, exp_0)
+{
+    Vector6s tau = Vector6s::Zero();
+    Vector7s pose; pose << 0,0,0, 0,0,0,1;
+
+    ASSERT_MATRIX_APPROX(pose, exp_SE3(tau), 1e-8);
+}
+
+TEST(SE3, log_I)
+{
+    Vector7s pose; pose << 0,0,0, 0,0,0,1;
+    Vector6s tau = Vector6s::Zero();
+
+    ASSERT_MATRIX_APPROX(tau, log_SE3(pose), 1e-8);
+}
+
+TEST(SE3, exp_log)
+{
+    Vector6s tau = Vector6s::Random() / 5.0;
+    Vector7s pose = exp_SE3(tau);
+
+    ASSERT_MATRIX_APPROX(tau, log_SE3(exp_SE3(tau)), 1e-8);
+    ASSERT_MATRIX_APPROX(pose, exp_SE3(log_SE3(pose)), 1e-8);
+}
+
+TEST(SE3, exp_of_multiple)
+{
+    Vector6s tau, tau2, tau3;
+    Vector7s pose, pose2, pose3;
+    tau = Vector6s::Random() / 5;
+    pose << exp_SE3(tau);
+    tau2  = 2*tau;
+    tau3  = 3*tau;
+    pose2 = compose(pose, pose);
+    pose3 = compose(pose2, pose);
+
+    // 1
+    ASSERT_MATRIX_APPROX(exp_SE3(tau), pose, 1e-8);
+
+    // 2
+    ASSERT_MATRIX_APPROX(exp_SE3(tau2), pose2, 1e-8);
+
+    // 3
+    ASSERT_MATRIX_APPROX(exp_SE3(tau3), pose3, 1e-8);
+}
+
+TEST(SE3, log_of_power)
+{
+    Vector6s tau, tau2, tau3;
+    Vector7s pose, pose2, pose3;
+    tau = Vector6s::Random() / 5;
+    pose << exp_SE3(tau);
+    tau2 = 2*tau;
+    tau3 = 3*tau;
+    pose2 = compose(pose, pose);
+    pose3 = compose(pose2, pose);
+
+    // 1
+    ASSERT_MATRIX_APPROX(tau, log_SE3(pose), 1e-8);
+
+    // 2
+    ASSERT_MATRIX_APPROX(tau2, log_SE3(pose2), 1e-8);
+
+    // 3
+    ASSERT_MATRIX_APPROX(tau3, log_SE3(pose3), 1e-8);
+}
+
+TEST(SE3, interpolate_I_xyz)
+{
+    Vector7s p1, p2, p_pre;
+
+    p1 << 0,0,0, 0,0,0,1;
+    p2 << 1,2,3, 0,0,0,1;
+    Scalar t = 0.2;
+
+    interpolate(p1, p2, t, p_pre);
+
+    Vector7s p_gt; p_gt << 0.2,0.4,0.6, 0,0,0,1;
+
+    ASSERT_MATRIX_APPROX(p_pre, p_gt, 1e-8);
+}
+
+TEST(SE3, interpolate_xyz_xyz)
+{
+    Vector7s p1, p2, p_pre;
+
+    p1 << 1,2,3, 0,0,0,1;
+    p2 << 2,4,6, 0,0,0,1;
+    Scalar t = 0.2;
+
+    interpolate(p1, p2, t, p_pre);
+
+    Vector7s p_gt; p_gt << 1.2,2.4,3.6, 0,0,0,1;
+
+    ASSERT_MATRIX_APPROX(p_pre, p_gt, 1e-8);
+}
+
+TEST(SE3, interpolate_I_qx)
+{
+    Vector7s p1, p2, p_pre;
+
+    p1 << 0,0,0, 0,0,0,1;
+    p2 << 0,0,0, 1,0,0,0;
+    Scalar t = 0.5;
+
+    interpolate(p1, p2, t, p_pre);
+
+    Vector7s p_gt; p_gt << 0,0,0, sqrt(2)/2,0,0,sqrt(2)/2;
+
+    ASSERT_MATRIX_APPROX(p_pre, p_gt, 1e-8);
+}
+
+TEST(SE3, interpolate_I_qy)
+{
+    Vector7s p1, p2, p_pre;
+
+    p1 << 0,0,0, 0,0,0,1;
+    p2 << 0,0,0, 0,1,0,0;
+    Scalar t = 0.5;
+
+    interpolate(p1, p2, t, p_pre);
+
+    Vector7s p_gt; p_gt << 0,0,0, 0,sqrt(2)/2,0,sqrt(2)/2;
+
+    ASSERT_MATRIX_APPROX(p_pre, p_gt, 1e-8);
+}
+
+TEST(SE3, interpolate_I_qz)
+{
+    Vector7s p1, p2, p_pre;
+
+    p1 << 0,0,0, 0,0,0,1;
+    p2 << 0,0,0, 0,0,1,0;
+    Scalar t = 0.5;
+
+    interpolate(p1, p2, t, p_pre);
+
+    Vector7s p_gt; p_gt << 0,0,0, 0,0,sqrt(2)/2,sqrt(2)/2;
+
+    ASSERT_MATRIX_APPROX(p_pre, p_gt, 1e-8);
+}
+
+TEST(SE3, interpolate_I_qxyz)
+{
+    Vector7s p1, p2, dp, p_pre, p_gt;
+    Vector3s da;
+
+    da.setRandom(); da /= 5;
+
+    p1 << 0,0,0, 0,0,0,1;
+    dp << 0,0,0, exp_q(da).coeffs();
+    p_gt = compose(p1, dp);
+    p2   = compose(p_gt, dp);
+    Scalar t = 0.5;
+
+    interpolate(p1, p2, t, p_pre);
+
+    ASSERT_MATRIX_APPROX(p_pre, p_gt, 1e-8);
+}
+
+TEST(SE3, interpolate_half)
+{
+    Vector7s p1, p2, dp, p_pre, p_gt;
+    Vector6s da;
+
+    p1.setRandom(); p1.tail(4).normalize();
+
+    da.setRandom(); da /= 5; // small rotation
+    dp  << exp_SE3(da);
+
+    // compose double, then interpolate 1/2
+
+    p_gt = compose(p1, dp);
+    p2   = compose(p_gt, dp);
+
+    Scalar t = 0.5;
+    interpolate(p1, p2, t, p_pre);
+
+    ASSERT_MATRIX_APPROX(p_pre, p_gt, 1e-8);
+}
+
+TEST(SE3, interpolate_third)
+{
+    Vector7s p1, p2, dp, dp2, dp3, p_pre, p_gt;
+    Vector6s da;
+
+    p1.setRandom(); p1.tail(4).normalize();
+
+    da.setRandom(); da /= 5; // small rotation
+    dp  << exp_SE3(da);
+    dp2 = compose(dp, dp);
+    dp3 = compose(dp2, dp);
+
+    // compose triple, then interpolate 1/3
+
+    p_gt = compose(p1, dp);
+    p2   = compose(p1, dp3);
+
+    Scalar t = 1.0/3.0;
+    interpolate(p1, p2, t, p_pre);
+
+    ASSERT_MATRIX_APPROX(p_pre, p_gt, 1e-8);
+}
+
+TEST(SE3, toSE3_I)
+{
+    Vector7s pose; pose << 0,0,0, 0,0,0,1;
+    Matrix4s R;
+    toSE3(pose, R);
+
+    ASSERT_MATRIX_APPROX(R, Matrix4s::Identity(), 1e-8);
+}
+
+int main(int argc, char **argv)
+{
+  testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
+
diff --git a/src/test/gtest_odom_2D.cpp b/src/test/gtest_odom_2D.cpp
index da1e5ca48bf5fd9f0e96217426cbb31f73be5772..d8e10b949a137e718d1ca51502e94671d8379e09 100644
--- a/src/test/gtest_odom_2D.cpp
+++ b/src/test/gtest_odom_2D.cpp
@@ -16,6 +16,7 @@
 #include "../state_block.h"
 #include "../wolf.h"
 #include "../ceres_wrapper/ceres_manager.h"
+#include "../capture_pose.h"
 
 // STL includes
 #include <map>
@@ -26,7 +27,6 @@
 // General includes
 #include <iostream>
 #include <iomanip>      // std::setprecision
-#include "../capture_pose.h"
 
 using namespace wolf;
 using namespace Eigen;
@@ -124,7 +124,7 @@ TEST(Odom2D, ConstraintFix_and_ConstraintOdom2D)
     Matrix3s delta_cov; delta_cov << .02, 0, 0, 0, .025, .02, 0, .02, .02;
 
     ProblemPtr          Pr = Problem::create("PO 2D");
-    CeresManager ceres_manager(Pr);
+    CeresManager        ceres_manager(Pr);
 
     // KF0 and absolute prior
     FrameBasePtr        F0 = Pr->setPrior(x0, P0,t0, dt/2);
diff --git a/src/test/gtest_processor_motion.cpp b/src/test/gtest_processor_motion.cpp
index 77d2a55186ae6084f54e6832c71bc88067edc081..94a2f0c15f61439d8f5d800d893d6ae95f45016a 100644
--- a/src/test/gtest_processor_motion.cpp
+++ b/src/test/gtest_processor_motion.cpp
@@ -29,13 +29,17 @@ class ProcessorMotion_test : public ProcessorOdom2D, public testing::Test{
         Vector2s            data;
         Matrix2s            data_cov;
 
-        ProcessorMotion_test() : ProcessorOdom2D(std::make_shared<ProcessorParamsOdom2D>()) { }
+        ProcessorMotion_test() :
+            ProcessorOdom2D(std::make_shared<ProcessorParamsOdom2D>()),
+            dt(0)
+        { }
 
         virtual void SetUp()
         {
-            dt                          = 1.0;
+            dt                      = 1.0;
             problem = Problem::create("PO 2D");
             ProcessorParamsOdom2DPtr params(std::make_shared<ProcessorParamsOdom2D>());
+            params->time_tolerance  = 0.25;
             params->dist_traveled   = 100;
             params->angle_turned    = 6.28;
             params->max_time_span   = 2.5*dt; // force KF at every third process()
@@ -52,19 +56,6 @@ class ProcessorMotion_test : public ProcessorOdom2D, public testing::Test{
 
         virtual void TearDown(){}
 
-        virtual Motion interpolate(const Motion& _ref,
-                                   Motion& _second,
-                                   TimeStamp& _ts)
-        {
-            return ProcessorMotion::interpolate(_ref, _second, _ts);
-        }
-
-        virtual Motion motionZero(TimeStamp& t)
-        {
-            return ProcessorOdom2D::motionZero(t);
-        }
-
-
 };
 
 
@@ -93,7 +84,7 @@ TEST_F(ProcessorMotion_test, IntegrateCircle)
     data_cov.setIdentity();
     TimeStamp t(0.0);
 
-    for (int i = 0; i<10; i++) // one full turn
+    for (int i = 0; i<10; i++) // one full turn exactly
     {
         t += dt;
         capture->setTimeStamp(t);
@@ -108,13 +99,13 @@ TEST_F(ProcessorMotion_test, IntegrateCircle)
 
 TEST_F(ProcessorMotion_test, Interpolate)
 {
-    data << 1, 2*M_PI/10; // advance straight
+    data << 1, 2*M_PI/10; // advance in turn
     data_cov.setIdentity();
     TimeStamp t(0.0);
     std::vector<Motion> motions;
     motions.push_back(motionZero(t));
 
-    for (int i = 0; i<10; i++)
+    for (int i = 0; i<10; i++) // one full turn exactly
     {
         t += dt;
         capture->setTimeStamp(t);