diff --git a/src/ceres_wrapper/create_auto_diff_cost_function.cpp b/src/ceres_wrapper/create_auto_diff_cost_function.cpp
index 3d2809b2d028dfee319fdffdba1e17f66e1c8dbc..c0e3edddd5fcc215e18b628e3e05854281b3dcfa 100644
--- a/src/ceres_wrapper/create_auto_diff_cost_function.cpp
+++ b/src/ceres_wrapper/create_auto_diff_cost_function.cpp
@@ -14,6 +14,7 @@
 #include "../constraint_gps_pseudorange_3D.h"
 #include "../constraint_gps_pseudorange_2D.h"
 #include "../constraint_odom_2D.h"
+#include "../constraint_odom_3D.h"
 #include "../constraint_corner_2D.h"
 #include "../constraint_point_2D.h"
 #include "../constraint_point_to_line_2D.h"
@@ -49,6 +50,12 @@ ceres::CostFunction* createAutoDiffCostFunction(ConstraintBasePtr _ctr_ptr, bool
             else
                 return createAutoDiffCostFunctionCeres<ConstraintOdom2D>(_ctr_ptr);
 
+        case CTR_ODOM_3D:
+            if (_use_wolf_autodiff)
+                return createAutoDiffCostFunctionWrapper<ConstraintOdom3D>(_ctr_ptr);
+            else
+                return createAutoDiffCostFunctionCeres<ConstraintOdom3D>(_ctr_ptr);
+
         case CTR_CORNER_2D:
             if (_use_wolf_autodiff)
                 return createAutoDiffCostFunctionWrapper<ConstraintCorner2D>(_ctr_ptr);
diff --git a/src/constraint_odom_3D.h b/src/constraint_odom_3D.h
index 1d58ea77ddc9a8ae8f4d134373c388c5b946337a..a513483263888cdad14995d8bdf79e2d04417019 100644
--- a/src/constraint_odom_3D.h
+++ b/src/constraint_odom_3D.h
@@ -29,8 +29,33 @@ class ConstraintOdom3D : public ConstraintSparse<6,3,4,3,4>
                                  const T* const _q2,
                                  T* _residuals) const;
 
+    private:
+        template<typename T>
+        void printRes(const Eigen::Matrix<T, 6, 1>& r) const;
+
+
 };
 
+template<typename T>
+inline void ConstraintOdom3D::printRes(const Eigen::Matrix<T, 6, 1>& r) const
+{
+    std::cout << "Jet residual = " << std::endl;
+    std::cout << r(0) << std::endl;
+    std::cout << r(1) << std::endl;
+    std::cout << r(2) << std::endl;
+    std::cout << r(3) << std::endl;
+    std::cout << r(4) << std::endl;
+    std::cout << r(5) << std::endl;
+}
+
+template<>
+inline void ConstraintOdom3D::printRes (const  Eigen::Matrix<Scalar,6,1> & r) const
+{
+    std::cout << "Scalar residual = " << std::endl;
+    std::cout << r.transpose() << std::endl;
+}
+
+
 inline ConstraintOdom3D::ConstraintOdom3D(FeatureBasePtr _ftr_ptr, FrameBasePtr _frame_ptr, bool _apply_loss_function,
                                           ConstraintStatus _status) :
         ConstraintSparse<6, 3, 4, 3, 4>(CTR_ODOM_3D, _frame_ptr, _apply_loss_function, _status,
@@ -96,14 +121,18 @@ inline bool wolf::ConstraintOdom3D::operator ()(const T* const _p1, const T* con
     Eigen::Quaternion<T> dq = q1.conjugate() * q2;
 
     // measured motion increment, dp_m, dq_m
-    Eigen::Map<Eigen::Matrix<T,3,1>> dp_m(getMeasurement().data());
-    Eigen::Quaternion<T> dq_m = v2q(getMeasurement().tail<3>());
+    Eigen::Matrix<T,3,1> dp_m = getMeasurement().head<3>().cast<T>();
+    Eigen::Quaternion<T> dq_m = v2q(getMeasurement().tail<3>()).cast<T>();
 
     // 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,6,1> r = residuals;
+
+//    printRes(r);
+
     return true;
 }
 
diff --git a/src/examples/test_2_lasers_offline.cpp b/src/examples/test_2_lasers_offline.cpp
index 13e77a26872d021672895c2d492fcfb357c63a85..b63732b21931019a31e5d82f4c64aabfc401d4c2 100644
--- a/src/examples/test_2_lasers_offline.cpp
+++ b/src/examples/test_2_lasers_offline.cpp
@@ -23,7 +23,6 @@
 #include "../sensor_odom_2D.h"
 #include "../sensor_gps_fix.h"
 #include "../capture_fix.h"
-#include "../capture_odom_2D.h"
 #include "../ceres_wrapper/ceres_manager.h"
 
 // laserscanutils
diff --git a/src/examples/test_ceres_2_lasers.cpp b/src/examples/test_ceres_2_lasers.cpp
index eecb272ae3d9497be941901bef632d9a140f7cf7..780af80435c7d3ed98b99ae83bd18bcabfeacfb8 100644
--- a/src/examples/test_ceres_2_lasers.cpp
+++ b/src/examples/test_ceres_2_lasers.cpp
@@ -23,7 +23,6 @@
 #include "sensor_odom_2D.h"
 #include "sensor_gps_fix.h"
 #include "capture_fix.h"
-#include "capture_odom_2D.h"
 #include "ceres_wrapper/ceres_manager.h"
 
 // laserscanutils
diff --git a/src/examples/test_ceres_2_lasers_polylines.cpp b/src/examples/test_ceres_2_lasers_polylines.cpp
index fa0e6990f89adf7db81bea0619906fe85b7c0cd9..b42b4da08805331c5324004a7aeb3bcfabfd1261 100644
--- a/src/examples/test_ceres_2_lasers_polylines.cpp
+++ b/src/examples/test_ceres_2_lasers_polylines.cpp
@@ -23,7 +23,6 @@
 #include "sensor_odom_2D.h"
 #include "sensor_gps_fix.h"
 #include "capture_fix.h"
-#include "capture_odom_2D.h"
 #include "ceres_wrapper/ceres_manager.h"
 
 // laserscanutils
diff --git a/src/examples/test_processor_odom_3D.cpp b/src/examples/test_processor_odom_3D.cpp
index d0c4808505ee8bf499caaa2891fc4dc8c9d7af8a..da3511e90a046a781fb9ca218cafdccec36ddfce 100644
--- a/src/examples/test_processor_odom_3D.cpp
+++ b/src/examples/test_processor_odom_3D.cpp
@@ -10,6 +10,11 @@
 #include "sensor_odom_2D.h"
 #include "processor_odom_3D.h"
 #include "capture_imu.h"
+#include "map_base.h"
+#include "landmark_base.h"
+#include "ceres_wrapper/ceres_manager.h"
+
+#include <cstdlib>
 
 using namespace wolf;
 using std::cout;
@@ -20,11 +25,75 @@ using Eigen::Vector7s;
 using Eigen::Quaternions;
 using Eigen::VectorXs;
 
-int main ()
+void print(Problem* P)
+{
+    cout << "P: wolf tree status:" << endl;
+    cout << "H" << endl;
+    for (auto S : *(P->getHardwarePtr()->getSensorListPtr() ) )
+    {
+        cout << "  S" << S->id() << endl;
+        for (auto p : *(S->getProcessorListPtr() ) )
+        {
+            cout << "    p" << p->id() << endl;
+        }
+    }
+    cout << "T" << endl;
+    for (auto F : *(P->getTrajectoryPtr()->getFrameListPtr() ) )
+    {
+        cout << (F->isKey() ?  "  KF" : "  F") << F->id() << (F->isFixed() ?  ", fixed" : ", estim") << ", ts=" << F->getTimeStamp().get();
+        cout << ",\t x = ( " << F->getState().transpose() << ")" << endl;
+        for (auto C : *(F->getCaptureListPtr() ) )
+        {
+            cout << "    C" << C->id() << endl;
+            for (auto f : *(C->getFeatureListPtr() ) )
+            {
+                cout << "      f" << f->id() << ",            \t m = ( " << std::setprecision(2) << f->getMeasurement().transpose() << ")" << endl;
+                for (auto c : *(f->getConstraintListPtr() ) )
+                {
+                    cout << "        c" << c->id();
+                    switch (c->getCategory())
+                    {
+                        case CTR_ABSOLUTE:
+                            cout << " --> A" << endl;
+                            break;
+                        case CTR_FRAME:
+                            cout << " --> F" << c->getFrameOtherPtr()->id() << endl;
+                            break;
+                        case CTR_FEATURE:
+                            cout << " --> f" << c->getFeatureOtherPtr()->id() << endl;
+                            break;
+                        case CTR_LANDMARK:
+                            cout << " --> L" << c->getLandmarkOtherPtr()->id() << endl;
+                            break;
+                    }
+                }
+            }
+        }
+    }
+    cout << "M" << endl;
+    for (auto L : *(P->getMapPtr()->getLandmarkListPtr() ) )
+    {
+        cout << "  L" << L->id() << endl;
+    }
+}
+
+
+int main (int argc, char** argv)
 {
+    cout << "\n========= Test ProcessorOdom3D ===========" << endl;
+
+    TimeStamp tf;
+    if (argc == 1)
+        tf = 0.3;
+    else
+    {
+
+        tf.set(strtod(argv[1],nullptr));
+    }
+    cout << "Final timestamp tf = " << tf.get() << " s" << endl;
 
     Problem* problem = new Problem(FRM_PO_3D);
-    CeresManager* ceres_manager = new CeresManager(problem);
+    CeresManager ceres_manager(problem);
 
     SensorBase* sen = problem->installSensor("ODOM 3D", "odom", (Vector7s()<<0,0,0,0,0,0,1).finished(),"");
     problem->installProcessor("ODOM 3D", "odometry integrator", "odom", "");
@@ -35,21 +104,32 @@ int main ()
 
     Vector6s data((Vector6s() << d_pos , d_theta).finished()); // will integrate this data repeatedly
 
-    Scalar dt = 0.01;
+    Scalar dt = 0.1;
 
-    for (TimeStamp t = 0; t < 5 - Constants::EPS; t += dt)
+    cout << "t: " << 0 << "  \t\t\t x = ( " << problem->getCurrentState().transpose() << ")" << endl;
+    print(problem);
+    cout << "--------------------------------------------------------------" << endl;
+
+    for (TimeStamp t = dt; t < tf - Constants::EPS; t += dt)
     {
 
         CaptureMotion* cap_odo = new CaptureMotion(t, sen, data);
 
         cap_odo->process();
 
-        cout << "t: " << t.get() << "   x: " << problem->getCurrentState().transpose() << endl;
+        cout << "t: " << t.get() << "  \t\t x = ( " << problem->getCurrentState().transpose() << ")" << endl;
+        print(problem);
+        cout << "--------------------------------------------------------------" << endl;
+
+        ceres::Solver::Summary summary = ceres_manager.solve();
+
+//        ceres_manager.computeCovariances(ALL);
+
+//        cout << summary.BriefReport() << endl;
 
-        ceres::Solver::Summary summary = ceres_manager->solve();
-        cout << summary << endl;
     }
 
-    delete problem;
+        delete problem; // XXX Why is this throwing segfault?
+
     return 0;
 }
diff --git a/src/hardware_base.cpp b/src/hardware_base.cpp
index c60d2f11c6d6e6435c9d4a057333ed6ef33717e9..0b9c3fef9c9af7feb465a2f7a47d17e16e28990e 100644
--- a/src/hardware_base.cpp
+++ b/src/hardware_base.cpp
@@ -16,7 +16,7 @@ HardwareBase::~HardwareBase()
     is_deleting_ = true;
     while (!sensor_list_.empty())
     {
-        delete sensor_list_.front();
+        sensor_list_.front()->destruct();
         sensor_list_.pop_front();
     }
 	//std::cout << "deleting HardwareBase " << nodeId() << std::endl;
@@ -27,10 +27,8 @@ SensorBasePtr HardwareBase::addSensor(SensorBasePtr _sensor_ptr)
     //std::cout << "adding sensor..." << std::endl;
     sensor_list_.push_back(_sensor_ptr);
     _sensor_ptr->setProblem(getProblem());
-//	addDownNode(_sensor_ptr);
     //std::cout << "added!" << std::endl;
 
-
     _sensor_ptr->registerNewStateBlocks();
 
     return _sensor_ptr;
@@ -41,7 +39,6 @@ void HardwareBase::removeSensor(SensorBasePtr _sensor_ptr)
 {
     sensor_list_.remove(_sensor_ptr);
     delete _sensor_ptr;
-//    removeDownNode(_sensor_ptr->nodeId());
 }
 
 } // namespace wolf
diff --git a/src/map_base.cpp b/src/map_base.cpp
index 3192c5a25de540fcbebf7394edd6363ffd482d54..5e77d7ea9d3b5f2b7c4fefd0dd674e67086c0b42 100644
--- a/src/map_base.cpp
+++ b/src/map_base.cpp
@@ -30,7 +30,7 @@ MapBase::~MapBase()
     is_deleting_ = true;
     while (!landmark_list_.empty())
     {
-        delete landmark_list_.front();
+        landmark_list_.front()->destruct();
         landmark_list_.pop_front();
     }
 
diff --git a/src/problem.h b/src/problem.h
index 1a7a8fb14d03e286740af6afe7b26f5ea9a69eb2..890372775594ac5ac603a5623a27715ac9532f95 100644
--- a/src/problem.h
+++ b/src/problem.h
@@ -268,11 +268,6 @@ class Problem
 
 };
 
-inline ProcessorMotion* Problem::getProcessorMotionPtr()
-{
-    return processor_motion_ptr_;
-}
-
 } // namespace wolf
 
 // IMPLEMENTATION
@@ -280,6 +275,11 @@ inline ProcessorMotion* Problem::getProcessorMotionPtr()
 namespace wolf
 {
 
+inline ProcessorMotion* Problem::getProcessorMotionPtr()
+{
+    return processor_motion_ptr_;
+}
+
 inline std::list<StateBlockNotification>& Problem::getStateBlockNotificationList()
 {
     return state_block_notification_list_;
diff --git a/src/processor_motion.h b/src/processor_motion.h
index 412cd5484341013252d93aef3dcbbb133b9f4880..f9c8e3a073674aac17cc1aa0e123344f7faa284f 100644
--- a/src/processor_motion.h
+++ b/src/processor_motion.h
@@ -459,6 +459,9 @@ inline void ProcessorMotion::process(CaptureBasePtr _incoming_ptr)
                                                  deltaZero(),
                                                  Eigen::MatrixXs::Zero(delta_cov_size_, delta_cov_size_),
                                                  Eigen::MatrixXs::Zero(delta_cov_size_, delta_cov_size_)}));
+        delta_integrated_ = deltaZero();
+        delta_integrated_cov_.setZero();
+
         // reset derived things
         resetDerived();
 
diff --git a/src/processor_odom_3D.h b/src/processor_odom_3D.h
index b40af6e1fb3c953b9edd7b51e6c04ec86155d86a..d4c0307f7edea3b30bc452b59133f9523241acdd 100644
--- a/src/processor_odom_3D.h
+++ b/src/processor_odom_3D.h
@@ -66,8 +66,8 @@ class ProcessorOdom3D : public ProcessorMotion
                            Motion& _motion,
                            TimeStamp& _ts);
         bool voteForKeyFrame();
-
-        virtual ConstraintBasePtr createConstraint(FeatureBasePtr _feature_motion, FrameBasePtr _frame_origin);
+        ConstraintBasePtr createConstraint(FeatureBasePtr _feature_motion,
+                                           FrameBasePtr _frame_origin);
 
     private:
         Eigen::Map<const Eigen::Vector3s> p1_, p2_;
@@ -78,10 +78,13 @@ class ProcessorOdom3D : public ProcessorMotion
 
     // Factory method
     public:
-        static ProcessorBasePtr create(const std::string& _unique_name, const ProcessorParamsBasePtr _params);
+        static ProcessorBasePtr create(const std::string& _unique_name,
+                                       const ProcessorParamsBasePtr _params);
 };
 
-inline void ProcessorOdom3D::data2delta(const Eigen::VectorXs& _data, const Eigen::MatrixXs& _data_cov, const Scalar _dt)
+inline void ProcessorOdom3D::data2delta(const Eigen::VectorXs& _data,
+                                        const Eigen::MatrixXs& _data_cov,
+                                        const Scalar _dt)
 {
     delta_.head<3>() = _data.head<3>();
     new (&q_out_) Eigen::Map<Eigen::Quaternions>(delta_.data() + 3);
@@ -104,7 +107,10 @@ inline void ProcessorOdom3D::data2delta(const Eigen::VectorXs& _data, const Eige
     delta_cov_ = _data_cov;
 }
 
-inline void ProcessorOdom3D::xPlusDelta(const Eigen::VectorXs& _x, const Eigen::VectorXs& _delta, const Scalar _Dt, Eigen::VectorXs& _x_plus_delta)
+inline void ProcessorOdom3D::xPlusDelta(const Eigen::VectorXs& _x,
+                                        const Eigen::VectorXs& _delta,
+                                        const Scalar _Dt,
+                                        Eigen::VectorXs& _x_plus_delta)
 {
     assert(_x.size() == x_size_ && "Wrong _x vector size");
     assert(_delta.size() == delta_size_ && "Wrong _delta vector size");
@@ -117,7 +123,10 @@ inline void ProcessorOdom3D::xPlusDelta(const Eigen::VectorXs& _x, const Eigen::
 
 }
 
-inline void ProcessorOdom3D::deltaPlusDelta(const Eigen::VectorXs& _delta1, const Eigen::VectorXs& _delta2, const Scalar _Dt2, Eigen::VectorXs& _delta1_plus_delta2)
+inline void ProcessorOdom3D::deltaPlusDelta(const Eigen::VectorXs& _delta1,
+                                            const Eigen::VectorXs& _delta2,
+                                            const Scalar _Dt2,
+                                            Eigen::VectorXs& _delta1_plus_delta2)
 {
     assert(_delta1.size() == delta_size_ && "Wrong _delta1 vector size");
     assert(_delta2.size() == delta_size_ && "Wrong _delta2 vector size");
@@ -128,9 +137,11 @@ inline void ProcessorOdom3D::deltaPlusDelta(const Eigen::VectorXs& _delta1, cons
     q_out_ = q1_ * q2_;
 }
 
-inline void ProcessorOdom3D::deltaPlusDelta(const Eigen::VectorXs& _delta1, const Eigen::VectorXs& _delta2,
+inline void ProcessorOdom3D::deltaPlusDelta(const Eigen::VectorXs& _delta1,
+                                            const Eigen::VectorXs& _delta2,
                                             const Scalar _Dt2,
-                                            Eigen::VectorXs& _delta1_plus_delta2, Eigen::MatrixXs& _jacobian1,
+                                            Eigen::VectorXs& _delta1_plus_delta2,
+                                            Eigen::MatrixXs& _jacobian1,
                                             Eigen::MatrixXs& _jacobian2)
 {
     assert(_delta1.size() == delta_size_ && "Wrong _delta1 vector size");
@@ -173,7 +184,9 @@ inline Eigen::VectorXs ProcessorOdom3D::deltaZero() const
     return (Eigen::VectorXs(7) << 0,0,0, 0,0,0,1).finished(); // p, q
 }
 
-inline Motion ProcessorOdom3D::interpolate(const Motion& _motion_ref, Motion& _motion, TimeStamp& _ts)
+inline Motion ProcessorOdom3D::interpolate(const Motion& _motion_ref,
+                                           Motion& _motion,
+                                           TimeStamp& _ts)
 {
     Motion tmp(_motion_ref);
     tmp.ts_ = _ts;
@@ -187,12 +200,15 @@ inline bool ProcessorOdom3D::voteForKeyFrame()
     return true;
 }
 
-inline ConstraintBasePtr ProcessorOdom3D::createConstraint(FeatureBasePtr _feature_motion, FrameBasePtr _frame_origin)
+inline ConstraintBasePtr ProcessorOdom3D::createConstraint(FeatureBasePtr _feature_motion,
+                                                           FrameBasePtr _frame_origin)
 {
     return new ConstraintOdom3D(_feature_motion, _frame_origin);
 }
 
-inline void ProcessorOdom3D::remap(const Eigen::VectorXs& _x1, const Eigen::VectorXs& _x2, Eigen::VectorXs& _x_out)
+inline void ProcessorOdom3D::remap(const Eigen::VectorXs& _x1,
+                                   const Eigen::VectorXs& _x2,
+                                   Eigen::VectorXs& _x_out)
 {
     new (&p1_) Eigen::Map<const Eigen::Vector3s>(_x1.data());
     new (&q1_) Eigen::Map<const Eigen::Quaternions>(_x1.data() + 3);
diff --git a/src/sensor_base.cpp b/src/sensor_base.cpp
index c0546d299a409b8b4b536255ea514958ce6d7935..abe926757af3acb788cb16673a3f7eeeaff55636 100644
--- a/src/sensor_base.cpp
+++ b/src/sensor_base.cpp
@@ -69,7 +69,7 @@ SensorBase::~SensorBase()
 
     while (!processor_list_.empty())
     {
-        delete processor_list_.front();
+        processor_list_.front()->destruct();
         processor_list_.pop_front();
     }
 
diff --git a/src/trajectory_base.cpp b/src/trajectory_base.cpp
index 18720c7d8b48dcb905fe67a7d51945a59b7e84b3..fcd0a436e9beb65e9cedcd4e55cfcec5b1a14bd2 100644
--- a/src/trajectory_base.cpp
+++ b/src/trajectory_base.cpp
@@ -16,7 +16,7 @@ TrajectoryBase::~TrajectoryBase()
     is_deleting_ = true;
     while (!frame_list_.empty())
     {
-        delete frame_list_.front();
+        frame_list_.front()->destruct();
         frame_list_.pop_front();
     }
     //std::cout << "deleting TrajectoryBase " << nodeId() << std::endl;
@@ -66,7 +66,7 @@ void TrajectoryBase::sortFrame(FrameBasePtr _frame_ptr)
 FrameBaseIter TrajectoryBase::computeFrameOrder(FrameBasePtr _frame_ptr)
 {
     for (auto frm_rit = getFrameListPtr()->rbegin(); frm_rit != getFrameListPtr()->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 getFrameListPtr()->begin();
 }
diff --git a/src/trajectory_base.h b/src/trajectory_base.h
index 4e43d98a4c5df232146f148801c8c6109c13af42..50d9e19f41e33cb9d2050d9a8af9b4f08ad141e6 100644
--- a/src/trajectory_base.h
+++ b/src/trajectory_base.h
@@ -55,7 +55,7 @@ class TrajectoryBase : public NodeBase
         FrameBasePtr getLastKeyFramePtr();
         FrameBasePtr closestKeyFrameToTimeStamp(const TimeStamp& _ts);
         void setLastKeyFramePtr(FrameBasePtr _key_frame_ptr);
-        void sortFrame(FrameBasePtr _frame_iter);
+        void sortFrame(FrameBasePtr _frm_ptr);
         void moveFrame(FrameBasePtr _frm_ptr, FrameBaseIter _place);
         FrameBaseIter computeFrameOrder(FrameBasePtr _frame_ptr);