GraspItServices.cpp
Go to the documentation of this file.
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 //    PRINTMSG("Accepting add to database: "<<req);
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 //    PRINTMSG("Accepting to load model: "<<req);
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 //    PRINTMSG("Accepting to save world: "<<req);
00226 
00227     const std::string inv = req.asInventor ? std::string(" as inventor") : std::string(" as graspit world");
00228 
00229     bool createDir = false;  // for safety, we'll keep the directory writing option disabled
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     // TODO: we can improve on this by picking the right values by joint names
00265     // and still return a valid grasp.
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; // use the same state, so the rest of the code doesn't crash
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     // not setting graspJS.header for the moment. Joint positions don't really need a reference
00288     // frame and we don't care about the timing...
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     // TODO here we could compute a better quality value, and it depends on whether we have used
00303     // other algorithms than simulated annealing also... for now, return the simulated annealing
00304     // energy
00305     g.grasp_quality = egResult.getEnergy();
00306 
00307     // Approach and retreat not supported yet
00308     // g.approach=
00309     // g.retreat=
00310 
00311     // Max contact force disabled as not supported yet
00312     g.max_contact_force = -1;
00313 
00314     // Allowed touch objects not supported yet
00315     // g.allowed_touch_objects =
00316     return g;
00317 }
00318 
00319 bool GraspItServices::acceptEGPlanning(moveit_msgs::GraspPlanning::Request &req,
00320                                        moveit_msgs::GraspPlanning::Response &res)
00321 {
00322 //    PRINTMSG("Accepting to plan grasp: "<<req);
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     // get the model ID for the robot and the name for the object
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     // TODO Should support string IDs for the database too at some point.
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     // Make sure we can get the robots joint names which we will need for the results
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     // If the reference frame is "0", use the object's current pose in the world.
00384     // Otherwise, change the model pose before planning.
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     // TODO in future we should provide options to change the planner type,
00394     // but at the moment only simulated annealing is supported
00395     EigenGraspPlanner::PlannerType planType = EigenGraspPlanner::SimAnn;
00396 
00397     // Would be nice to have a parameter in service request, bug GraspPlanning.srv
00398     // does not have this at the moment, so use default max planning steps.
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         // PRINTMSG(*it);
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 }


grasp_planning_graspit_ros
Author(s): Jennifer Buehler
autogenerated on Wed May 8 2019 02:53:42