diff --git a/include/core/processor/is_motion.h b/include/core/processor/is_motion.h
index 2f725e18d723463e810441c83f7fc81acc206785..09d7bc68dee5511c28ee456bb42467e89168bbb4 100644
--- a/include/core/processor/is_motion.h
+++ b/include/core/processor/is_motion.h
@@ -26,8 +26,8 @@ class IsMotion
 
         // Queries to the processor:
         virtual TimeStamp       getTimeStamp() const = 0;
-        virtual VectorComposite getState() const = 0;
-        virtual VectorComposite getState(const TimeStamp& _ts) const = 0;
+        virtual VectorComposite getState(const StateStructure& _structure = "") const = 0;
+        virtual VectorComposite getState(const TimeStamp& _ts, const StateStructure& _structure = "") const = 0;
 
         std::string getStateStructure(){return state_structure_;};
         void setStateStructure(std::string _state_structure){state_structure_ = _state_structure;};
diff --git a/include/core/processor/processor_motion.h b/include/core/processor/processor_motion.h
index 80017c423035ff9bd981bea1f85eb7adf06e9a67..6d2b81e9ed4425a693c7f669779d1f51a0118845 100644
--- a/include/core/processor/processor_motion.h
+++ b/include/core/processor/processor_motion.h
@@ -166,8 +166,8 @@ class ProcessorMotion : public ProcessorBase, public IsMotion
 
         // Queries to the processor:
         TimeStamp       getTimeStamp() const override;
-        VectorComposite getState() const override;
-        VectorComposite getState(const TimeStamp& _ts) const override;
+        VectorComposite getState(const StateStructure& _structure = "") const override;
+        VectorComposite getState(const TimeStamp& _ts, const StateStructure& _structure = "") const override;
 
         /** \brief Gets the delta preintegrated covariance from all integrations so far
          * \return the delta preintegrated covariance matrix
diff --git a/include/core/state_block/has_state_blocks.h b/include/core/state_block/has_state_blocks.h
index 8880fc0a2cfb09a46712a502601a801a1f923a39..b1af55f7b8c6adafc23d9ef4139b154537f0f9ff 100644
--- a/include/core/state_block/has_state_blocks.h
+++ b/include/core/state_block/has_state_blocks.h
@@ -74,12 +74,12 @@ class HasStateBlocks
         VectorComposite getState(const StateStructure& structure="") const;
         void setState(const VectorComposite& _state, const bool _notify = true);
         void setState(const Eigen::VectorXd& _state, const StateStructure& _structure, const std::list<SizeEigen>& _sizes, const bool _notify = true);
-        void setState(const Eigen::VectorXd& _state, const StateStructure& _sub_structure="", const bool _notify = true);
+        void setState(const Eigen::VectorXd& _state, const StateStructure& _structure="", const bool _notify = true);
         void setState(const StateStructure& _structure, const std::list<VectorXd>& _vectors, const bool _notify = true);
 
         VectorXd getStateVector(const StateStructure& structure="") const;
-        unsigned int getSize(const StateStructure& _sub_structure="") const;
-        unsigned int getLocalSize(const StateStructure& _sub_structure="") const;
+        unsigned int getSize(const StateStructure& _structure="") const;
+        unsigned int getLocalSize(const StateStructure& _structure="") const;
 
         // Perturb state
         void            perturb(double amplitude = 0.01);
@@ -225,13 +225,13 @@ inline void HasStateBlocks::setState(const VectorComposite& _state, const bool _
     }
 }
 
-inline void HasStateBlocks::setState(const Eigen::VectorXd& _state, const StateStructure& _sub_structure, const bool _notify)
+inline void HasStateBlocks::setState(const Eigen::VectorXd& _state, const StateStructure& _structure, const bool _notify)
 {
     StateStructure structure;
-    if (_sub_structure == "")
+    if (_structure == "")
         structure = structure_;
     else
-        structure = _sub_structure;
+        structure = _structure;
 
     int size = getSize(structure);
     assert(_state.size() == size && "In FrameBase::setState wrong state size");
@@ -286,14 +286,14 @@ inline void HasStateBlocks::setState(const StateStructure& _structure, const std
 }
 
 
-//// _sub_structure can be either stateblock structure of the node or a subset of this structure
-inline VectorXd HasStateBlocks::getStateVector(const StateStructure& _sub_structure) const
+//// _structure can be either stateblock structure of the node or a subset of this structure
+inline VectorXd HasStateBlocks::getStateVector(const StateStructure& _structure) const
 {
     StateStructure structure;
-    if (_sub_structure == "")
+    if (_structure == "")
         structure = structure_;
     else
-        structure = _sub_structure;
+        structure = _structure;
 
     VectorXd state(getSize(structure));
 
@@ -312,21 +312,31 @@ inline VectorXd HasStateBlocks::getStateVector(const StateStructure& _sub_struct
 
 inline VectorComposite HasStateBlocks::getState(const StateStructure& _structure) const
 {
+    const StateStructure& structure = (_structure == "" ? structure_ : _structure);
+
     VectorComposite state;
-    for (auto& pair_key_sb : state_block_map_)
+
+    for (const auto ckey : structure)
     {
-        state.emplace(pair_key_sb.first, pair_key_sb.second->getState());
+        const auto& key = string(1,ckey); // ckey is char
+
+        auto state_it = state_block_map_.find(key);
+
+        if (state_it != state_block_map_.end())
+
+            state.emplace(key, state_it->second->getState());
     }
+
+//    for (auto& pair_key_sb : state_block_map_)
+//    {
+//        state.emplace(pair_key_sb.first, pair_key_sb.second->getState());
+//    }
     return state;
 }
 
-inline unsigned int HasStateBlocks::getSize(const StateStructure& _sub_structure) const
+inline unsigned int HasStateBlocks::getSize(const StateStructure& _structure) const
 {
-    StateStructure structure;
-    if (_sub_structure == "")
-        structure = structure_;
-    else
-        structure = _sub_structure;
+    const StateStructure& structure = (_structure == "" ? structure_ : _structure);
 
     unsigned int size = 0;
     for (const char key : structure)
@@ -341,7 +351,6 @@ inline unsigned int HasStateBlocks::getSize(const StateStructure& _sub_structure
     return size;
 }
 
-//<<<<<<< HEAD
 inline std::unordered_map<std::string, StateBlockPtr>::const_iterator HasStateBlocks::find(const StateBlockPtr& _sb) const
 {
     const auto& it = std::find_if(state_block_map_.begin(),
@@ -380,13 +389,13 @@ inline bool HasStateBlocks::stateBlockKey(const StateBlockPtr &_sb, std::string&
     }
 }
 
-inline unsigned int HasStateBlocks::getLocalSize(const StateStructure& _sub_structure) const
+inline unsigned int HasStateBlocks::getLocalSize(const StateStructure& _structure) const
 {
     StateStructure structure;
-    if (_sub_structure == "")
+    if (_structure == "")
         structure = structure_;
     else
-        structure = _sub_structure;
+        structure = _structure;
 
     unsigned int size = 0;
     for (const char key : structure)
diff --git a/src/problem/problem.cpp b/src/problem/problem.cpp
index caf9e1115582963c64980a02bf10f15a8b0c108e..813077742ceca8ee0b7b60913fab479145c4298b 100644
--- a/src/problem/problem.cpp
+++ b/src/problem/problem.cpp
@@ -452,7 +452,7 @@ VectorComposite Problem::getState(const StateStructure& _structure) const
     // compose the states of all processor motions into one only state
     for (const auto& prc : processor_is_motion_list_)
     {
-        const auto& prc_state = prc->getState();
+        const auto& prc_state = prc->getState(structure);
         for (const auto& pair_key_vec : prc_state)
         {
             if (state.count(pair_key_vec.first) == 0) // only add those keys that do not exist yet
@@ -498,7 +498,7 @@ VectorComposite Problem::getState (const TimeStamp& _ts, const StateStructure& _
 
     for (const auto& prc : processor_is_motion_list_)
     {
-        const auto& prc_state = prc->getState(_ts);
+        const auto& prc_state = prc->getState(_ts, structure);
 
         // transfer processor vector blocks to problem state
         for (const auto& pair_key_vec : prc_state)
diff --git a/src/processor/processor_motion.cpp b/src/processor/processor_motion.cpp
index c403a87828f9266089f63c8e8cb274cb03616729..65960d878ac414308b1032f913e4a9f9e69cf243 100644
--- a/src/processor/processor_motion.cpp
+++ b/src/processor/processor_motion.cpp
@@ -427,8 +427,11 @@ void ProcessorMotion::processCapture(CaptureBasePtr _incoming_ptr)
     postProcess();
 }
 
-VectorComposite ProcessorMotion::getState() const
+VectorComposite ProcessorMotion::getState(const StateStructure& _structure) const
 {
+    const StateStructure& structure = (_structure == "" ? state_structure_ : _structure);
+
+
     if (origin_ptr_ == nullptr or
         origin_ptr_->isRemoving() or
         last_ptr_ == nullptr or
@@ -446,7 +449,7 @@ VectorComposite ProcessorMotion::getState() const
     // this may happen when in the very first frame where the capture has no motion info --> empty buffer
     if (last_ptr_->getBuffer().empty())
     {
-        return last_ptr_->getFrame()->getState(state_structure_);
+        return last_ptr_->getFrame()->getState(structure);
     }
 
     /* Doing this:
@@ -463,7 +466,7 @@ VectorComposite ProcessorMotion::getState() const
      */
 
     // Get state of origin
-    const auto& x_origin = origin_ptr_->getFrame()->getState();
+    const auto& x_origin = getOrigin()->getFrame()->getState(state_structure_);
 
     // Get most rescent motion
     const auto& motion = last_ptr_->getBuffer().back();
@@ -497,16 +500,35 @@ VectorComposite ProcessorMotion::getState() const
         statePlusDelta(x_origin, delta_preint, last_ptr_->getTimeStamp() - origin_ptr_->getTimeStamp(), state);
     }
 
-    return state;
+    if (_structure == "")
+        return state;
+
+    else
+    {
+        // remove states not requested by structure
+        auto pair_key_vec_it = state.begin();
+        while (pair_key_vec_it != state.end())
+        {
+            if (_structure.find(pair_key_vec_it->first) == std::string::npos)
+                pair_key_vec_it = state.erase(pair_key_vec_it);
+
+            else
+                pair_key_vec_it ++;
+
+        }
+        return state;
+    }
 }
 
 
 
 // _x needs to have the size of the processor state
-VectorComposite ProcessorMotion::getState(const TimeStamp& _ts) const
+VectorComposite ProcessorMotion::getState(const TimeStamp& _ts, const StateStructure& _structure) const
 {
     assert(_ts.ok());
 
+    const StateStructure& structure = (_structure == "" ? state_structure_ : _structure);
+
     // We need to search for the capture containing a motion buffer with the queried time stamp
     CaptureMotionPtr capture_motion = findCaptureContainingTimeStamp(_ts);
 
@@ -523,7 +545,7 @@ VectorComposite ProcessorMotion::getState(const TimeStamp& _ts) const
         // this may happen when in the very first frame where the capture has no motion info --> empty buffer
         if (capture_motion->getBuffer().empty())
         {
-            return capture_motion->getFrame()->getState(state_structure_);
+            return capture_motion->getFrame()->getState(structure);
         }
 
         /* Doing this:
@@ -541,7 +563,7 @@ VectorComposite ProcessorMotion::getState(const TimeStamp& _ts) const
 
         // Get state of origin
         CaptureBasePtr cap_orig   = capture_motion->getOriginCapture();
-        const auto& x_origin = cap_orig->getFrame()->getState();
+        const auto& x_origin = cap_orig->getFrame()->getState(state_structure_);
 
         // Get motion at time stamp
         const auto& motion = capture_motion->getBuffer().getMotion(_ts);
@@ -576,8 +598,24 @@ VectorComposite ProcessorMotion::getState(const TimeStamp& _ts) const
             statePlusDelta(x_origin, delta_preint, _ts - cap_orig->getTimeStamp(), state);
         }
 
-        // return success
-        return state;
+        if (_structure == "")
+            return state;
+
+        else
+        {
+            // remove states not requested by structure
+            auto pair_key_vec_it = state.begin();
+            while (pair_key_vec_it != state.end())
+            {
+                if (_structure.find(pair_key_vec_it->first) == std::string::npos)
+                    pair_key_vec_it = state.erase(pair_key_vec_it);
+
+                else
+                    pair_key_vec_it ++;
+
+            }
+            return state;
+        }
 
     }
 }
diff --git a/test/gtest_has_state_blocks.cpp b/test/gtest_has_state_blocks.cpp
index 4e3d610109e92b8fe6846b93050bc64af29a6f72..1369fd5a87dc31f4d0a7af14a929f0d23637b041 100644
--- a/test/gtest_has_state_blocks.cpp
+++ b/test/gtest_has_state_blocks.cpp
@@ -178,6 +178,46 @@ TEST_F(HasStateBlocksTest, stateBlockKey)
     ASSERT_TRUE(key == "");
 }
 
+TEST_F(HasStateBlocksTest, getState_structure)
+{
+    F0->addStateBlock("V", sbv0); // now KF0 is POV
+
+    WOLF_DEBUG("Retrieving state from F0 with structure ", F0->getStructure());
+
+    auto state0 = F0->getState();
+    WOLF_DEBUG("getState()     = ", state0);
+    ASSERT_EQ(state0.size(), 3);
+    ASSERT_TRUE(state0.count("P"));
+    ASSERT_TRUE(state0.count("O"));
+    ASSERT_TRUE(state0.count("V"));
+
+    state0 = F0->getState("PO");
+    WOLF_DEBUG("getState(\"PO\") = ", state0);
+    ASSERT_EQ(state0.size(), 2);
+    ASSERT_TRUE(state0.count("P"));
+    ASSERT_TRUE(state0.count("O"));
+    ASSERT_FALSE(state0.count("V"));
+
+    state0 = F0->getState("PV");
+    WOLF_DEBUG("getState(\"PV\") = ", state0);
+    ASSERT_EQ(state0.size(), 2);
+    ASSERT_TRUE(state0.count("P"));
+    ASSERT_FALSE(state0.count("O"));
+    ASSERT_TRUE(state0.count("V"));
+
+    state0 = F0->getState("OW"); // W does not exist
+    WOLF_DEBUG("getState(\"OW\") = ", state0);
+    ASSERT_EQ(state0.size(), 1);
+    ASSERT_FALSE(state0.count("P"));
+    ASSERT_TRUE(state0.count("O"));
+    ASSERT_FALSE(state0.count("V"));
+    ASSERT_FALSE(state0.count("W"));
+
+
+
+
+}
+
 
 int main(int argc, char **argv)
 {
diff --git a/test/gtest_problem.cpp b/test/gtest_problem.cpp
index 0e13554d43eb92416f04321d6039f930b8d5a6e5..1470052b849465705eb860b34600d8d624dfb61c 100644
--- a/test/gtest_problem.cpp
+++ b/test/gtest_problem.cpp
@@ -16,6 +16,7 @@
 #include "dummy/processor_tracker_feature_dummy.h"
 #include "core/solver/solver_manager.h"
 #include "dummy/solver_manager_dummy.h"
+#include "core/yaml/parser_yaml.h"
 
 #include "core/sensor/sensor_diff_drive.h"
 #include "core/processor/processor_diff_drive.h"
@@ -489,10 +490,77 @@ TEST(Problem, check)
     ASSERT_TRUE(problem->check(true, std::cout));
 }
 
+TEST(Problem, getState)
+{
+    std::string wolf_root = _WOLF_ROOT_DIR;
+
+    auto parser = ParserYaml("test/yaml/params_problem_odom_3d.yaml", wolf_root);
+    auto server = ParamsServer(parser.getParams());
+
+    auto P = Problem::autoSetup(server);
+
+    auto S = P->getHardware()->getSensorList().front();
+
+    auto C = std::make_shared<CaptureOdom3d>(0.0, S, 0.1*Vector6d::Ones(), 0.01*Matrix6d::Identity());
+
+    for (TimeStamp t = 0.0; t <= 3.9; t += 0.1)
+    {
+        C->setTimeStamp(t);
+        C->process();
+    }
+    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
+    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());
+
+}
+
 
 int main(int argc, char **argv)
 {
   testing::InitGoogleTest(&argc, argv);
-//  ::testing::GTEST_FLAG(filter) = "Problem.emplaceFrame_factory";
+  ::testing::GTEST_FLAG(filter) = "Problem.getState";
   return RUN_ALL_TESTS();
 }
diff --git a/test/gtest_processor_motion.cpp b/test/gtest_processor_motion.cpp
index bcf69745cea695fef25bbb2238b0c4fddf334799..410ebdf1faea8175c8e73435670fdb46de85fd9e 100644
--- a/test/gtest_processor_motion.cpp
+++ b/test/gtest_processor_motion.cpp
@@ -101,6 +101,66 @@ TEST_F(ProcessorMotion_test, IntegrateStraightAutoPrior)
     ASSERT_MATRIX_APPROX(problem->getState().vector("PO"), (Vector3d()<<9,0,0).finished(), 1e-8);
 }
 
+TEST_F(ProcessorMotion_test, getState_structure)
+{
+    // Prior
+    Vector3d x0; x0 << 0, 0, 0;
+    Matrix3d P0; P0.setIdentity();
+
+    data << 1, 0; // advance straight
+    data_cov.setIdentity();
+    TimeStamp t(0.0);
+
+    for (int i = 0; i<9; i++)
+    {
+        t += dt;
+        capture->setTimeStamp(t);
+        capture->setData(data);
+        capture->setDataCovariance(data_cov);
+        processor->captureCallback(capture);
+        WOLF_DEBUG("t: ", t, "  x: ", problem->getState().vector("PO").transpose());
+    }
+
+    ASSERT_TRUE (processor->getState("P").count("P"));
+    ASSERT_FALSE(processor->getState("P").count("O"));
+    ASSERT_FALSE(processor->getState("O").count("P"));
+    ASSERT_TRUE (processor->getState("O").count("O"));
+
+    WOLF_DEBUG("processor->getState(\"V\") = ", processor->getState("V"));
+    ASSERT_EQ   (processor->getState("V").size(), 0);
+}
+
+
+TEST_F(ProcessorMotion_test, getState_time_structure)
+{
+    // Prior
+    Vector3d x0; x0 << 0, 0, 0;
+    Matrix3d P0; P0.setIdentity();
+
+    data << 1, 0; // advance straight
+    data_cov.setIdentity();
+    TimeStamp t(0.0);
+
+    for (int i = 0; i<9; i++)
+    {
+        t += dt;
+        capture->setTimeStamp(t);
+        capture->setData(data);
+        capture->setDataCovariance(data_cov);
+        processor->captureCallback(capture);
+        WOLF_DEBUG("t: ", t, "  x: ", problem->getState().vector("PO").transpose());
+    }
+
+    ASSERT_TRUE (processor->getState(7, "P").count("P"));
+    ASSERT_FALSE(processor->getState(7, "P").count("O"));
+    ASSERT_FALSE(processor->getState(7, "O").count("P"));
+    ASSERT_TRUE (processor->getState(7, "O").count("O"));
+
+    WOLF_DEBUG("processor->getState(7, \"V\") = ", processor->getState(7, "V"));
+    ASSERT_EQ   (processor->getState(7, "V").size(), 0);
+}
+
+
 
 TEST_F(ProcessorMotion_test, IntegrateStraightFactorPrior)
 {
diff --git a/test/yaml/params_problem_odom_3d.yaml b/test/yaml/params_problem_odom_3d.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..0337cdc0bbc589d0d03054107643e632bb6be7b4
--- /dev/null
+++ b/test/yaml/params_problem_odom_3d.yaml
@@ -0,0 +1,44 @@
+config:
+  problem:
+    frame_structure: "PO"
+    dimension: 3
+    prior:
+      mode: "factor"
+      $state:
+        P: [0,0,0]
+        O: [0,0,0,1]
+      $sigma:
+        P: [0.31, 0.31, 0.31]
+        O: [0.31, 0.31, 0.31]
+      time_tolerance: 0.1
+    tree_manager: 
+      type: "None"
+  sensors: 
+    -
+      type: "SensorOdom3d"
+      name: "odom"
+      plugin: "core"
+      k_disp_to_disp: 0.1
+      k_disp_to_rot: 0.1
+      k_rot_to_rot: 0.1 
+      min_disp_var: 0.1 
+      min_rot_var: 0.1
+      extrinsic:
+        pose: [1,2,3,0,0,0,1]
+  processors:
+    -
+      type: "ProcessorOdom3d"
+      name: "my_proc_odom3d"
+      sensor_name: "odom"
+      plugin: "core"
+      apply_loss_function: false
+      time_tolerance:         0.01  # seconds
+      keyframe_vote:
+        voting_active:        true
+        voting_aux_active:    false
+        max_time_span:          1.95  # seconds
+        max_buff_length:        999   # motion deltas
+        dist_traveled:          999   # meters
+        angle_turned:           999   # radians (1 rad approx 57 deg, approx 60 deg)
+      
+      unmeasured_perturbation_std: 0.00111