Urdf2Graspit.cpp
Go to the documentation of this file.
00001 
00019 #include <baselib_binding/SharedPtr.h> 
00020 
00021 #include <urdf_traverser/ActiveJoints.h>
00022 #include <urdf_traverser/DependencyOrderedJoints.h>
00023 #include <urdf_traverser/Functions.h>
00024 
00025 #include <urdf2inventor/Helpers.h>
00026 #include <urdf2graspit/Types.h>
00027 #include <urdf2graspit/Urdf2Graspit.h>
00028 #include <urdf2graspit/XMLFuncs.h>
00029 
00030 #include <urdf2graspit/ConvertGraspitMesh.h>
00031 
00032 #include <string>
00033 #include <ros/ros.h>
00034 #include <ros/package.h>
00035 
00036 #include <map>
00037 #include <vector>
00038 #include <set>
00039 
00040 #define RAD_TO_DEG 180/M_PI
00041 
00042 using urdf2graspit::Urdf2GraspIt;
00043 using urdf2graspit::xmlfuncs::FingerChain;
00044 
00045 bool Urdf2GraspIt::getXML(const std::vector<DHParam>& dhparams,
00046                           const std::vector<std::string>& rootFingerJoints,
00047                           const std::string& palmLinkName,
00048                           const std::string * eigenXML,
00049                           const std::string * contactsVGR,
00050                           const std::string& mesh_pathprepend, std::string& result)
00051 {
00052     UrdfTraverserPtr trav = getTraverser();
00053     if (!trav)
00054     {
00055         ROS_ERROR("Traverser must be set");
00056         return false;
00057     }
00058     LinkPtr from_link = trav->getLink(palmLinkName);
00059     if (!from_link)
00060     {
00061         ROS_ERROR_STREAM("Could not find palm link "<<palmLinkName);
00062         return false;
00063     }
00064 
00065     if (urdf_traverser::hasFixedJoints(*trav, palmLinkName))
00066     {
00067         ROS_ERROR_STREAM("Only URDF formats without fixed joints supported. "
00068                          << "You can remove fixed joints with function joinFixedLinks()");
00069         return false;
00070     }
00071 
00072     std::stringstream str;
00073 
00074     str << "<?xml version=\"1.0\" ?>" << std::endl;
00075     str << "<robot type=\"Hand\">" << std::endl;
00076     str << "\t<palm>" << palmLinkName << ".xml</palm>" << std::endl;
00077 
00078     float def_kp = 1e+9;
00079     float def_kd = 1e+7;
00080 
00081     for (std::vector<DHParam>::const_iterator it = dhparams.begin(); it != dhparams.end(); ++it)
00082     {
00083         // ROS_INFO_STREAM("PRM Joint: "<<*it);
00084         float minValue, maxValue;
00085         getLimits(*(it->joint), minValue, maxValue);
00086         float draggerScale = 20; // fabs(maxValue - minValue);
00087         float velocity, effort;
00088         getJointMoves(*(it->joint), velocity, effort);
00089         str << urdf2graspit::xmlfuncs::getDOF(velocity, effort, def_kp, def_kd, draggerScale, "r") << std::endl;
00090     }
00091     // now, pick out the dhparam's for each chain
00092     for (std::vector<std::string>::const_iterator it = rootFingerJoints.begin(); it != rootFingerJoints.end(); ++it)
00093     {
00094         // ROS_INFO("Handling root finger %s",it->c_str());
00095         JointPtr joint = trav->getJoint(*it);
00096         if (!joint)
00097         {
00098             ROS_ERROR("Could not find joint %s", it->c_str());
00099             return false;
00100         }
00101         std::vector<JointPtr> chain;
00102         bool onlyActive = false;
00103         if (!urdf_traverser::getDependencyOrderedJoints(*trav, chain, joint, false, onlyActive) || chain.empty())
00104         {
00105             ROS_ERROR("Could not get joint chain, joint %s", joint->name.c_str());
00106             return false;
00107         }
00108         // ROS_INFO("---root finger joint %s",joint->name.c_str());
00109         // keep only those DHParams
00110         std::vector<DHParam> chain_dhparams;
00111         std::vector<std::string> linkFileNames;
00112         std::vector<std::string> jointTypes;
00113         for (std::vector<JointPtr>::iterator cit = chain.begin(); cit != chain.end(); ++cit)
00114         {
00115             // ROS_INFO("Chain joint %s",(*cit)->name.c_str());
00116             for (std::vector<DHParam>::const_iterator prit = dhparams.begin(); prit != dhparams.end(); ++prit)
00117             {
00118                 // ROS_INFO("DHJoint %s",prit->joint->name.c_str());
00119                 if ((*cit)->name == prit->joint->name)
00120                 {
00121                     // ROS_INFO("Keep param for joint %s",prit->joint->name.c_str());
00122 
00123                     chain_dhparams.push_back(*prit);
00124                     std::stringstream linkfilename;
00125                     linkfilename << mesh_pathprepend << prit->joint->child_link_name << ".xml";
00126                     linkFileNames.push_back(linkfilename.str());
00127                     if (prit->joint->type == urdf::Joint::REVOLUTE) jointTypes.push_back("Revolute");
00128                     else if (prit->joint->type == urdf::Joint::CONTINUOUS) jointTypes.push_back("Revolute");
00129                     else if (prit->joint->type == urdf::Joint::PRISMATIC) jointTypes.push_back("Prismatic");
00130                     else if (prit->joint->type == urdf::Joint::FIXED) jointTypes.push_back("Fixed");
00131                     else
00132                     {
00133                         ROS_ERROR_STREAM("Link type " << prit->joint->type << " not supported");
00134                         return false;
00135                     }
00136                     break;
00137                 }
00138             }
00139         }
00140         // ROS_INFO("Getting transform for joint %s (starting from %s)",joint->name.c_str(),from_link->name.c_str());
00141         EigenTransform m = getTransform(from_link, joint);
00142 
00143         // the joint's rotation axis must be z!
00144         Eigen::Vector3d rotAxis(joint->axis.x, joint->axis.y, joint->axis.z);
00145         Eigen::Vector3d z(0, 0, 1);
00146         if (std::fabs(acos(rotAxis.dot(z))) > 1e-03)
00147         {
00148             ROS_ERROR("Only z-axis rotation is supported, transform the URDF model before!");
00149             return false;
00150         }
00151         Eigen::Vector3d palmTranslation = m.translation();
00152         Eigen::Quaterniond palmRotation(m.rotation());
00153 
00154         // ROS_INFO_STREAM("Palm rotation: "<<palmRotation);
00155         std::string chainStr = getFingerChain(FingerChain(chain_dhparams, linkFileNames, jointTypes),
00156                                               palmTranslation, palmRotation, negateJointMoves);
00157         str << chainStr;
00158     }
00159 
00160     if (eigenXML) str << "\t<eigenGrasps>" << *eigenXML << "</eigenGrasps>" << std::endl;
00161     if (contactsVGR) str << "\t<virtualContacts>" << *contactsVGR << "</virtualContacts>" << std::endl;
00162 
00163     str << "</robot>" << std::endl;
00164 
00165     result = str.str();
00166     return true;
00167 }
00168 
00169 
00170 void Urdf2GraspIt::toGlobalCoordinates(const EigenTransform& transform,
00171                                        const Eigen::Vector3d& input, Eigen::Vector3d& output)
00172 {
00173     EigenTransform wtInv = transform.inverse();
00174     Eigen::Vector3d res = wtInv * input;    // transform the rotation axis in world coordinate frame
00175     //  ROS_INFO_STREAM("inverse transform: "<<wtInv<<" applied to "<<input<<" = "<<res);
00176     output = res;
00177 }
00178 
00179 
00180 void Urdf2GraspIt::getGlobalCoordinates(const JointConstPtr& joint,
00181                                         const EigenTransform& parentWorldTransform,
00182                                         Eigen::Vector3d& rotationAxis,
00183                                         Eigen::Vector3d& position) const
00184 {
00185     Eigen::Vector3d rotAxis = urdf_traverser::getRotationAxis(joint);
00186     // ROS_INFO_STREAM("Orig rotation axis of joint "<<joint->name<<": "<<rotAxis);
00187     EigenTransform jointTransform = urdf_traverser::getTransform(joint);
00188     EigenTransform jointWorldTransform = parentWorldTransform * jointTransform;
00189     // ROS_INFO_STREAM("Joint transform: "<<jointTransform);
00190     // ROS_INFO_STREAM("Joint world transform: "<<jointWorldTransform);
00191 
00192     // transform the rotation axis in world coordinate frame
00193     rotationAxis = jointWorldTransform.rotation() * rotAxis;
00194 
00195     // ROS_INFO_STREAM("Transformed rotation axis of joint "<<joint->name<<": "<<rotationAxis);
00196     // rotationAxis.normalize();
00197     if ((rotationAxis.norm()-1.0) > 1e-03)
00198     {
00199         ROS_ERROR_STREAM("getGlobalCoordinates: rotation axis is not uniform any more. "<<rotationAxis);
00200     }
00201     
00202     position = jointWorldTransform.translation();
00203 }
00204 
00205 bool Urdf2GraspIt::getDHParams(std::vector<DHParam>& dhparameters,
00206                                const JointConstPtr& joint,
00207                                const EigenTransform& parentWorldTransform,
00208                                const Eigen::Vector3d& parentX,
00209                                const Eigen::Vector3d& parentZ,
00210                                const Eigen::Vector3d& parentPos,
00211                                bool asRootJoint,
00212                                EigenTransform& parentWorldTransformDH) const
00213 {
00214     ROS_INFO_STREAM("======== Transforming joint " << joint->name << " to DH parameters.");
00215     // ROS_INFO_STREAM("       Parent axes: " << parentX << ", "<<parentZ<<", position "<<parentPos);
00216 
00217     UrdfTraverserConstPtr trav = readTraverser();
00218     if (!trav)
00219     {
00220         ROS_ERROR("Traverser must be set");
00221         return false;
00222     }
00223 
00224     LinkConstPtr childLink = trav->readLink(joint->child_link_name);
00225     if (!childLink)
00226     {
00227         ROS_ERROR("consistency, no child link");
00228         return false;
00229     }
00230 
00231 //    ROS_INFO_STREAM("Transform is for link "<<childLink->name);
00232 /*    LinkConstPtr parentLink = trav->readLink(joint->parent_link_name);
00233     ROS_INFO_STREAM("Parent is "<<parentLink->name); */
00234 
00235     Eigen::Vector3d z, pos, x;
00236 
00237     EigenTransform jointWorldTransform = EigenTransform::Identity();
00238     EigenTransform jointWorldTransformDH = EigenTransform::Identity();
00239 
00240     if (asRootJoint)
00241     {
00242         // if this is the root joint, we won't consider the joint's
00243         // previous transforms, as we'll set this one to be the origin
00244         jointWorldTransform.setIdentity();
00245         parentWorldTransformDH.setIdentity();
00246 
00247         z = urdf_traverser::getRotationAxis(joint);   // rotation axis is already in world coorinates
00248         // ROS_INFO_STREAM("Rotation axis of joint "<<joint->name<<": "<<z);
00249         pos = Eigen::Vector3d(0, 0, 0);
00250         x = parentX;
00251         // ROS_INFO_STREAM("Axes for root joint "<<joint->name<<": z="<<z<<", x="<<x<<", pos="<<pos);
00252         // ROS_INFO_STREAM("Joint world transform: "<<parentWorldTransform * urdf_traverser::getTransform(joint));
00253     }
00254     else
00255     {
00256         EigenTransform jointTransform = urdf_traverser::getTransform(joint);
00257         jointWorldTransform = parentWorldTransform * jointTransform;
00258         // ROS_INFO_STREAM("Parent world transform: "<<parentWorldTransform);
00259         // ROS_INFO_STREAM("Joint transform: "<<jointTransform);
00260         // ROS_INFO_STREAM("Joint world transform: "<<jointWorldTransform);
00261 
00262         // the global rotation axis of the joint is going to be the
00263         // new global z-axis of the DH joint transform.
00264         // the position is the global position of the joint.
00265         getGlobalCoordinates(joint, parentWorldTransform, z, pos);
00266         // ROS_INFO_STREAM("Global rotation axis of joint "<<joint->name<<": "<<z<<", pos "<<pos);
00267 
00268         DHParam param;
00269         if (!DHParam::toDenavitHartenberg(param, parentZ, parentX, parentPos, z, pos, x))
00270         {
00271             ROS_ERROR("could not obtain dh params");
00272             return false;
00273         }
00274 
00275         // The global pose of the DH joint may be different to the global pose 
00276         // of the URDF joint. Calculate the pose of the DH joint in world coordinates
00277         // and apply it to \e pos, so that the recursion can take this into account.
00278         // ROS_INFO_STREAM("Translating  "<<parentPos<<" ( target: "<<pos<<" ) using transform = "<<parentWorldTransformDH);
00279 
00280         EigenTransform jointTransformDH = EigenTransform::Identity();
00281         Eigen::Vector3d z(0,0,1);
00282         jointTransformDH.translate(z*param.d);
00283         jointTransformDH.rotate(Eigen::AngleAxisd(param.theta,z));
00284         Eigen::Vector3d x(1,0,0); 
00285         jointTransformDH.translate(x*param.r);
00286         jointTransformDH.rotate(Eigen::AngleAxisd(param.alpha,x));
00287 
00288         jointWorldTransformDH = parentWorldTransformDH * jointTransformDH;
00289 
00290         /*ROS_INFO_STREAM("parentWorldTransformDH: "<<jointTransformDH);
00291         ROS_INFO_STREAM("joint transform DH: "<<jointTransformDH);
00292         ROS_INFO_STREAM("joint world transform DH: "<<jointWorldTransformDH);*/
00293 
00294         Eigen::Vector3d pi_new = jointWorldTransformDH.translation();
00295         // ROS_INFO_STREAM("Transformed DH pose: "<<pi_new<<" ( vs URDF space "<<pos<<" )");
00296         pos = pi_new;
00297 
00298         param.dof_index = dhparameters.size();
00299         param.joint = trav->readParentJoint(joint);
00300 
00301         if (!param.joint)
00302         {
00303             ROS_ERROR_STREAM("Consistency: Joint "<<joint->name
00304                 <<" has no parent, should have been added as root joint instead!");
00305             return false;
00306         }
00307         LinkConstPtr paramChildLink = trav->readLink(param.joint->child_link_name);
00308         if (!paramChildLink)
00309         {
00310             ROS_ERROR("consistency, no child link");
00311             return false;
00312         }
00313         param.childLink = paramChildLink;
00314         dhparameters.push_back(param);
00315         // ROS_INFO_STREAM("DH for Joint "<<param.joint->name<<" parent axes: z="<<z<<", x="<<x<<", pos="<<pos<<": "<<param);
00316     }
00317         
00318 
00319     if (childLink->child_joints.empty())
00320     {
00321         // we've come to the end of the chain, so we have to add the parameter for the last frame.
00322         // while r should technically be the link length, we'll just leave this frame at the previous joint's
00323         // frame, as the DH parameters for the last joint don't really matter, they only specify the location
00324         // of a joint that would follow this one.
00325 
00326         DHParam param;
00327         param.dof_index = dhparameters.size();
00328         param.joint = joint;
00329         param.childLink = childLink;
00330 
00331         param.r = 0;
00332         param.d = 0;
00333         param.theta = 0;
00334         param.alpha = 0;
00335 
00336         dhparameters.push_back(param);
00337         // ROS_INFO_STREAM("DH for Joint "<<param.joint->name<<", parent axes: z="<<z<<", x="<<x<<", pos="<<pos<<": "<<param);
00338         return true;
00339     }
00340     
00341 
00342     // recurse to child joints
00343     for (std::vector<JointPtr>::const_iterator pj = childLink->child_joints.begin();
00344             pj != childLink->child_joints.end(); pj++)
00345     {
00346         if (!getDHParams(dhparameters, *pj, jointWorldTransform, x, z,
00347                          pos, false, jointWorldTransformDH)) return false;
00348     }
00349 
00350     return true;
00351 }
00352 
00353 
00354 
00355 bool Urdf2GraspIt::getDHParams(std::vector<DHParam>& dhparameters, const LinkConstPtr& from_link) const
00356 {
00357     if (!isDHReady(from_link->name))
00358     {
00359         ROS_ERROR("Need to call prepareModelForDenavitHartenberg() before DH parameters can be calculated");
00360         return false;
00361     }
00362     EigenTransform root_transform = EigenTransform::Identity();
00363     Eigen::Vector3d x(1, 0, 0);
00364     Eigen::Vector3d z(0, 0, 1);
00365     Eigen::Vector3d pos(0, 0, 0);
00366     ROS_INFO_STREAM("### Starting DH conversion from link "<<from_link->name);
00367     for (std::vector<JointPtr>::const_iterator pj = from_link->child_joints.begin();
00368             pj != from_link->child_joints.end(); pj++)
00369     {
00370       EigenTransform fullDHTrans = EigenTransform::Identity();
00371       if (!getDHParams(dhparameters, *pj, root_transform, x, z, pos, true, fullDHTrans)) return false;
00372     }
00373 
00374     return true;
00375 }
00376 
00377 
00378 
00379 bool Urdf2GraspIt::getDHParams(std::vector<DHParam>& dhparams, const std::string& fromLinkName) const
00380 {
00381     UrdfTraverserConstPtr trav = readTraverser();
00382     if (!trav)
00383     {
00384         ROS_ERROR("Traverser must be set");
00385         return false;
00386     }
00387 
00388     LinkConstPtr from_link = trav->readLink(fromLinkName);
00389     if (!from_link)
00390     {
00391         ROS_ERROR("Link %s does not exist", fromLinkName.c_str());
00392         return false;
00393     }
00394 
00395     return getDHParams(dhparams, from_link);
00396 }
00397 
00398 bool Urdf2GraspIt::getDHTransform(const JointPtr& joint, const std::vector<DHParam>& dh, EigenTransform& result) const
00399 {
00400     for (std::vector<DHParam>::const_iterator it = dh.begin(); it != dh.end(); ++it)
00401     {
00402         if (it->joint->name == joint->name)
00403         {
00404             result = DHParam::getTransform(*it);
00405             return true;
00406         }
00407     }
00408     return false;
00409 }
00410 
00411 /*
00412 bool Urdf2GraspIt::coordsConvert(const JointPtr& joint, const JointPtr& root_joint,
00413                                  const std::vector<DHParam>& dh, bool dhToKin, EigenTransform& result)
00414 {
00415     // starting from the root of a chain, these are the current reference frame transforms in the chain,
00416     // one in DH space, and one in URDF space
00417     EigenTransform refFrameDH;
00418     EigenTransform refFrameURDF;
00419     refFrameDH.setIdentity();
00420     refFrameURDF.setIdentity();
00421 
00422     JointPtr iter_joint = root_joint;
00423 
00424     bool finish = false;
00425     int i = 0;
00426     do
00427     {
00428         EigenTransform dhTrans;
00429         if (!getDHTransform(iter_joint, dh, dhTrans))
00430         {
00431             ROS_ERROR("Joint %s not represented in dh parameters", iter_joint->name.c_str());
00432             return false;
00433         }
00434 
00435         EigenTransform jointTransform = EigenTransform::Identity();
00436         if (i > 0) jointTransform = urdf_traverser::getTransform(iter_joint);
00437 
00438         // ROS_INFO_STREAM("Dh trans for "<<iter_joint->name<<": "<<dhTrans);
00439         // ROS_INFO_STREAM("Joint trans for "<<iter_joint->name<<": "<<jointTransform);
00440 
00441         refFrameDH = refFrameDH * dhTrans;
00442         refFrameURDF = refFrameURDF * jointTransform;
00443 
00444         if (iter_joint->name == joint->name)  // we are finished
00445         {
00446             if (dhToKin)
00447                 result = refFrameDH.inverse() * refFrameURDF;
00448             else
00449                 result = refFrameURDF.inverse() * refFrameDH;
00450             finish = true;
00451         }
00452         else
00453         {
00454             int cret = getChildJoint(iter_joint, iter_joint);
00455             if (cret < 0)
00456             {
00457                 ROS_ERROR("Child joint could not be retrieved");
00458                 return false;
00459             }
00460             if (cret == 0)
00461             {
00462                 ROS_ERROR("Found the chain end, meaning joints %s and %s are not connected",
00463                           joint->name.c_str(), root_joint->name.c_str());
00464                 return false;
00465             }
00466             ++i;
00467         }
00468     }
00469     while (!finish);
00470 
00471     return true;
00472 }
00473 */
00474 
00475 bool Urdf2GraspIt::linksToDHReferenceFrames(const std::vector<DHParam>& dh)
00476 {
00477     UrdfTraverserPtr trav = getTraverser();
00478     if (!trav)
00479     {
00480         ROS_ERROR("Traverser not set.");
00481         return false;
00482     }
00483 
00484     std::map<std::string,EigenTransform> transforms;
00485     if (!DHParam::getTransforms(dh, true, transforms))
00486     {
00487         ROS_ERROR("Could not get transforms from DH to URDF");
00488         return false; 
00489     }
00490 
00491     std::map<std::string,EigenTransform>::iterator it;
00492     for (it=transforms.begin(); it!=transforms.end(); ++it)
00493     {
00494         LinkPtr link=trav->getLink(it->first);
00495         if (!link)
00496         {
00497             ROS_ERROR("Link %s does not exist", it->first.c_str());
00498             return false;
00499         }
00500         bool preApply = true;
00501         urdf_traverser::applyTransform(link, it->second, preApply);
00502     }
00503     return true;
00504 }
00505 
00506 
00507 void Urdf2GraspIt::scaleParams(std::vector<DHParam>& dh, double scale_factor) const
00508 {
00509     for (std::vector<DHParam>::iterator it = dh.begin(); it != dh.end(); ++it)
00510     {
00511         it->d *= scale_factor;
00512         it->r *= scale_factor;
00513     }
00514 }
00515 
00516 
00517 void Urdf2GraspIt::printParams(const std::vector<DHParam>& dh) const
00518 {
00519     ROS_INFO("--- DH Parameters: ---");
00520     for (std::vector<DHParam>::const_iterator it = dh.begin(); it != dh.end(); ++it)
00521     {
00522         ROS_INFO_STREAM(*it);
00523     }
00524 }
00525 
00526 
00527 
00528 bool Urdf2GraspIt::toDenavitHartenberg(const std::string& fromLink)
00529 {
00530     ROS_INFO("############### Getting DH params");
00531 
00532     std::vector<DHParam> dhparams;
00533     if (!getDHParams(dhparams, fromLink))
00534     {
00535         ROS_ERROR("Could not get DH parameters");
00536         return false;
00537     }
00538     dh_parameters = dhparams;
00539     dhTransformed = true;
00540     
00541     // Urdf2GraspItBase::testVisualizeURDF(fromLink);
00542 
00543     /*for (std::vector<DHParam>::iterator d=dhparams.begin(); d!=dhparams.end(); ++d) {
00544         ROS_INFO_STREAM("DH param: "<<*d);
00545     }*/
00546 
00547     ROS_INFO("############### Transform links to DH reference frames");
00548 
00549     if (!linksToDHReferenceFrames(dhparams))
00550     {
00551         ROS_ERROR("Could not adjust transforms");
00552         return false;
00553     }
00554     
00555     // Urdf2GraspItBase::testVisualizeURDF(fromLink);
00556 
00557     return true;
00558 }
00559 
00560 
00561 bool Urdf2GraspIt::checkConversionPrerequisites(const GraspItConversionParametersPtr& param) const
00562 {
00563     if (!isDHReady(param->rootLinkName))
00564     {
00565         ROS_ERROR("Need to call prepareModelForDenavitHartenberg() before DH parameters can be calculated");
00566         return false;
00567     }
00568 
00569     UrdfTraverserConstPtr trav = readTraverser();
00570     if (!trav)
00571     {
00572         ROS_ERROR("Traverser not set.");
00573         return false;
00574     }
00575 
00576     // Can only convert if there are no active joints between the root
00577     // joint and the finger bases, and all fixed joints have been joined.
00578     LinkConstPtr rootLink = trav->readLink(param->rootLinkName);
00579     if (!rootLink)
00580     {
00581         ROS_ERROR_STREAM("No link named '"<<param->rootLinkName<<"' found in URDF.");
00582         return false;
00583     }
00584     for (std::vector<std::string>::iterator rIt=param->fingerRoots.begin(); rIt != param->fingerRoots.end(); ++rIt)
00585     {
00586         JointConstPtr fingerRootJoint = trav->readJoint(*rIt);
00587         if (!fingerRootJoint)
00588         {
00589             ROS_ERROR_STREAM("No joint named '"<<*rIt<<"' found in URDF.");
00590             return false;
00591         }
00592         if (!urdf_traverser::isChildJointOf(rootLink, fingerRootJoint))
00593         {
00594             ROS_ERROR_STREAM(*rIt<<"' is not direct child of root '"<<param->rootLinkName
00595                 <<". This is either the wrong link, or there are other active joints between the root (palm) link and the finger root links."
00596                 <<" This is a requirement for conversion to GraspIt in the current version.");
00597             return false;
00598         }
00599     }
00600     return true; 
00601 }
00602 
00603 Urdf2GraspIt::ConversionResultPtr Urdf2GraspIt::preConvert(const ConversionParametersPtr& cparams)
00604 {
00605     GraspItConversionParametersPtr param = baselib_binding_ns::dynamic_pointer_cast<GraspItConversionParameters>(cparams);
00606     if (!param)
00607     {
00608         ROS_ERROR("Conversion parameters not of right type");
00609         return GraspItConversionResultPtr();
00610     }
00611     
00612     ROS_INFO_STREAM("### Urdf2GraspIt::preConvert for robot "<<param->robotName);
00613     initOutStructure(param->robotName); 
00614     
00615     GraspItConversionResultPtr failResult;
00616 
00617     std::string outputMeshDir =  getOutStructure().getMeshDirPath();
00618     std::string outputTexDir =  getOutStructure().getTexDirPath();
00619     GraspItConversionResultPtr result(new GraspItConversionResult(OUTPUT_EXTENSION, outputMeshDir, outputTexDir));
00620     result->success = false;
00621     result->robotName = param->robotName;
00622 
00623     if (!checkConversionPrerequisites(param))
00624     {
00625         ROS_ERROR("Prerequisites for conversion not fulfilled.");
00626         return failResult;
00627     }
00628 
00629     ROS_INFO("##### Computing DH parameters out of model");
00630     if (!dhTransformed && !toDenavitHartenberg(param->rootLinkName))
00631     {
00632         ROS_ERROR("Could not transform to DH reference frames");
00633         return failResult;
00634     }
00635 
00636     printParams(dh_parameters);
00637     
00638     ROS_INFO("##### Scaling DH parameters");
00639 
00640     // scale up all dh parameters to match the scale factor,
00641     // and also all link/collision/intertial transforms given in the URDF
00642 
00643     if (!isDHScaled)
00644     {
00645         scaleParams(dh_parameters, getScaleFactor());
00646         isDHScaled = true;
00647     }
00648     
00649     // Urdf2GraspItBase::testVisualizeURDF(param->rootLinkName);
00650 
00651     return result;
00652 }
00653 
00654 
00655 Urdf2GraspIt::ConversionResultPtr Urdf2GraspIt::postConvert(const ConversionParametersPtr& cparams, ConversionResultPtr& _result)
00656 {
00657     // Urdf2GraspItBase::testVisualizeURDF();
00658 
00659     GraspItConversionResultPtr result = baselib_binding_ns::dynamic_pointer_cast<GraspItConversionResult>(_result);
00660     if (!result)
00661     {
00662         ROS_ERROR("postConvert: result not of right type");
00663         return GraspItConversionResultPtr();
00664     }
00665  
00666     result->success=false;
00667 
00668     GraspItConversionParametersPtr param = baselib_binding_ns::dynamic_pointer_cast<GraspItConversionParameters>(cparams);
00669     if (!param)
00670     {
00671         ROS_ERROR("Conversion parameters not of right type");
00672         return result;
00673     }
00674     
00675     ROS_INFO_STREAM("### Urdf2GraspIt::postConvert for robot "<<param->robotName);
00676 
00677     UrdfTraverserPtr trav = getTraverser();
00678     if (!trav)
00679     {
00680         ROS_ERROR("Traverser not set.");
00681         return result;
00682     }
00683 
00684     if (!urdf2graspit::convertGraspItMeshes(*trav, param->rootLinkName, getScaleFactor(),
00685         param->material,
00686         OUTPUT_EXTENSION,
00687         param->addVisualTransform, result->meshXMLDesc))
00688     {
00689         ROS_ERROR("Could not convert meshes");
00690         return result;
00691     }
00692 
00693     ROS_INFO("############### Getting XML");
00694 
00695     result->eigenGraspXML = urdf2graspit::xmlfuncs::getEigenGraspXML(dh_parameters, negateJointMoves);
00696 
00697     // path to eigen file from robot directory, needed below. Has to match the one created here.
00698     std::string eigenXML = getOutStructure().getEigenGraspFileRel();
00699     std::string contactsVGR = getOutStructure().getContactsFileRel();
00700 
00701     if (!getXML(dh_parameters, param->fingerRoots, 
00702             param->rootLinkName, &eigenXML, &contactsVGR, std::string(), result->robotXML))
00703     {
00704         ROS_ERROR("Could not get xml");
00705         return result;
00706     }
00707 
00708     // ROS_INFO_STREAM("XML: "<<std::endl<<res.robotXML);
00709 
00710     result->world = getWorldFileTemplate(param->robotName, dh_parameters, getOutStructure().getRobotFilePath());
00711 
00712     /*ROS_INFO("### Generating contacts...");
00713     ContactsGenerator contGen(getScaleFactor());
00714     // need to load the model into the contacts generator as well.
00715     // this will then be a fresh model (not the one already converted to DH).
00716     std::string _robot_urdf=getRobotURDF();
00717     if (_robot_urdf.empty() || !contGen.loadModelFromXMLString(_robot_urdf))
00718     {
00719         ROS_ERROR("Could not load the model into the contacts generator");
00720         return result;
00721     }
00722     float coefficient = 0.2;
00723     if (!contGen.generateContactsWithViewer(param->fingerRoots, param->rootLinkName, coefficient, dh_parameters))
00724     {
00725         ROS_ERROR("Could not generate contacts");
00726         return result;
00727     }
00728     result->contacts = contGen.getContactsFileContent(result->robotName);
00729     */
00730     result->success = true; 
00731     return result;
00732 }
00733 
00734 
00735 void Urdf2GraspIt::getLimits(const urdf::Joint& j, float& min, float& max)
00736 {
00737     min = j.limits->lower;
00738     max = j.limits->upper;
00739     if (negateJointMoves)
00740     {
00741         min = -min;
00742         max = -max;
00743     }
00744     bool revolute = j.type == urdf::Joint::REVOLUTE;
00745     if (revolute)
00746     {
00747         min *= RAD_TO_DEG;
00748         max *= RAD_TO_DEG;
00749     }
00750     else
00751     {   // convert from meter units to mm
00752         min *= 1000;
00753         max *= 1000;
00754     }
00755 }
00756 
00757 void Urdf2GraspIt::getJointMoves(const urdf::Joint& j, float& velocity, float& effort)
00758 {
00759     velocity = j.limits->velocity;
00760     effort = j.limits->effort;
00761     if (negateJointMoves)
00762     {
00763         velocity = -velocity;
00764         effort = -effort;
00765     }
00766 }
00767 
00768 std::string Urdf2GraspIt::getWorldFileTemplate(
00769     const std::string& robotName,
00770     const std::vector<DHParam>& dhparams,
00771     const std::string& prependpath)
00772 {
00773     return urdf2graspit::xmlfuncs::getWorldFileTemplate(robotName, dhparams, prependpath, negateJointMoves);
00774 }
00775 
00776    
00777 Urdf2GraspIt::ConversionResultPtr Urdf2GraspIt::processAll(const std::string& urdfFilename,
00778         const std::string& palmLinkName,
00779         const std::vector<std::string>& fingerRootNames,
00780         const std::string& material,
00781         const EigenTransform& addVisualTransform)
00782 {
00783     
00784     std::string outputMeshDir =  getOutStructure().getMeshDirPath();
00785     std::string outputTexDir =  getOutStructure().getMeshDirPath();
00786     GraspItConversionResultPtr failResult(new GraspItConversionResult(OUTPUT_EXTENSION, outputMeshDir, outputTexDir));
00787     failResult->success = false;
00788 
00789     ROS_INFO_STREAM("### Loading from URDF file "<<urdfFilename<<"...");
00790 
00791     if (!loadModelFromFile(urdfFilename))
00792     {
00793         ROS_ERROR("Could not load file");
00794         return failResult;
00795     }
00796 
00797     ROS_INFO_STREAM("### Converting files starting from link " << palmLinkName);
00798     if (!prepareModelForDenavitHartenberg(palmLinkName))
00799     {
00800         ROS_ERROR("Could not prepare for DH conversion");
00801         return failResult;
00802     }
00803 
00804     UrdfTraverserPtr trav = getTraverser();
00805     if (!trav)
00806     {
00807         ROS_ERROR("Traverser must be set");
00808         return failResult;
00809     }
00810 
00811     ROS_INFO("### Converting files...");
00812     ConversionParametersPtr params(new GraspItConversionParameters(trav->getModelName(),
00813             palmLinkName,
00814             material,
00815             fingerRootNames, addVisualTransform));
00816 
00817 /*    MeshConvertRecursionParamsPtr mParams(new GraspitMeshConvertRecursionParams(getScaleFactor(), material,
00818                                         OUTPUT_EXTENSION, addVisualTransform));
00819 */
00820     ConversionResultPtr convResult = convert(params); //, mParams);
00821     if (!convResult || !convResult->success)
00822     {
00823         ROS_ERROR("Could not do the conversion");
00824         return convResult ? convResult : failResult;
00825     }
00826 
00827     GraspItConversionResultPtr result = baselib_binding_ns::dynamic_pointer_cast<GraspItConversionResult>(convResult);
00828     if (!result)
00829     {
00830         ROS_ERROR("postConvert: result not of right type");
00831         return convResult ? convResult : failResult;
00832     }
00833  
00834     result->robotName = trav->getModelName();
00835 
00836     // ROS_INFO_STREAM("Contacts generated: "<<result->contacts);
00837 
00838     result->success = true;
00839     return result;
00840 }
00841 


urdf2graspit
Author(s): Jennifer Buehler
autogenerated on Wed May 8 2019 02:53:45