recovery_action.cpp
Go to the documentation of this file.
00001 /*
00002  *  Copyright 2018, Magazino GmbH, Sebastian Pütz, Jorge Santos Simón
00003  *
00004  *  Redistribution and use in source and binary forms, with or without
00005  *  modification, are permitted provided that the following conditions
00006  *  are met:
00007  *
00008  *  1. Redistributions of source code must retain the above copyright
00009  *     notice, this list of conditions and the following disclaimer.
00010  *
00011  *  2. Redistributions in binary form must reproduce the above
00012  *     copyright notice, this list of conditions and the following
00013  *     disclaimer in the documentation and/or other materials provided
00014  *     with the distribution.
00015  *
00016  *  3. Neither the name of the copyright holder nor the names of its
00017  *     contributors may be used to endorse or promote products derived
00018  *     from this software without specific prior written permission.
00019  *
00020  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00021  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00022  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00023  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00024  *  COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00025  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00026  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00027  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00028  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00029  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00030  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00031  *  POSSIBILITY OF SUCH DAMAGE.
00032  *
00033  *  recovery_action.cpp
00034  *
00035  *  authors:
00036  *    Sebastian Pütz <spuetz@uni-osnabrueck.de>
00037  *    Jorge Santos Simón <santos@magazino.eu>
00038  *
00039  */
00040 
00041 #include "mbf_abstract_nav/recovery_action.h"
00042 
00043 namespace mbf_abstract_nav{
00044 
00045 RecoveryAction::RecoveryAction(const std::string &name, const RobotInformation &robot_info)
00046   : AbstractAction(name, robot_info, boost::bind(&mbf_abstract_nav::RecoveryAction::run, this, _1, _2)){}
00047 
00048 void RecoveryAction::run(GoalHandle &goal_handle, AbstractRecoveryExecution &execution)
00049 {
00050   ROS_DEBUG_STREAM_NAMED(name_, "Start action "  << name_);
00051 
00052   const mbf_msgs::RecoveryGoal &goal = *(goal_handle.getGoal().get());
00053   mbf_msgs::RecoveryResult result;
00054   bool recovery_active = true;
00055 
00056   typename AbstractRecoveryExecution::RecoveryState state_recovery_input;
00057 
00058   while (recovery_active && ros::ok())
00059   {
00060     state_recovery_input = execution.getState();
00061     switch (state_recovery_input)
00062     {
00063       case AbstractRecoveryExecution::INITIALIZED:execution.start();
00064         break;
00065       case AbstractRecoveryExecution::STOPPED:
00066         // Recovery behavior doesn't support or didn't answered to cancel and has been ruthlessly stopped
00067         ROS_WARN_STREAM("Recovering \"" << goal.behavior << "\" exceeded the patience time and has been stopped!");
00068         recovery_active = false; // stopping the action
00069         result.outcome = mbf_msgs::RecoveryResult::CANCELED;
00070         result.message = "Recovery \"" + goal.behavior + "\" exceeded the patience time";
00071         goal_handle.setSucceeded(result, result.message);
00072         break;
00073 
00074       case AbstractRecoveryExecution::STARTED:
00075         ROS_DEBUG_STREAM_NAMED(name_, "Recovering \"" << goal.behavior << "\" was started");
00076         break;
00077 
00078       case AbstractRecoveryExecution::RECOVERING:
00079 
00080         if (execution.isPatienceExceeded())
00081         {
00082           ROS_INFO_STREAM("Recovery behavior \"" << goal.behavior << "\" patience exceeded! Cancel recovering...");
00083           if (!execution.cancel())
00084           {
00085             ROS_WARN_STREAM("Cancel recovering \"" << goal.behavior << "\" failed or not supported; interrupt it!");
00086             execution.stop();
00087             //TODO goal_handle.setAborted
00088           }
00089         }
00090 
00091         ROS_DEBUG_STREAM_THROTTLE_NAMED(3, name_, "Recovering with: " << goal.behavior);
00092         break;
00093 
00094       case AbstractRecoveryExecution::CANCELED:
00095         // Recovery behavior supports cancel and it worked
00096         recovery_active = false; // stopping the action
00097         result.outcome = mbf_msgs::RecoveryResult::CANCELED;
00098         result.message = "Recovering \"" + goal.behavior + "\" preempted!";
00099         goal_handle.setCanceled(result, result.message);
00100         ROS_DEBUG_STREAM_NAMED(name_, result.message);
00101         break;
00102 
00103       case AbstractRecoveryExecution::RECOVERY_DONE:
00104         recovery_active = false; // stopping the action
00105         result.outcome = execution.getOutcome();
00106         result.message = execution.getMessage();
00107         if (result.message.empty())
00108         {
00109           if (result.outcome < 10)
00110             result.message = "Recovery \"" + goal.behavior + "\" done";
00111           else
00112             result.message = "Recovery \"" + goal.behavior + "\" FAILED";
00113         }
00114 
00115         ROS_DEBUG_STREAM_NAMED(name_, result.message);
00116         goal_handle.setSucceeded(result, result.message);
00117         break;
00118 
00119       case AbstractRecoveryExecution::INTERNAL_ERROR:
00120         ROS_FATAL_STREAM_NAMED(name_, "Internal error: Unknown error thrown by the plugin!"); // TODO getMessage from recovery
00121         recovery_active = false;
00122         result.outcome = mbf_msgs::RecoveryResult::INTERNAL_ERROR;
00123         result.message = "Internal error: Unknown error thrown by the plugin!";
00124         goal_handle.setAborted(result, result.message);
00125         break;
00126 
00127       default:
00128         result.outcome = mbf_msgs::RecoveryResult::INTERNAL_ERROR;
00129         std::stringstream ss;
00130         ss << "Internal error: Unknown state in a move base flex recovery execution with the number: "
00131            << static_cast<int>(state_recovery_input);
00132         result.message = ss.str();
00133         ROS_FATAL_STREAM_NAMED(name_, result.message);
00134         goal_handle.setAborted(result, result.message);
00135         recovery_active = false;
00136     }
00137 
00138     if (recovery_active)
00139     {
00140       // try to sleep a bit
00141       // normally the thread should be woken up from the recovery unit
00142       // in order to transfer the results to the controller
00143       execution.waitForStateUpdate(boost::chrono::milliseconds(500));
00144     }
00145   }  // while (recovery_active && ros::ok())
00146 
00147   if (!recovery_active)
00148   {
00149     ROS_DEBUG_STREAM_NAMED(name_, "\"" << name_ << "\" action ended properly.");
00150   }
00151   else
00152   {
00153     ROS_ERROR_STREAM_NAMED(name_, "\"" << name_ << "\" action has been stopped!");
00154   }
00155 }
00156 
00157 } /* namespace mbf_abstract_nav */
00158 


mbf_abstract_nav
Author(s): Sebastian Pütz
autogenerated on Mon Jun 17 2019 20:11:35