diff --git a/include/laser/processor/polyline_2D_utils.h b/include/laser/processor/polyline_2D_utils.h
index 62be7c00d128074128eeec92445a83846ef32384..769168d25f3d901e17e8634a0e36be7f348fbef1 100644
--- a/include/laser/processor/polyline_2D_utils.h
+++ b/include/laser/processor/polyline_2D_utils.h
@@ -71,8 +71,8 @@ MatchPolyline2DPtr computeBestSqDist(const Eigen::MatrixXs& _points_A, bool _fir
                                      const Eigen::MatrixXs& _points_B, bool _first_defined_B, bool _last_defined_B, bool _closed_B,
                                      const Scalar& max_sq_error,
                                      const Scalar& min_overlapping_dist,
-                                     const int& min_N_overlapped,
-                                     const int& min_N_defined_overlapped,
+                                     int min_N_overlapped,
+                                     int min_N_defined_overlapped,
                                      bool both_exceeding_A_allowed_ = true,
                                      bool both_exceeding_B_allowed_ = true);
 
diff --git a/include/laser/processor/processor_tracker_feature_polyline_2D.h b/include/laser/processor/processor_tracker_feature_polyline_2D.h
index 9ed7379c50cd0fe484e6b9e4970fd72f72bf4dab..e507d9a82b0e48da52b1272dfe6fbfe0ec048d63 100644
--- a/include/laser/processor/processor_tracker_feature_polyline_2D.h
+++ b/include/laser/processor/processor_tracker_feature_polyline_2D.h
@@ -252,6 +252,16 @@ class ProcessorTrackerFeaturePolyline2D : public ProcessorTrackerFeature
         {
             return untracked_features_last_;
         }
+
+        const FeatureBasePtrList& getIncomingNewFeatures() const
+        {
+            return untracked_features_incoming_;
+        }
+
+        const FeatureBasePtrList& getIncomingKnownFeatures() const
+        {
+            return known_features_incoming_;
+        }
 };
 
 } /* namespace wolf */
diff --git a/src/landmark/landmark_match_polyline_2D.cpp b/src/landmark/landmark_match_polyline_2D.cpp
index 0b2bb446741b79c23f5cc53ce731067fcdf37b02..034a6181b90835b425621e080d4ab372c6ad1ec1 100644
--- a/src/landmark/landmark_match_polyline_2D.cpp
+++ b/src/landmark/landmark_match_polyline_2D.cpp
@@ -172,6 +172,7 @@ bool LandmarkMatchPolyline2D::check(bool check_partial_match) const
 
 Eigen::Array<Scalar,Eigen::Dynamic,1> LandmarkMatchPolyline2D::computeSqDistArray() const
 {
+	std::cout << "LandmarkMatchPolyline2D::computeSqDistArray\n";
     assert(pl_feature_ != nullptr);
     assert(pl_landmark_ != nullptr);
 
diff --git a/src/processor/polyline_2D_utils.cpp b/src/processor/polyline_2D_utils.cpp
index 8aad5acc286b6bc2e2b1123a8edebd51421f8cac..f1dd2da92c28a0d125d4c66969d1bc0baa57f008 100644
--- a/src/processor/polyline_2D_utils.cpp
+++ b/src/processor/polyline_2D_utils.cpp
@@ -168,13 +168,13 @@ Scalar sqDistPointToLine(const Eigen::Vector3s& _A, const Eigen::Vector3s& _A_au
 MatchPolyline2DPtr computeBestSqDist(const Eigen::MatrixXs& _points_A, bool _first_defined_A, bool _last_defined_A, bool _closed_A,
                                      const Eigen::MatrixXs& _points_B, bool _first_defined_B, bool _last_defined_B, bool _closed_B,
                                      const Scalar& sq_error_max,
-                                     const Scalar& overlap_dist_min,
-                                     const int& overlap_N_min,
-                                     const int& overlap_N_defined_min,
+                                     const Scalar& overlap_dist_ratio_min,
+                                     int overlap_N_min,
+                                     int overlap_N_defined_min,
                                      bool both_exceeding_A_allowed_,
                                      bool both_exceeding_B_allowed_)
 {
-    bool print = false;
+    bool print = true;
     if (print)
     {
         std::cout << "computeBestSqDist...\n";
@@ -185,11 +185,22 @@ MatchPolyline2DPtr computeBestSqDist(const Eigen::MatrixXs& _points_A, bool _fir
         std::cout << "\tpoints_A:\n" << _points_A.topRows(2) << std::endl;
         std::cout << "\tpoints_B:\n" << _points_B.topRows(2) << std::endl;
         std::cout << "\tsq_error_max: " << sq_error_max << std::endl;
-        std::cout << "\toverlap_dist_min: " << overlap_dist_min << std::endl;
+        std::cout << "\toverlap_dist_ratio_min: " << overlap_dist_ratio_min << std::endl;
         std::cout << "\toverlap_N_min: " << overlap_N_min << std::endl;
         std::cout << "\toverlap_N_defined_min: " << overlap_N_defined_min << std::endl;
     }
 
+    if (overlap_N_min < 2)
+    {
+    	WOLF_WARN("overlap_N_min should be at least 2! It is a sufficient condition (if enough overlapping distance ratio)");
+    	overlap_N_min = 2;
+    }
+    if (overlap_N_defined_min < 1)
+    {
+    	WOLF_WARN("overlap_N_defined_min should be at least 1! It is a sufficient condition");
+    	overlap_N_defined_min = 1;
+    }
+
     // ASSERTIONS if closed -> all points defined
     assert((_closed_A &&_first_defined_A && _last_defined_A) || !_closed_A);
     assert((_closed_B &&_first_defined_B && _last_defined_B) || !_closed_B);
@@ -215,10 +226,10 @@ MatchPolyline2DPtr computeBestSqDist(const Eigen::MatrixXs& _points_A, bool _fir
     {
         //std::cout << "Auto-calling switching A<->B...\n";
 
-        MatchPolyline2DPtr best_match = computeBestSqDist(_points_B, _first_defined_B, _last_defined_B, _closed_B,
+        best_match = computeBestSqDist(_points_B, _first_defined_B, _last_defined_B, _closed_B,
                                                           _points_A, _first_defined_A, _last_defined_A, _closed_A,
                                                           sq_error_max,
-                                                          overlap_dist_min,
+                                                          overlap_dist_ratio_min,
                                                           overlap_N_min,
                                                           overlap_N_defined_min,
                                                           both_exceeding_B_allowed_,
@@ -309,54 +320,58 @@ MatchPolyline2DPtr computeBestSqDist(const Eigen::MatrixXs& _points_A, bool _fir
         bool to_B_defined   = (to_B != 0 || _first_defined_B) && (to_B != last_B || _last_defined_B);       //((to_B   != 0 && to_B   != last_B) || _last_defined_B);
 
         // SUFFICIENT CONDITIONS
-        //      COND 1: sufficient overlapping points
-        //      COND 2: sufficient overlapping defined points
-        //      COND 3: sufficient overlapping distance
+        //      COND 1: sufficient overlapping defined points
+        //      COND 2: sufficient overlapping points (if no defined points, min overlapping distance)
         int N_defined_overlap = std::max(0,N_overlap - (from_A_defined && from_B_defined ? 0 : 1) - (to_A_defined && to_B_defined ? 0 : 1));
-        Scalar overlap_dist;
-        if (N_overlap <= 1)
-            overlap_dist = 0;
-        else
-        {
-            Eigen::Vector2s p_from_A = _points_A.col(from_A).head(2);
-            Eigen::Vector2s p_to_A   = _points_A.col(to_A).head(2);
-            Eigen::Vector2s p_from_B = _points_B.col(from_B).head(2);
-            Eigen::Vector2s p_to_B   = _points_B.col(to_B).head(2);
-            Eigen::Vector2s vA = p_to_A - p_from_A;
-            Eigen::Vector2s vB = p_to_B - p_from_B;
-
-            // THE MINIMUM OF ALL 6 possible overlap distances
-            Eigen::Vector6s overlap_dists;
-            // 1: fromA - toA
-            overlap_dists(0) = vA.norm();
-            // 2: fromB - toB
-            overlap_dists(1) = vB.norm();
-            // 3: fromA - projected(toB)
-            overlap_dists(2) = (vA.normalized()).dot(p_to_B - p_from_A);
-            // 4: fromB - projected(toA)
-            overlap_dists(3) = (vB.normalized()).dot(p_to_A - p_from_B);
-            // 5: projected(fromB) - toA
-            overlap_dists(4) = (-vA.normalized()).dot(p_from_B - p_to_A);
-            // 6: projected(fromA) - toB
-            overlap_dists(5) = (-vB.normalized()).dot(p_from_A - p_to_B);
-
-            //std::cout << "\tdist2.mean() = " << dist2.mean() << std::endl;
-            //std::cout << "\tmax_sq_error - dist2.mean() = " << max_sq_error - dist2.mean() << std::endl;
-            if (print)
-                std::cout << "\toverlap_dists = " << overlap_dists.transpose() << std::endl;
-            overlap_dist = overlap_dists.minCoeff();
-        }
-
-        // if none of the sufficient conditions hold, continue
-        if ( N_overlap < overlap_N_min &&
-             N_defined_overlap < overlap_N_defined_min &&
-             N_defined_overlap <= 0 && N_overlap < 2 &&
-             overlap_dist < overlap_dist_min)
-        {
-            if (print)
-                std::cout  << "\t\tnone of the sufficient conditions hold\n";
-            continue;
-        }
+		if ( N_defined_overlap < overlap_N_defined_min &&
+			 N_overlap < overlap_N_min )
+		{
+			if (print)
+				std::cout  << "\t\tnone of the sufficient conditions hold\n";
+			continue;
+		}
+		// additional overlapping distance contidion for 2 not defined points
+		if (N_defined_overlap == 0)
+		{
+			Scalar overlap_dist;
+			WOLF_WARN_COND(N_overlap != 2, "THIS SHOULDN'T HAPPEN. \nN_defined_overlap: ", N_defined_overlap, "\nN_overlap: ", N_overlap, "\noverlap_N_defined_min: ", overlap_N_defined_min, "\noverlap_N_min: ", overlap_N_min)
+			assert(N_overlap == 2);
+			Eigen::Vector2s p_from_A = _points_A.col(from_A).head(2);
+			Eigen::Vector2s p_to_A   = _points_A.col(to_A).head(2);
+			Eigen::Vector2s p_from_B = _points_B.col(from_B).head(2);
+			Eigen::Vector2s p_to_B   = _points_B.col(to_B).head(2);
+			Eigen::Vector2s vA = p_to_A - p_from_A;
+			Eigen::Vector2s vB = p_to_B - p_from_B;
+
+			// THE MINIMUM OF ALL 6 possible overlap distances
+			Eigen::Vector6s overlap_dists;
+			// 1: fromA - toA
+			overlap_dists(0) = vA.norm();
+			// 2: fromB - toB
+			overlap_dists(1) = vB.norm();
+			// 3: fromA - projected(toB)
+			overlap_dists(2) = std::abs((vA.normalized()).dot(p_to_B - p_from_A));
+			// 4: fromB - projected(toA)
+			overlap_dists(3) = std::abs((vB.normalized()).dot(p_to_A - p_from_B));
+			// 5: projected(fromB) - toA
+			overlap_dists(4) = std::abs((-vA.normalized()).dot(p_from_B - p_to_A));
+			// 6: projected(fromA) - toB
+			overlap_dists(5) = std::abs((-vB.normalized()).dot(p_from_A - p_to_B));
+
+			//std::cout << "\tdist2.mean() = " << dist2.mean() << std::endl;
+			//std::cout << "\tmax_sq_error - dist2.mean() = " << max_sq_error - dist2.mean() << std::endl;
+			if (print)
+				std::cout << "\toverlap_dists ratios = " << (overlap_dists/std::min(vA.norm(),vB.norm())).transpose() << std::endl;
+			overlap_dist = overlap_dists.minCoeff();
+
+			// if necessary overlapping condition does not hold, continue
+			if (overlap_dist/std::min(vA.norm(),vB.norm()) < overlap_dist_ratio_min)
+			{
+				if (print)
+					std::cout  << "\t\toverlapping distance ratio condition does not hold with 0 defined points overlapped\n";
+				continue;
+			}
+		}
 
         assert(N_overlap <= _points_B.cols());
         assert(N_overlap <= _points_A.cols() || (_closed_A && N_defined_B < _points_B.cols())); // N_overlap can be > _points_A if all defined points of B match with A points and the not defined extremes should match too
@@ -407,13 +422,14 @@ MatchPolyline2DPtr computeBestSqDist(const Eigen::MatrixXs& _points_A, bool _fir
             best_match->from_B_id_= from_B;
             best_match->to_B_id_= to_B;
             best_match->normalized_score_ = normalized_score;
-            best_match->overlap_dist_ = overlap_dist;
+            best_match->overlap_dist_ = 0;//overlap_dist;
 
             if (print)
                 best_match->print();
         }
     }
 
+    std::cout << "returning...\n";
     return best_match;
 }
 
@@ -421,6 +437,7 @@ Eigen::Array<Scalar,Eigen::Dynamic,1> computeSqDist(const Eigen::MatrixXs& _poin
                                                     const Eigen::MatrixXs& _points_B, const int& from_B, const int& to_B, bool from_B_defined, bool to_B_defined,
                                                     const int& last_A, const int& N_overlap )
 {
+	std::cout << "computeSqDist\n";
     // POINT-POINT DISTANCES for all overlap points (in case of closed A in two parts)
     // Fill with B points
     Eigen::ArrayXXd d(_points_B.block(0,from_B, 2, N_overlap).array());
@@ -468,7 +485,7 @@ Eigen::Array<Scalar,Eigen::Dynamic,1> computeSqDist(const Eigen::MatrixXs& _poin
                                                   to_A_defined,
                                                   to_B_defined);
     }
-    //std::cout << "\t\tsquared distances = " << dist2.transpose() << std::endl;
+    std::cout << "\t\tsquared distances = " << dist2.transpose() << std::endl;
 
     return dist2;
 }
diff --git a/src/processor/processor_tracker_feature_polyline_2D.cpp b/src/processor/processor_tracker_feature_polyline_2D.cpp
index b4bcdabceafb59835fd6a7852acb6fb4b4e4d115..b45dc4fda249d3d115d186cf9d6ae7bbf45b8648 100644
--- a/src/processor/processor_tracker_feature_polyline_2D.cpp
+++ b/src/processor/processor_tracker_feature_polyline_2D.cpp
@@ -48,7 +48,7 @@ unsigned int ProcessorTrackerFeaturePolyline2D::trackFeatures(const FeatureBaseP
         auto pl_incoming = std::static_pointer_cast<FeaturePolyline2D>(*ftr_it);
         FeatureMatchPolyline2DScalarMap best_matches;
 
-        // std::cout << "\tmatching feature incoming " << pl_incoming->id() << "\n";
+        std::cout << "\tmatching feature incoming " << pl_incoming->id() << "\n";
 
         // Check matching with all features in last
         // Store all matches consistent with T_last_incoming_prior in best_matches sorted by normalized score
@@ -114,7 +114,7 @@ unsigned int ProcessorTrackerFeaturePolyline2D::trackFeatures(const FeatureBaseP
                 // if concatenation did not succees -> next ftr match
                 if (pl_lmk_match_incoming == nullptr)
                 {
-                    WOLF_DEBUG("PTFP ", getName(), "::trackFeatures: incoming-last + last-landmark could not be concatenated into incoming-landmark");
+                    WOLF_WARN("PTFP ", getName(), "::trackFeatures: incoming-last + last-landmark could not be concatenated into incoming-landmark");
                     continue;
                 }
                 //std::cout << "\t\tlast-incoming valid, storing...\n";
@@ -135,8 +135,9 @@ unsigned int ProcessorTrackerFeaturePolyline2D::trackFeatures(const FeatureBaseP
 
             // match for this feature has been found
             matched = true;
-            // std::cout << "Feature tracked!\n";
-            // best_ftr_match->print();
+
+            std::cout << "Feature tracked!\n";
+            best_ftr_match->print();
             break;
         }
 
@@ -155,7 +156,9 @@ bool ProcessorTrackerFeaturePolyline2D::correctFeatureDrift(const FeatureBasePtr
                                                             const FeatureBasePtr _last_feature,
                                                             FeatureBasePtr _incoming_feature)
 {
-	WOLF_DEBUG("PTFP ", getName(), "::correctFeatureDrift: ");
+	WOLF_WARN("PTFP ", getName(), "::correctFeatureDrift: incoming feature ", _incoming_feature->id());
+	WOLF_WARN("PTFP ", getName(), "::correctFeatureDrift: last feature ", _last_feature->id());
+	//FIXME: sometimes last_feature is nullptr!!!
 
     /** After finding a valid feature match last-incoming, we have to check that the concatenated match
      *  incoming-landmark is also valid.
@@ -174,6 +177,9 @@ bool ProcessorTrackerFeaturePolyline2D::correctFeatureDrift(const FeatureBasePtr
     auto lmk_inc_match = std::static_pointer_cast<LandmarkMatchPolyline2D>(landmark_match_map_[_incoming_feature]);
     auto pl_lmk        = lmk_inc_match->pl_landmark_;
     auto pl_inc        = lmk_inc_match->pl_feature_;
+    assert(pl_lmk != nullptr);
+    assert(pl_inc != nullptr);
+    assert(lmk_inc_match != nullptr);
 
     // WOLF_DEBUG("LANDMARK-INCOMING:");
     // lmk_inc_match->print();
@@ -183,7 +189,7 @@ bool ProcessorTrackerFeaturePolyline2D::correctFeatureDrift(const FeatureBasePtr
     // COMPLETE PARTIAL MATCH
     if (!tryCompletePartialMatch(lmk_inc_match))
     {
-        WOLF_WARN("correctFeatureDrift: tryCompletePartialMatch didn't success, removing..", "last ", last_ptr_->id(), " incoming ", incoming_ptr_->id(), " landmark ", pl_lmk->id());
+        WOLF_WARN("correctFeatureDrift: tryCompletePartialMatch didn't success, removing..", "last feature ", _last_feature->id(), " incoming feature ", _incoming_feature->id(), " landmark ", pl_lmk->id());
         landmark_match_map_.erase(_incoming_feature);
         return false;
     }
@@ -191,7 +197,7 @@ bool ProcessorTrackerFeaturePolyline2D::correctFeatureDrift(const FeatureBasePtr
     // FILTER OUT matches that does not pass check
     if (!lmk_inc_match->check())
     {
-        WOLF_WARN("correctFeatureDrift: match didn't pass the check, removing..", "last ", last_ptr_->id(), " incoming ", incoming_ptr_->id(), " landmark ", pl_lmk->id());
+        WOLF_WARN("correctFeatureDrift: match didn't pass the check, removing..", "last feature ", _last_feature->id(), " incoming feature ", _incoming_feature->id(), " landmark ", pl_lmk->id());
         landmark_match_map_.erase(_incoming_feature);
         return false;
     }
@@ -204,25 +210,39 @@ bool ProcessorTrackerFeaturePolyline2D::correctFeatureDrift(const FeatureBasePtr
     // RETRY LANDMARK-MATCH IF TOO MUCH ERROR
     if ((lmk_inc_match->computeSqDistArray() >= 0.5).any())
     {
-        WOLF_WARN("too much error: ", lmk_inc_match->computeSqDistArray().transpose(), " retrying landmark match" );
+        WOLF_DEBUG("too much error: ", lmk_inc_match->computeSqDistArray().transpose(), " retrying match landmark ", pl_lmk->id(), " with feature ", _incoming_feature->id() );
         LandmarkMatchPolyline2DScalarMap lmk_matches;
+        // try with concatenated transformation
         tryMatchWithLandmark(lmk_matches, pl_lmk, pl_inc, lmk_inc_match->T_feature_landmark_);
-
+        std::cout << "again here...\n";
         // not succeed
         if (lmk_matches.empty())
         {
-            WOLF_WARN("correctFeatureDrift: tryMatchWithLandmark didn't success, removing..", "last ", last_ptr_->id(), " incoming ", incoming_ptr_->id(), " landmark ", pl_lmk->id());
-            landmark_match_map_.erase(_incoming_feature);
-            return false;
+            std::cout << "here...!?\n";
+			WOLF_WARN("correctFeatureDrift: after retrying tryMatchWithLandmark with concatenated transformation didn't success, trying with SLAM transformation..", "last feature ", _last_feature->id(), " incoming feature ", _incoming_feature->id(), " landmark ", pl_lmk->id());
+
+        	// try with SLAM transformation
+            Eigen::Matrix3s T_incoming_map_prior(Eigen::Matrix3s::Identity());
+            T_incoming_map_prior.topLeftCorner(2,2)  = R_sensor_world_incoming_;
+            T_incoming_map_prior.topRightCorner(2,1) = t_sensor_world_incoming_;
+        	tryMatchWithLandmark(lmk_matches, pl_lmk, pl_inc, T_incoming_map_prior);
+        	if (lmk_matches.empty())
+			{
+                std::cout << "here...?\n";
+				WOLF_WARN("correctFeatureDrift: after retrying tryMatchWithLandmark didn't success, removing..", "last feature ", _last_feature->id(), " incoming feature ", _incoming_feature->id(), " landmark ", pl_lmk->id());
+				landmark_match_map_.erase(_incoming_feature);
+				return false;
+			}
         }
+        std::cout << "and here...\n";
         // override if succed
-        else
-        {
-            lmk_inc_match = lmk_matches.rbegin()->second;
-            landmark_match_map_[_incoming_feature] = lmk_inc_match;
-        }
+		lmk_inc_match = lmk_matches.rbegin()->second;
+		landmark_match_map_[_incoming_feature] = lmk_inc_match;
     }
 
+    WOLF_WARN("Validated match:");
+    lmk_inc_match->print();
+
     assert(lmk_inc_match->check() && "after correct drift, check not passed"); // checking partial match
 
     return true;
@@ -308,7 +328,7 @@ bool ProcessorTrackerFeaturePolyline2D::voteForKeyFrame()
 
 unsigned int ProcessorTrackerFeaturePolyline2D::processNew(const int& _max_features)
 {
-	WOLF_DEBUG("PTFP ", getName(), "::processNew: ");
+	WOLF_INFO("PTFP ", getName(), "::processNew: ");
 
     // PT::processNew() ==========================================================
     unsigned int n = ProcessorTrackerFeature::processNew(_max_features); // implicit call to detectNewFeatures() and trackFeatures()
@@ -335,7 +355,7 @@ unsigned int ProcessorTrackerFeaturePolyline2D::processNew(const int& _max_featu
         for (auto lmk : getProblem()->getMap()->getLandmarkList())
             // Check only polyline landmarks that hasn't been just emplaced
             if (lmk->getType() == "POLYLINE 2D" && new_landmarks_.count(lmk) == 0)
-                // Store all matches consistent with T_sensor_world_last in best_lmk_matches sorted by difference from T_sensor_world_last
+                // Store all matches consistent with T_sensor_world_last in best_lmk_matches sorted by squared distance
                 tryMatchWithLandmark(best_lmk_matches, std::static_pointer_cast<LandmarkPolyline2D>(lmk), pl_ftr, T_sensor_world_last);
 
         // EMPLACE: If not matched with any existing landmark: emplace a new one
@@ -371,6 +391,9 @@ unsigned int ProcessorTrackerFeaturePolyline2D::processNew(const int& _max_featu
             landmark_match_map_[pl_ftr] = new_lmk_match;
 
             WOLF_DEBUG("New landmark ", new_lmk_ptr->id(), " created. Matching with feature ", pl_ftr->id());
+
+            WOLF_WARN("New match, last with new landmark:");
+            new_lmk_match->print();
         }
         // MATCH
         else
@@ -378,6 +401,9 @@ unsigned int ProcessorTrackerFeaturePolyline2D::processNew(const int& _max_featu
             // store best match (highest score) in map
             landmark_match_map_[pl_ftr] = best_lmk_matches.rbegin()->second;
 
+            WOLF_WARN("New match, last with existing landmark:");
+            landmark_match_map_[pl_ftr]->print();
+
             // store landmark candidates to be merged
             if (best_lmk_matches.size() > 1)
             {
@@ -406,6 +432,8 @@ unsigned int ProcessorTrackerFeaturePolyline2D::processNew(const int& _max_featu
         // Matched
         if (pl_lmk_match_incoming != nullptr)
         {
+        	WOLF_WARN("New match, incoming with new landmark:");
+        	pl_lmk_match_incoming->print();
             assert(landmark_match_map_.count(pl_incoming) == 0);
             landmark_match_map_[pl_incoming] = pl_lmk_match_incoming;
             ftr_it++;
@@ -438,7 +466,10 @@ unsigned int ProcessorTrackerFeaturePolyline2D::detectNewFeatures(const int& _ma
 
     // link detected features (only created in preProcess())
     for (auto ftr : _features_out)
-        ftr->link(_capture);
+    {
+    	WOLF_INFO("detect new feature in last: ", ftr->id());
+    	ftr->link(_capture);
+    }
 
     // WOLF_DEBUG(_features_out.size(), " were provided");
 
@@ -614,7 +645,7 @@ void ProcessorTrackerFeaturePolyline2D::emplaceFactorPoint(FeaturePolyline2DPtr
 
 LandmarkBasePtr ProcessorTrackerFeaturePolyline2D::emplaceLandmark(FeatureBasePtr _feature_ptr)
 {
-    // WOLF_DEBUG("PTFP ", getName(), "::emplaceLandmark: ");
+    WOLF_DEBUG("PTFP ", getName(), "::emplaceLandmark: ");
     //std::cout << "Robot global pose: " << t_world_robot_.transpose() << std::endl;
     //std::cout << "Sensor global pose: " << t_world_sensor_.transpose() << std::endl;
     assert(_feature_ptr->getType() == "POLYLINE 2D");
@@ -626,9 +657,9 @@ LandmarkBasePtr ProcessorTrackerFeaturePolyline2D::emplaceLandmark(FeatureBasePt
     Eigen::MatrixXs points_global = R_world_sensor_last_ * polyline_ptr->getPoints().topRows<2>() +
                                     t_world_sensor_last_ * Eigen::VectorXs::Ones(polyline_ptr->getNPoints()).transpose();
 
-    // std::cout << "Feature local points: " << std::endl << polyline_ptr->getPoints().topRows<2>() << std::endl;
-    // std::cout << "Landmark global points: " << std::endl << points_global << std::endl;
-    // std::cout << "New landmark: extremes defined " << polyline_ptr->isFirstDefined() << polyline_ptr->isLastDefined() << std::endl;
+    //std::cout << "Feature local points: " << std::endl << polyline_ptr->getPoints().topRows<2>() << std::endl;
+    //std::cout << "Landmark global points: " << std::endl << points_global << std::endl;
+    //std::cout << "New landmark: extremes defined " << polyline_ptr->isFirstDefined() << " "<< polyline_ptr->isLastDefined() << std::endl;
 
     // Create new landmark
     return LandmarkBase::emplace<LandmarkPolyline2D>(getProblem()->getMap(),
@@ -642,11 +673,11 @@ LandmarkBasePtr ProcessorTrackerFeaturePolyline2D::emplaceLandmark(FeatureBasePt
 
 bool ProcessorTrackerFeaturePolyline2D::modifyLandmarkAndMatch(LandmarkMatchPolyline2DPtr& lmk_match)
 {
-	WOLF_DEBUG("PTFP ", getName(), "::modifyLandmarkAndMatch: ");
+	WOLF_INFO("PTFP ", getName(), "::modifyLandmarkAndMatch: ");
     //lmk_match->print();
     auto pl_lmk = lmk_match->pl_landmark_;
     auto pl_ftr = lmk_match->pl_feature_;
-    bool print = false;
+    bool print = true;
     bool modified = false;
 
     assert(lmk_match->check() && "Bad landmark match provided");
@@ -656,13 +687,14 @@ bool ProcessorTrackerFeaturePolyline2D::modifyLandmarkAndMatch(LandmarkMatchPoly
     Eigen::MatrixXs points_global = lmk_match->T_feature_landmark_.inverse() * pl_ftr->getPoints();
     if (print)
     {
-        std::cout << "landmark points" << std::endl << pl_lmk->computePointsGlobal() << std::endl;
-        std::cout << "points_global " << std::endl << points_global << std::endl;
+    	std::cout << "------ modifying landmark: " << pl_lmk->id() << "matched with feature " << pl_ftr->id() << std::endl;
+        std::cout << "\tlandmark points" << std::endl << pl_lmk->computePointsGlobal() << std::endl;
+        std::cout << "\tfeature points_global " << std::endl << points_global << std::endl;
         //std::cout << "points_global2 " << std::endl << points_global2 << std::endl;
-        std::cout << "landmark points local" << std::endl << lmk_match->T_feature_landmark_ * pl_lmk->computePointsGlobal() << std::endl;
-        std::cout << "feature points " << std::endl << pl_ftr->getPoints() << std::endl;
-        std::cout << "feature local global" << std::endl << lmk_match->T_feature_landmark_ * points_global << std::endl;
-        std::cout << "lmk_match->T_feature_landmark_" << std::endl << lmk_match->T_feature_landmark_ << std::endl;
+        std::cout << "\tlandmark points local" << std::endl << lmk_match->T_feature_landmark_ * pl_lmk->computePointsGlobal() << std::endl;
+        std::cout << "\tfeature points " << std::endl << pl_ftr->getPoints() << std::endl;
+        //std::cout << "\tfeature local global" << std::endl << lmk_match->T_feature_landmark_ * points_global << std::endl;
+        std::cout << "\tlmk_match->T_feature_landmark_" << std::endl << lmk_match->T_feature_landmark_ << std::endl;
     }
 
     // MODIFY LANDMARK
@@ -972,7 +1004,7 @@ void ProcessorTrackerFeaturePolyline2D::tryMatchWithFeature(FeatureMatchPolyline
                                                             const FeaturePolyline2DPtr& _ftr_I,
                                                             const Eigen::Matrix3s& _T_last_incoming_prior) const
 {
-    //WOLF_DEBUG("tryMatchWithFeature: incoming ", _ftr_I->id(), " last ", _ftr_L->id());
+    WOLF_INFO("tryMatchWithFeature: incoming ", _ftr_I->id(), " last ", _ftr_L->id());
 
     MatchPolyline2DPtr best_match = nullptr;
 
@@ -1037,6 +1069,7 @@ void ProcessorTrackerFeaturePolyline2D::tryMatchWithFeature(FeatureMatchPolyline
     //valid match
     if (best_match != nullptr)
     {
+        WOLF_INFO("match found:");
 
         auto ftr_match = std::make_shared<FeatureMatchPolyline2D>();
         // feature pointers
@@ -1068,7 +1101,7 @@ void ProcessorTrackerFeaturePolyline2D::tryMatchWithFeature(FeatureMatchPolyline
 
         // store in list
         ftr_matches[ftr_match->normalized_score_] = ftr_match;
-        //WOLF_DEBUG("match stored:");
+        WOLF_INFO("match stored:");
         //ftr_match->print();
         assert(ftr_match->check() && "tryMatchWithFeature: wrong match");
     }
@@ -1080,7 +1113,7 @@ void ProcessorTrackerFeaturePolyline2D::tryMatchWithLandmark(LandmarkMatchPolyli
                                                              const FeaturePolyline2DPtr& _feat_ptr,
                                                              const Eigen::Matrix3s& _T_feature_landmark_prior) const
 {
-    //WOLF_DEBUG("PTFP ", getName(), "::tryMatchWithLandmark: ");
+	WOLF_INFO("PTFP ", getName(), "::tryMatchWithLandmark: ");
 
     MatchPolyline2DPtr best_match = nullptr;
 
@@ -1143,13 +1176,13 @@ void ProcessorTrackerFeaturePolyline2D::tryMatchWithLandmark(LandmarkMatchPolyli
                                        params_tracker_feature_polyline_->match_landmark_overlap_n_min,
                                        params_tracker_feature_polyline_->match_landmark_overlap_n_defined_min,
                                        true, // exceeding points in both extremes allowed for landmark
-                                       false);// exceeding points in both extremes allowed for feature
+                                       false);// exceeding points in both extremes not allowed for feature
     }
 
     //valid match
     if (best_match != nullptr)
     {
-        //WOLF_DEBUG("match found!");
+        WOLF_INFO("match found!");
         auto lmk_match = std::make_shared<LandmarkMatchPolyline2D>();
 
         // landmark
@@ -1179,9 +1212,10 @@ void ProcessorTrackerFeaturePolyline2D::tryMatchWithLandmark(LandmarkMatchPolyli
 
         // store in list
         lmk_matches[lmk_match->normalized_score_]= lmk_match;
-        //WOLF_DEBUG("match stored!");
+        WOLF_INFO("match stored!");
         assert(lmk_match->check() && "tryMatchWithLandmark: wrong match");
     }
+    WOLF_INFO("end!");
 }
 
 /* updateLandmarkMatch
@@ -1190,7 +1224,7 @@ void ProcessorTrackerFeaturePolyline2D::tryMatchWithLandmark(LandmarkMatchPolyli
  */
 bool ProcessorTrackerFeaturePolyline2D::updateLandmarkMatch(LandmarkMatchPolyline2DPtr& _lmk_match) const
 {
-    //WOLF_DEBUG("PTFP ", getName(), "::updateLandmarkMatch: ");
+    WOLF_INFO("PTFP ", getName(), "::updateLandmarkMatch: ");
 
     auto pl_lmk = _lmk_match->pl_landmark_;
     auto pl_ftr = _lmk_match->pl_feature_;
@@ -1313,26 +1347,28 @@ bool ProcessorTrackerFeaturePolyline2D::tryUpdateMatchTransformation(LandmarkMat
     if (lmk_match->getNDefinedPoints() > 0 && lmk_match->getNPoints() > 1)
     {
         //auto T_feature_landmark_prev = lmk_match->T_feature_landmark_;
+        auto prev_sqdist = lmk_match->computeSqDistArray();
 
         lmk_match->T_feature_landmark_ = pose2T2D(computeRigidTrans(lmk_match->pl_feature_->getPoints().middleCols(lmk_match->feature_from_id_,lmk_match->getNPoints()),
                                                                     lmk_match->pl_landmark_->computePointsGlobal(lmk_match->landmark_from_id_,lmk_match->landmark_to_id_),
                                                                     lmk_match->fromDefined(),
                                                                     lmk_match->toDefined()));
 
-//        WOLF_WARN_COND((T2pose2D(T_feature_landmark_prev)-T2pose2D(lmk_match->T_feature_landmark_)).head(2).norm() > 0.1 ||
-//                       abs(pi2pi((T2pose2D(T_feature_landmark_prev)-T2pose2D(lmk_match->T_feature_landmark_))(2))) > 0.1,
-//                       "tryUpdateMatchTransformation: lmk_match->T_feature_landmark_ changed significantly. \n\tPrev pose: ",
-//                       T2pose2D(T_feature_landmark_prev).transpose(),
-//                       "\n\tUpdated pose:",
-//                       T2pose2D(lmk_match->T_feature_landmark_).transpose());
+		//WOLF_WARN_COND((T2pose2D(T_feature_landmark_prev)-T2pose2D(lmk_match->T_feature_landmark_)).head(2).norm() > 0.1 ||
+		//			   abs(pi2pi((T2pose2D(T_feature_landmark_prev)-T2pose2D(lmk_match->T_feature_landmark_))(2))) > 0.1,
+		//			   "tryUpdateMatchTransformation: lmk_match->T_feature_landmark_ changed significantly. \n\tPrev pose: ",
+		//			   T2pose2D(T_feature_landmark_prev).transpose(),
+		//			   "\n\tUpdated pose:",
+		//			   T2pose2D(lmk_match->T_feature_landmark_).transpose());
 
-        //WOLF_WARN_COND((lmk_match->computeSqDistArray() >= 0.5).any(),
-        //                "after tryUpdateMatchTransformation too much error: ",
-        //                lmk_match->computeSqDistArray().transpose() );
+        WOLF_WARN_COND(lmk_match->computeSqDistArray().maxCoeff() > prev_sqdist.maxCoeff() + 1e-9,
+                        "after tryUpdateMatchTransformation more error! ",
+                        "\nprev:", prev_sqdist.transpose(),
+						"\nnow: ", lmk_match->computeSqDistArray().transpose());
 
         return true;
     }
-    //WOLF_DEBUG("tryUpdateMatchTransformation: Not enough points: ",lmk_match->getNPoints(), " (should be > 1) or defined points: ", lmk_match->getNDefinedPoints(), " (should be > 0)");
+    //WOLF_WARN("tryUpdateMatchTransformation: Not enough points: ",lmk_match->getNPoints(), " (should be > 1) or defined points: ", lmk_match->getNDefinedPoints(), " (should be > 0)");
     return false;
 }
 
@@ -1344,9 +1380,9 @@ void ProcessorTrackerFeaturePolyline2D::computeTransformations()
     //WOLF_DEBUG("ProcessorTrackerFeaturePolyline::computeTransformations: ");
     Eigen::Vector3s vehicle_pose_incoming = getProblem()->getState(incoming_ptr_->getTimeStamp());
     Eigen::Vector3s vehicle_pose_last     = getProblem()->getState(last_ptr_->getTimeStamp());
-    //WOLF_DEBUG("ProcessorTrackerFeaturePolyline::computeTransformations:",
-    //           "\n\tvehicle_pose_incoming: ", vehicle_pose_incoming.transpose(),
-    //           "\n\tvehicle_pose_last:     ", vehicle_pose_last.transpose());
+    WOLF_DEBUG("ProcessorTrackerFeaturePolyline::computeTransformations:",
+               "\n\tvehicle_pose_incoming: ", vehicle_pose_incoming.transpose(), " at ", incoming_ptr_->getTimeStamp(),
+               "\n\tvehicle_pose_last:     ", vehicle_pose_last.transpose(), " at ", last_ptr_->getTimeStamp());
 
     // world_robot
     Eigen::Matrix2s R_world_robot_incoming = Eigen::Rotation2Ds(vehicle_pose_incoming(2)).matrix();