diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 3696d52a048db65e2b09cd3a4a4aa42db9313b29..3dcf6dbafe78072fb683446c1fb279e5594f0cb1 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -77,21 +77,12 @@ stages:
 ############ LICENSE HEADERS ############
 license_header:
   stage: license
-  image: labrobotica/wolf_deps:16.04
+  image: labrobotica/wolf_deps:20.04
   before_script:  
     - *preliminaries_definition
   script: 
     - *license_header_definition
 
-############ UBUNTU 16.04 TESTS ############
-build_and_test:xenial:
-  stage: build_and_test
-  image: labrobotica/wolf_deps:16.04
-  except:
-    - master
-  script:
-    - *build_and_test_definition
-
 ############ UBUNTU 18.04 TESTS ############
 build_and_test:bionic:
   stage: build_and_test
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 176bdf1a2db64c9aac6da0dfb421d10c65fb8ba3..c94b33bfb04c9751c727f62bb16557cd1ef8f508 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,5 +1,5 @@
 #Start WOLF build
-MESSAGE("Starting WOLF CMakeLists ...")
+MESSAGE(STATUS "Starting WOLF CMakeLists ...")
 
 # Pre-requisites about cmake itself
 CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
@@ -63,7 +63,7 @@ ENDIF(NOT BUILD_DOC)
 
 IF(PROFILING)
   add_definitions(-DPROFILING)
-  message("Compiling with profiling options...")
+  message(STATUS "Compiling with profiling options...")
 ENDIF(PROFILING)
 
 if(BUILD_TESTS)
@@ -127,7 +127,6 @@ INCLUDE_DIRECTORIES("include") # In this same project
 INCLUDE_DIRECTORIES(${EIGEN3_INCLUDE_DIRS})
 INCLUDE_DIRECTORIES(${YAMLCPP_INCLUDE_DIR})
 INCLUDE_DIRECTORIES(${CERES_INCLUDE_DIRS})
-
 # ============ HEADERS ============ 
 SET(HDRS_CAPTURE
   include/core/capture/capture_base.h
@@ -160,6 +159,7 @@ SET(HDRS_FACTOR
   include/core/factor/factor_relative_pose_2d_with_extrinsics.h
   include/core/factor/factor_relative_pose_3d.h
   include/core/factor/factor_pose_3d_with_extrinsics.h
+  include/core/factor/factor_relative_pose_3d_with_extrinsics.h
   include/core/factor/factor_velocity_local_direction_3d.h
   )
 SET(HDRS_FEATURE
@@ -187,6 +187,7 @@ SET(HDRS_MATH
   include/core/math/covariance.h
   )
 SET(HDRS_MAP
+  include/core/map/factory_map.h
   include/core/map/map_base.h
   )
 SET(HDRS_PROBLEM
@@ -197,9 +198,8 @@ SET(HDRS_PROCESSOR
   include/core/processor/motion_provider.h
   include/core/processor/processor_base.h
   include/core/processor/processor_diff_drive.h
-  include/core/processor/processor_fix_wing_model.h
+  include/core/processor/processor_fixed_wing_model.h
   include/core/processor/factory_processor.h
-  include/core/processor/processor_logging.h
   include/core/processor/processor_loop_closure.h
   include/core/processor/processor_motion.h
   include/core/processor/processor_odom_2d.h
@@ -214,7 +214,7 @@ SET(HDRS_SENSOR
   include/core/sensor/sensor_base.h
   include/core/sensor/sensor_diff_drive.h
   include/core/sensor/factory_sensor.h
-  include/core/sensor/sensor_model.h
+  include/core/sensor/sensor_motion_model.h
   include/core/sensor/sensor_odom_2d.h
   include/core/sensor/sensor_odom_3d.h
   include/core/sensor/sensor_pose.h
@@ -249,11 +249,9 @@ SET(HDRS_UTILS
   include/core/utils/check_log.h
   include/core/utils/converter.h
   include/core/utils/eigen_assert.h
-  include/core/utils/eigen_predicates.h
   include/core/utils/graph_search.h
   include/core/utils/loader.h
   include/core/utils/logging.h
-  include/core/utils/make_unique.h
   include/core/utils/params_server.h
   include/core/utils/singleton.h
   include/core/utils/utils_gtest.h
@@ -309,7 +307,7 @@ SET(SRCS_PROCESSOR
   src/processor/motion_provider.cpp
   src/processor/processor_base.cpp
   src/processor/processor_diff_drive.cpp
-  src/processor/processor_fix_wing_model.cpp
+  src/processor/processor_fixed_wing_model.cpp
   src/processor/processor_loop_closure.cpp
   src/processor/processor_motion.cpp
   src/processor/processor_odom_2d.cpp
@@ -323,7 +321,7 @@ SET(SRCS_PROCESSOR
 SET(SRCS_SENSOR
   src/sensor/sensor_base.cpp
   src/sensor/sensor_diff_drive.cpp
-  src/sensor/sensor_model.cpp
+  src/sensor/sensor_motion_model.cpp
   src/sensor/sensor_odom_2d.cpp
   src/sensor/sensor_odom_3d.cpp
   src/sensor/sensor_pose.cpp
diff --git a/demos/hello_wolf/yaml/hello_wolf_config.yaml b/demos/hello_wolf/yaml/hello_wolf_config.yaml
index 55eb56a880cd3d407cf631ce7e052e135e9bacce..4260a8c8efb26928a6d2242edbd43830b4467875 100644
--- a/demos/hello_wolf/yaml/hello_wolf_config.yaml
+++ b/demos/hello_wolf/yaml/hello_wolf_config.yaml
@@ -17,6 +17,7 @@ config:
 
     tree_manager:
       type: "none"
+      plugin: "core"
   
   solver:
     max_num_iterations: 100
diff --git a/doc/main.dox b/doc/main.dox
index 62090c8648315200e0ba9b726d55048d74406425..efde8f91eab56973935fe8efa85d64e6dd558b48 100644
--- a/doc/main.dox
+++ b/doc/main.dox
@@ -1,258 +1,29 @@
 // EDIT CAPS TEXTS
 /*! \mainpage WOLF
-
-    \section Description
     
-    WOLF (Windowed Localization Frames) is a software library ...
-
-    \section Main Main Features
+    WOLF (Windowed Localization Frames) is a C++ framework for state estimation based on factor graphs.
     
-    - Uses Eigen3.2. as an algebra engine
-    - Suited for Filtering and Optimization approaches
-    - Allows different state spaces configurations
-    - Minimizes read/write of state vectors and matrix to memory
-
-    \section Contents
-
-    - \link Installation Installation       \endlink
-    - \link how_to       How To             \endlink
-    - \link Performance  Performance		\endlink
-    - \link faq          FAQ                \endlink
-    - \link todo         To Do              \endlink
-    - \link other        OTHER STUFF FTW 	\endlink
-  .
-
-
-  \section Authors
-    Joan Solà (jsola (_at_) iri.upc.edu)
-  
-    Andreu Corominas (acorominas (_at_) iri.upc.edu)
-
-    Faust Terrado  (fterrado (_at_) iri.upc.edu)
+    This is the Doxygen documentation of the  **WOLF core**  library.
     
-    Àngel Santamaria  (asantamaria (_at_) iri.upc.edu)
-
-    Joan Vallvé  (jvallve (_at_) iri.upc.edu)
-   
-    \section License
-
-    TO BE DISCUSSED :
-    This package is licensed under a
-    <a href="http://www.gnu.org/licenses/lgpl.html" target=”_blank”>
-    LGPL 3.0 License</a>.
-
-    \section Disclaimer
-
-    This is free software: you can redistribute it and/or modify
-    it under the terms of the GNU Lesser General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-    \section References References and External Documentation
+    If you are looking for one of the following:
     
-    ... Nothing written here yet ...
-
-*/
-
-
-
-// HERE STARTS THE FUN (THE DIFFERENT PAGES)
-
-// TITLE
-// MINI PAGES MENU
-// CONTENT (SECTIONS...)
-
-// ADDING PAGES:
-//  - add the new page in the menus of each page
-//  - current page is bold "\b", not a \link!
-
-
-/*! \page Installation Installation
-\b Installation | \link how_to How To \endlink | \link Performance \endlink | \link faq FAQ \endlink | \link todo To Do \endlink | \link other OTHER STUFF FTW \endlink
-
-
-To install the WOLF library, please follow the steps below: 
-
-\section Download
-
-Checkout the source code from the IRI public repository
-\code
-cd <your_developing_folder>
-svn checkout https://devel.iri.upc.edu/labrobotica/algorithms/wolf wolf
-\endcode
-
-\section Compilation
-
-After downloading, change directory to wolf/build and execute cmake, 
-\code
-cd build
-cmake ..
-\endcode
-compile the shared library (wolf.so) and the example programs, 
-\code
-make
-\endcode
-
-<!--
-The <em>cmake</em> only need to be executed once (make will automatically call
-<em>cmake</em> if you modify one of the <em>CMakeList.txt</em> files).
--->
-
-Optionally, if you want to generate this documentation in your local machine (uses doxygen default style type), 
-\code
-make doc
-\endcode <!--OTHER-->
-<!-- 
-- To generate this documentation with IRI-DOC style type
-\code
-cd doc
-svn checkout https://devel.iri.upc.edu/labrobotica/tools/iri_doc
-cd ../build; rm -rf *; cmake ..; make; make doc
-\endcode
--->
-
-Please note that the files in the <em>build</em> directory are genetated by <em>cmake</em>
-and <em>make</em> and can be safely removed.
-After doing so you will need to call cmake manually again.
-
-\section Installing_subsec Installing 
-
-In order to be able to use the library, it is necessary to copy it into the system.
-To do that, execute, from the build directory
-\code
-sudo make install
-\endcode
-
-as root and the shared libraries will be copied to <em>/usr/local/lib/iridrivers</em> directory
-and the header files will be copied to <em>/usr/local/include/iridrivers</em> dierctory. At
-this point, the library may be used by any user.
-
-To remove the library from the system, execute
-\code
-sudo make uninstall
-\endcode
-as root, and all the associated files will be removed from the system.
-OTHER
-
-\section Configuration
-
-The default build mode is DEBUG. That is, objects and executables
-include debug information.
-
-The RELEASE build mode optimizes for speed. To build in this mode
-execute
-\code
-cmake .. -DCMAKE_BUILD_TYPE=RELEASE
-\endcode
-The release mode will be kept until next time cmake is executed.
-
-*/
-
-
-
-/*! \page how_to How to use this library
-\link Installation \endlink | \b How \b To | \link Performance \endlink | \link faq FAQ \endlink | \link todo To Do \endlink | \link other OTHER STUFF FTW \endlink
-
-You can use only the functions provided by the library after \link Installation install this library \endlink.
-
-If you need to use this library in your code, you'll have to add these lines into your CMakeLists.txt file.
-
-- first it is necessary to locate if required libraries have been installed or not using the following command (TO DO)
-\code
-FIND_PACKAGE(wolf REQUIRED)
-\endcode
-- In the case that the packages are present, it is necessary to add the header files directory to
-the include directory path by using
-\code
-INCLUDE_DIRECTORIES(${wolf_INCLUDE_DIR})
-\endcode
-- Finally, it is also necessary to link with the desired libraries by using the following command
-\code
-TARGET_LINK_LIBRARIES(<executable name> ${wolf_LIBRARY})
-\endcode
-.
-
-<!-- 
-All these steps are automatically done when the new project is created following the instructions
-in <A href="http://wikiri.upc.es/index.php/Create_a_new_development_project" target=”_blank”>here</a>
--->
-
-From the programming point of view the following example illustrates how to use wolf:
-\code
-#include "state_pvq.h"
-int main()
-{
-    VectorXd storage(20);
-    unsigned int index = 0, bsize = 4;
-
-    //set storage vector
-    storage << 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19;
-
-    VectorXd vec_pvq(StatePVQ::SIZE_);
-    vec_pvq << 20, 21, 22, 23, 24, 25, 26, 27, 28, 29;
-
-    StatePVQ pvq(storage, index + bsize, vec_pvq);
-    cout << "storage   : " << storage.transpose() << endl;
-    cout << "pvq  state: " << pvq.x().transpose() << endl;
-    cout << "pvq  pos  : " << pvq.p().transpose() << endl;
-    cout << "pvq  vel  : " << pvq.v().transpose() << endl;
-    cout << "pvq  quat : " << pvq.q().coeffs().transpose() << endl;
-
-    VectorXd vec_pvq2(StatePVQ::SIZE_);
-    vec_pvq2 << 30, 31, 32, 33, 34, 35, 36, 37, 38, 39;
-    pvq.x(vec_pvq2);
-    cout << "storage   : " << storage.transpose() << endl;
-    cout << "pvq  state: " << pvq.x().transpose() << endl;
-
-
-    return 0;
-}
-\endcode
-
-For further code examples, please see the files at src/examples where there are some "main()" instances that make use of the library in different useful ways.
-
-*/
-
-/*! \page Performance Performance
-\link Installation \endlink | \link how_to How To \endlink | \b Performance | \link faq FAQ \endlink | \link todo To Do \endlink | \link other OTHER STUFF FTW \endlink
-
-The following plot shows the processing time spent to compute ...
-
- <!-- \image html "images/xxx.png" -->
-*/ 
-
-/*! \page faq Frequently Asked Questions
-\link Installation \endlink | \link how_to How To \endlink | \link Performance \endlink | \b FAQ | \link todo To Do \endlink | \link other OTHER STUFF FTW \endlink
-
-Do I need some extra libraries to compile WOLF ?
-- Yes, please take a look at the \link Installation \endlink page.
-
-*/
-
-
-// THIS IS SHOWN BEFORE THE TO DO AUTOMATIC PAGE
-
-/*! \page todo To Do
-\link Installation \endlink | \link how_to How To \endlink | \link Performance \endlink | \link faq FAQ \endlink| \b To \b Do | \link other OTHER STUFF FTW \endlink
-- some to do 
-- another to do
-*/
-
-
-
-
-/*! \page other OTHER STUFF FTW
-\link Installation \endlink | \link how_to How To \endlink | \link Performance \endlink | \link faq FAQ \endlink | \link todo To Do \endlink | \b OTHER \b STUFF \b FTW
-
-HERE IS YOUR CONTENT FOR THE WIN
-
-
+    - full documentation
+    - installation instructions
+    - access to the repositories
+    - WOLF plugins
+    - ROS packages
+     
+    please visit the main WOLF page at http://www.iri.upc.edu/wolf.
+    
+    WOLF is copyright 2015--2022
+    
+    - Joan Solà
+    - Joan Vallvé
+    - Joaquim Casals, 
+    - Jérémie Deray,
+    - Médéric Fourmy, 
+    - Dinesh Atchuthan, 
+    - Andreu Corominas-Murtra
+    
+    at IRI-CSIC-UPC.
 */
diff --git a/include/core/common/wolf.h b/include/core/common/wolf.h
index 7a7f9eeae3b50cbe7d96cd841d99ae1f07b566d3..197a6bfb1b30d79a64376f9468b9481c0a4bc3e3 100644
--- a/include/core/common/wolf.h
+++ b/include/core/common/wolf.h
@@ -275,6 +275,9 @@ WOLF_LIST_TYPEDEFS(FactorBase);
 // Map
 WOLF_PTR_TYPEDEFS(MapBase);
 
+// - - Map params
+WOLF_STRUCT_PTR_TYPEDEFS(ParamsMapBase);
+
 // - Landmark
 WOLF_PTR_TYPEDEFS(LandmarkBase);
 WOLF_LIST_TYPEDEFS(LandmarkBase);
diff --git a/include/core/factor/factor_relative_pose_2d_with_extrinsics.h b/include/core/factor/factor_relative_pose_2d_with_extrinsics.h
index 2247a898bb4d5030ed1b07ef6422d72a9ca968e8..b0eea0f2b8f91f00a9a2bc8a7bda6ce1be66dc45 100644
--- a/include/core/factor/factor_relative_pose_2d_with_extrinsics.h
+++ b/include/core/factor/factor_relative_pose_2d_with_extrinsics.h
@@ -19,8 +19,8 @@
 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
 //
 //--------LICENSE_END--------
-#ifndef FACTOR_RELATIVE_POSE_2D_WITH_EXTRINSICS_THETA_H_
-#define FACTOR_RELATIVE_POSE_2D_WITH_EXTRINSICS_THETA_H_
+#ifndef FACTOR_RELATIVE_POSE_2D_WITH_EXTRINSICS_H_
+#define FACTOR_RELATIVE_POSE_2D_WITH_EXTRINSICS_H_
 
 //Wolf includes
 #include "core/factor/factor_autodiff.h"
@@ -37,61 +37,104 @@ WOLF_PTR_TYPEDEFS(FactorRelativePose2dWithExtrinsics);
 class FactorRelativePose2dWithExtrinsics : public FactorAutodiff<FactorRelativePose2dWithExtrinsics, 3, 2, 1, 2, 1, 2, 1>
 {
     public:
+        /** \brief Class constructor Frame-Frame
+         */
         FactorRelativePose2dWithExtrinsics(const FeatureBasePtr& _ftr_ptr,
                                            const FrameBasePtr& _frame_other_ptr,
                                            const ProcessorBasePtr& _processor_ptr,
                                            bool _apply_loss_function,
                                            const FactorTopology& _top,
-                                           FactorStatus _status = FAC_ACTIVE) :
-             FactorAutodiff<FactorRelativePose2dWithExtrinsics, 3, 2, 1, 2, 1, 2, 1>("FactorRelativePose2dWithExtrinsics",
-                                                                                     _top,
-                                                                                     _ftr_ptr,
-                                                                                     _frame_other_ptr, nullptr, nullptr, nullptr,
-                                                                                     _processor_ptr,
-                                                                                     _apply_loss_function,
-                                                                                     _status,
-                                                                                     _frame_other_ptr->getP(),
-                                                                                     _frame_other_ptr->getO(),
-                                                                                     _ftr_ptr->getFrame()->getP(),
-                                                                                     _ftr_ptr->getFrame()->getO(),
-                                                                                     _ftr_ptr->getCapture()->getSensorP(),
-                                                                                     _ftr_ptr->getCapture()->getSensorO())
-        {
-            assert(_ftr_ptr->getCapture()->getSensorP() != nullptr && "No extrinsics found!");
-            assert(_ftr_ptr->getCapture()->getSensorO() != nullptr && "No extrinsics found!");
-            //
-        }
+                                           FactorStatus _status = FAC_ACTIVE);
+
+        /** \brief Class constructor Frame-Landmark
+         */
+        FactorRelativePose2dWithExtrinsics(const FeatureBasePtr& _ftr_ptr,
+                                           const LandmarkBasePtr& _lmk_other_ptr,
+                                           const ProcessorBasePtr& _processor_ptr,
+                                           bool _apply_loss_function,
+                                           const FactorTopology& _top = TOP_LMK,
+                                           FactorStatus _status = FAC_ACTIVE);
 
         ~FactorRelativePose2dWithExtrinsics() override = default;
 
         template<typename T>
-        bool operator ()(const T* const _p1,
-                         const T* const _o1,
-                         const T* const _p2,
-                         const T* const _o2,
-                         const T* const _sp,
-                         const T* const _so,
+        bool operator ()(const T* const _p_ref,
+                         const T* const _o_ref,
+                         const T* const _p_target,
+                         const T* const _o_target,
+                         const T* const _p_sensor,
+                         const T* const _o_sensor,
                          T* _residuals) const;
 };
 
+inline FactorRelativePose2dWithExtrinsics::FactorRelativePose2dWithExtrinsics(const FeatureBasePtr& _ftr_ptr,
+                                                                       const FrameBasePtr& _frame_other_ptr,
+                                                                       const ProcessorBasePtr& _processor_ptr,
+                                                                       bool _apply_loss_function,
+                                                                       const FactorTopology& _top,
+                                                                       FactorStatus _status) :
+     FactorAutodiff("FactorRelativePose2dWithExtrinsics",
+                    _top,
+                    _ftr_ptr,
+                    _frame_other_ptr, nullptr, nullptr, nullptr,
+                    _processor_ptr,
+                    _apply_loss_function,
+                    _status,
+                    _frame_other_ptr->getP(),
+                    _frame_other_ptr->getO(),
+                    _ftr_ptr->getFrame()->getP(),
+                    _ftr_ptr->getFrame()->getO(),
+                    _ftr_ptr->getCapture()->getSensorP(),
+                    _ftr_ptr->getCapture()->getSensorO())
+{
+    assert(_ftr_ptr->getCapture()->getSensorP() != nullptr && "No extrinsics found!");
+    assert(_ftr_ptr->getCapture()->getSensorO() != nullptr && "No extrinsics found!");
+    //
+}
+
+inline FactorRelativePose2dWithExtrinsics::FactorRelativePose2dWithExtrinsics(const FeatureBasePtr& _ftr_ptr,
+                                                                       const LandmarkBasePtr& _lmk_other_ptr,
+                                                                       const ProcessorBasePtr& _processor_ptr,
+                                                                       bool _apply_loss_function,
+                                                                       const FactorTopology& _top,
+                                                                       FactorStatus _status) :
+     FactorAutodiff("FactorRelativePose2dWithExtrinsics",
+                    _top,
+                    _ftr_ptr,
+                    nullptr, nullptr, nullptr, _lmk_other_ptr,
+                    _processor_ptr,
+                    _apply_loss_function,
+                    _status,
+                    _ftr_ptr->getFrame()->getP(),
+                    _ftr_ptr->getFrame()->getO(),
+                    _lmk_other_ptr->getP(),
+                    _lmk_other_ptr->getO(),
+                    _ftr_ptr->getCapture()->getSensorP(),
+                    _ftr_ptr->getCapture()->getSensorO())
+{
+    assert(_ftr_ptr->getCapture()->getSensorP() != nullptr && "No extrinsics found!");
+    assert(_ftr_ptr->getCapture()->getSensorO() != nullptr && "No extrinsics found!");
+    //
+}
+
 template<typename T>
-inline bool FactorRelativePose2dWithExtrinsics::operator ()(const T* const _p1,
-                                                            const T* const _o1,
-                                                            const T* const _p2,
-                                                            const T* const _o2,
-                                                            const T* const _ps,
-                                                            const T* const _os,
+inline bool FactorRelativePose2dWithExtrinsics::operator ()(const T* const _p_ref,
+                                                            const T* const _o_ref,
+                                                            const T* const _p_target,
+                                                            const T* const _o_target,
+                                                            const T* const _p_sensor,
+                                                            const T* const _o_sensor,
                                                             T* _residuals) const
 {
 
     // MAPS
     Eigen::Map<Eigen::Matrix<T,3,1> > res(_residuals);
-    Eigen::Map<const Eigen::Matrix<T,2,1> > p1(_p1);
-    Eigen::Map<const Eigen::Matrix<T,2,1> > p2(_p2);
-    Eigen::Map<const Eigen::Matrix<T,2,1> > ps(_ps);
-    T o1 = _o1[0];
-    T o2 = _o2[0];
-    T os = _os[0];
+    Eigen::Map<const Eigen::Matrix<T,2,1> > p_ref(_p_ref);
+    Eigen::Map<const Eigen::Matrix<T,2,1> > p_target(_p_target);
+    Eigen::Map<const Eigen::Matrix<T,2,1> > p_sensor(_p_sensor);
+    T o_ref = _o_ref[0];
+    T o_target = _o_target[0];
+    T o_sensor = _o_sensor[0];
 
     Eigen::Matrix<T, 3, 1> expected_measurement;
     Eigen::Matrix<T, 3, 1> er; // error
@@ -112,8 +155,8 @@ inline bool FactorRelativePose2dWithExtrinsics::operator ()(const T* const _p1,
 
     // s1_p_s1_s2 = s1_R_r1*(r1_p_s1_r1 + r1_R_w*(w_p_r1_w + w_p_w_r2 + w_R_r2*r2_p_r2_s2))
 
-    expected_measurement.head(2) = Eigen::Rotation2D<T>(-os)*(-ps + Eigen::Rotation2D<T>(-o1)*(-p1 + p2 + Eigen::Rotation2D<T>(o2)*ps));
-    expected_measurement(2) = o2 - o1;
+    expected_measurement.head(2) = Eigen::Rotation2D<T>(-o_sensor)*(-p_sensor + Eigen::Rotation2D<T>(-o_ref)*(-p_ref + p_target + Eigen::Rotation2D<T>(o_target)*p_sensor));
+    expected_measurement(2) = o_target - o_ref;
 
     // Error
     er = expected_measurement - getMeasurement().cast<T>();
diff --git a/include/core/factor/factor_relative_pose_3d_with_extrinsics.h b/include/core/factor/factor_relative_pose_3d_with_extrinsics.h
new file mode 100644
index 0000000000000000000000000000000000000000..19245f6bcf630f737e4a01aa78b4a11030d8264a
--- /dev/null
+++ b/include/core/factor/factor_relative_pose_3d_with_extrinsics.h
@@ -0,0 +1,215 @@
+//--------LICENSE_START--------
+//
+// Copyright (C) 2020,2021,2022 Institut de Robòtica i Informàtica Industrial, CSIC-UPC.
+// Authors: Joan Solà Ortega (jsola@iri.upc.edu)
+// All rights reserved.
+//
+// This file is part of WOLF
+// WOLF is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+//--------LICENSE_END--------
+#ifndef _FACTOR_TELATIVE_POSE_3D_WITH_EXTRINSICS
+#define _FACTOR_TELATIVE_POSE_3D_WITH_EXTRINSICS
+
+//Wolf includes
+#include "core/common/wolf.h"
+#include "core/math/rotations.h"
+#include "core/factor/factor_autodiff.h"
+#include "core/sensor/sensor_base.h"
+#include "core/landmark/landmark_base.h"
+#include "core/feature/feature_base.h"
+
+namespace wolf
+{
+
+WOLF_PTR_TYPEDEFS(FactorRelativePose3dWithExtrinsics);
+
+class FactorRelativePose3dWithExtrinsics : public FactorAutodiff<FactorRelativePose3dWithExtrinsics, 6, 3, 4, 3, 4, 3, 4>
+{
+    public:
+
+        /** \brief Class constructor Frame-Frame
+         */
+        FactorRelativePose3dWithExtrinsics(const FeatureBasePtr& _feature_ptr,
+                                           const FrameBasePtr& _frame_other_ptr,
+                                           const ProcessorBasePtr& _processor_ptr,
+                                           bool _apply_loss_function,
+                                           const FactorTopology& _top,
+                                           FactorStatus _status = FAC_ACTIVE);
+        /** \brief Class constructor Frame-Landmark
+         */
+        FactorRelativePose3dWithExtrinsics(const FeatureBasePtr& _feature_ptr,
+                                           const LandmarkBasePtr& _landmark_other_ptr,
+                                           const ProcessorBasePtr& _processor_ptr,
+                                           bool _apply_loss_function,
+                                           const FactorTopology& _top = TOP_LMK,
+                                           FactorStatus _status = FAC_ACTIVE);
+
+        /** \brief Class Destructor
+         */
+        ~FactorRelativePose3dWithExtrinsics() override;
+ 
+        /** brief : compute the residual from the state blocks being iterated by the solver.
+         **/
+        template<typename T>
+        bool operator ()(const T* const _p_ref,
+                         const T* const _o_ref,
+                         const T* const _p_target,
+                         const T* const _o_target,
+                         const T* const _p_sensor,
+                         const T* const _o_sensor,
+                         T* _residuals) const;
+
+        Eigen::Vector6d residual() const;
+        double cost() const;
+
+        // print function only for double (not Jet)
+        template<typename T, int Rows, int Cols>
+        void print(int kf, int lmk, const std::string s, const Eigen::Matrix<T, Rows, Cols> _M) const
+        {
+            // jet prints nothing
+        }
+        template<int Rows, int Cols>
+        void print(int kf, int lmk, const std::string s, const Eigen::Matrix<double, Rows, Cols> _M) const
+        {
+            // double prints stuff
+            WOLF_TRACE("KF", kf, " L", lmk, "; ", s, _M);
+        }
+};
+
+} // namespace wolf
+ 
+namespace wolf
+{
+
+inline FactorRelativePose3dWithExtrinsics::FactorRelativePose3dWithExtrinsics(const FeatureBasePtr& _feature_ptr,
+                                                                              const FrameBasePtr& _frame_other_ptr,
+                                                                              const ProcessorBasePtr& _processor_ptr,
+                                                                              bool _apply_loss_function,
+                                                                              const FactorTopology& _top,
+                                                                              FactorStatus _status) :
+    FactorAutodiff("FactorRelativePose3dWithExtrinsics",
+                   _top,
+                   _feature_ptr,
+                   _frame_other_ptr,
+                   nullptr,
+                   nullptr,
+                   nullptr,
+                   _processor_ptr,
+                   _apply_loss_function,
+                   _status,
+                   _frame_other_ptr->getP(),
+                   _frame_other_ptr->getO(),
+                   _feature_ptr->getFrame()->getP(),
+                   _feature_ptr->getFrame()->getO(),
+                   _feature_ptr->getCapture()->getSensorP(),
+                   _feature_ptr->getCapture()->getSensorO())
+{
+}
+
+inline FactorRelativePose3dWithExtrinsics::FactorRelativePose3dWithExtrinsics(const FeatureBasePtr& _feature_ptr,
+                                                                              const LandmarkBasePtr& _landmark_other_ptr,
+                                                                              const ProcessorBasePtr& _processor_ptr,
+                                                                              bool _apply_loss_function,
+                                                                              const FactorTopology& _top,
+                                                                              FactorStatus _status) :
+    FactorAutodiff("FactorRelativePose3dWithExtrinsics",
+                   _top,
+                   _feature_ptr,
+                   nullptr,
+                   nullptr,
+                   nullptr,
+                   _landmark_other_ptr,
+                   _processor_ptr,
+                   _apply_loss_function,
+                   _status,
+                   _feature_ptr->getFrame()->getP(),
+                   _feature_ptr->getFrame()->getO(),
+                   _landmark_other_ptr->getP(),
+                   _landmark_other_ptr->getO(),
+                   _feature_ptr->getCapture()->getSensorP(),
+                   _feature_ptr->getCapture()->getSensorO())
+{
+}
+
+inline FactorRelativePose3dWithExtrinsics::~FactorRelativePose3dWithExtrinsics()
+{
+    //
+}
+
+template<typename T>
+inline bool FactorRelativePose3dWithExtrinsics::operator ()(const T* const _p_ref,
+                                                     const T* const _o_ref,
+                                                     const T* const _p_target,
+                                                     const T* const _o_target,
+                                                     const T* const _p_sensor,
+                                                     const T* const _o_sensor,
+                                                     T* _residuals) const
+{
+    // Maps
+    Eigen::Map<const Eigen::Matrix<T,3,1>> p_r_c(_p_sensor);
+    Eigen::Map<const Eigen::Quaternion<T>> q_r_c(_o_sensor);
+    Eigen::Map<const Eigen::Matrix<T,3,1>> p_w_r(_p_ref);
+    Eigen::Map<const Eigen::Quaternion<T>> q_w_r(_o_ref);
+    Eigen::Map<const Eigen::Matrix<T,3,1>> p_w_l(_p_target);
+    Eigen::Map<const Eigen::Quaternion<T>> q_w_l(_o_target);
+    Eigen::Map<Eigen::Matrix<T,6,1>> residuals(_residuals);
+
+    // Expected measurement
+    Eigen::Quaternion<T> q_c_w = (q_w_r * q_r_c).conjugate();
+    Eigen::Quaternion<T> q_c_l = q_c_w * q_w_l;
+    Eigen::Matrix<T,3,1> p_c_l = q_c_w * (-(p_w_r + q_w_r * p_r_c) + p_w_l);
+
+    // Measurement
+    Eigen::Vector3d      p_c_l_meas(getMeasurement().head<3>());
+    Eigen::Quaterniond   q_c_l_meas(getMeasurement().data() + 3 );
+    Eigen::Quaternion<T> q_l_c_meas = q_c_l_meas.conjugate().cast<T>();
+    //Eigen::Matrix<T,3,1> p_l_c_meas = -q_l_c_meas * p_c_l_meas.cast<T>();
+
+    // Error
+    Eigen::Matrix<T, 6, 1> err;
+    err.head(3) = q_l_c_meas * (p_c_l_meas.cast<T>() - p_c_l);
+    //err.tail(3) = wolf::log_q(q_l_c_meas * q_c_l);  // true error function for which the covariance should be computed
+    err.tail(3) = T(2)*(q_l_c_meas * q_c_l).vec();  // 1rst order approximation of sin function ( 2*sin(aa/2) ~ aa )
+
+    // Residual
+    residuals = getMeasurementSquareRootInformationUpper().cast<T>() * err;
+
+    return true;
+}
+
+inline Eigen::Vector6d FactorRelativePose3dWithExtrinsics::residual() const
+{
+    Eigen::Vector6d res;
+    double * p_camera, * o_camera, * p_ref, * o_ref, * p_target, * o_target;
+    p_camera = getCapture()->getSensorP()->getState().data();
+    o_camera = getCapture()->getSensorO()->getState().data();
+    p_ref    = getCapture()->getFrame()->getP()->getState().data();
+    o_ref    = getCapture()->getFrame()->getO()->getState().data();
+    p_target = getLandmarkOther()->getP()->getState().data();
+    o_target = getLandmarkOther()->getO()->getState().data();
+
+    operator() (p_camera, o_camera, p_ref, o_ref, p_target, o_target, res.data());
+
+    return res;
+}
+
+inline double FactorRelativePose3dWithExtrinsics::cost() const
+{
+    return residual().squaredNorm();
+}
+
+} // namespace wolf
+
+#endif /* _FACTOR_TELATIVE_POSE_3D_WITH_EXTRINSICS */
diff --git a/include/core/map/factory_map.h b/include/core/map/factory_map.h
new file mode 100644
index 0000000000000000000000000000000000000000..5772e4e8a1abab280f5e6ee096161e99be39d515
--- /dev/null
+++ b/include/core/map/factory_map.h
@@ -0,0 +1,218 @@
+//--------LICENSE_START--------
+//
+// Copyright (C) 2020,2021,2022 Institut de Robòtica i Informàtica Industrial, CSIC-UPC.
+// Authors: Joan Solà Ortega (jsola@iri.upc.edu)
+// All rights reserved.
+//
+// This file is part of WOLF
+// WOLF is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+//--------LICENSE_END--------
+/**
+ * \file factory_map.h
+ *
+ *  Created on: Jul 25, 2016
+ *      \author: jvallve
+ */
+
+#ifndef FACTORY_MAP_H_
+#define FACTORY_MAP_H_
+
+namespace wolf
+{
+class MapBase;
+struct ParamsMapBase;
+}
+
+// wolf
+#include "core/common/factory.h"
+#include "core/utils/params_server.h"
+
+namespace wolf
+{
+
+/** \brief Map factory class
+ *
+ * This factory can create objects of classes deriving from MapBase.
+ *
+ * Specific object creation is invoked by `create(TYPE, params ... )`, and the TYPE of map is identified with a string.
+ * Currently, the following map types are implemented,
+ *   - "MapGrid2dGravity"    in plugin 'imu'
+ *
+ * among others.
+ *
+ * Find general Factory documentation in class Factory:
+ *   - Access the factory
+ *   - Register/unregister creators
+ *   - Invoke object creation
+ *
+ * This documentation shows you how to use the FactoryMap specifically:
+ *   - Write map creators.
+ *   - Create maps
+ *
+ * #### Write map creators
+ * Map creators have the following API:
+ *
+ *     \code
+ *     static MapBasePtr create(ParamsMapBasePtr _params_map);
+ *     \endcode
+ *
+ * They follow the general implementation shown below:
+ *
+ *     \code
+ *      static MapBasePtr create(ParamsMapBasePtr _params_map)
+ *      {
+ *          // cast map parameters to good type --- example: ParamsMapGrid
+ *          auto params_ptr = std::static_pointer_cast<ParamsMapGrid>(_params_map);
+ *
+ *          // Do create the Map object --- example: MapGrid
+ *          return map_ptr = std::make_shared<MapGrid>(params_ptr);
+ *      }
+ *     \endcode
+ *
+ * #### Creating maps
+ * Note: Prior to invoking the creation of a map of a particular type,
+ * you must register the creator for this type into the factory.
+ *
+ * To create e.g. a MapGrid, you type:
+ *
+ *     \code
+ *     auto grid_ptr = FactoryMap::create("MapGrid", params_grid);
+ *     \endcode
+ *
+ * #### See also
+ *  - FactoryParamsMap: to create parameter structs deriving from ParamsMapBase directly from YAML files.
+ *
+ * #### Example 1: writing a MapGrid creator
+ * Here is an example of MapGrid::create() extracted from map_grid.cpp:
+ *
+ *     \code
+ *      static MapBasePtr create(const std::string& _unique_name, Eigen::VectorXd& _extrinsics_pq, ParamsMapBasePtr _intrinsics)
+ *      {
+ *          // check extrinsics vector
+ *          assert(_extrinsics_pq.size() == 7 && "Bad extrinsics vector length. Should be 7 for 3d.");
+ *
+ *          // cast instrinsics to good type
+ *          auto intrinsics_ptr = std::static_pointer_cast<ParamsMapGrid>(_intrinsics);
+ *
+ *          // Do create the MapGrid object, and complete its setup
+ *          auto sen_ptr = std::make_shared<MapGrid>(_extrinsics_pq, intrinsics_ptr);
+ *
+ *          sen_ptr->setName(_unique_name);
+ *
+ *          return sen_ptr;
+ *      }
+ *     \endcode
+ *
+ * #### Example 2: registering a map creator into the factory
+ * Registration can be done manually or automatically. It involves the call to static functions.
+ * It is advisable to put these calls within unnamed namespaces.
+ *
+ *   - __Manual registration__: you control registration at application level.
+ *   Put the code either at global scope (you must define a dummy variable for this),
+ *      \code
+ *      namespace {
+ *      const bool registered_grid = FactoryMap::registerCreator("MapGrid", MapGrid::create);
+ *      }
+ *      main () { ... }
+ *      \endcode
+ *   or inside your main(), where a direct call is possible:
+ *      \code
+ *      main () {
+ *          FactoryMap::registerCreator("MapGrid", MapGrid::create);
+ *          ...
+ *      }
+ *      \endcode
+ *
+ *   - __Automatic registration__: registration is performed at library level.
+ *   Put the code at the last line of the map_xxx.cpp file,
+ *      \code
+ *      namespace {
+ *      const bool registered_grid = FactoryMap::registerCreator("MapGrid", MapGrid::create);
+ *      }
+ *      \endcode
+ *   Automatic registration is recommended in wolf, and implemented in the classes shipped with it.
+ *   You are free to comment out these lines and place them wherever you consider it more convenient for your design.
+ *
+ * #### Example 2: creating maps
+ * We finally provide the necessary steps to create a map of class MapGrid in our application:
+ *
+ *  \code
+ *  #include "core/map/factory_map.h"
+ *  #include "core/map/map_grid.h" // provides MapGrid
+ *
+ *  // Note: MapGrid::create() is already registered, automatically.
+ *
+ *  using namespace wolf;
+ *  int main() {
+ *
+ *      // To create a grid, provide:
+ *      //    a type = "MapGrid" and
+ *      //    a pointer to the intrinsics struct:
+ *
+ *      // Create a pointer to the struct of map parameters stored in a YAML file ( see FactoryParamsMap )
+ *      ParamsMapGridPtr  params_1 =
+ *          FactoryParamsMap::create("ParamsMapGrid",
+ *                                            grid_1.yaml);
+ *
+ *      MapBasePtr grid_1_ptr =
+ *          FactoryMap::create ( "MapGrid" ,
+ *                                        params_1 );
+ *
+ *      return 0;
+ *  }
+ *  \endcode
+ *
+ */
+typedef Factory<MapBase,
+                const ParamsMapBasePtr> FactoryMap;
+
+template<>
+inline std::string FactoryMap::getClass() const
+{
+  return "FactoryMap";
+}
+
+// ParamsMap factory
+struct ParamsMapBase;
+typedef Factory<ParamsMapBase,
+                const std::string&> FactoryParamsMap;
+template<>
+inline std::string FactoryParamsMap::getClass() const
+{
+    return "FactoryParamsMap";
+}
+
+#define WOLF_REGISTER_MAP(MapType)                              \
+  namespace{ const bool WOLF_UNUSED MapType##Registered =       \
+    FactoryMap::registerCreator(#MapType, MapType::create); }   \
+
+
+typedef Factory<MapBase,
+                const ParamsServer&> AutoConfFactoryMap;
+
+template<>
+inline std::string AutoConfFactoryMap::getClass() const
+{
+  return "AutoConfFactoryMap";
+}
+
+#define WOLF_REGISTER_MAP_AUTO(MapType)                                 \
+  namespace{ const bool WOLF_UNUSED MapType##AutoConfRegistered =       \
+     AutoConfFactoryMap::registerCreator(#MapType, MapType::create); }  \
+
+
+} /* namespace wolf */
+
+#endif /* SENSOR_FACTORY_H_ */
diff --git a/include/core/map/map_base.h b/include/core/map/map_base.h
index 13c870269665e595145b28d8ceca2a44aa0dac92..797d2bd3892e339c96a8c40e591eb56d39818ee5 100644
--- a/include/core/map/map_base.h
+++ b/include/core/map/map_base.h
@@ -32,11 +32,65 @@ class LandmarkBase;
 //Wolf includes
 #include "core/common/wolf.h"
 #include "core/common/node_base.h"
+#include "core/common/params_base.h"
 
 //std includes
 
 namespace wolf {
 
+/*
+ * Macro for defining Autoconf map creator.
+ *
+ * Place a call to this macro inside your class declaration (in the map_class.h file),
+ * preferably just after the constructors.
+ *
+ * In order to use this macro, the derived map class, MapClass,
+ * must have a constructor available with the API:
+ *
+ *   MapClass(const ParamsMapClassPtr _params);
+ *
+ * We recommend writing one of such constructors in your derived maps.
+ */
+#define WOLF_MAP_CREATE(MapClass, ParamsMapClass)                       \
+static                                                                  \
+MapBasePtr create(const ParamsServer& _server)                          \
+{                                                                       \
+    auto params = std::make_shared<ParamsMapClass>(_server);            \
+                                                                        \
+    return std::make_shared<MapClass>(params);                          \
+}                                                                       \
+                                                                        \
+static                                                                  \
+MapBasePtr create(const ParamsMapBasePtr _params)                       \
+{                                                                       \
+    auto params = std::static_pointer_cast<ParamsMapClass>(_params);    \
+                                                                        \
+    return std::make_shared<MapClass>(params);                          \
+}                                                                       \
+
+
+/** \brief base struct for map parameters
+ *
+ * Derive from this struct to create structs of map parameters.
+ */
+struct ParamsMapBase: public ParamsBase
+{
+    std::string prefix = "map";
+
+    ParamsMapBase(const ParamsServer& _param_server) :
+        ParamsBase("map", _param_server)
+    {
+
+    };
+
+    ~ParamsMapBase() override = default;
+
+    std::string print() const override
+    {
+        return "";
+    }
+};
+
 //class MapBase
 class MapBase : public NodeBase, public std::enable_shared_from_this<MapBase>
 {
@@ -47,6 +101,9 @@ class MapBase : public NodeBase, public std::enable_shared_from_this<MapBase>
 
     public:
         MapBase();
+        MapBase(ParamsMapBasePtr _params, const std::string& _type = "Base");
+        WOLF_MAP_CREATE(MapBase, ParamsMapBase);
+
         ~MapBase() override;
         
     protected:
diff --git a/include/core/math/SE2.h b/include/core/math/SE2.h
index 4ce5ab465d6e87ec8e7cacf5af05c06f2a6db32c..95631a8a6fb82ac22595b64d3e1d5b4fe7849cb4 100644
--- a/include/core/math/SE2.h
+++ b/include/core/math/SE2.h
@@ -102,6 +102,38 @@ inline VectorComposite identity()
     return v;
 }
 
+template<typename D1, typename D2>
+inline void inverse(const MatrixBase<D1>& p, const typename D1::Scalar& o,
+                    MatrixBase<D2>& ip, typename D2::Scalar& io)
+{
+    MatrixSizeCheck<2, 1>::check(p);
+    MatrixSizeCheck<2, 1>::check(ip);
+
+    ip = SO2::exp(-o) * -p;
+    io = -o;
+}
+
+template<typename D1, typename D2>
+inline void inverse(const MatrixBase<D1>& d,
+                    MatrixBase<D2>& id)
+{
+    MatrixSizeCheck<3, 1>::check(d);
+    MatrixSizeCheck<3, 1>::check(id);
+
+    Map<const Matrix<typename D1::Scalar, 2, 1> >   p   ( & d( 0 ) );
+    Map<Matrix<typename D2::Scalar, 2, 1> >         ip  ( & id( 0 ) );
+
+    inverse(p, d(2), ip, id(2));
+}
+
+template<typename D>
+inline Matrix<typename D::Scalar, 3, 1> inverse(const MatrixBase<D>& d)
+{
+    Matrix<typename D::Scalar, 3, 1> id;
+    inverse(d, id);
+    return id;
+}
+
 template<class D1, class D2>
 inline void exp(const Eigen::MatrixBase<D1>& _tau, Eigen::MatrixBase<D2>& _delta)
 {
@@ -408,7 +440,47 @@ inline VectorComposite plus(const VectorComposite& x, const VectorComposite& tau
     return res;
 }
 
+template<typename D1, typename D2, typename D3>
+inline void between(const MatrixBase<D1>& p1, const typename D1::Scalar& o1,
+                    const MatrixBase<D2>& p2, const typename D2::Scalar& o2,
+                    MatrixBase<D3>& p12, typename D3::Scalar& o12)
+{
+        MatrixSizeCheck<2, 1>::check(p1);
+        MatrixSizeCheck<2, 1>::check(p2);
+        MatrixSizeCheck<2, 1>::check(p12);
+
+        p12 = SO2::exp(-o1) * ( p2 - p1 );
+        o12 = o2 - o1;
+}
+
+template<typename D1, typename D2, typename D3>
+inline void between(const MatrixBase<D1>& d1,
+                    const MatrixBase<D2>& d2,
+                    MatrixBase<D3>& d12)
+{
+    MatrixSizeCheck<3, 1>::check(d1);
+    MatrixSizeCheck<3, 1>::check(d2);
+    MatrixSizeCheck<3, 1>::check(d12);
+
+    typedef typename D1::Scalar T;
+
+    Map<const Matrix<T, 2, 1> >   p1  ( & d1(0)  );
+    Map<const Matrix<T, 2, 1> >   p2  ( & d2(0)  );
+    Map<Matrix<T, 2, 1> >         p12 ( & d12(0) );
+
+    between(p1, d1(2), p2, d2(2), p12, d12(2));
+}
 
+template<typename D1, typename D2>
+inline Matrix<typename D1::Scalar, 3, 1> between(const MatrixBase<D1>& d1,
+                                                 const MatrixBase<D2>& d2 )
+{
+    MatrixSizeCheck<3, 1>::check(d1);
+    MatrixSizeCheck<3, 1>::check(d2);
+    Matrix<typename D1::Scalar, 3, 1> d12;
+    between(d1, d2, d12);
+    return d12;
+}
 
 } // namespace SE2
 } // namespacs wolf
diff --git a/include/core/problem/problem.h b/include/core/problem/problem.h
index 14f8588b7d01715a6ffb3dcd2e8be8d119aff78d..7405ae8320deb339ed6efdfe7319b4df8ec14cff 100644
--- a/include/core/problem/problem.h
+++ b/include/core/problem/problem.h
@@ -89,11 +89,11 @@ class Problem : public std::enable_shared_from_this<Problem>
         PriorOptionsPtr prior_options_;
 
     private: // CAUTION: THESE METHODS ARE PRIVATE, DO NOT MAKE THEM PUBLIC !!
-        Problem(const std::string& _frame_structure, SizeEigen _dim); // USE create() below !!
+        Problem(const std::string& _frame_structure, SizeEigen _dim, MapBasePtr _map); // USE create() below !!
         void setup();
 
     public:
-        static ProblemPtr create(const std::string& _frame_structure, SizeEigen _dim); // USE THIS AS A CONSTRUCTOR!
+        static ProblemPtr create(const std::string& _frame_structure, SizeEigen _dim, MapBasePtr _map = std::make_shared<MapBase>()); // USE THIS AS A CONSTRUCTOR!
         static ProblemPtr autoSetup(ParamsServer &_server);
         virtual ~Problem();
 
@@ -343,6 +343,7 @@ class Problem : public std::enable_shared_from_this<Problem>
 
         // Map branch -----------------------------------------
         MapBasePtr getMap() const;
+        void setMap(MapBasePtr);
         void loadMap(const std::string& _filename_dot_yaml);
         void saveMap(const std::string& _filename_dot_yaml, //
                      const std::string& _map_name = "Map automatically saved by Wolf");
diff --git a/include/core/processor/processor_fix_wing_model.h b/include/core/processor/processor_fixed_wing_model.h
similarity index 77%
rename from include/core/processor/processor_fix_wing_model.h
rename to include/core/processor/processor_fixed_wing_model.h
index 97c8ad6f3919c35744e824cde99d56c4d2b7e1b8..bccbc2317135376f7cf7dd1f70113fb933fc72b0 100644
--- a/include/core/processor/processor_fix_wing_model.h
+++ b/include/core/processor/processor_fixed_wing_model.h
@@ -26,31 +26,31 @@
  *      Author: joanvallve
  */
 
-#ifndef INCLUDE_CORE_PROCESSOR_PROCESSOR_FIX_WING_MODEL_H_
-#define INCLUDE_CORE_PROCESSOR_PROCESSOR_FIX_WING_MODEL_H_
+#ifndef INCLUDE_CORE_PROCESSOR_PROCESSOR_FIXED_WING_MODEL_H_
+#define INCLUDE_CORE_PROCESSOR_PROCESSOR_FIXED_WING_MODEL_H_
 
 #include "core/processor/processor_base.h"
 
 namespace wolf
 {
 
-WOLF_STRUCT_PTR_TYPEDEFS(ParamsProcessorFixWingModel);
+WOLF_STRUCT_PTR_TYPEDEFS(ParamsProcessorFixedWingModel);
 
-struct ParamsProcessorFixWingModel : public ParamsProcessorBase
+struct ParamsProcessorFixedWingModel : public ParamsProcessorBase
 {
         Eigen::Vector3d velocity_local;
         double angle_stdev;
         double min_vel_norm;
 
-        ParamsProcessorFixWingModel() = default;
-        ParamsProcessorFixWingModel(std::string _unique_name, const wolf::ParamsServer & _server) :
+        ParamsProcessorFixedWingModel() = default;
+        ParamsProcessorFixedWingModel(std::string _unique_name, const wolf::ParamsServer & _server) :
             ParamsProcessorBase(_unique_name, _server)
         {
             velocity_local   = _server.getParam<Eigen::Vector3d> (prefix + _unique_name + "/velocity_local");
             angle_stdev      = _server.getParam<double>          (prefix + _unique_name + "/angle_stdev");
             min_vel_norm     = _server.getParam<double>          (prefix + _unique_name + "/min_vel_norm");
 
-            assert(std::abs(velocity_local.norm() - 1.0) < wolf::Constants::EPS && "ParamsProcessorFixWingModel: 'velocity_local' must be normalized");
+            assert(std::abs(velocity_local.norm() - 1.0) < wolf::Constants::EPS && "ParamsProcessorFixedWingModel: 'velocity_local' must be normalized");
         }
         std::string print() const override
         {
@@ -61,17 +61,17 @@ struct ParamsProcessorFixWingModel : public ParamsProcessorBase
         }
 };
 
-WOLF_PTR_TYPEDEFS(ProcessorFixWingModel);
+WOLF_PTR_TYPEDEFS(ProcessorFixedWingModel);
 
-class ProcessorFixWingModel : public ProcessorBase
+class ProcessorFixedWingModel : public ProcessorBase
 {
     public:
-        ProcessorFixWingModel(ParamsProcessorFixWingModelPtr _params);
+        ProcessorFixedWingModel(ParamsProcessorFixedWingModelPtr _params);
 
         // Factory method for high level API
-        WOLF_PROCESSOR_CREATE(ProcessorFixWingModel, ParamsProcessorFixWingModel);
+        WOLF_PROCESSOR_CREATE(ProcessorFixedWingModel, ParamsProcessorFixedWingModel);
 
-        virtual ~ProcessorFixWingModel() override;
+        virtual ~ProcessorFixedWingModel() override;
         void configure(SensorBasePtr _sensor) override;
 
     protected:
@@ -105,9 +105,9 @@ class ProcessorFixWingModel : public ProcessorBase
         virtual bool voteForKeyFrame() const override {return false;};
 
         // ATTRIBUTES
-        ParamsProcessorFixWingModelPtr params_processor_;
+        ParamsProcessorFixedWingModelPtr params_processor_;
 };
 
 } /* namespace wolf */
 
-#endif /* INCLUDE_CORE_PROCESSOR_PROCESSOR_FIX_WING_MODEL_H_ */
+#endif /* INCLUDE_CORE_PROCESSOR_PROCESSOR_FIXED_WING_MODEL_H_ */
diff --git a/include/core/processor/processor_logging.h b/include/core/processor/processor_logging.h
deleted file mode 100644
index 52eab893a2647dc4ef0af352b4ea7bdcd7215e33..0000000000000000000000000000000000000000
--- a/include/core/processor/processor_logging.h
+++ /dev/null
@@ -1,52 +0,0 @@
-//--------LICENSE_START--------
-//
-// Copyright (C) 2020,2021,2022 Institut de Robòtica i Informàtica Industrial, CSIC-UPC.
-// Authors: Joan Solà Ortega (jsola@iri.upc.edu)
-// All rights reserved.
-//
-// This file is part of WOLF
-// WOLF is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with this program.  If not, see <http://www.gnu.org/licenses/>.
-//
-//--------LICENSE_END--------
-/**
- * \file processor_logging.h
- *
- *  Created on: Oct 5, 2017
- *  \author: Jeremie Deray
- */
-
-#ifndef _WOLF_PROCESSOR_LOGGING_H_
-#define _WOLF_PROCESSOR_LOGGING_H_
-
-/// @brief un-comment for IDE highlights.
-
-
-#define __INTERNAL_WOLF_ASSERT_PROCESSOR \
-  static_assert(std::is_base_of<ProcessorBase, \
-   typename std::remove_pointer<decltype(this)>::type>::value, \
-    "This macro can be used only within the body of a " \
-    "non-static " \
-    "ProcessorBase (and derived) function !");
-
-#define WOLF_PROCESSOR_INFO(...)  __INTERNAL_WOLF_ASSERT_PROCESSOR WOLF_INFO_NAMED(getType(),  __VA_ARGS__);
-#define WOLF_PROCESSOR_WARN(...)  __INTERNAL_WOLF_ASSERT_PROCESSOR WOLF_WARN_NAMED(getType(),  __VA_ARGS__);
-#define WOLF_PROCESSOR_ERROR(...) __INTERNAL_WOLF_ASSERT_PROCESSOR WOLF_ERROR_NAMED(getType(), __VA_ARGS__);
-#define WOLF_PROCESSOR_DEBUG(...) __INTERNAL_WOLF_ASSERT_PROCESSOR WOLF_DEBUG_NAMED(getType(), __VA_ARGS__);
-
-#define WOLF_PROCESSOR_INFO_COND(cond, ...)  __INTERNAL_WOLF_ASSERT_PROCESSOR WOLF_INFO_NAMED_COND(getType(),  cond, __VA_ARGS__);
-#define WOLF_PROCESSOR_WARN_COND(cond, ...)  __INTERNAL_WOLF_ASSERT_PROCESSOR WOLF_WARN_NAMED_COND(getType(),  cond, __VA_ARGS__);
-#define WOLF_PROCESSOR_ERROR_COND(cond, ...) __INTERNAL_WOLF_ASSERT_PROCESSOR WOLF_ERROR_NAMED_COND(getType(), cond, __VA_ARGS__);
-#define WOLF_PROCESSOR_DEBUG_COND(cond, ...) __INTERNAL_WOLF_ASSERT_PROCESSOR WOLF_DEBUG_NAMED_COND(getType(), cond, __VA_ARGS__);
-
-#endif /* _WOLF_PROCESSOR_LOGGING_H_ */
diff --git a/include/core/sensor/sensor_model.h b/include/core/sensor/sensor_motion_model.h
similarity index 80%
rename from include/core/sensor/sensor_model.h
rename to include/core/sensor/sensor_motion_model.h
index 7070ff1c72da933fa44a0ca180a596224ab66ee5..68da8c7d481aa502c8352a350e03498de7f758e0 100644
--- a/include/core/sensor/sensor_model.h
+++ b/include/core/sensor/sensor_motion_model.h
@@ -19,26 +19,27 @@
 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
 //
 //--------LICENSE_END--------
-#ifndef SRC_SENSOR_MODEL_H_
-#define SRC_SENSOR_MODEL_H_
+#ifndef SRC_SENSOR_MOTION_MODEL_H_
+#define SRC_SENSOR_MOTION_MODEL_H_
 
 //wolf includes
 #include "core/sensor/sensor_base.h"
 
 namespace wolf {
 
-WOLF_PTR_TYPEDEFS(SensorModel);
 
-class SensorModel : public SensorBase
+WOLF_PTR_TYPEDEFS(SensorMotionModel);
+
+class SensorMotionModel : public SensorBase
 {
     public:
-        SensorModel();
-        ~SensorModel() override;
+        SensorMotionModel();
+        ~SensorMotionModel() override;
 
         static SensorBasePtr create(const std::string& _unique_name,
                                     const ParamsServer& _server)
         {
-            auto sensor = std::make_shared<SensorModel>();
+            auto sensor = std::make_shared<SensorMotionModel>();
             sensor      ->setName(_unique_name);
             return sensor;
         }
@@ -47,7 +48,7 @@ class SensorModel : public SensorBase
                                     const Eigen::VectorXd& _extrinsics,
                                     const ParamsSensorBasePtr _intrinsics)
         {
-            auto sensor = std::make_shared<SensorModel>();
+            auto sensor = std::make_shared<SensorMotionModel>();
             sensor      ->setName(_unique_name);
             return sensor;
         }
@@ -56,4 +57,4 @@ class SensorModel : public SensorBase
 
 } /* namespace wolf */
 
-#endif /* SRC_SENSOR_POSE_H_ */
+#endif /* SRC_SENSOR_MOTION_MODEL_H_ */
diff --git a/include/core/utils/eigen_predicates.h b/include/core/utils/eigen_predicates.h
deleted file mode 100644
index 3a83601e84d95eba96d1193c651c220eca0ebf64..0000000000000000000000000000000000000000
--- a/include/core/utils/eigen_predicates.h
+++ /dev/null
@@ -1,121 +0,0 @@
-//--------LICENSE_START--------
-//
-// Copyright (C) 2020,2021,2022 Institut de Robòtica i Informàtica Industrial, CSIC-UPC.
-// Authors: Joan Solà Ortega (jsola@iri.upc.edu)
-// All rights reserved.
-//
-// This file is part of WOLF
-// WOLF is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with this program.  If not, see <http://www.gnu.org/licenses/>.
-//
-//--------LICENSE_END--------
-/**
- * \file eigen_predicates.h
- * \brief Some utils for comparing Eigen types
- * \author Jeremie Deray
- *  Created on: 24/10/2017
- */
-
-#ifndef _WOLF_EIGEN_PREDICATES_H_
-#define _WOLF_EIGEN_PREDICATES_H_
-
-#include "core/math/rotations.h"
-
-namespace wolf {
-
-/// @brief check that each Matrix/Vector elem is approx equal to value +- precision
-///
-/// @note we overload this rather than using Eigen::Matrix::isConstant() since it is
-/// defined as :
-///   abs(x - y) <= (min)(abs(x), abs(y)) * prec
-/// which does not play nice with y = 0
-auto is_constant = [](const Eigen::MatrixXd& lhs, const double val, const double precision)
-                      {
-                        for (Eigen::MatrixXd::Index j = 0; j < lhs.cols(); ++j)
-                          for (Eigen::MatrixXd::Index i = 0; i < lhs.rows(); ++i)
-                            if (std::abs(lhs.coeff(i, j) - val) > precision)
-                              return false;
-                        return true;
-                      };
-
-/// @brief check that each element of the Matrix/Vector difference
-/// is approx 0 +- precision
-auto pred_zero = [](const Eigen::MatrixXd& lhs, const double precision)
-                   { return is_constant(lhs, 0, precision); };
-
-/// @brief check that each element of the Matrix/Vector difference
-/// is approx 0 +- precision
-auto pred_diff_zero = [](const Eigen::MatrixXd& lhs, const Eigen::MatrixXd& rhs, const double precision)
-                        { return pred_zero(lhs - rhs, precision); };
-
-/// @brief check that the Matrix/Vector difference norm is approx 0 +- precision
-auto pred_diff_norm_zero = [](const Eigen::MatrixXd& lhs, const Eigen::MatrixXd& rhs, const double precision)
-                             { return std::abs((lhs - rhs).norm()) <= std::abs(precision); };
-
-/// @brief check that the lhs Matrix/Vector is elem-wise approx the rhs +-precision
-auto pred_is_approx = [](const Eigen::MatrixXd& lhs, const Eigen::MatrixXd& rhs, const double precision)
-                        { return lhs.isApprox(rhs, precision); };
-
-/// @brief check that angle θ of rotation required to get from lhs quaternion to rhs
-/// is <= precision
-auto pred_quat_is_approx = [](const Eigen::Quaterniond& lhs, const Eigen::Quaterniond& rhs, const double precision)
-                             { return pred_zero( log_q(rhs * lhs.inverse()), precision ); };
-
-/// @brief check that angle θ of rotation required to get from lhs quaternion to identity
-/// is <= precision
-auto pred_quat_identity = [](const Eigen::Quaterniond& lhs, const double precision)
-                            { return pred_quat_is_approx(lhs, Eigen::Quaterniond::Identity(), precision); };
-
-/// @brief check that rotation angle to get from lhs angle to rhs is <= precision
-auto pred_angle_is_approx = [](const double lhs, const double rhs, const double precision)
-                              { return std::abs(pi2pi(lhs - rhs)) <= std::abs(precision); };
-
-/// @brief check that rotation angle to get from lhs angle to 0 is <= precision
-auto pred_angle_zero = [](const double lhs, const double precision)
-                          { return pred_angle_is_approx(lhs, 0, precision); };
-
-/// @brief check that the lhs pose is approx rhs +- precision
-///
-/// @note
-/// Comparison is :
-/// d = inv(lhs) * rhs
-/// d.translation().elem_wise() ~ 0 (+- precision)
-///
-/// if pose 3d :
-/// d.rotation_as_quaternion() ~ quaternion.getIdentity (+- precision)
-///
-/// else if pose 2d:
-/// d.rotation_angle() ~ 0 (+- precision)
-///
-/// else throw std::runtime
-///
-/// @see pred_zero for translation comparison
-/// @see pred_quat_identity for 3d rotation comparison
-/// @see pred_angle_zero for 2d rotation comparison
-//auto pred_pose_is_approx = [](const Eigen::MatrixXd lhs, const Eigen::MatrixXd rhs, const double precision)
-//                              {
-//                                const Eigen::MatrixXd d = lhs.inverse() * rhs;
-//                                const bool tok = pred_zero(d.rightCols(1), precision);
-
-//                                const bool qok = (lhs.rows() == 3)?
-//                                      pred_quat_identity(Eigen::Quaterniond(d.block(0,0,3,1)),
-//                                                         precision)
-//                                      : (lhs.rows() == 2)? pred_angle_zero(getYaw(d), precision)
-//                                                         : throw std::runtime_error("Canno't compare pose in Dim > 3 !");
-
-//                                return tok && qok;
-//                              };
-
-} // namespace wolf
-
-#endif /* _WOLF_EIGEN_PREDICATES_H_ */
diff --git a/include/core/utils/logging.h b/include/core/utils/logging.h
index b34ceccb16c5e12567256f2749896d5369d017a8..a0e1556898fd453f5543ba90ec3645ccf282525c 100644
--- a/include/core/utils/logging.h
+++ b/include/core/utils/logging.h
@@ -222,16 +222,6 @@ inline void Logger::set_pattern(const std::string& p)
 
 using LoggerPtr = std::unique_ptr<Logger>;
 
-/// dummy namespace to avoid colision with c++14
-/// @todo use std version once we move to cxx14
-namespace not_std {
-template <typename T, typename... Args>
-std::unique_ptr<T> make_unique(Args&&... args)
-{
-  return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
-}
-} /* namespace not_std */
-
 class LoggerManager
 {
 public:
@@ -265,7 +255,7 @@ protected:
     /// @note would be easier with cpp17 map.try_emplace...
     const bool created = existsImpl(name) ?
                           false :
-                          logger_map_.emplace(name, not_std::make_unique<Logger>(name)).second;
+                          logger_map_.emplace(name, std::make_unique<Logger>(name)).second;
     return created;
   }
 
diff --git a/include/core/utils/make_unique.h b/include/core/utils/make_unique.h
deleted file mode 100644
index 0bfdbb8372a54fb59d2ab59d8ca1b78432b38dec..0000000000000000000000000000000000000000
--- a/include/core/utils/make_unique.h
+++ /dev/null
@@ -1,45 +0,0 @@
-//--------LICENSE_START--------
-//
-// Copyright (C) 2020,2021,2022 Institut de Robòtica i Informàtica Industrial, CSIC-UPC.
-// Authors: Joan Solà Ortega (jsola@iri.upc.edu)
-// All rights reserved.
-//
-// This file is part of WOLF
-// WOLF is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with this program.  If not, see <http://www.gnu.org/licenses/>.
-//
-//--------LICENSE_END--------
-/**
- * \file make_unique.h
- *
- *  Created on: Oct 11, 2017
- *  \author: Jeremie Deray
- */
-
-#ifndef _WOLF_MAKE_UNIQUE_H_
-#define _WOLF_MAKE_UNIQUE_H_
-
-#include <memory>
-
-namespace wolf {
-
-/// @note this appears only in cpp14
-template <typename T, typename... Args>
-std::unique_ptr<T> make_unique(Args&&... args)
-{
-  return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
-}
-
-}
-
-#endif /* _WOLF_MAKE_UNIQUE_H_ */
diff --git a/src/ceres_wrapper/solver_ceres.cpp b/src/ceres_wrapper/solver_ceres.cpp
index aed7fef36c99f71de9b664fa456620c7ef6523cd..ab8753351aee84c5b4f290af171b370663060499 100644
--- a/src/ceres_wrapper/solver_ceres.cpp
+++ b/src/ceres_wrapper/solver_ceres.cpp
@@ -27,7 +27,6 @@
 #include "core/trajectory/trajectory_base.h"
 #include "core/map/map_base.h"
 #include "core/landmark/landmark_base.h"
-#include "core/utils/make_unique.h"
 
 namespace wolf
 {
@@ -47,8 +46,8 @@ SolverCeres::SolverCeres(const ProblemPtr& _wolf_problem,
      , n_interrupted_(0)
      , n_no_convergence_(0)
 {
-    covariance_ = wolf::make_unique<ceres::Covariance>(params_ceres_->covariance_options);
-    ceres_problem_ = wolf::make_unique<ceres::Problem>(params_ceres_->problem_options);
+    covariance_ = std::make_unique<ceres::Covariance>(params_ceres_->covariance_options);
+    ceres_problem_ = std::make_unique<ceres::Problem>(params_ceres_->problem_options);
 
     if (params_ceres_->interrupt_on_problem_change)
         getSolverOptions().callbacks.push_back(new IterationUpdateCallback(wolf_problem_,
diff --git a/src/map/map_base.cpp b/src/map/map_base.cpp
index f736ce180aa565b43ec5a68d1ec061c551f33916..8194c87d95dc05bb20b5f736afdb704a11a75560 100644
--- a/src/map/map_base.cpp
+++ b/src/map/map_base.cpp
@@ -23,7 +23,7 @@
 // wolf
 #include "core/map/map_base.h"
 #include "core/landmark/landmark_base.h"
-#include "core/common/factory.h"
+//#include "core/common/factory.h"
 
 // YAML
 #include <yaml-cpp/yaml.h>
@@ -43,6 +43,12 @@ MapBase::MapBase() :
 //    std::cout << "constructed M"<< std::endl;
 }
 
+MapBase::MapBase(ParamsMapBasePtr _params, const std::string& _type) :
+    NodeBase("MAP", _type)
+{
+//    std::cout << "constructed M"<< std::endl;
+}
+
 MapBase::~MapBase()
 {
 //	std::cout << "destructed -M" << std::endl;
@@ -148,3 +154,12 @@ bool MapBase::check(CheckLog& _log, std::shared_ptr<NodeBase> _node_ptr, bool _v
     return _log.is_consistent_;
 }
 } // namespace wolf
+
+
+// Register in the FactorySensor
+#include "core/map/factory_map.h"
+namespace wolf {
+WOLF_REGISTER_MAP(MapBase);
+WOLF_REGISTER_MAP_AUTO(MapBase);
+} // namespace wolf
+
diff --git a/src/problem/problem.cpp b/src/problem/problem.cpp
index 8d5858a6e0045372d9dfb75a702f29c018ba9d22..a3981d2f9e1a8e2b08a25f290ee2e7cf60ffd6be 100644
--- a/src/problem/problem.cpp
+++ b/src/problem/problem.cpp
@@ -24,7 +24,10 @@
 #include "core/hardware/hardware_base.h"
 #include "core/trajectory/trajectory_base.h"
 #include "core/map/map_base.h"
+#include "core/map/factory_map.h"
 #include "core/sensor/sensor_base.h"
+#include "core/sensor/factory_sensor.h"
+#include "core/processor/factory_processor.h"
 #include "core/processor/processor_motion.h"
 #include "core/processor/processor_tracker.h"
 #include "core/capture/capture_pose.h"
@@ -32,8 +35,6 @@
 #include "core/factor/factor_base.h"
 #include "core/factor/factor_block_absolute.h"
 #include "core/factor/factor_quaternion_absolute.h"
-#include "core/sensor/factory_sensor.h"
-#include "core/processor/factory_processor.h"
 #include "core/state_block/state_block.h"
 #include "core/state_block/state_quaternion.h"
 #include "core/state_block/state_angle.h"
@@ -61,11 +62,11 @@
 namespace wolf
 {
 
-Problem::Problem(const std::string& _frame_structure, SizeEigen _dim) :
+Problem::Problem(const std::string& _frame_structure, SizeEigen _dim, MapBasePtr _map) :
         tree_manager_(nullptr),
         hardware_ptr_(std::make_shared<HardwareBase>()),
         trajectory_ptr_(std::make_shared<TrajectoryBase>()),
-        map_ptr_(std::make_shared<MapBase>()),
+        map_ptr_(_map),
         motion_provider_map_(),
         frame_structure_(_frame_structure),
         prior_options_(std::make_shared<PriorOptions>())
@@ -96,12 +97,13 @@ void Problem::setup()
 {
     hardware_ptr_  -> setProblem(shared_from_this());
     trajectory_ptr_-> setProblem(shared_from_this());
-    map_ptr_       -> setProblem(shared_from_this());
+    if (map_ptr_)
+        map_ptr_   -> setProblem(shared_from_this());
 }
 
-ProblemPtr Problem::create(const std::string& _frame_structure, SizeEigen _dim)
+ProblemPtr Problem::create(const std::string& _frame_structure, SizeEigen _dim, MapBasePtr _map)
 {
-    ProblemPtr p(new Problem(_frame_structure, _dim)); // We use `new` and not `make_shared` since the Problem constructor is private and cannot be passed to `make_shared`.
+    ProblemPtr p(new Problem(_frame_structure, _dim, _map)); // We use `new` and not `make_shared` since the Problem constructor is private and cannot be passed to `make_shared`.
     p->setup();
     return p->shared_from_this();
 }
@@ -117,17 +119,19 @@ ProblemPtr Problem::autoSetup(ParamsServer &_server)
     // Problem structure and dimension
     std::string frame_structure = _server.getParam<std::string> ("problem/frame_structure");
     int         dim             = _server.getParam<int>         ("problem/dimension");
-    auto        problem         = Problem::create(frame_structure, dim);
+    auto        problem         = Problem::create(frame_structure, dim, nullptr);
 
     WOLF_TRACE("Setting up problem with frame structure {" + frame_structure + "} and dimension " + std::to_string(dim) + "D");
 
     // Load plugins
     auto loaders = std::vector<std::shared_ptr<Loader>>();
     std::string plugins_path;
-    try{
+    try
+    {
         plugins_path = _server.getParam<std::string>("plugins_path");
     }
-    catch(MissingValueException& e){
+    catch (MissingValueException& e)
+    {
       WOLF_WARN(e.what());
       WOLF_WARN("Setting '/usr/local/lib/' as plugins path...");
       plugins_path="/usr/local/lib/";
@@ -145,9 +149,11 @@ ProblemPtr Problem::autoSetup(ParamsServer &_server)
 
     // load Packages for subscribers and publishers
     std::string packages_path;
-    try {
+    try 
+    {
         packages_path = _server.getParam<std::string>("packages_path");
-    } catch (MissingValueException& e) {
+    } 
+    catch (MissingValueException& e) {
         WOLF_WARN(e.what());
         WOLF_WARN("Support for subscribers disabled...");
     }
@@ -168,9 +174,12 @@ ProblemPtr Problem::autoSetup(ParamsServer &_server)
 
     // load raw libs
     std::vector<std::string> raw_libs;
-    try {
+    try
+    {
         raw_libs = _server.getParam<std::vector<std::string>>("raw_libs");
-    } catch (MissingValueException& e) {
+    } 
+    catch (MissingValueException& e) 
+    {
         WOLF_TRACE("No raw libraries to load...");
         raw_libs = std::vector<std::string>();
     }
@@ -196,11 +205,48 @@ ProblemPtr Problem::autoSetup(ParamsServer &_server)
                                   _server);
 
 
+    // Map (optional)
+    std::string map_type, map_plugin;
+    try
+    {
+        map_type = _server.getParam<std::string>("map/type");
+        map_plugin = _server.getParam<std::string>("map/plugin");
+    } 
+    catch (MissingValueException& e) 
+    {
+        WOLF_TRACE("No map/type and/or map/plugin specified. Emplacing the default map: MapBase.");
+        map_type = "MapBase";
+        map_plugin = "core";
+    }
+    WOLF_TRACE("Map Type: ", map_type, " in plugin ", map_plugin);
+    if (map_plugin != "core" and map_plugin != "wolf")
+    {
+        std::string plugin = plugins_path + "libwolf" + map_plugin + lib_extension;
+        WOLF_TRACE("Loading plugin " + plugin);
+        auto l = std::make_shared<LoaderRaw>(plugin);
+        l->load();
+        loaders.push_back(l);
+    }
+    auto map = AutoConfFactoryMap::create(map_type, _server);
+    map->setProblem(problem);
+    problem->setMap(map);
+
     // Tree manager
     std::string tree_manager_type = _server.getParam<std::string>("problem/tree_manager/type");
     WOLF_TRACE("Tree Manager Type: ", tree_manager_type);
     if (tree_manager_type != "None" and tree_manager_type != "none")
+    {
+        std::string tm_plugin = _server.getParam<std::string>("problem/tree_manager/plugin");
+        if (tm_plugin != "core" and tm_plugin != "wolf")
+        {
+            std::string plugin = plugins_path + "libwolf" + tm_plugin + lib_extension;
+            WOLF_TRACE("Loading plugin " + plugin);
+            auto l = std::make_shared<LoaderRaw>(plugin);
+            l->load();
+            loaders.push_back(l);
+        }
         problem->setTreeManager(AutoConfFactoryTreeManager::create(tree_manager_type, "tree manager", _server));
+    }
 
     // Set problem prior -- first keyframe
     std::string prior_mode = _server.getParam<std::string>("problem/prior/mode");
@@ -215,9 +261,6 @@ ProblemPtr Problem::autoSetup(ParamsServer &_server)
         problem->setPriorOptions(prior_mode,
                                  _server.getParam<VectorComposite>("problem/prior/state"),
                                  _server.getParam<VectorComposite>("problem/prior/sigma"));
-
-
-
     }
     else
     {
@@ -481,7 +524,15 @@ VectorComposite Problem::getState(const StateStructure& _structure) const
         for (const auto& pair_key_vec : prc_state)
         {
             if (state.count(pair_key_vec.first) == 0) // Only write once. This gives priority to processors with more priority
-                state.insert(pair_key_vec);
+            {  
+              state.insert(pair_key_vec);
+            }
+        }
+
+        //If all keys are filled return
+        if (state.size() == structure.size())
+        {
+            return state;
         }
     }
 
@@ -531,6 +582,12 @@ VectorComposite Problem::getState (const TimeStamp& _ts, const StateStructure& _
             if (state.count(pair_key_vec.first) == 0) // Only write once. This gives priority to processors with more priority
                 state.insert(pair_key_vec);
         }
+
+        //If all keys are filled return
+        if (state.size() == structure.size())
+        {
+            return state;
+        }
     }
 
     // check for empty blocks and fill them with the closest KF to ts, with the prior, or with zeros in the worst case
@@ -976,6 +1033,13 @@ MapBasePtr Problem::getMap() const
     return map_ptr_;
 }
 
+void Problem::setMap(MapBasePtr _map_ptr)
+{
+    assert(map_ptr_ == nullptr && "map has already been set");
+
+    map_ptr_ = _map_ptr;
+}
+
 TrajectoryBasePtr Problem::getTrajectory() const
 {
     return trajectory_ptr_;
diff --git a/src/processor/processor_fix_wing_model.cpp b/src/processor/processor_fixed_wing_model.cpp
similarity index 83%
rename from src/processor/processor_fix_wing_model.cpp
rename to src/processor/processor_fixed_wing_model.cpp
index 4c75926cc84925fa827f580a2d126ac294651d4b..4f67c52a8246ad06558e92cb4e43c1910b7e3baa 100644
--- a/src/processor/processor_fix_wing_model.cpp
+++ b/src/processor/processor_fixed_wing_model.cpp
@@ -26,7 +26,7 @@
  *      Author: joanvallve
  */
 
-#include "core/processor/processor_fix_wing_model.h"
+#include "core/processor/processor_fixed_wing_model.h"
 
 #include "core/capture/capture_base.h"
 #include "core/feature/feature_base.h"
@@ -35,22 +35,22 @@
 namespace wolf
 {
 
-ProcessorFixWingModel::ProcessorFixWingModel(ParamsProcessorFixWingModelPtr _params) :
-        ProcessorBase("ProcessorFixWingModel", 3, _params),
+ProcessorFixedWingModel::ProcessorFixedWingModel(ParamsProcessorFixedWingModelPtr _params) :
+        ProcessorBase("ProcessorFixedWingModel", 3, _params),
         params_processor_(_params)
 {
 }
 
-ProcessorFixWingModel::~ProcessorFixWingModel()
+ProcessorFixedWingModel::~ProcessorFixedWingModel()
 {
 }
 
-void ProcessorFixWingModel::configure(SensorBasePtr _sensor)
+void ProcessorFixedWingModel::configure(SensorBasePtr _sensor)
 {
     assert(_sensor->getProblem()->getFrameStructure().find('V') != std::string::npos && "Processor only works with problems with V");
 }
 
-void ProcessorFixWingModel::processKeyFrame(FrameBasePtr _keyframe_ptr)
+void ProcessorFixedWingModel::processKeyFrame(FrameBasePtr _keyframe_ptr)
 {
     if (_keyframe_ptr->getV()->isFixed())
         return;
@@ -81,7 +81,7 @@ void ProcessorFixWingModel::processKeyFrame(FrameBasePtr _keyframe_ptr)
 // Register in the FactoryProcessor
 #include "core/processor/factory_processor.h"
 namespace wolf {
-WOLF_REGISTER_PROCESSOR(ProcessorFixWingModel);
-WOLF_REGISTER_PROCESSOR_AUTO(ProcessorFixWingModel);
+WOLF_REGISTER_PROCESSOR(ProcessorFixedWingModel);
+WOLF_REGISTER_PROCESSOR_AUTO(ProcessorFixedWingModel);
 } // namespace wolf
 
diff --git a/src/sensor/sensor_model.cpp b/src/sensor/sensor_motion_model.cpp
similarity index 79%
rename from src/sensor/sensor_model.cpp
rename to src/sensor/sensor_motion_model.cpp
index 292f1a05e1bfd5aaf1931998106a505afaf10df8..d2f40087622650d8a500ba2418fff892f4cad88f 100644
--- a/src/sensor/sensor_model.cpp
+++ b/src/sensor/sensor_motion_model.cpp
@@ -19,18 +19,18 @@
 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
 //
 //--------LICENSE_END--------
-#include "core/sensor/sensor_model.h"
+#include "core/sensor/sensor_motion_model.h"
 
 namespace wolf {
 
 
-SensorModel::SensorModel() :
-    SensorBase("SensorModel", nullptr, nullptr, nullptr, 6)
+SensorMotionModel::SensorMotionModel() :
+    SensorBase("SensorMotionModel", nullptr, nullptr, nullptr, 6)
 {
     //
 }
 
-SensorModel::~SensorModel()
+SensorMotionModel::~SensorMotionModel()
 {
     //
 }
@@ -40,6 +40,6 @@ SensorModel::~SensorModel()
 // Register in the FactorySensor
 #include "core/sensor/factory_sensor.h"
 namespace wolf {
-WOLF_REGISTER_SENSOR(SensorModel);
-WOLF_REGISTER_SENSOR_AUTO(SensorModel);
+WOLF_REGISTER_SENSOR(SensorMotionModel);
+WOLF_REGISTER_SENSOR_AUTO(SensorMotionModel);
 }
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index a3da6a740948958190273e4526f997a6872a0cb1..9479b901549a8777580ab7455507a4f9a83a9567 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -68,10 +68,6 @@ target_link_libraries(gtest_factor_autodiff ${PLUGIN_NAME})
 wolf_add_gtest(gtest_factory_state_block gtest_factory_state_block.cpp)
 target_link_libraries(gtest_factory_state_block ${PLUGIN_NAME})
 
-# FeatureBase classes test
-wolf_add_gtest(gtest_eigen_predicates gtest_eigen_predicates.cpp)
-target_link_libraries(gtest_eigen_predicates ${PLUGIN_NAME})
-
 # Node Emplace test
 wolf_add_gtest(gtest_emplace gtest_emplace.cpp)
 target_link_libraries(gtest_emplace ${PLUGIN_NAME} dummy)
@@ -130,11 +126,16 @@ target_link_libraries(gtest_processor_motion ${PLUGIN_NAME})
   
 # Rotation test
 wolf_add_gtest(gtest_rotation gtest_rotation.cpp)
+target_link_libraries(gtest_rotation ${PLUGIN_NAME})
 
 # SE3 test
 wolf_add_gtest(gtest_SE3 gtest_SE3.cpp)
 target_link_libraries(gtest_SE3 ${PLUGIN_NAME})
 
+# SE2 test
+wolf_add_gtest(gtest_SE2 gtest_SE2.cpp)
+target_link_libraries(gtest_SE2 ${PLUGIN_NAME})
+
 # SensorBase test
 wolf_add_gtest(gtest_sensor_base gtest_sensor_base.cpp)
 target_link_libraries(gtest_sensor_base ${PLUGIN_NAME})
@@ -217,6 +218,10 @@ target_link_libraries(gtest_factor_relative_pose_2d_with_extrinsics ${PLUGIN_NAM
 wolf_add_gtest(gtest_factor_relative_pose_3d gtest_factor_relative_pose_3d.cpp)
 target_link_libraries(gtest_factor_relative_pose_3d ${PLUGIN_NAME})
 
+# FactorRelativePose3dWithExtrinsics class test
+wolf_add_gtest(gtest_factor_relative_pose_3d_with_extrinsics gtest_factor_relative_pose_3d_with_extrinsics.cpp)
+target_link_libraries(gtest_factor_relative_pose_3d_with_extrinsics ${PLUGIN_NAME})
+
 # FactorVelocityLocalDirection3d class test
 wolf_add_gtest(gtest_factor_velocity_local_direction_3d gtest_factor_velocity_local_direction_3d.cpp)
 target_link_libraries(gtest_factor_velocity_local_direction_3d ${PLUGIN_NAME})
@@ -233,11 +238,11 @@ target_link_libraries(gtest_map_yaml ${PLUGIN_NAME})
 wolf_add_gtest(gtest_param_prior gtest_param_prior.cpp)
 target_link_libraries(gtest_param_prior ${PLUGIN_NAME})
 
-# ProcessorDiffDriveSelfcalib class test
-wolf_add_gtest(gtest_processor_fix_wing_model gtest_processor_fix_wing_model.cpp)
-target_link_libraries(gtest_processor_fix_wing_model ${PLUGIN_NAME})
+# ProcessorFixedWingModel class test
+wolf_add_gtest(gtest_processor_fixed_wing_model gtest_processor_fixed_wing_model.cpp)
+target_link_libraries(gtest_processor_fixed_wing_model ${PLUGIN_NAME})
 
-# ProcessorFixWingModel class test
+# ProcessorDiffDrive class test
 wolf_add_gtest(gtest_processor_diff_drive gtest_processor_diff_drive.cpp)
 target_link_libraries(gtest_processor_diff_drive ${PLUGIN_NAME})
 
diff --git a/test/gtest_SE2.cpp b/test/gtest_SE2.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..690a5f373e2259c8cc2268c898b04f28c7c8fdc4
--- /dev/null
+++ b/test/gtest_SE2.cpp
@@ -0,0 +1,259 @@
+//--------LICENSE_START--------
+//
+// Copyright (C) 2020,2021,2022 Institut de Robòtica i Informàtica Industrial, CSIC-UPC.
+// Authors: Joan Solà Ortega (jsola@iri.upc.edu)
+// All rights reserved.
+//
+// This file is part of WOLF
+// WOLF is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+//--------LICENSE_END--------
+
+
+#include "core/math/SE2.h"
+#include "core/utils/utils_gtest.h"
+
+using namespace Eigen;
+using namespace wolf;
+using namespace SE2;
+
+TEST(SE2, exp)
+{
+    for (auto i = 1; i<10; i++)
+    {
+        double o = Vector1d::Random()(0) * M_PI;
+        ASSERT_MATRIX_APPROX(SO2::exp(o), Rotation2Dd(o).matrix(), 1e-8);
+    }
+}
+
+TEST(SE2, invBlocks)
+{
+    Vector2d p, ip;
+    double o, io;
+
+    // zero
+    p = Vector2d::Zero();
+    o = 0;
+
+    SE2::inverse(p,o,ip,io);
+    
+    ASSERT_MATRIX_APPROX(ip, Vector2d::Zero(), 1e-8);
+    ASSERT_NEAR(io, 0, 1e-8);
+
+    // zero angle
+    p = Vector2d::Random();
+    o = 0;
+
+    SE2::inverse(p,o,ip,io);
+    
+    ASSERT_MATRIX_APPROX(ip, -p, 1e-8);
+    ASSERT_NEAR(io, 0, 1e-8);
+
+    // zero translation
+    p = Vector2d::Zero();
+    o = Vector1d::Random()(0) * M_PI;
+
+    SE2::inverse(p,o,ip,io);
+    
+    ASSERT_MATRIX_APPROX(ip, Vector2d::Zero(), 1e-8);
+    ASSERT_NEAR(io, -o, 1e-8);
+
+    // random
+    for (auto i = 0; i < 10; i++)
+    {
+        p = Vector2d::Random();
+        o = Vector1d::Random()(0) * M_PI;
+
+        SE2::inverse(p,o,ip,io);
+        
+        ASSERT_MATRIX_APPROX(ip, Rotation2Dd(-o).matrix() * -p, 1e-8);
+        ASSERT_NEAR(io, -o, 1e-8);
+    }
+}
+
+TEST(SE2, invVector)
+{
+    Vector3d d, id;
+
+    // zero
+    d = Vector3d::Zero();
+
+    SE2::inverse(d,id);
+    
+    ASSERT_MATRIX_APPROX(id, Vector3d::Zero(), 1e-8);
+
+    // zero angle
+    d = Vector3d::Random();
+    d(2) = 0;
+
+    SE2::inverse(d,id);
+    
+    ASSERT_MATRIX_APPROX(id.head<2>(), -d.head<2>(), 1e-8);
+    ASSERT_NEAR(id(2), 0, 1e-8);
+
+    // zero translation
+    d = Vector3d::Zero();
+    d(2) = Vector1d::Random()(0) * M_PI;
+
+    SE2::inverse(d,id);
+    
+    ASSERT_MATRIX_APPROX(id.head<2>(), Vector2d::Zero(), 1e-8);
+    ASSERT_NEAR(id(2), -d(2), 1e-8);
+
+    // random
+    for (auto i = 0; i < 10; i++)
+    {
+        d = Vector3d::Random();
+        d(2) *= M_PI;
+
+        SE2::inverse(d,id);
+        
+        ASSERT_MATRIX_APPROX(id.head<2>(), Rotation2Dd(-d(2)) * -d.head<2>(), 1e-8);
+        ASSERT_NEAR(id(2), -d(2), 1e-8);
+    }
+}
+
+TEST(SE2, betweenBlocks)
+{
+    Vector2d p1, p2, pd;
+    double o1, o2, od;
+
+    // both origin: relative pose zero
+    p1 = Vector2d::Zero();
+    p2 = p1;
+    o1 = 0;
+    o2 = o1;
+    between(p1, o1, p2, o2, pd, od);
+
+    ASSERT_MATRIX_APPROX(pd, Vector2d::Zero(), 1e-8);
+    ASSERT_NEAR(od, 0, 1e-8);
+
+    // both same random pose: relative pose zero
+    for (auto i = 0; i < 10; i++)
+    {
+        p1 = Vector2d::Random();
+        p2 = p1;
+        o1 = Vector1d::Random()(0) * M_PI;
+        o2 = o1;
+
+        between(p1, o1, p2, o2, pd, od);
+
+        ASSERT_MATRIX_APPROX(pd, Vector2d::Zero(), 1e-8);
+        ASSERT_NEAR(od, 0, 1e-8);
+    }
+
+    // random relative pose
+    for (auto i = 0; i < 10; i++)
+    {
+        p1 = Vector2d::Random();
+        o1 = Vector1d::Random()(0) * M_PI;
+        Vector2d pd_gt = Vector2d::Random();
+        double od_gt = Vector1d::Random()(0) * M_PI;
+        
+        p2 = p1 + Rotation2Dd(o1) * pd_gt;
+        o2 = o1 + od_gt;
+
+        between(p1, o1, p2, o2, pd, od);
+
+        ASSERT_MATRIX_APPROX(pd, pd_gt, 1e-8);
+        ASSERT_NEAR(od, od_gt, 1e-8);
+    }
+}
+
+TEST(SE2, betweenVectors)
+{
+    Vector3d p1, p2, pd;
+
+    // both origin: relative pose zero
+    p1 = Vector3d::Zero();
+    p2 = p1;
+    between(p1, p2, pd);
+
+    ASSERT_MATRIX_APPROX(pd, Vector3d::Zero(), 1e-8);
+
+    // both same random pose: relative pose zero
+    for (auto i = 0; i < 10; i++)
+    {
+        p1 = Vector3d::Random();
+        p1(2) *= M_PI;
+        p2 = p1;
+
+        between(p1, p2, pd);
+
+        ASSERT_MATRIX_APPROX(pd, Vector3d::Zero(), 1e-8);
+    }
+
+    // random relative pose
+    for (auto i = 0; i < 10; i++)
+    {
+        p1 = Vector3d::Random();
+        p1(2) *= M_PI;
+        Vector3d pd_gt = Vector3d::Random();
+        pd_gt(2) *= M_PI;
+        
+        p2.head<2>() = p1.head<2>() + Rotation2Dd(p1(2)) * pd_gt.head<2>();
+        p2(2) = p1(2) + pd_gt(2);
+
+        between(p1, p2, pd);
+
+        ASSERT_MATRIX_APPROX(pd, pd_gt, 1e-8);
+    }
+}
+
+TEST(SE2, betweenVectorsReturn)
+{
+    Vector3d p1, p2, pd;
+
+    // both origin: relative pose zero
+    p1 = Vector3d::Zero();
+    p2 = p1;
+    pd = between(p1, p2);
+
+    ASSERT_MATRIX_APPROX(pd, Vector3d::Zero(), 1e-8);
+
+    // both same random pose: relative pose zero
+    for (auto i = 0; i < 10; i++)
+    {
+        p1 = Vector3d::Random();
+        p1(2) *= M_PI;
+        p2 = p1;
+
+        pd = between(p1, p2);
+
+        ASSERT_MATRIX_APPROX(pd, Vector3d::Zero(), 1e-8);
+    }
+
+    // random relative pose
+    for (auto i = 0; i < 10; i++)
+    {
+        p1 = Vector3d::Random();
+        p1(2) *= M_PI;
+        Vector3d pd_gt = Vector3d::Random();
+        pd_gt(2) *= M_PI;
+        
+        p2.head<2>() = p1.head<2>() + Rotation2Dd(p1(2)) * pd_gt.head<2>();
+        p2(2) = p1(2) + pd_gt(2);
+
+        pd = between(p1, p2);
+
+        ASSERT_MATRIX_APPROX(pd, pd_gt, 1e-8);
+    }
+}
+
+int main(int argc, char **argv)
+{
+  testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
+
diff --git a/test/gtest_eigen_predicates.cpp b/test/gtest_eigen_predicates.cpp
deleted file mode 100644
index 6dc7184ec5d1d39db31a2e26d06964023c26e65f..0000000000000000000000000000000000000000
--- a/test/gtest_eigen_predicates.cpp
+++ /dev/null
@@ -1,199 +0,0 @@
-//--------LICENSE_START--------
-//
-// Copyright (C) 2020,2021,2022 Institut de Robòtica i Informàtica Industrial, CSIC-UPC.
-// Authors: Joan Solà Ortega (jsola@iri.upc.edu)
-// All rights reserved.
-//
-// This file is part of WOLF
-// WOLF is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with this program.  If not, see <http://www.gnu.org/licenses/>.
-//
-//--------LICENSE_END--------
-#include "core/utils/utils_gtest.h"
-
-#include "core/utils/eigen_predicates.h"
-
-TEST(TestEigenPredicates, TestEigenDynPredZero)
-{
-  Eigen::MatrixXd A, B, C;
-
-  A = Eigen::MatrixXd::Zero(4,4);
-  B = Eigen::MatrixXd::Random(4,4);
-  C = Eigen::MatrixXd::Ones(4,4) * (wolf::Constants::EPS/2.);
-
-  EXPECT_TRUE(wolf::pred_zero(A,  wolf::Constants::EPS));
-  EXPECT_FALSE(wolf::pred_zero(B, wolf::Constants::EPS));
-  EXPECT_TRUE(wolf::pred_zero(C,  wolf::Constants::EPS));
-
-//  PRINT_TEST_FINISHED;
-}
-
-TEST(TestEigenPredicates, TestEigenFixPredZero)
-{
-  Eigen::MatrixXd A, B, C;
-
-  A = Eigen::Matrix4d::Zero();
-  B = Eigen::Matrix4d::Random();
-  C = Eigen::Matrix4d::Ones() * (wolf::Constants::EPS/2.);
-
-  EXPECT_TRUE(wolf::pred_zero(A,  wolf::Constants::EPS));
-  EXPECT_FALSE(wolf::pred_zero(B, wolf::Constants::EPS));
-  EXPECT_TRUE(wolf::pred_zero(C,  wolf::Constants::EPS));
-
-//  PRINT_TEST_FINISHED;
-}
-
-TEST(TestEigenPredicates, TestEigenDynPredDiffZero)
-{
-  Eigen::MatrixXd A, B, C;
-
-  A = Eigen::MatrixXd::Random(4,4);
-  B = Eigen::MatrixXd::Random(4,4);
-  C = A;
-
-  EXPECT_TRUE(wolf::pred_diff_zero(A, C, wolf::Constants::EPS));
-  EXPECT_FALSE(wolf::pred_diff_zero(A, B, wolf::Constants::EPS));
-
-//  PRINT_TEST_FINISHED;
-}
-
-TEST(TestEigenPredicates, TestEigenFixPredDiffZero)
-{
-  Eigen::MatrixXd A, B, C;
-
-  A = Eigen::Matrix4d::Random();
-  B = Eigen::Matrix4d::Random();
-  C = A;
-
-  EXPECT_TRUE(wolf::pred_diff_zero(A, C, wolf::Constants::EPS));
-  EXPECT_FALSE(wolf::pred_diff_zero(A, B, wolf::Constants::EPS));
-
-//  PRINT_TEST_FINISHED;
-}
-
-TEST(TestEigenPredicates, TestEigenDynPredDiffNorm)
-{
-  Eigen::MatrixXd A, B, C;
-
-  A = Eigen::MatrixXd::Random(4,4);
-  B = Eigen::MatrixXd::Random(4,4);
-  C = A;
-
-  EXPECT_TRUE(wolf::pred_diff_norm_zero(A, C, wolf::Constants::EPS));
-  EXPECT_FALSE(wolf::pred_diff_norm_zero(A, B, wolf::Constants::EPS));
-
-//  PRINT_TEST_FINISHED;
-}
-
-TEST(TestEigenPredicates, TestEigenFixPredDiffNorm)
-{
-  Eigen::MatrixXd A, B, C;
-
-  A = Eigen::Matrix4d::Random();
-  B = Eigen::Matrix4d::Random();
-  C = A;
-
-  EXPECT_TRUE(wolf::pred_diff_norm_zero(A, C, wolf::Constants::EPS));
-  EXPECT_FALSE(wolf::pred_diff_norm_zero(A, B, wolf::Constants::EPS));
-
-//  PRINT_TEST_FINISHED;
-}
-
-TEST(TestEigenPredicates, TestEigenDynPredIsApprox)
-{
-  Eigen::MatrixXd A, B, C;
-
-  A = Eigen::MatrixXd::Random(4,4);
-  B = Eigen::MatrixXd::Random(4,4);
-  C = A;
-
-  EXPECT_TRUE(wolf::pred_is_approx(A, C, wolf::Constants::EPS));
-  EXPECT_FALSE(wolf::pred_is_approx(A, B, wolf::Constants::EPS));
-
-//  PRINT_TEST_FINISHED;
-}
-
-TEST(TestEigenPredicates, TestEigenFixPredIsApprox)
-{
-  Eigen::MatrixXd A, B, C;
-
-  A = Eigen::Matrix4d::Random();
-  B = Eigen::Matrix4d::Random();
-  C = A;
-
-  EXPECT_TRUE(wolf::pred_is_approx(A, C, wolf::Constants::EPS));
-  EXPECT_FALSE(wolf::pred_is_approx(A, B, wolf::Constants::EPS));
-
-//  PRINT_TEST_FINISHED;
-}
-
-TEST(TestEigenPredicates, TestEigenPredQuatIsApprox)
-{
-  Eigen::Quaterniond A, B, C;
-
-  /// @todo which version of Eigen provides this ?
-//  A = Eigen::Quaterniond::UnitRandom();
-
-  A.coeffs() = Eigen::Vector4d::Random().normalized();
-  B.coeffs() = Eigen::Vector4d::Random().normalized();
-  C = A;
-
-  EXPECT_TRUE(wolf::pred_quat_is_approx(A, C, wolf::Constants::EPS));
-  EXPECT_FALSE(wolf::pred_quat_is_approx(A, B, wolf::Constants::EPS));
-
-//  PRINT_TEST_FINISHED;
-}
-
-TEST(TestEigenPredicates, TestEigenPredQuatIsIdentity)
-{
-  Eigen::Quaterniond A, B;
-
-  A = Eigen::Quaterniond::Identity();
-  B.coeffs() = Eigen::Vector4d::Random().normalized();
-
-  EXPECT_TRUE(wolf::pred_quat_identity(A, wolf::Constants::EPS));
-  EXPECT_FALSE(wolf::pred_quat_identity(B, wolf::Constants::EPS));
-
-//  PRINT_TEST_FINISHED;
-}
-
-TEST(TestEigenPredicates, TestEigenPredAngleIsApprox)
-{
-  double a = M_PI;
-  double b = -M_PI;
-  double c = 0;
-
-  EXPECT_TRUE(wolf::pred_angle_is_approx(a, b, wolf::Constants::EPS));
-  EXPECT_FALSE(wolf::pred_angle_is_approx(a, c, wolf::Constants::EPS));
-
-//  PRINT_TEST_FINISHED;
-}
-
-TEST(TestEigenPredicates, TestEigenPredAngleIsZero)
-{
-  double a = 0;
-  double b = M_PI;
-  double c = 2.*M_PI;
-
-  EXPECT_TRUE(wolf::pred_angle_zero(a, wolf::Constants::EPS));
-  EXPECT_FALSE(wolf::pred_angle_zero(b, wolf::Constants::EPS));
-  EXPECT_TRUE(wolf::pred_angle_zero(c, wolf::Constants::EPS));
-
-//  PRINT_TEST_FINISHED;
-}
-
-int main(int argc, char **argv)
-{
-  testing::InitGoogleTest(&argc, argv);
-  return RUN_ALL_TESTS();
-}
diff --git a/test/gtest_factor_relative_pose_3d_with_extrinsics.cpp b/test/gtest_factor_relative_pose_3d_with_extrinsics.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0f89a11003bd0e297ed6b3df283b6aba536ca5ea
--- /dev/null
+++ b/test/gtest_factor_relative_pose_3d_with_extrinsics.cpp
@@ -0,0 +1,325 @@
+//--------LICENSE_START--------
+//
+// Copyright (C) 2020,2021,2022 Institut de Robòtica i Informàtica Industrial, CSIC-UPC.
+// Authors: Joan Solà Ortega (jsola@iri.upc.edu)
+// All rights reserved.
+//
+// This file is part of WOLF
+// WOLF is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+//--------LICENSE_END--------
+#include <core/factor/factor_relative_pose_3d_with_extrinsics.h>
+#include <core/utils/utils_gtest.h>
+
+#include "core/common/wolf.h"
+#include "core/utils/logging.h"
+
+#include "core/state_block/state_quaternion.h"
+#include "core/ceres_wrapper/solver_ceres.h"
+#include "core/capture/capture_pose.h"
+#include "core/feature/feature_pose.h"
+
+
+
+using namespace Eigen;
+using namespace wolf;
+using std::static_pointer_cast;
+
+
+
+// Use the following in case you want to initialize tests with predefines variables or methods.
+class FactorRelativePose3dWithExtrinsics_class : public testing::Test{
+    public:
+        Vector3d    pos_camera,   pos_robot,   pos_landmark;
+        Vector3d    euler_camera, euler_robot, euler_landmark;
+        Quaterniond quat_camera,  quat_robot,  quat_landmark;
+        Vector4d    vquat_camera, vquat_robot, vquat_landmark; // quaternions as vectors
+        Vector7d    pose_camera,  pose_robot,  pose_landmark;
+
+        ProblemPtr     problem;
+        SolverCeresPtr solver;
+
+        SensorBasePtr   S;
+        FrameBasePtr    F1;
+        CapturePosePtr  c1;
+        FeaturePosePtr  f1;
+        LandmarkBasePtr lmk1;
+        FactorRelativePose3dWithExtrinsicsPtr fac;
+
+        Eigen::Matrix6d meas_cov;
+
+        void SetUp() override
+        {
+            // configuration
+
+             /* We have three poses to take into account:
+             *  - pose of the sensor (extrinsincs)
+             *  - pose of the landmark
+             *  - pose of the robot (Keyframe)
+             *
+             * The measurement provides the pose of the landmark wrt sensor's current pose in the world.
+             * Camera's current pose in World is the composition of the robot pose with the sensor extrinsics.
+             *
+             * The robot has a sensor looking forward
+             *   S: pos = (0,0,0), ori = (0, 0, 0)
+             *
+             * There is a point at the origin
+             *   P: pos = (0,0,0)
+             *
+             * Therefore, P projects exactly at the origin of the sensor,
+             *   f: p = (0,0)
+             *
+             * We form a Wolf tree with 1 frames F1, 1 capture C1,
+             * 1 feature f1 (measurement), 1 landmark l and 1 relative kf landmark constraint c1:
+             *
+             *   Frame F1, Capture C1, feature f1, landmark l1, constraint c1
+             *
+             * The frame pose F1, and the sensor pose S
+             * in the robot frame are variables subject to optimization
+             *
+             * We perform a number of tests based on this configuration.*/
+
+
+            // sensor is at origin of robot and looking forward
+            // robot is at (0,0,0)
+            // landmark is right in front of sensor. Its orientation wrt sensor is identity.
+            pos_camera      << 0,0,0;
+            pos_robot       << 0,0,0; //robot is at origin
+            pos_landmark    << 0,1,0;
+            euler_camera    << 0,0,0;
+            //euler_camera    << -M_PI_2, 0, -M_PI_2;
+            euler_robot     << 0,0,0;
+            euler_landmark  << 0,0,0;
+            quat_camera     = e2q(euler_camera);
+            quat_robot      = e2q(euler_robot);
+            quat_landmark   = e2q(euler_landmark);
+            vquat_camera    = quat_camera.coeffs();
+            vquat_robot     = quat_robot.coeffs();
+            vquat_landmark  = quat_landmark.coeffs();
+            pose_camera     << pos_camera, vquat_camera;
+            pose_robot      << pos_robot, vquat_robot;
+            pose_landmark   << pos_landmark, vquat_landmark;
+
+            // Build problem
+            problem = Problem::create("PO", 3);
+            solver = std::make_shared<SolverCeres>(problem);
+
+            // Create sensor to be able to initialize (a camera for instance)
+            S = SensorBase::emplace<SensorBase>(problem->getHardware(), "SensorPose", 
+                                                std::make_shared<StateBlock>(pos_camera, true), 
+                                                std::make_shared<StateQuaternion>(vquat_camera, true), 
+                                                std::make_shared<StateBlock>(Vector4d::Zero(), false),  // fixed
+                                                Vector1d::Zero());
+
+            // ParamsSensorCameraPtr params_camera = std::make_shared<ParamsSensorCamera>();
+            // S      = problem->installSensor("SensorCamera", "canonical", pose_camera, params_camera);
+            // camera = std::static_pointer_cast<SensorCamera>(S);
+
+
+            // F1 is be origin KF
+            VectorComposite x0(pose_robot, "PO", {3,4});
+            VectorComposite s0("PO", {Vector3d(1,1,1), Vector3d(1,1,1)});
+            F1 = problem->setPriorFactor(x0, s0, 0.0);
+
+
+            // the sensor is at origin as well as the robot. The measurement matches with the pose of the tag wrt sensor (and also wrt robot and world)
+            meas_cov = Eigen::Matrix6d::Identity();
+            meas_cov.topLeftCorner(3,3)     *= 1e-2;
+            meas_cov.bottomRightCorner(3,3) *= 1e-3;
+
+            //emplace feature and landmark
+            c1 = std::static_pointer_cast<CapturePose>(CaptureBase::emplace<CapturePose>(F1, 0, S, pose_landmark, meas_cov));
+            f1 = std::static_pointer_cast<FeaturePose>(FeatureBase::emplace<FeaturePose>(c1, pose_landmark, meas_cov));
+            lmk1 = LandmarkBase::emplace<LandmarkBase>(problem->getMap(), "LandmarkPose",  
+                                                       std::make_shared<StateBlock>(pos_landmark), 
+                                                       std::make_shared<StateQuaternion>(Quaterniond(vquat_landmark)));
+        }
+};
+
+
+TEST_F(FactorRelativePose3dWithExtrinsics_class, Constructor)
+{
+    auto factor = std::make_shared<FactorRelativePose3dWithExtrinsics>(f1,
+                                                                       lmk1,
+                                                                       nullptr,
+                                                                       false);
+
+    ASSERT_TRUE(factor->getType() == "FactorRelativePose3dWithExtrinsics");
+}
+
+/////////////////////////////////////////////
+// Tree not ok with this gtest implementation
+/////////////////////////////////////////////
+TEST_F(FactorRelativePose3dWithExtrinsics_class, Check_tree)
+{
+    ASSERT_TRUE(problem->check(1));
+
+    auto factor = FactorBase::emplace<FactorRelativePose3dWithExtrinsics>(f1,
+                                                                          f1,
+                                                                          lmk1,
+                                                                          nullptr,
+                                                                          false);
+    ASSERT_TRUE(problem->check(1));
+}
+
+TEST_F(FactorRelativePose3dWithExtrinsics_class, solve_F1_P_perturbated)
+{
+    auto factor = FactorBase::emplace<FactorRelativePose3dWithExtrinsics>(f1,
+                                                                          f1,
+                                                                          lmk1,
+                                                                          nullptr,
+                                                                          false);
+
+    // unfix F1, perturbate state
+    F1->unfix();
+    F1->getP()->perturb();
+
+    std::string report = solver->solve(SolverManager::ReportVerbosity::QUIET); // 0: nothing, 1: BriefReport, 2: FullReport
+    ASSERT_MATRIX_APPROX(F1->getState().vector("PO"), pose_robot, 1e-6);
+}
+
+TEST_F(FactorRelativePose3dWithExtrinsics_class, solve_F1_O_perturbated)
+{
+    auto factor = FactorBase::emplace<FactorRelativePose3dWithExtrinsics>(f1,
+                                                                          f1,
+                                                                          lmk1,
+                                                                          nullptr,
+                                                                          false);
+
+    // unfix F1, perturbate state
+    F1->unfix();
+    F1->getO()->perturb();
+
+    std::string report = solver->solve(SolverManager::ReportVerbosity::QUIET); // 0: nothing, 1: BriefReport, 2: FullReport
+    ASSERT_MATRIX_APPROX(F1->getState().vector("PO"), pose_robot, 1e-6);
+}
+
+TEST_F(FactorRelativePose3dWithExtrinsics_class, Check_initialization)
+{
+    auto factor = FactorBase::emplace<FactorRelativePose3dWithExtrinsics>(f1,
+                                                                          f1,
+                                                                          lmk1,
+                                                                          nullptr,
+                                                                          false);
+
+    ASSERT_MATRIX_APPROX(F1->getState().vector("PO"), pose_robot, 1e-6);
+    ASSERT_MATRIX_APPROX(f1->getMeasurement(), pose_landmark, 1e-6);
+    ASSERT_MATRIX_APPROX(lmk1->getState().vector("PO"), pose_landmark, 1e-6);
+
+}
+
+TEST_F(FactorRelativePose3dWithExtrinsics_class, solve_L1_P_perturbated)
+{
+    auto factor = FactorBase::emplace<FactorRelativePose3dWithExtrinsics>(f1,
+                                                                          f1,
+                                                                          lmk1,
+                                                                          nullptr,
+                                                                          false);
+
+    // unfix lmk1, perturbate state
+    lmk1->unfix();
+    lmk1->getP()->perturb();
+
+    std::string report = solver->solve(SolverManager::ReportVerbosity::QUIET); // 0: nothing, 1: BriefReport, 2: FullReport
+    ASSERT_MATRIX_APPROX(F1->getState().vector("PO"), pose_robot, 1e-6);
+    ASSERT_MATRIX_APPROX(lmk1->getState().vector("PO"), pose_landmark, 1e-6);
+}
+
+TEST_F(FactorRelativePose3dWithExtrinsics_class, solve_L1_O_perturbated)
+{
+    auto factor = FactorBase::emplace<FactorRelativePose3dWithExtrinsics>(f1,
+                                                                          f1,
+                                                                          lmk1,
+                                                                          nullptr,
+                                                                          false);
+
+    // unfix F1, perturbate state
+    lmk1->unfix();
+    lmk1->getO()->perturb();
+
+    std::string report = solver->solve(SolverManager::ReportVerbosity::QUIET); // 0: nothing, 1: BriefReport, 2: FullReport
+    ASSERT_MATRIX_APPROX(F1->getState().vector("PO"), pose_robot, 1e-6);
+    ASSERT_MATRIX_APPROX(lmk1->getState().vector("PO"), pose_landmark, 1e-6);
+
+}
+
+TEST_F(FactorRelativePose3dWithExtrinsics_class, solve_L1_PO_perturbated)
+{
+    // Change setup
+    Vector3d p_w_r, p_r_c, p_c_l, p_w_l;
+    Quaterniond q_w_r, q_r_c, q_c_l, q_w_l;
+    p_w_r << 1, 2, 3;
+    p_r_c << 4, 5, 6;
+    p_c_l << 7, 8, 9;
+    q_w_r.coeffs() << 1, 2, 3, 4; q_w_r.normalize();
+    q_r_c.coeffs() << 4, 5, 6, 7; q_r_c.normalize();
+    q_c_l.coeffs() << 7, 8, 9, 0; q_c_l.normalize();
+
+    q_w_l = q_w_r * q_r_c * q_c_l;
+    p_w_l = p_w_r + q_w_r * (p_r_c + q_r_c * p_c_l);
+
+    // Change feature (remove and emplace)
+    Vector7d meas;
+    meas << p_c_l, q_c_l.coeffs();
+    f1->remove();
+    f1 = std::static_pointer_cast<FeaturePose>(FeatureBase::emplace<FeaturePose>(c1, meas, meas_cov));
+
+    // emplace factor
+    auto factor = FactorBase::emplace<FactorRelativePose3dWithExtrinsics>(f1,
+                                                                          f1,
+                                                                          lmk1,
+                                                                          nullptr,
+                                                                          false);
+
+    // Change Landmark
+    lmk1->getP()->setState(p_w_l);
+    lmk1->getO()->setState(q_w_l.coeffs());
+    ASSERT_TRUE(lmk1->getP()->stateUpdated());
+    ASSERT_TRUE(lmk1->getO()->stateUpdated());
+
+    // Change Frame
+    F1->getP()->setState(p_w_r);
+    F1->getO()->setState(q_w_r.coeffs());
+    F1->fix();
+    ASSERT_TRUE(F1->getP()->stateUpdated());
+    ASSERT_TRUE(F1->getO()->stateUpdated());
+
+    // Change sensor extrinsics
+    S->getP()->setState(p_r_c);
+    S->getO()->setState(q_r_c.coeffs());
+    ASSERT_TRUE(S->getP()->stateUpdated());
+    ASSERT_TRUE(S->getO()->stateUpdated());
+
+    Vector7d t_w_r, t_w_l;
+    t_w_r << p_w_r, q_w_r.coeffs();
+    t_w_l << p_w_l, q_w_l.coeffs();
+    ASSERT_MATRIX_APPROX(F1->getState().vector("PO"), t_w_r, 1e-6);
+    ASSERT_MATRIX_APPROX(lmk1->getState().vector("PO"), t_w_l, 1e-6);
+
+    // unfix LMK, perturbate state
+    lmk1->unfix();
+    lmk1->perturb();
+
+    std::string report = solver->solve(SolverManager::ReportVerbosity::QUIET); // 0: nothing, 1: BriefReport, 2: FullReport
+    ASSERT_MATRIX_APPROX(F1->getState().vector("PO").transpose(), t_w_r.transpose(), 1e-6);
+    ASSERT_MATRIX_APPROX(lmk1->getState().vector("PO").transpose(), t_w_l.transpose(), 1e-6);
+
+}
+
+int main(int argc, char **argv)
+{
+    testing::InitGoogleTest(&argc, argv);
+    return RUN_ALL_TESTS();
+}
+
diff --git a/test/gtest_problem.cpp b/test/gtest_problem.cpp
index d5fa0054e26e64664dba42b3d0fc66a717bd8709..d86942de20f525f0b0995e2a5b43e18750311697 100644
--- a/test/gtest_problem.cpp
+++ b/test/gtest_problem.cpp
@@ -512,11 +512,35 @@ TEST(Problem, check)
     ASSERT_TRUE(problem->check(true, std::cout));
 }
 
+TEST(Problem, autoSetupMap)
+{
+    std::string wolf_root = _WOLF_ROOT_DIR;
+
+    auto parser = ParserYaml("test/yaml/params_problem_autosetup.yaml", wolf_root);
+    auto server = ParamsServer(parser.getParams());
+
+    auto P = Problem::autoSetup(server);
+
+    ASSERT_TRUE(P->check(true, std::cout));
+}
+
+TEST(Problem, autoSetupNoMap)
+{
+    std::string wolf_root = _WOLF_ROOT_DIR;
+
+    auto parser = ParserYaml("test/yaml/params_problem_autosetup_no_map.yaml", wolf_root);
+    auto server = ParamsServer(parser.getParams());
+
+    auto P = Problem::autoSetup(server);
+
+    ASSERT_TRUE(P->check(true, std::cout));
+}
+
 TEST(Problem, getState)
 {
     std::string wolf_root = _WOLF_ROOT_DIR;
 
-    auto parser = ParserYaml("test/yaml/params_problem_odom_3d.yaml", wolf_root);
+    auto parser = ParserYaml("test/yaml/params_problem_autosetup.yaml", wolf_root);
     auto server = ParamsServer(parser.getParams());
 
     auto P = Problem::autoSetup(server);
diff --git a/test/gtest_processor_fix_wing_model.cpp b/test/gtest_processor_fixed_wing_model.cpp
similarity index 94%
rename from test/gtest_processor_fix_wing_model.cpp
rename to test/gtest_processor_fixed_wing_model.cpp
index 41eaed71fd6bb47d2353bb6818349daad0aae326..b2bcb1990ccd266756c7f106478b79aadff3cc88 100644
--- a/test/gtest_processor_fix_wing_model.cpp
+++ b/test/gtest_processor_fixed_wing_model.cpp
@@ -23,12 +23,12 @@
 #include "core/utils/utils_gtest.h"
 #include "core/problem/problem.h"
 #include "core/ceres_wrapper/solver_ceres.h"
-#include "core/processor/processor_fix_wing_model.h"
 #include "core/state_block/state_quaternion.h"
 
 // STL
 #include <iterator>
 #include <iostream>
+#include "../include/core/processor/processor_fixed_wing_model.h"
 
 using namespace wolf;
 using namespace Eigen;
@@ -58,11 +58,11 @@ class ProcessorFixWingModelTest : public testing::Test
                                                      2);
 
             // Emplace processor
-            ParamsProcessorFixWingModelPtr params = std::make_shared<ParamsProcessorFixWingModel>();
+            ParamsProcessorFixedWingModelPtr params = std::make_shared<ParamsProcessorFixedWingModel>();
             params->velocity_local = (Vector3d() << 1, 0, 0).finished();
             params->angle_stdev = 0.1;
             params->min_vel_norm = 0;
-            processor = ProcessorBase::emplace<ProcessorFixWingModel>(sensor, params);
+            processor = ProcessorBase::emplace<ProcessorFixedWingModel>(sensor, params);
         }
 
         FrameBasePtr emplaceFrame(TimeStamp ts, const Vector10d& x)
diff --git a/test/yaml/params_problem_autosetup.yaml b/test/yaml/params_problem_autosetup.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..c61eab58146a9a5917c1130a14e234afa08a01b6
--- /dev/null
+++ b/test/yaml/params_problem_autosetup.yaml
@@ -0,0 +1,49 @@
+config:
+  problem:
+    frame_structure: "PO"
+    dimension: 3
+    prior:
+      mode: "factor"
+      $state:
+        P: [0,0,0]
+        O: [0,0,0,1]
+      $sigma:
+        P: [0.31, 0.31, 0.31]
+        O: [0.31, 0.31, 0.31]
+      time_tolerance: 0.1
+    tree_manager: 
+      type: "None"
+  map:
+    type: "MapBase"
+    plugin: "core"
+  sensors: 
+    -
+      type: "SensorOdom3d"
+      name: "odom"
+      plugin: "core"
+      k_disp_to_disp: 0.1
+      k_disp_to_rot: 0.1
+      k_rot_to_rot: 0.1 
+      min_disp_var: 0.1 
+      min_rot_var: 0.1
+      extrinsic:
+        pose: [1,2,3,0,0,0,1]
+  processors:
+    -
+      type: "ProcessorOdom3d"
+      name: "my_proc_odom3d"
+      sensor_name: "odom"
+      plugin: "core"
+      apply_loss_function: false
+      time_tolerance:         0.01  # seconds
+      keyframe_vote:
+        voting_active:        true
+        max_time_span:          1.95  # seconds
+        max_buff_length:        999   # motion deltas
+        dist_traveled:          999   # meters
+        angle_turned:           999   # radians (1 rad approx 57 deg, approx 60 deg)
+      
+      unmeasured_perturbation_std: 0.00111
+      
+      state_getter: true
+      state_priority: 1
diff --git a/test/yaml/params_problem_autosetup_no_map.yaml b/test/yaml/params_problem_autosetup_no_map.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..6c5ed47c2efc2afc3ba960b075e60cea73b58a73
--- /dev/null
+++ b/test/yaml/params_problem_autosetup_no_map.yaml
@@ -0,0 +1,46 @@
+config:
+  problem:
+    frame_structure: "PO"
+    dimension: 3
+    prior:
+      mode: "factor"
+      $state:
+        P: [0,0,0]
+        O: [0,0,0,1]
+      $sigma:
+        P: [0.31, 0.31, 0.31]
+        O: [0.31, 0.31, 0.31]
+      time_tolerance: 0.1
+    tree_manager: 
+      type: "None"
+  sensors: 
+    -
+      type: "SensorOdom3d"
+      name: "odom"
+      plugin: "core"
+      k_disp_to_disp: 0.1
+      k_disp_to_rot: 0.1
+      k_rot_to_rot: 0.1 
+      min_disp_var: 0.1 
+      min_rot_var: 0.1
+      extrinsic:
+        pose: [1,2,3,0,0,0,1]
+  processors:
+    -
+      type: "ProcessorOdom3d"
+      name: "my_proc_odom3d"
+      sensor_name: "odom"
+      plugin: "core"
+      apply_loss_function: false
+      time_tolerance:         0.01  # seconds
+      keyframe_vote:
+        voting_active:        true
+        max_time_span:          1.95  # seconds
+        max_buff_length:        999   # motion deltas
+        dist_traveled:          999   # meters
+        angle_turned:           999   # radians (1 rad approx 57 deg, approx 60 deg)
+      
+      unmeasured_perturbation_std: 0.00111
+      
+      state_getter: true
+      state_priority: 1
diff --git a/test/yaml/params_tree_manager1.yaml b/test/yaml/params_tree_manager1.yaml
index fa43fecb397dff295b683cfcd6a282adac61cc44..59aec3c70cee0e147e38dbfb9408c8879bc203e2 100644
--- a/test/yaml/params_tree_manager1.yaml
+++ b/test/yaml/params_tree_manager1.yaml
@@ -17,6 +17,7 @@ config:
       time_tolerance: 0.1
     tree_manager:
       type: "TreeManagerDummy"
+      plugin: "core"
       toy_param: 0
   sensors: 
     -
diff --git a/test/yaml/params_tree_manager2.yaml b/test/yaml/params_tree_manager2.yaml
index f37e31459d9a883aca9eb12898aa5ac285e63210..419125468ba5155eba8f0f75c972a5d52b5dbcef 100644
--- a/test/yaml/params_tree_manager2.yaml
+++ b/test/yaml/params_tree_manager2.yaml
@@ -15,7 +15,7 @@ config:
         O: [0.31, 0.31, 0.31]
         V: [0.31, 0.31, 0.31]
       time_tolerance: 0.1
-    tree_manager: 
+    tree_manager:
       type: "None"
   sensors: 
     -
diff --git a/test/yaml/params_tree_manager_sliding_window1.yaml b/test/yaml/params_tree_manager_sliding_window1.yaml
index 277810464d6f619ed342ce3706bec30d7ca8e5f9..61498d1b6c182a6ae95930047940c56bcc3ca4ae 100644
--- a/test/yaml/params_tree_manager_sliding_window1.yaml
+++ b/test/yaml/params_tree_manager_sliding_window1.yaml
@@ -13,6 +13,7 @@ config:
       time_tolerance: 0.1
     tree_manager:
       type: "TreeManagerSlidingWindow"
+      plugin: "core"
       n_frames: 3
       n_fix_first_frames: 2
       viral_remove_empty_parent: true
diff --git a/test/yaml/params_tree_manager_sliding_window2.yaml b/test/yaml/params_tree_manager_sliding_window2.yaml
index f22fdde12f065d17accb122ef7f8d1728ef6fb6c..db0a176fce7534934e9a10da0c5f84a5ae431517 100644
--- a/test/yaml/params_tree_manager_sliding_window2.yaml
+++ b/test/yaml/params_tree_manager_sliding_window2.yaml
@@ -13,6 +13,7 @@ config:
       time_tolerance: 0.1
     tree_manager:
       type: "TreeManagerSlidingWindow"
+      plugin: "core"
       n_frames: 3
       n_fix_first_frames: 0
       viral_remove_empty_parent: false
diff --git a/test/yaml/params_tree_manager_sliding_window_dual_rate1.yaml b/test/yaml/params_tree_manager_sliding_window_dual_rate1.yaml
index a7f0f7434fb8a71c74e3aa3f15b8dc9f6ea7c067..2b6313f5b9702ab0f7c3dc0187dbde23ae944d00 100644
--- a/test/yaml/params_tree_manager_sliding_window_dual_rate1.yaml
+++ b/test/yaml/params_tree_manager_sliding_window_dual_rate1.yaml
@@ -13,6 +13,7 @@ config:
       time_tolerance: 0.1
     tree_manager:
       type: "TreeManagerSlidingWindowDualRate"
+      plugin: "core"
       n_frames: 5
       n_frames_recent: 3
       rate_old_frames: 2
diff --git a/test/yaml/params_tree_manager_sliding_window_dual_rate2.yaml b/test/yaml/params_tree_manager_sliding_window_dual_rate2.yaml
index cae3df67f036430481cd936ea31a9d2b4c0bca9a..609fb96f585545376756279956377ee6730dbc0d 100644
--- a/test/yaml/params_tree_manager_sliding_window_dual_rate2.yaml
+++ b/test/yaml/params_tree_manager_sliding_window_dual_rate2.yaml
@@ -13,6 +13,7 @@ config:
       time_tolerance: 0.1
     tree_manager:
       type: "TreeManagerSlidingWindowDualRate"
+      plugin: "core"
       n_frames: 5
       n_frames_recent: 3
       rate_old_frames: 2
diff --git a/test/yaml/params_tree_manager_sliding_window_dual_rate3.yaml b/test/yaml/params_tree_manager_sliding_window_dual_rate3.yaml
index 0b030b80faa8a5f63dfa4c60aa19bcfd3c81a9b0..aed7a0c7e4da1313e261501c87e3748fb64cd2b5 100644
--- a/test/yaml/params_tree_manager_sliding_window_dual_rate3.yaml
+++ b/test/yaml/params_tree_manager_sliding_window_dual_rate3.yaml
@@ -15,6 +15,7 @@ config:
       time_tolerance: 0.1
     tree_manager:
       type: "TreeManagerSlidingWindowDualRate"
+      plugin: "core"
       n_frames: 5
       n_frames_recent: 3
       rate_old_frames: 2