00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <household_objects_database/objects_database.h>
00038 using household_objects_database::ObjectsDatabasePtr;
00039 #include <household_objects_database/database_grasp.h>
00040 using household_objects_database::DatabaseGraspPtr;
00041 #include <household_objects_database/database_perturbation.h>
00042 using household_objects_database::DatabasePerturbationPtr;
00043
00044 #include <object_manipulator/tools/hand_description.h>
00045 #include <object_manipulation_msgs/GraspPlanning.h>
00046 #include <object_manipulation_msgs/GraspPlanningErrorCode.h>
00047 #include <tf/transform_broadcaster.h>
00048
00049
00050
00051
00052 #include "probabilistic_grasp_planner/grasp_retriever.h"
00053
00054
00055
00056
00057 namespace probabilistic_grasp_planner {
00058
00060
00063 void DatabaseGraspRetriever::pruneGraspList(std::vector<DatabaseGraspPtr> &grasps,
00064 double gripper_threshold,
00065 double table_clearance_threshold)
00066 {
00067 std::vector<DatabaseGraspPtr>::iterator prune_it = grasps.begin();
00068 int pruned = 0;
00069 while ( prune_it != grasps.end() )
00070 {
00071
00072 if ((*prune_it)->final_grasp_posture_.get().joint_angles_[0] > gripper_threshold ||
00073 (table_clearance_threshold >= 0.0 && (*prune_it)->table_clearance_.get() < table_clearance_threshold*1.0e3) )
00074 {
00075 prune_it = grasps.erase(prune_it);
00076 pruned++;
00077 }
00078 else
00079 {
00080 prune_it++;
00081 }
00082 }
00083 ROS_DEBUG("Database grasp planner: pruned %d grasps for table collision or gripper angle above threshold", pruned);
00084 }
00085
00086 void DatabaseGraspRetriever::appendMetadataToGrasps(const std::vector<DatabaseGraspPtr> &db_grasps,
00087 std::vector<GraspWithMetadata> &grasps)
00088 {
00089 grasps.reserve(grasps.size()+db_grasps.size());
00090
00091 BOOST_FOREACH(DatabaseGraspPtr db_grasp, db_grasps) {
00092 GraspWithMetadata grasp;
00093
00094 ROS_ASSERT( db_grasp->final_grasp_posture_.get().joint_angles_.size() ==
00095 db_grasp->pre_grasp_posture_.get().joint_angles_.size() );
00096 ROS_ASSERT(db_grasp->scaled_model_id_.get() == model_.model_id);
00097
00098 std::vector<std::string> joint_names = object_manipulator::handDescription().handJointNames(arm_name_);
00099 if (object_manipulator::handDescription().handDatabaseName(arm_name_) != "WILLOW_GRIPPER_2010")
00100 {
00101
00102
00103 if (joint_names.size() != db_grasp->final_grasp_posture_.get().joint_angles_.size())
00104 {
00105 ROS_ERROR("Database grasp specification does not match ROS description of hand. "
00106 "Hand is expected to have %zd joints, but database grasp specifies %zd values",
00107 joint_names.size(), db_grasp->final_grasp_posture_.get().joint_angles_.size());
00108 continue;
00109 }
00110
00111
00112 grasp.grasp_.pre_grasp_posture.name = joint_names;
00113 grasp.grasp_.grasp_posture.name = joint_names;
00114 grasp.grasp_.pre_grasp_posture.position = db_grasp->pre_grasp_posture_.get().joint_angles_;
00115 grasp.grasp_.grasp_posture.position = db_grasp->final_grasp_posture_.get().joint_angles_;
00116 }
00117 else
00118 {
00119
00120
00121 if ( joint_names.size() != 4 || db_grasp->final_grasp_posture_.get().joint_angles_.size() != 1)
00122 {
00123 ROS_ERROR("PR2 gripper specs and database grasp specs do not match expected values");
00124 continue;
00125 }
00126 grasp.grasp_.pre_grasp_posture.name = joint_names;
00127 grasp.grasp_.grasp_posture.name = joint_names;
00128
00129 grasp.grasp_.pre_grasp_posture.position.resize( joint_names.size(),
00130 db_grasp->pre_grasp_posture_.get().joint_angles_.at(0));
00131 grasp.grasp_.grasp_posture.position.resize( joint_names.size(),
00132 db_grasp->final_grasp_posture_.get().joint_angles_.at(0));
00133 }
00134
00135
00136
00137 grasp.grasp_.pre_grasp_posture.effort.resize(joint_names.size(), 100);
00138 grasp.grasp_.grasp_posture.effort.resize(joint_names.size(), 50);
00139 grasp.grasp_.desired_approach_distance = 0.10;
00140 grasp.grasp_.min_approach_distance = 0.05;
00141
00142 grasp.grasp_.success_probability = 0.0;
00143
00144
00145
00146
00147 grasp.energy_function_score_ = db_grasp->quality_.get();
00148 grasp.model_id_ = db_grasp->scaled_model_id_.get();
00149 grasp.grasp_id_ = db_grasp->id_.get();
00150
00151 tf::Stamped<tf::Pose> base_to_object;
00152
00153 tf::poseStampedMsgToTF(model_.pose,base_to_object);
00154
00155 tf::Pose object_to_grasp;
00156 tf::poseMsgToTF(db_grasp->final_grasp_pose_.get().pose_, object_to_grasp);
00157
00158
00159
00160 grasp.object_pose_ = base_to_object;
00161
00162
00163
00164 tf::Pose base_to_grasp(base_to_object * object_to_grasp);
00165
00166 tf::poseTFToMsg(base_to_grasp,grasp.grasp_.grasp_pose);
00167
00168
00169 double wrist_to_tool_point_offset_ = 0.13;
00170
00171 tf::Pose offset_tf(tf::Matrix3x3::getIdentity(),tf::Vector3(wrist_to_tool_point_offset_,0,0));
00172
00174 grasp.tool_point_pose_ = tf::Stamped<tf::Pose>(base_to_grasp * offset_tf,
00175 grasp.object_pose_.stamp_, grasp.object_pose_.frame_id_);
00176
00177
00178 grasps.push_back(grasp);
00179 }
00180
00181 }
00182 DatabaseGraspRetriever::DatabaseGraspRetriever(ObjectsDatabasePtr database,
00183 const household_objects_database_msgs::DatabaseModelPose &model,
00184 const std::string &arm_name,
00185 bool prune_compliant_copies,
00186 bool use_cluster_rep_grasps) :
00187 GraspRetriever(arm_name),
00188 database_(database), model_(model), prune_compliant_copies_(prune_compliant_copies), use_cluster_rep_grasps_(use_cluster_rep_grasps)
00189 {
00190
00191 }
00192
00193 void DatabaseGraspRetriever::fetchFromDB()
00194 {
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206 std::vector<DatabaseGraspPtr> db_grasps;
00207 int model_id=model_.model_id;
00208
00209 if (use_cluster_rep_grasps_)
00210 {
00211 if (!database_->getClusterRepGrasps(model_id, object_manipulator::handDescription().handDatabaseName(arm_name_), db_grasps))
00212 {
00213 ROS_ERROR("Robust Database Grasp Planning Node: grasp retrieval error");
00214 }
00215 }
00216 else
00217 {
00218 if (!database_->getGrasps(model_id, object_manipulator::handDescription().handDatabaseName(arm_name_), db_grasps))
00219 {
00220 ROS_ERROR("Robust Database Grasp Planning Node: grasp retrieval error");
00221 }
00222 }
00223
00224 ROS_DEBUG("Robust Database Grasp Planning Node: retrieved %zd grasps from database", db_grasps.size());
00225
00226
00227 if (prune_compliant_copies_)
00228 {
00229 std::vector<DatabaseGraspPtr>::iterator it = db_grasps.begin();
00230 while (it!=db_grasps.end())
00231 {
00232 if ((*it)->compliant_copy_.get()) it = db_grasps.erase(it);
00233 else it++;
00234 }
00235 }
00236
00237 appendMetadataToGrasps(db_grasps, grasps_);
00238 }
00239
00240 void DatabaseGraspRetriever::getGrasps(std::vector<GraspWithMetadata> &grasps)
00241 {
00242 grasps.insert(grasps.end(), grasps_.begin(), grasps_.end());
00243 }
00244
00245 ClusterRepGraspRetriever::ClusterRepGraspRetriever(ObjectsDatabasePtr database,
00246 const household_objects_database_msgs::DatabaseModelPose &model,
00247 const std::string &arm_name) :
00248 DatabaseGraspRetriever(database, model, arm_name, true, false)
00249 {
00250
00251
00252 }
00253
00254 void ClusterRepGraspRetriever::fetchFromDB()
00255 {
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268 std::vector<DatabaseGraspPtr> db_grasps;
00269 int model_id=model_.model_id;
00270
00271 if (!database_->getClusterRepGrasps(model_id,
00272 object_manipulator::handDescription().handDatabaseName(arm_name_), db_grasps))
00273 {
00274 ROS_ERROR("Robust Database Grasp Planning Node: grasp retrieval error");
00275 }
00276
00277 ROS_WARN("Size from DB: %zd",db_grasps.size());
00278
00279 ROS_DEBUG("Robust Database Grasp Planning Node: retrieved %zd grasps from database", db_grasps.size());
00280
00281
00282 ROS_WARN("Size after pruning: %zd",db_grasps.size());
00283 ROS_WARN("Size before appending: %zd",grasps_.size());
00284 appendMetadataToGrasps(db_grasps, grasps_);
00285
00286 ROS_WARN("Size after appending: %zd",grasps_.size());
00287 }
00288
00289 void ClusterRepGraspRetriever::getGrasps(std::vector<GraspWithMetadata> &grasps)
00290 {
00291 grasps.insert(grasps.end(), grasps_.begin(), grasps_.end());
00292 }
00293
00297 void DebugClusterRepGraspRetriever::getGrasps(std::vector<GraspWithMetadata> &grasps)
00298 {
00299 std::vector<GraspWithMetadata>::iterator begin_plus_five(grasps_.begin());
00300 std::advance(begin_plus_five, 5);
00301 grasps.insert(grasps.end(), grasps_.begin(), begin_plus_five);
00302 }
00303
00304 PerturbationGraspRetriever::PerturbationGraspRetriever(ObjectsDatabasePtr database,
00305 const household_objects_database_msgs::DatabaseModelPose &model,
00306 const std::string &arm_name) :
00307 DatabaseGraspRetriever(database, model, arm_name, false, true), gstar_(NULL)
00308 {
00309 ROS_DEBUG("Created new perturbation grasp retriever for model_id %d",model.model_id);
00310 fetchFromDB();
00311 }
00312
00313 void PerturbationGraspRetriever::fetchFromDB()
00314 {
00315 std::vector<DatabasePerturbationPtr> perturbations;
00316 database_->getAllPerturbationsForModel(model_.model_id, perturbations);
00317
00318 ROS_DEBUG("Retrieved %zd perturbations of grasps for model %d from the DB", perturbations.size(), model_.model_id);
00319
00320 perturbations_.insert(perturbations_.begin(), perturbations.begin(), perturbations.end());
00321 }
00322
00323 void PerturbationGraspRetriever::getGrasps(std::vector<GraspWithMetadata> &grasps)
00324 {
00325 if (gstar_ == NULL)
00326 {
00327 ROS_ERROR("Requested perturbations for a grasp, but grasp is not set.");
00328 return;
00329 }
00330
00332 grasps.reserve(grasps.size()+250);
00333 BOOST_FOREACH(DatabasePerturbationPtr &perturbation, perturbations_)
00334 {
00335 int grasp_id = perturbation->grasp_id_.get();
00336 if (grasp_id == gstar_->grasp_id_)
00337 {
00339 GraspWithMetadata grasp_with_metadata;
00340 grasp_with_metadata.model_id_ = model_.model_id;
00341 grasp_with_metadata.grasp_id_ = grasp_id;
00342 grasp_with_metadata.energy_function_score_ = perturbation->score_.get();
00343 grasp_with_metadata.object_pose_ = gstar_->object_pose_;
00344
00345 object_manipulation_msgs::Grasp grasp;
00346
00347
00349
00350 std::vector<double> deltas = perturbation->deltas_.get();
00351
00352 grasps.push_back(grasp_with_metadata);
00353 }
00354 }
00355 }
00356
00357 ClusterPlannerGraspRetriever::ClusterPlannerGraspRetriever(ros::NodeHandle &nh, const std::string &cluster_planner_name,
00358 const object_manipulation_msgs::GraspableObject &graspable_object,
00359 const std::string &arm_name) :
00360 GraspRetriever(arm_name)
00361 {
00362
00363 cluster_planner_srv_ = register_service<object_manipulation_msgs::GraspPlanning>(nh, cluster_planner_name);
00364 cloud_ = graspable_object.cluster;
00365 fetchFromPlanner(graspable_object);
00366 }
00367
00368 void ClusterPlannerGraspRetriever::fetchFromPlanner(const object_manipulation_msgs::GraspableObject &graspable_object)
00369 {
00370 object_manipulation_msgs::GraspPlanning planner_call;
00373 planner_call.request.target = graspable_object;
00374 planner_call.request.arm_name = arm_name_;
00375 cluster_planner_srv_.call(planner_call);
00376 if (planner_call.response.error_code.value != object_manipulation_msgs::GraspPlanningErrorCode::SUCCESS)
00377 {
00378 ROS_ERROR("Call to cluster planner failed!");
00379 }
00380 grasps_from_cluster_planner_ = planner_call.response.grasps;
00381 ROS_INFO("Got %zd grasps from the cluster planner",grasps_from_cluster_planner_.size());
00382 }
00383
00384 void ClusterPlannerGraspRetriever::getGrasps(std::vector<GraspWithMetadata> &grasps)
00385 {
00386
00388 appendGraspsFromClusterPlanner(grasps);
00389 }
00390
00391 void ClusterPlannerGraspRetriever::appendGraspsFromClusterPlanner(std::vector<GraspWithMetadata> &grasps)
00392 {
00393 grasps.reserve(grasps.size()+grasps_from_cluster_planner_.size());
00394
00395
00396 BOOST_FOREACH(object_manipulation_msgs::Grasp &grasp, grasps_from_cluster_planner_)
00397 {
00398 GraspWithMetadata grasp_with_metadata;
00399 grasp_with_metadata.grasp_ = grasp;
00400
00401 grasp_with_metadata.model_id_ = -1;
00402 grasp_with_metadata.grasp_id_ = -1;
00403
00404 grasp_with_metadata.object_pose_.setIdentity();
00405 grasp_with_metadata.object_pose_.frame_id_ = cloud_.header.frame_id;
00406 grasp_with_metadata.object_pose_.stamp_ = cloud_.header.stamp;
00407
00408 tf::Pose grasp_in_base_frame;
00409 tf::poseMsgToTF(grasp.grasp_pose, grasp_in_base_frame);
00410
00411
00412
00413 tf::poseTFToMsg(grasp_in_base_frame,grasp_with_metadata.grasp_.grasp_pose);
00414
00415 double wrist_to_tool_point_offset_ = 0.13;
00416
00417 tf::Pose grasp_to_tool_point(tf::Matrix3x3::getIdentity(),tf::Vector3(wrist_to_tool_point_offset_,0,0));
00418
00420 grasp_with_metadata.tool_point_pose_ = tf::Stamped<tf::Pose>(
00421 grasp_in_base_frame * grasp_to_tool_point, cloud_.header.stamp,
00422 cloud_.header.frame_id);
00423
00424
00425 grasps.push_back(grasp_with_metadata);
00426 }
00427 }
00428
00429
00430 }