00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include <sstream>
00042
00043 #include "mbf_abstract_nav/planner_action.h"
00044
00045 namespace mbf_abstract_nav{
00046
00047 PlannerAction::PlannerAction(
00048 const std::string &name,
00049 const RobotInformation &robot_info)
00050 : AbstractAction(name, robot_info, boost::bind(&mbf_abstract_nav::PlannerAction::run, this, _1, _2)), path_seq_count_(0)
00051 {
00052 ros::NodeHandle private_nh("~");
00053
00054 current_goal_pub_ = private_nh.advertise<geometry_msgs::PoseStamped>("current_goal", 1);
00055 }
00056
00057 void PlannerAction::run(GoalHandle &goal_handle, AbstractPlannerExecution &execution)
00058 {
00059 const mbf_msgs::GetPathGoal& goal = *(goal_handle.getGoal().get());
00060
00061 mbf_msgs::GetPathResult result;
00062 geometry_msgs::PoseStamped start_pose;
00063
00064 result.path.header.seq = path_seq_count_++;
00065 result.path.header.frame_id = robot_info_.getGlobalFrame();
00066
00067 double tolerance = goal.tolerance;
00068 bool use_start_pose = goal.use_start_pose;
00069 current_goal_pub_.publish(goal.target_pose);
00070
00071 bool planner_active = true;
00072
00073 if(use_start_pose)
00074 {
00075 start_pose = goal.start_pose;
00076 const geometry_msgs::Point& p = start_pose.pose.position;
00077 ROS_DEBUG_STREAM_NAMED(name_, "Use the given start pose (" << p.x << ", " << p.y << ", " << p.z << ").");
00078 }
00079 else
00080 {
00081
00082 if (!robot_info_.getRobotPose(start_pose))
00083 {
00084 result.outcome = mbf_msgs::GetPathResult::TF_ERROR;
00085 result.message = "Could not get the current robot pose!";
00086 goal_handle.setAborted(result, result.message);
00087 ROS_ERROR_STREAM_NAMED(name_, result.message << " Canceling the action call.");
00088 return;
00089 }
00090 else
00091 {
00092 const geometry_msgs::Point& p = start_pose.pose.position;
00093 ROS_DEBUG_STREAM_NAMED(name_, "Got the current robot pose at ("
00094 << p.x << ", " << p.y << ", " << p.z << ").");
00095 }
00096 }
00097
00098 AbstractPlannerExecution::PlanningState state_planning_input;
00099
00100 std::vector<geometry_msgs::PoseStamped> plan, global_plan;
00101
00102 while (planner_active && ros::ok())
00103 {
00104
00105 state_planning_input = execution.getState();
00106
00107 switch (state_planning_input)
00108 {
00109 case AbstractPlannerExecution::INITIALIZED:
00110 ROS_DEBUG_STREAM_NAMED(name_, "planner state: initialized");
00111 if (!execution.start(start_pose, goal.target_pose, tolerance))
00112 {
00113 result.outcome = mbf_msgs::GetPathResult::INTERNAL_ERROR;
00114 result.message = "Another thread is still planning!";
00115 goal_handle.setAborted(result, result.message);
00116 ROS_ERROR_STREAM_NAMED(name_, result.message << " Canceling the action call.");
00117 planner_active = false;
00118 }
00119 break;
00120
00121 case AbstractPlannerExecution::STARTED:
00122 ROS_DEBUG_STREAM_NAMED(name_, "planner state: started");
00123 break;
00124
00125 case AbstractPlannerExecution::STOPPED:
00126 ROS_DEBUG_STREAM_NAMED(name_, "planner state: stopped");
00127 ROS_WARN_STREAM_NAMED(name_, "Planning has been stopped rigorously!");
00128 result.outcome = mbf_msgs::GetPathResult::STOPPED;
00129 result.message = "Global planner has been stopped!";
00130 goal_handle.setAborted(result, result.message);
00131 planner_active = false;
00132 break;
00133
00134 case AbstractPlannerExecution::CANCELED:
00135 ROS_DEBUG_STREAM_NAMED(name_, "planner state: canceled");
00136 ROS_DEBUG_STREAM_NAMED(name_, "Global planner has been canceled successfully");
00137 result.path.header.stamp = ros::Time::now();
00138 result.outcome = mbf_msgs::GetPathResult::CANCELED;
00139 result.message = "Global planner has been canceled!";
00140 goal_handle.setCanceled(result, result.message);
00141 planner_active = false;
00142 break;
00143
00144
00145 case AbstractPlannerExecution::PLANNING:
00146 if (execution.isPatienceExceeded())
00147 {
00148 ROS_INFO_STREAM_NAMED(name_, "Global planner patience has been exceeded! "
00149 << "Cancel planning...");
00150 if (!execution.cancel())
00151 {
00152 ROS_WARN_STREAM_THROTTLE_NAMED(2.0, name_, "Cancel planning failed or is not supported; "
00153 "must wait until current plan finish!");
00154 execution.stop();
00155 }
00156 }
00157 else
00158 {
00159 ROS_DEBUG_THROTTLE_NAMED(2.0, name_, "planner state: planning");
00160 }
00161 break;
00162
00163
00164 case AbstractPlannerExecution::FOUND_PLAN:
00165
00166 result.path.header.stamp = ros::Time::now();
00167 plan = execution.getPlan();
00168
00169 ROS_DEBUG_STREAM_NAMED(name_, "planner state: found plan with cost: " << execution.getCost());
00170
00171 if (!transformPlanToGlobalFrame(plan, global_plan))
00172 {
00173 result.outcome = mbf_msgs::GetPathResult::TF_ERROR;
00174 result.message = "Could not transform the plan to the global frame!";
00175
00176 ROS_ERROR_STREAM_NAMED(name_, result.message << " Canceling the action call.");
00177 goal_handle.setAborted(result, result.message);
00178 planner_active = false;
00179 break;
00180 }
00181
00182 if (global_plan.empty())
00183 {
00184 result.outcome = mbf_msgs::GetPathResult::EMPTY_PATH;
00185 result.message = "Global planner returned an empty path!";
00186
00187 ROS_ERROR_STREAM_NAMED(name_, result.message);
00188 goal_handle.setAborted(result, result.message);
00189 planner_active = false;
00190 break;
00191 }
00192
00193 result.path.poses = global_plan;
00194 result.cost = execution.getCost();
00195 result.outcome = execution.getOutcome();
00196 result.message = execution.getMessage();
00197 goal_handle.setSucceeded(result, result.message);
00198
00199 planner_active = false;
00200 break;
00201
00202
00203 case AbstractPlannerExecution::NO_PLAN_FOUND:
00204 ROS_DEBUG_STREAM_NAMED(name_, "planner state: no plan found");
00205 result.outcome = execution.getOutcome();
00206 result.message = execution.getMessage();
00207 goal_handle.setAborted(result, result.message);
00208 planner_active = false;
00209 break;
00210
00211 case AbstractPlannerExecution::MAX_RETRIES:
00212 ROS_DEBUG_STREAM_NAMED(name_, "Global planner reached the maximum number of retries");
00213 result.outcome = execution.getOutcome();
00214 result.message = execution.getMessage();
00215 goal_handle.setAborted(result, result.message);
00216 planner_active = false;
00217 break;
00218
00219 case AbstractPlannerExecution::PAT_EXCEEDED:
00220 ROS_DEBUG_STREAM_NAMED(name_, "Global planner exceeded the patience time");
00221 result.outcome = mbf_msgs::GetPathResult::PAT_EXCEEDED;
00222 result.message = "Global planner exceeded the patience time";
00223 goal_handle.setAborted(result, result.message);
00224 planner_active = false;
00225 break;
00226
00227 case AbstractPlannerExecution::INTERNAL_ERROR:
00228 ROS_FATAL_STREAM_NAMED(name_, "Internal error: Unknown error thrown by the plugin!");
00229 planner_active = false;
00230 result.outcome = mbf_msgs::GetPathResult::INTERNAL_ERROR;
00231 result.message = "Internal error: Unknown error thrown by the plugin!";
00232 goal_handle.setAborted(result, result.message);
00233 break;
00234
00235 default:
00236 result.outcome = mbf_msgs::GetPathResult::INTERNAL_ERROR;
00237 std::ostringstream ss;
00238 ss << "Internal error: Unknown state in a move base flex planner execution with the number: "
00239 << static_cast<int>(state_planning_input);
00240 result.message = ss.str();
00241 ROS_FATAL_STREAM_NAMED(name_, result.message);
00242 goal_handle.setAborted(result, result.message);
00243 planner_active = false;
00244 }
00245
00246
00247 if (planner_active)
00248 {
00249
00250
00251
00252 boost::mutex mutex;
00253 boost::unique_lock<boost::mutex> lock(mutex);
00254 execution.waitForStateUpdate(boost::chrono::milliseconds(500));
00255 }
00256 }
00257
00258 if (!planner_active)
00259 {
00260 ROS_DEBUG_STREAM_NAMED(name_, "\"" << name_ << "\" action ended properly.");
00261 }
00262 else
00263 {
00264 ROS_ERROR_STREAM_NAMED(name_, "\"" << name_ << "\" action has been stopped!");
00265 }
00266 }
00267
00268 bool PlannerAction::transformPlanToGlobalFrame(
00269 std::vector<geometry_msgs::PoseStamped> &plan, std::vector<geometry_msgs::PoseStamped> &global_plan)
00270 {
00271 global_plan.clear();
00272 std::vector<geometry_msgs::PoseStamped>::iterator iter;
00273 bool tf_success = false;
00274 for (iter = plan.begin(); iter != plan.end(); ++iter)
00275 {
00276 geometry_msgs::PoseStamped global_pose;
00277 tf_success = mbf_utility::transformPose(robot_info_.getTransformListener(), robot_info_.getGlobalFrame(), iter->header.stamp,
00278 robot_info_.getTfTimeout(), *iter, robot_info_.getGlobalFrame(), global_pose);
00279 if (!tf_success)
00280 {
00281 ROS_ERROR_STREAM("Can not transform pose from the \"" << iter->header.frame_id << "\" frame into the \""
00282 << robot_info_.getGlobalFrame() << "\" frame !");
00283 return false;
00284 }
00285 global_plan.push_back(global_pose);
00286 }
00287 return true;
00288 }
00289
00290 }
00291