Go to the documentation of this file.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 "mbf_abstract_nav/abstract_planner_execution.h"
00042
00043 namespace mbf_abstract_nav
00044 {
00045
00046
00047 AbstractPlannerExecution::AbstractPlannerExecution(const std::string name,
00048 const mbf_abstract_core::AbstractPlanner::Ptr planner_ptr,
00049 const MoveBaseFlexConfig &config,
00050 boost::function<void()> setup_fn,
00051 boost::function<void()> cleanup_fn) :
00052 AbstractExecutionBase(name, setup_fn, cleanup_fn),
00053 planner_(planner_ptr), state_(INITIALIZED), planning_(false),
00054 has_new_start_(false), has_new_goal_(false)
00055 {
00056 ros::NodeHandle private_nh("~");
00057
00058
00059 private_nh.param("robot_frame", robot_frame_, std::string("base_footprint"));
00060 private_nh.param("map_frame", global_frame_, std::string("map"));
00061
00062
00063 reconfigure(config);
00064 }
00065
00066 AbstractPlannerExecution::~AbstractPlannerExecution()
00067 {
00068 }
00069
00070
00071 double AbstractPlannerExecution::getCost()
00072 {
00073 boost::lock_guard<boost::mutex> guard(plan_mtx_);
00074
00075
00076 if(cost_ == 0 && !plan_.empty())
00077 {
00078 ROS_DEBUG_STREAM("Compute costs by discrete path length!");
00079 double cost = 0;
00080
00081 geometry_msgs::PoseStamped prev_pose = plan_.front();
00082 for(std::vector<geometry_msgs::PoseStamped>::iterator iter = plan_.begin() + 1; iter != plan_.end(); ++iter)
00083 {
00084 cost += mbf_utility::distance(prev_pose, *iter);
00085 prev_pose = *iter;
00086 }
00087 return cost;
00088 }
00089 return cost_;
00090 }
00091
00092 void AbstractPlannerExecution::reconfigure(const MoveBaseFlexConfig &config)
00093 {
00094 boost::lock_guard<boost::mutex> guard(configuration_mutex_);
00095
00096 max_retries_ = config.planner_max_retries;
00097 frequency_ = config.planner_frequency;
00098
00099
00100
00101 patience_ = ros::Duration(config.planner_patience);
00102 }
00103
00104
00105 typename AbstractPlannerExecution::PlanningState AbstractPlannerExecution::getState()
00106 {
00107 boost::lock_guard<boost::mutex> guard(state_mtx_);
00108 return state_;
00109 }
00110
00111 void AbstractPlannerExecution::setState(PlanningState state)
00112 {
00113 boost::lock_guard<boost::mutex> guard(state_mtx_);
00114 state_ = state;
00115 }
00116
00117
00118 ros::Time AbstractPlannerExecution::getLastValidPlanTime()
00119 {
00120 boost::lock_guard<boost::mutex> guard(plan_mtx_);
00121 return last_valid_plan_time_;
00122 }
00123
00124
00125 bool AbstractPlannerExecution::isPatienceExceeded()
00126 {
00127 return !patience_.isZero() && (ros::Time::now() - last_call_start_time_ > patience_);
00128 }
00129
00130
00131 std::vector<geometry_msgs::PoseStamped> AbstractPlannerExecution::getPlan()
00132 {
00133 boost::lock_guard<boost::mutex> guard(plan_mtx_);
00134
00135 return plan_;
00136 }
00137
00138
00139 void AbstractPlannerExecution::setNewGoal(const geometry_msgs::PoseStamped &goal, double tolerance)
00140 {
00141 boost::lock_guard<boost::mutex> guard(goal_start_mtx_);
00142 goal_ = goal;
00143 tolerance_ = tolerance;
00144 has_new_goal_ = true;
00145 }
00146
00147
00148 void AbstractPlannerExecution::setNewStart(const geometry_msgs::PoseStamped &start)
00149 {
00150 boost::lock_guard<boost::mutex> guard(goal_start_mtx_);
00151 start_ = start;
00152 has_new_start_ = true;
00153 }
00154
00155
00156 void AbstractPlannerExecution::setNewStartAndGoal(const geometry_msgs::PoseStamped &start,
00157 const geometry_msgs::PoseStamped &goal,
00158 double tolerance)
00159 {
00160 boost::lock_guard<boost::mutex> guard(goal_start_mtx_);
00161 start_ = start;
00162 goal_ = goal;
00163 tolerance_ = tolerance;
00164 has_new_start_ = true;
00165 has_new_goal_ = true;
00166 }
00167
00168
00169 bool AbstractPlannerExecution::start(const geometry_msgs::PoseStamped &start,
00170 const geometry_msgs::PoseStamped &goal,
00171 double tolerance)
00172 {
00173 if (planning_)
00174 {
00175 return false;
00176 }
00177 boost::lock_guard<boost::mutex> guard(planning_mtx_);
00178 planning_ = true;
00179 start_ = start;
00180 goal_ = goal;
00181 tolerance_ = tolerance;
00182
00183 geometry_msgs::Point s = start.pose.position;
00184 geometry_msgs::Point g = goal.pose.position;
00185
00186 ROS_DEBUG_STREAM("Start planning from the start pose: (" << s.x << ", " << s.y << ", " << s.z << ")"
00187 << " to the goal pose: ("<< g.x << ", " << g.y << ", " << g.z << ")");
00188
00189 return AbstractExecutionBase::start();
00190 }
00191
00192
00193 bool AbstractPlannerExecution::cancel()
00194 {
00195 cancel_ = true;
00196
00197
00198 if(!planner_->cancel())
00199 {
00200 ROS_WARN_STREAM("Cancel planning failed or is not supported by the plugin. "
00201 << "Wait until the current planning finished!");
00202
00203 return false;
00204 }
00205 return true;
00206 }
00207
00208 uint32_t AbstractPlannerExecution::makePlan(const geometry_msgs::PoseStamped &start,
00209 const geometry_msgs::PoseStamped &goal,
00210 double tolerance,
00211 std::vector<geometry_msgs::PoseStamped> &plan,
00212 double &cost,
00213 std::string &message)
00214 {
00215 return planner_->makePlan(start, goal, tolerance, plan, cost, message);
00216 }
00217
00218 void AbstractPlannerExecution::run()
00219 {
00220 boost::lock_guard<boost::mutex> guard(planning_mtx_);
00221 int retries = 0;
00222 geometry_msgs::PoseStamped current_start = start_;
00223 geometry_msgs::PoseStamped current_goal = goal_;
00224 double current_tolerance = tolerance_;
00225
00226 bool success = false;
00227 bool make_plan = false;
00228 bool exceeded = false;
00229
00230 last_call_start_time_ = ros::Time::now();
00231 last_valid_plan_time_ = ros::Time::now();
00232
00233 try
00234 {
00235 while (planning_ && ros::ok())
00236 {
00237 boost::chrono::thread_clock::time_point start_time = boost::chrono::thread_clock::now();
00238
00239
00240 std::vector<geometry_msgs::PoseStamped> plan;
00241 double cost;
00242
00243
00244 goal_start_mtx_.lock();
00245 if (has_new_start_)
00246 {
00247 has_new_start_ = false;
00248 current_start = start_;
00249 ROS_INFO_STREAM("A new start pose is available. Planning with the new start pose!");
00250 exceeded = false;
00251 geometry_msgs::Point s = start_.pose.position;
00252 ROS_INFO_STREAM("New planning start pose: (" << s.x << ", " << s.y << ", " << s.z << ")");
00253 }
00254 if (has_new_goal_)
00255 {
00256 has_new_goal_ = false;
00257 current_goal = goal_;
00258 current_tolerance = tolerance_;
00259 ROS_INFO_STREAM("A new goal pose is available. Planning with the new goal pose and the tolerance: "
00260 << current_tolerance);
00261 exceeded = false;
00262 geometry_msgs::Point g = goal_.pose.position;
00263 ROS_INFO_STREAM("New goal pose: (" << g.x << ", " << g.y << ", " << g.z << ")");
00264 }
00265
00266 make_plan = !(success || exceeded) || has_new_start_ || has_new_goal_;
00267
00268
00269 goal_start_mtx_.unlock();
00270 setState(PLANNING);
00271 if (make_plan)
00272 {
00273 outcome_ = makePlan(current_start, current_goal, current_tolerance, plan, cost, message_);
00274 success = outcome_ < 10;
00275
00276 boost::lock_guard<boost::mutex> guard(configuration_mutex_);
00277
00278 if (cancel_ && !isPatienceExceeded())
00279 {
00280 setState(CANCELED);
00281 ROS_INFO_STREAM("The global planner has been canceled!");
00282 planning_ = false;
00283 condition_.notify_all();
00284 }
00285 else if (success)
00286 {
00287 ROS_DEBUG_STREAM("Successfully found a plan.");
00288 exceeded = false;
00289 planning_ = false;
00290
00291 plan_mtx_.lock();
00292 plan_ = plan;
00293 cost_ = cost;
00294 last_valid_plan_time_ = ros::Time::now();
00295 plan_mtx_.unlock();
00296 setState(FOUND_PLAN);
00297
00298 condition_.notify_all();
00299 }
00300 else if (max_retries_ >= 0 && ++retries > max_retries_)
00301 {
00302 ROS_INFO_STREAM("Planning reached max retries! (" << max_retries_ << ")");
00303 setState(MAX_RETRIES);
00304 exceeded = true;
00305 planning_ = false;
00306 condition_.notify_all();
00307 }
00308 else if (isPatienceExceeded())
00309 {
00310
00311
00312
00313
00314 ROS_INFO_STREAM("Planning patience (" << patience_.toSec() << "s) has been exceeded"
00315 << (cancel_ ? "; planner canceled!" : ""));
00316 setState(PAT_EXCEEDED);
00317 exceeded = true;
00318 planning_ = false;
00319 condition_.notify_all();
00320 }
00321 else if (max_retries_ == 0 && patience_.isZero())
00322 {
00323 ROS_INFO_STREAM("Planning could not find a plan!");
00324 exceeded = true;
00325 setState(NO_PLAN_FOUND);
00326 condition_.notify_all();
00327 planning_ = false;
00328 }
00329 else
00330 {
00331 exceeded = false;
00332 ROS_DEBUG_STREAM("Planning could not find a plan! Trying again...");
00333 }
00334 }
00335 else if (cancel_)
00336 {
00337 ROS_INFO_STREAM("The global planner has been canceled!");
00338 setState(CANCELED);
00339 planning_ = false;
00340 condition_.notify_all();
00341 }
00342 }
00343 }
00344 catch (const boost::thread_interrupted &ex)
00345 {
00346
00347 ROS_WARN_STREAM("Planner thread interrupted!");
00348 setState(STOPPED);
00349 condition_.notify_all();
00350 planning_ = false;
00351 }
00352 catch (...)
00353 {
00354 ROS_FATAL_STREAM("Unknown error occurred: " << boost::current_exception_diagnostic_information());
00355 setState(INTERNAL_ERROR);
00356 }
00357 }
00358
00359 }
00360