diff --git a/include/laser/processor/processor_tracker_feature_polyline_2D.h b/include/laser/processor/processor_tracker_feature_polyline_2D.h
index 918a179610f325ddcf0a21fd69ec3663087ffacf..9d4b448a422d294a5132bba917bd0abbbd2caec3 100644
--- a/include/laser/processor/processor_tracker_feature_polyline_2D.h
+++ b/include/laser/processor/processor_tracker_feature_polyline_2D.h
@@ -37,9 +37,11 @@ typedef std::map<Scalar,LandmarkMatchPolyline2DPtr> LandmarkMatchPolyline2DScala
 struct ProcessorParamsTrackerFeaturePolyline2D : public ProcessorParamsTrackerFeature
 {
     laserscanutils::LineFinderIterativeParams line_finder_params;
-    Scalar match_alignment_position_sq_norm_th;
-    Scalar match_landmark_pose_sq_norm_th;
-    Scalar match_feature_pose_sq_norm_th;
+    Scalar match_feature_position_sq_norm_th;
+    Scalar match_feature_orientation_sq_norm_th;
+    Scalar match_landmark_position_sq_norm_th;
+    Scalar match_landmark_orientation_sq_norm_th;
+    bool use_probabilistic_match;
     Scalar class_position_error_th;
     unsigned int new_features_th;
     Scalar loop_time_th;
diff --git a/src/processor/processor_tracker_feature_polyline_2D.cpp b/src/processor/processor_tracker_feature_polyline_2D.cpp
index b28e0e43eb0961d62b1c4d2bf6a8dc3df3ee7e12..d2d71a9a870dfaa9de673b941f25de51aa8ca290 100644
--- a/src/processor/processor_tracker_feature_polyline_2D.cpp
+++ b/src/processor/processor_tracker_feature_polyline_2D.cpp
@@ -833,17 +833,60 @@ void ProcessorTrackerFeaturePolyline2D::tryMatchWithFeature(FeatureMatchPolyline
 {
     //WOLF_DEBUG("PTFP ", getName(), "::tryMatchWithFeature: ");
 
-    // compute best sq distance matching
-    Eigen::MatrixXs last_expected_points = _T_last_incoming_prior.inverse() * _ftr_L->getPoints();
-    MatchPolyline2DPtr best_match = computeBestSqDist(_ftr_I->getPoints(),       // <--feature incoming points
-                                                      _ftr_I->isFirstDefined(),
-                                                      _ftr_I->isLastDefined(),
-                                                      false,                     // <--feature is not closed for sure
-                                                      last_expected_points,      // <--feature last points
-                                                      _ftr_L->isFirstDefined(),
-                                                      _ftr_L->isLastDefined(),
-                                                      false,                     // <--feature is not closed for sure
-                                                      params_tracker_feature_polyline_->match_feature_pose_sq_norm_th);
+    MatchPolyline2DPtr best_match = nullptr;
+
+    if (params_tracker_feature_polyline_->use_probabilistic_match)
+    {
+        // Compute Covariance of projected points (only considering noise in T_last_incoming) and computing Jacobian using the mean of the points
+        Eigen::Vector2s mean_last_points = _ftr_L->getPoints().rowwise().mean().head(2);
+        Eigen::Vector2s J_th;
+        Scalar cos_th = _T_last_incoming_prior(0,0);
+        Scalar sin_th = _T_last_incoming_prior(1,0);
+        J_th << -sin_th * mean_last_points(0) - cos_th * mean_last_points(1),
+                 cos_th * mean_last_points(0) - sin_th * mean_last_points(1);
+        Eigen::Matrix2s Sigma = Eigen::Matrix2s::Identity()*params_tracker_feature_polyline_->match_feature_position_sq_norm_th +
+                                J_th*params_tracker_feature_polyline_->match_feature_orientation_sq_norm_th*J_th.transpose();
+
+        // sq root of inverse
+        Eigen::Matrix2s sqrtOmega = Sigma.llt().matrixL().inverse();
+
+        // last expected points
+        Eigen::Matrix<Scalar, 3, Eigen::Dynamic> last_expected_points = _T_last_incoming_prior.inverse() * _ftr_L->getPoints();
+
+        // Shape points in the equiprobabilistic space
+        Eigen::Matrix<Scalar, 3, Eigen::Dynamic> last_shaped = last_expected_points;
+        Eigen::Matrix<Scalar, 3, Eigen::Dynamic> inc_shaped  = _ftr_I->getPoints();
+        last_shaped.topRows<2>() = sqrtOmega*last_shaped.topRows<2>();
+        inc_shaped.topRows<2>()  = sqrtOmega*inc_shaped.topRows<2>();
+
+        // compute best sq Mahalanobis distance matching
+        best_match = computeBestSqDist(inc_shaped, // <--feature incoming points
+                                       _ftr_I->isFirstDefined(),
+                                       _ftr_I->isLastDefined(),
+                                       false,                     // <--feature is not closed for sure
+                                       last_shaped, // <--feature last points
+                                       _ftr_L->isFirstDefined(),
+                                       _ftr_L->isLastDefined(),
+                                       false,                     // <--feature is not closed for sure
+                                       1);
+    }
+    else // not probabilistic match
+    {
+        // last expected points
+        Eigen::Matrix<Scalar, 3, Eigen::Dynamic> last_expected_points = _T_last_incoming_prior.inverse() * _ftr_L->getPoints();
+
+        // compute best sq Mahalanobis distance matching
+        best_match = computeBestSqDist(_ftr_I->getPoints(),       // <--feature incoming points
+                                       _ftr_I->isFirstDefined(),
+                                       _ftr_I->isLastDefined(),
+                                       false,                     // <--feature is not closed for sure
+                                       last_expected_points,      // <--feature last points
+                                       _ftr_L->isFirstDefined(),
+                                       _ftr_L->isLastDefined(),
+                                       false,                     // <--feature is not closed for sure
+                                       params_tracker_feature_polyline_->match_feature_position_sq_norm_th);
+    }
+
     //valid match
     if (best_match != nullptr)
     {
@@ -932,17 +975,60 @@ void ProcessorTrackerFeaturePolyline2D::tryMatchWithLandmark(LandmarkMatchPolyli
 {
     //WOLF_DEBUG("PTFP ", getName(), "::tryMatchWithLandmark: ");
 
-    // compute best sq distance matching
-    Eigen::MatrixXs lmk_expected_points = _T_feature_landmark_prior * _lmk_ptr->computePointsGlobal();
-    MatchPolyline2DPtr best_match = computeBestSqDist(lmk_expected_points,  // <--landmark points in local coordinates
-                                                      _lmk_ptr->isFirstDefined(),
-                                                      _lmk_ptr->isLastDefined(),
-                                                      _lmk_ptr->isClosed(),
-                                                      _feat_ptr->getPoints(),        // <--feature points
-                                                      _feat_ptr->isFirstDefined(),
-                                                      _feat_ptr->isLastDefined(),
-                                                      false,                      // <--feature is not closed for sure
-                                                      params_tracker_feature_polyline_->match_landmark_pose_sq_norm_th);
+    MatchPolyline2DPtr best_match = nullptr;
+
+    if (params_tracker_feature_polyline_->use_probabilistic_match)
+    {
+        // Compute Covariance of projected points (only considering noise in _T_feature_landmark_prior) and computing Jacobian using the mean of the points
+        Eigen::Vector2s mean_last_points = _lmk_ptr->computePointsGlobal().rowwise().mean().head(2);
+        Eigen::Vector2s J_th;
+        Scalar cos_th = _T_feature_landmark_prior(0,0);
+        Scalar sin_th = _T_feature_landmark_prior(1,0);
+        J_th << -sin_th * mean_last_points(0) - cos_th * mean_last_points(1),
+                 cos_th * mean_last_points(0) - sin_th * mean_last_points(1);
+        Eigen::Matrix2s Sigma = Eigen::Matrix2s::Identity()*params_tracker_feature_polyline_->match_feature_position_sq_norm_th +
+                                J_th*params_tracker_feature_polyline_->match_feature_orientation_sq_norm_th*J_th.transpose();
+
+        // sq root of inverse
+        Eigen::Matrix2s sqrtOmega = Sigma.llt().matrixL().inverse();
+
+        // landmark expected points
+        Eigen::MatrixXs lmk_expected_points = _T_feature_landmark_prior * _lmk_ptr->computePointsGlobal();
+
+        // Shape points in the equiprobabilistic space
+        Eigen::Matrix<Scalar, 3, Eigen::Dynamic> lmk_shaped = lmk_expected_points;
+        Eigen::Matrix<Scalar, 3, Eigen::Dynamic> feat_shaped  = _feat_ptr->getPoints();
+        lmk_shaped.topRows<2>() = sqrtOmega*lmk_shaped.topRows<2>();
+        feat_shaped.topRows<2>()  = sqrtOmega*feat_shaped.topRows<2>();
+
+        // compute best sq Mahalanobis distance matching
+        best_match = computeBestSqDist(lmk_shaped, // <--landmark points in local coordinates
+                                       _lmk_ptr->isFirstDefined(),
+                                       _lmk_ptr->isLastDefined(),
+                                       _lmk_ptr->isClosed(),
+                                       feat_shaped,             // <--feature last points
+                                       _feat_ptr->isFirstDefined(),
+                                       _feat_ptr->isLastDefined(),
+                                       false,                     // <--feature is not closed for sure
+                                       1);
+    }
+    else // not probabilistic match
+    {
+        // landmark expected points
+        Eigen::MatrixXs lmk_expected_points = _T_feature_landmark_prior * _lmk_ptr->computePointsGlobal();
+
+        // compute best sq distance matching
+        best_match = computeBestSqDist(lmk_expected_points,  // <--landmark points in local coordinates
+                                       _lmk_ptr->isFirstDefined(),
+                                       _lmk_ptr->isLastDefined(),
+                                       _lmk_ptr->isClosed(),
+                                       _feat_ptr->getPoints(),        // <--feature points
+                                       _feat_ptr->isFirstDefined(),
+                                       _feat_ptr->isLastDefined(),
+                                       false,                      // <--feature is not closed for sure
+                                       params_tracker_feature_polyline_->match_landmark_pose_sq_norm_th);
+    }
+
     //valid match
     if (best_match != nullptr)
     {