diff --git a/rotational_recovery/include/rotational_recovery/rotational_recovery.h b/rotational_recovery/include/rotational_recovery/rotational_recovery.h
index a2b0feceeeef2bef9bc137c1a0db13cd5f0a9497..15f16640d9a51d53eeb13839a55f7aef1d0abc54 100644
--- a/rotational_recovery/include/rotational_recovery/rotational_recovery.h
+++ b/rotational_recovery/include/rotational_recovery/rotational_recovery.h
@@ -31,6 +31,8 @@ namespace rotational_recovery
 
     private:
 
+      void escapeFromLethalCost(const geometry_msgs::Pose2D& current_position, geometry_msgs::Twist& twist, const double cost);
+      void moveRobot(const geometry_msgs::Twist& twist, const double max_duration);
       geometry_msgs::Pose2D getCurrentLocalPose () const;
       geometry_msgs::Twist scaleGivenAccelerationLimits (const geometry_msgs::Twist& twist, const double time_remaining) const;
       double normalizedPoseCost (const geometry_msgs::Pose2D& pose) const;
diff --git a/rotational_recovery/src/rotational_recovery.cpp b/rotational_recovery/src/rotational_recovery.cpp
index 23aab7d28f739b070bb4262434dd65b91f24d530..96bbaabb342ab1198f9bf6f4dbe8595bfa8f810b 100644
--- a/rotational_recovery/src/rotational_recovery.cpp
+++ b/rotational_recovery/src/rotational_recovery.cpp
@@ -259,35 +259,346 @@ namespace rotational_recovery
   }
 
 
+  // Apply the given twist during the given time
+  void RotationalRecovery::moveRobot(const geometry_msgs::Twist& twist, const double max_duration)
+  {
+    ros::Rate r(controller_frequency_);
+    ROS_WARN_NAMED ("top", "Applying Twist recovery (%.2f, %.2f, %.2f) for %.2f seconds", twist.linear.x,
+    twist.linear.y, twist.angular.z, max_duration);
+
+    // We will now apply this twist open-loop for d seconds (scaled so we can
+    // guarantee stopping at the end)
+    for (double t=0; t<max_duration; t+=1/controller_frequency_) {
+      pub_.publish(scaleGivenAccelerationLimits(twist, max_duration-t));
+      r.sleep();
+    }
+    return;
+  }
+
+  // Apply algorithm to escape from a lethal obstacle
+  void RotationalRecovery::escapeFromLethalCost(const geometry_msgs::Pose2D& current_position, geometry_msgs::Twist& twist, const double cost)
+  {
+    double cost_front_1, cost_front_2, cost_front_3 = 0;
+    double cost_back_1, cost_back_2, cost_back_3 = 0;
+    double cost_left_1, cost_left_2, cost_left_3 = 0;
+    double cost_right_1, cost_right_2, cost_right_3 = 0;
+    double t = 0.0;
+    int count_cost = 0;
+
+    // Simulate cost moving 1 global_cmap's cell in each direction
+    t = 0.2;
+    twist.linear.x = 1.0;
+    cost_front_1 = normalizedPoseCost(forwardSimulate(current_position, twist, t));
+    twist.linear.x = -1.0;
+    cost_back_1 = normalizedPoseCost(forwardSimulate(current_position, twist, t));
+
+    twist.linear.x = 0.0;
+    twist.linear.y = 1.0;
+    cost_left_1 = normalizedPoseCost(forwardSimulate(current_position, twist, t));
+    twist.linear.y = -1.0;
+    cost_right_1 = normalizedPoseCost(forwardSimulate(current_position, twist, t));
+
+    // Simulate cost moving 2 global_cmap's cell in each direction
+    t = 0.4;
+    twist.linear.x = 1.0;
+    cost_front_2 = normalizedPoseCost(forwardSimulate(current_position, twist, t));
+    twist.linear.x = -1.0;
+    cost_back_2 = normalizedPoseCost(forwardSimulate(current_position, twist, t));
+
+    twist.linear.x = 0.0;
+    twist.linear.y = 1.0;
+    cost_left_2 = normalizedPoseCost(forwardSimulate(current_position, twist, t));
+    twist.linear.y = -1.0;
+    cost_right_2 = normalizedPoseCost(forwardSimulate(current_position, twist, t));
+
+    // Simulate cost moving 3 global_cmap's cell in each direction
+    t = 0.6;
+    twist.linear.x = 1.0;
+    cost_front_3 = normalizedPoseCost(forwardSimulate(current_position, twist, t));
+    twist.linear.x = -1.0;
+    cost_back_3 = normalizedPoseCost(forwardSimulate(current_position, twist, t));
+
+    twist.linear.x = 0.0;
+    twist.linear.y = 1.0;
+    cost_left_3 = normalizedPoseCost(forwardSimulate(current_position, twist, t));
+    twist.linear.y = -1.0;
+    cost_right_3 = normalizedPoseCost(forwardSimulate(current_position, twist, t));
+
+    twist.linear.x = 0.0;
+    twist.linear.y = 0.0;
+    twist.angular.z = 0.0;
+
+    ROS_INFO_NAMED ("top", "Original cost: %.2f", cost);
+    ROS_INFO_NAMED ("top", "1st costs: %.2f, %.2f, %.2f, %.2f", cost_front_1, cost_back_1, cost_left_1, cost_right_1);
+    ROS_INFO_NAMED ("top", "2nd costs: %.2f, %.2f, %.2f, %.2f", cost_front_2, cost_back_2, cost_left_2, cost_right_2);
+    ROS_INFO_NAMED ("top", "3rd costs: %.2f, %.2f, %.2f, %.2f", cost_front_3, cost_back_3, cost_left_3, cost_right_3);
+
+    if (cost_front_1 >= cost) count_cost++;
+    if (cost_back_1 >= cost) count_cost++;
+    if (cost_left_1 >= cost) count_cost++;
+    if (cost_right_1 >= cost) count_cost++;
+
+    switch(count_cost){
+      case 0: // If we are executing this function, there must be at least 1 lethal cost so this is Impossible
+        return;
+
+      case 1: // Moving just 1 cell arround and obtaining just 1 lethal cost means that our current cost is not lethal. Impossible
+        return;
+
+      case 2: // Two lethal costs mean a little edge
+        // Technically it is impossible that both front and back movements imply a lethal cost as well as both left and right
+        // So the question is to know towards which direction move the robot and towards which side turn it.
+        // 1st movement: move away
+        if (cost_front_1 >= cost) { // Lethal cost in the front, move backwards
+          if (cost_back_2 >= cost) { // Lethal cost too near the back, move just a bit
+            twist.linear.x = -0.2;
+            twist.linear.y = 0.0;
+            twist.angular.z = 0.0;
+            double max_duration = 1.0;
+            moveRobot(twist, max_duration);
+          }
+          else { // No problem at the back, move further
+            twist.linear.x = -0.2;
+            twist.linear.y = 0.0;
+            twist.angular.z = 0.0;
+            double max_duration = 2.0;
+            moveRobot(twist, max_duration);
+          }
+        }
+        else { // Lethal cost at the back, move forwards
+          if (cost_front_2 >= cost) { // Lethal cost too near the front, move just a bit
+            twist.linear.x = 0.2;
+            twist.linear.y = 0.0;
+            twist.angular.z = 0.0;
+            double max_duration = 1.0;
+            moveRobot(twist, max_duration);
+          }
+          else { // No problem, move further
+            twist.linear.x = 0.2;
+            twist.linear.y = 0.0;
+            twist.angular.z = 0.0;
+            double max_duration = 2.0;
+            moveRobot(twist, max_duration);
+          }
+        }
+        // 2nd movement: turn
+        if (cost_left_1 >= cost) { // Lethal cost on the left, move towards right
+          twist.linear.x = 0.0;
+          twist.linear.y = 0.0;
+          twist.angular.z = -0.5;
+          double max_duration = 1.5708/0.5; // Turn pi/2 rad
+          moveRobot(twist, max_duration);
+        }
+        else { // Lethal cost on the right, move towards left
+          twist.linear.x = 0.0;
+          twist.linear.y = 0.0;
+          twist.angular.z = 0.5;
+          double max_duration = 1.5708/0.5; // Turn pi/2 rad
+          moveRobot(twist, max_duration);
+        }
+        return;
+
+      case 3: // Three lethal cost mean a wall or a big edge
+        // There are two possibilities:
+        // 1. The obstacle is at the robot's front/back so it can move backwards/forwards without problems
+        // 2. The obstacle is at one side so it's necessary to know how long the robot must move forward or
+        // backward to create a gap big enough to turn to the other side
+        if (cost_back_1 < cost) { // Case 1.backwards
+          if (cost_back_2 >= cost) { // Lethal cost too near the back, move just a bit
+            twist.linear.x = -0.2;
+            twist.linear.y = 0.0;
+            twist.angular.z = 0.0;
+            double max_duration = 1.0;
+            moveRobot(twist, max_duration);
+          }
+          else { // No problem at the back, move further
+            twist.linear.x = -0.2;
+            twist.linear.y = 0.0;
+            twist.angular.z = 0.0;
+            double max_duration = 2.0;
+            moveRobot(twist, max_duration);
+          }
+        }
+        else if (cost_front_1 < cost) { // Case 1.forwards
+          if (cost_front_2 >= cost) { // Lethal cost too near the front, move just a bit
+            twist.linear.x = 0.2;
+            twist.linear.y = 0.0;
+            twist.angular.z = 0.0;
+            double max_duration = 1.0;
+            moveRobot(twist, max_duration);
+          }
+          else { // No problem, move further
+            twist.linear.x = 0.2;
+            twist.linear.y = 0.0;
+            twist.angular.z = 0.0;
+            double max_duration = 2.0;
+            moveRobot(twist, max_duration);
+          }
+        }
+        else { // Case 2
+          if (cost_left_1 >= cost) { // Lethal cost on the left, move towards right
+            double min_time = 0.2;
+            double turn_duration = 0.0;
+            bool move_for = true;
+            twist.linear.x = 0.0;
+            twist.linear.y = 0.0;
+            twist.angular.z = 0.0;
+            // Iterate until some movement (forward or backwards) allows the robot to rotate
+            while(true){
+              twist.linear.x = 1.0;
+              geometry_msgs::Pose2D forw = forwardSimulate(current_position, twist, min_time);
+              twist.linear.x = 0.0;
+              twist.linear.y = 1.0;
+              geometry_msgs::Pose2D forw_left = forwardSimulate(forw, twist, 0.2);
+              twist.linear.y = 0.0;
+              double cost_forw_left = normalizedPoseCost(forw_left);
+              if (cost_forw_left < cost) {
+                move_for = true;
+                break;
+              }
+
+              twist.linear.x = -1.0;
+              geometry_msgs::Pose2D backw = forwardSimulate(current_position, twist, min_time);
+              twist.linear.x = 0.0;
+              twist.linear.y = 1.0;
+              geometry_msgs::Pose2D backw_left = forwardSimulate(backw, twist, 0.2);
+              twist.linear.y = 0.0;
+              double cost_backw_left = normalizedPoseCost(backw_left);
+
+              if (cost_backw_left < cost) {
+                move_for = false;
+                break;
+              }
+              min_time = min_time + 0.2;
+            }
+            // At this point we know the time necessary to allow the robot to rotate
+            if (move_for) {
+              twist.linear.x = 0.2;
+              twist.linear.y = 0.0;
+              twist.angular.z = 0.0;
+              moveRobot(twist, 5.0*min_time);
+            }
+            else {
+              twist.linear.x = -0.2;
+              twist.linear.y = 0.0;
+              twist.angular.z = 0.0;
+              moveRobot(twist, 5.0*min_time);
+            }
+            twist.linear.x = 0.0;
+            twist.angular.z = -0.5;
+            turn_duration = 1.5708/0.5; // Turn pi/2 rad
+            moveRobot(twist, turn_duration);
+
+          } // End lethal cost on the left
+
+          else { // Lethal cost on the right, move towards left
+            double min_time = 0.2;
+            double turn_duration = 0.0;
+            bool move_for = true;
+            twist.linear.x = 0.0;
+            twist.linear.y = 0.0;
+            twist.angular.z = 0.0;
+            // Iterate until some movement (forward or backwards) allows the robot to rotate
+            while(true){
+              twist.linear.x = 1.0;
+              geometry_msgs::Pose2D forw = forwardSimulate(current_position, twist, min_time);
+              twist.linear.x = 0.0;
+              twist.linear.y = 1.0;
+              geometry_msgs::Pose2D forw_left = forwardSimulate(forw, twist, 0.2);
+              twist.linear.y = 0.0;
+              double cost_forw_left = normalizedPoseCost(forw_left);
+              if (cost_forw_left < cost) {
+                move_for = true;
+                break;
+              }
+
+              twist.linear.x = -1.0;
+              geometry_msgs::Pose2D backw = forwardSimulate(current_position, twist, min_time);
+              twist.linear.x = 0.0;
+              twist.linear.y = 1.0;
+              geometry_msgs::Pose2D backw_left = forwardSimulate(backw, twist, 0.2);
+              twist.linear.y = 0.0;
+              double cost_backw_left = normalizedPoseCost(backw_left);
+
+              if (cost_backw_left < cost) {
+                move_for = false;
+                break;
+              }
+              min_time = min_time + 0.2;
+            }
+            // At this point we know the time necessary to allow the robot to rotate
+            if (move_for) {
+              twist.linear.x = 0.2;
+              twist.linear.y = 0.0;
+              twist.angular.z = 0.0;
+              moveRobot(twist, 5.0*min_time);
+            }
+            else {
+              twist.linear.x = -0.2;
+              twist.linear.y = 0.0;
+              twist.angular.z = 0.0;
+              moveRobot(twist, 5.0*min_time);
+            }
+            twist.linear.x = 0.0;
+            twist.angular.z = 0.5;
+            turn_duration = 1.5708/0.5; // Turn pi/2 rad
+            moveRobot(twist, turn_duration);
+
+          }
+        }
+
+        return;
+
+      case 4: // Completely surrounded by lethal cost. Robot probably damaged. Don't do anything.
+        return;
+
+      default:
+        return;
+
+    }
+    return;
+
+  }
+
+
   void RotationalRecovery::runBehavior ()
   {
     ROS_ASSERT (initialized_);
-    // We need to calculate the angle that gives us the best clearance
-    geometry_msgs::Pose2D current_pose = getCurrentLocalPose();
-    ros::Rate r(controller_frequency_);
     double stop_time = 0.5;
-    ROS_WARN_NAMED ("top", "--- Applying Rotational recovery ---");
-    double angle = rotationalAngle(current_pose);
-
-    // We calculate the twist to move the robot towards that angle
+    ros::Rate r(controller_frequency_);
     geometry_msgs::Twist twist;
-    if (angle<0.0) {
-      twist.angular.z = -1.0 *angular_speed_steer_;
+
+    geometry_msgs::Pose2D current_pose = getCurrentLocalPose();
+    double cost = normalizedPoseCost(current_pose); // Cost of the original positon
+
+    // We need to calculate the angle that gives us the best clearance
+    if (cost >= costmap_2d::INSCRIBED_INFLATED_OBSTACLE){
+      escapeFromLethalCost(current_pose, twist, cost);
     }
     else {
-      twist.angular.z = angular_speed_steer_;
-    }
-    double max_duration = fabs(angle / angular_speed_steer_);
+      ROS_WARN_NAMED ("top", "--- Applying Rotational recovery ---");
+      double angle = rotationalAngle(current_pose);
 
-    // We apply this twist open-loop for d seconds (scaled so we can guarantee
-    // stopping at the end)
-    ROS_INFO_NAMED ("top", "Applying %.2f rad turn [turning %.2f s at %.2f rad/s]", angle, max_duration, twist.angular.z);
-    for (double t=0; t<max_duration; t+=1/controller_frequency_) {
-      if(t<0.05){
-        ROS_DEBUG_NAMED ("top", "twist.linear.x=%.2f, .y=%.2f, .z=%.2f, .angular.x=%.2f, .y=%.2f, .z=%.2f", twist.linear.x, twist.linear.y, twist.linear.z, twist.angular.x, twist.angular.y, twist.angular.z);
+      // We calculate the twist to move the robot towards that angle
+      if (angle<0.0) {
+        twist.angular.z = -1.0 *angular_speed_steer_;
       }
-      pub_.publish(scaleGivenAccelerationLimits(twist, max_duration-t));
-      r.sleep();
+      else {
+        twist.angular.z = angular_speed_steer_;
+      }
+      double max_duration = fabs(angle / angular_speed_steer_);
+
+      // We apply this twist open-loop for d seconds (scaled so we can guarantee
+      // stopping at the end)
+      ROS_INFO_NAMED ("top", "Applying %.2f rad turn [turning %.2f s at %.2f rad/s]", angle, max_duration, twist.angular.z);
+      for (double t=0; t<max_duration; t+=1/controller_frequency_) {
+        if(t<0.05){
+          ROS_DEBUG_NAMED ("top", "twist.linear.x=%.2f, .y=%.2f, .z=%.2f, .angular.x=%.2f, .y=%.2f, .z=%.2f", twist.linear.x, twist.linear.y, twist.linear.z, twist.angular.x, twist.angular.y, twist.angular.z);
+        }
+        pub_.publish(scaleGivenAccelerationLimits(twist, max_duration-t));
+        r.sleep();
+      }
+
     }
 
     twist.angular.z = 0.0;
@@ -296,6 +607,7 @@ namespace rotational_recovery
       pub_.publish(scaleGivenAccelerationLimits(twist, stop_time-t));
       r.sleep();
     }
+
   }
 
 } // namespace rotational_recovery
diff --git a/twist_recovery/include/twist_recovery/twist_recovery.h b/twist_recovery/include/twist_recovery/twist_recovery.h
index 75925452086a720f0de09f5ce5e4ceecc848420a..4f56f72669e5a7ed810bc400006ab873883d9ab5 100644
--- a/twist_recovery/include/twist_recovery/twist_recovery.h
+++ b/twist_recovery/include/twist_recovery/twist_recovery.h
@@ -61,6 +61,8 @@ namespace twist_recovery
 
     private:
 
+      void escapeFromLethalCost(const geometry_msgs::Pose2D& current_position, geometry_msgs::Twist& twist, const double cost);
+      void moveRobot(const geometry_msgs::Twist& twist, const double max_duration);
       geometry_msgs::Pose2D getCurrentLocalPose () const;
       geometry_msgs::Twist scaleGivenAccelerationLimits (const geometry_msgs::Twist& twist, const double time_remaining) const;
       double nonincreasingCostInterval (const geometry_msgs::Pose2D& current, const geometry_msgs::Twist& twist, const double min_time) const;
diff --git a/twist_recovery/src/twist_recovery.cpp b/twist_recovery/src/twist_recovery.cpp
index be56b0472a2f9915bd1b7e057de51cb25bee8963..1991a6e30685428f81a9cd5938a6e075c083f112 100644
--- a/twist_recovery/src/twist_recovery.cpp
+++ b/twist_recovery/src/twist_recovery.cpp
@@ -92,7 +92,7 @@ namespace twist_recovery
     private_nh.param("angular_z", base_frame_twist_.angular.z, 0.0);
 
     private_nh.param("duration", duration_, 3.0);
-    private_nh.param("linear_speed_limit", linear_speed_limit_, 0.3);
+    private_nh.param("linear_speed_limit", linear_speed_limit_, 1.0);
     private_nh.param("linear_speed_steer", linear_speed_steer_, -0.2);
     private_nh.param("angular_speed_limit", angular_speed_limit_, 1.0);
     private_nh.param("linear_acceleration_limit", linear_acceleration_limit_, 4.0);
@@ -148,6 +148,7 @@ namespace twist_recovery
     }
     double cost = normalizedPoseCost(current_position); // Cost of the original positon
     double cost_after_min_time = normalizedPoseCost(forwardSimulate(current_position, twist, min_time)); // Cost after the first k seconds we allow lethal cost
+
     if (cost_after_min_time > cost) {
       ROS_WARN_STREAM_NAMED("cost", "Cost after time allowing lethal cost [" << cost_after_min_time <<
       "] is greater than original cost [" << cost << "]");
@@ -204,18 +205,9 @@ namespace twist_recovery
     return pose;
   }
 
-  void TwistRecovery::runBehavior ()
+  // Apply the given twist during the given time
+  void TwistRecovery::moveRobot(const geometry_msgs::Twist& twist, const double max_duration)
   {
-    ROS_ASSERT (initialized_);
-    double stop_time = 0.5;
-
-    // Threre is a maximum duration this recovery can run defined in duration_.
-    // However, there may be an obstacle so it is necessary to figure out how
-    // long we can safely run the behavior.
-    const geometry_msgs::Pose2D& current_pose = getCurrentLocalPose();
-    const double max_duration = nonincreasingCostInterval(current_pose, base_frame_twist_);
-    geometry_msgs::Twist twist;
-    twist.linear.x = -0.2;
     ros::Rate r(controller_frequency_);
     ROS_WARN_NAMED ("top", "Applying Twist recovery (%.2f, %.2f, %.2f) for %.2f seconds", twist.linear.x,
     twist.linear.y, twist.angular.z, max_duration);
@@ -226,6 +218,324 @@ namespace twist_recovery
       pub_.publish(scaleGivenAccelerationLimits(twist, max_duration-t));
       r.sleep();
     }
+    return;
+  }
+
+  // Apply algorithm to escape from a lethal obstacle
+  void TwistRecovery::escapeFromLethalCost(const geometry_msgs::Pose2D& current_position, geometry_msgs::Twist& twist, const double cost)
+  {
+    double cost_front_1, cost_front_2, cost_front_3 = 0;
+    double cost_back_1, cost_back_2, cost_back_3 = 0;
+    double cost_left_1, cost_left_2, cost_left_3 = 0;
+    double cost_right_1, cost_right_2, cost_right_3 = 0;
+    double t = 0.0;
+    int count_cost = 0;
+
+    // Simulate cost moving 1 global_cmap's cell in each direction
+    t = 0.2;
+    twist.linear.x = 1.0;
+    cost_front_1 = normalizedPoseCost(forwardSimulate(current_position, twist, t));
+    twist.linear.x = -1.0;
+    cost_back_1 = normalizedPoseCost(forwardSimulate(current_position, twist, t));
+
+    twist.linear.x = 0.0;
+    twist.linear.y = 1.0;
+    cost_left_1 = normalizedPoseCost(forwardSimulate(current_position, twist, t));
+    twist.linear.y = -1.0;
+    cost_right_1 = normalizedPoseCost(forwardSimulate(current_position, twist, t));
+
+    // Simulate cost moving 2 global_cmap's cell in each direction
+    t = 0.4;
+    twist.linear.x = 1.0;
+    cost_front_2 = normalizedPoseCost(forwardSimulate(current_position, twist, t));
+    twist.linear.x = -1.0;
+    cost_back_2 = normalizedPoseCost(forwardSimulate(current_position, twist, t));
+
+    twist.linear.x = 0.0;
+    twist.linear.y = 1.0;
+    cost_left_2 = normalizedPoseCost(forwardSimulate(current_position, twist, t));
+    twist.linear.y = -1.0;
+    cost_right_2 = normalizedPoseCost(forwardSimulate(current_position, twist, t));
+
+    // Simulate cost moving 3 global_cmap's cell in each direction
+    t = 0.6;
+    twist.linear.x = 1.0;
+    cost_front_3 = normalizedPoseCost(forwardSimulate(current_position, twist, t));
+    twist.linear.x = -1.0;
+    cost_back_3 = normalizedPoseCost(forwardSimulate(current_position, twist, t));
+
+    twist.linear.x = 0.0;
+    twist.linear.y = 1.0;
+    cost_left_3 = normalizedPoseCost(forwardSimulate(current_position, twist, t));
+    twist.linear.y = -1.0;
+    cost_right_3 = normalizedPoseCost(forwardSimulate(current_position, twist, t));
+
+    twist.linear.x = 0.0;
+    twist.linear.y = 0.0;
+    twist.angular.z = 0.0;
+
+    ROS_INFO_NAMED ("top", "Original cost: %.2f", cost);
+    ROS_INFO_NAMED ("top", "1st costs: %.2f, %.2f, %.2f, %.2f", cost_front_1, cost_back_1, cost_left_1, cost_right_1);
+    ROS_INFO_NAMED ("top", "2nd costs: %.2f, %.2f, %.2f, %.2f", cost_front_2, cost_back_2, cost_left_2, cost_right_2);
+    ROS_INFO_NAMED ("top", "3rd costs: %.2f, %.2f, %.2f, %.2f", cost_front_3, cost_back_3, cost_left_3, cost_right_3);
+
+    if (cost_front_1 >= cost) count_cost++;
+    if (cost_back_1 >= cost) count_cost++;
+    if (cost_left_1 >= cost) count_cost++;
+    if (cost_right_1 >= cost) count_cost++;
+
+    switch(count_cost){
+      case 0: // If we are executing this function, there must be at least 1 lethal cost so this is Impossible
+        return;
+
+      case 1: // Moving just 1 cell arround and obtaining just 1 lethal cost means that our current cost is not lethal. Impossible
+        return;
+
+      case 2: // Two lethal costs mean a little edge
+        // Technically it is impossible that both front and back movements imply a lethal cost as well as both left and right
+        // So the question is to know towards which direction move the robot and towards which side turn it.
+        // 1st movement: move away
+        if (cost_front_1 >= cost) { // Lethal cost in the front, move backwards
+          if (cost_back_2 >= cost) { // Lethal cost too near the back, move just a bit
+            twist.linear.x = -0.2;
+            twist.linear.y = 0.0;
+            twist.angular.z = 0.0;
+            double max_duration = 1.0;
+            moveRobot(twist, max_duration);
+          }
+          else { // No problem at the back, move further
+            twist.linear.x = -0.2;
+            twist.linear.y = 0.0;
+            twist.angular.z = 0.0;
+            double max_duration = 2.0;
+            moveRobot(twist, max_duration);
+          }
+        }
+        else { // Lethal cost at the back, move forwards
+          if (cost_front_2 >= cost) { // Lethal cost too near the front, move just a bit
+            twist.linear.x = 0.2;
+            twist.linear.y = 0.0;
+            twist.angular.z = 0.0;
+            double max_duration = 1.0;
+            moveRobot(twist, max_duration);
+          }
+          else { // No problem, move further
+            twist.linear.x = 0.2;
+            twist.linear.y = 0.0;
+            twist.angular.z = 0.0;
+            double max_duration = 2.0;
+            moveRobot(twist, max_duration);
+          }
+        }
+        // 2nd movement: turn
+        if (cost_left_1 >= cost) { // Lethal cost on the left, move towards right
+          twist.linear.x = 0.0;
+          twist.linear.y = 0.0;
+          twist.angular.z = -0.5;
+          double max_duration = 1.5708/0.5; // Turn pi/2 rad
+          moveRobot(twist, max_duration);
+        }
+        else { // Lethal cost on the right, move towards left
+          twist.linear.x = 0.0;
+          twist.linear.y = 0.0;
+          twist.angular.z = 0.5;
+          double max_duration = 1.5708/0.5; // Turn pi/2 rad
+          moveRobot(twist, max_duration);
+        }
+        return;
+
+      case 3: // Three lethal cost mean a wall or a big edge
+        // There are two possibilities:
+        // 1. The obstacle is at the robot's front/back so it can move backwards/forwards without problems
+        // 2. The obstacle is at one side so it's necessary to know how long the robot must move forward or
+        // backward to create a gap big enough to turn to the other side
+        if (cost_back_1 < cost) { // Case 1.backwards
+          if (cost_back_2 >= cost) { // Lethal cost too near the back, move just a bit
+            twist.linear.x = -0.2;
+            twist.linear.y = 0.0;
+            twist.angular.z = 0.0;
+            double max_duration = 1.0;
+            moveRobot(twist, max_duration);
+          }
+          else { // No problem at the back, move further
+            twist.linear.x = -0.2;
+            twist.linear.y = 0.0;
+            twist.angular.z = 0.0;
+            double max_duration = 2.0;
+            moveRobot(twist, max_duration);
+          }
+        }
+        else if (cost_front_1 < cost) { // Case 1.forwards
+          if (cost_front_2 >= cost) { // Lethal cost too near the front, move just a bit
+            twist.linear.x = 0.2;
+            twist.linear.y = 0.0;
+            twist.angular.z = 0.0;
+            double max_duration = 1.0;
+            moveRobot(twist, max_duration);
+          }
+          else { // No problem, move further
+            twist.linear.x = 0.2;
+            twist.linear.y = 0.0;
+            twist.angular.z = 0.0;
+            double max_duration = 2.0;
+            moveRobot(twist, max_duration);
+          }
+        }
+        else { // Case 2
+          if (cost_left_1 >= cost) { // Lethal cost on the left, move towards right
+            double min_time = 0.2;
+            double turn_duration = 0.0;
+            bool move_for = true;
+            twist.linear.x = 0.0;
+            twist.linear.y = 0.0;
+            twist.angular.z = 0.0;
+            // Iterate until some movement (forward or backwards) allows the robot to rotate
+            while(true){
+              twist.linear.x = 1.0;
+              geometry_msgs::Pose2D forw = forwardSimulate(current_position, twist, min_time);
+              twist.linear.x = 0.0;
+              twist.linear.y = 1.0;
+              geometry_msgs::Pose2D forw_left = forwardSimulate(forw, twist, 0.2);
+              twist.linear.y = 0.0;
+              double cost_forw_left = normalizedPoseCost(forw_left);
+              if (cost_forw_left < cost) {
+                move_for = true;
+                break;
+              }
+
+              twist.linear.x = -1.0;
+              geometry_msgs::Pose2D backw = forwardSimulate(current_position, twist, min_time);
+              twist.linear.x = 0.0;
+              twist.linear.y = 1.0;
+              geometry_msgs::Pose2D backw_left = forwardSimulate(backw, twist, 0.2);
+              twist.linear.y = 0.0;
+              double cost_backw_left = normalizedPoseCost(backw_left);
+
+              if (cost_backw_left < cost) {
+                move_for = false;
+                break;
+              }
+              min_time = min_time + 0.2;
+            }
+            // At this point we know the time necessary to allow the robot to rotate
+            if (move_for) {
+              twist.linear.x = 0.2;
+              twist.linear.y = 0.0;
+              twist.angular.z = 0.0;
+              moveRobot(twist, 5.0*min_time);
+            }
+            else {
+              twist.linear.x = -0.2;
+              twist.linear.y = 0.0;
+              twist.angular.z = 0.0;
+              moveRobot(twist, 5.0*min_time);
+            }
+            twist.linear.x = 0.0;
+            twist.angular.z = -0.5;
+            turn_duration = 1.5708/0.5; // Turn pi/2 rad
+            moveRobot(twist, turn_duration);
+
+          } // End lethal cost on the left
+
+          else { // Lethal cost on the right, move towards left
+            double min_time = 0.2;
+            double turn_duration = 0.0;
+            bool move_for = true;
+            twist.linear.x = 0.0;
+            twist.linear.y = 0.0;
+            twist.angular.z = 0.0;
+            // Iterate until some movement (forward or backwards) allows the robot to rotate
+            while(true){
+              twist.linear.x = 1.0;
+              geometry_msgs::Pose2D forw = forwardSimulate(current_position, twist, min_time);
+              twist.linear.x = 0.0;
+              twist.linear.y = 1.0;
+              geometry_msgs::Pose2D forw_left = forwardSimulate(forw, twist, 0.2);
+              twist.linear.y = 0.0;
+              double cost_forw_left = normalizedPoseCost(forw_left);
+              if (cost_forw_left < cost) {
+                move_for = true;
+                break;
+              }
+
+              twist.linear.x = -1.0;
+              geometry_msgs::Pose2D backw = forwardSimulate(current_position, twist, min_time);
+              twist.linear.x = 0.0;
+              twist.linear.y = 1.0;
+              geometry_msgs::Pose2D backw_left = forwardSimulate(backw, twist, 0.2);
+              twist.linear.y = 0.0;
+              double cost_backw_left = normalizedPoseCost(backw_left);
+
+              if (cost_backw_left < cost) {
+                move_for = false;
+                break;
+              }
+              min_time = min_time + 0.2;
+            }
+            // At this point we know the time necessary to allow the robot to rotate
+            if (move_for) {
+              twist.linear.x = 0.2;
+              twist.linear.y = 0.0;
+              twist.angular.z = 0.0;
+              moveRobot(twist, 5.0*min_time);
+            }
+            else {
+              twist.linear.x = -0.2;
+              twist.linear.y = 0.0;
+              twist.angular.z = 0.0;
+              moveRobot(twist, 5.0*min_time);
+            }
+            twist.linear.x = 0.0;
+            twist.angular.z = 0.5;
+            turn_duration = 1.5708/0.5; // Turn pi/2 rad
+            moveRobot(twist, turn_duration);
+
+          }
+        }
+
+        return;
+
+      case 4: // Completely surrounded by lethal cost. Robot probably damaged. Don't do anything.
+        return;
+
+      default:
+        return;
+
+    }
+    return;
+
+  }
+
+  void TwistRecovery::runBehavior ()
+  {
+    ROS_ASSERT (initialized_);
+    double stop_time = 0.5;
+    ros::Rate r(controller_frequency_);
+
+    // Threre is a maximum duration this recovery can run defined in duration_.
+    // However, there may be an obstacle so it is necessary to figure out how
+    // long we can safely run the behavior.
+    geometry_msgs::Twist twist;
+    const geometry_msgs::Pose2D& current_pose = getCurrentLocalPose();
+    double cost = normalizedPoseCost(current_pose); // Cost of the original positon
+
+    if (cost >= costmap_2d::INSCRIBED_INFLATED_OBSTACLE){
+      escapeFromLethalCost(current_pose, twist, cost);
+    }
+    else {
+      const double max_duration = nonincreasingCostInterval(current_pose, base_frame_twist_);
+      twist.linear.x = -0.2;
+      ROS_WARN_NAMED ("top", "Applying Twist recovery (%.2f, %.2f, %.2f) for %.2f seconds", twist.linear.x,
+      twist.linear.y, twist.angular.z, max_duration);
+
+      // We will now apply this twist open-loop for d seconds (scaled so we can
+      // guarantee stopping at the end)
+      for (double t=0; t<max_duration; t+=1/controller_frequency_) {
+        pub_.publish(scaleGivenAccelerationLimits(twist, max_duration-t));
+        r.sleep();
+      }
+
+    }
 
     twist.linear.x = 0.0;
     ROS_INFO_NAMED ("top", "Applying STOP for %.2f s", stop_time);
@@ -233,6 +543,7 @@ namespace twist_recovery
       pub_.publish(scaleGivenAccelerationLimits(twist, stop_time-t));
       r.sleep();
     }
+
   }
 
 } // namespace twist_recovery