diff --git a/include/htc_vive_tracker_alg_node.h b/include/htc_vive_tracker_alg_node.h
index 30b6bbef1152a0c11e5d2d93b77d3f793ea10e26..566131516fd47df82184c766168ad7655901f857 100644
--- a/include/htc_vive_tracker_alg_node.h
+++ b/include/htc_vive_tracker_alg_node.h
@@ -38,6 +38,8 @@
 #include "geometry_msgs/PoseStamped.h"
 
 #include <nav_msgs/Odometry.h>
+
+#include <boost/circular_buffer.hpp>
 // [publisher subscriber headers]
  
 // [service client headers]
@@ -52,7 +54,8 @@ class HtcViveTrackerAlgNode : public algorithm_base::IriBaseAlgorithm<HtcViveTra
 {
   private:
     // [publisher attributes]
-    ros::Publisher vo_publisher_;
+    ros::Publisher vo_t1_publisher_;
+    ros::Publisher vo_c1_publisher_;
     ros::Publisher pose_publisher_;
     //Transformation from base to world. In this case, WAM to CHAPERONE
  
@@ -79,7 +82,18 @@ class HtcViveTrackerAlgNode : public algorithm_base::IriBaseAlgorithm<HtcViveTra
     uint32_t haptic_pulse_strength_;
     bool publish_hmd_;
     bool frame_names_set;
-
+    float controller_v_x;
+    float controller_v_y;
+    float controller_v_z;
+    float tracker_v_x;
+    float tracker_v_y;
+    float tracker_v_z;
+    boost::circular_buffer<float> C_x_buffer;
+    boost::circular_buffer<float> C_y_buffer;
+    boost::circular_buffer<float> C_z_buffer;
+    boost::circular_buffer<float> T_x_buffer;
+    boost::circular_buffer<float> T_y_buffer;
+    boost::circular_buffer<float> T_z_buffer;
     std::string target_frame_name_;
 
     ros::ServiceServer trigger_pulse_server_;
@@ -158,7 +172,7 @@ class HtcViveTrackerAlgNode : public algorithm_base::IriBaseAlgorithm<HtcViveTra
     
     tf::Quaternion ApplyZRotation(const tf::Quaternion & orig);
 
-    nav_msgs::Odometry CreateOdometryFromPoseVel(const geometry_msgs::Pose & pose, const Velocity & vel);
+    nav_msgs::Odometry CreateOdometryFromPoseVel(const geometry_msgs::Pose & pose, const Velocity & vel, const std::string &device_name);
     
 };
 
diff --git a/src/htc_vive_tracker_alg_node.cpp b/src/htc_vive_tracker_alg_node.cpp
index 2cead2762f06a0cbbd9ad57dc7b7c7e8ffbcc0f7..4c56d75a5770a233f5f5b04193faa1a2bc588473 100644
--- a/src/htc_vive_tracker_alg_node.cpp
+++ b/src/htc_vive_tracker_alg_node.cpp
@@ -8,7 +8,7 @@ HtcViveTrackerAlgNode::HtcViveTrackerAlgNode(void) :
 	this->public_node_handle_.getParam("loop_rate", loop_rate);
    } else {
 	ROS_INFO ("Using default loop_rate!");
-	loop_rate = 20;
+	loop_rate = 50;
    }
 
    this->setRate(loop_rate);
@@ -32,11 +32,24 @@ HtcViveTrackerAlgNode::HtcViveTrackerAlgNode(void) :
     }
     
 
-
+    controller_v_x=0;
+    controller_v_y=0;
+    controller_v_z=0;
+    tracker_v_x=0;
+    tracker_v_y=0;
+    tracker_v_z=0;
+    
+    this->C_x_buffer.set_capacity(5);  
+    this->C_y_buffer.set_capacity(5);  
+    this->C_z_buffer.set_capacity(5);  
+    this->T_x_buffer.set_capacity(5);  
+    this->T_y_buffer.set_capacity(5);  
+    this->T_z_buffer.set_capacity(5);  
 
   // [init publishers]
   
-    vo_publisher_ = this->public_node_handle_.advertise<nav_msgs::Odometry>("vo",100);
+    vo_t1_publisher_ = this->public_node_handle_.advertise<nav_msgs::Odometry>("vo_tracker_1",100);
+    vo_c1_publisher_ = this->public_node_handle_.advertise<nav_msgs::Odometry>("vo_controller_1",100);
     pose_publisher_ = this->public_node_handle_.advertise<geometry_msgs::PoseStamped>("new_pose",100);
   
   // [init subscribers]
@@ -158,32 +171,31 @@ void HtcViveTrackerAlgNode::BroadcastPoseRotated(const std::string & device_name
 	
     if (this->alg_.GetDevicePositionQuaternion(device_name,pose,quaternion)) {
 
-
-   	tf::Quaternion q = tf::Quaternion(quaternion[0], quaternion[1], quaternion[2], quaternion[3]);
-	
-	//Apply the necessary rotations so that the coordinate system is the one decided at IRI
-	q = this -> ApplyRotationForIRIStandardCoordinates(q);
-
-  if (device_name == "tracker_1" || device_name == "tracker_2" || device_name == "tracker_3" ){
-      q = this ->ApplyZRotation(q);
-  }
-
-	this->transform_stamped_.header.stamp = ros::Time::now();
-	this->transform_stamped_.header.frame_id = this->alg_.WORLD_NAME;
-    transform_stamped_.child_frame_id = device_name;
-	transform_stamped_.transform.translation.x = pose[0];
-	transform_stamped_.transform.translation.y = pose[1];
-	transform_stamped_.transform.translation.z = pose[2];
-	
-	transform_stamped_.transform.rotation.x = q.x();
-	transform_stamped_.transform.rotation.y = q.y();
-	transform_stamped_.transform.rotation.z = q.z();
-	transform_stamped_.transform.rotation.w = q.w();
-
-
-	tf_broadcaster.sendTransform(transform_stamped_);
-    //If the device is the one we want to follow, also publish the Odometry
-    if (this->frame_names_set && device_name == this->target_frame_name_){
+      tf::Quaternion q = tf::Quaternion(quaternion[0], quaternion[1], quaternion[2], quaternion[3]);
+
+      //Apply the necessary rotations so that the coordinate system is the one decided at IRI
+      q = this -> ApplyRotationForIRIStandardCoordinates(q);
+
+      if (device_name == "tracker_1" || device_name == "tracker_2" || device_name == "tracker_3" ){
+        q = this ->ApplyZRotation(q);
+      }
+
+      this->transform_stamped_.header.stamp = ros::Time::now();
+      this->transform_stamped_.header.frame_id = this->alg_.WORLD_NAME;
+      this->transform_stamped_.child_frame_id = device_name;
+      this->transform_stamped_.transform.translation.x = pose[0];
+      this->transform_stamped_.transform.translation.y = pose[1];
+      this->transform_stamped_.transform.translation.z = pose[2];
+      this->transform_stamped_.transform.rotation.x = q.x();
+      this->transform_stamped_.transform.rotation.y = q.y();
+      this->transform_stamped_.transform.rotation.z = q.z();
+      this->transform_stamped_.transform.rotation.w = q.w();
+      tf_broadcaster.sendTransform(transform_stamped_);
+
+      //If the device is the one we want to follow, also publish the Odometry
+      if (this->frame_names_set){
+      if (device_name == "tracker_1" || device_name == "controller_1" ){
+      //if (this->frame_names_set && device_name == this->target_frame_name_){
         geometry_msgs::Pose device_pose;
         device_pose.position.x = pose[0];
         device_pose.position.y = pose[1];
@@ -192,10 +204,16 @@ void HtcViveTrackerAlgNode::BroadcastPoseRotated(const std::string & device_name
         device_pose.orientation.y = q.y();
         device_pose.orientation.z = q.z();
         device_pose.orientation.w = q.w();
-        Velocity device_vel = this->alg_.GetDeviceVelocity(this->target_frame_name_);
-        nav_msgs::Odometry current_vo = this->CreateOdometryFromPoseVel(device_pose, device_vel);
-        this->vo_publisher_.publish(current_vo);
-    }
+        Velocity device_vel = this->alg_.GetDeviceVelocity(device_name);
+        nav_msgs::Odometry current_vo = this->CreateOdometryFromPoseVel(device_pose, device_vel, device_name);
+        if (device_name == "tracker_1") 
+          this->vo_t1_publisher_.publish(current_vo);
+        else if (device_name == "controller_1")
+          this->vo_c1_publisher_.publish(current_vo);
+        else
+          std::cout << "This is not possible" << std::endl;
+      }
+      }
     }
 
 }
@@ -258,15 +276,60 @@ tf::Quaternion HtcViveTrackerAlgNode::ApplyZRotation(const tf::Quaternion & orig
 }
 
 
-nav_msgs::Odometry HtcViveTrackerAlgNode::CreateOdometryFromPoseVel(const geometry_msgs::Pose & pose, const Velocity & vel){
+nav_msgs::Odometry HtcViveTrackerAlgNode::CreateOdometryFromPoseVel(const geometry_msgs::Pose & pose, const Velocity & vel, const std::string &device_name){
     
     geometry_msgs::TwistWithCovariance twist_msg;
-    twist_msg.twist.linear.x = vel.linear_velocity.x;
-    twist_msg.twist.linear.y = vel.linear_velocity.y;
-    twist_msg.twist.linear.z = vel.linear_velocity.z;
+    if (device_name == "tracker_1"){  
+      T_x_buffer.push_back(vel.linear_velocity.x);
+      T_y_buffer.push_back(vel.linear_velocity.y);
+      T_z_buffer.push_back(vel.linear_velocity.z);
+
+      float v_x = 0;
+      float v_y = 0;
+      float v_z = 0;
+
+      for(unsigned int i=0; i<T_x_buffer.size(); i++){
+        v_x += T_x_buffer[i];
+        v_y += T_y_buffer[i];
+        v_z += T_z_buffer[i];
+      }
+
+      twist_msg.twist.linear.x = v_x/(T_x_buffer.size());
+      twist_msg.twist.linear.y = v_z/(T_z_buffer.size());
+      twist_msg.twist.linear.z = v_y/(T_y_buffer.size());
+     // this->tracker_v_x = vel.linear_velocity.x;
+     // this->tracker_v_y = vel.linear_velocity.y;
+     // this->tracker_v_z = vel.linear_velocity.z;
+    }
+    else if (device_name == "controller_1"){
+      C_x_buffer.push_back(vel.linear_velocity.x);
+      C_y_buffer.push_back(vel.linear_velocity.y);
+      C_z_buffer.push_back(vel.linear_velocity.z);
+
+      float v_x = 0;
+      float v_y = 0;
+      float v_z = 0;
+
+      for(unsigned int i=0; i<C_x_buffer.size(); i++){
+        v_x += C_x_buffer[i];
+        v_y += C_y_buffer[i];
+        v_z += C_z_buffer[i];
+      }
+
+      twist_msg.twist.linear.x = v_x/(C_x_buffer.size());
+      twist_msg.twist.linear.y = v_z/(C_z_buffer.size());
+      twist_msg.twist.linear.z = v_y/(C_y_buffer.size());
+     // twist_msg.twist.linear.x = (vel.linear_velocity.x+this->controller_v_x)/2;
+     // twist_msg.twist.linear.y = (vel.linear_velocity.z+this->controller_v_z)/2;
+     // twist_msg.twist.linear.z = (vel.linear_velocity.y+this->controller_v_y)/2;
+     // this->controller_v_x = vel.linear_velocity.x;
+     // this->controller_v_y = vel.linear_velocity.y;
+     // this->controller_v_z = vel.linear_velocity.z;
+    }
+
     twist_msg.twist.angular.x = vel.angular_velocity.x;
-    twist_msg.twist.angular.y = vel.angular_velocity.y;
-    twist_msg.twist.angular.z = vel.angular_velocity.z;
+    twist_msg.twist.angular.y = vel.angular_velocity.z;
+    twist_msg.twist.angular.z = vel.angular_velocity.y;
 
     twist_msg.covariance = {{0.01, 0, 0, 0, 0, 0,  // covariance on pose x
                                 0, 0.01, 0, 0, 0, 0,  // covariance on pose y
@@ -287,7 +350,8 @@ nav_msgs::Odometry HtcViveTrackerAlgNode::CreateOdometryFromPoseVel(const geomet
     nav_msgs::Odometry odom;
     odom.header.stamp = ros::Time::now();
     odom.header.frame_id = this->alg_.WORLD_NAME; 
-    odom.child_frame_id = this->target_frame_name_;
+    //odom.child_frame_id = this->target_frame_name_;
+    odom.child_frame_id = device_name;
     odom.pose = pose_msg;
     odom.twist = twist_msg;
     return odom;