diff --git a/src/constraint_analytic.cpp b/src/constraint_analytic.cpp
index 8b0422380bc4ad0d39f2e7f38955ea3b0bd948a8..1d10e7a06c81a0370eed2df600e9ab0242398264 100644
--- a/src/constraint_analytic.cpp
+++ b/src/constraint_analytic.cpp
@@ -7,9 +7,19 @@ ConstraintAnalytic::ConstraintAnalytic(const std::string&  _tp,
                                        bool _apply_loss_function, ConstraintStatus _status,
                                        StateBlockPtr _state0Ptr, StateBlockPtr _state1Ptr, StateBlockPtr _state2Ptr, StateBlockPtr _state3Ptr, StateBlockPtr _state4Ptr,
                                        StateBlockPtr _state5Ptr, StateBlockPtr _state6Ptr, StateBlockPtr _state7Ptr, StateBlockPtr _state8Ptr, StateBlockPtr _state9Ptr ) :
-            ConstraintBase(_tp, _apply_loss_function, _status),
-            state_ptr_vector_({_state0Ptr, _state1Ptr, _state2Ptr, _state3Ptr, _state4Ptr,
-                               _state5Ptr, _state6Ptr, _state7Ptr, _state8Ptr, _state9Ptr})
+        ConstraintBase(_tp, _apply_loss_function, _status),
+        state_ptr_vector_({_state0Ptr, _state1Ptr, _state2Ptr, _state3Ptr, _state4Ptr,
+                           _state5Ptr, _state6Ptr, _state7Ptr, _state8Ptr, _state9Ptr}),
+        state_block_sizes_vector_({_state0Ptr ? (unsigned int) _state0Ptr->getSize() : 0,
+                                   _state1Ptr ? (unsigned int) _state1Ptr->getSize() : 0,
+                                   _state2Ptr ? (unsigned int) _state2Ptr->getSize() : 0,
+                                   _state3Ptr ? (unsigned int) _state3Ptr->getSize() : 0,
+                                   _state4Ptr ? (unsigned int) _state4Ptr->getSize() : 0,
+                                   _state5Ptr ? (unsigned int) _state5Ptr->getSize() : 0,
+                                   _state6Ptr ? (unsigned int) _state6Ptr->getSize() : 0,
+                                   _state7Ptr ? (unsigned int) _state7Ptr->getSize() : 0,
+                                   _state8Ptr ? (unsigned int) _state8Ptr->getSize() : 0,
+                                   _state9Ptr ? (unsigned int) _state9Ptr->getSize() : 0})
 {
     resizeVectors();
 }
@@ -23,9 +33,19 @@ ConstraintAnalytic::ConstraintAnalytic(const std::string&  _tp,
                                        bool _apply_loss_function, ConstraintStatus _status,
                                        StateBlockPtr _state0Ptr, StateBlockPtr _state1Ptr, StateBlockPtr _state2Ptr, StateBlockPtr _state3Ptr, StateBlockPtr _state4Ptr,
                                        StateBlockPtr _state5Ptr, StateBlockPtr _state6Ptr, StateBlockPtr _state7Ptr, StateBlockPtr _state8Ptr, StateBlockPtr _state9Ptr ) :
-            ConstraintBase(_tp,  _frame_other_ptr, _capture_other_ptr, _feature_other_ptr, _landmark_other_ptr, _processor_ptr, _apply_loss_function, _status),
-            state_ptr_vector_({_state0Ptr, _state1Ptr, _state2Ptr, _state3Ptr, _state4Ptr,
-                               _state5Ptr, _state6Ptr, _state7Ptr, _state8Ptr, _state9Ptr})
+        ConstraintBase(_tp,  _frame_other_ptr, _capture_other_ptr, _feature_other_ptr, _landmark_other_ptr, _processor_ptr, _apply_loss_function, _status),
+        state_ptr_vector_({_state0Ptr, _state1Ptr, _state2Ptr, _state3Ptr, _state4Ptr,
+                           _state5Ptr, _state6Ptr, _state7Ptr, _state8Ptr, _state9Ptr}),
+        state_block_sizes_vector_({_state0Ptr ? (unsigned int) _state0Ptr->getSize() : 0,
+                                   _state1Ptr ? (unsigned int) _state1Ptr->getSize() : 0,
+                                   _state2Ptr ? (unsigned int) _state2Ptr->getSize() : 0,
+                                   _state3Ptr ? (unsigned int) _state3Ptr->getSize() : 0,
+                                   _state4Ptr ? (unsigned int) _state4Ptr->getSize() : 0,
+                                   _state5Ptr ? (unsigned int) _state5Ptr->getSize() : 0,
+                                   _state6Ptr ? (unsigned int) _state6Ptr->getSize() : 0,
+                                   _state7Ptr ? (unsigned int) _state7Ptr->getSize() : 0,
+                                   _state8Ptr ? (unsigned int) _state8Ptr->getSize() : 0,
+                                   _state9Ptr ? (unsigned int) _state9Ptr->getSize() : 0})
 {
     resizeVectors();
 }
@@ -58,17 +78,15 @@ JacobianMethod ConstraintAnalytic::getJacobianMethod() const
 
 void ConstraintAnalytic::resizeVectors()
 {
-    for (unsigned int ii = 1; ii<state_ptr_vector_.size(); ii++)
-    {
-        if (state_ptr_vector_.at(ii) != nullptr)
-            state_block_sizes_vector_.push_back(state_ptr_vector_.at(ii)->getSize());
+    assert(state_ptr_vector_[0] != nullptr && "at least one not null state block pointer required");
 
-        else
+    for (unsigned int ii = 1; ii<state_ptr_vector_.size(); ii++)
+        if (state_ptr_vector_.at(ii) == nullptr)
         {
             state_ptr_vector_.resize(ii);
+            state_block_sizes_vector_.resize(ii);
             break;
         }
-    }
 }
 
 } // namespace wolf
diff --git a/src/constraint_analytic.h b/src/constraint_analytic.h
index 17ff4a079a55efc4908611801f11d95b9aa86305..93be1b1af130516c1fd7a0c2b8f0ce822733da2c 100644
--- a/src/constraint_analytic.h
+++ b/src/constraint_analytic.h
@@ -83,7 +83,6 @@ class ConstraintAnalytic: public ConstraintBase
 
         /** \brief Evaluate the constraint given the input parameters and returning the residuals and jacobians
         **/
-        // TODO
         virtual bool evaluate(Scalar const* const* parameters, Scalar* residuals, Scalar** jacobians) const override
         {
             // load parameters evaluation value
@@ -118,7 +117,7 @@ class ConstraintAnalytic: public ConstraintBase
             return true;
         };
 
-        /** Returns the residual vetor and a vector of Jacobian matrix corresponding to each state block evaluated in the point provided in _states_ptr
+        /** Returns the residual vector and a vector of Jacobian matrix corresponding to each state block evaluated in the point provided in _states_ptr
          **/
         // TODO
         virtual void evaluate(const std::vector<const Scalar*>& _states_ptr, Eigen::VectorXs& residual_, std::vector<Eigen::MatrixXs>& jacobians_) const override
@@ -132,9 +131,9 @@ class ConstraintAnalytic: public ConstraintBase
          **/
         virtual Eigen::VectorXs evaluateResiduals(const std::vector<Eigen::Map<const Eigen::VectorXs>>& _st_vector) const = 0;
 
-        /** \brief Returns the jacobians evaluated in the states provided
+        /** \brief Returns the normalized jacobians evaluated in the states
          *
-         * Returns the jacobians evaluated in the states provided in std::vector of mapped Eigen::VectorXs.
+         * Returns the normalized (by the measurement noise sqrt information) jacobians evaluated in the states provided in std::vector of mapped Eigen::VectorXs.
          * IMPORTANT: only fill the jacobians of the state blocks specified in _compute_jacobian.
          *
          * \param _st_vector is a vector containing the mapped eigen vectors of all state blocks involved in the constraint
@@ -144,11 +143,10 @@ class ConstraintAnalytic: public ConstraintBase
          **/
         virtual void evaluateJacobians(const std::vector<Eigen::Map<const Eigen::VectorXs>>& _st_vector, std::vector<Eigen::Map<Eigen::MatrixXs>>& jacobians, const std::vector<bool>& _compute_jacobian) const = 0;
 
-        /** \brief Returns the pure jacobians (without measurement noise) evaluated in the state blocks values
+        /** \brief Returns the jacobians (without measurement noise normalization) evaluated in the current state blocks values
          *
-         * Returns the pure jacobians (without measurement noise) evaluated in the state blocks values
+         * Returns the jacobians (without measurement noise normalization) evaluated in the current state blocks values
          *
-         * \param _st_vector is a vector containing the mapped eigen vectors of all state blocks involved in the constraint
          * \param jacobians is an output vector of mapped eigen matrices that sould contain the jacobians w.r.t each state block
          *
          **/
diff --git a/src/constraint_block_absolute.h b/src/constraint_block_absolute.h
index fe8eec7a9f01095838c0572d4517e4493d85fa3a..e3def4493f0444ada07ed097e737610e5459671b 100644
--- a/src/constraint_block_absolute.h
+++ b/src/constraint_block_absolute.h
@@ -9,7 +9,7 @@
 #define CONSTRAINT_BLOCK_ABSOLUTE_H_
 
 //Wolf includes
-#include "constraint_autodiff.h"
+#include "constraint_analytic.h"
 #include "frame_base.h"
 
 
@@ -18,43 +18,122 @@ namespace wolf {
 WOLF_PTR_TYPEDEFS(ConstraintBlockAbsolute);
 
 //class
-class ConstraintBlockAbsolute: public ConstraintAutodiff<ConstraintBlockAbsolute,3,3>
+class ConstraintBlockAbsolute : public ConstraintAnalytic
 {
+    private:
+        SizeEigen sb_size_;              // the size of the state block
+        SizeEigen sb_constrained_start_; // the index of the first state element that is constrained
+        SizeEigen sb_constrained_size_;  // the size of the state segment that is constrained
+        Eigen::MatrixXs J_;              // Jacobian
+
     public:
 
-        ConstraintBlockAbsolute(StateBlockPtr _sb_ptr, bool _apply_loss_function = false, ConstraintStatus _status = CTR_ACTIVE) :
-            ConstraintAutodiff<ConstraintBlockAbsolute,3,3>("BLOCK ABS",
-                                                            nullptr, nullptr, nullptr, nullptr, nullptr, _apply_loss_function, _status, _sb_ptr)
+        /** \brief Constructor
+         *
+         * \param _sb_ptr the constrained state block
+         * \param _start_idx (default=0) the index of the first state element that is constrained
+         * \param _start_idx (default=-1) the size of the state segment that is constrained, -1 = all the
+         *
+         */
+        ConstraintBlockAbsolute(StateBlockPtr _sb_ptr,
+                                unsigned int _start_idx = 0,
+                                int _size = -1,
+                                bool _apply_loss_function = false,
+                                ConstraintStatus _status = CTR_ACTIVE) :
+            ConstraintAnalytic("BLOCK ABS",
+                               _apply_loss_function,
+                               _status,
+                               _sb_ptr),
+            sb_size_(_sb_ptr->getSize()),
+            sb_constrained_start_(_start_idx),
+            sb_constrained_size_(_size == -1 ? sb_size_ : _size)
         {
-            //
+            assert(sb_constrained_size_+sb_constrained_start_ <= sb_size_);
+
+            // precompute Jacobian (Identity)
+            if (sb_constrained_start_ == 0)
+                J_ = Eigen::MatrixXs::Identity(sb_constrained_size_, sb_size_);
+            else
+            {
+                J_ = Eigen::MatrixXs::Zero(sb_constrained_size_,sb_size_);
+                J_.middleCols(sb_constrained_start_,sb_constrained_size_) = Eigen::MatrixXs::Identity(sb_constrained_size_, sb_constrained_size_);
+            }
         }
 
         virtual ~ConstraintBlockAbsolute() = default;
 
-        template<typename T>
-        bool operator ()(const T* const _sb, T* _residuals) const;
-
+        /** \brief Returns the residual evaluated in the states provided
+         *
+         * Returns the residual evaluated in the states provided in std::vector of mapped Eigen::VectorXs
+         *
+         **/
+        virtual Eigen::VectorXs evaluateResiduals(const std::vector<Eigen::Map<const Eigen::VectorXs> >& _st_vector) const;
+
+        /** \brief Returns the normalized jacobians evaluated in the states
+         *
+         * Returns the normalized (by the measurement noise sqrt information) jacobians evaluated in the states provided in std::vector of mapped Eigen::VectorXs.
+         * IMPORTANT: only fill the jacobians of the state blocks specified in _compute_jacobian.
+         *
+         * \param _st_vector is a vector containing the mapped eigen vectors of all state blocks involved in the constraint
+         * \param jacobians is an output vector of mapped eigen matrices that sould contain the jacobians w.r.t each state block
+         * \param _compute_jacobian is a vector that specifies whether the ith jacobian sould be computed or not
+         *
+         **/
+        virtual void evaluateJacobians(const std::vector<Eigen::Map<const Eigen::VectorXs> >& _st_vector,
+                                       std::vector<Eigen::Map<Eigen::MatrixXs> >& jacobians,
+                                       const std::vector<bool>& _compute_jacobian) const;
+
+        /** \brief Returns the pure jacobians (without measurement noise) evaluated in the state blocks values
+         *
+         * Returns the pure jacobians (without measurement noise) evaluated in the current state blocks values
+         *
+         * \param jacobians is an output vector of mapped eigen matrices that sould contain the jacobians w.r.t each state block
+         *
+         **/
+        virtual void evaluatePureJacobians(std::vector<Eigen::MatrixXs>& jacobians) const;
+
+        /** \brief Returns the constraint residual size
+         **/
+        virtual unsigned int getSize() const;
 };
 
-template<typename T>
-inline bool ConstraintBlockAbsolute::operator ()(const T* const _sb, T* _residuals) const
+inline Eigen::VectorXs ConstraintBlockAbsolute::evaluateResiduals(const std::vector<Eigen::Map<const Eigen::VectorXs> >& _st_vector) const
 {
+    assert(_st_vector.size() == 1 && "Wrong number of state blocks!");
+    assert(_st_vector.front().size() >= getMeasurement().size() && "Wrong StateBlock size");
 
-    // states
-    Eigen::Matrix<T, 3, 1>  sb(_sb);
+    // residual
+    if (sb_constrained_size_ == _st_vector.front().size())
+        return getMeasurementSquareRootInformationUpper() * (_st_vector.front() - getMeasurement());
+    else
+        return getMeasurementSquareRootInformationUpper() * (_st_vector.front().segment(sb_constrained_start_,sb_constrained_size_) - getMeasurement());
+}
 
-    // measurements
-    Eigen::Vector3s     measured_state(getMeasurement().data() + 0);
+inline void ConstraintBlockAbsolute::evaluateJacobians(
+        const std::vector<Eigen::Map<const Eigen::VectorXs> >& _st_vector,
+        std::vector<Eigen::Map<Eigen::MatrixXs> >& jacobians, const std::vector<bool>& _compute_jacobian) const
+{
+    assert(_st_vector.size() == 1 && "Wrong number of state blocks!");
+    assert(jacobians.size() == 1 && "Wrong number of jacobians!");
+    assert(_compute_jacobian.size() == 1 && "Wrong number of _compute_jacobian booleans!");
+    assert(_st_vector.front().size() == sb_size_ && "Wrong StateBlock size");
+    assert(_st_vector.front().size() >= getMeasurement().size() && "StateBlock size and measurement size should match");
+
+    // normalized jacobian
+    if (_compute_jacobian.front())
+        jacobians.front() = getMeasurementSquareRootInformationUpper() * J_;
+}
 
-    // error
-    Eigen::Matrix<T, 3, 1> er;
-    er       = measured_state.cast<T>() - sb;
+inline void ConstraintBlockAbsolute::evaluatePureJacobians(std::vector<Eigen::MatrixXs>& jacobians) const
+{
+    assert(jacobians.size() == 1 && "Wrong number of jacobians!");
 
-    // residual
-    Eigen::Map<Eigen::Matrix<T, 3, 1>> res(_residuals);
-    res               = getFeaturePtr()->getMeasurementSquareRootInformationUpper().cast<T>() * er;
+    jacobians.front() = J_;
+}
 
-    return true;
+inline unsigned int ConstraintBlockAbsolute::getSize() const
+{
+    return sb_constrained_size_;
 }
 
 } // namespace wolf
diff --git a/src/constraint_relative_2D_analytic.h b/src/constraint_relative_2D_analytic.h
index 32b8b30593a73717be3fccc4459652da17dce616..53dd71ef1037165d6d9efe460bb23867d5ad4f27 100644
--- a/src/constraint_relative_2D_analytic.h
+++ b/src/constraint_relative_2D_analytic.h
@@ -85,7 +85,6 @@ class ConstraintRelative2DAnalytic : public ConstraintAnalytic
                                        const std::vector<bool>& _compute_jacobian) const override;
 
         /** \brief Returns the pure jacobians (without measurement noise) evaluated in the state blocks values
-         * \param _st_vector is a vector containing the mapped eigen vectors of all state blocks involved in the constraint
          * \param jacobians is an output vector of mapped eigen matrices that sould contain the jacobians w.r.t each state block
          *
          **/
@@ -125,11 +124,11 @@ inline void ConstraintRelative2DAnalytic::evaluateJacobians(
             << -(_st_vector[2](0) - _st_vector[0](0)) * sin(_st_vector[1](0))
                     + (_st_vector[2](1) - _st_vector[0](1)) * cos(_st_vector[1](0)), -(_st_vector[2](0)
             - _st_vector[0](0)) * cos(_st_vector[1](0)) - (_st_vector[2](1) - _st_vector[0](1)) * sin(_st_vector[1](0)), -1;
-    jacobians[1] = getMeasurementSquareRootInformationUpper() * jacobians[0];
+    jacobians[1] = getMeasurementSquareRootInformationUpper() * jacobians[1];
     jacobians[2] << cos(_st_vector[1](0)), sin(_st_vector[1](0)), -sin(_st_vector[1](0)), cos(_st_vector[1](0)), 0, 0;
-    jacobians[2] = getMeasurementSquareRootInformationUpper() * jacobians[0];
+    jacobians[2] = getMeasurementSquareRootInformationUpper() * jacobians[2];
     jacobians[3] << 0, 0, 1;
-    jacobians[3] = getMeasurementSquareRootInformationUpper() * jacobians[0];
+    jacobians[3] = getMeasurementSquareRootInformationUpper() * jacobians[3];
 }
 
 inline void ConstraintRelative2DAnalytic::evaluatePureJacobians(std::vector<Eigen::MatrixXs>& jacobians) const
diff --git a/src/problem.cpp b/src/problem.cpp
index fec23b17497b920b575f3f80c05a9db5882e9bc8..f80a99b4dcb9bcabdf2b896c96a531dfdc03ee7c 100644
--- a/src/problem.cpp
+++ b/src/problem.cpp
@@ -754,7 +754,7 @@ void Problem::print(int depth, bool constr_by, bool metric, bool state_blocks)
                 {
                     if (i==0) cout << "    Extr " << (S->isExtrinsicDynamic() ? "[Dyn]" : "[Sta]") << " = [";
                     if (i==2) cout << "    Intr " << (S->isIntrinsicDynamic() ? "[Dyn]" : "[Sta]") << " = [";
-                    auto sb = S->getStateBlockPtrDynamic(i);
+                    auto sb = S->getStateBlockPtr(i);
                     if (sb)
                     {
                         cout << (sb->isFixed() ? " Fix( " : " Est( ") << sb->getState().transpose() << " )";
diff --git a/src/processor_odom_2D.cpp b/src/processor_odom_2D.cpp
index 19818dffcc1aee098c316f1b13bf603703333c39..5041ae985c60770b0c8124f753bcc802574f88ee 100644
--- a/src/processor_odom_2D.cpp
+++ b/src/processor_odom_2D.cpp
@@ -21,7 +21,7 @@ void ProcessorOdom2D::computeCurrentDelta(const Eigen::VectorXs& _data, const Ei
     assert(_data_cov.rows() == data_size_ && "Wrong _data_cov size");
     assert(_data_cov.cols() == data_size_ && "Wrong _data_cov size");
 
-    // data  is [dtheta, dr]
+    // data  is [dr, dtheta]
     // delta is [dx, dy, dtheta]
     // motion model is 1/2 turn + straight + 1/2 turn
     _delta(0) = cos(_data(1) / 2) * _data(0);
diff --git a/src/sensor_base.cpp b/src/sensor_base.cpp
index 429aaf9f142d08a3374d8242df8e79379e5c6d90..947984669e5c7cad26a0ca0c9c7d99732f2652f3 100644
--- a/src/sensor_base.cpp
+++ b/src/sensor_base.cpp
@@ -1,5 +1,8 @@
 #include "sensor_base.h"
 #include "state_block.h"
+#include "state_quaternion.h"
+#include "constraint_block_absolute.h"
+#include "constraint_quaternion_absolute.h"
 
 
 namespace wolf {
@@ -63,30 +66,6 @@ SensorBase::~SensorBase()
     removeStateBlocks();
 }
 
-void SensorBase::remove()
-{
-    if (!is_removing_)
-    {
-        is_removing_ = true;
-        SensorBasePtr this_S = shared_from_this(); // protect it while removing links
-
-        // Remove State Blocks
-        removeStateBlocks();
-
-        // remove from upstream
-        auto H = hardware_ptr_.lock();
-        if (H)
-            H->getSensorList().remove(this_S);
-
-        // remove downstream processors
-        while (!processor_list_.empty())
-        {
-            processor_list_.front()->remove();
-        }
-    }
-
-}
-
 void SensorBase::removeStateBlocks()
 {
     for (unsigned int i = 0; i < state_block_vec_.size(); i++)
@@ -103,8 +82,6 @@ void SensorBase::removeStateBlocks()
     }
 }
 
-
-
 void SensorBase::fix()
 {
     for( auto sbp : state_block_vec_)
@@ -165,7 +142,49 @@ void SensorBase::unfixIntrinsics()
     updateCalibSize();
 }
 
+void SensorBase::addPriorParameter(const unsigned int _i, const Eigen::VectorXs& _x, const Eigen::MatrixXs& _cov, unsigned int _start_idx, int _size)
+{
+    assert(!isStateBlockDynamic(_i) && "SensorBase::addPriorParameter only allowed for static parameters");
+    assert(_i < state_block_vec_.size() && "State block not found");
+
+    StateBlockPtr _sb = getStateBlockPtrStatic(_i);
+    bool is_quaternion = (std::dynamic_pointer_cast<StateQuaternion>(_sb) != nullptr);
+
+    assert(((!is_quaternion && _x.size() == _cov.rows() && _x.size() == _cov.cols()) ||
+            (is_quaternion && _x.size() == 4 &&_cov.rows() == 3 && _cov.cols() == 3)) && "bad prior/covariance dimensions");
+    assert((_size == -1 && _start_idx == 0) || (_size+_start_idx <= _sb->getSize()));
+    assert(_size == -1 || _size == _x.size());
+    assert(!(_size != -1 && is_quaternion) && "prior of a segment of state not available for quaternion");
+
+    // set StateBlock state
+    if (_size == -1)
+        _sb->setState(_x);
+    else
+    {
+        Eigen::VectorXs new_x = _sb->getState();
+        new_x.segment(_start_idx,_size) = _x;
+        _sb->setState(new_x);
+    }
+
+    // remove previous prior (if any)
+    if (params_prior_map_.find(_i) != params_prior_map_.end())
+        params_prior_map_[_i]->remove();
+
+    // create feature
+    FeatureBasePtr ftr_prior = std::make_shared<FeatureBase>("ABSOLUTE",_x,_cov);
+
+    // set feature problem
+    ftr_prior->setProblem(getProblem());
 
+    // create & add constraint absolute
+    if (is_quaternion)
+        ftr_prior->addConstraint(std::make_shared<ConstraintQuaternionAbsolute>(_sb));
+    else
+        ftr_prior->addConstraint(std::make_shared<ConstraintBlockAbsolute>(_sb, _start_idx, _size));
+
+    // store feature in params_prior_map_
+    params_prior_map_[_i] = ftr_prior;
+}
 
 void SensorBase::registerNewStateBlocks()
 {
@@ -243,32 +262,32 @@ CaptureBasePtr SensorBase::lastCapture(const TimeStamp& _ts)
 
 StateBlockPtr SensorBase::getPPtr(const TimeStamp _ts)
 {
-    return getStateBlockPtrDynamic(0, _ts);
+    return getStateBlockPtr(0, _ts);
 }
 
 StateBlockPtr SensorBase::getOPtr(const TimeStamp _ts)
 {
-    return getStateBlockPtrDynamic(1, _ts);
+    return getStateBlockPtr(1, _ts);
 }
 
 StateBlockPtr SensorBase::getIntrinsicPtr(const TimeStamp _ts)
 {
-    return getStateBlockPtrDynamic(2, _ts);
+    return getStateBlockPtr(2, _ts);
 }
 
 StateBlockPtr SensorBase::getPPtr()
 {
-    return getStateBlockPtrDynamic(0);
+    return getStateBlockPtr(0);
 }
 
 StateBlockPtr SensorBase::getOPtr()
 {
-    return getStateBlockPtrDynamic(1);
+    return getStateBlockPtr(1);
 }
 
 StateBlockPtr SensorBase::getIntrinsicPtr()
 {
-    return getStateBlockPtrDynamic(2);
+    return getStateBlockPtr(2);
 }
 
 SizeEigen SensorBase::computeCalibSize() const
@@ -322,32 +341,62 @@ ProcessorBasePtr SensorBase::addProcessor(ProcessorBasePtr _proc_ptr)
     return _proc_ptr;
 }
 
-StateBlockPtr SensorBase::getStateBlockPtrDynamic(unsigned int _i)
+StateBlockPtr SensorBase::getStateBlockPtr(unsigned int _i)
+{
+    CaptureBasePtr cap;
+
+    if (isStateBlockDynamic(_i, cap))
+        return cap->getStateBlockPtr(_i);
+
+    return getStateBlockPtrStatic(_i);
+}
+
+StateBlockPtr SensorBase::getStateBlockPtr(unsigned int _i, const TimeStamp& _ts)
+{
+    CaptureBasePtr cap;
+
+    if (isStateBlockDynamic(_i, _ts, cap))
+        return cap->getStateBlockPtr(_i);
+
+    return getStateBlockPtrStatic(_i);
+}
+
+bool SensorBase::isStateBlockDynamic(unsigned int _i, CaptureBasePtr& cap)
 {
     if ((_i<2 && this->extrinsicsInCaptures()) || (_i>=2 && intrinsicsInCaptures()))
     {
-        CaptureBasePtr cap = lastKeyCapture();
-        if (cap)
-            return cap->getStateBlockPtr(_i);
-        else
-            return getStateBlockPtrStatic(_i);
+        cap = lastKeyCapture();
+
+        return cap != nullptr;
     }
     else
-        return getStateBlockPtrStatic(_i);
+        return false;
 }
 
-StateBlockPtr SensorBase::getStateBlockPtrDynamic(unsigned int _i, const TimeStamp& _ts)
+bool SensorBase::isStateBlockDynamic(unsigned int _i, const TimeStamp& _ts, CaptureBasePtr& cap)
 {
     if ((_i<2 && this->extrinsicsInCaptures()) || (_i>=2 && intrinsicsInCaptures()))
     {
-        CaptureBasePtr cap = lastCapture(_ts);
-        if (cap)
-            return cap->getStateBlockPtr(_i);
-        else
-            return getStateBlockPtrStatic(_i);
+        cap = lastCapture(_ts);
+
+        return cap != nullptr;
     }
     else
-        return getStateBlockPtrStatic(_i);
+        return false;
+}
+
+bool SensorBase::isStateBlockDynamic(unsigned int _i)
+{
+    CaptureBasePtr cap;
+
+    return isStateBlockDynamic(_i,cap);
+}
+
+bool SensorBase::isStateBlockDynamic(unsigned int _i, const TimeStamp& _ts)
+{
+    CaptureBasePtr cap;
+
+    return isStateBlockDynamic(_i,_ts,cap);
 }
 
 void SensorBase::setProblem(ProblemPtr _problem)
diff --git a/src/sensor_base.h b/src/sensor_base.h
index 98a95e2c59e6f0248b83d90ea131a5008cde7d80..992058512a2bd6d29a253653a988ccbe932c8ad1 100644
--- a/src/sensor_base.h
+++ b/src/sensor_base.h
@@ -47,6 +47,8 @@ class SensorBase : public NodeBase, public std::enable_shared_from_this<SensorBa
         Eigen::VectorXs noise_std_; // std of sensor noise
         Eigen::MatrixXs noise_cov_; // cov matrix of noise
 
+        std::map<unsigned int,FeatureBasePtr> params_prior_map_; // Priors (value and covariance) of extrinsic & intrinsic state blocks (by index in state_block_vec_)
+
     public:
         /** \brief Constructor with noise size
          *
@@ -87,7 +89,6 @@ class SensorBase : public NodeBase, public std::enable_shared_from_this<SensorBa
                    const bool _intr_dyn = false);
 
         virtual ~SensorBase();
-        virtual void remove();
 
         unsigned int id();
 
@@ -108,11 +109,16 @@ class SensorBase : public NodeBase, public std::enable_shared_from_this<SensorBa
         const std::vector<StateBlockPtr>& getStateBlockVec() const;
         std::vector<StateBlockPtr>& getStateBlockVec();
         StateBlockPtr getStateBlockPtrStatic(unsigned int _i) const;
-        StateBlockPtr getStateBlockPtrDynamic(unsigned int _i);
-        StateBlockPtr getStateBlockPtrDynamic(unsigned int _i, const TimeStamp& _ts);
+        StateBlockPtr getStateBlockPtr(unsigned int _i);
+        StateBlockPtr getStateBlockPtr(unsigned int _i, const TimeStamp& _ts);
         void setStateBlockPtrStatic(unsigned int _i, const StateBlockPtr _sb_ptr);
         void resizeStateBlockVec(unsigned int _size);
 
+        bool isStateBlockDynamic(unsigned int _i, const TimeStamp& _ts, CaptureBasePtr& cap);
+        bool isStateBlockDynamic(unsigned int _i, CaptureBasePtr& cap);
+        bool isStateBlockDynamic(unsigned int _i, const TimeStamp& _ts);
+        bool isStateBlockDynamic(unsigned int _i);
+
         StateBlockPtr getPPtr(const TimeStamp _ts);
         StateBlockPtr getOPtr(const TimeStamp _ts);
         StateBlockPtr getIntrinsicPtr(const TimeStamp _ts);
@@ -131,6 +137,32 @@ class SensorBase : public NodeBase, public std::enable_shared_from_this<SensorBa
         void fixIntrinsics();
         void unfixIntrinsics();
 
+        /** \brief Add an absolute constraint to a parameter
+         *
+         * Add an absolute constraint to a parameter
+         * \param _i state block index (in state_block_vec_) of the parameter to be constrained
+         * \param _x prior value
+         * \param _cov covariance
+         * \param _start_idx state segment starting index (not used in quaternions)
+         * \param _size state segment size (-1: whole state) (not used in quaternions)
+         *
+         **/
+        void addPriorParameter(const unsigned int _i,
+                               const Eigen::VectorXs& _x,
+                               const Eigen::MatrixXs& _cov,
+                               unsigned int _start_idx = 0,
+                               int _size = -1);
+        void addPriorP(const Eigen::VectorXs& _x,
+                       const Eigen::MatrixXs& _cov,
+                       unsigned int _start_idx = 0,
+                       int _size = -1);
+        void addPriorO(const Eigen::VectorXs& _x,
+                       const Eigen::MatrixXs& _cov);
+        void addPriorIntrinsics(const Eigen::VectorXs& _x,
+                                const Eigen::MatrixXs& _cov,
+                                unsigned int _start_idx = 0,
+                                int _size = -1);
+
         SizeEigen getCalibSize() const;
         Eigen::VectorXs getCalibration() const;
 
@@ -194,6 +226,8 @@ inline StateBlockPtr SensorBase::getStateBlockPtrStatic(unsigned int _i) const
 
 inline void SensorBase::setStateBlockPtrStatic(unsigned int _i, const StateBlockPtr _sb_ptr)
 {
+    assert (_i < state_block_vec_.size() && "Setting a state block pointer out of the vector range!");
+    assert((params_prior_map_.find(_i) == params_prior_map_.end() || _sb_ptr == nullptr) && "overwriting a state block that has an absolute constraint");
     state_block_vec_[_i] = _sb_ptr;
 }
 
@@ -250,6 +284,21 @@ inline void SensorBase::setHardwarePtr(const HardwareBasePtr _hw_ptr)
     hardware_ptr_ = _hw_ptr;
 }
 
+inline void SensorBase::addPriorP(const Eigen::VectorXs& _x, const Eigen::MatrixXs& _cov, unsigned int _start_idx, int _size)
+{
+    addPriorParameter(0, _x, _cov, _start_idx, _size);
+}
+
+inline void SensorBase::addPriorO(const Eigen::VectorXs& _x, const Eigen::MatrixXs& _cov)
+{
+    addPriorParameter(1, _x, _cov);
+}
+
+inline void SensorBase::addPriorIntrinsics(const Eigen::VectorXs& _x, const Eigen::MatrixXs& _cov, unsigned int _start_idx, int _size)
+{
+    addPriorParameter(2, _x, _cov);
+}
+
 inline SizeEigen SensorBase::getCalibSize() const
 {
     return calib_size_;
diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt
index 219a8a27999e9a512ab6d1585a0f67d0a425494f..47e53807a4afa37b9fe04e6cb80fb702ad007986 100644
--- a/src/test/CMakeLists.txt
+++ b/src/test/CMakeLists.txt
@@ -168,6 +168,10 @@ target_link_libraries(gtest_IMU ${PROJECT_NAME})
 wolf_add_gtest(gtest_make_posdef gtest_make_posdef.cpp)
 target_link_libraries(gtest_make_posdef ${PROJECT_NAME})
 
+# Parameter prior test
+wolf_add_gtest(gtest_param_prior gtest_param_prior.cpp)
+target_link_libraries(gtest_param_prior ${PROJECT_NAME})
+
 # Pinhole test
 wolf_add_gtest(gtest_pinhole gtest_pinhole.cpp)
 target_link_libraries(gtest_pinhole ${PROJECT_NAME})
diff --git a/src/test/gtest_constraint_absolute.cpp b/src/test/gtest_constraint_absolute.cpp
index a0587e29ce96207c1e7bdaa05fb4f7e4a9b5cbc4..de55b4767d7edefdc39f04fb67691b3e5511ed9d 100644
--- a/src/test/gtest_constraint_absolute.cpp
+++ b/src/test/gtest_constraint_absolute.cpp
@@ -27,18 +27,17 @@ Vector10s pose9toPose10(Vector9s _pose9)
 // Input pose9 and covariance
 Vector9s pose(Vector9s::Random());
 Vector10s pose10 = pose9toPose10(pose);
-Vector9s data_var((Vector9s() << 0.2,0.2,0.2,0.2,0.2,0.2,0.2,0.2,0.2).finished());
-Eigen::Matrix<wolf::Scalar, 9, 9> data_cov = data_var.asDiagonal();
+Eigen::Matrix<wolf::Scalar, 9, 9> data_cov = 0.2 * Eigen::Matrix<Scalar,9,9>::Identity();
 
 // perturbated priors
 Vector10s x0 = pose9toPose10(pose + Vector9s::Random()*0.25);
 
 // Problem and solver
-ProblemPtr problem = Problem::create("POV 3D");
-CeresManager ceres_mgr(problem);
+ProblemPtr problem_ptr = Problem::create("POV 3D");
+CeresManager ceres_mgr(problem_ptr);
 
 // Two frames
-FrameBasePtr frm0 = problem->emplaceFrame(KEY_FRAME, problem->zeroState(), TimeStamp(0));
+FrameBasePtr frm0 = problem_ptr->emplaceFrame(KEY_FRAME, problem_ptr->zeroState(), TimeStamp(0));
 
 // Capture, feature and constraint
 CaptureBasePtr cap0 = frm0->addCapture(std::make_shared<CaptureMotion>("IMU ABS", 0, nullptr, pose10, 10, 9, nullptr));
@@ -49,22 +48,13 @@ CaptureBasePtr cap0 = frm0->addCapture(std::make_shared<CaptureMotion>("IMU ABS"
  * Both features and constraints are created in the TEST(). Hence, tests will not interfere each others.
  */
 
-TEST(ConstraintBlockAbs, ctr_block_abs_p_check)
+TEST(ConstraintBlockAbs, ctr_block_abs_p)
 {
     FeatureBasePtr fea0 = cap0->addFeature(std::make_shared<FeatureBase>("POSITION", pose10.head<3>(), data_cov.topLeftCorner<3,3>()));
-    ConstraintBlockAbsolutePtr ctr0 = std::static_pointer_cast<ConstraintBlockAbsolute>(
-        fea0->addConstraint(std::make_shared<ConstraintBlockAbsolute>(fea0->getFramePtr()->getPPtr()))
-        );
-    ASSERT_TRUE(problem->check(0));
-}
+    fea0->addConstraint(std::make_shared<ConstraintBlockAbsolute>(fea0->getFramePtr()->getPPtr()));
+
+    ASSERT_TRUE(problem_ptr->check(0));
 
-TEST(ConstraintBlockAbs, ctr_block_abs_p_solve)
-{
-    FeatureBasePtr fea0 = cap0->addFeature(std::make_shared<FeatureBase>("POSITION", pose10.head<3>(), data_cov.topLeftCorner<3,3>()));
-    ConstraintBlockAbsolutePtr ctr0 = std::static_pointer_cast<ConstraintBlockAbsolute>(
-        fea0->addConstraint(std::make_shared<ConstraintBlockAbsolute>(fea0->getFramePtr()->getPPtr()))
-        );
-    
     // Unfix frame 0, perturb frm0
     frm0->unfix();
     frm0->setState(x0);
@@ -73,24 +63,31 @@ TEST(ConstraintBlockAbs, ctr_block_abs_p_solve)
     std::string brief_report = ceres_mgr.solve(wolf::SolverManager::ReportVerbosity::BRIEF);
 
     //only orientation is constrained
-    ASSERT_MATRIX_APPROX(frm0->getState().head<3>(), pose10.head<3>(), 1e-6);
+    ASSERT_MATRIX_APPROX(frm0->getPPtr()->getState(), pose10.head<3>(), 1e-6);
 }
 
-TEST(ConstraintBlockAbs, ctr_block_abs_v_check)
+TEST(ConstraintBlockAbs, ctr_block_abs_p_tail2)
 {
-    FeatureBasePtr fea0 = cap0->addFeature(std::make_shared<FeatureBase>("VELOCITY", pose10.tail<3>(), data_cov.bottomRightCorner<3,3>()));
-    ConstraintBlockAbsolutePtr ctr0 = std::static_pointer_cast<ConstraintBlockAbsolute>(
-        fea0->addConstraint(std::make_shared<ConstraintBlockAbsolute>(fea0->getFramePtr()->getVPtr()))
-        );
-    ASSERT_TRUE(problem->check(0));
+    FeatureBasePtr fea0 = cap0->addFeature(std::make_shared<FeatureBase>("POSITION TAIL 2", pose10.segment<2>(1), data_cov.bottomRightCorner<2,2>()));
+    fea0->addConstraint(std::make_shared<ConstraintBlockAbsolute>(fea0->getFramePtr()->getPPtr(),1,2));
+
+    // Unfix frame 0, perturb frm0
+    frm0->unfix();
+    frm0->setState(x0);
+
+    // solve for frm0
+    std::string brief_report = ceres_mgr.solve(wolf::SolverManager::ReportVerbosity::BRIEF);
+
+    //only orientation is constrained
+    ASSERT_MATRIX_APPROX(frm0->getPPtr()->getState().tail<2>(), pose10.segment<2>(1), 1e-6);
 }
 
-TEST(ConstraintBlockAbs, ctr_block_abs_v_solve)
+TEST(ConstraintBlockAbs, ctr_block_abs_v)
 {
     FeatureBasePtr fea0 = cap0->addFeature(std::make_shared<FeatureBase>("VELOCITY", pose10.tail<3>(), data_cov.bottomRightCorner<3,3>()));
-    ConstraintBlockAbsolutePtr ctr0 = std::static_pointer_cast<ConstraintBlockAbsolute>(
-        fea0->addConstraint(std::make_shared<ConstraintBlockAbsolute>(fea0->getFramePtr()->getVPtr()))
-        );
+    fea0->addConstraint(std::make_shared<ConstraintBlockAbsolute>(fea0->getFramePtr()->getVPtr()));
+
+    ASSERT_TRUE(problem_ptr->check(0));
     
     // Unfix frame 0, perturb frm0
     frm0->unfix();
@@ -100,24 +97,15 @@ TEST(ConstraintBlockAbs, ctr_block_abs_v_solve)
     std::string brief_report = ceres_mgr.solve(wolf::SolverManager::ReportVerbosity::BRIEF);
 
     //only velocity is constrained
-    ASSERT_MATRIX_APPROX(frm0->getState().tail<3>(), pose10.tail<3>(), 1e-6);
+    ASSERT_MATRIX_APPROX(frm0->getVPtr()->getState(), pose10.tail<3>(), 1e-6);
 }
 
-TEST(ConstraintQuatAbs, ctr_block_abs_o_check)
+TEST(ConstraintQuatAbs, ctr_block_abs_o)
 {
     FeatureBasePtr fea0 = cap0->addFeature(std::make_shared<FeatureBase>("QUATERNION", pose10.segment<4>(3), data_cov.block<3,3>(3,3)));
-    ConstraintBlockAbsolutePtr ctr0 = std::static_pointer_cast<ConstraintBlockAbsolute>(
-        fea0->addConstraint(std::make_shared<ConstraintQuaternionAbsolute>(fea0->getFramePtr()->getOPtr()))
-        );
-    ASSERT_TRUE(problem->check(0));
-}
+    fea0->addConstraint(std::make_shared<ConstraintQuaternionAbsolute>(fea0->getFramePtr()->getOPtr()));
 
-TEST(ConstraintQuatAbs, ctr_block_abs_o_solve)
-{
-    FeatureBasePtr fea0 = cap0->addFeature(std::make_shared<FeatureBase>("QUATERNION", pose10.segment<4>(3), data_cov.block<3,3>(3,3)));
-    ConstraintBlockAbsolutePtr ctr0 = std::static_pointer_cast<ConstraintBlockAbsolute>(
-        fea0->addConstraint(std::make_shared<ConstraintQuaternionAbsolute>(fea0->getFramePtr()->getOPtr()))
-        );
+    ASSERT_TRUE(problem_ptr->check(0));
     
     // Unfix frame 0, perturb frm0
     frm0->unfix();
@@ -127,7 +115,7 @@ TEST(ConstraintQuatAbs, ctr_block_abs_o_solve)
     std::string brief_report = ceres_mgr.solve(wolf::SolverManager::ReportVerbosity::BRIEF);
 
     //only velocity is constrained
-    ASSERT_MATRIX_APPROX(frm0->getState().segment<4>(3), pose10.segment<4>(3), 1e-6);
+    ASSERT_MATRIX_APPROX(frm0->getOPtr()->getState(), pose10.segment<4>(3), 1e-6);
 }
 
 int main(int argc, char **argv)
diff --git a/src/test/gtest_constraint_odom_3D.cpp b/src/test/gtest_constraint_odom_3D.cpp
index 68408277551644f6e04abd3a1bb3894ef0bb57af..17cb8e9e65d4139b7393fb0a40a9e96715f1f783 100644
--- a/src/test/gtest_constraint_odom_3D.cpp
+++ b/src/test/gtest_constraint_odom_3D.cpp
@@ -35,12 +35,12 @@ Vector7s x0 = data2delta(Vector6s::Random()*0.25);
 Vector7s x1 = data2delta(data + Vector6s::Random()*0.25);
 
 // Problem and solver
-ProblemPtr problem = Problem::create("PO 3D");
-CeresManager ceres_mgr(problem);
+ProblemPtr problem_ptr = Problem::create("PO 3D");
+CeresManager ceres_mgr(problem_ptr);
 
 // Two frames
-FrameBasePtr frm0 = problem->emplaceFrame(KEY_FRAME, problem->zeroState(), TimeStamp(0));
-FrameBasePtr frm1 = problem->emplaceFrame(KEY_FRAME, delta, TimeStamp(1));
+FrameBasePtr frm0 = problem_ptr->emplaceFrame(KEY_FRAME, problem_ptr->zeroState(), TimeStamp(0));
+FrameBasePtr frm1 = problem_ptr->emplaceFrame(KEY_FRAME, delta, TimeStamp(1));
 
 // Capture, feature and constraint from frm1 to frm0
 CaptureBasePtr cap1 = frm1->addCapture(std::make_shared<CaptureMotion>("ODOM 3D", 1, nullptr, delta, 7, 6, nullptr));
@@ -52,7 +52,7 @@ ConstraintBasePtr dummy = frm0->addConstrainedBy(ctr1);
 
 TEST(ConstraintOdom3D, check_tree)
 {
-    ASSERT_TRUE(problem->check(0));
+    ASSERT_TRUE(problem_ptr->check(0));
 }
 
 TEST(ConstraintOdom3D, expectation)
@@ -85,7 +85,7 @@ TEST(ConstraintOdom3D, fix_1_solve)
     // solve for frm0
     std::string brief_report = ceres_mgr.solve(SolverManager::ReportVerbosity::BRIEF);
 
-    ASSERT_MATRIX_APPROX(frm0->getState(), problem->zeroState(), 1e-6);
+    ASSERT_MATRIX_APPROX(frm0->getState(), problem_ptr->zeroState(), 1e-6);
 }
 
 int main(int argc, char **argv)
diff --git a/src/test/gtest_param_prior.cpp b/src/test/gtest_param_prior.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0048fa2ef7f7a2f09505a7d5dc1d616bfafb8d1f
--- /dev/null
+++ b/src/test/gtest_param_prior.cpp
@@ -0,0 +1,85 @@
+/*
+ * gtest_param_prior.cpp
+ *
+ *  Created on: Feb 6, 2019
+ *      Author: jvallve
+ */
+
+#include "utils_gtest.h"
+#include "../src/logging.h"
+
+#include "../problem.h"
+#include "../ceres_wrapper/ceres_manager.h"
+#include "../sensor_odom_3D.h"
+
+#include <iostream>
+
+using namespace wolf;
+
+ProblemPtr problem_ptr = Problem::create("PO 3D");
+CeresManagerPtr ceres_mgr_ptr = std::make_shared<CeresManager>(problem_ptr);
+Eigen::Vector7s initial_extrinsics((Eigen::Vector7s() << 1, 2, 3, 1, 0, 0, 0).finished());
+Eigen::Vector7s prior_extrinsics((Eigen::Vector7s() << 10, 20, 30, 0, 0, 0, 1).finished());
+Eigen::Vector7s prior2_extrinsics((Eigen::Vector7s() << 100, 200, 300, 0, 0, 0, 1).finished());
+
+SensorOdom3DPtr odom_sensor_ptr_ = std::static_pointer_cast<SensorOdom3D>(problem_ptr->installSensor("ODOM 3D", "odometer", initial_extrinsics, std::make_shared<IntrinsicsOdom3D>()));
+
+TEST(ParameterPrior, initial_extrinsics)
+{
+    ASSERT_TRUE(problem_ptr->check(0));
+    ASSERT_TRUE(odom_sensor_ptr_->getPPtr());
+    ASSERT_TRUE(odom_sensor_ptr_->getOPtr());
+    ASSERT_MATRIX_APPROX(odom_sensor_ptr_->getPPtr()->getState(),initial_extrinsics.head(3),1e-9);
+    ASSERT_MATRIX_APPROX(odom_sensor_ptr_->getOPtr()->getState(),initial_extrinsics.tail(4),1e-9);
+}
+
+TEST(ParameterPrior, prior_p)
+{
+    odom_sensor_ptr_->addPriorP(prior_extrinsics.head(3),Eigen::Matrix3s::Identity());
+
+    std::string report = ceres_mgr_ptr->solve(SolverManager::ReportVerbosity::BRIEF);
+
+    ASSERT_MATRIX_APPROX(odom_sensor_ptr_->getPPtr()->getState(),prior_extrinsics.head(3),1e-6);
+}
+
+TEST(ParameterPrior, prior_o)
+{
+    odom_sensor_ptr_->addPriorO(prior_extrinsics.tail(4),Eigen::Matrix3s::Identity());
+
+    std::string report = ceres_mgr_ptr->solve(SolverManager::ReportVerbosity::BRIEF);
+
+    ASSERT_MATRIX_APPROX(odom_sensor_ptr_->getOPtr()->getState(),prior_extrinsics.tail(4),1e-6);
+}
+
+TEST(ParameterPrior, prior_p_overwrite)
+{
+    odom_sensor_ptr_->addPriorP(prior2_extrinsics.head(3),Eigen::Matrix3s::Identity());
+
+    std::string report = ceres_mgr_ptr->solve(SolverManager::ReportVerbosity::BRIEF);
+
+    ASSERT_MATRIX_APPROX(odom_sensor_ptr_->getPPtr()->getState(),prior2_extrinsics.head(3),1e-6);
+}
+
+TEST(ParameterPrior, prior_p_segment)
+{
+    odom_sensor_ptr_->addPriorP(prior_extrinsics.segment(1,2),Eigen::Matrix2s::Identity(),1,2);
+
+    std::string report = ceres_mgr_ptr->solve(SolverManager::ReportVerbosity::BRIEF);
+
+    ASSERT_MATRIX_APPROX(odom_sensor_ptr_->getPPtr()->getState().segment(1,2),prior_extrinsics.segment(1,2),1e-6);
+}
+
+TEST(ParameterPrior, prior_o_segment)
+{
+    // constraining segment of quaternion is not allowed
+    ASSERT_DEATH(odom_sensor_ptr_->addPriorParameter(1, prior_extrinsics.segment(1,2),Eigen::Matrix2s::Identity(),1,2),"");
+}
+
+
+
+int main(int argc, char **argv)
+{
+  testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
+