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