00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 #include <boost/shared_ptr.hpp>
00036 #include <boost/foreach.hpp>
00037 
00038 #include "bayesian_grasp_planner/bayesian_grasp_planner.h"
00039 #include "bayesian_grasp_planner/object_detector.h"
00040 #include "bayesian_grasp_planner/grasp_evaluator.h"
00041 #include "bayesian_grasp_planner/grasp_generator.h"
00042 #include "bayesian_grasp_planner/bayesian_grasp_planner_tools.h"
00043 
00044 namespace bayesian_grasp_planner {
00045 
00046 void BayesianGraspPlanner::bayesianInference(std::vector<GraspWM> &grasps,
00047                                           const std::vector<object_manipulation_msgs::GraspableObject> &objects,
00048                                           const std::vector< boost::shared_ptr<ObjectDetector> > &object_detectors,
00049                                           const std::vector< boost::shared_ptr<GraspEvaluatorProb> > &prob_evaluators)
00050 {
00051 
00052   
00053   ROS_INFO("computing grasp conditional probabilities");
00054   BOOST_FOREACH(const boost::shared_ptr<GraspEvaluatorProb> &prob_eval, prob_evaluators)
00055   {
00056     std::vector<double> grasp_success_probs;
00057     std::vector<double> grasp_failure_probs;
00058     
00059     
00060     BOOST_FOREACH(GraspWM &grasp, grasps)
00061     {
00062       grasp.success_cond_probs.resize(objects.size());
00063       grasp.failure_cond_probs.resize(objects.size());
00064     }
00065     
00066     
00067     if(prob_eval->is_object_dependent())
00068     {
00069       for(size_t object_ind = 0; object_ind < objects.size(); object_ind++)
00070       {
00071         
00072         if(objects[object_ind].potential_models.empty()) continue;
00073         
00074         
00075         prob_eval->getProbabilitiesForGraspList(grasps, objects[object_ind], grasp_success_probs, grasp_failure_probs);
00076         
00077         
00078         
00079         
00080         
00081         
00082         
00083         
00084         for (size_t grasp_ind = 0; grasp_ind < grasps.size(); grasp_ind++)
00085         {
00086           grasps[grasp_ind].success_cond_probs[object_ind].push_back(grasp_success_probs[grasp_ind]);
00087           grasps[grasp_ind].failure_cond_probs[object_ind].push_back(grasp_failure_probs[grasp_ind]);
00088         }
00089       }
00090     }
00091     
00092     
00093     else
00094     {
00095       
00096       prob_eval->getProbabilitiesForGraspList(grasps, objects[objects.size()-1], grasp_success_probs, grasp_failure_probs);
00097       
00098       
00099       
00100       
00101       
00102       
00103       
00104       
00105       for (size_t grasp_ind = 0; grasp_ind < grasps.size(); grasp_ind++)
00106       {
00107         for (size_t object_ind = 0; object_ind < objects.size(); object_ind++)
00108         {
00109           grasps[grasp_ind].success_cond_probs[object_ind].push_back(grasp_success_probs[grasp_ind]);
00110           grasps[grasp_ind].failure_cond_probs[object_ind].push_back(grasp_failure_probs[grasp_ind]);
00111         }
00112       }
00113     }
00114   }
00115 
00116   {
00117     for (size_t object_ind = 0; object_ind < objects.size(); object_ind++)
00118     {
00119       
00120       double object_prior;
00121       if (objects[object_ind].potential_models.size() > 0) 
00122       {        
00123         object_prior = 0.5 / (objects.size()-1);
00124         printf("Database object %d:\n", objects[object_ind].potential_models[0].model_id);
00125       }
00126       else 
00127       {
00128         printf("Non-database object:\n");
00129         object_prior = 0.5;
00130       }
00131       
00132       
00133       double detection_prob = 1.0;  
00134       BOOST_FOREACH(const boost::shared_ptr<ObjectDetector> &detector, object_detectors)
00135       {
00136         double obj_det_prob = detector->getProbabilityForDetection(objects[object_ind]);
00137         
00138         detection_prob *= obj_det_prob;
00139       }
00140       printf("  total detection probability: %f\n", detection_prob);
00141     }
00142   }
00143 
00144  
00145   
00146   ROS_INFO("performing inference");
00147   for (size_t grasp_ind = 0; grasp_ind < grasps.size(); grasp_ind++)
00148   {
00149     double grasp_overall_success_prob = 0.0;
00150     double grasp_overall_failure_prob = 0.0;
00151     for (size_t object_ind = 0; object_ind < objects.size(); object_ind++)
00152     {
00153       
00154       double object_prior;
00155       if (objects[object_ind].potential_models.size() > 0) object_prior = 0.5 / (objects.size()-1);
00156       else object_prior = 0.5;
00157       
00158       
00159       double detection_prob = 1.0;  
00160       
00161       BOOST_FOREACH(const boost::shared_ptr<ObjectDetector> &detector, object_detectors)
00162       {
00163         double obj_det_prob = detector->getProbabilityForDetection(objects[object_ind]);
00164         
00165         
00166         detection_prob *= obj_det_prob;
00167       }
00168       
00169       
00170       
00171       double success_prior = 0.5;  
00172       double failure_prior = 0.5;  
00173       
00174       
00175       double grasp_success_prob = 1.0;  
00176       double grasp_failure_prob = 1.0;  
00177           
00178 
00179 
00180 
00181 
00182 
00183 
00184 
00185 
00186       for (size_t eval_ind = 0; eval_ind < grasps[grasp_ind].success_cond_probs[object_ind].size(); eval_ind ++)
00187       {
00188         
00189         double succ_prob = grasps[grasp_ind].success_cond_probs[object_ind][eval_ind];
00190         
00191         double fail_prob = grasps[grasp_ind].failure_cond_probs[object_ind][eval_ind];
00192         
00193         double eval_prob = succ_prob * success_prior + fail_prob * failure_prior; 
00194         
00195         grasp_success_prob *= succ_prob / eval_prob;
00196         grasp_failure_prob *= fail_prob / eval_prob;
00197         
00198       }
00199       
00200       
00201       
00202       grasp_overall_success_prob += object_prior * detection_prob * success_prior * grasp_success_prob;
00203       grasp_overall_failure_prob += object_prior * detection_prob * failure_prior * grasp_failure_prob;
00204       
00205       
00206       
00207       
00208       
00209       
00210     }
00211     
00212     
00213     if (grasp_overall_success_prob + grasp_overall_failure_prob == 0)
00214     {
00215       ROS_WARN("sum of success and failure conditional probs was 0!");
00216       grasps[grasp_ind].grasp_.success_probability = 0.;
00217       continue;
00218     }
00219     double normalization_factor = 1.0 / (grasp_overall_success_prob + grasp_overall_failure_prob);
00220     grasps[grasp_ind].grasp_.success_probability = normalization_factor * grasp_overall_success_prob;
00221         
00222     
00223   }
00224 }
00225 
00226 
00227 void BayesianGraspPlanner::plan(const std::string &arm_name,
00228                                 const object_manipulation_msgs::GraspableObject &graspable_object,
00229                                 std::vector<object_manipulation_msgs::Grasp> &final_grasp_list)
00230 {
00231   
00232   boost::shared_ptr<ProbabilityDistribution> cluster_success_distribution( 
00233                                                                                   new BimodalGaussianProbabilityDistribution(.611, .285, .806) );
00234   boost::shared_ptr<ProbabilityDistribution> cluster_failure_distribution(                                 
00235                                                                                   new BimodalGaussianProbabilityDistribution(.563, .272, .935) );
00236 
00237   
00238   boost::shared_ptr<ProbabilityDistribution> graspit_success_distribution( 
00239                                                  new GaussianProbabilityDistribution(.825, .125, 0.0, 1.0, false) );
00240   boost::shared_ptr<ProbabilityDistribution> graspit_failure_distribution( 
00241                                                  new GaussianProbabilityDistribution(.627, .376, 0.0, 1.0, false) );
00242 
00243   
00244   std::vector<object_manipulation_msgs::GraspableObject> objects;
00245   createMutuallyExclusiveObjectRepresentations(graspable_object, objects);
00246 
00247   
00248   std::vector< boost::shared_ptr<ObjectDetector> > object_detectors;
00249   createDatabaseObjectDetectors(objects, object_detectors);
00250 
00251   
00252   std::vector< boost::shared_ptr<GraspGenerator> > grasp_generators;
00253 
00254   
00255   std::vector< boost::shared_ptr<GraspEvaluatorProb> > grasp_evaluators;
00256 
00257   
00258   
00259   {
00260     
00261     boost::shared_ptr<MultiplexEvaluator> graspit_multiplexer_regression_eval( new MultiplexEvaluator );
00262 
00263     
00264     BOOST_FOREACH(const household_objects_database_msgs::DatabaseModelPose &model, graspable_object.potential_models)
00265     {
00266       
00267       boost::shared_ptr<GraspGenerator> grasp_gen( new GraspGeneratorDatabaseRetriever(database_, model, arm_name, false) );
00268       grasp_gen->generateGrasps();
00269       
00270       
00271       boost::shared_ptr<RawGraspEvaluator> regression_eval( new RawGraspEvaluatorWithRegression(grasp_gen, true) );
00272       
00273       
00274       graspit_multiplexer_regression_eval->addEvaluator(regression_eval, model.model_id);
00275 
00276       
00277       boost::shared_ptr<GraspGenerator> grasp_gen_reps( new GraspGeneratorDatabaseRetriever(database_, model, arm_name, true) );
00278 
00279       
00280       grasp_generators.push_back( grasp_gen_reps );      
00281     }
00282 
00283     
00284     boost::shared_ptr<GraspEvaluatorProb> prob_eval( new GraspEvaluatorProb( graspit_success_distribution,
00285                                                                              graspit_failure_distribution,
00286                                                                              graspit_multiplexer_regression_eval ) );
00287 
00288     
00289     grasp_evaluators.push_back(prob_eval);
00290   }
00291 
00292   
00293   
00294   {
00295     
00296     boost::shared_ptr<GraspGenerator> grasp_gen( new GraspGeneratorServiceCaller(nh_, "/plan_point_cluster_grasp", 
00297                                                                                  graspable_object, arm_name));
00298 
00299     
00300     grasp_generators.push_back(grasp_gen);
00301 
00302     int cluster_computer_type;
00303     nh_.param("cluster_computer_type",cluster_computer_type, 1);
00304     ROS_INFO("cluster_computer_type = %d", cluster_computer_type);
00305     
00306     boost::shared_ptr<RawGraspEvaluator> cluster_eval;
00307     switch (cluster_computer_type)
00308     {
00309     case 1: 
00310       {
00311         std::string test_cluster_grasp_srv;
00312         nh_.param("test_cluster_grasp_srv", test_cluster_grasp_srv, std::string("/evaluate_point_cluster_grasps"));  
00313         cluster_eval.reset( new RawGraspEvaluatorServiceCaller(nh_, test_cluster_grasp_srv, false) );
00314         break;
00315       }
00316     case 2: 
00317       {
00318         cluster_eval.reset( new RawGraspEvaluatorWithRegression(grasp_gen, false) );
00319         break;
00320       }
00321     }
00322     
00323     
00324     boost::shared_ptr<GraspEvaluatorProb> prob_eval( new GraspEvaluatorProb( cluster_success_distribution,
00325                                                                              cluster_failure_distribution,
00326                                                                              cluster_eval ) );
00327     
00328     grasp_evaluators.push_back(prob_eval);
00329   }
00330   
00331   ROS_INFO("%d grasp generators created", (int)grasp_generators.size());
00332 
00333   
00334   std::vector<GraspWM> grasps;
00335   ROS_INFO("evaluating grasps");
00336 
00337   
00338   if (final_grasp_list.size() > 0)
00339   {
00340         
00341         appendMetadataToTestGrasps(final_grasp_list, grasps, graspable_object.reference_frame_id);             
00342   }
00343 
00344   
00345   else
00346   {
00347         BOOST_FOREACH(boost::shared_ptr<GraspGenerator> &gen, grasp_generators)
00348         {
00349           ROS_INFO("getting grasps from grasp generator");
00350           gen->generateGrasps();
00351           gen->getGrasps(grasps);
00352         }
00353   }
00354 
00355   ROS_INFO("number of grasps to evaluate: %d", (int)grasps.size());
00356 
00357   
00358   bayesianInference(grasps, objects, object_detectors, grasp_evaluators);  
00359   
00360   
00361 
00362 
00363 
00364 
00365 
00366 
00367 
00368   
00369   std::sort(grasps.rbegin(), grasps.rend());
00370 
00371   visualizeGrasps(grasps, &debug_preprune_grasp_marker_publisher_, false);
00372   
00373 
00374 
00375 
00376 
00377 
00378 
00379 
00380   
00381   if (final_grasp_list.size() == 0)
00382   {
00383     double grasp_probability_threshold;
00384     nh_.param("initial_probability_threshold", grasp_probability_threshold, 0.01);  
00385     pruneGraspList(grasps, grasp_probability_threshold);
00386   }
00387 
00388   visualizeGrasps(grasps, &debug_postprune_grasp_marker_publisher_, false);
00389 
00390   
00391   ROS_INFO("clustering");
00392   std::vector<GraspWM> clustered_grasps;
00393   clusterGrasps(grasps, clustered_grasps);
00394 
00395   
00396   int grasps_max;
00397   nh_.param("quantity_threshold", grasps_max, 100);
00398   size_t grasps_max_size = grasps_max;
00399   if (clustered_grasps.size() > grasps_max_size)
00400   {
00401         ROS_INFO("Taking top %zd grasps after clustering", grasps_max_size);
00402         clustered_grasps.resize(grasps_max_size);
00403   }    
00404 
00405   
00406   final_grasp_list.clear();
00407   final_grasp_list.reserve(clustered_grasps.size());
00408   BOOST_FOREACH(GraspWM graspwm, clustered_grasps)
00409   {
00410         final_grasp_list.push_back(graspwm.getGrasp());
00411         
00412   }
00413   visualizeGrasps(clustered_grasps, &grasp_marker_publisher_, false);
00414 
00415   ROS_INFO("done planning");
00416 }
00417 
00418 void BayesianGraspPlanner::createMutuallyExclusiveObjectRepresentations(
00419                                                const object_manipulation_msgs::GraspableObject &original_object,
00420                                                std::vector<object_manipulation_msgs::GraspableObject> &me_objects )
00421 {
00422   
00423   for (size_t i = 0; i < original_object.potential_models.size(); i++)
00424   {
00425         object_manipulation_msgs::GraspableObject new_object;
00426         new_object.potential_models.push_back(original_object.potential_models[i]);
00427         new_object.reference_frame_id = original_object.reference_frame_id;
00428         me_objects.push_back(new_object);
00429   }
00430 
00431   
00432   object_manipulation_msgs::GraspableObject new_object;
00433   new_object.cluster = original_object.cluster;
00434   new_object.reference_frame_id = original_object.reference_frame_id;
00435   me_objects.push_back(new_object);
00436 
00437   ROS_INFO("%d object representations created", (int)me_objects.size());
00438 }
00439 
00440 void BayesianGraspPlanner::createDatabaseObjectDetectors( 
00441                                     const std::vector<object_manipulation_msgs::GraspableObject> &objects,              
00442                                     std::vector< boost::shared_ptr<ObjectDetector> >&detectors)
00443 {
00444   
00445   
00446   
00447   boost::shared_ptr<ProbabilityDistribution> correct_distribution(
00448                                new GaussianProbabilityDistribution(.531, .125, 0., .005, true));  
00449   boost::shared_ptr<ProbabilityDistribution> incorrect_distribution(
00450                                new GaussianProbabilityDistribution(.292, .154, 0., .005, true));
00451 
00452   
00453   for (size_t i = 0; i < objects.size(); i++)
00454   {
00455     if (objects[i].potential_models.size() != 0)
00456     {
00457       
00458       
00459       boost::shared_ptr<ObjectDetector> detector ( new DatabaseObjectDetector(objects[i], correct_distribution, 
00460                                                                               incorrect_distribution) );
00461       detectors.push_back(detector);
00462     }   
00463   }             
00464   ROS_INFO("%d object detectors created", (int)detectors.size());
00465 }
00466 
00467 void BayesianGraspPlanner::appendMetadataToTestGrasps(std::vector<object_manipulation_msgs::Grasp> &input_list,
00468                                                       std::vector<GraspWM> &output_list, const std::string frame_id)
00469 {
00470 
00471   output_list.reserve(output_list.size()+input_list.size());
00472 
00473   ROS_INFO("Got %zd grasps to test",input_list.size());
00474   BOOST_FOREACH(object_manipulation_msgs::Grasp &grasp, input_list)
00475   {
00476     GraspWM grasp_wm;
00477     grasp_wm.grasp_ = grasp;
00478     grasp_wm.grasp_.success_probability = 0.0;
00479     grasp_wm.model_id_ = -1;
00480     grasp_wm.grasp_id_ = -1;
00481 
00482     grasp_wm.object_pose_.setIdentity();
00483     grasp_wm.object_pose_.frame_id_ = frame_id;
00484     grasp_wm.object_pose_.stamp_ = ros::Time(0);
00485 
00487     tf::Pose grasp_in_base_frame;
00488     tf::poseMsgToTF(grasp.grasp_pose, grasp_in_base_frame);
00489     double wrist_to_tool_point_offset_ = 0.13;
00490     tf::Pose grasp_to_tool_point(tf::Matrix3x3::getIdentity(),tf::Vector3(wrist_to_tool_point_offset_,0,0));
00491     grasp_wm.tool_point_pose_ = tf::Stamped<tf::Pose>(
00492         grasp_in_base_frame * grasp_to_tool_point, grasp_wm.object_pose_.stamp_, frame_id);
00493 
00494     output_list.push_back(grasp_wm);
00495   }
00496   ROS_DEBUG("Created %zd grasps", output_list.size());
00497 }
00498 
00499 
00500 void BayesianGraspPlanner::clusterGrasps(std::vector<GraspWM> &input_list, 
00501                                                                                  std::vector<GraspWM> &cluster_rep_list)
00502 {
00503   ROS_INFO("Clustering %zd grasps",input_list.size());
00504 
00505   double clustering_cart_distance_threshold = 0.01;
00506   double clustering_angle_distance_threshold = 0.266;
00507 
00508   int clusters = 0;
00509   while (!input_list.empty())
00510   {
00511     GraspWM *repGrasp = &input_list.front();
00512     repGrasp->grasp_.cluster_rep = true;
00513     cluster_rep_list.push_back(*repGrasp);
00514     input_list.erase(input_list.begin());
00515     ++clusters;
00516 
00517     int cloud=0;
00518     std::vector<GraspWM>::iterator it=input_list.begin();
00519     while (it != input_list.end())
00520     {
00521       double cart_distance, angle_distance;
00522       cluster_rep_list.back().getDistance(*it,cart_distance,angle_distance);
00523       if (cart_distance < clustering_cart_distance_threshold && 
00524           angle_distance < clustering_angle_distance_threshold)
00525       {
00526         ++cloud;
00527         it = input_list.erase(it);
00528       }
00529       else {
00530         ++it;
00531       }
00532     }
00533     ROS_DEBUG("Grouped cluster of size %d",cloud);
00534   }
00535   ROS_INFO("Selected %d cluster rep grasps",clusters);
00536 }
00537 
00538 void BayesianGraspPlanner::pruneGraspList(std::vector<GraspWM> &grasps, const double threshold)
00539 {
00540   std::vector<GraspWM>::iterator it=grasps.begin();
00541   int erased_count = 0;
00542   while( it != grasps.end())
00543   {
00544     if (it->grasp_.success_probability < threshold)
00545     {
00546       erased_count++;
00547       ROS_DEBUG("Erasing grasp with probability %g",it->grasp_.success_probability);
00548       it=grasps.erase(it);
00549     }
00550     else{
00551       it++;
00552     }
00553   }
00554 
00555   ROS_INFO("Removed %d grasps below threshold",erased_count);
00556 }
00557 
00558 
00559 
00560 void BayesianGraspPlanner::visualizeGrasps(const std::vector<GraspWM> &grasps,
00561         object_manipulator::GraspMarkerPublisher *grasp_publisher, bool color_by_rank)
00562 {
00563   grasp_publisher->clearAllMarkers();
00564   size_t sz = grasps.size();
00565   if (sz == 0)
00566   {
00567     return;
00568   }
00569 
00570   for (size_t i=0; i < sz; i++) {
00571     const GraspWM *grasp = &grasps[i];
00572     std::string ns_append = boost::lexical_cast<std::string>(grasp->model_id_);
00573     grasp_publisher->setNamespaceSuffix(ns_append);
00574 
00575     tf::Pose grasp_pose_tf;
00576     tf::poseMsgToTF(grasp->grasp_.grasp_pose, grasp_pose_tf);
00577 
00578     tf::Stamped<tf::Pose> grasp_in_world(grasp_pose_tf, grasp->object_pose_.stamp_, grasp->object_pose_.frame_id_);
00579 
00580     geometry_msgs::PoseStamped grasp_in_world_msg;
00581     tf::poseStampedTFToMsg(grasp_in_world, grasp_in_world_msg);
00582 
00583     unsigned int id = grasp_publisher->addGraspMarker(grasp_in_world_msg);
00584 
00585     float colorval;
00586     if (color_by_rank)
00587     {
00588       colorval = i/(1.0*sz);
00589     }
00590     else {
00591       colorval = 1 - grasp->grasp_.success_probability;
00592     }
00593     grasp_publisher->colorGraspMarker(id, colorval, 1-colorval, 0.0);
00594   }
00595 }
00596 
00597 
00598 }