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 #include <moveit/plan_execution/plan_execution.h>
00038 #include <moveit/robot_state/conversions.h>
00039 #include <moveit/trajectory_processing/trajectory_tools.h>
00040 #include <moveit/collision_detection/collision_tools.h>
00041 #include <boost/algorithm/string/join.hpp>
00042
00043 #include <dynamic_reconfigure/server.h>
00044 #include <moveit_ros_planning/PlanExecutionDynamicReconfigureConfig.h>
00045
00046 namespace plan_execution
00047 {
00048 using namespace moveit_ros_planning;
00049
00050 class PlanExecution::DynamicReconfigureImpl
00051 {
00052 public:
00053
00054 DynamicReconfigureImpl(PlanExecution *owner) : owner_(owner),
00055 dynamic_reconfigure_server_(ros::NodeHandle("~/plan_execution"))
00056 {
00057 dynamic_reconfigure_server_.setCallback(boost::bind(&DynamicReconfigureImpl::dynamicReconfigureCallback, this, _1, _2));
00058 }
00059
00060 private:
00061
00062 void dynamicReconfigureCallback(PlanExecutionDynamicReconfigureConfig &config, uint32_t level)
00063 {
00064 owner_->setMaxReplanAttempts(config.max_replan_attempts);
00065 owner_->setTrajectoryStateRecordingFrequency(config.record_trajectory_state_frequency);
00066 }
00067
00068 PlanExecution *owner_;
00069 dynamic_reconfigure::Server<PlanExecutionDynamicReconfigureConfig> dynamic_reconfigure_server_;
00070 };
00071
00072 }
00073
00074 plan_execution::PlanExecution::PlanExecution(const planning_scene_monitor::PlanningSceneMonitorPtr &planning_scene_monitor,
00075 const trajectory_execution_manager::TrajectoryExecutionManagerPtr& trajectory_execution) :
00076 node_handle_("~"), planning_scene_monitor_(planning_scene_monitor),
00077 trajectory_execution_manager_(trajectory_execution)
00078 {
00079 if (!trajectory_execution_manager_)
00080 trajectory_execution_manager_.reset(new trajectory_execution_manager::TrajectoryExecutionManager(planning_scene_monitor_->getRobotModel()));
00081
00082 default_max_replan_attempts_ = 5;
00083
00084 preempt_requested_ = false;
00085 new_scene_update_ = false;
00086
00087
00088 planning_scene_monitor_->addUpdateCallback(boost::bind(&PlanExecution::planningSceneUpdatedCallback, this, _1));
00089
00090
00091 reconfigure_impl_ = new DynamicReconfigureImpl(this);
00092 }
00093
00094 plan_execution::PlanExecution::~PlanExecution()
00095 {
00096 delete reconfigure_impl_;
00097 }
00098
00099 void plan_execution::PlanExecution::stop()
00100 {
00101 preempt_requested_ = true;
00102 }
00103
00104 std::string plan_execution::PlanExecution::getErrorCodeString(const moveit_msgs::MoveItErrorCodes& error_code)
00105 {
00106 if (error_code.val == moveit_msgs::MoveItErrorCodes::SUCCESS)
00107 return "Success";
00108 else
00109 if (error_code.val == moveit_msgs::MoveItErrorCodes::INVALID_GROUP_NAME)
00110 return "Invalid group name";
00111 else
00112 if (error_code.val == moveit_msgs::MoveItErrorCodes::PLANNING_FAILED)
00113 return "Planning failed.";
00114 else
00115 if (error_code.val == moveit_msgs::MoveItErrorCodes::INVALID_MOTION_PLAN)
00116 return "Invalid motion plan";
00117 else
00118 if (error_code.val == moveit_msgs::MoveItErrorCodes::UNABLE_TO_AQUIRE_SENSOR_DATA)
00119 return "Unable to aquire sensor data";
00120 else
00121 if (error_code.val == moveit_msgs::MoveItErrorCodes::MOTION_PLAN_INVALIDATED_BY_ENVIRONMENT_CHANGE)
00122 return "Motion plan invalidated by environment change";
00123 else
00124 if (error_code.val == moveit_msgs::MoveItErrorCodes::CONTROL_FAILED)
00125 return "Controller failed during execution";
00126 else
00127 if (error_code.val == moveit_msgs::MoveItErrorCodes::TIMED_OUT)
00128 return "Timeout reached";
00129 else
00130 if (error_code.val == moveit_msgs::MoveItErrorCodes::PREEMPTED)
00131 return "Preempted";
00132 else
00133 if (error_code.val == moveit_msgs::MoveItErrorCodes::INVALID_GOAL_CONSTRAINTS)
00134 return "Invalid goal constraints";
00135 else
00136 if (error_code.val == moveit_msgs::MoveItErrorCodes::INVALID_GROUP_NAME)
00137 return "Invalid group name";
00138 else
00139 if (error_code.val == moveit_msgs::MoveItErrorCodes::INVALID_OBJECT_NAME)
00140 return "Invalid object name";
00141 else
00142 if (error_code.val == moveit_msgs::MoveItErrorCodes::FAILURE)
00143 return "Catastrophic failure";
00144 return "Unknown event";
00145 }
00146
00147 void plan_execution::PlanExecution::planAndExecute(ExecutableMotionPlan &plan, const Options &opt)
00148 {
00149 plan.planning_scene_monitor_ = planning_scene_monitor_;
00150 plan.planning_scene_ = planning_scene_monitor_->getPlanningScene();
00151 planAndExecuteHelper(plan, opt);
00152 }
00153
00154 void plan_execution::PlanExecution::planAndExecute(ExecutableMotionPlan &plan, const moveit_msgs::PlanningScene &scene_diff, const Options &opt)
00155 {
00156 if (planning_scene::PlanningScene::isEmpty(scene_diff))
00157 planAndExecute(plan, opt);
00158 else
00159 {
00160 plan.planning_scene_monitor_ = planning_scene_monitor_;
00161 {
00162 planning_scene_monitor::LockedPlanningSceneRO lscene(planning_scene_monitor_);
00163 plan.planning_scene_ = lscene->diff(scene_diff);
00164 }
00165 planAndExecuteHelper(plan, opt);
00166 }
00167 }
00168
00169 void plan_execution::PlanExecution::planAndExecuteHelper(ExecutableMotionPlan &plan, const Options &opt)
00170 {
00171
00172 preempt_requested_ = false;
00173
00174
00175 unsigned int max_replan_attempts = opt.replan_ ? (opt.replan_attempts_ > 0 ? opt.replan_attempts_ : default_max_replan_attempts_) : 1;
00176 unsigned int replan_attempts = 0;
00177 bool previously_solved = false;
00178
00179
00180
00181 do
00182 {
00183 replan_attempts++;
00184 ROS_INFO("Planning attempt %u of at most %u", replan_attempts, max_replan_attempts);
00185
00186 if (opt.before_plan_callback_)
00187 opt.before_plan_callback_();
00188
00189 new_scene_update_ = false;
00190
00191
00192 bool solved = (!previously_solved || !opt.repair_plan_callback_) ?
00193 opt.plan_callback_(plan) :
00194 opt.repair_plan_callback_(plan, trajectory_execution_manager_->getCurrentExpectedTrajectoryIndex());
00195
00196 if (preempt_requested_)
00197 break;
00198
00199
00200
00201 if (plan.error_code_.val == moveit_msgs::MoveItErrorCodes::PLANNING_FAILED ||
00202 plan.error_code_.val == moveit_msgs::MoveItErrorCodes::INVALID_MOTION_PLAN ||
00203 plan.error_code_.val == moveit_msgs::MoveItErrorCodes::UNABLE_TO_AQUIRE_SENSOR_DATA)
00204 {
00205 if (plan.error_code_.val == moveit_msgs::MoveItErrorCodes::UNABLE_TO_AQUIRE_SENSOR_DATA && opt.replan_delay_ > 0.0)
00206 {
00207 ros::WallDuration d(opt.replan_delay_);
00208 d.sleep();
00209 }
00210 continue;
00211 }
00212
00213
00214 if (solved)
00215 previously_solved = true;
00216 else
00217 break;
00218
00219 if (plan.error_code_.val == moveit_msgs::MoveItErrorCodes::SUCCESS)
00220 {
00221 if (opt.before_execution_callback_)
00222 opt.before_execution_callback_();
00223
00224 if (preempt_requested_)
00225 break;
00226
00227
00228 plan.error_code_ = executeAndMonitor(plan);
00229 }
00230
00231
00232 if (plan.error_code_.val == moveit_msgs::MoveItErrorCodes::SUCCESS)
00233 break;
00234
00235
00236 if (plan.error_code_.val != moveit_msgs::MoveItErrorCodes::MOTION_PLAN_INVALIDATED_BY_ENVIRONMENT_CHANGE)
00237 break;
00238 else
00239 {
00240
00241 if (opt.replan_delay_ > 0.0)
00242 {
00243 ROS_INFO("Waiting for a %lf seconds before attempting a new plan ...", opt.replan_delay_);
00244 ros::WallDuration d(opt.replan_delay_);
00245 d.sleep();
00246 ROS_INFO("Done waiting");
00247 }
00248 }
00249 } while (!preempt_requested_ && max_replan_attempts > replan_attempts);
00250
00251 if (preempt_requested_)
00252 {
00253 ROS_DEBUG("PlanExecution was preempted");
00254 plan.error_code_.val = moveit_msgs::MoveItErrorCodes::PREEMPTED;
00255 }
00256
00257 if (opt.done_callback_)
00258 opt.done_callback_();
00259
00260 if( plan.error_code_.val == moveit_msgs::MoveItErrorCodes::SUCCESS )
00261 ROS_DEBUG("PlanExecution finished successfully.");
00262 else
00263 ROS_DEBUG("PlanExecution terminating with error code %d - '%s'", plan.error_code_.val,
00264 getErrorCodeString(plan.error_code_).c_str());
00265 }
00266
00267 bool plan_execution::PlanExecution::isRemainingPathValid(const ExecutableMotionPlan &plan)
00268 {
00269
00270
00271 return isRemainingPathValid(plan, trajectory_execution_manager_->getCurrentExpectedTrajectoryIndex());
00272 }
00273
00274 bool plan_execution::PlanExecution::isRemainingPathValid(const ExecutableMotionPlan &plan, const std::pair<int, int> &path_segment)
00275 {
00276 if (path_segment.first >= 0 && path_segment.second >= 0)
00277 {
00278 planning_scene_monitor::LockedPlanningSceneRO lscene(plan.planning_scene_monitor_);
00279 const robot_trajectory::RobotTrajectory &t = *plan.plan_components_[path_segment.first].trajectory_;
00280 const collision_detection::AllowedCollisionMatrix *acm = plan.plan_components_[path_segment.first].allowed_collision_matrix_.get();
00281 std::size_t wpc = t.getWayPointCount();
00282 collision_detection::CollisionRequest req;
00283 req.group_name = t.getGroupName();
00284 for (std::size_t i = std::max(path_segment.second - 1, 0) ; i < wpc ; ++i)
00285 {
00286 collision_detection::CollisionResult res;
00287 if (acm)
00288 plan.planning_scene_->checkCollisionUnpadded(req, res, t.getWayPoint(i), *acm);
00289 else
00290 plan.planning_scene_->checkCollisionUnpadded(req, res, t.getWayPoint(i));
00291
00292 if (res.collision || !plan.planning_scene_->isStateFeasible(t.getWayPoint(i), false))
00293 {
00294
00295 ROS_INFO("Trajectory component '%s' is invalid", plan.plan_components_[path_segment.first].description_.c_str());
00296
00297
00298 plan.planning_scene_->isStateFeasible(t.getWayPoint(i), true);
00299 req.verbose = true;
00300 res.clear();
00301 if (acm)
00302 plan.planning_scene_->checkCollisionUnpadded(req, res, t.getWayPoint(i), *acm);
00303 else
00304 plan.planning_scene_->checkCollisionUnpadded(req, res, t.getWayPoint(i));
00305 return false;
00306 }
00307 }
00308 }
00309 return true;
00310 }
00311
00312 moveit_msgs::MoveItErrorCodes plan_execution::PlanExecution::executeAndMonitor(const ExecutableMotionPlan &plan)
00313 {
00314 moveit_msgs::MoveItErrorCodes result;
00315
00316
00317 execution_complete_ = true;
00318
00319 if (!trajectory_execution_manager_)
00320 {
00321 ROS_ERROR("No trajectory execution manager");
00322 result.val = moveit_msgs::MoveItErrorCodes::CONTROL_FAILED;
00323 return result;
00324 }
00325
00326 if (plan.plan_components_.empty())
00327 {
00328 result.val = moveit_msgs::MoveItErrorCodes::SUCCESS;
00329 return result;
00330 }
00331
00332 execution_complete_ = false;
00333
00334
00335 int prev = -1;
00336 for (std::size_t i = 0 ; i < plan.plan_components_.size() ; ++i)
00337 {
00338 if (!plan.plan_components_[i].trajectory_ || plan.plan_components_[i].trajectory_->empty())
00339 continue;
00340
00341
00342
00343
00344
00345 bool unwound = false;
00346 for (std::size_t j = 0 ; j < i ; ++j)
00347
00348 if (plan.plan_components_[j].trajectory_ && plan.plan_components_[j].trajectory_->getGroup() == plan.plan_components_[i].trajectory_->getGroup() && !plan.plan_components_[j].trajectory_->empty())
00349 {
00350 plan.plan_components_[i].trajectory_->unwind(plan.plan_components_[j].trajectory_->getLastWayPoint());
00351 unwound = true;
00352 break;
00353 }
00354
00355 if (!unwound)
00356 {
00357
00358 if (prev < 0)
00359 plan.plan_components_[i].trajectory_->unwind(plan.planning_scene_monitor_ && plan.planning_scene_monitor_->getStateMonitor() ?
00360 *plan.planning_scene_monitor_->getStateMonitor()->getCurrentState() :
00361 plan.planning_scene_->getCurrentState());
00362 else
00363 plan.plan_components_[i].trajectory_->unwind(plan.plan_components_[prev].trajectory_->getLastWayPoint());
00364 }
00365
00366 prev = i;
00367
00368
00369 moveit_msgs::RobotTrajectory msg;
00370 plan.plan_components_[i].trajectory_->getRobotTrajectoryMsg(msg);
00371 if (!trajectory_execution_manager_->push(msg))
00372 {
00373 trajectory_execution_manager_->clear();
00374 ROS_ERROR_STREAM("Apparently trajectory initialization failed");
00375 execution_complete_ = true;
00376 result.val = moveit_msgs::MoveItErrorCodes::CONTROL_FAILED;
00377 return result;
00378 }
00379 }
00380
00381 if (!trajectory_monitor_ && planning_scene_monitor_->getStateMonitor())
00382 trajectory_monitor_.reset(new planning_scene_monitor::TrajectoryMonitor(planning_scene_monitor_->getStateMonitor()));
00383
00384
00385 if (trajectory_monitor_)
00386 trajectory_monitor_->startTrajectoryMonitor();
00387
00388
00389 trajectory_execution_manager_->execute(boost::bind(&PlanExecution::doneWithTrajectoryExecution, this, _1),
00390 boost::bind(&PlanExecution::successfulTrajectorySegmentExecution, this, &plan, _1));
00391
00392 ros::Rate r(100);
00393 path_became_invalid_ = false;
00394 while (node_handle_.ok() && !execution_complete_ && !preempt_requested_ && !path_became_invalid_)
00395 {
00396 r.sleep();
00397
00398 if (new_scene_update_)
00399 {
00400 new_scene_update_ = false;
00401 if (!isRemainingPathValid(plan))
00402 {
00403 path_became_invalid_ = true;
00404 break;
00405 }
00406 }
00407 }
00408
00409
00410 if (preempt_requested_)
00411 {
00412 ROS_INFO("Stopping execution due to preempt request");
00413 trajectory_execution_manager_->stopExecution();
00414 }
00415 else
00416 if (path_became_invalid_)
00417 {
00418 ROS_INFO("Stopping execution because the path to execute became invalid (probably the environment changed)");
00419 trajectory_execution_manager_->stopExecution();
00420 }
00421 else
00422 if (!execution_complete_)
00423 {
00424 ROS_WARN("Stopping execution due to unknown reason. Possibly the node is about to shut down.");
00425 trajectory_execution_manager_->stopExecution();
00426 }
00427
00428
00429 if (trajectory_monitor_)
00430 trajectory_monitor_->stopTrajectoryMonitor();
00431
00432
00433 if (path_became_invalid_)
00434 result.val = moveit_msgs::MoveItErrorCodes::MOTION_PLAN_INVALIDATED_BY_ENVIRONMENT_CHANGE;
00435 else
00436 {
00437 if (preempt_requested_)
00438 {
00439 result.val = moveit_msgs::MoveItErrorCodes::PREEMPTED;
00440 }
00441 else
00442 {
00443 if (trajectory_execution_manager_->getLastExecutionStatus() == moveit_controller_manager::ExecutionStatus::SUCCEEDED)
00444 result.val = moveit_msgs::MoveItErrorCodes::SUCCESS;
00445 else
00446 if (trajectory_execution_manager_->getLastExecutionStatus() == moveit_controller_manager::ExecutionStatus::TIMED_OUT)
00447 result.val = moveit_msgs::MoveItErrorCodes::TIMED_OUT;
00448 else
00449 result.val = moveit_msgs::MoveItErrorCodes::CONTROL_FAILED;
00450 }
00451 }
00452 return result;
00453 }
00454
00455 void plan_execution::PlanExecution::planningSceneUpdatedCallback(const planning_scene_monitor::PlanningSceneMonitor::SceneUpdateType update_type)
00456 {
00457 if (update_type & (planning_scene_monitor::PlanningSceneMonitor::UPDATE_GEOMETRY | planning_scene_monitor::PlanningSceneMonitor::UPDATE_TRANSFORMS))
00458 new_scene_update_ = true;
00459 }
00460
00461 void plan_execution::PlanExecution::doneWithTrajectoryExecution(const moveit_controller_manager::ExecutionStatus &status)
00462 {
00463 execution_complete_ = true;
00464 }
00465
00466 void plan_execution::PlanExecution::successfulTrajectorySegmentExecution(const ExecutableMotionPlan *plan, std::size_t index)
00467 {
00468 ROS_DEBUG("Completed '%s'", plan->plan_components_[index].description_.c_str());
00469
00470
00471 if (plan->plan_components_[index].effect_on_success_)
00472 if (!plan->plan_components_[index].effect_on_success_(plan))
00473 {
00474
00475 ROS_ERROR("Execution of path-completion side-effect failed. Preempting.");
00476 preempt_requested_ = true;
00477 return;
00478 }
00479
00480
00481 std::size_t test_index = index;
00482 while (++test_index < plan->plan_components_.size())
00483 if (plan->plan_components_[test_index].trajectory_ && !plan->plan_components_[test_index].trajectory_->empty())
00484 {
00485 if (!isRemainingPathValid(*plan, std::make_pair<int>(test_index, 0)))
00486 path_became_invalid_ = true;
00487 break;
00488 }
00489 }