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 #include "object_manipulator/object_manipulator.h"
00037
00038 #include <algorithm>
00039
00040
00041
00042
00043
00044
00045
00046 #include <object_manipulation_msgs/tools.h>
00047
00048
00049 #include "object_manipulator/grasp_execution/grasp_executor_with_approach.h"
00050 #include "object_manipulator/grasp_execution/reactive_grasp_executor.h"
00051 #include "object_manipulator/grasp_execution/unsafe_grasp_executor.h"
00052 #include "object_manipulator/place_execution/place_executor.h"
00053
00054
00055 #include "object_manipulator/grasp_execution/approach_lift_grasp.h"
00056 #include "object_manipulator/grasp_execution/grasp_tester_fast.h"
00057 #include "object_manipulator/place_execution/descend_retreat_place.h"
00058 #include "object_manipulator/place_execution/place_tester_fast.h"
00059
00060 #include "object_manipulator/tools/grasp_marker_publisher.h"
00061 #include "object_manipulator/tools/exceptions.h"
00062
00063 using object_manipulation_msgs::GraspableObject;
00064 using object_manipulation_msgs::PickupGoal;
00065 using object_manipulation_msgs::PickupResult;
00066 using object_manipulation_msgs::PickupFeedback;
00067 using object_manipulation_msgs::PlaceGoal;
00068 using object_manipulation_msgs::PlaceResult;
00069 using object_manipulation_msgs::PlaceFeedback;
00070 using object_manipulation_msgs::ManipulationResult;
00071 using object_manipulation_msgs::GraspResult;
00072 using object_manipulation_msgs::PlaceLocationResult;
00073 using object_manipulation_msgs::getGraspResultInfo;
00074 using object_manipulation_msgs::getPlaceLocationResultInfo;
00075 using object_manipulation_msgs::Grasp;
00076 using object_manipulation_msgs::GraspPlanningAction;
00077
00078 namespace object_manipulator {
00079
00080 ObjectManipulator::ObjectManipulator() :
00081 priv_nh_("~"),
00082 root_nh_(""),
00083 grasp_planning_actions_("", "", false, false),
00084 marker_pub_(NULL)
00085 {
00086 bool publish_markers = true;
00087 if (publish_markers)
00088 {
00089 marker_pub_ = new GraspMarkerPublisher();
00090 }
00091
00092
00093 grasp_executor_with_approach_ = new GraspExecutorWithApproach(marker_pub_);
00094 reactive_grasp_executor_ = new ReactiveGraspExecutor(marker_pub_);
00095 unsafe_grasp_executor_ = new UnsafeGraspExecutor(marker_pub_);
00096 place_executor_ = new PlaceExecutor(marker_pub_);
00097 reactive_place_executor_ = new ReactivePlaceExecutor(marker_pub_);
00098
00099
00100
00101 priv_nh_.param<std::string>("kinematics_plugin_name", kinematics_plugin_name_, "pr2_arm_kinematics/PR2ArmKinematicsPlugin");
00102
00103 grasp_tester_with_approach_ = new GraspTesterWithApproach;
00104 grasp_tester_with_approach_->setMarkerPublisher(marker_pub_);
00105 grasp_tester_fast_ = new GraspTesterFast(NULL, kinematics_plugin_name_);
00106 grasp_tester_fast_->setMarkerPublisher(marker_pub_);
00107 unsafe_grasp_tester_ = new UnsafeGraspTester;
00108 unsafe_grasp_tester_->setMarkerPublisher(marker_pub_);
00109 standard_grasp_performer_ = new StandardGraspPerformer;
00110 standard_grasp_performer_->setMarkerPublisher(marker_pub_);
00111 reactive_grasp_performer_ = new ReactiveGraspPerformer;
00112 reactive_grasp_performer_->setMarkerPublisher(marker_pub_);
00113 unsafe_grasp_performer_ = new UnsafeGraspPerformer;
00114 unsafe_grasp_performer_->setMarkerPublisher(marker_pub_);
00115
00116 standard_place_tester_ = new PlaceTesterFast(NULL, kinematics_plugin_name_);
00117 standard_place_tester_->setMarkerPublisher(marker_pub_);
00118 standard_place_performer_ = new StandardPlacePerformer;
00119 standard_place_performer_->setMarkerPublisher(marker_pub_);
00120 reactive_place_performer_ = new ReactivePlacePerformer;
00121 reactive_place_performer_->setMarkerPublisher(marker_pub_);
00122
00123 priv_nh_.param<std::string>("default_cluster_planner", default_cluster_planner_, "default_cluster_planner");
00124 priv_nh_.param<std::string>("default_database_planner", default_database_planner_, "default_database_planner");
00125 priv_nh_.param<std::string>("default_probabilistic_planner", default_probabilistic_planner_,
00126 "default_probabilistic_planner");
00127 priv_nh_.param<bool>("use_probabilistic_grasp_planner", use_probabilistic_planner_, false);
00128 priv_nh_.param<bool>("randomize_grasps", randomize_grasps_, false);
00129
00130 ROS_INFO("Object manipulator ready. Default cluster planner: %s. Default database planner: %s.",
00131 default_cluster_planner_.c_str(), default_database_planner_.c_str());
00132 if(use_probabilistic_planner_)
00133 {
00134 ROS_INFO("Probabilistic planner enabled");
00135 }
00136 ROS_INFO_NAMED("manipulation","Object manipulator ready");
00137 }
00138
00139 ObjectManipulator::~ObjectManipulator()
00140 {
00141 delete marker_pub_;
00142
00143
00144 delete grasp_executor_with_approach_;
00145 delete reactive_grasp_executor_;
00146 delete unsafe_grasp_executor_;
00147 delete place_executor_;
00148 delete reactive_place_executor_;
00149
00150
00151 delete grasp_tester_fast_;
00152 delete grasp_tester_with_approach_;
00153 delete unsafe_grasp_tester_;
00154 delete standard_grasp_performer_;
00155 delete reactive_grasp_performer_;
00156 delete unsafe_grasp_performer_;
00157
00158 delete standard_place_tester_;
00159 delete standard_place_performer_;
00160 delete reactive_place_performer_;
00161 }
00162
00163 void ObjectManipulator::graspFeedback(
00164 actionlib::SimpleActionServer<object_manipulation_msgs::PickupAction> *action_server,
00165 size_t tested_grasps, size_t current_grasp)
00166 {
00167 PickupFeedback feedback;
00168 feedback.total_grasps = grasp_container_.size();
00169 feedback.current_grasp = current_grasp + tested_grasps;
00170 action_server->publishFeedback(feedback);
00171 }
00172
00173 void ObjectManipulator::graspPlanningFeedbackCallback(
00174 const object_manipulation_msgs::GraspPlanningFeedbackConstPtr &feedback)
00175 {
00176 ROS_DEBUG_STREAM_NAMED("manipulation", "Feedback from planning action, total grasps: " << feedback->grasps.size());
00177 grasp_container_.addGrasps(feedback->grasps);
00178 }
00179
00180 void ObjectManipulator::graspPlanningDoneCallback(const actionlib::SimpleClientGoalState& state,
00181 const object_manipulation_msgs::GraspPlanningResultConstPtr &result)
00182 {
00183 if (state == actionlib::SimpleClientGoalState::SUCCEEDED)
00184 {
00185 ROS_DEBUG_STREAM_NAMED("manipulation", "Final result from planning action, total grasps: " << result->grasps.size());
00186 grasp_container_.addGrasps(result->grasps);
00187 }
00188 else
00189 {
00190 ROS_ERROR("Grasp planning action did not succeed");
00191 }
00192 }
00193
00194 void ObjectManipulator::pickup(const PickupGoal::ConstPtr &pickup_goal,
00195 actionlib::SimpleActionServer<object_manipulation_msgs::PickupAction> *action_server)
00196 {
00197
00198 PickupResult result;
00199
00200
00201
00202
00203
00204 if ( pickup_goal->target.cluster.points.size() > 0)
00205 {
00206 for (size_t i=0; i<pickup_goal->target.potential_models.size(); i++)
00207 {
00208 if ( pickup_goal->target.potential_models[i].pose.header.frame_id != pickup_goal->target.cluster.header.frame_id)
00209 {
00210 ROS_ERROR("Target object recognition result(s) not in the same frame as the cluster");
00211 result.manipulation_result.value = ManipulationResult::ERROR;
00212 action_server->setAborted(result);
00213 return;
00214 }
00215 }
00216 }
00217
00218
00219 grasp_container_.clear();
00220 bool using_planner_action;
00221 std::string planner_action;
00222 if (!pickup_goal->desired_grasps.empty())
00223 {
00224
00225 grasp_container_.addGrasps(pickup_goal->desired_grasps);
00226 using_planner_action = false;
00227 }
00228 else
00229 {
00230 if (use_probabilistic_planner_)
00231 {
00232 ROS_INFO("Using probabilistic planner");
00233
00234 planner_action = default_probabilistic_planner_;
00235 }
00236 else
00237 {
00238
00239 if (!pickup_goal->target.potential_models.empty())
00240 planner_action = default_database_planner_;
00241 else
00242 planner_action = default_cluster_planner_;
00243 }
00244
00245
00246 object_manipulation_msgs::GraspPlanningGoal goal;
00247 goal.arm_name = pickup_goal->arm_name;
00248 goal.target = pickup_goal->target;
00249 goal.collision_object_name = pickup_goal->collision_object_name;
00250 goal.collision_support_surface_name = pickup_goal->collision_support_surface_name;
00251 goal.movable_obstacles = pickup_goal->movable_obstacles;
00252 try
00253 {
00254 grasp_planning_actions_.client(planner_action).sendGoal(goal,
00255 boost::bind(&ObjectManipulator::graspPlanningDoneCallback, this, _1, _2),
00256 actionlib::SimpleActionClient<GraspPlanningAction>::SimpleActiveCallback(),
00257 boost::bind(&ObjectManipulator::graspPlanningFeedbackCallback, this, _1));
00258 }
00259 catch (ServiceNotFoundException &ex)
00260 {
00261 ROS_ERROR("Planning action %s not found", planner_action.c_str());
00262 result.manipulation_result.value = ManipulationResult::ERROR;
00263 action_server->setAborted(result);
00264 return;
00265 }
00266 using_planner_action = true;
00267 }
00268 ScopedGoalCancel<GraspPlanningAction> goal_cancel(NULL);
00269 if (using_planner_action)
00270 {
00271 goal_cancel.setClient(&grasp_planning_actions_.client(planner_action));
00272 }
00273
00274 GraspTester *grasp_tester;
00275 GraspPerformer *grasp_performer;
00276 if (pickup_goal->ignore_collisions)
00277 {
00278 grasp_tester = unsafe_grasp_tester_;
00279 grasp_performer = unsafe_grasp_performer_;
00280 }
00281 else
00282 {
00283 grasp_tester = grasp_tester_fast_;
00284 if (pickup_goal->use_reactive_execution)
00285 {
00286 grasp_performer = reactive_grasp_performer_;
00287 }
00288 else
00289 {
00290 grasp_performer = standard_grasp_performer_;
00291 }
00292 }
00293
00294 grasp_tester->setInterruptFunction(
00295 boost::bind(&actionlib::SimpleActionServer<object_manipulation_msgs::PickupAction>::isPreemptRequested,
00296 action_server));
00297 grasp_performer->setInterruptFunction(
00298 boost::bind(&actionlib::SimpleActionServer<object_manipulation_msgs::PickupAction>::isPreemptRequested,
00299 action_server));
00300
00301
00302
00303
00304 ros::WallDuration dur(1.0);
00305 dur.sleep();
00306
00307 arm_navigation_msgs::OrderedCollisionOperations emp_coll;
00308 std::vector<arm_navigation_msgs::LinkPadding> link_padding;
00309 mechInterface().getPlanningScene(emp_coll, link_padding);
00310
00311 std::map<unsigned int, unsigned int> results;
00312
00313 ros::WallTime start = ros::WallTime::now();
00314
00315
00316 result.manipulation_result.value = ManipulationResult::UNFEASIBLE;
00317 try
00318 {
00319 size_t tested_grasps = 0;
00320 while (1)
00321 {
00322 if (action_server->isPreemptRequested()) throw InterruptRequestedException();
00323
00324 ROS_DEBUG_STREAM_NAMED("manipulation", "Object manipulator: getting grasps beyond " << tested_grasps);
00325 std::vector<object_manipulation_msgs::Grasp> new_grasps = grasp_container_.getGrasps(tested_grasps);
00326 if ( new_grasps.empty() )
00327 {
00328 if ( using_planner_action && (grasp_planning_actions_.client(planner_action).getState() ==
00329 actionlib::SimpleClientGoalState::ACTIVE ||
00330 grasp_planning_actions_.client(planner_action).getState() ==
00331 actionlib::SimpleClientGoalState::PENDING) )
00332 {
00333 ROS_DEBUG_NAMED("manipulation", "Object manipulator: waiting for planner action to provide grasps");
00334 ros::Duration(0.25).sleep();
00335 continue;
00336 }
00337 else
00338 {
00339 ROS_INFO("Object manipulator: all grasps have been tested");
00340 break;
00341 }
00342 }
00343 grasp_tester->setFeedbackFunction(boost::bind(&ObjectManipulator::graspFeedback,
00344 this, action_server, tested_grasps, _1));
00345
00346 std::vector<GraspExecutionInfo> execution_info;
00347 grasp_tester->testGrasps(*pickup_goal, new_grasps, execution_info, !pickup_goal->only_perform_feasibility_test);
00348 if (execution_info.empty()) throw GraspException("grasp tester provided empty ExecutionInfo");
00349 if (execution_info.empty()) throw GraspException("grasp tester provided empty ExecutionInfo");
00350
00351 if (!pickup_goal->only_perform_feasibility_test)
00352 {
00353 ROS_DEBUG_NAMED("manipulation", "Attempting to perform grasps");
00354 grasp_performer->performGrasps(*pickup_goal, new_grasps, execution_info);
00355 }
00356 if (execution_info.empty()) throw GraspException("grasp performer provided empty ExecutionInfo");
00357
00358 for (size_t i=0; i<execution_info.size(); i++)
00359 {
00360 result.attempted_grasps.push_back(new_grasps[i]);
00361 result.attempted_grasp_results.push_back(execution_info[i].result_);
00362 }
00363
00364 if (execution_info.back().result_.result_code == GraspResult::SUCCESS)
00365 {
00366 result.manipulation_result.value = ManipulationResult::SUCCESS;
00367 if (!pickup_goal->only_perform_feasibility_test)
00368 {
00369 ROS_DEBUG_NAMED("manipulation", "Grasp reports success");
00370 result.grasp = new_grasps.at( execution_info.size() -1 );
00371 action_server->setSucceeded(result);
00372 return;
00373 }
00374 }
00375
00376 if (!execution_info.back().result_.continuation_possible)
00377 {
00378 if (pickup_goal->only_perform_feasibility_test)
00379 {
00380 ROS_ERROR("Continuation impossible when performing feasibility test");
00381 }
00382 result.grasp = new_grasps.at( execution_info.size() -1 );
00383 if (execution_info.back().result_.result_code == GraspResult::LIFT_FAILED)
00384 result.manipulation_result.value = ManipulationResult::LIFT_FAILED;
00385 else
00386 result.manipulation_result.value = ManipulationResult::FAILED;
00387 action_server->setAborted(result);
00388 return;
00389 }
00390
00391 tested_grasps += execution_info.size();
00392 }
00393
00394 if (pickup_goal->only_perform_feasibility_test && result.manipulation_result.value == ManipulationResult::SUCCESS)
00395 {
00396 action_server->setSucceeded(result);
00397 }
00398 else
00399 {
00400 action_server->setAborted(result);
00401 }
00402 return;
00403 }
00404 catch (InterruptRequestedException &ex)
00405 {
00406 ROS_DEBUG_NAMED("manipulation","Pickup goal preempted");
00407 action_server->setPreempted();
00408 return;
00409 }
00410 catch (MoveArmStuckException &ex)
00411 {
00412 ROS_ERROR("Grasp aborted because move_arm is stuck");
00413 result.manipulation_result.value = ManipulationResult::ARM_MOVEMENT_PREVENTED;
00414 action_server->setAborted(result);
00415 return;
00416 }
00417 catch (GraspException &ex)
00418 {
00419 ROS_ERROR("Grasp error; exception: %s", ex.what());
00420 result.manipulation_result.value = ManipulationResult::ERROR;
00421 action_server->setAborted(result);
00422 return;
00423 }
00424 }
00425
00426 void ObjectManipulator::placeFeedback(
00427 actionlib::SimpleActionServer<object_manipulation_msgs::PlaceAction> *action_server,
00428 size_t tested_places, size_t total_places, size_t current_place)
00429 {
00430 PlaceFeedback feedback;
00431 feedback.total_locations = total_places;
00432 feedback.current_location = current_place + tested_places;
00433 action_server->publishFeedback(feedback);
00434 }
00435
00436 void ObjectManipulator::place(const object_manipulation_msgs::PlaceGoal::ConstPtr &place_goal,
00437 actionlib::SimpleActionServer<object_manipulation_msgs::PlaceAction> *action_server)
00438 {
00439 PlaceResult result;
00440 PlaceTester *place_tester = standard_place_tester_;
00441 PlacePerformer *place_performer = standard_place_performer_;
00442 if (place_goal->use_reactive_place) place_performer = reactive_place_performer_;
00443
00444 place_tester->setInterruptFunction(
00445 boost::bind(&actionlib::SimpleActionServer<object_manipulation_msgs::PlaceAction>::isPreemptRequested,
00446 action_server));
00447 place_performer->setInterruptFunction(
00448 boost::bind(&actionlib::SimpleActionServer<object_manipulation_msgs::PlaceAction>::isPreemptRequested,
00449 action_server));
00450
00451 std::vector<geometry_msgs::PoseStamped> place_locations = place_goal->place_locations;
00452 try
00453 {
00454 std::vector<PlaceExecutionInfo> execution_info;
00455 result.manipulation_result.value = ManipulationResult::UNFEASIBLE;
00456 size_t tested_places = 0;
00457 while (!place_locations.empty())
00458 {
00459 if (action_server->isPreemptRequested()) throw InterruptRequestedException();
00460 place_tester->setFeedbackFunction(boost::bind(&ObjectManipulator::placeFeedback,
00461 this, action_server, tested_places, place_locations.size(), _1));
00462
00463 place_tester->testPlaces(*place_goal, place_locations, execution_info,
00464 !place_goal->only_perform_feasibility_test);
00465 if (execution_info.empty()) throw GraspException("place tester provided empty ExecutionInfo");
00466
00467 if (!place_goal->only_perform_feasibility_test)
00468 {
00469 place_performer->performPlaces(*place_goal, place_locations, execution_info);
00470 }
00471 if (execution_info.empty()) throw GraspException("place performer provided empty ExecutionInfo");
00472
00473 std::vector<geometry_msgs::PoseStamped>::iterator it = place_locations.begin();
00474 for (size_t i=0; i<execution_info.size(); i++)
00475 {
00476 result.attempted_locations.push_back(place_locations[i]);
00477 result.attempted_location_results.push_back(execution_info[i].result_);
00478 it++;
00479 }
00480
00481 if (execution_info.back().result_.result_code == PlaceLocationResult::SUCCESS)
00482 {
00483 result.manipulation_result.value = ManipulationResult::SUCCESS;
00484 if (!place_goal->only_perform_feasibility_test)
00485 {
00486 result.place_location = place_locations.at( execution_info.size() - 1 );
00487 action_server->setSucceeded(result);
00488 return;
00489 }
00490 }
00491
00492 if (!execution_info.back().result_.continuation_possible)
00493 {
00494 if (place_goal->only_perform_feasibility_test)
00495 {
00496 ROS_ERROR("Continuation impossible when performing feasibility test");
00497 }
00498 result.place_location = place_locations.at( execution_info.size() - 1 );
00499 if (execution_info.back().result_.result_code == PlaceLocationResult::RETREAT_FAILED)
00500 result.manipulation_result.value = ManipulationResult::RETREAT_FAILED;
00501 else
00502 result.manipulation_result.value = ManipulationResult::FAILED;
00503 action_server->setAborted(result);
00504 return;
00505 }
00506
00507 tested_places += execution_info.size();
00508 execution_info.clear();
00509 place_locations.erase(place_locations.begin(), it);
00510 }
00511
00512 if (place_goal->only_perform_feasibility_test && result.manipulation_result.value == ManipulationResult::SUCCESS)
00513 {
00514 action_server->setSucceeded(result);
00515 }
00516 else
00517 {
00518 action_server->setAborted(result);
00519 }
00520 return;
00521 }
00522 catch (InterruptRequestedException &ex)
00523 {
00524 ROS_DEBUG_NAMED("manipulation","Place goal preempted");
00525 action_server->setPreempted();
00526 return;
00527 }
00528 catch (MoveArmStuckException &ex)
00529 {
00530 ROS_ERROR("Place aborted because move_arm is stuck");
00531 result.manipulation_result.value = ManipulationResult::ARM_MOVEMENT_PREVENTED;
00532 action_server->setAborted(result);
00533 return;
00534 }
00535 catch (GraspException &ex)
00536 {
00537 ROS_ERROR("Place error; exception: %s", ex.what());
00538 result.manipulation_result.value = ManipulationResult::ERROR;
00539 action_server->setAborted(result);
00540 return;
00541 }
00542 }
00543
00544 }
00545