00001
00021 #include <grasp_planning_graspit_ros/GraspItServices.h>
00022
00023 #include <grasp_planning_graspit/GraspItSceneManagerHeadless.h>
00024 #include <grasp_planning_graspit/LogBinding.h>
00025 #include <grasp_planning_graspit/GraspItSimpleDBManager.h>
00026
00027 #include <grasp_planning_graspit/EigenGraspPlanner.h>
00028 #include <grasp_planning_graspit/EigenGraspResult.h>
00029 #include <grasp_planning_graspit/SharedPtr.h>
00030
00031 #include <eigen_conversions/eigen_msg.h>
00032
00033 #include <string>
00034 #include <algorithm>
00035 #include <vector>
00036
00037 using GraspIt::GraspItServices;
00038 using GraspIt::GraspItSceneManager;
00039 using GraspIt::GraspItSimpleDBManager;
00040 using GraspIt::EigenGraspPlanner;
00041
00042 #define DEFAULT_DB_NAME "DefaultDatabaseName"
00043 #define DEFAULT_EGPLANNER_NAME "graspitEGPlanner"
00044
00045 #define DEFAULT_ADD_DB_TOPIC "graspit_add_to_db"
00046 #define DEFAULT_LOAD_MODEL_TOPIC "graspit_add_to_db"
00047 #define DEFAULT_SAVE_WORLD_TOPIC "graspit_save_world"
00048 #define DEFAULT_EGPLANNING_TOPIC "graspit_eg_planning"
00049 #define DEFAULT_MAX_EGPLANNING_STEPS 70000
00050 #define DEFAULT_NUM_REPEAT_PLANNING 1
00051 #define DEFAULT_GRASP_MSG_POSITION_FACTOR 0.001
00052 #define DEFAULT_NUM_KEEP_RESULTS 3
00053 #define DEFAULT_FINISH_WITH_AUTOGRASP false
00054 #define DEFAULT_OUTPUT_DIRECTORY ""
00055 #define DEFAULT_SAVE_RESULT_FILES false
00056 #define DEFAULT_NEGATE_JOINT_DOFS true
00057
00058 GraspItServices::GraspItServices():
00059 priv("~"),
00060 pub(""),
00061 negateJointDOFs(DEFAULT_NEGATE_JOINT_DOFS)
00062 {
00063 init();
00064 }
00065
00066
00067
00068 GraspItServices::~GraspItServices()
00069 {
00070 PRINTMSG("Deleting GraspItServices");
00071 }
00072
00073 void GraspItServices::init()
00074 {
00075 readParams();
00076
00077 PRINTMSG("Creating graspit interface and database");
00078
00079 graspitMgr = SHARED_PTR<GraspItSceneManager>(new GraspItSceneManagerHeadless());
00080
00081 mgr = SHARED_PTR<GraspItSimpleDBManager>(new GraspItSimpleDBManager(dbName, graspitMgr));
00082 egPlanner = SHARED_PTR<EigenGraspPlanner>(new EigenGraspPlanner(egPlannerName, graspitMgr));
00083 }
00084
00085 void GraspItServices::readParams()
00086 {
00087 priv.param<std::string>("database_name", dbName, DEFAULT_DB_NAME);
00088 PRINTMSG("Using database name: " << dbName);
00089 priv.param<std::string>("eg_planner_name", egPlannerName, DEFAULT_EGPLANNER_NAME);
00090 PRINTMSG("Using eg planner name: " << egPlannerName);
00091 priv.param<std::string>("add_to_db_topic", addToDBTopic, DEFAULT_ADD_DB_TOPIC);
00092 PRINTMSG("Using add_to_db_topic: " << addToDBTopic);
00093 priv.param<std::string>("load_model_topic", loadModelTopic, DEFAULT_LOAD_MODEL_TOPIC);
00094 PRINTMSG("Using load_model_topic: " << loadModelTopic);
00095 priv.param<std::string>("save_world_topic", saveWorldTopic, DEFAULT_SAVE_WORLD_TOPIC);
00096 PRINTMSG("Using save_world_topic: " << saveWorldTopic);
00097 priv.param<std::string>("eg_planning_topic", egPlanningTopic, DEFAULT_EGPLANNING_TOPIC);
00098 PRINTMSG("Using eg_planning_topic: " << egPlanningTopic);
00099 priv.param<int>("default_max_planning_steps", defaultMaxPlanningSteps, DEFAULT_MAX_EGPLANNING_STEPS);
00100 PRINTMSG("Using default max number of planning steps: " << defaultMaxPlanningSteps);
00101 priv.param<int>("default_num_repeat_planning", defaultNumRepeatPlanning, DEFAULT_NUM_REPEAT_PLANNING);
00102 PRINTMSG("Using default number of planning repeats: " << defaultNumRepeatPlanning);
00103 priv.param<float>("grasp_msg_position_factor", graspMsgPositionFactor, DEFAULT_GRASP_MSG_POSITION_FACTOR);
00104 PRINTMSG("Using default factor for position values: " << graspMsgPositionFactor);
00105 priv.param<int>("default_num_keep_results", defaultNumKeepResults, DEFAULT_NUM_KEEP_RESULTS);
00106 PRINTMSG("Using default number of results kept: " << defaultNumKeepResults);
00107 priv.param<bool>("default_finish_with_autograsp", defaultFinishWithAutograsp, DEFAULT_FINISH_WITH_AUTOGRASP);
00108 PRINTMSG("Finish with auto-grasp by default: " << defaultFinishWithAutograsp);
00109 priv.param<bool>("save_result_files_inventor", saveResultFilesInventor, DEFAULT_SAVE_RESULT_FILES);
00110 PRINTMSG("Save result files inventor: " << saveResultFilesInventor);
00111 priv.param<bool>("save_result_files_graspit", saveResultFilesGraspit, DEFAULT_SAVE_RESULT_FILES);
00112 PRINTMSG("Save result files graspit: " << saveResultFilesGraspit);
00113 priv.param<std::string>("results_output_directory", resultsOutputDirectory, DEFAULT_OUTPUT_DIRECTORY);
00114 PRINTMSG("Results output directory: " << resultsOutputDirectory);
00115 }
00116
00117
00118 void GraspItServices::start()
00119 {
00120 addGraspitFileSrv = pub.advertiseService(addToDBTopic, &GraspItServices::acceptAddToDB, this);
00121 loadGraspitModelSrv = pub.advertiseService(loadModelTopic, &GraspItServices::acceptLoadModel, this);
00122 saveWorldSrv = pub.advertiseService(saveWorldTopic, &GraspItServices::acceptSaveWorld, this);
00123 egPlanningSrv = pub.advertiseService(egPlanningTopic, &GraspItServices::acceptEGPlanning, this);
00124
00125 PRINTMSG("Ready to accept planning messages");
00126 }
00127
00128 bool GraspItServices::acceptAddToDB(grasp_planning_graspit_msgs::AddToDatabase::Request &req,
00129 grasp_planning_graspit_msgs::AddToDatabase::Response &res)
00130 {
00131
00132
00133 int modelID = -1;
00134 int ret = -1;
00135 if (req.isRobot)
00136 {
00137 if ((ret = mgr->loadRobotToDatabase(req.filename, req.modelName, req.jointNames)) < 0)
00138 {
00139 PRINTERROR("Could not load robot " << req.modelName << " from file "
00140 << req.filename << ". Error code: " << ret);
00141 }
00142 else
00143 {
00144 PRINTMSG("Added robot " << req.modelName << " from file " << req.filename);
00145 modelID = ret;
00146 }
00147 }
00148 else
00149 {
00150 if ((ret = mgr->loadObjectToDatabase(req.filename, req.modelName, req.asGraspable)) < 0)
00151 {
00152 PRINTERROR("Could not load object " << req.modelName << " from file "
00153 << req.filename << ". Error code: " << ret);
00154 }
00155 else
00156 {
00157 modelID = ret;
00158 PRINTMSG("Added object " << req.modelName << " from file " << req.filename << " and got ID=" << modelID);
00159 }
00160 }
00161
00162 if (ret >= 0) res.returnCode = grasp_planning_graspit_msgs::AddToDatabase::Response::SUCCESS;
00163 else if (ret == -2) res.returnCode = grasp_planning_graspit_msgs::AddToDatabase::Response::NOT_READY;
00164 else if (ret == -3) res.returnCode = grasp_planning_graspit_msgs::AddToDatabase::Response::FILE_NOT_FOUND;
00165 else if (ret == -4) res.returnCode = grasp_planning_graspit_msgs::AddToDatabase::Response::MODEL_EXISTS;
00166 else if (ret == -5) res.returnCode = grasp_planning_graspit_msgs::AddToDatabase::Response::NO_NAME;
00167 else res.returnCode = grasp_planning_graspit_msgs::AddToDatabase::Response::OTHER_ERROR;
00168
00169 res.modelID = modelID;
00170
00171 return true;
00172 }
00173
00174
00175
00176 bool GraspItServices::acceptLoadModel(grasp_planning_graspit_msgs::LoadDatabaseModel::Request &req,
00177 grasp_planning_graspit_msgs::LoadDatabaseModel::Response &res)
00178 {
00179
00180
00181 int modelID = req.model_id;
00182 geometry_msgs::Pose modelPose = req.model_pose;
00183 bool clearOthers = req.clear_other_models;
00184
00185 GraspIt::EigenTransform transform;
00186 tf::poseMsgToEigen(modelPose, transform);
00187
00188 if (clearOthers)
00189 {
00190 PRINTMSG("Clearing other bodies before loading!");
00191 std::vector<int> ids;
00192 mgr->getAllLoadedRobotIDs(ids);
00193 mgr->getAllLoadedObjectIDs(ids);
00194 std::vector<int>::iterator it;
00195 for (it = ids.begin(); it != ids.end(); ++it)
00196 {
00197 int ret = mgr->unloadFromWorld(*it);
00198 if (ret != 0)
00199 {
00200 PRINTERROR("Could not unload model " << *it << " from world.");
00201 res.result = grasp_planning_graspit_msgs::LoadDatabaseModel::Response::LOAD_FAILURE;
00202 return true;
00203 }
00204 }
00205 }
00206
00207 int ret = mgr->loadToWorld(modelID, transform);
00208
00209 if (ret == 0)
00210 {
00211 PRINTMSG("Successfully loaded model " << modelID << " to the world.");
00212 res.result = grasp_planning_graspit_msgs::LoadDatabaseModel::Response::LOAD_SUCCESS;
00213 }
00214 else
00215 {
00216 PRINTERROR("Could not load model " << modelID << " to the world. Error code " << ret);
00217 res.result = grasp_planning_graspit_msgs::LoadDatabaseModel::Response::LOAD_FAILURE;
00218 }
00219 return true;
00220 }
00221
00222 bool GraspItServices::acceptSaveWorld(grasp_planning_graspit_msgs::SaveWorld::Request &req,
00223 grasp_planning_graspit_msgs::SaveWorld::Response &res)
00224 {
00225
00226
00227 const std::string inv = req.asInventor ? std::string(" as inventor") : std::string(" as graspit world");
00228
00229 bool createDir = false;
00230 if (!mgr->saveLoadedWorld(req.filename, req.asInventor, createDir))
00231 {
00232 PRINTMSG("Could not save loaded world in file " << req.filename << inv);
00233 res.success = false;
00234 }
00235 else
00236 {
00237 PRINTMSG("Saved loaded world in file " << req.filename << inv);
00238 res.success = true;
00239 }
00240
00241 return true;
00242 }
00243
00244
00245 moveit_msgs::Grasp GraspItServices::getGraspMsg(const EigenGraspResult& egResult, const std::string& id,
00246 const std::vector<std::string>& robotJointNames, const std::string& objectFrame) const
00247 {
00248 moveit_msgs::Grasp g;
00249 g.id = id;
00250
00251 trajectory_msgs::JointTrajectory preJS;
00252 trajectory_msgs::JointTrajectory graspJS;
00253 preJS.points.push_back(trajectory_msgs::JointTrajectoryPoint());
00254 graspJS.points.push_back(trajectory_msgs::JointTrajectoryPoint());
00255 trajectory_msgs::JointTrajectoryPoint &preJSPoint = preJS.points.front();
00256 trajectory_msgs::JointTrajectoryPoint &graspJSPoint = graspJS.points.front();
00257 graspJS.joint_names = robotJointNames;
00258 preJS.joint_names = robotJointNames;
00259 std::vector<double> graspDOFs = egResult.getGraspJointDOFs();
00260 std::vector<double> pregraspDOFs = egResult.getPregraspJointDOFs();
00261
00262 int nJoints = std::min(graspDOFs.size(), robotJointNames.size());
00263
00264
00265
00266 if (graspDOFs.size() != robotJointNames.size())
00267 {
00268 PRINTERROR("Number of DOFs for the robot is not equal to number of joint names.");
00269 PRINTERROR("Therefore will only write the first " << nJoints
00270 << " joint values. There is likely to be undefined behaviour.");
00271 }
00272 if (graspDOFs.size() != pregraspDOFs.size())
00273 {
00274 PRINTERROR("Inconsistency: the number of joints in grasp should be equal to pre-grasp");
00275 pregraspDOFs=graspDOFs;
00276 }
00277
00278 graspJSPoint.positions.resize(nJoints, 0);
00279 preJSPoint.positions.resize(nJoints, 0);
00280 for (int i = 0; i < nJoints; ++i)
00281 {
00282 int mult = 1;
00283 if (negateJointDOFs) mult = -1;
00284 graspJSPoint.positions[i] = mult * graspDOFs[i];
00285 preJSPoint.positions[i] = mult * pregraspDOFs[i];
00286 }
00287
00288
00289
00290 EigenTransform oToHand = egResult.getObjectToHandTransform();
00291 geometry_msgs::PoseStamped graspPose;
00292 tf::poseEigenToMsg(oToHand, graspPose.pose);
00293 graspPose.header.frame_id = objectFrame;
00294 graspPose.pose.position.x *= graspMsgPositionFactor;
00295 graspPose.pose.position.y *= graspMsgPositionFactor;
00296 graspPose.pose.position.z *= graspMsgPositionFactor;
00297
00298 g.pre_grasp_posture = preJS;
00299 g.grasp_posture = graspJS;
00300 g.grasp_pose = graspPose;
00301
00302
00303
00304
00305 g.grasp_quality = egResult.getEnergy();
00306
00307
00308
00309
00310
00311
00312 g.max_contact_force = -1;
00313
00314
00315
00316 return g;
00317 }
00318
00319 bool GraspItServices::acceptEGPlanning(moveit_msgs::GraspPlanning::Request &req,
00320 moveit_msgs::GraspPlanning::Response &res)
00321 {
00322
00323 const moveit_msgs::CollisionObject &objToGrasp = req.target;
00324 geometry_msgs::PoseStamped objToGraspPose;
00325 if (objToGrasp.primitive_poses.empty())
00326 {
00327 PRINTERROR("Cannot get a pose of the object to grasp, this is expected "
00328 << "as the first primitive pose in moveit_msgs::CollisionObj. "
00329 << "See also issue #40.");
00330 }
00331 else
00332 {
00333 objToGraspPose.pose = objToGrasp.primitive_poses.front();
00334 objToGraspPose.header = objToGrasp.header;
00335 }
00336
00337 if (objToGrasp.primitive_poses.size() != 1)
00338 {
00339 PRINTERROR("The primitive poses in moveit_msgs::CollisionObj are expected"
00340 << " to be of size 1. This is only a temporary hack, but you may get "
00341 << "unexpected results because of this. See also issue #40.");
00342 }
00343
00344
00345
00346 std::string& robotName = req.group_name;
00347 int robModelID = -1;
00348 if (!mgr->getRobotModelID(robotName, robModelID))
00349 {
00350 PRINTERROR("Could not get database ID for robot " << robotName);
00351 res.error_code.val = moveit_msgs::MoveItErrorCodes::FAILURE;
00352 return true;
00353 }
00354 std::string objectName;
00355 bool isRobot;
00356
00357 int objIntID = atoi(objToGrasp.id.c_str());
00358 ROS_INFO_STREAM("Integer ID of object " << objToGrasp.id << " is " << objIntID);
00359 if (!mgr->getModelNameAndType(objIntID, objectName, isRobot) || isRobot)
00360 {
00361 if (isRobot)
00362 {
00363 PRINTERROR("Model " << objToGrasp.id << " is a robot, not an object");
00364 }
00365 else
00366 {
00367 PRINTERROR("Could not get name for object model " << objToGrasp.id);
00368 }
00369 res.error_code.val = moveit_msgs::MoveItErrorCodes::FAILURE;
00370 return true;
00371 }
00372
00373
00374 std::vector<std::string> jointNames;
00375 if (!mgr->getRobotJointNames(robotName, jointNames) || jointNames.empty())
00376 {
00377 PRINTERROR("Could not get robot joint names, this is required for planning.");
00378 res.error_code.val = moveit_msgs::MoveItErrorCodes::FAILURE;
00379 return true;
00380 }
00381
00382 SHARED_PTR<GraspIt::EigenTransform> objTransform;
00383
00384
00385 if (objToGraspPose.header.frame_id == "1")
00386 {
00387 PRINTMSG("Changing transform of the object:");
00388 PRINTMSG(objToGraspPose.pose);
00389 objTransform = SHARED_PTR<GraspIt::EigenTransform>(new GraspIt::EigenTransform());
00390 tf::poseMsgToEigen(objToGraspPose.pose, *objTransform);
00391 }
00392
00393
00394
00395 EigenGraspPlanner::PlannerType planType = EigenGraspPlanner::SimAnn;
00396
00397
00398
00399 int maxPlanningSteps = defaultMaxPlanningSteps;
00400
00401 PRINTMSG("Now starting the planning process...");
00402 if (!egPlanner->plan(robotName, objectName, objTransform.get(), maxPlanningSteps,
00403 defaultNumRepeatPlanning, defaultNumKeepResults, defaultFinishWithAutograsp))
00404 {
00405 PRINTERROR("Could not plan.");
00406 res.error_code.val = moveit_msgs::MoveItErrorCodes::FAILURE;
00407 return true;
00408 }
00409
00410 if (saveResultFilesInventor || saveResultFilesGraspit)
00411 {
00412 PRINTMSG("Saving result world files in " << resultsOutputDirectory);
00413 std::stringstream filenamePrefix;
00414 filenamePrefix << robotName << "_" << objectName;
00415 egPlanner->saveResultsAsWorldFiles(resultsOutputDirectory, filenamePrefix.str(),
00416 saveResultFilesGraspit, saveResultFilesInventor);
00417 }
00418
00419 std::vector<GraspIt::EigenGraspResult> allGrasps;
00420 egPlanner->getResults(allGrasps);
00421
00422 PRINTMSG("Generating result grasp messages...");
00423 int i = 0;
00424 std::vector<GraspIt::EigenGraspResult>::iterator it;
00425 for (it = allGrasps.begin(); it != allGrasps.end(); ++it)
00426 {
00427
00428 std::stringstream id;
00429 id << robotName << "_" << objectName << "_" << i;
00430 moveit_msgs::Grasp g = getGraspMsg(*it, id.str(), jointNames,
00431 objToGraspPose.header.frame_id);
00432 res.grasps.push_back(g);
00433 ++i;
00434 }
00435
00436 PRINTMSG("Planning done.");
00437 res.error_code.val = moveit_msgs::MoveItErrorCodes::SUCCESS;
00438 return true;
00439 }