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 "pick_place_action_capability.h"
00038 #include <moveit/plan_execution/plan_execution.h>
00039 #include <moveit/plan_execution/plan_with_sensing.h>
00040 #include <moveit/move_group_pick_place_capability/capability_names.h>
00041
00042 #include <manipulation_msgs/GraspPlanning.h>
00043 #include <eigen_conversions/eigen_msg.h>
00044
00045 move_group::MoveGroupPickPlaceAction::MoveGroupPickPlaceAction() :
00046 MoveGroupCapability("PickPlaceAction"),
00047 pickup_state_(IDLE)
00048 {
00049 }
00050
00051 void move_group::MoveGroupPickPlaceAction::initialize()
00052 {
00053 pick_place_.reset(new pick_place::PickPlace(context_->planning_pipeline_));
00054 pick_place_->displayComputedMotionPlans(true);
00055
00056 if (context_->debug_)
00057 pick_place_->displayProcessedGrasps(true);
00058
00059
00060 pickup_action_server_.reset(new actionlib::SimpleActionServer<moveit_msgs::PickupAction>(root_node_handle_, PICKUP_ACTION,
00061 boost::bind(&MoveGroupPickPlaceAction::executePickupCallback, this, _1), false));
00062 pickup_action_server_->registerPreemptCallback(boost::bind(&MoveGroupPickPlaceAction::preemptPickupCallback, this));
00063 pickup_action_server_->start();
00064
00065
00066 place_action_server_.reset(new actionlib::SimpleActionServer<moveit_msgs::PlaceAction>(root_node_handle_, PLACE_ACTION,
00067 boost::bind(&MoveGroupPickPlaceAction::executePlaceCallback, this, _1), false));
00068 place_action_server_->registerPreemptCallback(boost::bind(&MoveGroupPickPlaceAction::preemptPlaceCallback, this));
00069 place_action_server_->start();
00070
00071 grasp_planning_service_ = root_node_handle_.serviceClient<manipulation_msgs::GraspPlanning>("database_grasp_planning");
00072 }
00073
00074 void move_group::MoveGroupPickPlaceAction::startPickupExecutionCallback()
00075 {
00076 setPickupState(MONITOR);
00077 }
00078
00079 void move_group::MoveGroupPickPlaceAction::startPickupLookCallback()
00080 {
00081 setPickupState(LOOK);
00082 }
00083
00084 void move_group::MoveGroupPickPlaceAction::startPlaceExecutionCallback()
00085 {
00086 setPlaceState(MONITOR);
00087 }
00088
00089 void move_group::MoveGroupPickPlaceAction::startPlaceLookCallback()
00090 {
00091 setPlaceState(LOOK);
00092 }
00093
00094 void move_group::MoveGroupPickPlaceAction::executePickupCallback_PlanOnly(const moveit_msgs::PickupGoalConstPtr& goal, moveit_msgs::PickupResult &action_res)
00095 {
00096 pick_place::PickPlanPtr plan;
00097 try
00098 {
00099 planning_scene_monitor::LockedPlanningSceneRO ps(context_->planning_scene_monitor_);
00100 plan = pick_place_->planPick(ps, *goal);
00101 }
00102 catch(std::runtime_error &ex)
00103 {
00104 ROS_ERROR("Pick&place threw an exception: %s", ex.what());
00105 }
00106 catch(...)
00107 {
00108 ROS_ERROR("Pick&place threw an exception");
00109 }
00110
00111 if (plan)
00112 {
00113 const std::vector<pick_place::ManipulationPlanPtr> &success = plan->getSuccessfulManipulationPlans();
00114 if (success.empty())
00115 {
00116 action_res.error_code = plan->getErrorCode();
00117 }
00118 else
00119 {
00120 const pick_place::ManipulationPlanPtr &result = success.back();
00121 convertToMsg(result->trajectories_, action_res.trajectory_start, action_res.trajectory_stages);
00122 action_res.trajectory_descriptions.resize(result->trajectories_.size());
00123 for (std::size_t i = 0 ; i < result->trajectories_.size() ; ++i)
00124 action_res.trajectory_descriptions[i] = result->trajectories_[i].description_;
00125 action_res.error_code.val = moveit_msgs::MoveItErrorCodes::SUCCESS;
00126 }
00127 }
00128 else
00129 {
00130 action_res.error_code.val = moveit_msgs::MoveItErrorCodes::FAILURE;
00131 }
00132 }
00133
00134 void move_group::MoveGroupPickPlaceAction::executePlaceCallback_PlanOnly(const moveit_msgs::PlaceGoalConstPtr& goal, moveit_msgs::PlaceResult &action_res)
00135 {
00136 pick_place::PlacePlanPtr plan;
00137 try
00138 {
00139 planning_scene_monitor::LockedPlanningSceneRO ps(context_->planning_scene_monitor_);
00140 plan = pick_place_->planPlace(ps, *goal);
00141 }
00142 catch(std::runtime_error &ex)
00143 {
00144 ROS_ERROR("Pick&place threw an exception: %s", ex.what());
00145 }
00146 catch(...)
00147 {
00148 ROS_ERROR("Pick&place threw an exception");
00149 }
00150
00151 if (plan)
00152 {
00153 const std::vector<pick_place::ManipulationPlanPtr> &success = plan->getSuccessfulManipulationPlans();
00154 if (success.empty())
00155 {
00156 action_res.error_code = plan->getErrorCode();
00157 }
00158 else
00159 {
00160 const pick_place::ManipulationPlanPtr &result = success.back();
00161 convertToMsg(result->trajectories_, action_res.trajectory_start, action_res.trajectory_stages);
00162 action_res.trajectory_descriptions.resize(result->trajectories_.size());
00163 for (std::size_t i = 0 ; i < result->trajectories_.size() ; ++i)
00164 action_res.trajectory_descriptions[i] = result->trajectories_[i].description_;
00165 action_res.error_code.val = moveit_msgs::MoveItErrorCodes::SUCCESS;
00166 }
00167 }
00168 else
00169 {
00170 action_res.error_code.val = moveit_msgs::MoveItErrorCodes::FAILURE;
00171 }
00172 }
00173
00174 bool move_group::MoveGroupPickPlaceAction::planUsingPickPlace_Pickup(const moveit_msgs::PickupGoal& goal, plan_execution::ExecutableMotionPlan &plan)
00175 {
00176 setPickupState(PLANNING);
00177
00178 planning_scene_monitor::LockedPlanningSceneRO ps(plan.planning_scene_monitor_);
00179
00180 pick_place::PickPlanPtr pick_plan;
00181 try
00182 {
00183 pick_plan = pick_place_->planPick(plan.planning_scene_, goal);
00184 }
00185 catch(std::runtime_error &ex)
00186 {
00187 ROS_ERROR("Pick&place threw an exception: %s", ex.what());
00188 }
00189 catch(...)
00190 {
00191 ROS_ERROR("Pick&place threw an exception");
00192 }
00193
00194 if (pick_plan)
00195 {
00196 const std::vector<pick_place::ManipulationPlanPtr> &success = pick_plan->getSuccessfulManipulationPlans();
00197 if (success.empty())
00198 {
00199 plan.error_code_ = pick_plan->getErrorCode();
00200 }
00201 else
00202 {
00203 const pick_place::ManipulationPlanPtr &result = success.back();
00204 plan.plan_components_ = result->trajectories_;
00205 plan.error_code_.val = moveit_msgs::MoveItErrorCodes::SUCCESS;
00206 }
00207 }
00208 else
00209 {
00210 plan.error_code_.val = moveit_msgs::MoveItErrorCodes::FAILURE;
00211 }
00212
00213 return plan.error_code_.val == moveit_msgs::MoveItErrorCodes::SUCCESS;
00214 }
00215
00216 bool move_group::MoveGroupPickPlaceAction::planUsingPickPlace_Place(const moveit_msgs::PlaceGoal& goal, plan_execution::ExecutableMotionPlan &plan)
00217 {
00218 setPlaceState(PLANNING);
00219
00220 planning_scene_monitor::LockedPlanningSceneRO ps(plan.planning_scene_monitor_);
00221
00222 pick_place::PlacePlanPtr place_plan;
00223 try
00224 {
00225 place_plan = pick_place_->planPlace(plan.planning_scene_, goal);
00226 }
00227 catch(std::runtime_error &ex)
00228 {
00229 ROS_ERROR("Pick&place threw an exception: %s", ex.what());
00230 }
00231 catch(...)
00232 {
00233 ROS_ERROR("Pick&place threw an exception");
00234 }
00235
00236 if (place_plan)
00237 {
00238 const std::vector<pick_place::ManipulationPlanPtr> &success = place_plan->getSuccessfulManipulationPlans();
00239 if (success.empty())
00240 {
00241 plan.error_code_ = place_plan->getErrorCode();
00242 }
00243 else
00244 {
00245 const pick_place::ManipulationPlanPtr &result = success.back();
00246 plan.plan_components_ = result->trajectories_;
00247 plan.error_code_.val = moveit_msgs::MoveItErrorCodes::SUCCESS;
00248 }
00249 }
00250 else
00251 {
00252 plan.error_code_.val = moveit_msgs::MoveItErrorCodes::FAILURE;
00253 }
00254
00255 return plan.error_code_.val == moveit_msgs::MoveItErrorCodes::SUCCESS;
00256 }
00257
00258 void move_group::MoveGroupPickPlaceAction::executePickupCallback_PlanAndExecute(const moveit_msgs::PickupGoalConstPtr& goal, moveit_msgs::PickupResult &action_res)
00259 {
00260 plan_execution::PlanExecution::Options opt;
00261
00262 opt.replan_ = goal->planning_options.replan;
00263 opt.replan_attempts_ = goal->planning_options.replan_attempts;
00264 opt.replan_delay_ = goal->planning_options.replan_delay;
00265 opt.before_execution_callback_ = boost::bind(&MoveGroupPickPlaceAction::startPickupExecutionCallback, this);
00266
00267 opt.plan_callback_ = boost::bind(&MoveGroupPickPlaceAction::planUsingPickPlace_Pickup, this, boost::cref(*goal), _1);
00268 if (goal->planning_options.look_around && context_->plan_with_sensing_)
00269 {
00270 opt.plan_callback_ = boost::bind(&plan_execution::PlanWithSensing::computePlan, context_->plan_with_sensing_.get(), _1, opt.plan_callback_,
00271 goal->planning_options.look_around_attempts, goal->planning_options.max_safe_execution_cost);
00272 context_->plan_with_sensing_->setBeforeLookCallback(boost::bind(&MoveGroupPickPlaceAction::startPickupLookCallback, this));
00273 }
00274
00275 plan_execution::ExecutableMotionPlan plan;
00276 context_->plan_execution_->planAndExecute(plan, goal->planning_options.planning_scene_diff, opt);
00277
00278 convertToMsg(plan.plan_components_, action_res.trajectory_start, action_res.trajectory_stages);
00279 action_res.trajectory_descriptions.resize(plan.plan_components_.size());
00280 for (std::size_t i = 0 ; i < plan.plan_components_.size() ; ++i)
00281 {
00282 action_res.trajectory_descriptions[i] = plan.plan_components_[i].description_;
00283 }
00284 addGraspToPickupResult(plan, action_res);
00285 action_res.error_code = plan.error_code_;
00286 }
00287
00288 void move_group::MoveGroupPickPlaceAction::addGraspToPickupResult(const plan_execution::ExecutableMotionPlan &plan,
00289 moveit_msgs::PickupResult &action_res) const
00290 {
00291 for (std::size_t i = 0 ; i < plan.plan_components_.size() ; ++i)
00292 {
00293 if(plan.plan_components_[i].description_ == "pre_grasp")
00294 {
00295 action_res.grasp.pre_grasp_posture.name = plan.plan_components_[i].trajectory_->getGroup()->getJointModelNames();
00296 plan.plan_components_[i].trajectory_->getLastWayPoint().getJointStateGroup(plan.plan_components_[i].trajectory_->getGroupName())->getVariableValues(action_res.grasp.pre_grasp_posture.position);
00297 }
00298 if(plan.plan_components_[i].description_ == "grasp")
00299 {
00300 action_res.grasp.grasp_posture.name = plan.plan_components_[i].trajectory_->getGroup()->getJointModelNames();
00301 plan.plan_components_[i].trajectory_->getLastWayPoint().getJointStateGroup(plan.plan_components_[i].trajectory_->getGroupName())->getVariableValues(action_res.grasp.grasp_posture.position);
00302 }
00303 }
00304 }
00305
00306 void move_group::MoveGroupPickPlaceAction::executePlaceCallback_PlanAndExecute(const moveit_msgs::PlaceGoalConstPtr& goal, moveit_msgs::PlaceResult &action_res)
00307 {
00308 plan_execution::PlanExecution::Options opt;
00309
00310 opt.replan_ = goal->planning_options.replan;
00311 opt.replan_attempts_ = goal->planning_options.replan_attempts;
00312 opt.replan_delay_ = goal->planning_options.replan_delay;
00313 opt.before_execution_callback_ = boost::bind(&MoveGroupPickPlaceAction::startPlaceExecutionCallback, this);
00314 opt.plan_callback_ = boost::bind(&MoveGroupPickPlaceAction::planUsingPickPlace_Place, this, boost::cref(*goal), _1);
00315 if (goal->planning_options.look_around && context_->plan_with_sensing_)
00316 {
00317 opt.plan_callback_ = boost::bind(&plan_execution::PlanWithSensing::computePlan, context_->plan_with_sensing_.get(), _1, opt.plan_callback_,
00318 goal->planning_options.look_around_attempts, goal->planning_options.max_safe_execution_cost);
00319 context_->plan_with_sensing_->setBeforeLookCallback(boost::bind(&MoveGroupPickPlaceAction::startPlaceLookCallback, this));
00320 }
00321
00322 plan_execution::ExecutableMotionPlan plan;
00323 context_->plan_execution_->planAndExecute(plan, goal->planning_options.planning_scene_diff, opt);
00324
00325 convertToMsg(plan.plan_components_, action_res.trajectory_start, action_res.trajectory_stages);
00326 action_res.trajectory_descriptions.resize(plan.plan_components_.size());
00327 for (std::size_t i = 0 ; i < plan.plan_components_.size() ; ++i)
00328 action_res.trajectory_descriptions[i] = plan.plan_components_[i].description_;
00329 action_res.error_code = plan.error_code_;
00330 }
00331
00332 void move_group::MoveGroupPickPlaceAction::executePickupCallback(const moveit_msgs::PickupGoalConstPtr& input_goal)
00333 {
00334 setPickupState(PLANNING);
00335
00336 context_->planning_scene_monitor_->updateFrameTransforms();
00337
00338 moveit_msgs::PickupGoalConstPtr goal;
00339 if (input_goal->possible_grasps.empty())
00340 {
00341 moveit_msgs::PickupGoal* copy(new moveit_msgs::PickupGoal(*input_goal));
00342 goal.reset(copy);
00343 fillGrasps(*copy);
00344 }
00345 else
00346 goal = input_goal;
00347
00348 moveit_msgs::PickupResult action_res;
00349
00350 if (goal->planning_options.plan_only || !context_->allow_trajectory_execution_)
00351 {
00352 if (!goal->planning_options.plan_only)
00353 ROS_WARN("This instance of MoveGroup is not allowed to execute trajectories but the pick goal request has plan_only set to false. Only a motion plan will be computed anyway.");
00354 executePickupCallback_PlanOnly(goal, action_res);
00355 }
00356 else
00357 executePickupCallback_PlanAndExecute(goal, action_res);
00358
00359 bool planned_trajectory_empty = action_res.trajectory_stages.empty();
00360 std::string response = getActionResultString(action_res.error_code, planned_trajectory_empty, goal->planning_options.plan_only);
00361 if (action_res.error_code.val == moveit_msgs::MoveItErrorCodes::SUCCESS)
00362 pickup_action_server_->setSucceeded(action_res, response);
00363 else
00364 {
00365 if (action_res.error_code.val == moveit_msgs::MoveItErrorCodes::PREEMPTED)
00366 pickup_action_server_->setPreempted(action_res, response);
00367 else
00368 pickup_action_server_->setAborted(action_res, response);
00369 }
00370
00371 setPickupState(IDLE);
00372 }
00373
00374 void move_group::MoveGroupPickPlaceAction::executePlaceCallback(const moveit_msgs::PlaceGoalConstPtr& goal)
00375 {
00376 setPlaceState(PLANNING);
00377
00378 context_->planning_scene_monitor_->updateFrameTransforms();
00379
00380 moveit_msgs::PlaceResult action_res;
00381
00382 if (goal->planning_options.plan_only || !context_->allow_trajectory_execution_)
00383 {
00384 if (!goal->planning_options.plan_only)
00385 ROS_WARN("This instance of MoveGroup is not allowed to execute trajectories but the place goal request has plan_only set to false. Only a motion plan will be computed anyway.");
00386 executePlaceCallback_PlanOnly(goal, action_res);
00387 }
00388 else
00389 executePlaceCallback_PlanAndExecute(goal, action_res);
00390
00391 bool planned_trajectory_empty = action_res.trajectory_stages.empty();
00392 std::string response = getActionResultString(action_res.error_code, planned_trajectory_empty, goal->planning_options.plan_only);
00393 if (action_res.error_code.val == moveit_msgs::MoveItErrorCodes::SUCCESS)
00394 place_action_server_->setSucceeded(action_res, response);
00395 else
00396 {
00397 if (action_res.error_code.val == moveit_msgs::MoveItErrorCodes::PREEMPTED)
00398 place_action_server_->setPreempted(action_res, response);
00399 else
00400 place_action_server_->setAborted(action_res, response);
00401 }
00402
00403 setPlaceState(IDLE);
00404 }
00405
00406 void move_group::MoveGroupPickPlaceAction::preemptPickupCallback()
00407 {
00408 }
00409
00410 void move_group::MoveGroupPickPlaceAction::preemptPlaceCallback()
00411 {
00412 }
00413
00414 void move_group::MoveGroupPickPlaceAction::setPickupState(MoveGroupState state)
00415 {
00416 pickup_state_ = state;
00417 pickup_feedback_.state = stateToStr(state);
00418 pickup_action_server_->publishFeedback(pickup_feedback_);
00419 }
00420
00421 void move_group::MoveGroupPickPlaceAction::setPlaceState(MoveGroupState state)
00422 {
00423 place_state_ = state;
00424 place_feedback_.state = stateToStr(state);
00425 place_action_server_->publishFeedback(place_feedback_);
00426 }
00427
00428 void move_group::MoveGroupPickPlaceAction::fillGrasps(moveit_msgs::PickupGoal& goal)
00429 {
00430 planning_scene_monitor::LockedPlanningSceneRO lscene(context_->planning_scene_monitor_);
00431 manipulation_msgs::GraspPlanning::Request request;
00432 manipulation_msgs::GraspPlanning::Response response;
00433
00434 if (grasp_planning_service_ && lscene->hasObjectType(goal.target_name) && !lscene->getObjectType(goal.target_name).key.empty())
00435 {
00436 collision_detection::World::ObjectConstPtr object = lscene->getWorld()->getObject(goal.target_name);
00437 if (object && !object->shape_poses_.empty())
00438 {
00439 request.arm_name = goal.group_name;
00440 request.target.reference_frame_id = lscene->getPlanningFrame();
00441
00442 household_objects_database_msgs::DatabaseModelPose dbp;
00443 dbp.pose.header.frame_id = lscene->getPlanningFrame();
00444 dbp.pose.header.stamp = ros::Time::now();
00445 tf::poseEigenToMsg(object->shape_poses_[0], dbp.pose.pose);
00446
00447 dbp.type = lscene->getObjectType(goal.target_name);
00448 std::stringstream dbp_type(dbp.type.key);
00449 dbp_type >> dbp.model_id;
00450 ROS_DEBUG("Asking database for grasps for %s with model id: %d", dbp.type.key.c_str(), dbp.model_id);
00451 request.target.potential_models.push_back(dbp);
00452 }
00453 else
00454 {
00455 ROS_ERROR("Object has no geometry");
00456 }
00457
00458 ROS_DEBUG("Calling grasp planner...");
00459 if (grasp_planning_service_.call(request, response))
00460 goal.possible_grasps = response.grasps;
00461 }
00462
00463 if (goal.possible_grasps.empty())
00464 {
00465 ROS_DEBUG("Using default grasp poses");
00466 goal.minimize_object_distance = true;
00467
00468
00469
00470 manipulation_msgs::Grasp g;
00471 g.grasp_pose.header.frame_id = goal.target_name;
00472 g.grasp_pose.pose.position.x = -0.2;
00473 g.grasp_pose.pose.position.y = 0.0;
00474 g.grasp_pose.pose.position.z = 0.0;
00475 g.grasp_pose.pose.orientation.x = 0.0;
00476 g.grasp_pose.pose.orientation.y = 0.0;
00477 g.grasp_pose.pose.orientation.z = 0.0;
00478 g.grasp_pose.pose.orientation.w = 1.0;
00479
00480 g.approach.direction.header.frame_id = lscene->getPlanningFrame();
00481 g.approach.direction.vector.x = 1.0;
00482 g.approach.min_distance = 0.1;
00483 g.approach.desired_distance = 0.2;
00484
00485 g.retreat.direction.header.frame_id = lscene->getPlanningFrame();
00486 g.retreat.direction.vector.z = 1.0;
00487 g.retreat.min_distance = 0.1;
00488 g.retreat.desired_distance = 0.2;
00489
00490 if (lscene->getRobotModel()->hasEndEffector(goal.end_effector))
00491 {
00492 g.pre_grasp_posture.name = lscene->getRobotModel()->getEndEffector(goal.end_effector)->getJointModelNames();
00493 g.pre_grasp_posture.position.resize(g.pre_grasp_posture.name.size(), std::numeric_limits<double>::max());
00494
00495 g.grasp_posture.name = g.pre_grasp_posture.name;
00496 g.grasp_posture.position.resize(g.grasp_posture.name.size(), -std::numeric_limits<double>::max());
00497 }
00498 goal.possible_grasps.push_back(g);
00499 }
00500 }
00501
00502 #include <class_loader/class_loader.h>
00503 CLASS_LOADER_REGISTER_CLASS(move_group::MoveGroupPickPlaceAction, move_group::MoveGroupCapability)