From d12f9682bd77c38f7279856fb7314c496d4c0bc6 Mon Sep 17 00:00:00 2001
From: asanjuan <asanjuan@iri.upc.edu>
Date: Tue, 9 Aug 2022 17:48:19 +0200
Subject: [PATCH] gtest modification

---
 ...problem_force_torque_inertial_dynamics.cpp | 161 +++++++++++++++++-
 ...e_torque_inertial_dynamics_solve_test.yaml |   2 +-
 2 files changed, 159 insertions(+), 4 deletions(-)

diff --git a/test/gtest_solve_problem_force_torque_inertial_dynamics.cpp b/test/gtest_solve_problem_force_torque_inertial_dynamics.cpp
index cc97b1c..066973c 100644
--- a/test/gtest_solve_problem_force_torque_inertial_dynamics.cpp
+++ b/test/gtest_solve_problem_force_torque_inertial_dynamics.cpp
@@ -205,7 +205,7 @@ TEST_F(Test_SolveProblemForceTorqueInertialDynamics_yaml, cdm_only_hovering)
     WOLF_INFO("Estimated cdm: ", S->getStateBlock('C')->getState().transpose(), " m.");
     WOLF_INFO("-----------------------------");
 
-    for (TimeStamp t = p->getLast()->getTimeStamp() + 1.0 ; t <= 11.0 ; t += 1.0)
+    for (TimeStamp t = p->getLast()->getTimeStamp() + 1.0 ; t <= 60.0 ; t += 1.0)
     {
         CaptureMotionPtr C = std::make_shared<CaptureForceTorqueInertial>( t, S, data, data_cov, nullptr);
         C->process();
@@ -284,7 +284,7 @@ TEST_F(Test_SolveProblemForceTorqueInertialDynamics_yaml, mass_and_cdm_hovering)
     // which if not eliminated contaminate the overall solution.
     // This is due to these first factors relying on the linearization Jacobian to correct the
     // poorly preintegrated delta.
-    for (TimeStamp t = p->getLast()->getTimeStamp() + 1.0 ; t <= 7.0 ; t += 1.0)
+    for (TimeStamp t = p->getLast()->getTimeStamp() + 1.0 ; t <= 60.0 ; t += 1.0)
     {
         CaptureMotionPtr C = std::make_shared<CaptureForceTorqueInertial>(t, S, data, data_cov, nullptr);
         C->setTimeStamp(t);
@@ -305,9 +305,164 @@ TEST_F(Test_SolveProblemForceTorqueInertialDynamics_yaml, mass_and_cdm_hovering)
     ASSERT_MATRIX_APPROX(cdm_estimated.head(2), cdm_true.head(2), 1e-6); // cdm_z is not observable while hovering
 }
 
+TEST_F(Test_SolveProblemForceTorqueInertialDynamics_yaml, cdm_and_ang_mom_hovering)
+{
+    S->getStateBlock('C')->setState(Vector3d(0.02, 0.02, 0.033));
+    S->getStateBlock('m')->setState(Vector1d(mass_true));
+    Vector3d cdm_guess = S->getStateBlock('C')->getState();
+
+    // Data
+    VectorXd data      = VectorXd::Zero(12);  // [ a, w, f, t ]
+    data.segment<3>(0) = -gravity();
+    data.segment<3>(6) = -mass_true * gravity();
+    MatrixXd data_cov  = MatrixXd::Identity(12, 12);
+
+    // We fix the parameters of the sensor except for the cdm
+    S->getStateBlock('P')->fix();
+    S->getStateBlock('O')->fix();
+    S->getStateBlock('I')->fix();
+    S->getStateBlock('C')->unfix();
+    S->getStateBlock('i')->fix();
+    S->getStateBlock('m')->fix();
+    // S->setStateBlockDynamic('I');
+
+    CaptureMotionPtr C0_0 = std::make_shared<CaptureForceTorqueInertial>( 0.0, S, data, data_cov, nullptr);
+    CaptureMotionPtr C1_0 = std::make_shared<CaptureForceTorqueInertial>( 0.2, S, data, data_cov, nullptr);
+    CaptureMotionPtr C2_0 = std::make_shared<CaptureForceTorqueInertial>( 0.4, S, data, data_cov, nullptr);
+    CaptureMotionPtr C3_0 = std::make_shared<CaptureForceTorqueInertial>( 0.6, S, data, data_cov, nullptr);
+    CaptureMotionPtr C4_0 = std::make_shared<CaptureForceTorqueInertial>( 0.8, S, data, data_cov, nullptr);
+    CaptureMotionPtr C5_1 = std::make_shared<CaptureForceTorqueInertial>( 1.0, S, data, data_cov, nullptr);
+
+    C0_0->process();
+    CaptureMotionPtr C_KF0 = std::static_pointer_cast<CaptureMotion>(p->getOrigin());
+    C1_0->process();
+    C2_0->process();
+    C3_0->process();
+    C4_0->process();
+    C5_1->process();
+
+    CaptureMotionPtr C_KF1 = std::static_pointer_cast<CaptureMotion>(p->getOrigin());
+
+    C_KF0->getFrame()->fix();
+    C_KF0->getFrame()->getStateBlock('L')->unfix();
+    C_KF1->getFrame()->fix();
+    C_KF1->getFrame()->getStateBlock('L')->unfix();
+
+    P->print(4, 1, 1, 1);
+
+    WOLF_INFO("======== SOLVE PROBLEM =======")
+    std::string report = solver->solve(wolf::SolverManager::ReportVerbosity::FULL);
+    WOLF_INFO(report);  // should show a very low iteration number (possibly 1)
+
+    WOLF_INFO("True cdm     : ", cdm_true.transpose(), " m.");
+    WOLF_INFO("Guess cdm    : ", cdm_guess.transpose(), " m.");
+    WOLF_INFO("Estimated cdm: ", S->getStateBlock('C')->getState().transpose(), " m.");
+    WOLF_INFO("-----------------------------");
+
+    for (TimeStamp t = p->getLast()->getTimeStamp() + 1.0 ; t <= 60.0 ; t += 1.0)
+    {
+        CaptureMotionPtr C = std::make_shared<CaptureForceTorqueInertial>( t, S, data, data_cov, nullptr);
+        C->process();
+        p->getOrigin()->getFrame()->fix();
+        p->getOrigin()->getFrame()->getStateBlock('L')->unfix();
+        report = solver->solve(wolf::SolverManager::ReportVerbosity::FULL);
+        WOLF_INFO("Estimated cdm : ", S->getStateBlock('C')->getState().transpose(), " m.");
+        WOLF_INFO("-----------------------------");
+    }
+
+
+    ASSERT_MATRIX_APPROX(S->getStateBlock('C')->getState().head(2), cdm_true.head(2), 1e-5); // cdm_z is not observable while hovering
+}
+
+TEST_F(Test_SolveProblemForceTorqueInertialDynamics_yaml, mass_and_cdm_and_ang_mom_hovering)
+{
+    S->getStateBlock('C')->setState(Vector3d(0.05, 0.05, 0.05));
+    S->getStateBlock('m')->setState(Vector1d(1.50));
+    Vector3d cdm_guess  = S->getStateBlock('C')->getState();
+    double   mass_guess = S->getStateBlock('m')->getState()(0);
+
+    // Data
+    VectorXd data      = VectorXd::Zero(12);  // [ a, w, f, t ]
+    data.segment<3>(0) = -gravity();
+    data.segment<3>(6) = -mass_true * gravity();
+    MatrixXd data_cov  = MatrixXd::Identity(12, 12);
+
+    // We fix the parameters of the sensor except for the cdm and the mass
+    S->getStateBlock('P')->fix();
+    S->getStateBlock('O')->fix();
+    S->getStateBlock('I')->fix();
+    S->getStateBlock('C')->unfix();
+    S->getStateBlock('i')->fix();
+    S->getStateBlock('m')->unfix();
+    // S->setStateBlockDynamic('I');
+
+    CaptureMotionPtr C0_0 = std::make_shared<CaptureForceTorqueInertial>(0.0, S, data, data_cov, nullptr);
+    CaptureMotionPtr C1_0 = std::make_shared<CaptureForceTorqueInertial>(0.2, S, data, data_cov, nullptr);
+    CaptureMotionPtr C2_0 = std::make_shared<CaptureForceTorqueInertial>(0.4, S, data, data_cov, nullptr);
+    CaptureMotionPtr C3_0 = std::make_shared<CaptureForceTorqueInertial>(0.6, S, data, data_cov, nullptr);
+    CaptureMotionPtr C4_0 = std::make_shared<CaptureForceTorqueInertial>(0.8, S, data, data_cov, nullptr);
+    CaptureMotionPtr C5_1 = std::make_shared<CaptureForceTorqueInertial>(1.0, S, data, data_cov, nullptr);
+
+    C0_0->process();
+    CaptureMotionPtr C_KF0 = std::static_pointer_cast<CaptureMotion>(p->getOrigin());
+    C1_0->process();
+    C2_0->process();
+    C3_0->process();
+    C4_0->process();
+    C5_1->process();
+
+    CaptureMotionPtr C_KF1 = std::static_pointer_cast<CaptureMotion>(p->getOrigin());
+
+    C_KF0->getFrame()->fix();
+    C_KF0->getFrame()->getStateBlock('L')->unfix();
+    C_KF1->getFrame()->fix();
+    C_KF1->getFrame()->getStateBlock('L')->unfix();
+
+    P->print(4, 1, 1, 1);
+
+    WOLF_INFO("======== SOLVE PROBLEM =======")
+    std::string report = solver->solve(wolf::SolverManager::ReportVerbosity::FULL);
+    WOLF_INFO(report);  // should show a very low iteration number (possibly 1)
+
+    WOLF_INFO("True mass     : ", mass_true, " Kg.");
+    WOLF_INFO("True cdm      : ", cdm_true.transpose(), " m.");
+    WOLF_INFO("Guess mass    : ", mass_guess, " Kg.");
+    WOLF_INFO("Guess cdm     : ", cdm_guess.transpose(), " m.");
+    WOLF_INFO("Estimated mass: ", S->getStateBlock('m')->getState(), " Kg.");
+    WOLF_INFO("Estimated cdm : ", S->getStateBlock('C')->getState().transpose(), " m.");
+    WOLF_INFO("-----------------------------");
+
+
+    // Do a number of iterations with more keyframes, solving so that the calibration gets better and better
+    // Here we take advantage of the sliding window, thereby getting rid progressively 
+    // of the old factors, which contained calibration parameters far from the converged values,
+    // which if not eliminated contaminate the overall solution.
+    // This is due to these first factors relying on the linearization Jacobian to correct the
+    // poorly preintegrated delta.
+    for (TimeStamp t = p->getLast()->getTimeStamp() + 1.0 ; t <= 60.0 ; t += 1.0)
+    {
+        CaptureMotionPtr C = std::make_shared<CaptureForceTorqueInertial>(t, S, data, data_cov, nullptr);
+        C->setTimeStamp(t);
+        C->process();
+        p->getOrigin()->getFrame()->fix();
+        p->getOrigin()->getFrame()->getStateBlock('L')->unfix();
+        report = solver->solve(wolf::SolverManager::ReportVerbosity::FULL);
+        WOLF_INFO("Estimated mass: ", S->getStateBlock('m')->getState(), " Kg.");
+        WOLF_INFO("Estimated cdm : ", S->getStateBlock('C')->getState().transpose(), " m.");
+        WOLF_INFO("-----------------------------");
+    }
+
+    auto cdm_estimated  = S->getStateBlock('C')->getState();
+    auto mass_estimated = S->getStateBlock('m')->getState()(0);
+
+
+    ASSERT_NEAR(mass_estimated, mass_true, 1e-6);
+    ASSERT_MATRIX_APPROX(cdm_estimated.head(2), cdm_true.head(2), 1e-6); // cdm_z is not observable while hovering
+}
+
 int main(int argc, char **argv)
 {
     testing::InitGoogleTest(&argc, argv);
-    // ::testing::GTEST_FLAG(filter) = "Test_SolveProblemForceTorqueInertialDynamics_yaml.cdm_only_hovering";
+    ::testing::GTEST_FLAG(filter) = "Test_SolveProblemForceTorqueInertialDynamics_yaml.mass_and_cdm_and_ang_mom_hovering";
     return RUN_ALL_TESTS();
 }
diff --git a/test/yaml/problem_force_torque_inertial_dynamics_solve_test.yaml b/test/yaml/problem_force_torque_inertial_dynamics_solve_test.yaml
index 8eb8204..ca0697e 100644
--- a/test/yaml/problem_force_torque_inertial_dynamics_solve_test.yaml
+++ b/test/yaml/problem_force_torque_inertial_dynamics_solve_test.yaml
@@ -18,7 +18,7 @@ config:
     tree_manager: 
       type: "TreeManagerSlidingWindow"
       plugin: "core"
-      n_frames: 3
+      n_frames: 10
       n_fix_first_frames: 1
       viral_remove_empty_parent: true
   map:
-- 
GitLab