diff --git a/CMakeLists.txt b/CMakeLists.txt
index e05b69ceb3c2840724a80df0f68f4b0bb516a9a3..8cce494e8ff4dd259249c90a91600a95a6f7411d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -177,7 +177,8 @@ SET(HDRS_SENSOR
   )
 SET(HDRS_SOLVER
   )
-SET(HDRS_DTASSC
+SET(HDRS_TREE_MANAGER
+  include/gnss/tree_manager/tree_manager_sliding_window_tdcp.h
   )
 
 #SOURCES
@@ -207,10 +208,11 @@ SET(SRCS_PROCESSOR
 SET(SRCS_SENSOR
   src/sensor/sensor_gnss.cpp
   )
-SET(SRCS_DTASSC
-  )
 SET(SRCS_SOLVER
   )
+SET(SRCS_TREE_MANAGER
+  src/tree_manager/tree_manager_sliding_window_tdcp.cpp
+  )
 SET(SRCS_YAML
   )
 #OPTIONALS
@@ -250,6 +252,7 @@ ADD_LIBRARY(${PLUGIN_NAME}
   ${SRCS_SENSOR}
   ${SRCS_SOLVER}
   ${SRCS_STATE_BLOCK}
+  ${SRCS_TREE_MANAGER}
   ${SRCS_UTILS}
   ${SRCS_WRAPPER}
   ${SRCS_YAML}
@@ -292,8 +295,6 @@ install(EXPORT ${PLUGIN_NAME}Targets DESTINATION lib/cmake/${PLUGIN_NAME})
 #install headers
 INSTALL(FILES ${HDRS_STATE_BLOCK}
   DESTINATION include/iri-algorithms/wolf/plugin_${PROJECT_NAME}/${PROJECT_NAME}/state_block)
-INSTALL(FILES ${HDRS_DTASSC}
-  DESTINATION include/iri-algorithms/wolf/plugin_${PROJECT_NAME}/${PROJECT_NAME}/association)
 INSTALL(FILES ${HDRS_CAPTURE}
   DESTINATION include/iri-algorithms/wolf/plugin_${PROJECT_NAME}/${PROJECT_NAME}/capture)
 INSTALL(FILES ${HDRS_FACTOR}
@@ -312,8 +313,8 @@ INSTALL(FILES ${HDRS_WRAPPER}
 #  DESTINATION include/iri-algorithms/wolf/plugin_${PROJECT_NAME}/${PROJECT_NAME}/solver_suitesparse)
 INSTALL(FILES ${HDRS_SOLVER}
   DESTINATION include/iri-algorithms/wolf/plugin_${PROJECT_NAME}/${PROJECT_NAME}/solver)
-INSTALL(FILES ${HDRS_SERIALIZATION}
-  DESTINATION include/iri-algorithms/wolf/plugin_${PROJECT_NAME}/${PROJECT_NAME}/serialization)
+INSTALL(FILES ${HDRS_TREE_MANAGER}
+  DESTINATION include/iri-algorithms/wolf/plugin_${PROJECT_NAME}/${PROJECT_NAME}/tree_manager)
 INSTALL(FILES ${HDRS_YAML}
   DESTINATION include/iri-algorithms/wolf/plugin_${PROJECT_NAME}/${PROJECT_NAME}/yaml)
 
diff --git a/include/gnss/factor/factor_gnss_tdcp_3d.h b/include/gnss/factor/factor_gnss_tdcp_3d.h
index df9bfe44df8201a3d429eb0032d0b9ec4212000b..fd4f1a0554363c627440f4a99482efc3558ac700 100644
--- a/include/gnss/factor/factor_gnss_tdcp_3d.h
+++ b/include/gnss/factor/factor_gnss_tdcp_3d.h
@@ -19,7 +19,12 @@ class FactorGnssTdcp3d : public FactorAutodiff<FactorGnssTdcp3d, 3, 3, 4, 3, 4,
 
     public:
 
-        FactorGnssTdcp3d(const FeatureBasePtr& _ftr_ptr, const FrameBasePtr& _frame_other_ptr, const SensorGnssPtr& _sensor_gnss_ptr, const ProcessorBasePtr& _processor_ptr, bool _apply_loss_function = false, FactorStatus _status = FAC_ACTIVE) :
+        FactorGnssTdcp3d(const FeatureBasePtr& _ftr_ptr,
+                         const FrameBasePtr& _frame_other_ptr,
+                         const SensorGnssPtr& _sensor_gnss_ptr,
+                         const ProcessorBasePtr& _processor_ptr,
+                         bool _apply_loss_function,
+                         FactorStatus _status = FAC_ACTIVE) :
             FactorAutodiff<FactorGnssTdcp3d, 3, 3, 4, 3, 4, 3, 1, 1, 1>("FactorGnssTdcp3d",
                                                                         TOP_GEOM,
                                                                         _ftr_ptr,
@@ -40,6 +45,7 @@ class FactorGnssTdcp3d : public FactorAutodiff<FactorGnssTdcp3d, 3, 3, 4, 3, 4,
                                                                         _sensor_gnss_ptr->getEnuMapYaw()),
             sensor_gnss_ptr_(_sensor_gnss_ptr)
         {
+            assert(_ftr_ptr->getMeasurement().size() == 3 && "FactorGnssTdcp3d uses 3d measurements. For FeatureGnssTdcp with also delta clock, use FactorGnssTdcpBatch instead");
             WOLF_WARN_COND(!sensor_gnss_ptr_->isEnuDefined(), "Creating a GNSS SingleDiff 3D factor without initializing ENU");
         }
 
diff --git a/include/gnss/factor/factor_gnss_tdcp_batch.h b/include/gnss/factor/factor_gnss_tdcp_batch.h
index 94a08eca6419220d547905c9ee9a5119c4139ac2..3a5786067f56baaf45ac910075351733d672ffd0 100644
--- a/include/gnss/factor/factor_gnss_tdcp_batch.h
+++ b/include/gnss/factor/factor_gnss_tdcp_batch.h
@@ -46,6 +46,7 @@ class FactorGnssTdcpBatch : public FactorAutodiff<FactorGnssTdcpBatch, 4, 3, 4,
                                                                                  _sensor_gnss_ptr->getEnuMapYaw()),
             sensor_gnss_ptr_(_sensor_gnss_ptr)
         {
+            assert(_ftr_ptr->getMeasurement().size() == 4 && "FactorGnssTdcpBatch uses 4d measurements (pos.displacement, delta clock). For FeatureGnssTdcp with only displacement, use FactorGnssTdcp3d instead");
             WOLF_WARN_COND(!sensor_gnss_ptr_->isEnuDefined(), "Creating a GNSS SingleDiff 3D factor without initializing ENU");
         }
 
@@ -84,22 +85,23 @@ inline bool FactorGnssTdcpBatch::operator ()(const T* const _x1,
     Eigen::Map<const Eigen::Matrix<T,3,1>> t_MAP_BASE2(_x2);
     Eigen::Map<const Eigen::Quaternion<T>> q_MAP_BASE2(_o2);
     Eigen::Map<const Eigen::Matrix<T,3,1>> t_BASE_ANTENA(_x_antena);
+    Eigen::Map<Eigen::Matrix<T,3,1> > disp_residuals(_residuals);
     Eigen::Map<Eigen::Matrix<T,4,1> > residuals(_residuals);
 
     Eigen::Matrix<T,3,3> R_ECEF_ENU = sensor_gnss_ptr_->getREnuEcef().transpose().cast<T>();
     Eigen::Matrix<T,3,3> R_ENU_MAP = sensor_gnss_ptr_->computeREnuMap(_roll_ENU_MAP[0], _pitch_ENU_MAP[0], _yaw_ENU_MAP[0]);
 
-    // Expected displacement
-    Eigen::Matrix<T,3,1> expected_ECEF = R_ECEF_ENU * R_ENU_MAP * ((q_MAP_BASE2 * t_BASE_ANTENA + t_MAP_BASE2) - (q_MAP_BASE1 * t_BASE_ANTENA + t_MAP_BASE1));
+    // Expected d
+    Eigen::Matrix<T,4,1> exp;
 
-    // position error
-    Eigen::Matrix<T,3,1> error_ECEF = expected_ECEF - getMeasurement().head<3>().cast<T>();
+    // Expected displacement in ECEF
+    exp.head(3) = R_ECEF_ENU * R_ENU_MAP * ((q_MAP_BASE2 * t_BASE_ANTENA + t_MAP_BASE2) - (q_MAP_BASE1 * t_BASE_ANTENA + t_MAP_BASE1));
 
     // clock error
-    T error_clock = _t2 - _t1;
+    exp(3) = *_t2 - *_t1;
 
     // Compute residual
-    residuals = getMeasurementSquareRootInformationUpper().cast<T>() * (expected_ECEF - getMeasurement().cast<T>());
+    residuals = getMeasurementSquareRootInformationUpper().cast<T>() * (exp - getMeasurement().cast<T>());
 
     //std::cout << "frame1: " << _x1[0] << " " << _x1[1] << " " << _x1[2] << " " << _o1[0] << " " << _o1[1] << " " << _o1[2] << " " << _o1[3] << std::endl;
     //std::cout << "frame2: " << _x2[0] << " " << _x2[1] << " " << _x2[2] << " " << _o2[0] << " " << _o2[1] << " " << _o2[2] << " " << _o2[3] << std::endl;
diff --git a/include/gnss/processor/processor_tracker_gnss.h b/include/gnss/processor/processor_tracker_gnss.h
index c821bffac1a775b2c5d0957cd2d14b8306028e42..9984f8014711a518a86a2d922d23ab92d1666470 100644
--- a/include/gnss/processor/processor_tracker_gnss.h
+++ b/include/gnss/processor/processor_tracker_gnss.h
@@ -26,7 +26,7 @@ struct ParamsProcessorTrackerGnss : public ParamsProcessorTrackerFeature
     double enu_map_fix_dist;
     int min_sbas_sats;
     bool tdcp_enabled;
-    bool tdcp_all_against_all;
+    std::string tdcp_structure;
 
     ParamsProcessorTrackerGnss() = default;
     ParamsProcessorTrackerGnss(std::string _unique_name, const ParamsServer& _server):
@@ -41,7 +41,6 @@ struct ParamsProcessorTrackerGnss : public ParamsProcessorTrackerFeature
         fix                         = _server.getParam<bool>    (prefix + _unique_name + "/fix");
         pseudo_ranges               = _server.getParam<bool>    (prefix + _unique_name + "/pseudo_ranges");
         min_sbas_sats               = _server.getParam<int>     (prefix + _unique_name + "/gnss/min_sbas_sats");
-        tdcp_all_against_all        = _server.getParam<bool>    (prefix + _unique_name + "/gnss/tdcp/all_against_all");
 
         // GNSS OPTIONS (see rtklib.h)
         gnss_opt.sateph     =        _server.getParam<int>   (prefix + _unique_name + "/gnss/sateph");  // satellite ephemeris option: EPHOPT_BRDC(0):broadcast ephemeris, EPHOPT_PREC(1): precise ephemeris, EPHOPT_SBAS(2): broadcast + SBAS, EPHOPT_SSRAPC(3): broadcast + SSR_APC, EPHOPT_SSRCOM(4): broadcast + SSR_COM, EPHOPT_LEX(5): QZSS LEX ephemeris, EPHOPT_SBAS2(6):broadcast + SBAS(sats with SBAS corr and sats with BRDC eph), EPHOPT_SBAS3(7):broadcast + SBAS(EPHOPT_SBAS if possible, otherwise EPHOPT_SBAS2), EPHOPT_SBAS4(8):broadcast + SBAS(EPHOPT_SBAS if possible, otherwise EPHOPT_BRDC)
@@ -65,6 +64,7 @@ struct ParamsProcessorTrackerGnss : public ParamsProcessorTrackerFeature
         tdcp_enabled = _server.getParam<bool>(prefix + _unique_name + "/gnss/tdcp/enabled");
         if (tdcp_enabled)
         {
+            tdcp_structure                      = _server.getParam<std::string>(prefix + _unique_name + "/gnss/tdcp/structure");
             remove_outliers_tdcp                = _server.getParam<bool>  (prefix + _unique_name + "/gnss/tdcp/remove_outliers");
             tdcp_params.batch                   = _server.getParam<bool>  (prefix + _unique_name + "/gnss/tdcp/batch");
             gnss_opt.carrier_opt.corr_iono      = _server.getParam<bool>  (prefix + _unique_name + "/gnss/tdcp/corr_iono");
@@ -84,6 +84,9 @@ struct ParamsProcessorTrackerGnss : public ParamsProcessorTrackerFeature
                 tdcp_params.max_iterations          = _server.getParam<int>       (prefix + _unique_name + "/gnss/tdcp/max_iterations");
                 tdcp_params.residual_opt            = _server.getParam<int>       (prefix + _unique_name + "/gnss/tdcp/residual_opt");
             }
+
+            if (tdcp_structure != "all-all" and tdcp_structure != "consecutive" and tdcp_structure != "first-all")
+                throw std::runtime_error("unknown value for '/gnss/tdcp/structure', should be 'all-all', 'consecutive' or 'first-all'");
         }
 
         // COMPUTE FIX OPTIONS (RAIM)
@@ -129,7 +132,7 @@ struct ParamsProcessorTrackerGnss : public ParamsProcessorTrackerFeature
             + "gnss/constellations/IRN: "       + std::to_string(gnss_opt.IRN)                  + "\n"
             + "gnss/constellations/LEO: "       + std::to_string(gnss_opt.LEO)                  + "\n"
             + "gnss/tdcp/enabled: "             + std::to_string(tdcp_enabled)                  + "\n"
-            + "gnss/tdcp/all_agains_all: "      + std::to_string(tdcp_all_against_all)          + "\n"
+            + "gnss/tdcp/structure: "           + tdcp_structure                                + "\n"
             + "gnss/tdcp/batch: "               + std::to_string(tdcp_params.batch)             + "\n"
             + "gnss/tdcp/corr_iono: "           + std::to_string(gnss_opt.carrier_opt.corr_iono)+ "\n"
             + "gnss/tdcp/corr_tropo: "          + std::to_string(gnss_opt.carrier_opt.corr_tropo)+ "\n"
diff --git a/include/gnss/tree_manager/tree_manager_sliding_window_tdcp.h b/include/gnss/tree_manager/tree_manager_sliding_window_tdcp.h
new file mode 100644
index 0000000000000000000000000000000000000000..9c46154057f16aa5e93d232cb15e01012c6cbe06
--- /dev/null
+++ b/include/gnss/tree_manager/tree_manager_sliding_window_tdcp.h
@@ -0,0 +1,43 @@
+#ifndef INCLUDE_TREE_MANAGER_SLIDING_WINDOW_TDCP_H_
+#define INCLUDE_TREE_MANAGER_SLIDING_WINDOW_TDCP_H_
+
+#include "core/tree_manager/tree_manager_sliding_window.h"
+
+namespace wolf
+{
+
+WOLF_STRUCT_PTR_TYPEDEFS(ParamsTreeManagerSlidingWindowTdcp)
+WOLF_PTR_TYPEDEFS(TreeManagerSlidingWindowTdcp)
+
+struct ParamsTreeManagerSlidingWindowTdcp : public ParamsTreeManagerSlidingWindow
+{
+        ParamsTreeManagerSlidingWindowTdcp() = default;
+        ParamsTreeManagerSlidingWindowTdcp(std::string _unique_name, const wolf::ParamsServer & _server) :
+            ParamsTreeManagerSlidingWindow(_unique_name, _server)
+        {
+        }
+        std::string print() const override
+        {
+            return "\n" + ParamsTreeManagerSlidingWindow::print();
+        }
+};
+
+class TreeManagerSlidingWindowTdcp : public TreeManagerSlidingWindow
+{
+    public:
+        TreeManagerSlidingWindowTdcp(ParamsTreeManagerSlidingWindowTdcpPtr _params);
+        WOLF_TREE_MANAGER_CREATE(TreeManagerSlidingWindowTdcp, ParamsTreeManagerSlidingWindowTdcp)
+
+        ~TreeManagerSlidingWindowTdcp() override{}
+
+        void keyFrameCallback(FrameBasePtr _key_frame) override;
+
+    protected:
+        ParamsTreeManagerSlidingWindowTdcpPtr params_sw_sb_;
+        SensorBasePtr sensor_imu_;
+        Eigen::Matrix6d cov_bias_;
+};
+
+} /* namespace wolf */
+
+#endif /* INCLUDE_TREE_MANAGER_SLIDING_WINDOW_H_ */
diff --git a/src/processor/processor_gnss_tdcp.cpp b/src/processor/processor_gnss_tdcp.cpp
index 3f2c15cfa393a235a4de3520638a0d82de28d80e..80cc5c99d3a9b3c11b4cecb95eb5814782f4cd38 100644
--- a/src/processor/processor_gnss_tdcp.cpp
+++ b/src/processor/processor_gnss_tdcp.cpp
@@ -190,10 +190,10 @@ FactorBasePtr ProcessorGnssTdcp::emplaceFactor(FeatureBasePtr _ftr, FrameBasePtr
     //WOLF_DEBUG("creating the factor...");
     // 2D
     if (getProblem()->getDim() == 2)
-        return FactorBase::emplace<FactorGnssTdcp2d>(_ftr, _ftr, _frm_ref, sensor_gnss_, shared_from_this());
+        return FactorBase::emplace<FactorGnssTdcp2d>(_ftr, _ftr, _frm_ref, sensor_gnss_, shared_from_this(), params_->apply_loss_function);
     // 3D
     else
-        return FactorBase::emplace<FactorGnssTdcp3d>(_ftr, _ftr, _frm_ref, sensor_gnss_, shared_from_this());
+        return FactorBase::emplace<FactorGnssTdcp3d>(_ftr, _ftr, _frm_ref, sensor_gnss_, shared_from_this(), params_->apply_loss_function);
 
     return nullptr;
 }
diff --git a/src/processor/processor_tracker_gnss.cpp b/src/processor/processor_tracker_gnss.cpp
index ca533fc159fe61c19abe897f6d2e1237acd69d0b..e3dd9e6ef9d4869472e22dbd9b25063d139baf5c 100644
--- a/src/processor/processor_tracker_gnss.cpp
+++ b/src/processor/processor_tracker_gnss.cpp
@@ -4,7 +4,7 @@
 #include "gnss/feature/feature_gnss_tdcp.h"
 #include "gnss/feature/feature_gnss_fix.h"
 #include "gnss/factor/factor_gnss_tdcp.h"
-#include "gnss/factor/factor_gnss_tdcp_3d.h"
+#include "gnss/factor/factor_gnss_tdcp_batch.h"
 #include "gnss/factor/factor_gnss_pseudo_range.h"
 #include "gnss/factor/factor_gnss_fix_3d.h"
 #include "gnss_utils/utils/rcv_position.h"
@@ -387,6 +387,7 @@ void ProcessorTrackerGnss::establishFactors()
         if (params_tracker_gnss_->tdcp_params.batch)
         {
             WOLF_DEBUG("TDCP BATCH frame ", last_ptr_->getFrame()->id());
+            FactorBasePtr last_fac_ptr = nullptr;
 
             for (auto KF_rit = getProblem()->getTrajectory()->rbegin();
                  KF_rit != getProblem()->getTrajectory()->rend();
@@ -439,9 +440,9 @@ void ProcessorTrackerGnss::establishFactors()
                 //std::cout << std::endl;
 
                 // DEBUG: FIND COMMON SATELLITES OBSERVATIONS
-                std::set<int> common_sats_debug = GnssUtils::Observations::findCommonObservations(*ref_cap_gnss->getSnapshot()->getObservations(),
-                                                                                                  *last_cap_gnss->getSnapshot()->getObservations());
-                WOLF_DEBUG("TDCP BATCH common_sats_debug: ", common_sats_debug.size());
+                //std::set<int> common_sats_debug = GnssUtils::Observations::findCommonObservations(*ref_cap_gnss->getSnapshot()->getObservations(),
+                //                                                                                  *last_cap_gnss->getSnapshot()->getObservations());
+                //WOLF_DEBUG("TDCP BATCH common_sats_debug: ", common_sats_debug.size());
                 //for (auto sat : common_sats_debug)
                 //    std::cout << sat << " ";
                 //std::cout << std::endl;
@@ -462,25 +463,39 @@ void ProcessorTrackerGnss::establishFactors()
                     WOLF_DEBUG("TDCP BATCH cov =\n", tdcp_output.cov_d);
 
                     // EMPLACE FEATURE
+                    auto factor_status = FAC_ACTIVE;
+                    if (params_tracker_gnss_->tdcp_structure == "first-all")
+                        factor_status = FAC_INACTIVE;
+
                     auto ftr = FeatureBase::emplace<FeatureGnssTdcp>(last_cap_gnss,
-                                                                     Eigen::Vector3d(tdcp_output.d.head<3>()),
-                                                                     Eigen::Matrix3d(tdcp_output.cov_d.topLeftCorner<3,3>()));
+                                                                     tdcp_output.d,
+                                                                     tdcp_output.cov_d);
 
                     // EMPLACE FACTOR
-                    FactorBase::emplace<FactorGnssTdcp3d>(ftr,
-                                                          ftr,
-                                                          KF,
-                                                          sensor_gnss_,
-                                                          shared_from_this());
+                    last_fac_ptr = FactorBase::emplace<FactorGnssTdcpBatch>(ftr,
+                                                                            ftr,
+                                                                            ref_cap_gnss,
+                                                                            sensor_gnss_,
+                                                                            shared_from_this(),
+                                                                            params_->apply_loss_function,
+                                                                            factor_status);
+
+                    WOLF_DEBUG("TDCP BATCH factor ", last_fac_ptr->id() , " emplaced as ", (last_fac_ptr->getStatus() == FAC_ACTIVE ? "ACTIVE" : "INACTIVE"));
+
+                    // only first (with previous frame) factor in "consecutive" structure
+                    if (params_tracker_gnss_->tdcp_structure == "consecutive")
+                        break;
                 }
                 else
                 {
                     WOLF_DEBUG("TDCP BATCH failed with msg: ", tdcp_output.msg);
                 }
-
-                // just one factor
-                if (not params_tracker_gnss_->tdcp_all_against_all)
-                    break;
+            }
+            // only last (with first frame) factor in "first-all" structure
+            if (params_tracker_gnss_->tdcp_structure == "first-all" and last_fac_ptr)
+            {
+                last_fac_ptr->setStatus(FAC_ACTIVE);
+                WOLF_DEBUG("TDCP BATCH factor ", last_fac_ptr->id() , " changed to ", (last_fac_ptr->getStatus() == FAC_ACTIVE ? "ACTIVE" : "INACTIVE"));
             }
         }
         // FACTOR per SATELLITE (FactorGnssTdcp)
@@ -530,6 +545,9 @@ void ProcessorTrackerGnss::establishFactors()
                     WOLF_DEBUG("previous feature at KF: ", ftr_r->getCapture()->getFrame()->id(), " sat: ", ftr_r->satNumber(), " id: ", ftr_r->id());
 
                     // emplace tdcp factor
+                    auto factor_status = FAC_ACTIVE;
+                    if (params_tracker_gnss_->tdcp_structure == "first-all")
+                        factor_status = FAC_INACTIVE;
                     double var_tdcp = dt * std::pow(params_tracker_gnss_->tdcp_params.sigma_atm,2) + std::pow(params_tracker_gnss_->tdcp_params.sigma_carrier,2);
                     auto new_fac = FactorBase::emplace<FactorGnssTdcp>(ftr_k,
                                                                        sqrt(var_tdcp),
@@ -537,17 +555,22 @@ void ProcessorTrackerGnss::establishFactors()
                                                                        ftr_k,
                                                                        sensor_gnss_,
                                                                        shared_from_this(),
-                                                                       params_tracker_gnss_->tdcp_params.loss_function);
+                                                                       params_tracker_gnss_->tdcp_params.loss_function,
+                                                                       factor_status);
                     new_factors.push_back(new_fac);
 
                     // WOLF_DEBUG( "Factor: track: " , feature_in_last->trackId(),
                     //             " origin: "       , feature_in_origin->id() ,
                     //             " from last: "    , feature_in_last->id() );
 
-                    // just one factor
-                    if (not params_tracker_gnss_->tdcp_all_against_all)
+                    // only first (with previous frame) factor in "consecutive" structure
+                    if (params_tracker_gnss_->tdcp_structure == "consecutive")
                         break;
                 }
+                // only last (with first frame) factor in "first-all" structure
+                if (params_tracker_gnss_->tdcp_structure == "first-all")
+                    new_factors.back()->setStatus(FAC_ACTIVE);
+
                 WOLF_DEBUG("All TDCP factors emplaced!");
             }
         }
diff --git a/src/tree_manager/tree_manager_sliding_window_tdcp.cpp b/src/tree_manager/tree_manager_sliding_window_tdcp.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0a68df7096fa17ca70adb3734046b588d2381967
--- /dev/null
+++ b/src/tree_manager/tree_manager_sliding_window_tdcp.cpp
@@ -0,0 +1,45 @@
+#include "gnss/tree_manager/tree_manager_sliding_window_tdcp.h"
+
+namespace wolf
+{
+
+TreeManagerSlidingWindowTdcp::TreeManagerSlidingWindowTdcp(ParamsTreeManagerSlidingWindowTdcpPtr _params) :
+            TreeManagerSlidingWindow(_params),
+            params_sw_sb_(_params)
+{
+    NodeBase::setType("TreeManagerSlidingWindowTdcp");
+};
+
+void TreeManagerSlidingWindowTdcp::keyFrameCallback(FrameBasePtr _key_frame)
+{
+    assert(getProblem() && "TreeManagerSlidingWindowTdcp::keyFrameCallback: problem not set.");
+
+    // store first frame
+    auto first_frame = getProblem()->getTrajectory()->getFirstFrame();
+
+    // call base sliding window tree manager
+    TreeManagerSlidingWindow::keyFrameCallback(_key_frame);
+
+    // if first frame was removed, activate all factors of new first frame
+    if (first_frame != getProblem()->getTrajectory()->getFirstFrame())
+    {
+        assert(first_frame->isRemoving());
+        for (auto fac : getProblem()->getTrajectory()->getFirstFrame()->getConstrainedByList())
+            if (fac and not fac->isRemoving() and
+                (fac->getType() == "FactorGnssTdcp" or
+                 fac->getType() == "FactorGnssTdcp2d" or
+                 fac->getType() == "FactorGnssTdcp3d" or
+                 fac->getType() == "FactorGnssTdcpBatch"))
+                fac->setStatus(FAC_ACTIVE);
+    }
+}
+
+} /* namespace wolf */
+
+// Register in the FactoryTreeManager
+#include "core/tree_manager/factory_tree_manager.h"
+namespace wolf {
+WOLF_REGISTER_TREE_MANAGER(TreeManagerSlidingWindowTdcp);
+WOLF_REGISTER_TREE_MANAGER_AUTO(TreeManagerSlidingWindowTdcp);
+} // namespace wolf
+