diff --git a/include/core/processor/processor_odom_3d.h b/include/core/processor/processor_odom_3d.h
index 676cb6cd05d51240cad7a5008ca301ccb5af67e3..438dcc33b0e02f62c241b6852cd5d4fd29c4184e 100644
--- a/include/core/processor/processor_odom_3d.h
+++ b/include/core/processor/processor_odom_3d.h
@@ -114,13 +114,6 @@ class ProcessorOdom3d : public ProcessorMotion
     protected:
         ParamsProcessorOdom3dPtr params_odom_3d_;
 
-        // noise parameters (stolen from owner SensorOdom3d)
-        double k_disp_to_disp_; // displacement variance growth per meter of linear motion
-        double k_disp_to_rot_;  // orientation  variance growth per meter of linear motion
-        double k_rot_to_rot_;   // orientation  variance growth per radian of rotational motion
-        double min_disp_var_;   // floor displacement variance when no  motion
-        double min_rot_var_;    // floor orientation variance when no motion
-
 };
 
 inline Eigen::VectorXd ProcessorOdom3d::deltaZero() const
diff --git a/include/core/sensor/sensor_odom_2d.h b/include/core/sensor/sensor_odom_2d.h
index 5f2fc1a717b7c58f985ede8845ea2de01dc17fcb..ca06c7c010bc153756650f35c55e01114fdf4e34 100644
--- a/include/core/sensor/sensor_odom_2d.h
+++ b/include/core/sensor/sensor_odom_2d.h
@@ -62,6 +62,25 @@ class SensorOdom2d : public SensorBase
          **/
         double getRotVarToRotNoiseFactor() const;
 
+        /**
+         * Compute covariance of odometry given the motion data.
+         *
+         * NOTE: This is a helper function for the user, not called automatically anywhere.
+         *
+         * computeCovFromMotion() produces a diagonal covariance that depends on the amount of motion:
+         *  - a linear dependence with total displacement
+         *  - a linear dependence with total rotation
+         *
+         *  The formula for the variances is as follows:
+         *
+         *    - disp_var = k_disp_to_disp * displacement
+         *    - rot_var  = k_rot_to_rot   * rotation
+         *
+         * See implementation for details.
+         */
+        Matrix3d computeCovFromMotion (const VectorXd& _data) const;
+
+
 };
 
 } // namespace wolf
diff --git a/include/core/sensor/sensor_odom_3d.h b/include/core/sensor/sensor_odom_3d.h
index ab0e8b46872c21015b02ffcb9d521dbd77e2a606..d5f5b417eb36a0628a3425822d03b3fef494fb36 100644
--- a/include/core/sensor/sensor_odom_3d.h
+++ b/include/core/sensor/sensor_odom_3d.h
@@ -72,6 +72,26 @@ class SensorOdom3d : public SensorBase
         double getMinDispVar() const;
         double getMinRotVar() const;
 
+        /**
+         * Compute covariance of odometry given the motion data.
+         *
+         * NOTE: This is a helper function for the user, not called automatically anywhere.
+         *
+         * computeCovFromMotion() produces a diagonal covariance that depends on the amount of motion:
+         *  - a minimal value for displacement
+         *  - a minimal value for rotation
+         *  - a linear dependence with total displacement
+         *  - a linear dependence with total rotation
+         *
+         *  The formula for the variances is as follows:
+         *
+         *    - disp_var = disp_var_min + k_disp_to_disp * displacement
+         *    - rot_var  = rot_var_min  + k_disp_to_rot  * displacement + k_rot_to_rot * rotation
+         *
+         * See implementation for details.
+         */
+        Matrix6d computeCovFromMotion (const VectorXd& _data) const;
+
 };
 
 inline double SensorOdom3d::getDispVarToDispNoiseFactor() const
diff --git a/src/processor/processor_odom_3d.cpp b/src/processor/processor_odom_3d.cpp
index c7be4d48c4d086d5d4f594dfa7849419d8cc5c30..8d8b190eef3ca6836e75b2868e40c56afea83fb4 100644
--- a/src/processor/processor_odom_3d.cpp
+++ b/src/processor/processor_odom_3d.cpp
@@ -6,12 +6,7 @@ namespace wolf
 
 ProcessorOdom3d::ProcessorOdom3d(ParamsProcessorOdom3dPtr _params) :
                         ProcessorMotion("ProcessorOdom3d", "PO", 3, 7, 7, 6, 6, 0, _params),
-                        params_odom_3d_ (_params),
-                        k_disp_to_disp_ (0),
-                        k_disp_to_rot_  (0),
-                        k_rot_to_rot_   (0),
-                        min_disp_var_   (0.1),          // around 10cm error
-                        min_rot_var_    (0.1)           // around 6 degrees error
+                        params_odom_3d_ (_params)
 {
      // Set constant parts of Jacobians
     jacobian_delta_preint_.setIdentity(6,6);
@@ -29,13 +24,6 @@ void ProcessorOdom3d::configure(SensorBasePtr _sensor)
     assert (_sensor && "Trying to configure processor with a sensor but provided sensor is nullptr.");
 
     SensorOdom3dPtr sen_ptr = std::static_pointer_cast<SensorOdom3d>(_sensor);
-
-    // we steal the parameters from the provided odom3d sensor.
-    k_disp_to_disp_ = sen_ptr->getDispVarToDispNoiseFactor();
-    k_disp_to_rot_  = sen_ptr->getDispVarToRotNoiseFactor();
-    k_rot_to_rot_   = sen_ptr->getRotVarToRotNoiseFactor();
-    min_disp_var_   = sen_ptr->getMinDispVar();
-    min_rot_var_    = sen_ptr->getMinRotVar();
 }
 
 void ProcessorOdom3d::computeCurrentDelta(const Eigen::VectorXd& _data,
diff --git a/src/sensor/sensor_odom_2d.cpp b/src/sensor/sensor_odom_2d.cpp
index ec7a3b54d3f8163f44276bf8120cb482a3a2fdd7..a3fe8ee9aa2a81849fb0caa2789d785cdafcf22a 100644
--- a/src/sensor/sensor_odom_2d.cpp
+++ b/src/sensor/sensor_odom_2d.cpp
@@ -34,6 +34,17 @@ double SensorOdom2d::getRotVarToRotNoiseFactor() const
     return k_rot_to_rot_;
 }
 
+Eigen::Matrix3d SensorOdom2d::computeCovFromMotion (const VectorXd& _data) const
+{
+    double d = fabs(_data(0));
+    double r = fabs(_data(1));
+
+    double dvar = k_disp_to_disp_ * d;
+    double rvar = k_rot_to_rot_   * r;
+
+    return (Matrix3d() << dvar, dvar, rvar).finished();
+}
+
 }
 
 // Register in the FactorySensor
diff --git a/src/sensor/sensor_odom_3d.cpp b/src/sensor/sensor_odom_3d.cpp
index 58b9b62ee9e111ce84887ba16e728a3494e40b7a..5954f505c0daf3e37588e0b78bf2b3b440b1052f 100644
--- a/src/sensor/sensor_odom_3d.cpp
+++ b/src/sensor/sensor_odom_3d.cpp
@@ -9,6 +9,7 @@
 
 #include "core/state_block/state_block.h"
 #include "core/state_block/state_quaternion.h"
+#include "core/math/rotations.h"
 
 namespace wolf {
 
@@ -37,6 +38,21 @@ SensorOdom3d::~SensorOdom3d()
     //
 }
 
+Eigen::Matrix6d SensorOdom3d::computeCovFromMotion (const VectorXd& _data) const
+{
+    double d = _data.head<3>().norm();
+    double r;
+    if (_data.size() == 6)
+        r = _data.tail<3>().norm();
+    else
+        r = 2 * acos(_data(6)); // arc cos of real part of quaternion
+
+    double dvar = min_disp_var_ + k_disp_to_disp_ * d;
+    double rvar = min_rot_var_  + k_disp_to_rot_  * d + k_rot_to_rot_ * r;
+
+    return (Matrix6d() << dvar, dvar, dvar, rvar, rvar, rvar).finished();
+}
+
 } // namespace wolf
 
 // Register in the FactorySensor
diff --git a/test/gtest_processor_odom_3d.cpp b/test/gtest_processor_odom_3d.cpp
index dc24beddd0643d7d64d21deeb59c2068752d50ec..876a4450d65e0da3231f1f9b91b9e56e3b97ac69 100644
--- a/test/gtest_processor_odom_3d.cpp
+++ b/test/gtest_processor_odom_3d.cpp
@@ -44,18 +44,10 @@ class ProcessorOdom3dTest : public ProcessorOdom3d
 {
     public:
         ProcessorOdom3dTest();
-
-        // getters :-D !!
-        double& kdd() {return k_disp_to_disp_;}
-        double& kdr() {return k_disp_to_rot_;}
-        double& krr() {return k_rot_to_rot_;}
-        double& dvar_min() {return min_disp_var_;}
-        double& rvar_min() {return min_rot_var_;}
 };
 ProcessorOdom3dTest::ProcessorOdom3dTest() : ProcessorOdom3d(std::make_shared<ParamsProcessorOdom3d>())
 {
-    dvar_min() = 0.5;
-    rvar_min() = 0.25;
+    //
 }
 
 TEST(ProcessorOdom3d, computeCurrentDelta)
@@ -76,11 +68,8 @@ TEST(ProcessorOdom3d, computeCurrentDelta)
     delta.head<3>() = delta_dp;
     delta.tail<4>() = delta_dq.coeffs();
 
-    // construct covariance from processor parameters and motion magnitudes
-    double disp = data_dp.norm();
-    double rot = data_do.norm();
-    double dvar = prc.dvar_min() + prc.kdd()*disp;
-    double rvar = prc.rvar_min() + prc.kdr()*disp + prc.krr()*rot;
+    double dvar = 0.1;
+    double rvar = 0.2;
     Vector6d diag; diag << dvar, dvar, dvar, rvar, rvar, rvar;
     Matrix6d data_cov = diag.asDiagonal();
     Matrix6d delta_cov = data_cov;
@@ -119,8 +108,6 @@ TEST(ProcessorOdom3d, deltaPlusDelta)
     prc.deltaPlusDelta(D, d, dt, D_int);
 
     ASSERT_MATRIX_APPROX(D_int , D_int_check, 1e-10);
-//        << "\nDpd  : " << D_int.transpose()
-//        << "\ncheck: " << D_int_check.transpose();
 }
 
 TEST(ProcessorOdom3d, deltaPlusDelta_Jac)