simple_grasps.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2013, University of Colorado, Boulder
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of the Univ of CO, Boulder nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  *********************************************************************/
00034 
00035 #include <moveit_simple_grasps/simple_grasps.h>
00036 
00037 namespace moveit_simple_grasps
00038 {
00039 
00040 // Constructor
00041 SimpleGrasps::SimpleGrasps(moveit_visual_tools::MoveItVisualToolsPtr visual_tools, bool verbose) :
00042   visual_tools_(visual_tools),
00043   verbose_(verbose)
00044 {
00045   ROS_DEBUG_STREAM_NAMED("grasps","Loaded simple grasp generator");
00046 }
00047 
00048 // Deconstructor
00049 SimpleGrasps::~SimpleGrasps()
00050 {
00051 }
00052 
00053 // Create all possible grasp positions for a object
00054 bool SimpleGrasps::generateBlockGrasps(const geometry_msgs::Pose& object_pose, const GraspData& grasp_data,
00055   std::vector<moveit_msgs::Grasp>& possible_grasps)
00056 {
00057   // ---------------------------------------------------------------------------------------------
00058   // Calculate grasps in two axis in both directions
00059   generateAxisGrasps( object_pose, X_AXIS, DOWN, HALF, 0, grasp_data, possible_grasps); // got no grasps with this alone
00060   generateAxisGrasps( object_pose, X_AXIS, UP,   HALF, 0, grasp_data, possible_grasps); // gives some grasps... looks ugly
00061   generateAxisGrasps( object_pose, Y_AXIS, DOWN, HALF, 0, grasp_data, possible_grasps); // GOOD ONES!
00062   generateAxisGrasps( object_pose, Y_AXIS, UP,   HALF, 0, grasp_data, possible_grasps); // gave a grasp from top... bad
00063 
00064   return true;
00065 }
00066 
00067 // Create grasp positions in one axis
00068 bool SimpleGrasps::generateAxisGrasps(
00069   const geometry_msgs::Pose& object_pose,
00070   grasp_axis_t axis,
00071   grasp_direction_t direction,
00072   grasp_rotation_t rotation,
00073   double hand_roll,
00074   const GraspData& grasp_data,
00075   std::vector<moveit_msgs::Grasp>& possible_grasps)
00076 {
00077   // ---------------------------------------------------------------------------------------------
00078   // Create a transform from the object's frame (center of object) to /base_link
00079   tf::poseMsgToEigen(object_pose, object_global_transform_);
00080 
00081   // ---------------------------------------------------------------------------------------------
00082   // Grasp parameters
00083 
00084   // Create re-usable approach motion
00085   moveit_msgs::GripperTranslation pre_grasp_approach;
00086   pre_grasp_approach.direction.header.stamp = ros::Time::now();
00087   pre_grasp_approach.desired_distance = grasp_data.approach_retreat_desired_dist_; // The distance the origin of a robot link needs to travel
00088   pre_grasp_approach.min_distance = grasp_data.approach_retreat_min_dist_; // half of the desired? Untested.
00089 
00090   // Create re-usable retreat motion
00091   moveit_msgs::GripperTranslation post_grasp_retreat;
00092   post_grasp_retreat.direction.header.stamp = ros::Time::now();
00093   post_grasp_retreat.desired_distance = grasp_data.approach_retreat_desired_dist_; // The distance the origin of a robot link needs to travel
00094   post_grasp_retreat.min_distance = grasp_data.approach_retreat_min_dist_; // half of the desired? Untested.
00095 
00096   // Create re-usable blank pose
00097   geometry_msgs::PoseStamped grasp_pose_msg;
00098   grasp_pose_msg.header.stamp = ros::Time::now();
00099   grasp_pose_msg.header.frame_id = grasp_data.base_link_;
00100 
00101   // ---------------------------------------------------------------------------------------------
00102   // Angle calculations
00103   double radius = grasp_data.grasp_depth_; //0.12
00104   double xb;
00105   double yb = 0.0; // stay in the y plane of the object
00106   double zb;
00107   double theta1 = 0.0; // Where the point is located around the object
00108   double theta2 = 0.0; // UP 'direction'
00109 
00110   // Gripper direction (UP/DOWN) rotation. UP set by default
00111   if( direction == DOWN )
00112   {
00113     theta2 = M_PI;
00114   }
00115 
00116   // ---------------------------------------------------------------------------------------------
00117   // ---------------------------------------------------------------------------------------------
00118   // Begin Grasp Generator Loop
00119   // ---------------------------------------------------------------------------------------------
00120   // ---------------------------------------------------------------------------------------------
00121 
00122   /* Developer Note:
00123    * Create angles 180 degrees around the chosen axis at given resolution
00124    * We create the grasps in the reference frame of the object, then later convert it to the base link
00125    */
00126   for(int i = 0; i <= grasp_data.angle_resolution_; ++i)
00127   {
00128     // Create a Grasp message
00129     moveit_msgs::Grasp new_grasp;
00130 
00131     // Calculate grasp pose
00132     xb = radius*cos(theta1);
00133     zb = radius*sin(theta1);
00134 
00135     Eigen::Affine3d grasp_pose;
00136 
00137     switch(axis)
00138     {
00139       case X_AXIS:
00140         grasp_pose = Eigen::AngleAxisd(theta1, Eigen::Vector3d::UnitX())
00141           * Eigen::AngleAxisd(-0.5*M_PI, Eigen::Vector3d::UnitZ())
00142           * Eigen::AngleAxisd(theta2, Eigen::Vector3d::UnitX()); // Flip 'direction'
00143 
00144         grasp_pose.translation() = Eigen::Vector3d( yb, xb ,zb);
00145 
00146         break;
00147       case Y_AXIS:
00148         grasp_pose =
00149           Eigen::AngleAxisd(M_PI - theta1, Eigen::Vector3d::UnitY())
00150           *Eigen::AngleAxisd(theta2, Eigen::Vector3d::UnitX()); // Flip 'direction'
00151 
00152         grasp_pose.translation() = Eigen::Vector3d( xb, yb ,zb);
00153 
00154         break;
00155       case Z_AXIS:
00156         grasp_pose =
00157                 Eigen::AngleAxisd(M_PI - theta1, Eigen::Vector3d::UnitZ())
00158                 *Eigen::AngleAxisd(theta2, Eigen::Vector3d::UnitX()); // Flip 'direction'
00159 
00160             grasp_pose.translation() = Eigen::Vector3d( xb, yb ,zb);
00161 
00162         break;
00163     }
00164 
00165     /* The estimated probability of success for this grasp, or some other measure of how "good" it is.
00166      * Here we base bias the score based on how far the wrist is from the surface, preferring a greater
00167      * distance to prevent wrist/end effector collision with the table
00168      */
00169     double score = sin(theta1);
00170     new_grasp.grasp_quality = std::max(score,0.1); // don't allow score to drop below 0.1 b/c all grasps are ok
00171 
00172     // Calculate the theta1 for next time
00173     if (rotation == HALF)
00174       theta1 += M_PI / grasp_data.angle_resolution_;
00175     else
00176     {
00177       theta1 += 2*M_PI / grasp_data.angle_resolution_;
00178     }
00179 
00180     // A name for this grasp
00181     static int grasp_id = 0;
00182     new_grasp.id = "Grasp" + boost::lexical_cast<std::string>(grasp_id);
00183     ++grasp_id;
00184 
00185     // PreGrasp and Grasp Postures --------------------------------------------------------------------------
00186 
00187     // The internal posture of the hand for the pre-grasp only positions are used
00188     new_grasp.pre_grasp_posture = grasp_data.pre_grasp_posture_;
00189 
00190     // The internal posture of the hand for the grasp positions and efforts are used
00191     new_grasp.grasp_posture = grasp_data.grasp_posture_;
00192 
00193     // Grasp ------------------------------------------------------------------------------------------------
00194 
00195 
00196     // DEBUG - show original grasp pose before tranform to gripper frame
00197     if( verbose_ )
00198     {
00199       tf::poseEigenToMsg(object_global_transform_ * grasp_pose, grasp_pose_msg.pose);
00200       visual_tools_->publishArrow(grasp_pose_msg.pose, rviz_visual_tools::GREEN);
00201     }
00202 
00203     // ------------------------------------------------------------------------
00204     // Optionally roll wrist with respect to object pose
00205     Eigen::Affine3d roll_gripper;
00206     roll_gripper = Eigen::AngleAxisd(hand_roll, Eigen::Vector3d::UnitX());
00207     grasp_pose = grasp_pose * roll_gripper;
00208 
00209     // ------------------------------------------------------------------------
00210     // Change grasp to frame of reference of this custom end effector
00211 
00212     // Convert to Eigen
00213     Eigen::Affine3d eef_conversion_pose;
00214     tf::poseMsgToEigen(grasp_data.grasp_pose_to_eef_pose_, eef_conversion_pose);
00215 
00216     // Transform the grasp pose
00217     grasp_pose = grasp_pose * eef_conversion_pose;
00218 
00219     // ------------------------------------------------------------------------
00220     // Convert pose to global frame (base_link)
00221     tf::poseEigenToMsg(object_global_transform_ * grasp_pose, grasp_pose_msg.pose);
00222 
00223     // The position of the end-effector for the grasp relative to a reference frame (that is always specified elsewhere, not in this message)
00224     new_grasp.grasp_pose = grasp_pose_msg;
00225 
00226     // Other ------------------------------------------------------------------------------------------------
00227 
00228     // the maximum contact force to use while grasping (<=0 to disable)
00229     new_grasp.max_contact_force = 0;
00230 
00231     // -------------------------------------------------------------------------------------------------------
00232     // -------------------------------------------------------------------------------------------------------
00233     // Approach and retreat
00234     // -------------------------------------------------------------------------------------------------------
00235     // -------------------------------------------------------------------------------------------------------
00236 
00237     // Straight down ---------------------------------------------------------------------------------------
00238     // With respect to the base link/world frame
00239 
00240     // Approach
00241     pre_grasp_approach.direction.header.frame_id = grasp_data.base_link_;
00242     pre_grasp_approach.direction.vector.x = 0;
00243     pre_grasp_approach.direction.vector.y = 0;
00244     pre_grasp_approach.direction.vector.z = -1; // Approach direction (negative z axis)  // TODO: document this assumption
00245     new_grasp.pre_grasp_approach = pre_grasp_approach;
00246 
00247     // Retreat
00248     post_grasp_retreat.direction.header.frame_id = grasp_data.base_link_;
00249     post_grasp_retreat.direction.vector.x = 0;
00250     post_grasp_retreat.direction.vector.y = 0;
00251     post_grasp_retreat.direction.vector.z = 1; // Retreat direction (pos z axis)
00252     new_grasp.post_grasp_retreat = post_grasp_retreat;
00253 
00254     // Add to vector
00255     possible_grasps.push_back(new_grasp);
00256 
00257     // Angled with pose -------------------------------------------------------------------------------------
00258     // Approach with respect to end effector orientation
00259 
00260     // Approach
00261     pre_grasp_approach.direction.header.frame_id = grasp_data.ee_parent_link_;
00262     pre_grasp_approach.direction.vector.x = 0;
00263     pre_grasp_approach.direction.vector.y = 0;
00264     pre_grasp_approach.direction.vector.z = 1;
00265     new_grasp.pre_grasp_approach = pre_grasp_approach;
00266 
00267     // Retreat
00268     post_grasp_retreat.direction.header.frame_id = grasp_data.ee_parent_link_;
00269     post_grasp_retreat.direction.vector.x = 0;
00270     post_grasp_retreat.direction.vector.y = 0;
00271     post_grasp_retreat.direction.vector.z = -1;
00272     new_grasp.post_grasp_retreat = post_grasp_retreat;
00273 
00274     // Add to vector
00275     possible_grasps.push_back(new_grasp);
00276 
00277   }
00278 
00279   ROS_INFO_STREAM_NAMED("grasp", "Generated " << possible_grasps.size() << " grasps." );
00280 
00281   return true;
00282 }
00283 
00284 geometry_msgs::PoseStamped SimpleGrasps::getPreGraspPose(const moveit_msgs::Grasp &grasp, const std::string &ee_parent_link)
00285 {
00286   // Grasp Pose Variables
00287   geometry_msgs::PoseStamped grasp_pose = grasp.grasp_pose;
00288   Eigen::Affine3d grasp_pose_eigen;
00289   tf::poseMsgToEigen(grasp_pose.pose, grasp_pose_eigen);
00290 
00291   // Get pre-grasp pose first
00292   geometry_msgs::PoseStamped pre_grasp_pose;
00293   Eigen::Affine3d pre_grasp_pose_eigen = grasp_pose_eigen; // Copy original grasp pose to pre-grasp pose
00294 
00295   // Approach direction variables
00296   Eigen::Vector3d pre_grasp_approach_direction_local;
00297 
00298   // The direction of the pre-grasp
00299   // Calculate the current animation position based on the percent
00300   Eigen::Vector3d pre_grasp_approach_direction = Eigen::Vector3d(
00301     -1 * grasp.pre_grasp_approach.direction.vector.x * grasp.pre_grasp_approach.desired_distance,
00302     -1 * grasp.pre_grasp_approach.direction.vector.y * grasp.pre_grasp_approach.desired_distance,
00303     -1 * grasp.pre_grasp_approach.direction.vector.z * grasp.pre_grasp_approach.desired_distance
00304   );
00305 
00306   // Decide if we need to change the approach_direction to the local frame of the end effector orientation
00307   if( grasp.pre_grasp_approach.direction.header.frame_id == ee_parent_link )
00308   {
00309     // Apply/compute the approach_direction vector in the local frame of the grasp_pose orientation
00310     pre_grasp_approach_direction_local = grasp_pose_eigen.rotation() * pre_grasp_approach_direction;
00311   }
00312   else
00313   {
00314     pre_grasp_approach_direction_local = pre_grasp_approach_direction; //grasp_pose_eigen.rotation() * pre_grasp_approach_direction;
00315   }
00316 
00317   // Update the grasp matrix usign the new locally-framed approach_direction
00318   pre_grasp_pose_eigen.translation() += pre_grasp_approach_direction_local;
00319 
00320   // Convert eigen pre-grasp position back to regular message
00321   tf::poseEigenToMsg(pre_grasp_pose_eigen, pre_grasp_pose.pose);
00322 
00323   // Copy original header to new grasp
00324   pre_grasp_pose.header = grasp_pose.header;
00325 
00326   return pre_grasp_pose;
00327 }
00328 
00329 
00330 
00331 } // namespace


moveit_simple_grasps
Author(s): Dave Coleman
autogenerated on Thu Jun 6 2019 20:55:20