diff --git a/include/publisher_pose.h b/include/publisher_pose.h
index 29fdc157c095c4e81f57fd97c55b6b722e421251..dff4bac7531ea8fccf2c580fae43532f03aab046 100644
--- a/include/publisher_pose.h
+++ b/include/publisher_pose.h
@@ -14,6 +14,7 @@
 #include <ros/ros.h>
 #include <geometry_msgs/PoseArray.h>
 #include <visualization_msgs/Marker.h>
+#include <tf/transform_listener.h>
 
 namespace wolf
 {
@@ -25,6 +26,9 @@ class PublisherPose: public Publisher
         geometry_msgs::PoseArray pose_array_msg_;
         visualization_msgs::Marker marker_msg_;
         std_msgs::ColorRGBA marker_color_;
+        bool extrinsics_;
+        SensorBasePtr sensor_;
+        std::string frame_id_, map_frame_id_;
 
         ros::Publisher pub_pose_array_, pub_marker_;
 
@@ -41,6 +45,13 @@ class PublisherPose: public Publisher
         void publishDerived() override;
 
         void publishPose(const geometry_msgs::Pose pose, const ros::Time& stamp);
+
+    protected:
+
+        bool listenTf();
+        Eigen::Quaterniond q_frame_;
+        Eigen::Vector3d t_frame_;
+        tf::TransformListener tfl_;
 };
 
 WOLF_REGISTER_PUBLISHER(PublisherPose)
diff --git a/src/publisher_pose.cpp b/src/publisher_pose.cpp
index 337cf8413010eecbbb415ccbe79cb95ad0ed4ab5..ae27c1ef00cf99b831c80a41182d828019baa307 100644
--- a/src/publisher_pose.cpp
+++ b/src/publisher_pose.cpp
@@ -5,6 +5,7 @@
  **************************/
 #include <ros/ros.h>
 #include "tf/transform_datatypes.h"
+#include "tf_conversions/tf_eigen.h"
 
 namespace wolf
 {
@@ -24,23 +25,27 @@ PublisherPose::PublisherPose(const std::string& _unique_name,
         marker_color_.b = col(2);
         marker_color_.a = col(3);
     }
+    extrinsics_     = _server.getParam<bool>(prefix_ + "/extrinsics");
+    if (extrinsics_)
+        sensor_ = _problem->getSensor(_server.getParam<std::string>(prefix_ + "/sensor"));
+    frame_id_ = _server.getParam<std::string>(prefix_ + "/frame_id");
 }
 
 void PublisherPose::initialize(ros::NodeHandle& nh, const std::string& topic)
 {
     std::string map_frame_id;
-    nh.param<std::string>("map_frame_id", map_frame_id, "map");
+    nh.param<std::string>("map_frame_id", map_frame_id_, "map");
 
     // initialize msg and publisher
     if (pose_array_)
     {
-        pose_array_msg_.header.frame_id = map_frame_id;
+        pose_array_msg_.header.frame_id = frame_id_;
 
         pub_pose_array_ = nh.advertise<geometry_msgs::PoseArray>(topic + "_pose_array", 1);
     }
     if (marker_)
     {
-        marker_msg_.header.frame_id = map_frame_id;
+        marker_msg_.header.frame_id = frame_id_;
         marker_msg_.type = visualization_msgs::Marker::LINE_STRIP;
         marker_msg_.action = visualization_msgs::Marker::ADD;
         marker_msg_.ns = "trajectory";
@@ -65,31 +70,65 @@ void PublisherPose::publishDerived()
         return;
     }
 
-    // Fill Pose msg
-    geometry_msgs::Pose pose_msg;
+
+    // fill vector and quaternion
+    Eigen::Vector3d p = Eigen::Vector3d::Zero();
+    Eigen::Quaterniond q;
 
     // 2D
     if (problem_->getDim() == 2)
     {
-        pose_msg.position.x = current_state['P'](0);
-        pose_msg.position.y = current_state['P'](1);
-        pose_msg.position.z = 0;
-
-        pose_msg.orientation = tf::createQuaternionMsgFromYaw(current_state['O'](0));
+        if (extrinsics_)
+        {
+            p.head(2) = current_state['P'] + Eigen::Rotation2Dd(current_state['O'](0)) * sensor_->getP()->getState().head(2);
+            if (sensor_->getO())
+                q = Eigen::Quaterniond(Eigen::AngleAxisd(current_state['O'](0) + sensor_->getO()->getState()(0),
+                                                         Eigen::Vector3d::UnitZ()));
+            else
+                q = Eigen::Quaterniond(Eigen::AngleAxisd(current_state['O'](0),
+                                                         Eigen::Vector3d::UnitZ()));
+        }
+        else
+        {
+            p.head(2) = current_state['P'];
+            q = Eigen::Quaterniond(Eigen::AngleAxisd(current_state['O'](0), Eigen::Vector3d::UnitZ()));
+        }
     }
     // 3D
     else
     {
-        pose_msg.position.x = current_state['P'](0);
-        pose_msg.position.y = current_state['P'](1);
-        pose_msg.position.z = current_state['P'](2);
-
-        pose_msg.orientation.x = current_state['O'](0);
-        pose_msg.orientation.y = current_state['O'](1);
-        pose_msg.orientation.z = current_state['O'](2);
-        pose_msg.orientation.w = current_state['O'](3);
+        if (extrinsics_)
+        {
+            p = current_state['P'] + Eigen::Quaterniond(Eigen::Vector4d(current_state['O'])) * sensor_->getP()->getState();
+            if (sensor_->getO())
+                q = Eigen::Quaterniond(Eigen::Vector4d(current_state['O'])) * Eigen::Quaterniond(Eigen::Vector4d(sensor_->getO()->getState()));
+            else
+                q = Eigen::Quaterniond(Eigen::Vector4d(current_state['O']));
+        }
+        else
+        {
+            p = current_state['P'];
+            q = Eigen::Quaterniond(Eigen::Vector4d(current_state['O']));
+        }
     }
 
+    // Change frame
+    if (frame_id_ != map_frame_id_)
+    {
+        p = t_frame_ + q_frame_ * p;
+        q = q_frame_ * q;
+    }
+
+    // Fill Pose msg
+    geometry_msgs::Pose pose_msg;
+    pose_msg.position.x = p(0);
+    pose_msg.position.y = p(1);
+    pose_msg.position.z = p(2);
+
+    pose_msg.orientation.x = q.x();
+    pose_msg.orientation.y = q.y();
+    pose_msg.orientation.z = q.z();
+    pose_msg.orientation.w = q.w();
     publishPose(pose_msg, ros::Time(loc_ts.getSeconds(), loc_ts.getNanoSeconds()));
 }
 
@@ -112,4 +151,21 @@ void PublisherPose::publishPose(const geometry_msgs::Pose pose, const ros::Time&
     }
 }
 
+bool PublisherPose::listenTf()
+{
+    tf::StampedTransform T;
+    if ( tfl_.waitForTransform(map_frame_id_, frame_id_, ros::Time(0), ros::Duration(0.01)) )
+    {
+        tfl_.lookupTransform(map_frame_id_, frame_id_, ros::Time(0), T);
+
+        Eigen::Matrix3d R;
+        tf::matrixTFToEigen(T.getBasis(), R);
+        tf::vectorTFToEigen(T.getOrigin(), t_frame_);
+        q_frame_ = Eigen::Quaterniond(R);
+
+        return true;
+    }
+    return false;
+}
+
 }
diff --git a/src/visualizer.cpp b/src/visualizer.cpp
index 140c70d9ac39b9ed74322a3b6c65c5b44171c027..a3d5896abc558c98adf55e4dee605200dd1334ed 100644
--- a/src/visualizer.cpp
+++ b/src/visualizer.cpp
@@ -22,7 +22,7 @@ void Visualizer::initialize(ros::NodeHandle& nh)
     nh.param<bool>(         "viz_landmarks",            viz_landmarks_,             true);
     nh.param<bool>(         "viz_trajectory",           viz_trajectory_,            true);
     // viz parameters
-    nh.param<std::string>(  "map_frame_name",           map_frame_id_,              "map");
+    nh.param<std::string>(  "map_frame_id",             map_frame_id_,              "map");
     nh.param<double>(       "viz_scale",                viz_scale_,                 1);
     nh.param<double>(       "factors_width",            factors_width_,             0.02);
     nh.param<double>(       "factors_absolute_height",  factors_absolute_height_,   20);