diff --git a/src/loop_closure_falko.h b/src/loop_closure_falko.h
index c4f94ca178be25d09b6d1e6ea7f5cd3d26c17e15..26961e5ff081f6415602ce8a3128172bd8759492 100644
--- a/src/loop_closure_falko.h
+++ b/src/loop_closure_falko.h
@@ -63,14 +63,13 @@ struct ParameterLoopClosureFalko
 
     // matching
     double matcher_ddesc_th_ = 0.2;
-
     // aht matcher
-    double xRes_        = 0.1;
-    double yRes_        = 0.1;
-    double thetaRes_    = 0.04;
-    double xAbsMax_     = 5;
-    double yAbsMax_     = 5;
-    double thetaAbsMax_ = 1.57;
+    double xRes_        = 0.15;
+    double yRes_        = 0.15;
+    double thetaRes_    = 0.1;
+    double xAbsMax_     = 3;
+    double yAbsMax_     = 3;
+    double thetaAbsMax_ = 3;
 };
 
 /** \brief A class for loop closure using falko library
@@ -94,7 +93,6 @@ struct ParameterLoopClosureFalko
 template <typename D, typename Extr, template <typename, typename> typename M>
 class LoopClosureFalko : public LoopClosureBase2d, public falkolib::FALKOExtractor
 {
-  private:
   public:
     typedef std::shared_ptr<SceneFalko<D>>       sceneFalkoBSCPtr;
     typedef std::shared_ptr<falkolib::LaserScan> laserScanPtr;
@@ -127,8 +125,311 @@ class LoopClosureFalko : public LoopClosureBase2d, public falkolib::FALKOExtract
         use_descriptors_     = _param.use_descriptors_;
     };
 
-    // Template specialization
+    /** \brief Destructor
+     **/
+    ~LoopClosureFalko() {}
+
+    /** \brief Create and update the scene struct with keypoints and descriptors
+     **/
+    sceneBasePtr extractScene(const LaserScan &_scan, const LaserScanParams &_scan_params) override
+    {
+        auto new_scene  = std::make_shared<SceneFalko<D>>();
+        auto scan_falko = convert2LaserScanFALKO(_scan, _scan_params);
+        // Extract keypoints
+        std::vector<falkolib::FALKO> keypoints_list;
+        extract(*scan_falko, keypoints_list);
+
+        double angle_min  = _scan_params.angle_min_;
+        double angle_step = _scan_params.angle_step_;
+
+        // Compute max_dist
+        new_scene->max_distance_ = 0;
+        for (int i = 0; i < keypoints_list.size(); i++)
+            for (int j = 0; j < keypoints_list.size(); j++)
+                {
+                    double X_dist   = fabs(keypoints_list[i].point[0] - keypoints_list[j].point[0]);
+                    double Y_dist   = fabs(keypoints_list[i].point[1] - keypoints_list[j].point[1]);
+                    double distance = sqrt((X_dist * X_dist) + (Y_dist * Y_dist));
+                    if (distance > new_scene->max_distance_)
+                        new_scene->max_distance_ = distance;
+                }
+
+        // discard too close by kp
+        for (int i = 0; i < keypoints_list.size(); i++)
+            {
+                int repeated = 0;
+                for (int j = i + 1; j < keypoints_list.size(); j++)
+                    {
+                        double X_dist   = fabs(keypoints_list[i].point[0] - keypoints_list[j].point[0]);
+                        double Y_dist   = fabs(keypoints_list[i].point[1] - keypoints_list[j].point[1]);
+                        double distance = sqrt((X_dist * X_dist) + (Y_dist * Y_dist));
+                        if (distance < 0.05)
+                            {
+                                repeated = 1;
+                            }
+                    }
+                if (repeated == 0)
+                    {
+                        new_scene->keypoints_list_.push_back(keypoints_list[i]);
+                    }
+            }
+
+        // Compute descriptors
+        extractor_.compute(*scan_falko, new_scene->keypoints_list_, new_scene->descriptors_list_);
+        std::vector<D> descriptors_list_rotated;
+        extractor_.compute(*scan_falko, new_scene->keypoints_list_, descriptors_list_rotated);
+
+        // Compute Scene mid point, angle for each keypoint and rotate descriptors
+        Eigen::Vector2d     mid_point(0, 0);
+        std::vector<double> angle_rotation;
+        for (int i = 0; i < new_scene->keypoints_list_.size(); i++)
+            {
+                mid_point[0] = mid_point[0] + new_scene->keypoints_list_[i].point[0];
+                mid_point[1] = mid_point[1] + new_scene->keypoints_list_[i].point[1];
+                angle_rotation.push_back(angle_min + angle_step * new_scene->keypoints_list_[i].index);
+                // double orientation = new_scene->keypoints_list_[i].orientation + angle_rotation[i];
+                double orientation = angle_rotation[i];
+                descriptors_list_rotated[i].rotate(orientation);
+                new_scene->descriptors_list_rotated.push_back(descriptors_list_rotated[i]);
+            }
+
+        new_scene->mid_point_ = mid_point / new_scene->keypoints_list_.size();
+        // Compute Scene Area and Perimeter
+        int    n = 3;
+        double X[n];
+        double Y[n];
+        new_scene->perimeter_ = 0.0;
+        new_scene->area_      = 0.0;
+        Eigen::Vector2d dist_between_two_kp;
+
+        if (new_scene->keypoints_list_.size() < 3)
+            return new_scene;
+
+        if (new_scene->keypoints_list_.size() < 4)
+            {
+                X[0] = new_scene->keypoints_list_[0].point[0];
+                Y[0] = new_scene->keypoints_list_[0].point[1];
+
+                X[1] = new_scene->keypoints_list_[1].point[0];
+                Y[1] = new_scene->keypoints_list_[1].point[1];
+
+                X[2] = new_scene->keypoints_list_[2].point[0];
+                Y[2] = new_scene->keypoints_list_[2].point[1];
+
+                new_scene->area_ = new_scene->area_ + triangleArea(X, Y, n);
+                return new_scene;
+            }
+
+        for (int i = 0; i < new_scene->keypoints_list_.size(); i++)
+            {
+                X[0] = new_scene->mid_point_[0];
+                Y[0] = new_scene->mid_point_[1];
+
+                // X[0] = 0.0;
+                // Y[0] = 0.0;
 
+                X[1] = new_scene->keypoints_list_[i].point[0];
+                Y[1] = new_scene->keypoints_list_[i].point[1];
+
+                if (i < new_scene->keypoints_list_.size() - 1) // Proceed until final keypoint
+                    {
+                        X[2] = new_scene->keypoints_list_[i + 1].point[0];
+                        Y[2] = new_scene->keypoints_list_[i + 1].point[1];
+
+                        dist_between_two_kp =
+                            new_scene->keypoints_list_[i].point - new_scene->keypoints_list_[i + 1].point;
+                    }
+                else // if you arrived to the final keypoint then use inital keypoint
+                    {
+                        X[2] = new_scene->keypoints_list_[0].point[0];
+                        Y[2] = new_scene->keypoints_list_[0].point[1];
+
+                        dist_between_two_kp = new_scene->keypoints_list_[i].point - new_scene->keypoints_list_[0].point;
+                    }
+                new_scene->area_      = new_scene->area_ + (double)triangleArea(X, Y, n);
+                new_scene->perimeter_ = new_scene->perimeter_ + hypot(dist_between_two_kp[0], dist_between_two_kp[1]);
+            }
+
+        // Compue Scene linear regresion and initial angle
+        double ss_xy = 0;
+        double ss_xx = 0;
+        for (int i = 0; i <= new_scene->keypoints_list_.size(); i++)
+            {
+                ss_xy += (new_scene->keypoints_list_[i].point[0] - new_scene->mid_point_[0]) *
+                         (new_scene->keypoints_list_[i].point[1] - new_scene->mid_point_[1]);
+                ss_xx += (new_scene->keypoints_list_[i].point[0] - new_scene->mid_point_[0]) *
+                         (new_scene->keypoints_list_[i].point[0] - new_scene->mid_point_[0]);
+            }
+        double b_1 = ss_xy / ss_xx;
+        // double b_0 = new_scene->mid_point_[1] - b_1 * new_scene->mid_point_[0];
+
+        // new_scene->regressor_coefs.push_back(b_0);
+        // new_scene->regressor_coefs.push_back(b_1);
+
+        double initial_angle = -atan(b_1);
+
+        // double inital_angle_inv = initial_angle - M_PI;
+
+        // rotate keypoints
+        for (int i = 0; i < new_scene->keypoints_list_.size(); i++)
+            {
+                falkolib::FALKO keypoint_mid;
+                keypoint_mid = new_scene->keypoints_list_[i];
+
+                keypoint_mid.point[0] = new_scene->keypoints_list_[i].point[0] - new_scene->mid_point_[0];
+                keypoint_mid.point[1] = new_scene->keypoints_list_[i].point[1] - new_scene->mid_point_[1];
+                new_scene->keypoints_list_mid_point_.push_back(keypoint_mid);
+
+                falkolib::FALKO keypoint_rotated;
+                keypoint_rotated          = new_scene->keypoints_list_[i];
+                keypoint_rotated.point[0] = new_scene->keypoints_list_[i].point[0] * cos(initial_angle) -
+                                            new_scene->keypoints_list_[i].point[1] * sin(initial_angle);
+                keypoint_rotated.point[1] = new_scene->keypoints_list_[i].point[0] * sin(initial_angle) +
+                                            new_scene->keypoints_list_[i].point[1] * cos(initial_angle);
+                new_scene->keypoints_list_rotated_.push_back(keypoint_rotated);
+
+                falkolib::FALKO keypoint_rot_trans;
+                keypoint_rot_trans = new_scene->keypoints_list_[i];
+                keypoint_rot_trans.point[0] =
+                    (new_scene->keypoints_list_[i].point[0] - new_scene->mid_point_[0]) * cos(initial_angle) -
+                    (new_scene->keypoints_list_[i].point[1] - new_scene->mid_point_[1]) * sin(initial_angle);
+
+                keypoint_rot_trans.point[1] =
+                    (new_scene->keypoints_list_[i].point[0] - new_scene->mid_point_[0]) * sin(initial_angle) +
+                    (new_scene->keypoints_list_[i].point[1] - new_scene->mid_point_[1]) * cos(initial_angle);
+
+                new_scene->keypoints_list_transl_rot_.push_back(keypoint_rot_trans);
+            }
+
+        return new_scene;
+    }
+
+    /** \brief Convert scans from laserscanutils::LaserScan to
+     *falkolib::LaserScan object
+     **/
+    laserScanPtr convert2LaserScanFALKO(const LaserScan &_scan, const LaserScanParams &_scan_params)
+    {
+        auto scan_falko = std::make_shared<falkolib::LaserScan>(_scan_params.angle_min_, _scan_params.angle_max_,
+                                                                _scan.ranges_raw_.size());
+        std::vector<double> double_ranges(_scan.ranges_raw_.begin(), _scan.ranges_raw_.end());
+        scan_falko->fromRanges(double_ranges);
+        return scan_falko;
+    }
+
+    /** \brief Create and update a matchLoopClosure struct with the info that is produced when matching two given scenes
+     * \param _scene_1 reference scene struct
+     * \param _scene_2 target scene struct
+     **/
+    MatchLoopClosureScenePtr matchScene(sceneBasePtr _scene_1, sceneBasePtr _scene_2) override
+    {
+        std::vector<std::pair<int, int>> asso_nn;
+        auto                             scene_1_falko = std::static_pointer_cast<SceneFalko<D>>(_scene_1);
+        auto                             scene_2_falko = std::static_pointer_cast<SceneFalko<D>>(_scene_2);
+
+        int matching_number = 0;
+
+        if (use_descriptors_ == 0)
+            {
+                // matching_number = matcher_.match(scene_1_falko->keypoints_list_transl_rot_,
+                //                                  scene_2_falko->keypoints_list_transl_rot_, asso_nn);
+
+                matching_number =
+                    matcher_.match(scene_1_falko->keypoints_list_, scene_2_falko->keypoints_list_, asso_nn);
+            }
+        else if (use_descriptors_ == 1)
+            {
+                // matching_number = matcher_.match(
+                //     scene_1_falko->keypoints_list_transl_rot_, scene_1_falko->descriptors_list_rotated,
+                //     scene_2_falko->keypoints_list_transl_rot_, scene_2_falko->descriptors_list_rotated, asso_nn);
+
+                matching_number =
+                    matcher_.match(scene_1_falko->keypoints_list_, scene_1_falko->descriptors_list_rotated,
+                                   scene_2_falko->keypoints_list_, scene_2_falko->descriptors_list_rotated, asso_nn);
+            }
+        auto new_match                    = std::make_shared<MatchLoopClosureScene>();
+        new_match->keypoints_number_match = matching_number;
+        if (matching_number > keypoints_number_th_)
+            {
+                new_match->match = computeTransform(scene_1_falko->keypoints_list_, scene_2_falko->keypoints_list_,
+                                                    asso_nn, new_match->transform);
+            }
+        else
+            {
+                new_match->match = false;
+            }
+
+        new_match->associations = asso_nn;
+        new_match->scene_1      = _scene_1;
+        new_match->scene_2      = _scene_2;
+
+        // new_match->score = (double)matching_number / (double)std::min(scene_1_falko->keypoints_list_.size(),
+        //                                                               scene_2_falko->keypoints_list_.size());
+
+        new_match->score = (double)matching_number;
+
+        new_match->transform_vector.head(2) = new_match->transform.translation();
+        new_match->transform_vector(2)      = Eigen::Rotation2Dd(new_match->transform.rotation()).angle();
+
+        return new_match;
+    }
+
+    int  keypoints_number_th_;
+    bool use_descriptors_;
+
+    // (X[i], Y[i]) are coordinates of i'th point.
+    double triangleArea(double X[], double Y[], int n)
+    {
+        // Initialize area
+        double area = 0.0;
+
+        // Calculate value of shoelace formula
+        int j = n - 1;
+        for (int i = 0; i < n; i++)
+            {
+                area += (X[j] + X[i]) * (Y[j] - Y[i]);
+                j = i; // j is previous vertex to i
+            }
+
+        // Return absolute value
+        return fabs((double)area / 2.0);
+    }
+};
+// Partial template specialization
+template <typename D, typename Extr>
+class LoopClosureFalko<D, Extr, falkolib::AHTMatcher> : public LoopClosureBase2d, public falkolib::FALKOExtractor
+{
+  public:
+    typedef std::shared_ptr<SceneFalko<D>>       sceneFalkoBSCPtr;
+    typedef std::shared_ptr<falkolib::LaserScan> laserScanPtr;
+
+    Extr                                     extractor_;
+    falkolib::AHTMatcher<falkolib::FALKO, D> matcher_;
+
+    /** \brief Constructor
+     * \param _param parameter struct with falko lib parameters
+     **/
+    LoopClosureFalko(ParameterLoopClosureFalko _param)
+        : LoopClosureBase2d()
+        , falkolib::FALKOExtractor()
+        , extractor_(_param.circularSectorNumber_, _param.radialRingNumber_)
+        , matcher_(_param.xRes_, _param.yRes_, _param.thetaRes_, _param.xAbsMax_, _param.yAbsMax_, _param.thetaAbsMax_)
+
+    {
+        // FALKO Extractor Parameters
+        setMinExtractionRange(_param.min_extraction_range_);
+        setMaxExtractionRange(_param.max_extraction_range_);
+        enableSubbeam(_param.enable_subbeam_);
+        setNMSRadius(_param.nms_radius_);
+        setNeighB(_param.neigh_b_);
+        setBRatio(_param.b_ratio_);
+        setGridSectors(_param.grid_sectors_);
+
+        // Matcher Extractor Parameters
+        matcher_.setDistanceThreshold(_param.matcher_distance_th_);
+        matcher_.setDescriptorThreshold(_param.matcher_ddesc_th_);
+        keypoints_number_th_ = _param.keypoints_number_th_;
+        use_descriptors_     = _param.use_descriptors_;
+    };
     /** \brief Destructor
      **/
     ~LoopClosureFalko() {}
@@ -191,16 +492,9 @@ class LoopClosureFalko : public LoopClosureBase2d, public falkolib::FALKOExtract
                 mid_point[0] = mid_point[0] + new_scene->keypoints_list_[i].point[0];
                 mid_point[1] = mid_point[1] + new_scene->keypoints_list_[i].point[1];
                 angle_rotation.push_back(angle_min + angle_step * new_scene->keypoints_list_[i].index);
-                // descriptors_list_rotated[i].rotate(angle_rotation[i]);
                 // double orientation = new_scene->keypoints_list_[i].orientation + angle_rotation[i];
                 double orientation = angle_rotation[i];
-                // if (orientation < 0)
-                //     {
-                //         orientation = 2 * M_PI + orientation;
-                //     }
                 descriptors_list_rotated[i].rotate(orientation);
-                // std::cout << "orientation : " << angle_rotation[i] << std::endl;
-                // std::cout << "orientation  desc : " << orientation << std::endl;
                 new_scene->descriptors_list_rotated.push_back(descriptors_list_rotated[i]);
             }
 
diff --git a/test/gtest_loop_closure_falko.cpp b/test/gtest_loop_closure_falko.cpp
index 878ac4bf6c4d7871eb825123a8f59949ab691587..6394926a1b4982807b38f0495b62daa86d4f379a 100644
--- a/test/gtest_loop_closure_falko.cpp
+++ b/test/gtest_loop_closure_falko.cpp
@@ -88,7 +88,7 @@ TEST(loop_closure_falko, TestDescriptorsRotation)
     auto new_scene_2 = std::static_pointer_cast<SceneFalko<bsc>>(loop_cl_falko.extractScene(scan_2, laser_params));
     auto key_1       = new_scene->keypoints_list_;
     auto key_2       = new_scene_2->keypoints_list_;
-    auto desc_1      = new_scene->descriptors_list_rotated;
+    auto desc_1      = new_scene->descriptors_list_;
     auto desc_2      = new_scene_2->descriptors_list_rotated;
 
     int radialRingNumber     = new_scene->descriptors_list_[0].radialRingNumber;
@@ -111,9 +111,8 @@ TEST(loop_closure_falko, TestDescriptorsRotation)
                             min_dist    = asso_dist[i][j];
                             asso_number = j;
                         }
-                    std::cout << "pair : " << i << " , " << j << " , distance : " << asso_dist[i][j] << std::endl;
                 }
-            // std::cout << "pair : " << i << " , " << asso_number << " , distance : " << min_dist << std::endl;
+            std::cout << "pair : " << i << " , " << asso_number << " , distance : " << min_dist << std::endl;
         }
 
     // for (int i = 0; i < desc_1.size(); i++)
@@ -167,7 +166,6 @@ TEST(loop_closure_falko, TestDescriptorsRotation)
     //                     }
     //             }
     //     }
-    std::cout << "acum_distance : " << acum_distance << std::endl;
     ASSERT_EQ(acum_distance, 39);
 }