diff --git a/src/features/feature_diff_drive.cpp b/src/features/feature_diff_drive.cpp
index ae1f8a2b3a3298824ffd6703786d901b272a88c6..c33d5fdec4e487e4e1b8893625ba140b60b4f54e 100644
--- a/src/features/feature_diff_drive.cpp
+++ b/src/features/feature_diff_drive.cpp
@@ -13,7 +13,7 @@ FeatureDiffDrive::FeatureDiffDrive(const Eigen::VectorXs& _delta_preintegrated,
   //
 }
 
-const Eigen::VectorXs& FeatureDiffDrive::getJacobianFactor() const
+const Eigen::MatrixXs& FeatureDiffDrive::getJacobianFactor() const
 {
   return jacobian_diff_drive_factors_;
 }
diff --git a/src/features/feature_diff_drive.h b/src/features/feature_diff_drive.h
index ac13c490717c66b54c652d9f93e49387672a1d1c..5c837469b577cf411eb8c830e2941823d1a0d91f 100644
--- a/src/features/feature_diff_drive.h
+++ b/src/features/feature_diff_drive.h
@@ -26,12 +26,12 @@ public:
 
   virtual ~FeatureDiffDrive() = default;
 
-  const Eigen::VectorXs& getJacobianFactor() const;
+  const Eigen::MatrixXs& getJacobianFactor() const;
 
 protected:
 
   Eigen::VectorXs diff_drive_factors_;
-  Eigen::VectorXs jacobian_diff_drive_factors_;
+  Eigen::MatrixXs jacobian_diff_drive_factors_;
 };
 
 } /* namespace wolf */
diff --git a/src/sensors/sensor_diff_drive.cpp b/src/sensors/sensor_diff_drive.cpp
index 0931b700ce658b486823fa930e3f1c454f87be5e..4c57144c96375f6c077d90ea20fde5ad027e488d 100644
--- a/src/sensors/sensor_diff_drive.cpp
+++ b/src/sensors/sensor_diff_drive.cpp
@@ -33,7 +33,7 @@ SensorBasePtr SensorDiffDrive::create(const std::string& _unique_name,
 
   StateBlockPtr pos_ptr = std::make_shared<StateBlock>(_extrinsics_po.head(2), true);
   StateBlockPtr ori_ptr = std::make_shared<StateBlock>(_extrinsics_po.tail(1), true);
-  StateBlockPtr int_ptr = std::make_shared<StateBlock>(params->factors_,       true);
+  StateBlockPtr int_ptr = std::make_shared<StateBlock>(params->factors_,       false);
 
   SensorBasePtr odo = std::make_shared<SensorDiffDrive>(pos_ptr, ori_ptr, int_ptr, params);
 
@@ -41,7 +41,7 @@ SensorBasePtr SensorDiffDrive::create(const std::string& _unique_name,
 
   /// @todo make calibration optional at creation
   //if (calibrate)
-    odo->unfixIntrinsics();
+  //  odo->unfixIntrinsics();
 
   return odo;
 }
diff --git a/src/sensors/sensor_diff_drive.h b/src/sensors/sensor_diff_drive.h
index f4556a84a16c7a347f27a6f7f51ce913c02dc477..749772902dcf39e035b318705a4797028c896d5b 100644
--- a/src/sensors/sensor_diff_drive.h
+++ b/src/sensors/sensor_diff_drive.h
@@ -14,6 +14,9 @@
 
 namespace wolf {
 
+WOLF_STRUCT_PTR_TYPEDEFS(IntrinsicsDiffDrive);
+WOLF_STRUCT_PTR_TYPEDEFS(SensorDiffDrive);
+
 struct IntrinsicsDiffDrive : public IntrinsicsBase
 {
   Scalar left_radius_;
diff --git a/src/test/gtest_odom_2D.cpp b/src/test/gtest_odom_2D.cpp
index 2f3da744717fa0c9a8d99e6d163a09f0a16ea77c..ef833a48a77679f658627edc3be1a7a68f972769 100644
--- a/src/test/gtest_odom_2D.cpp
+++ b/src/test/gtest_odom_2D.cpp
@@ -354,12 +354,16 @@ TEST(Odom2D, KF_callback)
     // Capture to use as container for all incoming data
     CaptureMotionPtr capture = std::make_shared<CaptureMotion>("ODOM 2D", t, sensor_odom2d, data, data_cov, 3, 3, nullptr);
 
+    std::cout << "t: " << t << std::endl;
     for (int n=1; n<=N; n++)
     {
         t += dt;
 
         // re-use capture with updated timestamp
         capture->setTimeStamp(t);
+        std::cout << "capture ts: " << capture->getTimeStamp() << " - " << capture->getTimeStamp().get();
+        std::cout << "nsec:        " << capture->getTimeStamp().getNanoSeconds() << std::endl;
+        std::cout << "filled nsec: " << std::setfill('0') << std::setw(9) << std::right << capture->getTimeStamp().getNanoSeconds() << std::endl;
 
         // Processor
         sensor_odom2d->process(capture);
@@ -388,9 +392,9 @@ TEST(Odom2D, KF_callback)
     ////////////////////////////////////////////////////////////////
     // Split after the last keyframe, exact timestamp
     int n_split = 8;
-    TimeStamp t_split (t0 + n_split*dt);
+    TimeStamp t_split = t0 + n_split*dt;
 
-//    std::cout << "-----------------------------\nSplit after last KF; time: " << t_split - t0 << std::endl;
+    std::cout << "-----------------------------\nSplit after last KF; time: " << t_split << std::endl;
 
     Vector3s x_split = processor_odom2d->getState(t_split);
     FrameBasePtr keyframe_2 = problem->emplaceFrame(KEY_FRAME, x_split, t_split);
@@ -418,7 +422,7 @@ TEST(Odom2D, KF_callback)
     // Split between keyframes, exact timestamp
     int m_split = 4;
     t_split = t0 + m_split*dt;
-//    std::cout << "-----------------------------\nSplit between KFs; time: " << t_split - t0 << std::endl;
+    std::cout << "-----------------------------\nSplit between KFs; time: " << t_split << std::endl;
 
     problem->print(4,1,1,1);
 
@@ -445,6 +449,8 @@ TEST(Odom2D, KF_callback)
     report = ceres_manager.solve(SolverManager::ReportVerbosity::BRIEF);
     ceres_manager.computeCovariances(SolverManager::CovarianceBlocksToBeComputed::ALL_MARGINALS);
 
+    problem->print(4,1,1,1);
+
     // check the split KF
     ASSERT_POSE2D_APPROX(keyframe_1->getState()                  , integrated_pose_vector[m_split], 1e-6);
     ASSERT_MATRIX_APPROX(problem->getFrameCovariance(keyframe_1) , integrated_cov_vector [m_split], 1e-6); // FIXME test does not pass
diff --git a/src/test/gtest_time_stamp.cpp b/src/test/gtest_time_stamp.cpp
index 73a69606e77a8dd45b33bf8789a742db06f062a3..a5feaf39b5e6467866ee89235ccd9579ffa6f568 100644
--- a/src/test/gtest_time_stamp.cpp
+++ b/src/test/gtest_time_stamp.cpp
@@ -39,7 +39,7 @@ TEST(WolfTestTimeStamp, TimeStampInitScalar)
   std::stringstream ss;
   start.print(ss);
 
-  ASSERT_STREQ("101010.0000000000", ss.str().c_str());
+  ASSERT_STREQ("101010.000000000", ss.str().c_str());
 
 //  PRINTF("All good at WolfTestTimeStamp::TimeStampInitScalar !\n");
 }
@@ -61,11 +61,58 @@ TEST(WolfTestTimeStamp, TimeStampInitScalarSecNano)
   std::stringstream ss;
   start.print(ss);
 
-  ASSERT_STREQ("101010.0002020200", ss.str().c_str());
+  ASSERT_STREQ("101010.000202020", ss.str().c_str());
 
 //  PRINTF("All good at WolfTestTimeStamp::TimeStampInitScalarSecNano !\n");
 }
 
+TEST(WolfTestTimeStamp, TimeStampSetNow)
+{
+  wolf::TimeStamp t1;
+  wolf::TimeStamp t2(t1);
+
+  ASSERT_EQ(t1,t2);
+
+  // If we don't sleep, start == time_stamp sometimes.
+  // And sometimes start <= time_stamp ...
+  std::this_thread::sleep_for(std::chrono::microseconds(1));
+
+  t2.setToNow();
+
+  ASSERT_LT(t1,t2);
+}
+
+TEST(WolfTestTimeStamp, TimeStampSetScalar)
+{
+  wolf::Scalar val(101010.000202020);
+
+  wolf::TimeStamp start;
+  start.set(val);
+
+  ASSERT_EQ(start.get(), val);
+  ASSERT_EQ(start.getSeconds(), 101010);
+  ASSERT_EQ(start.getNanoSeconds(), 202020);
+
+  std::stringstream ss;
+  start.print(ss);
+
+  ASSERT_STREQ("101010.000202020", ss.str().c_str());
+}
+
+TEST(WolfTestTimeStamp, TimeStampSetSecNano)
+{
+  unsigned long int sec(101010);
+  unsigned long int nano(202020);
+
+  wolf::TimeStamp start;
+  start.set(sec,nano);
+
+  // start.get -> 101010.000202020004508
+
+  ASSERT_EQ(start.getSeconds(), sec);
+  ASSERT_EQ(start.getNanoSeconds(), nano);
+}
+
 TEST(WolfTestTimeStamp, TimeStampEquality)
 {
   wolf::TimeStamp start;
@@ -111,14 +158,40 @@ TEST(WolfTestTimeStamp, TimeStampInequality)
 //  PRINTF("All good at WolfTestTimeStamp::TimeStampInequality !\n");
 }
 
+TEST(WolfTestTimeStamp, TimeStampSubstraction)
+{
+  wolf::TimeStamp t1;
+  wolf::TimeStamp t2(t1);
+  wolf::Scalar dt(1e-5);
+
+  t2+=dt;
+
+  ASSERT_LT(t1, t2);
+  ASSERT_EQ(t2-t1, dt);
+  ASSERT_EQ(t1-t2, -dt);
+}
+
+TEST(WolfTestTimeStamp, TimeStampAdding)
+{
+  wolf::TimeStamp t1,t3;
+  wolf::TimeStamp t2(t1);
+  wolf::Scalar dt(1e-5);
+
+  t2 +=dt;
+  t3 = t1+dt;
+
+  ASSERT_EQ(t2, t3);
+}
+
 TEST(WolfTestTimeStamp, TimeStampOperatorOstream)
 {
     wolf::TimeStamp t(5);
     wolf::Scalar dt = 1e-4;
     t+=dt;
+
     std::ostringstream ss1, ss2;
+    t.print(ss1);
 
-    ss1 << t.get();
     ss2 << t;
 
     ASSERT_EQ(ss1.str(), ss2.str());
@@ -126,6 +199,19 @@ TEST(WolfTestTimeStamp, TimeStampOperatorOstream)
 //    PRINTF("All good at WolfTestTimeStamp::TimeStampOperatorOstream !\n");
 }
 
+TEST(WolfTestTimeStamp, TimeStampSecNanoSec)
+{
+    unsigned long int sec = 5;
+    unsigned long int nano = 1e5;
+    wolf::TimeStamp t1(wolf::Scalar(sec)+wolf::Scalar(nano)*1e-9);
+    wolf::TimeStamp t2(sec,nano);
+
+    ASSERT_EQ(t1.getSeconds(),sec);
+    ASSERT_EQ(t2.getSeconds(),sec);
+    ASSERT_EQ(t1.getNanoSeconds(),nano);
+    ASSERT_EQ(t2.getNanoSeconds(),nano);
+}
+
 int main(int argc, char **argv)
 {
   testing::InitGoogleTest(&argc, argv);
diff --git a/src/time_stamp.cpp b/src/time_stamp.cpp
index 738ff922b19ba77cfefc2bc19117fa294011a2e2..3ec68441b044a87ea38725708ed3f5b424b0f326 100644
--- a/src/time_stamp.cpp
+++ b/src/time_stamp.cpp
@@ -5,35 +5,33 @@ namespace wolf {
 
 std::ostream& operator<<(std::ostream& os, const TimeStamp& _ts)
 {
-    //    std::ios_base::fmtflags fmtfl;
-    //
-    //    //get/set ostream flags and precision digits
-    //    fmtfl = os.flags(std::ios::left);
-    //    os.setf(std::ios::fixed, std::ios::floatfield);
-
-    //    std::streamsize nn;
-    //    nn = os.precision(TimeStamp::TIME_STAMP_DIGITS_);
-
-    os << _ts.getSeconds() << "." << _ts.getNanoSeconds(); // write obj to stream
+    os << _ts.getSeconds() << "." << std::setfill('0') << std::setw(9) << std::right <<_ts.getNanoSeconds(); // write obj to stream
     return os;
 }
 
 
 
 TimeStamp::TimeStamp() :
-        time_stamp_(0)
+        //time_stamp_(0)
+        time_stamp_nano_(0)
 {
     setToNow();
 }
 
-TimeStamp::TimeStamp(const Scalar _ts) :
-        time_stamp_(_ts)
+TimeStamp::TimeStamp(const TimeStamp& _ts) :
+        time_stamp_nano_(_ts.time_stamp_nano_)
+{
+    //
+}
+
+TimeStamp::TimeStamp(const Scalar& _ts) :
+        time_stamp_nano_(_ts > 0 ? (unsigned long int)(_ts*1e9) : 0)
 {
     //
 }
 
-TimeStamp::TimeStamp(const unsigned long int _sec, const unsigned long int _nsec) :
-        time_stamp_((Scalar)_sec + (Scalar)_nsec/(Scalar)1e9)
+TimeStamp::TimeStamp(const unsigned long int& _sec, const unsigned long int& _nsec) :
+        time_stamp_nano_(_sec*NANOSECS+_nsec)
 {
     //
 }
@@ -47,39 +45,32 @@ void TimeStamp::setToNow()
 {
     timeval ts;
     gettimeofday(&ts, NULL);
-    time_stamp_ = (Scalar)((ts.tv_sec)) + (Scalar)((ts.tv_usec)) / 1e6;
+    set(ts);
 }
 
-unsigned long int TimeStamp::getSeconds() const
+TimeStamp TimeStamp::operator +(const Scalar& dt) const
 {
-    unsigned long int ts;
-    ts = (unsigned long int)(((floor(time_stamp_))));
+    TimeStamp ts(*this);
+    ts += dt;
     return ts;
 }
 
-unsigned long int TimeStamp::getNanoSeconds() const
+TimeStamp TimeStamp::operator -(const Scalar& dt) const
 {
-    Scalar ts;
-    ts = (Scalar)(((floor(time_stamp_))));
-    return (unsigned long int)(((time_stamp_ - ts) * 1e9));
+    TimeStamp ts(*this);
+    ts -= dt;
+    return ts;
 }
 
-void TimeStamp::print(std::ostream & ost) const
+inline void TimeStamp::operator -=(const Scalar& dt)
 {
-    std::streamsize nn;
-    std::ios_base::fmtflags fmtfl;
-
-    //get/set ostream flags and precision digits
-    fmtfl = ost.flags(std::ios::left);
-    ost.setf(std::ios::fixed, std::ios::floatfield);
-    nn = ost.precision(TIME_STAMP_DIGITS_);
-
-    //send to ostream
-    ost << this->time_stamp_;
+    unsigned long int dt_nano = (unsigned long int)(dt*NANOSECS);
+    time_stamp_nano_ = (dt_nano > time_stamp_nano_ ? 0 : time_stamp_nano_ - dt_nano);
+}
 
-    //restore flags and precision
-    ost.flags(fmtfl);
-    ost.precision(nn);
+void TimeStamp::print(std::ostream & ost) const
+{
+    ost << *this;
 }
 
 } // namespace wolf
diff --git a/src/time_stamp.h b/src/time_stamp.h
index d3902e82f2732bfc63c23a3b223a721435bdadb1..d38d25b5fa10b40d0374a5c518681802fac1ffea 100644
--- a/src/time_stamp.h
+++ b/src/time_stamp.h
@@ -8,7 +8,9 @@
 //C, std
 #include <sys/time.h>
 #include <iostream>
+#include <iomanip>
 
+static const unsigned int NANOSECS = 1000000000;
 
 namespace wolf {
 
@@ -19,9 +21,8 @@ namespace wolf {
  */
 class TimeStamp
 {
-    private:
-        Scalar time_stamp_; ///< Time stamp. Expressed in seconds from 1th jan 1970.
-        static const unsigned int TIME_STAMP_DIGITS_ = 10; ///< Number of digits to print time stamp values        
+    protected:
+        unsigned long int time_stamp_nano_; ///< Time stamp. Expressed in nanoseconds from 1th jan 1970.
 
     public:
         /** \brief Constructor
@@ -31,19 +32,26 @@ class TimeStamp
          */
         TimeStamp();
 
+        /** \brief Copy constructor
+         *
+         * Copy constructor
+         *
+         */
+        TimeStamp(const TimeStamp& _ts);
+
         /** \brief Constructor with argument
          *
          * Constructor with arguments
          *
          */
-        TimeStamp(const Scalar _ts);
+        TimeStamp(const Scalar& _ts);
 
         /** \brief Constructor from sec and nsec
          *
          * Constructor from sec and nsec
          *
          */
-        TimeStamp(const unsigned long int _sec, const unsigned long int _nsec);
+        TimeStamp(const unsigned long int& _sec, const unsigned long int& _nsec);
 
         /** \brief Destructor
          *
@@ -67,14 +75,14 @@ class TimeStamp
          * Sets time stamp to a given value passed as a two-integer (seconds and nanoseconds)
          *
          */
-        void set(const unsigned long int sec, const unsigned long int nanosec);
+        void set(const unsigned long int& sec, const unsigned long int& nanosec);
 
         /** \brief Set time stamp
          *
          * Sets time stamp to a given value passed as a scalar_t (seconds)
          *
          */
-        void set(const Scalar ts);
+        void set(const Scalar& ts);
 
         /** \brief Get time stamp
          *
@@ -129,13 +137,6 @@ class TimeStamp
         bool operator <=(const TimeStamp& ts) const;
         bool operator >=(const TimeStamp& ts) const;
 
-        /** \brief difference operator
-         * 
-         * difference operator that returns a scalar_t (seconds)
-         * 
-         */
-        Scalar operator -(const TimeStamp& ts) const;
-
         /** \brief Add-assign operator given a scalar_t (seconds)
          */
         void operator +=(const Scalar& dt);
@@ -144,6 +145,24 @@ class TimeStamp
          */
         TimeStamp operator +(const Scalar& dt) const;
 
+        /** \brief Substraction-assign operator given a scalar_t (seconds)
+         */
+        void operator -=(const Scalar& dt);
+
+        /** \brief difference operator
+         * 
+         * difference operator that returns a scalar_t (seconds)
+         * 
+         */
+        TimeStamp operator -(const Scalar& ts) const;
+
+        /** \brief difference operator
+         *
+         * difference operator that returns a Timestamp (seconds)
+         *
+         */
+        Scalar operator -(const TimeStamp& ts) const;
+
         /** \brief Prints time stamp to a given ostream
          *
          * Prints time stamp to a given ostream
@@ -155,79 +174,84 @@ class TimeStamp
 
 };
 
-inline void TimeStamp::set(const Scalar ts)
+inline void TimeStamp::set(const Scalar& ts)
 {
-    time_stamp_ = ts;
+    time_stamp_nano_ = (ts > 0 ? (unsigned long int)(ts*NANOSECS) : 0);
 }
 
-inline void TimeStamp::set(const unsigned long int sec, const unsigned long int nanosec)
+inline void TimeStamp::set(const unsigned long int& sec, const unsigned long int& nanosec)
 {
-    time_stamp_ = (Scalar)(sec) + (Scalar)(nanosec) / (Scalar)(1e9);
+    time_stamp_nano_ = sec*NANOSECS+nanosec;
 }
 
 inline void TimeStamp::set(const timeval& ts)
 {
-    time_stamp_ = (Scalar)(ts.tv_sec) + (Scalar)(ts.tv_usec) / 1e6;
+    time_stamp_nano_ = (unsigned long int)(ts.tv_sec*NANOSECS) + (unsigned long int)(ts.tv_usec*1000);
 }
 
 inline Scalar TimeStamp::get() const
 {
-    return time_stamp_;
+    return ((Scalar)( time_stamp_nano_))*1e-9;
+}
+
+inline unsigned long int TimeStamp::getSeconds() const
+{
+    return time_stamp_nano_ / NANOSECS;
+}
+
+inline unsigned long int TimeStamp::getNanoSeconds() const
+{
+    return time_stamp_nano_ % NANOSECS;
 }
 
 inline void TimeStamp::operator =(const TimeStamp& ts)
 {
-    time_stamp_ = ts.get();
+    time_stamp_nano_ = ts.time_stamp_nano_;
 }
 
 inline void TimeStamp::operator =(const Scalar& ts)
 {
-    time_stamp_ = ts;
+    time_stamp_nano_ = (unsigned long int)(ts*NANOSECS);
 }
 
 inline bool TimeStamp::operator ==(const TimeStamp& ts) const
 {
-    return (time_stamp_ == ts.get());
+    return (time_stamp_nano_ == ts.time_stamp_nano_);
 }
 
 inline bool TimeStamp::operator !=(const TimeStamp& ts) const
 {
-    return (time_stamp_ != ts.get());
+    return (time_stamp_nano_ != ts.time_stamp_nano_);
 }
 
 inline bool TimeStamp::operator <(const TimeStamp& ts) const
 {
-    return (time_stamp_ < ts.get());
+    return (time_stamp_nano_ < ts.time_stamp_nano_);
 }
 
 inline bool TimeStamp::operator >(const TimeStamp& ts) const
 {
-    return (time_stamp_ > ts.get());
+    return (time_stamp_nano_ > ts.time_stamp_nano_);
 }
 
 inline bool TimeStamp::operator <=(const TimeStamp& ts) const
 {
-    return (time_stamp_ <= ts.get());
+    return (time_stamp_nano_ <= ts.time_stamp_nano_);
 }
 
 inline bool TimeStamp::operator >=(const TimeStamp& ts) const
 {
-    return (time_stamp_ >= ts.get());
-}
-
-inline Scalar TimeStamp::operator -(const TimeStamp& ts) const
-{
-    return (time_stamp_ - ts.get());
+    return (time_stamp_nano_ >= ts.time_stamp_nano_);
 }
 
 inline void TimeStamp::operator +=(const Scalar& dt)
 {
-    time_stamp_ += dt;
+    time_stamp_nano_ += (unsigned long int)(dt*NANOSECS);
 }
 
-inline TimeStamp TimeStamp::operator +(const Scalar& dt) const
+inline Scalar TimeStamp::operator -(const TimeStamp& ts) const
 {
-    return TimeStamp(time_stamp_ + dt);
+    return Scalar((long int)(time_stamp_nano_ - ts.time_stamp_nano_))*1e-9; // long int cast fix overflow in case of negative substraction result
 }
 
 static const TimeStamp InvalidStamp(-1,-1);
diff --git a/src/trajectory_base.cpp b/src/trajectory_base.cpp
index 577291e4f4621d95e1c42c7c66b7ffa83a4735b5..df3a9f5f7d932c5049ba093c59d3206ab19ddcc8 100644
--- a/src/trajectory_base.cpp
+++ b/src/trajectory_base.cpp
@@ -88,7 +88,8 @@ FrameBasePtr TrajectoryBase::closestKeyFrameToTimeStamp(const TimeStamp& _ts)
     for (auto frm_rit = getFrameList().rbegin(); frm_rit != getFrameList().rend(); frm_rit++)
         if ((*frm_rit)->isKey())
         {
-            Scalar dt = std::abs((*frm_rit)->getTimeStamp().get() - _ts.get());
+            Scalar dt = std::fabs((*frm_rit)->getTimeStamp() - _ts);
+            std::cout << "dt " << dt << std::endl;
             if (dt < min_dt)
             {
                 min_dt = dt;