diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 88b7ee732f0294ece7d258692e599e6483ee5b5a..d492ed52fa980e3be84bb34201142fd51f047a57 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -35,6 +35,7 @@ stages:
   - if [ -d wolf ]; then
   -   echo "directory wolf exists"
   -   cd wolf
+  -   git checkout devel
   -   git pull
   -   git checkout $WOLF_CORE_BRANCH
   - else
@@ -344,3 +345,96 @@ build_and_test_csm_falko:bionic:
     - *install_laserscanutils_definition
   script:
     - *build_and_test_definition
+
+############ UBUNTU 20.04 TESTS ############
+build_and_test_none:focal:
+  stage: none
+  image: labrobotica/wolf_deps:20.04
+  cache:
+    - key: wolf-focal
+      paths:
+      - ci_deps/wolf/
+    - key: laserscanutils-focal
+      paths:
+      - ci_deps/laser_scan_utils/
+  except:
+    - master
+  before_script:
+    - *preliminaries_definition
+    - *install_wolf_definition
+    - *install_laserscanutils_definition
+  script:
+    - *build_and_test_definition
+
+build_and_test_csm:focal:
+  stage: csm
+  image: labrobotica/wolf_deps:20.04
+  cache:
+    - key: wolf-focal
+      paths:
+      - ci_deps/wolf/
+    - key: laserscanutils-focal
+      paths:
+      - ci_deps/laser_scan_utils/
+    - key: csm-focal
+      paths:
+      - ci_deps/csm/
+  except:
+    - master
+  before_script:
+    - *preliminaries_definition
+    - *install_wolf_definition
+    - *install_csm_definition
+    - *install_laserscanutils_definition
+  script:
+    - *build_and_test_definition
+
+build_and_test_falko:focal:
+  stage: falko
+  image: labrobotica/wolf_deps:20.04
+  cache:
+    - key: wolf-focal
+      paths:
+      - ci_deps/wolf/
+    - key: laserscanutils-focal
+      paths:
+      - ci_deps/laser_scan_utils/
+    - key: falko-focal
+      paths:
+      - ci_deps/falkolib/
+  except:
+    - master
+  before_script:
+    - *preliminaries_definition
+    - *install_wolf_definition
+    - *install_falko_definition
+    - *install_laserscanutils_definition
+  script:
+    - *build_and_test_definition
+    
+build_and_test_csm_falko:focal:
+  stage: csm_falko
+  image: labrobotica/wolf_deps:20.04
+  cache:
+    - key: wolf-focal
+      paths:
+      - ci_deps/wolf/
+    - key: laserscanutils-focal
+      paths:
+      - ci_deps/laser_scan_utils/
+    - key: csm-focal
+      paths:
+      - ci_deps/csm/
+    - key: falko-focal
+      paths:
+      - ci_deps/falkolib/
+  except:
+    - master
+  before_script:
+    - *preliminaries_definition
+    - *install_wolf_definition
+    - *install_falko_definition
+    - *install_csm_definition
+    - *install_laserscanutils_definition
+  script:
+    - *build_and_test_definition
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 846ef85bd5640f895a8e797e32fdff45d4e035f9..b16e4964e99fd5092e512860d3edca8cfa5bc4ef 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -39,8 +39,8 @@ endif()
 
 if(UNIX)
   # GCC is not strict enough by default, so enable most of the warnings.
-  set(CMAKE_CXX_FLAGS
-    "${CMAKE_CXX_FLAGS} -Werror=all -Werror=extra -Wno-unknown-pragmas -Wno-sign-compare -Wno-unused-parameter -Wno-missing-field-initializers")
+   set(CMAKE_CXX_FLAGS
+     "${CMAKE_CXX_FLAGS} -Werror=all -Werror=extra -Wno-unknown-pragmas -Wno-sign-compare -Wno-unused-parameter -Wno-missing-field-initializers")
 endif(UNIX)
 
 
@@ -53,7 +53,7 @@ IF(NOT BUILD_DEMOS)
 ENDIF(NOT BUILD_DEMOS)
 
 IF(NOT BUILD_DOC)
-  OPTION(BUILD_DOC "Build Documentation" OFF)
+  OPTION(BUILD_DOC "Build Documentation" ON)
 ENDIF(NOT BUILD_DOC)
 
 
@@ -93,6 +93,7 @@ ENDIF(BUILD_EXAMPLES OR BUILD_TESTS)
 FIND_PACKAGE(wolfcore REQUIRED)
 FIND_PACKAGE(laser_scan_utils REQUIRED)
 FIND_PACKAGE(csm QUIET)
+FIND_PACKAGE(falkolib QUIET)
 
 # Define the directory where will be the configured config.h
 SET(WOLF_CONFIG_DIR ${PROJECT_BINARY_DIR}/conf/${PROJECT_NAME}/internal)
@@ -173,9 +174,38 @@ SET(SRCS_STATE_BLOCK
 SET(SRCS_YAML
   src/yaml/sensor_laser_2d_yaml.cpp
   )
-  
-#OPTIONALS
+
+#OPTIONAL (falko)
+if (falkolib_FOUND)
+  message("Found Falkolib. Compiling some extra classes.")
+  SET(HDRS_PROCESSOR ${HDRS_PROCESSOR}
+    include/laser/processor/processor_loop_closure_falko.h
+    )
+    #OPTIONAL (falko & CSM)
+    if (csm_FOUND)
+      SET(HDRS_PROCESSOR ${HDRS_PROCESSOR}
+        include/laser/processor/processor_loop_closure_falko_icp.h
+        )
+      SET(SRCS_PROCESSOR ${SRCS_PROCESSOR}
+        src/processor/processor_loop_closure_falko_icp.cpp
+        )
+
+    endif()
+  SET(HDRS_FEATURE ${HDRS_FEATURE}
+    include/laser/feature/feature_scene_falko.h
+    )
+  SET(SRCS_FEATURE ${SRCS_FEATURE}
+    src/feature/feature_scene_falko.cpp
+    )
+
+  SET(SRCS_PROCESSOR ${SRCS_PROCESSOR}
+    src/processor/processor_loop_closure_falko.cpp
+    )
+endif()
+
+#OPTIONAL (CSM)
 if(csm_FOUND)
+  message("Found CSM. Compiling some extra classes.")
   SET(HDRS_PROCESSOR ${HDRS_PROCESSOR}
       include/laser/processor/processor_loop_closure_icp.h
       include/laser/processor/processor_odom_icp.h
@@ -198,6 +228,7 @@ endif(csm_FOUND)
 # create the shared library
 ADD_LIBRARY(${PLUGIN_NAME}
   SHARED
+  ${SRCS_MATH}
   ${SRCS_CAPTURE}
   ${SRCS_FEATURE}
   ${SRCS_LANDMARK}
@@ -209,20 +240,23 @@ ADD_LIBRARY(${PLUGIN_NAME}
   
 # Set compiler options
 # ====================
-if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+IF (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
   message(STATUS "Using C++ compiler clang")
   target_compile_options(${PLUGIN_NAME} PRIVATE -Winconsistent-missing-override)
   # using Clang
-elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ELSEIF (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
   message(STATUS "Using C++ compiler gnu")
   target_compile_options(${PLUGIN_NAME} PRIVATE -Wsuggest-override)
   # using GCC
-endif()
+ENDIF()
 
 #Link the created libraries
 #===============EXAMPLE=========================
 TARGET_LINK_LIBRARIES(${PLUGIN_NAME} ${wolfcore_LIBRARIES})
 TARGET_LINK_LIBRARIES(${PLUGIN_NAME} ${laser_scan_utils_LIBRARY})
+IF (falkolib_FOUND)
+	TARGET_LINK_LIBRARIES(${PLUGIN_NAME} ${wolfcore_LIBRARIES} ${laser_scan_utils_LIBRARY} ${falkolib_LIBRARY})
+ENDIF(falkolib_FOUND)
 
 #Build tests
 #===============EXAMPLE=========================
diff --git a/include/laser/feature/feature_scene_falko.h b/include/laser/feature/feature_scene_falko.h
new file mode 100644
index 0000000000000000000000000000000000000000..6cd1b5fb232acaf627fe37eec4059cefceb19d15
--- /dev/null
+++ b/include/laser/feature/feature_scene_falko.h
@@ -0,0 +1,77 @@
+//--------LICENSE_START--------
+//
+// Copyright (C) 2020,2021 Institut de Robòtica i Informàtica Industrial, CSIC-UPC.
+// Authors: Joan Solà Ortega (jsola@iri.upc.edu)
+// All rights reserved.
+//
+// This file is part of WOLF
+// WOLF is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+//--------LICENSE_END--------
+#ifndef FEATURE_SCENE_FALKO_H_
+#define FEATURE_SCENE_FALKO_H_
+
+// Wolf includes
+#include "core/common/wolf.h"
+#include "core/feature/feature_base.h"
+#include "laser_scan_utils/scene_falko.h"
+
+// std includes
+
+namespace wolf {
+
+template <typename D> class FeatureSceneFalko : public FeatureBase
+{
+  public:
+    FeatureSceneFalko(const std::shared_ptr<laserscanutils::SceneFalko<D>> _falko_scene)
+        : FeatureBase("FeatureSceneFalko", Eigen::VectorXd::Zero(1), Eigen::MatrixXd::Ones(1, 1))
+    {
+        scene_ = _falko_scene;
+    }
+
+    ~FeatureSceneFalko() override{};
+
+    std::shared_ptr<laserscanutils::SceneFalko<D>> getScene() { return scene_; }
+
+  private:
+    std::shared_ptr<laserscanutils::SceneFalko<D>> scene_;
+};
+
+WOLF_PTR_TYPEDEFS(FeatureSceneFalkoBsc);
+
+class FeatureSceneFalkoBsc : public FeatureSceneFalko<laserscanutils::bsc>
+{
+  public:
+    FeatureSceneFalkoBsc(const std::shared_ptr<laserscanutils::SceneFalko<laserscanutils::bsc>> _falko_scene)
+        : FeatureSceneFalko(_falko_scene)
+    {
+    }
+    ~FeatureSceneFalkoBsc();
+};
+
+WOLF_PTR_TYPEDEFS(FeatureSceneFalkoCgh);
+
+class FeatureSceneFalkoCgh : public FeatureSceneFalko<laserscanutils::cgh>
+{
+  public:
+    FeatureSceneFalkoCgh(const std::shared_ptr<laserscanutils::SceneFalko<laserscanutils::cgh>> _falko_scene)
+        : FeatureSceneFalko(_falko_scene)
+    {
+    }
+    ~FeatureSceneFalkoCgh() override{};
+};
+
+} // namespace wolf
+
+#endif
diff --git a/include/laser/processor/processor_loop_closure_falko.h b/include/laser/processor/processor_loop_closure_falko.h
new file mode 100644
index 0000000000000000000000000000000000000000..f7f9d6085d7e1b3ec493ad1ee79b43502e6a6cfb
--- /dev/null
+++ b/include/laser/processor/processor_loop_closure_falko.h
@@ -0,0 +1,677 @@
+//--------LICENSE_START--------
+//
+// Copyright (C) 2020,2021 Institut de Robòtica i Informàtica Industrial, CSIC-UPC.
+// Authors: Joan Solà Ortega (jsola@iri.upc.edu)
+// All rights reserved.
+//
+// This file is part of WOLF
+// WOLF is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+//--------LICENSE_END--------
+#ifndef PROCESSOR_LOOP_CLOSURE_FALKO_H_
+#define PROCESSOR_LOOP_CLOSURE_FALKO_H_
+
+#include <iostream>
+#include <fstream>
+
+/**************************
+ *      WOLF includes     *
+ **************************/
+#include "core/common/wolf.h"
+#include "core/processor/processor_loop_closure.h"
+#include "core/factor/factor_relative_pose_2d_with_extrinsics.h"
+#include "core/utils/graph_search.h"
+#include "laser/capture/capture_laser_2d.h"
+#include "laser/feature/feature_scene_falko.h"
+
+/**************************
+ *      laseScanUtils includes      *
+ **************************/
+#include "laser_scan_utils/loop_closure_falko.h"
+
+namespace wolf {
+
+WOLF_STRUCT_PTR_TYPEDEFS(MatchLoopClosureFalko);
+
+/** \brief Match between a capture and a capture
+ *
+ * Match between a capture and a capture (capture-capture correspondence)
+ *
+ */
+struct MatchLoopClosureFalko : public MatchLoopClosure
+{
+        laserscanutils::MatchLoopClosureScenePtr match_falko_;
+};
+
+WOLF_STRUCT_PTR_TYPEDEFS(ParamsProcessorLoopClosureFalko);
+
+/** \brief Struct class that store falkolib parameters and processorBase parameters
+ **/
+struct ParamsProcessorLoopClosureFalko : public ParamsProcessorLoopClosure
+{
+    int         min_keypoints;
+    double      score_th;
+    double      distance_between_ref_frm;
+    int         near_matches_th;
+    bool        logging;
+    double      th_kp_area;
+    double      th_kp_perimeter;
+    double      th_kp_maxd;
+    double      th_kp_eig;
+    double      th_scan_area;
+    double      th_scan_eig;
+    std::string logging_filepath;
+
+    laserscanutils::ParameterLoopClosureFalko param;
+
+    ParamsProcessorLoopClosureFalko() = default;
+    ParamsProcessorLoopClosureFalko(std::string _unique_name, const ParamsServer &_server)
+    : ParamsProcessorLoopClosure(_unique_name, _server)
+    {
+
+        // processor params
+        min_keypoints               = _server.getParam<int>(prefix          + _unique_name + "/min_keypoints");
+        score_th                    = _server.getParam<double>(prefix       + _unique_name + "/score_th");
+        distance_between_ref_frm    = _server.getParam<double>(prefix       + _unique_name + "/distance_between_ref_frm");
+        near_matches_th             = _server.getParam<int>(prefix          + _unique_name + "/near_matches_th");
+        th_kp_area                  = _server.getParam<double>(prefix       + _unique_name + "/th_kp_area");
+        th_kp_perimeter             = _server.getParam<double>(prefix       + _unique_name + "/th_kp_perimeter");
+        th_kp_maxd                  = _server.getParam<double>(prefix       + _unique_name + "/th_kp_maxd");
+        th_kp_eig                   = _server.getParam<double>(prefix       + _unique_name + "/th_kp_eig");
+        th_scan_area                = _server.getParam<double>(prefix       + _unique_name + "/th_scan_area");
+        th_scan_eig                 = _server.getParam<double>(prefix       + _unique_name + "/th_scan_eig");
+        logging                     = _server.getParam<bool>(prefix         + _unique_name + "/logging");
+        if (logging)
+            logging_filepath        = _server.getParam<std::string>(prefix  + _unique_name + "/logging_filepath");
+
+        // Falko
+        param.matcher_distance_th_  = _server.getParam<double>(prefix       + _unique_name + "/falko/matcher_distance_th");
+        param.use_descriptors_      = _server.getParam<bool>(prefix         + _unique_name + "/falko/use_descriptors");
+        param.circularSectorNumber_ = _server.getParam<int>(prefix          + _unique_name + "/falko/circularSectorNumber");
+        param.radialRingNumber_     = _server.getParam<int>(prefix          + _unique_name + "/falko/radialRingNumber");
+        param.matcher_ddesc_th_     = _server.getParam<double>(prefix       + _unique_name + "/falko/matcher_ddesc_th");
+        param.keypoints_number_th_  = _server.getParam<int>(prefix          + _unique_name + "/falko/keypoints_number_th");
+        // Keypoints extractor params
+        param.enable_subbeam_       = _server.getParam<bool>(prefix         + _unique_name + "/falko/enable_subbeam");
+        param.nms_radius_           = _server.getParam<double>(prefix       + _unique_name + "/falko/nms_radius");
+        param.neigh_b_              = _server.getParam<double>(prefix       + _unique_name + "/falko/neigh_b");
+        param.b_ratio_              = _server.getParam<double>(prefix       + _unique_name + "/falko/b_ratio");
+        // Aht matcher params
+        param.xRes_                 = _server.getParam<double>(prefix       + _unique_name + "/falko/xRes");
+        param.yRes_                 = _server.getParam<double>(prefix       + _unique_name + "/falko/yRes");
+        param.thetaRes_             = _server.getParam<double>(prefix       + _unique_name + "/falko/thetaRes");
+        param.xAbsMax_              = _server.getParam<double>(prefix       + _unique_name + "/falko/xAbsMax");
+        param.yAbsMax_              = _server.getParam<double>(prefix       + _unique_name + "/falko/yAbsMax");
+        param.thetaAbsMax_          = _server.getParam<double>(prefix       + _unique_name + "/falko/thetaAbsMax");
+    };
+    virtual ~ParamsProcessorLoopClosureFalko() = default;
+
+    std::string print() const override
+    {
+
+        return ParamsProcessorLoopClosure::print() + "\n"
+                + "min_keypoints: " + std::to_string(min_keypoints) + "\n"
+                + "score_th: " + std::to_string(score_th) + "\n"
+                + "distance_between_ref_frm: " + std::to_string(distance_between_ref_frm) + "\n"
+                + "near_matches_th: " + std::to_string(near_matches_th) + "\n"
+                + "th_kp_area: " + std::to_string(th_kp_area) + "\n"
+                + "th_kp_perimeter: " + std::to_string(th_kp_perimeter) + "\n"
+                + "th_kp_maxd: " + std::to_string(th_kp_maxd) + "\n"
+                + "th_kp_eig: " + std::to_string(th_kp_eig) + "\n"
+                + "th_scan_area: " + std::to_string(th_scan_area) + "\n"
+                + "th_scan_eig: " + std::to_string(th_scan_eig) + "\n"
+                + "logging: " + std::to_string(logging) + "\n"
+                + "logging_filepath: " + logging_filepath + "\n"
+
+                + "falko/matcher_distance_th_: " + std::to_string(param.matcher_distance_th_) + "\n"
+                + "falko/use_descriptors_: " + std::to_string(param.use_descriptors_) + "\n"
+                + "falko/circularSectorNumber_: " + std::to_string(param.circularSectorNumber_) + "\n"
+                + "falko/radialRingNumber_: " + std::to_string(param.radialRingNumber_) + "\n"
+                + "falko/matcher_ddesc_th_: " + std::to_string(param.matcher_ddesc_th_) + "\n"
+                + "falko/keypoints_number_th_: " + std::to_string(param.keypoints_number_th_) + "\n"
+
+                + "falko/enable_subbeam_: " + std::to_string(param.enable_subbeam_) + "\n"
+                + "falko/nms_radius_: " + std::to_string(param.nms_radius_) + "\n"
+                + "falko/neigh_b_: " + std::to_string(param.neigh_b_) + "\n"
+                + "falko/b_ratio_: " + std::to_string(param.b_ratio_) + "\n"
+
+                + "falko/xRes_: " + std::to_string(param.xRes_) + "\n"
+                + "falko/yRes_: " + std::to_string(param.yRes_) + "\n"
+                + "falko/thetaRes_: " + std::to_string(param.thetaRes_) + "\n"
+                + "falko/xAbsMax_: " + std::to_string(param.xAbsMax_) + "\n"
+                + "falko/yAbsMax_: " + std::to_string(param.yAbsMax_) + "\n"
+                + "falko/thetaAbsMax_: " + std::to_string(param.thetaAbsMax_) + "\n";
+    };
+};
+
+/** \brief A class to implement a loop closure processor using loop closure detection from falko library
+ * The Laser data is provided by the sensor owning this processor.
+ *
+ * It extracts Features that contain laserscanutils::SceneFalko. The scene contain keypoints and descriptors
+ *
+ * It manages the capture and frame links in the inherited class ProcessorLoopClosure.
+ *
+ * It matches a target falko feature against a list of reference falko features.
+ *
+ * The reference features are found from a search of the previous captures
+ *
+ * The loop closures are not validated with an ICP
+ *
+ * Different types of descriptors and matchers can be used and are specified as template parameters.
+ * \tparam D Descriptor type. <bsc> or <cgh>
+ * \tparam Extr descriptor extractor type <bscExtractor> or <cghExtractor>
+ * \tparam L Loop closure Type <LoopClosureFalkoAht> or <LoopClosureFalkoNn>
+ * \param _param_falko parameter struct with falko lib parameters
+ **/
+template <typename D, typename Extr, template <typename, typename> typename L>
+class ProcessorLoopClosureFalko : public ProcessorLoopClosure
+{
+    public:
+        ProcessorLoopClosureFalko(ParamsProcessorLoopClosureFalkoPtr _params_falko)
+            : ProcessorLoopClosure("ProcessorLoopClosureFalko", 2, _params_falko)
+            , params_falko_(_params_falko)
+            , loop_closure_(std::make_shared<L<D, Extr>>(params_falko_->param))
+        {
+            if (!params_falko_->logging)
+                return;
+
+            std::ostringstream ss, ss1, ss2, ss3, ss4, ss5, ss6, ss7, ss8, ss9, ss10, ss11, ss12;
+            ss << std::setw(2) << std::setfill('0') << params_falko_->score_th;
+            std::string score_th(ss.str());
+
+            ss1 << std::setw(4) << std::setfill('0') << params_falko_->param.matcher_distance_th_;
+            std::string matcher_distance_th(ss1.str());
+
+            ss2 << std::setw(4) << std::setfill('0') << params_falko_->param.matcher_ddesc_th_;
+            std::string matcher_ddesc_th(ss2.str());
+
+            ss3 << std::setw(4) << std::setfill('0') << params_falko_->param.enable_subbeam_;
+            std::string enable_subbeam(ss3.str());
+
+            ss4 << std::setw(4) << std::setfill('0') << params_falko_->param.nms_radius_;
+            std::string nms_radius(ss4.str());
+
+            ss5 << std::setw(4) << std::setfill('0') << params_falko_->param.neigh_b_;
+            std::string neigh_b(ss5.str());
+
+            ss6 << std::setw(4) << std::setfill('0') << params_falko_->param.b_ratio_;
+            std::string b_ratio(ss6.str());
+
+            ss7 << std::setw(3) << std::setfill('0') << params_falko_->th_kp_area;
+            std::string th_kp_area(ss7.str());
+
+            ss8 << std::setw(3) << std::setfill('0') << params_falko_->th_kp_perimeter;
+            std::string th_kp_perimeter(ss8.str());
+
+            ss9 << std::setw(3) << std::setfill('0') << params_falko_->th_kp_maxd;
+            std::string th_kp_maxd(ss9.str());
+
+            ss10 << std::setw(3) << std::setfill('0') << params_falko_->th_kp_eig;
+            std::string th_kp_eig(ss10.str());
+
+            ss11 << std::setw(3) << std::setfill('0') << params_falko_->th_scan_area;
+            std::string th_scan_area(ss11.str());
+
+            ss12 << std::setw(3) << std::setfill('0') << params_falko_->th_scan_eig;
+            std::string th_scan_eig(ss12.str());
+
+            std::string filename = params_falko_->logging_filepath + "/log" +
+                                   "_use_descriptors_" + std::to_string(params_falko_->param.use_descriptors_) +
+                                   "_score_th_" + score_th +
+                                   "_th_kp_area_" + th_kp_area +
+                                   "_th_kp_perimeter_" + th_kp_perimeter +
+                                   "_th_kp_maxd_" + th_kp_maxd +
+                                   "_th_kp_eig_" + th_kp_eig +
+                                   "_th_scan_area_" + th_scan_area +
+                                   "_th_scan_eig_" + th_scan_eig +
+                                   "_matcher_distance_th_" + matcher_distance_th +
+                                   "matcher_ddesc_th_" + matcher_ddesc_th +
+                                   "_enable_subbeam_" + enable_subbeam +
+                                   "_nms_radius_" + nms_radius +
+                                   "_neigh_b_" + neigh_b +
+                                   "_b_ratio_" + b_ratio + ".dat";
+
+            // change ~ with HOME using environment variable
+            if (filename.at(0) == '~')
+                filename = std::string(std::getenv("HOME")) + filename.substr(1);
+
+            outdata.open(filename, std::ofstream::out); // opens the file
+            if (outdata.fail())
+                WOLF_ERROR("ProcessorLoopClosureFalko: logging file '", filename, "' could not be created. \nError: ", strerror(errno));
+
+            init_outData_ = 0;
+        };
+
+        ~ProcessorLoopClosureFalko() { outdata.close(); };
+
+        std::list<MatchLoopClosurePtr> match_list_;
+
+    protected:
+        /** \brief Function not implemented
+         **/
+        bool voteFindLoopClosures(CaptureBasePtr cap) override { return true; };
+
+        /** \brief Function not implemented
+         **/
+        bool validateLoopClosure(MatchLoopClosurePtr match) override { return true; };
+
+        /** \brief It emplace factors between frames that its scenes are a match
+         * \param match structure that contains scenes and capture pointers that are a match
+         **/
+        void emplaceFactors(MatchLoopClosurePtr match) override
+        {
+            match_list_.push_back(match);
+            auto falko_match = std::static_pointer_cast<MatchLoopClosureFalko>(match);
+            auto ftr         = FeatureBase::emplace<FeatureBase>(match->capture_reference, "FeatureTransformFalko",
+                                                                 falko_match->match_falko_->transform_vector,
+                                                                 Eigen::MatrixXd::Identity(3, 3));
+            FactorBase::emplace<FactorRelativePose2dWithExtrinsics>(ftr, ftr, match->capture_target->getFrame(),
+                                                                    shared_from_this(), params_->apply_loss_function,
+                                                                    TOP_LOOP);
+        };
+
+        /** \brief Extracts a falko scene from a laser scan and emplaces it as a scen feature
+         * \param cap laser capture with a laser scan
+         **/
+        void emplaceFeatures(CaptureBasePtr cap) override
+        {
+            auto start_extract_scene = std::chrono::high_resolution_clock::now();
+
+            auto cap_laser = std::dynamic_pointer_cast<CaptureLaser2d>(cap);
+
+            assert(cap_laser && "ProcessorLoopClosureFalko::emplaceFeatures called with a capture of wrong type.");
+            // WOLF_INFO(params_falko_->print());
+            auto scene_falko = std::static_pointer_cast<laserscanutils::SceneFalko<D>>(loop_closure_->extractScene(
+                    cap_laser->getScan(), std::static_pointer_cast<SensorLaser2d>(getSensor())->getScanParams()));
+
+            // Falko implementation
+            FeatureBase::emplace<FeatureSceneFalko<D>>(cap_laser, scene_falko);
+
+            WOLF_INFO("empalceFeatures: number of keypoints ", scene_falko->keypoints_list_.size())
+
+            auto duration_ms = std::chrono::duration_cast<std::chrono::microseconds>(
+                    std::chrono::high_resolution_clock::now() - start_extract_scene);
+
+            duration_extract_scene = duration_ms;
+        };
+
+        /** \brief It matches a target falko feature against a list of reference falko features.
+         * The reference features are found from a search of the previous captures
+         * \param cap laser capture with a laser scan and a falko feature
+         **/
+        std::map<double, MatchLoopClosurePtr> findLoopClosures(CaptureBasePtr _capture) override
+        {
+            auto start_find_loop = std::chrono::high_resolution_clock::now();
+
+            auto current_frame = _capture->getFrame();
+            assert(_capture->getFrame() && "ProcessorLoopClosureFalko::findLoopClosures capture with no frame.");
+            assert(_capture->getFrame()->getTrajectory() &&
+                   "ProcessorLoopClosureFalko::findLoopClosures capture with frame not in trajectory");
+
+            std::shared_ptr<laserscanutils::SceneFalko<D>> scene_falko_current;
+            // Find current falko scene
+            for (auto feat : _capture->getFeatureList())
+                if (feat->getType() == "FeatureSceneFalko")
+                {
+                    auto feat_falko     = std::static_pointer_cast<FeatureSceneFalko<D>>(feat);
+                    scene_falko_current = feat_falko->getScene();
+                }
+
+            // Find reference scenes
+            std::map<laserscanutils::sceneBasePtr, CaptureBasePtr> map_scene_cap_ref;
+            std::list<laserscanutils::sceneBasePtr>                list_scene_reference;
+            auto                                                   old_frame = _capture->getFrame()->getPreviousFrame();
+
+            const double&   target_kp_area      = scene_falko_current->area_;
+            const double&   target_scan_area    = scene_falko_current->area_scan_;
+            const double&   target_kp_perimeter = scene_falko_current->perimeter_;
+            const double&   target_kp_maxd      = scene_falko_current->max_distance_;
+            const auto&     target_eig_kp       = scene_falko_current->eigenvalues_kp_;
+            const auto&     target_eig_scan     = scene_falko_current->eigenvalues_scan_;
+            GraphSearch graph_search;
+
+            int num_ref_scenes = 0;
+            int acum_score     = 0;
+            while (old_frame)
+            {
+                for (auto cap : old_frame->getCaptureList())
+                {
+                    for (auto feat : cap->getFeatureList())
+                        if (feat->getType() == "FeatureSceneFalko")
+                        {
+
+                            num_ref_scenes += 1;
+                            auto   feat_falko = std::static_pointer_cast<FeatureSceneFalko<D>>(feat);
+                            double a_kp       = feat_falko->getScene()->area_;
+                            double a_min_kp   = target_kp_area * params_falko_->th_kp_area;
+                            double a_max_kp   = target_kp_area * (1 + (1 - params_falko_->th_kp_area));
+
+                            double p_kp  = feat_falko->getScene()->perimeter_;
+                            double p_min = target_kp_perimeter * params_falko_->th_kp_perimeter;
+                            double p_max = target_kp_perimeter * (1 + (1 - params_falko_->th_kp_perimeter));
+
+                            double maxd_kp     = feat_falko->getScene()->max_distance_;
+                            double maxd_min_kp = target_kp_maxd * params_falko_->th_kp_maxd;
+                            double maxd_max_kp = target_kp_maxd * (1 + (1 - params_falko_->th_kp_maxd));
+
+                            double a_scan     = feat_falko->getScene()->area_scan_;
+                            double a_min_scan = target_scan_area * params_falko_->th_scan_area;
+                            double a_max_scan = target_scan_area * (1 + (1 - params_falko_->th_scan_area));
+
+                            auto   eig1_kp     = feat_falko->getScene()->eigenvalues_kp_[0];
+                            double eig1_min_kp = target_eig_kp[0] * params_falko_->th_kp_eig;
+                            double eig1_max_kp = target_eig_kp[0] * (1 + (1 - params_falko_->th_kp_eig));
+
+                            auto   eig2_kp     = feat_falko->getScene()->eigenvalues_kp_[1];
+                            double eig2_min_kp = target_eig_kp[1] * params_falko_->th_kp_eig;
+                            double eig2_max_kp = target_eig_kp[1] * (1 + (1 - params_falko_->th_kp_eig));
+
+                            auto   eig1_scan     = feat_falko->getScene()->eigenvalues_scan_[0];
+                            double eig1_min_scan = target_eig_scan[0] * params_falko_->th_scan_eig;
+                            double eig1_max_scan = target_eig_scan[0] * (1 + (1 - params_falko_->th_scan_eig));
+
+                            auto   eig2_scan     = feat_falko->getScene()->eigenvalues_scan_[1];
+                            double eig2_min_scan = target_eig_scan[1] * params_falko_->th_scan_eig;
+                            double eig2_max_scan = target_eig_scan[1] * (1 + (1 - params_falko_->th_scan_eig));
+
+                            if (feat_falko->getScene()->keypoints_list_.size() <
+                                    params_falko_->min_keypoints) // min KEYPOINTS
+                                            continue;
+                            if (((a_min_kp > a_kp) or (a_max_kp < params_falko_->th_kp_area)) and
+                                    a_kp != 0) // Area KEYPOINTS restriction
+                                continue;
+                            if (((p_min > p_kp) or (p_max < p_kp)) and
+                                    params_falko_->th_kp_perimeter != 0) //  Perimeter KEYPOINTS restriction
+                                continue;
+                            if (((maxd_min_kp > maxd_kp) or (maxd_max_kp < maxd_kp)) and
+                                    params_falko_->th_kp_maxd != 0) // max_dist KEYPOINTS restriction
+                                continue;
+                            if (((a_min_scan > a_scan) or (a_max_scan < a_scan)) and
+                                    params_falko_->th_scan_area != 0) // Area SCAN restriction
+                                continue;
+                            if (((eig1_min_kp > eig1_kp) or (eig1_max_kp < eig1_kp)) and
+                                    params_falko_->th_kp_eig != 0) // eigenvalue 1 KEYPOINTS restriction
+                                continue;
+                            if (((eig2_min_kp > eig2_kp) or (eig2_max_kp < eig2_kp)) and
+                                    params_falko_->th_kp_eig != 0) // eigenvalue 2 KEYPOINTS restriction
+                                continue;
+                            if (((eig1_min_scan > eig1_scan) or (eig1_max_scan < eig1_scan)) and
+                                    params_falko_->th_scan_eig != 0) // eigenvalue 1 SCAN restriction
+                                continue;
+                            if (((eig2_min_scan > eig2_scan) or (eig2_max_scan < eig2_scan)) and
+                                    params_falko_->th_scan_eig != 0) // eigenvalue 2 SCAN restriction
+                                continue;
+
+                            auto shortest_path = graph_search.computeShortestPath(old_frame, current_frame, 10);
+
+                            map_scene_cap_ref.emplace(feat_falko->getScene(), cap);
+                            list_scene_reference.push_back(feat_falko->getScene());
+                        }
+                }
+                old_frame = old_frame->getPreviousFrame();
+            }
+
+            WOLF_INFO("findLoopClosures: number of ref Scene ", list_scene_reference.size())
+            // find loop closure
+            std::map<double, laserscanutils::MatchLoopClosureScenePtr> match_lc_scene;
+
+            match_lc_scene = loop_closure_->findLoopClosure(list_scene_reference, scene_falko_current);
+            // fill MatchLoopClosurePtr list
+            std::map<double, MatchLoopClosurePtr> match_lc_map;
+            for (auto match_scenes : match_lc_scene)
+            {
+                if (match_scenes.first >= params_falko_->score_th)
+                {
+                    WOLF_INFO("loop closure candidate score : ", match_scenes.first)
+                                MatchLoopClosureFalkoPtr match_captures = std::make_shared<MatchLoopClosureFalko>();
+                    match_captures->capture_reference  = map_scene_cap_ref.at(match_scenes.second->scene_1);
+                    match_captures->capture_target     = _capture;
+                    match_captures->normalized_score       = match_scenes.first;
+                    match_captures->match_falko_            = match_scenes.second;
+                    while (match_lc_map.count(match_captures->normalized_score) != 0)
+                        match_captures->normalized_score +=
+                                (match_captures->normalized_score < 1.0 ? 1e-12 : -1e12);
+                    acum_score += match_captures->normalized_score;
+                    match_lc_map.emplace(match_captures->normalized_score, match_captures);
+
+                    // TODO: calcular consistency
+                }
+            }
+
+            WOLF_INFO("findLoopClosures: lc number of candidates : ", match_lc_map.size())
+
+            duration_find_loop = std::chrono::duration_cast<std::chrono::microseconds>(
+                    std::chrono::high_resolution_clock::now() - start_find_loop);
+
+            if (params_falko_->logging)
+                printOutData(list_scene_reference, num_ref_scenes, match_lc_map, scene_falko_current->keypoints_list_,
+                             acum_score);
+
+            if (params_falko_->near_matches_th == 1)
+            {
+                return match_lc_map;
+            }
+            // Check for robustness: more than one loop closure with nearby frames
+            std::map<double, MatchLoopClosurePtr> match_lc_map_robust;
+            // TODO: double scene_estimated_size = mean(keyoints.distance)
+            // distance_between_ref_frm_ =scene_estimated_size*factor; factor add to params
+            // near_matches_th = desapear
+            // Check angle
+            // Check in validate function: error max between transform and estimation -> consistency parameter in
+            // MatchLoopClosure if good consistency, not needed the other checks -> param for when consistency is good
+            // enough buscar papers per robustesa amb loop closures
+            for (auto match_capture_1 : match_lc_map)
+            {
+                bool consensus  = true;
+                auto position_1 = match_capture_1.second->capture_reference->getFrame()->getP()->getState();
+
+                auto frame_1 = match_capture_1.second->capture_reference->getFrame();
+                // Backwards search
+                auto prev_frame_1       = frame_1->getPreviousFrame();
+                int  match_prev_1_found = 0;
+                while (prev_frame_1)
+                {
+                    // si surtim de la distance deixem de buscar
+                    if ((position_1 - prev_frame_1->getP()->getState()).norm() >
+                    params_falko_->distance_between_ref_frm)
+                    {
+                        break;
+                    }
+                    // Busquem match amb el prev_frame_1
+                    for (auto match_capture_2 : match_lc_map)
+                    {
+                        // We look for a loop closure with the prev_frame_1
+                        if (match_capture_2.second->capture_reference->getFrame() == prev_frame_1)
+                        {
+                            match_prev_1_found += 1;
+                        }
+                    }
+                    prev_frame_1 = prev_frame_1->getPreviousFrame();
+                }
+
+                // Busqueda enrera
+                auto next_frame_1       = frame_1->getNextFrame();
+                int  match_next_1_found = 0;
+                while (next_frame_1)
+                {
+                    // si surtim de la distance deixem de buscar
+                    if ((position_1 - next_frame_1->getP()->getState()).norm() >
+                    params_falko_->distance_between_ref_frm)
+                    {
+                        break;
+                    }
+                    // Busquem match amb el next_frame_1
+                    for (auto match_capture_2 : match_lc_map)
+                    {
+                        if (match_capture_2.second->capture_target->getFrame() == prev_frame_1)
+                        {
+                            match_next_1_found += 1;
+                        }
+                    }
+                    next_frame_1 = next_frame_1->getNextFrame();
+                }
+
+                if (match_prev_1_found + match_next_1_found + 1 > params_falko_->near_matches_th)
+                {
+                    consensus = true;
+                }
+                else
+                {
+                    consensus = false;
+                }
+                if (consensus)
+                {
+                    match_lc_map_robust.insert(match_capture_1);
+                }
+            }
+
+            return match_lc_map_robust;
+        }
+
+        void printOutData(std::list<laserscanutils::sceneBasePtr> &list_scene_reference, int num_ref_scenes,
+                          std::map<double, MatchLoopClosurePtr> &match_lc_map, std::vector<falkolib::FALKO> &keypoints_list,
+                          int acum_score)
+        {
+            if (init_outData_ == 1)
+            {
+                outdata << std::to_string(num_ok_) << ";";
+                outdata << std::to_string(num_nok_) << ";";
+                if (num_ok_ > 0)
+                {
+                    outdata << std::to_string(duration_validation_ok.count() / num_ok_) << ";";
+                }
+                else
+                    outdata << std::to_string(0) << ";";
+
+                if (num_nok_ > 0)
+                {
+                    outdata << std::to_string(duration_validation_nok.count() / num_nok_) << ";" << std::endl;
+                }
+                else
+                    outdata << std::to_string(0) << ";" << std::endl;
+                num_ok_                 = 0;
+                num_nok_                = 0;
+                duration_validation_ok  = std::chrono::duration_values<std::chrono::microseconds>::zero();
+                duration_validation_nok = std::chrono::duration_values<std::chrono::microseconds>::zero();
+            }
+            else
+            {
+                num_ok_  = 0;
+                num_nok_ = 0;
+            }
+            init_outData_ = 1;
+            outdata << std::to_string(list_scene_reference.size()) << ";";
+            outdata << std::to_string(num_ref_scenes) << ";";
+            outdata << std::to_string(match_lc_map.size()) << ";";
+            outdata << std::to_string(keypoints_list.size()) << ";";
+            if (match_lc_map.size() > 0)
+            {
+                outdata << std::to_string(acum_score / match_lc_map.size()) << ";";
+            }
+            else
+            {
+                outdata << std::to_string(0) << ";";
+            }
+            outdata << std::to_string(duration_find_loop.count()) << ";";
+            outdata << std::to_string(duration_extract_scene.count()) << ";";
+        }
+
+        ParamsProcessorLoopClosureFalkoPtr params_falko_;
+
+        std::shared_ptr<L<D, Extr>>             loop_closure_;
+        std::ofstream                           outdata;
+        std::chrono::duration<long, std::micro> duration_find_loop;
+        std::chrono::duration<long, std::micro> duration_validation_ok;
+        std::chrono::duration<long, std::micro> duration_validation_nok;
+        std::chrono::duration<long, std::micro> duration_extract_scene;
+
+    public:
+        unsigned int getNStoredFrames() { return buffer_frame_.getContainer().size(); }
+        unsigned int getNStoredCaptures() { return buffer_capture_.getContainer().size(); }
+        int          num_ok_;
+        int          num_nok_;
+        int          init_outData_;
+};
+
+WOLF_STRUCT_PTR_TYPEDEFS(ProcessorLoopClosureFalkoNnBsc);
+
+/** \brief A class that implements the loop closure with BSC descriptors and NN matcher
+ **/
+class ProcessorLoopClosureFalkoNnBsc
+        : public ProcessorLoopClosureFalko<laserscanutils::bsc, laserscanutils::bscExtractor,
+          laserscanutils::LoopClosureFalkoNn>
+{
+    public:
+        ProcessorLoopClosureFalkoNnBsc(ParamsProcessorLoopClosureFalkoPtr _params_falko)
+    : ProcessorLoopClosureFalko(_params_falko){};
+
+        WOLF_PROCESSOR_CREATE(ProcessorLoopClosureFalkoNnBsc, ParamsProcessorLoopClosureFalko);
+
+        ~ProcessorLoopClosureFalkoNnBsc() = default;
+};
+
+WOLF_STRUCT_PTR_TYPEDEFS(ProcessorLoopClosureFalkoAhtBsc);
+
+/** \brief A class that implements the loop closure with BSC descriptors and AHT matcher
+ **/
+class ProcessorLoopClosureFalkoAhtBsc : public ProcessorLoopClosureFalko<laserscanutils::bsc,
+                                                                         laserscanutils::bscExtractor,
+                                                                         laserscanutils::LoopClosureFalkoAht>
+{
+    public:
+        ProcessorLoopClosureFalkoAhtBsc(ParamsProcessorLoopClosureFalkoPtr _params_falko)
+    : ProcessorLoopClosureFalko(_params_falko){};
+
+        WOLF_PROCESSOR_CREATE(ProcessorLoopClosureFalkoAhtBsc, ParamsProcessorLoopClosureFalko);
+
+        ~ProcessorLoopClosureFalkoAhtBsc() = default;
+};
+
+WOLF_STRUCT_PTR_TYPEDEFS(ProcessorLoopClosureFalkoNnCgh);
+
+/** \brief A class that implements the loop closure with CGH descriptors and NN matcher
+ **/
+class ProcessorLoopClosureFalkoNnCgh : public ProcessorLoopClosureFalko<laserscanutils::cgh,
+                                                                        laserscanutils::cghExtractor,
+                                                                        laserscanutils::LoopClosureFalkoNn>
+{
+    public:
+        ProcessorLoopClosureFalkoNnCgh(ParamsProcessorLoopClosureFalkoPtr _params_falko)
+    : ProcessorLoopClosureFalko(_params_falko){};
+
+        WOLF_PROCESSOR_CREATE(ProcessorLoopClosureFalkoNnCgh, ParamsProcessorLoopClosureFalko);
+
+        ~ProcessorLoopClosureFalkoNnCgh() = default;
+};
+
+WOLF_STRUCT_PTR_TYPEDEFS(ProcessorLoopClosureFalkoAhtCgh);
+
+/** \brief A class that implements the loop closure with CGH descriptors and AHT matcher
+ **/
+class ProcessorLoopClosureFalkoAhtCgh : public ProcessorLoopClosureFalko<laserscanutils::cgh,
+                                                                         laserscanutils::cghExtractor,
+                                                                         laserscanutils::LoopClosureFalkoAht>
+{
+    public:
+        ProcessorLoopClosureFalkoAhtCgh(ParamsProcessorLoopClosureFalkoPtr _params_falko)
+    : ProcessorLoopClosureFalko(_params_falko){};
+
+        WOLF_PROCESSOR_CREATE(ProcessorLoopClosureFalkoAhtCgh, ParamsProcessorLoopClosureFalko);
+
+        ~ProcessorLoopClosureFalkoAhtCgh() = default;
+};
+
+} // namespace wolf
+
+#endif // SRC_PROCESSOR_LOOP_CLOSURE_FALKO_H_
diff --git a/include/laser/processor/processor_loop_closure_falko_icp.h b/include/laser/processor/processor_loop_closure_falko_icp.h
new file mode 100644
index 0000000000000000000000000000000000000000..5ed8e6bb2de33f330f43642da1d0cacadaee2158
--- /dev/null
+++ b/include/laser/processor/processor_loop_closure_falko_icp.h
@@ -0,0 +1,298 @@
+//--------LICENSE_START--------
+//
+// Copyright (C) 2020,2021 Institut de Robòtica i Informàtica Industrial, CSIC-UPC.
+// Authors: Joan Solà Ortega (jsola@iri.upc.edu)
+// All rights reserved.
+//
+// This file is part of WOLF
+// WOLF is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+//--------LICENSE_END--------
+#ifndef PROCESSOR_LOOP_CLOSURE_FALKO_ICP_H_
+#define PROCESSOR_LOOP_CLOSURE_FALKO_ICP_H_
+
+/**************************
+ *      WOLF includes     *
+ **************************/
+#include <laser/processor/processor_loop_closure_falko.h>
+#include <laser/feature/feature_icp_align.h>
+
+/**************************
+ *      laseScanUtils - ICP includes      *
+ **************************/
+
+#include <laser_scan_utils/icp.h>
+
+using namespace laserscanutils;
+
+namespace wolf {
+
+WOLF_STRUCT_PTR_TYPEDEFS(ParamsProcessorLoopClosureFalkoIcp);
+
+struct ParamsProcessorLoopClosureFalkoIcp : public ParamsProcessorLoopClosureFalko
+{
+
+    // ParameterLoopClosureFalko param;
+    double max_error_threshold;
+    double min_points_percent;
+
+    laserscanutils::icpParams icp_params;
+
+    ParamsProcessorLoopClosureFalkoIcp() = default;
+    ParamsProcessorLoopClosureFalkoIcp(std::string _unique_name, const ParamsServer &_server)
+        : ParamsProcessorLoopClosureFalko(_unique_name, _server)
+    {
+        // param.matcher_ddesc_th_    = _server.getParam<double>(prefix + _unique_name + "/matcher_ddesc_th");
+        // param.keypoints_number_th_ = _server.getParam<int>(prefix + _unique_name + "/keypoints_number_th");
+        max_error_threshold = _server.getParam<double>(prefix + _unique_name + "/max_error_threshold");
+        min_points_percent  = _server.getParam<double>(prefix + _unique_name + "/min_points_percent");
+
+        icp_params.use_point_to_line_distance =
+            _server.getParam<int>(prefix + _unique_name + "/icp/use_point_to_line_distance");
+        icp_params.max_correspondence_dist =
+            _server.getParam<double>(prefix + _unique_name + "/icp/max_correspondence_dist");
+        icp_params.max_iterations   = _server.getParam<int>(prefix + _unique_name + "/icp/max_iterations");
+        icp_params.use_corr_tricks  = _server.getParam<int>(prefix + _unique_name + "/icp/use_corr_tricks");
+        icp_params.outliers_maxPerc = _server.getParam<double>(prefix + _unique_name + "/icp/outliers_maxPerc");
+        icp_params.outliers_adaptive_order =
+            _server.getParam<double>(prefix + _unique_name + "/icp/outliers_adaptive_order");
+        icp_params.outliers_adaptive_mult =
+            _server.getParam<double>(prefix + _unique_name + "/icp/outliers_adaptive_mult");
+        icp_params.do_compute_covariance = _server.getParam<int>(prefix + _unique_name + "/icp/do_compute_covariance");
+        icp_params.max_angular_correction_deg =
+            _server.getParam<double>(prefix + _unique_name + "/icp/max_angular_correction_deg");
+        icp_params.max_linear_correction =
+            _server.getParam<double>(prefix + _unique_name + "/icp/max_linear_correction");
+        icp_params.epsilon_xy    = _server.getParam<double>(prefix + _unique_name + "/icp/epsilon_xy");
+        icp_params.epsilon_theta = _server.getParam<double>(prefix + _unique_name + "/icp/epsilon_theta");
+        icp_params.sigma         = _server.getParam<double>(prefix + _unique_name + "/icp/sigma");
+        icp_params.restart       = _server.getParam<int>(prefix + _unique_name + "/icp/restart");
+        icp_params.restart_threshold_mean_error =
+            _server.getParam<double>(prefix + _unique_name + "/icp/restart_threshold_mean_error");
+        icp_params.restart_dt           = _server.getParam<double>(prefix + _unique_name + "/icp/restart_dt");
+        icp_params.restart_dtheta       = _server.getParam<double>(prefix + _unique_name + "/icp/restart_dtheta");
+        icp_params.clustering_threshold = _server.getParam<double>(prefix + _unique_name + "/icp/clustering_threshold");
+        icp_params.orientation_neighbourhood =
+            _server.getParam<int>(prefix + _unique_name + "/icp/orientation_neighbourhood");
+        icp_params.do_alpha_test = _server.getParam<int>(prefix + _unique_name + "/icp/do_alpha_test");
+        icp_params.do_alpha_test_thresholdDeg =
+            _server.getParam<double>(prefix + _unique_name + "/icp/do_alpha_test_thresholdDeg");
+        icp_params.do_visibility_test = _server.getParam<int>(prefix + _unique_name + "/icp/do_visibility_test");
+        icp_params.outliers_remove_doubles =
+            _server.getParam<int>(prefix + _unique_name + "/icp/outliers_remove_doubles");
+        icp_params.debug_verify_tricks = _server.getParam<int>(prefix + _unique_name + "/icp/debug_verify_tricks");
+        icp_params.gpm_theta_bin_size_deg =
+            _server.getParam<double>(prefix + _unique_name + "/icp/gpm_theta_bin_size_deg");
+        icp_params.gpm_extend_range_deg = _server.getParam<double>(prefix + _unique_name + "/icp/gpm_extend_range_deg");
+        icp_params.gpm_interval         = _server.getParam<double>(prefix + _unique_name + "/icp/gpm_interval");
+        icp_params.min_reading          = _server.getParam<double>(prefix + _unique_name + "/icp/min_reading");
+        icp_params.max_reading          = _server.getParam<double>(prefix + _unique_name + "/icp/max_reading");
+        icp_params.use_ml_weights       = _server.getParam<int>(prefix + _unique_name + "/icp/use_ml_weights");
+        icp_params.use_sigma_weights    = _server.getParam<int>(prefix + _unique_name + "/icp/use_sigma_weights");
+    };
+
+    virtual ~ParamsProcessorLoopClosureFalkoIcp() = default;
+};
+
+/** \brief A class to implement a loop closure processor using loop closure detection from falko library
+ * The Laser data is provided by the sensor owning this processor.
+ *
+ * All the falko loop Closure functionality is implemented in the inherited class
+ *
+ * In this class is only implemented the validation of the falko loop closures with an ICP
+ *
+ * Diferent types of descriptors and matchers can be used and are specified as template parameters.
+ * \tparam D Descriptor type. <bsc> or <cgh>
+ * \tparam Extr descriptor extractor type <bscExtractor> or <cghExtractor>
+ * \tparam M Matcher type <nn_matcher> or <aht_matcher>
+ * \param _param_falko parameter struct with falko lib parameters
+ **/
+
+template <typename D, typename Extr, template <typename, typename> typename L>
+class ProcessorLoopClosureFalkoIcp : public ProcessorLoopClosureFalko<D, Extr, L>
+{
+
+  public:
+    ProcessorLoopClosureFalkoIcp(ParamsProcessorLoopClosureFalkoIcpPtr _params_falko)
+        : ProcessorLoopClosureFalko<D, Extr, L>(_params_falko)
+        , params_falko_icp_(_params_falko){
+
+          };
+
+    ~ProcessorLoopClosureFalkoIcp() = default;
+
+    WOLF_PROCESSOR_CREATE(ProcessorLoopClosureFalkoIcp, ParamsProcessorLoopClosureFalkoIcp);
+
+  protected:
+    ParamsProcessorLoopClosureFalkoIcpPtr params_falko_icp_;
+    // ICP algorithm
+    std::shared_ptr<laserscanutils::ICP> icp_tools_ptr_;
+
+    /** \brief Function that validates the falko loop closures with an ICP aligment.
+     *
+     * For the ICP alignment it uses the transform provided by the falko algorithm as an initial guess.
+     *
+     * \param match structure that contains scenes and capture pointers that are a match
+     **/
+    bool validateLoopClosure(MatchLoopClosurePtr match) override
+    {
+        auto start_validation = std::chrono::high_resolution_clock::now();
+        auto capture_own      = match->capture_reference; //< Capture reference
+        auto capture_other    = match->capture_target;    // Capture target
+        auto frame_own        = capture_own->getFrame();
+        auto frame_other      = capture_other->getFrame();
+        bool match_valid      = false;
+
+        auto match_falko = std::static_pointer_cast<MatchLoopClosureFalko>(match);
+
+        if ((capture_own->getType() == "CaptureLaser2d") & (capture_other->getType() == "CaptureLaser2d"))
+            {
+                CaptureLaser2dPtr capture_laser_other = std::static_pointer_cast<CaptureLaser2d>(capture_other);
+                CaptureLaser2dPtr capture_laser_own   = std::static_pointer_cast<CaptureLaser2d>(capture_own);
+
+                SensorLaser2dPtr sensor_own, sensor_other;
+                sensor_own   = std::static_pointer_cast<SensorLaser2d>(capture_laser_own->getSensor());
+                sensor_other = std::static_pointer_cast<SensorLaser2d>(capture_laser_other->getSensor());
+
+                WOLF_INFO("DBG Attempting to close loop with ", frame_own->id(), " and ", frame_other->id());
+                try
+                    {
+                        laserscanutils::icpOutput trf = icp_tools_ptr_->align(
+                            capture_laser_other->getScan(), capture_laser_own->getScan(), sensor_own->getScanParams(),
+                            sensor_other->getScanParams(), params_falko_icp_->icp_params,
+                            match_falko->match_falko_->transform_vector);
+
+                        double points_coeff_used =
+                            ((double)trf.nvalid / (double)fmin(capture_laser_own->getScan().ranges_raw_.size(),
+                                                               capture_laser_other->getScan().ranges_raw_.size()));
+                        double          mean_error = trf.error / trf.nvalid;
+                        Eigen::Vector3d displacement_other_own;
+                        displacement_other_own.head(2) =
+                            Eigen::Rotation2Dd(-frame_other->getState().vector("O")(0)) *
+                            (frame_own->getState().vector("P") - frame_other->getState().vector("P"));
+                        displacement_other_own(2) =
+                            frame_own->getState().vector("O")(0) - frame_other->getState().vector("O")(0);
+
+                        Eigen::Vector3d displacement_own_other;
+                        displacement_own_other.head(2) =
+                            Eigen::Rotation2Dd(-frame_own->getState().vector("O")(0)) *
+                            (frame_other->getState().vector("P") - frame_own->getState().vector("P"));
+                        displacement_own_other(2) =
+                            frame_other->getState().vector("O")(0) - frame_own->getState().vector("O")(0);
+
+                        WOLF_INFO("DBG ------------------------------");
+                        WOLF_INFO("DBG valid? ", trf.valid, "\n m_er ", mean_error,
+                                  " \n % points used :", points_coeff_used * 100);
+                        // WOLF_INFO("DBG own_POSE: ", frame_own->getState().vector("PO").transpose(),
+                        //           "\nother_POSE: ", frame_other->getState().vector("PO").transpose(),
+                        // WOLF_INFO("\ndisplacement_other_own : ", displacement_other_own.transpose(),
+                        WOLF_INFO("\ndisplacement_own_other : ", displacement_own_other.transpose(),
+                                  "\nIcp initial guess: ", match_falko->match_falko_->transform_vector.transpose(),
+                                  "\nIcp final transfr: ", trf.res_transf.transpose());
+                        // WOLF_INFO("Covariance \n", trf.res_covar);
+                        if (trf.valid == 1 and mean_error < params_falko_icp_->max_error_threshold and
+                            points_coeff_used * 100 > params_falko_icp_->min_points_percent)
+                            {
+                                WOLF_INFO("Match validated ", frame_own->id(), " and ", frame_other->id());
+                                match_valid                                 = true;
+                                match_falko->match_falko_->transform_vector = trf.res_transf;
+                                this->num_ok_ += 1;
+                                this->duration_validation_ok += std::chrono::duration_cast<std::chrono::microseconds>(
+                                    std::chrono::high_resolution_clock::now() - start_validation);
+                            }
+                        else
+                            {
+                                WOLF_INFO("Match DISCARDED ", frame_own->id(), " and ", frame_other->id());
+                                this->num_nok_ += 1;
+                                this->duration_validation_nok += std::chrono::duration_cast<std::chrono::microseconds>(
+                                    std::chrono::high_resolution_clock::now() - start_validation);
+                            }
+                    }
+                catch (std::exception &e)
+                    {
+                        this->num_nok_ += 1;
+                        WOLF_WARN(e.what())
+                    }
+            }
+        return match_valid;
+    }
+};
+
+WOLF_STRUCT_PTR_TYPEDEFS(ProcessorLoopClosureFalkoIcpNnBsc);
+
+/** \brief A class that implements the loop closure with BSC descriptors and NN matcher
+ **/
+class ProcessorLoopClosureFalkoIcpNnBsc
+    : public ProcessorLoopClosureFalkoIcp<bsc, bscExtractor, laserscanutils::LoopClosureFalkoNn>
+{
+  public:
+    ProcessorLoopClosureFalkoIcpNnBsc(ParamsProcessorLoopClosureFalkoIcpPtr _params_falko)
+        : ProcessorLoopClosureFalkoIcp(_params_falko){};
+
+    WOLF_PROCESSOR_CREATE(ProcessorLoopClosureFalkoIcpNnBsc, ParamsProcessorLoopClosureFalkoIcp);
+
+    ~ProcessorLoopClosureFalkoIcpNnBsc() = default;
+};
+
+WOLF_STRUCT_PTR_TYPEDEFS(ProcessorLoopClosureFalkoIcpAhtBsc);
+
+/** \brief A class that implements the loop closure with BSC descriptors and NN matcher
+ **/
+class ProcessorLoopClosureFalkoIcpAhtBsc
+    : public ProcessorLoopClosureFalkoIcp<bsc, bscExtractor, laserscanutils::LoopClosureFalkoAht>
+{
+  public:
+    ProcessorLoopClosureFalkoIcpAhtBsc(ParamsProcessorLoopClosureFalkoIcpPtr _params_falko)
+        : ProcessorLoopClosureFalkoIcp(_params_falko){};
+
+    WOLF_PROCESSOR_CREATE(ProcessorLoopClosureFalkoIcpAhtBsc, ParamsProcessorLoopClosureFalkoIcp);
+
+    ~ProcessorLoopClosureFalkoIcpAhtBsc() = default;
+};
+
+WOLF_STRUCT_PTR_TYPEDEFS(ProcessorLoopClosureFalkoIcpNnCgh);
+
+/** \brief A class that implements the loop closure with Cgh descriptors and NN matcher
+ **/
+class ProcessorLoopClosureFalkoIcpNnCgh
+    : public ProcessorLoopClosureFalkoIcp<cgh, cghExtractor, laserscanutils::LoopClosureFalkoNn>
+{
+  public:
+    ProcessorLoopClosureFalkoIcpNnCgh(ParamsProcessorLoopClosureFalkoIcpPtr _params_falko)
+        : ProcessorLoopClosureFalkoIcp(_params_falko){};
+
+    WOLF_PROCESSOR_CREATE(ProcessorLoopClosureFalkoIcpNnCgh, ParamsProcessorLoopClosureFalkoIcp);
+
+    ~ProcessorLoopClosureFalkoIcpNnCgh() = default;
+};
+
+WOLF_STRUCT_PTR_TYPEDEFS(ProcessorLoopClosureFalkoIcpAhtCgh);
+
+/** \brief A class that implements the loop closure with Cgh descriptors and NN matcher
+ **/
+class ProcessorLoopClosureFalkoIcpAhtCgh
+    : public ProcessorLoopClosureFalkoIcp<cgh, cghExtractor, laserscanutils::LoopClosureFalkoAht>
+{
+  public:
+    ProcessorLoopClosureFalkoIcpAhtCgh(ParamsProcessorLoopClosureFalkoIcpPtr _params_falko)
+        : ProcessorLoopClosureFalkoIcp(_params_falko){};
+
+    WOLF_PROCESSOR_CREATE(ProcessorLoopClosureFalkoIcpAhtCgh, ParamsProcessorLoopClosureFalkoIcp);
+
+    ~ProcessorLoopClosureFalkoIcpAhtCgh() = default;
+};
+
+} // namespace wolf
+
+#endif // SRC_PROCESSOR_LOOP_CLOSURE_FALKO_ICP_H_
diff --git a/include/laser/processor/processor_loop_closure_icp.h b/include/laser/processor/processor_loop_closure_icp.h
index 226c19e950f2993b04f77795ab2f7ee637f62129..079ab82e3a184eebce74b466efb859b15bb31d6a 100644
--- a/include/laser/processor/processor_loop_closure_icp.h
+++ b/include/laser/processor/processor_loop_closure_icp.h
@@ -26,17 +26,17 @@
  *      WOLF includes     *
  **************************/
 #include "core/common/wolf.h"
-#include <core/processor/processor_loop_closure.h>
-#include <laser/capture/capture_laser_2d.h>
+#include "core/processor/processor_loop_closure.h"
+#include "core/factor/factor_relative_pose_2d_with_extrinsics.h"
 
-#include <core/factor/factor_relative_pose_2d_with_extrinsics.h>
-#include <laser/feature/feature_icp_align.h>
+#include "laser/capture/capture_laser_2d.h"
+#include "laser/feature/feature_icp_align.h"
 
 /**************************
  *      ICP includes      *
  **************************/
-#include <laser_scan_utils/laser_scan_utils.h>
-#include <laser_scan_utils/icp.h>
+#include "laser_scan_utils/laser_scan_utils.h"
+#include "laser_scan_utils/icp.h"
 
 namespace wolf
 {
@@ -45,8 +45,7 @@ WOLF_STRUCT_PTR_TYPEDEFS(ParamsProcessorLoopClosureIcp);
 
 struct ParamsProcessorLoopClosureIcp : public ParamsProcessorLoopClosure
 {
-    int recent_frames_ignored;
-    int frames_to_wait;
+    int recent_frames_ignored, frames_ignored_after_loop;
     double max_error_threshold;
     double min_points_percent;
 
@@ -58,20 +57,18 @@ struct ParamsProcessorLoopClosureIcp : public ParamsProcessorLoopClosure
         ParamsProcessorLoopClosure(_unique_name, _server)
     {
         recent_frames_ignored     = _server.getParam<int>    (prefix + _unique_name + "/recent_frames_ignored");
-        frames_to_wait            = _server.getParam<int>    (prefix + _unique_name + "/frames_to_wait");
+        frames_ignored_after_loop = _server.getParam<int>    (prefix + _unique_name + "/frames_ignored_after_loop");
         max_error_threshold       = _server.getParam<double> (prefix + _unique_name + "/max_error_threshold");
         min_points_percent        = _server.getParam<double> (prefix + _unique_name + "/min_points_percent");
 
-        icp_params.cov_factor                 = _server.getParam<double> (prefix + _unique_name + "/cov_factor");
-
-        icp_params.use_point_to_line_distance = _server.getParam<int>    (prefix + _unique_name + "/use_point_to_line_distance");
-        icp_params.max_correspondence_dist    = _server.getParam<double> (prefix + _unique_name + "/max_correspondence_dist");
-        icp_params.max_iterations             = _server.getParam<int>    (prefix + _unique_name + "/max_iterations");
-        icp_params.use_corr_tricks            = _server.getParam<int>    (prefix + _unique_name + "/use_corr_tricks");
-        icp_params.outliers_maxPerc           = _server.getParam<double> (prefix + _unique_name + "/outliers_maxPerc");
-        icp_params.outliers_adaptive_order    = _server.getParam<double> (prefix + _unique_name + "/outliers_adaptive_order");
-        icp_params.outliers_adaptive_mult     = _server.getParam<double> (prefix + _unique_name + "/outliers_adaptive_mult");
-
+        icp_params.use_point_to_line_distance   = _server.getParam<int>    (prefix + _unique_name + "/use_point_to_line_distance");
+        icp_params.max_correspondence_dist      = _server.getParam<double> (prefix + _unique_name + "/max_correspondence_dist");
+        icp_params.max_iterations               = _server.getParam<int>    (prefix + _unique_name + "/max_iterations");
+        icp_params.use_corr_tricks              = _server.getParam<int>    (prefix + _unique_name + "/use_corr_tricks");
+        icp_params.outliers_maxPerc             = _server.getParam<double> (prefix + _unique_name + "/outliers_maxPerc");
+        icp_params.outliers_adaptive_order      = _server.getParam<double> (prefix + _unique_name + "/outliers_adaptive_order");
+        icp_params.outliers_adaptive_mult       = _server.getParam<double> (prefix + _unique_name + "/outliers_adaptive_mult");
+        icp_params.cov_factor                   = _server.getParam<double> (prefix + _unique_name + "/cov_factor");
         icp_params.do_compute_covariance        = _server.getParam<int>    (prefix + _unique_name + "/do_compute_covariance");
         icp_params.max_angular_correction_deg   = _server.getParam<double> (prefix + _unique_name + "/max_angular_correction_deg");
         icp_params.max_linear_correction        = _server.getParam<double> (prefix + _unique_name + "/max_linear_correction");
@@ -92,26 +89,29 @@ struct ParamsProcessorLoopClosureIcp : public ParamsProcessorLoopClosure
         icp_params.gpm_theta_bin_size_deg       = _server.getParam<double> (prefix + _unique_name + "/gpm_theta_bin_size_deg");
         icp_params.gpm_extend_range_deg         = _server.getParam<double> (prefix + _unique_name + "/gpm_extend_range_deg");
         icp_params.gpm_interval                 = _server.getParam<double> (prefix + _unique_name + "/gpm_interval");
-
-        icp_params.min_reading       = _server.getParam<double> (prefix + _unique_name + "/min_reading");
-        icp_params.max_reading       = _server.getParam<double> (prefix + _unique_name + "/max_reading");
-        icp_params.use_ml_weights    = _server.getParam<int>    (prefix + _unique_name + "/use_ml_weights");
-        icp_params.use_sigma_weights = _server.getParam<int>    (prefix + _unique_name + "/use_sigma_weights");
+        icp_params.min_reading                  = _server.getParam<double> (prefix + _unique_name + "/min_reading");
+        icp_params.max_reading                  = _server.getParam<double> (prefix + _unique_name + "/max_reading");
+        icp_params.use_ml_weights               = _server.getParam<int>    (prefix + _unique_name + "/use_ml_weights");
+        icp_params.use_sigma_weights            = _server.getParam<int>    (prefix + _unique_name + "/use_sigma_weights");
     }
     std::string print() const override
     {
-        return "\n" + ParamsProcessorLoopClosure::print()
+        return "\n" + ParamsProcessorBase::print()
             + "recent_frames_ignored: " + std::to_string(recent_frames_ignored) + "\n"
-            + "frames_to_wait: "        + std::to_string(frames_to_wait) + "\n"
-            + "max_error_threshold: "   + std::to_string(max_error_threshold) + "\n"
-            + "min_points_percent: "    + std::to_string(min_points_percent) + "\n";
+            + "frames_ignored_after_loop: " + std::to_string(frames_ignored_after_loop) + "\n"
+            + "max_error_threshold: " + std::to_string(max_error_threshold) + "\n"
+            + "min_points_percent: " + std::to_string(min_points_percent) + "\n";
     }
 };
 
-WOLF_STRUCT_PTR_TYPEDEFS(MatchLoopClosureIcp);
+/** \brief Match between a capture and a capture
+ *
+ * Match between a capture and a capture (capture-capture correspondence)
+ *
+ */
 struct MatchLoopClosureIcp : public MatchLoopClosure
 {
-    laserscanutils::icpOutput align_result;
+    laserscanutils::icpOutput icp_result;
 };
 
 class ProcessorLoopClosureIcp : public ProcessorLoopClosure
@@ -123,37 +123,45 @@ class ProcessorLoopClosureIcp : public ProcessorLoopClosure
 
         //Closeloop parameters
         ParamsProcessorLoopClosureIcpPtr params_loop_closure_icp_;
-        int frames_skipped_;
 
         // ICP algorithm
         std::shared_ptr<laserscanutils::ICP> icp_tools_ptr_;
 
+        MatchLoopClosurePtr last_loop_closure_;
+
     public:
         ProcessorLoopClosureIcp(ParamsProcessorLoopClosureIcpPtr _params);
 
         WOLF_PROCESSOR_CREATE(ProcessorLoopClosureIcp, ParamsProcessorLoopClosureIcp);
         void configure(SensorBasePtr _sensor) override;
 
+        ParamsProcessorLoopClosureIcpPtr getParams() const;
+
     protected:
 
         /** \brief Returns if findLoopClosures() has to be called for the given capture
-         * Since there is no enough information in the capture to decide if a loop can be closed, try always.
+         *
+         * This case avoids searching if a recent loop closure
          */
         bool voteFindLoopClosures(CaptureBasePtr cap) override;
 
         /** \brief detects and emplaces all features of the given capture
-         * Since the loop closures of this processor are not based on any features, it is empty
+         *
+         * In this case, ICP does not work with features to find a loop closure.
+         * A feature will be added when emplacing the factors.
+         *
          */
-        void emplaceFeatures(CaptureBasePtr cap) override{};
+        void emplaceFeatures(CaptureBasePtr cap) override {/*nothing*/};
 
         /** \brief Find captures that correspond to loop closures with the given capture
          */
-        std::map<double, MatchLoopClosurePtr> findLoopClosures(CaptureBasePtr _capture) override;
+        std::map<double,MatchLoopClosurePtr> findLoopClosures(CaptureBasePtr _capture) override;
+
+        MatchLoopClosurePtr matchScans(CaptureLaser2dPtr cap_ref, CaptureLaser2dPtr cap_target) const;
 
         /** \brief validates a loop closure
-         * Loops are validated just after calling ICP
          */
-        bool validateLoopClosure(MatchLoopClosurePtr) override{ return true;};
+        bool validateLoopClosure(MatchLoopClosurePtr) override {return true;};
 
         /** \brief emplaces the factor(s) corresponding to a Loop Closure between two captures
          */
diff --git a/src/feature/feature_scene_falko.cpp b/src/feature/feature_scene_falko.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..113e1568808f9d8d86bdd92166943c02b9fe264f
--- /dev/null
+++ b/src/feature/feature_scene_falko.cpp
@@ -0,0 +1,27 @@
+//--------LICENSE_START--------
+//
+// Copyright (C) 2020,2021 Institut de Robòtica i Informàtica Industrial, CSIC-UPC.
+// Authors: Joan Solà Ortega (jsola@iri.upc.edu)
+// All rights reserved.
+//
+// This file is part of WOLF
+// WOLF is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+//--------LICENSE_END--------
+#include "laser/feature/feature_scene_falko.h"
+
+namespace wolf
+{
+
+} // namespace wolf
diff --git a/src/processor/processor_loop_closure_falko.cpp b/src/processor/processor_loop_closure_falko.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..730782a8e66d7d618da8cce1b113e6bee2b9cf81
--- /dev/null
+++ b/src/processor/processor_loop_closure_falko.cpp
@@ -0,0 +1,37 @@
+//--------LICENSE_START--------
+//
+// Copyright (C) 2020,2021 Institut de Robòtica i Informàtica Industrial, CSIC-UPC.
+// Authors: Joan Solà Ortega (jsola@iri.upc.edu)
+// All rights reserved.
+//
+// This file is part of WOLF
+// WOLF is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+//--------LICENSE_END--------
+#include "laser/processor/processor_loop_closure_falko.h"
+// Register in the FactorySensor
+#include "core/processor/factory_processor.h"
+namespace wolf {
+WOLF_REGISTER_PROCESSOR(ProcessorLoopClosureFalkoNnBsc);
+WOLF_REGISTER_PROCESSOR_AUTO(ProcessorLoopClosureFalkoNnBsc);
+
+WOLF_REGISTER_PROCESSOR(ProcessorLoopClosureFalkoNnCgh);
+WOLF_REGISTER_PROCESSOR_AUTO(ProcessorLoopClosureFalkoNnCgh);
+
+WOLF_REGISTER_PROCESSOR(ProcessorLoopClosureFalkoAhtBsc);
+WOLF_REGISTER_PROCESSOR_AUTO(ProcessorLoopClosureFalkoAhtBsc);
+
+// WOLF_REGISTER_PROCESSOR(ProcessorLoopClosureFalkoAhtCgh);
+// WOLF_REGISTER_PROCESSOR_AUTO(ProcessorLoopClosureFalkoAhtCgh);
+} // namespace wolf
\ No newline at end of file
diff --git a/src/processor/processor_loop_closure_falko_icp.cpp b/src/processor/processor_loop_closure_falko_icp.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1312f27b3353bed70570c0615a31e61acac3bf19
--- /dev/null
+++ b/src/processor/processor_loop_closure_falko_icp.cpp
@@ -0,0 +1,38 @@
+//--------LICENSE_START--------
+//
+// Copyright (C) 2020,2021 Institut de Robòtica i Informàtica Industrial, CSIC-UPC.
+// Authors: Joan Solà Ortega (jsola@iri.upc.edu)
+// All rights reserved.
+//
+// This file is part of WOLF
+// WOLF is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+//--------LICENSE_END--------
+#include "laser/processor/processor_loop_closure_falko_icp.h"
+// Register in the FactorySensor
+#include "core/processor/factory_processor.h"
+namespace wolf {
+    WOLF_REGISTER_PROCESSOR(ProcessorLoopClosureFalkoIcpNnBsc);
+    WOLF_REGISTER_PROCESSOR_AUTO(ProcessorLoopClosureFalkoIcpNnBsc);
+
+    WOLF_REGISTER_PROCESSOR(ProcessorLoopClosureFalkoIcpAhtBsc);
+    WOLF_REGISTER_PROCESSOR_AUTO(ProcessorLoopClosureFalkoIcpAhtBsc);
+
+    WOLF_REGISTER_PROCESSOR(ProcessorLoopClosureFalkoIcpNnCgh);
+    WOLF_REGISTER_PROCESSOR_AUTO(ProcessorLoopClosureFalkoIcpNnCgh);
+
+    WOLF_REGISTER_PROCESSOR(ProcessorLoopClosureFalkoIcpAhtCgh);
+    WOLF_REGISTER_PROCESSOR_AUTO(ProcessorLoopClosureFalkoIcpAhtCgh);
+
+} // namespace wolf
\ No newline at end of file
diff --git a/src/processor/processor_loop_closure_icp.cpp b/src/processor/processor_loop_closure_icp.cpp
index b93ee3848a279510bdf5267c0f61300bbe19bd5d..b7f71dc1e831d27e58dc88f0801c0338ab62a814 100644
--- a/src/processor/processor_loop_closure_icp.cpp
+++ b/src/processor/processor_loop_closure_icp.cpp
@@ -23,15 +23,17 @@
 #include "laser/sensor/sensor_laser_2d.h"
 #include "core/math/covariance.h"
 
-namespace wolf
-{
+using namespace laserscanutils;
+using namespace Eigen;
+
+namespace wolf{
 
 ProcessorLoopClosureIcp::ProcessorLoopClosureIcp(ParamsProcessorLoopClosureIcpPtr _params) :
     ProcessorLoopClosure("ProcessorLoopClosureIcp", 2, _params),
     params_loop_closure_icp_(_params),
-    frames_skipped_(0)
+    last_loop_closure_(nullptr)
 {
-    icp_tools_ptr_ = std::make_shared<laserscanutils::ICP>();
+    icp_tools_ptr_ = std::make_shared<ICP>();
 }
 
 void ProcessorLoopClosureIcp::configure(SensorBasePtr _sensor)
@@ -40,141 +42,177 @@ void ProcessorLoopClosureIcp::configure(SensorBasePtr _sensor)
     laser_scan_params_  = sensor_laser_->getScanParams();
 }
 
+ParamsProcessorLoopClosureIcpPtr ProcessorLoopClosureIcp::getParams() const
+{
+    return params_loop_closure_icp_;
+}
+
 bool ProcessorLoopClosureIcp::voteFindLoopClosures(CaptureBasePtr cap)
 {
-    // process 1 and skip 'frames_to_wait' frames
-    if (frames_skipped_ >= params_loop_closure_icp_->frames_to_wait)
-    {
-        frames_skipped_=0;
+    if (not last_loop_closure_)
+        return true;
+
+    if (params_loop_closure_icp_->frames_ignored_after_loop <= 0)
         return true;
+
+    auto last_frm = last_loop_closure_->capture_target->getFrame();
+    for (auto i = 1; i <= params_loop_closure_icp_->frames_ignored_after_loop; i++)
+    {
+        last_frm = last_frm->getNextFrame();
+        if (not last_frm or last_frm == cap->getFrame())
+        {
+            return false;
+        }
     }
-    frames_skipped_++;
-    return false;
+
+    return true;
 }
 
-std::map<double, MatchLoopClosurePtr> ProcessorLoopClosureIcp::findLoopClosures(CaptureBasePtr _capture)
+std::map<double,MatchLoopClosurePtr> ProcessorLoopClosureIcp::findLoopClosures(CaptureBasePtr _capture)
 {
-    assert(std::dynamic_pointer_cast<CaptureLaser2d>(_capture));
-    std::map<double, MatchLoopClosurePtr> match_map;
+    std::map<double,MatchLoopClosurePtr> match_lc_map;
 
-    auto cap_own = std::static_pointer_cast<CaptureLaser2d>(_capture);
-    auto frame_own = _capture->getFrame();
-    auto frame_ref = frame_own->getPreviousFrame();
-    auto frame_distance = 1;
+    auto cap_laser = std::dynamic_pointer_cast<CaptureLaser2d>(_capture);
+    assert(cap_laser != nullptr);
 
-    while (frame_ref)
+    // Ignore the most recent 'recent_frames_ignored' frames
+    const auto &trajectory = getProblem()->getTrajectory();
+    int n_ignored = 0;
+    for(auto frm_it  = trajectory->rbegin();
+             frm_it != trajectory->rend();
+             frm_it++)
     {
-        // not too recent frames
-        if (frame_distance > params_loop_closure_icp_->recent_frames_ignored)
+        if (frm_it->second == _capture->getFrame())
+            continue;
+
+        if (n_ignored < params_loop_closure_icp_->recent_frames_ignored)
+        {
+            n_ignored++;
+            continue;
+        }
+
+        auto cap_ref_list = frm_it->second->getCapturesOfType<CaptureLaser2d>();
+        for (auto cap_ref : cap_ref_list)
         {
-            // search CaptureLaser2d
-            for (auto cap : frame_ref->getCaptureList())
+            auto cap_ref_laser = std::dynamic_pointer_cast<CaptureLaser2d>(cap_ref);
+            if (cap_ref_laser != nullptr)
             {
-                auto cap_ref = std::static_pointer_cast<wolf::CaptureLaser2d>(cap);
-                // try to match if no too far  (more than laser range)
-                if (cap_ref and
-                    (frame_ref->getP()->getState() - frame_own->getP()->getState()).norm() < laser_scan_params_.range_max_)
+                // Match Scans
+                auto match = matchScans(cap_ref_laser, cap_laser);
+
+                // IT'S A MATCH!
+                if (match != nullptr)
                 {
-                    // Initial guess for alignment
-                    Eigen::Vector3d transform_guess;
-                    Eigen::Isometry2d T_w_rown, T_w_rref, T_r_s, T_sref_sown;
-
-                    // Transformations
-                    T_w_rown = Eigen::Translation2d(frame_own->getP()->getState()) *
-                                                    Eigen::Rotation2Dd(frame_own->getO()->getState()(0));
-                    T_w_rref = Eigen::Translation2d(frame_ref->getP()->getState()) *
-                                                      Eigen::Rotation2Dd(frame_ref->getO()->getState()(0));
-                    T_r_s = Eigen::Translation2d(this->getSensor()->getP()->getState()) * Eigen::Rotation2Dd(this->getSensor()->getO()->getState()(0));
-                    T_sref_sown = T_r_s.inverse() * T_w_rref.inverse() * T_w_rown * T_r_s;
-
-                    // Fill up initial guess
-                    transform_guess.head(2) = T_sref_sown.translation();
-                    Eigen::Rotation2Dd R(T_sref_sown.rotation());
-                    transform_guess(2) = R.angle();
-
-                    SensorLaser2dPtr sensor_own, sensor_ref;
-                    sensor_own = std::static_pointer_cast<wolf::SensorLaser2d>(cap_own->getSensor());
-                    sensor_ref = std::static_pointer_cast<wolf::SensorLaser2d>(cap_ref->getSensor());
-
-                    // WOLF_DEBUG("LOOP CLOSURE: Aligning key frames: ", frame_own->id(), " and ", frame_ref->id(), "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
-                    // Finally align
-                    // WOLF_DEBUG("Sensor own scan params\n");
-                    // sensor_own->getScanParams().print();
-                    // WOLF_DEBUG("Sensor ref scan params\n");
-                    // sensor_ref->getScanParams().print();
-                    // WOLF_DEBUG("Icp params\n");
-                    // WOLF_DEBUG("\n max_correspondence_dist: ", this->icp_params_.max_correspondence_dist,
-                    //           "\n use_point_to_line_distance: ", this->icp_params_.use_point_to_line_distance,
-                    //           "\n max_iterations: ", this->icp_params_.max_iterations,
-                    //           "\n outliers_adaptive_mult: ", this->icp_params_.outliers_adaptive_mult,
-                    //           "\n outliers_adaptive_order: ", this->icp_params_.outliers_adaptive_order,
-                    //           "\n outliers_maxPerc: ", this->icp_params_.outliers_maxPerc, "\n use corr tricks: ", this->icp_params_.use_corr_tricks);
-                    WOLF_DEBUG("DBG Attempting to close loop with ", frame_own->id(), " and ", frame_ref->id());
-                    try
-                    {
-                        laserscanutils::icpOutput trf =
-                                icp_tools_ptr_->align(cap_own->getScan(),
-                                                      cap_ref->getScan(),
-                                                      sensor_own->getScanParams(),
-                                                      sensor_ref->getScanParams(),
-                                                      params_loop_closure_icp_->icp_params,
-                                                      transform_guess);
-
-                        double points_coeff_used = ((double)trf.nvalid / (double)fmin(cap_own->getScan().ranges_raw_.size(),
-                                                                                      cap_ref->getScan().ranges_raw_.size()));
-                        double mean_error = trf.error / trf.nvalid;
-                        WOLF_DEBUG("DBG ------------------------------");
-                        WOLF_DEBUG("DBG valid? ", trf.valid, " m_er ", mean_error, " ", points_coeff_used * 100, "% own_id: ", frame_own->id(),
-                                   " ref_id: ", frame_ref->id());
-                        WOLF_DEBUG("DBG own_POSE: ", frame_own->getState().vector("PO").transpose(), " ref_POSE: ", frame_ref->getState().vector("PO").transpose(),
-                                   " Icp_guess: ", transform_guess.transpose(), " Icp_trf: ", trf.res_transf.transpose());
-
-                        // WOLF_DEBUG("Covariance \n", trf.res_covar);
-                        if (trf.valid == 1 and
-                            mean_error < params_loop_closure_icp_->max_error_threshold and
-                            points_coeff_used * 100 > params_loop_closure_icp_->min_points_percent)
-                        {
-                            WOLF_DEBUG("DBG ADDED ", frame_own->id(), " and ", frame_ref->id());
-
-                            auto match = std::make_shared<MatchLoopClosureIcp>();
-                            match->capture_reference    = cap_ref;
-                            match->capture_target       = cap_own;
-                            match->normalized_score     = 1 - mean_error / params_loop_closure_icp_->max_error_threshold;
-                            match->align_result         = trf;
-
-                            match_map.emplace(match->normalized_score, match);
-                        }
-                        else
-                        {
-                            WOLF_DEBUG("DBG DISCARDED ", frame_own->id(), " and ", frame_ref->id());
-                        }
-
-                    }
-                    catch (std::exception &e)
-                    {
-                        WOLF_WARN("ProcessorLoopClosureIcp: ICP failed with error: ", e.what());
-                    }
+                    // avoid duplicated scores (std::map)
+                    while (match_lc_map.count(match->normalized_score))
+                        match->normalized_score -= 1e-9;
+
+                    match_lc_map.emplace(match->normalized_score, match);
                 }
             }
         }
-        frame_ref = frame_ref->getPreviousFrame();
-        frame_distance++;
     }
 
-    return match_map;
+    return match_lc_map;
 }
 
-void ProcessorLoopClosureIcp::emplaceFactors(MatchLoopClosurePtr _match)
+MatchLoopClosurePtr ProcessorLoopClosureIcp::matchScans(CaptureLaser2dPtr cap_ref, CaptureLaser2dPtr cap_tar) const
 {
-    auto match_icp = std::static_pointer_cast<MatchLoopClosureIcp>(_match);
+    auto frm_tar = cap_tar->getFrame();
+    auto frm_ref = cap_ref->getFrame();
+    auto sen_tar = std::static_pointer_cast<wolf::SensorLaser2d>(cap_tar->getSensor());
+    auto sen_ref = std::static_pointer_cast<wolf::SensorLaser2d>(cap_ref->getSensor());
+
+    // INITIAL GUESS
+    // Transformations
+    Isometry2d T_w_r_tar = Translation2d(frm_tar->getP()->getState()) * Rotation2Dd(frm_tar->getO()->getState()(0));
+    Isometry2d T_w_r_ref = Translation2d(frm_ref->getP()->getState()) * Rotation2Dd(frm_ref->getO()->getState()(0));
+    Isometry2d T_r_s_tar = Translation2d(sen_tar->getP()->getState()) * Rotation2Dd(sen_tar->getO()->getState()(0));
+    Isometry2d T_r_s_ref = Translation2d(sen_ref->getP()->getState()) * Rotation2Dd(sen_ref->getO()->getState()(0));
+    Isometry2d T_s_ref_s_tar = T_r_s_ref.inverse() * T_w_r_ref.inverse() * T_w_r_tar * T_r_s_tar;
+
+    // Fill up initial guess
+    Vector3d transform_guess;
+    transform_guess.head(2) = T_s_ref_s_tar.translation();
+    Rotation2Dd R(T_s_ref_s_tar.rotation());
+    transform_guess(2) = R.angle();
+
+    // WOLF_DEBUG("LOOP CLOSURE: Aligning key frames: ", _keyframe_tar->id(), " and ", frm_ref->id(), "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
+    // WOLF_DEBUG("Sensor own scan params\n");
+    // sen_tar->getScanParams().print();
+    // WOLF_DEBUG("Sensor other scan params\n");
+    // sensor_ref->getScanParams().print();
+    // WOLF_DEBUG("Icp params\n");
+    // WOLF_DEBUG("\n max_correspondence_dist: ", this->icp_params_.max_correspondence_dist,
+    //           "\n use_point_to_line_distance: ", this->icp_params_.use_point_to_line_distance,
+    //           "\n max_iterations: ", this->icp_params_.max_iterations,
+    //           "\n outliers_adaptive_mult: ", this->icp_params_.outliers_adaptive_mult,
+    //           "\n outliers_adaptive_order: ", this->icp_params_.outliers_adaptive_order,
+    //           "\n outliers_maxPerc: ", this->icp_params_.outliers_maxPerc, "\n use corr tricks: ", this->icp_params_.use_corr_tricks);
+    WOLF_DEBUG("DBG Attempting to close loop with ", frm_tar->id(), " and ", frm_ref->id());
+    try
+    {
+        icpOutput icp_out = icp_tools_ptr_->align(cap_tar->getScan(),
+                                                  cap_ref->getScan(),
+                                                  sen_tar->getScanParams(),
+                                                  sen_ref->getScanParams(),
+                                                  params_loop_closure_icp_->icp_params,
+                                                  transform_guess);
+
+        double points_coeff_used = ((double)icp_out.nvalid / (double)fmin(cap_tar->getScan().ranges_raw_.size(),
+                                                                          cap_ref->getScan().ranges_raw_.size()));
+        double mean_error = icp_out.error / icp_out.nvalid;
+
+        WOLF_DEBUG("DBG ------------------------------");
+        WOLF_DEBUG("DBG valid? ", trf.valid,
+                   " m_er ", mean_error, " ", points_coeff_used * 100, "% own_id: ", frm_tar->id(),
+                   " other_id: ", frm_ref->id());
+        WOLF_DEBUG("DBG own_POSE: ", frm_tar->getState().vector("PO").transpose(),
+                   " other_POSE: ", frm_ref->getState().vector("PO").transpose(),
+                   " Icp_guess: ", transform_guess.transpose(),
+                   " Icp_trf: ", icp_out.res_transf.transpose());
+        // WOLF_DEBUG("Covariance \n", icp_out.res_covar);
+
+        // Valid output
+        if (icp_out.valid == 1 and
+            mean_error < params_loop_closure_icp_->max_error_threshold and
+            points_coeff_used * 100 > params_loop_closure_icp_->min_points_percent)
+        {
+            WOLF_DEBUG("DBG MATCH CONFIRMED ", frm_tar->id(), " and ", frm_ref->id());
+
+            auto match = std::make_shared<MatchLoopClosureIcp>();
+            match->capture_reference    = cap_ref;
+            match->capture_target       = cap_tar;
+            match->normalized_score     = points_coeff_used; // ratio points normalized (0, 1]
+            //match->normalized_score_ = exp(-mean_error); // error normalized (0, 1]
+            match->icp_result           = icp_out;
+
+            return match;
+        }
+        else
+        {
+            WOLF_DEBUG("DBG DISCARDED ", frm_tar->id(), " and ", _keyframe_ref->id());
+            return nullptr;
+        }
+
+    }
+    catch (std::exception &e)
+    {
+        WOLF_WARN("ProcessorLoopClosureIcp::matchScans ICP failed with output: ", e.what())
+    }
+    return nullptr;
+}
 
-    assert(match_icp->align_result.valid == 1);
+void ProcessorLoopClosureIcp::emplaceFactors(MatchLoopClosurePtr match)
+{
+    auto match_icp = std::static_pointer_cast<MatchLoopClosureIcp>(match);
 
-    if (not isCovariance(match_icp->align_result.res_covar))
-        match_icp->align_result.res_covar = 1e-4 * Eigen::Matrix3d::Identity();
+    assert(match_icp->icp_result.valid == 1);
+    if (not isCovariance(match_icp->icp_result.res_covar))
+        match_icp->icp_result.res_covar = 1e-4 * Matrix3d::Identity();
 
     auto ftr = FeatureBase::emplace<FeatureICPAlign>(match_icp->capture_target,
-                                                     match_icp->align_result);
+                                                     match_icp->icp_result);
 
     FactorBase::emplace<FactorRelativePose2dWithExtrinsics>(ftr,
                                                             ftr,
@@ -182,6 +220,9 @@ void ProcessorLoopClosureIcp::emplaceFactors(MatchLoopClosurePtr _match)
                                                             shared_from_this(),
                                                             params_->apply_loss_function,
                                                             TOP_LOOP);
+
+    // store last frame
+    last_loop_closure_ = match;
 }
 
 }
diff --git a/src/processor/processor_odom_icp.cpp b/src/processor/processor_odom_icp.cpp
index ad55f0aa8d949adbec78fcb0c76ba39aa581e00c..2b75292daf5c0f8e8388fca88d9e9ba786587b78 100644
--- a/src/processor/processor_odom_icp.cpp
+++ b/src/processor/processor_odom_icp.cpp
@@ -201,24 +201,10 @@ void ProcessorOdomIcp::advanceDerived()
 {
     using namespace Eigen;
 
-    // overwrite last frame's state
-
-    auto  w_T_ro = laser::trf2isometry(origin_ptr_->getFrame()->getP()->getState(), origin_ptr_->getFrame()->getO()->getState());
-    auto ro_T_so = laser::trf2isometry(origin_ptr_->getSensorP()->getState(), origin_ptr_->getSensorO()->getState());
-    const auto& ri_T_si = ro_T_so; // A reference just to have nice names without computing overhead
     odom_last_ = odom_incoming_;
 
-
-    // incoming
-
-    auto       so_T_si = laser::trf2isometry(trf_origin_incoming_.res_transf);
-    Isometry2d  w_T_ri = w_T_ro * ro_T_so * so_T_si * ri_T_si.inverse();
-    Vector3d x_inc; x_inc << w_T_ri.translation() , Rotation2Dd(w_T_ri.rotation()).angle();
-
-    // Put the state of incoming in last
-    // last_ptr_->getFrame()->setState(x_inc, "PO", {2,1});
-
     // computing odometry
+    auto       so_T_si = laser::trf2isometry(trf_origin_incoming_.res_transf);
     auto       so_T_sl = laser::trf2isometry(trf_origin_last_.res_transf);
     Isometry2d sl_T_si = so_T_sl.inverse() * so_T_si;
     odometry_['P'] = sl_T_si.translation();
@@ -230,36 +216,15 @@ void ProcessorOdomIcp::advanceDerived()
 
 void ProcessorOdomIcp::resetDerived()
 {
-    // WOLF_DEBUG("NDEBUG origin ", origin_ptr_->id(), " last ", last_ptr_->id(), " error ", trf_origin_last_.error, " merror ", trf_origin_last_.error/(double) trf_origin_last_.nvalid, " nvalid ", trf_origin_last_.nvalid, " sqrt diag. ", trf_origin_last_.res_covar.diagonal().cwiseSqrt().transpose(), " trnsf ", trf_origin_last_.res_transf.transpose());
-    if (origin_ptr_ != nullptr and last_ptr_ != nullptr)
-    {
-        //
-    }
-
     // Using processing_step_ to ensure that origin, last and incoming are different
-    if (processing_step_ != FIRST_TIME_WITH_KEYFRAME && processing_step_ != FIRST_TIME_WITHOUT_KEYFRAME) {
+    if (processing_step_ != FIRST_TIME_WITH_KEYFRAME && processing_step_ != FIRST_TIME_WITHOUT_KEYFRAME)
+    {
         // Notation explanation:
         // x1_R_x2: Rotation from frame x1 to frame x2
         // x1_p_y1_y2: translation vector from y1 to y2 expressed in frame x1
 
-
-        auto  w_T_ro = laser::trf2isometry(origin_ptr_->getFrame()->getP()->getState(), origin_ptr_->getFrame()->getO()->getState());
-        auto ro_T_so = laser::trf2isometry(origin_ptr_->getSensorP()->getState(), origin_ptr_->getSensorO()->getState());
-        const auto &ri_T_si = ro_T_so; // A reference just to have nice names without computing overhead
-
-        // incoming
-
-        auto      so_T_si = laser::trf2isometry(trf_origin_incoming_.res_transf);
-        Isometry2d w_T_ri = w_T_ro * ro_T_so * so_T_si * ri_T_si.inverse();
-        Vector3d x_current;
-        x_current << w_T_ri.translation(), Rotation2Dd(w_T_ri.rotation()).angle();
-
-        // last
-
-        // last_ptr_->getFrame()->setState(x_current, "PO", {2,1});
-        // incoming_ptr_->getFrame()->setState(x_current);
-
         // computing odometry
+        auto       so_T_si = laser::trf2isometry(trf_origin_incoming_.res_transf);
         auto       so_T_sl = laser::trf2isometry(trf_origin_last_.res_transf);
         Isometry2d sl_T_si = so_T_sl.inverse() * so_T_si;
         odometry_['P'] = sl_T_si.translation();
@@ -321,11 +286,8 @@ VectorComposite ProcessorOdomIcp::getState( const StateStructure& _structure ) c
     auto ro_T_so = laser::trf2isometry(origin_ptr_->getSensorP()->getState(), origin_ptr_->getSensorO()->getState());
     const auto& rl_T_sl = ro_T_so; // A reference just to have nice names without computing overhead
 
-    // incoming
-
     auto      so_T_sl = laser::trf2isometry(trf_origin_last_.res_transf);
     Isometry2d w_T_rl = w_T_ro * ro_T_so * so_T_sl * rl_T_sl.inverse();
-    Vector3d x_current;
 
     VectorComposite state("PO", {w_T_rl.translation(), Vector1d(Rotation2Dd(w_T_rl.rotation()).angle())});
 
@@ -344,7 +306,7 @@ VectorComposite ProcessorOdomIcp::getState(const TimeStamp& _ts, const StateStru
 {
     // todo fix this code to get any state in the whole trajectory!
 
-
+    //
     if (last_ptr_ != nullptr)
     {
         double d = fabs(_ts - last_ptr_->getTimeStamp());
@@ -358,8 +320,9 @@ VectorComposite ProcessorOdomIcp::getState(const TimeStamp& _ts, const StateStru
             return getProblem()->stateZero("PO"); // return zero
         }
     }
-
-    else { // return state at origin if possible
+    // return state at origin if possible
+    else
+    {
         if (origin_ptr_ == nullptr || fabs(_ts - last_ptr_->getTimeStamp()) > params_->time_tolerance)
             return VectorComposite("PO", {Vector2d(0,0), Vector1d(0)});
         else
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 75cecdb4bec2513ac44e59bf0cc276f9ccdad93f..c75a1957be69ff023966f3c9d0c59dd1fd7eb0f6 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -1,7 +1,6 @@
 # Retrieve googletest from github & compile
 add_subdirectory(gtest)
 
-
 # Include gtest directory.
 include_directories(${GTEST_INCLUDE_DIRS})
 
@@ -17,12 +16,22 @@ wolf_add_gtest(gtest_landmark_polyline gtest_landmark_polyline.cpp)
 target_link_libraries(gtest_landmark_polyline ${PLUGIN_NAME})
 
 if(csm_FOUND)
-  wolf_add_gtest(gtest_processor_odom_icp gtest_processor_odom_icp.cpp)
-  target_link_libraries(gtest_processor_odom_icp ${PLUGIN_NAME})
+	wolf_add_gtest(gtest_processor_odom_icp gtest_processor_odom_icp.cpp)
+	target_link_libraries(gtest_processor_odom_icp ${PLUGIN_NAME} ${wolf_LIBRARY})
+	
+	wolf_add_gtest(gtest_processor_loop_closure_icp gtest_processor_loop_closure_icp.cpp)
+	target_link_libraries(gtest_processor_loop_closure_icp ${PLUGIN_NAME} ${wolf_LIBRARY})
 endif(csm_FOUND)
 
 wolf_add_gtest(gtest_polyline_2d gtest_polyline_2d.cpp)
 target_link_libraries(gtest_polyline_2d ${PLUGIN_NAME})
 
-# wolf_add_gtest(gtest_processor_tracker_feature_polyline_2d gtest_processor_tracker_feature_polyline_2d.cpp)
-# target_link_libraries(gtest_processor_tracker_feature_polyline_2d ${PLUGIN_NAME})
+if(falkolib_FOUND)
+	wolf_add_gtest(gtest_processor_loop_closure_falko gtest_processor_loop_closure_falko.cpp)
+	target_link_libraries(gtest_processor_loop_closure_falko ${PLUGIN_NAME} ${wolf_LIBRARY})
+
+	if(csm_FOUND)
+    	wolf_add_gtest(gtest_processor_loop_closure_falko_icp gtest_processor_loop_closure_falko_icp.cpp)
+    	target_link_libraries(gtest_processor_loop_closure_falko_icp ${PLUGIN_NAME} ${wolf_LIBRARY})
+  	endif(csm_FOUND)
+endif(falkolib_FOUND)
diff --git a/test/data/scan_data.h b/test/data/scan_data.h
new file mode 100644
index 0000000000000000000000000000000000000000..bb09376965e24d8f448cd2e8f5e96d0886850d35
--- /dev/null
+++ b/test/data/scan_data.h
@@ -0,0 +1,2929 @@
+//--------LICENSE_START--------
+//
+// Copyright (C) 2020,2021 Institut de Robòtica i Informàtica Industrial, CSIC-UPC.
+// Authors: Joan Solà Ortega (jsola@iri.upc.edu)
+// All rights reserved.
+//
+// This file is part of WOLF
+// WOLF is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+//--------LICENSE_END--------
+/**
+ * FALKOLib - Fast Adaptive Laser Keypoint Orientation-invariant
+ * Copyright (C) 2016 Fabjan Kallasi and Dario Lodi Rizzini.
+ *
+ * This file is part of FALKOLib.
+ *
+ * FALKOLib is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * FALKOLib is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with FALKOLib.  If not, see <http://www.gnu.org/licenses/>.
+ */
+std::vector<float> testRanges1 = {250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        17.263999938964844,
+                        17.263999938964844,
+                        17.263999938964844,
+                        17.263999938964844,
+                        13.552000045776367,
+                        13.552000045776367,
+                        13.552000045776367,
+                        12.95199966430664,
+                        12.95199966430664,
+                        12.95199966430664,
+                        12.95199966430664,
+                        12.51200008392334,
+                        11.567999839782715,
+                        11.567999839782715,
+                        10.720000267028809,
+                        10.720000267028809,
+                        10.720000267028809,
+                        10.359999656677246,
+                        10.336000442504883,
+                        10.343999862670898,
+                        10.35200023651123,
+                        10.35200023651123,
+                        10.32800006866455,
+                        10.319999694824219,
+                        10.383999824523926,
+                        10.407999992370605,
+                        10.432000160217285,
+                        10.432000160217285,
+                        10.447999954223633,
+                        10.46399974822998,
+                        10.46399974822998,
+                        10.503999710083008,
+                        10.503999710083008,
+                        10.527999877929688,
+                        10.592000007629395,
+                        10.62399959564209,
+                        8.368000030517578,
+                        8.343999862670898,
+                        8.343999862670898,
+                        8.031999588012695,
+                        7.831999778747559,
+                        7.6479997634887695,
+                        7.552000045776367,
+                        7.415999889373779,
+                        7.415999889373779,
+                        7.263999938964844,
+                        7.144000053405762,
+                        7.0320000648498535,
+                        6.920000076293945,
+                        6.776000022888184,
+                        6.776000022888184,
+                        6.671999931335449,
+                        6.576000213623047,
+                        6.440000057220459,
+                        6.328000068664551,
+                        6.271999835968018,
+                        6.271999835968018,
+                        6.263999938964844,
+                        6.271999835968018,
+                        6.296000003814697,
+                        6.320000171661377,
+                        6.328000068664551,
+                        6.328000068664551,
+                        6.335999965667725,
+                        6.320000171661377,
+                        3.187999963760376,
+                        3.187999963760376,
+                        4.495999813079834,
+                        4.495999813079834,
+                        4.495999813079834,
+                        4.495999813079834,
+                        4.504000186920166,
+                        4.504000186920166,
+                        4.504000186920166,
+                        4.544000148773193,
+                        4.544000148773193,
+                        4.544000148773193,
+                        4.544000148773193,
+                        4.51200008392334,
+                        4.51200008392334,
+                        4.51200008392334,
+                        4.51200008392334,
+                        4.599999904632568,
+                        4.576000213623047,
+                        4.495999813079834,
+                        4.455999851226807,
+                        4.455999851226807,
+                        4.455999851226807,
+                        4.455999851226807,
+                        4.4079999923706055,
+                        4.368000030517578,
+                        4.320000171661377,
+                        4.271999835968018,
+                        4.271999835968018,
+                        4.223999977111816,
+                        4.184000015258789,
+                        4.168000221252441,
+                        4.159999847412109,
+                        4.168000221252441,
+                        4.176000118255615,
+                        4.176000118255615,
+                        4.184000015258789,
+                        4.199999809265137,
+                        4.199999809265137,
+                        4.208000183105469,
+                        4.216000080108643,
+                        4.216000080108643,
+                        4.223999977111816,
+                        4.23199987411499,
+                        4.23199987411499,
+                        4.176000118255615,
+                        250,
+                        250,
+                        4.111999988555908,
+                        4.111999988555908,
+                        4.111999988555908,
+                        4.111999988555908,
+                        4.099999904632568,
+                        4.099999904632568,
+                        4.099999904632568,
+                        4.079999923706055,
+                        4.0320000648498535,
+                        3.98799991607666,
+                        3.9719998836517334,
+                        3.9719998836517334,
+                        3.9560000896453857,
+                        3.9240000247955322,
+                        3.888000011444092,
+                        3.859999895095825,
+                        3.8320000171661377,
+                        3.8320000171661377,
+                        3.803999900817871,
+                        3.7880001068115234,
+                        3.259999990463257,
+                        3.240000009536743,
+                        3.2200000286102295,
+                        3.2200000286102295,
+                        3.200000047683716,
+                        3.1760001182556152,
+                        3.1559998989105225,
+                        3.1440000534057617,
+                        3.128000020980835,
+                        3.128000020980835,
+                        3.119999885559082,
+                        2.5959999561309814,
+                        2.5959999561309814,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        2.4839999675750732,
+                        2.4839999675750732,
+                        2.4839999675750732,
+                        2.4839999675750732,
+                        2.496000051498413,
+                        2.5320000648498535,
+                        250,
+                        2.624000072479248,
+                        2.624000072479248,
+                        2.624000072479248,
+                        2.624000072479248,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        2.6679999828338623,
+                        2.6679999828338623,
+                        2.6679999828338623,
+                        2.6679999828338623,
+                        2.640000104904175,
+                        2.640000104904175,
+                        2.640000104904175,
+                        2.628000020980835,
+                        2.615999937057495,
+                        2.615999937057495,
+                        2.6080000400543213,
+                        2.5959999561309814,
+                        2.5880000591278076,
+                        2.5759999752044678,
+                        2.563999891281128,
+                        2.563999891281128,
+                        2.555999994277954,
+                        2.5439999103546143,
+                        2.5320000648498535,
+                        2.5199999809265137,
+                        2.51200008392334,
+                        2.51200008392334,
+                        2.503999948501587,
+                        2.492000102996826,
+                        2.4839999675750732,
+                        2.4719998836517334,
+                        2.4639999866485596,
+                        2.4639999866485596,
+                        2.4600000381469727,
+                        2.4519999027252197,
+                        2.440000057220459,
+                        2.431999921798706,
+                        2.4200000762939453,
+                        2.4200000762939453,
+                        2.4159998893737793,
+                        2.4079999923706055,
+                        2.4079999923706055,
+                        2.427999973297119,
+                        2.444000005722046,
+                        2.444000005722046,
+                        2.4600000381469727,
+                        2.4719998836517334,
+                        2.48799991607666,
+                        2.5,
+                        2.5160000324249268,
+                        2.5160000324249268,
+                        2.5280001163482666,
+                        2.5399999618530273,
+                        2.559999942779541,
+                        2.5799999237060547,
+                        2.5840001106262207,
+                        2.5840001106262207,
+                        3.0480000972747803,
+                        3.0480000972747803,
+                        2.631999969482422,
+                        2.631999969482422,
+                        2.631999969482422,
+                        2.624000072479248,
+                        2.624000072479248,
+                        2.624000072479248,
+                        2.624000072479248,
+                        2.615999937057495,
+                        2.611999988555908,
+                        2.6040000915527344,
+                        2.6040000915527344,
+                        2.5959999561309814,
+                        2.5920000076293945,
+                        2.5840001106262207,
+                        2.5759999752044678,
+                        2.572000026702881,
+                        2.572000026702881,
+                        2.563999891281128,
+                        2.555999994277954,
+                        2.5480000972747803,
+                        2.5439999103546143,
+                        2.5399999618530273,
+                        2.5399999618530273,
+                        2.5360000133514404,
+                        2.5320000648498535,
+                        2.5239999294281006,
+                        2.5199999809265137,
+                        2.507999897003174,
+                        2.507999897003174,
+                        2.503999948501587,
+                        2.5,
+                        2.496000051498413,
+                        2.492000102996826,
+                        2.48799991607666,
+                        2.48799991607666,
+                        2.4800000190734863,
+                        2.4760000705718994,
+                        2.4719998836517334,
+                        2.4679999351501465,
+                        2.4639999866485596,
+                        2.4560000896453857,
+                        2.4560000896453857,
+                        2.4519999027252197,
+                        2.447999954223633,
+                        2.447999954223633,
+                        2.444000005722046,
+                        2.436000108718872,
+                        2.436000108718872,
+                        2.431999921798706,
+                        2.427999973297119,
+                        2.4240000247955322,
+                        2.4240000247955322,
+                        2.4200000762939453,
+                        2.4200000762939453,
+                        2.4159998893737793,
+                        2.4079999923706055,
+                        2.4040000438690186,
+                        2.4040000438690186,
+                        2.4000000953674316,
+                        2.4000000953674316,
+                        2.3959999084472656,
+                        2.3919999599456787,
+                        2.3919999599456787,
+                        2.388000011444092,
+                        2.384000062942505,
+                        2.384000062942505,
+                        2.380000114440918,
+                        2.375999927520752,
+                        2.371999979019165,
+                        2.371999979019165,
+                        2.368000030517578,
+                        2.364000082015991,
+                        2.364000082015991,
+                        2.364000082015991,
+                        2.364000082015991,
+                        2.359999895095825,
+                        2.3559999465942383,
+                        2.3559999465942383,
+                        2.3559999465942383,
+                        2.6600000858306885,
+                        2.6600000858306885,
+                        2.6600000858306885,
+                        2.003999948501587,
+                        2.003999948501587,
+                        2.003999948501587,
+                        2.003999948501587,
+                        2.003999948501587,
+                        2.003999948501587,
+                        2.003999948501587,
+                        2.0,
+                        2.0,
+                        2.0,
+                        2.0,
+                        1.9980000257492065,
+                        1.9980000257492065,
+                        1.9980000257492065,
+                        1.9980000257492065,
+                        1.996000051498413,
+                        1.996000051498413,
+                        1.996000051498413,
+                        1.99399995803833,
+                        1.9919999837875366,
+                        1.996000051498413,
+                        1.996000051498413,
+                        1.996000051498413,
+                        1.996000051498413,
+                        1.996000051498413,
+                        1.99399995803833,
+                        2.0,
+                        2.0,
+                        2.009999990463257,
+                        2.0220000743865967,
+                        2.0460000038146973,
+                        2.0460000038146973,
+                        2.0260000228881836,
+                        2.0260000228881836,
+                        2.00600004196167,
+                        1.996000051498413,
+                        1.99399995803833,
+                        1.9900000095367432,
+                        1.9919999837875366,
+                        1.9919999837875366,
+                        1.996000051498413,
+                        1.9980000257492065,
+                        1.99399995803833,
+                        1.9919999837875366,
+                        1.9919999837875366,
+                        1.9919999837875366,
+                        1.99399995803833,
+                        1.99399995803833,
+                        1.996000051498413,
+                        1.9980000257492065,
+                        1.9980000257492065,
+                        1.9980000257492065,
+                        1.9980000257492065,
+                        2.0,
+                        2.0,
+                        1.9980000257492065,
+                        1.9980000257492065,
+                        1.9919999837875366,
+                        1.9520000219345093,
+                        2.0320000648498535,
+                        2.0999999046325684,
+                        2.1040000915527344,
+                        2.1040000915527344,
+                        2.0280001163482666,
+                        1.9040000438690186,
+                        1.9279999732971191,
+                        1.9520000219345093,
+                        1.9559999704360962,
+                        1.9559999704360962,
+                        1.9600000381469727,
+                        1.9579999446868896,
+                        1.9600000381469727,
+                        1.9620000123977661,
+                        1.9639999866485596,
+                        1.9639999866485596,
+                        1.965999960899353,
+                        1.965999960899353,
+                        1.968000054359436,
+                        1.972000002861023,
+                        1.9759999513626099,
+                        1.9759999513626099,
+                        1.9759999513626099,
+                        1.9759999513626099,
+                        1.9800000190734863,
+                        1.9839999675750732,
+                        1.9800000190734863,
+                        1.9800000190734863,
+                        1.9819999933242798,
+                        1.9880000352859497,
+                        1.996000051498413,
+                        2.009999990463257,
+                        2.00600004196167,
+                        2.00600004196167,
+                        1.99399995803833,
+                        2.687999963760376,
+                        2.687999963760376,
+                        2.687999963760376,
+                        1.74399995803833,
+                        1.74399995803833,
+                        2.063999891281128,
+                        2.115999937057495,
+                        2.196000099182129,
+                        2.191999912261963,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        2.5280001163482666,
+                        2.5280001163482666,
+                        2.5280001163482666,
+                        2.5280001163482666,
+                        2.5199999809265137,
+                        2.5239999294281006,
+                        2.5239999294281006,
+                        2.5239999294281006,
+                        2.5239999294281006,
+                        2.5239999294281006,
+                        2.5280001163482666,
+                        2.5280001163482666,
+                        2.5239999294281006,
+                        2.5239999294281006,
+                        2.5239999294281006,
+                        2.5239999294281006,
+                        2.5239999294281006,
+                        2.5239999294281006,
+                        2.5239999294281006,
+                        2.5239999294281006,
+                        2.5239999294281006,
+                        2.5280001163482666,
+                        2.5239999294281006,
+                        2.5280001163482666,
+                        2.5280001163482666,
+                        2.5280001163482666,
+                        2.5280001163482666,
+                        2.5280001163482666,
+                        2.5320000648498535,
+                        2.5320000648498535,
+                        2.5320000648498535,
+                        2.5320000648498535,
+                        2.5320000648498535,
+                        2.5320000648498535,
+                        2.5360000133514404,
+                        2.5399999618530273,
+                        2.5480000972747803,
+                        2.5480000972747803,
+                        2.5480000972747803,
+                        2.5399999618530273,
+                        2.5439999103546143,
+                        2.552000045776367,
+                        2.555999994277954,
+                        2.555999994277954,
+                        2.552000045776367,
+                        2.5480000972747803,
+                        250,
+                        1.3179999589920044,
+                        1.3179999589920044,
+                        1.3179999589920044,
+                        1.3179999589920044,
+                        1.3079999685287476,
+                        1.2999999523162842,
+                        1.2940000295639038,
+                        1.2940000295639038,
+                        1.2879999876022339,
+                        1.2860000133514404,
+                        1.2940000295639038,
+                        1.3040000200271606,
+                        1.3040000200271606,
+                        1.3040000200271606,
+                        1.2999999523162842,
+                        1.2979999780654907,
+                        1.3020000457763672,
+                        1.309999942779541,
+                        1.3140000104904175,
+                        1.3140000104904175,
+                        1.3140000104904175,
+                        1.3240000009536743,
+                        1.3359999656677246,
+                        1.3420000076293945,
+                        1.343999981880188,
+                        1.343999981880188,
+                        1.2200000286102295,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        1.093999981880188,
+                        1.093999981880188,
+                        1.093999981880188,
+                        1.093999981880188,
+                        1.090000033378601,
+                        1.090000033378601,
+                        1.0920000076293945,
+                        1.0980000495910645,
+                        1.0980000495910645,
+                        1.100000023841858,
+                        1.100000023841858,
+                        1.100000023841858,
+                        1.100000023841858,
+                        1.0980000495910645,
+                        1.0980000495910645,
+                        1.0980000495910645,
+                        1.0959999561309814,
+                        1.093999981880188,
+                        1.093999981880188,
+                        1.093999981880188,
+                        1.093999981880188,
+                        1.093999981880188,
+                        1.0920000076293945,
+                        1.093999981880188,
+                        1.093999981880188,
+                        1.093999981880188,
+                        1.1019999980926514,
+                        1.1119999885559082,
+                        1.121999979019165,
+                        1.1260000467300415,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        5.791999816894531,
+                        5.791999816894531,
+                        5.791999816894531,
+                        5.791999816894531,
+                        5.776000022888184,
+                        5.776000022888184,
+                        5.776000022888184,
+                        5.751999855041504,
+                        5.751999855041504,
+                        5.751999855041504,
+                        5.751999855041504,
+                        5.751999855041504,
+                        5.736000061035156,
+                        5.679999828338623,
+                        5.671999931335449,
+                        5.671999931335449,
+                        5.631999969482422,
+                        5.631999969482422,
+                        5.552000045776367,
+                        5.552000045776367,
+                        5.552000045776367,
+                        5.552000045776367,
+                        5.559999942779541,
+                        5.584000110626221,
+                        6.104000091552734,
+                        6.783999919891357,
+                        6.831999778747559,
+                        6.831999778747559,
+                        6.831999778747559,
+                        6.760000228881836,
+                        6.616000175476074,
+                        6.455999851226807,
+                        6.343999862670898,
+                        6.343999862670898,
+                        6.320000171661377,
+                        6.311999797821045,
+                        9.192000389099121,
+                        9.175999641418457,
+                        9.15999984741211,
+                        9.15999984741211,
+                        9.128000259399414,
+                        9.119999885559082,
+                        7.992000102996826,
+                        7.9120001792907715,
+                        7.8480000495910645,
+                        7.8480000495910645,
+                        7.800000190734863,
+                        7.74399995803833,
+                        7.71999979019165,
+                        7.711999893188477,
+                        7.711999893188477,
+                        7.711999893188477,
+                        7.711999893188477,
+                        7.71999979019165,
+                        7.71999979019165,
+                        7.711999893188477,
+                        7.703999996185303,
+                        7.703999996185303,
+                        7.703999996185303,
+                        7.688000202178955,
+                        7.688000202178955,
+                        7.688000202178955,
+                        7.688000202178955,
+                        7.671999931335449,
+                        8.67199993133545,
+                        8.640000343322754,
+                        8.607999801635742,
+                        8.583999633789062,
+                        8.583999633789062,
+                        8.5600004196167,
+                        8.552000045776367,
+                        8.53600025177002,
+                        8.520000457763672,
+                        8.503999710083008,
+                        8.503999710083008,
+                        8.472000122070312,
+                        8.447999954223633,
+                        8.416000366210938,
+                        8.383999824523926,
+                        8.383999824523926,
+                        8.383999824523926,
+                        8.368000030517578,
+                        8.35200023651123,
+                        8.35200023651123,
+                        8.336000442504883,
+                        8.303999900817871,
+                        8.303999900817871,
+                        8.263999938964844,
+                        8.239999771118164,
+                        8.279999732971191,
+                        8.392000198364258,
+                        8.496000289916992,
+                        8.496000289916992,
+                        8.656000137329102,
+                        8.807999610900879,
+                        8.928000450134277,
+                        9.015999794006348,
+                        11.767999649047852,
+                        11.767999649047852,
+                        12.071999549865723,
+                        12.175999641418457,
+                        12.567999839782715,
+                        12.663999557495117,
+                        13.064000129699707,
+                        13.064000129699707,
+                        13.168000221252441,
+                        13.607999801635742,
+                        13.640000343322754,
+                        13.53600025177002,
+                        13.968000411987305,
+                        13.968000411987305,
+                        14.008000373840332,
+                        14.104000091552734,
+                        14.175999641418457,
+                        14.104000091552734,
+                        15.4399995803833,
+                        15.4399995803833,
+                        15.543999671936035,
+                        15.48799991607666,
+                        15.48799991607666,
+                        15.503999710083008,
+                        15.479999542236328,
+                        15.479999542236328,
+                        15.447999954223633,
+                        15.399999618530273,
+                        15.37600040435791,
+                        15.35200023651123,
+                        15.319999694824219,
+                        15.319999694824219,
+                        15.272000312805176,
+                        15.272000312805176,
+                        15.336000442504883,
+                        15.303999900817871,
+                        15.248000144958496,
+                        15.248000144958496,
+                        14.744000434875488,
+                        15.303999900817871,
+                        15.272000312805176,
+                        15.248000144958496,
+                        15.215999603271484,
+                        15.223999977111816,
+                        15.223999977111816,
+                        15.248000144958496,
+                        16.784000396728516,
+                        16.719999313354492,
+                        16.719999313354492,
+                        16.719999313354492,
+                        16.719999313354492,
+                        16.672000885009766,
+                        16.687999725341797,
+                        16.719999313354492,
+                        16.70400047302246,
+                        16.607999801635742,
+                        16.607999801635742,
+                        16.624000549316406,
+                        16.6560001373291,
+                        16.23200035095215,
+                        16.143999099731445,
+                        16.06399917602539,
+                        16.06399917602539,
+                        16.016000747680664,
+                        17.472000122070312,
+                        19.007999420166016,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250};
+
+std::vector<float> testRanges2 = {250,
+                        250,
+                        250,
+                        250,
+                        16.799999237060547,
+                        16.799999237060547,
+                        16.799999237060547,
+                        16.799999237060547,
+                        14.095999717712402,
+                        14.095999717712402,
+                        14.095999717712402,
+                        14.095999717712402,
+                        13.255999565124512,
+                        13.255999565124512,
+                        13.255999565124512,
+                        12.767999649047852,
+                        12.175999641418457,
+                        12.175999641418457,
+                        10.911999702453613,
+                        10.4399995803833,
+                        10.4399995803833,
+                        10.4399995803833,
+                        10.32800006866455,
+                        10.32800006866455,
+                        10.32800006866455,
+                        10.343999862670898,
+                        10.336000442504883,
+                        10.312000274658203,
+                        10.368000030517578,
+                        10.368000030517578,
+                        10.407999992370605,
+                        10.472000122070312,
+                        10.48799991607666,
+                        10.520000457763672,
+                        10.48799991607666,
+                        10.48799991607666,
+                        10.472000122070312,
+                        10.503999710083008,
+                        10.51200008392334,
+                        10.51200008392334,
+                        10.520000457763672,
+                        10.520000457763672,
+                        8.295999526977539,
+                        8.13599967956543,
+                        7.984000205993652,
+                        7.791999816894531,
+                        7.624000072479248,
+                        7.624000072479248,
+                        7.5279998779296875,
+                        7.4079999923706055,
+                        7.263999938964844,
+                        7.119999885559082,
+                        7.007999897003174,
+                        7.007999897003174,
+                        6.9120001792907715,
+                        6.760000228881836,
+                        6.639999866485596,
+                        6.544000148773193,
+                        6.415999889373779,
+                        6.415999889373779,
+                        6.311999797821045,
+                        6.271999835968018,
+                        6.263999938964844,
+                        6.288000106811523,
+                        6.303999900817871,
+                        6.303999900817871,
+                        6.320000171661377,
+                        6.335999965667725,
+                        6.343999862670898,
+                        6.335999965667725,
+                        6.303999900817871,
+                        6.303999900817871,
+                        6.271999835968018,
+                        4.5920000076293945,
+                        250,
+                        4.480000019073486,
+                        4.480000019073486,
+                        4.480000019073486,
+                        4.480000019073486,
+                        4.4720001220703125,
+                        4.504000186920166,
+                        4.519999980926514,
+                        4.5279998779296875,
+                        4.5279998779296875,
+                        4.5279998779296875,
+                        4.5279998779296875,
+                        4.567999839782715,
+                        4.559999942779541,
+                        250,
+                        4.48799991607666,
+                        4.48799991607666,
+                        4.48799991607666,
+                        4.48799991607666,
+                        4.440000057220459,
+                        4.392000198364258,
+                        4.360000133514404,
+                        4.360000133514404,
+                        4.320000171661377,
+                        4.263999938964844,
+                        4.223999977111816,
+                        4.191999912261963,
+                        4.168000221252441,
+                        4.168000221252441,
+                        4.168000221252441,
+                        4.176000118255615,
+                        4.176000118255615,
+                        4.191999912261963,
+                        4.208000183105469,
+                        4.208000183105469,
+                        4.208000183105469,
+                        4.216000080108643,
+                        4.216000080108643,
+                        4.216000080108643,
+                        4.23199987411499,
+                        4.23199987411499,
+                        4.223999977111816,
+                        4.184000015258789,
+                        250,
+                        4.136000156402588,
+                        4.136000156402588,
+                        4.136000156402588,
+                        4.136000156402588,
+                        4.111999988555908,
+                        4.111999988555908,
+                        4.0960001945495605,
+                        4.064000129699707,
+                        4.015999794006348,
+                        4.015999794006348,
+                        3.9839999675750732,
+                        3.9679999351501465,
+                        3.947999954223633,
+                        3.9119999408721924,
+                        3.875999927520752,
+                        3.875999927520752,
+                        3.8480000495910645,
+                        3.8239998817443848,
+                        3.7039999961853027,
+                        3.5920000076293945,
+                        3.259999990463257,
+                        3.259999990463257,
+                        3.240000009536743,
+                        3.2160000801086426,
+                        3.196000099182129,
+                        3.171999931335449,
+                        3.1519999504089355,
+                        3.1519999504089355,
+                        3.140000104904175,
+                        3.124000072479248,
+                        3.115999937057495,
+                        2.5959999561309814,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        2.51200008392334,
+                        2.51200008392334,
+                        2.51200008392334,
+                        2.51200008392334,
+                        2.5320000648498535,
+                        2.5320000648498535,
+                        2.5320000648498535,
+                        2.6040000915527344,
+                        2.6040000915527344,
+                        2.6040000915527344,
+                        2.6040000915527344,
+                        250,
+                        250,
+                        250,
+                        2.6480000019073486,
+                        2.6480000019073486,
+                        2.6480000019073486,
+                        2.6480000019073486,
+                        250,
+                        250,
+                        250,
+                        2.6480000019073486,
+                        2.6480000019073486,
+                        2.6480000019073486,
+                        2.6480000019073486,
+                        2.635999917984009,
+                        2.628000020980835,
+                        2.619999885559082,
+                        2.619999885559082,
+                        2.6080000400543213,
+                        2.5959999561309814,
+                        2.5880000591278076,
+                        2.5759999752044678,
+                        2.563999891281128,
+                        2.563999891281128,
+                        2.552000045776367,
+                        2.5399999618530273,
+                        2.5280001163482666,
+                        2.5199999809265137,
+                        2.51200008392334,
+                        2.51200008392334,
+                        2.5,
+                        2.48799991607666,
+                        2.4839999675750732,
+                        2.4719998836517334,
+                        2.4639999866485596,
+                        2.4639999866485596,
+                        2.4560000896453857,
+                        2.444000005722046,
+                        2.436000108718872,
+                        2.431999921798706,
+                        2.4200000762939453,
+                        2.4200000762939453,
+                        2.4159998893737793,
+                        2.4159998893737793,
+                        2.4200000762939453,
+                        2.431999921798706,
+                        2.444000005722046,
+                        2.4600000381469727,
+                        2.4600000381469727,
+                        2.4760000705718994,
+                        2.48799991607666,
+                        2.5,
+                        2.5160000324249268,
+                        2.5360000133514404,
+                        2.5360000133514404,
+                        2.5480000972747803,
+                        2.563999891281128,
+                        2.5840001106262207,
+                        2.7079999446868896,
+                        2.684000015258789,
+                        2.684000015258789,
+                        2.5880000591278076,
+                        2.5880000591278076,
+                        2.5880000591278076,
+                        2.631999969482422,
+                        2.631999969482422,
+                        2.631999969482422,
+                        2.631999969482422,
+                        2.624000072479248,
+                        2.615999937057495,
+                        2.611999988555908,
+                        2.6040000915527344,
+                        2.6040000915527344,
+                        2.5920000076293945,
+                        2.5880000591278076,
+                        2.5840001106262207,
+                        2.5759999752044678,
+                        2.572000026702881,
+                        2.559999942779541,
+                        2.559999942779541,
+                        2.552000045776367,
+                        2.5480000972747803,
+                        2.5439999103546143,
+                        2.5399999618530273,
+                        2.5320000648498535,
+                        2.5320000648498535,
+                        2.5280001163482666,
+                        2.5239999294281006,
+                        2.5160000324249268,
+                        2.507999897003174,
+                        2.503999948501587,
+                        2.503999948501587,
+                        2.5,
+                        2.492000102996826,
+                        2.492000102996826,
+                        2.4839999675750732,
+                        2.4800000190734863,
+                        2.4800000190734863,
+                        2.4760000705718994,
+                        2.4719998836517334,
+                        2.4679999351501465,
+                        2.4600000381469727,
+                        2.4600000381469727,
+                        2.4519999027252197,
+                        2.447999954223633,
+                        2.447999954223633,
+                        2.447999954223633,
+                        2.440000057220459,
+                        2.440000057220459,
+                        2.431999921798706,
+                        2.427999973297119,
+                        2.427999973297119,
+                        2.4240000247955322,
+                        2.4200000762939453,
+                        2.4200000762939453,
+                        2.4159998893737793,
+                        2.4119999408721924,
+                        2.4079999923706055,
+                        2.4040000438690186,
+                        2.4000000953674316,
+                        2.4000000953674316,
+                        2.4000000953674316,
+                        2.3959999084472656,
+                        2.3919999599456787,
+                        2.388000011444092,
+                        2.384000062942505,
+                        2.384000062942505,
+                        2.384000062942505,
+                        2.380000114440918,
+                        2.375999927520752,
+                        2.371999979019165,
+                        2.371999979019165,
+                        2.371999979019165,
+                        2.368000030517578,
+                        2.364000082015991,
+                        2.364000082015991,
+                        2.364000082015991,
+                        2.364000082015991,
+                        2.364000082015991,
+                        2.359999895095825,
+                        2.371999979019165,
+                        2.388000011444092,
+                        2.388000011444092,
+                        2.003999948501587,
+                        2.003999948501587,
+                        2.003999948501587,
+                        2.003999948501587,
+                        2.002000093460083,
+                        2.002000093460083,
+                        2.002000093460083,
+                        2.002000093460083,
+                        2.002000093460083,
+                        1.9980000257492065,
+                        1.9980000257492065,
+                        1.996000051498413,
+                        1.996000051498413,
+                        1.996000051498413,
+                        1.9980000257492065,
+                        1.996000051498413,
+                        1.996000051498413,
+                        1.996000051498413,
+                        1.996000051498413,
+                        1.996000051498413,
+                        1.99399995803833,
+                        1.9919999837875366,
+                        1.99399995803833,
+                        1.9919999837875366,
+                        1.9919999837875366,
+                        1.9919999837875366,
+                        1.996000051498413,
+                        1.996000051498413,
+                        2.0,
+                        2.009999990463257,
+                        2.009999990463257,
+                        2.0320000648498535,
+                        2.0480000972747803,
+                        2.0320000648498535,
+                        2.0179998874664307,
+                        2.007999897003174,
+                        2.007999897003174,
+                        1.996000051498413,
+                        1.9919999837875366,
+                        1.9900000095367432,
+                        1.9880000352859497,
+                        1.99399995803833,
+                        1.99399995803833,
+                        1.99399995803833,
+                        1.99399995803833,
+                        1.996000051498413,
+                        1.996000051498413,
+                        1.996000051498413,
+                        1.996000051498413,
+                        1.996000051498413,
+                        1.99399995803833,
+                        1.99399995803833,
+                        1.9980000257492065,
+                        1.9980000257492065,
+                        2.0,
+                        2.002000093460083,
+                        2.0,
+                        2.002000093460083,
+                        1.9759999513626099,
+                        1.9759999513626099,
+                        1.9359999895095825,
+                        2.0360000133514404,
+                        2.0859999656677246,
+                        2.0439999103546143,
+                        1.9819999933242798,
+                        1.9819999933242798,
+                        1.9279999732971191,
+                        1.9559999704360962,
+                        1.9559999704360962,
+                        1.9600000381469727,
+                        1.9579999446868896,
+                        1.9559999704360962,
+                        1.9559999704360962,
+                        1.9579999446868896,
+                        1.9620000123977661,
+                        1.9639999866485596,
+                        1.968000054359436,
+                        1.9700000286102295,
+                        1.9700000286102295,
+                        1.972000002861023,
+                        1.9739999771118164,
+                        1.9739999771118164,
+                        1.9739999771118164,
+                        1.9780000448226929,
+                        1.9780000448226929,
+                        1.9839999675750732,
+                        1.9859999418258667,
+                        1.9859999418258667,
+                        1.9900000095367432,
+                        1.99399995803833,
+                        1.99399995803833,
+                        1.996000051498413,
+                        1.99399995803833,
+                        1.9980000257492065,
+                        2.003999948501587,
+                        2.003999948501587,
+                        2.003999948501587,
+                        2.003999948501587,
+                        2.5999999046325684,
+                        1.6720000505447388,
+                        2.0480000972747803,
+                        2.115999937057495,
+                        2.115999937057495,
+                        2.191999912261963,
+                        2.196000099182129,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        2.5160000324249268,
+                        2.5160000324249268,
+                        2.5160000324249268,
+                        2.5160000324249268,
+                        2.5160000324249268,
+                        2.5160000324249268,
+                        2.5160000324249268,
+                        2.5239999294281006,
+                        2.5280001163482666,
+                        2.5280001163482666,
+                        2.5280001163482666,
+                        2.5280001163482666,
+                        2.5280001163482666,
+                        2.5280001163482666,
+                        2.5280001163482666,
+                        2.5239999294281006,
+                        2.5239999294281006,
+                        2.5239999294281006,
+                        2.5239999294281006,
+                        2.5239999294281006,
+                        2.5239999294281006,
+                        2.5239999294281006,
+                        2.5239999294281006,
+                        2.5280001163482666,
+                        2.5320000648498535,
+                        2.5320000648498535,
+                        2.5239999294281006,
+                        2.5239999294281006,
+                        2.5280001163482666,
+                        2.5320000648498535,
+                        2.5320000648498535,
+                        2.5320000648498535,
+                        2.5320000648498535,
+                        2.5320000648498535,
+                        2.5360000133514404,
+                        2.5360000133514404,
+                        2.5360000133514404,
+                        2.5360000133514404,
+                        2.5399999618530273,
+                        2.5439999103546143,
+                        2.5439999103546143,
+                        2.5439999103546143,
+                        2.5439999103546143,
+                        2.5439999103546143,
+                        2.5480000972747803,
+                        2.555999994277954,
+                        2.559999942779541,
+                        1.315999984741211,
+                        1.315999984741211,
+                        1.315999984741211,
+                        1.315999984741211,
+                        1.3040000200271606,
+                        1.3040000200271606,
+                        1.2979999780654907,
+                        1.2920000553131104,
+                        1.2920000553131104,
+                        1.2860000133514404,
+                        1.2899999618530273,
+                        1.2999999523162842,
+                        1.3020000457763672,
+                        1.3020000457763672,
+                        1.3020000457763672,
+                        1.2999999523162842,
+                        1.2960000038146973,
+                        1.3020000457763672,
+                        1.312000036239624,
+                        1.315999984741211,
+                        1.315999984741211,
+                        1.3179999589920044,
+                        1.3279999494552612,
+                        1.3359999656677246,
+                        1.3420000076293945,
+                        1.2200000286102295,
+                        1.2200000286102295,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        1.090000033378601,
+                        1.090000033378601,
+                        1.090000033378601,
+                        1.090000033378601,
+                        1.0880000591278076,
+                        1.0880000591278076,
+                        1.0880000591278076,
+                        1.0920000076293945,
+                        1.0959999561309814,
+                        1.0980000495910645,
+                        1.0980000495910645,
+                        1.0980000495910645,
+                        1.0980000495910645,
+                        1.0980000495910645,
+                        1.0980000495910645,
+                        1.0959999561309814,
+                        1.0959999561309814,
+                        1.0959999561309814,
+                        1.0959999561309814,
+                        1.093999981880188,
+                        1.093999981880188,
+                        1.093999981880188,
+                        1.0920000076293945,
+                        1.0920000076293945,
+                        1.0920000076293945,
+                        1.0920000076293945,
+                        1.093999981880188,
+                        1.1019999980926514,
+                        1.1139999628067017,
+                        1.1239999532699585,
+                        1.1239999532699585,
+                        1.1299999952316284,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        5.888000011444092,
+                        5.888000011444092,
+                        5.888000011444092,
+                        5.888000011444092,
+                        5.863999843597412,
+                        5.863999843597412,
+                        5.808000087738037,
+                        5.751999855041504,
+                        5.751999855041504,
+                        5.74399995803833,
+                        5.74399995803833,
+                        5.656000137329102,
+                        5.656000137329102,
+                        5.656000137329102,
+                        5.584000110626221,
+                        5.584000110626221,
+                        5.584000110626221,
+                        5.584000110626221,
+                        5.552000045776367,
+                        5.559999942779541,
+                        5.599999904632568,
+                        5.599999904632568,
+                        6.71999979019165,
+                        6.783999919891357,
+                        6.831999778747559,
+                        6.815999984741211,
+                        6.696000099182129,
+                        6.552000045776367,
+                        6.552000045776367,
+                        6.423999786376953,
+                        6.343999862670898,
+                        6.328000068664551,
+                        9.232000350952148,
+                        9.192000389099121,
+                        9.192000389099121,
+                        9.175999641418457,
+                        9.144000053405762,
+                        9.039999961853027,
+                        8.960000038146973,
+                        7.943999767303467,
+                        7.943999767303467,
+                        7.863999843597412,
+                        7.8480000495910645,
+                        7.791999816894531,
+                        7.751999855041504,
+                        7.736000061035156,
+                        7.736000061035156,
+                        7.71999979019165,
+                        7.728000164031982,
+                        7.728000164031982,
+                        7.711999893188477,
+                        7.696000099182129,
+                        7.696000099182129,
+                        7.688000202178955,
+                        7.696000099182129,
+                        7.696000099182129,
+                        7.688000202178955,
+                        7.688000202178955,
+                        7.688000202178955,
+                        7.736000061035156,
+                        7.800000190734863,
+                        8.616000175476074,
+                        8.600000381469727,
+                        8.600000381469727,
+                        8.576000213623047,
+                        8.543999671936035,
+                        8.520000457763672,
+                        8.51200008392334,
+                        8.496000289916992,
+                        8.496000289916992,
+                        8.472000122070312,
+                        8.456000328063965,
+                        8.4399995803833,
+                        8.4399995803833,
+                        8.423999786376953,
+                        8.423999786376953,
+                        8.383999824523926,
+                        8.37600040435791,
+                        8.37600040435791,
+                        8.368000030517578,
+                        8.35200023651123,
+                        8.35200023651123,
+                        8.35200023651123,
+                        8.312000274658203,
+                        8.248000144958496,
+                        8.223999977111816,
+                        8.288000106811523,
+                        8.288000106811523,
+                        8.4399995803833,
+                        8.607999801635742,
+                        8.776000022888184,
+                        8.895999908447266,
+                        9.064000129699707,
+                        9.064000129699707,
+                        9.168000221252441,
+                        11.84000015258789,
+                        12.175999641418457,
+                        12.312000274658203,
+                        12.656000137329102,
+                        12.656000137329102,
+                        12.767999649047852,
+                        13.208000183105469,
+                        13.35200023651123,
+                        13.656000137329102,
+                        13.64799976348877,
+                        13.64799976348877,
+                        13.527999877929688,
+                        14.015999794006348,
+                        13.960000038146973,
+                        14.119999885559082,
+                        14.255999565124512,
+                        14.255999565124512,
+                        13.784000396728516,
+                        15.407999992370605,
+                        15.496000289916992,
+                        15.53600025177002,
+                        15.423999786376953,
+                        15.423999786376953,
+                        15.37600040435791,
+                        15.416000366210938,
+                        15.423999786376953,
+                        15.383999824523926,
+                        15.343999862670898,
+                        15.343999862670898,
+                        15.368000030517578,
+                        15.32800006866455,
+                        15.255999565124512,
+                        15.272000312805176,
+                        15.272000312805176,
+                        15.272000312805176,
+                        15.215999603271484,
+                        15.272000312805176,
+                        15.295999526977539,
+                        15.208000183105469,
+                        15.215999603271484,
+                        15.215999603271484,
+                        15.208000183105469,
+                        15.208000183105469,
+                        15.192000389099121,
+                        15.168000221252441,
+                        15.168000221252441,
+                        16.719999313354492,
+                        16.719999313354492,
+                        16.639999389648438,
+                        16.6560001373291,
+                        16.719999313354492,
+                        16.719999313354492,
+                        16.639999389648438,
+                        16.672000885009766,
+                        16.687999725341797,
+                        16.54400062561035,
+                        16.576000213623047,
+                        16.6560001373291,
+                        16.6560001373291,
+                        16.27199935913086,
+                        16.583999633789062,
+                        16.079999923706055,
+                        16.399999618530273,
+                        16.736000061035156,
+                        16.736000061035156,
+                        16.143999099731445,
+                        250,
+                        20.304000854492188,
+                        20.304000854492188,
+                        20.304000854492188,
+                        20.304000854492188,
+                        250,
+                        250,
+                        250,
+                        20.20800018310547,
+                        20.20800018310547,
+                        20.20800018310547,
+                        20.20800018310547,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250,
+                        250};
+
+// std::vector<float> target_scan_1 = {2.03169,1.9677,2.02369,2.01969,1.9517,1.93171,1.93171,1.89171,1.92771,1.92771,1.89171,1.85172,1.83172,1.85972,1.85172,1.79173,1.55576,1.54376,1.53577,1.49577,1.49577,1.49577,1.45178,1.47977,1.47977,1.45578,1.59576,250,250,250,1.59576,1.59576,1.59576,1.59576,1.54776,1.55176,1.53577,1.53577,1.51977,1.50377,1.49577,1.48377,1.47977,1.44378,1.47178,1.47578,1.44378,1.42378,1.41978,1.42778,1.42378,1.41179,1.3198,1.26781,1.22781,1.24781,1.21981,1.20782,1.23581,1.19582,1.22781,1.19982,1.17982,1.20382,1.17582,1.17982,1.16782,1.16382,1.15582,1.15182,1.15982,1.14783,1.13183,1.14783,1.12383,1.15182,1.14383,1.13583,1.24781,1.24781,1.19582,1.2958,1.3118,1.3038,1.2958,1.2998,1.2998,1.3038,1.2978,1.2858,1.2818,1.27581,1.2838,1.2878,1.27981,1.3078,1.2898,1.27781,1.2878,1.27981,1.3018,1.2998,1.2938,1.2958,250,250,1.19582,1.21182,1.20382,1.18382,1.23581,1.19582,250,250,250,1.9777,1.9837,1.9777,1.9857,1.9917,2.09168,250,4.49132,4.48732,4.48332,4.48532,4.47732,4.47132,4.48532,4.47332,4.47532,4.46332,4.47332,4.47132,4.46332,4.49931,4.96124,5.04323,6.571,6.567,6.579,6.579,6.64299,7.55685,7.52685,7.56485,7.93079,250,250,8.70467,8.69668,8.69268,8.72067,8.72067,8.72067,8.73267,8.73667,8.76467,8.76267,8.76467,5.01924,5.01524,5.02723,5.02723,5.03123,5.05523,5.04323,5.07123,5.07123,5.07123,5.09722,5.01924,4.92325,4.68529,4.64729,4.66929,4.66529,4.68929,4.68729,4.70128,4.71728,4.70928,4.73928,4.74928,4.75128,4.76927,4.76327,4.79527,4.79527,4.80927,4.82926,4.83526,4.85326,4.86926,4.86726,4.88926,4.90725,4.92325,4.94325,4.95125,4.97124,5.00524,3.13952,3.11753,3.06953,3.03754,2.99154,2.96555,2.91156,2.87756,2.83757,2.22366,2.18967,2.16167,2.15367,2.15167,2.14167,2.17367,2.16767,2.16367,2.18567,2.32765,2.37964,2.44363,2.43163,2.41763,2.38564,2.37364,2.34164,2.30165,2.27565,2.26965,2.30565,2.31765,2.33764,2.34364,2.36164,2.37364,2.38364,2.40563,2.41163,2.41963,2.44163,2.45363,2.47362,2.48362,2.49162,2.51162,2.52961,2.55961,2.56561,2.57361,2.5996,2.6136,2.6396,2.6576,2.66959,2.69559,250,2.71959,7.15891,7.17491,7.2469,7.27889,7.37888,9.08662,9.06062,8.99063,8.90664,8.84865,8.76266,8.68668,8.67868,8.66668,8.66268,8.73067,8.81066,8.91064,9.01063,9.11461,9.2106,9.28259,9.43456,9.49056,9.62653,9.73252,9.8625,9.96848,10.0825,10.2244,10.3484,10.4724,10.6244,10.7524,10.9003,11.0623,11.2203,11.4623,11.6362,11.8122,11.9922,3.79342,3.78142,3.77343,3.76743,3.75143,3.73943,3.73743,3.71743,3.71143,3.70544,3.69144,3.68544,3.67344,3.67544,3.66144,3.63945,3.64145,3.62945,3.63345,3.61745,3.61345,3.61145,3.60345,3.60345,3.58545,3.58545,3.57746,3.55746,3.56946,3.56946,3.54746,3.55546,3.53346,3.54146,3.53346,3.52746,3.52146,3.50947,3.51547,3.50547,3.48947,3.50347,3.49947,3.50147,3.48547,3.47747,3.49147,3.47947,1.90571,1.90571,2.38764,2.37764,2.36764,3.47747,3.47747,3.45947,3.46147,3.46547,3.47747,3.45747,3.46747,3.48147,3.46747,3.47947,3.48147,3.46147,3.47947,3.47347,3.48147,3.47347,3.47147,2.38764,2.36364,1.90171,1.88771,1.88771,3.48547,3.59145,5.19121,4.08338,3.88341,3.69544,3.58345,4.18136,4.17536,3.2915,2.89156,2.83157,2.77958,2.79157,2.82357,2.81957,2.82557,2.84357,250,250,1.9677,2.0037,250,250,2.87956,2.86156,2.85956,2.87756,2.87356,2.89956,2.89956,2.89356,2.91356,2.90756,2.92955,4.41933,4.42333,4.44332,4.44332,4.47132,4.47532,1.43178,1.42778,1.37579,1.35979,1.3418,1.3298,1.3098,1.2858,1.2938,1.2818,1.25581,1.34779,1.44978,1.46778,1.47178,1.48177,1.49377,1.49177,1.51777,1.51377,1.49977,1.51977,1.52377,1.54376,1.54976,1.54376,1.55976,1.55976,1.57176,1.57576,1.57576,1.59176,1.59376,1.60975,1.61575,1.61975,1.62775,1.63775,1.65375,1.65175,1.66575,1.68174,1.68174,1.69774,1.70574,1.70574,1.73174,1.72774,1.75173,1.74973,1.76573,1.77573,1.78573,1.80573,1.81372,1.81372,1.83372,1.84572,1.86772,1.87571,1.88771,1.91171,1.92571,1.93371,1.9597,1.9637,1.9917,1.9857,2.01969,2.03169,2.03569,2.05969,2.07168,2.09368,2.11768,2.13168,2.15967,2.16967,2.19967,2.21566,2.23166,2.25966,2.28365,2.27765,2.25766,2.23566,2.23166,2.21166,2.21966,2.20766,2.19767,2.21566,2.24766,4.41933,4.39133,4.38333,4.37533,4.35134,4.32334,4.30334,4.29935,4.28335,4.29135,4.25935,4.24335,4.21536,4.21136,4.19536,4.19536,4.17137,4.15137,4.15137,4.11537,4.12737,4.09538,3.79542,3.79142,3.87541,3.9314,4.03139,4.45332,4.44332,3.04754,3.03554,3.05353,3.08753,2.98755,2.98755,3.21951,3.2715,3.07753,3.03954,3.03554,2.85357,2.86556,2.91156,2.90956,3.01554,3.03754,3.01754,3.00754,2.89556,2.90156,2.88556,3.02154,3.37349,3.33949,2.95155,2.92156,2.91956,2.91156,2.91156,2.91956,2.95155,2.99954,3.2595,3.65944,4.18736,4.18336,4.19536,4.19536,2.79557,2.93355,2.97955,3.01954,3.03554,3.05554,3.08753,3.08753,3.12552,3.12552,3.12952,3.15352,3.13952,3.17352,3.69944,3.82142,3.89141,250,2.19167,2.17967,2.13567,2.08368,2.04369,2.04369,1.9837,1.9677,1.92371,1.69174,1.64975,1.63375,1.62775,1.62775,1.62375,1.63375,1.63775,1.64175,1.65775,1.67774,1.68774,1.90371,1.9477,1.9837,1.9797,1.9877,1.9757,1.93171,1.9557,1.9437,1.9637,1.89171,1.78173,1.76173,1.75173,1.76573,1.74573,1.73974,1.76373,1.75973,1.77973,1.77373,1.75373,1.79573,4.64729,4.6193,4.63129,4.63929,4.65529,4.67529,4.70328,4.71928,4.70328,4.33934,250,4.11537,4.09938,4.07538,4.01739,3.98539,3.98339,3.9614,3.97539,4.01539,1.70574,1.67774,1.65975,1.66575,1.64775,1.63975,1.62175,1.59976,1.65175,1.68974,1.69974,1.69774,1.63975,1.64575,1.63175,1.63575,1.64975,1.62775,1.63975,1.64575,1.64375,1.65375,1.64975,1.65175,1.65575,1.65775,1.67574,1.67175,1.68974,1.68974,1.69974,1.70574,1.71774,1.72974,1.73574,1.76173,1.76973,1.78373,1.81972,1.89171,250,250,250,250,5.05923,5.16521,5.15122,5.10922,5.09722,5.05923,5.03123,5.00924,4.97724,4.95525,4.92925,4.90325,4.89126,4.85326,4.85126,4.81727,4.52731,4.51531,4.49132,4.48332,4.45932,4.43532,4.42333,4.39533,4.39333,4.37533,4.35734,4.33134,4.31334,4.30534,4.28735,4.32134,4.38733,4.43732,4.47332,4.44732,4.43332,4.42533,4.26935,3.82742,3.81542,3.79942,3.80142,3.77942,3.77543,3.76943,3.74143,3.73943,3.72143,3.71543,3.69544,3.67544,3.65944,3.64345,3.63945,3.65744,3.63945,3.63345,3.61545,3.62345,3.60345,3.60545,3.58145,3.57146,2.75158,2.77758,2.77158,2.74758,2.71159,2.70559,2.68359,2.69559,2.71359,2.73358,2.75958,2.75758,2.81357,2.82957,3.00354,3.18152,3.2755,3.2735,3.2635,3.2615,3.2595,3.23951,3.24951,3.24351,3.23151,3.23951,3.22351,2.99754,2.98355,2.98555,2.99154,2.97555,2.99954,2.99154,2.98155,2.99354,2.97155,2.97755,2.97355,2.97755,2.98355,2.98155,2.98954,2.98755,2.97555,2.98555,2.96555,2.99154,4.01739,4.02139,4.02339,3.72943,3.57946,3.44348,3.2695,3.2555,3.2695,3.2755,3.2695,3.2735,3.2915,3.2815,3.3015,3.3075,3.3095,3.31949,3.3155,3.33749,3.32749,3.32749,4.04538,4.04738,4.12537,3.9674,3.82942,3.69744,3.51147,3.46547,3.48147,3.41148,3.46947,4.21136,4.21936,4.21936,4.23136,4.24935,4.25135,4.26135,3.56346,3.50347,3.45147,3.40548,3.40348,3.38348,3.38748,3.38149,3.37749,3.39948,3.39948,3.43748,3.47347,3.49947,3.59145,3.85141,3.84541,4.47132,4.52331,4.54331,3.9334,4.5813,4.17736,4.5953,4.62929,2.25366,2.19966,2.18567,2.17967,2.19967,2.23166,250,3.41948,2.06369,2.09168,2.07168,2.06369,2.07168,1.9917,1.9917};
+// std::vector<float> reference_scan_1 = {3.64145,3.66544,3.62545,3.62945,3.61945,3.61545,2.81157,2.77558,2.77758,2.74958,2.73158,2.72159,2.73358,2.75158,2.78158,2.78558,2.80757,2.83557,2.87756,3.2835,3.2935,3.2995,3.2955,3.2915,3.2915,3.2775,3.2835,3.2635,3.2755,3.2655,3.2535,3.2595,3.20351,3.04754,3.04354,4.01539,3.08353,3.07153,3.07753,3.06953,3.06553,3.06753,3.05553,3.06353,3.04354,3.03154,3.00954,3.00554,3.02954,250,2.99354,2.99554,4.01739,4.03539,4.03339,3.84741,3.61545,3.56346,3.35149,3.2675,3.2695,3.2815,3.2795,3.2955,3.2995,3.2955,3.3155,3.3155,3.33149,3.32349,3.32349,3.35149,3.33549,3.36549,4.08338,4.07138,4.10937,4.01539,3.86741,3.71343,3.47947,3.48547,3.48747,3.43148,3.48547,3.48147,4.22736,4.22936,4.25335,4.24735,4.24735,4.26935,4.27135,3.51946,4.27735,3.43148,3.40348,3.39148,3.39548,3.38948,3.38548,3.39748,3.40148,3.41148,3.45347,3.47147,3.51946,250,3.84541,4.37333,4.51931,4.53131,4.54331,3.9414,2.94555,2.91956,2.93555,2.21166,2.17767,2.18167,2.16767,2.17767,2.04769,1.91971,1.85572,1.9917,250,250,250,250,1.9917,1.9917,1.9917,1.9917,2.03169,1.9917,1.9517,1.9597,1.90771,1.86772,1.87971,1.87971,1.85972,1.85172,1.82772,1.79173,1.53977,1.52777,1.50777,1.50777,1.47977,1.47977,1.47977,1.45178,1.43978,1.46778,1.46778,1.42378,250,250,1.59576,250,1.59576,250,1.59576,1.52377,1.51577,1.48377,1.49577,1.47977,1.48377,1.48377,1.46778,1.44778,1.44378,1.41978,1.44778,1.41978,1.41179,1.43978,1.39579,1.40379,1.26781,1.21581,1.22381,1.20382,1.23181,1.19582,1.20382,1.18382,1.16382,1.16982,1.15582,1.16182,1.16782,1.14583,1.13983,1.13983,1.14183,1.14183,1.13183,1.12383,1.13583,1.11583,1.12383,1.13983,1.09983,1.09583,1.09983,1.09583,1.13183,1.19582,250,250,1.3158,1.27181,1.2838,1.27181,1.27181,1.27981,1.25181,1.27581,1.27781,1.26381,1.26781,1.25781,1.25781,1.25781,1.25781,1.26781,1.26781,1.25181,1.27781,1.27581,1.2958,250,250,250,1.23581,1.17982,1.16582,1.19582,1.23581,250,250,250,1.9617,1.9537,1.9397,1.9657,1.9617,1.9517,1.9597,250,4.47732,4.45932,4.45532,4.45732,4.45332,4.45532,4.45332,4.44732,4.45532,4.44332,4.44932,4.43932,4.43932,4.43932,4.43532,4.86526,4.95725,6.575,6.551,6.543,6.555,6.559,250,250,250,250,250,7.58685,8.64468,8.64468,8.65868,8.66468,8.66268,8.68068,8.69068,8.70467,8.70867,8.71067,8.73867,8.73067,4.98324,4.99124,4.98724,5.01124,5.00324,5.00924,5.01524,5.01724,5.04323,5.03923,5.04323,4.99924,4.88326,4.67129,4.6093,4.6213,4.6313,4.63329,4.64729,4.66729,4.65929,4.68129,4.69129,4.71128,4.72328,4.72928,4.75328,4.74928,4.77127,4.77527,4.78727,4.81127,4.81527,4.82726,4.84726,4.85326,4.88326,4.88126,4.90925,4.91725,4.92725,4.96124,3.09553,3.10153,3.04554,2.98755,2.94555,2.91556,2.87756,2.83157,2.79557,2.77558,2.43763,2.13767,2.13368,2.10168,2.11168,2.10368,2.13567,2.13168,2.14567,2.28165,2.31565,2.39164,2.40163,2.38564,2.36164,2.32165,2.30965,2.26566,2.22366,2.23366,2.24166,2.27765,2.29165,2.30165,2.31965,2.32165,2.33964,2.36564,2.36564,2.38764,2.39763,2.40963,2.41763,2.42563,2.44963,2.45563,2.47162,2.48962,2.50562,2.54361,2.54561,2.56361,2.58561,2.59361,2.6296,2.6456,2.6576,2.67759,2.67359,7.15891,7.17091,7.2349,7.29889,7.35888,9.08062,8.99263,8.91664,8.85065,8.76867,8.71067,8.64268,8.74867,8.58669,8.65868,8.75467,8.84265,8.91464,9.04262,9.10661,9.23859,9.33058,9.44656,9.55455,9.65853,9.77851,9.88649,10.0185,10.1425,10.2704,10.4224,10.5384,10.6944,10.8423,10.9863,11.1423,11.3983,11.5582,11.7342,11.9262,12.0302,3.76743,3.74743,3.74543,3.72543,3.73343,3.70944,3.70744,3.68944,3.68144,3.68744,3.67544,3.66144,3.66544,3.64944,3.63745,3.63545,3.61745,3.62145,3.60945,3.59745,3.59345,3.58145,3.58545,3.56746,3.57146,3.55346,3.54546,3.55746,3.53746,3.53546,3.53746,3.52546,3.52746,3.51546,3.50747,3.50747,3.48947,3.49547,3.49147,3.47547,3.48347,3.48147,3.48147,3.47747,3.46147,3.47147,3.46347,3.47147,3.45947,1.86972,1.87771,2.33164,2.37564,3.44548,3.44548,3.46347,3.45147,3.46547,3.46547,3.44148,3.45747,3.43148,3.45947,3.45747,3.44947,3.46147,3.44947,3.46547,3.45147,3.45347,3.46347,2.36564,2.37564,2.34364,1.87771,1.87971,1.87371,250,4.19936,4.01939,3.83942,3.63945,3.58545,4.16936,4.16337,3.32349,2.99154,2.82357,2.75958,2.75558,2.78558,2.80357,2.80757,2.81757,2.79957,250,250,250,2.01169,250,250,250,2.87356,2.87156,2.86556,2.88756,2.88156,2.88156,2.89556,2.90356,2.91756,2.92355,4.41333,4.43532,4.43532,4.45932,4.46932,4.46932,4.50331,4.50731,1.42378,1.40379,1.36379,1.37179,1.3378,1.3318,1.3018,1.2978,1.2858,1.26781,1.2998,1.43978,1.45178,1.48177,1.47178,1.49977,1.49377,1.50577,1.51177,1.50977,1.53177,1.53177,1.52377,1.55376,1.55176,1.56976,1.57176,1.57176,1.59576,1.59176,1.60376,1.61375,1.61175,1.62575,1.62975,1.64575,1.65175,1.64975,1.66775,1.67375,1.69374,1.70974,1.70374,1.71974,1.71774,1.72374,1.74973,1.75173,1.77573,1.77373,1.78773,1.80972,1.80972,1.82972,1.83772,1.84772,1.86572,1.86972,1.89771,1.91371,1.92171,1.9457,1.9557,1.9777,1.9917,2.00569,2.01969,2.02769,2.06769,2.07968,2.08768,2.11568,2.13168,2.16367,2.17167,2.17967,2.22366,2.23566,2.26765,2.27565,2.29565,2.28965,2.25566,2.26765,2.24366,2.23366,2.21966,2.22366,2.22566,2.22166,4.43133,4.41933,4.39133,4.35934,4.35534,4.32734,4.33134,4.29135,4.29935,4.29135,4.27535,4.27935,4.24335,4.23935,4.20336,4.19136,4.18336,4.16337,4.16737,4.13537,4.11537,4.08738,3.83142,3.86741,3.89141,4.04338,4.11137,4.47332,4.45732,4.45332,4.43532,4.43932,4.42133,4.40933,4.40333,4.38333,3.10353,3.09153,3.07153,3.08353,3.09553,3.09753,3.02154,2.98755,3.15552,3.39148,3.10553,3.09753,2.93955,2.87156,2.87156,2.89156,2.95155,3.02354,3.06753,3.04954,3.06353,3.04354,3.03954,2.97955,2.94955,3.2835,4.21536,3.00354,2.99954,2.96755,2.97155,2.96755,2.97955,2.98555,3.03154,3.57546,4.21136,4.21536,4.22336,4.21136,4.23535,2.86356,2.92755,2.99354,3.03154,3.06753,3.08553,3.09553,3.12752,3.13552,3.15752,3.16152,3.15752,3.18152,3.17152,3.85341,3.86341,3.87941,250,2.20766,2.12768,2.07168,2.05969,2.04369,1.9877,1.9557,1.85372,1.77973,1.72174,1.68174,1.65975,1.65175,1.65375,1.66375,1.65975,1.66575,1.68374,1.67574,1.71174,1.76373,1.82372,1.84372,1.84372,1.84972,1.85572,1.86372,1.87971,1.87371,1.88571,1.90171,1.86972,1.80572,1.78173,1.79373,1.78573,1.78173,1.79373,1.78373,1.79773,1.79773,1.79773,1.81172,1.86372,4.67129,4.67529,4.69129,4.71528,4.71928,4.75928,4.76727,4.36733,4.46732,4.46732,4.09938,4.06338,4.03738,4.03339,4.01339,4.00139,1.75373,1.70974,1.70774,1.68174,1.67175,1.66975,1.65375,1.66775,1.65575,1.63975,1.64775,1.62975,1.64175,1.63975,1.64775,1.64175,1.64175,1.65175,1.65375,1.66375,1.66775,1.66775,1.68974,1.68974,1.69974,1.71774,1.72574,1.73574,1.73774,1.78173,1.79573,1.81172,1.85572,1.88971,250,250,250,250,5.19121,5.2252,5.20121,5.16921,5.14122,5.09522,5.07923,5.07123,5.02723,5.01724,4.98524,4.96524,4.94725,4.90725,4.90125,4.86126,4.84526,4.82127,4.79527,4.77927,4.76327,4.73528,4.72928,4.69129,4.64329,4.48532,4.47732,4.6153,4.5973,4.5893,4.5633,4.54531,4.53731,4.51131,4.50731,4.48932,4.46932,4.45932,3.99139,3.85941,3.84341,3.82742,3.82742,3.80342,3.81142,3.78742,3.77742,3.76543,3.74343,3.74743,3.72143,3.70544,3.69744,3.67344,3.66744,3.67744,3.66344,3.67144};
+
+std::vector<float> reference_scan_1 ={3.64145,3.66544,3.62545,3.62945,3.61945,3.61545,2.81157,2.77558,2.77758,2.74958,2.73158,2.72159,2.73358,2.75158,2.78158,2.78558,2.80757,2.83557,2.87756,3.2835,3.2935,3.2995,3.2955,3.2915,3.2915,3.2775,3.2835,3.2635,3.2755,3.2655,3.2535,3.2595,3.20351,3.04754,3.04354,4.01539,3.08353,3.07153,3.07753,3.06953,3.06553,3.06753,3.05553,3.06353,3.04354,3.03154,3.00954,3.00554,3.02954,250,2.99354,2.99554,4.01739,4.03539,4.03339,3.84741,3.61545,3.56346,3.35149,3.2675,3.2695,3.2815,3.2795,3.2955,3.2995,3.2955,3.3155,3.3155,3.33149,3.32349,3.32349,3.35149,3.33549,3.36549,4.08338,4.07138,4.10937,4.01539,3.86741,3.71343,3.47947,3.48547,3.48747,3.43148,3.48547,3.48147,4.22736,4.22936,4.25335,4.24735,4.24735,4.26935,4.27135,3.51946,4.27735,3.43148,3.40348,3.39148,3.39548,3.38948,3.38548,3.39748,3.40148,3.41148,3.45347,3.47147,3.51946,250,3.84541,4.37333,4.51931,4.53131,4.54331,3.9414,2.94555,2.91956,2.93555,2.21166,2.17767,2.18167,2.16767,2.17767,2.04769,1.91971,1.85572,1.9917,250,250,250,250,1.9917,1.9917,1.9917,1.9917,2.03169,1.9917,1.9517,1.9597,1.90771,1.86772,1.87971,1.87971,1.85972,1.85172,1.82772,1.79173,1.53977,1.52777,1.50777,1.50777,1.47977,1.47977,1.47977,1.45178,1.43978,1.46778,1.46778,1.42378,250,250,1.59576,250,1.59576,250,1.59576,1.52377,1.51577,1.48377,1.49577,1.47977,1.48377,1.48377,1.46778,1.44778,1.44378,1.41978,1.44778,1.41978,1.41179,1.43978,1.39579,1.40379,1.26781,1.21581,1.22381,1.20382,1.23181,1.19582,1.20382,1.18382,1.16382,1.16982,1.15582,1.16182,1.16782,1.14583,1.13983,1.13983,1.14183,1.14183,1.13183,1.12383,1.13583,1.11583,1.12383,1.13983,1.09983,1.09583,1.09983,1.09583,1.13183,1.19582,250,250,1.3158,1.27181,1.2838,1.27181,1.27181,1.27981,1.25181,1.27581,1.27781,1.26381,1.26781,1.25781,1.25781,1.25781,1.25781,1.26781,1.26781,1.25181,1.27781,1.27581,1.2958,250,250,250,1.23581,1.17982,1.16582,1.19582,1.23581,250,250,250,1.9617,1.9537,1.9397,1.9657,1.9617,1.9517,1.9597,250,4.47732,4.45932,4.45532,4.45732,4.45332,4.45532,4.45332,4.44732,4.45532,4.44332,4.44932,4.43932,4.43932,4.43932,4.43532,4.86526,4.95725,6.575,6.551,6.543,6.555,6.559,250,250,250,250,250,7.58685,8.64468,8.64468,8.65868,8.66468,8.66268,8.68068,8.69068,8.70467,8.70867,8.71067,8.73867,8.73067,4.98324,4.99124,4.98724,5.01124,5.00324,5.00924,5.01524,5.01724,5.04323,5.03923,5.04323,4.99924,4.88326,4.67129,4.6093,4.6213,4.6313,4.63329,4.64729,4.66729,4.65929,4.68129,4.69129,4.71128,4.72328,4.72928,4.75328,4.74928,4.77127,4.77527,4.78727,4.81127,4.81527,4.82726,4.84726,4.85326,4.88326,4.88126,4.90925,4.91725,4.92725,4.96124,3.09553,3.10153,3.04554,2.98755,2.94555,2.91556,2.87756,2.83157,2.79557,2.77558,2.43763,2.13767,2.13368,2.10168,2.11168,2.10368,2.13567,2.13168,2.14567,2.28165,2.31565,2.39164,2.40163,2.38564,2.36164,2.32165,2.30965,2.26566,2.22366,2.23366,2.24166,2.27765,2.29165,2.30165,2.31965,2.32165,2.33964,2.36564,2.36564,2.38764,2.39763,2.40963,2.41763,2.42563,2.44963,2.45563,2.47162,2.48962,2.50562,2.54361,2.54561,2.56361,2.58561,2.59361,2.6296,2.6456,2.6576,2.67759,2.67359,7.15891,7.17091,7.2349,7.29889,7.35888,9.08062,8.99263,8.91664,8.85065,8.76867,8.71067,8.64268,8.74867,8.58669,8.65868,8.75467,8.84265,8.91464,9.04262,9.10661,9.23859,9.33058,9.44656,9.55455,9.65853,9.77851,9.88649,10.0185,10.1425,10.2704,10.4224,10.5384,10.6944,10.8423,10.9863,11.1423,11.3983,11.5582,11.7342,11.9262,12.0302,3.76743,3.74743,3.74543,3.72543,3.73343,3.70944,3.70744,3.68944,3.68144,3.68744,3.67544,3.66144,3.66544,3.64944,3.63745,3.63545,3.61745,3.62145,3.60945,3.59745,3.59345,3.58145,3.58545,3.56746,3.57146,3.55346,3.54546,3.55746,3.53746,3.53546,3.53746,3.52546,3.52746,3.51546,3.50747,3.50747,3.48947,3.49547,3.49147,3.47547,3.48347,3.48147,3.48147,3.47747,3.46147,3.47147,3.46347,3.47147,3.45947,1.86972,1.87771,2.33164,2.37564,3.44548,3.44548,3.46347,3.45147,3.46547,3.46547,3.44148,3.45747,3.43148,3.45947,3.45747,3.44947,3.46147,3.44947,3.46547,3.45147,3.45347,3.46347,2.36564,2.37564,2.34364,1.87771,1.87971,1.87371,250,4.19936,4.01939,3.83942,3.63945,3.58545,4.16936,4.16337,3.32349,2.99154,2.82357,2.75958,2.75558,2.78558,2.80357,2.80757,2.81757,2.79957,250,250,250,2.01169,250,250,250,2.87356,2.87156,2.86556,2.88756,2.88156,2.88156,2.89556,2.90356,2.91756,2.92355,4.41333,4.43532,4.43532,4.45932,4.46932,4.46932,4.50331,4.50731,1.42378,1.40379,1.36379,1.37179,1.3378,1.3318,1.3018,1.2978,1.2858,1.26781,1.2998,1.43978,1.45178,1.48177,1.47178,1.49977,1.49377,1.50577,1.51177,1.50977,1.53177,1.53177,1.52377,1.55376,1.55176,1.56976,1.57176,1.57176,1.59576,1.59176,1.60376,1.61375,1.61175,1.62575,1.62975,1.64575,1.65175,1.64975,1.66775,1.67375,1.69374,1.70974,1.70374,1.71974,1.71774,1.72374,1.74973,1.75173,1.77573,1.77373,1.78773,1.80972,1.80972,1.82972,1.83772,1.84772,1.86572,1.86972,1.89771,1.91371,1.92171,1.9457,1.9557,1.9777,1.9917,2.00569,2.01969,2.02769,2.06769,2.07968,2.08768,2.11568,2.13168,2.16367,2.17167,2.17967,2.22366,2.23566,2.26765,2.27565,2.29565,2.28965,2.25566,2.26765,2.24366,2.23366,2.21966,2.22366,2.22566,2.22166,4.43133,4.41933,4.39133,4.35934,4.35534,4.32734,4.33134,4.29135,4.29935,4.29135,4.27535,4.27935,4.24335,4.23935,4.20336,4.19136,4.18336,4.16337,4.16737,4.13537,4.11537,4.08738,3.83142,3.86741,3.89141,4.04338,4.11137,4.47332,4.45732,4.45332,4.43532,4.43932,4.42133,4.40933,4.40333,4.38333,3.10353,3.09153,3.07153,3.08353,3.09553,3.09753,3.02154,2.98755,3.15552,3.39148,3.10553,3.09753,2.93955,2.87156,2.87156,2.89156,2.95155,3.02354,3.06753,3.04954,3.06353,3.04354,3.03954,2.97955,2.94955,3.2835,4.21536,3.00354,2.99954,2.96755,2.97155,2.96755,2.97955,2.98555,3.03154,3.57546,4.21136,4.21536,4.22336,4.21136,4.23535,2.86356,2.92755,2.99354,3.03154,3.06753,3.08553,3.09553,3.12752,3.13552,3.15752,3.16152,3.15752,3.18152,3.17152,3.85341,3.86341,3.87941,250,2.20766,2.12768,2.07168,2.05969,2.04369,1.9877,1.9557,1.85372,1.77973,1.72174,1.68174,1.65975,1.65175,1.65375,1.66375,1.65975,1.66575,1.68374,1.67574,1.71174,1.76373,1.82372,1.84372,1.84372,1.84972,1.85572,1.86372,1.87971,1.87371,1.88571,1.90171,1.86972,1.80572,1.78173,1.79373,1.78573,1.78173,1.79373,1.78373,1.79773,1.79773,1.79773,1.81172,1.86372,4.67129,4.67529,4.69129,4.71528,4.71928,4.75928,4.76727,4.36733,4.46732,4.46732,4.09938,4.06338,4.03738,4.03339,4.01339,4.00139,1.75373,1.70974,1.70774,1.68174,1.67175,1.66975,1.65375,1.66775,1.65575,1.63975,1.64775,1.62975,1.64175,1.63975,1.64775,1.64175,1.64175,1.65175,1.65375,1.66375,1.66775,1.66775,1.68974,1.68974,1.69974,1.71774,1.72574,1.73574,1.73774,1.78173,1.79573,1.81172,1.85572,1.88971,250,250,250,250,5.19121,5.2252,5.20121,5.16921,5.14122,5.09522,5.07923,5.07123,5.02723,5.01724,4.98524,4.96524,4.94725,4.90725,4.90125,4.86126,4.84526,4.82127,4.79527,4.77927,4.76327,4.73528,4.72928,4.69129,4.64329,4.48532,4.47732,4.6153,4.5973,4.5893,4.5633,4.54531,4.53731,4.51131,4.50731,4.48932,4.46932,4.45932,3.99139,3.85941,3.84341,3.82742,3.82742,3.80342,3.81142,3.78742,3.77742,3.76543,3.74343,3.74743,3.72143,3.70544,3.69744,3.67344,3.66744,3.67744,3.66344,3.67144};
+std::vector<float> target_scan_1 ={1.93771,1.93171,1.9437,1.9597,1.9537,1.9737,1.9777,1.9757,1.9937,1.9617,1.89771,1.87371,1.85772,1.86372,1.85572,1.86372,1.86172,1.86372,1.88371,1.89171,1.91971,4.73128,4.74128,4.76927,4.76927,4.78927,4.80327,4.81927,4.83526,4.85126,4.31534,4.23136,4.19536,4.16337,4.14137,4.13537,1.82572,1.79173,1.78373,1.75373,1.76173,1.74773,1.73974,1.72774,1.71574,1.71574,1.70974,1.70374,1.70974,1.70374,1.71174,1.70774,1.70374,1.71174,1.69974,1.71574,1.71374,1.70774,1.71774,1.71374,1.72374,1.72574,1.74773,1.75773,1.75373,1.78173,1.77773,1.77173,1.79573,1.79773,1.82972,1.83772,1.85572,1.87571,1.92571,1.9737,250,250,250,250,250,250,250,5.14722,5.2752,5.2692,5.2252,5.18921,5.17521,5.13322,5.12122,5.08523,5.04923,5.03123,5.00524,4.98324,4.95525,4.92525,4.91325,4.86926,4.86126,4.83926,4.81727,4.80527,4.77527,4.75528,4.67729,4.53931,4.54331,4.65929,4.65529,4.63529,4.6153,4.6033,4.5773,4.5633,4.55131,4.52131,4.52131,4.48732,3.9194,3.89541,3.88741,3.87941,3.85941,3.85941,3.83542,3.81542,3.81142,3.78742,3.78142,3.76343,3.74943,3.73343,3.70744,3.72343,3.72143,3.70344,3.70544,3.68344,3.68344,3.66744,3.65144,3.65544,2.85157,2.83557,2.81357,2.78358,2.77158,2.76358,2.76358,2.76358,2.79357,2.82157,2.79557,2.85557,2.89356,3.14552,3.2775,3.32349,3.32949,3.3075,3.2995,3.3055,3.2975,3.3055,3.2855,3.2795,3.2855,3.2675,3.04954,3.02354,3.01954,3.03354,3.01754,3.02554,3.01354,3.00354,3.02154,3.00954,3.01354,3.00354,3.00354,3.01954,2.99954,3.01154,3.00754,3.01354,3.00754,2.99154,3.01354,4.03339,4.02939,4.03539,3.82342,3.62345,3.74343,3.2695,3.2815,3.2735,3.2875,3.2895,3.2875,3.2935,3.2955,3.3115,3.3135,3.3135,3.32949,3.32149,3.34349,3.33749,4.12537,4.10737,4.07138,4.05538,4.03738,3.85941,3.44947,3.42548,3.53146,3.44348,3.43548,3.48547,4.19136,4.20336,4.21336,3.59145,3.59145,3.59145,3.59145,3.59145,3.47147,3.45147,3.42348,3.45147,3.42348,3.34749,3.34749,3.44348,250,250,250,2.95955,2.93355,2.93555,2.92955,2.91556,2.88756,2.88756,2.92355,4.50331,2.19167,2.16767,2.13368,2.04369,1.91971,1.85972,1.83172,1.85972,1.79173,1.76773,1.73174,1.79173,1.84772,1.79173,1.79173,1.86372,1.79173,1.86372,1.89171,1.84772,1.89171,1.87571,1.89171,1.84372,1.85572,1.66775,1.51577,1.45978,1.47977,1.47178,1.42778,1.43178,1.41179,1.40779,1.37979,1.39579,1.39579,1.37579,1.35579,1.35979,1.3078,1.3398,1.3278,1.39579,1.39579,1.39579,250,1.39579,1.43578,1.44778,1.39579,1.45978,1.41578,1.42778,1.43978,1.41179,1.39579,1.36779,1.37979,1.37179,1.3158,1.3318,1.21182,1.17582,1.15582,1.14783,1.11183,1.12383,1.11183,1.12183,1.09783,1.10783,1.10183,1.08783,1.08783,1.08384,1.08384,1.07384,1.06784,1.06984,1.05784,1.06184,1.05584,1.04784,1.05784,1.03784,1.05184,1.04184,1.03584,1.05584,1.01984,1.02384,1.03584,1.01585,1.00785,1.00785,1.09583,250,250,1.19582,250,1.19582,1.17982,1.19582,1.17782,1.17582,1.18782,1.17582,1.17182,1.17382,1.16582,1.17982,1.16782,1.13583,1.12783,1.09583,1.12783,1.08384,1.09583,1.08384,1.07584,1.06384,1.05184,1.03384,1.05384,1.05184,1.04784,1.04184,1.05584,1.05584,1.05984,1.06784,1.12383,1.84772,1.83972,1.85172,1.85972,1.84772,1.85572,1.85972,1.89171,250,4.36734,4.36334,4.37333,4.35534,4.36534,4.36933,4.35934,4.36733,4.35134,4.34734,4.36134,4.33734,4.34934,4.33734,4.35334,4.34134,4.77927,4.85926,4.90325,6.45502,6.45902,6.44702,6.45102,8.5347,250,7.61484,7.59484,8.5287,8.5347,8.5427,8.5447,8.5527,8.5627,8.5627,8.5727,8.57869,8.58269,8.60069,8.59469,8.61669,8.62469,4.86726,4.88326,4.88926,4.89725,4.89925,4.90725,4.92325,4.91525,4.94125,4.93525,4.94725,4.90125,4.79127,4.54931,4.52131,4.51731,4.54331,4.53731,4.55331,4.5633,4.5693,4.6033,4.6073,4.6193,4.6233,4.64729,4.65329,4.66729,4.68129,4.69528,4.72328,4.72128,4.73528,4.75728,4.75728,4.79327,4.79927,4.80727,4.82527,4.83126,4.85726,4.87526,4.89126,3.02154,2.99954,2.98155,2.91556,2.87756,2.85357,2.80757,2.78958,2.75158,2.70359,2.67559,2.6176,2.06569,2.04769,2.03569,2.04369,2.03369,2.03969,2.04969,2.06169,2.10168,2.22166,2.30765,2.32165,2.31165,2.29765,2.25766,2.24566,2.21766,2.17367,2.17767,2.16567,2.19967,2.21966,2.22566,2.24366,2.23966,2.27165,2.27965,2.29365,2.31965,2.32765,2.35564,2.35764,2.36564,2.39164,2.40163,2.41763,2.43363,2.44563,2.47162,2.47962,2.51762,2.52162,2.54161,2.56561,2.57961,2.6056,2.59161,2.6076,7.2149,7.2469,7.30689,9.00663,8.91864,8.85865,8.77066,8.71467,8.63868,8.57469,8.69468,8.5327,8.62469,8.70867,8.80066,8.90464,8.99663,9.10061,9.2046,9.29259,9.43456,9.51655,9.66053,9.75451,9.88649,10.0145,10.1425,10.2784,10.4224,10.5424,10.7024,10.8423,11.0103,11.1783,11.4323,11.6122,11.7702,11.9642,12.0702,12.0462,3.74743,3.70744,3.70944,3.70744,3.69144,3.68144,3.66544,3.66944,3.64944,3.64544,3.64744,3.62345,3.62745,3.61145,3.60545,3.60545,3.58945,3.59345,3.57346,3.57346,3.56346,3.54146,3.55546,3.53746,3.53746,3.54146,3.53346,3.52746,3.51746,3.50947,3.51147,3.49547,3.50347,3.49547,3.48747,3.48947,3.47547,3.47947,3.47347,3.46147,3.46947,3.46147,3.46947,3.46347,3.45147,3.46347,3.44548,3.45347,3.45347,3.44748,3.45147,250,1.86972,1.87172,1.86772,3.43548,3.43348,3.46547,3.44548,3.43548,3.44947,3.44348,3.46747,3.44947,3.43748,3.44747,3.44947,3.45547,3.45547,3.45547,3.46347,3.45747,3.47147,2.36764,2.37164,2.35964,3.47547,1.89771,1.88971,1.87971,1.91171,3.68144,3.59345,4.16936,4.18736,4.20936,3.2695,250,2.79158,2.77758,2.78958,2.81557,2.82357,2.81957,2.82357,2.85357,2.84357,250,250,250,2.09168,2.04369,250,250,2.89356,2.89956,2.89956,2.91556,2.91956,2.92156,2.93755,2.93555,4.46932,4.47532,4.48332,4.50331,4.51331,4.53331,4.54331,4.55131,4.5813,4.54931,4.52131,1.49577,1.45978,1.43978,1.40379,1.38379,1.37979,1.35579,1.3318,1.3218,1.3318,1.3138,1.3018,1.3118,1.49977,1.52577,1.52377,1.52777,1.53977,1.54376,1.56376,1.57176,1.56376,1.58776,1.58376,1.60376,1.60376,1.60975,1.62575,1.62975,1.64575,1.64575,1.65375,1.66775,1.66575,1.68774,1.70174,1.70374,1.71374,1.72574,1.74373,1.74573,1.75573,1.78573,1.78973,1.80173,1.81772,1.81772,1.84172,1.84972,1.86772,1.87371,1.88971,1.90971,1.91371,1.9457,1.9617,1.9737,1.9897,1.9997,2.02369,2.03169,2.04569,2.07968,2.08768,2.12168,2.13368,2.13967,2.17967,2.18767,2.21966,2.23966,2.24366,2.27965,2.29965,2.34364,2.36164,2.37564,2.34364,2.32765,2.33564,2.31165,2.29165,2.29165,2.29565,2.29165,2.29165,4.49132,4.46332,4.43532,4.43133,4.41533,4.39933,4.38333,4.36334,4.33534,4.34734,4.30334,4.29535,4.27935,4.28335,4.29135,4.24735,4.26735,4.22736,4.19936,4.08738,3.87141,3.9594,4.03139,4.23136,4.55131,4.54531,4.52931,4.51731,4.52131,4.50531,4.50131,4.48932,4.47532,4.46932,3.2755,3.21951,3.21151,3.20751,3.24351,3.24151,3.11153,3.11553,3.12552,3.13152,3.09153,3.01954,2.94755,2.96355,3.03554,3.04354,3.09753,3.09953,3.09953,3.07753,3.08953,3.07553,3.01954,3.09353,3.14352,3.09153,3.46547,3.13152,3.09953,3.09153,3.09353,3.13152,3.17352,3.76143,4.31734,4.31934,4.30934,4.31734,4.30934,4.32534,4.31334,4.30934,4.30934,3.9354,3.9174,3.61945,3.9314,3.9394,3.9374,3.9494,3.9454,3.9394,3.9654,3.9454,3.99139,2.09168,2.17167,2.19167,2.08768,2.08768,2.03169,1.88771,1.87971,1.85372,1.83372,1.78973,1.74973,1.74773,1.73774,1.75173,1.74573,1.74773,1.76173,1.75773,1.78173,1.79173};
+
+std::vector<float> reference_scan_2 ={4.86126,4.82527,4.84126,4.83326,4.85326,250,250,4.43932,4.43332,5.68313,5.04523,4.74728,4.80527,5.59715,5.01724,5.44117,5.54915,5.54516,5.51716,4.96524,5.16921,5.47317,4.28935,4.27335,5.46517,4.5893,5.43117,5.42317,5.41318,5.40318,4.68529,4.67329,5.36718,5.36518,5.36118,5.30319,5.33719,5.31519,5.38718,5.39518,5.45717,5.43317,5.44117,5.41718,5.39318,5.42117,5.39318,5.36118,5.34919,5.33719,5.35718,5.32919,5.33719,5.30519,5.32919,5.30519,5.32119,5.29319,5.30519,5.32119,5.30119,5.32119,5.2772,5.30519,5.30519,5.29319,5.2812,5.2732,5.29319,13.6039,13.5939,13.6079,13.6119,13.6159,13.6299,13.6099,13.6299,13.6179,13.6259,13.6419,11.5742,11.5642,6.51301,6.549,6.553,6.52101,6.45702,250,250,250,250,250,250,250,250,5.43317,5.38718,5.37118,5.30519,5.32519,5.31519,3.2655,3.11153,2.98155,2.78558,2.81157,2.73358,2.71359,2.6276,2.55361,2.49762,2.44163,2.37364,2.33564,2.27365,2.22766,2.17967,2.12768,2.08768,2.05369,2.01969,1.9757,1.93371,1.87971,1.86772,1.84372,1.81572,1.77573,1.76373,1.72574,1.70174,1.67575,1.65975,1.62975,1.61775,1.59176,1.57176,1.53977,1.52777,1.49577,1.48777,1.44778,1.43578,1.41578,1.39779,1.38779,1.36579,1.37579,1.35979,1.35579,1.35579,1.38179,1.39379,1.38779,1.39379,1.40779,1.40579,1.42178,1.42178,1.42178,1.43178,1.43578,1.44378,1.45178,1.45578,1.47178,1.48377,1.48977,1.48977,1.50377,1.52777,1.52577,1.55176,1.54976,1.55176,1.58176,1.57976,1.61175,1.59976,1.62775,1.62575,1.63775,1.63775,1.62975,1.64775,1.67575,1.67974,1.91571,1.82372,1.72174,1.68974,1.67774,1.69974,1.70774,1.74773,1.78373,1.79173,1.82372,1.84772,1.89371,1.91771,1.9477,1.9897,2.01769,2.05969,2.09568,2.11968,2.17167,2.20966,2.25966,2.30365,2.33564,2.40563,2.77558,2.13767,2.17167,2.23366,2.27365,2.31765,2.37764,2.78158,2.80957,2.84157,2.86556,2.90956,2.93755,2.98954,3.01754,3.04754,3.10353,3.14352,3.18352,3.19351,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,3.07353,2.97755,2.96755,3.03754,3.11353,3.18951,3.2615,250,1.21781,1.21981,1.21382,1.22581,1.22381,1.22381,1.21182,1.20382,1.21581,1.20382,1.20582,1.20582,1.19982,1.20582,1.20382,1.21382,1.20582,1.18982,1.18982,1.18982,1.20182,1.19782,1.18782,1.19582,1.18182,1.19982,1.19582,1.18182,1.19582,1.18182,1.20382,1.18982,1.18182,1.19582,1.19382,1.19382,1.18582,1.18382,1.19182,1.19182,1.19382,1.18782,1.18382,1.18982,1.19382,1.19382,1.16782,1.10983,0.751886,0.761884,0.761884,0.735888,0.731889,0.735888,0.731889,0.743887,0.743887,0.735888,0.751886,0.739887,0.747886,0.749886,0.743887,0.751886,0.743887,0.759884,0.753885,0.743887,0.751886,0.751886,0.749886,0.759884,0.757885,0.763884,0.763884,0.773882,0.759884,0.773882,0.763884,0.763884,0.777882,0.763884,0.777882,0.779881,0.775882,0.78788,0.775882,0.791879,0.78988,0.791879,0.791879,0.791879,0.797879,0.791879,0.795879,0.807877,0.803878,0.811876,0.811876,0.811876,0.823875,0.815876,0.831873,0.811876,0.823875,0.835873,0.831873,0.835873,0.839872,0.839872,0.85587,0.85187,0.863868,0.85587,0.85587,0.865868,0.85587,0.871867,0.867868,0.871867,0.883865,0.879866,0.897863,0.893864,0.897863,0.909861,0.901863,0.91986,0.91786,0.923859,0.931858,0.931858,0.939857,0.943856,0.953855,0.959854,0.959854,0.977851,0.971852,0.999848,0.991849,0.995848,1.00785,1.00585,1.02784,1.01984,1.02984,1.03984,1.04584,1.06384,1.06584,1.06784,1.08384,1.07984,1.10383,1.10783,1.10783,1.12383,1.12783,1.14383,1.15582,1.15582,1.17982,1.17982,1.20382,1.20982,1.21981,1.23181,1.23381,1.24981,1.26381,1.27581,1.3098,1.3078,1.3358,1.3358,1.35179,1.36579,1.37379,1.40179,1.41378,1.41778,1.44178,1.45378,1.48977,1.49177,1.50977,1.53377,1.54976,1.58176,1.59776,1.60975,1.63775,1.65375,1.68974,1.71374,1.73374,1.77573,1.79173,1.82772,1.83972,1.88771,1.90771,1.9577,1.9877,2.01569,2.05569,2.08768,2.12368,2.16567,2.25766,2.39364,2.32365,2.33764,2.39364,2.39364,250,2.46762,2.55361,250,250,250,3.40748,3.39748,3.39748,3.39548,3.40348,3.47347,3.58145,4.28535,4.45532,4.5973,4.72128,250,250,250,250,7.8888,250,250,9.11661,9.8685,10.0405,9.98848,250,12.3841,13.8739,13.8639,13.8519,17.6173,19.1251,25.3661,25.7701,25.7561,25.8161,13.8179,13.8239,13.8299,13.8359,250,9.93649,9.94449,7.56485,9.95848,9.96648,9.94849,9.98448,8.29874,8.30474,8.31273,250,250,250,250,250,250,250,250,10.1125,10.0445,250,8.18875,8.22875,250,7.34888,7.32488,7.34088,7.34888,7.37288,7.37688,7.38488,7.40887,10.2564,10.2604,250,250,10.3024,10.3844,250,10.3544,7.63684,250,7.18891,250,5.2652,5.2212,5.2332,5.19321,5.19721,5.08123,5.20521,5.19321,7.58884,4.13337,4.10138,4.08738,4.08738,4.11137,4.12137,3.9734,3.9374,3.9094,3.9294,5.12122,4.69329,4.66929,4.5933,4.54131,4.46932,4.84526,4.85726,4.86926,4.89325,4.89325,4.92125,4.98124,5.00524,4.15937,4.12537,4.04538,4.01339,3.9694,3.9214,3.88541,3.83342,3.79542,3.75143,3.70944,3.67144,3.63545,3.61745,3.57346,3.55146,3.52146,3.48347,3.45547,3.41948,3.40948,3.37749,3.32549,3.3175,3.2815,3.2695,3.24151,3.24151,3.22151,3.19351,3.21751,3.22751,3.24151,1.3118,1.2978,1.3038,1.2918,1.2958,1.2978,1.27381,1.26781,1.26181,1.24381,1.24781,1.23781,1.24181,1.21382,1.21981,1.20582,1.19582,1.19582,1.18582,1.17982,1.16582,1.15582,1.15982,1.14783,1.15382,1.14583,1.12783,1.13183,1.11983,1.12583,1.11383,1.10183,1.10183,1.09183,1.10183,1.09183,1.07784,1.07984,1.06384,1.07784,1.06384,1.05384,1.06384,1.03784,1.05384,1.04384,1.03184,1.04984,1.02784,1.03784,1.03384,1.01585,1.01984,1.00185,1.01585,1.00985,0.999848,1.00785,0.993849,1.00185,0.995848,0.993849,0.989849,0.98585,0.98585,0.977851,0.98385,0.961854,0.971852,0.963853,0.939857,0.975851,0.965853,0.953855,1.00385,1.02984,1.07784,1.10583,1.11783,1.16582,1.20182,1.23781,1.2978,1.36979,1.44978,1.50977,1.58176,1.60975,1.64375,1.70174,1.70574,1.77773,1.86572,1.73774,1.70374,1.67774,1.68774,1.68974,1.67574,1.68974,1.68974,1.70574,1.70374,1.75773,1.84172,1.82172,1.81772,1.79573,1.79573,1.80573,1.79773,1.80173,1.79373,1.81972,1.81972,1.82972,1.88171,7.93879,7.95679,7.95879,7.17291,6.68498,6.70498,6.74097,6.69698,6.73897,6.71498,6.70098,6.60899,6.64099,8.02078,8.02478,8.02078,8.04877,8.04278,7.71683,7.67083,7.40487,7.69083,7.69683,7.70083,7.72282,250,8.14876,8.15476,6.10507,6.04908,5.84111,5.73313,5.62714,5.52916,5.50916,5.53716,5.85911,5.82511,5.78112,5.73313,5.65314,5.65314,5.63714,8.45471,8.46071,8.48071,8.5087,8.5207,8.5567,5.54516,5.50916,5.48317,5.45517,5.46717,5.46317,5.46717,5.47117,5.47317,5.47717,5.50916,5.58115,5.64914,8.95664,8.99063,8.97663,250,250,2.89356,2.86556,2.85157,2.85756,2.79357,2.79357,2.79357,2.69359,2.74158,2.59361,2.59361,2.59361,2.59361,2.53361,2.49362,2.43363,2.47762,2.43363,2.46562,2.41763,2.32165,2.21366,2.18567,2.19767,2.17967,2.16967,2.22166,2.24566,2.39364,2.35764,2.39364,2.39364,2.49362,2.49362,2.59361,250,2.59361,2.59361,250,250,250,250,250,250,250,250,2.89356,2.79357,2.89356,250,250,2.91956,2.90356,2.92156,250,2.99354,3.07353,3.00554,3.01354,3.03754,3.41748,3.47747,3.43748,250,3.50947,3.42348,3.44148,3.66544,3.79342,250,3.56146,3.50147,3.59345,3.56346,5.42117,4.42133,4.38733,4.37133,4.38933,4.99324};
\ No newline at end of file
diff --git a/test/gtest_processor_loop_closure_falko.cpp b/test/gtest_processor_loop_closure_falko.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0fd43107dd4ee5240a1f6304406043e09a52f821
--- /dev/null
+++ b/test/gtest_processor_loop_closure_falko.cpp
@@ -0,0 +1,719 @@
+//--------LICENSE_START--------
+//
+// Copyright (C) 2020,2021 Institut de Robòtica i Informàtica Industrial, CSIC-UPC.
+// Authors: Joan Solà Ortega (jsola@iri.upc.edu)
+// All rights reserved.
+//
+// This file is part of WOLF
+// WOLF is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+//--------LICENSE_END--------
+#include "laser/internal/config.h"
+
+#include "core/capture/capture_void.h"
+#include "core/problem/problem.h"
+#include "core/utils/utils_gtest.h"
+#include "core/yaml/parser_yaml.h"
+#include "core/utils/params_server.h"
+
+#include "laser/processor/processor_loop_closure_falko.h"
+#include "laser/sensor/sensor_laser_2d.h"
+
+#include "data/scan_data.h"
+
+// STL
+#include <iostream>
+#include <iterator>
+
+using namespace wolf;
+using namespace Eigen;
+using namespace laserscanutils;
+
+std::string laser_root_dir = _WOLF_LASER_ROOT_DIR;
+
+WOLF_PTR_TYPEDEFS(ProcessorLoopClosureFalkoPublic);
+class ProcessorLoopClosureFalkoPublic : public ProcessorLoopClosureFalkoAhtBsc
+{
+    public:
+        ProcessorLoopClosureFalkoPublic(ParamsProcessorLoopClosureFalkoPtr _params_falko)
+            : ProcessorLoopClosureFalkoAhtBsc(_params_falko)
+        {
+        }
+
+        ~ProcessorLoopClosureFalkoPublic() = default;
+
+        std::shared_ptr<LoopClosureFalko<bsc, bscExtractor, aht_matcher>> getLoopClosure()
+        {
+            return loop_closure_;
+        }
+
+        void emplaceFeatures(CaptureBasePtr cap)
+        {
+            ProcessorLoopClosureFalkoAhtBsc::emplaceFeatures(cap);
+        }
+
+        std::map<double, MatchLoopClosurePtr> findLoopClosures(CaptureBasePtr cap)
+        {
+            return ProcessorLoopClosureFalkoAhtBsc::findLoopClosures(cap);
+        }
+};
+
+class ProcessorLoopClosureFalkoTest : public testing::Test
+{
+  public:
+    // Wolf problem
+    ProblemPtr                         problem = Problem::create("PO", 2);
+    SensorBasePtr                      sensor;
+    ProcessorLoopClosureFalkoPublicPtr  processor;
+
+    virtual void SetUp()
+    {
+
+        // Emplace sensor
+        LaserScanParams _params;
+        _params.angle_min_  = 0;
+        _params.angle_max_  = 2.0 * M_PI;
+        _params.angle_step_ = 0.00701248;
+        sensor =
+            SensorBase::emplace<SensorLaser2d>(problem->getHardware(),
+                                               std::make_shared<StateBlock>(Vector2d::Zero()),
+                                               std::make_shared<StateBlock>(Vector1d::Zero()),
+                                               _params);
+
+        // Emplace processor
+
+        ParserYaml   parser = ParserYaml("test/yaml/params_processor_loop_closure_falko.yaml", laser_root_dir);
+        ParamsServer server = ParamsServer(parser.getParams());
+
+        ParamsProcessorLoopClosureFalkoPtr params =
+            std::make_shared<ParamsProcessorLoopClosureFalko>("ProcessorLoopClosureFalko", server);
+        processor = ProcessorBase::emplace<ProcessorLoopClosureFalkoPublic>(sensor, params);
+    }
+
+    FrameBasePtr emplaceFrame(TimeStamp ts, const Vector3d &x)
+    {
+        // new frame
+        return problem->emplaceFrame(ts, x);
+    }
+
+    CaptureBasePtr emplaceCapture(FrameBasePtr frame)
+    {
+        // new capture
+        return CaptureBase::emplace<CaptureBase>(frame, "CaptureBase", frame->getTimeStamp(), sensor);
+    }
+
+    CaptureBasePtr createCapture(TimeStamp ts)
+    {
+        // new capture
+        return std::make_shared<CaptureBase>("CaptureBase", ts, sensor);
+    }
+
+    CaptureLaser2dPtr emplaceCaptureLaser2d(FrameBasePtr frame, const std::vector<float> &_ranges)
+    {
+        // new capture
+        return CaptureBase::emplace<CaptureLaser2d>(frame, frame->getTimeStamp(), sensor, _ranges);
+    }
+
+    CaptureLaser2dPtr createCaptureLaser2d(TimeStamp ts, const std::vector<float> &_ranges)
+    {
+        // new capture
+        return std::make_shared<CaptureLaser2d>(ts, sensor, _ranges);
+    }
+};
+
+TEST_F(ProcessorLoopClosureFalkoTest, installProcessor)
+{
+    // Stored Frames
+    EXPECT_EQ(processor->getNStoredFrames(), 0);
+    // Stored Captures
+    EXPECT_EQ(processor->getNStoredCaptures(), 0);
+}
+
+TEST_F(ProcessorLoopClosureFalkoTest, frame_stored)
+{
+    // new frame
+    auto frm1 = emplaceFrame(1, Vector3d::Zero());
+
+    // keyframecallback
+    problem->keyFrameCallback(frm1, nullptr);
+
+    EXPECT_EQ(processor->getNStoredFrames(), 1);
+    EXPECT_EQ(processor->getNStoredCaptures(), 0);
+}
+
+TEST_F(ProcessorLoopClosureFalkoTest, capture_stored)
+{
+    // new capture
+    auto cap1 = createCapture(1);
+
+    // captureCallback
+    processor->captureCallback(cap1);
+
+    EXPECT_EQ(processor->getNStoredFrames(), 0);
+    EXPECT_EQ(processor->getNStoredCaptures(), 1);
+}
+
+TEST_F(ProcessorLoopClosureFalkoTest, captureCallbackCase1)
+{
+    // emplace frame and capture
+    auto frm1 = emplaceFrame(1, Vector3d::Zero());
+
+    ASSERT_TRUE(frm1 != nullptr);
+
+    std::vector<float> ranges;
+    auto               cap1 = emplaceCaptureLaser2d(frm1, ranges);
+
+    // captureCallback
+    std::cout << __LINE__ << std::endl;
+    processor->captureCallback(cap1);
+    std::cout << __LINE__ << std::endl;
+
+    EXPECT_EQ(cap1->getFeatureList().size(), 1); // capture processed by the processor
+    EXPECT_EQ(processor->getNStoredFrames(), 0);
+    EXPECT_EQ(processor->getNStoredCaptures(), 0);
+}
+
+TEST_F(ProcessorLoopClosureFalkoTest, captureCallbackCase2)
+{
+    // new frame
+    auto frm1 = emplaceFrame(1, Vector3d::Zero());
+
+    // new capture
+    std::vector<float> ranges;
+    auto               cap1 = createCaptureLaser2d(1, ranges);
+
+    // keyframecallback
+    problem->keyFrameCallback(frm1, nullptr);
+
+    // captureCallback
+    processor->captureCallback(cap1);
+
+    EXPECT_EQ(cap1->getFrame(), frm1);           // capture processed by the processor
+    EXPECT_EQ(cap1->getFeatureList().size(), 1); // capture processed by the
+    EXPECT_EQ(processor->getNStoredFrames(), 0);
+    EXPECT_EQ(processor->getNStoredCaptures(), 0);
+}
+
+TEST_F(ProcessorLoopClosureFalkoTest, captureCallbackCase3)
+{
+    // new frame
+    auto frm1 = emplaceFrame(1, Vector3d::Zero());
+    // new capture
+    std::vector<float> ranges;
+    auto               cap1 = createCaptureLaser2d(2, ranges);
+
+    // keyframecallback
+    problem->keyFrameCallback(frm1, nullptr);
+
+    // captureCallback
+    processor->captureCallback(cap1);
+
+    EXPECT_TRUE(cap1->getFrame() == nullptr);
+    EXPECT_EQ(cap1->getFeatureList().size(), 0);
+    EXPECT_EQ(processor->getNStoredFrames(), 1);
+    EXPECT_EQ(processor->getNStoredCaptures(), 1);
+}
+
+TEST_F(ProcessorLoopClosureFalkoTest, keyFrameCallbackCase1)
+{
+    // emplace frame and capture
+    std::cout << __LINE__ << std::endl;
+    auto               frm1 = emplaceFrame(1, Vector3d::Zero());
+    std::cout << __LINE__ << std::endl;
+    std::vector<float> ranges;
+    std::cout << __LINE__ << std::endl;
+    auto               cap1 = emplaceCaptureLaser2d(frm1, ranges);
+
+    std::cout << __LINE__ << std::endl;
+    // keyframecallback
+    problem->keyFrameCallback(frm1, nullptr);
+    std::cout << __LINE__ << std::endl;
+
+    EXPECT_EQ(cap1->getFeatureList().size(), 1); // capture processed by the
+    std::cout << __LINE__ << std::endl;
+    EXPECT_EQ(processor->getNStoredFrames(), 0);
+    std::cout << __LINE__ << std::endl;
+    EXPECT_EQ(processor->getNStoredCaptures(), 0);
+    std::cout << __LINE__ << std::endl;
+}
+
+TEST_F(ProcessorLoopClosureFalkoTest, keyFrameCallbackCase2)
+{
+    // new frame
+    auto frm1 = emplaceFrame(1, Vector3d::Zero());
+    // new capture
+    std::vector<float> ranges;
+    auto               cap1 = createCaptureLaser2d(1, ranges);
+
+    // captureCallback
+    processor->captureCallback(cap1);
+
+    // keyframecallback
+    problem->keyFrameCallback(frm1, nullptr);
+
+    EXPECT_EQ(cap1->getFrame(), frm1);           // capture processed by the processor
+    EXPECT_EQ(cap1->getFeatureList().size(), 1); // capture processed by the
+    EXPECT_EQ(processor->getNStoredFrames(), 0);
+    EXPECT_EQ(processor->getNStoredCaptures(), 0);
+}
+
+TEST_F(ProcessorLoopClosureFalkoTest, keyFrameCallbackCase3)
+{
+    // new frame
+    auto frm1 = emplaceFrame(2, Vector3d::Zero());
+    // new capture
+    auto cap1 = createCapture(1);
+
+    // captureCallback
+    processor->captureCallback(cap1);
+
+    // keyframecallback
+    problem->keyFrameCallback(frm1, nullptr);
+
+    EXPECT_TRUE(cap1->getFrame() == nullptr);
+    EXPECT_EQ(cap1->getFeatureList().size(), 0);
+    EXPECT_EQ(processor->getNStoredFrames(), 1);
+    EXPECT_EQ(processor->getNStoredCaptures(), 1);
+}
+
+TEST_F(ProcessorLoopClosureFalkoTest, keyFrameCallbackCase4)
+{
+    // new frame
+    auto frm1 = emplaceFrame(1, Vector3d::Zero());
+    // new capture
+    auto cap1 = createCapture(2);
+
+    // captureCallback
+    processor->captureCallback(cap1);
+
+    // keyframecallback
+    problem->keyFrameCallback(frm1, nullptr);
+
+    EXPECT_TRUE(cap1->getFrame() == nullptr);
+    EXPECT_EQ(cap1->getFeatureList().size(), 0);
+    EXPECT_EQ(processor->getNStoredFrames(), 0);
+    EXPECT_EQ(processor->getNStoredCaptures(), 1);
+}
+
+TEST_F(ProcessorLoopClosureFalkoTest, captureCallbackMatch)
+{
+    // new frame
+    auto frm1 = emplaceFrame(1, Vector3d::Zero());
+    auto frm2 = emplaceFrame(2, Vector3d::Zero());
+    auto frm3 = emplaceFrame(3, Vector3d::Zero());
+    auto frm4 = emplaceFrame(4, Vector3d::Zero());
+    auto frm5 = emplaceFrame(5, Vector3d::Zero());
+    // new captures
+    std::vector<float> ranges;
+    auto               cap4 = createCaptureLaser2d(4, ranges);
+
+    // keyframecallback
+    problem->keyFrameCallback(frm1, nullptr);
+    problem->keyFrameCallback(frm2, nullptr);
+    problem->keyFrameCallback(frm3, nullptr);
+    problem->keyFrameCallback(frm4, nullptr);
+    problem->keyFrameCallback(frm5, nullptr);
+
+    // captureCallback
+    processor->captureCallback(cap4);
+
+    EXPECT_EQ(frm1->getCaptureList().size(), 0);
+    EXPECT_EQ(frm2->getCaptureList().size(), 0);
+    EXPECT_EQ(frm3->getCaptureList().size(), 0);
+    EXPECT_EQ(frm4->getCaptureList().size(), 1);
+    EXPECT_EQ(frm5->getCaptureList().size(), 0);
+
+    EXPECT_TRUE(cap4->getFrame() == frm4);
+    EXPECT_EQ(cap4->getFeatureList().size(), 1);
+
+    EXPECT_EQ(processor->getNStoredFrames(), 1); // all oldest frames are
+    // removed from buffer
+    EXPECT_EQ(processor->getNStoredCaptures(), 0);
+}
+
+TEST_F(ProcessorLoopClosureFalkoTest, keyFrameCallbackMatch)
+{
+    // new frame
+    auto frm2 = emplaceFrame(2, Vector3d::Zero());
+    // new captures
+    std::vector<float> ranges;
+    auto               cap1 = createCaptureLaser2d(1, ranges);
+    auto               cap2 = createCaptureLaser2d(2, ranges);
+    auto               cap3 = createCaptureLaser2d(3, ranges);
+    auto               cap4 = createCaptureLaser2d(4, ranges);
+    auto               cap5 = createCaptureLaser2d(5, ranges);
+
+    // captureCallback
+    processor->captureCallback(cap1);
+    processor->captureCallback(cap2);
+    processor->captureCallback(cap3);
+    processor->captureCallback(cap4);
+    processor->captureCallback(cap5);
+
+    // keyframecallback
+    problem->keyFrameCallback(frm2, nullptr);
+
+    EXPECT_TRUE(cap1->getFrame() == nullptr);
+    EXPECT_TRUE(cap2->getFrame() == frm2);
+    EXPECT_TRUE(cap3->getFrame() == nullptr);
+    EXPECT_TRUE(cap4->getFrame() == nullptr);
+    EXPECT_TRUE(cap5->getFrame() == nullptr);
+
+    EXPECT_EQ(cap1->getFeatureList().size(), 0);
+    EXPECT_EQ(cap2->getFeatureList().size(), 1);
+    EXPECT_EQ(cap3->getFeatureList().size(), 0);
+    EXPECT_EQ(cap4->getFeatureList().size(), 0);
+    EXPECT_EQ(cap5->getFeatureList().size(), 0);
+
+    EXPECT_EQ(processor->getNStoredFrames(), 0);
+    EXPECT_EQ(processor->getNStoredCaptures(), 4);
+}
+
+TEST_F(ProcessorLoopClosureFalkoTest, emplaceFeatures)
+{
+    std::vector<float> ranges;
+
+    // add scan to capture:
+    auto cap1 = createCaptureLaser2d(1, ranges);
+
+    // captureCallback
+    processor->captureCallback(cap1);
+
+    EXPECT_EQ(cap1->getFeatureList().size(), 0);
+
+    auto frm1 = emplaceFrame(1, Vector3d::Zero());
+
+    // keyframecallback
+    problem->keyFrameCallback(frm1, nullptr);
+
+    EXPECT_EQ(cap1->getFeatureList().size(), 1);
+}
+
+TEST_F(ProcessorLoopClosureFalkoTest, findLoopClosures)
+{
+    Vector3d pos1 = {0.5, 0.3, 0};
+    auto     cap1 = emplaceCaptureLaser2d(emplaceFrame(1, Vector3d::Zero()), testRanges1);
+    auto     cap2 = emplaceCaptureLaser2d(emplaceFrame(2, pos1), testRanges2);
+    auto     cap3 = emplaceCaptureLaser2d(emplaceFrame(3, Vector3d::Zero()), testRanges1);
+
+    // captureCallback
+    processor->captureCallback(cap1);
+    EXPECT_EQ(processor->match_list_.size(), 0);
+
+    processor->captureCallback(cap2);
+    EXPECT_EQ(processor->match_list_.size(), 1);
+    EXPECT_EQ(processor->match_list_.back()->capture_reference, cap1);
+    EXPECT_EQ(processor->match_list_.back()->capture_target, cap2);
+
+    processor->captureCallback(cap3);
+    EXPECT_EQ(processor->match_list_.size(), 3);
+    EXPECT_EQ(processor->match_list_.back()->capture_reference, cap1);
+    EXPECT_EQ(processor->match_list_.back()->capture_target, cap3);
+
+    // Verify factors
+    EXPECT_EQ(cap1->getFrame()->getConstrainedByList().size(), 0);
+    EXPECT_EQ(cap2->getFrame()->getConstrainedByList().size(), 1);
+    EXPECT_EQ(cap3->getFrame()->getConstrainedByList().size(), 2);
+}
+
+TEST_F(ProcessorLoopClosureFalkoTest, TestExtractScene)
+{
+    auto cap_ref    = emplaceCaptureLaser2d(emplaceFrame(1, Vector3d::Zero()), reference_scan_1);
+    auto cap_target = emplaceCaptureLaser2d(emplaceFrame(2, Vector3d::Zero()), target_scan_1);
+
+    processor->captureCallback(cap_ref);
+    processor->captureCallback(cap_target);
+
+    std::vector<falkolib::FALKO> key_target;
+    std::vector<falkolib::FALKO> key_ref;
+
+    for (auto feat : cap_ref->getFeatureList())
+        if (feat->getType() == "FeatureSceneFalko")
+        {
+            auto feat_falko = std::static_pointer_cast<FeatureSceneFalkoBsc>(feat);
+            key_ref         = feat_falko->getScene()->keypoints_list_;
+        }
+
+
+    auto cap_laser_1 = std::dynamic_pointer_cast<CaptureLaser2d>(cap_target);
+    auto scan_1      = cap_laser_1->getScan();
+
+    for (auto feat : cap_target->getFeatureList())
+        if (feat->getType() == "FeatureSceneFalko")
+        {
+            auto feat_falko = std::static_pointer_cast<FeatureSceneFalkoBsc>(feat);
+            key_target      = feat_falko->getScene()->keypoints_list_;
+        }
+    std::vector<double> x_ref_all, x_target_all;
+    std::vector<double> y_ref_all, y_target_all;
+
+    // Plotting keypoints scenes
+    for (int i = 0; i < key_ref.size(); i++)
+    {
+        x_ref_all.push_back(key_ref[i].point.x());
+        y_ref_all.push_back(key_ref[i].point.y());
+    }
+
+    for (int i = 0; i < key_target.size(); i++)
+    {
+        x_target_all.push_back(key_target[i].point.x());
+        y_target_all.push_back(key_target[i].point.y());
+    }
+
+    std::vector<double> x_ref, x_target;
+    std::vector<double> y_ref, y_target;
+
+    auto match_falko = std::static_pointer_cast<MatchLoopClosureFalko>(processor->match_list_.front());
+
+    auto associations = match_falko->match_falko_->associations;
+
+    std::cout<< "transform : " << match_falko->match_falko_->transform_vector.transpose() << std::endl;
+
+    for (auto asso : associations)
+        if (asso.second != -1)
+        {
+            x_ref.push_back(key_ref[asso.first].point.x());
+            y_ref.push_back(key_ref[asso.first].point.y());
+
+            x_target.push_back(key_target[asso.second].point.x());
+            y_target.push_back(key_target[asso.second].point.y());
+        }
+}
+
+TEST_F(ProcessorLoopClosureFalkoTest, TestExtractSceneReference)
+{
+    auto cap_ref    = emplaceCaptureLaser2d(emplaceFrame(1, Vector3d::Zero()), reference_scan_2);
+
+    processor->captureCallback(cap_ref);
+
+    std::vector<falkolib::FALKO> key_target;
+    std::vector<falkolib::FALKO> key_ref;
+
+    for (auto feat : cap_ref->getFeatureList())
+        if (feat->getType() == "FeatureSceneFalko")
+        {
+            auto feat_falko = std::static_pointer_cast<FeatureSceneFalkoBsc>(feat);
+            key_ref         = feat_falko->getScene()->keypoints_list_;
+        }
+
+    std::cout << "keypoints size : " << key_ref.size() << std::endl;
+}
+
+TEST_F(ProcessorLoopClosureFalkoTest, TestExtractScene2)
+{
+    // Initialization
+    LaserScan       scan_target, scan_ref;
+    LaserScanParams laser_params;
+
+    laser_params.angle_min_ = 0;
+    laser_params.angle_max_ = 2.0 * M_PI;
+
+    // ** TEST WITH TARGET AND REFERENCE SCENE
+    for (int i = 0; i < target_scan_1.size(); i++)
+    {
+        scan_target.ranges_raw_.push_back(target_scan_1[i]);
+        scan_ref.ranges_raw_.push_back(reference_scan_1[i]);
+    }
+    laser_params.angle_step_ = 0.00701248;
+
+    auto loop_cl_falko_2 = processor->getLoopClosure();
+
+    auto new_scene_target = std::static_pointer_cast<SceneFalko<bsc>>(loop_cl_falko_2->extractScene(scan_target, laser_params));
+    auto new_scene_reference = std::static_pointer_cast<SceneFalko<bsc>>(loop_cl_falko_2->extractScene(scan_ref, laser_params));
+
+    // std::cout << "keypoints target size : " << new_scene_target->keypoints_list_.size() << std::endl;
+    // std::cout << "keypoints reference size : " << new_scene_reference->keypoints_list_.size() << std::endl;
+
+    auto match_r_t = loop_cl_falko_2->matchScene(new_scene_reference, new_scene_target);
+    for (int i = 0; i < match_r_t->associations.size(); i++)
+        if (match_r_t->associations[i].second != -1)
+        {
+            std::cout << "id first : " << match_r_t->associations[i].first << std::endl;
+            std::cout << "id second : " << match_r_t->associations[i].second << std::endl;
+        }
+
+    auto key_ref    = new_scene_reference->keypoints_list_;
+    auto key_target = new_scene_target->keypoints_list_;
+
+    std::vector<double> x_ref_all, x_target_all;
+    std::vector<double> y_ref_all, y_target_all;
+
+    // Plotting keypoints scenes
+    for (int i = 0; i < key_ref.size(); i++)
+    {
+        x_ref_all.push_back(key_ref[i].point.x());
+        y_ref_all.push_back(key_ref[i].point.y());
+    }
+
+    for (int i = 0; i < key_target.size(); i++)
+    {
+        x_target_all.push_back(key_target[i].point.x());
+        y_target_all.push_back(key_target[i].point.y());
+    }
+
+    std::vector<double> x_ref, x_target;
+    std::vector<double> y_ref, y_target;
+    for (auto asso : match_r_t->associations)
+        if (asso.second != -1)
+        {
+            x_ref.push_back(key_ref[asso.first].point.x());
+            y_ref.push_back(key_ref[asso.first].point.y());
+
+            x_target.push_back(key_target[asso.second].point.x());
+            y_target.push_back(key_target[asso.second].point.y());
+        }
+}
+
+TEST_F(ProcessorLoopClosureFalkoTest, TestEmplaceFeatures)
+{
+    auto cap_ref    = emplaceCaptureLaser2d(emplaceFrame(1, Vector3d::Zero()), reference_scan_1);
+    auto cap_target = emplaceCaptureLaser2d(emplaceFrame(2, Vector3d::Zero()), target_scan_1);
+
+    processor->emplaceFeatures(cap_target);
+    processor->emplaceFeatures(cap_ref);
+
+    auto cap_laser_1 = std::dynamic_pointer_cast<CaptureLaser2d>(cap_target);
+    auto scan_1      = cap_laser_1->getScan();
+
+    std::vector<falkolib::FALKO> key_target;
+    std::vector<falkolib::FALKO> key_ref;
+
+    for (auto feat : cap_target->getFeatureList())
+        if (feat->getType() == "FeatureSceneFalko")
+        {
+            auto feat_falko = std::static_pointer_cast<FeatureSceneFalkoBsc>(feat);
+            key_target      = feat_falko->getScene()->keypoints_list_;
+        }
+
+    for (auto feat : cap_ref->getFeatureList())
+        if (feat->getType() == "FeatureSceneFalko")
+        {
+            auto feat_falko = std::static_pointer_cast<FeatureSceneFalkoBsc>(feat);
+            key_ref         = feat_falko->getScene()->keypoints_list_;
+        }
+
+    // std::cout << "reference keypoints size : " << key_ref.size() << std::endl;
+    // std::cout << "target keypoints size : " << key_target.size() << std::endl;
+
+    std::vector<double> x_ref_all, x_target_all;
+    std::vector<double> y_ref_all, y_target_all;
+
+    // Plotting keypoints scenes
+    for (int i = 0; i < key_ref.size(); i++)
+    {
+        x_ref_all.push_back(key_ref[i].point.x());
+        y_ref_all.push_back(key_ref[i].point.y());
+    }
+
+    for (int i = 0; i < key_target.size(); i++)
+    {
+        x_target_all.push_back(key_target[i].point.x());
+        y_target_all.push_back(key_target[i].point.y());
+    }
+
+    auto matches = processor->findLoopClosures(cap_target);
+
+    ASSERT_TRUE(matches.size() > 0);
+
+    auto match_falko = std::static_pointer_cast<MatchLoopClosureFalko>(matches.begin()->second);
+
+    auto associations = match_falko->match_falko_->associations;
+
+    // std::cout << "associations.size() :" << associations.size() << std::endl;
+
+    std::vector<double> x_ref, x_target;
+    std::vector<double> y_ref, y_target;
+
+    for (auto asso : associations)
+        if (asso.second != -1)
+        {
+            x_ref.push_back(key_ref[asso.first].point.x());
+            y_ref.push_back(key_ref[asso.first].point.y());
+
+            x_target.push_back(key_target[asso.second].point.x());
+            y_target.push_back(key_target[asso.second].point.y());
+        }
+}
+
+TEST_F(ProcessorLoopClosureFalkoTest, TestProcessCapture)
+{
+    auto cap_ref    = emplaceCaptureLaser2d(emplaceFrame(1, Vector3d::Zero()), reference_scan_1);
+    auto cap_target = emplaceCaptureLaser2d(emplaceFrame(2, Vector3d::Zero()), target_scan_1);
+
+    processor->captureCallback(cap_ref);
+    auto cap_laser_1 = std::dynamic_pointer_cast<CaptureLaser2d>(cap_target);
+    auto scan_1      = cap_laser_1->getScan();
+
+    std::vector<falkolib::FALKO> key_target;
+    std::vector<falkolib::FALKO> key_ref;
+
+    for (auto feat : cap_ref->getFeatureList())
+        if (feat->getType() == "FeatureSceneFalko")
+        {
+            auto feat_falko = std::static_pointer_cast<FeatureSceneFalkoBsc>(feat);
+            key_ref         = feat_falko->getScene()->keypoints_list_;
+        }
+
+    cap_target->process();
+    //processor->process(cap_target);
+
+    for (auto feat : cap_target->getFeatureList())
+        if (feat->getType() == "FeatureSceneFalko")
+        {
+            auto feat_falko = std::static_pointer_cast<FeatureSceneFalkoBsc>(feat);
+            key_target      = feat_falko->getScene()->keypoints_list_;
+        }
+
+    // std::cout << "reference keypoints size : " << key_ref.size() << std::endl;
+    // std::cout << "target keypoints size : " << key_target.size() << std::endl;
+    // std::cout << "processor->match_list_.size() : " << processor->match_list_.size() << std::endl;
+
+    std::vector<double> x_ref_all, x_target_all;
+    std::vector<double> y_ref_all, y_target_all;
+
+    // Plotting keypoints scenes
+    for (int i = 0; i < key_ref.size(); i++)
+    {
+        x_ref_all.push_back(key_ref[i].point.x());
+        y_ref_all.push_back(key_ref[i].point.y());
+    }
+
+    for (int i = 0; i < key_target.size(); i++)
+    {
+        x_target_all.push_back(key_target[i].point.x());
+        y_target_all.push_back(key_target[i].point.y());
+    }
+
+    std::vector<double> x_ref, x_target;
+    std::vector<double> y_ref, y_target;
+
+    auto match_falko = std::static_pointer_cast<MatchLoopClosureFalko>(processor->match_list_.front());
+    auto associations = match_falko->match_falko_->associations;
+
+    for (auto asso : associations)
+        if (asso.second != -1)
+        {
+            x_ref.push_back(key_ref[asso.first].point.x());
+            y_ref.push_back(key_ref[asso.first].point.y());
+
+            x_target.push_back(key_target[asso.second].point.x());
+            y_target.push_back(key_target[asso.second].point.y());
+        }
+}
+
+int main(int argc, char **argv)
+{
+    testing::InitGoogleTest(&argc, argv);
+    return RUN_ALL_TESTS();
+}
diff --git a/test/gtest_processor_loop_closure_falko_icp.cpp b/test/gtest_processor_loop_closure_falko_icp.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f061bb06f13eddcec2ac6159d4b493fef74380bc
--- /dev/null
+++ b/test/gtest_processor_loop_closure_falko_icp.cpp
@@ -0,0 +1,121 @@
+//--------LICENSE_START--------
+//
+// Copyright (C) 2020,2021 Institut de Robòtica i Informàtica Industrial, CSIC-UPC.
+// Authors: Joan Solà Ortega (jsola@iri.upc.edu)
+// All rights reserved.
+//
+// This file is part of WOLF
+// WOLF is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+//--------LICENSE_END--------
+#include "laser/internal/config.h"
+#include "core/capture/capture_void.h"
+#include "core/problem/problem.h"
+#include "core/utils/utils_gtest.h"
+
+#include "laser/processor/processor_loop_closure_falko_icp.h"
+#include "laser/sensor/sensor_laser_2d.h"
+
+#include "core/yaml/parser_yaml.h"
+#include "core/utils/params_server.h"
+
+#include "data/scan_data.h"
+
+// STL
+#include <iostream>
+#include <iterator>
+
+using namespace wolf;
+using namespace Eigen;
+
+std::string laser_root_dir = _WOLF_LASER_ROOT_DIR;
+
+class ProcessorLoopClosureFalkoIcpTest : public testing::Test
+{
+  public:
+    // Wolf problem
+    ProblemPtr    problem = Problem::create("PO", 2);
+    SensorBasePtr sensor;
+    // std::shared_ptr<ProcessorLoopClosureFalkoIcp<bsc, bscExtractor, nn_matcher>> processor;
+    ProcessorLoopClosureFalkoIcpNnBscPtr processor;
+
+    virtual void SetUp()
+    {
+
+        // Emplace sensor
+        laserscanutils::LaserScanParams _params;
+        _params.angle_min_  = 0;
+        _params.angle_max_  = 2.0 * M_PI;
+        _params.angle_step_ = 2.0 * M_PI / (testRanges1.size() - 1);
+        _params.range_min_  = 0;
+        _params.range_max_  = 200;
+        sensor =
+        SensorBase::emplace<SensorLaser2d>(problem->getHardware(), std::make_shared<StateBlock>(Vector2d::Zero()),
+                                           std::make_shared<StateBlock>(Vector1d::Zero()), _params);
+
+        // Emplace processor
+        ParserYaml   parser = ParserYaml("test/yaml/params_processor_loop_closure_falko.yaml", laser_root_dir);
+        ParamsServer server = ParamsServer(parser.getParams());
+
+        auto params = std::make_shared<ParamsProcessorLoopClosureFalkoIcp>("ProcessorLoopClosureFalko",
+                                                                           server);
+        processor = ProcessorBase::emplace<ProcessorLoopClosureFalkoIcpNnBsc>(sensor, params);
+    }
+
+    FrameBasePtr emplaceFrame(TimeStamp ts, const Vector3d &x)
+    {
+        // new frame
+        return problem->emplaceFrame(ts, x);
+    }
+
+    CaptureLaser2dPtr emplaceCaptureLaser2d(FrameBasePtr frame, const std::vector<float> &_ranges)
+    {
+        // new capture
+        return CaptureBase::emplace<CaptureLaser2d>(frame, frame->getTimeStamp(), sensor, _ranges);
+    }
+
+    CaptureLaser2dPtr createCaptureLaser2d(TimeStamp ts, const std::vector<float> &_ranges)
+    {
+        // new capture
+        return std::make_shared<CaptureLaser2d>(ts, sensor, _ranges);
+    }
+};
+
+TEST_F(ProcessorLoopClosureFalkoIcpTest, validatefindLoopClosures)
+{
+
+    auto cap1 = emplaceCaptureLaser2d(emplaceFrame(1, Vector3d::Zero()), testRanges1);
+    auto cap2 = emplaceCaptureLaser2d(emplaceFrame(2, Vector3d::Zero()), testRanges2);
+    auto cap3 = emplaceCaptureLaser2d(emplaceFrame(3, Vector3d::Zero()), testRanges1);
+
+    // captureCallback
+    processor->captureCallback(cap1);
+    EXPECT_EQ(processor->match_list_.size(), 0);
+
+    processor->captureCallback(cap2);
+    EXPECT_EQ(processor->match_list_.size(), 1);
+    EXPECT_EQ(processor->match_list_.back()->capture_reference, cap1);
+    EXPECT_EQ(processor->match_list_.back()->capture_target, cap2);
+
+    processor->captureCallback(cap3);
+    EXPECT_EQ(processor->match_list_.size(), 3);
+    EXPECT_EQ(processor->match_list_.back()->capture_reference, cap1);
+    EXPECT_EQ(processor->match_list_.back()->capture_target, cap3);
+}
+
+int main(int argc, char **argv)
+{
+    testing::InitGoogleTest(&argc, argv);
+    return RUN_ALL_TESTS();
+}
diff --git a/test/gtest_processor_loop_closure_icp.cpp b/test/gtest_processor_loop_closure_icp.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c5941b063f42865d97b2d5d70eb64e512fb58acf
--- /dev/null
+++ b/test/gtest_processor_loop_closure_icp.cpp
@@ -0,0 +1,245 @@
+//--------LICENSE_START--------
+//
+// Copyright (C) 2020,2021 Institut de Robòtica i Informàtica Industrial, CSIC-UPC.
+// Authors: Joan Solà Ortega (jsola@iri.upc.edu)
+// All rights reserved.
+//
+// This file is part of WOLF
+// WOLF is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+//--------LICENSE_END--------
+#include "laser/internal/config.h"
+
+#include <core/ceres_wrapper/solver_ceres.h>
+#include <core/utils/utils_gtest.h>
+
+#include "laser/processor/processor_loop_closure_icp.h"
+#include <stdlib.h>
+
+using namespace wolf;
+using namespace Eigen;
+
+std::string laser_root_dir = _WOLF_LASER_ROOT_DIR;
+
+class ProcessorLoopClosureIcp_Test : public testing::Test
+{
+    public:
+        ProblemPtr problem;
+        SensorLaser2dPtr lidar;
+        ProcessorLoopClosureIcpPtr processor;
+
+        void SetUp() override
+        {
+            problem     = Problem::create("PO", 2);
+            lidar       = std::static_pointer_cast<SensorLaser2d>(problem->installSensor("SensorLaser2d",
+                                                                                         "lidar",
+                                                                                         Eigen::Vector3d(0,0,0),
+                                                                                         laser_root_dir + "/test/yaml/sensor_laser_2d.yaml"));
+            auto params = std::make_shared<ParamsProcessorLoopClosureIcp>();
+
+            params->recent_frames_ignored                   = 0;
+            params->frames_ignored_after_loop               = 0;
+            params->max_error_threshold                     = 0.1;
+            params->min_points_percent                      = 50;
+
+            params->icp_params.use_point_to_line_distance   = 1;
+            params->icp_params.max_correspondence_dist      = 1e9;
+            params->icp_params.max_iterations               = 1e3;
+            params->icp_params.use_corr_tricks              = 1;
+            params->icp_params.outliers_maxPerc             = 5;
+            params->icp_params.outliers_adaptive_order      = 6;
+            params->icp_params.outliers_adaptive_mult       = 7;
+            params->icp_params.do_compute_covariance        = 1;
+            params->icp_params.cov_factor                   = 1;
+            params->icp_params.max_angular_correction_deg   = 1e9;
+            params->icp_params.max_linear_correction        = 1e9;
+            params->icp_params.epsilon_xy                   = 0.1;
+            params->icp_params.epsilon_theta                = 0.1;
+            params->icp_params.sigma                        = 0.1;
+            params->icp_params.restart                      = 0;
+            params->icp_params.restart_threshold_mean_error = 0;
+            params->icp_params.restart_dt                   = 0;
+            params->icp_params.restart_dtheta               = 0;
+            params->icp_params.clustering_threshold         = 0;
+            params->icp_params.orientation_neighbourhood    = 0;
+            params->icp_params.do_alpha_test                = 0;
+            params->icp_params.do_alpha_test_thresholdDeg   = 0;
+            params->icp_params.do_visibility_test           = 0;
+            params->icp_params.outliers_remove_doubles      = 0;
+            params->icp_params.debug_verify_tricks          = 0;
+            params->icp_params.gpm_theta_bin_size_deg       = 0;
+            params->icp_params.gpm_extend_range_deg         = 0;
+            params->icp_params.gpm_interval                 = 0;
+            params->icp_params.min_reading                  = 0;
+            params->icp_params.max_reading                  = 100;
+            params->icp_params.use_ml_weights               = 0;
+            params->icp_params.use_sigma_weights            = 0;
+
+            processor   = std::static_pointer_cast<ProcessorLoopClosureIcp>(problem->installProcessor("ProcessorLoopClosureIcp",
+                                                                                                      "prc icp",
+                                                                                                      lidar,
+                                                                                                      params));
+        }
+
+        std::vector<float> generateRanges(const int& frame_idx)
+        {
+            // generating synthetic 360º scan, half with range_A and half with range_B depending on the frame_idx. Randomly rotated.
+            // loop closures should occur (exact ranges but rotated) between pairs of frame_idx separated by 4 (0-4, 1-5, ...)
+
+            int n_ranges = std::round((lidar->getScanParams().angle_max_-lidar->getScanParams().angle_min_) / lidar->getScanParams().angle_step_);
+
+            // shape: 0-2 half circles, 1-square, 2-star-like
+            int shape = frame_idx % 3;
+
+            std::vector<float> ranges(n_ranges);
+            for (auto i = 0; i < n_ranges; i++)
+            {
+                // HALF CIRCLES (10m and 5m)
+                if (shape == 0)
+                    ranges[i] = (i < n_ranges / 2 ? 10.0 : 5.0);
+
+                // SQUARE (2m)
+                else if (shape == 1)
+                    ranges[i] = 2.0 * sqrt(std::pow(cos(i * lidar->getScanParams().angle_step_),2) +
+                                           std::pow(sin(i * lidar->getScanParams().angle_step_),2));
+
+                // STAR-LIKE (2m to 10m)
+                else if (shape == 2)
+                    ranges[i] = 2.0 + (i % (n_ranges / 6)) * 8.0 / (n_ranges / 6);
+            }
+
+            // rotate randomly
+            srand (time(NULL)); // initialize random seed
+            int init = rand() % n_ranges; // half starting randomly between 0 and n_ranges-1
+            std::rotate(ranges.begin(),ranges.begin()+init,ranges.end());
+
+            return ranges;
+        }
+
+        FrameBasePtr emplaceFrame(TimeStamp ts, const Vector3d &x)
+        {
+            // new frame
+            return problem->emplaceFrame(ts, x);
+        }
+
+        CaptureLaser2dPtr emplaceCaptureLaser2d(FrameBasePtr frame, const std::vector<float> &_ranges)
+        {
+            // new capture
+            return CaptureBase::emplace<CaptureLaser2d>(frame, frame->getTimeStamp(), lidar, _ranges);
+        }
+};
+
+
+TEST_F(ProcessorLoopClosureIcp_Test, setup)
+{
+    ASSERT_TRUE(problem->check());
+}
+
+TEST_F(ProcessorLoopClosureIcp_Test, loop_closure)
+{
+    TimeStamp t(0.0);
+
+    for (int i = 0; i < 6; i++)
+    {
+        auto frm = emplaceFrame(t, Vector3d::Zero());
+        auto cap = emplaceCaptureLaser2d(frm, generateRanges(i));
+
+        processor->keyFrameCallback(frm);
+        if (i > 2)
+        {
+            EXPECT_EQ(cap->getFeatureList().size(), 1);
+            EXPECT_EQ(cap->getFeatureList().front()->getFactorList().size(), 1);
+            EXPECT_EQ(cap->getFeatureList().front()->getFactorList().front()->getType(), "FactorRelativePose2dWithExtrinsics");
+            EXPECT_FALSE(cap->getFeatureList().front()->getFactorList().front()->getFrameOther() == nullptr);
+            EXPECT_EQ(cap->getFeatureList().front()->getFactorList().front()->getFrameOther()->getTimeStamp(), TimeStamp(i%3));
+            problem->print(4,1,1,1);
+        }
+        else
+        {
+            EXPECT_TRUE(cap->getFeatureList().empty());
+            EXPECT_TRUE(frm->getConstrainedByList().empty());
+            problem->print(4,1,1,1);
+        }
+        t += 1;
+    }
+}
+
+TEST_F(ProcessorLoopClosureIcp_Test, loop_closure_ignore_previous)
+{
+    processor->getParams()->recent_frames_ignored = 3;
+
+    TimeStamp t(0.0);
+
+    for (int i = 0; i < 6; i++)
+    {
+        auto frm = emplaceFrame(t, Vector3d::Zero());
+        auto cap = emplaceCaptureLaser2d(frm, generateRanges(i));
+
+        processor->keyFrameCallback(frm);
+        if (i > 5)
+        {
+            EXPECT_EQ(cap->getFeatureList().size(), 1);
+            EXPECT_EQ(cap->getFeatureList().front()->getFactorList().size(), 1);
+            EXPECT_EQ(cap->getFeatureList().front()->getFactorList().front()->getType(), "FactorRelativePose2dWithExtrinsics");
+            EXPECT_FALSE(cap->getFeatureList().front()->getFactorList().front()->getFrameOther() == nullptr);
+            EXPECT_EQ(cap->getFeatureList().front()->getFactorList().front()->getFrameOther()->getTimeStamp(), TimeStamp(i%3));
+            problem->print(4,1,1,1);
+        }
+        else
+        {
+            EXPECT_TRUE(cap->getFeatureList().empty());
+            EXPECT_TRUE(frm->getConstrainedByList().empty());
+            problem->print(4,1,1,1);
+        }
+        t += 1;
+    }
+}
+
+TEST_F(ProcessorLoopClosureIcp_Test, loop_closure_frames_ignored_after_loop)
+{
+    processor->getParams()->frames_ignored_after_loop = 2;
+
+    TimeStamp t(0.0);
+
+    for (int i = 0; i < 6; i++)
+    {
+        auto frm = emplaceFrame(t, Vector3d::Zero());
+        auto cap = emplaceCaptureLaser2d(frm, generateRanges(i));
+
+        processor->keyFrameCallback(frm);
+        if (i == 3)
+        {
+            EXPECT_EQ(cap->getFeatureList().size(), 1);
+            EXPECT_EQ(cap->getFeatureList().front()->getFactorList().size(), 1);
+            EXPECT_EQ(cap->getFeatureList().front()->getFactorList().front()->getType(), "FactorRelativePose2dWithExtrinsics");
+            EXPECT_FALSE(cap->getFeatureList().front()->getFactorList().front()->getFrameOther() == nullptr);
+            EXPECT_EQ(cap->getFeatureList().front()->getFactorList().front()->getFrameOther()->getTimeStamp(), TimeStamp(i%3));
+            problem->print(4,1,1,1);
+        }
+        else
+        {
+            EXPECT_TRUE(cap->getFeatureList().empty());
+            EXPECT_TRUE(frm->getConstrainedByList().empty());
+            problem->print(4,1,1,1);
+        }
+        t += 1;
+    }
+}
+
+int main(int argc, char **argv)
+{
+  testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
+
diff --git a/test/gtest_processor_tracker_feature_polyline_2d.cpp b/test/gtest_processor_tracker_feature_polyline_2d.cpp
deleted file mode 100644
index 0553e9e6814e0444f22338c8aadf6de94665b359..0000000000000000000000000000000000000000
--- a/test/gtest_processor_tracker_feature_polyline_2d.cpp
+++ /dev/null
@@ -1,1203 +0,0 @@
-//--------LICENSE_START--------
-//
-// Copyright (C) 2020,2021 Institut de Robòtica i Informàtica Industrial, CSIC-UPC.
-// Authors: Joan Solà Ortega (jsola@iri.upc.edu)
-// All rights reserved.
-//
-// This file is part of WOLF
-// WOLF is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with this program.  If not, see <http://www.gnu.org/licenses/>.
-//
-//--------LICENSE_END--------
-/**
- * \file gtest_processor_tracker_feature_polyline_2d.cpp
- *
- *  Created on: Apr 3, 2019
- *      \author: jvallve
- */
-
-#include "laser/processor/processor_tracker_feature_polyline_2d.h"
-#include "core/common/wolf.h"
-
-#include <core/utils/utils_gtest.h>
-#include "core/utils/logging.h"
-
-#include "core/ceres_wrapper/ceres_manager.h"
-
-#include <cmath>
-#include <iostream>
-
-using namespace Eigen;
-using namespace wolf;
-WOLF_PTR_TYPEDEFS(ProcessorPolylinePublicMethods);
-class ProcessorPolylinePublicMethods : public ProcessorTrackerFeaturePolyline2d
-{
-    public:
-        ProcessorPolylinePublicMethods(ParamsProcessorTrackerFeaturePolyline2dPtr _params) :
-            ProcessorTrackerFeaturePolyline2d(_params)
-        {
-
-        }
-
-        unsigned int trackFeatures(const FeatureBasePtrList& _features_last_in,
-                                   FeatureBasePtrList& _features_incoming_out,
-                                   FeatureMatchMap& _feature_correspondences)
-        {
-            return ProcessorTrackerFeaturePolyline2d::trackFeatures(_features_last_in,_features_incoming_out,_feature_correspondences);
-        }
-
-        bool correctFeatureDrift(const FeatureBasePtr _origin_feature,
-                                 const FeatureBasePtr _last_feature,
-                                 FeatureBasePtr _incoming_feature)
-        {
-            return ProcessorTrackerFeaturePolyline2d::correctFeatureDrift(_origin_feature,
-                                                                          _last_feature,
-                                                                          _incoming_feature);
-        }
-
-        bool voteForKeyFrame()
-        {
-            return ProcessorTrackerFeaturePolyline2d::voteForKeyFrame();
-        }
-
-        unsigned int processNew(const unsigned int& _max_features)
-        {
-            return ProcessorTrackerFeaturePolyline2d::processNew(_max_features);
-        }
-
-        unsigned int detectNewFeatures(const int& _max_new_features,
-                                       FeatureBasePtrList& _features_last_out)
-        {
-            return ProcessorTrackerFeaturePolyline2d::detectNewFeatures(_max_new_features, _features_last_out);
-        }
-
-        void establishConstraints()
-        {
-            ProcessorTrackerFeaturePolyline2d::establishFactors();
-        }
-
-        void emplaceConstraintPointToLine(FeaturePolyline2dPtr _polyline_feature,
-                                          LandmarkPolyline2dPtr _polyline_landmark,
-                                          const int& _ftr_point_id,
-                                          const int& _lmk_point_id,
-                                          const int& _lmk_prev_point_id)
-        {
-            ProcessorTrackerFeaturePolyline2d::emplaceFactorPointToLine(_polyline_feature,
-                                                                            _polyline_landmark,
-                                                                            _ftr_point_id,
-                                                                            _lmk_point_id,
-                                                                            _lmk_prev_point_id);
-        }
-
-        void emplaceConstraintPoint(FeaturePolyline2dPtr _polyline_feature,
-                                    LandmarkPolyline2dPtr _polyline_landmark,
-                                    const int& _ftr_point_id,
-                                    const int& _lmk_point_id)
-        {
-            ProcessorTrackerFeaturePolyline2d::emplaceFactorPoint(_polyline_feature,
-                                                                      _polyline_landmark,
-                                                                      _ftr_point_id,
-                                                                      _lmk_point_id);
-        }
-
-        LandmarkBasePtr createLandmark(FeatureBasePtr _feature_ptr)
-        {
-            return ProcessorTrackerFeaturePolyline2d::createLandmark(_feature_ptr);
-        }
-
-        bool modifyLandmarkAndMatch(LandmarkMatchPolyline2dPtr& lmk_match, FeaturePolyline2dPtr& pl_ftr)
-        {
-            return ProcessorTrackerFeaturePolyline2d::modifyLandmarkAndMatch( lmk_match, pl_ftr);
-        }
-
-        void tryMatchWithFeature(FeatureMatchPolyline2dScalarMap& ftr_matches,
-                                 const FeaturePolyline2dPtr& _ftr_last,
-                                 const FeaturePolyline2dPtr& _ftr_incoming,
-                                 const Eigen::Matrix3d& _T_last_incoming_prior) const
-        {
-            ProcessorTrackerFeaturePolyline2d::tryMatchWithFeature( ftr_matches,
-                                                                   _ftr_last,
-                                                                   _ftr_incoming,
-                                                                   _T_last_incoming_prior);
-        }
-
-        void tryMatchWithLandmark(LandmarkMatchPolyline2dScalarMap& lmk_matches,
-                                  const LandmarkPolyline2dPtr& _lmk_ptr,
-                                  const FeaturePolyline2dPtr& _feat_ptr,
-                                  const Eigen::Matrix3d& _T_feature_landmark_prior) const
-        {
-            ProcessorTrackerFeaturePolyline2d::tryMatchWithLandmark(lmk_matches,
-                                                                    _lmk_ptr,
-                                                                    _feat_ptr,
-                                                                    _T_feature_landmark_prior);
-        }
-
-        bool updateMatchWithLandmark(LandmarkMatchPolyline2dPtr& _lmk_match, LandmarkPolyline2dPtr& _lmk_ptr, FeaturePolyline2dPtr& _feat_ptr) const
-        {
-            return ProcessorTrackerFeaturePolyline2d::updateMatchWithLandmark(_lmk_match, _lmk_ptr, _feat_ptr);
-        }
-
-        void computeTransformations()
-        {
-            ProcessorTrackerFeaturePolyline2d::computeTransformations();
-        }
-
-        LandmarkMatchPolyline2dPtr concatenateFeatureLandmarkMatches(FeaturePolyline2dPtr pl_incoming,
-                                                                     FeatureMatchPolyline2dPtr ftr_match_incoming_last,
-                                                                     LandmarkMatchPolyline2dPtr lmk_match_last) const
-        {
-            return ProcessorTrackerFeaturePolyline2d::concatenateFeatureLandmarkMatches(pl_incoming,
-                                                                                        ftr_match_incoming_last,
-                                                                                        lmk_match_last);
-        }
-};
-
-class ProcessorPolyline2dt : public testing::Test
-{
-    public: //These can be accessed in fixtures
-        ProcessorPolylinePublicMethodsPtr processor_pl;
-        wolf::SensorBasePtr sensor_ptr;
-        wolf::TimeStamp t;
-        double mti_clock, tmp;
-        double dt;
-        Vector6d data;
-        Matrix6d data_cov;
-        VectorXd x0;
-        std::shared_ptr<wolf::CaptureIMU> cap_imu_ptr;
-
-    //a new of this will be created for each new test
-    virtual void SetUp()
-    {
-        using namespace wolf;
-        using namespace Eigen;
-        using std::shared_ptr;
-        using std::make_shared;
-        using std::static_pointer_cast;
-        using namespace wolf::Constants;
-
-        std::string wolf_root = _WOLF_ROOT_DIR;
-
-        // Wolf problem
-        problem = Problem::create("POV", 3);
-        Vector7d extrinsics = (Vector7d() << 0,0,0, 0,0,0,1).finished();
-        sensor_ptr = problem->installSensor("IMU", "Main IMU", extrinsics,  wolf_root + "/src/examples/sensor_imu.yaml");
-        ProcessorBasePtr processor_ptr = problem->installProcessor("IMU", "IMU pre-integrator", "Main IMU", wolf_root + "/src/examples/processor_imu.yaml");
-
-        // Time and data variables
-        data = Vector6d::Zero();
-        data_cov = Matrix6d::Identity();
-
-        // Set the origin
-        x0.resize(10);
-
-        // Create one capture to store the IMU data arriving from (sensor / callback / file / etc.)
-        cap_imu_ptr = make_shared<CaptureIMU>(t, sensor_ptr, data, data_cov, Vector6d::Zero());
-    }
-
-    virtual void TearDown()
-    {
-        // code here will be called just after the test completes
-        // ok to through exceptions from here if need be
-        /*
-            You can do deallocation of resources in TearDown or the destructor routine. 
-                However, if you want exception handling you must do it only in the TearDown code because throwing an exception 
-                from the destructor results in undefined behavior.
-            The Google assertion macros may throw exceptions in platforms where they are enabled in future releases. 
-                Therefore, it's a good idea to use assertion macros in the TearDown code for better maintenance.
-        */
-    }
-};
-
-TEST(ProcessorIMU_constructors, ALL)
-{
-    using namespace wolf;
-
-    //constructor with ProcessorIMUParamsPtr argument only
-    ParamsProcessorIMUPtr param_ptr = std::make_shared<ParamsProcessorIMU>();
-    param_ptr->max_time_span =   2.0;
-    param_ptr->max_buff_length = 20000;
-    param_ptr->dist_traveled =   2.0;
-    param_ptr->angle_turned =    2.0;
-
-    ProcessorIMUPtr prc1 = std::make_shared<ProcessorIMU>(param_ptr);
-    ASSERT_EQ(prc1->getMaxTimeSpan(), param_ptr->max_time_span);
-    ASSERT_EQ(prc1->getMaxBuffLength(), param_ptr->max_buff_length);
-    ASSERT_EQ(prc1->getDistTraveled(), param_ptr->dist_traveled);
-    ASSERT_EQ(prc1->getAngleTurned(), param_ptr->angle_turned);
-
-    //Factory constructor without yaml
-    std::string wolf_root = _WOLF_ROOT_DIR;
-    ProblemPtr problem = Problem::create("POV", 3);
-    Vector7d extrinsics = (Vector7d()<<1,0,0, 0,0,0,1).finished();
-    SensorBasePtr sensor_ptr = problem->installSensor("IMU", "Main IMU", extrinsics, wolf_root + "/src/examples/sensor_imu.yaml");
-    ProcessorBasePtr processor_ptr = problem->installProcessor("IMU", "IMU pre-integrator", "Main IMU", "");
-    ParamsProcessorIMU params_default;
-    ASSERT_EQ(std::static_pointer_cast<ProcessorIMU>(processor_ptr)->getMaxTimeSpan(),   params_default.max_time_span);
-    ASSERT_EQ(std::static_pointer_cast<ProcessorIMU>(processor_ptr)->getMaxBuffLength(), params_default.max_buff_length);
-    ASSERT_EQ(std::static_pointer_cast<ProcessorIMU>(processor_ptr)->getDistTraveled(),  params_default.dist_traveled);
-    ASSERT_EQ(std::static_pointer_cast<ProcessorIMU>(processor_ptr)->getAngleTurned(),   params_default.angle_turned);
-
-    //Factory constructor with yaml
-    processor_ptr = problem->installProcessor("IMU", "Sec IMU pre-integrator", "Main IMU", wolf_root + "/src/examples/processor_imu.yaml");
-    ASSERT_EQ(std::static_pointer_cast<ProcessorIMU>(processor_ptr)->getMaxTimeSpan(),   2.0);
-    ASSERT_EQ(std::static_pointer_cast<ProcessorIMU>(processor_ptr)->getMaxBuffLength(), 20000);
-    ASSERT_EQ(std::static_pointer_cast<ProcessorIMU>(processor_ptr)->getDistTraveled(),  2.0);
-    ASSERT_EQ(std::static_pointer_cast<ProcessorIMU>(processor_ptr)->getAngleTurned(),   0.2);
-}
-
-TEST(ProcessorIMU, voteForKeyFrame)
-{
-    using namespace wolf;
-    using namespace Eigen;
-    using std::shared_ptr;
-    using std::make_shared;
-    using std::static_pointer_cast;
-    using namespace wolf::Constants;
-
-    std::string wolf_root = _WOLF_ROOT_DIR;
-
-    // Wolf problem
-    ProblemPtr problem = Problem::create("POV", 3);
-    Vector7d extrinsics = (Vector7d()<<1,0,0, 0,0,0,1).finished();
-    SensorBasePtr sensor_ptr = problem->installSensor("IMU", "Main IMU", extrinsics,  wolf_root + "/src/examples/sensor_imu.yaml");
-    ParamsProcessorIMUPtr prc_imu_params = std::make_shared<ParamsProcessorIMU>();
-    prc_imu_params->max_time_span = 1;
-    prc_imu_params->max_buff_length = 1000000000; //make it very high so that this condition will not pass
-    prc_imu_params->dist_traveled = 1000000000;
-    prc_imu_params->angle_turned = 1000000000;
-    prc_imu_params->voting_active = true;
-    ProcessorBasePtr processor_ptr = problem->installProcessor("IMU", "IMU pre-integrator", sensor_ptr, prc_imu_params);
-    
-    //setting origin
-    VectorXd x0(10);
-    TimeStamp t(0);
-    x0 << 0,0,0,  0,0,0,1,  0,0,0;
-    MatrixXd P0(9,9); P0.setIdentity();
-    problem->setPrior(x0, P0, t);
-    //data variable and covariance matrix
-    // since we integrate only a few times, give the capture a big covariance, otherwise it will be so small that it won't pass following assertions
-    Vector6d data;
-    data << 1,0,0, 0,0,0;
-    Matrix6d data_cov(Matrix6d::Identity());
-    data_cov(0,0) = 0.5;
-
-    // Create the captureIMU to store the IMU data arriving from (sensor / callback / file / etc.)
-    std::shared_ptr<wolf::CaptureIMU> cap_imu_ptr = make_shared<CaptureIMU>(t, sensor_ptr, data, data_cov, Vector6d::Zero());
-
-    //  Time  
-    // we want more than one data to integrate otherwise covariance will be 0
-    double dt = std::static_pointer_cast<ProcessorIMU>(processor_ptr)->getMaxTimeSpan() - 0.1;
-    t.set(dt);
-    cap_imu_ptr->setTimeStamp(t);
-    sensor_ptr->process(cap_imu_ptr);
-
-    dt = std::static_pointer_cast<ProcessorIMU>(processor_ptr)->getMaxTimeSpan() + 0.1;
-    t.set(dt);
-    cap_imu_ptr->setTimeStamp(t);
-    sensor_ptr->process(cap_imu_ptr);
-
-    /*There should be 3 frames :
-        - 1 KeyFrame at origin
-        - 1 keyframe created by process() in voteForKeyFrame() since conditions to create a keyframe are met
-        - 1 frame that would be used by future data
-    */
-    ASSERT_EQ(problem->getTrajectoryPtr()->getFrameList().size(),(unsigned int) 3);
-
-    /* if max_time_span == 2,  Wolf tree should be
-
-    Hardware
-        S1
-            pm5
-            o: C2 - F2
-            l: C4 - F3
-        Trajectory
-        KF1
-            Estim, ts=0,	 x = ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0)
-            C1 -> S1
-        KF2
-            Estim, ts=2.1,	 x = ( 2.2     0       -22     0       0       0       1       2.1     0       -21     0       0       0       0       0       0      )
-            C2 -> S1
-                f1
-                    m = ( 2.21 0   0   0   0   0   1   2.1 0   0  )
-                    c1 --> F1
-        F3
-            Estim, ts=2.1,	 x = ( . . .)
-            C4 -> S1
-    */
-    //TODO : ASSERT TESTS to make sure the constraints are correctly set + check the tree above
-
-}
-
-//replace TEST by TEST_F if SetUp() needed
-TEST_F(ProcessorIMUt, interpolate)
-{
-    using namespace wolf;
-
-    t.set(0);
-    x0 << 0,0,0,  0,0,0,1,  0,0,0;
-    MatrixXd P0(9,9); P0.setIdentity();
-    problem->setPrior(x0, P0, t);
-
-    data << 2, 0, 0, 0, 0, 0; // only acc_x
-    cap_imu_ptr->setData(data);
-
-    // make one step to depart from origin
-    cap_imu_ptr->setTimeStamp(0.05);
-    sensor_ptr->process(cap_imu_ptr);
-    Motion mot_ref = problem->getProcessorMotionPtr()->getMotion();
-
-    // make two steps, then pretend it's just one
-    cap_imu_ptr->setTimeStamp(0.10);
-    sensor_ptr->process(cap_imu_ptr);
-    Motion mot_int_gt = problem->getProcessorMotionPtr()->getMotion();
-
-    cap_imu_ptr->setTimeStamp(0.15);
-    sensor_ptr->process(cap_imu_ptr);
-    Motion mot_final = problem->getProcessorMotionPtr()->getMotion();
-    mot_final.delta_ = mot_final.delta_integr_;
-    Motion mot_sec = mot_final;
-
-//    problem->getProcessorMotionPtr()->getBuffer().print(0,1,1,0);
-
-class P : public wolf::ProcessorIMU
-{
-    public:
-        P() : ProcessorIMU(std::make_shared<ParamsProcessorIMU>()) {}
-        Motion interp(const Motion& ref, Motion& sec, TimeStamp ts)
-        {
-            return ProcessorIMU::interpolate(ref, sec, ts);
-        }
-} imu;
-
-Motion mot_int = imu.interp(mot_ref, mot_sec, TimeStamp(0.10));
-
-ASSERT_MATRIX_APPROX(mot_int.data_,  mot_int_gt.data_, 1e-6);
-//ASSERT_MATRIX_APPROX(mot_int.delta_, mot_int_gt.delta_, 1e-6); // FIXME: delta_p not correctly interpolated
-ASSERT_MATRIX_APPROX(mot_final.delta_integr_,  mot_sec.delta_integr_, 1e-6);
-
-}
-
-TEST_F(ProcessorIMUt, acc_x)
-{
-    t.set(0); // clock in 0,1 ms ticks
-    x0 << 0,0,0,  0,0,0,1,  0,0,0;
-    MatrixXd P0(9,9); P0.setIdentity();
-    problem->setPrior(x0, P0, t);
-
-    data << 2, 0, 9.806, 0, 0, 0; // only acc_x, but measure gravity!
-
-    cap_imu_ptr->setData(data);
-    cap_imu_ptr->setTimeStamp(0.1);
-    sensor_ptr->process(cap_imu_ptr);
-
-    // Expected state after one integration
-    VectorXd x(10);
-    x << 0.01,0,0, 0,0,0,1, 0.2,0,0; // advanced at a=2m/s2 during 0.1s ==> dx = 0.5*2*0.1^2 = 0.01; dvx = 2*0.1 = 0.2
-    Vector6d b; b << 0,0,0, 0,0,0;
-
-    ASSERT_MATRIX_APPROX(problem->getCurrentState().head(10) , x, wolf::Constants::EPS_SMALL);
-    ASSERT_MATRIX_APPROX(problem->getProcessorMotionPtr()->getLastPtr()->getCalibration() , b, wolf::Constants::EPS_SMALL);
-    ASSERT_MATRIX_APPROX(problem->getProcessorMotionPtr()->getLastPtr()->getCalibrationPreint() , b, wolf::Constants::EPS_SMALL);
-}
-
-TEST_F(ProcessorIMUt, acc_y)
-{
-    // last part of this test fails with precision wolf::Constants::EPS_SMALL beacause error is in 1e-12
-    // difference hier is that we integrate over 1ms periods
-
-    t.set(0); // clock in 0,1 ms ticks
-    x0 << 0,0,0,  0,0,0,1,  0,0,0;
-    MatrixXd P0(9,9); P0.setIdentity();
-    problem->setPrior(x0, P0, t);
-
-    data << 0, 20, 9.806, 0, 0, 0; // only acc_y, but measure gravity!
-
-    cap_imu_ptr->setData(data);
-    cap_imu_ptr->setTimeStamp(0.001);
-    sensor_ptr->process(cap_imu_ptr);
-
-    // Expected state after one integration
-    VectorXd x(10);
-    x << 0,0.00001,0, 0,0,0,1, 0,0.02,0; // advanced at a=20m/s2 during 0.001s ==> dx = 0.5*20*0.001^2 = 0.00001; dvx = 20*0.001 = 0.02
-    Vector6d b; b<< 0,0,0, 0,0,0;
-
-    ASSERT_MATRIX_APPROX(problem->getCurrentState().head(10) , x, wolf::Constants::EPS_SMALL);
-    ASSERT_MATRIX_APPROX(problem->getProcessorMotionPtr()->getLastPtr()->getCalibration() , b, wolf::Constants::EPS_SMALL);
-    ASSERT_MATRIX_APPROX(problem->getProcessorMotionPtr()->getLastPtr()->getCalibrationPreint() , b, wolf::Constants::EPS_SMALL);
-
-    //do so for 5s
-    const unsigned int iter = 1000; //how many ms
-    for(unsigned int i = 1; i < iter; i++) //already did one integration above
-    {
-        cap_imu_ptr->setTimeStamp(i*0.001 + 0.001); //first one will be 0.002 and last will be 5.000
-        sensor_ptr->process(cap_imu_ptr);
-    }
-
-    // advanced at a=20m/s2 during 1s ==> dx = 0.5*20*1^2 = 10; dvx = 20*1 = 20
-    x << 0,10,0, 0,0,0,1, 0,20,0;
-    ASSERT_MATRIX_APPROX(problem->getCurrentState().head(10) , x, wolf::Constants::EPS);
-    ASSERT_MATRIX_APPROX(problem->getProcessorMotionPtr()->getLastPtr()->getCalibration() , b, wolf::Constants::EPS);
-    ASSERT_MATRIX_APPROX(problem->getProcessorMotionPtr()->getLastPtr()->getCalibrationPreint() , b, wolf::Constants::EPS);
-}
-
-TEST_F(ProcessorIMUt, acc_z)
-{
-    t.set(0); // clock in 0,1 ms ticks
-    x0 << 0,0,0,  0,0,0,1,  0,0,0;
-    MatrixXd P0(9,9); P0.setIdentity();
-    problem->setPrior(x0, P0, t);
-
-    data << 0, 0, 9.806 + 2.0, 0, 0, 0; // only acc_z, but measure gravity!
-
-    cap_imu_ptr->setData(data);
-    cap_imu_ptr->setTimeStamp(0.1);
-    sensor_ptr->process(cap_imu_ptr);
-
-    // Expected state after one integration
-    VectorXd x(10);
-    x << 0,0,0.01, 0,0,0,1, 0,0,0.2; // advanced at a=2m/s2 during 0.1s ==> dz = 0.5*2*0.1^2 = 0.01; dvz = 2*0.1 = 0.2
-    Vector6d b; b<< 0,0,0, 0,0,0;
-
-    ASSERT_MATRIX_APPROX(problem->getCurrentState().head(10) , x, wolf::Constants::EPS_SMALL);
-    ASSERT_MATRIX_APPROX(problem->getProcessorMotionPtr()->getLastPtr()->getCalibration() , b, wolf::Constants::EPS_SMALL);
-    ASSERT_MATRIX_APPROX(problem->getProcessorMotionPtr()->getLastPtr()->getCalibrationPreint() , b, wolf::Constants::EPS_SMALL);
-
-    //do so for 5s
-    const unsigned int iter = 50; //how 0.1s 
-    for(unsigned int i = 1; i < iter; i++) //already did one integration above
-    {
-        cap_imu_ptr->setTimeStamp(i*0.1 + 0.1); //first one will be 0.2 and last will be 5.0
-        sensor_ptr->process(cap_imu_ptr);
-    }
-
-    // advanced at a=2m/s2 during 5s ==> dz = 0.5*2*5^2 = 25; dvz = 2*5 = 10
-    x << 0,0,25, 0,0,0,1, 0,0,10;
-    ASSERT_MATRIX_APPROX(problem->getCurrentState().head(10) , x, wolf::Constants::EPS);
-    ASSERT_MATRIX_APPROX(problem->getProcessorMotionPtr()->getLastPtr()->getCalibration() , b, wolf::Constants::EPS);
-    ASSERT_MATRIX_APPROX(problem->getProcessorMotionPtr()->getLastPtr()->getCalibrationPreint() , b, wolf::Constants::EPS);
-}
-
-TEST_F(ProcessorIMUt, check_Covariance)
-{
-    t.set(0); // clock in 0,1 ms ticks
-    x0 << 0,0,0,  0,0,0,1,  0,0,0;
-    MatrixXd P0(9,9); P0.setIdentity();
-    problem->setPrior(x0, P0, t);
-
-    data << 2, 0, 9.806, 0, 0, 0; // only acc_x, but measure gravity!
-
-    cap_imu_ptr->setData(data);
-    cap_imu_ptr->setTimeStamp(0.1);
-    sensor_ptr->process(cap_imu_ptr);
-
-    VectorXd delta_preint(problem->getProcessorMotionPtr()->getMotion().delta_integr_);
-//    Matrix<double,9,9> delta_preint_cov = problem->getProcessorMotionPtr()->getCurrentDeltaPreintCov();
-
-    ASSERT_FALSE(delta_preint.isMuchSmallerThan(1, wolf::Constants::EPS_SMALL));
-//    ASSERT_MATRIX_APPROX(delta_preint_cov, MatrixXd::Zero(9,9), wolf::Constants::EPS_SMALL); // << "delta_preint_cov :\n" << delta_preint_cov; //covariances computed only at keyframe creation
-}
-
-TEST_F(ProcessorIMUt, gyro_x)
-{
-    double dt(0.001);
-    t.set(0); // clock in 0,1 ms ticks
-    x0 << 0,0,0,  0,0,0,1,  0,0,0;
-    MatrixXd P0(9,9); P0.setIdentity();
-    problem->setPrior(x0, P0, t);
-
-    double rate_of_turn = 5 * M_PI/180.0;
-    data << 0, 0, 9.806, rate_of_turn, 0, 0; // measure gravity
-
-    cap_imu_ptr->setData(data);
-    cap_imu_ptr->setTimeStamp(0.001);
-    sensor_ptr->process(cap_imu_ptr);
-
-    // Expected state after one integration
-    Quaterniond quat_comp(Quaterniond::Identity());
-    quat_comp = quat_comp * wolf::v2q(data.tail(3)*dt);
-
-    VectorXd x(10);
-    x << 0,0,0, quat_comp.x(),quat_comp.y(),quat_comp.z(),quat_comp.w(), 0,0,0; // rotated at 5 deg/s for 0.001s = 0.005 deg => 0.005 * M_PI/180
-
-    ASSERT_MATRIX_APPROX(problem->getCurrentState().head(10) , x, wolf::Constants::EPS_SMALL);
-
-    //do so for 5s
-    const unsigned int iter = 1000; //how many ms 
-    for(unsigned int i = 1; i < iter; i++) //already did one integration above
-    {
-        // quaternion composition
-        quat_comp = quat_comp * wolf::v2q(data.tail(3)*dt);
-
-        Quaterniond rot(problem->getCurrentState().data()+3);
-        data.head(3) =  rot.conjugate() * (- wolf::gravity());
-
-        cap_imu_ptr->setTimeStamp(i*dt + dt); //first one will be 0.002 and last will be 1.000
-        cap_imu_ptr->setData(data);
-        sensor_ptr->process(cap_imu_ptr);
-    }
-
-    x << 0,0,0, quat_comp.x(),quat_comp.y(),quat_comp.z(),quat_comp.w(), 0,0,0;
-    ASSERT_MATRIX_APPROX(problem->getCurrentState().head(10) , x, wolf::Constants::EPS);
-}
-
-TEST_F(ProcessorIMUt, gyro_x_biasedAbx)
-{
-    // time
-    double dt(0.001);
-    t.set(0); // clock in 0,1 ms ticks
-
-    // bias
-    double abx = 0.002;
-    Vector6d bias; bias << abx,0,0,  0,0,0;
-    Vector3d acc_bias = bias.head(3);
-    // state
-    x0 << 0,0,0,  0,0,0,1,  0,0,0;
-    MatrixXd P0(9,9); P0.setIdentity();
-
-    // init things
-    problem->setPrior(x0, P0, t);
-
-    problem->getProcessorMotionPtr()->getOriginPtr()->setCalibration(bias);
-    problem->getProcessorMotionPtr()->getLastPtr()->setCalibrationPreint(bias);
-//    WOLF_DEBUG("calib: ", cap_imu_ptr->getCalibration().transpose());
-
-    // data
-    double rate_of_turn = 5 * M_PI/180.0;
-    data << acc_bias - wolf::gravity(), rate_of_turn, 0, 0; // measure gravity
-
-    cap_imu_ptr->setData(data);
-    cap_imu_ptr->setTimeStamp(0.001);
-    sensor_ptr->process(cap_imu_ptr);
-
-    // Expected state after one integration
-    Quaterniond quat_comp(Quaterniond::Identity());
-    quat_comp = quat_comp * wolf::v2q(data.tail(3)*dt);
-
-    VectorXd x_true(10);
-    x_true << 0,0,0, quat_comp.x(),quat_comp.y(),quat_comp.z(),quat_comp.w(), 0,0,0; // rotated at 5 deg/s for 0.001s = 0.005 deg => 0.005 * M_PI/180
-
-    VectorXd x_est(10);
-    x_est = problem->getCurrentState().head(10);
-
-    ASSERT_MATRIX_APPROX(x_est.transpose() , x_true.transpose(), wolf::Constants::EPS);
-
-    //do so for 5s
-    const unsigned int iter = 1000; //how many ms 
-    for(unsigned int i = 1; i < iter; i++) //already did one integration above
-    {
-        // quaternion composition
-        quat_comp = quat_comp * wolf::v2q(data.tail(3)*dt);
-
-        Quaterniond rot(problem->getCurrentState().data()+3);
-        data.head(3) =  rot.conjugate() * (- wolf::gravity()) + acc_bias;
-
-        cap_imu_ptr->setTimeStamp(i*dt + dt); //first one will be 0.002 and last will be 1.000
-        cap_imu_ptr->setData(data);
-        sensor_ptr->process(cap_imu_ptr);
-    }
-
-    x_true << 0,0,0, quat_comp.x(),quat_comp.y(),quat_comp.z(),quat_comp.w(), 0,0,0;
-    ASSERT_MATRIX_APPROX(problem->getCurrentState().head(10) , x_true, wolf::Constants::EPS);
-
-}
-
-TEST_F(ProcessorIMUt, gyro_xy_biasedAbxy)
-{
-    double dt(0.001);
-    t.set(0); // clock in 0,1 ms ticks
-    double abx(0.002), aby(0.01);
-    x0 << 0,0,0,  0,0,0,1,  0,0,0;
-    MatrixXd P0(9,9); P0.setIdentity();
-    problem->setPrior(x0, P0, t);
-
-    Vector6d bias; bias << abx,aby,0,  0,0,0;
-    Vector3d acc_bias = bias.head(3);
-
-    problem->getProcessorMotionPtr()->getOriginPtr()->setCalibration(bias);
-    problem->getProcessorMotionPtr()->getLastPtr()->setCalibrationPreint(bias);
-
-    double rate_of_turn = 5 * M_PI/180.0;
-//    data << 0+abx, 0+aby, 9.806, rate_of_turn, rate_of_turn*1.5, 0; // measure gravity
-    data << acc_bias - wolf::gravity(), rate_of_turn*1.5, 0, 0; // measure gravity
-
-    cap_imu_ptr->setData(data);
-    cap_imu_ptr->setTimeStamp(0.001);
-    sensor_ptr->process(cap_imu_ptr);
-
-    // Expected state after one integration
-    Quaterniond quat_comp(Quaterniond::Identity());
-    quat_comp = quat_comp * wolf::v2q(data.tail(3)*dt);
-
-    VectorXd x(10);
-    x << 0,0,0, quat_comp.x(),quat_comp.y(),quat_comp.z(),quat_comp.w(), 0,0,0;//, abx,aby,0, 0,0,0;
-
-    ASSERT_MATRIX_APPROX(problem->getCurrentState().head(10) , x, wolf::Constants::EPS_SMALL);// << "expected state : " << problem->getCurrentState().transpose()
-//    << "\n estimated state : " << x.transpose();
-
-    //do so for 5s
-    const unsigned int iter = 1000; //how many ms 
-    for(unsigned int i = 1; i < iter; i++) //already did one integration above
-    {
-        // quaternion composition
-        quat_comp = quat_comp * wolf::v2q(data.tail(3)*dt);
-
-        Quaterniond rot(problem->getCurrentState().data()+3);
-        data.head(3) =  rot.conjugate() * (- wolf::gravity()) + acc_bias;
-
-        cap_imu_ptr->setTimeStamp(i*dt + dt); //first one will be 0.002 and last will be 1.000
-        cap_imu_ptr->setData(data);
-        sensor_ptr->process(cap_imu_ptr);
-    }
-
-    x << 0,0,0, quat_comp.x(),quat_comp.y(),quat_comp.z(),quat_comp.w(), 0,0,0;
-    ASSERT_MATRIX_APPROX(problem->getCurrentState().head(10) , x, wolf::Constants::EPS);// << "estimated state is : \n" << problem->getCurrentState().transpose() <<
-//    "\n expected state is : \n" << x.transpose() << std::endl;
-}
-
-TEST_F(ProcessorIMUt, gyro_z)
-{
-    double dt(0.001);
-    t.set(0); // clock in 0,1 ms ticks
-    x0 << 0,0,0,  0,0,0,1,  0,0,0;
-    MatrixXd P0(9,9); P0.setIdentity();
-    problem->setPrior(x0, P0, t);
-
-    double rate_of_turn = 5 * M_PI/180.0;
-    data << -wolf::gravity(), 0, 0, rate_of_turn; // measure gravity!
-
-    cap_imu_ptr->setData(data);
-    cap_imu_ptr->setTimeStamp(0.001);
-    sensor_ptr->process(cap_imu_ptr);
-
-    // Expected state after one integration
-    Quaterniond quat_comp(Quaterniond::Identity());
-    quat_comp = quat_comp * wolf::v2q(data.tail(3)*dt);
-
-    VectorXd x(10);
-    x << 0,0,0, quat_comp.x(),quat_comp.y(),quat_comp.z(),quat_comp.w(), 0,0,0; // rotated at 5 deg/s for 0.001s = 0.005 deg => 0.005 * M_PI/180
-
-    ASSERT_MATRIX_APPROX(problem->getCurrentState().head(10) , x, wolf::Constants::EPS_SMALL);
-
-    //do so for 5s
-    const unsigned int iter = 1000; //how many ms 
-    for(unsigned int i = 1; i < iter; i++) //already did one integration above
-    {
-        // quaternion composition
-        quat_comp = quat_comp * wolf::v2q(data.tail(3)*dt);
-
-        cap_imu_ptr->setTimeStamp(i*dt + dt); //first one will be 0.002 and last will be 1.000
-        sensor_ptr->process(cap_imu_ptr);
-    }
-
-    x << 0,0,0, quat_comp.x(),quat_comp.y(),quat_comp.z(),quat_comp.w(), 0,0,0;
-    ASSERT_MATRIX_APPROX(problem->getCurrentState().head(10) , x, wolf::Constants::EPS);
-}
-
-TEST_F(ProcessorIMUt, gyro_xyz)
-{
-    t.set(0); // clock in 0,1 ms ticks
-    x0 << 0,0,0,  0,0,0,1,  0,0,0;
-    MatrixXd P0(9,9); P0.setIdentity();
-    problem->setPrior(x0, P0, t);
-
-    Vector3d tmp_vec; //will be used to store rate of turn data
-    Quaterniond quat_comp(Quaterniond::Identity());
-    Matrix3d R0(Matrix3d::Identity());
-    double time = 0;
-    const unsigned int x_rot_vel = 5;
-    const unsigned int y_rot_vel = 6;
-    const unsigned int z_rot_vel = 13;
-
-    double tmpx, tmpy, tmpz;
-    
-    /*
-        ox oy oz evolution in degrees (for understanding) --> converted in rad
-        with * pi/180
-        ox = pi*sin(alpha*t*pi/180); %express angle in rad before using sinus
-        oy = pi*sin(beta*t*pi/180);
-        oz = pi*sin(gamma*t*pi/180);
-
-        corresponding rate of turn
-        %rate of turn expressed in radians/s
-        wx = pi*alpha*cos(alpha*t*pi/180)*pi/180;
-        wy = pi*beta*cos(beta*t*pi/180)*pi/180;
-        wz = pi*gamma*cos(gamma*t*pi/180)*pi/180;
-     */
-
-     const double dt = 0.001;
-
-    for(unsigned int data_iter = 0; data_iter <= 1000; data_iter ++)
-    {   
-        time += dt;
-
-        tmpx = M_PI*x_rot_vel*cos((M_PI/180) * x_rot_vel * time)*M_PI/180;
-        tmpy = M_PI*y_rot_vel*cos((M_PI/180) * y_rot_vel * time)*M_PI/180;
-        tmpz = M_PI*z_rot_vel*cos((M_PI/180) * z_rot_vel * time)*M_PI/180;
-        tmp_vec << tmpx, tmpy, tmpz;
-
-        // quaternion composition
-        quat_comp = quat_comp * wolf::v2q(tmp_vec*dt);
-        R0 = R0 * wolf::v2R(tmp_vec*dt);
-        // use processorIMU
-        Quaterniond rot(problem->getCurrentState().data()+3);
-        data.head(3) =  rot.conjugate() * (- wolf::gravity()); //gravity measured
-        data.tail(3) = tmp_vec;
-
-        cap_imu_ptr->setData(data);
-        cap_imu_ptr->setTimeStamp(time);
-        sensor_ptr->process(cap_imu_ptr);
-    }
-
-    /* We focus on orientation here. position is supposed not to have moved
-     * we integrated using 2 ways : 
-        - a direct quaternion composition q = q (x) q(w*dt)
-        - using methods implemented in processorIMU
-
-        We check one against the other
-     */
-
-     // validating that the quaternion composition and rotation matrix composition actually describe the same rotation.
-    Quaterniond R2quat(wolf::v2q(wolf::R2v(R0)));
-    Vector4d quat_comp_vec((Vector4d() <<quat_comp.x(), quat_comp.y(), quat_comp.z(), quat_comp.w()).finished() );
-    Vector4d R2quat_vec((Vector4d() <<R2quat.x(), R2quat.y(), R2quat.z(), R2quat.w()).finished() );
-
-    ASSERT_MATRIX_APPROX(quat_comp_vec , R2quat_vec, wolf::Constants::EPS);// << "quat_comp_vec : " << quat_comp_vec.transpose() << "\n R2quat_vec : " << R2quat_vec.transpose() << std::endl;
-
-    VectorXd x(10);
-    x << 0,0,0, quat_comp.x(), quat_comp.y(), quat_comp.z(), quat_comp.w(), 0,0,0;
-
-    Quaterniond result_quat(problem->getCurrentState().data() + 3);
-    //std::cout << "final orientation : " << wolf::q2v(result_quat).transpose() << std::endl;
-
-    //check position part
-    ASSERT_MATRIX_APPROX(problem->getCurrentState().head(3) , x.head(3), wolf::Constants::EPS);
-
-    //check orientation part
-    ASSERT_MATRIX_APPROX(problem->getCurrentState().segment(3,4) , x.segment(3,4) , wolf::Constants::EPS);
-
-    //check velocity and bias parts
-    ASSERT_MATRIX_APPROX(problem->getCurrentState().segment(7,3) , x.segment(7,3), wolf::Constants::EPS);
-}
-
-TEST_F(ProcessorIMUt, gyro_z_ConstVelocity)
-{
-    double dt(0.001);
-    t.set(0); // clock in 0,1 ms ticks
-    x0 << 0,0,0,  0,0,0,1,  2,0,0;
-    MatrixXd P0(9,9); P0.setIdentity();
-    problem->setPrior(x0, P0, t);
-
-    double rate_of_turn = 5 * M_PI/180.0;
-    data << -wolf::gravity(), 0, 0, rate_of_turn; // measure gravity!
-
-    cap_imu_ptr->setData(data);
-    cap_imu_ptr->setTimeStamp(0.001);
-    sensor_ptr->process(cap_imu_ptr);
-
-    // Expected state after one integration
-    Quaterniond quat_comp(Quaterniond::Identity());
-    quat_comp = quat_comp * wolf::v2q(data.tail(3)*dt);
-
-    VectorXd x(10);
-    x << 0.002,0,0, quat_comp.x(),quat_comp.y(),quat_comp.z(),quat_comp.w(), 2,0,0; // rotated at 5 deg/s for 0.001s = 0.005 deg => 0.005 * M_PI/180, 2m/s * 0.001s = 0.002m
-
-    ASSERT_MATRIX_APPROX(problem->getCurrentState().head(10) , x, wolf::Constants::EPS_SMALL);
-
-    //do so for 1s
-    const unsigned int iter = 1000; //how many ms 
-    for(unsigned int i = 1; i < iter; i++) //already did one integration above
-    {
-        // quaternion composition
-        quat_comp = quat_comp * wolf::v2q(data.tail(3)*dt);
-
-        cap_imu_ptr->setTimeStamp(i*dt + dt); //first one will be 0.002 and last will be 5.000
-        sensor_ptr->process(cap_imu_ptr);
-    }
-
-    x << 2,0,0, quat_comp.x(),quat_comp.y(),quat_comp.z(),quat_comp.w(), 2,0,0; //2m/s * 1s = 2m
-    ASSERT_MATRIX_APPROX(problem->getCurrentState().head(10) , x, wolf::Constants::EPS);
-}
-
-TEST_F(ProcessorIMUt, gyro_x_ConstVelocity)
-{
-    double dt(0.001);
-    t.set(0); // clock in 0,1 ms ticks
-    x0 << 0,0,0,  0,0,0,1,  2,0,0;
-    MatrixXd P0(9,9); P0.setIdentity();
-    problem->setPrior(x0, P0, t);
-
-    double rate_of_turn = 5 * M_PI/180.0;
-    data << 0, 0, 9.806, rate_of_turn, 0, 0; // measure gravity
-
-    cap_imu_ptr->setData(data);
-    cap_imu_ptr->setTimeStamp(0.001);
-    sensor_ptr->process(cap_imu_ptr);
-
-    // Expected state after one integration
-    Quaterniond quat_comp(Quaterniond::Identity());
-    quat_comp = quat_comp * wolf::v2q(data.tail(3)*dt);
-
-    VectorXd x(10);
-    // rotated at 5 deg/s for 0.001s = 0.005 deg => 0.005 * M_PI/180, 2m/s * 0.001s = 0.002
-    x << 0.002,0,0, quat_comp.x(),quat_comp.y(),quat_comp.z(),quat_comp.w(), 2,0,0;
-
-    ASSERT_MATRIX_APPROX(problem->getCurrentState().head(10) , x, wolf::Constants::EPS_SMALL);
-
-    //do so for 1s
-    const unsigned int iter = 1000; //how many ms 
-    for(unsigned int i = 1; i < iter; i++) //already did one integration above
-    {
-        // quaternion composition
-        quat_comp = quat_comp * wolf::v2q(data.tail(3)*dt);
-
-        Quaterniond rot(problem->getCurrentState().data()+3);
-        data.head(3) =  rot.conjugate() * (- wolf::gravity());
-
-        cap_imu_ptr->setTimeStamp(i*dt + dt); //first one will be 0.002 and last will be 1.000
-        cap_imu_ptr->setData(data);
-        sensor_ptr->process(cap_imu_ptr);
-    }
-
-    x << 2,0,0, quat_comp.x(),quat_comp.y(),quat_comp.z(),quat_comp.w(), 2,0,0; //2m/s * 1s = 2m
-    ASSERT_MATRIX_APPROX(problem->getCurrentState().head(10) , x, wolf::Constants::EPS);
-}
-
-TEST_F(ProcessorIMUt, gyro_xy_ConstVelocity)
-{
-    double dt(0.001);
-    t.set(0); // clock in 0,1 ms ticks
-    x0 << 0,0,0,  0,0,0,1,  2,0,0;
-    MatrixXd P0(9,9); P0.setIdentity();
-    problem->setPrior(x0, P0, t);
-
-    double rate_of_turn = 5 * M_PI/180.0;
-    data << 0, 0, 9.806, 0, rate_of_turn, 0; // measure gravity
-
-    cap_imu_ptr->setData(data);
-    cap_imu_ptr->setTimeStamp(0.001);
-    sensor_ptr->process(cap_imu_ptr);
-
-    // Expected state after one integration
-    Quaterniond quat_comp(Quaterniond::Identity());
-    quat_comp = quat_comp * wolf::v2q(data.tail(3)*dt);
-
-    VectorXd x(10);
-    // rotated at 5 deg/s for 0.001s = 0.005 deg => 0.005 * M_PI/180, 2m/s * 0.001s = 0.002
-    x << 0.002,0,0, quat_comp.x(),quat_comp.y(),quat_comp.z(),quat_comp.w(), 2,0,0;
-
-    ASSERT_MATRIX_APPROX(problem->getCurrentState().head(10) , x, wolf::Constants::EPS_SMALL);
-
-    //do so for 1s
-    const unsigned int iter = 1000; //how many ms 
-    for(unsigned int i = 1; i < iter; i++) //already did one integration above
-    {
-        // quaternion composition
-        quat_comp = quat_comp * wolf::v2q(data.tail(3)*dt);
-
-        Quaterniond rot(problem->getCurrentState().data()+3);
-        data.head(3) =  rot.conjugate() * (- wolf::gravity());
-
-        cap_imu_ptr->setTimeStamp(i*dt + dt); //first one will be 0.002 and last will be 1.000
-        cap_imu_ptr->setData(data);
-        sensor_ptr->process(cap_imu_ptr);
-    }
-
-    x << 2,0,0, quat_comp.x(),quat_comp.y(),quat_comp.z(),quat_comp.w(), 2,0,0; //2m/s * 1s = 2m
-    ASSERT_MATRIX_APPROX(problem->getCurrentState().head(10) , x, wolf::Constants::EPS);
-}
-
-TEST_F(ProcessorIMUt, gyro_y_ConstVelocity)
-{
-    double dt(0.001);
-    t.set(0); // clock in 0,1 ms ticks
-    x0 << 0,0,0,  0,0,0,1,  2,0,0;
-    MatrixXd P0(9,9); P0.setIdentity();
-    problem->setPrior(x0, P0, t);
-
-    double rate_of_turn = 5 * M_PI/180.0;
-    data << 0, 0, 9.806, 0, rate_of_turn, 0; // measure gravity
-
-    cap_imu_ptr->setData(data);
-    cap_imu_ptr->setTimeStamp(0.001);
-    sensor_ptr->process(cap_imu_ptr);
-
-    // Expected state after one integration
-    Quaterniond quat_comp(Quaterniond::Identity());
-    quat_comp = quat_comp * wolf::v2q(data.tail(3)*dt);
-
-    VectorXd x(10);
-    // rotated at 5 deg/s for 0.001s = 0.005 deg => 0.005 * M_PI/180, 2m/s * 0.001s = 0.002
-    x << 0.002,0,0, quat_comp.x(),quat_comp.y(),quat_comp.z(),quat_comp.w(), 2,0,0;
-
-    ASSERT_MATRIX_APPROX(problem->getCurrentState().head(10) , x, wolf::Constants::EPS_SMALL);
-
-    //do so for 1s
-    const unsigned int iter = 1000; //how many ms 
-    for(unsigned int i = 1; i < iter; i++) //already did one integration above
-    {
-        // quaternion composition
-        quat_comp = quat_comp * wolf::v2q(data.tail(3)*dt);
-
-        Quaterniond rot(problem->getCurrentState().data()+3);
-        data.head(3) =  rot.conjugate() * (- wolf::gravity());
-
-        cap_imu_ptr->setTimeStamp(i*dt + dt); //first one will be 0.002 and last will be 1.000
-        cap_imu_ptr->setData(data);
-        sensor_ptr->process(cap_imu_ptr);
-    }
-
-    x << 2,0,0, quat_comp.x(),quat_comp.y(),quat_comp.z(),quat_comp.w(), 2,0,0; //2m/s * 1s = 2m
-    ASSERT_MATRIX_APPROX(problem->getCurrentState().head(10) , x, wolf::Constants::EPS);
-}
-
-TEST_F(ProcessorIMUt, gyro_xyz_ConstVelocity)
-{
-    t.set(0); // clock in 0,1 ms ticks
-    x0 << 0,0,0,  0,0,0,1,  2,0,0;
-    MatrixXd P0(9,9); P0.setIdentity();
-    problem->setPrior(x0, P0, t);
-
-    Vector3d tmp_vec; //will be used to store rate of turn data
-    Quaterniond quat_comp(Quaterniond::Identity());
-    Matrix3d R0(Matrix3d::Identity());
-    double time = 0;
-    const unsigned int x_rot_vel = 5;
-    const unsigned int y_rot_vel = 6;
-    const unsigned int z_rot_vel = 13;
-
-    double tmpx, tmpy, tmpz;
-    
-    /*
-        ox oy oz evolution in degrees (for understanding) --> converted in rad
-        with * pi/180
-        ox = pi*sin(alpha*t*pi/180); %express angle in rad before using sinus
-        oy = pi*sin(beta*t*pi/180);
-        oz = pi*sin(gamma*t*pi/180);
-
-        corresponding rate of turn
-        %rate of turn expressed in radians/s
-        wx = pi*alpha*cos(alpha*t*pi/180)*pi/180;
-        wy = pi*beta*cos(beta*t*pi/180)*pi/180;
-        wz = pi*gamma*cos(gamma*t*pi/180)*pi/180;
-     */
-
-     const double dt = 0.001;
-
-    for(unsigned int data_iter = 0; data_iter < 1000; data_iter ++)
-    {   
-        time += dt;
-
-        tmpx = M_PI*x_rot_vel*cos((M_PI/180) * x_rot_vel * time)*M_PI/180;
-        tmpy = M_PI*y_rot_vel*cos((M_PI/180) * y_rot_vel * time)*M_PI/180;
-        tmpz = M_PI*z_rot_vel*cos((M_PI/180) * z_rot_vel * time)*M_PI/180;
-        tmp_vec << tmpx, tmpy, tmpz;
-
-        // quaternion composition
-        quat_comp = quat_comp * wolf::v2q(tmp_vec*dt);
-        R0 = R0 * wolf::v2R(tmp_vec*dt);
-        // use processorIMU
-        Quaterniond rot(problem->getCurrentState().data()+3);
-        data.head(3) =  rot.conjugate() * (- wolf::gravity()); //gravity measured
-        data.tail(3) = tmp_vec;
-
-        cap_imu_ptr->setData(data);
-        cap_imu_ptr->setTimeStamp(time);
-        sensor_ptr->process(cap_imu_ptr);
-    }
-
-    /* We focus on orientation here. position is supposed not to have moved
-     * we integrated using 2 ways : 
-        - a direct quaternion composition q = q (x) q(w*dt)
-        - using methods implemented in processorIMU
-
-        We check one against the other
-     */
-
-     // validating that the quaternion composition and rotation matrix composition actually describe the same rotation.
-    Quaterniond R2quat(wolf::v2q(wolf::R2v(R0)));
-    Vector4d quat_comp_vec((Vector4d() <<quat_comp.x(), quat_comp.y(), quat_comp.z(), quat_comp.w()).finished() );
-    Vector4d R2quat_vec((Vector4d() <<R2quat.x(), R2quat.y(), R2quat.z(), R2quat.w()).finished() );
-
-    ASSERT_MATRIX_APPROX(quat_comp_vec , R2quat_vec, wolf::Constants::EPS); // << "quat_comp_vec : " << quat_comp_vec.transpose() << "\n R2quat_vec : " << R2quat_vec.transpose() << std::endl;
-
-    VectorXd x(10);
-    //rotation + translation due to initial velocity
-    x << 2,0,0, quat_comp.x(), quat_comp.y(), quat_comp.z(), quat_comp.w(), 2,0,0;
-
-    Quaterniond result_quat(problem->getCurrentState().data() + 3);
-    //std::cout << "final orientation : " << wolf::q2v(result_quat).transpose() << std::endl;
-
-    //check position part
-    ASSERT_MATRIX_APPROX(problem->getCurrentState().head(3) , x.head(3), wolf::Constants::EPS);
-
-    //check orientation part
-    ASSERT_MATRIX_APPROX(problem->getCurrentState().segment(3,4) , x.segment(3,4) , wolf::Constants::EPS);
-
-    //check velocity
-    ASSERT_MATRIX_APPROX(problem->getCurrentState().segment(7,3) , x.segment(7,3), wolf::Constants::EPS);
-
-}
-
-TEST_F(ProcessorIMUt, gyro_x_acc_x)
-{
-    double dt(0.001);
-    t.set(0); // clock in 0,1 ms ticks
-    x0 << 0,0,0,  0,0,0,1,  0,0,0;
-    MatrixXd P0(9,9); P0.setIdentity();
-    problem->setPrior(x0, P0, t);
-
-    double rate_of_turn = 5 * M_PI/180.0;
-    data << 1, 0, -wolf::gravity()(2), rate_of_turn, 0, 0; // measure gravity
-
-    cap_imu_ptr->setData(data);
-    cap_imu_ptr->setTimeStamp(0.001);
-    sensor_ptr->process(cap_imu_ptr);
-
-    // Expected state after one integration
-    Quaterniond quat_comp(Quaterniond::Identity());
-    quat_comp = quat_comp * wolf::v2q(data.tail(3)*dt);
-
-    VectorXd x(10);
-    // rotated at 5 deg/s for 0.001s = 0.005 deg => 0.005 * M_PI/180 on x axis
-    // translation with constant acc : 1 m/s^2 for 0.001 second. Initial velocity : 0, p = 0.5*a*dt^2 + v*dt = 0.5*1*0.001^2 = 0.0000005 on x axis
-    // v = a*dt = 0.001
-    x << 0.0000005,0,0, quat_comp.x(),quat_comp.y(),quat_comp.z(),quat_comp.w(), 0.001,0,0;
-
-    ASSERT_MATRIX_APPROX(problem->getCurrentState().head(10) , x, wolf::Constants::EPS); // << "1. current state is : \n" << problem->getCurrentState().transpose() <<
-//    "\n current x is : \n" << x.transpose() << std::endl;
-
-    //do so for 1s
-    const unsigned int iter = 1000; //how many ms 
-    for(unsigned int i = 2; i <= iter; i++) //already did one integration above
-    {
-        // quaternion composition
-        quat_comp = quat_comp * wolf::v2q(data.tail(3)*dt);
-
-        Quaterniond rot(problem->getCurrentState().data()+3);
-        data.head(3) =  rot.conjugate() * (- wolf::gravity()) + (Vector3d()<<1,0,0).finished();
-
-        cap_imu_ptr->setTimeStamp(i*dt); //first one will be 0.002 and last will be 1.000
-        cap_imu_ptr->setData(data);
-        sensor_ptr->process(cap_imu_ptr);
-    }
-
-    // translation with constant acc : 1 m/s for 1 second. Initial velocity : 0, p = 0.5*a*dt + v*dt = 0.5 on x axis
-    // v = a*dt = 1
-    x << 0.5,0,0, quat_comp.x(),quat_comp.y(),quat_comp.z(),quat_comp.w(), 1,0,0;
-    ASSERT_MATRIX_APPROX(problem->getCurrentState().head(10) , x, wolf::Constants::EPS);
-}
-
-TEST_F(ProcessorIMUt, gyro_y_acc_y)
-{
-    double dt(0.001);
-    t.set(0); // clock in 0,1 ms ticks
-    x0 << 0,0,0,  0,0,0,1,  0,0,0;
-    MatrixXd P0(9,9); P0.setIdentity();
-    problem->setPrior(x0, P0, t);
-
-    double rate_of_turn = 5 * M_PI/180.0;
-    data << 0, 1, -wolf::gravity()(2), 0, rate_of_turn, 0; // measure gravity
-
-    cap_imu_ptr->setData(data);
-    cap_imu_ptr->setTimeStamp(0.001);
-    sensor_ptr->process(cap_imu_ptr);
-
-    // Expected state after one integration
-    Quaterniond quat_comp(Quaterniond::Identity());
-    quat_comp = quat_comp * wolf::v2q(data.tail(3)*dt);
-
-    VectorXd x(10);
-    // rotated at 5 deg/s for 0.001s = 0.005 deg => 0.005 * M_PI/180 on y axis
-    // translation with constant acc : 1 m/s^2 for 0.001 second. Initial velocity : 0, p = 0.5*a*dt^2 + v*dt = 0.5*1*0.001^2 = 0.0000005 on y axis
-    // v = a*dt = 0.001
-    x << 0,0.0000005,0, quat_comp.x(),quat_comp.y(),quat_comp.z(),quat_comp.w(), 0,0.001,0;
-
-    ASSERT_MATRIX_APPROX(problem->getCurrentState().head(10) , x, wolf::Constants::EPS); // << "1. current state is : \n" << problem->getCurrentState().transpose() <<
-//    "\n current x is : \n" << x.transpose() << std::endl;
-
-    //do so for 1s
-    const unsigned int iter = 1000; //how many ms 
-    for(unsigned int i = 2; i <= iter; i++) //already did one integration above
-    {
-        // quaternion composition
-        quat_comp = quat_comp * wolf::v2q(data.tail(3)*dt);
-
-        Quaterniond rot(problem->getCurrentState().data()+3);
-        data.head(3) =  rot.conjugate() * (- wolf::gravity()) + (Vector3d()<<0,1,0).finished();
-
-        cap_imu_ptr->setTimeStamp(i*dt); //first one will be 0.002 and last will be 1.000
-        cap_imu_ptr->setData(data);
-        sensor_ptr->process(cap_imu_ptr);
-    }
-
-    // translation with constant acc : 1 m/s for 1 second. Initial velocity : 0, p = 0.5*a*dt + v*dt = 0.5 on y axis
-    // v = a*dt = 1
-    x << 0,0.5,0, quat_comp.x(),quat_comp.y(),quat_comp.z(),quat_comp.w(), 0,1,0;
-    ASSERT_MATRIX_APPROX(problem->getCurrentState().head(10) , x, wolf::Constants::EPS);
-}
-
-TEST_F(ProcessorIMUt, gyro_z_acc_z)
-{
-    double dt(0.001);
-    t.set(0); // clock in 0,1 ms ticks
-    x0 << 0,0,0,  0,0,0,1,  0,0,0;
-    MatrixXd P0(9,9); P0.setIdentity();
-    problem->setPrior(x0, P0, t);
-
-    double rate_of_turn = 5 * M_PI/180.0;
-    data << 0, 0, -wolf::gravity()(2) + 1, 0, 0, rate_of_turn; // measure gravity
-
-    cap_imu_ptr->setData(data);
-    cap_imu_ptr->setTimeStamp(0.001);
-    sensor_ptr->process(cap_imu_ptr);
-
-    // Expected state after one integration
-    Quaterniond quat_comp(Quaterniond::Identity());
-    quat_comp = quat_comp * wolf::v2q(data.tail(3)*dt);
-
-    VectorXd x(10);
-    // rotated at 5 deg/s for 0.001s = 0.005 deg => 0.005 * M_PI/180 on z axis
-    // translation with constant acc : 1 m/s^2 for 0.001 second. Initial velocity : 0, p = 0.5*a*dt^2 + v*dt = 0.5*1*0.001^2 = 0.0000005 on z axis
-    // v = a*dt = 0.001
-    x << 0,0,0.0000005, quat_comp.x(),quat_comp.y(),quat_comp.z(),quat_comp.w(), 0,0,0.001;
-
-    ASSERT_MATRIX_APPROX(problem->getCurrentState().head(10) , x, wolf::Constants::EPS);
-
-    //do so for 1s
-    const unsigned int iter = 1000; //how many ms 
-    for(unsigned int i = 2; i <= iter; i++) //already did one integration above
-    {
-        // quaternion composition
-        quat_comp = quat_comp * wolf::v2q(data.tail(3)*dt);
-
-        Quaterniond rot(problem->getCurrentState().data()+3);
-        data.head(3) =  rot.conjugate() * (- wolf::gravity()) + (Vector3d()<<0,0,1).finished();
-
-        cap_imu_ptr->setTimeStamp(i*dt); //first one will be 0.002 and last will be 1.000
-        cap_imu_ptr->setData(data);
-        sensor_ptr->process(cap_imu_ptr);
-    }
-
-    // translation with constant acc : 1 m/s for 1 second. Initial velocity : 0, p = 0.5*a*dt + v*dt = 0.5 on z axis
-    // v = a*dt = 1
-    x << 0,0,0.5, quat_comp.x(),quat_comp.y(),quat_comp.z(),quat_comp.w(), 0,0,1;
-    ASSERT_MATRIX_APPROX(problem->getCurrentState().head(10) , x, wolf::Constants::EPS);
-}
-
-int main(int argc, char **argv)
-{
-  testing::InitGoogleTest(&argc, argv);
-  //::testing::GTEST_FLAG(filter) = "ProcessorIMUt.check_Covariance";
-  return RUN_ALL_TESTS();
-}
-
diff --git a/test/params1.yaml b/test/params1.yaml
deleted file mode 100644
index 194560afa773cb1910c1d8a94b6b80163486401f..0000000000000000000000000000000000000000
--- a/test/params1.yaml
+++ /dev/null
@@ -1,30 +0,0 @@
-config:
-  sensors: 
-    -
-      type: "ODOM 2d"
-      name: "odom"
-      intrinsic:
-        k_disp_to_disp: 0.1
-        k_rot_to_rot: 0.1 
-      extrinsic:
-        pos: [1,2,3]
-    -
-      type: "RANGE BEARING"
-      name: "rb"
-  processors:
-    -
-      type: "ODOM 2d"
-      name: "processor1"
-      sensor name: "odom"
-    -
-      type: "RANGE BEARING"
-      name: "rb_processor"
-      sensor name: "rb"
-    -
-      type: "ODOM 2d"
-      name: "my_proc_test"
-      sensor name: "odom"
-      follow: "/test/params3.1.yaml"
-files:
-  - "/home/jcasals/workspace/wip/wolf/lib/libsensor_odo.so"
-  - "/home/jcasals/workspace/wip/wolf/lib/librange_bearing.so"
\ No newline at end of file
diff --git a/test/params2.yaml b/test/params2.yaml
deleted file mode 100644
index b9ac1565e165af26bd168f4969ba520e346a8c13..0000000000000000000000000000000000000000
--- a/test/params2.yaml
+++ /dev/null
@@ -1,33 +0,0 @@
-config:
-  sensors: 
-    -
-      type: "ODOM 2d"
-      name: "odom"
-      intrinsic:
-        k_disp_to_disp: 0.1
-        k_rot_to_rot: 0.1 
-      extrinsic:
-        pos: [1,2,3]
-    -
-      type: "RANGE BEARING"
-      name: "rb"
-  processors:
-    -
-      type: "ODOM 2d"
-      name: "processor1"
-      sensor name: "odom"
-      $mymap:
-        k1: v1
-        k2: v2
-        k3: [v3,v4,v5]
-    -
-      type: "RANGE BEARING"
-      name: "rb_processor"
-      sensor name: "rb"
-    -
-      type: "ODOM 2d"
-      name: "my_proc_test"
-      sensor name: "odom"
-files:
-  - "/home/jcasals/workspace/wip/wolf/lib/libsensor_odo.so"
-  - "/home/jcasals/workspace/wip/wolf/lib/librange_bearing.so"
\ No newline at end of file
diff --git a/test/params3.1.yaml b/test/params3.1.yaml
deleted file mode 100644
index bd9b495c830e56f17f11abbb5b2109d780f4e438..0000000000000000000000000000000000000000
--- a/test/params3.1.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
-cov_det: 100
-unmeasured_perturbation_std: 100
-angle_turned: 100
-dist_traveled: 100
-max_buff_length: 100
-max_time_span: 100
-time_tolerance: 100
-voting_active: false 
\ No newline at end of file
diff --git a/test/params3.yaml b/test/params3.yaml
deleted file mode 100644
index 23b9db1db2149e9f9c51255d38c629959672e436..0000000000000000000000000000000000000000
--- a/test/params3.yaml
+++ /dev/null
@@ -1,31 +0,0 @@
-config:
-  sensors: 
-    -
-      type: "ODOM 2d"
-      name: "odom"
-      intrinsic:
-        k_disp_to_disp: 0.1
-        k_rot_to_rot: 0.1 
-      extrinsic:
-        pos: [1,2,3]
-    -
-      type: "RANGE BEARING"
-      name: "rb"
-  processors:
-    -
-      type: "ODOM 2d"
-      name: "processor1"
-      sensor name: "odom"
-    -
-      type: "RANGE BEARING"
-      name: "rb_processor"
-      sensor name: "rb"
-    -
-      type: "ODOM 2d"
-      name: "my_proc_test"
-      sensor name: "odom"
-      follow: "/test/params3.1.yaml"
-      jump: "@/test/params3.1.yaml"
-files:
-  - "/home/jcasals/workspace/wip/wolf/lib/libsensor_odo.so"
-  - "/home/jcasals/workspace/wip/wolf/lib/librange_bearing.so"
\ No newline at end of file
diff --git a/test/yaml/params_processor_loop_closure_falko.yaml b/test/yaml/params_processor_loop_closure_falko.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..c41ca1198cfa4c7e5cc6cb2e8089b830ce6ec3a0
--- /dev/null
+++ b/test/yaml/params_processor_loop_closure_falko.yaml
@@ -0,0 +1,93 @@
+  config:
+    problem:
+      dim: 2
+    processor:
+      ProcessorLoopClosureFalko:
+        time_tolerance              : 0.1
+        apply_loss_function         : false
+        min_keypoints               : 4
+        max_loops                   : 3
+        distance_between_ref_frm    : 0.5
+        near_matches_th             : 1
+        score_th                    : 5
+        th_kp_area                  : 0.66
+        th_kp_perimeter             : 0.66
+        th_kp_maxd                  : 0.66
+        th_kp_eig                   : 0
+        th_scan_area                : 0
+        th_scan_eig                 : 0
+        logging                     : false
+        logging_filepath            : ~/Desktop
+
+# Parameters for matcher
+        falko: 
+          matcher_distance_th        : 100
+          use_descriptors            : true
+          circularSectorNumber       : 16
+          radialRingNumber           : 8
+          matcher_ddesc_th           : 20
+          keypoints_number_th        : 5
+          enable_subbeam             : false
+          nms_radius                 : 0.1
+          neigh_b                    : 0.1
+          b_ratio                    : 4
+          xRes                       : 0.15
+          yRes                       : 0.15
+          thetaRes                   : 0.1
+          xAbsMax                    : 3
+          yAbsMax                    : 3
+          thetaAbsMax                : 3
+
+# from processor base
+        keyframe_vote:
+          time_tolerance              : 0.1
+          voting_active               : true
+
+# from processor odom ICP
+        max_error_threshold         : 0.5
+        min_points_percent          : 0.5
+# from CSM
+        icp:
+          max_iterations:                      50
+          max_correspondence_dist:             1
+          use_corr_tricks:                     1
+          outliers_maxPerc:                    0.9
+          use_point_to_line_distance:          1
+          outliers_adaptive_order:             0.7
+          outliers_adaptive_mult:              1.5
+          do_compute_covariance:               1
+
+          max_angular_correction_deg:          0
+          max_linear_correction:               0
+          epsilon_xy:                          0
+          epsilon_theta:                       0
+          sigma:                               0.2
+          restart:                             0
+          restart_threshold_mean_error:        0
+          restart_dt:                          0
+          restart_dtheta:                      0
+          clustering_threshold:                0
+          orientation_neighbourhood:           0
+          do_alpha_test:                       0
+          do_alpha_test_thresholdDeg:          0
+          do_visibility_test:                  0
+          outliers_remove_doubles:             0
+          debug_verify_tricks:                 0
+          gpm_theta_bin_size_deg:              0
+          gpm_extend_range_deg:                0
+          gpm_interval:                        0
+          laser_x:                             0
+          laser_y:                             0
+          laser_theta:                         0
+          min_reading:                         0.023
+          max_reading:                         60
+          use_ml_weights:                      0
+          use_sigma_weights:                   0
+          hsm_linear_cell_size:                0.03
+          hsm_angular_cell_size_deg:           1
+          hsm_num_angular_hypotheses:          8
+          hsm_xc_directions_min_distance_deg:  10
+          hsm_xc_ndirections:                  3
+          hsm_angular_hyp_min_distance_deg:    10
+          hsm_linear_xc_max_npeaks:            5
+          hsm_linear_xc_peaks_min_distance:    5
\ No newline at end of file
diff --git a/test/yaml/processor_loop_closure_icp.yaml b/test/yaml/processor_loop_closure_icp.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b0fb57d38e7e27e45fc8fc87fd72a0627c87f543
--- /dev/null
+++ b/test/yaml/processor_loop_closure_icp.yaml
@@ -0,0 +1,26 @@
+# from processor base
+time_tolerance              : 0.1
+voting_active               : true
+
+# from  processor tracker
+min_features_for_keyframe   : 0
+max_new_features            : 0
+
+# from processor odom ICP
+cov_factor                  : 1
+use_point_to_line_distance  : 1
+max_correspondence_dist     : 2
+max_iterations              : 3
+use_corr_tricks             : 1
+outliers_maxPerc            : 5
+outliers_adaptive_order     : 6
+outliers_adaptive_mult      : 7
+max_reading                 : 100
+min_reading                 : 0
+do_compute_covariance       : 1
+vfk_min_dist                : 0
+vfk_min_angle               : 0
+vfk_min_time                : 0
+vfk_min_error               : 0
+vfk_max_points              : 0
+initial_guess               : "zero"