diff --git a/CMakeLists.txt b/CMakeLists.txt
index 24bac9581829cc4fadb2eb007fd15c1e88b8adec..261e7816bda8c492d043c0a3f7e26a47821cc120 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -192,7 +192,7 @@ SET(HDRS_PROCESSOR
   )
 SET(HDRS_SENSOR
   include/${PROJECT_NAME}/sensor/factory_sensor.h
-  include/${PROJECT_NAME}/sensor/prior_sensor.h
+  include/${PROJECT_NAME}/sensor/spec_state_sensor.h
   include/${PROJECT_NAME}/sensor/sensor_base.h
   include/${PROJECT_NAME}/sensor/sensor_diff_drive.h
   include/${PROJECT_NAME}/sensor/sensor_motion_model.h
@@ -210,7 +210,7 @@ SET(HDRS_STATE_BLOCK
   include/${PROJECT_NAME}/state_block/local_parametrization_base.h
   include/${PROJECT_NAME}/state_block/local_parametrization_homogeneous.h
   include/${PROJECT_NAME}/state_block/local_parametrization_quaternion.h
-  include/${PROJECT_NAME}/state_block/prior.h
+  include/${PROJECT_NAME}/state_block/spec_composite.h
   include/${PROJECT_NAME}/state_block/state_angle.h
   include/${PROJECT_NAME}/state_block/state_block.h
   include/${PROJECT_NAME}/state_block/state_block_derived.h
@@ -302,7 +302,7 @@ SET(SRCS_PROCESSOR
   src/processor/track_matrix.cpp
   )
 SET(SRCS_SENSOR
-  src/sensor/prior_sensor.cpp
+  src/sensor/spec_state_sensor.cpp
   src/sensor/sensor_base.cpp
   src/sensor/sensor_diff_drive.cpp
   src/sensor/sensor_motion_model.cpp
@@ -315,7 +315,7 @@ SET(SRCS_STATE_BLOCK
   src/state_block/local_parametrization_base.cpp
   src/state_block/local_parametrization_homogeneous.cpp
   src/state_block/local_parametrization_quaternion.cpp
-  src/state_block/prior.cpp
+  src/state_block/spec_composite.cpp
   src/state_block/state_block.cpp
   src/state_block/state_block_derived.cpp
   src/state_block/state_composite.cpp
diff --git a/demos/hello_wolf/hello_wolf.cpp b/demos/hello_wolf/hello_wolf.cpp
index 91d99685abded46079b5431c615abef6df155e9f..dde271376d13561d0055aea7f67dfe37a6fdcf4e 100644
--- a/demos/hello_wolf/hello_wolf.cpp
+++ b/demos/hello_wolf/hello_wolf.cpp
@@ -130,8 +130,8 @@ int main()
 
     // sensor odometer 2d
     ParamsSensorOdomPtr intrinsics_odo      = std::make_shared<ParamsSensorOdom>();
-    PriorSensorMap priors_odo                       = {{'P',PriorSensor("P", Vector2d::Zero())},
-                                               {'O',PriorSensor("O", Vector1d::Zero())}};
+    SpecSensorComposite priors_odo                       = {{'P',SpecStateSensor("P", Vector2d::Zero())},
+                                               {'O',SpecStateSensor("O", Vector1d::Zero())}};
     SensorBasePtr sensor_odo                = problem->installSensor("SensorOdom", "sensor odo", intrinsics_odo, priors_odo);
 
     // processor odometer 2d
@@ -147,8 +147,8 @@ int main()
 
     // sensor Range and Bearing
     ParamsSensorRangeBearingPtr intrinsics_rb = std::make_shared<ParamsSensorRangeBearing>();
-    PriorSensorMap priors_rb                          = {{'P',PriorSensor("P", Vector2d(1,1))},
-                                                 {'O',PriorSensor("O", Vector1d::Zero())}};
+    SpecSensorComposite priors_rb                          = {{'P',SpecStateSensor("P", Vector2d(1,1))},
+                                                 {'O',SpecStateSensor("O", Vector1d::Zero())}};
     intrinsics_rb->noise_range_metres_std     = 0.1;
     intrinsics_rb->noise_bearing_degrees_std  = 1.0;
     SensorBasePtr sensor_rb                   = problem->installSensor("SensorRangeBearing", "sensor RB", intrinsics_rb, priors_rb);
diff --git a/demos/hello_wolf/sensor_range_bearing.cpp b/demos/hello_wolf/sensor_range_bearing.cpp
index 39527e6c9d024cd5972bfa9bdcf90ed4fd2d60e3..0738c4418483859406db657530110b7199afaf74 100644
--- a/demos/hello_wolf/sensor_range_bearing.cpp
+++ b/demos/hello_wolf/sensor_range_bearing.cpp
@@ -27,7 +27,7 @@ WOLF_PTR_TYPEDEFS(SensorRangeBearing);
 
 SensorRangeBearing::SensorRangeBearing(const SizeEigen& _dim,
                                        ParamsSensorRangeBearingPtr _params,
-                                       const PriorSensorMap& _priors) :
+                                       const SpecSensorComposite& _priors) :
         SensorBase("SensorRangeBearing", _dim, _params, _priors),
         params_rb_(_params)
 {
diff --git a/demos/hello_wolf/sensor_range_bearing.h b/demos/hello_wolf/sensor_range_bearing.h
index 5b407dd50603bd50337b42a6486aa6e6f4a644f4..75d6e773108834161c60e5601ef657a42b8cd7cc 100644
--- a/demos/hello_wolf/sensor_range_bearing.h
+++ b/demos/hello_wolf/sensor_range_bearing.h
@@ -58,7 +58,7 @@ class SensorRangeBearing : public SensorBase
     public:
         SensorRangeBearing(const SizeEigen& _dim,
                            ParamsSensorRangeBearingPtr _params,
-                           const PriorSensorMap& _priors);
+                           const SpecSensorComposite& _priors);
         WOLF_SENSOR_CREATE(SensorRangeBearing, ParamsSensorRangeBearing);
         
         ~SensorRangeBearing() override;
diff --git a/demos/hello_wolf/yaml/hello_wolf_config.yaml b/demos/hello_wolf/yaml/hello_wolf_config.yaml
index f01ad2b227a8824025d6d1aa0b2f415cde34c2c6..33889188f950760ec83fe03119313dbbe494d832 100644
--- a/demos/hello_wolf/yaml/hello_wolf_config.yaml
+++ b/demos/hello_wolf/yaml/hello_wolf_config.yaml
@@ -5,7 +5,7 @@ config:
     dimension:            2               # space is 2d
     frame_structure:      "PO"            # keyframes have position and orientation
   
-    prior:
+    first_frame:
       mode:               "factor"
       $state:
         P: [0,0]
diff --git a/include/core/frame/frame_base.h b/include/core/frame/frame_base.h
index 97d76c632258a5ed7177c6f8230f26ce79f6aaff..2a468a08be01670400227919182bbe04f4caa917 100644
--- a/include/core/frame/frame_base.h
+++ b/include/core/frame/frame_base.h
@@ -70,13 +70,36 @@ class FrameBase : public NodeBase, public HasStateBlocks, public std::enable_sha
                   StateBlockPtr _o_ptr = nullptr,
                   StateBlockPtr _v_ptr = nullptr);
 
+        /** \brief Constructor with type, time stamp and state pointer
+         * 
+         * Constructor with type, time stamp and state pointer
+         * \param _ts is the time stamp associated to this frame, provided in seconds
+         * \param _frame_structure StateStructure (string) with the state keys
+         * \param _state VectorComposite containing the state of each key
+         **/   
         FrameBase(const TimeStamp& _ts,
                   const StateStructure& _frame_structure,
                   const VectorComposite& _state);
 
+        /** \brief Constructor with type, time stamp and state pointer
+         * 
+         * Constructor with type, time stamp and state pointer
+         * \param _ts is the time stamp associated to this frame, provided in seconds
+         * \param _frame_structure StateStructure (string) with the state keys
+         * \param _vectors std::list of VectorXd containing the state of each key
+         **/   
         FrameBase(const TimeStamp& _ts,
                   const StateStructure& _frame_structure,
                   const std::list<VectorXd>& _vectors);
+        
+        /** \brief Constructor time stamp and specs composite
+         * 
+         * Constructor with time stamp and specs composite
+         * \param _ts is the time stamp associated to this frame, provided in seconds
+         * \param _frame_specs SpecComposite containing all information needed to create the state blocs.
+         **/             
+        FrameBase(const TimeStamp& _ts,
+                  const SpecComposite& _frame_specs);
 
         ~FrameBase() override;
 
diff --git a/include/core/problem/problem.h b/include/core/problem/problem.h
index 6bfabeb1f79dd845c3c36760bb289673b79256f8..3b2799e311f30b35105f14d56a2974b590599ebf 100644
--- a/include/core/problem/problem.h
+++ b/include/core/problem/problem.h
@@ -38,8 +38,8 @@ class Loader;
 //wolf includes
 #include "core/common/wolf.h"
 #include "core/frame/frame_base.h"
-#include "core/state_block/prior.h"
 #include "core/state_block/state_block.h"
+#include "core/state_block/spec_composite.h"
 #include "core/state_block/state_composite.h"
 #include "core/processor/motion_provider.h"
 
@@ -79,7 +79,7 @@ class Problem : public std::enable_shared_from_this<Problem>
         mutable std::mutex mut_notifications_;
         mutable std::mutex mut_covariances_;
         StateStructure frame_structure_;
-        PriorMap prior_options_;
+        SpecComposite prior_options_;
         bool prior_applied_;
 
         std::atomic_bool transformed_;
@@ -190,15 +190,9 @@ class Problem : public std::enable_shared_from_this<Problem>
 
         // Prior
         bool isPriorApplied() const;
-        void setPriorOptions(const PriorMap& priors);
+        void setPriorOptions(const SpecComposite& priors);
         FrameBasePtr applyPriorOptions(const TimeStamp& _ts);
-        FrameBasePtr setPriorFactor(const VectorComposite &_state,
-                                    const VectorComposite &_sigma,
-                                    const TimeStamp &_ts);
-        FrameBasePtr setPriorFix(const VectorComposite &_state,
-                                 const TimeStamp &_ts);
-        FrameBasePtr setPriorInitialGuess(const VectorComposite &_state,
-                                          const TimeStamp &_ts);
+        FrameBasePtr setPrior(const SpecComposite& priors, const TimeStamp& _ts);
 
         /** \brief Emplace frame from string frame_structure, dimension and vector
          * \param _time_stamp Time stamp of the frame
@@ -293,6 +287,22 @@ class Problem : public std::enable_shared_from_this<Problem>
          */
         FrameBasePtr emplaceFrame(const TimeStamp& _time_stamp);
 
+        /** \brief Emplace frame from state specs composite
+         * \param _time_stamp Time stamp of the frame
+         * \param _frame_spec_composite SpecComposite; each state must match in size and type with the 
+         * problem dimension and the corresponding key, for example, 'P' must be a 'StatePoint2d' in a 2D problem.
+         *
+         * - The structure is taken from _frame_spec_composite
+         * - The state sizes and types are taken from _frame_spec_composite
+         *
+         * This acts as a Frame factory, but also takes care to update related lists in WolfProblem:
+         *   - Create a Frame
+         *   - Add it to Trajectory
+         *   - If it is key-frame, update state-block lists in Problem
+         */
+        FrameBasePtr emplaceFrame(const TimeStamp& _time_stamp, //
+                                  const SpecComposite& _frame_spec_composite);
+
         // Frame getters
         FrameBaseConstPtr getLastFrame( ) const;
         FrameBasePtr getLastFrame( );
diff --git a/include/core/sensor/sensor_base.h b/include/core/sensor/sensor_base.h
index 612775d7100cb624348c416ffa5c1122aae64ba0..00d8da23e2f4247f9bfa1a2adeb75b2a65fe9c01 100644
--- a/include/core/sensor/sensor_base.h
+++ b/include/core/sensor/sensor_base.h
@@ -31,7 +31,7 @@ class ParamsServer;
 
 //Wolf includes
 #include "core/common/wolf.h"
-#include "core/sensor/prior_sensor.h"
+#include "core/sensor/spec_state_sensor.h"
 #include "core/common/node_base.h"
 #include "core/common/time_stamp.h"
 #include "core/common/params_base.h"
@@ -54,7 +54,7 @@ namespace wolf {
  *   SensorClass(const std::string& _unique_name, 
  *               SizeEigen _dim,
  *               ParamsSensorClassPtr _params, 
- *               const PriorSensorMap& _priors)
+ *               const SpecSensorComposite& _priors)
  * 
  * Also, there should be the schema file 'SensorClass.schema' containing the specifications 
  * of the user input yaml file.
@@ -64,7 +64,7 @@ static SensorBasePtr create(const YAML::Node& _input_node)
 {                                                                               \
     auto params = std::make_shared<ParamsSensorClass>(_input_node);             \
                                                                                 \
-    auto priors = PriorSensorMap(_input_node["states"]);                        \
+    auto priors = SpecSensorComposite(_input_node["states"]);                   \
                                                                                 \
     return std::make_shared<SensorClass>(params, priors);                       \
 }                                                                               \
@@ -80,7 +80,7 @@ static SensorBasePtr create(const std::string& _schema,
     }                                                                           \
     auto params = std::make_shared<ParamsSensorClass>(server.getNode());        \
                                                                                 \
-    auto priors = PriorSensorMap(server.getNode()["states"]);                   \
+    auto priors = SpecSensorComposite(server.getNode()["states"]);              \
                                                                                 \
     return std::make_shared<SensorClass>(params, priors);                       \
 }                                                                               \
@@ -135,7 +135,6 @@ class SensorBase : public NodeBase, public HasStateBlocks, public std::enable_sh
         int dim_; ///< Dimension compatibility of the sensor: 2: 2D, 3: 3D, -1: both
 
         void setProblem(ProblemPtr _problem) override final;
-        virtual void loadPriors(const PriorSensorMap& _priors);
 
     public:
 
@@ -151,7 +150,7 @@ class SensorBase : public NodeBase, public HasStateBlocks, public std::enable_sh
         SensorBase(const std::string& _type,
                    const int& _dim,
                    ParamsSensorBasePtr _params,
-                   const PriorSensorMap& _priors);
+                   const SpecSensorComposite& _priors);
 
         ~SensorBase() override;
 
diff --git a/include/core/sensor/sensor_diff_drive.h b/include/core/sensor/sensor_diff_drive.h
index db2e2c40079cdf673e7fe17a3ce783ef15c4af1a..1220137dafeb87af4df08400bae3d96a5c251589 100644
--- a/include/core/sensor/sensor_diff_drive.h
+++ b/include/core/sensor/sensor_diff_drive.h
@@ -55,7 +55,7 @@ class SensorDiffDrive : public SensorBase
 {
     public:
         SensorDiffDrive(ParamsSensorDiffDrivePtr _params,
-                        const PriorSensorMap& _priors);
+                        const SpecSensorComposite& _priors);
         WOLF_SENSOR_CREATE(SensorDiffDrive, ParamsSensorDiffDrive);
 
         ~SensorDiffDrive() override = default;
diff --git a/include/core/sensor/sensor_motion_model.h b/include/core/sensor/sensor_motion_model.h
index 884cf57a779d8cc81632294acbfd72605558d78f..95be10c126e69e7f54fc63c3d42206f758322fe4 100644
--- a/include/core/sensor/sensor_motion_model.h
+++ b/include/core/sensor/sensor_motion_model.h
@@ -32,7 +32,7 @@ class SensorMotionModel : public SensorBase
 {
     public:
         SensorMotionModel(ParamsSensorBasePtr _params,
-                          const PriorSensorMap& _priors);
+                          const SpecSensorComposite& _priors);
 
         WOLF_SENSOR_CREATE(SensorMotionModel, ParamsSensorBase);
 
diff --git a/include/core/sensor/sensor_odom.h b/include/core/sensor/sensor_odom.h
index 1d0610b29583ff3db99a0b090f22ffcdb28a8fa8..8efa6ae80be7acdf4def33a41ddcb99466738a3b 100644
--- a/include/core/sensor/sensor_odom.h
+++ b/include/core/sensor/sensor_odom.h
@@ -68,7 +68,7 @@ class SensorOdom : public SensorBase
         
 	public:
         SensorOdom(ParamsSensorOdomPtr _params, 
-                   const PriorSensorMap& _priors) :
+                   const SpecSensorComposite& _priors) :
             SensorBase("SensorOdom"+toString(DIM)+"d",
                        DIM,
                        _params,
diff --git a/include/core/sensor/sensor_pose.h b/include/core/sensor/sensor_pose.h
index 5817cabc06098ce4f94501d3d7a67626ebcfd466..6a3d8adefcd3156f11be904fdd0cb5517e1a2e8f 100644
--- a/include/core/sensor/sensor_pose.h
+++ b/include/core/sensor/sensor_pose.h
@@ -57,7 +57,7 @@ class SensorPose : public SensorBase
 
     public:
         SensorPose(ParamsSensorPosePtr _params,
-                   const PriorSensorMap& _priors) :
+                   const SpecSensorComposite& _priors) :
             SensorBase("SensorPose"+toString(DIM)+"d", 
                        DIM,
                        _params,
diff --git a/include/core/sensor/prior_sensor.h b/include/core/sensor/spec_state_sensor.h
similarity index 56%
rename from include/core/sensor/prior_sensor.h
rename to include/core/sensor/spec_state_sensor.h
index 496926a610aa3bf5076dbc58fe3aa01aa5efac3b..c8ea62affc3009528ea7c3b271200a4a2810f24e 100644
--- a/include/core/sensor/prior_sensor.h
+++ b/include/core/sensor/spec_state_sensor.h
@@ -21,51 +21,48 @@
 //--------LICENSE_END--------
 #pragma once
 
-#include "core/state_block/prior.h"
+#include "core/state_block/spec_composite.h"
 
 namespace wolf
 {
 
-class PriorSensor : public Prior
+class SpecStateSensor : public SpecState
 {
     protected:
         bool            dynamic_;    // State dynamic
         Eigen::VectorXd drift_std_;  // OPTIONAL std of the state drift [in units/sqrt(s)] diagonal elements (ONLY IF if dynamic)
 
     public:
-        PriorSensor() = default;
-        PriorSensor(const std::string&     _type,
-                    const Eigen::VectorXd& _state,
-                    const std::string&     _mode      = "fix",
-                    const Eigen::VectorXd& _noise_std = Eigen::VectorXd(0),
-                    bool                   _dynamic   = false,
-                    const Eigen::VectorXd& _drift_std = Eigen::VectorXd(0));
+        SpecStateSensor() = default;
+        SpecStateSensor(const std::string&     _type,
+                        const Eigen::VectorXd& _state,
+                        const std::string&     _mode      = "fix",
+                        const Eigen::VectorXd& _noise_std = Eigen::VectorXd(0),
+                        bool                   _dynamic   = false,
+                        const Eigen::VectorXd& _drift_std = Eigen::VectorXd(0));
 
-        PriorSensor(const YAML::Node& _n);
+        SpecStateSensor(const YAML::Node& _n);
 
-        virtual ~PriorSensor() = default;
+        virtual ~SpecStateSensor() = default;
 
         bool                   isDynamic() const;
         const Eigen::VectorXd& getDriftStd() const;
 
         void check() const override;
 
-        std::string print() const override;
+        std::string print(const std::string& _spaces = "") const override;
 };
 
-typedef std::unordered_map<char, PriorSensor> StdMapPriorSensor;
-
-class PriorSensorMap : public StdMapPriorSensor
+class SpecSensorComposite : public SpecCompositeTemplate<SpecStateSensor>
 {
     public:
-        using StdMapPriorSensor::StdMapPriorSensor;
+        using SpecCompositeTemplate::SpecCompositeTemplate;
 
-        PriorSensorMap(const YAML::Node& _n);
-        virtual ~PriorSensorMap() = default;
+        SpecComposite getSpecComposite() const;
 };
 
-inline bool PriorSensor::isDynamic() const { return dynamic_; }
+inline bool SpecStateSensor::isDynamic() const { return dynamic_; }
 
-inline const Eigen::VectorXd& PriorSensor::getDriftStd() const { return drift_std_; }
+inline const Eigen::VectorXd& SpecStateSensor::getDriftStd() const { return drift_std_; }
 
 }  // namespace wolf
\ No newline at end of file
diff --git a/include/core/state_block/has_state_blocks.h b/include/core/state_block/has_state_blocks.h
index 4857055c7392fffe063a38c574a68aaeb67e555b..a61e1605540820b1edb6d6687a582e85a0ed7a48 100644
--- a/include/core/state_block/has_state_blocks.h
+++ b/include/core/state_block/has_state_blocks.h
@@ -23,6 +23,7 @@
 
 #include "core/common/wolf.h"
 #include "core/state_block/state_composite.h"
+#include "core/state_block/spec_composite.h"
 
 #include <map>
 
@@ -37,11 +38,12 @@ class HasStateBlocks
     public:
         HasStateBlocks();
         HasStateBlocks(const StateStructure& _structure) : structure_(_structure), state_block_map_() {}
+        HasStateBlocks(const SpecComposite& _specs);
         virtual ~HasStateBlocks();
 
         const StateStructure& getStructure() const { return structure_; }
-        void appendToStructure(const char& _frame_type){ structure_ += _frame_type; }
-        bool isInStructure(const char& _sb_type) const { return structure_.find(_sb_type) != std::string::npos; }
+        void appendToStructure(const char& _new_key){ structure_ += _new_key; }
+        bool isInStructure(const char& _sb_key) const { return structure_.find(_sb_key) != std::string::npos; }
 
         const std::unordered_map<char, StateBlockConstPtr>& getStateBlockMap() const;
         const std::unordered_map<char, StateBlockPtr>& getStateBlockMap();
@@ -59,20 +61,20 @@ class HasStateBlocks
         virtual void unfix();
         virtual bool isFixed() const;
 
-        virtual StateBlockPtr   addStateBlock(const char& _sb_type, const StateBlockPtr& _sb, ProblemPtr _problem);
-        virtual unsigned int    removeStateBlock(const char& _sb_type);
-        bool            hasStateBlock(const char& _sb_type) const { return state_block_map_.count(_sb_type) > 0; }
+        virtual StateBlockPtr   addStateBlock(const char& _sb_key, const StateBlockPtr& _sb, ProblemPtr _problem);
+        virtual unsigned int    removeStateBlock(const char& _sb_key);
+        bool            hasStateBlock(const char& _sb_key) const { return state_block_map_.count(_sb_key) > 0; }
         bool            hasStateBlock(const StateBlockConstPtr& _sb) const;
-        bool            setStateBlock(const char _sb_type, const StateBlockPtr& _sb);
+        bool            setStateBlock(const char _sb_key, const StateBlockPtr& _sb);
         bool            stateBlockKey(const StateBlockConstPtr& _sb, char& _key) const;
-        StateBlockConstPtr  getStateBlock(const char& _sb_type) const;
-        StateBlockPtr       getStateBlock(const char& _sb_type);
+        StateBlockConstPtr  getStateBlock(const char& _sb_key) const;
+        StateBlockPtr       getStateBlock(const char& _sb_key);
         std::unordered_map<char, StateBlockConstPtr>::const_iterator find(const StateBlockConstPtr& _sb) const;
         std::unordered_map<char, StateBlockPtr>::const_iterator find(const StateBlockPtr& _sb);
 
         // Emplace derived state blocks (angle, quaternion, etc).
         template<typename SB, typename ... Args>
-        std::shared_ptr<SB> emplaceStateBlock(const char& _sb_type, ProblemPtr _problem, Args&&... _args_of_derived_state_block_constructor);
+        std::shared_ptr<SB> emplaceStateBlock(const char& _sb_key, ProblemPtr _problem, Args&&... _args_of_derived_state_block_constructor);
 
         // Register/remove state blocks to/from wolf::Problem
         virtual void registerNewStateBlocks(ProblemPtr _problem);
@@ -157,44 +159,44 @@ inline std::vector<StateBlockPtr> HasStateBlocks::getStateBlockVec()
     return sbv;
 }
 
-inline unsigned int HasStateBlocks::removeStateBlock(const char& _sb_type)
+inline unsigned int HasStateBlocks::removeStateBlock(const char& _sb_key)
 {
-    return state_block_map_.erase(_sb_type);
-    return state_block_const_map_.erase(_sb_type);
+    return state_block_map_.erase(_sb_key);
+    return state_block_const_map_.erase(_sb_key);
 }
 
 template<typename SB, typename ... Args>
-inline std::shared_ptr<SB> HasStateBlocks::emplaceStateBlock(const char& _sb_type, ProblemPtr _problem, Args&&... _args_of_derived_state_block_constructor)
+inline std::shared_ptr<SB> HasStateBlocks::emplaceStateBlock(const char& _sb_key, ProblemPtr _problem, Args&&... _args_of_derived_state_block_constructor)
 {
-    assert(state_block_map_.count(_sb_type) == 0 && state_block_const_map_.count(_sb_type) == 0 && "Trying to add a state block with an existing type! Use setStateBlock instead.");
+    assert(state_block_map_.count(_sb_key) == 0 && state_block_const_map_.count(_sb_key) == 0 && "Trying to add a state block with an existing type! Use setStateBlock instead.");
     std::shared_ptr<SB> sb = std::make_shared<SB>(std::forward<Args>(_args_of_derived_state_block_constructor)...);
 
-    addStateBlock(_sb_type, sb, _problem);
+    addStateBlock(_sb_key, sb, _problem);
 
     return sb;
 }
 
-inline bool HasStateBlocks::setStateBlock(const char _sb_type, const StateBlockPtr& _sb)
+inline bool HasStateBlocks::setStateBlock(const char _sb_key, const StateBlockPtr& _sb)
 {
-    assert (structure_.find(_sb_type) > 0 && "Cannot set a state block out of the state structure! Use addStateBlock instead.");
-    assert ( state_block_map_.count(_sb_type) > 0 &&  state_block_const_map_.count(_sb_type) > 0 && "Cannot set an inexistent state block! Use addStateBlock instead.");
-    state_block_map_.at(_sb_type) = _sb;
-    state_block_const_map_.at(_sb_type) = _sb;
+    assert (structure_.find(_sb_key) > 0 && "Cannot set a state block out of the state structure! Use addStateBlock instead.");
+    assert ( state_block_map_.count(_sb_key) > 0 &&  state_block_const_map_.count(_sb_key) > 0 && "Cannot set an inexistent state block! Use addStateBlock instead.");
+    state_block_map_.at(_sb_key) = _sb;
+    state_block_const_map_.at(_sb_key) = _sb;
     return true; // success
 }
 
-inline wolf::StateBlockConstPtr HasStateBlocks::getStateBlock(const char& _sb_type) const
+inline wolf::StateBlockConstPtr HasStateBlocks::getStateBlock(const char& _sb_key) const
 {
-    auto it = state_block_const_map_.find(_sb_type);
+    auto it = state_block_const_map_.find(_sb_key);
     if (it != state_block_const_map_.end())
         return it->second;
     else
         return nullptr;
 }
 
-inline wolf::StateBlockPtr HasStateBlocks::getStateBlock(const char& _sb_type)
+inline wolf::StateBlockPtr HasStateBlocks::getStateBlock(const char& _sb_key)
 {
-    auto it = state_block_map_.find(_sb_type);
+    auto it = state_block_map_.find(_sb_key);
     if (it != state_block_map_.end())
         return it->second;
     else
diff --git a/include/core/state_block/prior.h b/include/core/state_block/prior.h
deleted file mode 100644
index 870614fe887592432d1c8e91d9655316af1b32e4..0000000000000000000000000000000000000000
--- a/include/core/state_block/prior.h
+++ /dev/null
@@ -1,91 +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--------
-#pragma once
-
-#include <string>
-#include <unordered_map>
-#include <eigen3/Eigen/Dense>
-#include "yaml-cpp/yaml.h"
-
-namespace wolf
-{
-
-class Prior
-{
-    protected:
-        std::string     type_;       // State type
-        Eigen::VectorXd state_;      // state values
-        std::string     mode_;       // Prior mode. Can be 'initial_guess', 'fix' or 'factor'
-        Eigen::VectorXd noise_std_;  // factor noise std, sqrt of the diagonal of the covariance mtrix (ONLY IF mode == 'factor')
-
-    public:
-        Prior() = delete;
-        Prior(const std::string&     _type,
-              const Eigen::VectorXd& _state,
-              const std::string&     _mode      = "fix",
-              const Eigen::VectorXd& _noise_std = Eigen::VectorXd(0));
-
-        Prior(const YAML::Node& _n);
-
-        virtual ~Prior() = default;
-
-        const std::string&     getType() const;
-        const std::string&     getMode() const;
-        const Eigen::VectorXd& getState() const;
-        const Eigen::VectorXd& getNoiseStd() const;
-        bool                   isFixed() const;
-        bool                   isInitialGuess() const;
-        bool                   isFactor() const;
-
-        virtual void check() const;
-
-        virtual std::string print() const;
-};
-
-typedef std::unordered_map<char, Prior> StdMapPrior;
-
-class PriorMap : public StdMapPrior
-{
-    public:
-        using StdMapPrior::StdMapPrior;
-
-        PriorMap(const YAML::Node& _n);
-        virtual ~PriorMap() = default;
-
-        VectorComposite getState() const;
-};
-
-inline const std::string& Prior::getType() const { return type_; }
-
-inline const std::string& Prior::getMode() const { return mode_; }
-
-inline const Eigen::VectorXd& Prior::getState() const { return state_; }
-
-inline const Eigen::VectorXd& Prior::getNoiseStd() const { return noise_std_; }
-
-inline bool Prior::isFixed() const { return mode_ == "fix"; }
-
-inline bool Prior::isInitialGuess() const { return mode_ == "initial_guess"; }
-
-inline bool Prior::isFactor() const { return mode_ == "factor"; }
-
-}  // namespace wolf
\ No newline at end of file
diff --git a/include/core/state_block/spec_composite.h b/include/core/state_block/spec_composite.h
new file mode 100644
index 0000000000000000000000000000000000000000..f53b296fdc215ef0b088d06c0d6c2503c6c540cf
--- /dev/null
+++ b/include/core/state_block/spec_composite.h
@@ -0,0 +1,145 @@
+//--------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--------
+#pragma once
+
+#include "core/state_block/state_composite.h"
+
+#include <string>
+#include <unordered_map>
+#include <eigen3/Eigen/Dense>
+#include "yaml-cpp/yaml.h"
+
+namespace wolf
+{
+
+using std::unordered_map;
+
+class SpecState
+{
+    protected:
+        std::string     type_;       // State type
+        Eigen::VectorXd state_;      // state values
+        std::string     mode_;       // Prior mode. Can be 'initial_guess', 'fix' or 'factor'
+        Eigen::VectorXd noise_std_;  // factor noise std, sqrt of the diagonal of the covariance mtrix (ONLY IF mode == 'factor')
+
+    public:
+        SpecState() = delete;
+        SpecState(const std::string&     _type,
+                  const Eigen::VectorXd& _state,
+                  const std::string&     _mode      = "fix",
+                  const Eigen::VectorXd& _noise_std = Eigen::VectorXd(0));
+
+        SpecState(const YAML::Node& _n);
+
+        virtual ~SpecState() = default;
+
+        const std::string&     getType() const;
+        const std::string&     getMode() const;
+        const Eigen::VectorXd& getState() const;
+        const Eigen::VectorXd& getNoiseStd() const;
+        bool                   isFixed() const;
+        bool                   isInitialGuess() const;
+        bool                   isFactor() const;
+
+        virtual void check() const;
+
+        virtual std::string print(const std::string& _spaces = "") const;
+};
+
+template <typename SPEC>
+class SpecCompositeTemplate : public std::unordered_map<char, SPEC>
+{
+    public:
+        using unordered_map<char, SPEC>::unordered_map;
+
+        SpecCompositeTemplate(const YAML::Node& _n);
+        virtual ~SpecCompositeTemplate() = default;
+
+        VectorComposite getState() const;
+
+        void emplace(char _key, const SPEC& _spec);
+
+        std::string print() const;
+};
+
+typedef SpecCompositeTemplate<SpecState> SpecComposite;
+
+
+template <typename SPEC>
+SpecCompositeTemplate<SPEC>::SpecCompositeTemplate(const YAML::Node& _n)
+{
+    if (not _n.IsMap())
+    {
+        throw std::runtime_error("SpecComposite: constructor with a non-map yaml node");
+    }
+    for (auto spec_pair : _n)
+    {
+        this->emplace(spec_pair.first.as<char>(), SPEC(spec_pair.second));
+    }
+}
+
+template <typename SPEC>
+void SpecCompositeTemplate<SPEC>::emplace(char _key, const SPEC& _spec)
+{
+    this->insert({_key,_spec});
+}
+
+template <typename SPEC>
+VectorComposite SpecCompositeTemplate<SPEC>::getState() const
+{
+    VectorComposite states;
+    for (auto spec_pair : *this)
+    {
+        states.emplace(spec_pair.first, spec_pair.second.getState());
+    }
+    return states;
+}
+
+template <typename SPEC>
+std::string SpecCompositeTemplate<SPEC>::print() const
+{
+    std::string output;
+    
+    for (auto spec_pair : *this)
+    {
+        output += std::string(1,spec_pair.first) + ":\n";
+        output += spec_pair.second.print("\t");
+    }
+
+    return output;
+}
+
+inline const std::string& SpecState::getType() const { return type_; }
+
+inline const std::string& SpecState::getMode() const { return mode_; }
+
+inline const Eigen::VectorXd& SpecState::getState() const { return state_; }
+
+inline const Eigen::VectorXd& SpecState::getNoiseStd() const { return noise_std_; }
+
+inline bool SpecState::isFixed() const { return mode_ == "fix"; }
+
+inline bool SpecState::isInitialGuess() const { return mode_ == "initial_guess"; }
+
+inline bool SpecState::isFactor() const { return mode_ == "factor"; }
+
+}  // namespace wolf
\ No newline at end of file
diff --git a/schema/map/MapBase.schema b/schema/map/MapBase.schema
index 50484d21e94bea91ba327b4f94613c472daafeb5..8b2f4f7562e55b3563f6fea22762f7744f91b070 100644
--- a/schema/map/MapBase.schema
+++ b/schema/map/MapBase.schema
@@ -4,7 +4,7 @@ type:
   yaml_type: scalar
   default: MapBase
   doc: Type of the Map used in the problem.
-type:
+plugin:
   mandatory: false
   type: string
   yaml_type: scalar
diff --git a/schema/problem/Problem.schema b/schema/problem/Problem.schema
index 12519e7b93eb693dcc4d0eb8d5f4c91fb960d414..0a7943acdbb1beca7e2946d4d0f90e1a08899d99 100644
--- a/schema/problem/Problem.schema
+++ b/schema/problem/Problem.schema
@@ -16,10 +16,9 @@ problem:
     mandatory: true
     options: [2, 3]
     doc: Dimension of the problem. '2' for 2D or '3' for 3D
-  #prior:
 map:
   type: derived
-  base: Map.schema
+  base: MapBase.schema
   yaml_type: scalar
   mandatory: false
   doc: The map used in the wolf problem.
diff --git a/schema/problem/Problem2d.schema b/schema/problem/Problem2d.schema
index ff52fcd1f121e026681c44b682a97240776bd25f..51625eeefda54e05d2a4f7af004e87bdaf595309 100644
--- a/schema/problem/Problem2d.schema
+++ b/schema/problem/Problem2d.schema
@@ -1,7 +1,7 @@
 follow: Problem.schema
 problem:
-  prior:
+  first_frame:
     P:
-      follow: PriorP2d.schema
+      follow: SpecStateP2d.schema
     O:
-      follow: PriorO2d.schema
\ No newline at end of file
+      follow: SpecStateO2d.schema
\ No newline at end of file
diff --git a/schema/problem/Problem3d.schema b/schema/problem/Problem3d.schema
index b849bec3ce39d22ca8de78d42758367399fe5e3a..42a77ba48f49234a789ddd2b8ee694b065d033a1 100644
--- a/schema/problem/Problem3d.schema
+++ b/schema/problem/Problem3d.schema
@@ -1,7 +1,7 @@
 follow: Problem.schema
 problem:
-  prior:
+  first_frame:
     P:
-      follow: PriorP3d.schema
+      follow: SpecStateP3d.schema
     O:
-      follow: PriorO3d.schema
\ No newline at end of file
+      follow: SpecStateO3d.schema
\ No newline at end of file
diff --git a/schema/problem/Prior.schema b/schema/problem/SpecState.schema
similarity index 100%
rename from schema/problem/Prior.schema
rename to schema/problem/SpecState.schema
diff --git a/schema/problem/PriorO2d.schema b/schema/problem/SpecStateO2d.schema
similarity index 91%
rename from schema/problem/PriorO2d.schema
rename to schema/problem/SpecStateO2d.schema
index c5afbd8499317a4bfde12bf07a58e5fd3818a7b3..321c4eaf9ef1c1383de33b656aceeb34398e501d 100644
--- a/schema/problem/PriorO2d.schema
+++ b/schema/problem/SpecStateO2d.schema
@@ -1,4 +1,4 @@
-follow: Prior.schema
+follow: SpecState.schema
 type:
   type: string
   yaml_type: scalar
diff --git a/schema/problem/PriorO3d.schema b/schema/problem/SpecStateO3d.schema
similarity index 92%
rename from schema/problem/PriorO3d.schema
rename to schema/problem/SpecStateO3d.schema
index c819039b271552bfdd085c782e161a6379233ba3..deb47e1f884354474665cd26beb53e8a85483370 100644
--- a/schema/problem/PriorO3d.schema
+++ b/schema/problem/SpecStateO3d.schema
@@ -1,4 +1,4 @@
-follow: Prior.schema
+follow: SpecState.schema
 type:
   type: string
   yaml_type: scalar
diff --git a/schema/problem/PriorP2d.schema b/schema/problem/SpecStateP2d.schema
similarity index 91%
rename from schema/problem/PriorP2d.schema
rename to schema/problem/SpecStateP2d.schema
index ef333199230dfd8dc08847c1eb830b2a36f2eb99..44227445621cce38bdea2353e0f0c5792892131a 100644
--- a/schema/problem/PriorP2d.schema
+++ b/schema/problem/SpecStateP2d.schema
@@ -1,4 +1,4 @@
-follow: Prior.schema
+follow: SpecState.schema
 type:
   type: string
   yaml_type: scalar
diff --git a/schema/problem/PriorP3d.schema b/schema/problem/SpecStateP3d.schema
similarity index 91%
rename from schema/problem/PriorP3d.schema
rename to schema/problem/SpecStateP3d.schema
index de70f20a0ab78f2a3a0914aca916947cde5a22a6..6f1f0c173ce87655627020a15cd1f602c7c8fe13 100644
--- a/schema/problem/PriorP3d.schema
+++ b/schema/problem/SpecStateP3d.schema
@@ -1,4 +1,4 @@
-follow: Prior.schema
+follow: SpecState.schema
 type:
   type: string
   yaml_type: scalar
diff --git a/schema/problem/SpecStateV2d.schema b/schema/problem/SpecStateV2d.schema
new file mode 100644
index 0000000000000000000000000000000000000000..c76380cbd782d979372728bc8863f6113fe855a2
--- /dev/null
+++ b/schema/problem/SpecStateV2d.schema
@@ -0,0 +1,13 @@
+follow: SpecState.schema
+type:
+  type: string
+  yaml_type: scalar
+  mandatory: false
+  default: StateVector2d
+  options: [StateVector2d]
+  doc: The derived type of the StateBlock
+state:
+  type: Vector2d
+  yaml_type: scalar
+  mandatory: true
+  doc: A vector containing the state values
\ No newline at end of file
diff --git a/schema/problem/SpecStateV3d.schema b/schema/problem/SpecStateV3d.schema
new file mode 100644
index 0000000000000000000000000000000000000000..2c3109ae89e77e04024c80e40b1efad483920d06
--- /dev/null
+++ b/schema/problem/SpecStateV3d.schema
@@ -0,0 +1,13 @@
+follow: SpecState.schema
+type:
+  type: string
+  yaml_type: scalar
+  mandatory: false
+  default: StateVector3d
+  options: [StateVector3d]
+  doc: The derived type of the state in 'V'
+state:
+  type: Vector3d
+  yaml_type: scalar
+  mandatory: true
+  doc: A vector containing the state 'V' values
\ No newline at end of file
diff --git a/schema/sensor/SensorDiffDrive.schema b/schema/sensor/SensorDiffDrive.schema
index ba16781b06d9492b95a46f8d3a91e8256fd596f3..eb21483483c301beccb36b248c56e71e1cbde04a 100644
--- a/schema/sensor/SensorDiffDrive.schema
+++ b/schema/sensor/SensorDiffDrive.schema
@@ -30,11 +30,11 @@ ticks_std_factor:
 
 states:
   P:
-    follow: PriorSensorP2d.schema
+    follow: SpecStateSensorP2d.schema
   O:
-    follow: PriorSensorO2d.schema
+    follow: SpecStateSensorO2d.schema
   I:
-    follow: PriorSensor.schema
+    follow: SpecStateSensor.schema
     type:
       type: string
       yaml_type: scalar
diff --git a/schema/sensor/SensorOdom2d.schema b/schema/sensor/SensorOdom2d.schema
index 08dc1f8dd6d8e5257bb8cd065c3cfbc8ec82afd1..24615eac3b6f0330de3e7865d6e5f973a66f827a 100644
--- a/schema/sensor/SensorOdom2d.schema
+++ b/schema/sensor/SensorOdom2d.schema
@@ -32,7 +32,7 @@ min_rot_var:
 
 states:
   P:
-    follow: PriorSensorP2d.schema
+    follow: SpecStateSensorP2d.schema
   O:
-    follow: PriorSensorO2d.schema
+    follow: SpecStateSensorO2d.schema
 
diff --git a/schema/sensor/SensorOdom3d.schema b/schema/sensor/SensorOdom3d.schema
index 4ef58d18aaa39fef4a8d86b0eac41aef0fd6c564..02845f9af3f74ca3b77d5f564ebc2b24ff08c93f 100644
--- a/schema/sensor/SensorOdom3d.schema
+++ b/schema/sensor/SensorOdom3d.schema
@@ -49,6 +49,6 @@ min_rot_var:
 
 states:
   P:
-    follow: PriorSensorP3d.schema
+    follow: SpecStateSensorP3d.schema
   O:
-    follow: PriorSensorO3d.schema
\ No newline at end of file
+    follow: SpecStateSensorO3d.schema
\ No newline at end of file
diff --git a/schema/sensor/PriorSensor.schema b/schema/sensor/SpecStateSensor.schema
similarity index 93%
rename from schema/sensor/PriorSensor.schema
rename to schema/sensor/SpecStateSensor.schema
index e650d3961ed1187d46735019e32380b843f064cf..75e3052c71fe8c4b9d5adc51f80a305c9e1448b2 100644
--- a/schema/sensor/PriorSensor.schema
+++ b/schema/sensor/SpecStateSensor.schema
@@ -1,4 +1,4 @@
-follow: Prior.schema
+follow: SpecState.schema
 dynamic:
   type: bool
   yaml_type: scalar
diff --git a/schema/sensor/SpecStateSensorO2d.schema b/schema/sensor/SpecStateSensorO2d.schema
new file mode 100644
index 0000000000000000000000000000000000000000..519ca225baf3b4b15d688162dcced59d7dc1b356
--- /dev/null
+++ b/schema/sensor/SpecStateSensorO2d.schema
@@ -0,0 +1,13 @@
+follow: SpecStateSensor.schema
+type:
+  type: string
+  yaml_type: scalar
+  mandatory: false
+  default: StateAngle
+  options: [StateAngle]
+  doc: The derived type of the StateBlock
+state:
+  type: Vector1d
+  yaml_type: scalar
+  mandatory: true
+  doc: A vector containing the state values
\ No newline at end of file
diff --git a/schema/sensor/SpecStateSensorO3d.schema b/schema/sensor/SpecStateSensorO3d.schema
new file mode 100644
index 0000000000000000000000000000000000000000..c248eb442a986415e6cddc4cc745447d5b358e1f
--- /dev/null
+++ b/schema/sensor/SpecStateSensorO3d.schema
@@ -0,0 +1,13 @@
+follow: SpecStateSensor.schema
+type:
+  type: string
+  yaml_type: scalar
+  mandatory: false
+  default: StateQuaternion
+  options: [StateQuaternion]
+  doc: The derived type of the State in 'O'
+state:
+  type: Vector4d
+  yaml_type: scalar
+  mandatory: true
+  doc: A vector containing the state values. It should be a quaternion (i.e. four values and normalized)
\ No newline at end of file
diff --git a/schema/sensor/SpecStateSensorP2d.schema b/schema/sensor/SpecStateSensorP2d.schema
new file mode 100644
index 0000000000000000000000000000000000000000..4d3ea92c2bad73ccf9d33c340150e8a51ed31457
--- /dev/null
+++ b/schema/sensor/SpecStateSensorP2d.schema
@@ -0,0 +1,13 @@
+follow: SpecStateSensor.schema
+type:
+  type: string
+  yaml_type: scalar
+  mandatory: false
+  default: StatePoint2d
+  options: [StatePoint2d]
+  doc: The derived type of the StateBlock
+state:
+  type: Vector2d
+  yaml_type: scalar
+  mandatory: true
+  doc: A vector containing the state values
\ No newline at end of file
diff --git a/schema/sensor/SpecStateSensorP3d.schema b/schema/sensor/SpecStateSensorP3d.schema
new file mode 100644
index 0000000000000000000000000000000000000000..c7d681d7f101c068a11d37b6df462d4b41b92255
--- /dev/null
+++ b/schema/sensor/SpecStateSensorP3d.schema
@@ -0,0 +1,13 @@
+follow: SpecStateSensor.schema
+type:
+  type: string
+  yaml_type: scalar
+  mandatory: false
+  default: StatePoint3d
+  options: [StatePoint3d]
+  doc: The derived type of the state in 'P'
+state:
+  type: Vector3d
+  yaml_type: scalar
+  mandatory: true
+  doc: A vector containing the state 'P' values
\ No newline at end of file
diff --git a/src/frame/frame_base.cpp b/src/frame/frame_base.cpp
index aae21b6eb2fa9d5552e8212259299b71e0e0c440..47da4c53dd823503ef5cd8dd5cd6a720b4a6e9df 100644
--- a/src/frame/frame_base.cpp
+++ b/src/frame/frame_base.cpp
@@ -102,6 +102,17 @@ FrameBase::FrameBase(const TimeStamp& _ts,
 }
 
 
+FrameBase::FrameBase(const TimeStamp& _ts,
+                     const SpecComposite& _frame_specs) :
+            NodeBase("FRAME", "FrameBase"),
+            HasStateBlocks(_frame_specs),
+            trajectory_ptr_(),
+            frame_id_(++frame_id_count_),
+            time_stamp_(_ts)
+{
+}
+
+
 FrameBase::~FrameBase()
 {
 }
diff --git a/src/problem/problem.cpp b/src/problem/problem.cpp
index be215e57726ee0693d590a97e804a71c24920eb0..dc7720fe56ee59e37153bdadd14cd1a88c07c532 100644
--- a/src/problem/problem.cpp
+++ b/src/problem/problem.cpp
@@ -165,7 +165,9 @@ ProblemPtr Problem::autoSetup(const std::string& _input_yaml_file, const std::ve
 
     // First frame 
     WOLF_INFO("Loading problem first frame parameters");
-    PriorMap priors(problem_node["first_frame"]);
+    WOLF_INFO(problem_node["first_frame"])
+    SpecComposite priors(problem_node["first_frame"]);
+    WOLF_INFO(priors.print());
     problem->setPriorOptions(priors);
 
     // SENSORS =============================================================================== 
@@ -437,6 +439,38 @@ FrameBasePtr Problem::emplaceFrame(const TimeStamp& _time_stamp)
                         this->getDim());
 }
 
+FrameBasePtr Problem::emplaceFrame(const TimeStamp& _time_stamp,
+                                   const SpecComposite& _frame_spec_composite)
+{
+    // Checks
+    if (_frame_spec_composite.count('P') == 0 or _frame_spec_composite.count('O') == 0)
+    {
+        WOLF_INFO(_frame_spec_composite.print());
+        throw std::runtime_error("Problem::emplaceFrame: emplacing a frame without P or O");
+    }
+    if (_frame_spec_composite.at('P').getType() != "P" and 
+        _frame_spec_composite.at('P').getType() != (dim_ == 2 ? "StatePoint2d" : "StatePoint3d"))
+    {
+        throw std::runtime_error("Problem::emplaceFrame: State type of key P should be 'StatePoint2d' or 'StatePoint3d' for 2D and 3D problem, respectively");
+    }
+    if (_frame_spec_composite.at('O').getType() != "O" and 
+        _frame_spec_composite.at('O').getType() != (dim_ == 2 ? "StateAngle" : "StateQuaternion"))
+    {
+        throw std::runtime_error("Problem::emplaceFrame: State type of key O should be 'StateAngle' or 'StateQuaternion' for 2D and 3D problem, respectively");
+    }
+    if (_frame_spec_composite.count('V') != 0 and 
+        _frame_spec_composite.at('V').getType() != "V" and 
+        _frame_spec_composite.at('V').getType() != (dim_ == 2 ? "StateVector2d" : "StateVector3d"))
+    {
+        throw std::runtime_error("Problem::emplaceFrame: State type of key O should be 'StateAngle' or 'StateQuaternion' for 2D and 3D problem, respectively");
+    }
+
+    return FrameBase::emplace<FrameBase>(getTrajectory(),
+                                         _time_stamp,
+                                         _frame_spec_composite);
+}
+
+
 TimeStamp Problem::getTimeStamp ( ) const
 {
     TimeStamp  ts = TimeStamp::Invalid();
@@ -1041,72 +1075,38 @@ FrameBasePtr Problem::closestFrameToTimeStamp(const TimeStamp& _ts)
     return trajectory_ptr_->closestFrameToTimeStamp(_ts);
 }
 
-void Problem::setPriorOptions(const PriorMap& priors)
+void Problem::setPriorOptions(const SpecComposite& _priors)
 {
     if (not prior_options_.empty())
     {
         throw std::runtime_error("prior options have already been applied");
     }
 
-    prior_options_ = priors;
+    prior_options_ = _priors;
 }
 
-/*void Problem::setPriorOptions(const std::string& _mode,
-                              const VectorComposite& _state ,
-                              const VectorComposite& _sigma   )
+FrameBasePtr Problem::applyPriorOptions(const TimeStamp& _ts)
 {
-    assert(prior_options_ != nullptr && "prior options have already been applied");
-    assert(prior_options_->mode == "" && "prior options have already been set");
-    assert((_mode == "nothing" || _mode == "initial_guess" || _mode == "fix" || _mode == "factor") && "wrong _mode value, it should be: 'nothing', 'initial_guess', 'fix' or 'factor'");
-
-    // Store options (optionals depending on the mode)
-    WOLF_TRACE("prior mode:           ", _mode);
-    prior_options_->mode = _mode;
-
-    if (prior_options_->mode != "nothing")
+    if (isPriorApplied())
     {
-        assert(_state.includesStructure(frame_structure_) && "any missing key in prior state");
-
-        WOLF_TRACE("prior state:          ", _state);
-        prior_options_->state = _state;
-
-        if (prior_options_->mode == "factor")
-        {
-            assert(_sigma.includesStructure(frame_structure_) && "any missing key in prior sigma");
-
-            bool isPositive = true;
-            for(const auto& it: _sigma)
-                isPositive = isPositive and (it.second.array() > Constants::EPS).all();
-
-            assert(isPositive && "prior sigma is not positive");
-
-            MatrixComposite Q;
-            for (const auto& pair_key_sig : _sigma)
-            {
-                const auto& key = pair_key_sig.first;
-                const auto& sig_blk = pair_key_sig.second;
-
-                const auto& cov_blk = (sig_blk.array() * sig_blk.array()).matrix().asDiagonal();
-                Q.emplace(key,key,cov_blk);
-            }
-            WOLF_TRACE("prior covariance:"    , Q);
-            prior_options_->cov = Q;
-        }
+        throw std::runtime_error("applyPriorOptions can be called once!");
     }
-}*/
 
-FrameBasePtr Problem::applyPriorOptions(const TimeStamp& _ts)
-{
-    assert(!isPriorApplied() && "applyPriorOptions can be called once!");
+    // No prior options set
+    if (prior_options_.empty())
+    {
+        prior_applied_ = true;
+        return nullptr;
+    }
 
     // Create first frame
-    FrameBasePtr prior_keyframe = emplaceFrame(_ts, frame_structure_, prior_options_.getState());
+    FrameBasePtr first_frame = emplaceFrame(_ts, prior_options_);
     CaptureBasePtr prior_cap(nullptr);
 
     for (auto prior_pair : prior_options_)
     {
         auto key = prior_pair.first;
-        auto sb = prior_keyframe->getStateBlock(key);
+        auto sb = first_frame->getStateBlock(key);
 
         // Fix
         if (prior_pair.second.isFixed())
@@ -1115,21 +1115,21 @@ FrameBasePtr Problem::applyPriorOptions(const TimeStamp& _ts)
         }
 
         // Factor
-        if (prior_pair.second.isFactor())
+        else if (prior_pair.second.isFactor())
         {
 
             // Emplace a capture (if not done already)
             if (not prior_cap)
-                prior_cap = CaptureBase::emplace<CaptureVoid>(prior_keyframe, _ts, nullptr);
+                prior_cap = CaptureBase::emplace<CaptureVoid>(first_frame, _ts, nullptr);
 
             // Emplace a feature
-            // TODO: compute cov
-            Eigen::MatrixXd cov; 
+            Eigen::MatrixXd cov = prior_pair.second.getNoiseStd().cwiseAbs2().asDiagonal();
+            if(cov.rows() != sb->getLocalSize())
+            {
+                throw std::runtime_error("Problem::applyPriorOptions: covariance matrix has wrong size");
+            }
             auto prior_fea = FeatureBase::emplace<FeatureBase>(prior_cap, "Prior " + string(1,key), prior_pair.second.getState(), cov);
 
-            assert(sb->getSize()      == state_blk.size() && "prior_options state wrong size");
-            assert(sb->getLocalSize() == covar_blk.rows() && "prior_options cov. wrong size");
-
             // Emplace a factor
             if (sb->hasLocalParametrization())
             {
@@ -1144,93 +1144,21 @@ FrameBasePtr Problem::applyPriorOptions(const TimeStamp& _ts)
             {
                 auto prior_fac = FactorBase::emplace<FactorBlockAbsolute>(prior_fea, prior_fea, sb, nullptr, false);
             }
-
-            }
-        }
-    }
-
-    if (prior_options_->mode != "nothing" and prior_options_->mode != "")
-    {
-        prior_keyframe = emplaceFrame(_ts, frame_structure_, prior_options_->state);
-
-        // Update origin for odometry processors
-        for (auto proc_pair : motion_provider_map_)
-            proc_pair.second->setOdometry(prior_options_->state);
-
-        if (prior_options_->mode == "fix")
-            prior_keyframe->fix();
-        else if (prior_options_->mode == "factor")
-        {
-            // ASSUMPTION: Independent measurements (non-correlated block-diagonal covariance matrix)
-
-            // Emplace a capture
-            auto prior_cap = CaptureBase::emplace<CaptureVoid>(prior_keyframe, _ts, nullptr);
-
-            // Emplace a feature and a factor for each state block
-            for (auto pair_key_sb : prior_keyframe->getStateBlockMap())
-            {
-                auto key = pair_key_sb.first;
-                auto sb  = pair_key_sb.second;
-
-                const auto& state_blk = prior_options_->state.at(key);
-                const auto& covar_blk = prior_options_->cov.at(key,key);
-
-                assert(sb->getSize()      == state_blk.size() && "prior_options state wrong size");
-                assert(sb->getLocalSize() == covar_blk.rows() && "prior_options cov. wrong size");
-
-                // feature
-                auto prior_fea = FeatureBase::emplace<FeatureBase>(prior_cap, "Prior " + string(1,key), state_blk, covar_blk);
-
-                // factor
-                if (sb->hasLocalParametrization())
-                {
-                    if (std::dynamic_pointer_cast<StateQuaternion>(sb) != nullptr)
-                        auto prior_fac = FactorBase::emplace<FactorQuaternionAbsolute>(prior_fea, prior_fea, sb, nullptr, false);
-                    else if (std::dynamic_pointer_cast<StateAngle>(sb) != nullptr)
-                        auto prior_fac = FactorBase::emplace<FactorBlockAbsolute>(prior_fea, prior_fea, sb, nullptr, false);
-                    else
-                        throw std::runtime_error("not implemented...!");
-                }
-                else
-                {
-                    auto prior_fac = FactorBase::emplace<FactorBlockAbsolute>(prior_fea, prior_fea, sb, nullptr, false);
-                }
-
-            }
-
         }
-        else
-            assert(prior_options_->mode == "initial_guess" && "wrong prior_options->mode");
-
-        // notify all processors
-        keyFrameCallback(prior_keyframe, nullptr);
     }
-    // remove prior options
-    prior_options_ = nullptr;
-
-    return prior_keyframe;
-}
-
-FrameBasePtr Problem::setPriorFactor(const VectorComposite &_state,
-                                     const VectorComposite &_sigma,
-                                     const TimeStamp &_ts)
-{
-    setPriorOptions("factor", _state, _sigma);
-    return applyPriorOptions(_ts);
-}
 
+    // notify all processors
+    keyFrameCallback(first_frame, nullptr);
+    
+    // raise flag
+    prior_applied_ = true;
 
-FrameBasePtr Problem::setPriorFix(const VectorComposite &_state,
-                                  const TimeStamp &_ts)
-{
-    setPriorOptions("fix", _state);
-    return applyPriorOptions(_ts);
+    return first_frame;
 }
 
-FrameBasePtr Problem::setPriorInitialGuess(const VectorComposite &_state,
-                                           const TimeStamp &_ts)
+FrameBasePtr Problem::setPrior(const SpecComposite& _priors, const TimeStamp& _ts)
 {
-    setPriorOptions("initial_guess", _state);
+    setPriorOptions(_priors);
     return applyPriorOptions(_ts);
 }
 
diff --git a/src/sensor/prior_sensor.cpp b/src/sensor/prior_sensor.cpp
deleted file mode 100644
index b3b67f2443168d0dde35b2ee680dc0c0910f3251..0000000000000000000000000000000000000000
--- a/src/sensor/prior_sensor.cpp
+++ /dev/null
@@ -1,97 +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/sensor/prior_sensor.h"
-#include "core/state_block/factory_state_block.h"
-#include "core/common/params_base.h" // toString()
-
-namespace wolf
-{
-
-PriorSensorMap::PriorSensorMap(const YAML::Node& priors_node)
-{
-    if (not priors_node.IsMap())
-    {
-        throw std::runtime_error("PriorSensorMap: constructor with a non-map yaml node");
-    }
-    for (auto prior_pair : priors_node)
-    {
-        this->emplace(prior_pair.first.as<char>(), PriorSensor(prior_pair.second));
-    }
-}
-
-PriorSensor::PriorSensor(const std::string&     _type,
-                         const Eigen::VectorXd& _state,
-                         const std::string&     _mode,
-                         const Eigen::VectorXd& _noise_std,
-                         bool                   _dynamic,
-                         const Eigen::VectorXd& _drift_std) :
-    Prior(_type, _state, _mode, _noise_std),
-    dynamic_(_dynamic), 
-    drift_std_(_drift_std)
-{
-    check();
-}
-
-PriorSensor::PriorSensor(const YAML::Node& prior_node) :
-    Prior(prior_node)
-{
-    dynamic_ = prior_node["dynamic"].as<bool>();
-
-    if (dynamic_ and prior_node["drift_std"])
-        drift_std_ = prior_node["drift_std"].as<Eigen::VectorXd>();
-    else
-        drift_std_ = Eigen::VectorXd(0);
-
-    check();
-}
-
-void PriorSensor::check() const
-{
-    Prior::check();
-
-    // try to create a state block and check for local parameterization and dimensions consistency
-    StateBlockPtr sb;
-    try 
-    {
-        sb = FactoryStateBlock::create(type_, state_, mode_ == "fix");
-    }
-    catch (const std::exception& e)
-    {
-        throw std::runtime_error("Prior::check() could not create state block from prior with error: " + 
-                                 std::string(e.what()) + print());
-    }
-
-    // check drift sigma size
-    if (dynamic_ and drift_std_.size() > 0 and drift_std_.size() != sb->getLocalSize())
-        throw std::runtime_error("Prior::check() Prior " + type_ +
-                                 " drift_std size different of StateBlock local size. " + print());
-}
-
-std::string PriorSensor::print() const
-{
-    return Prior::print() + 
-           "dynamic: " + toString(dynamic_) + "\n" + 
-           (drift_std_.size() > 0 ? "drift_std: " + toString(drift_std_) + "\n" : "");
-}
-
-}  // namespace wolf
\ No newline at end of file
diff --git a/src/sensor/sensor_base.cpp b/src/sensor/sensor_base.cpp
index 90d40f660ff1c5df3ba584288074ae2065a70cef..bdcfc17b0a5c94b48705d9e876ee1a469286b998 100644
--- a/src/sensor/sensor_base.cpp
+++ b/src/sensor/sensor_base.cpp
@@ -34,9 +34,9 @@ unsigned int SensorBase::sensor_id_count_ = 0;
 SensorBase::SensorBase(const std::string& _type,
                        const int& _dim,
                        ParamsSensorBasePtr _params,
-                       const PriorSensorMap& _priors) :
+                       const SpecSensorComposite& _priors) :
         NodeBase("SENSOR", _type, _params->name),
-        HasStateBlocks("PO"),
+        HasStateBlocks(),
         hardware_ptr_(),
         sensor_id_(++sensor_id_count_), // simple ID factory
         params_(_params),
@@ -44,18 +44,6 @@ SensorBase::SensorBase(const std::string& _type,
         features_prior_map_(),
         last_capture_(nullptr),
         dim_(_dim)
-{
-    // load priors
-    loadPriors(_priors);
-}
-
-SensorBase::~SensorBase()
-{
-    // Remove State Blocks
-    removeStateBlocks(getProblem());
-}
-
-void SensorBase::loadPriors(const PriorSensorMap& _priors)
 {
     // Iterate all keys in _priors
     for (auto state_pair : _priors)
@@ -71,17 +59,13 @@ void SensorBase::loadPriors(const PriorSensorMap& _priors)
         if (key == 'O' and prior.getType() != "O" and prior.getType() != "StateAngle" and prior.getType() != "StateQuaternion")
             throw std::runtime_error("Prior type for key O in 3D has to be 'O', 'StateAngle' or 'StateQuaternion'");
         
-        // --- CREATE STATE BLOCK ---
+        // Create state block
         auto sb = FactoryStateBlock::create(prior.getType(), prior.getState(), prior.isFixed());
 
-        // check local param 
-        if (not sb->isValid()) // always false I think, the stateblock constructor would have failed...
-            throw std::runtime_error("The created stateblock " + prior.getType() + " for key " + std::string(1,key) + " is not valid (local param violation)");
-
-        // --- ADD STATE BLOCK ---
+        // Add state block
         addStateBlock(key, sb, prior.isDynamic());
 
-        // Factor
+        // Add factor
         if (prior.isFactor())
             addPriorParameter(key, prior.getState(), prior.getNoiseStd().cwiseAbs2().asDiagonal());
 
@@ -91,6 +75,12 @@ void SensorBase::loadPriors(const PriorSensorMap& _priors)
     }
 }
 
+SensorBase::~SensorBase()
+{
+    // Remove State Blocks
+    removeStateBlocks(getProblem());
+}
+
 void SensorBase::fixExtrinsics()
 {
     for (auto key : std::string("PO"))
diff --git a/src/sensor/sensor_diff_drive.cpp b/src/sensor/sensor_diff_drive.cpp
index 5e4aef093efc4cab77eb44a1ebd4a1ce179d21fc..4a3b7401b3caad2a905e6a19f67f0294534f9a16 100644
--- a/src/sensor/sensor_diff_drive.cpp
+++ b/src/sensor/sensor_diff_drive.cpp
@@ -34,7 +34,7 @@ namespace wolf
 {
 
 SensorDiffDrive::SensorDiffDrive(ParamsSensorDiffDrivePtr _params,
-                                 const PriorSensorMap& _priors) :
+                                 const SpecSensorComposite& _priors) :
         SensorBase("SensorDiffDrive", 
                    2,
                    _params,
diff --git a/src/sensor/sensor_motion_model.cpp b/src/sensor/sensor_motion_model.cpp
index b2aa8d5d3cd7c1677874316d94460343f2396284..58a28fa17532374b8fb035c9f644a20cf5eec49d 100644
--- a/src/sensor/sensor_motion_model.cpp
+++ b/src/sensor/sensor_motion_model.cpp
@@ -24,7 +24,7 @@
 namespace wolf {
 
 SensorMotionModel::SensorMotionModel(ParamsSensorBasePtr _params,
-                                     const PriorSensorMap& _priors) :
+                                     const SpecSensorComposite& _priors) :
         SensorBase("SensorMotionModel", 
                    -1,
                    _params,
diff --git a/src/sensor/spec_state_sensor.cpp b/src/sensor/spec_state_sensor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..281338cc66a9f0f12bfa58839935a99762f6643a
--- /dev/null
+++ b/src/sensor/spec_state_sensor.cpp
@@ -0,0 +1,88 @@
+//--------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/sensor/spec_state_sensor.h"
+#include "core/state_block/factory_state_block.h"
+#include "core/common/params_base.h" // toString()
+
+namespace wolf
+{
+
+SpecComposite SpecSensorComposite::getSpecComposite() const
+{
+    SpecComposite spec_composite;
+    for (auto spec_sensor_pair : *this)
+    {
+        spec_composite.emplace(spec_sensor_pair.first, SpecState(spec_sensor_pair.second.getType(), 
+                                                                 spec_sensor_pair.second.getState(),
+                                                                 spec_sensor_pair.second.getMode(),
+                                                                 spec_sensor_pair.second.getNoiseStd()));
+    }
+    return spec_composite;
+}
+
+SpecStateSensor::SpecStateSensor(const std::string&     _type,
+                                 const Eigen::VectorXd& _state,
+                                 const std::string&     _mode,
+                                 const Eigen::VectorXd& _noise_std,
+                                 bool                   _dynamic,
+                                 const Eigen::VectorXd& _drift_std) :
+    SpecState(_type, _state, _mode, _noise_std),
+    dynamic_(_dynamic), 
+    drift_std_(_drift_std)
+{
+    check();
+}
+
+SpecStateSensor::SpecStateSensor(const YAML::Node& prior_node) :
+    SpecState(prior_node)
+{
+    dynamic_ = prior_node["dynamic"].as<bool>();
+
+    if (dynamic_ and prior_node["drift_std"])
+        drift_std_ = prior_node["drift_std"].as<Eigen::VectorXd>();
+    else
+        drift_std_ = Eigen::VectorXd(0);
+
+    check();
+}
+
+void SpecStateSensor::check() const
+{
+    SpecState::check();
+
+    auto sb = FactoryStateBlock::create(type_, state_, mode_ == "fix"); // already tried in SpecState::check()
+
+    // check drift sigma size
+    if (dynamic_ and drift_std_.size() > 0 and drift_std_.size() != sb->getLocalSize())
+        throw std::runtime_error("SpecStateSensor::check() Prior " + type_ +
+                                 " drift_std size different of StateBlock local size. " + print());
+}
+
+std::string SpecStateSensor::print(const std::string& _spaces) const
+{
+    return SpecState::print(_spaces) + 
+           _spaces + "dynamic: " + toString(dynamic_) + "\n" + 
+           (drift_std_.size() > 0 ? _spaces + "drift_std: " + toString(drift_std_) + "\n" : "");
+}
+
+}  // namespace wolf
\ No newline at end of file
diff --git a/src/state_block/has_state_blocks.cpp b/src/state_block/has_state_blocks.cpp
index c348c5109ac0f34a5ff90705428bc6a2c1a4427d..67f6a6fa7a5204c3e827113cafea638644de6a1f 100644
--- a/src/state_block/has_state_blocks.cpp
+++ b/src/state_block/has_state_blocks.cpp
@@ -26,13 +26,42 @@
 namespace wolf
 {
 
-StateBlockPtr HasStateBlocks::addStateBlock(const char& _sb_type, const StateBlockPtr& _sb, ProblemPtr _problem)
+HasStateBlocks::HasStateBlocks(const SpecComposite& _specs)
 {
-    assert(state_block_map_.count(_sb_type) == 0 && state_block_const_map_.count(_sb_type) == 0 && "Trying to add a state block with an existing type! Use setStateBlock instead.");
-    state_block_map_.emplace(_sb_type, _sb);
-    state_block_const_map_.emplace(_sb_type, _sb);
-    if (!isInStructure(_sb_type))
-        appendToStructure(_sb_type);
+    for (auto spec : _specs)
+    {
+        if (spec.first == 'P' and 
+            spec.second.getType() != "P" and 
+            spec.second.getType() != "StatePoint2d" and 
+            spec.second.getType() != "StatePoint3d" )
+        {
+            throw std::runtime_error("HasStateBlocks: in key 'P', the state block should be of type 'P', 'StatePoint2d' or 'StatePoint3d'");
+        }
+        if (spec.first == 'O' and 
+            spec.second.getType() != "O" and 
+            spec.second.getType() != "StateAngle" and 
+            spec.second.getType() != "StateQuaternion" )
+        {
+            throw std::runtime_error("HasStateBlocks: in key 'O', the state block should be of type 'O', 'StateAngle' or 'StateQuaternion'");
+        }
+        if (spec.first == 'V' and 
+            spec.second.getType() != "V" and 
+            spec.second.getType() != "StateVector2d" and 
+            spec.second.getType() != "StateVector3d" )
+        {
+            throw std::runtime_error("HasStateBlocks: in key 'O', the state block should be of type 'O', 'StateAngle' or 'StateQuaternion'");
+        }
+        addStateBlock(spec.first, FactoryStateBlock::create(spec.second.getType(), spec.second.getState(), spec.second.isFixed()), nullptr);
+    }
+}
+
+StateBlockPtr HasStateBlocks::addStateBlock(const char& _sb_key, const StateBlockPtr& _sb, ProblemPtr _problem)
+{
+    assert(state_block_map_.count(_sb_key) == 0 && state_block_const_map_.count(_sb_key) == 0 && "Trying to add a state block with an existing type! Use setStateBlock instead.");
+    state_block_map_.emplace(_sb_key, _sb);
+    state_block_const_map_.emplace(_sb_key, _sb);
+    if (!isInStructure(_sb_key))
+        appendToStructure(_sb_key);
 
     // conditionally register to problem
     if(_problem)
diff --git a/src/state_block/prior.cpp b/src/state_block/prior.cpp
deleted file mode 100644
index a37b084e2e4a8f4a9e997a8e0ab1c3dd644550e8..0000000000000000000000000000000000000000
--- a/src/state_block/prior.cpp
+++ /dev/null
@@ -1,117 +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/state_block/prior.h"
-#include "core/state_block/factory_state_block.h"
-#include "core/common/params_base.h" // toString()
-
-namespace wolf
-{
-
-PriorMap::PriorMap(const YAML::Node& priors_node)
-{
-    if (not priors_node.IsMap())
-    {
-        throw std::runtime_error("PriorMap: constructor with a non-map yaml node");
-    }
-    for (auto prior_pair : priors_node)
-    {
-        this->emplace(prior_pair.first.as<char>(), Prior(prior_pair.second));
-    }
-}
-
-VectorComposite PriorMap::getState() const
-{
-    VectorComposite prior_states;
-    for (auto prior_pair : *this)
-    {
-        prior_states.emplace(prior_pair.first, prior_pair.second.getState());
-    }
-}
-
-Prior::Prior(const std::string&     _type,
-             const Eigen::VectorXd& _state,
-             const std::string&     _mode,
-             const Eigen::VectorXd& _noise_std)
-    : type_(_type), state_(_state), mode_(_mode), noise_std_(_noise_std)
-{
-    check();
-}
-
-Prior::Prior(const YAML::Node& prior_node)
-{
-    type_  = prior_node["type"].as<std::string>();
-    state_ = prior_node["state"].as<Eigen::VectorXd>();
-    mode_  = prior_node["mode"].as<std::string>();
-    if (mode_ == "factor") 
-      noise_std_ = prior_node["noise_std"].as<Eigen::VectorXd>();
-    else 
-      noise_std_ = Eigen::VectorXd(0);
-
-    check();
-}
-
-void Prior::check() const
-{
-    if (mode_ != "initial_guess" and mode_ != "fix" and mode_ != "factor")
-        throw std::runtime_error("Prior::check() wrong mode value: " + mode_ +
-                                 ", it should be: 'initial_guess', 'fix' or 'factor'. " + print());
-
-    // check empty state
-    if (state_.size() == 0)
-        throw std::runtime_error("Prior::check() Prior " + type_ + " state size zero. " + print());
-
-    // try to create a state block and check for local parameterization and dimensions consistency
-    StateBlockPtr sb;
-    try 
-    {
-        sb = FactoryStateBlock::create(type_, state_, mode_ == "fix");
-    }
-    catch (const std::exception& e) 
-    {
-        throw std::runtime_error("Prior::check() could not create state block from prior with error: " + std::string(e.what()) + print());
-    }
-
-    // check local param
-    if (not sb->isValid())
-        throw std::runtime_error("Prior::check() Prior " + type_ + " state is not valid (local param violation). " +
-                                 print());
-
-    // check state size
-    if (state_.size() != sb->getSize())
-        throw std::runtime_error("Prior::check() Prior " + type_ + " state size different of StateBlock size. " + print());
-
-    // check factor sigma size
-    if (mode_ == "factor" and noise_std_.size() != sb->getLocalSize())
-        throw std::runtime_error("Prior::check() Prior " + type_ + " noise_std size different of StateBlock local size. " +
-                                 print());
-}
-
-std::string Prior::print() const
-{
-    return "Prior " + type_ + "\n" +
-           "mode: " + mode_ + "\n" + 
-           "state: " + toString(state_) + "\n" +
-           (mode_ == "factor" ? "noise_std: " + toString(noise_std_) + "\n" : "");
-}
-
-}  // namespace wolf
\ No newline at end of file
diff --git a/src/state_block/spec_composite.cpp b/src/state_block/spec_composite.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7a648badba22d1992db71d1bee684a3f720c08bb
--- /dev/null
+++ b/src/state_block/spec_composite.cpp
@@ -0,0 +1,83 @@
+//--------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/state_block/spec_composite.h"
+#include "core/state_block/factory_state_block.h"
+#include "core/common/params_base.h" // toString()
+
+namespace wolf
+{
+
+SpecState::SpecState(const std::string&     _type,
+                     const Eigen::VectorXd& _state,
+                     const std::string&     _mode,
+                     const Eigen::VectorXd& _noise_std)
+    : type_(_type), state_(_state), mode_(_mode), noise_std_(_noise_std)
+{
+    check();
+}
+
+SpecState::SpecState(const YAML::Node& _n)
+{
+    type_  = _n["type"].as<std::string>();
+    state_ = _n["state"].as<Eigen::VectorXd>();
+    mode_  = _n["mode"].as<std::string>();
+    if (mode_ == "factor") 
+      noise_std_ = _n["noise_std"].as<Eigen::VectorXd>();
+    else 
+      noise_std_ = Eigen::VectorXd(0);
+
+    check();
+}
+
+void SpecState::check() const
+{
+    if (mode_ != "initial_guess" and mode_ != "fix" and mode_ != "factor")
+        throw std::runtime_error("SpecState::check() wrong mode value: " + mode_ +
+                                 ", it should be: 'initial_guess', 'fix' or 'factor'. " + print());
+
+    // try to create a state block and check for local parameterization and dimensions consistency
+    StateBlockPtr sb;
+    try 
+    {
+        sb = FactoryStateBlock::create(type_, state_, mode_ == "fix");
+    }
+    catch (const std::exception& e) 
+    {
+        throw std::runtime_error("SpecState::check() could not create state block from prior with error: " + std::string(e.what()) + print());
+    }
+
+    // check factor sigma size
+    if (mode_ == "factor" and noise_std_.size() != sb->getLocalSize())
+        throw std::runtime_error("SpecState::check() SpecState " + type_ + " noise_std size different of StateBlock local size. " +
+                                 print());
+}
+
+std::string SpecState::print(const std::string& _spaces) const
+{
+    return _spaces + "SpecState " + type_ + "\n" +
+           _spaces + "mode: " + mode_ + "\n" + 
+           _spaces + "state: " + toString(state_) + "\n" +
+           (mode_ == "factor" ? _spaces + "noise_std: " + toString(noise_std_) + "\n" : "");
+}
+
+}  // namespace wolf
\ No newline at end of file
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 5736cabf66600b37b16cd9da8fc4bc56b215f0af..0e96bf4bb0d8442a9614e690d9d586883bb97ab8 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -197,7 +197,7 @@ wolf_add_gtest(gtest_tree_manager gtest_tree_manager.cpp)
 # # ProcessorMotion in 2d
 # wolf_add_gtest(gtest_odom_2d gtest_odom_2d.cpp)
 
-# PriorSensor
+# SpecStateSensor
 wolf_add_gtest(gtest_prior_sensor gtest_prior_sensor.cpp)
 
 # # ProcessorOdom3d class test
diff --git a/test/dummy/SensorDummy2d.schema b/test/dummy/SensorDummy2d.schema
index 0175bd14bd1e5b31ffca663d870f48cc901fa9b8..c45f3d5b3fd93ee906ee354e97566559d1ddde0f 100644
--- a/test/dummy/SensorDummy2d.schema
+++ b/test/dummy/SensorDummy2d.schema
@@ -1,9 +1,9 @@
 follow: SensorBase.schema
 states:
   P:
-    follow: PriorP2d.schema
+    follow: SpecStateSensorP2d.schema
   O:
-    follow: PriorO2d.schema
+    follow: SpecStateSensorO2d.schema
 noise_p_std:
   mandatory: true
   type: double
diff --git a/test/dummy/SensorDummy3d.schema b/test/dummy/SensorDummy3d.schema
index 941cb53d050d8d25ebb26c8ead01a79a05bb750f..588905e62bf8e21ac07d140caa03450fc4884bff 100644
--- a/test/dummy/SensorDummy3d.schema
+++ b/test/dummy/SensorDummy3d.schema
@@ -1,9 +1,9 @@
 follow: SensorBase.schema
 states:
   P:
-    follow: PriorP3d.schema
+    follow: SpecStateSensorP3d.schema
   O:
-    follow: PriorO3d.schema
+    follow: SpecStateSensorO3d.schema
 noise_p_std:
   mandatory: true
   type: double
diff --git a/test/dummy/SensorDummyPoia3d.schema b/test/dummy/SensorDummyPoia3d.schema
index 180e9e84230c364548c5d0c8aa5206db961d1135..a36247c84db2706d0d4ebfa93f036973120eed48 100644
--- a/test/dummy/SensorDummyPoia3d.schema
+++ b/test/dummy/SensorDummyPoia3d.schema
@@ -1,11 +1,11 @@
 follow: SensorBase.schema
 states:
   P:
-    follow: PriorP3d.schema
+    follow: SpecStateSensorP3d.schema
   O:
-    follow: PriorO3d.schema
+    follow: SpecStateSensorO3d.schema
   I:
-    follow: Prior.schema
+    follow: SpecStateSensor.schema
     type:
       type: string
       yaml_type: scalar
@@ -19,7 +19,7 @@ states:
       mandatory: true
       doc: A vector containing the state 'I' values
   A:
-    follow: Prior.schema
+    follow: SpecStateSensor.schema
     type:
       type: string
       yaml_type: scalar
diff --git a/test/dummy/sensor_dummy.h b/test/dummy/sensor_dummy.h
index 77b8c9772ffb56ab6522a2194508655fe96cfa1e..bca6fed749f1158fc4898f113a5878db01366dd5 100644
--- a/test/dummy/sensor_dummy.h
+++ b/test/dummy/sensor_dummy.h
@@ -59,7 +59,7 @@ class SensorDummy : public SensorBase
 
     public:
         SensorDummy(ParamsSensorDummyPtr _params,
-                    const PriorSensorMap& _priors) :
+                    const SpecSensorComposite& _priors) :
             SensorBase("SensorDummy"+toString(DIM)+"d",
                        DIM,
                        _params,
diff --git a/test/gtest_emplace.cpp b/test/gtest_emplace.cpp
index 3e9fd8f63fbab40985179670ae055288247e1f32..c9f34bbf031ec8b09e5d50ea3ab0fcc7f6c370bb 100644
--- a/test/gtest_emplace.cpp
+++ b/test/gtest_emplace.cpp
@@ -62,8 +62,8 @@ TEST(Emplace, Sensor)
                                                 "dummy_name", 
                                                 2, 
                                                 std::make_shared<ParamsSensorDummy>(), 
-                                                PriorSensorMap({{'P',PriorSensor("P",Vector2d::Zero())},
-                                                                {'O',PriorSensor("O",Vector1d::Zero())}}));
+                                                SpecSensorComposite({{'P',SpecStateSensor("P",Vector2d::Zero())},
+                                                                {'O',SpecStateSensor("O",Vector1d::Zero())}}));
                                                         
     ASSERT_EQ(P, P->getHardware()->getSensorList().front()->getHardware()->getProblem());
 }
@@ -84,8 +84,8 @@ TEST(Emplace, Processor)
                                                 "dummy_name", 
                                                 2, 
                                                 std::make_shared<ParamsSensorDummy>(), 
-                                                PriorSensorMap({{'P',PriorSensor("P",Vector2d::Zero())},
-                                                        {'O',PriorSensor("O",Vector1d::Zero())}}));
+                                                SpecSensorComposite({{'P',SpecStateSensor("P",Vector2d::Zero())},
+                                                        {'O',SpecStateSensor("O",Vector1d::Zero())}}));
     auto prc = ProcessorOdom2d::emplace<ProcessorOdom2d>(sen, std::make_shared<ParamsProcessorOdom2d>());
     ASSERT_EQ(P, P->getHardware()->getSensorList().front()->getProcessorList().front()->getSensor()->getProblem());
     ASSERT_EQ(sen, sen->getProcessorList().front()->getSensor());
@@ -95,8 +95,8 @@ TEST(Emplace, Processor)
                                                           "dummy_name", 
                                                           2, 
                                                           std::make_shared<ParamsSensorDummy>(), 
-                                                          PriorSensorMap({{'P',PriorSensor("P",Vector2d::Zero())},
-                                                                  {'O',PriorSensor("O",Vector1d::Zero())}}));
+                                                          SpecSensorComposite({{'P',SpecStateSensor("P",Vector2d::Zero())},
+                                                                  {'O',SpecStateSensor("O",Vector1d::Zero())}}));
     ProcessorOdom2dPtr prc2 = ProcessorOdom2d::emplace<ProcessorOdom2d>(sen2, std::make_shared<ParamsProcessorOdom2d>());
     ASSERT_EQ(sen2, sen2->getProcessorList().front()->getSensor());
     ASSERT_EQ(prc2, sen2->getProcessorList().front());
@@ -164,8 +164,8 @@ TEST(Emplace, EmplaceDerived)
                                                "dummy_name", 
                                                2, 
                                                std::make_shared<ParamsSensorOdom>(), 
-                                               PriorSensorMap({{'P',PriorSensor("P",Vector2d::Zero())},
-                                                       {'O',PriorSensor("O",Vector1d::Zero())}}));
+                                               SpecSensorComposite({{'P',SpecStateSensor("P",Vector2d::Zero())},
+                                                       {'O',SpecStateSensor("O",Vector1d::Zero())}}));
     auto cov = Eigen::MatrixXd::Identity(2,2);
     auto cpt = CaptureBase::emplace<CaptureOdom2d>(frm, TimeStamp(0), sen, Eigen::VectorXd(2), cov, nullptr);
     auto m = Eigen::Matrix<double,9,6>();
diff --git a/test/gtest_factor_diff_drive.cpp b/test/gtest_factor_diff_drive.cpp
index e69b506e3effcaf721b12eca254d616fe312441d..78f05eb997127d4dc723f0db15f2cfd8b3de9852 100644
--- a/test/gtest_factor_diff_drive.cpp
+++ b/test/gtest_factor_diff_drive.cpp
@@ -164,9 +164,9 @@ class FactorDiffDriveTest : public testing::Test
             params_sen = make_shared<ParamsSensorDiffDrive>();
             params_sen->ticks_per_wheel_revolution = 100; // DO NOT MODIFY THESE VALUES !!!
 
-            PriorSensorMap priors{{'P',PriorSensor("P", Vector2d::Zero())},           //default "fix", not dynamic
-                          {'O',PriorSensor("O", Vector1d::Zero())},           //default "fix", not dynamic
-                          {'I',PriorSensor("StateBlock", Vector3d::Ones(), "initial_guess")}}; // not dynamic
+            SpecSensorComposite priors{{'P',SpecStateSensor("P", Vector2d::Zero())},           //default "fix", not dynamic
+                          {'O',SpecStateSensor("O", Vector1d::Zero())},           //default "fix", not dynamic
+                          {'I',SpecStateSensor("StateBlock", Vector3d::Ones(), "initial_guess")}}; // not dynamic
             
             sensor = static_pointer_cast<SensorDiffDrive>(problem->installSensor("SensorDiffDrive", 
                                                                                  "sensor",
@@ -466,9 +466,9 @@ TEST(FactorDiffDrive, preintegrate_and_solve_sensor_intrinsics_gt)
     ParamsSensorDiffDrivePtr params_sen = make_shared<ParamsSensorDiffDrive>();
     params_sen->ticks_per_wheel_revolution = 100; // DO NOT MODIFY THESE VALUES !!!
 
-    PriorSensorMap priors{{'P',PriorSensor("P", Vector2d::Zero())},           //default "fix", not dynamic
-                  {'O',PriorSensor("O", Vector1d::Zero())},           //default "fix", not dynamic
-                  {'I',PriorSensor("StateBlock", Vector3d::Ones(), "initial_guess")}}; // not dynamic
+    SpecSensorComposite priors{{'P',SpecStateSensor("P", Vector2d::Zero())},           //default "fix", not dynamic
+                  {'O',SpecStateSensor("O", Vector1d::Zero())},           //default "fix", not dynamic
+                  {'I',SpecStateSensor("StateBlock", Vector3d::Ones(), "initial_guess")}}; // not dynamic
     
     auto sensor = static_pointer_cast<SensorDiffDrive>(problem->installSensor("SensorDiffDrive", 
                                                                             "sensor",
@@ -601,9 +601,9 @@ TEST(FactorDiffDrive, preintegrate_and_solve_sensor_intrinsics)
     ParamsSensorDiffDrivePtr params_sen = make_shared<ParamsSensorDiffDrive>();
     params_sen->ticks_per_wheel_revolution = 100; // DO NOT MODIFY THESE VALUES !!!
 
-    PriorSensorMap priors{{'P',PriorSensor("P", Vector2d::Zero())},           //default "fix", not dynamic
-                  {'O',PriorSensor("O", Vector1d::Zero())},           //default "fix", not dynamic
-                  {'I',PriorSensor("StateBlock", Vector3d::Ones(), "initial_guess")}}; // not dynamic
+    SpecSensorComposite priors{{'P',SpecStateSensor("P", Vector2d::Zero())},           //default "fix", not dynamic
+                  {'O',SpecStateSensor("O", Vector1d::Zero())},           //default "fix", not dynamic
+                  {'I',SpecStateSensor("StateBlock", Vector3d::Ones(), "initial_guess")}}; // not dynamic
     
     auto sensor = static_pointer_cast<SensorDiffDrive>(problem->installSensor("SensorDiffDrive", 
                                                                             "sensor",
diff --git a/test/gtest_factor_relative_pose_3d_with_extrinsics.cpp b/test/gtest_factor_relative_pose_3d_with_extrinsics.cpp
index f9b7a27b5d11c80a3fab5da79cd4aff061fe948b..d9be016dd463ede52c70e9213705a563770c387c 100644
--- a/test/gtest_factor_relative_pose_3d_with_extrinsics.cpp
+++ b/test/gtest_factor_relative_pose_3d_with_extrinsics.cpp
@@ -119,8 +119,8 @@ class FactorRelativePose3dWithExtrinsics_class : public testing::Test{
             S = problem->installSensor("SensorPose", 
                                        "sensor_pose_1", 
                                        std::make_shared<ParamsSensorPose>(),
-                                       PriorSensorMap{{'P',PriorSensor("P",pos_camera)},
-                                              {'O',PriorSensor("O",vquat_camera)}});
+                                       SpecSensorComposite{{'P',SpecStateSensor("P",pos_camera)},
+                                              {'O',SpecStateSensor("O",vquat_camera)}});
 
             // F1 is be origin KF
             VectorComposite x0(pose_robot, "PO", {3,4});
diff --git a/test/gtest_param_prior.cpp b/test/gtest_param_prior.cpp
index 8ff7aefc9b877cbb8ff74aaf62f684f427f2d1ca..3f4146a10fe9201887f3ab5a0f9c509dd39ae689 100644
--- a/test/gtest_param_prior.cpp
+++ b/test/gtest_param_prior.cpp
@@ -46,8 +46,8 @@ Vector7d prior_extrinsics((Vector7d() << 10, 20, 30, 0, 0, 0, 1).finished());
 Vector7d prior2_extrinsics((Vector7d() << 100, 200, 300, 0, 0, 0, 1).finished());
 
 ParamsSensorOdomPtr params = std::make_shared<ParamsSensorOdom>();
-PriorSensorMap priors{{'P',PriorSensor("P",initial_extrinsics_p,"initial_guess")},
-              {'O',PriorSensor("O",initial_extrinsics_o,"initial_guess")}};
+SpecSensorComposite priors{{'P',SpecStateSensor("P",initial_extrinsics_p,"initial_guess")},
+              {'O',SpecStateSensor("O",initial_extrinsics_o,"initial_guess")}};
 SensorBasePtr sensor_ptr_ = problem_ptr->installSensor("SensorOdom", 
                                                        "odometer", 
                                                        params, 
diff --git a/test/gtest_prior_sensor.cpp b/test/gtest_prior_sensor.cpp
index a850f3a5d664ee6a8ca01c6b82ab8118844e4434..53bda0b3e1379939454150e52a6e162e4b29e29e 100644
--- a/test/gtest_prior_sensor.cpp
+++ b/test/gtest_prior_sensor.cpp
@@ -22,7 +22,7 @@
 
 #include "core/utils/utils_gtest.h"
 #include "core/common/wolf.h"
-#include "core/sensor/prior_sensor.h"
+#include "core/sensor/spec_state_sensor.h"
 #include "core/common/params_base.h" // toString
 
 using namespace wolf;
@@ -47,7 +47,7 @@ struct PriorAsStruct
   VectorXd drift_std;
 };
 
-void testPriorSensor(const PriorSensor& P,
+void testPriorSensor(const SpecStateSensor& P,
                      const PriorAsStruct& pstruct)
 {
   ASSERT_EQ(pstruct.type, P.getType());
@@ -84,15 +84,15 @@ void testPriorSensorSensorMap(const std::vector<PriorAsStruct>& setups, bool sho
               "\n\tdynamic: ", setup.dynamic,
               "\n\tdrift_std: ", setup.drift_std.transpose());
     if (should_work)
-      testPriorSensor(PriorSensor(setup.type, setup.state, setup.mode, setup.noise_std, setup.dynamic, setup.drift_std), setup);
+      testPriorSensor(SpecStateSensor(setup.type, setup.state, setup.mode, setup.noise_std, setup.dynamic, setup.drift_std), setup);
     else
     {
-      ASSERT_THROW(testPriorSensor(PriorSensor(setup.type, setup.state, setup.mode, setup.noise_std, setup.dynamic, setup.drift_std), setup),std::runtime_error);
+      ASSERT_THROW(testPriorSensor(SpecStateSensor(setup.type, setup.state, setup.mode, setup.noise_std, setup.dynamic, setup.drift_std), setup),std::runtime_error);
     }
   }
 }
 
-TEST(PriorSensor, P)
+TEST(SpecStateSensor, P)
 {
   std::vector<PriorAsStruct> setups_ok, setups_death;
 
@@ -142,7 +142,7 @@ TEST(PriorSensor, P)
   testPriorSensorSensorMap(setups_death, false);
 }
 
-TEST(PriorSensor, O)
+TEST(SpecStateSensor, O)
 {
   std::vector<PriorAsStruct> setups_ok, setups_death;
 
@@ -198,7 +198,7 @@ TEST(PriorSensor, O)
   testPriorSensorSensorMap(setups_death, false);
 }
 
-TEST(PriorSensor, StateBlock)
+TEST(SpecStateSensor, StateBlock)
 {
   std::vector<PriorAsStruct> setups_ok, setups_death;
 
@@ -247,7 +247,7 @@ TEST(PriorSensor, StateBlock)
   testPriorSensorSensorMap(setups_ok, true);
   testPriorSensorSensorMap(setups_death, false);
 }
-TEST(PriorSensor, StateAngle)
+TEST(SpecStateSensor, StateAngle)
 {
   std::vector<PriorAsStruct> setups_ok, setups_death;
 
@@ -288,7 +288,7 @@ TEST(PriorSensor, StateAngle)
   testPriorSensorSensorMap(setups_death, false);
 }
 
-TEST(PriorSensor, StateQuaternion)
+TEST(SpecStateSensor, StateQuaternion)
 {
   std::vector<PriorAsStruct> setups_ok, setups_death;
 
@@ -335,7 +335,7 @@ TEST(PriorSensor, StateQuaternion)
   testPriorSensorSensorMap(setups_death, false);
 }
 
-TEST(PriorSensor, YamlNode)
+TEST(SpecStateSensor, YamlNode)
 {
   YAML::Node input_node = YAML::LoadFile(wolf_root + "/test/yaml/params_prior.yaml");
 
@@ -364,7 +364,7 @@ TEST(PriorSensor, YamlNode)
             std::string prefix = key + "_" + toString(dim) + "D_" + mode + (dynamic ? "_dynamic" : "") + (drift ? "_drift" : "");
 
             WOLF_INFO("Creating prior from prefix ", prefix);
-            auto P = PriorSensor(input_node[prefix]);
+            auto P = SpecStateSensor(input_node[prefix]);
 
             // Checks
             ASSERT_EQ(P.getMode(), mode);
@@ -401,7 +401,7 @@ TEST(PriorSensor, YamlNode)
 
         std::string prefix = "I_" + mode + (dynamic ? "_dynamic" : "") + (drift ? "_drift" : "");
         WOLF_INFO("Creating prior from prefix ", prefix);
-        auto P = PriorSensor(input_node[prefix]);
+        auto P = SpecStateSensor(input_node[prefix]);
         ASSERT_EQ(P.getMode(), mode);
         ASSERT_EQ(P.isDynamic(), dynamic);
         ASSERT_MATRIX_APPROX(P.getState(),p_state,wolf::Constants::EPS);
@@ -416,7 +416,7 @@ TEST(PriorSensor, YamlNode)
       }
 }
 
-TEST(PriorSensor, ParamsServerWrong)
+TEST(SpecStateSensor, ParamsServerWrong)
 {
   YAML::Node input_node = YAML::LoadFile(wolf_root + "/test/yaml/params_prior_wrong.yaml");
 
@@ -440,7 +440,7 @@ TEST(PriorSensor, ParamsServerWrong)
             std::string prefix = key + "_" + toString(dim) + "D_" + mode + (dynamic ? "_dynamic" : "") + (drift ? "_drift" : "");
 
             WOLF_INFO("Creating prior from prefix ", prefix);
-            ASSERT_THROW(auto prior = PriorSensor(input_node[prefix]),std::runtime_error);
+            ASSERT_THROW(auto prior = SpecStateSensor(input_node[prefix]),std::runtime_error);
           }
 
   // I
@@ -454,7 +454,7 @@ TEST(PriorSensor, ParamsServerWrong)
 
         std::string prefix = "I_" + mode + (dynamic ? "_dynamic" : "") + (drift ? "_drift" : "");
         WOLF_INFO("Creating prior from prefix ", prefix);
-        ASSERT_THROW(auto prior = PriorSensor(input_node[prefix]),std::runtime_error);
+        ASSERT_THROW(auto prior = SpecStateSensor(input_node[prefix]),std::runtime_error);
       }
 }
 
diff --git a/test/gtest_problem.cpp b/test/gtest_problem.cpp
index a019989126e9904dcfc3a87ecaf1fe385f48aeb0..6c8dbf4ac368867c90052eb034125156a42f9b76 100644
--- a/test/gtest_problem.cpp
+++ b/test/gtest_problem.cpp
@@ -80,8 +80,8 @@ TEST(Problem, Sensors)
     params->name = "dummy_name";
     auto S = SensorBase::emplace<SensorDummy3d>(P->getHardware(),
                                                 params,
-                                                PriorSensorMap({{'P',PriorSensor("P",Vector3d::Zero())},
-                                                        {'O',PriorSensor("O",Vector4d::Random().normalized())}}));
+                                                SpecSensorComposite({{'P',SpecStateSensor("P",Vector3d::Zero())},
+                                                        {'O',SpecStateSensor("O",Vector4d::Random().normalized())}}));
     // check pointers
     ASSERT_EQ(P, S->getProblem());
     ASSERT_EQ(P->getHardware(), S->getHardware());
@@ -100,8 +100,8 @@ TEST(Problem, Processor)
     params->name = "dummy_name";
     auto Sm = SensorBase::emplace<SensorOdom3d>(P->getHardware(), 
                                                 params, 
-                                                PriorSensorMap({{'P',PriorSensor("P",Vector3d::Zero())},
-                                                        {'O',PriorSensor("O",Vector4d::Random().normalized())}}));
+                                                SpecSensorComposite({{'P',SpecStateSensor("P",Vector3d::Zero())},
+                                                        {'O',SpecStateSensor("O",Vector4d::Random().normalized())}}));
 
     // add motion processor
     auto Pm = ProcessorBase::emplace<ProcessorOdom3d>(Sm, std::make_shared<ParamsProcessorOdom3d>());
@@ -137,13 +137,13 @@ TEST(Problem, Installers)
 TEST(Problem, SetOrigin_PO_2d)
 {
     ProblemPtr P = Problem::create("PO", 2);
-    TimeStamp       t0(0);
-    // Eigen::VectorXd x0(3); x0 << 1,2,3;
-    VectorComposite x0(Vector3d(1,2,3), "PO", {2,1});
-    // Eigen::MatrixXd P0(Eigen::MatrixXd::Identity(3,3) * 0.1); // P0 is 0.1*Id
-    VectorComposite s0(Vector3d(sqrt(0.1),sqrt(0.1),sqrt(0.1)), "PO", {2,1});
+    TimeStamp t0(0);
+    SpecComposite prior;
+    prior.emplace('P',SpecState("P",Vector2d(1,2),"factor",Vector2d(sqrt(0.1),sqrt(0.1))));
+    prior.emplace('O',SpecState("O",Vector1d(3),"factor",Vector1d(sqrt(0.1))));
+    P->setPrior(prior, t0);
 
-    P->setPriorFactor(x0, s0, t0);
+    // P->setPriorFactor(x0, s0, t0);
     WOLF_INFO("printing.-..");
     P->print(4,1,1,1);
 
@@ -151,7 +151,7 @@ TEST(Problem, SetOrigin_PO_2d)
     ASSERT_EQ(P->getHardware()->getSensorList().size(), (SizeStd) 0);
 
     // check that the state is correct
-    ASSERT_POSE2d_APPROX(x0.vector("PO"), P->getState().vector("PO"), Constants::EPS_SMALL );
+    ASSERT_POSE2d_APPROX(prior.getState().vector("PO"), P->getState().vector("PO"), Constants::EPS_SMALL );
 
     // check that we have one frame, one capture, one feature, one factor
     TrajectoryBasePtr T = P->getTrajectory();
@@ -180,15 +180,15 @@ TEST(Problem, SetOrigin_PO_2d)
         ASSERT_FALSE(fac->getCaptureOther());
         ASSERT_FALSE(fac->getFeatureOther());
     }
-    auto x0_vector = x0.vector("PO");
-    auto s0_vector = s0.vector("PO");
-    MatrixXd P0_matrix = (s0_vector.array() * s0_vector.array()).matrix().asDiagonal();
+    auto x0_vector = prior.getState().vector("PO");
+    auto P0_p = prior.at('P').getNoiseStd().cwiseAbs2().asDiagonal();
+    auto P0_o = prior.at('O').getNoiseStd().cwiseAbs2().asDiagonal();
 
     // check that the Feature measurement and covariance are the ones provided
     ASSERT_MATRIX_APPROX(x0_vector.head<2>(), fp->getMeasurement(), Constants::EPS_SMALL );
     ASSERT_MATRIX_APPROX(x0_vector.tail<1>(), fo->getMeasurement(), Constants::EPS_SMALL );
-    ASSERT_MATRIX_APPROX(P0_matrix.topLeftCorner(2,2), fp->getMeasurementCovariance(), Constants::EPS_SMALL );
-    ASSERT_MATRIX_APPROX(P0_matrix.bottomRightCorner(1,1), fo->getMeasurementCovariance(), Constants::EPS_SMALL );
+    ASSERT_MATRIX_APPROX(P0_p, fp->getMeasurementCovariance(), Constants::EPS_SMALL );
+    ASSERT_MATRIX_APPROX(P0_o, fo->getMeasurementCovariance(), Constants::EPS_SMALL );
 
     //    P->print(4,1,1,1);
 }
@@ -197,20 +197,24 @@ TEST(Problem, SetOrigin_PO_3d)
 {
     ProblemPtr P = Problem::create("PO", 3);
     TimeStamp       t0(0);
-    Eigen::VectorXd vec7(7); vec7 << 1,2,3,4,5,6,7;
-    vec7.tail(4).normalize();
-    VectorComposite x0(vec7, "PO", {3,4});
+    SpecComposite prior;
+    prior.emplace('P',SpecState("P",Vector3d(1,2,3),"factor",Vector3d(sqrt(0.1),sqrt(0.1),sqrt(0.1))));
+    prior.emplace('O',SpecState("O",Vector4d(4,5,6,7).normalized(),"factor",Vector3d(sqrt(0.1),sqrt(0.1),sqrt(0.1))));
+    P->setPrior(prior, t0);
+    // Eigen::VectorXd vec7(7); vec7 << 1,2,3,4,5,6,7;
+    // vec7.tail(4).normalize();
+    // VectorComposite x0(vec7, "PO", {3,4});
     // Eigen::MatrixXd P0(6,6); P0.setIdentity(); P0 *= 0.1; // P0 is 0.1*Id
-    Eigen::VectorXd vec6(6); vec6 << sqrt(0.1), sqrt(0.1), sqrt(0.1), sqrt(0.1), sqrt(0.1), sqrt(0.1);
-    VectorComposite s0(vec6, "PO", {3,3});
+    // Eigen::VectorXd vec6(6); vec6 << sqrt(0.1), sqrt(0.1), sqrt(0.1), sqrt(0.1), sqrt(0.1), sqrt(0.1);
+    // VectorComposite s0(vec6, "PO", {3,3});
 
-    P->setPriorFactor(x0, s0, t0);
+    // P->setPriorFactor(x0, s0, t0);
 
     // check that no sensor has been added
     ASSERT_EQ(P->getHardware()->getSensorList().size(), (SizeStd) 0);
 
     // check that the state is correct
-    ASSERT_TRUE((x0.vector("PO") - P->getState().vector("PO")).isMuchSmallerThan(1, Constants::EPS_SMALL));
+    ASSERT_TRUE((prior.getState().vector("PO") - P->getState().vector("PO")).isMuchSmallerThan(1, Constants::EPS_SMALL));
 
     // check that we have one frame, one capture, one feature, one factor
     TrajectoryBasePtr T = P->getTrajectory();
@@ -240,14 +244,15 @@ TEST(Problem, SetOrigin_PO_3d)
         ASSERT_FALSE(fac->getFeatureOther());
     }
 
-    auto x0_vector = x0.vector("PO");
-    auto s0_vector = s0.vector("PO");
-    MatrixXd P0_matrix = (s0_vector.array() * s0_vector.array()).matrix().asDiagonal();
+    auto x0_vector = prior.getState().vector("PO");
+    auto P0_p = prior.at('P').getNoiseStd().cwiseAbs2().asDiagonal();
+    auto P0_o = prior.at('O').getNoiseStd().cwiseAbs2().asDiagonal();
+    
     // check that the Feature measurement and covariance are the ones provided
     ASSERT_MATRIX_APPROX(x0_vector.head<3>(), fp->getMeasurement(), Constants::EPS_SMALL );
     ASSERT_MATRIX_APPROX(x0_vector.tail<4>(), fo->getMeasurement(), Constants::EPS_SMALL );
-    ASSERT_MATRIX_APPROX(P0_matrix.topLeftCorner(3,3), fp->getMeasurementCovariance(), Constants::EPS_SMALL );
-    ASSERT_MATRIX_APPROX(P0_matrix.bottomRightCorner(3,3), fo->getMeasurementCovariance(), Constants::EPS_SMALL );
+    ASSERT_MATRIX_APPROX(P0_p, fp->getMeasurementCovariance(), Constants::EPS_SMALL );
+    ASSERT_MATRIX_APPROX(P0_o, fo->getMeasurementCovariance(), Constants::EPS_SMALL );
 
     //    P->print(4,1,1,1);
 }
@@ -386,9 +391,9 @@ TEST(Problem, perturb)
     param->ticks_per_wheel_revolution = 100;
     auto sensor = SensorBase::emplace<SensorDiffDrive>(problem->getHardware(),
                                                        param,
-                                                       PriorSensorMap({{'P',PriorSensor("P",Vector2d::Zero())},
-                                                               {'O',PriorSensor("O",Vector1d::Zero())},
-                                                               {'I',PriorSensor("StateParams3",Vector3d::Ones(),"initial_guess", VectorXd(0),true)}}));
+                                                       SpecSensorComposite({{'P',SpecStateSensor("P",Vector2d::Zero())},
+                                                               {'O',SpecStateSensor("O",Vector1d::Zero())},
+                                                               {'I',SpecStateSensor("StateParams3",Vector3d::Ones(),"initial_guess", VectorXd(0),true)}}));
 
     Vector3d pose; pose << 0,0,0;
 
@@ -472,9 +477,9 @@ TEST(Problem, check)
     param->ticks_per_wheel_revolution = 100;
     auto sensor = SensorBase::emplace<SensorDiffDrive>(problem->getHardware(),
                                                        param,
-                                                       PriorSensorMap({{'P',PriorSensor("P",Vector2d::Zero())},
-                                                               {'O',PriorSensor("O",Vector1d::Zero())},
-                                                               {'I',PriorSensor("StateParams3",Vector3d::Ones(),"initial_guess", VectorXd(0),true)}}));
+                                                       SpecSensorComposite({{'P',SpecStateSensor("P",Vector2d::Zero())},
+                                                               {'O',SpecStateSensor("O",Vector1d::Zero())},
+                                                               {'I',SpecStateSensor("StateParams3",Vector3d::Ones(),"initial_guess", VectorXd(0),true)}}));
     Vector3d pose; pose << 0,0,0;
 
     int i = 0;
diff --git a/test/gtest_processor_and_factor_pose_3d_with_extrinsics.cpp b/test/gtest_processor_and_factor_pose_3d_with_extrinsics.cpp
index fb321e4295e06594e899b5f93250097f86ee9802..08578a640eec7afda29a42b3aa84b76d28424a30 100644
--- a/test/gtest_processor_and_factor_pose_3d_with_extrinsics.cpp
+++ b/test/gtest_processor_and_factor_pose_3d_with_extrinsics.cpp
@@ -130,8 +130,8 @@ class FactorPose3dWithExtrinsicsBase_Test : public testing::Test
         params_sp->std_p = 1;
         params_sp->std_o = 1;
         
-        sensor_pose_ = problem_->installSensor("SensorPose", "pose", params_sp, PriorSensorMap{{'P',PriorSensor("P",b_p_bm_)},
-                                                                                       {'O',PriorSensor("O",b_q_m_.coeffs())}});
+        sensor_pose_ = problem_->installSensor("SensorPose", "pose", params_sp, SpecSensorComposite{{'P',SpecStateSensor("P",b_p_bm_)},
+                                                                                       {'O',SpecStateSensor("O",b_q_m_.coeffs())}});
         auto params_proc = std::make_shared<ParamsProcessorPose>();
         params_proc->time_tolerance = 0.5;
         auto proc_pose = problem_->installProcessor("ProcessorPose", "pose", sensor_pose_, params_proc);
diff --git a/test/gtest_processor_base.cpp b/test/gtest_processor_base.cpp
index 81c3ac989141fd8d65bb351baafeed15c9373be8..1c484638d4617173a7906a571cf865c2656f9d5c 100644
--- a/test/gtest_processor_base.cpp
+++ b/test/gtest_processor_base.cpp
@@ -123,11 +123,9 @@ TEST(ProcessorBase, KeyFrameCallback)
 
     // initialize
     TimeStamp   t(0.0);
-    // Vector3d    x(0,0,0);
-    VectorComposite x(Vector3d(0,0,0), "PO", {2,1});
-    // Matrix3d    P = Matrix3d::Identity() * 0.1;
-    VectorComposite P(Vector3d(sqrt(0.1),sqrt(0.1),sqrt(0.1)), "PO", {2,1});
-    problem->setPriorFactor(x, P, t);             // KF1
+    SpecComposite prior{{'P',SpecState("P",Vector2d(0,0),"factor",Vector2d(sqrt(0.1),sqrt(0.1)))},
+                        {'O',SpecState("O",Vector1d(0),"factor",Vector1d(sqrt(0.1)))}};
+    problem->setPrior(prior, t);
 
     CaptureOdom2dPtr capt_odo = make_shared<CaptureOdom2d>(t, sens_odo, Vector2d(0.5,0));
 
diff --git a/test/gtest_processor_diff_drive.cpp b/test/gtest_processor_diff_drive.cpp
index 79a3b59cdb88f242d4c000bf5f9929dbcb462d81..c67f9294fb9bff2ac5d1e82f827642b459f54a6a 100644
--- a/test/gtest_processor_diff_drive.cpp
+++ b/test/gtest_processor_diff_drive.cpp
@@ -144,9 +144,9 @@ class ProcessorDiffDriveTest : public testing::Test
             params_sen = std::make_shared<ParamsSensorDiffDrive>();
             params_sen->ticks_per_wheel_revolution = 100; // DO NOT MODIFY THESE VALUES !!!
 
-            PriorSensorMap priors{{'P',PriorSensor("P", Vector2d::Zero())},           //default "fix", not dynamic
-                          {'O',PriorSensor("O", Vector1d::Zero())},           //default "fix", not dynamic
-                          {'I',PriorSensor("StateBlock", Vector3d::Ones(), "initial_guess")}}; // not dynamic DO NOT MODIFY THESE VALUES !!!
+            SpecSensorComposite priors{{'P',SpecStateSensor("P", Vector2d::Zero())},           //default "fix", not dynamic
+                          {'O',SpecStateSensor("O", Vector1d::Zero())},           //default "fix", not dynamic
+                          {'I',SpecStateSensor("StateBlock", Vector3d::Ones(), "initial_guess")}}; // not dynamic DO NOT MODIFY THESE VALUES !!!
             
             sensor = std::static_pointer_cast<SensorDiffDrive>(problem->installSensor("SensorDiffDrive", 
                                                                                       "sensor",
diff --git a/test/gtest_processor_motion.cpp b/test/gtest_processor_motion.cpp
index 8b157d5ee90eee6ec002855695e960b5edec9bf7..443e4f1edd4e02ea85e849476c34cc7e8ada6423 100644
--- a/test/gtest_processor_motion.cpp
+++ b/test/gtest_processor_motion.cpp
@@ -177,11 +177,10 @@ TEST_F(ProcessorMotion_test, IntegrateStraightFactorPrior)
 {
     // Prior
     TimeStamp t(0.0);
-    // Vector3d x0; x0 << 0, 0, 0;
-    VectorComposite x0(Vector3d(0,0,0), "PO", {2,1});
-    // Matrix3d P0; P0.setIdentity();
-    VectorComposite s0(Vector3d(1,1,1), "PO", {2,1});
-    auto KF_0 = problem->setPriorFactor(x0, s0, t);
+    SpecComposite prior;
+    prior.emplace('P',SpecState("P",Vector2d(0,0),"factor",Vector2d(1,1)));
+    prior.emplace('O',SpecState("O",Vector1d(0),"factor",Vector1d(1)));
+    auto KF_0 = problem->setPrior(prior, t);
     processor->setOrigin(KF_0);
 
     data << 1, 0; // advance straight
@@ -204,11 +203,9 @@ TEST_F(ProcessorMotion_test, IntegrateStraightFixPrior)
 {
     // Prior
     TimeStamp t(0.0);
-    // Vector3d x0; x0 << 0, 0, 0;
-    // Matrix3d P0; P0.setIdentity();
-    VectorComposite x0(Vector3d(0,0,0), "PO", {2,1});
-    VectorComposite s0(Vector3d(1,1,1), "PO", {2,1});
-    auto KF_0 = problem->setPriorFix(x0, t);
+    SpecComposite prior{{'P',SpecState("P",Vector2d(0,0),"fix")},
+                        {'O',SpecState("O",Vector1d(0),"fix")}};
+    auto KF_0 = problem->setPrior(prior, t);
     processor->setOrigin(KF_0);
 
     data << 1, 0; // advance straight
@@ -254,11 +251,9 @@ TEST_F(ProcessorMotion_test, IntegrateCircleFactorPrior)
 {
     // Prior
     TimeStamp t(0.0);
-    // Vector3d x0; x0 << 0, 0, 0;
-    VectorComposite x0(Vector3d(0,0,0), "PO", {2,1});
-    // Matrix3d P0; P0.setIdentity();
-    VectorComposite s0(Vector3d(1,1,1), "PO", {2,1});
-    auto KF_0 = problem->setPriorFactor(x0, s0, t);
+    SpecComposite prior{{'P',SpecState("P",Vector2d(0,0),"factor",Vector2d(1,1))},
+                        {'O',SpecState("O",Vector1d(0),"factor",Vector1d(1))}};
+    auto KF_0 = problem->setPrior(prior, t);
     processor->setOrigin(KF_0);
 
     data << 1, 2*M_PI/10; // advance in circle
@@ -281,11 +276,10 @@ TEST_F(ProcessorMotion_test, IntegrateCircleFixPrior)
 {
     // Prior
     TimeStamp t(0.0);
-    // Vector3d x0; x0 << 0, 0, 0;
-    // Matrix3d P0; P0.setIdentity();
-    VectorComposite x0(Vector3d(0,0,0), "PO", {2,1});
-    VectorComposite s0(Vector3d(1,1,1), "PO", {2,1});
-    auto KF_0 = problem->setPriorFix(x0, t);
+    SpecComposite prior;
+    prior.emplace('P',SpecState("P",Vector2d(0,0),"fix"));
+    prior.emplace('O',SpecState("O",Vector1d(0),"fix"));
+    auto KF_0 = problem->setPrior(prior, t);
     processor->setOrigin(KF_0);
 
     data << 1, 2*M_PI/10; // advance in circle
@@ -424,11 +418,9 @@ TEST_F(ProcessorMotion_test, splitBufferFactorPrior)
 {
     // Prior
     TimeStamp t(0.0);
-    // Vector3d x0; x0 << 0, 0, 0;
-    VectorComposite x0(Vector3d(0,0,0), "PO", {2,1});
-    // Matrix3d P0; P0.setIdentity();
-    VectorComposite s0(Vector3d(1,1,1), "PO", {2,1});
-    auto KF_0 = problem->setPriorFactor(x0, s0, t);
+    SpecComposite prior{{'P',SpecState("P",Vector2d(0,0),"factor",Vector2d(1,1))},
+                        {'O',SpecState("O",Vector1d(0),"factor",Vector1d(1))}};
+    auto KF_0 = problem->setPrior(prior, t);
     processor->setOrigin(KF_0);
 
     data << 1, 2*M_PI/10; // advance in circle
@@ -468,11 +460,9 @@ TEST_F(ProcessorMotion_test, splitBufferFixPrior)
 {
     // Prior
     TimeStamp t(0.0);
-    // Vector3d x0; x0 << 0, 0, 0;
-    // Matrix3d P0; P0.setIdentity();
-    VectorComposite x0(Vector3d(0,0,0), "PO", {2,1});
-    VectorComposite s0(Vector3d(1,1,1), "PO", {2,1});
-    auto KF_0 = problem->setPriorFix(x0, t);
+    SpecComposite prior{{'P',SpecState("P",Vector2d(0,0),"fix")},
+                        {'O',SpecState("O",Vector1d(0),"fix")}};
+    auto KF_0 = problem->setPrior(prior, t);
     processor->setOrigin(KF_0);
 
     data << 1, 2*M_PI/10; // advance in circle
diff --git a/test/gtest_sensor_base.cpp b/test/gtest_sensor_base.cpp
index 0a12ed5723484c4a2ac7b326669bb304504ce49b..634a8b795c476185f9031a0fcf1e1bd72bb4cf33 100644
--- a/test/gtest_sensor_base.cpp
+++ b/test/gtest_sensor_base.cpp
@@ -104,8 +104,8 @@ TEST(SensorBase, makeshared_priors_POfix2D)
   params->noise_o_std = noise_o_std;
   
   auto S = std::make_shared<SensorDummy2d>(params, 
-                                           PriorSensorMap({{'P',PriorSensor("P", p_state_2D)}, //default "fix", not dynamic
-                                                   {'O',PriorSensor("O", o_state_2D)}}));
+                                           SpecSensorComposite({{'P',SpecStateSensor("P", p_state_2D)}, //default "fix", not dynamic
+                                                   {'O',SpecStateSensor("O", o_state_2D)}}));
 
   // noise
   ASSERT_MATRIX_APPROX(S->computeNoiseCov(vector0), noise_cov_dummy, Constants::EPS);
@@ -124,8 +124,8 @@ TEST(SensorBase, makeshared_priors_POfix3D)
   params->noise_o_std = noise_o_std;
   
   auto S = std::make_shared<SensorDummy3d>(params, 
-                                           PriorSensorMap({{'P',PriorSensor("P", p_state_3D)}, //default "fix", not dynamic
-                                                   {'O',PriorSensor("O", o_state_3D)}}));
+                                           SpecSensorComposite({{'P',SpecStateSensor("P", p_state_3D)}, //default "fix", not dynamic
+                                                   {'O',SpecStateSensor("O", o_state_3D)}}));
 
   // noise
   ASSERT_MATRIX_APPROX(S->computeNoiseCov(vector0), noise_cov_dummy, Constants::EPS);
@@ -147,8 +147,8 @@ TEST(SensorBase, makeshared_priors_POinitial_guess2D)
   params->noise_o_std = noise_o_std;
   
   auto S = std::make_shared<SensorDummy2d>(params, 
-                                           PriorSensorMap({{'P',PriorSensor("P", p_state_2D, "initial_guess")},
-                                                   {'O',PriorSensor("O", o_state_2D, "initial_guess")}}));
+                                           SpecSensorComposite({{'P',SpecStateSensor("P", p_state_2D, "initial_guess")},
+                                                   {'O',SpecStateSensor("O", o_state_2D, "initial_guess")}}));
 
   // noise
   ASSERT_MATRIX_APPROX(S->computeNoiseCov(vector0), noise_cov_dummy, Constants::EPS);
@@ -170,8 +170,8 @@ TEST(SensorBase, makeshared_priors_POinitial_guess3D)
   params->noise_o_std = noise_o_std;
   
   auto S = std::make_shared<SensorDummy3d>(params, 
-                                           PriorSensorMap({{'P',PriorSensor("P", p_state_3D, "initial_guess")},
-                                                   {'O',PriorSensor("O", o_state_3D, "initial_guess")}}));
+                                           SpecSensorComposite({{'P',SpecStateSensor("P", p_state_3D, "initial_guess")},
+                                                   {'O',SpecStateSensor("O", o_state_3D, "initial_guess")}}));
 
   // noise
   ASSERT_MATRIX_APPROX(S->computeNoiseCov(vector0), noise_cov_dummy, Constants::EPS);
@@ -193,8 +193,8 @@ TEST(SensorBase, makeshared_priors_POfactor2D)
   params->noise_o_std = noise_o_std;
   
   auto S = std::make_shared<SensorDummy2d>(params, 
-                                           PriorSensorMap({{'P',PriorSensor("P", p_state_2D, "factor", p_std_2D)},
-                                                   {'O',PriorSensor("O", o_state_2D, "factor", o_std_2D)}}));
+                                           SpecSensorComposite({{'P',SpecStateSensor("P", p_state_2D, "factor", p_std_2D)},
+                                                   {'O',SpecStateSensor("O", o_state_2D, "factor", o_std_2D)}}));
 
   // noise
   ASSERT_MATRIX_APPROX(S->computeNoiseCov(vector0), noise_cov_dummy, Constants::EPS);
@@ -216,8 +216,8 @@ TEST(SensorBase, makeshared_priors_POfactor3D)
   params->noise_o_std = noise_o_std;
   
   auto S = std::make_shared<SensorDummy3d>(params, 
-                                           PriorSensorMap({{'P',PriorSensor("P", p_state_3D, "factor", p_std_3D)},
-                                                   {'O',PriorSensor("O", o_state_3D, "factor", o_std_3D)}}));
+                                           SpecSensorComposite({{'P',SpecStateSensor("P", p_state_3D, "factor", p_std_3D)},
+                                                   {'O',SpecStateSensor("O", o_state_3D, "factor", o_std_3D)}}));
 
   // noise
   ASSERT_MATRIX_APPROX(S->computeNoiseCov(vector0), noise_cov_dummy, Constants::EPS);
@@ -239,8 +239,8 @@ TEST(SensorBase, makeshared_priors_POinitial_guess_dynamic2D)
   params->noise_o_std = noise_o_std;
   
   auto S = std::make_shared<SensorDummy2d>(params, 
-                                           PriorSensorMap({{'P',PriorSensor("P", p_state_2D, "initial_guess", vector0, true)},
-                                                   {'O',PriorSensor("O", o_state_2D, "initial_guess", vector0, true)}}));
+                                           SpecSensorComposite({{'P',SpecStateSensor("P", p_state_2D, "initial_guess", vector0, true)},
+                                                   {'O',SpecStateSensor("O", o_state_2D, "initial_guess", vector0, true)}}));
 
   // noise
   ASSERT_MATRIX_APPROX(S->computeNoiseCov(vector0), noise_cov_dummy, Constants::EPS);
@@ -262,8 +262,8 @@ TEST(SensorBase, makeshared_priors_POinitial_guess_dynamic3D)
   params->noise_o_std = noise_o_std;
   
   auto S = std::make_shared<SensorDummy3d>(params, 
-                                           PriorSensorMap({{'P',PriorSensor("P", p_state_3D, "initial_guess", vector0, true)},
-                                                   {'O',PriorSensor("O", o_state_3D, "initial_guess", vector0, true)}}));
+                                           SpecSensorComposite({{'P',SpecStateSensor("P", p_state_3D, "initial_guess", vector0, true)},
+                                                   {'O',SpecStateSensor("O", o_state_3D, "initial_guess", vector0, true)}}));
 
   // noise
   ASSERT_MATRIX_APPROX(S->computeNoiseCov(vector0), noise_cov_dummy, Constants::EPS);
@@ -285,8 +285,8 @@ TEST(SensorBase, makeshared_priors_POinitial_guess_dynamic2D_drift)
   params->noise_o_std = noise_o_std;
   
   auto S = std::make_shared<SensorDummy2d>(params, 
-                                           PriorSensorMap({{'P',PriorSensor("P", p_state_2D, "initial_guess", vector0, true, p_std_2D)},
-                                                   {'O',PriorSensor("O", o_state_2D, "initial_guess", vector0, true, o_std_2D)}}));
+                                           SpecSensorComposite({{'P',SpecStateSensor("P", p_state_2D, "initial_guess", vector0, true, p_std_2D)},
+                                                   {'O',SpecStateSensor("O", o_state_2D, "initial_guess", vector0, true, o_std_2D)}}));
 
   // noise
   ASSERT_MATRIX_APPROX(S->computeNoiseCov(vector0), noise_cov_dummy, Constants::EPS);
@@ -308,8 +308,8 @@ TEST(SensorBase, makeshared_priors_POinitial_guess_dynamic3D_drift)
   params->noise_o_std = noise_o_std;
   
   auto S = std::make_shared<SensorDummy3d>(params, 
-                                           PriorSensorMap({{'P',PriorSensor("P", p_state_3D, "initial_guess", vector0, true, p_std_3D)},
-                                                   {'O',PriorSensor("O", o_state_3D, "initial_guess", vector0, true, o_std_3D)}}));
+                                           SpecSensorComposite({{'P',SpecStateSensor("P", p_state_3D, "initial_guess", vector0, true, p_std_3D)},
+                                                   {'O',SpecStateSensor("O", o_state_3D, "initial_guess", vector0, true, o_std_3D)}}));
 
   // noise
   ASSERT_MATRIX_APPROX(S->computeNoiseCov(vector0), noise_cov_dummy, Constants::EPS);
@@ -333,10 +333,10 @@ TEST(SensorBase, makeshared_priors_POIA_mixed)
   VectorXd i_state_3D = VectorXd::Random(5);
 
   auto S = std::make_shared<SensorDummy3d>(params, 
-                                           PriorSensorMap({{'P',PriorSensor("P", p_state_3D, "fix", vector0, true)},
-                                                   {'O',PriorSensor("O", o_state_3D, "factor", o_std_3D, true, o_std_3D)},
-                                                   {'I',PriorSensor("StateParams5", i_state_3D, "initial_guess")},
-                                                   {'A',PriorSensor("StateQuaternion", o_state_3D, "factor", o_std_3D)}}));
+                                           SpecSensorComposite({{'P',SpecStateSensor("P", p_state_3D, "fix", vector0, true)},
+                                                   {'O',SpecStateSensor("O", o_state_3D, "factor", o_std_3D, true, o_std_3D)},
+                                                   {'I',SpecStateSensor("StateParams5", i_state_3D, "initial_guess")},
+                                                   {'A',SpecStateSensor("StateQuaternion", o_state_3D, "factor", o_std_3D)}}));
      
   // noise
   ASSERT_MATRIX_APPROX(S->computeNoiseCov(vector0), noise_cov_dummy, Constants::EPS);
diff --git a/test/gtest_sensor_diff_drive.cpp b/test/gtest_sensor_diff_drive.cpp
index 7271e389f018ab8b9a4dd7d490a05817eb3742b3..1ab3e464fd1f2692a15afb04f802118085943141 100644
--- a/test/gtest_sensor_diff_drive.cpp
+++ b/test/gtest_sensor_diff_drive.cpp
@@ -45,9 +45,9 @@ TEST(SensorDiffDrive, constructor_priors)
 {
     auto param = std::make_shared<ParamsSensorDiffDrive>();
 
-    PriorSensorMap priors{{'P',PriorSensor("P", p_state)},            //default "fix", not dynamic
-                  {'O',PriorSensor("O", o_state)},            //default "fix", not dynamic
-                  {'I',PriorSensor("StateBlock", i_state)}};  //default "fix", not dynamic
+    SpecSensorComposite priors{{'P',SpecStateSensor("P", p_state)},            //default "fix", not dynamic
+                  {'O',SpecStateSensor("O", o_state)},            //default "fix", not dynamic
+                  {'I',SpecStateSensor("StateBlock", i_state)}};  //default "fix", not dynamic
 
     auto sen = std::make_shared<SensorDiffDrive>("sensor_1", 2, param, priors);
 
@@ -114,9 +114,9 @@ TEST(SensorDiffDrive, factory_priors)
 {
     auto param = std::make_shared<ParamsSensorDiffDrive>();
 
-    PriorSensorMap priors{{'P',PriorSensor("P", p_state)},            //default "fix", not dynamic
-                  {'O',PriorSensor("O", o_state)},            //default "fix", not dynamic
-                  {'I',PriorSensor("StateBlock", i_state)}};  //default "fix", not dynamic
+    SpecSensorComposite priors{{'P',SpecStateSensor("P", p_state)},            //default "fix", not dynamic
+                  {'O',SpecStateSensor("O", o_state)},            //default "fix", not dynamic
+                  {'I',SpecStateSensor("StateBlock", i_state)}};  //default "fix", not dynamic
 
     auto sb = FactorySensorPriors::create("SensorDiffDrive","sensor_1", 2, param, priors);
 
@@ -137,9 +137,9 @@ TEST(SensorDiffDrive, getParams)
     param->ticks_per_wheel_revolution = 400;
     param->ticks_std_factor = 2;
 
-    PriorSensorMap priors{{'P',PriorSensor("P", p_state)},            //default "fix", not dynamic
-                  {'O',PriorSensor("O", o_state)},            //default "fix", not dynamic
-                  {'I',PriorSensor("StateBlock", i_state)}};  //default "fix", not dynamic
+    SpecSensorComposite priors{{'P',SpecStateSensor("P", p_state)},            //default "fix", not dynamic
+                  {'O',SpecStateSensor("O", o_state)},            //default "fix", not dynamic
+                  {'I',SpecStateSensor("StateBlock", i_state)}};  //default "fix", not dynamic
 
     auto sen = std::make_shared<SensorDiffDrive>("sensor_1", 2, param, priors);
 
@@ -156,9 +156,9 @@ TEST(SensorDiffDrive, computeNoiseCov)
     param->ticks_per_wheel_revolution = 400;
     param->ticks_std_factor = 2;
 
-    PriorSensorMap priors{{'P',PriorSensor("P", p_state)},            //default "fix", not dynamic
-                  {'O',PriorSensor("O", o_state)},            //default "fix", not dynamic
-                  {'I',PriorSensor("StateBlock", i_state)}};  //default "fix", not dynamic
+    SpecSensorComposite priors{{'P',SpecStateSensor("P", p_state)},            //default "fix", not dynamic
+                  {'O',SpecStateSensor("O", o_state)},            //default "fix", not dynamic
+                  {'I',SpecStateSensor("StateBlock", i_state)}};  //default "fix", not dynamic
 
     auto sen = std::make_shared<SensorDiffDrive>("sensor_1", 2, param, priors);
 
diff --git a/test/gtest_sensor_odom.cpp b/test/gtest_sensor_odom.cpp
index de64ac89351097bb5444526f2586773962f56161..54d9a21b2e354a9c94b9acd3d84e2eed692180b4 100644
--- a/test/gtest_sensor_odom.cpp
+++ b/test/gtest_sensor_odom.cpp
@@ -110,8 +110,8 @@ TEST(SensorOdom, makeshared_priors_fix_2D)
   params->min_rot_var    = min_rot_var;
   
   auto S = std::make_shared<SensorOdom>("sensor1", 2, params, 
-                                         PriorSensorMap({{'P',PriorSensor("P", p_state_2D)}, //default "fix", not dynamic
-                                                 {'O',PriorSensor("O", o_state_2D)}}));
+                                         SpecSensorComposite({{'P',SpecStateSensor("P", p_state_2D)}, //default "fix", not dynamic
+                                                 {'O',SpecStateSensor("O", o_state_2D)}}));
 
   // checks
   checkSensor(S, 'P', p_state_2D, true, vector0, false, vector0);
@@ -129,8 +129,8 @@ TEST(SensorOdom, makeshared_priors_fix_3D)
   params->min_rot_var    = min_rot_var;
   
   auto S = std::make_shared<SensorOdom>("sensor1", 3, params, 
-                                         PriorSensorMap({{'P',PriorSensor("P", p_state_3D)}, //default "fix", not dynamic
-                                                 {'O',PriorSensor("O", o_state_3D)}}));
+                                         SpecSensorComposite({{'P',SpecStateSensor("P", p_state_3D)}, //default "fix", not dynamic
+                                                 {'O',SpecStateSensor("O", o_state_3D)}}));
 
   // factors
   ASSERT_EQ(S->getPriorFeatures().size(), 0);
@@ -151,8 +151,8 @@ TEST(SensorOdom, makeshared_priors_initial_guess_2D)
   params->min_rot_var    = min_rot_var;
   
   auto S = std::make_shared<SensorOdom>("sensor1", 2, params, 
-                                         PriorSensorMap({{'P',PriorSensor("P", p_state_2D, "initial_guess")},
-                                                 {'O',PriorSensor("O", o_state_2D, "initial_guess")}}));
+                                         SpecSensorComposite({{'P',SpecStateSensor("P", p_state_2D, "initial_guess")},
+                                                 {'O',SpecStateSensor("O", o_state_2D, "initial_guess")}}));
 
   // factors
   ASSERT_EQ(S->getPriorFeatures().size(), 0);
@@ -173,8 +173,8 @@ TEST(SensorOdom, makeshared_priors_initial_guess_3D)
   params->min_rot_var    = min_rot_var;
   
   auto S = std::make_shared<SensorOdom>("sensor1", 3, params, 
-                                         PriorSensorMap({{'P',PriorSensor("P", p_state_3D, "initial_guess")},
-                                                 {'O',PriorSensor("O", o_state_3D, "initial_guess")}}));
+                                         SpecSensorComposite({{'P',SpecStateSensor("P", p_state_3D, "initial_guess")},
+                                                 {'O',SpecStateSensor("O", o_state_3D, "initial_guess")}}));
 
   // factors
   ASSERT_EQ(S->getPriorFeatures().size(), 0);
@@ -195,8 +195,8 @@ TEST(SensorOdom, makeshared_priors_factor_2D)
   params->min_rot_var    = min_rot_var;
   
   auto S = std::make_shared<SensorOdom>("sensor1", 2, params, 
-                                         PriorSensorMap({{'P',PriorSensor("P", p_state_2D, "factor", p_std_2D)},
-                                                 {'O',PriorSensor("O", o_state_2D, "factor", o_std_2D)}}));
+                                         SpecSensorComposite({{'P',SpecStateSensor("P", p_state_2D, "factor", p_std_2D)},
+                                                 {'O',SpecStateSensor("O", o_state_2D, "factor", o_std_2D)}}));
 
   // factors
   ASSERT_EQ(S->getPriorFeatures().size(), 2);
@@ -217,8 +217,8 @@ TEST(SensorOdom, makeshared_priors_factor_3D)
   params->min_rot_var    = min_rot_var;
   
   auto S = std::make_shared<SensorOdom>("sensor1", 3, params, 
-                                         PriorSensorMap({{'P',PriorSensor("P", p_state_3D, "factor", p_std_3D)},
-                                                 {'O',PriorSensor("O", o_state_3D, "factor", o_std_3D)}}));
+                                         SpecSensorComposite({{'P',SpecStateSensor("P", p_state_3D, "factor", p_std_3D)},
+                                                 {'O',SpecStateSensor("O", o_state_3D, "factor", o_std_3D)}}));
 
   // factors
   ASSERT_EQ(S->getPriorFeatures().size(), 2);
@@ -239,8 +239,8 @@ TEST(SensorOdom, makeshared_priors_initial_guess_dynamic_2D)
   params->min_rot_var    = min_rot_var;
   
   auto S = std::make_shared<SensorOdom>("sensor1", 2, params, 
-                                         PriorSensorMap({{'P',PriorSensor("P", p_state_2D, "initial_guess", vector0, true)},
-                                                 {'O',PriorSensor("O", o_state_2D, "initial_guess", vector0, true)}}));
+                                         SpecSensorComposite({{'P',SpecStateSensor("P", p_state_2D, "initial_guess", vector0, true)},
+                                                 {'O',SpecStateSensor("O", o_state_2D, "initial_guess", vector0, true)}}));
 
   // factors
   ASSERT_EQ(S->getPriorFeatures().size(), 0);
@@ -261,8 +261,8 @@ TEST(SensorOdom, makeshared_priors_initial_guess_dynamic_3D)
   params->min_rot_var    = min_rot_var;
   
   auto S = std::make_shared<SensorOdom>("sensor1", 3, params, 
-                                         PriorSensorMap({{'P',PriorSensor("P", p_state_3D, "initial_guess", vector0, true)},
-                                                 {'O',PriorSensor("O", o_state_3D, "initial_guess", vector0, true)}}));
+                                         SpecSensorComposite({{'P',SpecStateSensor("P", p_state_3D, "initial_guess", vector0, true)},
+                                                 {'O',SpecStateSensor("O", o_state_3D, "initial_guess", vector0, true)}}));
 
   // factors
   ASSERT_EQ(S->getPriorFeatures().size(), 0);
@@ -283,8 +283,8 @@ TEST(SensorOdom, makeshared_priors_initial_guess_dynamic_drift_2D)
   params->min_rot_var    = min_rot_var;
   
   auto S = std::make_shared<SensorOdom>("sensor1", 2, params, 
-                                         PriorSensorMap({{'P',PriorSensor("P", p_state_2D, "initial_guess", vector0, true, p_std_2D)},
-                                                 {'O',PriorSensor("O", o_state_2D, "initial_guess", vector0, true, o_std_2D)}}));
+                                         SpecSensorComposite({{'P',SpecStateSensor("P", p_state_2D, "initial_guess", vector0, true, p_std_2D)},
+                                                 {'O',SpecStateSensor("O", o_state_2D, "initial_guess", vector0, true, o_std_2D)}}));
 
   // factors
   ASSERT_EQ(S->getPriorFeatures().size(), 0);
@@ -305,8 +305,8 @@ TEST(SensorOdom, makeshared_priors_initial_guess_dynamic_drift_3D)
   params->min_rot_var    = min_rot_var;
   
   auto S = std::make_shared<SensorOdom>("sensor1", 3, params, 
-                                         PriorSensorMap({{'P',PriorSensor("P", p_state_3D, "initial_guess", vector0, true, p_std_3D)},
-                                                 {'O',PriorSensor("O", o_state_3D, "initial_guess", vector0, true, o_std_3D)}}));
+                                         SpecSensorComposite({{'P',SpecStateSensor("P", p_state_3D, "initial_guess", vector0, true, p_std_3D)},
+                                                 {'O',SpecStateSensor("O", o_state_3D, "initial_guess", vector0, true, o_std_3D)}}));
 
   // factors
   ASSERT_EQ(S->getPriorFeatures().size(), 0);
@@ -463,8 +463,8 @@ TEST(SensorOdom, compute_noise_cov_3D)
   params->min_rot_var    = min_rot_var;
   
   auto S = FactorySensorPriors::create("SensorOdom","sensor1", 3, params, 
-                                       PriorSensorMap({{'P',PriorSensor("P", p_state_3D)}, //default "fix", not dynamic
-                                               {'O',PriorSensor("O", o_state_3D)}}));
+                                       SpecSensorComposite({{'P',SpecStateSensor("P", p_state_3D)}, //default "fix", not dynamic
+                                               {'O',SpecStateSensor("O", o_state_3D)}}));
 
   Vector6d disp_elements, rot_elements;
   disp_elements << 1, 1, 1, 0, 0, 0;
diff --git a/test/gtest_sensor_pose.cpp b/test/gtest_sensor_pose.cpp
index 2bf0d87ae928cf688ced83c968702cd2fbd2b914..4f905a0169af8a6aafaea99064407f86074d60d4 100644
--- a/test/gtest_sensor_pose.cpp
+++ b/test/gtest_sensor_pose.cpp
@@ -52,8 +52,8 @@ TEST(Pose, constructor_priors_2D)
     param->std_p = std_p;
     param->std_o = std_o;
 
-    PriorSensorMap priors{{'P',PriorSensor("P", p_state_2D)}, //default "fix", not dynamic
-                  {'O',PriorSensor("O", o_state_2D)}}; //default "fix", not dynamic
+    SpecSensorComposite priors{{'P',SpecStateSensor("P", p_state_2D)}, //default "fix", not dynamic
+                  {'O',SpecStateSensor("O", o_state_2D)}}; //default "fix", not dynamic
 
     auto sen = std::make_shared<SensorPose>("sensor_1", 2, param, priors);
 
@@ -77,8 +77,8 @@ TEST(Pose, constructor_priors_3D)
     param->std_p = std_p;
     param->std_o = std_o;
 
-    PriorSensorMap priors{{'P',PriorSensor("P", p_state_3D)}, //default "fix", not dynamic
-                  {'O',PriorSensor("O", o_state_3D)}}; //default "fix", not dynamic
+    SpecComposite priors{{'P',SpecStateSensor("P", p_state_3D)}, //default "fix", not dynamic
+                  {'O',SpecStateSensor("O", o_state_3D)}}; //default "fix", not dynamic
 
     auto sen = std::make_shared<SensorPose>("sensor_1", 3, param, priors);
 
@@ -232,8 +232,8 @@ TEST(Pose, factory_priors_2D)
     param->std_p = std_p;
     param->std_o = std_o;
 
-    PriorSensorMap priors{{'P',PriorSensor("P", p_state_2D)}, //default "fix", not dynamic
-                  {'O',PriorSensor("O", o_state_2D)}}; //default "fix", not dynamic
+    SpecComposite priors{{'P',SpecStateSensor("P", p_state_2D)}, //default "fix", not dynamic
+                  {'O',SpecStateSensor("O", o_state_2D)}}; //default "fix", not dynamic
 
     auto sb = FactorySensorPriors::create("SensorPose","sensor_1", 2, param, priors);
 
@@ -259,8 +259,8 @@ TEST(Pose, factory_priors_3D)
     param->std_p = std_p;
     param->std_o = std_o;
 
-    PriorSensorMap priors{{'P',PriorSensor("P", p_state_3D)}, //default "fix", not dynamic
-                  {'O',PriorSensor("O", o_state_3D)}}; //default "fix", not dynamic
+    SpecComposite priors{{'P',SpecStateSensor("P", p_state_3D)}, //default "fix", not dynamic
+                  {'O',SpecStateSensor("O", o_state_3D)}}; //default "fix", not dynamic
 
     auto sb = FactorySensorPriors::create("SensorPose","sensor_1", 3, param, priors);
 
diff --git a/test/yaml/params_problem_autosetup.yaml b/test/yaml/params_problem_autosetup.yaml
index 4f8f593f23cbc301d8a49e96bcacb44f2221530e..7c445e2c32fe2de43f48b4f6e36636fa38f26329 100644
--- a/test/yaml/params_problem_autosetup.yaml
+++ b/test/yaml/params_problem_autosetup.yaml
@@ -1,15 +1,15 @@
 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
+  first_frame:
+    P:
+      state: [0,0,0]
+      mode: "factor"
+      noise_std: [0.31, 0.31, 0.31]
+    O: 
+      state: [0,0,0,1]
+      mode: "factor"
+      noise_std: [0.31, 0.31, 0.31]
   tree_manager: 
     type: "None"
 map:
diff --git a/test/yaml/params_problem_autosetup_no_map.yaml b/test/yaml/params_problem_autosetup_no_map.yaml
index e7aa7c81b9c030259fead40bb72943b369e9964d..c0713d0f39d04da8920000e38dfa434950b3e1d9 100644
--- a/test/yaml/params_problem_autosetup_no_map.yaml
+++ b/test/yaml/params_problem_autosetup_no_map.yaml
@@ -1,15 +1,15 @@
 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
+  first_frame:
+    P:
+      state: [0,0,0]
+      mode: "factor"
+      noise_std: [0.31, 0.31, 0.31]
+    O: 
+      state: [0,0,0,1]
+      mode: "factor"
+      noise_std: [0.31, 0.31, 0.31]
   tree_manager: 
     type: "None"
 sensors:  
diff --git a/test/yaml/params_problem_odom_3d.yaml b/test/yaml/params_problem_odom_3d.yaml
index b5e8c455bc8eafe7bc51020878240aadb42aaec5..e038298e42bb24516caff219fd8b3a80ea976ac3 100644
--- a/test/yaml/params_problem_odom_3d.yaml
+++ b/test/yaml/params_problem_odom_3d.yaml
@@ -1,7 +1,7 @@
 problem:
   frame_structure: "PO"
   dimension: 3
-  prior:
+  first_frame:
     mode: "factor"
     $state:
       P: [0,0,0]
diff --git a/test/yaml/params_tree_manager1.yaml b/test/yaml/params_tree_manager1.yaml
index af9245339e4a0dd9ad5538a84598b6bbfcd0f240..f7a110bf8f5ec83efeb186fd4b934c5a5817047b 100644
--- a/test/yaml/params_tree_manager1.yaml
+++ b/test/yaml/params_tree_manager1.yaml
@@ -1,19 +1,20 @@
 problem:
   frame_structure: "POV"
   dimension: 3
-  prior:
-    mode: "factor"
-    # state: [0,0,0,0,0,0,1,0,0,0]
-    # cov: [[9,9],.1,0,0,0,0,0,0,0,0, 0,.1,0,0,0,0,0,0,0, 0,0,.1,0,0,0,0,0,0, 0,0,0,.1,0,0,0,0,0, 0,0,0,0,.1,0,0,0,0, 0,0,0,0,0,.1,0,0,0, 0,0,0,0,0,0,.1,0,0, 0,0,0,0,0,0,0,.1,0, 0,0,0,0,0,0,0,0,.1]
-    $state:
-      P: [0,0,0]
-      O: [0,0,0,1]
-      V: [0,0,0]
-    $sigma:
-      P: [0.31, 0.31, 0.31]
-      O: [0.31, 0.31, 0.31]
-      V: [0.31, 0.31, 0.31]
-    time_tolerance: 0.1
+  first_frame:
+    P:
+      state: [0,0,0]
+      mode: "factor"
+      noise_std: [0.31, 0.31, 0.31]
+    O: 
+      state: [0,0,0,1]
+      mode: "factor"
+      noise_std: [0.31, 0.31, 0.31]
+    V:
+      state: [0,0,0]
+      mode: "factor"
+      noise_std: [0.31, 0.31, 0.31]
+      type: StateVector3d
   tree_manager:
     follow: "tree_manager_dummy.yaml"
 sensors: 
diff --git a/test/yaml/params_tree_manager2.yaml b/test/yaml/params_tree_manager2.yaml
index b8acc1b021309cfae76c86b4f96b8b059ee75cf8..edb6b17b80eda799719190d7d1b2efd6cf4d82af 100644
--- a/test/yaml/params_tree_manager2.yaml
+++ b/test/yaml/params_tree_manager2.yaml
@@ -1,19 +1,20 @@
 problem:
   frame_structure: "POV"
   dimension: 3
-  prior:
-    mode: "factor"
-    # state: [0,0,0,0,0,0,1,0,0,0]
-    # cov: [[9,9],.1,0,0,0,0,0,0,0,0, 0,.1,0,0,0,0,0,0,0, 0,0,.1,0,0,0,0,0,0, 0,0,0,.1,0,0,0,0,0, 0,0,0,0,.1,0,0,0,0, 0,0,0,0,0,.1,0,0,0, 0,0,0,0,0,0,.1,0,0, 0,0,0,0,0,0,0,.1,0, 0,0,0,0,0,0,0,0,.1]
-    $state:
-      P: [0,0,0]
-      O: [0,0,0,1]
-      V: [0,0,0]
-    $sigma:
-      P: [0.31, 0.31, 0.31]
-      O: [0.31, 0.31, 0.31]
-      V: [0.31, 0.31, 0.31]
-    time_tolerance: 0.1
+  first_frame:
+    P:
+      state: [0,0,0]
+      mode: "factor"
+      noise_std: [0.31, 0.31, 0.31]
+    O: 
+      state: [0,0,0,1]
+      mode: "factor"
+      noise_std: [0.31, 0.31, 0.31]
+    V:
+      state: [0,0,0]
+      mode: "factor"
+      noise_std: [0.31, 0.31, 0.31]
+      type: StateVector3d
   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 a317726ac748b5353a320517b2c20ac8f7e10597..22aea41299db11cc1a6ccc326067827d14e525ec 100644
--- a/test/yaml/params_tree_manager_sliding_window1.yaml
+++ b/test/yaml/params_tree_manager_sliding_window1.yaml
@@ -1,7 +1,7 @@
 problem:
   frame_structure: "PO"
   dimension: 3
-  prior:
+  first_frame:
     mode: "factor"
     $state:
       P: [0,0,0]
diff --git a/test/yaml/params_tree_manager_sliding_window2.yaml b/test/yaml/params_tree_manager_sliding_window2.yaml
index 935f0899fe5330a382c8581954fb2166c546de72..09288cfd12247f66f2cc2b3800380d87a9cbd4e0 100644
--- a/test/yaml/params_tree_manager_sliding_window2.yaml
+++ b/test/yaml/params_tree_manager_sliding_window2.yaml
@@ -1,7 +1,7 @@
 problem:
   frame_structure: "PO"
   dimension: 3
-  prior:
+  first_frame:
     mode: "factor"
     $state:
       P: [0,0,0]
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 6a7b21625aac524b72da9fcb35d01573dfd655aa..4d9b7a7cb58d44b5067b5f90711796ba5e48e9cf 100644
--- a/test/yaml/params_tree_manager_sliding_window_dual_rate1.yaml
+++ b/test/yaml/params_tree_manager_sliding_window_dual_rate1.yaml
@@ -1,7 +1,7 @@
 problem:
   frame_structure: "PO"
   dimension: 3
-  prior:
+  first_frame:
     mode: "factor"
     $state:
       P: [0,0,0]
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 12f59ad4a91a0adb50f433ace29e4d910a3354e0..db6c4a2940bcf51e1b90cb7a53350b5bc68c8a9f 100644
--- a/test/yaml/params_tree_manager_sliding_window_dual_rate2.yaml
+++ b/test/yaml/params_tree_manager_sliding_window_dual_rate2.yaml
@@ -1,7 +1,7 @@
 problem:
   frame_structure: "PO"
   dimension: 3
-  prior:
+  first_frame:
     mode: "factor"
     $state:
       P: [0,0,0]
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 d7c53fb130fadc88f4de1c5a971b23d2f51fdce9..0d725631260166ea8aebcc3b89d206638b6532ac 100644
--- a/test/yaml/params_tree_manager_sliding_window_dual_rate3.yaml
+++ b/test/yaml/params_tree_manager_sliding_window_dual_rate3.yaml
@@ -3,7 +3,7 @@ solver:
 problem:
   frame_structure: "PO"
   dimension: 3
-  prior:
+  first_frame:
     mode: "factor"
     $state:
       P: [0,0,0]
diff --git a/test/yaml/params_tree_manager_sliding_window_dual_rate_baseline.yaml b/test/yaml/params_tree_manager_sliding_window_dual_rate_baseline.yaml
index e51b8a14692e17fca9ca6d6194be21a7291dd9d7..47e54b3ab04136e768c7479b18d3b09adfa592f8 100644
--- a/test/yaml/params_tree_manager_sliding_window_dual_rate_baseline.yaml
+++ b/test/yaml/params_tree_manager_sliding_window_dual_rate_baseline.yaml
@@ -3,7 +3,7 @@ solver:
 problem:
   frame_structure: "PO"
   dimension: 3
-  prior:
+  first_frame:
     mode: "factor"
     $state:
       P: [0,0,0]