diff --git a/src/processor/processor_imu.cpp b/src/processor/processor_imu.cpp
index 0e4257e65940cbdd753423fe9941b57150fe3c69..8f3433ea0bf34d322988fed3bbfb6dca91d92e34 100644
--- a/src/processor/processor_imu.cpp
+++ b/src/processor/processor_imu.cpp
@@ -261,24 +261,47 @@ void ProcessorImu::bootstrap()
             // TODO implement static strategy
             break;
         }
-        case ParamsProcessorImu::BootstrapMethod::BOOTSTRAP_G:
-        {
-            // Implementation of G strategy. 
-            if (last_ptr_->getBuffer().size() - 1 > params_motion_Imu_->bootstrap_averaging_length) 
+        case ParamsProcessorImu::BootstrapMethod::BOOTSTRAP_G: {
+            // Implementation of G strategy.
+            CaptureBasePtr first_capture;
+            if (list_fac_inactive_bootstrap_.empty()) first_capture = origin_ptr_;
+            else
+            first_capture =
+                std::static_pointer_cast<CaptureMotion>(list_fac_inactive_bootstrap_.front()->getCapture())
+                    ->getOriginCapture();
+            TimeStamp t_current = last_ptr_->getBuffer().back().ts_;
+            if (t_current - first_capture->getTimeStamp() >= params_motion_Imu_->bootstrap_averaging_length)
             {
                 // frames:
                 //   w: world global ( where g = [0,0,-9.806] );
                 //   l: world local;
                 //   r: robot;
                 //   s: sensor (IMU)
-                Quaterniond q_l_r(this->getOrigin()->getFrame()->getStateVector("O").data());
-                Quaterniond q_r_s(this->getSensor()->getStateVector("O").data());
-
-                Vector3d    delta_v    = getMotion().delta_integr_.segment(7, 3);              //
-                double      delta_t    = getMotion().ts_ - this->getOrigin()->getTimeStamp();  //
-                Vector3d    g_l        = -((q_l_r * q_r_s) * delta_v / delta_t);               // See eq. (20)
-                const auto& g_w        = gravity();                                            //
-                Vector3d    p_w_l      = Vector3d::Zero();                       // will pivot around the local origin
+
+                // get initial IMU frame 's' expressed in local world frame 'l'
+                Quaterniond q_l_r(first_capture->getFrame()->getStateVector("O").data());
+                Quaterniond q_r_s(first_capture->getSensor()->getStateVector("O").data());
+
+                // Compute total integrated delta during bootstrap period
+                // first, integrate all deltas in previous factors
+                VectorXd delta_int = deltaZero();
+                for (const auto& fac : list_fac_inactive_bootstrap_)
+                // here, we take advantage of the list of IMU factors to recover all deltas
+                {
+                    double      dt    = fac->getCapture()->getTimeStamp() - fac->getCaptureOther()->getTimeStamp();
+                    const auto& delta = fac->getFeature()->getMeasurement();  // In FeatImu, delta = measurement
+                    delta_int         = imu::compose(delta_int, delta, dt);
+                }
+                // now compose with delta in last_ptr_
+                double dt = t_current - origin_ptr_->getTimeStamp();
+                delta_int = imu::compose(delta_int, last_ptr_->getDeltaPreint(), dt);
+
+                // compute local g and transformation to global g
+                dt                     = t_current - first_capture->getTimeStamp();  //
+                Vector3d    dv         = delta_int.segment(7, 3);                    //
+                Vector3d    g_l        = -((q_l_r * q_r_s) * dv / dt);               // See eq. (20)
+                const auto& g_w        = gravity();                                  //
+                const auto& p_w_l      = Vector3d::Zero();                       // will pivot around the local origin
                 Quaterniond q_w_l      = Quaterniond::FromTwoVectors(g_l, g_w);  //
                 transformation.at('P') = p_w_l;                                  //
                 transformation.at('O') = q_w_l.coeffs();                         //
@@ -287,8 +310,7 @@ void ProcessorImu::bootstrap()
             }
             break;
         }
-        case ParamsProcessorImu::BootstrapMethod::BOOTSTRAP_V0_G:
-        {
+        case ParamsProcessorImu::BootstrapMethod::BOOTSTRAP_V0_G: {
             // TODO implement v0-g strategy
             break;
         }
diff --git a/test/gtest_imu.cpp b/test/gtest_imu.cpp
index 91f648ac1dffac1ea777fce3be71ab98eec7a7d4..bc812631b78c79d9daf233ee2601061f34cacbfa 100644
--- a/test/gtest_imu.cpp
+++ b/test/gtest_imu.cpp
@@ -1542,7 +1542,7 @@ TEST_F(Process_Factor_Imu_ODO, RecoverTrajectory_MotionRandom_PqV_b__pqV_b) // F
 TEST_F(Process_Factor_Imu, bootstrap)
 {
     processor_imu->setVotingActive(true);
-    processor_imu->setMaxBuffLength(20);
+    processor_imu->setMaxTimeSpan(0.1);
 
     auto KF0 = problem->emplaceFrame(0.0);
     problem->keyFrameCallback(KF0,nullptr);
@@ -1553,18 +1553,18 @@ TEST_F(Process_Factor_Imu, bootstrap)
 
     capture_imu = std::make_shared<CaptureImu>(0.0, sensor_imu, data, Matrix6d::Identity());
 
-    for (t = 0.0; t < 1.0; t += dt)
+    for (t = 0; t < 0.35; t += dt)
     {
         capture_imu->setTimeStamp(t);
         capture_imu->process();
-        problem->print(4, 0, 1, 0);
+        problem->print(4, 0, 1, 1);
     }
 }
 
 int main(int argc, char **argv)
 {
     testing::InitGoogleTest(&argc, argv);
-    //    ::testing::GTEST_FLAG(filter) = "Process_Factor_Imu.bootstrap";
+    ::testing::GTEST_FLAG(filter) = "Process_Factor_Imu.bootstrap";
     //    ::testing::GTEST_FLAG(filter) = "Process_Factor_Imu_ODO.*";
     //    ::testing::GTEST_FLAG(filter) = "Process_Factor_Imu_ODO.RecoverTrajectory_MotionRandom_PqV_b__pqV_b";