diff --git a/CMakeLists.txt b/CMakeLists.txt
index fef41cbba74fb13c7d02841c2ddbb876a0c28959..8d4e1e7e0661b09326ccc803a22d732916081879 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -603,7 +603,6 @@ IF (laser_scan_utils_FOUND)
   SET(HDRS_PROCESSOR ${HDRS_PROCESSOR}
     include/base/processor/processor_tracker_feature_corner.h
     include/base/processor/processor_tracker_landmark_corner.h
-    include/base/processor/processor_tracker_landmark_polyline.h
     )
   SET(HDRS_SENSOR ${HDRS_SENSOR}
     include/base/sensor/sensor_laser_2D.h
@@ -612,7 +611,6 @@ IF (laser_scan_utils_FOUND)
     src/sensor/sensor_laser_2D.cpp
     src/processor/processor_tracker_feature_corner.cpp
     src/processor/processor_tracker_landmark_corner.cpp
-    src/processor/processor_tracker_landmark_polyline.cpp
     )
 ENDIF(laser_scan_utils_FOUND)
 
diff --git a/include/base/processor/processor_tracker_landmark_polyline.h b/include/base/processor/processor_tracker_landmark_polyline.h
deleted file mode 100644
index a6f902c930d696dc595ae19f133a0df4fd0e00c2..0000000000000000000000000000000000000000
--- a/include/base/processor/processor_tracker_landmark_polyline.h
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * processor_tracker_landmark_polyline.h
- *
- *  Created on: May 26, 2016
- *      Author: jvallve
- */
-
-#ifndef SRC_PROCESSOR_TRACKER_LANDMARK_POLYLINE_H_
-#define SRC_PROCESSOR_TRACKER_LANDMARK_POLYLINE_H_
-
-// Wolf includes
-#include "base/sensor/sensor_laser_2D.h"
-#include "base/capture/capture_laser_2D.h"
-#include "base/feature/feature_polyline_2D.h"
-#include "base/landmark/landmark_polyline_2D.h"
-#include "base/factor/factor_point_2D.h"
-#include "base/factor/factor_point_to_line_2D.h"
-#include "base/state_block.h"
-#include "base/association/association_tree.h"
-#include "base/processor/processor_tracker_landmark.h"
-
-//laser_scan_utils
-#include "laser_scan_utils/laser_scan.h"
-#include "laser_scan_utils/line_finder_iterative.h"
-#include "laser_scan_utils/polyline.h"
-
-namespace wolf
-{
-
-//some consts.. TODO: this tuning params should be grouped in a struct and passed to the class from ros node, at constructor level
-const Scalar position_error_th_ = 1;
-const Scalar min_features_ratio_th_ = 0.5;
-
-//forward declaration to typedef class pointers
-struct LandmarkPolylineMatch;
-typedef std::shared_ptr<LandmarkPolylineMatch> LandmarkPolylineMatchPtr;
-
-//forward declaration to typedef class pointers
-struct ProcessorParamsPolyline;
-typedef std::shared_ptr<ProcessorParamsPolyline> ProcessorParamsPolylinePtr;
-
-WOLF_PTR_TYPEDEFS(ProcessorTrackerLandmarkPolyline);
-
-// Match Feature - Landmark
-struct LandmarkPolylineMatch : public LandmarkMatch
-{
-        int landmark_match_from_id_;
-        int feature_match_from_id_;
-        int landmark_match_to_id_;
-        int feature_match_to_id_;
-
-//    std::vector<unsigned int> landmark_points_match_;
-//    std::vector<unsigned int> feature_points_match_;
-//    std::vector<unsigned int> feature_points_add_front_;
-//    std::vector<unsigned int> feature_points_add_back_;
-
-        LandmarkPolylineMatch() :
-            landmark_match_from_id_(0),
-            feature_match_from_id_(0),
-            landmark_match_to_id_(0),
-            feature_match_to_id_(0)
-        {
-            //
-        }
-        LandmarkPolylineMatch(int _landmark_match_from_id,
-                              int _feature_match_from_id,
-                              int _landmark_match_to_id,
-                              int _feature_match_to_id) :
-                                  landmark_match_from_id_(_landmark_match_from_id),
-                                  feature_match_from_id_(_feature_match_from_id),
-                                  landmark_match_to_id_(_landmark_match_to_id),
-                                  feature_match_to_id_(_landmark_match_to_id)
-        {
-            //
-        }
-};
-
-WOLF_STRUCT_PTR_TYPEDEFS(ProcessorParamsPolyline);
-struct ProcessorParamsPolyline : public ProcessorParamsTrackerLandmark
-{
-        laserscanutils::LineFinderIterativeParams line_finder_params;
-        Scalar position_error_th;
-        unsigned int new_features_th;
-        unsigned int loop_frames_th;
-
-        // These values below are constant and defined within the class -- provide a setter or accept them at construction time if you need to configure them
-        //        Scalar aperture_error_th_ = 20.0 * M_PI / 180.; //20 degrees
-        //        Scalar angular_error_th_ = 10.0 * M_PI / 180.; //10 degrees;
-        //        Scalar position_error_th_ = 1;
-        //        Scalar min_features_ratio_th_ = 0.5;
-};
-
-class ProcessorTrackerLandmarkPolyline : public ProcessorTrackerLandmark
-{
-    private:
-        laserscanutils::LineFinderIterative line_finder_;
-        ProcessorParamsPolylinePtr params_;
-
-        FeatureBasePtrList polylines_incoming_;
-        FeatureBasePtrList polylines_last_;
-
-        Eigen::Matrix2s R_sensor_world_, R_world_sensor_;
-        Eigen::Matrix2s R_robot_sensor_;
-        Eigen::Matrix2s R_current_prev_;
-        Eigen::Vector2s t_sensor_world_, t_world_sensor_, t_world_sensor_prev_, t_sensor_world_prev_;
-        Eigen::Vector2s t_robot_sensor_;
-        Eigen::Vector2s t_current_prev_;
-        Eigen::Vector2s t_world_robot_;
-        bool extrinsics_transformation_computed_;
-
-    public:
-        EIGEN_MAKE_ALIGNED_OPERATOR_NEW; // to guarantee alignment (see http://eigen.tuxfamily.org/dox-devel/group__TopicStructHavingEigenMembers.html)
-
-        ProcessorTrackerLandmarkPolyline(ProcessorParamsPolylinePtr _params);
-
-        virtual ~ProcessorTrackerLandmarkPolyline();
-        virtual void configure(SensorBasePtr _sensor) { };
-
-        const FeatureBasePtrList& getLastPolylines() const;
-
-    protected:
-
-        virtual void preProcess();
-        void computeTransformations(const TimeStamp& _ts);
-        virtual void postProcess();
-
-        void advanceDerived();
-
-        void resetDerived();
-
-        /** \brief Find provided landmarks in the incoming capture
-         * \param _landmarks_in input list of landmarks to be found in incoming
-         * \param _features_incoming_out returned list of incoming features corresponding to a landmark of _landmarks_in
-         * \param _feature_landmark_correspondences returned map of landmark correspondences: _feature_landmark_correspondences[_feature_out_ptr] = landmark_in_ptr
-         */
-        virtual unsigned int findLandmarks(const LandmarkBasePtrList& _landmarks_in, FeatureBasePtrList& _features_incoming_out,
-                                           LandmarkMatchMap& _feature_landmark_correspondences);
-
-        /** \brief Vote for KeyFrame generation
-         *
-         * If a KeyFrame criterion is validated, this function returns true,
-         * meaning that it wants to create a KeyFrame at the \b last Capture.
-         *
-         * WARNING! This function only votes! It does not create KeyFrames!
-         */
-        virtual bool voteForKeyFrame();
-
-        /** \brief Detect new Features
-         * \param _capture_ptr Capture for feature detection. Defaults to incoming_ptr_.
-         * \param _new_features_list The list of detected Features. Defaults to member new_features_list_.
-         * \return The number of detected Features.
-         *
-         * This function detects Features that do not correspond to known Features/Landmarks in the system.
-         *
-         * The function sets the member new_features_list_, the list of newly detected features,
-         * to be used for landmark initialization.
-         */
-        virtual unsigned int detectNewFeatures(const unsigned int& _max_features, FeatureBasePtrList& _features_incoming_out);
-
-        /** \brief Creates a landmark for each of new_features_last_
-         **/
-        virtual void createNewLandmarks();
-
-        /** \brief Create one landmark
-         *
-         * Implement in derived classes to build the type of landmark you need for this tracker.
-         */
-        virtual LandmarkBasePtr createLandmark(FeatureBasePtr _feature_ptr);
-
-        /** \brief Establish factors between features in Captures \b last and \b origin
-         */
-        virtual void establishFactors();
-
-        /** \brief look for known objects in the list of unclassified polylines
-        */
-        void classifyPolilines(LandmarkBasePtrList& _lmk_list);
-
-        /** \brief Create a new factor
-         * \param _feature_ptr pointer to the Feature to constrain
-         * \param _landmark_ptr LandmarkBase pointer to the Landmark constrained.
-         *
-         * Implement this method in derived classes.
-         */
-        virtual FactorBasePtr createFactor(FeatureBasePtr _feature_ptr, LandmarkBasePtr _landmark_ptr);
-
-    private:
-
-        void extractPolylines(CaptureLaser2DPtr _capture_laser_ptr, FeatureBasePtrList& _polyline_list);
-
-        void expectedFeature(LandmarkBasePtr _landmark_ptr, Eigen::MatrixXs& expected_feature_,
-                             Eigen::MatrixXs& expected_feature_cov_);
-
-        Eigen::VectorXs computeSquaredMahalanobisDistances(const Eigen::Vector2s& _feature,
-                                                           const Eigen::Matrix2s& _feature_cov,
-                                                           const Eigen::Vector2s& _expected_feature,
-                                                           const Eigen::Matrix2s& _expected_feature_cov,
-                                                           const Eigen::MatrixXs& _mu);
-        Scalar sqDistPointToLine(const Eigen::Vector3s& _A, const Eigen::Vector3s& _A_aux, const Eigen::Vector3s& _B,
-                               bool _A_extreme, bool _B_extreme);
-    // Factory method
-    public:
-        static ProcessorBasePtr create(const std::string& _unique_name, const ProcessorParamsBasePtr _params, const SensorBasePtr sensor_ptr = nullptr);
-};
-
-inline ProcessorTrackerLandmarkPolyline::ProcessorTrackerLandmarkPolyline(ProcessorParamsPolylinePtr _params) :
-        ProcessorTrackerLandmark("TRACKER LANDMARK POLYLINE", _params),
-        line_finder_(_params->line_finder_params),
-        params_(_params),
-        extrinsics_transformation_computed_(false)
-{
-}
-
-inline unsigned int ProcessorTrackerLandmarkPolyline::detectNewFeatures(const unsigned int& _max_features, FeatureBasePtrList& _features_incoming_out)
-{
-    // already computed since each scan is computed in preprocess()
-    _features_incoming_out = std::move(polylines_last_);
-    return _features_incoming_out.size();
-}
-
-inline void ProcessorTrackerLandmarkPolyline::advanceDerived()
-{
-    //std::cout << "\tProcessorTrackerLandmarkPolyline::advance:" << std::endl;
-    //std::cout << "\t\tcorners_last: " << polylines_last_.size() << std::endl;
-    //std::cout << "\t\tcorners_incoming_: " << polylines_incoming_.size() << std::endl;
-    ProcessorTrackerLandmark::advanceDerived();
-    for (auto polyline : polylines_last_)
-        polyline->remove();
-    polylines_last_ = std::move(polylines_incoming_);
-    //std::cout << "advanced" << std::endl;
-}
-
-inline void ProcessorTrackerLandmarkPolyline::resetDerived()
-{
-    //std::cout << "\tProcessorTrackerLandmarkPolyline::reset:" << std::endl;
-    //std::cout << "\t\tcorners_last: " << corners_last_.size() << std::endl;
-    //std::cout << "\t\tcorners_incoming_: " << polylines_incoming_.size() << std::endl;
-    ProcessorTrackerLandmark::resetDerived();
-    polylines_last_ = std::move(polylines_incoming_);
-}
-
-inline const FeatureBasePtrList& ProcessorTrackerLandmarkPolyline::getLastPolylines() const
-{
-    return polylines_last_;
-}
-
-} // namespace wolf
-
-#endif /* SRC_PROCESSOR_TRACKER_LASER_H_ */
diff --git a/src/processor/processor_tracker_landmark_polyline.cpp b/src/processor/processor_tracker_landmark_polyline.cpp
deleted file mode 100644
index c3f91c0278eda1a7a73657f4d18d40710c59f999..0000000000000000000000000000000000000000
--- a/src/processor/processor_tracker_landmark_polyline.cpp
+++ /dev/null
@@ -1,1020 +0,0 @@
-#include "base/processor/processor_tracker_landmark_polyline.h"
-
-namespace wolf
-{
-
-void ProcessorTrackerLandmarkPolyline::preProcess()
-{
-    //std::cout << "PreProcess: " << std::endl;
-
-    // extract corners of incoming
-    extractPolylines(std::static_pointer_cast<CaptureLaser2D>(incoming_ptr_), polylines_incoming_);
-
-    // compute transformations
-    computeTransformations(incoming_ptr_->getTimeStamp());
-
-    //std::cout << "PreProcess: incoming new features: " << polylines_incoming_.size() << std::endl;
-}
-
-void ProcessorTrackerLandmarkPolyline::computeTransformations(const TimeStamp& _ts)
-{
-    Eigen::Vector3s vehicle_pose = getProblem()->getState(_ts);
-    t_world_robot_ = vehicle_pose.head<2>();
-
-    // world_robot
-    Eigen::Matrix2s R_world_robot = Eigen::Rotation2Ds(vehicle_pose(2)).matrix();
-
-    // robot_sensor (to be computed once if extrinsics are fixed and not dynamic)
-    if (getSensor()->extrinsicsInCaptures() || !getSensor()->getP()->isFixed()
-            || !getSensor()->getO()->isFixed() || !extrinsics_transformation_computed_)
-    {
-        t_robot_sensor_ = getSensor()->getP()->getState();
-        R_robot_sensor_ = Eigen::Rotation2Ds(getSensor()->getO()->getState()(0)).matrix();
-        extrinsics_transformation_computed_ = true;
-    }
-
-    // global_sensor
-    R_world_sensor_ = R_world_robot * R_robot_sensor_;
-    t_world_sensor_ = t_world_robot_ + R_world_robot * t_robot_sensor_;
-
-    // sensor_global
-    R_sensor_world_ = R_robot_sensor_.transpose() * R_world_robot.transpose();
-    t_sensor_world_ = -R_robot_sensor_.transpose() * t_robot_sensor_ -R_sensor_world_ * t_world_robot_ ;
-
-    //std::cout << "t_world_robot_ " << t_world_robot_.transpose() << std::endl;
-    //std::cout << "t_robot_sensor_ " << t_robot_sensor_.transpose() << std::endl;
-    //std::cout << "R_robot_sensor_ " << std::endl << R_robot_sensor_ << std::endl;
-    //std::cout << "t_world_sensor_ " << t_world_sensor_.transpose() << std::endl;
-    //std::cout << "R_world_sensor_ " << std::endl << R_world_sensor_ << std::endl;
-    //std::cout << "t_sensor_world_ " << t_sensor_world_.transpose() << std::endl;
-    //std::cout << "R_sensor_world_ " << std::endl << R_sensor_world_ << std::endl;
-
-}
-
-unsigned int ProcessorTrackerLandmarkPolyline::findLandmarks(const LandmarkBasePtrList& _landmarks_searched,
-                                                           FeatureBasePtrList& _features_found,
-                                                           LandmarkMatchMap& _feature_landmark_correspondences)
-{
-    //std::cout << "ProcessorTrackerLandmarkPolyline::findLandmarks: " << _landmarks_searched.size() << " features: " << polylines_incoming_.size()  << std::endl;
-
-    // COMPUTING ALL EXPECTED FEATURES
-    std::map<LandmarkBasePtr, Eigen::MatrixXs> expected_features;
-    std::map<LandmarkBasePtr, Eigen::MatrixXs> expected_features_covs;
-    for (auto landmark : _landmarks_searched)
-        if (landmark->getType() == "POLYLINE 2D")
-        {
-            expected_features[landmark] = Eigen::MatrixXs(3, (std::static_pointer_cast<LandmarkPolyline2D>(landmark))->getNPoints());
-            expected_features_covs[landmark] = Eigen::MatrixXs(2, 2*(std::static_pointer_cast<LandmarkPolyline2D>(landmark))->getNPoints());
-            expectedFeature(landmark, expected_features[landmark], expected_features_covs[landmark]);
-        }
-
-    // NAIVE NEAREST NEIGHBOR MATCHING
-    LandmarkPolylineMatchPtr best_match = nullptr;
-    FeaturePolyline2DPtr polyline_feature;
-    LandmarkPolyline2DPtr polyline_landmark;
-
-    auto next_feature_it = polylines_incoming_.begin();
-    auto feature_it = next_feature_it++;
-    int max_ftr, max_lmk, max_offset, min_offset, offset, from_ftr, from_lmk, to_ftr, to_lmk, N_overlapped;
-
-    // iterate over all polylines features
-    while (feature_it != polylines_incoming_.end())
-    {
-        polyline_feature = std::static_pointer_cast<FeaturePolyline2D>(*feature_it);
-        max_ftr = polyline_feature->getNPoints() - 1;
-
-        // Check with all landmarks
-        for (auto landmark_it = _landmarks_searched.begin(); landmark_it != _landmarks_searched.end(); landmark_it++)
-        {
-            polyline_landmark = std::static_pointer_cast<LandmarkPolyline2D>(*landmark_it);
-
-            // Open landmark polyline
-            if (!polyline_landmark->isClosed())
-            {
-                //std::cout << "MATCHING WITH OPEN LANDMARK" << std::endl;
-                //std::cout << "\tfeature  " << polyline_feature->id() << ": 0-" << max_ftr << std::endl;
-                //std::cout << "\tlandmark " << polyline_landmark->id() << ": 0-" << polyline_landmark->getNPoints() - 1 << std::endl;
-                max_lmk = polyline_landmark->getNPoints() - 1;
-                max_offset = max_ftr;
-                min_offset = -max_lmk;
-
-                // Check all overlapping positions between each feature-landmark pair
-                for (offset = min_offset; offset <= max_offset; offset++)
-                {
-                    if (offset == min_offset && !polyline_landmark->isLastDefined() && !polyline_feature->isFirstDefined())
-                        continue;
-
-                    if (offset == max_offset && !polyline_landmark->isFirstDefined() && !polyline_feature->isLastDefined())
-                        continue;
-
-                    from_lmk = std::max(0, -offset);
-                    from_ftr = std::max(0, offset);
-                    N_overlapped = std::min(max_ftr - from_ftr, max_lmk - from_lmk)+1;
-                    to_lmk = from_lmk+N_overlapped-1;
-                    to_ftr = from_ftr+N_overlapped-1;
-
-                    //std::cout << "\t\toffset " << offset << std::endl;
-                    //std::cout << "\t\t\tfrom_lmk " << from_lmk << std::endl;
-                    //std::cout << "\t\t\tfrom_ftr " << from_ftr << std::endl;
-                    //std::cout << "\t\t\tN_overlapped " << N_overlapped << std::endl;
-
-                    // Compute the squared distance for all overlapped points
-                    Eigen::ArrayXXd d = (polyline_feature->getPoints().block(0,from_ftr, 2,N_overlapped) -
-                                         expected_features[*landmark_it].block(0,from_lmk, 2, N_overlapped)).array();
-
-                    Eigen::ArrayXd dist2 = d.row(0).pow(2) + d.row(1).pow(2);
-                    //std::cout << "\t\t\tsquared distances = " << dist2.transpose() << std::endl;
-
-                    if (offset != min_offset && offset != max_offset)
-                    {
-                        // Point-to-line first distance
-                        bool from_ftr_not_defined = (from_ftr == 0 && !polyline_feature->isFirstDefined());
-                        bool from_lmk_not_defined = (from_lmk == 0 && !polyline_landmark->isFirstDefined());
-                        //std::cout << "\t\tfrom_ftr_not_defined " << from_ftr_not_defined << (from_ftr == 0) << !polyline_feature->isFirstDefined() << std::endl;
-                        //std::cout << "\t\tfrom_lmk_not_defined " << from_lmk_not_defined << (from_lmk == 0) << !polyline_landmark->isFirstDefined() << std::endl;
-                        if (from_ftr_not_defined || from_lmk_not_defined)
-                        {
-                            //std::cout << "\t\t\tFirst feature not defined distance to line" << std::endl;
-                            //std::cout << "\t\t\tA" << expected_features[*landmark_it].col(from_lmk).transpose() << std::endl;
-                            //std::cout << "\t\t\tAaux" << expected_features[*landmark_it].col(from_lmk+1).transpose() << std::endl;
-                            //std::cout << "\t\t\tB" << polyline_feature->getPoints().col(from_ftr).transpose() << std::endl;
-                            dist2(0) = sqDistPointToLine(expected_features[*landmark_it].col(from_lmk),
-                                                         expected_features[*landmark_it].col(from_lmk+1),
-                                                         polyline_feature->getPoints().col(from_ftr),
-                                                         !from_lmk_not_defined,
-                                                         !from_ftr_not_defined);
-                        }
-
-                        // Point-to-line last distance
-                        bool last_ftr_not_defined = !polyline_feature->isLastDefined() && to_ftr == max_ftr;
-                        bool last_lmk_not_defined = !polyline_landmark->isLastDefined() && to_lmk == max_lmk;
-                        //std::cout << "\t\tlast_ftr_not_defined " << last_ftr_not_defined << (to_ftr == max_ftr) << !polyline_feature->isLastDefined() << std::endl;
-                        //std::cout << "\t\tlast_lmk_not_defined " << last_lmk_not_defined << (to_lmk == max_lmk) << !polyline_landmark->isLastDefined() << std::endl;
-                        if (last_ftr_not_defined || last_lmk_not_defined)
-                        {
-                            //std::cout << "\t\t\tLast feature not defined distance to line" << std::endl;
-                            //std::cout << "\t\t\tA" << expected_features[*landmark_it].col(to_lmk).transpose() << std::endl;
-                            //std::cout << "\t\t\tAaux" << expected_features[*landmark_it].col(to_lmk-1).transpose() << std::endl;
-                            //std::cout << "\t\t\tB" << polyline_feature->getPoints().col(to_ftr).transpose() << std::endl;
-                            dist2(N_overlapped-1) = sqDistPointToLine(expected_features[*landmark_it].col(to_lmk),
-                                                                      expected_features[*landmark_it].col(to_lmk-1),
-                                                                      polyline_feature->getPoints().col(to_ftr),
-                                                                      !last_lmk_not_defined,
-                                                                      !last_ftr_not_defined);
-                        }
-                    }
-                    //std::cout << "\t\t\tsquared distances = " << dist2.transpose() << std::endl;
-
-                    // All squared distances should be witin a threshold
-                    // Choose the most overlapped one
-                    if ((dist2 < params_->position_error_th*params_->position_error_th).all() && (best_match == nullptr ||
-                                                                                  (N_overlapped >= best_match->feature_match_to_id_-best_match->feature_match_from_id_+1 &&
-                                                                                   dist2.mean() < best_match->normalized_score_ )))
-                    {
-                        //std::cout << "BEST MATCH" << std::endl;
-                        best_match = std::make_shared<LandmarkPolylineMatch>();
-                        best_match->feature_match_from_id_= from_ftr;
-                        best_match->landmark_match_from_id_= from_lmk+polyline_landmark->getFirstId();
-                        best_match->feature_match_to_id_= from_ftr+N_overlapped-1;
-                        best_match->landmark_match_to_id_= from_lmk+N_overlapped-1+polyline_landmark->getFirstId();
-                        best_match->landmark_ptr_=polyline_landmark;
-                        best_match->normalized_score_ = dist2.mean();
-                    }
-                }
-            }
-            // Closed landmark polyline
-            else
-            {
-                if (polyline_feature->getNPoints() > polyline_landmark->getNPoints())
-                    continue;
-
-                //std::cout << "MATCHING WITH CLOSED LANDMARK" << std::endl;
-                //std::cout << "\tfeature  " << polyline_feature->id() << ": 0-" << max_ftr << std::endl;
-                //std::cout << "\tlandmark " << polyline_landmark->id() << ": 0-" << polyline_landmark->getNPoints() - 1 << std::endl;
-
-                max_offset = 0;
-                min_offset = -polyline_landmark->getNPoints() + 1;
-
-                // Check all overlapping positions between each feature-landmark pair
-                for (offset = min_offset; offset <= max_offset; offset++)
-                {
-                    from_lmk = -offset;
-                    to_lmk = from_lmk+polyline_feature->getNPoints()-1;
-                    if (to_lmk >= polyline_landmark->getNPoints())
-                        to_lmk -= polyline_landmark->getNPoints();
-
-                    //std::cout << "\t\toffset " << offset << std::endl;
-                    //std::cout << "\t\t\tfrom_lmk " << from_lmk << std::endl;
-                    //std::cout << "\t\t\tto_lmk " << to_lmk << std::endl;
-
-                    // Compute the squared distance for all overlapped points
-                    Eigen::ArrayXXd d = polyline_feature->getPoints().topRows(2).array();
-                    if (to_lmk > from_lmk)
-                        d -= expected_features[*landmark_it].block(0,from_lmk, 2, polyline_feature->getNPoints()).array();
-                    else
-                    {
-                        d.leftCols(polyline_landmark->getNPoints()-from_lmk) -= expected_features[*landmark_it].block(0,from_lmk, 2, polyline_landmark->getNPoints()-from_lmk).array();
-                        d.rightCols(to_lmk+1) -= expected_features[*landmark_it].block(0, 0, 2, to_lmk+1).array();
-                    }
-                    Eigen::ArrayXd dist2 = d.row(0).pow(2) + d.row(1).pow(2);
-                    //std::cout << "\t\t\tsquared distances = " << dist2.transpose() << std::endl;
-
-                    // Point-to-line first distance
-                    if (!polyline_feature->isFirstDefined())
-                    {
-                        int next_from_lmk = (from_lmk+1 == polyline_landmark->getNPoints() ? 0 : from_lmk+1);
-                        dist2(0) = sqDistPointToLine(expected_features[*landmark_it].col(from_lmk),
-                                                     expected_features[*landmark_it].col(next_from_lmk),
-                                                     polyline_feature->getPoints().col(0),
-                                                     true,
-                                                     false);
-                    }
-
-                    // Point-to-line last distance
-                    if (!polyline_feature->isLastDefined())
-                    {
-                        int prev_to_lmk = (to_lmk == 0 ? polyline_landmark->getNPoints()-1 : to_lmk-1);
-                        dist2(polyline_feature->getNPoints()-1) = sqDistPointToLine(expected_features[*landmark_it].col(to_lmk),
-                                                                                    expected_features[*landmark_it].col(prev_to_lmk),
-                                                                                    polyline_feature->getPoints().col(polyline_feature->getNPoints()-1),
-                                                                                    true,
-                                                                                    false);
-                    }
-                    //std::cout << "\t\t\tsquared distances = " << dist2.transpose() << std::endl;
-
-                    // All squared distances should be witin a threshold
-                    // Choose the most overlapped one
-                    if ((dist2 < params_->position_error_th*params_->position_error_th).all() && (best_match == nullptr || dist2.mean() < best_match->normalized_score_ ))
-                    {
-                        //std::cout << "BEST MATCH" << std::endl;
-                        best_match = std::make_shared<LandmarkPolylineMatch>();
-                        best_match->feature_match_from_id_= 0;
-                        best_match->landmark_match_from_id_= from_lmk+polyline_landmark->getFirstId();
-                        best_match->feature_match_to_id_= polyline_feature->getNPoints()-1;
-                        best_match->landmark_match_to_id_= to_lmk+polyline_landmark->getFirstId();
-                        best_match->landmark_ptr_=polyline_landmark;
-                        best_match->normalized_score_ = dist2.mean();
-                    }
-                }
-            }
-
-            //std::cout << "landmark " << (*landmark_it)->id() << ": 0-" << max_lmk << " - defined " << polyline_landmark->isFirstDefined() << polyline_landmark->isLastDefined() << std::endl;
-            //std::cout << "feature " << (*feature_it)->id() << ": 0-" << max_ftr << " - defined " << polyline_feature->isFirstDefined() << polyline_feature->isLastDefined() << std::endl;
-            //std::cout << expected_features[*landmark_it] << std::endl;
-            //std::cout << "\tmax_offset " << max_offset << std::endl;
-            //std::cout << "\tmin_offset " << min_offset << std::endl;
-            //if (!polyline_landmark->isFirstDefined() && !polyline_feature->isLastDefined())
-            //    std::cout << "\tLIMITED max offset " << max_offset << std::endl;
-            //if (!polyline_feature->isFirstDefined() && !polyline_landmark->isLastDefined())
-            //    std::cout << "\tLIMITED min offset " << min_offset << std::endl;
-
-        }
-        // Match found for this feature
-        if (best_match != nullptr)
-        {
-            //std::cout << "\tclosest landmark: " << best_match->landmark_ptr_->id() << std::endl;
-            // match
-            matches_landmark_from_incoming_[*feature_it] = best_match;
-            // move corner feature to output list
-            _features_found.splice(_features_found.end(), polylines_incoming_, feature_it);
-            // reset match
-            best_match = nullptr;
-        }
-        //else
-        //{
-        //    std::cout << "\t-------------------------->NO LANDMARK CLOSE ENOUGH!!!!" << std::endl;
-        //    std::getchar();
-        //}
-        feature_it = next_feature_it++;
-    }
-    return matches_landmark_from_incoming_.size();
-}
-
-bool ProcessorTrackerLandmarkPolyline::voteForKeyFrame()
-{
-    //std::cout << "------------- ProcessorTrackerLandmarkPolyline::voteForKeyFrame:" << std::endl;
-    //std::cout << "polylines_last_.size():" << polylines_last_.size()<< std::endl;
-    // option 1: more than TH new features in last
-    if (polylines_last_.size() >= params_->new_features_th)
-    {
-        std::cout << "------------- NEW KEY FRAME: Option 1 - Enough new features" << std::endl;
-        //std::cout << "\tnew features in last = " << corners_last_.size() << std::endl;
-        return true;
-    }
-    // option 2: loop closure (if the newest frame from which a matched landmark was observed is old enough)
-    for (auto new_ftr : new_features_last_)
-    {
-        if (last_ptr_->getFrame()->id() - matches_landmark_from_last_[new_ftr]->landmark_ptr_->getConstrainedByList().back()->getCapture()->getFrame()->id() > params_->loop_frames_th)
-        {
-            std::cout << "------------- NEW KEY FRAME: Option 2 - Loop closure" << std::endl;
-            return true;
-        }
-    }
-    return false;
-}
-
-void ProcessorTrackerLandmarkPolyline::extractPolylines(CaptureLaser2DPtr _capture_laser_ptr,
-                                                        FeatureBasePtrList& _polyline_list)
-{
-    //std::cout << "ProcessorTrackerLandmarkPolyline::extractPolylines: " << std::endl;
-    // TODO: sort corners by bearing
-    std::list<laserscanutils::Polyline> polylines;
-
-    line_finder_.findPolylines(_capture_laser_ptr->getScan(), (std::static_pointer_cast<SensorLaser2D>(getSensor()))->getScanParams(), polylines);
-
-    for (auto&& pl : polylines)
-    {
-        //std::cout << "new polyline detected: Defined" << pl.first_defined_ << pl.last_defined_ << std::endl;
-        //std::cout << "covs: " << std::endl << pl.covs_ << std::endl;
-        _polyline_list.push_back(std::make_shared<FeaturePolyline2D>(pl.points_, pl.covs_, pl.first_defined_, pl.last_defined_));
-        //std::cout << "new polyline detected: " << std::endl;
-    }
-    //std::cout << _polyline_list.size() << " polylines extracted" << std::endl;
-}
-
-void ProcessorTrackerLandmarkPolyline::expectedFeature(LandmarkBasePtr _landmark_ptr, Eigen::MatrixXs& expected_feature_,
-                                                   Eigen::MatrixXs& expected_feature_cov_)
-{
-    assert(_landmark_ptr->getType() == "POLYLINE 2D" && "ProcessorTrackerLandmarkPolyline::expectedFeature: Bad landmark type");
-    LandmarkPolyline2DPtr polyline_landmark = std::static_pointer_cast<LandmarkPolyline2D>(_landmark_ptr);
-    assert(expected_feature_.cols() == polyline_landmark->getNPoints() && expected_feature_.rows() == 3 && "ProcessorTrackerLandmarkPolyline::expectedFeature: bad expected_feature_ sizes");
-
-    //std::cout << "ProcessorTrackerLandmarkPolyline::expectedFeature" << std::endl;
-    //std::cout << "t_world_sensor_: " << t_world_sensor_.transpose() << std::endl;
-    //std::cout << "R_sensor_world_: "  << std::endl << R_sensor_world_ << std::endl;
-
-    expected_feature_ = Eigen::MatrixXs::Zero(3,polyline_landmark->getNPoints());
-    expected_feature_cov_ = Eigen::MatrixXs::Zero(2,2*polyline_landmark->getNPoints());
-    Eigen::Vector3s col = Eigen::Vector3s::Ones();
-
-    ////////// global coordinates points
-    if (polyline_landmark->getClassification() == UNCLASSIFIED)
-        for (auto i = 0; i < polyline_landmark->getNPoints(); i++)
-        {
-            //std::cout << "Point " << i+polyline_landmark->getFirstId() << std::endl;
-            //std::cout << "First Point " << polyline_landmark->getFirstId() << std::endl;
-            //std::cout << "Landmark global position: " << polyline_landmark->getPointVector(i+polyline_landmark->getFirstId()).transpose() << std::endl;
-
-            // ------------ expected feature point
-            col.head<2>() = R_sensor_world_ * (polyline_landmark->getPointVector(i+polyline_landmark->getFirstId()) - t_world_sensor_);
-            expected_feature_.col(i) = col;
-
-            //std::cout << "Expected point " << i << ": " << expected_feature_.col(i).transpose() << std::endl;
-            // ------------ expected feature point covariance
-            // TODO
-            expected_feature_cov_.middleCols(i*2, 2) = Eigen::MatrixXs::Identity(2,2);
-        }
-
-    ////////// landmark with origin
-    else
-    {
-        Eigen::Matrix2s R_world_points = Eigen::Rotation2Ds(polyline_landmark->getO()->getState()(0)).matrix();
-        const Eigen::VectorXs& t_world_points = polyline_landmark->getP()->getState();
-
-        for (auto i = 0; i < polyline_landmark->getNPoints(); i++)
-        {
-            //std::cout << "Point " << i+polyline_landmark->getFirstId() << std::endl;
-            //std::cout << "First Point " << polyline_landmark->getFirstId() << std::endl;
-            //std::cout << "Landmark global position: " << polyline_landmark->getPointVector(i+polyline_landmark->getFirstId()).transpose() << std::endl;
-
-            // ------------ expected feature point
-            col.head<2>() = R_sensor_world_ * (R_world_points * polyline_landmark->getPointVector(i+polyline_landmark->getFirstId()) + t_world_points - t_world_sensor_);
-            expected_feature_.col(i) = col;
-
-            //std::cout << "Expected point " << i << ": " << expected_feature_.col(i).transpose() << std::endl;
-            // ------------ expected feature point covariance
-            // TODO
-            expected_feature_cov_.middleCols(i*2, 2) = Eigen::MatrixXs::Identity(2,2);
-        }
-    }
-}
-
-Eigen::VectorXs ProcessorTrackerLandmarkPolyline::computeSquaredMahalanobisDistances(const Eigen::Vector2s& _feature,
-                                                                                     const Eigen::Matrix2s& _feature_cov,
-                                                                                     const Eigen::Vector2s& _expected_feature,
-                                                                                     const Eigen::Matrix2s& _expected_feature_cov,
-                                                                                     const Eigen::MatrixXs& _mu)
-{
-    // ------------------------ d
-    Eigen::Vector2s d = _feature - _expected_feature;
-
-    // ------------------------ Sigma_d
-    Eigen::Matrix2s iSigma_d = (_feature_cov + _expected_feature_cov).inverse();
-    Eigen::VectorXs squared_mahalanobis_distances(_mu.cols());
-    for (unsigned int i = 0; i < _mu.cols(); i++)
-    {
-        squared_mahalanobis_distances(i) = (d - _mu.col(i)).transpose() * iSigma_d * (d - _mu.col(i));
-        //if ((d - _mu.col(i)).norm() < 1)
-        //{
-        //    std::cout << "distance:    " << (d - _mu.col(i)).norm() << std::endl;
-        //    std::cout << "iSigma_d:    " << std::endl << iSigma_d << std::endl;
-        //    std::cout << "mahalanobis: " << squared_mahalanobis_distances(i) << std::endl;
-        //}
-    }
-
-    return squared_mahalanobis_distances;
-}
-
-Scalar ProcessorTrackerLandmarkPolyline::sqDistPointToLine(const Eigen::Vector3s& _A, const Eigen::Vector3s& _A_aux,
-                                                         const Eigen::Vector3s& _B, bool _A_defined, bool _B_defined)
-{
-    /* Squared distance from B to the line A_aux-A (match evaluated is A-B)
-     *
-     * No matter if A_aux is defined or not.
-     *
-     * Case 1: B not defined
-     *
-     *      The projection of B over the line AAaux must be in [A_aux, inf(in A direction)). Otherwise, return squared distance Aaux-B.
-     *      Check: the angle BAauxA is <= 90º:
-     *          (BA)² <= (BAaux)² + (AAaux)²
-     *
-     *      Case 1.1: A not defined
-     *
-     *          No more restrictions: return distance line to point.
-     *
-     *      Case 1.2: A defined
-     *
-     *          The projection of B over the line AAaux must be in (inf(in Aaux direction), A]. Otherwise, return squared distance A-B.
-     *          Additional check: the angle BAAaux is <= 90º:
-     *              (BAaux)² <= (BA)² + (AAaux)²
-     *
-     * Case 2: B is defined and A is not
-     *
-     *      Returns the distance B-Line if the projection of B to the line is in [A, inf). Otherwise, return squared distance A-B.
-     *      Checks if the angle BAAaux is >=  90º: (BAaux)² >= (BA)² + (AAaux)²
-     *
-     * ( Case B and A are defined is not point-to-line, is point to point -> assertion )
-     *
-     */
-
-    assert((!_A_defined || !_B_defined) && "ProcessorTrackerLandmarkPolyline::sqDistPointToLine: at least one point must not be defined.");
-
-    Scalar AB_sq = (_B-_A).head<2>().squaredNorm();
-    Scalar AauxB_sq = (_B-_A_aux).head<2>().squaredNorm();
-    Scalar AAaux_sq = (_A_aux-_A).head<2>().squaredNorm();
-
-    // Case 1
-    if (!_B_defined)
-    {
-        if (AB_sq <= AauxB_sq + AAaux_sq)
-        {
-            // Case 1.1
-            if (!_A_defined)
-                return AB_sq - std::pow(((_A_aux-_A).head<2>()).dot((_B-_A).head<2>()),2) / AAaux_sq; //squared distance to line
-            // Case 1.2
-            else if (AauxB_sq <= AB_sq + AAaux_sq)
-                return AB_sq - std::pow(((_A_aux-_A).head<2>()).dot((_B-_A).head<2>()),2) / AAaux_sq; //squared distance to line
-        }
-    }
-    // Case 2
-    else if (!_A_defined && _B_defined)
-        if (AauxB_sq >= AB_sq + AAaux_sq)
-            return AB_sq - std::pow(((_A_aux-_A).head<2>()).dot((_B-_A).head<2>()),2) / AAaux_sq; //squared distance to line
-
-    // Default return A-B squared distance
-    return (_A.head<2>() - _B.head<2>()).squaredNorm();
-}
-
-void ProcessorTrackerLandmarkPolyline::createNewLandmarks()
-{
-    //std::cout << "ProcessorTrackerLandmarkPolyline::createNewLandmarks" << std::endl;
-    FeaturePolyline2DPtr polyline_ft_ptr;
-    LandmarkBasePtr new_lmk_ptr;
-    for (auto new_feature_ptr : new_features_last_)
-    {
-        // create new landmark
-        new_lmk_ptr = createLandmark(new_feature_ptr);
-        //std::cout << "\tfeature: " << new_feature_ptr->id() << std::endl;
-        //std::cout << "\tnew_landmark: " << new_lmk_ptr->id() << ": "<< ((LandmarkPolyline2D*)new_lmk_ptr)->getNPoints() << " points" << std::endl;
-        new_landmarks_.push_back(new_lmk_ptr);
-        // cast
-        polyline_ft_ptr = std::static_pointer_cast<FeaturePolyline2D>(new_feature_ptr);
-        // create new correspondence
-        LandmarkPolylineMatchPtr match = std::make_shared<LandmarkPolylineMatch>();
-        match->feature_match_from_id_= 0; // all points match
-        match->landmark_match_from_id_ = 0;
-        match->feature_match_to_id_= polyline_ft_ptr->getNPoints()-1; // all points match
-        match->landmark_match_to_id_ = polyline_ft_ptr->getNPoints()-1;
-        match->normalized_score_ = 1.0; // max score
-        match->landmark_ptr_ = new_lmk_ptr;
-        matches_landmark_from_last_[new_feature_ptr] = match;
-    }
-}
-
-LandmarkBasePtr ProcessorTrackerLandmarkPolyline::createLandmark(FeatureBasePtr _feature_ptr)
-{
-    assert(_feature_ptr->getType() == "POLYLINE 2D");
-    //std::cout << "ProcessorTrackerLandmarkPolyline::createLandmark" << std::endl;
-    //std::cout << "Robot global pose: " << t_world_robot_.transpose() << std::endl;
-    //std::cout << "Sensor global pose: " << t_world_sensor_.transpose() << std::endl;
-
-    FeaturePolyline2DPtr polyline_ptr = std::static_pointer_cast<FeaturePolyline2D>(_feature_ptr);
-    // compute feature global pose
-    Eigen::MatrixXs points_global = R_world_sensor_ * polyline_ptr->getPoints().topRows<2>() +
-                                    t_world_sensor_ * 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;
-
-    // Create new landmark
-    return std::make_shared<LandmarkPolyline2D>(std::make_shared<StateBlock>(Eigen::Vector2s::Zero(), true), std::make_shared<StateBlock>(Eigen::Vector1s::Zero(), true), points_global, polyline_ptr->isFirstDefined(), polyline_ptr->isLastDefined());
-}
-
-ProcessorTrackerLandmarkPolyline::~ProcessorTrackerLandmarkPolyline()
-{
-    while (!polylines_last_.empty())
-    {
-        polylines_last_.front()->remove();
-        polylines_last_.pop_front(); // TODO see if this is needed
-    }
-    while (!polylines_incoming_.empty())
-    {
-        polylines_incoming_.front()->remove();
-        polylines_incoming_.pop_front(); // TODO see if this is needed
-    }
-}
-
-void ProcessorTrackerLandmarkPolyline::establishFactors()
-{
-	//TODO: update with new index in landmarks
-
-    //std::cout << "ProcessorTrackerLandmarkPolyline::establishFactors" << std::endl;
-    LandmarkPolylineMatchPtr polyline_match;
-    FeaturePolyline2DPtr polyline_feature;
-    LandmarkPolyline2DPtr polyline_landmark;
-
-    for (auto last_feature : last_ptr_->getFeatureList())
-    {
-        polyline_feature = std::static_pointer_cast<FeaturePolyline2D>(last_feature);
-        polyline_match = std::static_pointer_cast<LandmarkPolylineMatch>(matches_landmark_from_last_[last_feature]);
-        polyline_landmark = std::static_pointer_cast<LandmarkPolyline2D>(polyline_match->landmark_ptr_);
-
-        assert(polyline_landmark != nullptr && polyline_match != nullptr);
-
-        // Modify landmark (only for not closed)
-        if (!polyline_landmark->isClosed())
-        {
-            //std::cout << std::endl << "MODIFY LANDMARK" << std::endl;
-            //std::cout << "feature " << polyline_feature->id() << ": " << std::endl;
-            //std::cout << "\tpoints " << polyline_feature->getNPoints() << std::endl;
-            //std::cout << "\tfirst defined " << polyline_feature->isFirstDefined() << std::endl;
-            //std::cout << "\tlast defined " << polyline_feature->isLastDefined() << std::endl;
-            //std::cout << "landmark " << polyline_landmark->id() << ": " << std::endl;
-            //std::cout << "\tpoints " << polyline_landmark->getNPoints() << std::endl;
-            //std::cout << "\tfirst defined " << polyline_landmark->isFirstDefined() << std::endl;
-            //std::cout << "\tlast defined " << polyline_landmark->isLastDefined() << std::endl << std::endl;
-            //std::cout << "\tmatch from feature point " << polyline_match->feature_match_from_id_ << std::endl;
-            //std::cout << "\tmatch to feature point " << polyline_match->feature_match_to_id_ << std::endl;
-            //std::cout << "\tmatch from landmark point " << polyline_match->landmark_match_from_id_ << std::endl;
-            //std::cout << "\tmatch to landmark point " << polyline_match->landmark_match_to_id_ << std::endl;
-
-            Eigen::MatrixXs points_global = R_world_sensor_ * polyline_feature->getPoints().topRows<2>() +
-                                            t_world_sensor_ * Eigen::VectorXs::Ones(polyline_feature->getNPoints()).transpose();
-            // GROW/CLOSE LANDMARK
-            // -----------------Front-----------------
-            bool check_front_closing = // Sufficient conditions
-                                       // condition 1: feature first defined point not matched
-                                       (polyline_feature->isFirstDefined() && polyline_match->feature_match_from_id_ > 0) ||
-                                       // condition 2: feature second point not matched
-                                       (polyline_match->feature_match_from_id_ > 1) ||
-                                       // condition 3: matched front points but feature front point defined and landmark front point not defined
-                                       (polyline_match->landmark_match_from_id_ == polyline_landmark->getFirstId() && polyline_feature->isFirstDefined() && !polyline_landmark->isFirstDefined());
-
-            // Check closing with landmark's last points
-            if (check_front_closing)
-            {
-                //std::cout << "---------------- Trying to close polyline..." << std::endl;
-                //std::cout << "feature " << polyline_feature->id() << ": " << std::endl;
-                //std::cout << "\tpoints " << polyline_feature->getNPoints() << std::endl;
-                //std::cout << "\tfirst defined " << polyline_feature->isFirstDefined() << std::endl;
-                //std::cout << "\tlast defined " << polyline_feature->isLastDefined() << std::endl;
-                //std::cout << "\tmatch from feature point " << polyline_match->feature_match_from_id_ << std::endl;
-                //std::cout << "\tmatch to feature point " << polyline_match->feature_match_to_id_ << std::endl;
-                //std::cout << "landmark " << polyline_landmark->id() << ": " << std::endl;
-                //std::cout << "\tpoints " << polyline_landmark->getNPoints() << std::endl;
-                //std::cout << "\tfirst defined " << polyline_landmark->isFirstDefined() << std::endl;
-                //std::cout << "\tlast defined " << polyline_landmark->isLastDefined() << std::endl << std::endl;
-                //std::cout << "\tmatch from landmark point " << polyline_match->landmark_match_from_id_ << std::endl;
-                //std::cout << "\tmatch to landmark point " << polyline_match->landmark_match_to_id_ << std::endl;
-
-                int feat_point_id_matching = polyline_feature->isFirstDefined() ? 0 : 1;
-                int lmk_last_defined_point = polyline_landmark->getLastId() - (polyline_landmark->isLastDefined() ? 0 : 1);
-                //std::cout << std::endl << "\tfeat point matching " << feat_point_id_matching << std::endl;
-                //std::cout << std::endl << "\tlmk last defined point " << lmk_last_defined_point << std::endl;
-
-                for (int id_lmk = lmk_last_defined_point; id_lmk > polyline_match->landmark_match_to_id_; id_lmk--)
-                {
-                    //std::cout << "\t\tid_lmk " << id_lmk << std::endl;
-                    //std::cout << "\t\td2 = " << (points_global.col(feat_point_id_matching)-polyline_landmark->getPointVector(id_lmk)).squaredNorm() << " (th = " << params_->position_error_th*params_->position_error_th << std::endl;
-
-                    if ((points_global.col(feat_point_id_matching)-polyline_landmark->getPointVector(id_lmk)).squaredNorm() < params_->position_error_th*params_->position_error_th)
-                    {
-                        std::cout << "CLOSING POLYLINE" << std::endl;
-
-                        unsigned int N_back_overlapped = polyline_landmark->getLastId() - id_lmk + 1;
-                        int N_feature_new_points = polyline_match->feature_match_from_id_ - feat_point_id_matching - N_back_overlapped;
-
-                        // define first point (if not defined and no points have to be merged)
-                        if (!polyline_landmark->isFirstDefined() && N_feature_new_points >= 0)
-                            polyline_landmark->setFirst(points_global.col(polyline_match->feature_match_from_id_), true);
-
-                        // add other points (if there are)
-                        if (N_feature_new_points > 0)
-                            polyline_landmark->addPoints(points_global.middleCols(feat_point_id_matching + N_back_overlapped, N_feature_new_points), // points matrix in global coordinates
-                                                         N_feature_new_points-1, // last index to be added
-                                                         true, // defined
-                                                         false); // front (!back)
-
-                        // define last point (if not defined and no points have to be merged)
-                        if (!polyline_landmark->isLastDefined() && N_feature_new_points >= 0)
-                            polyline_landmark->setLast(points_global.col(feat_point_id_matching + N_back_overlapped - 1), true);
-
-                        // close landmark
-                        polyline_landmark->setClosed();
-
-                        polyline_match->landmark_match_from_id_ = id_lmk - (polyline_feature->isFirstDefined() ? 0 : 1);
-                        polyline_match->feature_match_from_id_ = 0;
-                        break;
-                    }
-                }
-            }
-            // Add new front points (if not matched feature points)
-            if (polyline_match->feature_match_from_id_ > 0) // && !polyline_landmark->isClosed()
-            {
-                assert(!polyline_landmark->isClosed() && "feature not matched points in a closed landmark");
-                //std::cout << "Add new front points. Defined: " << polyline_feature->isFirstDefined() << std::endl;
-                //std::cout << "\tfeat from " << polyline_match->feature_match_from_id_ << std::endl;
-                //std::cout << "\tfeat to " << polyline_match->feature_match_to_id_ << std::endl;
-                //std::cout << "\tland from " << polyline_match->landmark_match_from_id_ << std::endl;
-                //std::cout << "\tland to " << polyline_match->landmark_match_to_id_ << std::endl;
-
-                polyline_landmark->addPoints(points_global, // points matrix in global coordinates
-                                             polyline_match->feature_match_from_id_-1, // last feature point index to be added
-                                             polyline_feature->isFirstDefined(), // is defined
-                                             false); // front
-
-                polyline_match->landmark_match_from_id_ = polyline_landmark->getFirstId();
-                polyline_match->feature_match_from_id_ = 0;
-                //std::cout << "\tfeat from " << polyline_match->feature_match_from_id_ << std::endl;
-                //std::cout << "\tfeat to " << polyline_match->feature_match_to_id_ << std::endl;
-                //std::cout << "\tland from " << polyline_match->landmark_match_from_id_ << std::endl;
-                //std::cout << "\tland to " << polyline_match->landmark_match_to_id_ << std::endl;
-            }
-            // Change first point
-            else if (polyline_match->landmark_match_from_id_ == polyline_landmark->getFirstId() && !polyline_landmark->isFirstDefined())
-            {
-                //std::cout << "Change first point. Defined: " << polyline_feature->isFirstDefined() << std::endl;
-                //std::cout << "\tpoint " << polyline_landmark->getFirstId() << ": " << polyline_landmark->getPointVector(polyline_landmark->getFirstId()).transpose() << std::endl;
-                //std::cout << "\tpoint " << polyline_landmark->getFirstId()+1 << ": " << polyline_landmark->getPointVector(polyline_landmark->getFirstId()+1).transpose() << std::endl;
-                //std::cout << "\tfeature point: " << points_global.topLeftCorner(2,1).transpose() << std::endl;
-
-                if (// new defined first
-                    polyline_feature->isFirstDefined() ||
-                    // new not defined first
-                    (points_global.topLeftCorner(2,1)-polyline_landmark->getPointVector(polyline_landmark->getFirstId()+1)).squaredNorm() >
-                    (points_global.topLeftCorner(2,1)-polyline_landmark->getPointVector(polyline_landmark->getFirstId())).squaredNorm() +
-                    (polyline_landmark->getPointVector(polyline_landmark->getFirstId()+1)-polyline_landmark->getPointVector(polyline_landmark->getFirstId())).squaredNorm())
-                    polyline_landmark->setFirst(points_global.leftCols(1), polyline_feature->isFirstDefined());
-
-            }
-            // -----------------Back-----------------
-            bool check_back_closing = // Sufficient conditions
-                                      // condition 1: feature last defined point not matched
-                                      (polyline_feature->isLastDefined() && polyline_match->feature_match_to_id_ < polyline_feature->getNPoints()-1) ||
-                                      // condition 2: feature second last point not matched
-                                      (polyline_match->feature_match_to_id_ < polyline_feature->getNPoints() - 2) ||
-                                      // condition 3: matched back points but feature last point defined and landmark last point not defined
-                                      (polyline_match->landmark_match_to_id_ == polyline_landmark->getLastId() && polyline_feature->isLastDefined() && !polyline_landmark->isLastDefined());
-
-            // Necessary condition: still open landmark
-            check_back_closing = check_back_closing && !polyline_landmark->isClosed();
-
-            // Check closing with landmark's first points
-            if (check_back_closing)
-            {
-                int feat_point_id_matching = polyline_feature->getNPoints() - (polyline_feature->isLastDefined() ? 1 : 2);
-                int lmk_first_defined_point = polyline_landmark->getFirstId() + (polyline_landmark->isFirstDefined() ? 0 : 1);
-                //std::cout << std::endl << "\tfeat point matching " << feat_point_id_matching << std::endl;
-                //std::cout << std::endl << "\tlmk first defined point " << lmk_first_defined_point << std::endl;
-
-                for (int id_lmk = lmk_first_defined_point; id_lmk < polyline_match->landmark_match_from_id_; id_lmk++)
-                {
-                    //std::cout << "\t\tid_lmk " << id_lmk << std::endl;
-                    //std::cout << "\t\td2 = " << (points_global.col(feat_point_id_matching)-polyline_landmark->getPointVector(id_lmk)).squaredNorm() << " (th = " << params_->position_error_th*params_->position_error_th << std::endl;
-
-                    if ((points_global.col(feat_point_id_matching)-polyline_landmark->getPointVector(id_lmk)).squaredNorm() < params_->position_error_th*params_->position_error_th)
-                    {
-                        std::cout << "CLOSING POLYLINE" << std::endl;
-
-                        unsigned int N_front_overlapped = id_lmk - polyline_landmark->getFirstId() + 1;
-                        int N_feature_new_points = feat_point_id_matching - polyline_match->feature_match_to_id_ - N_front_overlapped;
-
-                        // define first point (if not defined and no points have to be merged)
-                        if (!polyline_landmark->isFirstDefined() && N_feature_new_points >= 0)
-                            polyline_landmark->setFirst(points_global.col(feat_point_id_matching - N_front_overlapped + 1), true);
-
-                        // add other points (if there are)
-                        if (N_feature_new_points > 0)
-                            polyline_landmark->addPoints(points_global.middleCols(polyline_match->feature_match_to_id_ + 1, N_feature_new_points), // points matrix in global coordinates
-                                                         N_feature_new_points-1, // last index to be added
-                                                         true, // defined
-                                                         false); // front (!back)
-
-                        // define last point (if not defined and no points have to be merged)
-                        if (!polyline_landmark->isLastDefined() && N_feature_new_points >= 0)
-                            polyline_landmark->setLast(points_global.col(polyline_match->feature_match_to_id_), true);
-
-                        // close landmark
-                        polyline_landmark->setClosed();
-
-                        polyline_match->landmark_match_to_id_ = id_lmk + (polyline_feature->isLastDefined() ? 0 : 1);
-                        polyline_match->feature_match_to_id_ = polyline_feature->getNPoints() - 1;
-                        break;
-                    }
-                }
-            }
-            // Add new back points (if it wasn't closed)
-            if (polyline_match->feature_match_to_id_ < polyline_feature->getNPoints()-1)
-            {
-                assert(!polyline_landmark->isClosed() && "feature not matched points in a closed landmark");
-                //std::cout << "Add back points. Defined: " << polyline_feature->isLastDefined() << std::endl;
-                //std::cout << "\tfeat from " << polyline_match->feature_match_from_id_ << std::endl;
-                //std::cout << "\tfeat to " << polyline_match->feature_match_to_id_ << std::endl;
-                //std::cout << "\tland from " << polyline_match->landmark_match_from_id_ << std::endl;
-                //std::cout << "\tland to " << polyline_match->landmark_match_to_id_ << std::endl;
-
-                polyline_landmark->addPoints(points_global, // points matrix in global coordinates
-                                             polyline_match->feature_match_to_id_+1, // last feature point index to be added
-                                             polyline_feature->isLastDefined(), // is defined
-                                             true); // back
-
-                polyline_match->landmark_match_to_id_ = polyline_landmark->getLastId();
-                polyline_match->feature_match_to_id_ = polyline_feature->getNPoints()-1;
-                //std::cout << "\tfeat from " << polyline_match->feature_match_from_id_ << std::endl;
-                //std::cout << "\tfeat to " << polyline_match->feature_match_to_id_ << std::endl;
-                //std::cout << "\tland from " << polyline_match->landmark_match_from_id_ << std::endl;
-                //std::cout << "\tland to " << polyline_match->landmark_match_to_id_ << std::endl;
-            }
-            // Change last point
-            else if (polyline_match->landmark_match_to_id_ == polyline_landmark->getLastId() && !polyline_landmark->isLastDefined()) //&& polyline_match->feature_match_to_id_ == polyline_feature->getNPoints()-1
-            {
-                //std::cout << "Change last point. Defined: " << (polyline_feature->isLastDefined() ? 1 : 0) << std::endl;
-                //std::cout << "\tpoint " << polyline_landmark->getLastId() << ": " << polyline_landmark->getPointVector(polyline_landmark->getLastId()).transpose() << std::endl;
-                //std::cout << "\tpoint " << polyline_landmark->getLastId()-1 << ": " << polyline_landmark->getPointVector(polyline_landmark->getLastId()-1).transpose() << std::endl;
-                //std::cout << "\tfeature point: " << points_global.topRightCorner(2,1).transpose() << std::endl;
-                if (// new defined last
-                    polyline_feature->isLastDefined() ||
-                    // new not defined last
-                    (points_global.topRightCorner(2,1)-polyline_landmark->getPointVector(polyline_landmark->getLastId()-1)).squaredNorm() >
-                    (points_global.topRightCorner(2,1)-polyline_landmark->getPointVector(polyline_landmark->getLastId())).squaredNorm() +
-                    (polyline_landmark->getPointVector(polyline_landmark->getLastId()-1)-polyline_landmark->getPointVector(polyline_landmark->getLastId())).squaredNorm())
-                    polyline_landmark->setLast(points_global.rightCols(1), polyline_feature->isLastDefined());
-            }
-
-            //std::cout << "MODIFIED LANDMARK" << std::endl;
-            //std::cout << "feature " << polyline_feature->id() << ": " << std::endl;
-            //std::cout << "\tpoints " << polyline_feature->getNPoints() << std::endl;
-            //std::cout << "\tfirst defined " << polyline_feature->isFirstDefined() << std::endl;
-            //std::cout << "\tlast defined " << polyline_feature->isLastDefined() << std::endl;
-            //std::cout << "landmark " << polyline_landmark->id() << ": " << std::endl;
-            //std::cout << "\tpoints " << polyline_landmark->getNPoints() << std::endl;
-            //std::cout << "\tfirst defined " << polyline_landmark->isFirstDefined() << std::endl;
-            //std::cout << "\tlast defined " << polyline_landmark->isLastDefined() << std::endl << std::endl;
-        }
-
-        // ESTABLISH CONSTRAINTS
-        //std::cout << "ESTABLISH CONSTRAINTS" << std::endl;
-        //std::cout << "\tfeature " << polyline_feature->id() << std::endl;
-        //std::cout << "\tlandmark " << polyline_landmark->id() << std::endl;
-        //std::cout << "\tmatch from feature point " << polyline_match->feature_match_from_id_ << std::endl;
-        //std::cout << "\tmatch to feature point " << polyline_match->feature_match_to_id_ << std::endl;
-        //std::cout << "\tmatch from landmark point " << polyline_match->landmark_match_from_id_ << std::endl;
-        //std::cout << "\tmatch to landmark point " << polyline_match->landmark_match_to_id_ << std::endl;
-
-        // Factors for all inner and defined feature points
-        int lmk_point_id = polyline_match->landmark_match_from_id_;
-
-        for (int ftr_point_id = 0; ftr_point_id < polyline_feature->getNPoints(); ftr_point_id++, lmk_point_id++)
-        {
-            if (lmk_point_id > polyline_landmark->getLastId())
-                lmk_point_id -= polyline_landmark->getNPoints();
-            if (lmk_point_id < polyline_landmark->getFirstId())
-                lmk_point_id += polyline_landmark->getNPoints();
-
-            //std::cout << "feature point " << ftr_point_id << std::endl;
-            //std::cout << "landmark point " << lmk_point_id << std::endl;
-
-            // First not defined point
-            if (ftr_point_id == 0 && !polyline_feature->isFirstDefined())
-                // first point to line factor
-            {
-                int lmk_next_point_id = lmk_point_id+1;
-                if (lmk_next_point_id > polyline_landmark->getLastId())
-                    lmk_next_point_id -= polyline_landmark->getNPoints();
-                //std::cout << "point-line: landmark points " << lmk_point_id << ", " << lmk_next_point_id << std::endl;
-                last_feature->addFactor(std::make_shared<FactorPointToLine2D>(polyline_feature, polyline_landmark, shared_from_this(),
-                                                                                      ftr_point_id, lmk_point_id, lmk_next_point_id));
-                //std::cout << "factor added" << std::endl;
-            }
-
-            // Last not defined point
-            else if (ftr_point_id == polyline_feature->getNPoints()-1 && !polyline_feature->isLastDefined())
-                // last point to line factor
-            {
-                int lmk_prev_point_id = lmk_point_id-1;
-                if (lmk_prev_point_id < polyline_landmark->getFirstId())
-                    lmk_prev_point_id += polyline_landmark->getNPoints();
-                //std::cout << "point-line: landmark points " << lmk_point_id << ", " << lmk_prev_point_id << std::endl;
-                last_feature->addFactor(std::make_shared<FactorPointToLine2D>(polyline_feature, polyline_landmark, shared_from_this(),
-                                                                                      ftr_point_id, lmk_point_id, lmk_prev_point_id));
-                //std::cout << "factor added" << std::endl;
-            }
-
-            // Defined point
-            else
-                // point to point factor
-            {
-                //std::cout << "point-point: landmark point " << lmk_point_id << std::endl;
-				//std::cout << "landmark first id:" << polyline_landmark->getFirstId() << std::endl;
-				//std::cout << "landmark last id:" << polyline_landmark->getLastId() << std::endl;
-				//std::cout << "landmark n points:" << polyline_landmark->getNPoints() << std::endl;
-                last_feature->addFactor(std::make_shared<FactorPoint2D>(polyline_feature, polyline_landmark, shared_from_this(),
-                                                                                ftr_point_id, lmk_point_id));
-                //std::cout << "factor added" << std::endl;
-            }
-        }
-        //std::cout << "Factors established" << std::endl;
-    }
-}
-
-void ProcessorTrackerLandmarkPolyline::classifyPolilines(LandmarkBasePtrList& _lmk_list)
-{
-    //std::cout << "ProcessorTrackerLandmarkPolyline::classifyPolilines: " << _lmk_list->size() << std::endl;
-    std::vector<Scalar> object_L({12, 5.9, 1.2});
-    std::vector<Scalar> object_W({2.345, 2.345, 0.9});
-    std::vector<Scalar> object_D({sqrt(12*12+2.345*2.345), sqrt(5.9*5.9+2.345*2.345), sqrt(0.9*0.9+1.2*1.2)});
-    std::vector<LandmarkClassification> object_class({CONTAINER, SMALL_CONTAINER, PALLET});
-
-    for (auto lmk_ptr : _lmk_list)
-        if (lmk_ptr->getType() == "POLYLINE 2D")
-        {
-            LandmarkPolyline2DPtr polyline_ptr = std::static_pointer_cast<LandmarkPolyline2D>(lmk_ptr);
-            auto n_defined_points = polyline_ptr->getNPoints() - (polyline_ptr->isFirstDefined() ? 0 : 1) - (polyline_ptr->isLastDefined() ? 0 : 1);
-            auto A_id = polyline_ptr->getFirstId() + (polyline_ptr->isFirstDefined() ? 0 : 1);
-            auto B_id = A_id + 1;
-            auto C_id = B_id + 1;
-            auto D_id = C_id + 1;
-
-            // necessary conditions
-            if (polyline_ptr->getClassification() != UNCLASSIFIED ||
-                n_defined_points < 3 ||
-                n_defined_points > 4 )
-                continue;
-
-            //std::cout << "landmark " << lmk_ptr->id() << std::endl;
-
-            // consider 3 first defined points
-            Scalar dAB = (polyline_ptr->getPointVector(A_id) - polyline_ptr->getPointVector(B_id)).norm();
-            Scalar dBC = (polyline_ptr->getPointVector(B_id) - polyline_ptr->getPointVector(C_id)).norm();
-            Scalar dAC = (polyline_ptr->getPointVector(A_id) - polyline_ptr->getPointVector(C_id)).norm();
-
-            //std::cout << "dAB = " << dAB << " error 1: " << fabs(dAB-CONT_L) << " error 2: " << fabs(dAB-CONT_W) << std::endl;
-            //std::cout << "dBC = " << dBC << " error 1: " << fabs(dBC-CONT_W) << " error 2: " << fabs(dBC-CONT_L)   << std::endl;
-            //std::cout << "dAC = " << dAC << " error 1&2: " << fabs(dAC-CONT_D) << std::endl;
-
-            auto classification = -1;
-            bool configuration;
-
-            for (unsigned int i = 0; i < object_L.size(); i++)
-            {
-                // check configuration 1
-                if(fabs(dAB-object_L[i]) < params_->position_error_th &&
-                   fabs(dBC-object_W[i]) < params_->position_error_th &&
-                   fabs(dAC-object_D[i]) < params_->position_error_th)
-                {
-                    configuration = true;
-                    classification = i;
-                    break;
-                }
-
-                // check configuration 2
-                if(fabs(dAB-object_W[i]) < params_->position_error_th &&
-                   fabs(dBC-object_L[i]) < params_->position_error_th &&
-                   fabs(dAC-object_D[i]) < params_->position_error_th)
-                {
-                    configuration = false;
-                    classification = i;
-                    break;
-                }
-            }
-
-            // any container position fitted
-            if (classification != -1)
-            {
-                // if 4 defined checking
-                if (n_defined_points == 4)
-                {
-                    //std::cout << "checking with 4th point... " << std::endl;
-
-                    Scalar dAD = (polyline_ptr->getPointVector(A_id) - polyline_ptr->getPointVector(D_id)).norm();
-                    Scalar dBD = (polyline_ptr->getPointVector(B_id) - polyline_ptr->getPointVector(D_id)).norm();
-                    Scalar dCD = (polyline_ptr->getPointVector(C_id) - polyline_ptr->getPointVector(D_id)).norm();
-
-                    // necessary conditions
-                    if (fabs(dAD-dBC) > params_->position_error_th ||
-                        fabs(dBD-dAC) > params_->position_error_th ||
-                        fabs(dCD-dAB) > params_->position_error_th)
-                        continue;
-                }
-
-                // if not 4 defined add/define points
-                else
-                {
-                    //std::cout << "adding/defining points... " << std::endl;
-                    if (!polyline_ptr->isFirstDefined())
-                    {
-                        polyline_ptr->defineExtreme(false);
-                        D_id = polyline_ptr->getFirstId();
-                    }
-                    else if (!polyline_ptr->isLastDefined())
-                        polyline_ptr->defineExtreme(true);
-                    else
-                        polyline_ptr->addPoint(Eigen::Vector2s::Zero(), true, true);
-                }
-                //std::cout << "landmark " << lmk_ptr->id() << " classified as " << object_class[classification] << " in configuration " << configuration << std::endl;
-
-                // Close
-                polyline_ptr->setClosed();
-
-                // Classify
-                polyline_ptr->classify(object_class[classification]);
-
-                // Unfix origin
-                polyline_ptr->getP()->unfix();
-                polyline_ptr->getO()->unfix();
-
-                // Move origin to B
-                polyline_ptr->getP()->setState(polyline_ptr->getPointVector((configuration ? B_id : A_id)));
-                Eigen::Vector2s frame_x = (configuration ? polyline_ptr->getPointVector(A_id)-polyline_ptr->getPointVector(B_id) : polyline_ptr->getPointVector(C_id)-polyline_ptr->getPointVector(B_id));
-                polyline_ptr->getO()->setState(Eigen::Vector1s::Constant(atan2(frame_x(1),frame_x(0))));
-
-                //std::cout << "A: " << polyline_ptr->getPointVector(A_id).transpose() << std::endl;
-                //std::cout << "B: " << polyline_ptr->getPointVector(B_id).transpose() << std::endl;
-                //std::cout << "C: " << polyline_ptr->getPointVector(C_id).transpose() << std::endl;
-                //std::cout << "frame_x:           " << frame_x.transpose() << std::endl;
-                //std::cout << "frame position:    " << polyline_ptr->getP()->getVector().transpose() << std::endl;
-                //std::cout << "frame orientation: " << polyline_ptr->getO()->getVector() << std::endl;
-
-                // Fix polyline points to its respective relative positions
-                if (configuration)
-                {
-                    polyline_ptr->getPointStateBlock(A_id)->setState(Eigen::Vector2s(object_L[classification], 0));
-                    polyline_ptr->getPointStateBlock(B_id)->setState(Eigen::Vector2s(0, 0));
-                    polyline_ptr->getPointStateBlock(C_id)->setState(Eigen::Vector2s(0, object_W[classification]));
-                    polyline_ptr->getPointStateBlock(D_id)->setState(Eigen::Vector2s(object_L[classification], object_W[classification]));
-                }
-                else
-                {
-                    polyline_ptr->getPointStateBlock(A_id)->setState(Eigen::Vector2s(0, 0));
-                    polyline_ptr->getPointStateBlock(B_id)->setState(Eigen::Vector2s(0, object_W[classification]));
-                    polyline_ptr->getPointStateBlock(C_id)->setState(Eigen::Vector2s(object_L[classification], object_W[classification]));
-                    polyline_ptr->getPointStateBlock(D_id)->setState(Eigen::Vector2s(object_L[classification], 0));
-                }
-                for (auto id = polyline_ptr->getFirstId(); id <= polyline_ptr->getLastId(); id++)
-                {
-                    polyline_ptr->getPointStateBlock(id)->fix();
-                }
-            }
-        }
-}
-
-void ProcessorTrackerLandmarkPolyline::postProcess()
-{
-    //std::cout << "postProcess: " << std::endl;
-    //std::cout << "New Last features: " << getNewFeaturesListLast().size() << std::endl;
-    //std::cout << "Last features: " << last_ptr_->getFeatureList().size() << std::endl;
-    classifyPolilines(getProblem()->getMap()->getLandmarkList());
-}
-
-FactorBasePtr ProcessorTrackerLandmarkPolyline::createFactor(FeatureBasePtr _feature_ptr, LandmarkBasePtr _landmark_ptr)
-{
-    // not used
-    return nullptr;
-}
-
-ProcessorBasePtr ProcessorTrackerLandmarkPolyline::create(const std::string& _unique_name, const ProcessorParamsBasePtr _params, const SensorBasePtr)
-{
-    ProcessorParamsPolylinePtr params = std::static_pointer_cast<ProcessorParamsPolyline>(_params);
-    ProcessorTrackerLandmarkPolylinePtr prc_ptr = std::make_shared<ProcessorTrackerLandmarkPolyline>(params);
-    prc_ptr->setName(_unique_name);
-    return prc_ptr;
-}
-
-}        //namespace wolf
-
-// Register in the SensorFactory
-#include "base/processor/processor_factory.h"
-namespace wolf {
-WOLF_REGISTER_PROCESSOR("POLYLINE", ProcessorTrackerLandmarkPolyline)
-} // namespace wolf