diff --git a/cfg/CollisionManager.cfg b/cfg/CollisionManager.cfg
index f9f86bae3282136f0bb0f43a74fba8bf3aa3bd26..ad1f303ab71286eb60161520034a2e91d9b3bddf 100755
--- a/cfg/CollisionManager.cfg
+++ b/cfg/CollisionManager.cfg
@@ -47,15 +47,17 @@ gen.add("fixed_frame",                          str_t,      0,           "Fixed
 gen.add("base_link_frame",                      str_t,      0,           "Base_link frame",                                       "base_link")
 gen.add("tf_timeout",                           double_t,   0,           "Timeout to find a transform",                           0.2, 0.1, 2.0)
 
-collision_detection.add("collision_timeout",                        double_t,   0,           "Timeout to detect an end of collision",                            2.0, 1.0, 10.0)
+collision_detection.add("collision_timeout",                        double_t,   0,           "Timeout to detect an end of collision",                            2.0, 1.0, 30.0)
 collision_detection.add("collision_acc_transition_counter_en",      bool_t,     0,           "Enable the collision counter for the acc detection",               False)
 collision_detection.add("collision_acc_th",                         double_t,   0,           "Acceleration threshold to detect a collision",                     9.8,    0.1, 160.0)
 collision_detection.add("collision_acc_counter_limit",              int_t,      0,           "Number of low acc imu meassures to detect an end of collision",    6, 1, 30)
 collision_detection.add("collision_ang_vel_transition_counter_en",  bool_t,     0,           "Enable the collision counter",                                     False)
 collision_detection.add("collision_ang_vel_th",                     double_t,   0,           "Angular velocity threshold to detect a collision",                 0.3,    0.1, 1)
 collision_detection.add("collision_ang_vel_counter_limit",          int_t,      0,           "Number of low acc imu meassures to detect an end of collision",    3, 1, 30)
+collision_detection.add("odom_trans_th",                            double_t,   0,           "Max translational difference between wheels and ICP odometries",   0.1,    0.01, 0.3)
+collision_detection.add("odom_angular_th",                          double_t,   0,           "Max angular difference between wheels and ICP odometries in rad",  0.15,   0.05, 0.35)
 
-icp.add("scan_buffer_size",                     int_t,      0,           "Number of laser_scan buffered for the ICP",             3, 1, 10)
+icp.add("buffer_size",                          int_t,      0,           "Number of laser_scan and odometry buffered for the ICP",              3, 1, 30)
 icp.add("scan_diff_t_from_collision",           double_t,   0,           "Time to subtract from collision time stamp to ensure a clean scan",   0.0,    0.0, 0.5)
 icp.add("front_laser_en",                       bool_t,     0,           "Enable front laser for ICP",                            True)
 icp.add("rear_laser_en",                        bool_t,     0,           "Enable rear laser for ICP",                             True)
diff --git a/config/params.yaml b/config/params.yaml
index 743745751a9050c711dfa4eb2079ab2ae1ca9415..ad040c2b33bde6cbaafa404082ffd6fcd146d546 100644
--- a/config/params.yaml
+++ b/config/params.yaml
@@ -7,19 +7,20 @@ err_msg_rate: 0.5
 
 collision_timeout: 4.0
 collision_acc_transition_counter_en: True
-collision_acc_th: 4.0
-#collision_acc_th: 2.0
-collision_acc_counter_limit: 12
+collision_acc_th: 5.0
+collision_acc_counter_limit: 20
 collision_ang_vel_transition_counter_en: True
 collision_ang_vel_th: 0.4
 #collision_ang_vel_th: 0.2
-collision_ang_vel_counter_limit: 4
+collision_ang_vel_counter_limit: 20
+odom_trans_th: 0.1
+odom_angular_th: 0.15
 
 front_laser_en: True
 rear_laser_en: True
-scan_buffer_size: 6
-scan_diff_t_from_collision: 0.0
+buffer_size: 10
+scan_diff_t_from_collision: 0.15
 front_laser_en: True
 rear_laser_en: True
-icp_min_points: 100
-icp_max_err_by_points: 1.0
+icp_min_points: 280
+icp_max_err_by_points: 0.5
diff --git a/include/collision_manager_alg_node.h b/include/collision_manager_alg_node.h
index 5d6e95ac41f2a5132ce295379615d275629dd490..ad654bb8989746260e1613dffb7e8f06a9b1e7d9 100644
--- a/include/collision_manager_alg_node.h
+++ b/include/collision_manager_alg_node.h
@@ -56,6 +56,17 @@ typedef struct {
   ros::Time stamp; ///< Laser scan time stamp.
 }RangesWithStamp;
 
+/**
+ * \struct OdomWithStamp.
+ *
+ * \brief A struct with the Odometry information and the time stamp.
+ *
+ */
+typedef struct {
+  Eigen::Vector3d odom; ///< Odometry data.
+  ros::Time stamp; ///< Time stamp.
+}OdomWithStamp;
+
 /**
  * \brief IRI ROS Specific Algorithm Class
  *
@@ -87,9 +98,12 @@ class CollisionManagerAlgNode : public algorithm_base::IriBaseAlgorithm<Collisio
     std::list<RangesWithStamp> rear_ranges_; ///< Rear laser ranges buffer.
     bool is_front_icp_input_data_ok_; ///<Boolean to know of all the necessary data has been saved on the service request.
     bool is_rear_icp_input_data_ok_; ///<Boolean to know of all the necessary data has been saved on the service request.
-    bool front_icp_succedded_; ///< Boolean to know that ICP service was called withs success.
-    bool rear_icp_succedded_; ///< Boolean to know that ICP service was called withs success.
     double angular_vel_; ///< Robot's angular velocity from odometry.
+    std::string odom_frame_; ///< Odometry Frame id.
+    std::list<OdomWithStamp> odom_buffer_; ///< Odometry buffer.
+    Eigen::Vector3d odom_before_collision_; ///< Odometry data before collision.
+    Eigen::Vector3d odom_after_collision_; ///< Odometry data after collision.
+    bool odom_input_is_ok_; ///< Bool to know if the wheel odometry from a collision is ok.
 
     // [publisher attributes]
     ros::Publisher collisions_publisher_;
@@ -262,13 +276,18 @@ class CollisionManagerAlgNode : public algorithm_base::IriBaseAlgorithm<Collisio
     /**
      * \brief Function to find the last scan before a collision.
      * 
-     * \param _stamp The collision time stamp.
-     * 
      * \param _front To select the laser.
      * 
      * \return True if succeeded.
      */
-    bool set_ref_ranges(ros::Time _stamp, bool _front);
+    bool set_ref_ranges(bool _front);
+
+    /**
+     * \brief Function to find the last odometry before a collision.
+     * 
+     * \return True if succeeded.
+     */
+    bool set_odom_before_collision(void);
 
     /**
      * \brief Function to find the last scan after a collision.
@@ -279,6 +298,13 @@ class CollisionManagerAlgNode : public algorithm_base::IriBaseAlgorithm<Collisio
      */
     bool set_last_ranges(bool _front);
 
+    /**
+     * \brief Function to find the last odom after a collision.
+     * 
+     * \return True if succeeded.
+     */
+    bool get_last_odom(void);
+
     /**
      * \brief Function to load tf from base_link to fron/rear laser.
      * 
@@ -307,6 +333,38 @@ class CollisionManagerAlgNode : public algorithm_base::IriBaseAlgorithm<Collisio
      */
     bool get_base_link_new_pose_from_icp(const Eigen::Vector3d& _new_laser_pose, const Eigen::Matrix3d& _covariances, Eigen::Vector3d& _blink_pose, Eigen::Matrix3d& _blink_cov, const bool _front);
 
+    /**
+     * \brief Function to get the new robot's base_link pose from ICP result.
+     * 
+     * It checks that ICP result is good enough and calculates the pose.
+     * 
+     * \param _new_laser_pose New laser pose from ICP.
+     * 
+     * \param _covariances Laser pose covariances from ICP.
+     * 
+     * \param _odom The 2D base link pose.
+     * 
+     * \param _odom_cov Its covariances.
+     * 
+     * \param _odom_diff The ICP displacment on odom frame.
+     * 
+     * \param _front To select the laser.
+     * 
+     * \return True if succeeded.
+     */
+    bool get_icp_odometry(const Eigen::Vector3d& _new_laser_pose, const Eigen::Matrix3d& _covariances, Eigen::Vector3d& _odom, Eigen::Matrix3d& _odom_cov, Eigen::Vector3d& _odom_diff, const bool _front);
+
+    /**
+     * \brief Function to compare the odometry with the ICP to check that is actually a collision.
+     * 
+     * \param _icp_odometry ICP odometry result.
+     * 
+     * \param _icp_odometry_diff To return the odometry difference.
+     * 
+     * \return True if the difference is big enough.
+     */
+    bool check_odometry_diff(const Eigen::Vector3d& _icp_odometry, Eigen::Vector3d& _icp_odometry_diff);
+
    /**
     * \brief main node thread
     *
diff --git a/msg/collision.msg b/msg/collision.msg
index b825c40dbf4b829be2903be5ff99d613cccb0c43..8983d31be5746ad8f67d3b04b1ceba96d9807087 100644
--- a/msg/collision.msg
+++ b/msg/collision.msg
@@ -1,15 +1,19 @@
 Header header                           # Msg header.
+bool acc_trigger                        # If acc has trigger the collision detection.
 float32 acc_peak                        # Acceleration peak at collision
 float32 acc_angle                       # Estimation of the collision angle from accelerometer data.
 
+bool ang_vel_trigger                    # If angular velocity has trigger the collision detection.
 float32 ang_vel_diff                    # Angular velocity difference between IMU data and odometry.
 
+bool front_icp_check                    # If front ICP checks that is a collision.
 int32 front_icp_points                  # Front ICP laser scan matching points.
 float32 front_icp_err                   # Front ICP error per point.
-geometry_msgs/Pose2D front_laser_disp   # Front laser displacement.
-float32[9] front_covariance             # Front laser displacement covariance.
+geometry_msgs/Pose2D front_odom_diff    # Difference between Odometry and front laser ICP.
+float32[9] front_covariance             # Front ICP odometry covariance.
 
+bool rear_icp_check                     # If rear ICP checks that is a collision.
 int32 rear_icp_points                   # Rear ICP laser scan matching points.
 float32 rear_icp_err                    # Rear ICP error per point.
-geometry_msgs/Pose2D rear_laser_disp    # Rear laser displacement.
-float32[9] rear_covariance              # Rear laser displacement covariance.
+geometry_msgs/Pose2D rear_odom_diff     # Difference between Odometry and rear laser ICP.
+float32[9] rear_covariance              # Rear ICP odometry covariance.
diff --git a/rviz/dogs.rviz b/rviz/dogs.rviz
index 62dc34192dccb7a70964b447b27ea6aeb9d7e129..64e35553b8bb63f55465f140e8fa8d30b7c47d82 100644
--- a/rviz/dogs.rviz
+++ b/rviz/dogs.rviz
@@ -10,8 +10,7 @@ Panels:
         - /LandmarksRobotPose1/Covariance1
         - /LandmarksRobotPose1/Covariance1/Position1
         - /LandmarksRobotPose1/Covariance1/Orientation1
-        - /Rear_icp1/rear_after_icp1
-      Splitter Ratio: 0.5
+      Splitter Ratio: 0.6882352828979492
     Tree Height: 728
   - Class: rviz/Selection
     Name: Selection
@@ -54,6 +53,10 @@ Visualization Manager:
           Value: true
         map:
           Value: true
+        new_front_laser:
+          Value: true
+        new_rear_laser:
+          Value: true
         odom:
           Value: true
       Marker Scale: 1
@@ -66,9 +69,11 @@ Visualization Manager:
           odom:
             base_link:
               base_laser_front_link:
-                {}
+                new_front_laser:
+                  {}
               base_laser_rear_link:
-                {}
+                new_rear_laser:
+                  {}
               imu_bno055:
                 {}
       Update Interval: 0
@@ -417,7 +422,7 @@ Visualization Manager:
           Axis: Z
           Channel Name: intensity
           Class: rviz/LaserScan
-          Color: 206; 92; 0
+          Color: 52; 101; 164
           Color Transformer: FlatColor
           Decay Time: 0
           Enabled: true
@@ -563,7 +568,7 @@ Visualization Manager:
           Axis: Z
           Channel Name: intensity
           Class: rviz/LaserScan
-          Color: 173; 127; 168
+          Color: 252; 233; 79
           Color Transformer: FlatColor
           Decay Time: 0
           Enabled: true
@@ -621,7 +626,7 @@ Visualization Manager:
           Axis: Z
           Channel Name: intensity
           Class: rviz/LaserScan
-          Color: 252; 233; 79
+          Color: 239; 41; 41
           Color Transformer: FlatColor
           Decay Time: 0
           Enabled: true
@@ -679,11 +684,11 @@ Visualization Manager:
       Invert Z Axis: false
       Name: Current View
       Near Clip Distance: 0.009999999776482582
-      Scale: 30.226451873779297
+      Scale: 21.86640739440918
       Target Frame: base_link
       Value: TopDownOrtho (rviz)
-      X: 0.819812536239624
-      Y: 0.7132653594017029
+      X: -3.3158531188964844
+      Y: 3.8758318424224854
     Saved: ~
 Window Geometry:
   Displays:
diff --git a/src/collision_manager_alg_node.cpp b/src/collision_manager_alg_node.cpp
index 5296f3a591a71e71c352ce1242c0f5fa8757a5c2..67d0fd03d64c6b403dcb86d20d75b4c1e7c073a7 100644
--- a/src/collision_manager_alg_node.cpp
+++ b/src/collision_manager_alg_node.cpp
@@ -36,9 +36,8 @@ CollisionManagerAlgNode::CollisionManagerAlgNode(void) :
   this->is_rear_icp_input_data_ok_ = false;
   this->tf_base_link_front_laser_loaded_ = false;
   this->tf_base_link_rear_laser_loaded_ = false;
-  this->front_icp_succedded_ = false;
-  this->rear_icp_succedded_ = false;
   this->angular_vel_ = 0.0;
+  this->odom_input_is_ok_ = false;
 
   this->debug_rear_icp_pose_msg_.header.frame_id = this->config_.fixed_frame;
   this->debug_rear_icp_pose_msg_.pose.pose.position.z = 0.0;
@@ -106,8 +105,9 @@ void CollisionManagerAlgNode::mainNodeThread(void)
   this->rear_laser_scan_mutex_enter();
   this->front_laser_scan_mutex_enter();
   this->odom_mutex_enter();
-  Eigen::Vector3d blink_acc, blink_ang_vel, rear_blink_pose, front_blink_pose, new_laser_pose;
-  Eigen::Matrix3d rear_cov, front_cov, covariances;
+  Eigen::Vector3d blink_acc, blink_ang_vel, blink_pose, new_laser_pose, icp_odometry, icp_odometry_diff, diff_wheel_icp_odom;
+  Eigen::Matrix3d blink_cov, covariances, icp_odom_cov;
+  bool icp_succedded, icp_odom_calculated, icp_blink_pose_calculated, icp_is_collision;
 
   if (this->new_imu_input_)
   {
@@ -140,6 +140,7 @@ void CollisionManagerAlgNode::mainNodeThread(void)
 
           // ROS_INFO_STREAM("CollisionManagerAlgNode::mainNodeThread -> collision detected: angle estimated = " << this->front_icp_srv_.request.rot_angle_estimation);
 
+          this->odom_input_is_ok_ = (this->odom_input_is_ok_ && get_last_odom());
           // Call the service
           if (!(this->config_.front_laser_en || this->config_.rear_laser_en))
             ROS_WARN("CollisionManagerAlgNode::mainNodeThread -> Collision end detected but no laser is enabled.");
@@ -157,64 +158,101 @@ void CollisionManagerAlgNode::mainNodeThread(void)
                 // ROS_INFO_STREAM("   error " << front_icp_srv_.response.error);
                 // ROS_INFO_STREAM("   error/points " << front_icp_srv_.response.error/front_icp_srv_.response.nvalid << "; max " << this->config_.icp_max_err_by_points);
 
+                icp_succedded = true;
+
                 //update collison msg data.
                 this->collision_msg_.front_icp_err = front_icp_srv_.response.error/front_icp_srv_.response.nvalid;
-                this->collision_msg_.front_laser_disp = front_icp_srv_.response.new_laser_pose;
-                for (unsigned int i=0; i<9; i++)
-                  this->collision_msg_.front_covariance[i] = front_icp_srv_.response.covariance[i];
+                this->collision_msg_.front_icp_points = front_icp_srv_.response.nvalid;
 
-                if (front_icp_srv_.response.nvalid > this->config_.icp_min_points && front_icp_srv_.response.error/front_icp_srv_.response.nvalid < this->config_.icp_max_err_by_points)
+                //calculate new base_link pose in fixed frame coordenates
+                new_laser_pose << front_icp_srv_.response.new_laser_pose.x, front_icp_srv_.response.new_laser_pose.y, front_icp_srv_.response.new_laser_pose.theta;
+                covariances << front_icp_srv_.response.covariance[0], front_icp_srv_.response.covariance[1], front_icp_srv_.response.covariance[2],
+                                front_icp_srv_.response.covariance[3], front_icp_srv_.response.covariance[4], front_icp_srv_.response.covariance[5],
+                                front_icp_srv_.response.covariance[6], front_icp_srv_.response.covariance[7], front_icp_srv_.response.covariance[8];
+
+                icp_blink_pose_calculated = get_base_link_new_pose_from_icp(new_laser_pose, covariances, blink_pose, blink_cov, true);
+
+                //publish new laser tf to visualize the laser points.
+                if (this->config_.debug)
                 {
-                  new_laser_pose << front_icp_srv_.response.new_laser_pose.x, front_icp_srv_.response.new_laser_pose.y, front_icp_srv_.response.new_laser_pose.theta;
-                  covariances << front_icp_srv_.response.covariance[0], front_icp_srv_.response.covariance[1], front_icp_srv_.response.covariance[2],
-                                  front_icp_srv_.response.covariance[3], front_icp_srv_.response.covariance[4], front_icp_srv_.response.covariance[5],
-                                  front_icp_srv_.response.covariance[6], front_icp_srv_.response.covariance[7], front_icp_srv_.response.covariance[8];
-                  this->front_icp_succedded_ = true;
+                  this->transform_msg.header.frame_id = this->front_laser_frame_;
+                  this->transform_msg.child_frame_id = "new_front_laser";
+                  this->transform_msg.header.stamp = this->imu_stamp_;
+                  this->transform_msg.transform.translation.x = front_icp_srv_.response.new_laser_pose.x;
+                  this->transform_msg.transform.translation.y = front_icp_srv_.response.new_laser_pose.y;
+                  this->transform_msg.transform.translation.z = 0.0;
+                  tf2::Quaternion q;
+                  q.setRPY(0.0, 0.0, front_icp_srv_.response.new_laser_pose.theta);
+                  this->transform_msg.transform.rotation = tf2::toMsg(q);
+                  // this->transform_msg.transform.rotation.x = q.getRotation().x();
+                  // this->transform_msg.transform.rotation.y = q.getRotation().y();
+                  // this->transform_msg.transform.rotation.z = q.getRotation().z();
+                  // this->transform_msg.transform.rotation.w = q.getRotation().w();
+                  this->tf2_broadcaster.sendTransform(this->transform_msg);
+                }
 
-                  if (this->config_.debug)
+                if (front_icp_srv_.response.nvalid > this->config_.icp_min_points && front_icp_srv_.response.error/front_icp_srv_.response.nvalid < this->config_.icp_max_err_by_points)
+                {
+                  if (get_icp_odometry(new_laser_pose, covariances, icp_odometry, icp_odom_cov, icp_odometry_diff, true))
                   {
-                    this->transform_msg.header.frame_id = this->front_laser_frame_;
-                    this->transform_msg.child_frame_id = "new_front_laser";
-                    this->transform_msg.header.stamp = this->imu_stamp_;
-                    this->transform_msg.transform.translation.x = front_icp_srv_.response.new_laser_pose.x;
-                    this->transform_msg.transform.translation.y = front_icp_srv_.response.new_laser_pose.y;
-                    this->transform_msg.transform.translation.z = 0.0;
-                    tf2::Quaternion q;
-                    q.setRPY(0.0, 0.0, front_icp_srv_.response.new_laser_pose.theta);
-                    this->transform_msg.transform.rotation = tf2::toMsg(q);
-                    // this->transform_msg.transform.rotation.x = q.getRotation().x();
-                    // this->transform_msg.transform.rotation.y = q.getRotation().y();
-                    // this->transform_msg.transform.rotation.z = q.getRotation().z();
-                    // this->transform_msg.transform.rotation.w = q.getRotation().w();
-                    this->tf2_broadcaster.sendTransform(this->transform_msg);
+                    icp_odom_calculated = true;
+                    ROS_INFO_STREAM("Odom before collision " << this->odom_before_collision_);
+                    ROS_INFO_STREAM("Odom after collision " << this->odom_after_collision_);
+                    ROS_INFO_STREAM("New laser pose " << new_laser_pose);
+                    ROS_INFO_STREAM("ICP odom " << icp_odometry);
+                    ROS_INFO_STREAM("ICP odom diff " << icp_odometry_diff);
+                    icp_is_collision = check_odometry_diff(icp_odometry_diff, diff_wheel_icp_odom);
+
+                    // Update collision msg
+                    this->collision_msg_.front_odom_diff.x = diff_wheel_icp_odom(0);
+                    this->collision_msg_.front_odom_diff.y = diff_wheel_icp_odom(1);
+                    this->collision_msg_.front_odom_diff.theta = diff_wheel_icp_odom(2);
+                    for (unsigned int i=0; i<9; i++)
+                      this->collision_msg_.front_covariance[i] = icp_odom_cov(i);
+                  }
+                  else
+                  {
+                    this->collision_msg_.front_odom_diff.x = 0.0;
+                    this->collision_msg_.front_odom_diff.y = 0.0;
+                    this->collision_msg_.front_odom_diff.theta = 0.0;
+                    for (unsigned int i=0; i<9; i++)
+                      this->collision_msg_.front_covariance[i] = 0.0;
+                    icp_odom_calculated = false;
+                    icp_is_collision = false;
                   }
-
-                  this->front_icp_succedded_ = get_base_link_new_pose_from_icp(new_laser_pose, covariances, front_blink_pose, front_cov, true);
-
-                  this->collision_msg_.front_icp_points = front_icp_srv_.response.nvalid;
                 }
                 else
                 {
-                  this->collision_msg_.front_icp_points = 0;
-                  this->front_icp_succedded_ = false;
+                  this->collision_msg_.front_odom_diff.x = 0.0;
+                  this->collision_msg_.front_odom_diff.y = 0.0;
+                  this->collision_msg_.front_odom_diff.theta = 0.0;
+                  for (unsigned int i=0; i<9; i++)
+                    this->collision_msg_.front_covariance[i] = 0.0;
+                  icp_odom_calculated = false;
+                  icp_is_collision = false;
                 }
               }
               else
               {
-                this->front_icp_succedded_ = false;
+                icp_succedded = false;
+                icp_odom_calculated = false;
+                icp_is_collision = false;
+                icp_blink_pose_calculated = false;
                 this->collision_msg_.front_icp_points = 0;
                 ROS_ERROR("CollisionManagerAlgNode::mainNodeThread -> Failed to call service on topic %s",this->icp_client_.getService().c_str());
               }
+              this->collision_msg_.front_icp_check = icp_is_collision;
               if (this->config_.debug)
               {
                 this->debug_front_icp_last_scan_publisher_.publish(this->debug_front_icp_last_scan_msg_);
                 this->debug_front_icp_ref_scan_publisher_.publish(this->debug_front_icp_ref_scan_msg_);
-                if (this->front_icp_succedded_)
+                if (icp_succedded)
                 {
                   this->debug_front_after_icp_scan_msg_.header.frame_id = "new_front_laser";
                   this->debug_front_after_icp_scan_publisher_.publish(this->debug_front_after_icp_scan_msg_);
 
-                  this->debug_front_icp_pose_publisher_.publish(this->debug_front_icp_pose_msg_);
+                  if (icp_blink_pose_calculated)
+                    this->debug_front_icp_pose_publisher_.publish(this->debug_front_icp_pose_msg_);
                 }
               }
             }
@@ -230,64 +268,103 @@ void CollisionManagerAlgNode::mainNodeThread(void)
                 // ROS_INFO_STREAM("   error " << rear_icp_srv_.response.error);
                 // ROS_INFO_STREAM("   error/points " << rear_icp_srv_.response.error/rear_icp_srv_.response.nvalid << "; max " << this->config_.icp_max_err_by_points);
 
+                icp_succedded = true;
                 //update collison msg data.
                 this->collision_msg_.rear_icp_err = rear_icp_srv_.response.error/rear_icp_srv_.response.nvalid;
-                this->collision_msg_.rear_laser_disp = rear_icp_srv_.response.new_laser_pose;
-                for (unsigned int i=0; i<9; i++)
-                  this->collision_msg_.rear_covariance[i] = rear_icp_srv_.response.covariance[i];
+                this->collision_msg_.rear_icp_points = rear_icp_srv_.response.nvalid;
+                // this->collision_msg_.rear_laser_disp = rear_icp_srv_.response.new_laser_pose;
+                // for (unsigned int i=0; i<9; i++)
+                //   this->collision_msg_.rear_covariance[i] = rear_icp_srv_.response.covariance[i];
+
+                //calculate new base_link pose in fixed frame coordenates
+                new_laser_pose << rear_icp_srv_.response.new_laser_pose.x, rear_icp_srv_.response.new_laser_pose.y, rear_icp_srv_.response.new_laser_pose.theta;
+                covariances << rear_icp_srv_.response.covariance[0], rear_icp_srv_.response.covariance[1], rear_icp_srv_.response.covariance[2],
+                                rear_icp_srv_.response.covariance[3], rear_icp_srv_.response.covariance[4], rear_icp_srv_.response.covariance[5],
+                                rear_icp_srv_.response.covariance[6], rear_icp_srv_.response.covariance[7], rear_icp_srv_.response.covariance[8];
+                
+                icp_blink_pose_calculated = get_base_link_new_pose_from_icp(new_laser_pose, covariances, blink_pose, blink_cov, false);
+
+                //publish new laser tf to visualize the laser points.
+                if (this->config_.debug)
+                {
+                  this->transform_msg.header.frame_id = this->rear_laser_frame_;
+                  this->transform_msg.child_frame_id = "new_rear_laser";
+                  this->transform_msg.header.stamp = this->imu_stamp_;
+                  this->transform_msg.transform.translation.x = rear_icp_srv_.response.new_laser_pose.x;
+                  this->transform_msg.transform.translation.y = rear_icp_srv_.response.new_laser_pose.y;
+                  this->transform_msg.transform.translation.z = 0.0;
+                  tf2::Quaternion q;
+                  q.setRPY(0.0, 0.0, rear_icp_srv_.response.new_laser_pose.theta);
+                  this->transform_msg.transform.rotation = tf2::toMsg(q);
+                  // this->transform_msg.transform.rotation.x = q.getRotation().x();
+                  // this->transform_msg.transform.rotation.y = q.getRotation().y();
+                  // this->transform_msg.transform.rotation.z = q.getRotation().z();
+                  // this->transform_msg.transform.rotation.w = q.getRotation().w();
+                  this->tf2_broadcaster.sendTransform(this->transform_msg);
+                }
 
                 if (rear_icp_srv_.response.nvalid > this->config_.icp_min_points && rear_icp_srv_.response.error/rear_icp_srv_.response.nvalid < this->config_.icp_max_err_by_points)
                 {
-                  new_laser_pose << rear_icp_srv_.response.new_laser_pose.x, rear_icp_srv_.response.new_laser_pose.y, rear_icp_srv_.response.new_laser_pose.theta;
-                  covariances << rear_icp_srv_.response.covariance[0], rear_icp_srv_.response.covariance[1], rear_icp_srv_.response.covariance[2],
-                                  rear_icp_srv_.response.covariance[3], rear_icp_srv_.response.covariance[4], rear_icp_srv_.response.covariance[5],
-                                  rear_icp_srv_.response.covariance[6], rear_icp_srv_.response.covariance[7], rear_icp_srv_.response.covariance[8];
-                  this->rear_icp_succedded_ = true;
-
-                  if (this->config_.debug)
+                  if (get_icp_odometry(new_laser_pose, covariances, icp_odometry, icp_odom_cov, icp_odometry_diff, true))
                   {
-                    this->transform_msg.header.frame_id = this->rear_laser_frame_;
-                    this->transform_msg.child_frame_id = "new_rear_laser";
-                    this->transform_msg.header.stamp = this->imu_stamp_;
-                    this->transform_msg.transform.translation.x = rear_icp_srv_.response.new_laser_pose.x;
-                    this->transform_msg.transform.translation.y = rear_icp_srv_.response.new_laser_pose.y;
-                    this->transform_msg.transform.translation.z = 0.0;
-                    tf2::Quaternion q;
-                    q.setRPY(0.0, 0.0, rear_icp_srv_.response.new_laser_pose.theta);
-                    this->transform_msg.transform.rotation = tf2::toMsg(q);
-                    // this->transform_msg.transform.rotation.x = q.getRotation().x();
-                    // this->transform_msg.transform.rotation.y = q.getRotation().y();
-                    // this->transform_msg.transform.rotation.z = q.getRotation().z();
-                    // this->transform_msg.transform.rotation.w = q.getRotation().w();
-                    this->tf2_broadcaster.sendTransform(this->transform_msg);
+                    icp_odom_calculated = true;
+                    ROS_INFO_STREAM("Odom before collision " << this->odom_before_collision_);
+                    ROS_INFO_STREAM("Odom after collision " << this->odom_after_collision_);
+                    ROS_INFO_STREAM("New laser pose " << new_laser_pose);
+                    ROS_INFO_STREAM("ICP odom " << icp_odometry);
+                    ROS_INFO_STREAM("ICP odom diff " << icp_odometry_diff);
+                    icp_is_collision = check_odometry_diff(icp_odometry_diff, diff_wheel_icp_odom);
+
+                    // Update collision msg
+                    this->collision_msg_.rear_odom_diff.x = diff_wheel_icp_odom(0);
+                    this->collision_msg_.rear_odom_diff.y = diff_wheel_icp_odom(1);
+                    this->collision_msg_.rear_odom_diff.theta = diff_wheel_icp_odom(2);
+                    for (unsigned int i=0; i<9; i++)
+                      this->collision_msg_.rear_covariance[i] = icp_odom_cov(i);
+                  }
+                  else
+                  {
+                    this->collision_msg_.rear_odom_diff.x = 0.0;
+                    this->collision_msg_.rear_odom_diff.y = 0.0;
+                    this->collision_msg_.rear_odom_diff.theta = 0.0;
+                    for (unsigned int i=0; i<9; i++)
+                      this->collision_msg_.rear_covariance[i] = 0.0;
+                    icp_odom_calculated = false;
+                    icp_is_collision = false;
                   }
-
-                  this->rear_icp_succedded_ = get_base_link_new_pose_from_icp(new_laser_pose, covariances, rear_blink_pose, rear_cov, false);
-
-                  this->collision_msg_.rear_icp_points = rear_icp_srv_.response.nvalid;
                 }
                 else
                 {
-                  this->collision_msg_.rear_icp_points = 0;
-                  this->rear_icp_succedded_ = false;
+                  this->collision_msg_.rear_odom_diff.x = 0.0;
+                  this->collision_msg_.rear_odom_diff.y = 0.0;
+                  this->collision_msg_.rear_odom_diff.theta = 0.0;
+                  for (unsigned int i=0; i<9; i++)
+                    this->collision_msg_.rear_covariance[i] = 0.0;
+                  icp_odom_calculated = false;
+                  icp_is_collision = false;
                 }
               }
               else
               {
-                this->rear_icp_succedded_ = false;
+                icp_succedded = false;
+                icp_odom_calculated = false;
+                icp_is_collision = false;
+                icp_blink_pose_calculated = false;
                 this->collision_msg_.rear_icp_points = 0;
                 ROS_ERROR("CollisionManagerAlgNode::mainNodeThread -> Failed to call service on topic %s",this->icp_client_.getService().c_str());
               }
+              this->collision_msg_.rear_icp_check = icp_is_collision;
               if (this->config_.debug)
               {
                 this->debug_rear_icp_last_scan_publisher_.publish(this->debug_rear_icp_last_scan_msg_);
                 this->debug_rear_icp_ref_scan_publisher_.publish(this->debug_rear_icp_ref_scan_msg_);
-                if (this->rear_icp_succedded_)
+                if (icp_succedded)
                 {
                   this->debug_rear_after_icp_scan_msg_.header.frame_id = "new_rear_laser";
                   this->debug_rear_after_icp_scan_publisher_.publish(this->debug_rear_after_icp_scan_msg_);
 
-                  this->debug_rear_icp_pose_publisher_.publish(this->debug_rear_icp_pose_msg_);
+                  if (icp_blink_pose_calculated)
+                    this->debug_rear_icp_pose_publisher_.publish(this->debug_rear_icp_pose_msg_);
                 }
               }
             }
@@ -336,8 +413,8 @@ void CollisionManagerAlgNode::mainNodeThread(void)
           ROS_WARN("CollisionManagerAlgNode::mainNodeThread -> Collision detected but no laser is enabled.");
         else
         {
-          this->is_front_icp_input_data_ok_ = set_ref_ranges(this->collision_start_stamp_, true);
-          this->is_rear_icp_input_data_ok_ = set_ref_ranges(this->collision_start_stamp_, false);
+          this->is_front_icp_input_data_ok_ = set_ref_ranges(true);
+          this->is_rear_icp_input_data_ok_ = set_ref_ranges(false);
 
           if (!this->is_front_icp_input_data_ok_)
             this->collision_msg_.front_icp_points = 0;
@@ -345,6 +422,8 @@ void CollisionManagerAlgNode::mainNodeThread(void)
             this->collision_msg_.rear_icp_points = 0;
         }
 
+        this->odom_input_is_ok_ = set_odom_before_collision();
+
         //init variables
         this->in_collision_ = true;
         this->max_acc_ = blink_acc;
@@ -573,6 +652,12 @@ bool CollisionManagerAlgNode::check_start_of_collision(double _acc_norm_2d, doub
 {
   bool acc_true = check_acc_collision_transition(_acc_norm_2d, true);
   bool ang_vel_true = check_ang_vel_collision_transition(_ang_vel, true);
+
+  // update collision msg
+  if (acc_true)
+    this->collision_msg_.acc_trigger = true;
+  if (ang_vel_true)
+    this->collision_msg_.ang_vel_trigger = true;
   // if (acc_true)
   //   ROS_INFO_STREAM("CollisionManagerAlgNode::check_start_of_collision -> (START) Acc true. acc: " << _acc_norm_2d << "; vel: " << _ang_vel);
   // if (ang_vel_true)
@@ -580,7 +665,7 @@ bool CollisionManagerAlgNode::check_start_of_collision(double _acc_norm_2d, doub
   return acc_true || ang_vel_true;
 }
 
-bool CollisionManagerAlgNode::set_ref_ranges(ros::Time _stamp, bool _front)
+bool CollisionManagerAlgNode::set_ref_ranges(bool _front)
 {
   if (!(_front? this->config_.front_laser_en: this->config_.rear_laser_en))
     return false;
@@ -606,6 +691,24 @@ bool CollisionManagerAlgNode::set_ref_ranges(ros::Time _stamp, bool _front)
   return true;
 }
 
+bool CollisionManagerAlgNode::set_odom_before_collision(void)
+{
+  auto it = this->odom_buffer_.begin();
+  while ((it != this->odom_buffer_.end()) && (it->stamp > (this->collision_start_stamp_ - ros::Duration(this->config_.scan_diff_t_from_collision))))
+    ++it;
+  if (it == this->odom_buffer_.end())
+  {
+    ROS_WARN_STREAM("CollisionManagerAlgNode::set_odom_before_collision -> Collision detected at " << this->collision_start_stamp_ << " but there is no odometry before collision"); 
+    if (this->odom_buffer_.size() > 0)
+      ROS_WARN_STREAM("CollisionManagerAlgNode::set_odom_before_collision -> Odometry times: " << this->odom_buffer_.front().stamp << ", " << this->odom_buffer_.back().stamp);
+    else
+      ROS_WARN_STREAM("CollisionManagerAlgNode::set_odom_before_collision -> No Odometry buffered");
+    return false;
+  }
+  this->odom_before_collision_ = it->odom;
+  return true;
+}
+
 bool CollisionManagerAlgNode::set_last_ranges(bool _front)
 {
   if (!(_front? this->config_.front_laser_en: this->config_.rear_laser_en))
@@ -627,13 +730,21 @@ bool CollisionManagerAlgNode::set_last_ranges(bool _front)
   return false;
 }
 
+bool CollisionManagerAlgNode::get_last_odom(void)
+{
+  if (this->odom_buffer_.size() > 0)
+  {
+    this->odom_after_collision_ = this->odom_buffer_.front().odom;
+    return true;
+  }
+  ROS_WARN_STREAM("CollisionManagerAlgNode::get_last_odom -> No odom buffered");
+  return false;
+}
+
 bool CollisionManagerAlgNode::get_base_link_new_pose_from_icp(const Eigen::Vector3d& _new_laser_pose, const Eigen::Matrix3d& _covariances, Eigen::Vector3d& _blink_pose, Eigen::Matrix3d& _blink_cov, const bool _front)
 {
   geometry_msgs::TransformStamped tf_aux;
-  tf2::Transform tf_map_laser, tf_map_new_laser, tf_laser_new_laser, tf_map_new_blink;
-
-  if ((_front? !this->front_icp_succedded_: !this->rear_icp_succedded_))
-    return false;
+  tf2::Transform tf_map_laser, tf_map_new_laser, tf_laser_new_laser, tf_map_new_blink, tf_laser_map;
 
   if (!load_tf_blink_laser(_front))
     return false;
@@ -657,10 +768,11 @@ bool CollisionManagerAlgNode::get_base_link_new_pose_from_icp(const Eigen::Vecto
   tf_map_new_blink = tf_map_new_laser*(_front? this->tf_blink_front_laser: this->tf_blink_rear_laser).inverse();
   _blink_pose << tf_map_new_blink.getOrigin().x(), tf_map_new_blink.getOrigin().y(), tf2::getYaw(tf_map_new_blink.getRotation());
 
-  Eigen::Quaternion<double> rot(tf_map_laser.getRotation().w(), tf_map_laser.getRotation().x(), tf_map_laser.getRotation().y(), tf_map_laser.getRotation().z());
+  tf_laser_map = tf_map_laser.inverse();
+  Eigen::Quaternion<double> rot(tf_laser_map.getRotation().w(), tf_laser_map.getRotation().x(), tf_laser_map.getRotation().y(), tf_laser_map.getRotation().z());
   
-  Eigen::Transform<double,3,Eigen::Affine> map_laser_rot(rot);
-  _blink_cov = map_laser_rot*_covariances;
+  Eigen::Transform<double,3,Eigen::Affine> laser_map_rot(rot);
+  _blink_cov = laser_map_rot*_covariances;
 
   for (unsigned int i=0; i<9; i++)
     _blink_cov(i) = std::fabs(_blink_cov(i))*(_covariances(i) < 0? -1: 1);
@@ -700,6 +812,49 @@ bool CollisionManagerAlgNode::get_base_link_new_pose_from_icp(const Eigen::Vecto
   return true;
 }
 
+bool CollisionManagerAlgNode::get_icp_odometry(const Eigen::Vector3d& _new_laser_pose, const Eigen::Matrix3d& _covariances, Eigen::Vector3d& _odom, Eigen::Matrix3d& _odom_cov, Eigen::Vector3d& _odom_diff, const bool _front)
+{
+  geometry_msgs::TransformStamped tf_aux;
+  tf2::Transform tf_odom_laser, tf_odom_new_laser, tf_laser_new_laser, tf_odom_new_blink, tf_laser_odom, tf_odom_new_laser_diff, rot_odom_laser;
+
+  if (!load_tf_blink_laser(_front))
+    return false;
+
+  if (!this->tf2_buffer.canTransform(this->odom_frame_, (_front? this->front_laser_frame_: this->rear_laser_frame_), this->imu_stamp_, ros::Duration(this->config_.tf_timeout)))
+  {
+    ROS_WARN_STREAM("CollisionManagerAlgNode::get_icp_odometry -> Can't transform from " << this->odom_frame_ << " to " << (_front? this->front_laser_frame_: this->rear_laser_frame_) << " at " << this->imu_stamp_);
+    return false;
+  }
+  else
+  {
+    tf_aux = this->tf2_buffer.lookupTransform(this->odom_frame_, (_front? this->front_laser_frame_: this->rear_laser_frame_), this->imu_stamp_);
+    tf2::fromMsg(tf_aux.transform, tf_odom_laser);
+  }
+
+  tf2::Quaternion q;
+  q.setRPY(0.0, 0.0, _new_laser_pose(2));
+  tf_laser_new_laser = tf2::Transform(q, tf2::Vector3(_new_laser_pose(0), _new_laser_pose(1), 0.0));
+  tf_odom_new_laser = tf_odom_laser*tf_laser_new_laser;
+
+  tf_odom_new_blink = tf_odom_new_laser*(_front? this->tf_blink_front_laser: this->tf_blink_rear_laser).inverse();
+  _odom << tf_odom_new_blink.getOrigin().x(), tf_odom_new_blink.getOrigin().y(), tf2::getYaw(tf_odom_new_blink.getRotation());
+
+  tf_laser_odom = tf_odom_laser.inverse();
+  Eigen::Quaternion<double> rot(tf_laser_odom.getRotation().w(), tf_laser_odom.getRotation().x(), tf_laser_odom.getRotation().y(), tf_laser_odom.getRotation().z());
+  
+  Eigen::Transform<double,3,Eigen::Affine> laser_odom_rot(rot);
+  _odom_cov = laser_odom_rot*_covariances;
+
+  for (unsigned int i=0; i<9; i++)
+    _odom_cov(i) = std::fabs(_odom_cov(i))*(_covariances(i) < 0? -1: 1);
+
+  rot_odom_laser = tf2::Transform(tf_odom_laser.getRotation(), tf2::Vector3(0.0, 0.0, 0.0));
+  tf_odom_new_laser_diff = rot_odom_laser*tf_laser_new_laser;
+  _odom_diff <<  tf_odom_new_laser_diff.getOrigin().x(), tf_odom_new_laser_diff.getOrigin().y(), _new_laser_pose(2);
+
+  return true;
+}
+
 bool CollisionManagerAlgNode::load_tf_blink_laser(bool _front)
 {
   geometry_msgs::TransformStamped tf_aux;
@@ -720,6 +875,22 @@ bool CollisionManagerAlgNode::load_tf_blink_laser(bool _front)
   return true;
 }
 
+bool CollisionManagerAlgNode::check_odometry_diff(const Eigen::Vector3d& _icp_odometry, Eigen::Vector3d& _icp_odometry_diff)
+{
+  if (!this->odom_input_is_ok_)
+  {
+    ROS_WARN_STREAM("CollisionManagerAlgNode::check_odometry_diff -> No wheel odometry information has been saved. Odometry diff can't be calculated.");
+    _icp_odometry_diff << 0.0, 0.0, 0.0;
+    return false;
+  }
+  Eigen::Vector3d limits;
+  limits << this->config_.odom_trans_th, this->config_.odom_trans_th, this->config_.odom_angular_th;
+  _icp_odometry_diff = _icp_odometry - (this->odom_after_collision_ - this->odom_before_collision_);
+
+  Eigen::Matrix<bool, 3, 1> odom_check = _icp_odometry.array().abs() >= limits.array();
+  return (odom_check(0) || odom_check(1) || odom_check(2));
+}
+
 /*  [subscriber callbacks] */
 void CollisionManagerAlgNode::odom_callback(const nav_msgs::Odometry::ConstPtr& msg)
 {
@@ -728,7 +899,18 @@ void CollisionManagerAlgNode::odom_callback(const nav_msgs::Odometry::ConstPtr&
   //use appropiate mutex to shared variables if necessary
   //this->alg_.lock();
   this->odom_mutex_enter();
+  OdomWithStamp odom;
+  tf2::Transform tf;
+  tf2::fromMsg(msg->pose.pose, tf);
+  odom.stamp = msg->header.stamp;
+  odom.odom(0) = msg->pose.pose.position.x;
+  odom.odom(1) = msg->pose.pose.position.y;
+  odom.odom(2) = tf2::getYaw(tf.getRotation());
+  if (this->odom_buffer_.size() >= this->config_.buffer_size)
+    this->odom_buffer_.pop_back();
+  this->odom_buffer_.push_front(odom);
   this->angular_vel_ = msg->twist.twist.angular.z;
+  this->odom_frame_ = msg->header.frame_id;
 
   //std::cout << msg->data << std::endl;
   //unlock previously blocked shared variables
@@ -786,7 +968,7 @@ void CollisionManagerAlgNode::rear_laser_scan_callback(const sensor_msgs::LaserS
     RangesWithStamp r;
     r.ranges = msg->ranges;
     r.stamp = msg->header.stamp;
-    if (this->rear_ranges_.size() >= this->config_.scan_buffer_size)
+    if (this->rear_ranges_.size() >= this->config_.buffer_size)
       this->rear_ranges_.pop_back();
     this->rear_ranges_.push_front(r);
   }
@@ -846,7 +1028,7 @@ void CollisionManagerAlgNode::front_laser_scan_callback(const sensor_msgs::Laser
     RangesWithStamp r;
     r.ranges = msg->ranges;
     r.stamp = msg->header.stamp;
-    if (this->front_ranges_.size() >= this->config_.scan_buffer_size)
+    if (this->front_ranges_.size() >= this->config_.buffer_size)
       this->front_ranges_.pop_back();
     this->front_ranges_.push_front(r);
   }
@@ -913,11 +1095,6 @@ void CollisionManagerAlgNode::node_config_update(Config &config, uint32_t level)
   this->rear_laser_scan_mutex_enter();
   this->front_laser_scan_mutex_enter();
 
-  if (!config.front_laser_en)
-    this->front_icp_succedded_ = false;
-  if (!config.rear_laser_en)
-    this->rear_icp_succedded_ = false;
-
   if(config.rate!=this->getRate())
     this->setRate(config.rate);
   this->config_=config;