00001
00019 #include <urdf2graspit/XMLFuncs.h>
00020 #include <string>
00021 #include <vector>
00022
00023 using urdf2graspit::xmlfuncs::FingerChain;
00024 using urdf2graspit::JointPtr;
00025 using urdf2graspit::JointConstPtr;
00026 using urdf2graspit::InertialPtr;
00027
00028 using urdf2graspit::DHParam;
00029
00030 #define RAD_TO_DEG 180/M_PI
00031
00032 FingerChain& FingerChain::operator=(const FingerChain& o)
00033 {
00034 if (&o == this) return *this;
00035 prms = o.prms;
00036 linkFileNames = o.linkFileNames;
00037 linkTypes = o.linkTypes;
00038 return *this;
00039 }
00040
00041 std::ostream& operator<<(std::ostream& o, const FingerChain& p)
00042 {
00043 o << "Joints: " << std::endl;
00044 for (std::vector<DHParam>::const_iterator it = p.prms.begin(); it != p.prms.end(); ++it)
00045 {
00046 o << *it << std::endl;
00047 }
00048 o << "Links:" << std::endl;
00049 std::vector<std::string>::const_iterator t = p.linkTypes.begin();
00050 for (std::vector<std::string>::const_iterator it = p.linkFileNames.begin(); it != p.linkFileNames.end(); ++it)
00051 {
00052 o << *it << ", type=" << *t << std::endl;
00053 ++t;
00054 }
00055 return o;
00056 }
00057
00058 void getJointLimits(const urdf::Joint& j, float& min, float& max, bool negateAndSwapMinMax, bool scaleRevolute=false, bool scalePrismatic=true)
00059 {
00060 min = j.limits->lower;
00061 max = j.limits->upper;
00062 if (negateAndSwapMinMax)
00063 {
00064 float minTmp = min;
00065 min = -max;
00066 max = -minTmp;
00067 }
00068 bool revolute = j.type == urdf::Joint::REVOLUTE;
00069 if (revolute && scaleRevolute)
00070 {
00071 min *= RAD_TO_DEG;
00072 max *= RAD_TO_DEG;
00073 }
00074
00075 if (!revolute && scalePrismatic)
00076 {
00077 min *= 1000;
00078 max *= 1000;
00079 }
00080 }
00081
00082
00083 std::string getEigenGraspValues(const std::vector<DHParam>& dhparams, bool negateJointValues)
00084 {
00085 std::stringstream str;
00086 str << "\t<EG>" << std::endl;
00087 str << "\t\t<EigenValue value=\"0.5\"/> <!--EigenValue is not used in the code at this stage -->" << std::endl;
00088 float minAmpl = 0;
00089 float maxAmpl = 0;
00090 str<<"\t\t<!--Limits min=\""<<minAmpl<<"\" max=\""<<maxAmpl<<"\"/-->"<<std::endl;
00091 str << "\t\t<DimVals";
00092 int i = 0;
00093 for (std::vector<DHParam>::const_iterator it = dhparams.begin(); it != dhparams.end(); ++it, ++i)
00094 {
00095 float minValue, maxValue;
00096 getJointLimits(*(it->joint), minValue, maxValue, negateJointValues, false, false);
00097 float num = (minValue + maxValue) / 2;
00098 str << " d" << i << "=\"" << num << "\"";
00099 }
00100 str << "/>" << std::endl;
00101 str << "\t</EG>" << std::endl;
00102 return str.str();
00103 }
00104
00105 std::string urdf2graspit::xmlfuncs::getEigenGraspXML(const std::vector<DHParam>& dhparams, bool negateJointValues)
00106 {
00107 std::stringstream str;
00108 str << "<?xml version=\"1.0\" ?>" << std::endl;
00109
00110
00111 unsigned int i=0;
00112 for (std::vector<DHParam>::const_iterator it = dhparams.begin(); it != dhparams.end(); ++it, ++i)
00113 {
00114 float minValue, maxValue;
00115 getJointLimits(*(it->joint), minValue, maxValue, negateJointValues, false, false);
00116 str << "<!-- d" << i <<": "<<it->joint->name<<", min="<<minValue<<", max="<<maxValue<<" -->" << std::endl;
00117 }
00118
00119 str << "<EigenGrasps dimensions=\"" << dhparams.size() << "\">" << std::endl;
00120
00121 str << getEigenGraspValues(dhparams, negateJointValues);
00122
00123 str << "\t<ORIGIN>" << std::endl;
00124 str << "\t\t<EigenValue value=\"0.5\"/> " << std::endl;
00125 str << "\t\t<DimVals";
00126
00127 i = 0;
00128 for (std::vector<DHParam>::const_iterator it = dhparams.begin(); it != dhparams.end(); ++it, ++i)
00129 {
00130 float minValue, maxValue;
00131 getJointLimits(*(it->joint), minValue, maxValue, negateJointValues, false, true);
00132 float num = (minValue + maxValue) / 2;
00133 str << " d" << i << "=\"" << num << "\"";
00134 }
00135 str << "/>" << std::endl;
00136 str << "\t</ORIGIN>" << std::endl;
00137 str << "</EigenGrasps>" << std::endl;
00138 return str.str();
00139 }
00140
00141 bool isRevolutingJoint(const JointConstPtr& joint)
00142 {
00143 return (joint->type == urdf::Joint::REVOLUTE) || (joint->type == urdf::Joint::CONTINUOUS);
00144 }
00145 bool isPrismaticJoint(const JointConstPtr& joint)
00146 {
00147 return (joint->type == urdf::Joint::PRISMATIC);
00148 }
00149
00150 std::string getChainJointSpec(const DHParam& dh, bool negateJointValues)
00151 {
00152 if (!isRevolutingJoint(dh.joint) && !isPrismaticJoint(dh.joint))
00153 {
00154 ROS_ERROR("Joint has to be revoluting or prismatic!");
00155 return std::string();
00156 }
00157
00158 bool revolute = isRevolutingJoint(dh.joint);
00159 float minValue, maxValue;
00160 getJointLimits(*(dh.joint), minValue, maxValue, negateJointValues, true, true);
00161 std::stringstream ret;
00162 ret << "\t\t<joint type=" << (revolute ? "'Revolute'" : "'Prismatic'") << ">" << std::endl;
00163
00164
00165
00166
00167 if (isRevolutingJoint(dh.joint))
00168 ret << "\t\t\t<theta> d" << dh.dof_index << "+"
00169 << dh.theta*RAD_TO_DEG << "</theta>" << std::endl;
00170 else ret << "\t\t\t<theta>" << dh.theta*RAD_TO_DEG << "</theta>" << std::endl;
00171
00172 if (isPrismaticJoint(dh.joint))
00173 ret << "\t\t\t<d> d" <<dh.dof_index <<"+" << dh.d << "</d>" << std::endl;
00174 else ret << "\t\t\t<d>" << dh.d << "</d>" << std::endl;
00175
00176 ret << "\t\t\t<a>" << dh.r << "</a>" << std::endl;
00177 ret << "\t\t\t<alpha>" << dh.alpha*RAD_TO_DEG << "</alpha>" << std::endl;
00178
00179 ret << "\t\t\t<minValue>" << minValue << "</minValue>" << std::endl;
00180 ret << "\t\t\t<maxValue>" << maxValue << "</maxValue>" << std::endl;
00181 ret << "\t\t\t<viscousFriction>5.0e+7</viscousFriction>" << std::endl;
00182 ret << "\t\t</joint>" << std::endl;
00183 return ret.str();
00184 }
00185
00186 std::string urdf2graspit::xmlfuncs::getFingerChain(const FingerChain& c, const Eigen::Vector3d& palmTranslation,
00187 const Eigen::Quaterniond& palmRotation, bool negateJointValues)
00188 {
00189 std::stringstream str;
00190
00191 Eigen::Quaterniond corrPalmRotation = palmRotation.inverse();
00192 Eigen::Quaterniond::Matrix3 m = corrPalmRotation.toRotationMatrix();
00193 str << "\t<chain> " << std::endl;
00194 str << "\t\t<transform> " << std::endl;
00195 str << "\t\t\t<translation>" << palmTranslation.x() << " "
00196 << palmTranslation.y() << " " << palmTranslation.z() << "</translation>" << std::endl;
00197 str << "\t\t\t<rotationMatrix>"
00198 << m(0, 0) << " " << m(0, 1) << " " << m(0, 2) << " "
00199 << m(1, 0) << " " << m(1, 1) << " " << m(1, 2) << " "
00200 << m(2, 0) << " " << m(2, 1) << " " << m(2, 2) << " "
00201 << "</rotationMatrix> " << std::endl;
00202 str << "\t\t</transform>" << std::endl;
00203 for (std::vector<DHParam>::const_iterator it = c.prms.begin(); it != c.prms.end(); ++it)
00204 {
00205
00206 std::string j = getChainJointSpec(*it, negateJointValues);
00207 str << j;
00208 }
00209
00210 std::vector<std::string>::const_iterator t = c.linkTypes.begin();
00211 for (std::vector<std::string>::const_iterator it = c.linkFileNames.begin(); it != c.linkFileNames.end(); ++it)
00212 {
00213 str << "\t\t<link dynamicJointType='" << *t << "'>" << *it << "</link>" << std::endl;
00214 ++t;
00215 }
00216 str << "\t</chain>" << std::endl;
00217 return str.str();
00218 }
00219
00220
00221 std::string urdf2graspit::xmlfuncs::getDOF(float defaultVel, float maxEffort, float kp,
00222 float kd, float draggerScale, const std::string& type)
00223 {
00224 std::stringstream ret;
00225 ret << "\t<dof type='" << type << "'>" << std::endl;
00226 ret << "\t\t<defaultVelocity>" << defaultVel << "</defaultVelocity>" << std::endl;
00227 ret << "\t\t<maxEffort>" << maxEffort << "</maxEffort>" << std::endl;
00228 ret << "\t\t<Kp>" << kp << "</Kp>" << std::endl;
00229 ret << "\t\t<Kd>" << kd << "</Kd>" << std::endl;
00230 ret << "\t\t<draggerScale>" << draggerScale << "</draggerScale>" << std::endl;
00231
00232 ret << "\t</dof>" << std::endl;
00233 return ret.str();
00234 }
00235
00236
00237 std::string urdf2graspit::xmlfuncs::getLinkDescXML(
00238 const LinkPtr& link,
00239 const std::string& linkMeshFile,
00240 const std::string& material)
00241 {
00242 InertialPtr i = link->inertial;
00243
00244 std::stringstream str;
00245 str << "<?xml version=\"1.0\" ?>" << std::endl;
00246 str << "<root>" << std::endl;
00247 str << "\t<material>" << material << "</material>" << std::endl;
00248 float msc = 1000;
00249 if (i)
00250 {
00251 str << "\t<mass>" << i->mass*msc << "</mass>" << std::endl;
00252 str << "\t<cog>" << i->origin.position.x << " " << i->origin.position.y
00253 << " " << i->origin.position.z << "</cog>" << std::endl;
00254 str << "\t<inertia_matrix>"
00255 << i->ixx*msc << " " << i->ixy*msc << " " << i->ixz*msc << " "
00256 << i->ixy*msc << " " << " " << i->iyy*msc << " " << i->iyz*msc << " "
00257 << i->ixz*msc << " " << " " << i->iyz*msc << " " << i->izz*msc << "</inertia_matrix>" << std::endl;
00258 }
00259 else
00260 {
00261 ROS_WARN_STREAM("No inertial for link "<<link->name<<", setting to mass=1");
00262
00263 str << "\t<mass>1</mass>" << std::endl;
00264 str << "\t<cog>0 0 0 </cog>" << std::endl;
00265 str << "\t<inertia_matrix>"
00266 <<"1 0 0 "
00267 <<"0 1 0 "
00268 <<"0 0 1</inertia_matrix>" << std::endl;
00269 }
00270 str << "\t<geometryFile>" << linkMeshFile << "</geometryFile>" << std::endl;
00271 str << "</root>" << std::endl;
00272 return str.str();
00273 }
00274
00275
00276
00277
00278 std::string urdf2graspit::xmlfuncs::getWorldFileTemplate(
00279 const std::string& robotName,
00280 const std::vector<DHParam>& dhparams,
00281 const std::string& robotFileRelToGraspitRoot,
00282 bool negateJointValues)
00283 {
00284 bool includeCube = false;
00285
00286 std::stringstream str;
00287 str << "<?xml version=\"1.0\"?>" << std::endl;
00288 str << "<world>" << std::endl;
00289
00290 if (!includeCube) str << "<!--" << std::endl;
00291 str << "\t<graspableBody>" << std::endl;
00292 str << "\t\t<filename>models/objects/small_cube.xml</filename>" << std::endl;
00293 str << "\t\t<transform>" << std::endl;
00294 str << "\t\t\t<fullTransform>(+1 0 0 0)[+100 +0 +0]</fullTransform>" << std::endl;
00295 str << "\t\t</transform>" << std::endl;
00296 str << "\t</graspableBody>" << std::endl;
00297 if (!includeCube) str << "-->" << std::endl;
00298
00299 str << "\t<robot>" << std::endl;
00300 str << "\t\t<filename>" << robotFileRelToGraspitRoot << "</filename>" << std::endl;
00301
00302
00303 str << "\t\t<dofValues>";
00304 for (std::vector<DHParam>::const_iterator it = dhparams.begin(); it != dhparams.end(); ++it)
00305 {
00306 float min, max;
00307 getJointLimits(*(it->joint), min, max, negateJointValues, false, false);
00308 str<<((max + min) * 0.5)<<" ";
00309 }
00310 str << "</dofValues>" << std::endl;
00311
00312 str << "\t\t<transform>" << std::endl;
00313 str << "\t\t\t<fullTransform>(+1 0 0 0)[0 0 0]</fullTransform>" << std::endl;
00314 str << "\t\t</transform>" << std::endl;
00315 str << "\t</robot>" << std::endl;
00316 str << "\t<camera>" << std::endl;
00317 str << "\t\t<position>+0 +0 +500</position>" << std::endl;
00318 str << "\t\t<orientation>0 0 0 1</orientation>" << std::endl;
00319 str << "\t\t<focalDistance>+500</focalDistance>" << std::endl;
00320 str << "\t</camera>" << std::endl;
00321
00322 str << "</world>" << std::endl;
00323 str << "" << std::endl;
00324
00325 return str.str();
00326 }
00327
00328