diff --git a/test/gtest_processor_odom_icp_3d.cpp b/test/gtest_processor_odom_icp_3d.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0703ed18b8a2f88e1aab438c37424cf05cee5df8
--- /dev/null
+++ b/test/gtest_processor_odom_icp_3d.cpp
@@ -0,0 +1,327 @@
+// wolf
+#include "laser/processor/processor_odom_icp_3d.h"
+#include "core/processor/factory_processor.h"
+
+// wolf yaml
+#include <core/utils/params_server.h>
+#include <core/yaml/parser_yaml.h>
+#include "core/yaml/yaml_conversion.h"
+
+// testing
+#include <core/utils/utils_gtest.h>
+#include <core/utils/logging.h>
+
+using namespace wolf;
+using namespace laser;
+
+WOLF_REGISTER_STATEBLOCK_WITH_KEY(L, StateVector3d);
+
+class Test_FactorForceTorqueInertialDynamics_yaml : public testing::Test
+{
+  public:
+    ProblemPtr                           P;
+    SensorLaser3dPtr                     S;
+    ProcessorOdomIcp3dPtr                p;
+    FrameBasePtr                         F0, F1, F;
+    CaptureLaser3dPtr                     C0, C1, C;
+    FeatureBasePtr                        f1;
+    FactorBasePtr c1;
+
+    VectorXd              data;
+    MatrixXd              data_cov;
+    VectorXd              delta;
+    MatrixXd              delta_cov;
+    Matrix<double, 13, 1> calib;
+    MatrixXd              J_delta_calib;
+
+  protected:
+    void SetUp() override
+    {
+        std::string  wolf_root = _WOLF_BODYDYNAMICS_ROOT_DIR;
+        ParserYaml   parser    = ParserYaml("processor_odom_icp_3d.yaml", wolf_root + "/test/yaml/");
+        ParamsServer server    = ParamsServer(parser.getParams());
+        P                      = Problem::autoSetup(server);
+
+        S = std::static_pointer_cast<SensorForceTorqueInertial>(P->getHardware()->getSensorList().front());
+        p = std::static_pointer_cast<ProcessorForceTorqueInertialPreintDynamics>(S->getProcessorList().front());
+
+        data     = VectorXd::Zero(12);  // [ a, w, f, t ]
+        data_cov = MatrixXd::Identity(12, 12);
+        C        = std::make_shared<CaptureMotion>("CaptureMotion", 0.0, S, data, data_cov, nullptr);
+
+        C->process();
+
+        C0 = std::static_pointer_cast<CaptureMotion>(p->getOrigin());
+        F0 = C0->getFrame();
+
+        ASSERT_EQ(C0->getTimeStamp(), F0->getTimeStamp());
+        ASSERT_EQ(C0->getTimeStamp(), F0->getCaptureOf(S)->getTimeStamp());
+
+        C = std::make_shared<CaptureMotion>("CaptureMotion", 1.0, S, data, data_cov, nullptr);
+        C->process();
+
+        C1 = std::static_pointer_cast<CaptureMotion>(p->getLast());
+        F1 = C1->getFrame();
+
+        F1->link(P);  // by the face
+
+        VectorXd delta_preint(VectorXd::Zero(19));
+        delta_preint.head<3>()     = -0.5 * gravity();
+        delta_preint.segment<3>(3) = -gravity();
+        delta_preint.segment<3>(6) = -0.5 * gravity();
+        delta_preint.segment<3>(9) = -gravity();
+        delta_preint(18)           = 1;
+        MatrixXd delta_preint_cov(MatrixXd::Identity(18, 18));
+        VectorXd calib_preint(VectorXd::Zero(13));
+        MatrixXd jacobian_calib(MatrixXd::Zero(18, 13));
+        f1 = FeatureBase::emplace<FeatureMotion>(
+            C1, "FeatureMotion", delta_preint, delta_preint_cov, calib_preint, jacobian_calib);
+
+        c1 = FactorBase::emplace<FactorForceTorqueInertialDynamics>(f1, f1, C0, p, false);
+
+        F1->getStateBlock('P')->setState(Vector3d(0, 0, 0));
+        F1->getStateBlock('V')->setState(Vector3d(0, 0, 0));
+        F1->getStateBlock('O')->setState(Vector4d(0, 0, 0, 1));
+        F1->getStateBlock('L')->setState(Vector3d(0, 0, 0));
+    }
+};
+
+class Test_FactorForceTorqueInertialDynamics : public testing::Test
+{
+  public:
+    ProblemPtr                                    P;
+    SensorForceTorqueInertialPtr                  S;
+    ProcessorForceTorqueInertialPreintDynamicsPtr p;
+    FrameBasePtr                                  F0, F1;
+    CaptureMotionPtr                              C0, C1;
+    FeatureMotionPtr                              f1;
+    FactorForceTorqueInertialDynamicsPtr          c1;
+
+    VectorXd              data;
+    MatrixXd              data_cov;
+    VectorXd              delta;
+    MatrixXd              delta_cov;
+    Matrix<double, 13, 1> calib;
+    MatrixXd              J_delta_calib;
+
+  protected:
+    void SetUp() override
+    {
+        data     = VectorXd::Zero(12);  // [ a, w, f, t ]
+        data_cov = MatrixXd::Identity(12, 12);
+
+        // crear un problem
+        P = Problem::create("POVL", 3);
+
+        // crear un sensor
+        auto     params_sensor = std::make_shared<ParamsSensorForceTorqueInertial>();
+        Vector7d extrinsics;
+        extrinsics << 0, 0, 0, 0, 0, 0, 1;
+        S = SensorBase::emplace<SensorForceTorqueInertial>(P->getHardware(), extrinsics, params_sensor);
+        S->setStateBlockDynamic('I', true);
+
+        // crear processador
+        auto params_processor = std::make_shared<ParamsProcessorForceTorqueInertialPreintDynamics>();
+        p = ProcessorBase::emplace<ProcessorForceTorqueInertialPreintDynamics>(S, params_processor);
+
+        // crear dos frame
+        VectorXd state(13);
+        state << 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0;
+        VectorComposite state_c(state, "POVL", {3, 4, 3, 3});
+        F0 = FrameBase::emplace<FrameBase>(P->getTrajectory(), 0.0, "POVL", state_c);
+        F1 = FrameBase::emplace<FrameBase>(P->getTrajectory(), 1.0, "POVL", state_c);
+
+        // crear dues capture
+        VectorXd data(VectorXd::Zero(12));
+        MatrixXd data_cov(MatrixXd::Identity(12, 12));
+        Vector6d bias(Vector6d::Zero());
+        auto     sb_bias = std::make_shared<StateParams6>(bias);
+        C0               = CaptureBase::emplace<CaptureMotion>(
+            F0, "CaptureMotion", 0.0, S, data, data_cov, nullptr, nullptr, nullptr, sb_bias);
+        C1 = CaptureBase::emplace<CaptureMotion>(
+            F1, "CaptureMotion", 1.0, S, data, data_cov, C0, nullptr, nullptr, sb_bias);
+
+        // crear un feature
+        VectorXd delta_preint(VectorXd::Zero(19));
+        delta_preint.head<3>()     = -0.5 * gravity();
+        delta_preint.segment<3>(3) = -gravity();
+        delta_preint.segment<3>(6) = -0.5 * gravity();
+        delta_preint.segment<3>(9) = -gravity();
+        delta_preint(18)           = 1;
+        MatrixXd delta_preint_cov(MatrixXd::Identity(18, 18));
+        VectorXd calib_preint(VectorXd::Zero(13));
+        MatrixXd jacobian_calib(MatrixXd::Zero(18, 13));
+        f1 = FeatureBase::emplace<FeatureMotion>(
+            C1, "FeatureMotion", delta_preint, delta_preint_cov, calib_preint, jacobian_calib);
+
+        // crear un factor
+        c1 = FactorBase::emplace<FactorForceTorqueInertialDynamics>(f1, f1, C0, p, false);
+    }
+};
+
+// TEST(FactorForceTorqueInertialDynamics_yaml, force_registraion)
+// {
+//     FactorySensor::registerCreator("SensorForceTorqueInertial", SensorForceTorqueInertial::create);
+// }
+
+// Test to see if the constructor works (not yaml files)
+TEST_F(Test_FactorForceTorqueInertialDynamics, constructor)
+{
+    ASSERT_EQ(c1->getCapture(), C1);
+    ASSERT_EQ(c1->getCalibPreint().size(), 13);
+}
+
+// Test to see if the constructor works (yaml files)
+TEST_F(Test_FactorForceTorqueInertialDynamics_yaml, constructor)
+{
+    ASSERT_EQ(c1->getCapture(), C1);
+    ASSERT_EQ(c1->getCalibPreint().size(), 13);
+}
+
+// Test en el que no hi ha moviment (not yaml files)
+TEST_F(Test_FactorForceTorqueInertialDynamics, residual)
+{
+    VectorXd              res_exp = VectorXd::Zero(18);
+    Matrix<double, 18, 1> res;
+    VectorXd              bias = VectorXd::Zero(6);
+
+    P->print(4, 1, 1, 1);
+
+    c1->residual(F0->getStateBlock('P')->getState(),                      // p0
+                 Quaterniond(F0->getStateBlock('O')->getState().data()),  // q0
+                 F0->getStateBlock('V')->getState(),                      // v0
+                 F0->getStateBlock('L')->getState(),                      // L0
+                 bias,                                                    // I
+                 F1->getStateBlock('P')->getState(),                      // p1
+                 Quaterniond(F1->getStateBlock('O')->getState().data()),  // q1
+                 F1->getStateBlock('V')->getState(),                      // v1
+                 F1->getStateBlock('L')->getState(),                      // L1
+                 S->getCom(),                                             // C
+                 S->getInertia(),                                         // i
+                 S->getMass(),                                            // m
+                 res);
+
+    ASSERT_MATRIX_APPROX(res_exp, res, 1e-8);
+}
+
+// Test en el que no hi ha moviment (yaml files)
+TEST_F(Test_FactorForceTorqueInertialDynamics_yaml, residual)
+{
+    VectorXd              res_exp = VectorXd::Zero(18);
+    Matrix<double, 18, 1> res;
+    VectorXd              bias = VectorXd::Zero(6);
+
+    c1->residual(F0->getStateBlock('P')->getState(),                      // p0
+                 Quaterniond(F0->getStateBlock('O')->getState().data()),  // q0
+                 F0->getStateBlock('V')->getState(),                      // v0
+                 F0->getStateBlock('L')->getState(),                      // L0
+                 bias,                                                    // I
+                 F1->getStateBlock('P')->getState(),                      // p1
+                 Quaterniond(F1->getStateBlock('O')->getState().data()),  // q1
+                 F1->getStateBlock('V')->getState(),                      // v1
+                 F1->getStateBlock('L')->getState(),                      // L1
+                 S->getCom(),                                             // C
+                 S->getInertia(),                                         // i
+                 S->getMass(),                                            // m
+                 res);
+
+    ASSERT_MATRIX_APPROX(res_exp, res, 1e-8);
+}
+
+// Test en el que s'avança 1m en direcció x (not yaml files)
+TEST_F(Test_FactorForceTorqueInertialDynamics, residualx)
+{
+    VectorXd              res_exp = VectorXd::Zero(18);
+    Matrix<double, 18, 1> res;
+    VectorXd              bias = VectorXd::Zero(6);
+
+    // provem el moviment de P=(0,0,0) a P=(1,0,0) i v, o i L queden igual
+    F1->getStateBlock('P')->setState(Vector3d(1, 0, 0));
+
+    // Hem de crear un nou feature i un nou factor ja que la delta preint canvia.
+    VectorXd delta_preint(VectorXd::Zero(19));
+    delta_preint.head<3>()     = -0.5 * gravity();
+    delta_preint(0)            = 1;
+    delta_preint.segment<3>(3) = -gravity();
+    delta_preint.segment<3>(6) = -0.5 * gravity();
+    delta_preint(6)            = 1;
+    delta_preint.segment<3>(9) = -gravity();
+    delta_preint(18)           = 1;
+    MatrixXd         delta_preint_cov(MatrixXd::Identity(18, 18));
+    VectorXd         calib_preint(VectorXd::Zero(13));
+    MatrixXd         jacobian_calib(MatrixXd::Zero(18, 13));
+    FeatureMotionPtr f2 = FeatureBase::emplace<FeatureMotion>(
+        C1, "FeatureMotion", delta_preint, delta_preint_cov, calib_preint, jacobian_calib);
+
+    FactorForceTorqueInertialDynamicsPtr c2 =
+        FactorBase::emplace<FactorForceTorqueInertialDynamics>(f2, f2, C0, p, false);
+
+    c2->residual(F0->getStateBlock('P')->getState(),                      // p0
+                 Quaterniond(F0->getStateBlock('O')->getState().data()),  // q0
+                 F0->getStateBlock('V')->getState(),                      // v0
+                 F0->getStateBlock('L')->getState(),                      // L0
+                 bias,                                                    // I
+                 F1->getStateBlock('P')->getState(),                      // p1
+                 Quaterniond(F1->getStateBlock('O')->getState().data()),  // q1
+                 F1->getStateBlock('V')->getState(),                      // v1
+                 F1->getStateBlock('L')->getState(),                      // L1
+                 S->getCom(),                                             // C
+                 S->getInertia(),                                         // i
+                 S->getMass(),                                            // m
+                 res);
+
+    ASSERT_MATRIX_APPROX(res_exp, res, 1e-8);
+}
+
+// Test en el que s'avança 1m en direcció x (fitxers yaml)
+
+TEST_F(Test_FactorForceTorqueInertialDynamics_yaml, residualx)
+{
+    VectorXd              res_exp = VectorXd::Zero(18);
+    Matrix<double, 18, 1> res;
+    VectorXd              bias = VectorXd::Zero(6);
+
+    // provem el moviment de P=(0,0,0) a P=(1,0,0) i v, o i L queden igual
+    F1->getStateBlock('P')->setState(Vector3d(1, 0, 0));
+
+    // Hem de crear un nou feature i un nou factor ja que la delta preint canvia.
+    VectorXd delta_preint(VectorXd::Zero(19));
+    delta_preint.head<3>()     = -0.5 * gravity();
+    delta_preint(0)            = 1;
+    delta_preint.segment<3>(3) = -gravity();
+    delta_preint.segment<3>(6) = -0.5 * gravity();
+    delta_preint(6)            = 1;
+    delta_preint.segment<3>(9) = -gravity();
+    delta_preint(18)           = 1;
+    MatrixXd         delta_preint_cov(MatrixXd::Identity(18, 18));
+    VectorXd         calib_preint(VectorXd::Zero(13));
+    MatrixXd         jacobian_calib(MatrixXd::Zero(18, 13));
+    FeatureMotionPtr f2 = FeatureBase::emplace<FeatureMotion>(
+        C1, "FeatureMotion", delta_preint, delta_preint_cov, calib_preint, jacobian_calib);
+
+    FactorForceTorqueInertialDynamicsPtr c2 =
+        FactorBase::emplace<FactorForceTorqueInertialDynamics>(f2, f2, C0, p, false);
+
+    c2->residual(F0->getStateBlock('P')->getState(),                      // p0
+                 Quaterniond(F0->getStateBlock('O')->getState().data()),  // q0
+                 F0->getStateBlock('V')->getState(),                      // v0
+                 F0->getStateBlock('L')->getState(),                      // L0
+                 bias,                                                    // I
+                 F1->getStateBlock('P')->getState(),                      // p1
+                 Quaterniond(F1->getStateBlock('O')->getState().data()),  // q1
+                 F1->getStateBlock('V')->getState(),                      // v1
+                 F1->getStateBlock('L')->getState(),                      // L1
+                 S->getCom(),                                             // C
+                 S->getInertia(),                                         // i
+                 S->getMass(),                                            // m
+                 res);
+
+    ASSERT_MATRIX_APPROX(res_exp, res, 1e-8);
+}
+
+int main(int argc, char **argv)
+{
+    testing::InitGoogleTest(&argc, argv);
+    //::testing::GTEST_FLAG(filter) = "Test_FactorForceTorqueInertialDynamics_yaml.residual";
+    return RUN_ALL_TESTS();
+}
\ No newline at end of file
diff --git a/test/yaml/processor_odom_icp_3d.yaml b/test/yaml/processor_odom_icp_3d.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391