approach_lift_grasp.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002 *
00003 *  Copyright (c) 2009, Willow Garage, Inc.
00004 *  All rights reserved.
00005 *
00006 *  Redistribution and use in source and binary forms, with or without
00007 *  modification, are permitted provided that the following conditions
00008 *  are met:
00009 *
00010 *   * Redistributions of source code must retain the above copyright
00011 *     notice, this list of conditions and the following disclaimer.
00012 *   * Redistributions in binary form must reproduce the above
00013 *     copyright notice, this list of conditions and the following
00014 *     disclaimer in the documentation and/or other materials provided
00015 *     with the distribution.
00016 *   * Neither the name of the Willow Garage nor the names of its
00017 *     contributors may be used to endorse or promote products derived
00018 *     from this software without specific prior written permission.
00019 *
00020 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00021 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00022 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00023 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00024 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00025 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00026 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00027 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00028 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00029 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00030 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00031 *  POSSIBILITY OF SUCH DAMAGE.
00032 *********************************************************************/
00033 
00034 #include "object_manipulator/grasp_execution/approach_lift_grasp.h"
00035 
00036 #include "object_manipulator/tools/mechanism_interface.h"
00037 #include "object_manipulator/tools/exceptions.h"
00038 #include "object_manipulator/tools/hand_description.h"
00039 #include "object_manipulator/tools/vector_tools.h"
00040 
00041 using object_manipulation_msgs::GraspResult;
00042 using arm_navigation_msgs::ArmNavigationErrorCodes;
00043 
00044 namespace object_manipulator {
00045 
00047 float GraspTesterWithApproach::EPS = 1.0e-6;
00048 
00049 // ---------------------------- Definitions ---------------------------------
00050 
00051 void GraspTester::testGrasps(const object_manipulation_msgs::PickupGoal &goal,
00052                              const std::vector<manipulation_msgs::Grasp> &grasps,
00053                              std::vector<GraspExecutionInfo> &execution_info,
00054                              bool return_on_first_hit)
00055 {
00056   execution_info.clear();
00057   for (size_t i=0; i<grasps.size(); i++)
00058   {
00059     GraspExecutionInfo info;
00060     ROS_DEBUG_NAMED("manipulation","Grasp tester: testing grasp %zd out of batch of %zd", i, grasps.size());
00061     if (feedback_function_) feedback_function_(i);
00062     if (interrupt_function_ && interrupt_function_()) throw InterruptRequestedException();   
00063     if (marker_publisher_)
00064     {
00065       geometry_msgs::PoseStamped marker_pose = grasps[i].grasp_pose;
00066       marker_pose.header.stamp = ros::Time::now();
00067       info.marker_id_ = marker_publisher_->addGraspMarker(marker_pose);
00068     }  
00069     testGrasp(goal, grasps[i], info);
00070     execution_info.push_back(info);
00071     if (info.result_.result_code == info.result_.SUCCESS && return_on_first_hit) return;
00072   }
00073 }
00074 
00075 void GraspPerformer::performGrasps(const object_manipulation_msgs::PickupGoal &goal,
00076                                    const std::vector<manipulation_msgs::Grasp> &grasps,
00077                                    std::vector<GraspExecutionInfo> &execution_info)
00078 {
00079   for (size_t i=0; i<grasps.size(); i++)
00080   {
00081     if (feedback_function_) feedback_function_(i);
00082     if (interrupt_function_ && interrupt_function_()) throw InterruptRequestedException();
00083     if (i>= execution_info.size()) throw GraspException("Grasp Performer: not enough execution info provided");
00084     if (execution_info[i].result_.result_code != GraspResult::SUCCESS) continue;
00085     ROS_DEBUG_NAMED("manipulation","Grasp performer: trying grasp %zd out of batch of %zd", i, grasps.size());
00086     performGrasp(goal, grasps[i], execution_info[i]);
00087     if (execution_info[i].result_.result_code == execution_info[i].result_.SUCCESS || 
00088         !execution_info[i].result_.continuation_possible) return;
00089   }
00090 }
00091 
00092 // ------------------------------ Grasp Testers ----------------------------------
00093 
00097 arm_navigation_msgs::OrderedCollisionOperations 
00098 GraspTesterWithApproach::collisionOperationsForLift(const object_manipulation_msgs::PickupGoal &pickup_goal,
00099                                                     const manipulation_msgs::Grasp &grasp)
00100 {
00101   arm_navigation_msgs::OrderedCollisionOperations ord;
00102   arm_navigation_msgs::CollisionOperation coll;
00103   coll.object1 = handDescription().gripperCollisionName(pickup_goal.arm_name);
00104   coll.operation = arm_navigation_msgs::CollisionOperation::DISABLE;
00105   if (!pickup_goal.collision_object_name.empty())
00106   {
00107     coll.object2 = pickup_goal.collision_object_name;
00108     ord.collision_operations.push_back(coll);
00109   }
00110   if (pickup_goal.allow_gripper_support_collision)
00111   {
00112     coll.object2 = pickup_goal.collision_support_surface_name;
00113     ord.collision_operations.push_back(coll);
00114   }
00115 
00116   for (unsigned int i = 0; i < grasp.allowed_touch_objects.size(); i++)
00117   {
00118     ROS_DEBUG_NAMED("manipulation","  Disabling all collisions for lift against moved obstacle %s",
00119                      grasp.allowed_touch_objects[i].c_str());
00120     coll.object1 = grasp.allowed_touch_objects[i];
00121     //This disables all collisions with the object. Ignore possible collisions of the robot with the object 
00122     //during the push-grasp. We need all the capture region to be able to do this safely. Or we can disable 
00123     //collisions just with the forearm, which should work almost always but still theoretically is not the right 
00124     //thing to do.
00125     coll.object2 = arm_navigation_msgs::CollisionOperation::COLLISION_SET_ALL;
00126     ord.collision_operations.push_back(coll);
00127   }
00128 
00129   ord.collision_operations = concat(ord.collision_operations, 
00130                                     pickup_goal.additional_collision_operations.collision_operations);  
00131   return ord;
00132 }
00133 
00135 std::vector<arm_navigation_msgs::LinkPadding> 
00136 GraspTesterWithApproach::linkPaddingForLift(const object_manipulation_msgs::PickupGoal &pickup_goal,
00137                                             const manipulation_msgs::Grasp&)
00138 {
00139   return concat(MechanismInterface::gripperPadding(pickup_goal.arm_name, 0.0), 
00140                 pickup_goal.additional_link_padding);
00141 }
00142 
00143 GraspResult 
00144 GraspTesterWithApproach::getInterpolatedIKForLift(const object_manipulation_msgs::PickupGoal &pickup_goal,
00145                                                   const manipulation_msgs::Grasp &grasp,
00146                                                   const std::vector<double> &grasp_joint_angles,
00147                                                   GraspExecutionInfo &execution_info)
00148 {
00149   geometry_msgs::PoseStamped grasp_pose = grasp.grasp_pose;
00150   grasp_pose.header.stamp = ros::Time(0);
00151 
00152   float actual_lift_distance;
00153   int error_code = 
00154     mechInterface().getInterpolatedIK(pickup_goal.arm_name, 
00155                                       grasp_pose, 
00156                                       pickup_goal.lift.direction, pickup_goal.lift.desired_distance,
00157                                       grasp_joint_angles, 
00158                                       grasp.grasp_posture, 
00159                                       collisionOperationsForLift(pickup_goal, grasp), 
00160                                       linkPaddingForLift(pickup_goal, grasp),
00161                                       false, execution_info.lift_trajectory_, actual_lift_distance);
00162   ROS_DEBUG_NAMED("manipulation","  Lift distance: actual %f, min %f and desired %f", 
00163                   actual_lift_distance, pickup_goal.lift.min_distance, pickup_goal.lift.desired_distance);
00164 
00165   if (actual_lift_distance < pickup_goal.lift.min_distance - EPS)
00166   {
00167     ROS_DEBUG_NAMED("manipulation","  Lift trajectory  below min. threshold");
00168     if (marker_publisher_) marker_publisher_->colorGraspMarker(execution_info.marker_id_, 0.0, 0.0, 1.0);
00169     if (execution_info.lift_trajectory_.points.empty())
00170     {
00171       ROS_DEBUG_NAMED("manipulation","  Lift trajectory empty; problem is with grasp location");
00172       if (error_code == ArmNavigationErrorCodes::COLLISION_CONSTRAINTS_VIOLATED) 
00173         return Result(GraspResult::GRASP_IN_COLLISION, true);
00174       else if (error_code == ArmNavigationErrorCodes::JOINT_LIMITS_VIOLATED)
00175         return Result(GraspResult::GRASP_OUT_OF_REACH, true);
00176       else return Result(GraspResult::GRASP_UNFEASIBLE, true);
00177     }
00178     if (error_code == ArmNavigationErrorCodes::COLLISION_CONSTRAINTS_VIOLATED) 
00179       return Result(GraspResult::LIFT_IN_COLLISION, true);
00180     else if (error_code == ArmNavigationErrorCodes::JOINT_LIMITS_VIOLATED)
00181       return Result(GraspResult::LIFT_OUT_OF_REACH, true);
00182     else return Result(GraspResult::LIFT_UNFEASIBLE, true);
00183   }
00184  
00185   return Result(GraspResult::SUCCESS, true);
00186 }
00187 
00191 arm_navigation_msgs::OrderedCollisionOperations 
00192 GraspTesterWithApproach::collisionOperationsForGrasp(const object_manipulation_msgs::PickupGoal &pickup_goal,
00193                                                      const manipulation_msgs::Grasp &grasp)
00194 {
00195   arm_navigation_msgs::OrderedCollisionOperations ord;
00196   arm_navigation_msgs::CollisionOperation coll;
00197   coll.object1 = handDescription().gripperCollisionName(pickup_goal.arm_name);
00198   coll.operation = arm_navigation_msgs::CollisionOperation::DISABLE;
00199   if (!pickup_goal.collision_object_name.empty())
00200   {
00201     coll.object2 = pickup_goal.collision_object_name;
00202     ord.collision_operations.push_back(coll);
00203   }
00204   if (pickup_goal.allow_gripper_support_collision)
00205   {
00206     coll.object2 = pickup_goal.collision_support_surface_name;
00207     ord.collision_operations.push_back(coll);
00208   }
00209 
00210   coll.object1 = pickup_goal.collision_object_name;
00211   //This disables all collisions with the object. Ignore possible collisions of the robot with the object 
00212   //during the push-grasp. We need all the capture region to be able to do this safely. Or we can disable 
00213   //collisions just with the forearm, which should work almost always but still theoretially is not the right 
00214   //thing to do.
00215   coll.object2 = arm_navigation_msgs::CollisionOperation::COLLISION_SET_ALL;
00216   ord.collision_operations.push_back(coll);
00217 
00218 
00219   for (unsigned int i = 0; i < grasp.allowed_touch_objects.size(); i++)
00220   {
00221     ROS_DEBUG_NAMED("manipulation","  Disabling all collisions for grasp against moved obstacle %s",
00222                      grasp.allowed_touch_objects[i].c_str());
00223     coll.object1 = grasp.allowed_touch_objects[i];
00224     //This disables all collisions with the object. Ignore possible collisions of the robot with the object 
00225     //during the push-grasp. We need all the capture region to be able to do this safely. Or we can disable 
00226     //collisions just with the forearm, which should work almost always but still theoretically is not the right 
00227     //thing to do.
00228     coll.object2 = arm_navigation_msgs::CollisionOperation::COLLISION_SET_ALL;
00229     ord.collision_operations.push_back(coll);
00230   }
00231 
00232   ord.collision_operations = concat(ord.collision_operations, 
00233                                     pickup_goal.additional_collision_operations.collision_operations);
00234   return ord;
00235 }
00236 
00238 std::vector<arm_navigation_msgs::LinkPadding> 
00239 GraspTesterWithApproach::linkPaddingForGrasp(const object_manipulation_msgs::PickupGoal &pickup_goal,
00240                                              const manipulation_msgs::Grasp&)
00241 {
00242   return concat(MechanismInterface::gripperPadding(pickup_goal.arm_name, 0.0), 
00243                 pickup_goal.additional_link_padding);
00244 }
00245 
00246 GraspResult 
00247 GraspTesterWithApproach::getInterpolatedIKForGrasp(const object_manipulation_msgs::PickupGoal &pickup_goal,
00248                                                    const manipulation_msgs::Grasp &grasp,
00249                                                    GraspExecutionInfo &execution_info)
00250 {
00251   //get the grasp pose in the right frame
00252   geometry_msgs::PoseStamped grasp_pose_stamped = grasp.grasp_pose;
00253   grasp_pose_stamped.header.stamp = ros::Time(0);
00254 
00255   //use the opposite of the approach direction as we are going backwards, from grasp to pre-grasp
00256   geometry_msgs::Vector3Stamped direction = grasp.approach.direction;
00257   direction.header.stamp = ros::Time::now();
00258   direction.vector = mechInterface().negate( direction.vector );
00259 
00260   std::vector<double> empty;
00261   //remember to pass that we want to flip the trajectory
00262   float actual_approach_distance;
00263   int error_code = mechInterface().getInterpolatedIK(pickup_goal.arm_name, 
00264                                                      grasp_pose_stamped, 
00265                                                      direction, grasp.approach.desired_distance,
00266                                                      empty, 
00267                                                      grasp.pre_grasp_posture,
00268                                                      collisionOperationsForGrasp(pickup_goal, grasp), 
00269                                                      linkPaddingForGrasp(pickup_goal, grasp),
00270                                                      true, execution_info.approach_trajectory_, 
00271                                                      actual_approach_distance);
00272   ROS_DEBUG_NAMED("manipulation","  Grasp executor approach distance: actual (%f), min(%f) and desired (%f)", 
00273             actual_approach_distance, grasp.approach.min_distance, grasp.approach.desired_distance);
00274 
00275   if ( actual_approach_distance < grasp.approach.min_distance - EPS)
00276   {
00277     ROS_DEBUG_NAMED("manipulation","  Grasp executor: interpolated IK for grasp below min threshold");
00278     if (execution_info.approach_trajectory_.points.empty())
00279     {
00280       ROS_DEBUG_NAMED("manipulation","  Grasp executor: interpolated IK empty, problem is with grasp location");
00281       if (marker_publisher_) marker_publisher_->colorGraspMarker(execution_info.marker_id_, 1.0, 1.0, 0.0); //yellow
00282       if (error_code == ArmNavigationErrorCodes::COLLISION_CONSTRAINTS_VIOLATED) 
00283         return Result(GraspResult::GRASP_IN_COLLISION, true);
00284       else if (error_code == ArmNavigationErrorCodes::JOINT_LIMITS_VIOLATED)
00285         return Result(GraspResult::GRASP_OUT_OF_REACH, true);
00286       else return Result(GraspResult::GRASP_UNFEASIBLE, true);      
00287     }
00288     if (marker_publisher_) marker_publisher_->colorGraspMarker(execution_info.marker_id_, 0.0, 1.0, 1.0); //cyan
00289     if (error_code == ArmNavigationErrorCodes::COLLISION_CONSTRAINTS_VIOLATED) 
00290       return Result(GraspResult::PREGRASP_IN_COLLISION, true);
00291     else if (error_code == ArmNavigationErrorCodes::JOINT_LIMITS_VIOLATED)
00292       return Result(GraspResult::PREGRASP_OUT_OF_REACH, true);
00293     else return Result(GraspResult::PREGRASP_UNFEASIBLE, true);      
00294   }
00295 
00296   return Result(GraspResult::SUCCESS, true);
00297 }
00298 
00299 void GraspTesterWithApproach::testGrasp(const object_manipulation_msgs::PickupGoal &pickup_goal,
00300                                         const manipulation_msgs::Grasp &grasp,
00301                                         GraspExecutionInfo &execution_info)
00302 {
00303   if (marker_publisher_) marker_publisher_->colorGraspMarker(execution_info.marker_id_, 1.0, 0.0, 0.0); //red
00304 
00305   execution_info.result_ = getInterpolatedIKForGrasp(pickup_goal, grasp, execution_info);
00306   if ( execution_info.result_.result_code != GraspResult::SUCCESS )
00307   {
00308     ROS_DEBUG_NAMED("manipulation","  Grasp executor: failed to generate approach trajectory");
00309     return;
00310   }
00311 
00312   //check for lift trajectory starting from grasp solution
00313   std::vector<double> grasp_joint_angles = execution_info.approach_trajectory_.points.back().positions;
00314   execution_info.result_ = getInterpolatedIKForLift(pickup_goal, grasp, grasp_joint_angles, execution_info);
00315   if (execution_info.result_.result_code != GraspResult::SUCCESS)
00316   {
00317     ROS_DEBUG_NAMED("manipulation","  Grasp executor: failed to generate lift trajectory");
00318     return;
00319   }
00320 
00321   //check if the first pose in grasp trajectory is valid
00322   //when we check from pre-grasp to grasp we use custom link padding, so we need to check here
00323   //if the initial pose is feasible with default padding; otherwise, move_arm might refuse to 
00324   //take us there
00325   if ( !mechInterface().checkStateValidity(pickup_goal.arm_name, 
00326                                            execution_info.approach_trajectory_.points.front().positions,
00327                                            pickup_goal.additional_collision_operations,
00328                                            pickup_goal.additional_link_padding) )
00329   {
00330     ROS_DEBUG_NAMED("manipulation","  Grasp executor: initial pose in grasp trajectory is unfeasible "
00331                     "with default padding");
00332     execution_info.result_ = Result(GraspResult::PREGRASP_UNFEASIBLE, true);
00333     return;
00334   }
00335   ROS_DEBUG_NAMED("manipulation","  Grasp executor: goal pose for move arm passed validity test");
00336 
00337   //check if the last pose in lift trajectory is valid
00338   //when we check for lift we use custom link padding, so we need to check here if the last pose 
00339   //is feasible with default padding; otherwise, move_arm might refuse to take us out of there
00340   if ( pickup_goal.lift.min_distance != 0 && 
00341        !mechInterface().checkStateValidity(pickup_goal.arm_name, 
00342                                            execution_info.lift_trajectory_.points.back().positions,
00343                                            collisionOperationsForLift(pickup_goal, grasp),
00344                                            pickup_goal.additional_link_padding) )
00345   {
00346     ROS_DEBUG_NAMED("manipulation","  Grasp executor: last pose in lift trajectory is unfeasible with default padding");
00347     execution_info.result_ = Result(GraspResult::LIFT_UNFEASIBLE, true);
00348     return;
00349   }  
00350   ROS_DEBUG_NAMED("manipulation","  Grasp executor: final lift pose passed validity test");
00351 }
00352 
00354 arm_navigation_msgs::OrderedCollisionOperations 
00355 UnsafeGraspTester::collisionOperationsForGrasp(const object_manipulation_msgs::PickupGoal &pickup_goal,
00356                                                const manipulation_msgs::Grasp&)
00357 {
00358   arm_navigation_msgs::OrderedCollisionOperations ord;
00359   arm_navigation_msgs::CollisionOperation coll;
00360   coll.object1 = arm_navigation_msgs::CollisionOperation::COLLISION_SET_ALL;
00361   coll.object2 = arm_navigation_msgs::CollisionOperation::COLLISION_SET_ALL;
00362   coll.operation = arm_navigation_msgs::CollisionOperation::DISABLE;
00363   ord.collision_operations.push_back(coll);
00364   ord.collision_operations = concat(ord.collision_operations, 
00365                                     pickup_goal.additional_collision_operations.collision_operations);
00366   return ord;
00367 }
00368 
00370 arm_navigation_msgs::OrderedCollisionOperations 
00371 UnsafeGraspTester::collisionOperationsForLift(const object_manipulation_msgs::PickupGoal &pickup_goal,
00372                                               const manipulation_msgs::Grasp&)
00373 {
00374   arm_navigation_msgs::OrderedCollisionOperations ord;
00375   arm_navigation_msgs::CollisionOperation coll;
00376   coll.object1 = arm_navigation_msgs::CollisionOperation::COLLISION_SET_ALL;
00377   coll.object2 = arm_navigation_msgs::CollisionOperation::COLLISION_SET_ALL;
00378   coll.operation = arm_navigation_msgs::CollisionOperation::DISABLE;
00379   ord.collision_operations.push_back(coll);
00380   ord.collision_operations = concat(ord.collision_operations, 
00381                                     pickup_goal.additional_collision_operations.collision_operations);
00382   return ord;
00383 }
00384 
00385 
00386 // ---------------------------- Grasp Performers ---------------------------------
00387 
00388 void StandardGraspPerformer::performGrasp(const object_manipulation_msgs::PickupGoal &pickup_goal,
00389                                           const manipulation_msgs::Grasp &grasp,
00390                                           GraspExecutionInfo &execution_info)
00391 {
00392   execution_info.result_ = approachAndGrasp(pickup_goal, grasp, execution_info);
00393   if (execution_info.result_.result_code != GraspResult::SUCCESS) return;
00394 
00395   //check if there is anything in gripper; if not, open gripper and retreat
00396   if (!mechInterface().graspPostureQuery(pickup_goal.arm_name, grasp))
00397   {
00398     ROS_DEBUG_NAMED("manipulation","Hand reports that grasp was not successfully executed; "
00399                     "releasing object and retreating");
00400     mechInterface().handPostureGraspAction(pickup_goal.arm_name, grasp,
00401                                 object_manipulation_msgs::GraspHandPostureExecutionGoal::RELEASE, -1);    
00402     retreat(pickup_goal, grasp, execution_info);
00403     execution_info.result_ = Result(GraspResult::GRASP_FAILED, false);
00404     return;
00405   }
00406   
00407   //attach object to gripper
00408   if (!pickup_goal.collision_object_name.empty())
00409   {
00410     mechInterface().attachObjectToGripper(pickup_goal.arm_name, pickup_goal.collision_object_name);
00411   }
00412 
00413   execution_info.result_ = lift(pickup_goal, grasp, execution_info);
00414 }
00415 
00416 
00417 object_manipulation_msgs::GraspResult 
00418 StandardGraspPerformer::approachAndGrasp(const object_manipulation_msgs::PickupGoal &pickup_goal,
00419                                          const manipulation_msgs::Grasp &grasp,
00420                                          GraspExecutionInfo &execution_info)
00421 {
00422   ROS_INFO("Additional collision operations:");
00423   for (unsigned int i = 0; i < pickup_goal.additional_collision_operations.collision_operations.size(); i++)
00424   {
00425     ROS_INFO_STREAM("\t for objects " << pickup_goal.additional_collision_operations.collision_operations[i].object1 << " and " << pickup_goal.additional_collision_operations.collision_operations[i].object2 );
00426   }
00427   if ( !mechInterface().attemptMoveArmToGoal(pickup_goal.arm_name, 
00428                                              execution_info.approach_trajectory_.points.front().positions,
00429                                              pickup_goal.additional_collision_operations,
00430                                              pickup_goal.additional_link_padding) ) 
00431   {
00432     ROS_DEBUG_NAMED("manipulation","  Grasp executor: move_arm to pre-grasp reports failure");
00433     if (marker_publisher_) marker_publisher_->colorGraspMarker(execution_info.marker_id_, 1.0, 0.5, 0.0); //orange-ish
00434     return Result(GraspResult::MOVE_ARM_FAILED, true);
00435   }
00436 
00437   mechInterface().handPostureGraspAction(pickup_goal.arm_name, grasp, 
00438                      object_manipulation_msgs::GraspHandPostureExecutionGoal::PRE_GRASP, -1);
00439 
00440   mechInterface().attemptTrajectory(pickup_goal.arm_name, execution_info.approach_trajectory_, true);
00441 
00442   mechInterface().handPostureGraspAction(pickup_goal.arm_name, grasp, 
00443                      object_manipulation_msgs::GraspHandPostureExecutionGoal::GRASP, pickup_goal.max_contact_force);    
00444 
00445   if (marker_publisher_) marker_publisher_->colorGraspMarker(execution_info.marker_id_, 0.0, 1.0, 0.0); //green
00446   return Result(GraspResult::SUCCESS, true);
00447 }
00448 
00449 object_manipulation_msgs::GraspResult 
00450 StandardGraspPerformer::lift(const object_manipulation_msgs::PickupGoal &pickup_goal,
00451                              const manipulation_msgs::Grasp &grasp,
00452                              GraspExecutionInfo &execution_info)
00453 {
00454   if (execution_info.lift_trajectory_.points.empty())
00455   {
00456     ROS_ERROR("  Grasp executor: lift trajectory not set");
00457     return Result(GraspResult::LIFT_FAILED, false);
00458   }
00459   mechInterface().attemptTrajectory(pickup_goal.arm_name, execution_info.lift_trajectory_, true);
00460   return Result(GraspResult::SUCCESS, true);
00461 
00462 }
00463 
00464 object_manipulation_msgs::GraspResult 
00465 StandardGraspPerformer::retreat(const object_manipulation_msgs::PickupGoal &pickup_goal,
00466                                 const manipulation_msgs::Grasp &grasp,
00467                                 GraspExecutionInfo &execution_info)
00468 {
00469   arm_navigation_msgs::OrderedCollisionOperations ord;
00470   arm_navigation_msgs::CollisionOperation coll;
00471   //disable collision between gripper and object
00472   coll.object1 = handDescription().gripperCollisionName(pickup_goal.arm_name);
00473   coll.object2 = pickup_goal.collision_object_name;
00474   coll.operation = arm_navigation_msgs::CollisionOperation::DISABLE;
00475   ord.collision_operations.push_back(coll);
00476   //disable collision between gripper and table
00477   coll.object2 = pickup_goal.collision_support_surface_name;
00478   ord.collision_operations.push_back(coll);
00479   ord.collision_operations = concat(ord.collision_operations, 
00480                                     pickup_goal.additional_collision_operations.collision_operations);
00481 
00482   geometry_msgs::Vector3Stamped direction;
00483   direction.header.stamp = ros::Time::now();
00484   direction.header.frame_id = handDescription().gripperFrame(pickup_goal.arm_name);
00485   direction.vector = mechInterface().negate( handDescription().approachDirection(pickup_goal.arm_name) );
00486 
00487   //even if the complete retreat trajectory is not possible, execute as many
00488   //steps as we can (pass min_distance = 0)
00489   float retreat_distance = grasp.approach.min_distance;
00490   float actual_distance;
00491   if (!mechInterface().translateGripper(pickup_goal.arm_name, direction,
00492                                         ord, pickup_goal.additional_link_padding, 
00493                                         retreat_distance, 0, actual_distance))
00494   {
00495     ROS_ERROR(" Grasp executor: failed to retreat gripper at all");
00496     return Result(GraspResult::RETREAT_FAILED, false);
00497   }
00498   if (actual_distance < retreat_distance)
00499   {
00500     ROS_WARN(" Grasp executor: only partial retreat (%f) succeeeded", actual_distance);
00501     return Result(GraspResult::RETREAT_FAILED, false);
00502   }
00503   return Result(GraspResult::SUCCESS, true);
00504 }
00505 
00506 object_manipulation_msgs::GraspResult 
00507 ReactiveGraspPerformer::nonReactiveLift(const object_manipulation_msgs::PickupGoal &pickup_goal,
00508                                         const manipulation_msgs::Grasp &grasp,
00509                                         GraspExecutionInfo &execution_info)
00510 {
00511   arm_navigation_msgs::OrderedCollisionOperations ord;
00512   arm_navigation_msgs::CollisionOperation coll;
00513   coll.object1 = handDescription().gripperCollisionName(pickup_goal.arm_name);
00514   coll.operation = arm_navigation_msgs::CollisionOperation::DISABLE;
00515   //disable collisions between end-effector and table
00516   if (!pickup_goal.collision_support_surface_name.empty())
00517   {
00518     coll.object2 = pickup_goal.collision_support_surface_name;
00519     ord.collision_operations.push_back(coll);
00520   }
00521   //disable collisions between attached object and table
00522   if (!pickup_goal.collision_support_surface_name.empty() && !pickup_goal.collision_object_name.empty())
00523   {
00524     coll.object1 = pickup_goal.collision_object_name;
00525     coll.object2 = pickup_goal.collision_support_surface_name;
00526     ord.collision_operations.push_back(coll);
00527   }
00528   ord.collision_operations = concat(ord.collision_operations, 
00529                                     pickup_goal.additional_collision_operations.collision_operations);
00530 
00531   float actual_distance;
00532   if (!mechInterface().translateGripper(pickup_goal.arm_name, 
00533                                         pickup_goal.lift.direction, 
00534                                         ord, pickup_goal.additional_link_padding, 
00535                                         pickup_goal.lift.desired_distance, 0.0, actual_distance))
00536   {
00537     ROS_DEBUG_NAMED("manipulation","  Reactive grasp executor: lift performed no steps");
00538     return Result(GraspResult::LIFT_FAILED, false);
00539   }
00540   if (actual_distance < pickup_goal.lift.min_distance)
00541   {
00542     ROS_DEBUG_NAMED("manipulation","  Reactive grasp executor: lift distance below min threshold ");
00543     return Result(GraspResult::LIFT_FAILED, false);
00544   }
00545   if (actual_distance < pickup_goal.lift.desired_distance)
00546   {
00547     ROS_DEBUG_NAMED("manipulation","  Reactive grasp executor: lift distance below desired, but above min threshold");
00548   }
00549   else 
00550   {
00551     ROS_DEBUG_NAMED("manipulation","  Reactive grasp executor: desired lift distance executed");
00552   }
00553   return Result(GraspResult::SUCCESS, true);
00554 }
00555 
00556 object_manipulation_msgs::GraspResult 
00557 ReactiveGraspPerformer::reactiveLift(const object_manipulation_msgs::PickupGoal &pickup_goal,
00558                                      const manipulation_msgs::Grasp &grasp,
00559                                      GraspExecutionInfo &execution_info)
00560 {
00561   object_manipulation_msgs::ReactiveLiftGoal reactive_lift_goal;
00562   reactive_lift_goal.lift = pickup_goal.lift;
00563   reactive_lift_goal.arm_name = pickup_goal.arm_name;
00564   reactive_lift_goal.target = pickup_goal.target;
00565   reactive_lift_goal.trajectory = execution_info.lift_trajectory_;
00566   reactive_lift_goal.collision_support_surface_name = pickup_goal.collision_support_surface_name;
00567 
00568   //give the reactive lift 1 minute to do its thing
00569   ros::Duration timeout = ros::Duration(60.0);
00570   mechInterface().reactive_lift_action_client_.client(pickup_goal.arm_name).sendGoal(reactive_lift_goal);
00571   if ( !mechInterface().reactive_lift_action_client_.client(pickup_goal.arm_name).waitForResult(timeout) )
00572   {
00573     ROS_ERROR("  Reactive lift timed out");
00574     return Result(GraspResult::LIFT_FAILED, false);
00575   }
00576   object_manipulation_msgs::ReactiveLiftResult reactive_lift_result = 
00577     *mechInterface().reactive_lift_action_client_.client(pickup_goal.arm_name).getResult();
00578   if (reactive_lift_result.manipulation_result.value != reactive_lift_result.manipulation_result.SUCCESS)
00579   {
00580     ROS_ERROR("Reactive lift failed with error code %d", reactive_lift_result.manipulation_result.value);
00581     return Result(GraspResult::LIFT_FAILED, false);
00582   }
00583   return Result(GraspResult::SUCCESS, true);
00584 }
00585 
00586 object_manipulation_msgs::GraspResult 
00587 ReactiveGraspPerformer::lift(const object_manipulation_msgs::PickupGoal &pickup_goal,
00588                              const manipulation_msgs::Grasp &grasp,
00589                              GraspExecutionInfo &execution_info)
00590 {
00591   if (pickup_goal.use_reactive_lift)
00592   {
00593     return reactiveLift(pickup_goal, grasp, execution_info);
00594   }
00595   else
00596   {
00597     return nonReactiveLift(pickup_goal, grasp, execution_info);
00598   }
00599 }
00600 
00601 object_manipulation_msgs::GraspResult 
00602 ReactiveGraspPerformer::approachAndGrasp(const object_manipulation_msgs::PickupGoal &pickup_goal,
00603                                          const manipulation_msgs::Grasp &grasp,
00604                                          GraspExecutionInfo &execution_info)
00605 {
00606   if ( !mechInterface().attemptMoveArmToGoal(pickup_goal.arm_name, 
00607                                              execution_info.approach_trajectory_.points.front().positions,
00608                                              pickup_goal.additional_collision_operations,
00609                                              pickup_goal.additional_link_padding) ) 
00610   {
00611     ROS_DEBUG_NAMED("manipulation","  Grasp executor: move_arm to pre-grasp reports failure");
00612     if (marker_publisher_) marker_publisher_->colorGraspMarker(execution_info.marker_id_, 1.0, 0.5, 0.0); //orange-ish
00613     return Result(GraspResult::MOVE_ARM_FAILED, true);
00614   }
00615 
00616   mechInterface().handPostureGraspAction(pickup_goal.arm_name, grasp, 
00617                           object_manipulation_msgs::GraspHandPostureExecutionGoal::PRE_GRASP, -1);
00618   
00619   geometry_msgs::PoseStamped final_grasp_pose_stamped = grasp.grasp_pose;
00620   final_grasp_pose_stamped.header.stamp = ros::Time(0);
00621 
00622   object_manipulation_msgs::ReactiveGraspGoal reactive_grasp_goal;
00623   reactive_grasp_goal.arm_name = pickup_goal.arm_name;
00624   reactive_grasp_goal.target = pickup_goal.target;
00625   reactive_grasp_goal.final_grasp_pose = final_grasp_pose_stamped;
00626   reactive_grasp_goal.trajectory = execution_info.approach_trajectory_;
00627   reactive_grasp_goal.collision_support_surface_name = pickup_goal.collision_support_surface_name;
00628   reactive_grasp_goal.pre_grasp_posture = grasp.pre_grasp_posture;
00629   reactive_grasp_goal.grasp_posture = grasp.grasp_posture;
00630 
00631   //give the reactive grasp 3 minutes to do its thing
00632   ros::Duration timeout = ros::Duration(180.0);
00633   mechInterface().reactive_grasp_action_client_.client(pickup_goal.arm_name).sendGoal(reactive_grasp_goal);
00634   if ( !mechInterface().reactive_grasp_action_client_.client(pickup_goal.arm_name).waitForResult(timeout) )
00635   {
00636     ROS_ERROR("  Reactive grasp timed out");
00637     return Result(GraspResult::GRASP_FAILED, false);
00638   }
00639   object_manipulation_msgs::ReactiveGraspResult reactive_grasp_result = 
00640     *mechInterface().reactive_grasp_action_client_.client(pickup_goal.arm_name).getResult();
00641   if (reactive_grasp_result.manipulation_result.value != reactive_grasp_result.manipulation_result.SUCCESS)
00642   {
00643     ROS_ERROR("Reactive grasp failed with error code %d", reactive_grasp_result.manipulation_result.value);
00644     return Result(GraspResult::GRASP_FAILED, false);
00645   }
00646   if (marker_publisher_) marker_publisher_->colorGraspMarker(execution_info.marker_id_, 0.0, 1.0, 0.0); //green
00647   return Result(GraspResult::SUCCESS, true);
00648 }
00649 
00650 object_manipulation_msgs::GraspResult 
00651 UnsafeGraspPerformer::approachAndGrasp(const object_manipulation_msgs::PickupGoal &pickup_goal,
00652                                        const manipulation_msgs::Grasp &grasp,
00653                                        GraspExecutionInfo &execution_info)
00654 {
00655   ROS_DEBUG_NAMED("manipulation", "executing unsafe grasp");
00656 
00657   //compute the pre-grasp pose
00658   //get the grasp pose in the right frame
00659   geometry_msgs::PoseStamped grasp_pose_stamped = grasp.grasp_pose;
00660   grasp_pose_stamped.header.stamp = ros::Time(0);
00661 
00662   //use the opposite of the approach direction as we are going backwards, from grasp to pre-grasp
00663   geometry_msgs::Vector3Stamped direction;
00664   direction.header.stamp = ros::Time::now();
00665   direction.header.frame_id = handDescription().gripperFrame(pickup_goal.arm_name);
00666   direction.vector = mechInterface().negate( handDescription().approachDirection(pickup_goal.arm_name) );
00667 
00668   //make sure the input is normalized
00669   geometry_msgs::Vector3Stamped direction_norm = direction;
00670   direction_norm.vector = mechInterface().normalize(direction.vector);
00671 
00672   //multiply the approach direction by the desired length and translate the grasp pose back along it
00673   double desired_trajectory_length = fabs(grasp.approach.desired_distance);
00674   direction_norm.vector.x *= desired_trajectory_length;
00675   direction_norm.vector.y *= desired_trajectory_length;
00676   direction_norm.vector.z *= desired_trajectory_length;
00677   geometry_msgs::PoseStamped pregrasp_pose = mechInterface().translateGripperPose(direction_norm, grasp_pose_stamped, 
00678                                                                                   pickup_goal.arm_name);
00679   
00680   //move to the pre-grasp using the Cartesian controller
00681   mechInterface().moveArmToPoseCartesian(pickup_goal.arm_name, pregrasp_pose, ros::Duration(15.0), 
00682                                          .0015, .01, 0.02, 0.16, 0.005, 0.087, 0.1, 
00683                                          execution_info.approach_trajectory_.points.front().positions);
00684 
00685   //move to the pre-grasp hand posture
00686   mechInterface().handPostureGraspAction(pickup_goal.arm_name, grasp, 
00687                            object_manipulation_msgs::GraspHandPostureExecutionGoal::PRE_GRASP, -1);
00688 
00689   //if not using reactive grasping, execute the unnormalized interpolated trajectory from pre-grasp to grasp
00690   if(!pickup_goal.use_reactive_execution)
00691   {  
00692     mechInterface().attemptTrajectory(pickup_goal.arm_name, execution_info.approach_trajectory_, true);
00693     mechInterface().handPostureGraspAction(pickup_goal.arm_name, grasp, 
00694                            object_manipulation_msgs::GraspHandPostureExecutionGoal::GRASP, pickup_goal.max_contact_force);    
00695   }
00696 
00697   //otherwise, call reactive grasping
00698   else
00699   {
00700     geometry_msgs::PoseStamped final_grasp_pose_stamped = grasp.grasp_pose;
00701     final_grasp_pose_stamped.header.stamp = ros::Time(0);
00702 
00703     object_manipulation_msgs::ReactiveGraspGoal reactive_grasp_goal;
00704     reactive_grasp_goal.arm_name = pickup_goal.arm_name;
00705     reactive_grasp_goal.target = pickup_goal.target;
00706     reactive_grasp_goal.final_grasp_pose = final_grasp_pose_stamped;
00707     reactive_grasp_goal.trajectory = execution_info.approach_trajectory_;
00708     reactive_grasp_goal.collision_support_surface_name = pickup_goal.collision_support_surface_name;
00709     reactive_grasp_goal.pre_grasp_posture = grasp.pre_grasp_posture;
00710     reactive_grasp_goal.grasp_posture = grasp.grasp_posture;
00711 
00712     //give the reactive grasp 3 minutes to do its thing
00713     ros::Duration timeout = ros::Duration(180.0);
00714     mechInterface().reactive_grasp_action_client_.client(pickup_goal.arm_name).sendGoal(reactive_grasp_goal);
00715     if ( !mechInterface().reactive_grasp_action_client_.client(pickup_goal.arm_name).waitForResult(timeout) )
00716     {
00717       ROS_ERROR("  Reactive grasp timed out");
00718       return Result(GraspResult::GRASP_FAILED, false);
00719     }
00720     object_manipulation_msgs::ReactiveGraspResult reactive_grasp_result = 
00721       *mechInterface().reactive_grasp_action_client_.client(pickup_goal.arm_name).getResult();
00722     if (reactive_grasp_result.manipulation_result.value != reactive_grasp_result.manipulation_result.SUCCESS)
00723     {
00724       ROS_ERROR("Reactive grasp failed with error code %d", reactive_grasp_result.manipulation_result.value);
00725       return Result(GraspResult::GRASP_FAILED, false);
00726     }
00727   }
00728   if (marker_publisher_) marker_publisher_->colorGraspMarker(execution_info.marker_id_, 0.0, 1.0, 0.0); //green
00729   return Result(GraspResult::SUCCESS, true);
00730 }
00731 
00732 }


object_manipulator
Author(s): Matei Ciocarlie and Kaijen Hsiao
autogenerated on Mon Oct 6 2014 02:59:50