diff --git a/include/subscriber_landmarks.h b/include/subscriber_landmarks.h
index 6b8d16b07f022bc644e81bec35cb6dfaa3cc87da..f389542a57bfcc607692c7c772e56bf69bf89d93 100644
--- a/include/subscriber_landmarks.h
+++ b/include/subscriber_landmarks.h
@@ -42,6 +42,9 @@ class SubscriberLandmarks : public Subscriber
 {
    protected:
       SizeEigen dim; 
+      bool inverse_detections_;
+      Eigen::Vector3d sensor_p_;
+      Eigen::Quaterniond sensor_q_;
 
    public:
 
diff --git a/src/node.cpp b/src/node.cpp
index 4df79958f0cebce854c69224d677276459bcadd0..7e102f812439d204fa69dc6e65142ca57ebcd263 100644
--- a/src/node.cpp
+++ b/src/node.cpp
@@ -130,11 +130,15 @@ WolfRosNode::WolfRosNode()
         l->load();
         loaders_.push_back(l);
 
+        auto sensor_ptr = problem_ptr_->findSensor(sensor);
+        if (not sensor_ptr)
+            throw std::runtime_error("Sensor " + sensor + " was not found!");
+
         WOLF_TRACE("From sensor {" + sensor + "} subscribing {" + type + "} to {" + topic + "} topic");
         subscribers_.push_back(FactorySubscriber::create(type,
                                                          name,
                                                          server,
-                                                         problem_ptr_->findSensor(sensor),
+                                                         sensor_ptr,
                                                          nh_));
     }
 
diff --git a/src/subscriber_landmarks.cpp b/src/subscriber_landmarks.cpp
index 7c2ac3507258dc8ecb5cebcffca1514e28c132e4..503b9f1cd735c29a8394f4400642f38407418f80 100644
--- a/src/subscriber_landmarks.cpp
+++ b/src/subscriber_landmarks.cpp
@@ -26,11 +26,16 @@
  *      WOLF includes     *
  **************************/
 #include <core/capture/capture_landmarks_external.h>
+#include <core/math/covariance.h>
+#include <core/math/rotations.h>
+#include <core/math/SE3.h>
 
 /**************************
  *      ROS includes      *
  **************************/
-#include <tf/transform_datatypes.h>
+// #include <tf/transform_datatypes.h>
+
+using namespace Eigen;
 
 namespace wolf
 {
@@ -41,6 +46,10 @@ SubscriberLandmarks::SubscriberLandmarks(const std::string& _unique_name,
 {
     assert(_sensor_ptr);
     dim = _sensor_ptr->getProblem()->getDim();
+    inverse_detections_ = _server.getParam<bool>(prefix_ + "/inverse_detections");
+    auto sensor_extrinsics = _server.getParam<VectorXd>(prefix_ + "/sensor_extrinsics");
+    sensor_p_ = sensor_extrinsics.head<3>();
+    sensor_q_ = Quaterniond(Vector4d(sensor_extrinsics.tail<4>()));
 }
 
 void SubscriberLandmarks::initialize(ros::NodeHandle& nh, const std::string& topic)
@@ -50,7 +59,7 @@ void SubscriberLandmarks::initialize(ros::NodeHandle& nh, const std::string& top
 
 void SubscriberLandmarks::callback(const wolf_ros_node::LandmarkDetectionArray::ConstPtr& msg)
 {
-    ROS_DEBUG("SubscriberLandmarks::callback");
+    ROS_INFO("SubscriberLandmarks::callback: %lu detections", msg->detections.size());
 
     updateLastHeader(msg->header);
 
@@ -58,40 +67,55 @@ void SubscriberLandmarks::callback(const wolf_ros_node::LandmarkDetectionArray::
     // Extract detections from msg
     for (auto i = 0; i < msg->detections.size(); i++)
     {
-        // measurement
-        VectorXd meas(dim == 2 ? 3 : 7);
-        if (dim == 2)
-        {
-            meas(0) = msg->detections.at(i).pose.pose.position.x;
-            meas(1) = msg->detections.at(i).pose.pose.position.y;
-            meas(2) = tf::getYaw(msg->detections.at(i).pose.pose.orientation);
-        }
-        else
-        {
-            meas(0) = msg->detections.at(i).pose.pose.position.x;
-            meas(1) = msg->detections.at(i).pose.pose.position.y;
-            meas(2) = msg->detections.at(i).pose.pose.position.z;
-            meas(3) = msg->detections.at(i).pose.pose.orientation.x;
-            meas(4) = msg->detections.at(i).pose.pose.orientation.y;
-            meas(5) = msg->detections.at(i).pose.pose.orientation.z;
-            meas(6) = msg->detections.at(i).pose.pose.orientation.w;
-        }
-        // covariance
+        // 3D measurement from msg
+        VectorXd meas(7);
+        meas << msg->detections.at(i).pose.pose.position.x,
+                msg->detections.at(i).pose.pose.position.y,
+                msg->detections.at(i).pose.pose.position.z,
+                msg->detections.at(i).pose.pose.orientation.x,
+                msg->detections.at(i).pose.pose.orientation.y,
+                msg->detections.at(i).pose.pose.orientation.z,
+                msg->detections.at(i).pose.pose.orientation.w;
+        
+        meas.head<3>() = sensor_p_ + sensor_q_ * meas.head<3>();
+        meas.tail<4>() = (sensor_q_ * Quaterniond(Vector4d(meas.tail<4>()))).coeffs();
+
         // PoseWithCovariance documentation:
         //   Row-major representation of the 6x6 covariance matrix.
         //   The orientation parameters use a fixed-axis representation.
         //   In order, the parameters are: (x, y, z, rotation about X axis, rotation about Y axis, rotation about Z axis)
-        MatrixXd cov(dim == 2 ? 3 : 6, dim == 2 ? 3 : 6);
+        MatrixXd cov = Eigen::Map<const Eigen::Matrix6d>(msg->detections.at(i).pose.covariance.data());
+        auto R = q2R(meas.tail<4>());
+        cov.topLeftCorner<3,3>() = R * cov.topLeftCorner<3,3>() * R.transpose();
+        //TODO: rotate covariance for orientation
+
+        // inverse measurement
+        if (inverse_detections_)
+        {
+            meas = SE3::inverse(meas);
+            cov.topLeftCorner<3,3>() = R.transpose() * cov.topLeftCorner<3,3>() * R;
+            //TODO: rotate covariance for orientation
+        }
+
+        // 2D
         if (dim == 2)
         {
-            cov << msg->detections.at(i).pose.covariance.at(0),  msg->detections.at(i).pose.covariance.at(1),  msg->detections.at(i).pose.covariance.at(5),
-                   msg->detections.at(i).pose.covariance.at(6),  msg->detections.at(i).pose.covariance.at(7),  msg->detections.at(i).pose.covariance.at(11),
-                   msg->detections.at(i).pose.covariance.at(30), msg->detections.at(i).pose.covariance.at(31), msg->detections.at(i).pose.covariance.at(35);
+            VectorXd meas2d = meas.head<3>();
+            meas2d(2) = getYaw(q2R(meas.tail<4>()));
+
+            MatrixXd cov2d(3,3);
+            cov2d << cov(0,0), cov(0,1), cov(0,5),
+                     cov(1,0), cov(1,1), cov(1,5),
+                     cov(5,0), cov(5,1), cov(5,5);
+
+            meas = meas2d;
+            cov = cov2d;
         }
-        else
-            cov = Eigen::Map<const Eigen::Matrix6d>(msg->detections.at(i).pose.covariance.data());
+        
+        std::cout << "\tid " << msg->detections.at(i).id << ": quality: " << msg->detections.at(i).quality << ", meas: " << meas.transpose() << std::endl;
 
         // fill capture
+        makePosDef(cov);
         cap->addDetection(msg->detections.at(i).id, meas, cov, msg->detections.at(i).quality);
     }