diff --git a/CMakeLists.txt b/CMakeLists.txt
index cab800a231b74a05eb9c466e0ec5d508ca561918..98de6dbd9bfb7521238c7c784b077456b35b5629 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -285,7 +285,11 @@ SET(HDRS_SOLVER
   include/core/solver/solver_manager.h
   include/core/solver/solver_factory.h
   )
-
+SET(HDRS_TREE_MANAGER
+  include/core/tree_manager/factory_tree_manager.h
+  include/core/tree_manager/tree_manager_base.h
+  include/core/tree_manager/tree_manager_sliding_window.h
+  )
 SET(HDRS_YAML
   include/core/yaml/parser_yaml.h
   include/core/yaml/yaml_conversion.h
@@ -371,6 +375,9 @@ SET(SRCS_SENSOR
 SET(SRCS_SOLVER
   src/solver/solver_manager.cpp
   )
+SET(SRCS_TREE_MANAGER
+  src/tree_manager/tree_manager_sliding_window.cpp
+  )
 SET(SRCS_YAML
   src/yaml/parser_yaml.cpp
   src/yaml/processor_odom_3d_yaml.cpp
@@ -431,6 +438,7 @@ ADD_LIBRARY(${PROJECT_NAME}
   ${SRCS_SOLVER}
   ${SRCS_STATE_BLOCK}
   ${SRCS_TRAJECTORY}
+  ${SRCS_TREE_MANAGER}
   ${SRCS_UTILS}
   ${SRCS_WRAPPER}
   ${SRCS_YAML}
@@ -471,44 +479,46 @@ INSTALL(TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME}Targets
 
 install(EXPORT ${PROJECT_NAME}Targets DESTINATION lib/cmake/${PROJECT_NAME})
 #install headers
-INSTALL(FILES ${HDRS_MATH}
-  DESTINATION include/iri-algorithms/wolf/plugin_core/core/math)
-INSTALL(FILES ${HDRS_UTILS}
-  DESTINATION include/iri-algorithms/wolf/plugin_core/core/utils)
-INSTALL(FILES ${HDRS_PROBLEM}
-  DESTINATION include/iri-algorithms/wolf/plugin_core/core/problem)
-INSTALL(FILES ${HDRS_HARDWARE}
-  DESTINATION include/iri-algorithms/wolf/plugin_core/core/hardware)
-INSTALL(FILES ${HDRS_TRAJECTORY}
-  DESTINATION include/iri-algorithms/wolf/plugin_core/core/trajectory)
-INSTALL(FILES ${HDRS_MAP}
-  DESTINATION include/iri-algorithms/wolf/plugin_core/core/map)
-INSTALL(FILES ${HDRS_FRAME}
-  DESTINATION include/iri-algorithms/wolf/plugin_core/core/frame)
-INSTALL(FILES ${HDRS_STATE_BLOCK}
-  DESTINATION include/iri-algorithms/wolf/plugin_core/core/state_block)
-INSTALL(FILES ${HDRS_COMMON}
-  DESTINATION include/iri-algorithms/wolf/plugin_core/core/common)
 INSTALL(FILES ${HDRS_CAPTURE}
    DESTINATION include/iri-algorithms/wolf/plugin_core/core/capture)
+INSTALL(FILES ${HDRS_COMMON}
+  DESTINATION include/iri-algorithms/wolf/plugin_core/core/common)
 INSTALL(FILES ${HDRS_FACTOR}
   DESTINATION include/iri-algorithms/wolf/plugin_core/core/factor)
 INSTALL(FILES ${HDRS_FEATURE}
   DESTINATION include/iri-algorithms/wolf/plugin_core/core/feature)
-INSTALL(FILES ${HDRS_SENSOR}
-  DESTINATION include/iri-algorithms/wolf/plugin_core/core/sensor)
-INSTALL(FILES ${HDRS_PROCESSOR}
-  DESTINATION include/iri-algorithms/wolf/plugin_core/core/processor)
+INSTALL(FILES ${HDRS_FRAME}
+  DESTINATION include/iri-algorithms/wolf/plugin_core/core/frame)
+INSTALL(FILES ${HDRS_HARDWARE}
+  DESTINATION include/iri-algorithms/wolf/plugin_core/core/hardware)
 INSTALL(FILES ${HDRS_LANDMARK}
   DESTINATION include/iri-algorithms/wolf/plugin_core/core/landmark)
-INSTALL(FILES ${HDRS_WRAPPER}
-  DESTINATION include/iri-algorithms/wolf/plugin_core/core/ceres_wrapper)
-INSTALL(FILES ${HDRS_SOLVER_SUITESPARSE}
-  DESTINATION include/iri-algorithms/wolf/plugin_core/core/solver_suitesparse)
-INSTALL(FILES ${HDRS_SOLVER}
-  DESTINATION include/iri-algorithms/wolf/plugin_core/core/solver)
+INSTALL(FILES ${HDRS_MAP}
+  DESTINATION include/iri-algorithms/wolf/plugin_core/core/map)
+INSTALL(FILES ${HDRS_MATH}
+  DESTINATION include/iri-algorithms/wolf/plugin_core/core/math)
+INSTALL(FILES ${HDRS_PROBLEM}
+  DESTINATION include/iri-algorithms/wolf/plugin_core/core/problem)
+INSTALL(FILES ${HDRS_PROCESSOR}
+  DESTINATION include/iri-algorithms/wolf/plugin_core/core/processor)
+INSTALL(FILES ${HDRS_SENSOR}
+  DESTINATION include/iri-algorithms/wolf/plugin_core/core/sensor)
 INSTALL(FILES ${HDRS_SERIALIZATION}
   DESTINATION include/iri-algorithms/wolf/plugin_core/core/serialization)
+INSTALL(FILES ${HDRS_SOLVER}
+  DESTINATION include/iri-algorithms/wolf/plugin_core/core/solver)
+INSTALL(FILES ${HDRS_SOLVER_SUITESPARSE}
+  DESTINATION include/iri-algorithms/wolf/plugin_core/core/solver_suitesparse)
+INSTALL(FILES ${HDRS_STATE_BLOCK}
+  DESTINATION include/iri-algorithms/wolf/plugin_core/core/state_block)
+INSTALL(FILES ${HDRS_TRAJECTORY}
+  DESTINATION include/iri-algorithms/wolf/plugin_core/core/trajectory)
+INSTALL(FILES ${HDRS_TREE_MANAGER}
+  DESTINATION include/iri-algorithms/wolf/plugin_core/core/tree_manager)
+INSTALL(FILES ${HDRS_UTILS}
+  DESTINATION include/iri-algorithms/wolf/plugin_core/core/utils)
+INSTALL(FILES ${HDRS_WRAPPER}
+  DESTINATION include/iri-algorithms/wolf/plugin_core/core/ceres_wrapper)
 INSTALL(FILES ${HDRS_YAML}
   DESTINATION include/iri-algorithms/wolf/plugin_core/core/yaml)
 
diff --git a/include/core/common/wolf.h b/include/core/common/wolf.h
index 64a4741c518ecd0f75bf029aa4e3267b1e3f8c4e..b11165468e47ef55e7c65ce046571d7e68ebd945 100644
--- a/include/core/common/wolf.h
+++ b/include/core/common/wolf.h
@@ -212,6 +212,10 @@ WOLF_PTR_TYPEDEFS(NodeBase);
 // Problem
 WOLF_PTR_TYPEDEFS(Problem);
 
+// Tree Manager
+WOLF_PTR_TYPEDEFS(TreeManagerBase);
+WOLF_STRUCT_PTR_TYPEDEFS(ParamsTreeManagerBase);
+
 // Hardware
 WOLF_PTR_TYPEDEFS(HardwareBase);
 
diff --git a/include/core/problem/problem.h b/include/core/problem/problem.h
index f2b19ef05c22f7a4c6777f889031dbda45d80a5b..edda0b3b59fa839cdb6c5156abf61e1f2c338174 100644
--- a/include/core/problem/problem.h
+++ b/include/core/problem/problem.h
@@ -43,6 +43,7 @@ class Problem : public std::enable_shared_from_this<Problem>
     friend ProcessorMotion;
 
     protected:
+        TreeManagerBasePtr tree_manager_;
         HardwareBasePtr     hardware_ptr_;
         TrajectoryBasePtr   trajectory_ptr_;
         MapBasePtr          map_ptr_;
@@ -73,6 +74,10 @@ class Problem : public std::enable_shared_from_this<Problem>
         SizeEigen getDim() const;
         std::string getFrameStructure() const;
 
+        // Tree manager --------------------------------------
+        void setTreeManager(TreeManagerBasePtr _gm);
+        TreeManagerBasePtr getTreeManager() const;
+
         // Hardware branch ------------------------------------
         HardwareBasePtr getHardware() const;
 
@@ -361,6 +366,11 @@ class Problem : public std::enable_shared_from_this<Problem>
 namespace wolf
 {
 
+inline TreeManagerBasePtr Problem::getTreeManager() const
+{
+    return tree_manager_;
+}
+
 inline bool Problem::priorIsSet() const
 {
     return prior_is_set_;
diff --git a/include/core/tree_manager/factory_tree_manager.h b/include/core/tree_manager/factory_tree_manager.h
new file mode 100644
index 0000000000000000000000000000000000000000..7b421461c4c636a5a87ccc35b87fc83213d5b4d0
--- /dev/null
+++ b/include/core/tree_manager/factory_tree_manager.h
@@ -0,0 +1,61 @@
+#ifndef FACTORY_TREE_MANAGER_H_
+#define FACTORY_TREE_MANAGER_H_
+
+namespace wolf
+{
+class TreeManagerBase;
+struct ParamsTreeManagerBase;
+}
+
+// wolf
+#include "core/common/factory.h"
+
+// std
+
+namespace wolf
+{
+/** \brief TreeManager factory class
+ * TODO
+ */
+
+// ParamsTreeManager factory
+struct ParamsTreeManagerBase;
+typedef Factory<ParamsTreeManagerBase,
+        const std::string&> FactoryParamsTreeManager;
+template<>
+inline std::string FactoryParamsTreeManager::getClass()
+{
+    return "FactoryParamsTreeManager";
+}
+
+// TreeManager factory
+typedef Factory<TreeManagerBase,
+        const std::string&,
+        const ParamsTreeManagerBasePtr> FactoryTreeManager;
+template<>
+inline std::string FactoryTreeManager::getClass()
+{
+  return "FactoryTreeManager";
+}
+
+#define WOLF_REGISTER_TREE_MANAGER(TreeManagerType, TreeManagerName)                                   \
+  namespace{ const bool WOLF_UNUSED TreeManagerName##Registered =                                 \
+    wolf::FactoryTreeManager::get().registerCreator(TreeManagerType, TreeManagerName::create); }      \
+
+typedef Factory<TreeManagerBase,
+        const std::string&,
+        const ParamsServer&> AutoConfFactoryTreeManager;
+template<>
+inline std::string AutoConfFactoryTreeManager::getClass()
+{
+    return "AutoConfFactoryTreeManager";
+}
+
+
+#define WOLF_REGISTER_TREE_MANAGER_AUTO(TreeManagerType, TreeManagerName)                                  \
+  namespace{ const bool WOLF_UNUSED TreeManagerName##AutoConfRegistered =                             \
+    wolf::AutoConfFactoryTreeManager::get().registerCreator(TreeManagerType, TreeManagerName::create); }  \
+
+} /* namespace wolf */
+
+#endif /* FACTORY_TREE_MANAGER_H_ */
diff --git a/include/core/tree_manager/tree_manager_base.h b/include/core/tree_manager/tree_manager_base.h
new file mode 100644
index 0000000000000000000000000000000000000000..53ef9825ab029933b8c58e497e792d4f101c0406
--- /dev/null
+++ b/include/core/tree_manager/tree_manager_base.h
@@ -0,0 +1,82 @@
+#ifndef INCLUDE_TREE_MANAGER_BASE_H_
+#define INCLUDE_TREE_MANAGER_BASE_H_
+
+// Wolf includes
+#include "core/common/wolf.h"
+#include "core/common/node_base.h"
+#include "core/common/params_base.h"
+#include "core/problem/problem.h"
+
+namespace wolf
+{
+/*
+ * Macro for defining Autoconf tree manager creator for WOLF's high level API.
+ *
+ * Place a call to this macro inside your class declaration (in the tree_manager_class.h file),
+ * preferably just after the constructors.
+ *
+ * In order to use this macro, the derived processor class, ProcessorClass,
+ * must have a constructor available with the API:
+ *
+ *   TreeManagerClass(const ParamsTreeManagerPtr _params);
+ */
+#define WOLF_TREE_MANAGER_CREATE(TreeManagerClass, ParamsTreeManagerClass)                  \
+static TreeManagerBasePtr create(const std::string& _unique_name,                           \
+                                  const ParamsServer& _server)                              \
+{                                                                                           \
+    auto params         = std::make_shared<ParamsTreeManagerClass>(_unique_name, _server);  \
+                                                                                            \
+    auto tree_manager  = std::make_shared<TreeManagerClass>(params);                        \
+                                                                                            \
+    tree_manager       ->setName(_unique_name);                                             \
+                                                                                            \
+    return tree_manager;                                                                    \
+}                                                                                           \
+static TreeManagerBasePtr create(const std::string& _unique_name,                           \
+                                  const ParamsTreeManagerBasePtr _params)                   \
+{                                                                                           \
+    auto params         = std::static_pointer_cast<ParamsTreeManagerClass>(_params);        \
+                                                                                            \
+    auto tree_manager  = std::make_shared<TreeManagerClass>(params);                        \
+                                                                                            \
+    tree_manager       ->setName(_unique_name);                                             \
+                                                                                            \
+    return tree_manager;                                                                    \
+}                                                                                           \
+
+struct ParamsTreeManagerBase : public ParamsBase
+{
+    std::string prefix = "problem/tree_manager";
+    ParamsTreeManagerBase() = default;
+    ParamsTreeManagerBase(std::string _unique_name, const ParamsServer& _server):
+        ParamsBase(_unique_name, _server)
+    {
+    }
+
+    virtual ~ParamsTreeManagerBase() = default;
+
+    std::string print() const
+    {
+        return ParamsBase::print() + "\n";
+    }
+};
+
+class TreeManagerBase : public NodeBase
+{
+    public:
+        TreeManagerBase(const std::string& _type, ParamsTreeManagerBasePtr _params) :
+            NodeBase("TREE_MANAGER", _type),
+            params_(_params)
+        {}
+
+        virtual ~TreeManagerBase(){}
+
+        virtual void keyFrameCallback(FrameBasePtr _key_frame) = 0;
+
+    protected:
+        ParamsTreeManagerBasePtr params_;
+};
+
+} /* namespace wolf */
+
+#endif /* INCLUDE_TREE_MANAGER_BASE_H_ */
diff --git a/include/core/tree_manager/tree_manager_sliding_window.h b/include/core/tree_manager/tree_manager_sliding_window.h
new file mode 100644
index 0000000000000000000000000000000000000000..8b2deec3b4fe8de046e1dd6c65c646be1a773727
--- /dev/null
+++ b/include/core/tree_manager/tree_manager_sliding_window.h
@@ -0,0 +1,54 @@
+#ifndef INCLUDE_TREE_MANAGER_SLIDING_WINDOW_H_
+#define INCLUDE_TREE_MANAGER_SLIDING_WINDOW_H_
+
+#include "../tree_manager/tree_manager_base.h"
+
+namespace wolf
+{
+
+WOLF_STRUCT_PTR_TYPEDEFS(ParamsTreeManagerSlidingWindow)
+WOLF_PTR_TYPEDEFS(TreeManagerSlidingWindow)
+
+struct ParamsTreeManagerSlidingWindow : public ParamsTreeManagerBase
+{
+        ParamsTreeManagerSlidingWindow() = default;
+        ParamsTreeManagerSlidingWindow(std::string _unique_name, const wolf::ParamsServer & _server) :
+            ParamsTreeManagerBase(_unique_name, _server)
+        {
+            n_key_frames                = _server.getParam<unsigned int>(prefix + "/n_key_frames");
+            fix_first_key_frame         = _server.getParam<bool>        (prefix + "/fix_first_key_frame");
+            viral_remove_empty_parent   = _server.getParam<bool>        (prefix + "/viral_remove_empty_parent");
+        }
+        std::string print() const
+        {
+            return "\n" + ParamsTreeManagerBase::print()                                            + "\n"
+                        + "n_key_frames: "              + std::to_string(n_key_frames)              + "\n"
+                        + "fix_first_key_frame: "       + std::to_string(fix_first_key_frame)       + "\n"
+                        + "viral_remove_empty_parent: " + std::to_string(viral_remove_empty_parent) + "\n";
+        }
+
+        unsigned int n_key_frames;
+        bool fix_first_key_frame;
+        bool viral_remove_empty_parent;
+};
+
+class TreeManagerSlidingWindow : public TreeManagerBase
+{
+    public:
+        TreeManagerSlidingWindow(ParamsTreeManagerSlidingWindowPtr _params) :
+            TreeManagerBase("TreeManagerSlidingWindow", _params),
+            params_sw_(_params)
+        {};
+        WOLF_TREE_MANAGER_CREATE(TreeManagerSlidingWindow, ParamsTreeManagerSlidingWindow)
+
+        virtual ~TreeManagerSlidingWindow(){}
+
+        virtual void keyFrameCallback(FrameBasePtr _key_frame) override;
+
+    protected:
+        ParamsTreeManagerSlidingWindowPtr params_sw_;
+};
+
+} /* namespace wolf */
+
+#endif /* INCLUDE_TREE_MANAGER_SLIDING_WINDOW_H_ */
diff --git a/src/problem/problem.cpp b/src/problem/problem.cpp
index 53acc960ecc87a61d28d7e1567af966d0579b375..747737dc1ff0ea4b742a97017065d229889ea7d6 100644
--- a/src/problem/problem.cpp
+++ b/src/problem/problem.cpp
@@ -11,12 +11,13 @@
 #include "core/sensor/sensor_factory.h"
 #include "core/processor/processor_factory.h"
 #include "core/state_block/state_block.h"
+#include "core/tree_manager/factory_tree_manager.h"
+#include "core/tree_manager/tree_manager_base.h"
 #include "core/utils/logging.h"
 #include "core/utils/params_server.h"
 #include "core/utils/loader.h"
 #include "core/utils/check_log.h"
 
-
 // IRI libs includes
 
 // C++ includes
@@ -28,10 +29,12 @@
 #include <vector>
 #include <unordered_set>
 
+
 namespace wolf
 {
 
 Problem::Problem(const std::string& _frame_structure, SizeEigen _dim) :
+        tree_manager_(nullptr),
         hardware_ptr_(std::make_shared<HardwareBase>()),
         trajectory_ptr_(std::make_shared<TrajectoryBase>(_frame_structure)),
         map_ptr_(std::make_shared<MapBase>()),
@@ -152,6 +155,12 @@ ProblemPtr Problem::autoSetup(ParamsServer &_server)
         procesorMap.insert(std::pair<std::string, ProcessorBasePtr>(prc["name"], problem->installProcessor(prc["type"], prc["name"], prc["sensor_name"], _server)));
     }
 
+    // Tree manager
+    std::string tree_manager_type = _server.getParam<std::string>("problem/tree_manager/type");
+    WOLF_TRACE("Tree Manager Type: ", tree_manager_type);
+    if (tree_manager_type != "None" and tree_manager_type != "none")
+        problem->setTreeManager(AutoConfFactoryTreeManager::get().create(tree_manager_type, "tree manager", _server));
+
     // Prior
     Eigen::VectorXd prior_state = _server.getParam<Eigen::VectorXd>("problem/prior/state");
     Eigen::MatrixXd prior_cov   = _server.getParam<Eigen::MatrixXd>("problem/prior/cov");
@@ -471,12 +480,22 @@ std::string Problem::getFrameStructure() const
     return frame_structure_;
 }
 
+void Problem::setTreeManager(TreeManagerBasePtr _gm)
+{
+    if (tree_manager_)
+        tree_manager_->setProblem(nullptr);
+    tree_manager_ = _gm;
+    tree_manager_->setProblem(shared_from_this());
+
+}
+
 void Problem::addProcessorIsMotion(IsMotionPtr _processor_motion_ptr)
 {
     processor_is_motion_list_.push_back(_processor_motion_ptr);
 }
 
-void Problem::clearProcessorIsMotion(IsMotionPtr proc){
+void Problem::clearProcessorIsMotion(IsMotionPtr proc)
+{
     auto it = std::find(processor_is_motion_list_.begin(), processor_is_motion_list_.end(), proc);
     if (it != processor_is_motion_list_.end()){
         processor_is_motion_list_.erase(it);
@@ -528,6 +547,10 @@ void Problem::keyFrameCallback(FrameBasePtr _keyframe_ptr, ProcessorBasePtr _pro
                           " microseconds: ", duration.count());
 #endif
             }
+
+    // notify tree manager
+    if (tree_manager_)
+        tree_manager_->keyFrameCallback(_keyframe_ptr);
 }
 
 bool Problem::permitAuxFrame(ProcessorBasePtr _processor_ptr) const
@@ -909,6 +932,10 @@ FrameBasePtr Problem::setPrior(const Eigen::VectorXd& _prior_state, const Eigen:
                 if ( !processor->isMotion() )
                     processor->keyFrameCallback(origin_keyframe, _time_tolerance);
 
+        // Notify tree manager
+        if (tree_manager_)
+            tree_manager_->keyFrameCallback(origin_keyframe);
+
         return origin_keyframe;
     }
     else
diff --git a/src/tree_manager/tree_manager_sliding_window.cpp b/src/tree_manager/tree_manager_sliding_window.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..710cd3566cd477e2dd8f9c02c0a71070c20e07d5
--- /dev/null
+++ b/src/tree_manager/tree_manager_sliding_window.cpp
@@ -0,0 +1,43 @@
+#include "core/tree_manager/tree_manager_sliding_window.h"
+
+namespace wolf
+{
+
+void TreeManagerSlidingWindow::keyFrameCallback(FrameBasePtr _key_frame)
+{
+    int n_kf(0);
+    FrameBasePtr first_KF(nullptr), second_KF(nullptr);
+    for (auto frm : getProblem()->getTrajectory()->getFrameList())
+    {
+        if (frm->isKey())
+        {
+            n_kf++;
+            if (first_KF == nullptr)
+                first_KF = frm;
+            else if (second_KF == nullptr)
+                second_KF = frm;
+        }
+    }
+
+    // remove first KF if too many KF
+    if (n_kf > params_sw_->n_key_frames)
+    {
+        WOLF_INFO("TreeManagerSlidingWindow removing first frame");
+        first_KF->remove(params_sw_->viral_remove_empty_parent);
+        if (params_sw_->fix_first_key_frame)
+        {
+            WOLF_INFO("TreeManagerSlidingWindow fixing new first frame");
+            second_KF->fix();
+        }
+    }
+}
+
+} /* namespace wolf */
+
+// Register in the FactoryTreeManager
+#include "core/tree_manager/factory_tree_manager.h"
+namespace wolf {
+WOLF_REGISTER_TREE_MANAGER("TreeManagerSlidingWindow", TreeManagerSlidingWindow);
+WOLF_REGISTER_TREE_MANAGER_AUTO("TreeManagerSlidingWindow", TreeManagerSlidingWindow);
+} // namespace wolf
+
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index db82caf1fc34b83b2509fe7d4f3ac4d6cc9e8c82..501965cdff67102f807e482f87ca7eafb7109e54 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -149,6 +149,10 @@ target_link_libraries(gtest_track_matrix ${PROJECT_NAME})
 wolf_add_gtest(gtest_trajectory gtest_trajectory.cpp)
 target_link_libraries(gtest_trajectory ${PROJECT_NAME})
 
+# TreeManager class test
+wolf_add_gtest(gtest_tree_manager gtest_tree_manager.cpp)
+target_link_libraries(gtest_tree_manager ${PROJECT_NAME})
+
 # ------- Now Derived classes ----------
 
 IF (Ceres_FOUND)
@@ -229,6 +233,10 @@ target_link_libraries(gtest_processor_tracker_landmark_dummy ${PROJECT_NAME} dum
 wolf_add_gtest(gtest_sensor_diff_drive gtest_sensor_diff_drive.cpp)
 target_link_libraries(gtest_sensor_diff_drive ${PROJECT_NAME})
 
+# TreeManagerSlidingWindow class test
+wolf_add_gtest(gtest_tree_manager_sliding_window gtest_tree_manager_sliding_window.cpp)
+target_link_libraries(gtest_tree_manager_sliding_window ${PROJECT_NAME})
+
 # yaml conversions
 wolf_add_gtest(gtest_yaml_conversions gtest_yaml_conversions.cpp)
 target_link_libraries(gtest_yaml_conversions ${PROJECT_NAME})
diff --git a/test/dummy/tree_manager_dummy.h b/test/dummy/tree_manager_dummy.h
new file mode 100644
index 0000000000000000000000000000000000000000..379fdd23902daaa5e3ba9d29a3f6a445f9e21373
--- /dev/null
+++ b/test/dummy/tree_manager_dummy.h
@@ -0,0 +1,61 @@
+#ifndef INCLUDE_TREE_MANAGER_DUMMY_H_
+#define INCLUDE_TREE_MANAGER_DUMMY_H_
+
+#include "core/tree_manager/tree_manager_base.h"
+
+namespace wolf
+{
+
+WOLF_STRUCT_PTR_TYPEDEFS(ParamsTreeManagerDummy)
+struct ParamsTreeManagerDummy : public ParamsTreeManagerBase
+{
+    ParamsTreeManagerDummy() = default;
+    ParamsTreeManagerDummy(std::string _unique_name, const ParamsServer& _server):
+        ParamsTreeManagerBase(_unique_name, _server)
+    {
+        toy_param = _server.getParam<double>(prefix + "/toy_param");
+    }
+
+    virtual ~ParamsTreeManagerDummy() = default;
+
+    bool toy_param;
+
+    std::string print() const
+    {
+        return ParamsTreeManagerBase::print() + "\n"
+               + "toy_param: " + std::to_string(toy_param) + "\n";
+    }
+};
+
+WOLF_PTR_TYPEDEFS(TreeManagerDummy)
+
+class TreeManagerDummy : public TreeManagerBase
+{
+    public:
+        TreeManagerDummy(ParamsTreeManagerBasePtr _params) :
+            TreeManagerBase("TreeManagerDummy", _params),
+            n_KF_(0)
+        {};
+        WOLF_TREE_MANAGER_CREATE(TreeManagerDummy, ParamsTreeManagerBase)
+
+        virtual ~TreeManagerDummy(){}
+
+        virtual void keyFrameCallback(FrameBasePtr _KF) override
+        {
+            n_KF_++;
+        };
+
+        int n_KF_;
+};
+
+} /* namespace wolf */
+
+// Register in the FactoryTreeManager
+#include "core/tree_manager/factory_tree_manager.h"
+namespace wolf {
+WOLF_REGISTER_TREE_MANAGER("TreeManagerDummy", TreeManagerDummy)
+WOLF_REGISTER_TREE_MANAGER_AUTO("TreeManagerDummy", TreeManagerDummy)
+
+} /* namespace wolf */
+
+#endif /* INCLUDE_TREE_MANAGER_DUMMY_H_ */
diff --git a/test/gtest_tree_manager.cpp b/test/gtest_tree_manager.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5799117ffa523a9cbf5132ed504fa1525001c0ae
--- /dev/null
+++ b/test/gtest_tree_manager.cpp
@@ -0,0 +1,105 @@
+#include "core/utils/utils_gtest.h"
+#include "core/utils/logging.h"
+
+#include "core/problem/problem.h"
+#include "dummy/tree_manager_dummy.h"
+#include "core/yaml/parser_yaml.h"
+
+using namespace wolf;
+using namespace Eigen;
+
+std::string wolf_root = _WOLF_ROOT_DIR;
+
+TEST(TreeManager, make_shared)
+{
+    ProblemPtr P = Problem::create("PO", 2);
+
+    auto ParamsGM = std::make_shared<ParamsTreeManagerBase>();
+
+    auto GM = std::make_shared<TreeManagerDummy>(ParamsGM);
+
+    P->setTreeManager(GM);
+
+    ASSERT_EQ(std::static_pointer_cast<TreeManagerDummy>(P->getTreeManager())->n_KF_, 0);
+    ASSERT_EQ(P->getTreeManager(), GM);
+}
+
+TEST(TreeManager, createParams)
+{
+    ProblemPtr P = Problem::create("PO", 2);
+
+    auto ParamsGM = std::make_shared<ParamsTreeManagerBase>();
+
+    auto GM = TreeManagerDummy::create("tree_manager", ParamsGM);
+
+    ASSERT_TRUE(std::dynamic_pointer_cast<TreeManagerDummy>(GM) != nullptr);
+
+    P->setTreeManager(GM);
+
+    ASSERT_EQ(std::static_pointer_cast<TreeManagerDummy>(P->getTreeManager())->n_KF_, 0);
+    ASSERT_EQ(P->getTreeManager(), GM);
+}
+
+TEST(TreeManager, createParamServer)
+{
+    ProblemPtr P = Problem::create("PO", 2);
+
+    ParserYAML parser = ParserYAML("test/yaml/params_tree_manager1.yaml", wolf_root);
+    ParamsServer server = ParamsServer(parser.getParams());
+
+    auto GM = TreeManagerDummy::create("tree_manager", server);
+
+    ASSERT_TRUE(std::dynamic_pointer_cast<TreeManagerDummy>(GM) != nullptr);
+
+    P->setTreeManager(GM);
+
+    ASSERT_EQ(std::static_pointer_cast<TreeManagerDummy>(P->getTreeManager())->n_KF_, 0);
+    ASSERT_EQ(P->getTreeManager(), GM);
+}
+
+TEST(TreeManager, autoConf)
+{
+
+    ParserYAML parser = ParserYAML("test/yaml/params_tree_manager1.yaml", wolf_root);
+    ParamsServer server = ParamsServer(parser.getParams());
+
+    ProblemPtr P = Problem::autoSetup(server);
+
+    ASSERT_TRUE(std::dynamic_pointer_cast<TreeManagerDummy>(P->getTreeManager()) != nullptr);
+    ASSERT_EQ(std::static_pointer_cast<TreeManagerDummy>(P->getTreeManager())->n_KF_, 1); // prior KF
+}
+
+TEST(TreeManager, autoConfNone)
+{
+
+    ParserYAML parser = ParserYAML("test/yaml/params_tree_manager2.yaml", wolf_root);
+    ParamsServer server = ParamsServer(parser.getParams());
+
+    ProblemPtr P = Problem::autoSetup(server);
+
+    ASSERT_TRUE(P->getTreeManager() == nullptr); // params_tree_manager2.yaml problem/tree_manager/type: None
+}
+
+TEST(TreeManager, keyFrameCallback)
+{
+    ProblemPtr P = Problem::create("PO", 3);
+
+    auto ParamsGM = std::make_shared<ParamsTreeManagerBase>();
+
+    auto GM = std::make_shared<TreeManagerDummy>(ParamsGM);
+
+    P->setTreeManager(GM);
+
+    ASSERT_EQ(GM->n_KF_, 0);
+
+    auto F0 = P->emplaceFrame("PO", 3,    KEY, VectorXd(7),  TimeStamp(0.0));
+    P->keyFrameCallback(F0, nullptr, 0);
+
+    ASSERT_EQ(GM->n_KF_, 1);
+}
+
+int main(int argc, char **argv)
+{
+  testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/test/gtest_tree_manager_sliding_window.cpp b/test/gtest_tree_manager_sliding_window.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ed3a8052bfb4a73b4395cc885904d8f752af91d2
--- /dev/null
+++ b/test/gtest_tree_manager_sliding_window.cpp
@@ -0,0 +1,267 @@
+#include "core/utils/utils_gtest.h"
+#include "core/utils/logging.h"
+
+#include "core/problem/problem.h"
+#include "core/tree_manager/tree_manager_sliding_window.h"
+#include "core/yaml/parser_yaml.h"
+#include "core/capture/capture_void.h"
+#include "core/feature/feature_base.h"
+#include "core/factor/factor_odom_3d.h"
+#include "core/factor/factor_pose_3d.h"
+
+using namespace wolf;
+using namespace Eigen;
+
+std::string wolf_root = _WOLF_ROOT_DIR;
+
+TEST(TreeManagerSlidingWindow, make_shared)
+{
+    ProblemPtr P = Problem::create("PO", 2);
+
+    auto ParamsGM = std::make_shared<ParamsTreeManagerSlidingWindow>();
+
+    auto GM = std::make_shared<TreeManagerSlidingWindow>(ParamsGM);
+
+    P->setTreeManager(GM);
+
+    ASSERT_EQ(P->getTreeManager(), GM);
+}
+
+TEST(TreeManagerSlidingWindow, createParams)
+{
+    ProblemPtr P = Problem::create("PO", 2);
+
+    auto ParamsGM = std::make_shared<ParamsTreeManagerSlidingWindow>();
+
+    auto GM = TreeManagerSlidingWindow::create("tree_manager", ParamsGM);
+
+    ASSERT_TRUE(std::dynamic_pointer_cast<TreeManagerSlidingWindow>(GM) != nullptr);
+
+    P->setTreeManager(GM);
+
+    ASSERT_TRUE(std::dynamic_pointer_cast<TreeManagerSlidingWindow>(P->getTreeManager()) != nullptr);
+    ASSERT_EQ(P->getTreeManager(), GM);
+}
+
+TEST(TreeManagerSlidingWindow, createParamServer)
+{
+    ProblemPtr P = Problem::create("PO", 2);
+
+    ParserYAML parser = ParserYAML("test/yaml/params_tree_manager_sliding_window1.yaml", wolf_root);
+    ParamsServer server = ParamsServer(parser.getParams());
+
+    auto GM = TreeManagerSlidingWindow::create("tree_manager", server);
+
+    ASSERT_TRUE(std::dynamic_pointer_cast<TreeManagerSlidingWindow>(GM) != nullptr);
+
+    P->setTreeManager(GM);
+
+    ASSERT_TRUE(std::dynamic_pointer_cast<TreeManagerSlidingWindow>(P->getTreeManager()) != nullptr);
+    ASSERT_EQ(P->getTreeManager(), GM);
+}
+
+TEST(TreeManagerSlidingWindow, autoConf)
+{
+    ParserYAML parser = ParserYAML("test/yaml/params_tree_manager_sliding_window1.yaml", wolf_root);
+    ParamsServer server = ParamsServer(parser.getParams());
+
+    ProblemPtr P = Problem::autoSetup(server);
+
+    ASSERT_TRUE(std::dynamic_pointer_cast<TreeManagerSlidingWindow>(P->getTreeManager()) != nullptr);
+}
+
+TEST(TreeManagerSlidingWindow, slidingWindowFixViral)
+{
+    ParserYAML parser = ParserYAML("test/yaml/params_tree_manager_sliding_window1.yaml", wolf_root);
+    ParamsServer server = ParamsServer(parser.getParams());
+
+    ProblemPtr P = Problem::autoSetup(server);
+
+    // FRAME 1 ----------------------------------------------------------
+    auto F1 = P->getTrajectory()->getLastKeyFrame();
+    ASSERT_TRUE(F1 != nullptr);
+
+    Vector7d state = F1->getState();
+    Vector7d zero_disp(state);
+    Matrix6d cov = Matrix6d::Identity();
+
+    // FRAME 2 ----------------------------------------------------------
+    auto F2 = P->emplaceFrame("PO", 3,    KEY, state,  TimeStamp(2));
+    P->keyFrameCallback(F2, nullptr, 0);
+
+    // absolute factor
+    auto C2 = CaptureBase::emplace<CaptureVoid>(F2, TimeStamp(2), nullptr);
+    auto f2 = FeatureBase::emplace<FeatureBase>(C2, "absolute", state, cov);
+    auto c2 = FactorBase::emplace<FactorPose3d>(f2, f2, nullptr, false);
+    // displacement
+    auto C12 = CaptureBase::emplace<CaptureVoid>(F2, TimeStamp(2), nullptr);
+    auto f12 = FeatureBase::emplace<FeatureBase>(C12, "odom", zero_disp, cov);
+    auto c12 = FactorBase::emplace<FactorOdom3d>(f12, f12, F1, nullptr, false);
+
+    // Check no frame removed
+    ASSERT_FALSE(F1->isRemoving());
+
+    // FRAME 3 ----------------------------------------------------------
+    auto F3 = P->emplaceFrame("PO", 3,    KEY, state, TimeStamp(3));
+    P->keyFrameCallback(F3, nullptr, 0);
+
+    // absolute factor
+    auto C3 = CaptureBase::emplace<CaptureVoid>(F3, TimeStamp(3), nullptr);
+    auto f3 = FeatureBase::emplace<FeatureBase>(C3, "absolute", state, cov);
+    auto c3 = FactorBase::emplace<FactorPose3d>(f3, f3, nullptr, false);
+    // displacement
+    auto C23 = CaptureBase::emplace<CaptureVoid>(F3, TimeStamp(3), nullptr);
+    auto f23 = FeatureBase::emplace<FeatureBase>(C23, "odom", zero_disp, cov);
+    auto c23 = FactorBase::emplace<FactorOdom3d>(f23, f23, F2, nullptr, false);
+
+    // Check no frame removed
+    ASSERT_FALSE(F1->isRemoving());
+
+    // FRAME 4 ----------------------------------------------------------
+    auto F4 = P->emplaceFrame("PO", 3,    KEY, state,  TimeStamp(4));
+    P->keyFrameCallback(F4, nullptr, 0);
+
+    // absolute factor
+    auto C4 = CaptureBase::emplace<CaptureVoid>(F4, TimeStamp(4), nullptr);
+    auto f4 = FeatureBase::emplace<FeatureBase>(C4, "absolute", state, cov);
+    auto c4 = FactorBase::emplace<FactorPose3d>(f4, f4, nullptr, false);
+    // displacement
+    auto C34 = CaptureBase::emplace<CaptureVoid>(F4, TimeStamp(4), nullptr);
+    auto f34 = FeatureBase::emplace<FeatureBase>(C34, "odom", zero_disp, cov);
+    auto c34 = FactorBase::emplace<FactorOdom3d>(f34, f34, F3, nullptr, false);
+
+    // Checks
+    ASSERT_TRUE(F1->isRemoving());
+    ASSERT_TRUE(c12->isRemoving());
+    ASSERT_TRUE(C12->isRemoving()); //Virally removed
+    ASSERT_TRUE(f12->isRemoving()); //Virally removed
+    ASSERT_TRUE(F2->isFixed()); //Fixed
+
+    // FRAME 5 ----------------------------------------------------------
+    auto F5 = P->emplaceFrame("PO", 3,    KEY, state,  TimeStamp(5));
+    P->keyFrameCallback(F5, nullptr, 0);
+
+    // absolute factor
+    auto C5 = CaptureBase::emplace<CaptureVoid>(F5, TimeStamp(5), nullptr);
+    auto f5 = FeatureBase::emplace<FeatureBase>(C5, "absolute", state, cov);
+    auto c5 = FactorBase::emplace<FactorPose3d>(f5, f5, nullptr, false);
+    // displacement
+    auto C45 = CaptureBase::emplace<CaptureVoid>(F5, TimeStamp(5), nullptr);
+    auto f45 = FeatureBase::emplace<FeatureBase>(C45, "odom", zero_disp, cov);
+    auto c45 = FactorBase::emplace<FactorOdom3d>(f45, f45, F4, nullptr, false);
+
+    // Checks
+    ASSERT_TRUE(F1->isRemoving());
+    ASSERT_TRUE(c12->isRemoving());
+    ASSERT_TRUE(C12->isRemoving()); //Virally removed
+    ASSERT_TRUE(f12->isRemoving()); //Virally removed
+    ASSERT_TRUE(F2->isRemoving());
+    ASSERT_TRUE(c2->isRemoving());
+    ASSERT_TRUE(C2->isRemoving()); //Virally removed
+    ASSERT_TRUE(f2->isRemoving()); //Virally removed
+    ASSERT_TRUE(c23->isRemoving());
+    ASSERT_TRUE(C23->isRemoving()); //Virally removed
+    ASSERT_TRUE(f23->isRemoving()); //Virally removed
+    ASSERT_TRUE(F3->isFixed()); //Fixed
+}
+
+TEST(TreeManagerSlidingWindow, slidingWindowNoFixNoViral)
+{
+    ParserYAML parser = ParserYAML("test/yaml/params_tree_manager_sliding_window2.yaml", wolf_root);
+    ParamsServer server = ParamsServer(parser.getParams());
+
+    ProblemPtr P = Problem::autoSetup(server);
+
+    // FRAME 1 ----------------------------------------------------------
+    auto F1 = P->getTrajectory()->getLastKeyFrame();
+    ASSERT_TRUE(F1 != nullptr);
+
+    Vector7d state = F1->getState();
+    Vector7d zero_disp(state);
+    Matrix6d cov = Matrix6d::Identity();
+
+    // FRAME 2 ----------------------------------------------------------
+    auto F2 = P->emplaceFrame("PO", 3,    KEY, state,  TimeStamp(2));
+    P->keyFrameCallback(F2, nullptr, 0);
+
+    // absolute factor
+    auto C2 = CaptureBase::emplace<CaptureVoid>(F2, TimeStamp(2), nullptr);
+    auto f2 = FeatureBase::emplace<FeatureBase>(C2, "absolute", state, cov);
+    auto c2 = FactorBase::emplace<FactorPose3d>(f2, f2, nullptr, false);
+    // displacement
+    auto C12 = CaptureBase::emplace<CaptureVoid>(F2, TimeStamp(2), nullptr);
+    auto f12 = FeatureBase::emplace<FeatureBase>(C12, "odom", zero_disp, cov);
+    auto c12 = FactorBase::emplace<FactorOdom3d>(f12, f12, F1, nullptr, false);
+
+    // Check no frame removed
+    ASSERT_FALSE(F1->isRemoving());
+
+    // FRAME 3 ----------------------------------------------------------
+    auto F3 = P->emplaceFrame("PO", 3,    KEY, state, TimeStamp(3));
+    P->keyFrameCallback(F3, nullptr, 0);
+
+    // absolute factor
+    auto C3 = CaptureBase::emplace<CaptureVoid>(F3, TimeStamp(3), nullptr);
+    auto f3 = FeatureBase::emplace<FeatureBase>(C3, "absolute", state, cov);
+    auto c3 = FactorBase::emplace<FactorPose3d>(f3, f3, nullptr, false);
+    // displacement
+    auto C23 = CaptureBase::emplace<CaptureVoid>(F3, TimeStamp(3), nullptr);
+    auto f23 = FeatureBase::emplace<FeatureBase>(C23, "odom", zero_disp, cov);
+    auto c23 = FactorBase::emplace<FactorOdom3d>(f23, f23, F2, nullptr, false);
+
+    // Check no frame removed
+    ASSERT_FALSE(F1->isRemoving());
+
+    // FRAME 4 ----------------------------------------------------------
+    auto F4 = P->emplaceFrame("PO", 3,    KEY, state,  TimeStamp(4));
+    P->keyFrameCallback(F4, nullptr, 0);
+
+    // absolute factor
+    auto C4 = CaptureBase::emplace<CaptureVoid>(F4, TimeStamp(4), nullptr);
+    auto f4 = FeatureBase::emplace<FeatureBase>(C4, "absolute", state, cov);
+    auto c4 = FactorBase::emplace<FactorPose3d>(f4, f4, nullptr, false);
+    // displacement
+    auto C34 = CaptureBase::emplace<CaptureVoid>(F4, TimeStamp(4), nullptr);
+    auto f34 = FeatureBase::emplace<FeatureBase>(C34, "odom", zero_disp, cov);
+    auto c34 = FactorBase::emplace<FactorOdom3d>(f34, f34, F3, nullptr, false);
+
+    // Checks
+    ASSERT_TRUE(F1->isRemoving());
+    ASSERT_TRUE(c12->isRemoving());
+    ASSERT_FALSE(C12->isRemoving()); //Not virally removed
+    ASSERT_FALSE(f12->isRemoving()); //Not virally removed
+    ASSERT_FALSE(F2->isFixed()); //Not fixed
+
+    // FRAME 5 ----------------------------------------------------------
+    auto F5 = P->emplaceFrame("PO", 3,    KEY, state,  TimeStamp(5));
+    P->keyFrameCallback(F5, nullptr, 0);
+
+    // absolute factor
+    auto C5 = CaptureBase::emplace<CaptureVoid>(F5, TimeStamp(5), nullptr);
+    auto f5 = FeatureBase::emplace<FeatureBase>(C5, "absolute", state, cov);
+    auto c5 = FactorBase::emplace<FactorPose3d>(f5, f5, nullptr, false);
+    // displacement
+    auto C45 = CaptureBase::emplace<CaptureVoid>(F5, TimeStamp(5), nullptr);
+    auto f45 = FeatureBase::emplace<FeatureBase>(C45, "odom", zero_disp, cov);
+    auto c45 = FactorBase::emplace<FactorOdom3d>(f45, f45, F4, nullptr, false);
+
+    // Checks
+    ASSERT_TRUE(F1->isRemoving());
+    ASSERT_TRUE(c12->isRemoving());
+    ASSERT_TRUE(C12->isRemoving());
+    ASSERT_TRUE(f12->isRemoving());
+    ASSERT_TRUE(F2->isRemoving());
+    ASSERT_TRUE(c2->isRemoving());
+    ASSERT_TRUE(C2->isRemoving());
+    ASSERT_TRUE(f2->isRemoving());
+    ASSERT_TRUE(c23->isRemoving());
+    ASSERT_FALSE(C23->isRemoving()); //Not virally removed
+    ASSERT_FALSE(f23->isRemoving()); //Not virally removed
+    ASSERT_FALSE(F3->isFixed()); //Not fixed
+}
+
+int main(int argc, char **argv)
+{
+  testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/test/yaml/params_tree_manager1.yaml b/test/yaml/params_tree_manager1.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..25e8ac8a4417ffec910fee4cac96669a00ebdc4f
--- /dev/null
+++ b/test/yaml/params_tree_manager1.yaml
@@ -0,0 +1,41 @@
+config:
+  problem:
+    frame_structure: "POV"
+    dimension: 3
+    prior:
+      state: [0,0,0,0,0,0,1,0,0,0]
+      cov: [[9,9],.1,0,0,0,0,0,0,0,0, 0,.1,0,0,0,0,0,0,0, 0,0,.1,0,0,0,0,0,0, 0,0,0,.1,0,0,0,0,0, 0,0,0,0,.1,0,0,0,0, 0,0,0,0,0,.1,0,0,0, 0,0,0,0,0,0,.1,0,0, 0,0,0,0,0,0,0,.1,0, 0,0,0,0,0,0,0,0,.1]
+      time_tolerance: 0.1
+      timestamp: 0
+    tree_manager:
+      type: "TreeManagerDummy"
+      toy_param: 0
+  sensors: 
+    -
+      type: "SensorOdom3d"
+      name: "odom"
+      plugin: "core"
+      k_disp_to_disp: 0.1
+      k_disp_to_rot: 0.1
+      k_rot_to_rot: 0.1 
+      min_disp_var: 0.1 
+      min_rot_var: 0.1
+      extrinsic:
+        pose: [1,2,3,0,0,0,1]
+  processors:
+    -
+      type: "ProcessorOdom3d"
+      name: "my_proc_odom3d"
+      sensor_name: "odom"
+      plugin: "core"
+      apply_loss_function: false
+      time_tolerance:         0.01  # seconds
+      keyframe_vote:
+        voting_active:        false
+        voting_aux_active:    false
+        max_time_span:          0.2   # seconds
+        max_buff_length:        10    # motion deltas
+        dist_traveled:          0.5   # meters
+        angle_turned:           0.1   # radians (1 rad approx 57 deg, approx 60 deg)
+      
+      unmeasured_perturbation_std: 0.00111
\ No newline at end of file
diff --git a/test/yaml/params_tree_manager2.yaml b/test/yaml/params_tree_manager2.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..913f5875bfd09750e024fcfeab910ff45d6058ee
--- /dev/null
+++ b/test/yaml/params_tree_manager2.yaml
@@ -0,0 +1,40 @@
+config:
+  problem:
+    frame_structure: "POV"
+    dimension: 3
+    prior:
+      state: [0,0,0,0,0,0,1,0,0,0]
+      cov: [[9,9],.1,0,0,0,0,0,0,0,0, 0,.1,0,0,0,0,0,0,0, 0,0,.1,0,0,0,0,0,0, 0,0,0,.1,0,0,0,0,0, 0,0,0,0,.1,0,0,0,0, 0,0,0,0,0,.1,0,0,0, 0,0,0,0,0,0,.1,0,0, 0,0,0,0,0,0,0,.1,0, 0,0,0,0,0,0,0,0,.1]
+      time_tolerance: 0.1
+      timestamp: 0
+    tree_manager: 
+      type: "None"
+  sensors: 
+    -
+      type: "SensorOdom3d"
+      name: "odom"
+      plugin: "core"
+      k_disp_to_disp: 0.1
+      k_disp_to_rot: 0.1
+      k_rot_to_rot: 0.1 
+      min_disp_var: 0.1 
+      min_rot_var: 0.1
+      extrinsic:
+        pose: [1,2,3,0,0,0,1]
+  processors:
+    -
+      type: "ProcessorOdom3d"
+      name: "my_proc_odom3d"
+      sensor_name: "odom"
+      plugin: "core"
+      apply_loss_function: false
+      time_tolerance:         0.01  # seconds
+      keyframe_vote:
+        voting_active:        false
+        voting_aux_active:    false
+        max_time_span:          0.2   # seconds
+        max_buff_length:        10    # motion deltas
+        dist_traveled:          0.5   # meters
+        angle_turned:           0.1   # radians (1 rad approx 57 deg, approx 60 deg)
+      
+      unmeasured_perturbation_std: 0.00111
\ No newline at end of file
diff --git a/test/yaml/params_tree_manager_sliding_window1.yaml b/test/yaml/params_tree_manager_sliding_window1.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..5cbb9e5a787b4ad2e70f9cf7f283ab1747e1279b
--- /dev/null
+++ b/test/yaml/params_tree_manager_sliding_window1.yaml
@@ -0,0 +1,43 @@
+config:
+  problem:
+    frame_structure: "PO"
+    dimension: 3
+    prior:
+      state: [0,0,0,0,0,0,1]
+      cov: [[6,6],.1,0,0,0,0,0, 0,.1,0,0,0,0, 0,0,.1,0,0,0, 0,0,0,.1,0,0, 0,0,0,0,.1,0, 0,0,0,0,0,.1]
+      time_tolerance: 0.1
+      timestamp: 0
+    tree_manager:
+      type: "TreeManagerSlidingWindow"
+      n_key_frames: 3
+      fix_first_key_frame: true
+      viral_remove_empty_parent: true
+  sensors: 
+    -
+      type: "SensorOdom3d"
+      name: "odom"
+      plugin: "core"
+      k_disp_to_disp: 0.1
+      k_disp_to_rot: 0.1
+      k_rot_to_rot: 0.1 
+      min_disp_var: 0.1 
+      min_rot_var: 0.1
+      extrinsic:
+        pose: [1,2,3,0,0,0,1]
+  processors:
+    -
+      type: "ProcessorOdom3d"
+      name: "my_proc_odom3d"
+      sensor_name: "odom"
+      plugin: "core"
+      apply_loss_function: false
+      time_tolerance:         0.01  # seconds
+      keyframe_vote:
+        voting_active:        false
+        voting_aux_active:    false
+        max_time_span:          0.2   # seconds
+        max_buff_length:        10    # motion deltas
+        dist_traveled:          0.5   # meters
+        angle_turned:           0.1   # radians (1 rad approx 57 deg, approx 60 deg)
+      
+      unmeasured_perturbation_std: 0.00111
\ No newline at end of file
diff --git a/test/yaml/params_tree_manager_sliding_window2.yaml b/test/yaml/params_tree_manager_sliding_window2.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..01f41eea97c7cca943d4aa12a143736668c2673f
--- /dev/null
+++ b/test/yaml/params_tree_manager_sliding_window2.yaml
@@ -0,0 +1,43 @@
+config:
+  problem:
+    frame_structure: "PO"
+    dimension: 3
+    prior:
+      state: [0,0,0,0,0,0,1]
+      cov: [[6,6],.1,0,0,0,0,0, 0,.1,0,0,0,0, 0,0,.1,0,0,0, 0,0,0,.1,0,0, 0,0,0,0,.1,0, 0,0,0,0,0,.1]
+      time_tolerance: 0.1
+      timestamp: 0
+    tree_manager:
+      type: "TreeManagerSlidingWindow"
+      n_key_frames: 3
+      fix_first_key_frame: false
+      viral_remove_empty_parent: false
+  sensors: 
+    -
+      type: "SensorOdom3d"
+      name: "odom"
+      plugin: "core"
+      k_disp_to_disp: 0.1
+      k_disp_to_rot: 0.1
+      k_rot_to_rot: 0.1 
+      min_disp_var: 0.1 
+      min_rot_var: 0.1
+      extrinsic:
+        pose: [1,2,3,0,0,0,1]
+  processors:
+    -
+      type: "ProcessorOdom3d"
+      name: "my_proc_odom3d"
+      sensor_name: "odom"
+      plugin: "core"
+      apply_loss_function: false
+      time_tolerance:         0.01  # seconds
+      keyframe_vote:
+        voting_active:        false
+        voting_aux_active:    false
+        max_time_span:          0.2   # seconds
+        max_buff_length:        10    # motion deltas
+        dist_traveled:          0.5   # meters
+        angle_turned:           0.1   # radians (1 rad approx 57 deg, approx 60 deg)
+      
+      unmeasured_perturbation_std: 0.00111
\ No newline at end of file