diff --git a/include/imu/factor/factor_imu.h b/include/imu/factor/factor_imu.h
index a7ff2d7b063657ec39fff82552fceedf82999847..61a2daa8c981e210ce281b3f898e31bcaf42ed82 100644
--- a/include/imu/factor/factor_imu.h
+++ b/include/imu/factor/factor_imu.h
@@ -46,6 +46,8 @@ class FactorImu : public FactorAutodiff<FactorImu, 15, 3, 4, 3, 6, 3, 4, 3, 6>
          *
          */
         Eigen::Vector9d error();
+        Eigen::Vector9d res();
+        double cost();
 
 
         /** \brief : compute the residual from the state blocks being iterated by the solver. (same as operator())
@@ -252,6 +254,18 @@ Eigen::Vector9d FactorImu::error()
     return err;
 }
 
+
+Eigen::Vector9d FactorImu::res(){
+    Eigen::Vector9d err = error();
+    return getMeasurementSquareRootInformationUpper()*err;
+}
+
+
+double FactorImu::cost(){
+    return res().squaredNorm();
+}
+
+
 template<typename D1, typename D2, typename D3>
 inline bool FactorImu::residual(const Eigen::MatrixBase<D1> &       _p1,
                                 const Eigen::QuaternionBase<D2> &   _q1,
diff --git a/include/imu/sensor/sensor_imu.h b/include/imu/sensor/sensor_imu.h
index 07b289c0ac0e21451dbe682774d3aeddc79ffa7b..c4e5f5bb8df481d7d53205ffb83511fd565225d8 100644
--- a/include/imu/sensor/sensor_imu.h
+++ b/include/imu/sensor/sensor_imu.h
@@ -33,12 +33,12 @@ struct ParamsSensorImu : public ParamsSensorBase
     ParamsSensorImu(std::string _unique_name, const ParamsServer& _server):
         ParamsSensorBase(_unique_name, _server)
     {
-        w_noise             = _server.getParam<double>(prefix + _unique_name + "/w_noise");
-        a_noise             = _server.getParam<double>(prefix + _unique_name + "/a_noise");
-        ab_initial_stdev    = _server.getParam<double>(prefix + _unique_name + "/ab_initial_stdev");
-        wb_initial_stdev    = _server.getParam<double>(prefix + _unique_name + "/wb_initial_stdev");
-        ab_rate_stdev       = _server.getParam<double>(prefix + _unique_name + "/ab_rate_stdev");
-        wb_rate_stdev       = _server.getParam<double>(prefix + _unique_name + "/wb_rate_stdev");
+        w_noise             = _server.getParam<double>(prefix + _unique_name + "/motion_variances/w_noise");
+        a_noise             = _server.getParam<double>(prefix + _unique_name + "/motion_variances/a_noise");
+        ab_initial_stdev    = _server.getParam<double>(prefix + _unique_name + "/motion_variances/ab_initial_stdev");
+        wb_initial_stdev    = _server.getParam<double>(prefix + _unique_name + "/motion_variances/wb_initial_stdev");
+        ab_rate_stdev       = _server.getParam<double>(prefix + _unique_name + "/motion_variances/ab_rate_stdev");
+        wb_rate_stdev       = _server.getParam<double>(prefix + _unique_name + "/motion_variances/wb_rate_stdev");
     }
     std::string print() const override
     {
diff --git a/test/gtest_imu_mocap_fusion.cpp b/test/gtest_imu_mocap_fusion.cpp
index bb668f2b85062e100ad80dbd92ce29411dd19458..c753366d6ec44e2a6c2bf668acc5a493d109a0c6 100644
--- a/test/gtest_imu_mocap_fusion.cpp
+++ b/test/gtest_imu_mocap_fusion.cpp
@@ -20,6 +20,7 @@
 #include "imu/capture/capture_imu.h"
 #include "imu/sensor/sensor_imu.h"
 #include "imu/processor/processor_imu.h"
+#include "imu/factor/factor_imu.h"
 
 #include "Eigen/Dense"
 #include <Eigen/SparseQR>
@@ -32,6 +33,24 @@ using namespace wolf;
 const Vector3d zero3 = Vector3d::Zero();
 const double dt = 0.001;
 
+const bool WRITE_CSV = false;
+
+
+void printingFactorErrors(ProblemPtr pbe){
+    std::cout << "\n\nPrinting factor errors: " << std::endl;
+    for (auto KF: pbe->getTrajectory()->getFrameMap()){
+        for (auto fac: KF.second->getFactorList()){
+            auto f = std::dynamic_pointer_cast<FactorPose3dWithExtrinsics>(fac);
+            if (f){
+                std::cout << f->getType()  << " " << f->error().transpose() << std::endl;
+            }
+            else{
+                auto fi = std::dynamic_pointer_cast<FactorImu>(fac);
+                std::cout << fi->getType() << " " << fi->error().transpose() << std::endl;
+            }
+        }
+    }
+}
 
 class ImuMocapFusion_Test : public testing::Test
 {
@@ -47,7 +66,7 @@ class ImuMocapFusion_Test : public testing::Test
         Quaterniond b_q_m_;
         Vector3d ba_;
         Vector3d bw_;
-        double t_max;
+        double t_max_;
 
     void SetUp() override
     {
@@ -61,30 +80,27 @@ class ImuMocapFusion_Test : public testing::Test
         Vector3d freq_ang; freq_ang << 3.5, 3, 2.5; // in seconds
         freq_lin *= 2*M_PI;  // pass in radians
         freq_ang *= 2*M_PI;
-        Vector3d amp_p; amp_p << 1.2, 1, 0.8;
+        Vector3d amp_p; amp_p << 0.1, 0.2, 0.3;
         Vector3d amp_a = amp_p.array() * freq_lin.array().square();
-        Vector3d amp_o; amp_o << 1, 1, 1;
+        Vector3d amp_o; amp_o << 0.5, 0.6, 0.7;  // rad
         // Vector3d amp_o; amp_o << 0,0,0;
         Vector3d amp_w = amp_o.array() * freq_ang.array();
 
-        // P = cos(freq*t) + cst
-        // V = -freq*sin(freq*t)
-        // A = -freq^2*cos(freq*t)
-
         // biases and extrinsics
         // ba_ = Vector3d::Zero();
         // bw_ = Vector3d::Zero();
-        ba_ << 0.003, 0.002, 0.002;
-        bw_ << 0.004, 0.003, 0.002;
+        ba_ << 0.01, 0.02, 0.03;
+        bw_ << 0.04, 0.03, 0.02;
         // b_p_bm_ = Vector3d::Zero();
         // b_q_m_ = Quaterniond::Identity();
         b_p_bm_ << 0.1, 0.2, 0.3;
-        b_q_m_ = Quaterniond(0,0,0,1);
+        Vector4d b_q_m_vec; b_q_m_vec << 0.5,0.5,0.5,0.5;
+        b_q_m_ = Quaterniond(b_q_m_vec);
         
         // initialize state
         Vector3d w_p_wb = Vector3d::Zero();
         Quaterniond w_q_b = Quaterniond::Identity();
-        Vector3d w_v_wb = Vector3d::Zero();  // * cos(0)
+        Vector3d w_v_wb = Vector3d::Zero();
 
         // Problem and solver_
         problem_ = Problem::create("POV", 3);
@@ -92,20 +108,21 @@ class ImuMocapFusion_Test : public testing::Test
         solver_->getSolverOptions().max_num_iterations = 500;
         // initial guess
         VectorComposite x_origin("POV", {w_p_wb, w_q_b.coeffs(), w_v_wb});
-        FrameBasePtr KF1 = problem_->setPriorInitialGuess(x_origin, 0, 0.0005);  // if mocap used
+        FrameBasePtr KF1 = problem_->setPriorInitialGuess(x_origin, 0, 0.0005);
 
         // pose sensor and proc (to get extrinsics in the prb)
         auto intr_sp = std::make_shared<ParamsSensorPose>();
         intr_sp->std_p = 0.001;
         intr_sp->std_o = 0.001;
-        Vector7d extr; extr << 0,0,0, 0,0,0,1;
-        sensor_pose_ = problem_->installSensor("SensorPose", "pose", extr, intr_sp);
+        // Vector7d pose_extr; pose_extr << 0,0,0, 0,0,0,1;
+        Vector7d pose_extr; pose_extr << b_p_bm_, b_q_m_vec;
+        sensor_pose_ = problem_->installSensor("SensorPose", "pose", pose_extr, intr_sp);
         auto params_proc = std::make_shared<ParamsProcessorPose>();
-        params_proc->time_tolerance = 0.0005;
+        params_proc->time_tolerance = dt/2;
         auto proc_pose = problem_->installProcessor("ProcessorPose", "pose", sensor_pose_, params_proc);
         // somehow by default the sensor extrinsics is fixed
-        sensor_pose_->unfixExtrinsics();
-        // sensor_pose_->fixExtrinsics();
+        // sensor_pose_->unfixExtrinsics();
+        sensor_pose_->fixExtrinsics();
         Matrix6d cov_pose = sensor_pose_->getNoiseCov();
 
         // IMU sensor 
@@ -113,8 +130,8 @@ class ImuMocapFusion_Test : public testing::Test
         ParamsSensorImuPtr sen_imu_params = std::make_shared<ParamsSensorImu>();
         sen_imu_params->a_noise = 0.01;
         sen_imu_params->w_noise = 0.01;
-        sen_imu_params->ab_rate_stdev = 0.00001;
-        sen_imu_params->wb_rate_stdev = 0.00001;
+        sen_imu_params->ab_rate_stdev = 1e-12;
+        sen_imu_params->wb_rate_stdev = 1e-12;
         sensor_imu_ = problem_->installSensor("SensorImu", "Main Imu", imu_extr, sen_imu_params);
         ParamsProcessorImuPtr prc_imu_params = std::make_shared<ParamsProcessorImu>();
         prc_imu_params->max_time_span   = 0.199999;
@@ -122,40 +139,57 @@ class ImuMocapFusion_Test : public testing::Test
         prc_imu_params->dist_traveled   = 10000000000;
         prc_imu_params->angle_turned    = 1000000000;  
         prc_imu_params->voting_active   = true;
+        prc_imu_params->time_tolerance = dt/2;
         auto proc_base = problem_->installProcessor("ProcessorImu", "Imu pre-integrator", sensor_imu_, prc_imu_params);
         ProcessorImuPtr proc_imu = std::static_pointer_cast<ProcessorImu>(proc_base);
+        Vector6d imu_bias; imu_bias << ba_, bw_;
+        sensor_imu_->getStateBlock('I')->setState(imu_bias);
+        sensor_imu_->getStateBlock('I')->perturb(0.01);
         proc_imu->setOrigin(KF1);
         Matrix6d cov_imu = sensor_imu_->getNoiseCov();
         // sensor_imu_->fixIntrinsics();
         sensor_imu_->unfixIntrinsics();
 
-        // Store necessary values in vectors
-        // std::vector<Vector3d> w_p_wb_vec; 
-        // std::vector<Vector3d> w_p_wb_sin_vec; 
-        // std::vector<Quaterniond> w_q_b_vec; 
-        // std::vector<Vector3d> w_v_wb_vec;
 
-        // w_p_wb_vec.push_back(w_p_wb);
-        // w_p_wb_sin_vec.push_back(w_p_wb);
-        // w_q_b_vec.push_back(w_q_b);
-        // w_v_wb_vec.push_back(w_v_wb);
-
-
-        // std::fstream file_gtr; 
-        // file_gtr.open("/home/mfourmy/Documents/Phd_LAAS/phd_misc/PhdTests/gtest_gtr.csv", std::fstream::out); 
-        // std::string header = "t,px,py,pz,qx,qy,qz,qw,vx,vy,vz\n";
-        // file_gtr << header;
-
-        double t = 0;
-        t_max = 5.0;
-        while (t <= t_max){
-            // P = cos(freq*t) + cst
+        #ifdef WRITE_CSV
+            std::fstream file_gtr; 
+            file_gtr.open("/home/mfourmy/Documents/Phd_LAAS/phd_misc/PhdTests/gtest_gtr.csv", std::fstream::out); 
+            std::string header = "t,px,py,pz,qx,qy,qz,qw,vx,vy,vz\n";
+            file_gtr << header;
+
+            std::fstream file_bias; 
+            file_bias.open("/home/mfourmy/Documents/Phd_LAAS/phd_misc/PhdTests/gtest_bias.csv", std::fstream::out); 
+            std::string header_bias = "t,bax,bay,baz,bwx,bwy,bwz\n";
+            file_bias << header_bias;
+
+            file_gtr << std::setprecision(std::numeric_limits<long double>::digits10 + 1)
+                << 0.0 << ","
+                << w_p_wb(0) << ","
+                << w_p_wb(1) << ","
+                << w_p_wb(2) << "," 
+                << w_q_b.coeffs()(0) << "," 
+                << w_q_b.coeffs()(1) << "," 
+                << w_q_b.coeffs()(2) << "," 
+                << w_q_b.coeffs()(3) << "," 
+                << w_v_wb(0) << "," 
+                << w_v_wb(1) << "," 
+                << w_v_wb(2) 
+                << "\n"; 
+        #endif
+
+
+
+        double t = dt; // skip the zero so that data correspond to current state
+        t_max_ = 2;
+        int nb_kf = 1;
+        while (t <= t_max_){
+            // P = cos(freq*t)
             // V = -freq*sin(freq*t)
             // A = -freq^2*cos(freq*t)
             Vector3d b_omg_b = -amp_w.array()*Eigen::sin((freq_ang*t).array());
-            Vector3d b_a_wb = -amp_a.array()*Eigen::cos((freq_lin*t).array());
+            Vector3d b_a_wb =  -amp_a.array()*Eigen::cos((freq_lin*t).array());
 
-            // imu measurements (BETTER HERE)
+            // imu measurements
             Vector3d acc_meas = b_a_wb - w_q_b.conjugate() * wolf::gravity() + ba_;
             Vector3d omg_meas = b_omg_b + bw_;
 
@@ -164,41 +198,61 @@ class ImuMocapFusion_Test : public testing::Test
             w_v_wb = w_v_wb + w_q_b*b_a_wb*dt;
             w_q_b =  w_q_b*wolf::exp_q(b_omg_b*dt);
 
-            // file_gtr << std::setprecision(std::numeric_limits<long double>::digits10 + 1)
-            //     << t << ","
-            //     << w_p_wb(0) << ","
-            //     << w_p_wb(1) << ","
-            //     << w_p_wb(2) << "," 
-            //     << w_q_b.coeffs()(0) << "," 
-            //     << w_q_b.coeffs()(1) << "," 
-            //     << w_q_b.coeffs()(2) << "," 
-            //     << w_q_b.coeffs()(3) << "," 
-            //     << w_v_wb(0) << "," 
-            //     << w_v_wb(1) << "," 
-            //     << w_v_wb(2) 
-            //     << "\n"; 
-
-            // // imu measurements
-            // Vector3d acc_meas = b_a_wb - w_q_b.conjugate() * wolf::gravity() + ba_;
-            // Vector3d omg_meas = b_omg_b + bw_;
             // mocap measurements
             Vector3d w_p_wm = w_p_wb + w_q_b*b_p_bm_;
             Quaterniond w_q_m = w_q_b * b_q_m_;
 
+            #ifdef WRITE_CSV
+                file_gtr << std::setprecision(std::numeric_limits<long double>::digits10 + 1)
+                    << t << ","
+                    << w_p_wb(0) << ","
+                    << w_p_wb(1) << ","
+                    << w_p_wb(2) << "," 
+                    << w_q_b.coeffs()(0) << "," 
+                    << w_q_b.coeffs()(1) << "," 
+                    << w_q_b.coeffs()(2) << "," 
+                    << w_q_b.coeffs()(3) << "," 
+                    << w_v_wb(0) << "," 
+                    << w_v_wb(1) << "," 
+                    << w_v_wb(2) 
+                    << "\n";
+            #endif 
+   
             // process data
             Vector6d imu_data; imu_data << acc_meas, omg_meas;
             CaptureBasePtr CIMU = std::make_shared<CaptureImu>(t, sensor_imu_, imu_data, cov_imu);
             CIMU->process();
-            // sensor_imu_->fixIntrinsics();
-            sensor_imu_->unfixIntrinsics();
             Vector7d pose_data; pose_data << w_p_wm, w_q_m.coeffs();
             CaptureBasePtr CP = std::make_shared<CapturePose>(t, sensor_pose_, pose_data, cov_pose);
             CP->process();
 
+
+            // solve every new KF
+            if (problem_->getTrajectory()->getFrameMap().size() > nb_kf ){
+                std::string report = solver_->solve(SolverManager::ReportVerbosity::BRIEF);
+                nb_kf = problem_->getTrajectory()->getFrameMap().size();
+
+                Vector6d imu_bias = sensor_imu_->getIntrinsic()->getState();
+                #ifdef WRITE_CSV
+                    file_bias << std::setprecision(std::numeric_limits<long double>::digits10 + 1)
+                        << t << ","
+                        << imu_bias(0) << ","
+                        << imu_bias(1) << ","
+                        << imu_bias(2) << "," 
+                        << imu_bias(3) << ","
+                        << imu_bias(4) << ","
+                        << imu_bias(5)
+                        << "\n"; 
+                #endif
+            }
+
             t+=dt;
         }
 
-        // file_gtr.close();
+        #ifdef WRITE_CSV
+            file_gtr.close();
+            file_bias.close();
+        #endif WRITE_CSV
 
     }
 
@@ -216,61 +270,66 @@ TEST_F(ImuMocapFusion_Test, check_tree)
 TEST_F(ImuMocapFusion_Test, solve)
 {
 
-    // std::fstream file_int; 
-    // std::fstream file_est; 
-    // file_int.open("/home/mfourmy/Documents/Phd_LAAS/phd_misc/PhdTests/gtest_int.csv", std::fstream::out); 
-    // file_est.open("/home/mfourmy/Documents/Phd_LAAS/phd_misc/PhdTests/gtest_est.csv", std::fstream::out); 
-    // std::string header = "t,px,py,pz,qx,qy,qz,qw,vx,vy,vz\n";
-    // file_int << header;
-    // file_est << header;
-
-    // double t = 0;
-    // while (t <= t_max){
-    //     auto s = problem_->getState(t);
-    //     file_int << std::setprecision(std::numeric_limits<long double>::digits10 + 1)
-    //         << t << ","
-    //         << s['P'](0) << ","
-    //         << s['P'](1) << ","
-    //         << s['P'](2) << "," 
-    //         << s['O'](0) << "," 
-    //         << s['O'](1) << "," 
-    //         << s['O'](2) << "," 
-    //         << s['O'](3) << "," 
-    //         << s['V'](0) << "," 
-    //         << s['V'](1) << "," 
-    //         << s['V'](2) 
-    //         << "\n"; 
-    //     t+=dt;
-    // }
-    // problem_->print(4, 1, 1, 1);
+    std::fstream file_int; 
+    std::fstream file_est; 
+    file_int.open("/home/mfourmy/Documents/Phd_LAAS/phd_misc/PhdTests/gtest_int.csv", std::fstream::out); 
+    file_est.open("/home/mfourmy/Documents/Phd_LAAS/phd_misc/PhdTests/gtest_est.csv", std::fstream::out); 
+    std::string header = "t,px,py,pz,qx,qy,qz,qw,vx,vy,vz\n";
+    file_int << header;
+    file_est << header;
+
+    double t = 0;
+    while (t <= t_max_){
+        auto s = problem_->getState(t);
+        file_int << std::setprecision(std::numeric_limits<long double>::digits10 + 1)
+            << t << ","
+            << s['P'](0) << ","
+            << s['P'](1) << ","
+            << s['P'](2) << "," 
+            << s['O'](0) << "," 
+            << s['O'](1) << "," 
+            << s['O'](2) << "," 
+            << s['O'](3) << "," 
+            << s['V'](0) << "," 
+            << s['V'](1) << "," 
+            << s['V'](2) 
+            << "\n"; 
+        t+=dt;
+    }
+
+    printingFactorErrors(problem_);
+
+    problem_->print(4, 1, 1, 1);
     problem_->perturb();
     std::string report = solver_->solve(SolverManager::ReportVerbosity::FULL);
-    // std::cout << report << std::endl;
-    // problem_->print(4, 1, 1, 1);
-
-    // t = 0;
-    // while (t <= t_max){
-    //     auto s = problem_->getState(t);
-    //     file_est << std::setprecision(std::numeric_limits<long double>::digits10 + 1)
-    //         << t << ","
-    //         << s['P'](0) << ","
-    //         << s['P'](1) << ","
-    //         << s['P'](2) << "," 
-    //         << s['O'](0) << "," 
-    //         << s['O'](1) << "," 
-    //         << s['O'](2) << "," 
-    //         << s['O'](3) << "," 
-    //         << s['V'](0) << "," 
-    //         << s['V'](1) << "," 
-    //         << s['V'](2)
-    //         << "\n"; 
-    //     t+=dt;
-    // }
-
-    // file_int.close();
-    // file_est.close();
-
-    ASSERT_MATRIX_APPROX(sensor_pose_->getP()->getState(), b_p_bm_, 1e-6);
+    std::cout << report << std::endl;
+    problem_->print(4, 1, 1, 1);
+
+    t = 0;
+    while (t <= t_max_){
+        auto s = problem_->getState(t);
+        file_est << std::setprecision(std::numeric_limits<long double>::digits10 + 1)
+            << t << ","
+            << s['P'](0) << ","
+            << s['P'](1) << ","
+            << s['P'](2) << "," 
+            << s['O'](0) << "," 
+            << s['O'](1) << "," 
+            << s['O'](2) << "," 
+            << s['O'](3) << "," 
+            << s['V'](0) << "," 
+            << s['V'](1) << "," 
+            << s['V'](2)
+            << "\n"; 
+        t+=dt;
+    }
+
+    file_int.close();
+    file_est.close();
+
+    printingFactorErrors(problem_);
+
+    ASSERT_MATRIX_APPROX(sensor_pose_->getP()->getState(), b_p_bm_, 1e-5);
     ASSERT_MATRIX_APPROX(sensor_pose_->getO()->getState(), b_q_m_.coeffs(), 1e-6);
     ASSERT_MATRIX_APPROX(sensor_imu_->getIntrinsic()->getState(), (Vector6d() << ba_, bw_).finished(), 1e-4);
 }