ros_graspit_interface.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2010, Willow Garage, Inc.
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 Willow Garage 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 "graspit_ros_planning/ros_graspit_interface.h"
00036 
00037 #include <boost/foreach.hpp>
00038 #include <cmath>
00039 #include <Inventor/actions/SoGetBoundingBoxAction.h>
00040 
00041 #include <src/DBase/DBPlanner/ros_database_manager.h>
00042 #include <src/DBase/graspit_db_model.h>
00043 #include <src/Collision/collisionStructures.h>
00044 #include <include/EGPlanner/searchEnergy.h>
00045 #include <include/mytools.h>
00046 #include <include/world.h>
00047 #include <include/body.h>
00048 #include <include/graspitGUI.h>
00049 #include <include/ivmgr.h>
00050 #include <include/scanSimulator.h>
00051 #include <include/pr2Gripper.h>
00052 
00053 #include <sensor_msgs/PointCloud.h>
00054 #include <sensor_msgs/point_cloud_conversion.h>
00055 
00056 //------------------------- Convenience functions -------------------------------
00057 
00058 template<typename T>
00059   inline T mean(const std::vector<T> &input)
00060   {
00061     T total = 0.0;
00062     BOOST_FOREACH(const T &val, input)
00063           {
00064             total += val;
00065           }
00066     return total / input.size();
00067   }
00068 ;
00069 
00070 template<typename T>
00071   inline T stddev(const std::vector<T> &input)
00072   {
00073     T m = mean(input);
00074     T total_err = 0.0;
00075     BOOST_FOREACH(const T &val, input)
00076           {
00077             total_err += std::pow(m - val, 2);
00078           }
00079 
00080     total_err /= input.size();
00081 
00082     return std::sqrt(total_err);
00083   }
00084 
00085 namespace graspit_ros_planning
00086 {
00087 
00088 transf poseToTransf(const geometry_msgs::Pose &pose)
00089 {
00090   return transf(Quaternion(pose.orientation.w, pose.orientation.x, pose.orientation.y, pose.orientation.z),
00091                 vec3(1000 * pose.position.x, 1000 * pose.position.y, 1000 * pose.position.z));
00092 }
00093 
00094 transf poseStampedToTransf(const geometry_msgs::PoseStamped &pose)
00095 {
00096   return transf(Quaternion(pose.pose.orientation.w, pose.pose.orientation.x, pose.pose.orientation.y, pose.pose.orientation.z),
00097                 vec3(1000 * pose.pose.position.x, 1000 * pose.pose.position.y, 1000 * pose.pose.position.z));
00098 }
00099 
00100 geometry_msgs::Pose transfToPose(const transf &tr)
00101 {
00102   geometry_msgs::Pose pose;
00103   return pose;
00104 }
00105 
00106 inline void getSbBoxDimension(SbBox3f& bbx, vec3& dimension)
00107 {
00108   // SbBox3f is axis aligned, so the dimension of the box can be easily computed
00109   float xmin, ymin, zmin, xmax, ymax, zmax;
00110   bbx.getBounds(xmin, ymin, zmin, xmax, ymax, zmax);
00111   dimension.set(xmax - xmin, ymax - ymin, zmax - zmin);
00112   ROS_INFO("Boundind box: (%.3lf, %.3lf, %.3lf), (%.3lf, %.3lf, %.3lf) ", xmin, ymin, zmin, xmax, ymax, zmax);
00113 }
00114 
00115 inline bool smallerThanSbVec3f(const SbVec3f& b1, const SbVec3f& b2)
00116 {
00117   float x1, y1, z1, x2, y2, z2;
00118   b1.getValue(x1, y1, z1);
00119   b2.getValue(x2, y2, z2);
00120 
00121   if (x1 <= x2 && y1 <= y2 && z1 <= z2)
00122     return true;
00123   else
00124     return false;
00125 }
00126 
00127 inline bool biggerThanSbVec3f(const SbVec3f& b1, const SbVec3f& b2)
00128 {
00129   float x1, y1, z1, x2, y2, z2;
00130   b1.getValue(x1, y1, z1);
00131   b2.getValue(x2, y2, z2);
00132 
00133   if (x1 >= x2 && y1 >= y2 && z1 >= z2)
00134     return true;
00135   else
00136     return false;
00137 }
00138 
00139 inline double randomUniformReal(double min, double max)
00140 {
00141   return ((1.0 * rand() / RAND_MAX) * (max - min) + min);
00142 }
00143 
00144 void randomPoseGenerate(SbBox3f &bb_space, geometry_msgs::Pose& grasp_random_pose)
00145 {
00146 
00147   float xmin, ymin, zmin, xmax, ymax, zmax;
00148   bb_space.getBounds(xmin, ymin, zmin, xmax, ymax, zmax);
00149 
00150   // Generate a random position within the bounding space first
00151   grasp_random_pose.position.x = randomUniformReal(xmin, xmax);
00152   grasp_random_pose.position.y = randomUniformReal(ymin, ymax);
00153   grasp_random_pose.position.z = randomUniformReal(zmin, zmax);
00154 
00155   // Generate a random orientation then
00156   double angle = randomUniformReal(0, 2.0 * M_PI);
00157   vec3 axis(randomUniformReal(0 + 0.0001, 1), randomUniformReal(0, 1), randomUniformReal(0, 1)); //make sure axis valid
00158   Quaternion orientation(angle, axis);
00159 
00160   grasp_random_pose.orientation.w = orientation.w;
00161   grasp_random_pose.orientation.x = orientation.x;
00162   grasp_random_pose.orientation.y = orientation.y;
00163   grasp_random_pose.orientation.z = orientation.z;
00164 }
00165 
00166 RosGraspitInterface::RosGraspitInterface() :
00167   root_nh_(NULL), priv_nh_(NULL), db_mgr_(NULL)
00168 {
00169   default_energy_threshold_ = 68.6;
00170 }
00171 
00172 RosGraspitInterface::~RosGraspitInterface()
00173 {
00174   ROS_INFO("ROS GraspIt node stopping");
00175   ros::shutdown();
00176   delete root_nh_;
00177   delete priv_nh_;
00178   delete db_mgr_;
00179 }
00180 
00181 //------------------------- Main class  -------------------------------
00182 
00183 int RosGraspitInterface::init(int argc, char **argv)
00184 {
00185   //copy the arguments somewhere else so we can pass them to ROS
00186   int ros_argc = argc;
00187   char** ros_argv = new char*[argc];
00188   for (int i = 0; i < argc; i++)
00189   {
00190     ros_argv[i] = new char[strlen(argv[i])];
00191     strcpy(ros_argv[i], argv[i]);
00192   }
00193   //see if a node name was requested
00194   std::string node_name("ros_graspit_interface");
00195   for (int i = 0; i < argc - 1; i++)
00196   {
00197     //std::cerr << argv[i] << "\n";
00198     if (!strcmp(argv[i], "_name"))
00199     {
00200       node_name = argv[i + 1];
00201     }
00202   }
00203   //init ros
00204   ros::init(ros_argc, ros_argv, node_name.c_str());
00205   //ROS_INFO("Using node name %s", node_name.c_str());
00206   //clean up ros arguments
00207   for (int i = 0; i < argc; i++)
00208   {
00209     delete ros_argv[i];
00210   }
00211   delete ros_argv;
00212   //init node handles
00213   root_nh_ = new ros::NodeHandle("");
00214   priv_nh_ = new ros::NodeHandle("~");
00215   //advertise service in private namespace
00216   load_model_srv_ = priv_nh_->advertiseService("load_database_model", &RosGraspitInterface::loadModelCB, this);
00217   load_obstacle_srv_ = priv_nh_->advertiseService("load_obstacle", &RosGraspitInterface::loadObstacleCB, this);
00218   clear_bodies_srv_ = priv_nh_->advertiseService("clear_bodies", &RosGraspitInterface::clearBodiesCB, this);
00219   simulate_scan_srv_ = priv_nh_->advertiseService("simulate_scan", &RosGraspitInterface::simulateScanCB, this);
00220   test_grasp_srv_ = priv_nh_->advertiseService("test_grasp", &RosGraspitInterface::testGraspCB, this);
00221   grasp_planning_srv_ = priv_nh_->advertiseService("grasp_planning", &RosGraspitInterface::graspPlanningCB, this);
00222 
00223   generate_grasp_srv_ = priv_nh_->advertiseService("generate_grasp", &RosGraspitInterface::generateGraspCB, this);
00224 
00225   scan_publisher_ = priv_nh_->advertise<sensor_msgs::PointCloud2> ("simulated_scans", 5);
00226 
00227   verify_grasp_srv_ = priv_nh_->advertiseService("verify_grasp", &RosGraspitInterface::verifyGraspCB, this);
00228 
00229   srand(1);
00230   //initialize database connection
00231   //careful: we pass a null for the grasp allocator as we don't know yet which hand we'll be using
00232   db_mgr_ = new db_planner::RosDatabaseManager("wgs36", "5432", "willow", "willow", "household_objects", NULL, NULL);
00233   //use the special allocator for models that get geometry directly from the database
00234   GeomGraspitDBModelAllocator* allocator = new GeomGraspitDBModelAllocator(db_mgr_);
00235   db_mgr_->SetModelAllocator(allocator);
00236   gripper_ = NULL;
00237   if (!db_mgr_->isConnected())
00238   {
00239     ROS_ERROR("Failed to connect to database");
00240     return -1;
00241   }
00242   ROS_INFO("ROS GraspIt node ready");
00243   return 0;
00244 }
00245 
00246 int RosGraspitInterface::mainLoop()
00247 {
00248   ros::spinOnce();
00249   return 0;
00250 }
00251 
00256 GraspitDBModel* RosGraspitInterface::getModel(int model_id)
00257 {
00258   std::map<int, GraspitDBModel*>::iterator it = models_.find(model_id);
00259   if (it != models_.end())
00260     return it->second;
00261 
00262   //retrieve the model from the database
00263   db_planner::Model* db_model;
00264   if (!db_mgr_->ScaledModel(db_model, model_id))
00265   {
00266     ROS_ERROR("Failed to load database model with id %d", model_id);
00267     return NULL;
00268   }
00269   GraspitDBModel *model = static_cast<GraspitDBModel*> (db_model);
00270   models_.insert(std::pair<int, GraspitDBModel*>(model_id, model));
00271   return model;
00272 }
00273 
00274 bool RosGraspitInterface::loadGripper()
00275 {
00276   World *world = graspItGUI->getIVmgr()->getWorld();
00277   if (gripper_)
00278   {
00279     ROS_WARN("Gripper load requested, but gripper already present. Re-loading.");
00280     world->removeRobot(gripper_);
00281   }
00282   std::string hand_path("/models/robots/pr2_gripper/pr2_gripper_2010.xml");
00283   hand_path = getenv("GRASPIT") + hand_path;
00284   gripper_ = static_cast<Pr2Gripper2010*> (world->importRobot(QString(hand_path.c_str())));
00285   if (!gripper_)
00286   {
00287     ROS_ERROR("Failed to load PR2 gripper from file %s", hand_path.c_str());
00288     return false;
00289   }
00290   return true;
00291 }
00292 
00293 bool RosGraspitInterface::loadModelCB(graspit_ros_planning_msgs::LoadDatabaseModel::Request &request,
00294                                       graspit_ros_planning_msgs::LoadDatabaseModel::Response &response)
00295 {
00296   //retrieve model from database, if not already retrieved
00297   GraspitDBModel *model = getModel(request.model_id);
00298   if (!model)
00299   {
00300     response.result = response.LOAD_FAILURE;
00301     return true;
00302   }
00303 
00304   //load the geometry, if not already loaded
00305   World *world = graspItGUI->getIVmgr()->getWorld();
00306   if (!model->geometryLoaded())
00307   {
00308     if (model->load(world) != SUCCESS)
00309     {
00310       ROS_ERROR("Failed to load geometry for database model with id %d", request.model_id);
00311       response.result = response.LOAD_FAILURE;
00312       return true;
00313     }
00314   }
00315 
00316   //if requested, if there are any models in the world that are not this one, remove them
00317   if (request.clear_other_models)
00318   {
00319     bool done = false;
00320     while (!done)
00321     {
00322       done = true;
00323       for (int i = 0; i < world->getNumGB(); i++)
00324       {
00325         if (world->getGB(i) != model->getGraspableBody())
00326         {
00327           world->destroyElement(world->getGB(i), false);
00328           done = false;
00329           break;
00330         }
00331       }
00332     }
00333   }
00334 
00335   //add the model to the world, if not already there
00336   if (world->getIVRoot()->findChild(model->getGraspableBody()->getIVRoot()) == -1)
00337   {
00338     model->getGraspableBody()->addToIvc();
00339     world->addBody(model->getGraspableBody());
00340   }
00341 
00342   //set the correct transform
00343   model->getGraspableBody()->setTran(poseToTransf(request.model_pose));
00344   model->getGraspableBody()->showAxes(false);
00345   response.result = response.LOAD_SUCCESS;
00346   return true;
00347 }
00348 
00349 bool RosGraspitInterface::clearBodiesCB(graspit_ros_planning_msgs::ClearBodies::Request &request,
00350                                         graspit_ros_planning_msgs::ClearBodies::Response &response)
00351 {
00352   World *world = graspItGUI->getIVmgr()->getWorld();
00353   if (request.which_bodies == request.GRASPABLE_BODIES || request.which_bodies == request.ALL_BODIES)
00354   {
00355     while (world->getNumGB() > 0)
00356     {
00357       //careful, we remove it from the world here but do not delete it
00358       //all geometry stays in place if we need it in the future, it just gets disconnected 
00359       //from the scene graph and the collision engine
00360       world->destroyElement(world->getGB(0), false);
00361     }
00362     ROS_INFO("Cleared graspable bodies");
00363   }
00364   if (request.which_bodies == request.OBSTACLES || request.which_bodies == request.ALL_BODIES)
00365   {
00366     bool removal = true;
00367     while (removal)
00368     {
00369       removal = false;
00370       for (int i = 0; i < world->getNumBodies(); i++)
00371       {
00372         if (!world->getBody(i)->inherits("DynamicBody"))
00373         {
00374           //obstacles get deleted for good as we don't keep track of them here
00375           world->destroyElement(world->getBody(i), true);
00376           removal = true;
00377           break;
00378         }
00379       }
00380     }
00381     ROS_INFO("Cleared obstacles bodies");
00382   }
00383   return true;
00384 }
00385 
00386 bool RosGraspitInterface::loadObstacleCB(graspit_ros_planning_msgs::LoadObstacle::Request &request,
00387                                          graspit_ros_planning_msgs::LoadObstacle::Response &response)
00388 {
00389   std::string filename = getenv("GRASPIT") + std::string("/") + request.file_name;
00390   World *world = graspItGUI->getIVmgr()->getWorld();
00391   Body *body = world->importBody("Body", QString(filename.c_str()));
00392   if (!body)
00393   {
00394     ROS_ERROR("Failed to import obstacle from file %s", filename.c_str());
00395     response.result = response.LOAD_FAILURE;
00396     return true;
00397   }
00398 
00399   //set the correct transform
00400   body->setTran(poseToTransf(request.obstacle_pose));
00401   response.result = response.LOAD_SUCCESS;
00402   return true;
00403 }
00404 
00405 bool RosGraspitInterface::simulateScanCB(graspit_ros_planning_msgs::SimulateScan::Request &request,
00406                                          graspit_ros_planning_msgs::SimulateScan::Response &response)
00407 {
00408   ScanSimulator scan_sim;
00409   scan_sim.setType(ScanSimulator::SCANNER_COORDINATES);
00410   scan_sim.setPosition(poseToTransf(request.scanner_pose), ScanSimulator::STEREO_CAMERA);
00411   //for now, we hard-code this in for the stereo camera, but they could be in the message
00412   double horiz_fov = 45;
00413   //half resolution to speed things up
00414   double horiz_res = 640;
00415   double vertical_res = 480;
00416   double vertical_fov = horiz_fov * vertical_res / horiz_res;
00417   scan_sim.setOptics(-horiz_fov / 2.0, horiz_fov / 2.0, horiz_res, -vertical_fov / 2.0, vertical_fov / 2.0,
00418                      vertical_res);
00419 
00420   //if the gripper is there, get it out of the scene graph so it does not show up in the scan
00421   World *world = graspItGUI->getIVmgr()->getWorld();
00422   if (gripper_)
00423   {
00424     world->removeElementFromSceneGraph(gripper_);
00425   }
00426   //get the scan (without the raw data)
00427   std::vector<position> cloud;
00428   ROS_INFO("Simulating scan...");
00429 
00430   if (request.request_ray_directions)
00431   {
00432     std::vector<RawScanPoint> rawData;
00433     scan_sim.scan(&cloud, &rawData);
00434     ROS_INFO("Simulated scan has %d points, %d rays", (int)cloud.size(), (int)rawData.size());
00435     // Also publish the direction of the rays that doesn't hit any object
00436     response.missing_ray_directions.reserve(rawData.size());
00437     for (size_t j = 0; j < rawData.size(); j++)
00438     {
00439       if (rawData[j].distance < -0.9) // If the ray doesn't hit anything, the distance is set to -1
00440       {
00441         geometry_msgs::Point32 dir;
00442         dir.x = rawData[j].dx;
00443         dir.y = rawData[j].dy;
00444         dir.z = rawData[j].dz;
00445         response.missing_ray_directions.push_back(dir);
00446       }
00447     }
00448   }
00449   else
00450   {
00451     scan_sim.scan(&cloud);
00452     ROS_INFO("Simulated scan has %d points", (int)cloud.size());
00453   }
00454   if (gripper_)
00455   {
00456     world->addElementToSceneGraph(gripper_);
00457   }
00458   //world->getIVRoot()->addChild(scan_sim.getVisualIndicator());
00459 
00460   //convert it to a PointCloud2
00461   //convert to a PointCloud first
00462   ROS_INFO("Converting scan to ROS format");
00463   sensor_msgs::PointCloud point_cloud;
00464   for (size_t i = 0; i < cloud.size(); i++)
00465   {
00466     geometry_msgs::Point32 point;
00467     point.x = 1.0e-3 * cloud[i].x();
00468     point.y = 1.0e-3 * cloud[i].y();
00469     point.z = 1.0e-3 * cloud[i].z();
00470     point_cloud.points.push_back(point);
00471   }
00472   point_cloud.header.frame_id = "graspit_scanner_frame";
00473   point_cloud.header.stamp = ros::Time::now();
00474   //convert to a PointCloud2
00475   ROS_INFO("Converting scan to point cloud 2");
00476   sensor_msgs::convertPointCloudToPointCloud2(point_cloud, response.scan);
00477   response.scan.header.stamp = ros::Time::now();
00478 
00479   //publish it on our internal topic
00480   ROS_INFO("Publishing scan");
00481   scan_publisher_.publish(response.scan);
00482 
00483   ROS_INFO("Done");
00484   return true;
00485 }
00486 
00487 void RosGraspitInterface::gripperCollisionCheck(const Body *object,
00488                                                 graspit_ros_planning_msgs::TestGrasp::Response &response)
00489 {
00490   response.hand_environment_collision = false;
00491   response.hand_object_collision = false;
00492   std::vector<DynamicBody*> gripper_link_list;
00493   gripper_->getAllLinks(gripper_link_list);
00494   std::vector<Body*> interest_list;
00495   for (size_t i = 0; i < gripper_link_list.size(); i++)
00496   {
00497     interest_list.push_back(gripper_link_list[i]);
00498   }
00499   CollisionReport collision_report;
00500   World *world = graspItGUI->getIVmgr()->getWorld();
00501   world->getCollisionReport(&collision_report, &interest_list);
00502   for (size_t i = 0; i < collision_report.size(); i++)
00503   {
00504     //figure out what the other body we are colliding with is
00505     Body *collision_body = collision_report[i].first;
00506     if (collision_body->getOwner() == gripper_)
00507     {
00508       collision_body = collision_report[i].second;
00509     }
00510     if (collision_body == object)
00511       response.hand_object_collision = true;
00512     else
00513       response.hand_environment_collision = true;
00514   }
00515 }
00516 
00517 void RosGraspitInterface::computeEnergy(Body *object, graspit_ros_planning_msgs::TestGrasp::Response &response)
00518 {
00519   SearchEnergy energy_calculator;
00520   energy_calculator.setType(ENERGY_CONTACT);
00521   energy_calculator.setContactType(CONTACT_PRESET);
00522   bool legal;
00523   double energy;
00524   energy_calculator.analyzeCurrentPosture(gripper_, object, legal, energy, false);
00525   if (!legal)
00526   {
00527     //this should not really happen, as we've checked for collisions already
00528     ROS_WARN("Energy calculator reports illegal state");
00529     response.test_result = response.HAND_COLLISION;
00530     response.energy_value = -1.0;
00531     return;
00532   }
00533   response.energy_value = energy;
00534   //hard-coded threshold for now, will make it into a parameter
00535   if (energy < 10.0)
00536     response.test_result = response.GRASP_SUCCESS;
00537   else
00538     response.test_result = response.GRASP_FAILURE;
00539 }
00540 
00541 bool RosGraspitInterface::verifyGraspCB(graspit_ros_planning_msgs::VerifyGrasp::Request &request,
00542                                         graspit_ros_planning_msgs::VerifyGrasp::Response &response)
00543 {
00544   response.hand_environment_collision = false;
00545   response.hand_object_collision = false;
00546 
00547   //  static int last_object_id = 0;
00548 
00549   graspit_ros_planning_msgs::LoadDatabaseModel::Request req_load_object;
00550   graspit_ros_planning_msgs::LoadDatabaseModel::Response res_load_object;
00551 
00552   World *world_p = graspItGUI->getIVmgr()->getWorld();
00553   GraspableBody *object = NULL;
00554   Body *obstacle = NULL;
00555 
00556   std::string filename = getenv("GRASPIT") + std::string("/") + request.table_file_name;
00557 
00558   req_load_object.model_id = request.scaled_model_id;
00559   req_load_object.model_pose = geometry_msgs::Pose();
00560   req_load_object.model_pose.orientation.w = 1.0;
00561   req_load_object.clear_other_models = true;
00562 
00563   loadModelCB(req_load_object, res_load_object);
00564 
00565   if (res_load_object.result == graspit_ros_planning_msgs::LoadDatabaseModel::Response::LOAD_FAILURE)
00566   {
00567     response.result = graspit_ros_planning_msgs::VerifyGrasp::Response::LOAD_OBJECT_FAILURE;
00568     ROS_WARN_STREAM("Object load failed!");
00569     return true;
00570   }
00571 
00572   object = world_p->getGB(0);
00573 
00574   //Get the bounding box of the object
00575   SoGetBoundingBoxAction bboxAction(graspItGUI->getIVmgr()->getViewer()->getViewportRegion());
00576   bboxAction.apply(object->getIVRoot());
00577   SbBox3f object_bbx = bboxAction.getBoundingBox();
00578   vec3 obj_bbx_dim;
00579   SbVec3f object_bbx_min, object_bbx_max;
00580   object_bbx.getBounds(object_bbx_min, object_bbx_max);
00581   getSbBoxDimension(object_bbx, obj_bbx_dim);
00582 
00583   // Load the tabletop
00584   // ROS_INFO_STREAM("Number of objects in the world " << world_p->getNumBodies());
00585   for (int i = 0; i < world_p->getNumBodies(); i++)
00586   {
00587     if (world_p->getBody(i)->getFilename().compare(QString(request.table_file_name.c_str())) == 0)
00588     {
00589       obstacle = world_p->getBody(i);
00590       break;
00591     }
00592   }
00593 
00594   graspit_ros_planning_msgs::LoadObstacle::Request req_load_obstacle;
00595   req_load_obstacle.file_name = request.table_file_name;
00596   req_load_obstacle.obstacle_pose = geometry_msgs::Pose();
00597   req_load_obstacle.obstacle_pose.orientation.w = 1.0;
00598   if (obstacle == NULL)
00599   {
00600     graspit_ros_planning_msgs::LoadObstacle::Response res_load_obstacle;
00601 
00602     loadObstacleCB(req_load_obstacle, res_load_obstacle);
00603 
00604     if (res_load_obstacle.result == graspit_ros_planning_msgs::LoadObstacle::Response::LOAD_FAILURE)
00605     {
00606       response.result = graspit_ros_planning_msgs::VerifyGrasp::Response::LOAD_OBSTACLE_FAILURE;
00607       ROS_WARN_STREAM("Tabletop load failed!");
00608       return true;
00609     }
00610 
00611     for (int i = 0; i < world_p->getNumBodies(); i++)
00612     {
00613       if (world_p->getBody(i)->getFilename().compare(QString(request.table_file_name.c_str())) == 0)
00614       {
00615         obstacle = world_p->getBody(i);
00616         break;
00617       }
00618     }
00619   }
00620 
00621   //Get the bounding box of the obstacle
00622   bboxAction.apply(obstacle->getIVRoot());
00623   SbBox3f obstacle_bbx = bboxAction.getBoundingBox();
00624   vec3 obstacle_bbx_dim;
00625   SbVec3f obstacle_bbx_min, obstacle_bbx_max;
00626   obstacle_bbx.getBounds(obstacle_bbx_min, obstacle_bbx_max);
00627   ROS_INFO("Tabletop");
00628   getSbBoxDimension(obstacle_bbx, obstacle_bbx_dim);
00629 
00630   float obstacle_current_z = obstacle->getTran().translation().z();
00631   float obstacle_top_z = obstacle_bbx_max[2];
00632   float object_bottom_z = object_bbx_min[2];
00633   float new_obstacle_z = obstacle_current_z + object_bottom_z - obstacle_top_z;
00634   req_load_obstacle.obstacle_pose.position.z = new_obstacle_z * 0.001; //
00635   obstacle->setTran(poseToTransf(req_load_obstacle.obstacle_pose));
00636 
00637   bboxAction.apply(obstacle->getIVRoot());
00638   SbBox3f obstacle_bbx_new = bboxAction.getBoundingBox();
00639   obstacle_bbx_new.getBounds(obstacle_bbx_min, obstacle_bbx_max);
00640   getSbBoxDimension(obstacle_bbx_new, obstacle_bbx_dim);
00641 
00642   // Load gripper to the scene
00643   if (!gripper_ && !loadGripper())
00644   {
00645     response.result = graspit_ros_planning_msgs::VerifyGrasp::Response::LOAD_GRIPPER_FAILURE;
00646     ROS_WARN_STREAM("Gripper load failed!");
00647     return true;
00648   }
00649 
00650   // Result valid
00651   response.result = graspit_ros_planning_msgs::VerifyGrasp::Response::CHECK_SUCCESS;
00652   //place the hand in the right pose
00653   gripper_->setTran(poseToTransf(request.grasp_pose));
00654   //set the gripper dof
00655   gripper_->forceDOFVal(0, request.grasp_joint_angle);
00656 
00657   graspit_ros_planning_msgs::TestGrasp::Response test_collision_response;
00658 
00659   response.gripper_tabletop_clearance = world_p->getDist(gripper_, obstacle);
00660   response.gripper_object_distance = world_p->getDist(gripper_, object);
00661   gripperCollisionCheck(object, test_collision_response);
00662 
00663   bool any_collision = false;
00664 
00665   if (test_collision_response.hand_environment_collision)
00666   {
00667     response.hand_environment_collision = true;
00668     ROS_WARN_STREAM("Collision with environment detected!");
00669     any_collision = true;
00670   }
00671   if (test_collision_response.hand_object_collision)
00672   {
00673     response.hand_object_collision = true;
00674     ROS_WARN_STREAM("Collision with object detected!");
00675     any_collision = true;
00676   }
00677 
00678   if (request.grasp_pose.position.z < 0.0 && !test_collision_response.hand_environment_collision)
00679   {
00680     ROS_WARN_STREAM("Gripper under desktop, hack the collision result");
00681     response.hand_environment_collision = true;
00682     response.gripper_tabletop_clearance = -1.0;
00683     any_collision = true;
00684   }
00685 
00686   if (!any_collision)
00687     ROS_WARN_STREAM("No Collision detected!");
00688   return true;
00689 }
00690 
00691 bool RosGraspitInterface::generateGraspCB(graspit_ros_planning_msgs::GenerateGrasp::Request &request,
00692                                           graspit_ros_planning_msgs::GenerateGrasp::Response &response)
00693 {
00694   // The resulted grasp pose doesn't guarantee that the object will be reasonably close to the gripper. (Generating voxelgrid using this grasp pose might get a completedly free voxelgrid)
00695 
00696   response.result = response.GENERATE_FAILURE;
00697 
00698   // Load the requested object to graspit and clear other objects
00699   graspit_ros_planning_msgs::LoadDatabaseModel::Request req_load_object;
00700   graspit_ros_planning_msgs::LoadDatabaseModel::Response res_load_object;
00701 
00702   static int last_model_id = 0;
00703   static int acc_count = 1;
00704 
00705   // object's pose will coincides with world frame, to simplify everything
00706   req_load_object.model_id = request.model_id;
00707   req_load_object.model_pose = geometry_msgs::Pose();
00708   req_load_object.model_pose.orientation.w = 1.0;
00709   req_load_object.clear_other_models = true;
00710 
00711   loadModelCB(req_load_object, res_load_object);
00712 
00713   if (res_load_object.result == res_load_object.LOAD_FAILURE)
00714   {
00715     response.result = response.GENERATE_FAILURE;
00716     ROS_INFO_STREAM("Object loaded failed!");
00717     return true;
00718   }
00719 
00720   //ROS_INFO_STREAM("Object loaded successful!");
00721 
00722 
00723   // Get a pointer to the object
00724   GraspitDBModel *model = getModel(request.model_id);
00725   if (!model)
00726   {
00727     response.result = response.GENERATE_FAILURE;
00728     return true;
00729   }
00730 
00731   // Load gripper to the scene
00732   if (!gripper_ && !loadGripper())
00733   {
00734     response.result = response.GENERATE_FAILURE;
00735     return true;
00736   }
00737 
00738   //  ROS_INFO_STREAM("Gripper loaded successful!");
00739 
00740   // Calculate bounding box sizes of both the object and gripper
00741   SoGetBoundingBoxAction bboxAction(graspItGUI->getIVmgr()->getViewer()->getViewportRegion());
00742   bboxAction.apply(model->getGraspableBody()->getIVRoot());
00743   SbBox3f object_bbx = bboxAction.getBoundingBox();
00744 
00745   gripper_->setTran(transf());
00746   //set the gripper dof (for the moment all the way open)
00747   gripper_->forceDOFVal(0, 0.26);
00748   bboxAction.apply(gripper_->getIVRoot());
00749   SbBox3f gripper_bbx = bboxAction.getBoundingBox();
00750 
00751   // Define the bounding space for randomly selecting the gripper
00752   vec3 gripper_bbx_dim, obj_bbx_dim, bbs_dim;
00753   //ROS_INFO("Gripper");
00754   getSbBoxDimension(gripper_bbx, gripper_bbx_dim);
00755   // double gripper_bbx_diag = sqrt(gripper_bbx_dim.len_sq());
00756   double gripper_box_xdim = gripper_bbx_dim.x();
00757 
00758   SbVec3f object_bbx_min, object_bbx_max;
00759   object_bbx.getBounds(object_bbx_min, object_bbx_max);
00760   // ROS_INFO("Object");
00761   getSbBoxDimension(object_bbx, obj_bbx_dim);
00762 
00763   SbBox3f bb_space;
00764   SbVec3f offset(30, 30, 0);
00765   SbVec3f offset2(30, 30, 30);
00766   if (last_model_id == request.model_id)
00767   {
00768     acc_count = (acc_count+1)%2; // acc_count != 0 and acc_count will accumulate
00769   }
00770   else
00771   {
00772     acc_count = 0;
00773   }
00774   last_model_id = request.model_id;
00775   SbVec3f bb_min, bb_max;
00776   bb_min = object_bbx_min - SbVec3f(gripper_box_xdim, gripper_box_xdim, 0) + acc_count * offset;
00777   bb_max = object_bbx_max + SbVec3f(gripper_box_xdim, gripper_box_xdim, gripper_box_xdim) - acc_count * offset2;
00778 
00779   bb_space.setBounds(bb_min, bb_max);
00780   //ROS_INFO("Bounding space");
00781   getSbBoxDimension(bb_space, bbs_dim);
00782 
00783   // PressEnterToContinue();
00784   ROS_ASSERT(gripper_->getNumChains() == 2); // Pr2 gripper should have two kinematic chains
00785 
00786   // Randomly generate grasp pose within the bounding space
00787   geometry_msgs::Pose grasp_random_pose;
00788   graspit_ros_planning_msgs::TestGrasp::Response test_grasp_res;
00789   std::vector<Body*> interest_list;
00790   interest_list.push_back(gripper_->getBase()); // palm
00791   interest_list.push_back(gripper_->getChain(0)->getLink(0)); //upper finger
00792   interest_list.push_back(gripper_->getChain(1)->getLink(0)); //another upper finger
00793   if (request.reject_fingertip_collision)
00794   {
00795     interest_list.push_back(gripper_->getChain(0)->getLink(1)); //fingertip
00796     interest_list.push_back(gripper_->getChain(1)->getLink(1)); //fingertip
00797   }
00798 
00799   World *world = graspItGUI->getIVmgr()->getWorld();
00800   Body *obstacle = NULL;
00801 
00802   if (request.request_tabletop)
00803   {
00804     std::string filename = getenv("GRASPIT") + std::string("/") + request.tabletop_file_name;
00805 
00806     for (int i = 0; i < world->getNumBodies(); i++)
00807     {
00808       if (world->getBody(i)->getFilename().compare(QString(request.tabletop_file_name.c_str())) == 0)
00809       {
00810         obstacle = world->getBody(i);
00811         break;
00812       }
00813     }
00814 
00815     graspit_ros_planning_msgs::LoadObstacle::Request req_load_obstacle;
00816     req_load_obstacle.file_name = request.tabletop_file_name;
00817     req_load_obstacle.obstacle_pose = geometry_msgs::Pose();
00818     req_load_obstacle.obstacle_pose.orientation.w = 1.0;
00819 
00820     if (obstacle == NULL)
00821     {
00822       graspit_ros_planning_msgs::LoadObstacle::Response res_load_obstacle;
00823       loadObstacleCB(req_load_obstacle, res_load_obstacle);
00824 
00825       if (res_load_obstacle.result == graspit_ros_planning_msgs::LoadObstacle::Response::LOAD_FAILURE)
00826       {
00827         response.result = response.GENERATE_FAILURE;
00828         ROS_WARN_STREAM("Tabletop load failed!");
00829         return true;
00830       }
00831       for (int i = 0; i < world->getNumBodies(); i++)
00832       {
00833         if (world->getBody(i)->getFilename().compare(QString(request.tabletop_file_name.c_str())) == 0)
00834         {
00835           obstacle = world->getBody(i);
00836           break;
00837         }
00838       }
00839     }
00840 
00841     //Get the bounding box of the obstacle
00842     bboxAction.apply(obstacle->getIVRoot());
00843     SbBox3f obstacle_bbx = bboxAction.getBoundingBox();
00844     vec3 obstacle_bbx_dim;
00845     SbVec3f obstacle_bbx_min, obstacle_bbx_max;
00846     obstacle_bbx.getBounds(obstacle_bbx_min, obstacle_bbx_max);
00847     getSbBoxDimension(obstacle_bbx, obstacle_bbx_dim);
00848 
00849     float obstacle_current_z = obstacle->getTran().translation().z();
00850     float obstacle_top_height = obstacle_bbx_max[2];
00851     float object_bottom_height = object_bbx_min[2];
00852     float new_obstacle_height = obstacle_current_z + object_bottom_height - obstacle_top_height;
00853     req_load_obstacle.obstacle_pose.position.z = new_obstacle_height * 0.001; //
00854     obstacle->setTran(poseToTransf(req_load_obstacle.obstacle_pose));
00855 
00856     bboxAction.apply(obstacle->getIVRoot());
00857     SbBox3f obstacle_bbx_new = bboxAction.getBoundingBox();
00858     obstacle_bbx_new.getBounds(obstacle_bbx_min, obstacle_bbx_max);
00859     getSbBoxDimension(obstacle_bbx_new, obstacle_bbx_dim);
00860   }
00861 
00862   int test_count = 1;
00863   double gripper_tabletop_clearance = -1;
00864   double gripper_object_distance = -1;
00865   while (true/*test_count > 0*/)
00866   {
00867     // ROS_INFO_STREAM("Trial " << test_count);
00868     test_count++;
00869 
00870     randomPoseGenerate(bb_space, grasp_random_pose); // Generate a random gripper pose in the bounding space
00871     //   ROS_INFO_STREAM( " Random grasp pose:" << grasp_random_pose);
00872     //   PressEnterToContinue();
00873     grasp_random_pose.position.x = grasp_random_pose.position.x * 1.0e-3; //Convert to meters
00874     grasp_random_pose.position.y = grasp_random_pose.position.y * 1.0e-3;
00875     grasp_random_pose.position.z = grasp_random_pose.position.z * 1.0e-3;
00876 
00877     //place the hand in the right pose
00878     gripper_->setTran(poseToTransf(grasp_random_pose));
00879     //set the gripper dof (for the moment all the way open)
00880     gripper_->forceDOFVal(0, 0.523);
00881     // Let the gripper automatically hold to the object
00882     gripper_->autoGrasp(false, 0.5, true);
00883 
00884     //ROS_INFO_STREAM( " Random grasp pose:" << grasp_random_pose << " grasp joint angle " << gripper_->getDOF(0)->getVal() );
00885 
00886     gripper_object_distance = world->getDist(gripper_, model->getGraspableBody());
00887     if (request.request_tabletop)
00888     {
00889       gripper_tabletop_clearance = world->getDist(gripper_, obstacle);
00890       graspit_ros_planning_msgs::TestGrasp::Response test_collision_response;
00891 
00892       gripperCollisionCheck(model->getGraspableBody(), test_collision_response);
00893 
00894       if (test_collision_response.hand_environment_collision)
00895       {
00896         //      ROS_WARN_STREAM("Collision with environment detected!, reject it!");
00897         continue;
00898       }
00899 
00900       if (grasp_random_pose.position.z < 0.0)
00901       {
00902         gripper_tabletop_clearance = -1.0;
00903         continue;
00904       }
00905     }
00906 
00907     // For every grasp pose, detect collision between gripper palm, two gripper upper fingers (i.e. all gripper parts except fingertips) and the object
00908     // If collision exists, reject this grasp pose
00909     CollisionReport collision_report;
00910     world->getCollisionReport(&collision_report, &interest_list);
00911     if (collision_report.size() > 0)
00912     {
00913       //      if (request.reject_fingertip_collision)
00914       //       ROS_INFO_STREAM("Collision exists between the gripper and the object, reject it");
00915       //     else
00916       //       ROS_INFO_STREAM("Collision exists between the gripper bottom part and the object, reject it");
00917 
00918       continue; //if collision exists, then continue to the next grasp pose
00919     }
00920 
00921     //  ROS_INFO_STREAM("No collision exists between the gripper bottom part and the object");
00922 
00923     // Compute grasp energy
00924     computeEnergy(model->getGraspableBody(), test_grasp_res);
00925 
00926     if (test_grasp_res.test_result == test_grasp_res.HAND_COLLISION) // collision exists, which should be with the fingertip, we found a bad grasp
00927 
00928     {
00929       if (request.reject_fingertip_collision)
00930       {
00931         ROS_INFO_STREAM("Collision exists between fingertip and the object, reject it and this should not happen");
00932         continue;
00933       }
00934       else
00935       {
00936         response.hand_object_collision = true;
00937         ROS_INFO_STREAM("Collision exists between fingertip and the object, accept it");
00938         break;
00939       }
00940     }
00941 
00942     if (test_grasp_res.energy_value > request.energy_high_threshold || test_grasp_res.energy_value
00943         < request.energy_low_threshold)
00944     {
00945 
00946       //   if (test_grasp_res.energy_value > request.energy_high_threshold)
00947       //     ROS_INFO_STREAM("Too high grasp energy, reject it");
00948       //   if (test_grasp_res.energy_value < request.energy_low_threshold)
00949       //     ROS_INFO_STREAM("Too low grasp energy , reject it");
00950       continue; // if energy too high or too low, reject
00951       // too high could be because object too far away from the gripper, too low is not bad grasp as we want
00952     }
00953     if (request.reject_fingertip_collision) // Only accept grasp with a grasp energy between two thresholds
00954 
00955     {
00956       ROS_INFO_STREAM("Bad grasp we found, accept it");
00957       response.hand_object_collision = false;
00958       break;
00959     }
00960     else // Only accept bad grasp that involves fingertip collision with the object
00961 
00962     {
00963       continue;
00964     }
00965   }
00966 
00967   ROS_INFO_STREAM( "Random grasp pose:" << grasp_random_pose << " grasp joint angle " << gripper_->getDOF(0)->getVal() <<" energy " << test_grasp_res.energy_value );
00968   ROS_INFO_STREAM("Number of objects "<<world->getNumBodies());
00969   response.grasp_pose = grasp_random_pose;
00970   response.grasp_energy = test_grasp_res.energy_value;
00971   response.grasp_joint_angle = gripper_->getDOF(0)->getVal();
00972   response.gripper_tabletop_clearance = gripper_tabletop_clearance;
00973   response.gripper_object_distance = gripper_object_distance;
00974   response.result = response.GENERATE_SUCCESS;
00975   return true;
00976 
00977 }
00978 
00979 void RosGraspitInterface::testGraspDirect(const manipulation_msgs::Grasp &grasp, GraspableBody *object,
00980                                           graspit_ros_planning_msgs::TestGrasp::Response &response)
00981 {
00982   //place the hand in the right pose
00983   gripper_->setTran(poseStampedToTransf(grasp.grasp_pose));
00984   //set the gripper dof (for the moment all the way open)
00985   gripper_->forceDOFVal(0, 0.523);//request.grasp.grasp_posture.position[0]);
00986   gripper_->autoGrasp(false, 0.5, true);
00987   //check for collisions
00988   gripperCollisionCheck(object, response);
00989   //if we find a collision, we are done
00990   if (response.hand_object_collision || response.hand_environment_collision)
00991   {
00992     response.test_result = response.HAND_COLLISION;
00993     return;
00994   }
00995   //compute the energy value
00996   computeEnergy(object, response);
00997 }
00998 
00999 void RosGraspitInterface::testGraspCompliant(const manipulation_msgs::Grasp &grasp, GraspableBody *object,
01000                                              graspit_ros_planning_msgs::TestGrasp::Response &response)
01001 {
01002   //place the hand in the right pose
01003   gripper_->setTran(poseStampedToTransf(grasp.grasp_pose));
01004   //set the gripper dof in the pre-grasp
01005   gripper_->forceDOFVal(0, grasp.pre_grasp_posture.position[0]);
01006   //check for collisions
01007   gripperCollisionCheck(object, response);
01008   //if we find a collision, we are done
01009   if (response.hand_object_collision || response.hand_environment_collision)
01010   {
01011     response.test_result = response.HAND_COLLISION;
01012     return;
01013   }
01014   //perform the compliant close
01015   gripper_->compliantClose();
01016   //compute the energy value
01017   computeEnergy(object, response);
01018 }
01019 
01020 void RosGraspitInterface::testGraspReactive(const manipulation_msgs::Grasp &grasp, GraspableBody *object,
01021                                             graspit_ros_planning_msgs::TestGrasp::Response &response)
01022 {
01023   // put hand in pre-grasp pose
01024   transf pre_grasp = poseStampedToTransf(grasp.grasp_pose);
01025   double moveDist = 100;
01026   pre_grasp = translate_transf(vec3(0, 0, -moveDist) * gripper_->getApproachTran()) * pre_grasp;
01027   gripper_->setTran(pre_grasp);
01028   // Open hand all the way up
01029   gripper_->forceDOFVal(0, 0.523);
01030   // check for collisions
01031   gripperCollisionCheck(object, response);
01032   //if we find a collision, we are done
01033   if (response.hand_object_collision || response.hand_environment_collision)
01034   {
01035     response.test_result = response.HAND_COLLISION;
01036     return;
01037   }
01038   // move hand forward until it contacts
01039   gripper_->approachToContact(moveDist, false);
01040   // Execute a compliant close
01041   gripper_->compliantClose();
01042   //Compute the score for the resulting grasp
01043   computeEnergy(object, response);
01044   response.energy_value_list.push_back(response.energy_value);
01045 }
01046 
01047 void RosGraspitInterface::testGraspRobustReactive(const manipulation_msgs::Grasp &grasp, GraspableBody *object,
01048                                                   graspit_ros_planning_msgs::TestGrasp::Response &response)
01049 {
01050   // put hand in pre-grasp pose
01051   transf orig_pre_grasp = poseStampedToTransf(grasp.grasp_pose);
01052   double moveDist = 100;
01053   const int n_tsteps = 3;
01054   //double t_steps[n_tsteps] = {-15,-10,-5,0,5,10,15};
01055   double t_steps[n_tsteps] = {-10, 0, 10};
01056   for (int x_step = 0; x_step < n_tsteps; x_step++)
01057   {
01058     transf pre_grasp = translate_transf(vec3(t_steps[x_step], 0, -moveDist) * gripper_->getApproachTran())
01059         * orig_pre_grasp;
01060     gripper_->setTran(pre_grasp);
01061     // Open hand all the way up
01062     gripper_->forceDOFVal(0, 0.523);
01063     // check for collisions
01064     gripperCollisionCheck(object, response);
01065     //if we find a collision, we are done
01066     if (response.hand_object_collision || response.hand_environment_collision)
01067     {
01068       response.energy_value_list.push_back(100);
01069     }
01070     else
01071     {
01072       // move hand forward until it contacts
01073       gripper_->approachToContact(moveDist, false);
01074       // Execute a compliant close
01075       gripper_->compliantClose();
01076       //Compute the score for the resulting grasp
01077       computeEnergy(object, response);
01078       response.energy_value_list.push_back(response.energy_value);
01079     }
01080   }
01081 
01082   for (int y_step = 0; y_step < n_tsteps; y_step++)
01083   {
01084     transf pre_grasp = translate_transf(vec3(0, t_steps[y_step], -moveDist) * gripper_->getApproachTran())
01085         * orig_pre_grasp;
01086     gripper_->setTran(pre_grasp);
01087     // Open hand all the way up
01088     gripper_->forceDOFVal(0, 0.523);
01089     // check for collisions
01090     gripperCollisionCheck(object, response);
01091     //if we find a collision, we are done
01092     if (response.hand_object_collision || response.hand_environment_collision)
01093     {
01094       response.energy_value_list.push_back(100);
01095     }
01096     else
01097     {
01098       // move hand forward until it contacts
01099       gripper_->approachToContact(moveDist, false);
01100       // Execute a compliant close
01101       gripper_->compliantClose();
01102 
01103       //Compute the score for the resulting grasp
01104       computeEnergy(object, response);
01105       response.energy_value_list.push_back(response.energy_value);
01106     }
01107   }
01108 
01109   for (int z_step = 0; z_step < n_tsteps; z_step++)
01110   {
01111     transf pre_grasp = translate_transf(vec3(0, 0, t_steps[z_step] - moveDist) * gripper_->getApproachTran())
01112         * orig_pre_grasp;
01113     gripper_->setTran(pre_grasp);
01114     // Open hand all the way up
01115     gripper_->forceDOFVal(0, 0.523);
01116     // check for collisions
01117     gripperCollisionCheck(object, response);
01118     //if we find a collision, we are done
01119     if (response.hand_object_collision || response.hand_environment_collision)
01120     {
01121       response.energy_value_list.push_back(100);
01122     }
01123     else
01124     {
01125       // move hand forward until it contacts
01126       gripper_->approachToContact(moveDist, false);
01127       // Execute a compliant close
01128       gripper_->compliantClose();
01129 
01130       //Compute the score for the resulting grasp
01131       computeEnergy(object, response);
01132       response.energy_value_list.push_back(response.energy_value);
01133     }
01134   }
01135 
01136   double m_energy = mean(response.energy_value_list);
01137   double stddev_energy = stddev(response.energy_value_list);
01138   response.energy_value = m_energy + stddev_energy;
01139 }
01140 
01141 bool RosGraspitInterface::testGraspCB(graspit_ros_planning_msgs::TestGrasp::Request &request,
01142                                       graspit_ros_planning_msgs::TestGrasp::Response &response)
01143 {
01144   response.test_performed = response.TEST_WAS_NOT_PERFORMED;
01145   //check if we have a gripper
01146   if (!gripper_ && !loadGripper())
01147     return true;
01148   //check if we have an object
01149   //by default (for now) we only test against the first graspable object in the world
01150   World *world = graspItGUI->getIVmgr()->getWorld();
01151   if (!world->getNumGB())
01152   {
01153     ROS_ERROR("No graspable object loaded");
01154     return true;
01155   }
01156   GraspableBody *object = world->getGB(0);
01157   //check is grasp is correctly specified  
01158   if (request.grasp.grasp_posture.position.empty() || request.grasp.pre_grasp_posture.position.empty())
01159   {
01160     ROS_ERROR("Gripper DOF not specified in grasp or pre-grasp");
01161     return true;
01162   }
01163 
01164   response.test_performed = response.TEST_WAS_PERFORMED;
01165   if (request.test_type == request.DIRECT)
01166   {
01167     testGraspDirect(request.grasp, object, response);
01168   }
01169   else if (request.test_type == request.COMPLIANT_CLOSE)
01170   {
01171     testGraspCompliant(request.grasp, object, response);
01172   }
01173   else if (request.test_type == request.REACTIVE_GRASP)
01174   {
01175     testGraspReactive(request.grasp, object, response);
01176   }
01177   else if (request.test_type == request.ROBUST_REACTIVE_GRASP)
01178   {
01179     testGraspReactive(request.grasp, object, response);
01180   }
01181   else
01182   {
01183     ROS_ERROR("Unknown test type requested");
01184     response.test_performed = response.TEST_WAS_NOT_PERFORMED;
01185   }
01186   return true;
01187 }
01188 
01189 bool RosGraspitInterface::graspPlanningCB(manipulation_msgs::GraspPlanning::Request &request,
01190                                           manipulation_msgs::GraspPlanning::Response &response)
01191 {
01192   response.error_code.value = response.error_code.OTHER_ERROR;
01193   if (!gripper_ && !loadGripper())
01194   {
01195     ROS_ERROR("Failed to load gripper for grasp planning");
01196     return true;
01197   }
01198   if (request.target.potential_models.empty())
01199   {
01200     ROS_ERROR("Graspit can only evaluate grasps on database objects");
01201     return true;
01202   }
01203   if (request.target.potential_models.size() != 1)
01204   {
01205     ROS_WARN("Graspit can only evaluate grasps on the first potential model in the list");
01206   }
01207   if (request.grasps_to_evaluate.empty())
01208   {
01209     ROS_ERROR("For now, graspit will test grasps on-line, but not plan new grasps");
01210     return true;
01211   }
01212   graspit_ros_planning_msgs::LoadDatabaseModel load_srv;
01213   load_srv.request.model_id = request.target.potential_models[0].model_id;
01214   load_srv.request.clear_other_models = true;
01215   loadModelCB(load_srv.request, load_srv.response);
01216   if (load_srv.response.result != load_srv.response.LOAD_SUCCESS)
01217   {
01218     ROS_ERROR("Failed to load database model for graspit grasp testing");
01219     return true;
01220   }
01221   GraspableBody *object = graspItGUI->getIVmgr()->getWorld()->getGB(0);
01222 
01223   //have to hardcode SUCCESS as graspit defines over it...
01224   response.error_code.value = 0;
01225 
01226   BOOST_FOREACH(manipulation_msgs::Grasp grasp, request.grasps_to_evaluate)
01227         {
01228           if (grasp.grasp_posture.position.empty() || grasp.pre_grasp_posture.position.empty())
01229           {
01230             ROS_ERROR("Gripper DOF not specified in grasp or pre-grasp");
01231             response.error_code.value = response.error_code.OTHER_ERROR;
01232             return true;
01233           }
01234 
01235           graspit_ros_planning_msgs::TestGrasp test_srv;
01236           if (default_grasp_test_type_ == test_srv.request.DIRECT)
01237           {
01238             testGraspDirect(grasp, object, test_srv.response);
01239           }
01240           else if (default_grasp_test_type_ == test_srv.request.COMPLIANT_CLOSE)
01241           {
01242             testGraspCompliant(grasp, object, test_srv.response);
01243           }
01244           else if (default_grasp_test_type_ == test_srv.request.REACTIVE_GRASP)
01245           {
01246             testGraspReactive(grasp, object, test_srv.response);
01247           }
01248           else if (default_grasp_test_type_ == test_srv.request.ROBUST_REACTIVE_GRASP)
01249           {
01250             testGraspReactive(grasp, object, test_srv.response);
01251           }
01252           if (test_srv.response.test_performed != test_srv.response.TEST_WAS_PERFORMED)
01253           {
01254             ROS_ERROR("Failed to test grasp");
01255             response.error_code.value = response.error_code.OTHER_ERROR;
01256             return true;
01257           }
01258 
01259           //come up with some probability value based on the test result
01260           double probability;
01261           //0 probability for grasps that result in collision
01262           if (test_srv.response.test_result == test_srv.response.HAND_COLLISION)
01263             probability = 0.0;
01264           //otherwise, return non-zero linear probability if the energy is below the threshold
01265           if (default_grasp_test_type_ == test_srv.request.ROBUST_REACTIVE_GRASP)
01266           {
01267             // Compute the mean and stddev of the values
01268           }
01269           probability = std::max(0.0, 1 - (test_srv.response.energy_value / default_energy_threshold_));
01270           grasp.grasp_quality = probability;
01271 
01272           response.grasps.push_back(grasp);
01273         }
01274 
01275   return true;
01276 }
01277 
01278 }


graspit_ros_planning
Author(s): Matei Ciocarlie
autogenerated on Mon Jan 6 2014 11:20:14