diff --git a/demos/hello_wolf/hello_wolf.cpp b/demos/hello_wolf/hello_wolf.cpp
index 787f27623a37d9510cea7293d1efb98ce1afb475..fc389145b8db006e5907a71453cd66b56a78ecd8 100644
--- a/demos/hello_wolf/hello_wolf.cpp
+++ b/demos/hello_wolf/hello_wolf.cpp
@@ -131,6 +131,7 @@ int main()
     params_sen_odo["states"]["O"]["dynamic"]       = false;
 
     params_sen_odo["name"]           = "Sensor Odometry";
+    params_sen_odo["enabled"]        = true;
     params_sen_odo["k_disp_to_disp"] = 0.1;
     params_sen_odo["k_disp_to_rot"]  = 0.1;
     params_sen_odo["k_rot_to_rot"]   = 0.1;
@@ -168,6 +169,7 @@ int main()
     params_sen_rb["states"]["O"]["dynamic"]       = false;
 
     params_sen_rb["name"]                      = "Sensor Range Bearing";
+    params_sen_rb["enabled"]                   = true;
     params_sen_rb["noise_range_metres_std"]    = 0.1;
     params_sen_rb["noise_bearing_degrees_std"] = 1.0;
 
diff --git a/demos/hello_wolf/processor_range_bearing.cpp b/demos/hello_wolf/processor_range_bearing.cpp
index b41f0391a7de60679d917ab85af5711ae594a61a..8005adfbb620574aeb9c43df2aba98d5f4e84cc1 100644
--- a/demos/hello_wolf/processor_range_bearing.cpp
+++ b/demos/hello_wolf/processor_range_bearing.cpp
@@ -26,7 +26,7 @@
 namespace wolf
 {
 ProcessorRangeBearing::ProcessorRangeBearing(const YAML::Node& _params)
-    : ProcessorBase("ProcessorRangeBearing", 2, _params)
+    : ProcessorBase("ProcessorRangeBearing", {{'P', "StatePoint2d"}, {'O', "StateAngle"}}, _params)
 {
     //
 }
@@ -128,14 +128,13 @@ ProcessorRangeBearing::Trf ProcessorRangeBearing::transform(const Eigen::Vector2
 
 Eigen::Vector2d ProcessorRangeBearing::fromSensor(const Eigen::Vector2d& lmk_s) const
 {
-    Trf H_w_r = transform(getProblem()->getState().vector("PO"));
+    Trf H_w_r = transform(getProblem()->getState("PO").vector("PO"));
     return H_w_r * H_r_s * lmk_s;
 }
 
 Eigen::Vector2d ProcessorRangeBearing::toSensor(const Eigen::Vector2d& lmk_w) const
 {
-    //    Trf H_w_r = transform(getSensor()->getP()->getState(), getSensor()->getO()->getState());
-    Trf H_w_r = transform(getProblem()->getState().vector("PO"));
+    Trf H_w_r = transform(getProblem()->getState("PO").vector("PO"));
     return (H_w_r * H_r_s).inverse() * lmk_w;
 }
 
diff --git a/include/core/common/node_state_blocks.h b/include/core/common/node_state_blocks.h
index 418abd564337d693abfb72ed262f3f977731709b..9dc0f134afb61c8eef96b522c291f68b00f4027a 100644
--- a/include/core/common/node_state_blocks.h
+++ b/include/core/common/node_state_blocks.h
@@ -84,13 +84,22 @@ class NodeStateBlocks : public NodeBase, public std::enable_shared_from_this<Nod
      *
      * \param _key Key of the new state.
      * \param _type Types of the new state.
-     * \param _vectors Vector of the new state.
+     * \param _vector Vector of the new state.
      * \param _fixed If the new state is fixed (i.e. not estimated).
      **/
     StateBlockPtr emplaceStateBlock(const char             key,
-                                    const std::string&     _type,
-                                    const Eigen::VectorXd& _vector,
-                                    const bool&            _fixed);
+        const std::string&     _type,
+        const Eigen::VectorXd& _vector,
+        const bool&            _fixed);
+        /** \brief Emplace a state block with zero state
+         *
+         * \param _key Key of the new state.
+         * \param _type Types of the new state.
+         * \param _fixed If the new state is fixed (i.e. not estimated).
+         **/
+        StateBlockPtr emplaceStateBlockZero(const char             key,
+                                        const std::string&     _type,
+                                        const bool&            _fixed);
 
   protected:
     virtual void removeStateBlock(const char& _sb_key);
diff --git a/include/core/problem/problem.h b/include/core/problem/problem.h
index 91cc837f3e66fd57136a47f09bd12938d81373e5..73eab66545543855df753984a5fb5fb55d3607d6 100644
--- a/include/core/problem/problem.h
+++ b/include/core/problem/problem.h
@@ -73,7 +73,6 @@ class Problem : public std::enable_shared_from_this<Problem>
     std::map<unsigned int, MotionProviderPtr> motion_provider_map_;
 
     SizeEigen       dim_;
-    StateKeys       frame_keys_;
     TypeComposite   frame_types_;
     VectorComposite first_frame_values_;
     PriorComposite  first_frame_priors_;
@@ -94,14 +93,14 @@ class Problem : public std::enable_shared_from_this<Problem>
 
   private:  // CAUTION: THESE METHODS ARE PRIVATE, DO NOT MAKE THEM PUBLIC !!
     Problem(SizeEigen            _dim,
-            const TypeComposite& _frame_structure = {},
-            LoaderPtr            _loader          = nullptr);  // USE create() below !!
+            const TypeComposite& _frame_types = {},
+            LoaderPtr            _loader      = nullptr);  // USE create() below !!
     void setup();
 
   public:
     static ProblemPtr create(SizeEigen            _dim,
-                             const TypeComposite& _frame_structure = {},
-                             LoaderPtr            _loader          = nullptr);  // USE THIS AS A CONSTRUCTOR!
+                             const TypeComposite& _frame_types = {},
+                             LoaderPtr            _loader      = nullptr);  // USE THIS AS A CONSTRUCTOR!
     static ProblemPtr autoSetup(const std::string&       _input_yaml_file,
                                 std::vector<std::string> _primary_schema_folders = {},
                                 LoaderPtr                _loader                 = nullptr,
@@ -115,13 +114,10 @@ class Problem : public std::enable_shared_from_this<Problem>
     // Properties -----------------------------------------
     LoaderPtr     getLoader();
     SizeEigen     getDim() const;
-    StateKeys     getFrameKeys() const;
-    bool          hasFrameKeys(StateKeys _keys) const;
     TypeComposite getFrameTypes(StateKeys _keys) const;
 
   protected:
-    void addFrameKeys(StateKeys _keys);
-    void addFrameTypes(const TypeComposite& _structure);
+    void addFrameTypes(const TypeComposite& _types);
 
     // Tree manager --------------------------------------
   public:
@@ -245,11 +241,11 @@ class Problem : public std::enable_shared_from_this<Problem>
      *   - Add it to Trajectory
      *   - If it is key-frame, update state-block lists in Problem
      */
-    FrameBasePtr emplaceFrame(const TimeStamp& _time_stamp, const StateKeys& _frame_keys = "");
+    FrameBasePtr emplaceFrame(const TimeStamp& _time_stamp, const StateKeys& _frame_keys);
 
     /** \brief Emplace frame from timestamps and state
      * \param _time_stamp Time stamp of the frame
-     * \param _frame_state State; must be part of the problem's frame structure
+     * \param _frame_state State; must be part of the problem's frame state_keys
      *
      * - The frame_types are taken from Problem
      *
@@ -263,7 +259,7 @@ class Problem : public std::enable_shared_from_this<Problem>
     /** \brief Emplace frame from timestamp and state vector
      * \param _time_stamp Time stamp of the frame
      * \param _frame_keys String containing the keys of the desired frame. Empty means all keys available.
-     * \param _frame_state State vector; must match the size and format of the chosen frame structure
+     * \param _frame_state State vector; must match the size and format of the chosen frame state_keys
      *
      * - The frame_types are taken from Problem
      *
@@ -276,6 +272,17 @@ class Problem : public std::enable_shared_from_this<Problem>
                               const StateKeys&       _frame_keys,
                               const Eigen::VectorXd& _frame_state);
 
+    /** \brief Take a frame and emplace to it the missing states with the frame timestamp
+     * \param _frame_ptr Frame to which states have to be emplaced
+     * \param _frame_keys the keys that the frame is requested to have.
+     *
+     * - The frame_types are taken from Problem.
+     * - Only the missing keys are emplaced.
+     * - The states are taken from Problem::getState(_frame_ptr->getTimeStamp(), _frame_keys)
+     * - The states are emplaced to the frame as unfixed.
+     */
+    void emplaceStatesToFrame(FrameBasePtr _frame_ptr, const StateKeys& _frame_keys);
+
     // Frame getters
     FrameBaseConstPtr getLastFrame() const;
     FrameBasePtr      getLastFrame();
@@ -300,13 +307,13 @@ class Problem : public std::enable_shared_from_this<Problem>
 
     // State getters
     TimeStamp       getTimeStamp() const;
-    VectorComposite getState(const StateKeys& _structure = "") const;
-    VectorComposite getState(const TimeStamp& _ts, const StateKeys& _structure = "") const;
-    VectorComposite getOdometry(const StateKeys& _structure = "") const;
+    VectorComposite getState(const StateKeys& _keys) const;
+    VectorComposite getState(const TimeStamp& _ts, const StateKeys& _keys) const;
+    VectorComposite getOdometry(const StateKeys& _keys) const;
 
     // Zero state provider
-    VectorComposite stateZero(TypeComposite _types = {}) const;
-    VectorComposite stateZero(const StateKeys& _structure) const;
+    VectorComposite stateZero(TypeComposite _types) const;
+    VectorComposite stateZero(const StateKeys& _keys) const;
 
     // Map branch -----------------------------------------
     MapBaseConstPtr getMap() const;
diff --git a/include/core/processor/motion_provider.h b/include/core/processor/motion_provider.h
index b9c5d7b4e52ed923a398e5bd06af718bde6740c8..70175fb70179e5d30dc2d8bd6c1433e3aa1b33b9 100644
--- a/include/core/processor/motion_provider.h
+++ b/include/core/processor/motion_provider.h
@@ -36,9 +36,9 @@ class MotionProvider
     virtual ~MotionProvider();
 
     // Queries to the processor:
-    virtual TimeStamp       getTimeStamp() const                                            = 0;
-    virtual VectorComposite getState(StateKeys _structure = "") const                       = 0;
-    virtual VectorComposite getState(const TimeStamp& _ts, StateKeys _structure = "") const = 0;
+    virtual TimeStamp       getTimeStamp() const                                       = 0;
+    virtual VectorComposite getState(StateKeys _keys = "") const                       = 0;
+    virtual VectorComposite getState(const TimeStamp& _ts, StateKeys _keys = "") const = 0;
 
     VectorComposite getOdometry() const;
     void            setOdometry(const VectorComposite&);
@@ -47,21 +47,6 @@ class MotionProvider
     unsigned int getOrder() const;
     void         setOrder(unsigned int);
 
-  public:
-    TypeComposite getStateTypes() const
-    {
-        return state_types_;
-    };
-    StateKeys getStateKeys() const
-    {
-        return state_types_.getKeys();
-    };
-    void setStateTypes(const TypeComposite& _state_structure)
-    {
-        state_types_ = _state_structure;
-    };
-    void addToProblem(ProblemPtr _prb_ptr, MotionProviderPtr _motion_ptr);
-
   protected:
     TypeComposite state_types_;
     bool          is_state_provider_;
diff --git a/include/core/processor/processor_base.h b/include/core/processor/processor_base.h
index b4d22b4035c5a69a1f1927083b571c2196ef771b..73bf60933c51fc1c12ffbc35a9cf63b9252c3a0f 100644
--- a/include/core/processor/processor_base.h
+++ b/include/core/processor/processor_base.h
@@ -119,7 +119,7 @@ class ProcessorBase : public NodeBase, public std::enable_shared_from_this<Proce
     YAML::Node    params_;
     BufferFrame   buffer_frame_;
     BufferCapture buffer_capture_;
-    unsigned int  dim_compatible_;  ///< Dimension compatibility of the processor: 2: 2D, 3: 3D, 0: both
+    TypeComposite state_types_;  ///< State type composite of frames created or used by this processor
 
   private:
     SensorBaseWPtr      sensor_ptr_;
@@ -142,15 +142,17 @@ class ProcessorBase : public NodeBase, public std::enable_shared_from_this<Proce
     /** \brief constructor
      *
      * \param _type TO BE HARDCODED IN THE DERIVED CLASS CONSTRUCTOR: type name
-     * \param _dim_compatible TO BE HARDCODED IN THE DERIVED CLASS CONSTRUCTOR:
-     * Which dimension is the processor compatible (2: 2D, 3: 3D, 0: both)
+     * \param _state_types TO BE HARDCODED IN THE DERIVED CLASS CONSTRUCTOR:
+     * The composite of state types of the frames created or used by this processor
      * \param _params params yaml node
      */
-    ProcessorBase(const std::string& _type, unsigned int _dim_compatible, const YAML::Node& _params);
+    ProcessorBase(const std::string& _type, const TypeComposite& _state_types, const YAML::Node& _params);
     ~ProcessorBase() override;
-    virtual void configure(SensorBasePtr _sensor) = 0;
-    virtual void remove();
-    bool         hasChildren() const override;
+    virtual void         configure(SensorBasePtr _sensor) = 0;
+    virtual void         remove();
+    bool                 hasChildren() const override;
+    const TypeComposite& getStateTypes() const;
+    StateKeys     getStateKeys() const;
 
     unsigned int id() const;
 
@@ -232,7 +234,6 @@ class ProcessorBase : public NodeBase, public std::enable_shared_from_this<Proce
   public:
     YAML::Node   getParams() const;
     bool         isMotionProvider() const;
-    unsigned int getDimCompatible() const;
     bool         applyLossFunction() const;
     bool         isVotingActive() const;
     double       getTimeTolerance() const;
@@ -331,9 +332,14 @@ inline SensorBasePtr ProcessorBase::getSensor()
     return sensor_ptr_.lock();
 }
 
-inline unsigned int ProcessorBase::getDimCompatible() const
+inline StateKeys ProcessorBase::getStateKeys() const
 {
-    return dim_compatible_;
+    return state_types_.getKeys();
+}
+
+inline const TypeComposite& ProcessorBase::getStateTypes() const
+{
+    return state_types_;
 }
 
 inline void ProcessorBase::setTimeTolerance(double _time_tolerance)
diff --git a/include/core/processor/processor_landmark_external.h b/include/core/processor/processor_landmark_external.h
index 89439337b62230545b9addf883c16cb1632aa736..969502b2c4c28f3cf2225c61f6a7a071b669caa1 100644
--- a/include/core/processor/processor_landmark_external.h
+++ b/include/core/processor/processor_landmark_external.h
@@ -38,7 +38,7 @@ class ProcessorLandmarkExternal : public ProcessorTracker
     // Factory method for high level API
     WOLF_PROCESSOR_CREATE(ProcessorLandmarkExternal);
 
-    void configure(SensorBasePtr _sensor) override{};
+    void configure(SensorBasePtr _sensor) override {};
 
   protected:
     TrackMatrix track_matrix_;
@@ -103,7 +103,7 @@ class ProcessorLandmarkExternal : public ProcessorTracker
      *
      * It does nothing for now
      */
-    void postProcess() override{};
+    void postProcess() override {};
 
     void advanceDerived() override;
     void resetDerived() override;
@@ -120,6 +120,7 @@ class ProcessorLandmarkExternal : public ProcessorTracker
                              const VectorComposite& _pose_sen) const;
 
     // PROCESSOR PARAMETERS
+    int          dim_;                        ///< dimension of the problem (2D or 3D)
     bool         use_orientation_;            ///< use orientation measure or not when emplacing factors
     unsigned int new_features_for_keyframe_;  ///< for keyframe voting: amount of new features with respect to origin
                                               ///< (sufficient condition if more than min_features_for_keyframe)
@@ -140,7 +141,11 @@ class ProcessorLandmarkExternal : public ProcessorTracker
 };
 
 inline ProcessorLandmarkExternal::ProcessorLandmarkExternal(const YAML::Node& _params)
-    : ProcessorTracker("ProcessorLandmarkExternal", "PO", 0, _params),
+    : ProcessorTracker("ProcessorLandmarkExternal",
+                       {{'P', _params["dimension"].as<int>() == 2 ? "StatePoint2d" : "StatePoint3d"},
+                        {'O', _params["dimension"].as<int>() == 2 ? "StateAngle" : "StateQuaternion"}},
+                       _params),
+      dim_(_params["dimension"].as<int>()),
       use_orientation_(_params["use_orientation"].as<bool>()),
       new_features_for_keyframe_(_params["keyframe_vote"]["new_features_for_keyframe"].as<unsigned int>()),
       time_span_(_params["keyframe_vote"]["time_span"].as<double>()),
@@ -150,6 +155,6 @@ inline ProcessorLandmarkExternal::ProcessorLandmarkExternal(const YAML::Node& _p
       match_dist_th_unknown_(_params["match_dist_th_unknown"].as<double>()),
       track_length_th_(_params["track_length_th"].as<unsigned int>()),
       close_loops_by_id_(_params["close_loops_by_id"].as<bool>()),
-      close_loops_by_type_(_params["close_loops_by_type"].as<bool>()){};
+      close_loops_by_type_(_params["close_loops_by_type"].as<bool>()) {};
 
 }  // namespace wolf
diff --git a/include/core/processor/processor_loop_closure.h b/include/core/processor/processor_loop_closure.h
index a04ed6f0204d348371272d84b67e9c4a023c2426..b923ea90db0ad58a7234772f2c0566ca63198f05 100644
--- a/include/core/processor/processor_loop_closure.h
+++ b/include/core/processor/processor_loop_closure.h
@@ -52,7 +52,7 @@ struct MatchLoopClosure
 class ProcessorLoopClosure : public ProcessorBase
 {
   public:
-    ProcessorLoopClosure(const std::string& _type, int _dim, const YAML::Node& _params);
+    ProcessorLoopClosure(const std::string& _type, const TypeComposite& _state_types, const YAML::Node& _params);
 
     ~ProcessorLoopClosure() override = default;
     void configure(SensorBasePtr _sensor) override{};
diff --git a/include/core/processor/processor_motion.h b/include/core/processor/processor_motion.h
index 62c75554606f0db12d8d9558c46efc87ffa43b36..4d8dcee2844eafebb27865d38329c6c6eb263c7e 100644
--- a/include/core/processor/processor_motion.h
+++ b/include/core/processor/processor_motion.h
@@ -129,7 +129,6 @@ class ProcessorMotion : public ProcessorBase, public MotionProvider
   public:
     ProcessorMotion(const std::string& _type,
                     TypeComposite      _state_types,
-                    int                _dim,
                     SizeEigen          _state_size,
                     SizeEigen          _delta_size,
                     SizeEigen          _delta_cov_size,
diff --git a/include/core/processor/processor_pose.h b/include/core/processor/processor_pose.h
index bfd7582b1d7544780cc41eef1805870878bcbbc2..22396e638119baad77fb36715472f1d380c4d2fb 100644
--- a/include/core/processor/processor_pose.h
+++ b/include/core/processor/processor_pose.h
@@ -78,7 +78,11 @@ WOLF_DECLARED_PTR_TYPEDEFS(ProcessorPose3d);
 namespace wolf
 {
 template <unsigned int DIM>
-inline ProcessorPose<DIM>::ProcessorPose(const YAML::Node& _params) : ProcessorBase("ProcessorPose", DIM, _params)
+inline ProcessorPose<DIM>::ProcessorPose(const YAML::Node& _params)
+    : ProcessorBase(
+          "ProcessorPose",
+          {{'P', DIM == 2 ? "StatePoint2d" : "StatePoint3d"}, {'O', DIM == 2 ? "StateAngle" : "StateQuaternion"}},
+          _params)
 {
     static_assert(DIM == 2 or DIM == 3);
 }
diff --git a/include/core/processor/processor_tracker.h b/include/core/processor/processor_tracker.h
index 54eade13bf31e4dad72d1d3ab88748fbc670e2bd..147f3caccd8133a5f53166d4064c7d9b24c8df9c 100644
--- a/include/core/processor/processor_tracker.h
+++ b/include/core/processor/processor_tracker.h
@@ -88,7 +88,6 @@ class ProcessorTracker : public ProcessorBase
     CaptureBasePtr origin_ptr_;       ///< Pointer to the origin of the tracker.
     CaptureBasePtr last_ptr_;         ///< Pointer to the last tracked capture.
     CaptureBasePtr incoming_ptr_;     ///< Pointer to the incoming capture being processed.
-    FrameBasePtr   last_frame_ptr_;
 
     FeatureBasePtrList new_features_last_;  ///< List of new features in \b last for landmark initialization and new
                                             ///< key-frame creation.
@@ -98,7 +97,6 @@ class ProcessorTracker : public ProcessorBase
         known_features_last_;  ///< list of the known features in previous captures successfully tracked in \b last
     FeatureBasePtrList
               known_features_incoming_;  ///< list of the known features in \b last successfully tracked in \b incoming
-    StateKeys state_keys_;               ///< Keys of frames created or used by this processor
 
     // PARAMS
     unsigned int min_features_for_keyframe_;  ///< minimum nbr. of features to vote for keyframe
@@ -110,17 +108,13 @@ class ProcessorTracker : public ProcessorBase
         establish_factors_profiling_, postprocess_profiling_;
 
   public:
-    ProcessorTracker(const std::string& _type, const StateKeys& _structure, int _dim, const YAML::Node& _params);
+    ProcessorTracker(const std::string& _type, const TypeComposite& state_types_, const YAML::Node& _params);
     ~ProcessorTracker() override;
 
-    const StateKeys& getStateKeys() const;
-
     virtual CaptureBaseConstPtr getOrigin() const;
     virtual CaptureBasePtr      getOrigin();
     virtual CaptureBaseConstPtr getLast() const;
     virtual CaptureBasePtr      getLast();
-    virtual FrameBaseConstPtr   getLastFrame() const;
-    virtual FrameBasePtr        getLastFrame();
     virtual CaptureBaseConstPtr getIncoming() const;
     virtual CaptureBasePtr      getIncoming();
 
@@ -187,7 +181,7 @@ class ProcessorTracker : public ProcessorBase
      *   - initializing counters, flags, or any derived variables
      *   - initializing algorithms needed for processing the derived data
      */
-    virtual void preProcess(){};
+    virtual void preProcess() {};
 
     /** Post-process
      *
@@ -199,7 +193,7 @@ class ProcessorTracker : public ProcessorBase
      *   - resetting and/or clearing variables and/or algorithms at the end of processing
      *   - drawing / printing / logging the results of the processing
      */
-    virtual void postProcess(){};
+    virtual void postProcess() {};
 
     /** \brief Tracker function
      * \return The number of successful tracks.
@@ -307,11 +301,6 @@ inline FeatureBasePtrList& ProcessorTracker::getNewFeaturesListIncoming()
     return new_features_incoming_;
 }
 
-inline const StateKeys& ProcessorTracker::getStateKeys() const
-{
-    return state_keys_;
-}
-
 inline void ProcessorTracker::addNewFeatureIncoming(FeatureBasePtr _feature_ptr)
 {
     new_features_incoming_.push_back(_feature_ptr);
@@ -337,16 +326,6 @@ inline CaptureBasePtr ProcessorTracker::getLast()
     return last_ptr_;
 }
 
-inline FrameBaseConstPtr ProcessorTracker::getLastFrame() const
-{
-    return last_frame_ptr_;
-}
-
-inline FrameBasePtr ProcessorTracker::getLastFrame()
-{
-    return last_frame_ptr_;
-}
-
 inline CaptureBaseConstPtr ProcessorTracker::getIncoming() const
 {
     return incoming_ptr_;
diff --git a/include/core/processor/processor_tracker_feature.h b/include/core/processor/processor_tracker_feature.h
index eebf6e782877e4a285678c0028bbba433a86b4d7..79a4c3ca8a8d1f3c5ac141c26128d32722312394 100644
--- a/include/core/processor/processor_tracker_feature.h
+++ b/include/core/processor/processor_tracker_feature.h
@@ -86,10 +86,7 @@ class ProcessorTrackerFeature : public ProcessorTracker
   public:
     /** \brief Constructor with type
      */
-    ProcessorTrackerFeature(const std::string& _type,
-                            const StateKeys&   _structure,
-                            int                _dim,
-                            const YAML::Node&  _params);
+    ProcessorTrackerFeature(const std::string& _type, const TypeComposite& state_types_, const YAML::Node& _params);
     ~ProcessorTrackerFeature() override;
 
   protected:
diff --git a/include/core/processor/processor_tracker_landmark.h b/include/core/processor/processor_tracker_landmark.h
index ebf22d98ccd5962191e5fd5e436f0ae4106c7dd2..bf8eb2143b81dd017d0aa01a3e99acbcb9348ac0 100644
--- a/include/core/processor/processor_tracker_landmark.h
+++ b/include/core/processor/processor_tracker_landmark.h
@@ -82,9 +82,9 @@ WOLF_PTR_TYPEDEFS(ProcessorTrackerLandmark);
 class ProcessorTrackerLandmark : public ProcessorTracker
 {
   public:
-    ProcessorTrackerLandmark(const std::string& _type,
-                             const StateKeys&   _structure,
-                             const YAML::Node&  _params_tracker_landmark);
+    ProcessorTrackerLandmark(const std::string&   _type,
+                             const TypeComposite& _state_types,
+                             const YAML::Node&    _params_tracker_landmark);
     ~ProcessorTrackerLandmark() override;
 
   protected:
diff --git a/include/core/state_block/factory_state_block.h b/include/core/state_block/factory_state_block.h
index c9494cac8e17187c287c0ab68f87084fbc29e28f..c876c66bdda4bd66bca5cc3a61194be9a4780315 100644
--- a/include/core/state_block/factory_state_block.h
+++ b/include/core/state_block/factory_state_block.h
@@ -84,7 +84,7 @@ inline std::string FactoryStateBlock::getClass() const
 {
     return "FactoryStateBlock";
 }
-typedef Factory<std::shared_ptr<StateBlock>> FactoryStateBlockIdentity;
+typedef Factory<std::shared_ptr<StateBlock>, bool> FactoryStateBlockIdentity;
 template <>
 inline std::string FactoryStateBlockIdentity::getClass() const
 {
diff --git a/include/core/state_block/state_block.h b/include/core/state_block/state_block.h
index 46533f9de0650810a38f9ba510c66f2d205bb7a5..f0739a87ada759e2e7b87f9d7a7ef1cdb55b820a 100644
--- a/include/core/state_block/state_block.h
+++ b/include/core/state_block/state_block.h
@@ -38,9 +38,9 @@
     {                                                                                                                 \
         return std::make_shared<StateBlockClass>(_state, _fixed);                                                     \
     }                                                                                                                 \
-    static StateBlockPtr createIdentity()                                                                             \
+    static StateBlockPtr createIdentity(bool _fixed)                                                                  \
     {                                                                                                                 \
-        return std::make_shared<StateBlockClass>(StateBlockClass::Identity(), false);                                 \
+        return std::make_shared<StateBlockClass>(StateBlockClass::Identity(), _fixed);                                \
     }
 
 // Fwd references
@@ -116,8 +116,8 @@ class StateBlock : public std::enable_shared_from_this<StateBlock>
                bool                        _transformable   = true);
 
     ///< Explicitly not copyable/movable
-    StateBlock(const StateBlock& o) = delete;
-    StateBlock(StateBlock&& o)      = delete;
+    StateBlock(const StateBlock& o)            = delete;
+    StateBlock(StateBlock&& o)                 = delete;
     StateBlock& operator=(const StateBlock& o) = delete;
 
     /** \brief Destructor
diff --git a/schema/processor/ProcessorLandmarkExternal.schema b/schema/processor/ProcessorLandmarkExternal.schema
index c929de2307515879a73a2eb51d839f82aafc939e..611400c7c63f29ebd61179c451f8c411a504d5b2 100644
--- a/schema/processor/ProcessorLandmarkExternal.schema
+++ b/schema/processor/ProcessorLandmarkExternal.schema
@@ -1,5 +1,11 @@
 follow: ProcessorTracker.schema
 
+dimension:
+  _mandatory: true
+  _type: int
+  _options: [2, 3]
+  _doc: "Dimension of the problem representation is 2D or 3D."
+
 quality_th:
   _mandatory: true
   _type: double
diff --git a/src/common/node_state_blocks.cpp b/src/common/node_state_blocks.cpp
index 8ea9d6b0d86f2518328b84b2eaa33a18c3883d57..a8ecdce30be2b3e11c6889d7b7a878b85480bb23 100644
--- a/src/common/node_state_blocks.cpp
+++ b/src/common/node_state_blocks.cpp
@@ -118,6 +118,38 @@ StateBlockPtr NodeStateBlocks::emplaceStateBlock(const char         _key,
     return sb;
 }
 
+StateBlockPtr NodeStateBlocks::emplaceStateBlockZero(const char _key, const std::string& _type, const bool& _fixed)
+{
+    // check key available
+    if (state_blocks_.count(_key))
+    {
+        throw std::runtime_error(std::string("NodeStateBlocks::emplaceStateBlockZero: key ") + _key +
+                                 " already in the node.");
+    }
+    // check correct type
+    checkTypeComposite({{_key, _type}});
+    if (state_types_.count(_key))
+    {
+        if (state_types_.at(_key) != _type)
+            throw std::runtime_error(
+                std::string("NodeStateBlocks::emplaceStateBlockZero: Wrong input type: " + _type + " for key ") +
+                _key + ". It should be " + state_types_.at(_key));
+    }
+    else
+        state_types_[_key] = _type;
+
+    // create state block
+    auto sb = FactoryStateBlockIdentity::create(_type, _fixed);
+
+    // store state block
+    state_blocks_.emplace(_key, sb);
+
+    // register to problem (if linked)
+    if (getProblem()) getProblem()->notifyStateBlock(sb, ADD);
+
+    return sb;
+}
+
 void NodeStateBlocks::removeStateBlock(const char& _key)
 {
     StateBlockPtr _sb = getStateBlock(_key);
diff --git a/src/problem/problem.cpp b/src/problem/problem.cpp
index 965a0aa506d3127489bb7b53cc8722f3e070bcea..2c5d981e15d701e0b65d581555a504dd0cd0df47 100644
--- a/src/problem/problem.cpp
+++ b/src/problem/problem.cpp
@@ -46,7 +46,6 @@ Problem::Problem(SizeEigen _dim, const TypeComposite& _frame_types, LoaderPtr _l
       tree_manager_(nullptr),
       motion_provider_map_(),
       dim_(_dim),
-      frame_keys_(),
       // reseved state types (P -> position, O -> orientation, V -> velocity)
       frame_types_({{'P', (dim_ == 2 ? "StatePoint2d" : "StatePoint3d")},
                     {'O', (dim_ == 2 ? "StateAngle" : "StateQuaternion")},
@@ -316,10 +315,6 @@ ProcessorBasePtr Problem::installProcessor(const YAML::Node& _processor_node, st
 
     if (not prc_ptr) throw std::runtime_error("Processor could not be created.");
 
-    // Dimension check
-    if (prc_ptr->getDimCompatible() != 0 and prc_ptr->getDimCompatible() != this->getDim())
-        throw std::runtime_error("Processor not compatible with the Problem dimension.");
-
     // Link
     prc_ptr->configure(sen_ptr);
     prc_ptr->link(sen_ptr);
@@ -368,10 +363,6 @@ ProcessorBasePtr Problem::installProcessor(SensorBasePtr            _sensor_corr
     ProcessorBasePtr prc_ptr = FactoryProcessorNode::create(prc_type, processor_node, _schema_folders);
     if (not prc_ptr) throw std::runtime_error("Processor could not be created.");
 
-    // Dimension check
-    if (prc_ptr->getDimCompatible() != 0 and prc_ptr->getDimCompatible() != this->getDim())
-        throw std::runtime_error("Processor not compatible with the Problem dimension.");
-
     // Add processor
     prc_ptr->configure(_sensor_corresponding);
     prc_ptr->link(_sensor_corresponding);
@@ -422,10 +413,6 @@ ProcessorBasePtr Problem::installProcessor(const std::string&       _params_yaml
     ProcessorBasePtr prc_ptr = FactoryProcessorNode::create(prc_type, processor_node, _schema_folders);
     if (not prc_ptr) throw std::runtime_error("Processor could not be created.");
 
-    // Dimension check
-    if (prc_ptr->getDimCompatible() != 0 and prc_ptr->getDimCompatible() != this->getDim())
-        throw std::runtime_error("Processor not compatible with the Problem dimension.");
-
     // Add processor
     prc_ptr->configure(sen_ptr);
     prc_ptr->link(sen_ptr);
@@ -464,25 +451,20 @@ FrameBasePtr Problem::emplaceFrame(const TimeStamp&       _time_stamp,
                                    const VectorComposite& _frame_state,
                                    const PriorComposite&  _frame_priors)
 {
-    // check input _frame_specs
+    // check input _frame_types
     checkTypeComposite(_frame_types);
 
     // add the types of the keys that are not in frame_types_ (also checks that are consistent)
     addFrameTypes(_frame_types);
 
-    // add the keys that are not in frame_keys_
-    addFrameKeys(_frame_state.getKeys());
-
     return FrameBase::emplace<FrameBase>(getTrajectory(), _time_stamp, _frame_types, _frame_state, _frame_priors);
 }
 
 FrameBasePtr Problem::emplaceFrame(const TimeStamp& _time_stamp, const StateKeys& _frame_keys)
 {
     if (not frame_types_.has(_frame_keys))
-    {
-        throw std::runtime_error("Problem::emplaceFrame: any unknown type, asked for " + _frame_keys +
+        throw std::runtime_error("Problem::emplaceFrame: any unknown type. Asked for key " + _frame_keys +
                                  " but problem only know the types of " + frame_types_.getKeys());
-    }
 
     auto state = getState(_time_stamp, _frame_keys);
 
@@ -492,11 +474,8 @@ FrameBasePtr Problem::emplaceFrame(const TimeStamp& _time_stamp, const StateKeys
 FrameBasePtr Problem::emplaceFrame(const TimeStamp& _time_stamp, const VectorComposite& _frame_state)
 {
     if (not frame_types_.has(_frame_state.getKeys()))
-    {
-        throw std::runtime_error("Problem::emplaceFrame: any unknown type, given vectors of " +
-                                 _frame_state.getKeys() + " but problem only know the types of " +
-                                 frame_types_.getKeys());
-    }
+        throw std::runtime_error("Problem::emplaceFrame: any unknown type. given vectors for keys " + _frame_state.getKeys() +
+                                 " but problem only know the types of " + frame_types_.getKeys());
 
     return Problem::emplaceFrame(_time_stamp, getFrameTypes(_frame_state.getKeys()), _frame_state);
 }
@@ -506,10 +485,8 @@ FrameBasePtr Problem::emplaceFrame(const TimeStamp&       _time_stamp,
                                    const Eigen::VectorXd& _frame_state)
 {
     if (not frame_types_.has(_frame_keys))
-    {
-        throw std::runtime_error("Problem::emplaceFrame: any unknown type, given vectors of " + _frame_keys +
+        throw std::runtime_error("Problem::emplaceFrame: any unknown type. given vectors for keys " + _frame_keys +
                                  " but problem only know the types of " + frame_types_.getKeys());
-    }
 
     VectorComposite vec_composite;
 
@@ -534,6 +511,32 @@ FrameBasePtr Problem::emplaceFrame(const TimeStamp&       _time_stamp,
     return Problem::emplaceFrame(_time_stamp, getFrameTypes(vec_composite.getKeys()), vec_composite);
 }
 
+void Problem::emplaceStatesToFrame(FrameBasePtr _frame_ptr, const StateKeys& _frame_keys)
+{
+    if (not _frame_ptr) throw std::runtime_error("Problem::emplaceStatesToFrame: the provided frame is nullptr");
+
+    if (not frame_types_.has(_frame_keys))
+        throw std::runtime_error("Problem::emplaceStatesToFrame: any unknown type. Asked for key " + _frame_keys +
+                                 " but problem only know the types of " + frame_types_.getKeys());
+
+    // missing keys
+    StateKeys missing_keys;
+    for (auto key : _frame_keys)
+        if (not _frame_ptr->getState().has(key)) missing_keys.push_back(key);
+
+    // if no missing keys, return the frame
+    if (missing_keys.empty()) return;
+
+    WOLF_DEBUG("Emplacing missing states (", missing_keys, ") to frame ", _frame_ptr->id());
+
+    // get state of missing keys
+    auto state = getState(_frame_ptr->getTimeStamp(), _frame_keys);
+
+    // emplace states to the frame (unfixed)
+    for (auto vec_pair : state)
+        _frame_ptr->emplaceStateBlock(vec_pair.first, frame_types_.at(vec_pair.first), vec_pair.second, false);
+}
+
 TimeStamp Problem::getTimeStamp() const
 {
     TimeStamp ts = TimeStamp::Invalid();
@@ -556,14 +559,19 @@ TimeStamp Problem::getTimeStamp() const
 
 VectorComposite Problem::getState(const StateKeys& _keys) const
 {
-    StateKeys keys = (_keys == "" ? getFrameKeys() : _keys);
+    if (not frame_types_.has(_keys))
+        throw std::runtime_error("Problem::getState: unknown key! Asked for " + _keys +
+                                 " but installed processors only work with " + frame_types_.getKeys());
+
+    WOLF_WARN_COND(_keys.empty(), "Problem::getState: empty keys provided. Returning empty state.");
+    if (_keys.empty()) return VectorComposite();
 
     VectorComposite state;
 
     // compose the states of all MotionProvider processors (ordered by user-defined priority) into one only state
     for (auto prc_pair : motion_provider_map_)
     {
-        auto prc_state = prc_pair.second->getState(keys);
+        auto prc_state = prc_pair.second->getState(_keys);
 
         // transfer processor vector blocks to problem state
         for (auto pair_key_vec : prc_state)
@@ -576,7 +584,7 @@ VectorComposite Problem::getState(const StateKeys& _keys) const
         }
 
         // If all keys are filled return
-        if (state.has(keys))
+        if (state.has(_keys))
         {
             return state;
         }
@@ -588,12 +596,12 @@ VectorComposite Problem::getState(const StateKeys& _keys) const
     auto last_kf = trajectory_ptr_->getLastFrame();
 
     if (last_kf)
-        state_last = last_kf->getState(keys);
+        state_last = last_kf->getState(_keys);
 
     else if (not first_frame_values_.empty())
         state_last = first_frame_values_;
 
-    for (auto key : keys)
+    for (auto key : _keys)
     {
         if (state.has(key) == 0)
         {
@@ -603,23 +611,34 @@ VectorComposite Problem::getState(const StateKeys& _keys) const
                 state.emplace(key, state_last_it->second);
 
             else
+            {
+                WOLF_WARN("Could not find any state for key ", key, ". Filling with zero state.");
                 state.emplace(key, stateZero(std::string(1, key)).at(key));
+            }
         }
     }
 
     return state;
 }
 
-VectorComposite Problem::getState(const TimeStamp& _ts, const StateKeys& _structure) const
+VectorComposite Problem::getState(const TimeStamp& _ts, const StateKeys& _keys) const
 {
-    StateKeys structure = (_structure == "" ? getFrameKeys() : _structure);
+    if (not frame_types_.has(_keys))
+        throw std::runtime_error("Problem::getState: unknown key! Asked for " + _keys +
+                                " but installed processors only work with " + frame_types_.getKeys());
+
+    WOLF_WARN_COND(_keys.empty(), "Empty keys provided. Returning empty state.");
+    if (_keys.empty()) return VectorComposite();
+
+    WOLF_WARN_COND(not _ts.ok(), "Wrong timestamp provided. Returning empty state.");
+    if (not _ts.ok()) return VectorComposite();
 
     VectorComposite state;
 
     // compose the states of all MotionProvider processors (ordered by user-defined priority) into one only state
     for (auto prc_pair : motion_provider_map_)
     {
-        auto prc_state = prc_pair.second->getState(_ts, structure);
+        auto prc_state = prc_pair.second->getState(_ts, _keys);
 
         // transfer processor vector blocks to problem state
         for (auto pair_key_vec : prc_state)
@@ -630,7 +649,7 @@ VectorComposite Problem::getState(const TimeStamp& _ts, const StateKeys& _struct
         }
 
         // If all keys are filled return
-        if (state.size() == structure.size())
+        if (state.size() == _keys.size())
         {
             return state;
         }
@@ -643,12 +662,12 @@ VectorComposite Problem::getState(const TimeStamp& _ts, const StateKeys& _struct
     auto last_kf = trajectory_ptr_->closestFrameToTimeStamp(_ts);
 
     if (last_kf)
-        state_last = last_kf->getState(structure);
+        state_last = last_kf->getState(_keys);
 
     else if (not first_frame_values_.empty())
         state_last = first_frame_values_;
 
-    for (auto key : structure)
+    for (auto key : _keys)
     {
         if (state.count(key) == 0)
         {
@@ -658,16 +677,24 @@ VectorComposite Problem::getState(const TimeStamp& _ts, const StateKeys& _struct
                 state.emplace(key, state_last_it->second);
 
             else
+            {
+                WOLF_WARN("Could not find any state for key ", key, ". Filling with zero state.");
                 state.emplace(key, stateZero(std::string(1, key)).at(key));
+            }
         }
     }
 
     return state;
 }
 
-VectorComposite Problem::getOdometry(const StateKeys& _structure) const
+VectorComposite Problem::getOdometry(const StateKeys& _keys) const
 {
-    StateKeys structure = (_structure == "" ? getFrameKeys() : _structure);
+    if (not frame_types_.has(_keys))
+        throw std::runtime_error("Problem::getState: unknown key! Asked for " + _keys +
+                                " but installed processors only work with " + frame_types_.getKeys());
+
+    WOLF_WARN_COND(_keys.empty(), "Empty keys provided. Returning empty state.");
+    if (_keys.empty()) return VectorComposite();
 
     VectorComposite odom_state;
 
@@ -686,7 +713,7 @@ VectorComposite Problem::getOdometry(const StateKeys& _structure) const
     }
 
     // check for empty blocks and fill them with the prior, or with zeros in the worst case
-    for (auto key : structure)
+    for (auto key : _keys)
     {
         if (odom_state.count(key) == 0)
         {
@@ -696,7 +723,10 @@ VectorComposite Problem::getOdometry(const StateKeys& _structure) const
                 odom_state.emplace(key, state_last_it->second);
 
             else
+            {
+                WOLF_WARN("Could not find any odometry for key ", key, ". Filling with zero state.");
                 odom_state.emplace(key, stateZero(std::string(1, key)).at(key));
+            }
         }
     }
 
@@ -708,15 +738,8 @@ SizeEigen Problem::getDim() const
     return dim_;
 }
 
-StateKeys Problem::getFrameKeys() const
-{
-    return frame_keys_;
-}
-
 TypeComposite Problem::getFrameTypes(StateKeys _keys) const
 {
-    if (_keys == "") return frame_types_(frame_keys_);
-
     if (not frame_types_.has(_keys))
         throw std::runtime_error("Problem::getFrameTypes: frame_types_ does not have any of the required keys");
 
@@ -726,29 +749,19 @@ TypeComposite Problem::getFrameTypes(StateKeys _keys) const
     return types;
 }
 
-bool Problem::hasFrameKeys(StateKeys _keys) const
-{
-    for (auto input_key : _keys)
-        if (frame_keys_.find(input_key) == std::string::npos) return false;
-
-    return true;
-}
-
-void Problem::addFrameKeys(StateKeys _keys)
-{
-    for (auto input_key : _keys)
-        if (frame_keys_.find(input_key) == std::string::npos) frame_keys_.push_back(input_key);
-}
-
 void Problem::addFrameTypes(const TypeComposite& _types)
 {
     for (auto pair : _types)
-        if (not frame_types_.has(pair.first))  // new key not found in problem structure -> append!
+        if (not frame_types_.has(pair.first))  // new key not found in problem keys -> append!
             frame_types_.emplace(pair.first, pair.second);
         else
         {
             WOLF_DEBUG_COND(frame_types_.at(pair.first) == pair.second,
-                            "Type already in 'frame_types_' doing nothing.");
+                            "Type '",
+                            pair.second,
+                            "' already in 'frame_types_' in key '",
+                            pair.first,
+                            "' doing nothing.");
             if (frame_types_.at(pair.first) != pair.second)
             {
                 WOLF_ERROR("Trying to append type '",
@@ -761,8 +774,6 @@ void Problem::addFrameTypes(const TypeComposite& _types)
                 throw std::runtime_error("Problem::addFrameTypes: Different type already defined in this key.");
             }
         }
-    // add also keys
-    addFrameKeys(_types.getKeys());
 }
 
 void Problem::setTreeManager(TreeManagerBasePtr _gm)
@@ -795,18 +806,6 @@ void Problem::addMotionProvider(MotionProviderPtr _motion_provider_ptr)
 
     // add to map ordered by priority
     motion_provider_map_.emplace(_motion_provider_ptr->getOrder(), _motion_provider_ptr);
-
-    // check consistent types
-    for (auto new_key : _motion_provider_ptr->getStateTypes().getKeys())
-        if (frame_types_.has(new_key) and frame_types_[new_key] != _motion_provider_ptr->getStateTypes().at(new_key))
-        {
-            throw std::runtime_error("Problem::addMotionProvider: inconsistent type for key " +
-                                     std::string(1, new_key) + " previously registered as " + frame_types_[new_key] +
-                                     " and now as " + _motion_provider_ptr->getStateTypes().at(new_key));
-        }
-
-    // Grow TypeComposite storing information about the types of the StateBlocks corresponding to each key
-    addFrameTypes(_motion_provider_ptr->getStateTypes());
 }
 
 void Problem::removeMotionProvider(MotionProviderPtr proc)
@@ -814,16 +813,10 @@ void Problem::removeMotionProvider(MotionProviderPtr proc)
     WOLF_WARN_COND(motion_provider_map_.count(proc->getOrder()) == 0, "Missing processor");
 
     motion_provider_map_.erase(proc->getOrder());
-
-    // rebuild frame structure with remaining motion processors
-    frame_keys_.clear();
-    for (auto pm : motion_provider_map_) addFrameKeys(pm.second->getStateTypes().getKeys());
 }
 
 VectorComposite Problem::stateZero(TypeComposite _types) const
 {
-    if (_types.empty()) _types = frame_types_(frame_keys_);
-
     VectorComposite state;
     for (auto&& type_pair : _types)
     {
@@ -838,8 +831,6 @@ VectorComposite Problem::stateZero(const StateKeys& _keys) const
         throw std::runtime_error("Problem::stateZero any unknown type... asked for " + _keys +
                                  " but only have types for " + frame_types_.getKeys());
 
-    StateKeys keys = (_keys == "" ? getFrameKeys() : _keys);
-
     return stateZero(getFrameTypes(_keys));
 }
 
diff --git a/src/processor/motion_provider.cpp b/src/processor/motion_provider.cpp
index 7b36f391298091a588ccf4157a0a2938f32d05b8..05303de561b39e68f68bd04901bbf9f4448f9710 100644
--- a/src/processor/motion_provider.cpp
+++ b/src/processor/motion_provider.cpp
@@ -16,7 +16,8 @@
 //
 // You should have received a copy of the GNU General Public License
 // along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <core/processor/motion_provider.h>
+#include "core/processor/motion_provider.h"
+#include "core/state_block/factory_state_block.h"
 #include "core/problem/problem.h"
 
 using namespace wolf;
@@ -27,26 +28,38 @@ MotionProvider::MotionProvider(const TypeComposite& _state_types, const YAML::No
       state_provider_order_(_params["state_provider_order"] ? _params["state_provider_order"].as<unsigned int>() : 0)
 {
     checkTypeComposite(_state_types);
-}
 
-void MotionProvider::addToProblem(ProblemPtr _prb_ptr, MotionProviderPtr _motion_ptr)
-{
-    WOLF_DEBUG_COND(not isStateProvider(),
-                    "MotionProvider processor with 'state_provider'=false. Not adding this processor");
-    if (isStateProvider())
-    {
-        _prb_ptr->addMotionProvider(_motion_ptr);
-    }
-    setOdometry(_prb_ptr->stateZero(state_types_));
+    // initialize odometry
+    for (auto&& type_pair : _state_types)
+        odometry_.emplace(type_pair.first, FactoryStateBlockIdentityVector::create(type_pair.second));
 }
 
 void MotionProvider::setOdometry(const VectorComposite& _odom)
 {
     std::lock_guard<std::mutex> lock(mut_odometry_);
-    if (not _odom.has(getStateKeys()))
+    if (not _odom.has(state_types_.getKeys()))
         throw std::runtime_error("MotionProvider::setOdometry(): any key missing in _odom.");
 
-    for (auto key : getStateKeys()) odometry_[key] = _odom.at(key);  // overwrite/insert only keys of the state_types_
+    for (auto key : state_types_.getKeys())
+    {
+        // check vector goodness
+        try
+        {
+            auto sb = FactoryStateBlock::create(state_types_.at(key), _odom.at(key), false);
+        }
+        catch (const std::exception& e)
+        {
+            WOLF_ERROR("Wrong odometry input for key '",
+                       key,
+                       "'. Could not create a stateblock of type '",
+                       state_types_.at(key),
+                       "' with the provided vector. Error: ",
+                       e.what());
+            continue;
+        }
+        // store
+        odometry_[key] = _odom.at(key);  // overwrite only
+    }
 }
 
 wolf::VectorComposite MotionProvider::getOdometry() const
diff --git a/src/processor/processor_base.cpp b/src/processor/processor_base.cpp
index c33dfc2db53adcaa15b03090ffd1fc41ba0527ca..90102584c1449d815c8547b205df712e6fd79b71 100644
--- a/src/processor/processor_base.cpp
+++ b/src/processor/processor_base.cpp
@@ -25,16 +25,18 @@ namespace wolf
 {
 unsigned int ProcessorBase::processor_id_count_ = 0;
 
-ProcessorBase::ProcessorBase(const std::string& _type, unsigned int _dim_compatible, const YAML::Node& _params)
+ProcessorBase::ProcessorBase(const std::string& _type, const TypeComposite& _state_types, const YAML::Node& _params)
     : NodeBase("PROCESSOR", _type, _params["name"].as<std::string>()),
       processor_id_(++processor_id_count_),
       params_(Clone(_params)),
-      dim_compatible_(_dim_compatible),
+      state_types_(_state_types),
       sensor_ptr_(),
       capture_period_mean_(0),
       prev_capture_stamp_(TimeStamp::Invalid())
 {
-    assert(dim_compatible_ == 0 or dim_compatible_ == 2 or dim_compatible_ == 3);
+    // check input state_types_
+    checkTypeComposite(state_types_);
+
     WOLF_DEBUG("Constructed ProcessorBase - ", getType(), " id: ", id(), " name: ", getName());
 }
 
@@ -104,10 +106,16 @@ void ProcessorBase::captureCallback(CaptureBasePtr _capture)
     }
     prev_capture_stamp_ = _capture->getTimeStamp();
 
-    // apply prior in problem if not done (very first capture)
+    // apply first frame options in problem if not done (very first capture)
     if (getProblem() and not getProblem()->isFirstFrameApplied())
+    {
+        WOLF_DEBUG(getType(),
+                   " - ",
+                   getName(),
+                   ": applying first frame options to problem with ts = ",
+                   _capture->getTimeStamp());
         getProblem()->applyFirstFrameOptions(_capture->getTimeStamp());
-
+    }
     // asking if capture should be stored
     if (storeCapture(_capture)) buffer_capture_.emplace(_capture);
 
@@ -159,15 +167,16 @@ void ProcessorBase::setProblem(ProblemPtr _problem)
 {
     if (_problem == nullptr or _problem == this->getProblem()) return;
 
-    if (dim_compatible_ != 0 and dim_compatible_ != _problem->getDim())
-        throw std::runtime_error("Processor works with " + std::to_string(dim_compatible_) + "D but problem is " +
-                                 std::to_string(_problem->getDim()) + "D");
-
+    // set problem
     NodeBase::setProblem(_problem);
 
+    // add types to problem (checks compatibility with other processors' types)
+    _problem->addFrameTypes(state_types_);
+
     // adding motion provider to the motion providers vector
     auto motion_provider_ptr = std::dynamic_pointer_cast<MotionProvider>(shared_from_this());
-    if (motion_provider_ptr) motion_provider_ptr->addToProblem(_problem, motion_provider_ptr);
+    if (motion_provider_ptr and motion_provider_ptr->isStateProvider())
+        _problem->addMotionProvider(motion_provider_ptr);
 }
 
 void ProcessorBase::printHeader(int           _depth,
diff --git a/src/processor/processor_fixed_wing_model.cpp b/src/processor/processor_fixed_wing_model.cpp
index dd41de9c9596fb1524625add1a1644e6a1eaecb7..a70ca60c9fb75ca116c694b48d9db643906e1441 100644
--- a/src/processor/processor_fixed_wing_model.cpp
+++ b/src/processor/processor_fixed_wing_model.cpp
@@ -25,7 +25,7 @@
 namespace wolf
 {
 ProcessorFixedWingModel::ProcessorFixedWingModel(const YAML::Node& _params)
-    : ProcessorBase("ProcessorFixedWingModel", 3, _params),
+    : ProcessorBase("ProcessorFixedWingModel", {{'V', "StateVector3d"}}, _params),
       velocity_local_(_params["velocity_local"].as<Eigen::Vector3d>().normalized()),
       angle_stdev_(_params["angle_stdev"].as<double>()),
       min_vel_norm_(_params["min_vel_norm"].as<double>())
diff --git a/src/processor/processor_landmark_external.cpp b/src/processor/processor_landmark_external.cpp
index ca15feb4327bb547ac540059f108662cc87dc9c1..e1b164265a65198e986b7aeb868eaf5bf32dbe06 100644
--- a/src/processor/processor_landmark_external.cpp
+++ b/src/processor/processor_landmark_external.cpp
@@ -37,7 +37,6 @@ void ProcessorLandmarkExternal::preProcess()
 {
     new_features_incoming_.clear();
 
-    auto dim           = getProblem()->getDim();
     auto cap_landmarks = std::dynamic_pointer_cast<CaptureLandmarksExternal>(incoming_ptr_);
     if (not cap_landmarks)
         throw std::runtime_error(
@@ -58,16 +57,16 @@ void ProcessorLandmarkExternal::preProcess()
         MatrixXd cov;
         if (not use_orientation_)
         {
-            assert(detection.measure.size() >= dim);
-            assert(detection.covariance.rows() >= dim and detection.covariance.rows() == detection.covariance.cols());
+            assert(detection.measure.size() >= dim_);
+            assert(detection.covariance.rows() >= dim_ and detection.covariance.rows() == detection.covariance.cols());
 
-            meas = detection.measure.head(dim);
-            cov  = detection.covariance.topLeftCorner(dim, dim);
+            meas = detection.measure.head(dim_);
+            cov  = detection.covariance.topLeftCorner(dim_, dim_);
         }
         else
         {
-            assert(detection.measure.size() == (dim == 2 ? 3 : 7));
-            assert(detection.covariance.rows() == (dim == 2 ? 3 : 6) and
+            assert(detection.measure.size() == (dim_ == 2 ? 3 : 7));
+            assert(detection.covariance.rows() == (dim_ == 2 ? 3 : 6) and
                    detection.covariance.rows() == detection.covariance.cols());
 
             meas = detection.measure;
@@ -341,7 +340,7 @@ double ProcessorLandmarkExternal::detectionDistance(FeatureBasePtr         _ftr1
     }
     else
     {
-        if (getProblem()->getDim() == 2)
+        if (dim_ == 2)
         {
             VectorComposite pose_s1 = SE2::compose(_pose1, _pose_sen);
             VectorComposite pose_s2 = SE2::compose(_pose2, _pose_sen);
@@ -378,7 +377,7 @@ double ProcessorLandmarkExternal::detectionDistance(FeatureBasePtr         _ftr,
             "ProcessorLandmarkExternal::detectionDistance: Missing any required geometric information");
     }
 
-    if (getProblem()->getDim() == 2)
+    if (dim_ == 2)
     {
         auto            pose_s = SE2::compose(_pose_frm, _pose_sen);
         Eigen::Vector2d p      = pose_s.at('P') + Rotation2Dd(pose_s.at('O')(0)) * _ftr->getMeasurement().head<2>();
@@ -577,7 +576,7 @@ FactorBasePtr ProcessorLandmarkExternal::emplaceFactor(FeatureBasePtr _feature,
     assert(_landmark);
 
     // 2D - Relative Position
-    if (getProblem()->getDim() == 2 and (_feature->getMeasurement().size() == 2 or not use_orientation_))
+    if (dim_ == 2 and (_feature->getMeasurement().size() == 2 or not use_orientation_))
     {
         return FactorBase::emplace<FactorRelativePosition2dWithExtrinsics>(
             _feature,
@@ -590,7 +589,7 @@ FactorBasePtr ProcessorLandmarkExternal::emplaceFactor(FeatureBasePtr _feature,
             applyLossFunction());
     }
     // 2D - Relative Pose
-    else if (getProblem()->getDim() == 2 and _feature->getMeasurement().size() == 3 and use_orientation_)
+    else if (dim_ == 2 and _feature->getMeasurement().size() == 3 and use_orientation_)
     {
         return FactorBase::emplace<FactorRelativePose2dWithExtrinsics>(
             _feature,
@@ -604,7 +603,7 @@ FactorBasePtr ProcessorLandmarkExternal::emplaceFactor(FeatureBasePtr _feature,
             TOP_LMK);
     }
     // 3D - Relative Position
-    else if (getProblem()->getDim() == 3 and (_feature->getMeasurement().size() == 3 or not use_orientation_))
+    else if (dim_ == 3 and (_feature->getMeasurement().size() == 3 or not use_orientation_))
     {
         return FactorBase::emplace<FactorRelativePosition3dWithExtrinsics>(
             _feature,
@@ -617,7 +616,7 @@ FactorBasePtr ProcessorLandmarkExternal::emplaceFactor(FeatureBasePtr _feature,
             applyLossFunction());
     }
     // 3D - Relative Pose
-    else if (getProblem()->getDim() == 3 and _feature->getMeasurement().size() == 7 and use_orientation_)
+    else if (dim_ == 3 and _feature->getMeasurement().size() == 7 and use_orientation_)
     {
         return FactorBase::emplace<FactorRelativePose3dWithExtrinsics>(
             _feature,
@@ -656,7 +655,7 @@ LandmarkBasePtr ProcessorLandmarkExternal::emplaceLandmark(FeatureLandmarkExtern
     LandmarkBasePtr lmk;
 
     // 2D - Relative Position
-    if (getProblem()->getDim() == 2 and (_feature->getMeasurement().size() == 2 or not use_orientation_))
+    if (dim_ == 2 and (_feature->getMeasurement().size() == 2 or not use_orientation_))
     {
         Vector2d frm_p = _feature->getCapture()->getFrame()->getP()->getState();
         Vector2d sen_p = _feature->getCapture()->getSensorP()->getState();
@@ -669,7 +668,7 @@ LandmarkBasePtr ProcessorLandmarkExternal::emplaceLandmark(FeatureLandmarkExtern
             getProblem()->getMap(), VectorComposite({{'P', lmk_p}}), PriorComposite{});
     }
     // 2D - Relative Pose
-    else if (getProblem()->getDim() == 2 and _feature->getMeasurement().size() == 3 and use_orientation_)
+    else if (dim_ == 2 and _feature->getMeasurement().size() == 3 and use_orientation_)
     {
         Vector2d frm_p = _feature->getCapture()->getFrame()->getP()->getState();
         Vector2d sen_p = _feature->getCapture()->getSensorP()->getState();
@@ -684,7 +683,7 @@ LandmarkBasePtr ProcessorLandmarkExternal::emplaceLandmark(FeatureLandmarkExtern
             getProblem()->getMap(), VectorComposite({{'P', lmk_p}, {'O', Vector1d(lmk_o)}}), PriorComposite{});
     }
     // 3D - Relative Position
-    else if (getProblem()->getDim() == 3 and (_feature->getMeasurement().size() == 3 or not use_orientation_))
+    else if (dim_ == 3 and (_feature->getMeasurement().size() == 3 or not use_orientation_))
     {
         Vector3d    frm_p = _feature->getCapture()->getFrame()->getP()->getState();
         Vector3d    sen_p = _feature->getCapture()->getSensorP()->getState();
@@ -697,7 +696,7 @@ LandmarkBasePtr ProcessorLandmarkExternal::emplaceLandmark(FeatureLandmarkExtern
             getProblem()->getMap(), VectorComposite({{'P', lmk_p}}), PriorComposite{});
     }
     // 3D - Relative Pose
-    else if (getProblem()->getDim() == 3 and _feature->getMeasurement().size() == 7 and use_orientation_)
+    else if (dim_ == 3 and _feature->getMeasurement().size() == 7 and use_orientation_)
     {
         Vector3d    frm_p = _feature->getCapture()->getFrame()->getP()->getState();
         Vector3d    sen_p = _feature->getCapture()->getSensorP()->getState();
@@ -732,13 +731,13 @@ void ProcessorLandmarkExternal::modifyLandmark(LandmarkBasePtr _landmark, Featur
     if (not _landmark) throw std::runtime_error("ProcessorLandmarkExternal::modifyLandmark: null landmark");
 
     // 2D - Relative Position
-    if (getProblem()->getDim() == 2 and (_feature->getMeasurement().size() == 2 or not use_orientation_))
+    if (dim_ == 2 and (_feature->getMeasurement().size() == 2 or not use_orientation_))
     {
         // nothing to do (we assume P already in landmark)
         return;
     }
     // 2D - Relative Pose
-    else if (getProblem()->getDim() == 2 and _feature->getMeasurement().size() == 3 and use_orientation_)
+    else if (dim_ == 2 and _feature->getMeasurement().size() == 3 and use_orientation_)
     {
         // no orientation, add it
         if (not _landmark->getO())
@@ -752,13 +751,13 @@ void ProcessorLandmarkExternal::modifyLandmark(LandmarkBasePtr _landmark, Featur
         }
     }
     // 3D - Relative Position
-    else if (getProblem()->getDim() == 3 and (_feature->getMeasurement().size() == 3 or not use_orientation_))
+    else if (dim_ == 3 and (_feature->getMeasurement().size() == 3 or not use_orientation_))
     {
         // nothing to do (we assume P already in landmark)
         return;
     }
     // 3D - Relative Pose
-    else if (getProblem()->getDim() == 3 and _feature->getMeasurement().size() == 7 and use_orientation_)
+    else if (dim_ == 3 and _feature->getMeasurement().size() == 7 and use_orientation_)
     {
         // no orientation, add it
         if (not _landmark->getO())
diff --git a/src/processor/processor_loop_closure.cpp b/src/processor/processor_loop_closure.cpp
index 957a080b36e86b1d4dbeca6a64bdac34d7e71d9c..cad2e26f876b1649cb0271bc92d203d91579025f 100644
--- a/src/processor/processor_loop_closure.cpp
+++ b/src/processor/processor_loop_closure.cpp
@@ -20,8 +20,8 @@
 
 namespace wolf
 {
-ProcessorLoopClosure::ProcessorLoopClosure(const std::string& _type, int _dim, const YAML::Node& _params)
-    : ProcessorBase(_type, _dim, _params)
+ProcessorLoopClosure::ProcessorLoopClosure(const std::string& _type, const TypeComposite& _state_types, const YAML::Node& _params)
+    : ProcessorBase(_type, _state_types, _params)
 {
     //
 }
diff --git a/src/processor/processor_motion.cpp b/src/processor/processor_motion.cpp
index 56aea70f8f2fc2492970ba410498b16d98081910..abad4de30d6f6eb0b01839040e69216825dcfaf6 100644
--- a/src/processor/processor_motion.cpp
+++ b/src/processor/processor_motion.cpp
@@ -23,14 +23,13 @@ namespace wolf
 {
 ProcessorMotion::ProcessorMotion(const std::string& _type,
                                  TypeComposite      _state_types,
-                                 int                _dim,
                                  SizeEigen          _state_size,
                                  SizeEigen          _delta_size,
                                  SizeEigen          _delta_cov_size,
                                  SizeEigen          _data_size,
                                  SizeEigen          _calib_size,
                                  const YAML::Node&  _params)
-    : ProcessorBase(_type, _dim, _params),
+    : ProcessorBase(_type, _state_types, _params),
       MotionProvider(_state_types, _params),
       processing_step_(RUNNING_WITHOUT_KF),
       bootstrapping_(false),
@@ -300,7 +299,8 @@ void ProcessorMotion::processCapture(CaptureBasePtr _incoming_ptr)
                 if (not keyframe_from_callback->has(pair_key_vec.first))
                     keyframe_from_callback->emplaceStateBlock(
                         pair_key_vec.first, getStateTypes().at(pair_key_vec.first), pair_key_vec.second, false);
-            keyframe_from_callback->setState(proc_state);
+                else
+                    keyframe_from_callback->getStateBlock(pair_key_vec.first)->setState(pair_key_vec.second);
 
             // Find the capture acting as the buffer's origin
             auto capture_origin = capture_existing->getOriginCapture();
@@ -393,7 +393,8 @@ void ProcessorMotion::processCapture(CaptureBasePtr _incoming_ptr)
                 if (not keyframe_from_callback->has(pair_key_vec.first))
                     keyframe_from_callback->emplaceStateBlock(
                         pair_key_vec.first, getStateTypes().at(pair_key_vec.first), pair_key_vec.second, false);
-            keyframe_from_callback->setState(proc_state);
+                else
+                    keyframe_from_callback->getStateBlock(pair_key_vec.first)->setState(pair_key_vec.second);
 
             auto& capture_existing = last_ptr_;
 
@@ -441,7 +442,8 @@ void ProcessorMotion::processCapture(CaptureBasePtr _incoming_ptr)
         if (not last_ptr_->getFrame()->has(pair_key_vec.first))
             last_ptr_->getFrame()->emplaceStateBlock(
                 pair_key_vec.first, getStateTypes().at(pair_key_vec.first), pair_key_vec.second, false);
-    last_ptr_->getFrame()->setState(state_propa);
+        else
+            last_ptr_->getFrame()->getStateBlock(pair_key_vec.first)->setState(pair_key_vec.second);
 
     if (permittedKeyFrame() && voteForKeyFrame())
     {
@@ -765,14 +767,8 @@ void ProcessorMotion::setOrigin(FrameBasePtr _origin_frame)
            "ProcessorMotion::setOrigin: origin frame must be in the trajectory.");
 
     // add (zero) states to origin_frame if missing
-    if (not _origin_frame->has(getStateKeys()))
-        for (auto key : getStateKeys())
-            if (not _origin_frame->has(key))
-                _origin_frame->emplaceStateBlock(
-                    key,
-                    getStateTypes().at(key),
-                    getProblem()->stateZero(std::string(1, key)).vector(std::string(1, key)),
-                    false);
+    for (auto key : getStateKeys())
+        if (not _origin_frame->has(key)) _origin_frame->emplaceStateBlockZero(key, getStateTypes().at(key), false);
 
     TimeStamp origin_ts = _origin_frame->getTimeStamp();
 
diff --git a/src/processor/processor_odom_2d.cpp b/src/processor/processor_odom_2d.cpp
index d8414746e1a5fb8224373428117837d30313bace..4fd2531e7ab5f6c9612dcf4e98f64e549ada753a 100644
--- a/src/processor/processor_odom_2d.cpp
+++ b/src/processor/processor_odom_2d.cpp
@@ -25,7 +25,7 @@
 namespace wolf
 {
 ProcessorOdom2d::ProcessorOdom2d(const YAML::Node& _params)
-    : ProcessorMotion("ProcessorOdom2d", {{'P', "StatePoint2d"}, {'O', "StateAngle"}}, 2, 3, 3, 3, 2, 0, _params)
+    : ProcessorMotion("ProcessorOdom2d", {{'P', "StatePoint2d"}, {'O', "StateAngle"}}, 3, 3, 3, 2, 0, _params)
 {
     //
 }
diff --git a/src/processor/processor_odom_3d.cpp b/src/processor/processor_odom_3d.cpp
index ed4d97aeb4afbf51d83dfac5a3961644447d9517..fef1b7819564327961e51c92bc30eafd97c32a35 100644
--- a/src/processor/processor_odom_3d.cpp
+++ b/src/processor/processor_odom_3d.cpp
@@ -23,7 +23,7 @@
 namespace wolf
 {
 ProcessorOdom3d::ProcessorOdom3d(const YAML::Node& _params)
-    : ProcessorMotion("ProcessorOdom3d", {{'P', "StatePoint3d"}, {'O', "StateQuaternion"}}, 3, 7, 7, 6, 6, 0, _params)
+    : ProcessorMotion("ProcessorOdom3d", {{'P', "StatePoint3d"}, {'O', "StateQuaternion"}}, 7, 7, 6, 6, 0, _params)
 {
     //
 }
diff --git a/src/processor/processor_tracker.cpp b/src/processor/processor_tracker.cpp
index 0f58985a31a3d4c01c7eeb08c023fc57e4541d0b..0b8c2f7a35051c7b32dd88b19dd980e9224c091e 100644
--- a/src/processor/processor_tracker.cpp
+++ b/src/processor/processor_tracker.cpp
@@ -24,17 +24,14 @@
 
 namespace wolf
 {
-ProcessorTracker::ProcessorTracker(const std::string& _type,
-                                   const StateKeys&   _state_keys,
-                                   int                _dim,
-                                   const YAML::Node&  _params)
-    : ProcessorBase(_type, _dim, _params),
+ProcessorTracker::ProcessorTracker(const std::string&   _type,
+                                   const TypeComposite& _state_types,
+                                   const YAML::Node&    _params)
+    : ProcessorBase(_type, _state_types, _params),
       processing_step_(FIRST_TIME_WITHOUT_KEYFRAME),
       origin_ptr_(nullptr),
       last_ptr_(nullptr),
       incoming_ptr_(nullptr),
-      last_frame_ptr_(nullptr),
-      state_keys_(_state_keys),
       min_features_for_keyframe_(_params["keyframe_vote"]["min_features_for_keyframe"].as<unsigned int>()),
       max_new_features_(_params["max_new_features"].as<int>())
 {
@@ -94,6 +91,9 @@ void ProcessorTracker::processCapture(CaptureBasePtr _incoming_ptr)
                 incoming_ptr_->link(keyframe_from_callback);
             }
 
+            // Emplace missing states to KF
+            getProblem()->emplaceStatesToFrame(keyframe_from_callback, getStateKeys());
+
             // TrackerFeature:  We only process new features in Last, here last = nullptr, so we do not have anything
             // to do. TrackerLandmark: If we have been given a map, all landmarks in the map are known. Process them.
             processKnownProfiling();
@@ -101,11 +101,11 @@ void ProcessorTracker::processCapture(CaptureBasePtr _incoming_ptr)
             // Reset this
             last_ptr_ = incoming_ptr_;  // Before calling resetDerived() since it will assume KF in last
             resetDerived();
+
             // Update pointers
-            origin_ptr_     = incoming_ptr_;
-            last_ptr_       = incoming_ptr_;
-            last_frame_ptr_ = keyframe_from_callback;
-            incoming_ptr_   = nullptr;
+            origin_ptr_   = incoming_ptr_;
+            last_ptr_     = incoming_ptr_;
+            incoming_ptr_ = nullptr;
 
             break;
         }
@@ -121,7 +121,7 @@ void ProcessorTracker::processCapture(CaptureBasePtr _incoming_ptr)
             WOLF_DEBUG("PT ", getName(), " Incoming capture has not been processed by another processor!")
 
             // make a new KF at incoming
-            FrameBasePtr keyframe = getProblem()->emplaceFrame(incoming_ptr_->getTimeStamp(), state_keys_);
+            FrameBasePtr keyframe = getProblem()->emplaceFrame(incoming_ptr_->getTimeStamp(), getStateKeys());
 
             // Append incoming to KF
             incoming_ptr_->link(keyframe);
@@ -137,11 +137,11 @@ void ProcessorTracker::processCapture(CaptureBasePtr _incoming_ptr)
             // Reset this
             last_ptr_ = incoming_ptr_;  // Before calling resetDerived() since it will assume KF in last
             resetDerived();
+
             // Update pointers
-            origin_ptr_     = incoming_ptr_;
-            last_ptr_       = incoming_ptr_;
-            last_frame_ptr_ = keyframe;
-            incoming_ptr_   = nullptr;
+            origin_ptr_   = incoming_ptr_;
+            last_ptr_     = incoming_ptr_;
+            incoming_ptr_ = nullptr;
 
             break;
         }
@@ -169,11 +169,6 @@ void ProcessorTracker::processCapture(CaptureBasePtr _incoming_ptr)
         case SECOND_TIME_WITHOUT_KEYFRAME: {
             WOLF_DEBUG("PT ", getName(), " SECOND_TIME_WITHOUT_KEYFRAME");
 
-            // Make a NON KEY Frame to hold incoming capture
-            FrameBasePtr frame = std::make_shared<FrameBase>(incoming_ptr_->getTimeStamp(),
-                                                             getProblem()->getFrameTypes(state_keys_),
-                                                             getProblem()->getState(incoming_ptr_->getTimeStamp()));
-
             // Process known information
             processKnownProfiling();
 
@@ -185,11 +180,11 @@ void ProcessorTracker::processCapture(CaptureBasePtr _incoming_ptr)
 
             // Reset this
             resetDerived();
+
             // Update pointers
-            origin_ptr_     = last_ptr_;
-            last_ptr_       = incoming_ptr_;
-            last_frame_ptr_ = frame;
-            incoming_ptr_   = nullptr;
+            origin_ptr_   = last_ptr_;
+            last_ptr_     = incoming_ptr_;
+            incoming_ptr_ = nullptr;
 
             break;
         }
@@ -204,6 +199,10 @@ void ProcessorTracker::processCapture(CaptureBasePtr _incoming_ptr)
                        " callback unpacked with ts= ",
                        keyframe_from_callback->getTimeStamp());
 
+            // Emplace missing states to KF
+            getProblem()->emplaceStatesToFrame(keyframe_from_callback, getStateKeys());
+
+            // Process known information
             processKnownProfiling();
 
             // chack if the received KF has a capture of this sensor, and if it matches with last_ptr
@@ -225,10 +224,6 @@ void ProcessorTracker::processCapture(CaptureBasePtr _incoming_ptr)
                 last_ptr_->link(keyframe_from_callback);
             }
 
-            // Create new NON KEY frame for incoming
-            FrameBasePtr frame = std::make_shared<FrameBase>(
-                incoming_ptr_->getTimeStamp(), getProblem()->getFrameTypes(state_keys_), getProblem()->getState());
-
             // Detect new Features, initialize Landmarks, ...
             processNewProfiling(max_new_features_);
 
@@ -237,11 +232,11 @@ void ProcessorTracker::processCapture(CaptureBasePtr _incoming_ptr)
 
             // Reset this
             resetDerived();
+
             // Update pointers
-            origin_ptr_     = last_ptr_;
-            last_ptr_       = incoming_ptr_;
-            last_frame_ptr_ = frame;
-            incoming_ptr_   = nullptr;
+            origin_ptr_   = last_ptr_;
+            last_ptr_     = incoming_ptr_;
+            incoming_ptr_ = nullptr;
 
             break;
         }
@@ -256,47 +251,33 @@ void ProcessorTracker::processCapture(CaptureBasePtr _incoming_ptr)
                 processNewProfiling(max_new_features_);
 
                 // We create a KF
-                // set KF on last
-                last_frame_ptr_->setState(getProblem()->getState(last_ptr_->getTimeStamp()));
-                last_frame_ptr_->link(getProblem());
-                last_ptr_->link(last_frame_ptr_);
+                FrameBasePtr keyframe = getProblem()->emplaceFrame(last_ptr_->getTimeStamp(), getStateKeys());
+                last_ptr_->link(keyframe);
 
                 // Establish factors
                 establishFactorsProfiling();
 
                 // Call the new keyframe callback in order to let the other processors to join
-                getProblem()->keyFrameCallback(last_frame_ptr_, shared_from_this());
-
-                // make NON KEY frame; append incoming to new frame
-                FrameBasePtr frame =
-                    std::make_shared<FrameBase>(incoming_ptr_->getTimeStamp(),
-                                                getProblem()->getFrameTypes(state_keys_),
-                                                getProblem()->getState(incoming_ptr_->getTimeStamp()));
+                getProblem()->keyFrameCallback(keyframe, shared_from_this());
 
                 // Reset this
                 resetDerived();
+
                 // Update pointers
-                origin_ptr_     = last_ptr_;
-                last_ptr_       = incoming_ptr_;
-                last_frame_ptr_ = frame;
-                incoming_ptr_   = nullptr;
+                origin_ptr_   = last_ptr_;
+                last_ptr_     = incoming_ptr_;
+                incoming_ptr_ = nullptr;
             }
             else
             {
                 // We do not create a KF
 
-                // Replace last frame for a new NON KEY frame in incoming
-                FrameBasePtr frame =
-                    std::make_shared<FrameBase>(incoming_ptr_->getTimeStamp(),
-                                                getProblem()->getFrameTypes(state_keys_),
-                                                getProblem()->getState(incoming_ptr_->getTimeStamp()));
-
                 // Advance this
                 advanceDerived();
+
                 // Update pointers
-                last_ptr_       = incoming_ptr_;
-                last_frame_ptr_ = frame;
-                incoming_ptr_   = nullptr;
+                last_ptr_     = incoming_ptr_;
+                incoming_ptr_ = nullptr;
             }
             break;
         }
@@ -330,7 +311,7 @@ void ProcessorTracker::computeProcessingStep()
 
             if (buffer_frame_.select(incoming_ptr_->getTimeStamp(), getTimeTolerance()))
                 processing_step_ = FIRST_TIME_WITH_KEYFRAME;
-            else  // ! last && ! pack(incoming)
+            else
                 processing_step_ = FIRST_TIME_WITHOUT_KEYFRAME;
             break;
 
@@ -346,19 +327,7 @@ void ProcessorTracker::computeProcessingStep()
         default:
 
             if (buffer_frame_.select(last_ptr_->getTimeStamp(), getTimeTolerance()))
-            {
-                if (last_frame_ptr_->getProblem())
-                {
-                    WOLF_WARN("||*||");
-                    WOLF_INFO(" ... It seems you missed something!");
-                    WOLF_INFO("Received KF and last's Frame have matching time stamps (i.e. below time tolerances)");
-                    WOLF_INFO("Check the following for correctness:");
-                    WOLF_INFO("  - You have all processors installed before starting receiving any data");
-                    WOLF_INFO("  - You have configured all your processors with compatible time tolerances");
-                    WOLF_ERROR("Received KF and last's KF have matching time stamps (i.e. below time tolerances).");
-                }
                 processing_step_ = RUNNING_WITH_KEYFRAME;
-            }
             else
                 processing_step_ = RUNNING_WITHOUT_KEYFRAME;
             break;
@@ -379,8 +348,7 @@ void ProcessorTracker::printHeader(int           _depth,
                 << " Frm" << getOrigin()->getFrame()->id() << std::endl;
     if (getLast())
         _stream << _tabs << "  "
-                << "l: Cap" << getLast()->id() << " - "
-                << " Frm" << getLastFrame()->id() << std::endl;
+                << "l: Cap" << getLast()->id() << std::endl;
     if (getIncoming())
         _stream << _tabs << "  "
                 << "i: Cap" << getIncoming()->id() << std::endl;
diff --git a/src/processor/processor_tracker_feature.cpp b/src/processor/processor_tracker_feature.cpp
index 7c6d618bed2429b2e6c42b62facb3196973a36e4..3d9380b0ca1131b1accf1a2277e7bfe4d5d9926a 100644
--- a/src/processor/processor_tracker_feature.cpp
+++ b/src/processor/processor_tracker_feature.cpp
@@ -20,11 +20,10 @@
 
 namespace wolf
 {
-ProcessorTrackerFeature::ProcessorTrackerFeature(const std::string& _type,
-                                                 const StateKeys&   _structure,
-                                                 int                _dim,
-                                                 const YAML::Node&  _params)
-    : ProcessorTracker(_type, _structure, _dim, _params)
+ProcessorTrackerFeature::ProcessorTrackerFeature(const std::string&   _type,
+                                                 const TypeComposite& _frame_types,
+                                                 const YAML::Node&    _params)
+    : ProcessorTracker(_type, _frame_types, _params)
 {
 }
 
diff --git a/src/processor/processor_tracker_landmark.cpp b/src/processor/processor_tracker_landmark.cpp
index 0a2307ea19d9a05db10510c2fe0fc0256be0f2c4..71ad36f151c65d124697183d155e28e840c39711 100644
--- a/src/processor/processor_tracker_landmark.cpp
+++ b/src/processor/processor_tracker_landmark.cpp
@@ -23,10 +23,10 @@
 
 namespace wolf
 {
-ProcessorTrackerLandmark::ProcessorTrackerLandmark(const std::string& _type,
-                                                   const StateKeys&   _structure,
-                                                   const YAML::Node&  _params)
-    : ProcessorTracker(_type, _structure, 0, _params)
+ProcessorTrackerLandmark::ProcessorTrackerLandmark(const std::string&   _type,
+                                                   const TypeComposite& _state_types,
+                                                   const YAML::Node&    _params)
+    : ProcessorTracker(_type, _state_types, _params)
 {
     //
 }
diff --git a/test/dummy/processor_loop_closure_dummy.cpp b/test/dummy/processor_loop_closure_dummy.cpp
index f7709d8ee39488446c4b3251aed18c41270e1f3a..d45e900c4e762df6d9a827a50598050f48e4e626 100644
--- a/test/dummy/processor_loop_closure_dummy.cpp
+++ b/test/dummy/processor_loop_closure_dummy.cpp
@@ -23,7 +23,7 @@ using namespace Eigen;
 namespace wolf
 {
 ProcessorLoopClosureDummy::ProcessorLoopClosureDummy(const YAML::Node& _params)
-    : ProcessorLoopClosure("ProcessorLoopClosureDummy", 2, _params)
+    : ProcessorLoopClosure("ProcessorLoopClosureDummy", {{'P', "StatePoint2d"}, {'O', "StateAngle"}}, _params)
 {
 }
 bool ProcessorLoopClosureDummy::voteFindLoopClosures(CaptureBasePtr cap)
diff --git a/test/dummy/processor_motion_provider_dummy.cpp b/test/dummy/processor_motion_provider_dummy.cpp
index c5219fde3102aba924f21a5d417b8a405df5f50e..ee31343895b469eb49607a5d5da4bd4d0ee941e9 100644
--- a/test/dummy/processor_motion_provider_dummy.cpp
+++ b/test/dummy/processor_motion_provider_dummy.cpp
@@ -21,7 +21,7 @@
 namespace wolf
 {
 ProcessorMotionProviderDummy::ProcessorMotionProviderDummy(const YAML::Node& _params)
-    : ProcessorBase("ProcessorMotionProviderDummy", 2, _params),
+    : ProcessorBase("ProcessorMotionProviderDummy", {{'P', "StatePoint2d"}, {'O', "StateAngle"}}, _params),
       MotionProvider({{'P', "StatePoint2d"}, {'O', "StateAngle"}}, _params)
 {
 }
@@ -55,12 +55,12 @@ TimeStamp ProcessorMotionProviderDummy::getTimeStamp() const
     return TimeStamp(0);
 };
 
-VectorComposite ProcessorMotionProviderDummy::getState(StateKeys _structure) const
+VectorComposite ProcessorMotionProviderDummy::getState(StateKeys _keys) const
 {
     return getOdometry();
 };
 
-VectorComposite ProcessorMotionProviderDummy::getState(const TimeStamp& _ts, StateKeys _structure) const
+VectorComposite ProcessorMotionProviderDummy::getState(const TimeStamp& _ts, StateKeys _keys) const
 {
     return getOdometry();
 };
diff --git a/test/dummy/processor_motion_provider_dummy.h b/test/dummy/processor_motion_provider_dummy.h
index 35955e32d5819a3b06a25a56a24005a4104f0acc..a9a1e70a6e2c224b11864b6251c6f3ab0a73c17c 100644
--- a/test/dummy/processor_motion_provider_dummy.h
+++ b/test/dummy/processor_motion_provider_dummy.h
@@ -45,9 +45,9 @@ class ProcessorMotionProviderDummy : public ProcessorBase, public MotionProvider
     bool      voteForKeyFrame() const override;
     TimeStamp getTimeStamp() const override;
 
-    VectorComposite getState(StateKeys _structure = "") const override;
+    VectorComposite getState(StateKeys _keys = "") const override;
 
-    VectorComposite getState(const TimeStamp& _ts, StateKeys _structure = "") const override;
+    VectorComposite getState(const TimeStamp& _ts, StateKeys _keys = "") const override;
 };
 
 } /* namespace wolf */
diff --git a/test/dummy/processor_motion_provider_dummy_pov.cpp b/test/dummy/processor_motion_provider_dummy_pov.cpp
index 402b5163dce89b04d826267b73c80d15b007ddba..4cb0850a3c9f48cebf4be207e7a79ffbe1b16adf 100644
--- a/test/dummy/processor_motion_provider_dummy_pov.cpp
+++ b/test/dummy/processor_motion_provider_dummy_pov.cpp
@@ -21,7 +21,7 @@
 namespace wolf
 {
 ProcessorMotionProviderDummyPOV::ProcessorMotionProviderDummyPOV(const YAML::Node& _params)
-    : ProcessorBase("ProcessorMotionProviderDummyPOV", 2, _params),
+    : ProcessorBase("ProcessorMotionProviderDummyPOV", {{'P', "StatePoint2d"}, {'O', "StateAngle"}, {'V', "StateVector2d"}}, _params),
       MotionProvider({{'P', "StatePoint2d"}, {'O', "StateAngle"}, {'V', "StateVector2d"}}, _params)
 {
 }
@@ -55,12 +55,12 @@ TimeStamp ProcessorMotionProviderDummyPOV::getTimeStamp() const
     return TimeStamp(0);
 };
 
-VectorComposite ProcessorMotionProviderDummyPOV::getState(StateKeys _structure) const
+VectorComposite ProcessorMotionProviderDummyPOV::getState(StateKeys _keys) const
 {
     return getOdometry();
 };
 
-VectorComposite ProcessorMotionProviderDummyPOV::getState(const TimeStamp& _ts, StateKeys _structure) const
+VectorComposite ProcessorMotionProviderDummyPOV::getState(const TimeStamp& _ts, StateKeys _keys) const
 {
     return getOdometry();
 };
diff --git a/test/dummy/processor_motion_provider_dummy_pov.h b/test/dummy/processor_motion_provider_dummy_pov.h
index 948f8528fddcf6b2b5e8c009698428205968e06b..b76e4699e972a6d771c921240ed956ea520e2891 100644
--- a/test/dummy/processor_motion_provider_dummy_pov.h
+++ b/test/dummy/processor_motion_provider_dummy_pov.h
@@ -45,9 +45,9 @@ class ProcessorMotionProviderDummyPOV : public ProcessorBase, public MotionProvi
     bool      voteForKeyFrame() const override;
     TimeStamp getTimeStamp() const override;
 
-    VectorComposite getState(StateKeys _structure = "") const override;
+    VectorComposite getState(StateKeys _keys = "") const override;
 
-    VectorComposite getState(const TimeStamp& _ts, StateKeys _structure = "") const override;
+    VectorComposite getState(const TimeStamp& _ts, StateKeys _keys = "") const override;
 };
 
 } /* namespace wolf */
diff --git a/test/dummy/processor_tracker_feature_dummy.h b/test/dummy/processor_tracker_feature_dummy.h
index e230ff1247d23b6420b75a524c4d246f795e50c8..8a1c6e72cb733460655c31ee9f1705024d79c14a 100644
--- a/test/dummy/processor_tracker_feature_dummy.h
+++ b/test/dummy/processor_tracker_feature_dummy.h
@@ -166,7 +166,7 @@ class ProcessorTrackerFeatureDummy : public ProcessorTrackerFeature
 };
 
 inline ProcessorTrackerFeatureDummy::ProcessorTrackerFeatureDummy(const YAML::Node& _params)
-    : ProcessorTrackerFeature("ProcessorTrackerFeatureDummy", "PO", 0, _params),
+    : ProcessorTrackerFeature("ProcessorTrackerFeatureDummy", {{'P', "StatePoint2d"}, {'O', "StateAngle"}}, _params),
       n_tracks_lost_(_params["n_tracks_lost"].as<unsigned int>())
 {
     //
diff --git a/test/dummy/processor_tracker_landmark_dummy.cpp b/test/dummy/processor_tracker_landmark_dummy.cpp
index 7d78446a9ab48b6d755104e8ba2f560f509e94fc..56fde47bc37952d7a87bd6216ac95ddee2dfd8ef 100644
--- a/test/dummy/processor_tracker_landmark_dummy.cpp
+++ b/test/dummy/processor_tracker_landmark_dummy.cpp
@@ -25,7 +25,7 @@
 namespace wolf
 {
 ProcessorTrackerLandmarkDummy::ProcessorTrackerLandmarkDummy(const YAML::Node& _params)
-    : ProcessorTrackerLandmark("ProcessorTrackerLandmarkDummy", "PO", _params),
+    : ProcessorTrackerLandmark("ProcessorTrackerLandmarkDummy", {{'P', "StatePoint2d"}, {'O', "StateAngle"}}, _params),
       n_landmarks_lost_(_params["n_landmarks_lost"].as<unsigned int>())
 {
     //
diff --git a/test/gtest_capture_base.cpp b/test/gtest_capture_base.cpp
index 9b24898d82ede6476a536ccac244011fde9c99fd..9fc1ae902ebb664fea928bf0e088376f71167251 100644
--- a/test/gtest_capture_base.cpp
+++ b/test/gtest_capture_base.cpp
@@ -124,8 +124,8 @@ TEST(CaptureBase, emplaceDriftFactor)
 
     auto sensor = problem->installSensor(wolf_dir + "/test/yaml/sensor_diff_drive_dynamic.yaml", {wolf_dir});
 
-    auto F0 = problem->emplaceFrame(0.0);
-    auto F1 = problem->emplaceFrame(1.0);
+    auto F0 = problem->emplaceFrame(0.0, "PO");
+    auto F1 = problem->emplaceFrame(1.0, "PO");
 
     CaptureBasePtr C0 = CaptureBase::emplace<CaptureBase>(
         F0,
@@ -204,7 +204,7 @@ TEST(CaptureBase, move_from_F_to_KF)
 {
     ProblemPtr problem = Problem::create(2);
 
-    auto KF = problem->emplaceFrame(0.0);  // dummy F object
+    auto KF = problem->emplaceFrame(0.0, "");  // dummy F object
 
     auto KC = CaptureBase::emplace<CaptureBase>(KF, "Dummy", 0.0);
 
@@ -244,7 +244,7 @@ TEST(CaptureBase, move_from_null_to_KF)
 {
     ProblemPtr problem = Problem::create(2);
 
-    auto KF = problem->emplaceFrame(0.0);  // dummy F object
+    auto KF = problem->emplaceFrame(0.0, "");  // dummy F object
 
     auto KC = CaptureBase::emplace<CaptureBase>(KF, "Dummy", 0.0);
 
@@ -277,7 +277,7 @@ TEST(CaptureBase, move_from_KF_to_F)
 {
     ProblemPtr problem = Problem::create(2);
 
-    auto KF = problem->emplaceFrame(0.0);  // dummy F object
+    auto KF = problem->emplaceFrame(0.0, "");  // dummy F object
 
     auto F = std::make_shared<FrameBase>(0.0, TypeComposite(), VectorComposite());  // dummy F object
 
diff --git a/test/gtest_factor_block_difference.cpp b/test/gtest_factor_block_difference.cpp
index b4d0697aade652283842deabf9c4e9175812f207..8845a3c70d1a66a59e3f5f1f5323a5661754db4b 100644
--- a/test/gtest_factor_block_difference.cpp
+++ b/test/gtest_factor_block_difference.cpp
@@ -61,7 +61,7 @@ class FixtureFactorBlockDifference : public testing::Test
                                         problem_->stateZero("POV"),
                                         PriorComposite{{'P', Prior("fix")}, {'O', Prior("fix")}, {'V', Prior("fix")}});
 
-        KF1_ = problem_->emplaceFrame(t1, problem_->stateZero());
+        KF1_ = problem_->emplaceFrame(t1, problem_->stateZero("POV"));
 
         Cap_ = CaptureBase::emplace<CaptureBase>(KF1_, "BlockDifference", t1);
     }
diff --git a/test/gtest_factor_diff_drive.cpp b/test/gtest_factor_diff_drive.cpp
index 56a01ecfec206af0a2b5b2dcec825f7e4d612a8d..0ddbf90136834b7150c8c8af1fe63bab5063a872 100644
--- a/test/gtest_factor_diff_drive.cpp
+++ b/test/gtest_factor_diff_drive.cpp
@@ -69,7 +69,7 @@ class FactorDiffDriveTest : public testing::Test
                                       {wolf_dir + "/test/dummy", wolf_dir + "/schema"}));
 
         // frames
-        F0 = problem->emplaceFrame(0.0, problem->stateZero());
+        F0 = problem->emplaceFrame(0.0, problem->stateZero("PO"));
         F1 = problem->emplaceFrame(1.0, VectorComposite{{'P', Vector2d(1, 0)}, {'O', Vector1d(0)}});
 
         // captures
@@ -385,7 +385,7 @@ TEST(FactorDiffDrive, preintegrate_and_solve_sensor_intrinsics_gt)
     auto report = solver->solve(SolverManager::ReportVerbosity::FULL);
     WOLF_TRACE("\n", report);
 
-    WOLF_TRACE("x1           : ", problem->getState(N * dt).vector("PO").transpose());
+    WOLF_TRACE("x1           : ", problem->getState(N * dt, "PO").vector("PO").transpose());
     WOLF_TRACE("x2           : ", F2->getStateVector("PO").transpose());
     WOLF_TRACE("calib_preint : ", calib_preint.transpose());
     WOLF_TRACE("calib_pert   : ", calib_pert.transpose());
@@ -393,8 +393,8 @@ TEST(FactorDiffDrive, preintegrate_and_solve_sensor_intrinsics_gt)
     WOLF_TRACE("calib_gt     : ", calib_gt.transpose());
 
     ASSERT_MATRIX_APPROX(sensor->getIntrinsic()->getState(), calib_gt, 1e-6);
-    ASSERT_POSE2d_APPROX(problem->getState(N * dt).vector("PO"), x1, 1e-6);
-    ASSERT_POSE2d_APPROX(problem->getState(2 * N * dt).vector("PO"), x2, 1e-6);
+    ASSERT_POSE2d_APPROX(problem->getState(N * dt, "PO").vector("PO"), x1, 1e-6);
+    ASSERT_POSE2d_APPROX(problem->getState(2 * N * dt, "PO").vector("PO"), x2, 1e-6);
 
     std::cout << "\n\n" << std::endl;
 }
@@ -507,15 +507,15 @@ TEST(FactorDiffDrive, preintegrate_and_solve_sensor_intrinsics)
     auto report = solver->solve(SolverManager::ReportVerbosity::FULL);
     WOLF_TRACE("\n", report);
 
-    WOLF_TRACE("x1           : ", problem->getState(N * dt).vector("PO").transpose());
+    WOLF_TRACE("x1           : ", problem->getState(N * dt, "PO").vector("PO").transpose());
     WOLF_TRACE("x2           : ", F2->getStateVector("PO").transpose());
     WOLF_TRACE("calib_preint : ", calib_preint.transpose());
     WOLF_TRACE("calib_est    : ", sensor->getIntrinsic()->getState().transpose());
     WOLF_TRACE("calib_GT     : ", calib_gt.transpose());
 
     ASSERT_MATRIX_APPROX(sensor->getIntrinsic()->getState(), calib_gt, 1e-2);
-    ASSERT_POSE2d_APPROX(problem->getState(N * dt).vector("PO"), x1, 1e-2);
-    ASSERT_POSE2d_APPROX(problem->getState(2 * N * dt).vector("PO"), x2, 1e-6);
+    ASSERT_POSE2d_APPROX(problem->getState(N * dt, "PO").vector("PO"), x1, 1e-2);
+    ASSERT_POSE2d_APPROX(problem->getState(2 * N * dt, "PO").vector("PO"), x2, 1e-6);
 }
 
 int main(int argc, char** argv)
diff --git a/test/gtest_factory_state_block.cpp b/test/gtest_factory_state_block.cpp
index b50443f1f902f6fa8481386487dbb20ec9e26dff..1020aa3ce30a46decb5482c1308f972070d8d1d1 100644
--- a/test/gtest_factory_state_block.cpp
+++ b/test/gtest_factory_state_block.cpp
@@ -151,17 +151,17 @@ TEST(FactoryStateBlock, creator_Params)
 TEST(FactoryStateBlockIdentity, creator_idendity_non_registered_key)
 {
     // non registered -> throw
-    ASSERT_THROW(auto sba = FactoryStateBlockIdentity::create("A"), std::runtime_error);
+    ASSERT_THROW(auto sba = FactoryStateBlockIdentity::create("A", false), std::runtime_error);
 }
 
 TEST(FactoryStateBlockIdentity, creator_StateBlock)
 {
-    ASSERT_THROW(auto sbp = FactoryStateBlockIdentity::create("StateBlock"), std::runtime_error);
+    ASSERT_THROW(auto sbp = FactoryStateBlockIdentity::create("StateBlock", false), std::runtime_error);
 }
 
 TEST(FactoryStateBlockIdentity, creator_Quaternion)
 {
-    auto sbq = FactoryStateBlockIdentity::create("StateQuaternion");
+    auto sbq = FactoryStateBlockIdentity::create("StateQuaternion", false);
 
     ASSERT_EQ(sbq->getSize(), 4);
     ASSERT_EQ(sbq->getLocalSize(), 3);
@@ -172,7 +172,7 @@ TEST(FactoryStateBlockIdentity, creator_Quaternion)
 
 TEST(FactoryStateBlockIdentity, creator_Angle)
 {
-    auto sba = FactoryStateBlockIdentity::create("StateAngle");
+    auto sba = FactoryStateBlockIdentity::create("StateAngle", false);
 
     ASSERT_EQ(sba->getSize(), 1);
     ASSERT_EQ(sba->getLocalSize(), 1);
@@ -183,7 +183,7 @@ TEST(FactoryStateBlockIdentity, creator_Angle)
 
 TEST(FactoryStateBlockIdentity, creator_Homogeneous3d)
 {
-    auto sbh = FactoryStateBlockIdentity::create("StateHomogeneous3d");
+    auto sbh = FactoryStateBlockIdentity::create("StateHomogeneous3d", false);
 
     ASSERT_EQ(sbh->getSize(), 4);
     ASSERT_EQ(sbh->getLocalSize(), 3);
@@ -194,7 +194,7 @@ TEST(FactoryStateBlockIdentity, creator_Homogeneous3d)
 
 TEST(FactoryStateBlockIdentity, creator_Point)
 {
-    auto sbp2d = FactoryStateBlockIdentity::create("StatePoint2d");
+    auto sbp2d = FactoryStateBlockIdentity::create("StatePoint2d", false);
 
     ASSERT_EQ(sbp2d->getSize(), 2);
     ASSERT_EQ(sbp2d->getLocalSize(), 2);
@@ -202,7 +202,7 @@ TEST(FactoryStateBlockIdentity, creator_Point)
     ASSERT_TRUE(sbp2d->isValid());
     ASSERT_MATRIX_APPROX(Vector2d::Zero(), sbp2d->getState(), Constants::EPS_SMALL);
 
-    auto sbp3d = FactoryStateBlockIdentity::create("StatePoint3d");
+    auto sbp3d = FactoryStateBlockIdentity::create("StatePoint3d", false);
 
     ASSERT_EQ(sbp3d->getSize(), 3);
     ASSERT_EQ(sbp3d->getLocalSize(), 3);
@@ -213,7 +213,7 @@ TEST(FactoryStateBlockIdentity, creator_Point)
 
 TEST(FactoryStateBlockIdentity, creator_Vector)
 {
-    auto sbv2d = FactoryStateBlockIdentity::create("StateVector2d");
+    auto sbv2d = FactoryStateBlockIdentity::create("StateVector2d", false);
 
     ASSERT_EQ(sbv2d->getSize(), 2);
     ASSERT_EQ(sbv2d->getLocalSize(), 2);
@@ -221,7 +221,7 @@ TEST(FactoryStateBlockIdentity, creator_Vector)
     ASSERT_TRUE(sbv2d->isValid());
     ASSERT_MATRIX_APPROX(Vector2d::Zero(), sbv2d->getState(), Constants::EPS_SMALL);
 
-    auto sbv3d = FactoryStateBlockIdentity::create("StateVector3d");
+    auto sbv3d = FactoryStateBlockIdentity::create("StateVector3d", false);
 
     ASSERT_EQ(sbv3d->getSize(), 3);
     ASSERT_EQ(sbv3d->getLocalSize(), 3);
@@ -232,16 +232,27 @@ TEST(FactoryStateBlockIdentity, creator_Vector)
 
 TEST(FactoryStateBlockIdentity, creator_Params)
 {
-    auto sb1  = FactoryStateBlockIdentity::create("StateParams1");
-    auto sb2  = FactoryStateBlockIdentity::create("StateParams2");
-    auto sb3  = FactoryStateBlockIdentity::create("StateParams3");
-    auto sb4  = FactoryStateBlockIdentity::create("StateParams4");
-    auto sb5  = FactoryStateBlockIdentity::create("StateParams5");
-    auto sb6  = FactoryStateBlockIdentity::create("StateParams6");
-    auto sb7  = FactoryStateBlockIdentity::create("StateParams7");
-    auto sb8  = FactoryStateBlockIdentity::create("StateParams8");
-    auto sb9  = FactoryStateBlockIdentity::create("StateParams9");
-    auto sb10 = FactoryStateBlockIdentity::create("StateParams10");
+    auto sb1  = FactoryStateBlockIdentity::create("StateParams1", false);
+    auto sb2  = FactoryStateBlockIdentity::create("StateParams2", true);
+    auto sb3  = FactoryStateBlockIdentity::create("StateParams3", false);
+    auto sb4  = FactoryStateBlockIdentity::create("StateParams4", false);
+    auto sb5  = FactoryStateBlockIdentity::create("StateParams5", true);
+    auto sb6  = FactoryStateBlockIdentity::create("StateParams6", false);
+    auto sb7  = FactoryStateBlockIdentity::create("StateParams7", true);
+    auto sb8  = FactoryStateBlockIdentity::create("StateParams8", false);
+    auto sb9  = FactoryStateBlockIdentity::create("StateParams9", true);
+    auto sb10 = FactoryStateBlockIdentity::create("StateParams10", false);
+
+    ASSERT_EQ(sb1->isFixed(), false);
+    ASSERT_EQ(sb2->isFixed(), true);
+    ASSERT_EQ(sb3->isFixed(), false);
+    ASSERT_EQ(sb4->isFixed(), false);
+    ASSERT_EQ(sb5->isFixed(), true);
+    ASSERT_EQ(sb6->isFixed(), false);
+    ASSERT_EQ(sb7->isFixed(), true);
+    ASSERT_EQ(sb8->isFixed(), false);
+    ASSERT_EQ(sb9->isFixed(), true);
+    ASSERT_EQ(sb10->isFixed(), false);
 
     ASSERT_EQ(sb1->getSize(), 1);
     ASSERT_EQ(sb2->getSize(), 2);
diff --git a/test/gtest_motion_provider.cpp b/test/gtest_motion_provider.cpp
index 57ca89c7652c33250fbb30ac81bd42786aa90992..f2c315db09ec55127b69b0a50cdddd65c5345136 100644
--- a/test/gtest_motion_provider.cpp
+++ b/test/gtest_motion_provider.cpp
@@ -96,15 +96,6 @@ TEST_F(MotionProviderTest, install)
     ASSERT_TRUE(mp3->isStateProvider());
     ASSERT_EQ(mp2->getOrder(), 1);
     ASSERT_EQ(mp3->getOrder(), 2);
-    ASSERT_TRUE(mp1->getStateTypes().has('P'));
-    ASSERT_TRUE(mp1->getStateTypes().has('O'));
-    ASSERT_FALSE(mp1->getStateTypes().has('V'));
-    ASSERT_TRUE(mp2->getStateTypes().has('P'));
-    ASSERT_TRUE(mp2->getStateTypes().has('O'));
-    ASSERT_FALSE(mp2->getStateTypes().has('V'));
-    ASSERT_TRUE(mp3->getStateTypes().has('P'));
-    ASSERT_TRUE(mp3->getStateTypes().has('O'));
-    ASSERT_TRUE(mp3->getStateTypes().has('V'));
 
     // Only 2 and 3 in problem::motion_provider_map_
     ASSERT_EQ(problem->getMotionProviderMap().size(), 2);
@@ -161,7 +152,7 @@ TEST_F(MotionProviderTest, odometry)
     EXPECT_MATRIX_APPROX(odom3_get.at('V'), odom3.at('V'), 1e-9);
 
     // problem::getOdometry(): by priority P and O should come from mp2 and V from mp3
-    auto odom_get = problem->getOdometry();
+    auto odom_get = problem->getOdometry("PO");
     EXPECT_TRUE(odom_get.count('P') == 1);
     EXPECT_TRUE(odom_get.count('O') == 1);
     EXPECT_TRUE(odom_get.count('V') == 1);
@@ -170,7 +161,7 @@ TEST_F(MotionProviderTest, odometry)
     EXPECT_MATRIX_APPROX(odom_get.at('V'), odom3.at('V'), 1e-9);
 
     // problem::getState(): by priority P and O should come from mp2 and V from mp3
-    auto state_get = problem->getState();
+    auto state_get = problem->getState("POV");
     EXPECT_TRUE(state_get.count('P') == 1);
     EXPECT_TRUE(state_get.count('O') == 1);
     EXPECT_TRUE(state_get.count('V') == 1);
diff --git a/test/gtest_problem.cpp b/test/gtest_problem.cpp
index d8363c132c80b55d0cfba9a706f5cb4bc3762e83..737b19422c4452b7f238f3bbc58d3a89db5140ae 100644
--- a/test/gtest_problem.cpp
+++ b/test/gtest_problem.cpp
@@ -56,10 +56,6 @@ TEST(Problem, create)
     ASSERT_EQ(P, P->getHardware()->getProblem());
     ASSERT_EQ(P, P->getTrajectory()->getProblem());
     ASSERT_EQ(P, P->getMap()->getProblem());
-
-    // check frame structure through the state size
-    ASSERT_EQ(P->getFrameKeys().size(), 0);
-    ASSERT_FALSE(P->hasFrameKeys("POV"));
 }
 
 TEST(Problem, Installers)
@@ -94,10 +90,8 @@ TEST(Problem, emplaceFirstFrame_PO_2d)
     TimeStamp       t0(0);
     VectorComposite first_frame_values{{'P', Vector2d(1, 2)}, {'O', Vector1d(3)}};
     PriorComposite  first_frame_priors{{'P', Prior("factor", Vector2d::Constant(sqrt(0.1)))},
-                                      {'O', Prior("factor", Vector1d::Constant(sqrt(0.1)))}};
+                                       {'O', Prior("factor", Vector1d::Constant(sqrt(0.1)))}};
     P->emplaceFirstFrame(t0, {{'P', "StatePoint2d"}, {'O', "StateAngle"}}, first_frame_values, first_frame_priors);
-    ASSERT_EQ(P->getFrameKeys().size(), 2);
-    ASSERT_TRUE(P->hasFrameKeys("PO"));
 
     WOLF_INFO("printing...");
     P->print(4, 1, 1, 1);
@@ -106,7 +100,7 @@ TEST(Problem, emplaceFirstFrame_PO_2d)
     ASSERT_EQ(P->getHardware()->getSensorList().size(), (SizeStd)0);
 
     // check that the state is correct
-    ASSERT_POSE2d_APPROX(first_frame_values.vector("PO"), P->getState().vector("PO"), Constants::EPS_SMALL);
+    ASSERT_POSE2d_APPROX(first_frame_values.vector("PO"), P->getState("PO").vector("PO"), Constants::EPS_SMALL);
 
     // check that the tree has one frame without captures
     TrajectoryBasePtr T = P->getTrajectory();
@@ -150,11 +144,9 @@ TEST(Problem, emplaceFirstFrame_PO_3d)
     TimeStamp       t0(0);
     VectorComposite first_frame_values{{'P', Vector3d(1, 2, 3)}, {'O', Vector4d(4, 5, 6, 7).normalized()}};
     PriorComposite  first_frame_priors{{'P', Prior("factor", Vector3d::Constant(sqrt(0.1)))},
-                                      {'O', Prior("factor", Vector3d::Constant(sqrt(0.1)))}};
+                                       {'O', Prior("factor", Vector3d::Constant(sqrt(0.1)))}};
     P->emplaceFirstFrame(
         t0, {{'P', "StatePoint3d"}, {'O', "StateQuaternion"}}, first_frame_values, first_frame_priors);
-    ASSERT_EQ(P->getFrameKeys().size(), 2);
-    ASSERT_TRUE(P->hasFrameKeys("PO"));
 
     WOLF_INFO("printing...");
     P->print(4, 1, 1, 1);
@@ -163,7 +155,7 @@ TEST(Problem, emplaceFirstFrame_PO_3d)
     ASSERT_EQ(P->getHardware()->getSensorList().size(), (SizeStd)0);
 
     // check that the state is correct
-    ASSERT_POSE3d_APPROX(first_frame_values.vector("PO"), P->getState().vector("PO"), Constants::EPS_SMALL);
+    ASSERT_POSE3d_APPROX(first_frame_values.vector("PO"), P->getState("PO").vector("PO"), Constants::EPS_SMALL);
 
     // check that the tree has one frame without captures
     TrajectoryBasePtr T = P->getTrajectory();
@@ -208,12 +200,8 @@ TEST(Problem, emplaceFrame_factory_2D)
 
     ProblemPtr   P  = Problem::create(2);
     FrameBasePtr f1 = P->emplaceFrame(0, "PO", xpo);
-    ASSERT_EQ(P->getFrameKeys().size(), 2);
-    ASSERT_TRUE(P->hasFrameKeys("PO"));
 
     FrameBasePtr f2 = P->emplaceFrame(1, "POV", xpov);
-    ASSERT_EQ(P->getFrameKeys().size(), 3);
-    ASSERT_TRUE(P->hasFrameKeys("POV"));
 
     // check that all frames are effectively in the trajectory
     ASSERT_EQ(P->getTrajectory()->size(), (SizeStd)2);
@@ -250,9 +238,6 @@ TEST(Problem, emplaceFrame_factory_3D)
     // check that all frames are linked to Problem
     ASSERT_EQ(f1->getProblem(), P);
     ASSERT_EQ(f2->getProblem(), P);
-
-    ASSERT_EQ(P->getFrameKeys().size(), 3);
-    ASSERT_TRUE(P->hasFrameKeys("POV"));
 }
 
 TEST(Problem, StateBlocks)
@@ -620,52 +605,40 @@ TEST(Problem, getState)
     P->print(4, 1, 1, 1);
 
     // get at t = origin
-    WOLF_DEBUG("P (0) = ", P->getState(0, "P"));        // partial structure
-    WOLF_DEBUG("PO(0) = ", P->getState(0, "PO"));       // all but explicit structure
-    WOLF_DEBUG("x (0) = ", P->getState(TimeStamp(0)));  // own structure
+    WOLF_DEBUG("P (0) = ", P->getState(0, "P"));
+    WOLF_DEBUG("PO(0) = ", P->getState(0, "PO"));
     ASSERT_EQ(P->getState(0, "P").size(), 1);
     ASSERT_EQ(P->getState(0, "PO").size(), 2);
-    ASSERT_EQ(P->getState(TimeStamp(0)).size(), 2);
 
     // get at t = before KF
     WOLF_DEBUG("P (1) = ", P->getState(1, "P"));
     WOLF_DEBUG("PO(1) = ", P->getState(1, "PO"));
-    WOLF_DEBUG("x (1) = ", P->getState(1));
     ASSERT_EQ(P->getState(1, "P").size(), 1);
     ASSERT_EQ(P->getState(1, "PO").size(), 2);
-    ASSERT_EQ(P->getState(TimeStamp(1)).size(), 2);
 
     // get at t = KF
     WOLF_DEBUG("P (2) = ", P->getState(2, "P"));
     WOLF_DEBUG("PO(2) = ", P->getState(2, "PO"));
-    WOLF_DEBUG("x (2) = ", P->getState(2));
     ASSERT_EQ(P->getState(2, "P").size(), 1);
     ASSERT_EQ(P->getState(2, "PO").size(), 2);
-    ASSERT_EQ(P->getState(TimeStamp(2)).size(), 2);
 
     // get at t = after last KF
     WOLF_DEBUG("P (3) = ", P->getState(3, "P"));
     WOLF_DEBUG("PO(3) = ", P->getState(3, "PO"));
-    WOLF_DEBUG("x (3) = ", P->getState(3));
     ASSERT_EQ(P->getState(3, "P").size(), 1);
     ASSERT_EQ(P->getState(3, "PO").size(), 2);
-    ASSERT_EQ(P->getState(TimeStamp(3)).size(), 2);
 
     // get at t = last processed capture
     WOLF_DEBUG("P (3.9) = ", P->getState(3.9, "P"));
     WOLF_DEBUG("PO(3.9) = ", P->getState(3.9, "PO"));
-    WOLF_DEBUG("x (3.9) = ", P->getState(3.9));
     ASSERT_EQ(P->getState(3.9, "P").size(), 1);
     ASSERT_EQ(P->getState(3.9, "PO").size(), 2);
-    ASSERT_EQ(P->getState(TimeStamp(3.9)).size(), 2);
 
     // get at t = current state
     WOLF_DEBUG("P () = ", P->getState("P"));
     WOLF_DEBUG("PO() = ", P->getState("PO"));
-    WOLF_DEBUG("x () = ", P->getState());
     ASSERT_EQ(P->getState("P").size(), 1);
     ASSERT_EQ(P->getState("PO").size(), 2);
-    ASSERT_EQ(P->getState().size(), 2);
 }
 
 TEST(Problem, transform)
diff --git a/test/gtest_processor_landmark_external.cpp b/test/gtest_processor_landmark_external.cpp
index 169d54c38c5470bbb308ffeef9b1fec41d69e5fb..5b82bb2acd1ce0d696507cd9c3105a2909ceba01 100644
--- a/test/gtest_processor_landmark_external.cpp
+++ b/test/gtest_processor_landmark_external.cpp
@@ -59,7 +59,7 @@ class ProcessorLandmarkExternalTest : public testing::Test
     VectorComposite              state_robot, state_sensor;
     std::vector<VectorComposite> state_landmarks;
 
-    virtual void                SetUp(){};
+    virtual void                SetUp() {};
     void                        initProblem(int          _dim,
                                             bool         _orientation,
                                             int          _mode,
@@ -133,6 +133,7 @@ void ProcessorLandmarkExternalTest::initProblem(int          _dim,
 
     // Take parameters from YAML and modify some of them
     YAML::Node params                    = YAML::LoadFile(wolf_dir + "/test/yaml/processor_landmark_external.yaml");
+    params["dimension"]                  = dim;
     params["time_tolerance"]             = dt / 2;
     params["use_orientation"]            = orientation;
     params["quality_th"]                 = _quality_th;
diff --git a/test/gtest_processor_motion.cpp b/test/gtest_processor_motion.cpp
index 9fd70a8123e9d50c8d6f6a6c1e6d34bb2ca70abf..072297eb4de696e285fe2a1b56f63969b54cbcf5 100644
--- a/test/gtest_processor_motion.cpp
+++ b/test/gtest_processor_motion.cpp
@@ -111,10 +111,10 @@ TEST_F(ProcessorMotion_test, IntegrateStraightAutoPrior)
         capture->setData(data);
         capture->setDataCovariance(data_cov);
         processor->captureCallback(capture);
-        WOLF_DEBUG("t: ", t, "  x: ", problem->getState().vector("PO").transpose());
+        WOLF_DEBUG("t: ", t, "  x: ", problem->getState("PO").vector("PO").transpose());
     }
 
-    ASSERT_POSE2d_APPROX(problem->getState().vector("PO"), (Vector3d() << 9, 0, 0).finished(), 1e-8);
+    ASSERT_POSE2d_APPROX(problem->getState("PO").vector("PO"), (Vector3d() << 9, 0, 0).finished(), 1e-8);
 }
 
 TEST_F(ProcessorMotion_test, getState_structure)
@@ -136,7 +136,7 @@ TEST_F(ProcessorMotion_test, getState_structure)
         capture->setData(data);
         capture->setDataCovariance(data_cov);
         processor->captureCallback(capture);
-        WOLF_DEBUG("t: ", t, "  x: ", problem->getState().vector("PO").transpose());
+        WOLF_DEBUG("t: ", t, "  x: ", problem->getState("PO").vector("PO").transpose());
     }
 
     ASSERT_TRUE(processor->getState("P").count('P'));
@@ -167,7 +167,7 @@ TEST_F(ProcessorMotion_test, getState_time_structure)
         capture->setData(data);
         capture->setDataCovariance(data_cov);
         capture->process();
-        WOLF_DEBUG("t: ", t, "  x: ", problem->getState().vector("PO").transpose());
+        WOLF_DEBUG("t: ", t, "  x: ", problem->getState("PO").vector("PO").transpose());
     }
 
     problem->print(2, 1, 1, 1);
@@ -203,10 +203,10 @@ TEST_F(ProcessorMotion_test, IntegrateStraightFactorPrior)
         capture->setDataCovariance(data_cov);
         processor->captureCallback(capture);
 
-        WOLF_DEBUG("t: ", t, "  x: ", problem->getState().vector("PO").transpose());
+        WOLF_DEBUG("t: ", t, "  x: ", problem->getState("PO").vector("PO").transpose());
     }
 
-    ASSERT_POSE2d_APPROX(problem->getState().vector("PO"), (Vector3d() << 9, 0, 0).finished(), 1e-8);
+    ASSERT_POSE2d_APPROX(problem->getState("PO").vector("PO"), (Vector3d() << 9, 0, 0).finished(), 1e-8);
 }
 
 TEST_F(ProcessorMotion_test, IntegrateStraightFixPrior)
@@ -229,10 +229,10 @@ TEST_F(ProcessorMotion_test, IntegrateStraightFixPrior)
         capture->setData(data);
         capture->setDataCovariance(data_cov);
         processor->captureCallback(capture);
-        WOLF_DEBUG("t: ", t, "  x: ", problem->getState().vector("PO").transpose());
+        WOLF_DEBUG("t: ", t, "  x: ", problem->getState("PO").vector("PO").transpose());
     }
 
-    ASSERT_POSE2d_APPROX(problem->getState().vector("PO"), (Vector3d() << 9, 0, 0).finished(), 1e-8);
+    ASSERT_POSE2d_APPROX(problem->getState("PO").vector("PO"), (Vector3d() << 9, 0, 0).finished(), 1e-8);
 }
 
 TEST_F(ProcessorMotion_test, IntegrateCircleAutoPrior)
@@ -254,10 +254,10 @@ TEST_F(ProcessorMotion_test, IntegrateCircleAutoPrior)
         capture->setData(data);
         capture->setDataCovariance(data_cov);
         processor->captureCallback(capture);
-        WOLF_DEBUG("t: ", t, "  x: ", problem->getState().vector("PO").transpose());
+        WOLF_DEBUG("t: ", t, "  x: ", problem->getState("PO").vector("PO").transpose());
     }
 
-    ASSERT_POSE2d_APPROX(problem->getState().vector("PO"), (Vector3d() << 0, 0, 0).finished(), 1e-8);
+    ASSERT_POSE2d_APPROX(problem->getState("PO").vector("PO"), (Vector3d() << 0, 0, 0).finished(), 1e-8);
 }
 
 TEST_F(ProcessorMotion_test, IntegrateCircleFactorPrior)
@@ -281,10 +281,10 @@ TEST_F(ProcessorMotion_test, IntegrateCircleFactorPrior)
         capture->setData(data);
         capture->setDataCovariance(data_cov);
         processor->captureCallback(capture);
-        WOLF_DEBUG("t: ", t, "  x: ", problem->getState().vector("PO").transpose());
+        WOLF_DEBUG("t: ", t, "  x: ", problem->getState("PO").vector("PO").transpose());
     }
 
-    ASSERT_POSE2d_APPROX(problem->getState().vector("PO"), (Vector3d() << 0, 0, 0).finished(), 1e-8);
+    ASSERT_POSE2d_APPROX(problem->getState("PO").vector("PO"), (Vector3d() << 0, 0, 0).finished(), 1e-8);
 }
 
 TEST_F(ProcessorMotion_test, IntegrateCircleFixPrior)
@@ -307,10 +307,10 @@ TEST_F(ProcessorMotion_test, IntegrateCircleFixPrior)
         capture->setData(data);
         capture->setDataCovariance(data_cov);
         processor->captureCallback(capture);
-        WOLF_DEBUG("t: ", t, "  x: ", problem->getState().vector("PO").transpose());
+        WOLF_DEBUG("t: ", t, "  x: ", problem->getState("PO").vector("PO").transpose());
     }
 
-    ASSERT_POSE2d_APPROX(problem->getState().vector("PO"), (Vector3d() << 0, 0, 0).finished(), 1e-8);
+    ASSERT_POSE2d_APPROX(problem->getState("PO").vector("PO"), (Vector3d() << 0, 0, 0).finished(), 1e-8);
 }
 
 TEST_F(ProcessorMotion_test, mergeCaptures)
@@ -332,13 +332,13 @@ TEST_F(ProcessorMotion_test, mergeCaptures)
         capture->setData(data);
         capture->setDataCovariance(data_cov);
         processor->captureCallback(capture);
-        WOLF_DEBUG("t: ", t, "  x: ", problem->getState().vector("PO").transpose());
+        WOLF_DEBUG("t: ", t, "  x: ", problem->getState("PO").vector("PO").transpose());
     }
 
     SensorBasePtr S = processor->getSensor();
 
     TimeStamp        t_target = 8.5;
-    FrameBasePtr     F_target = problem->emplaceFrame(t_target);
+    FrameBasePtr     F_target = problem->emplaceFrame(t_target, "PO");
     CaptureMotionPtr C_source = std::dynamic_pointer_cast<CaptureMotion>(processor->getLast());
     CaptureMotionPtr C_target =
         CaptureBase::emplace<CaptureMotion>(F_target, "CaptureOdom2d", t_target, sensor, data, nullptr);
@@ -404,13 +404,13 @@ TEST_F(ProcessorMotion_test, splitBufferAutoPrior)
         capture->setData(data);
         capture->setDataCovariance(data_cov);
         processor->captureCallback(capture);
-        WOLF_DEBUG("t: ", t, "  x: ", problem->getState().vector("PO").transpose());
+        WOLF_DEBUG("t: ", t, "  x: ", problem->getState("PO").vector("PO").transpose());
     }
 
     SensorBasePtr S = processor->getSensor();
 
     TimeStamp        t_target = 8.5;
-    FrameBasePtr     F_target = problem->emplaceFrame(t_target);
+    FrameBasePtr     F_target = problem->emplaceFrame(t_target, "PO");
     CaptureMotionPtr C_source = std::dynamic_pointer_cast<CaptureMotion>(processor->getLast());
     CaptureMotionPtr C_target =
         CaptureBase::emplace<CaptureMotion>(F_target, "ODOM 2d", t_target, sensor, data, nullptr);
@@ -442,13 +442,13 @@ TEST_F(ProcessorMotion_test, splitBufferFactorPrior)
         capture->setData(data);
         capture->setDataCovariance(data_cov);
         processor->captureCallback(capture);
-        WOLF_DEBUG("t: ", t, "  x: ", problem->getState().vector("PO").transpose());
+        WOLF_DEBUG("t: ", t, "  x: ", problem->getState("PO").vector("PO").transpose());
     }
 
     SensorBasePtr S = processor->getSensor();
 
     TimeStamp        t_target = 8.5;
-    FrameBasePtr     F_target = problem->emplaceFrame(t_target);
+    FrameBasePtr     F_target = problem->emplaceFrame(t_target, "PO");
     CaptureMotionPtr C_source = std::dynamic_pointer_cast<CaptureMotion>(processor->getLast());
     CaptureMotionPtr C_target =
         CaptureBase::emplace<CaptureMotion>(F_target, "ODOM 2d", t_target, sensor, data, nullptr);
@@ -479,13 +479,13 @@ TEST_F(ProcessorMotion_test, splitBufferFixPrior)
         capture->setData(data);
         capture->setDataCovariance(data_cov);
         processor->captureCallback(capture);
-        WOLF_DEBUG("t: ", t, "  x: ", problem->getState().vector("PO").transpose());
+        WOLF_DEBUG("t: ", t, "  x: ", problem->getState("PO").vector("PO").transpose());
     }
 
     SensorBasePtr S = processor->getSensor();
 
     TimeStamp        t_target = 8.5;
-    FrameBasePtr     F_target = problem->emplaceFrame(t_target);
+    FrameBasePtr     F_target = problem->emplaceFrame(t_target, "PO");
     CaptureMotionPtr C_source = std::dynamic_pointer_cast<CaptureMotion>(processor->getLast());
     CaptureMotionPtr C_target =
         CaptureBase::emplace<CaptureMotion>(F_target, "ODOM 2d", t_target, sensor, data, nullptr);
diff --git a/test/gtest_processor_odom_2d.cpp b/test/gtest_processor_odom_2d.cpp
index fb68aa20c3b2d92df6241383b9c12273f062151c..978d694f18ba62a719797fe347dabadd6a27e9a8 100644
--- a/test/gtest_processor_odom_2d.cpp
+++ b/test/gtest_processor_odom_2d.cpp
@@ -392,9 +392,9 @@ TEST(ProcessorOdom2d, KF_callback)
     for (int n = 1; n <= N; n++)
     {
         t += dt;
-        WOLF_DEBUG("   estimated(", t, ") = ", problem->getState(t).vector("PO").transpose());
+        WOLF_DEBUG("   estimated(", t, ") = ", problem->getState(t, "PO").vector("PO").transpose());
         WOLF_DEBUG("ground truth(", t, ") = ", integrated_pose_vector[n].transpose());
-        ASSERT_POSE2d_APPROX(problem->getState(t).vector("PO"), integrated_pose_vector[n], 1e-6);
+        ASSERT_POSE2d_APPROX(problem->getState(t, "PO").vector("PO"), integrated_pose_vector[n], 1e-6);
     }
 }
 
diff --git a/test/gtest_processor_tracker_feature_dummy.cpp b/test/gtest_processor_tracker_feature_dummy.cpp
index 0c33991a6652b8c82fde2cab790cf974642b7f15..72505e093bbd5c59e696f7bc286ea5d00a7d3397 100644
--- a/test/gtest_processor_tracker_feature_dummy.cpp
+++ b/test/gtest_processor_tracker_feature_dummy.cpp
@@ -164,14 +164,12 @@ TEST_F(ProcessorTrackerFeatureDummyTest, processKnown)
 
 TEST_F(ProcessorTrackerFeatureDummyTest, emplaceFactor)
 {
-    FrameBasePtr frm = FrameBase::emplace<FrameBase>(
-        problem->getTrajectory(), 0, problem->getFrameTypes("P"), problem->stateZero("P"));
+    FrameBasePtr frm = problem->emplaceFrame(0, problem->stateZero("P"));
     CaptureBasePtr cap = CaptureBase::emplace<CaptureVoid>(frm, 0, sensor);
     FeatureBasePtr ftr =
         FeatureBase::emplace<FeatureBase>(cap, "DUMMY FEATURE", Eigen::Vector1d::Ones(), Eigen::MatrixXd::Ones(1, 1));
 
-    FrameBasePtr frm_other = FrameBase::emplace<FrameBase>(
-        problem->getTrajectory(), 1, problem->getFrameTypes("P"), problem->stateZero("P"));
+    FrameBasePtr frm_other = problem->emplaceFrame(1, problem->stateZero("P"));
     CaptureBasePtr cap_other = CaptureBase::emplace<CaptureVoid>(frm_other, 1, sensor);
     FeatureBasePtr ftr_other = FeatureBase::emplace<FeatureBase>(
         cap_other, "DUMMY FEATURE", Eigen::Vector1d::Ones(), Eigen::MatrixXd::Ones(1, 1));
@@ -193,14 +191,12 @@ TEST_F(ProcessorTrackerFeatureDummyTest, emplaceFactor)
 TEST_F(ProcessorTrackerFeatureDummyTest, establishFactors)
 {
     // Put a capture on last_ptr_
-    FrameBasePtr last_frm = FrameBase::emplace<FrameBase>(
-        problem->getTrajectory(), 0, problem->getFrameTypes("P"), problem->stateZero("P"));
+    FrameBasePtr last_frm = problem->emplaceFrame(0, problem->stateZero("P"));
     CaptureBasePtr last_cap = CaptureBase::emplace<CaptureVoid>(last_frm, 0, sensor);
     processor->setLast(last_cap);
 
     // Put a capture on incoming_ptr_
-    FrameBasePtr inc_frm = FrameBase::emplace<FrameBase>(
-        problem->getTrajectory(), 1, problem->getFrameTypes("P"), problem->stateZero("P"));
+    FrameBasePtr inc_frm = problem->emplaceFrame(1, problem->stateZero("P"));
     CaptureBasePtr inc_cap = CaptureBase::emplace<CaptureVoid>(inc_frm, 1, sensor);
     processor->setInc(inc_cap);
 
@@ -283,6 +279,8 @@ TEST_F(ProcessorTrackerFeatureDummyTest, process)
     ASSERT_EQ(processor->getLast()->getFeatureList().size(), processor->getParams()["max_new_features"].as<int>() - 3);
     ASSERT_TRUE(problem->check(0));
 
+    problem->print(4, 1, 0, 0);
+    
     // 5TH TIME -> KF in cap4 (tracked features < 7 (params->min_features_for_keyframe))
     WOLF_INFO("Fifth time...");
     CaptureBasePtr cap5 = std::make_shared<CaptureVoid>(4, sensor);
diff --git a/test/gtest_processor_tracker_landmark_dummy.cpp b/test/gtest_processor_tracker_landmark_dummy.cpp
index d8d508173f496238eac28740e89a2473012758e9..e6ae208475b3ff3eca0d4c01505c169ecef8cd56 100644
--- a/test/gtest_processor_tracker_landmark_dummy.cpp
+++ b/test/gtest_processor_tracker_landmark_dummy.cpp
@@ -209,8 +209,7 @@ TEST_F(ProcessorTrackerLandmarkDummyTest, processKnown)
 
 TEST_F(ProcessorTrackerLandmarkDummyTest, emplaceFactor)
 {
-    FrameBasePtr frm = FrameBase::emplace<FrameBase>(
-        problem->getTrajectory(), 0, problem->getFrameTypes("P"), problem->stateZero("P"));
+    FrameBasePtr   frm = problem->emplaceFrame(0, problem->stateZero("P"));
     CaptureBasePtr cap = CaptureBase::emplace<CaptureVoid>(frm, 0, sensor);
     FeatureBasePtr ftr =
         FeatureBase::emplace<FeatureBase>(cap, "DUMMY FEATURE", Eigen::Vector1d::Ones(), Eigen::MatrixXd::Ones(1, 1));
@@ -233,14 +232,12 @@ TEST_F(ProcessorTrackerLandmarkDummyTest, emplaceFactor)
 TEST_F(ProcessorTrackerLandmarkDummyTest, establishFactors)
 {
     // Put a capture on last_ptr_
-    FrameBasePtr last_frm = FrameBase::emplace<FrameBase>(
-        problem->getTrajectory(), 0, problem->getFrameTypes("P"), problem->stateZero("P"));
+    FrameBasePtr   last_frm = problem->emplaceFrame(0, problem->stateZero("P"));
     CaptureBasePtr last_cap = CaptureBase::emplace<CaptureVoid>(last_frm, 0, sensor);
     processor->setLast(last_cap);
 
     // Put a capture on incoming_ptr_
-    FrameBasePtr inc_frm = FrameBase::emplace<FrameBase>(
-        problem->getTrajectory(), 1, problem->getFrameTypes("P"), problem->stateZero("P"));
+    FrameBasePtr   inc_frm = problem->emplaceFrame(1, problem->stateZero("P"));
     CaptureBasePtr inc_cap = CaptureBase::emplace<CaptureVoid>(inc_frm, 1, sensor);
     processor->setInc(inc_cap);
 
diff --git a/test/gtest_tree_manager_sliding_window_dual_rate.cpp b/test/gtest_tree_manager_sliding_window_dual_rate.cpp
index 772ed0c8bcb30f49ff73c31021b899bd9b0a0aa7..0fb4ef3d889df64228d5dae599de5fe366e9a3f9 100644
--- a/test/gtest_tree_manager_sliding_window_dual_rate.cpp
+++ b/test/gtest_tree_manager_sliding_window_dual_rate.cpp
@@ -1170,17 +1170,17 @@ TEST(TreeManagerSlidingWindowDualRate, slidingWindowWithProcessor)
         capture_bl->setData(data);
         capture_bl->process();
 
-        WOLF_INFO("state: ", problem->getState().vector("PO").transpose());
+        WOLF_INFO("state: ", problem->getState("PO").vector("PO").transpose());
 
         ASSERT_POSE3d_APPROX(
-            problem->getState().vector("PO").transpose(), problem_bl->getState().vector("PO").transpose(), 1e-12);
+            problem->getState("PO").vector("PO").transpose(), problem_bl->getState("PO").vector("PO").transpose(), 1e-12);
 
         // Solve
         solver->solve();
         solver_bl->solve();
 
         ASSERT_POSE3d_APPROX(
-            problem->getState().vector("PO").transpose(), problem_bl->getState().vector("PO").transpose(), 1e-12);
+            problem->getState("PO").vector("PO").transpose(), problem_bl->getState("PO").vector("PO").transpose(), 1e-12);
 
         ASSERT_TRUE(problem->check());
     }
diff --git a/test/yaml/processor_landmark_external.yaml b/test/yaml/processor_landmark_external.yaml
index b70dcc32f26786e0acdb2a313b8964523100ada1..da0b76f89cef744152c5ee5b9c9a4ff2948c18e6 100644
--- a/test/yaml/processor_landmark_external.yaml
+++ b/test/yaml/processor_landmark_external.yaml
@@ -9,6 +9,8 @@ keyframe_vote:
   min_features_for_keyframe:  1
   new_features_for_keyframe:  1000
 
+dimension:                    3
+
 time_tolerance:               0.05
 apply_loss_function:          false
 max_new_features:             -1