collada_to_urdf.cpp
Go to the documentation of this file.
00001 /* Author: Yohei Kakiuchi */
00002 
00003 #include "collada_parser/collada_parser.h"
00004 #include "urdf/model.h"
00005 
00006 #if 0
00007 // assimp 2
00008 #include <assimp/assimp.hpp>
00009 #include <assimp/export.hpp>
00010 #include <assimp/aiScene.h>
00011 #include <assimp/aiPostProcess.h>
00012 #else
00013 // assimp 3 (assimp_devel)
00014 #include <assimp3/IOSystem.hpp>
00015 #include <assimp3/IOStream.hpp>
00016 #include <assimp3/Importer.hpp>
00017 #include <assimp3/Exporter.hpp>
00018 #include <assimp3/postprocess.h>
00019 #include <assimp3/scene.h>
00020 #endif
00021 
00022 #include <iostream>
00023 #include <fstream>
00024 
00025 #include <boost/program_options.hpp>
00026 #include <boost/filesystem/path.hpp>
00027 #include <boost/filesystem/operations.hpp>
00028 
00029 #include <tf/LinearMath/Transform.h>
00030 #include <tf/LinearMath/Quaternion.h>
00031 
00032 #undef GAZEBO_1_0
00033 #undef GAZEBO_1_3
00034 //#define GAZEBO_1_0
00035 #define GAZEBO_1_3
00036 
00037 using namespace urdf;
00038 using namespace std;
00039 
00040 bool use_simple_visual = false;
00041 bool use_simple_collision = false;
00042 bool add_gazebo_description = false;
00043 bool use_assimp_export = false;
00044 bool use_same_collision_as_visual = true;
00045 bool rotate_inertia_frame = true;
00046 bool export_collision_mesh = true;
00047 
00048 string mesh_dir = "/tmp";
00049 string arobot_name = "";
00050 string output_file = "";
00051 string mesh_prefix = "";
00052 
00053 #define PRINT_ORIGIN(os, origin) \
00054 os << "xyz: " << origin.position.x << " " << origin.position.y << " " << origin.position.z << " "; \
00055 { double r,p,y; origin.rotation.getRPY(r, p, y); \
00056   os << "rpy: " << r << " " << p << " " << y; }
00057 
00058 #define PRINT_ORIGIN_XML(os, origin) \
00059   os << "xyz=\"" << origin.position.x << " " << origin.position.y << " " << origin.position.z << "\""; \
00060   { double h___r, h___p, h___y; \
00061      origin.rotation.getRPY(h___r, h___p, h___y); \
00062   os << " rpy=\"" << h___r << " " << h___p << " " << h___y << "\""; }
00063 
00064 #define PRINT_GEOM(os, geometry) \
00065   if ( geometry->type == urdf::Geometry::MESH ) { os << "geom: name: " << ((urdf::Mesh *)geometry.get())->filename; }
00066 
00067 void assimp_file_export(std::string fname, std::string ofname,
00068                         std::string mesh_type = "collada") {
00069   if (fname.find("file://") == 0) {
00070     fname.erase(0, strlen("file://"));
00071   }
00072 
00073   Assimp::Importer importer;
00074   const aiScene* scene = importer.ReadFile(fname.c_str(),
00075                                            aiProcess_Triangulate            |
00076                                            aiProcess_GenNormals             |
00077                                            aiProcess_JoinIdenticalVertices  |
00078                                            aiProcess_SplitLargeMeshes       |
00079                                            aiProcess_OptimizeMeshes         |
00080                                            aiProcess_SortByPType);
00081 
00082   if (!scene) {
00083     std::string str( importer.GetErrorString() );
00084     std::cerr << ";; " << str << std::endl;
00085     return;
00086   }
00087 
00088   Assimp::Exporter aexpt;
00089   aiReturn ret = aexpt.Export(scene, mesh_type, ofname);
00090   if ( ret != AI_SUCCESS ) {
00091     std::string str( "assimp error" );
00092     std::cerr << ";; " << str << std::endl;
00093   }
00094 }
00095 
00096 // assimp bounding box calculation
00097 void assimp_calc_bbox(string fname, float &minx, float &miny, float &minz,
00098                       float &maxx, float &maxy, float &maxz) {
00099 
00100   if (fname.find("file://") == 0) {
00101     fname.erase(0, strlen("file://"));
00102   }
00103 
00104   Assimp::Importer importer;
00105   const aiScene* scene = importer.ReadFile(fname.c_str(),
00106                                            aiProcess_Triangulate            |
00107                                            aiProcess_JoinIdenticalVertices  |
00108                                            aiProcess_SortByPType);   // aiProcess_GenNormals
00109                                                                      // aiProcess_GenSmoothNormals
00110                                                                      // aiProcess_SplitLargeMeshes
00111   if (!scene) {
00112     std::string str( importer.GetErrorString() );
00113     std::cerr << ";; " << str << std::endl;
00114     return;
00115   }
00116 
00117   aiNode *node = scene->mRootNode;
00118 
00119   bool found = false;
00120   if(node->mNumMeshes > 0 && node->mMeshes != NULL) {
00121     std::cerr << "Root node has meshes " << node->mMeshes << std::endl;;
00122     found = true;
00123   } else {
00124     for (unsigned int i=0; i < node->mNumChildren; ++i) {
00125       if(node->mChildren[i]->mNumMeshes > 0 && node->mChildren[i]->mMeshes != NULL) {
00126         std::cerr << "Child " << i << " has meshes" << std::endl;
00127         node = node->mChildren[i];
00128         found = true;
00129         break;
00130       }
00131     }
00132   }
00133   if(found == false) {
00134     std::cerr << "Can't find meshes in file" << std::endl;
00135     return;
00136   }
00137 
00138   aiMatrix4x4 transform = node->mTransformation;
00139 
00140   // copy vertices
00141   maxx = maxy = maxz = -100000000.0;
00142   minx = miny = minz =  100000000.0;
00143 
00144   std::cerr << ";; num meshes: " << node->mNumMeshes << std::endl;
00145   for (unsigned int m = 0; m < node->mNumMeshes; m++) {
00146     aiMesh *a = scene->mMeshes[node->mMeshes[m]];
00147     std::cerr << ";; num vertices: " << a->mNumVertices << std::endl;
00148 
00149     for (unsigned int i = 0 ; i < a->mNumVertices ; ++i) {
00150       aiVector3D p;
00151       p.x = a->mVertices[i].x;
00152       p.y = a->mVertices[i].y;
00153       p.z = a->mVertices[i].z;
00154       p *= transform;
00155 
00156       if ( maxx < p.x ) {
00157         maxx = p.x;
00158       }
00159       if ( maxy < p.y ) {
00160         maxy = p.y;
00161       }
00162       if ( maxz < p.z ) {
00163         maxz = p.z;
00164       }
00165       if ( minx > p.x ) {
00166         minx = p.x;
00167       }
00168       if ( miny > p.y ) {
00169         miny = p.y;
00170       }
00171       if ( minz > p.z ) {
00172         minz = p.z;
00173       }
00174     }
00175   }
00176 }
00177 
00178 void addChildLinkNamesXML(boost::shared_ptr<const Link> link, ofstream& os)
00179 {
00180   os << "  <link name=\"" << link->name << "\">" << endl;
00181   if ( !!link->visual ) {
00182     os << "    <visual>" << endl;
00183 
00184     if (!use_simple_visual) {
00185       os << "      <origin ";
00186       PRINT_ORIGIN_XML(os, link->visual->origin);
00187       os << "/>" << endl;
00188       os << "      <geometry>" << endl;
00189       if ( link->visual->geometry->type == urdf::Geometry::MESH ) {
00190         std::string ifname (((urdf::Mesh *)link->visual->geometry.get())->filename);
00191         if (ifname.find("file://") == 0) {
00192           ifname.erase(0, strlen("file://"));
00193         }
00194         std::string ofname (mesh_dir + "/" + link->name + "_mesh.dae");
00195 
00196         if (use_assimp_export) {
00197           // using collada export
00198           assimp_file_export (ifname, ofname);
00199         } else {
00200           // copy to ofname
00201           std::ofstream tmp_os;
00202           tmp_os.open(ofname.c_str());
00203           std::ifstream is;
00204           is.open(ifname.c_str());
00205           std::string buf;
00206           while(is && getline(is, buf)) tmp_os << buf << std::endl;
00207           is.close();
00208           tmp_os.close();
00209         }
00210         if (mesh_prefix != "") {
00211           os << "        <mesh filename=\"" << mesh_prefix + "/" + link->name + "_mesh.dae" << "\" scale=\"1 1 1\" />" << endl;
00212         } else {
00213           os << "        <mesh filename=\"" << "file://" << ofname << "\" scale=\"1 1 1\" />" << endl;
00214         }
00215       }
00216       os << "      </geometry>" << endl;
00217     } else {
00218       // simple visual
00219       float ax,ay,az,bx,by,bz;
00220       if ( link->visual->geometry->type == urdf::Geometry::MESH ) {
00221         assimp_calc_bbox(((urdf::Mesh *)link->visual->geometry.get())->filename,
00222                          ax, ay, az, bx, by, bz);
00223       }
00224       os << "      <origin ";
00225       urdf::Pose pp = link->visual->origin;
00226       // ROS_INFO("%f %f %f / %f %f %f", ax, ay, az, bx, by, bz);
00227       pp.position.x += ( ax + bx ) / 2 ;
00228       pp.position.y += ( ay + by ) / 2 ;
00229       pp.position.z += ( az + bz ) / 2 ;
00230       PRINT_ORIGIN_XML(os, pp);
00231       os << "/>" << endl;
00232 
00233       os << "      <geometry>" << endl;
00234       os << "         <box size=\"" << bx - ax << " " << by - ay << " " << bz - az << "\"/>" << endl;
00235       os << "      </geometry>" << endl;
00236     }
00237     os << "    </visual>" << endl;
00238   }
00239   if ( !!link->collision ) {
00240     os << "    <collision>" << endl;
00241     if (!use_simple_collision) {
00242       os << "      <origin ";
00243       PRINT_ORIGIN_XML(os, link->collision->origin);
00244       os << "/>" << endl;
00245       os << "      <geometry>" << endl;
00246 
00247       if ( link->visual->geometry->type == urdf::Geometry::MESH ) {
00248         std::string ifname;
00249         if (use_same_collision_as_visual) {
00250           ifname.assign (((urdf::Mesh *)link->visual->geometry.get())->filename);
00251         } else {
00252           ifname.assign (((urdf::Mesh *)link->collision->geometry.get())->filename);
00253         }
00254         if (ifname.find("file://") == 0) {
00255           ifname.erase(0, strlen("file://"));
00256         }
00257         std::string oofname;
00258         if (export_collision_mesh) {
00259           oofname = link->name + "_mesh.stl";
00260         } else {
00261           oofname = link->name + "_mesh.dae";
00262         }
00263         std::string ofname = (mesh_dir + "/" + oofname);
00264 
00265         if (use_assimp_export) {
00266           // using collada export
00267           if (export_collision_mesh) {
00268             assimp_file_export (ifname, ofname, "stl");
00269           } else {
00270             assimp_file_export (ifname, ofname);
00271           }
00272         } else {
00273           // copy to ofname
00274           std::ofstream tmp_os;
00275           tmp_os.open(ofname.c_str());
00276           std::ifstream is;
00277           is.open(ifname.c_str());
00278           std::string buf;
00279           while(is && getline(is, buf)) tmp_os << buf << std::endl;
00280           is.close();
00281           tmp_os.close();
00282         }
00283         if (mesh_prefix != "") {
00284           os << "        <mesh filename=\"" << mesh_prefix + "/" + oofname;
00285         } else {
00286           os << "        <mesh filename=\"" << "file://" << ofname;
00287         }
00288         os << "\" scale=\"1 1 1\" />" << endl;
00289       }
00290       os << "      </geometry>" << endl;
00291     } else {
00292       // simple collision
00293       float ax,ay,az,bx,by,bz;
00294       if ( link->visual->geometry->type == urdf::Geometry::MESH ) {
00295         assimp_calc_bbox(std::string ( ((urdf::Mesh *)link->visual->geometry.get())->filename ),
00296                          ax, ay, az, bx, by, bz);
00297       }
00298       os << "      <origin ";
00299       urdf::Pose pp = link->visual->origin;
00300       pp.position.x += ( ax + bx ) / 2 ;
00301       pp.position.y += ( ay + by ) / 2 ;
00302       pp.position.z += ( az + bz ) / 2 ;
00303       PRINT_ORIGIN_XML(os, pp);
00304       os << "/>" << endl;
00305 
00306       os << "      <geometry>" << endl;
00307       os << "         <box size=\"" << bx - ax << " " << by - ay << " " << bz - az << "\"/>" << endl;
00308       os << "      </geometry>" << endl;
00309     }
00310     os << "    </collision>" << endl;
00311   }
00312   if ( !!link->inertial ) {
00313     if (!rotate_inertia_frame) {
00314       os << "    <inertial>" << endl;
00315       os << "      <mass value=\"" << link->inertial->mass << "\" />" << endl;
00316       os << "      <origin ";
00317       PRINT_ORIGIN_XML(os, link->inertial->origin);
00318       os << "/>" << endl;
00319       os << "      <inertia ixx=\"" << link->inertial->ixx << "\" ";
00320       os << "ixy=\"" << link->inertial->ixy << "\" ";
00321       os << "ixz=\"" << link->inertial->ixz << "\" ";
00322       os << "iyy=\"" << link->inertial->iyy << "\" ";
00323       os << "iyz=\"" << link->inertial->iyz << "\" ";
00324       os << "izz=\"" << link->inertial->izz << "\"/>" << endl;
00325       os << "    </inertial>" << endl;
00326     } else {
00327       // rotation should be identity ???
00328       os << "    <inertial>" << endl;
00329       os << "      <mass value=\"" << link->inertial->mass << "\" />" << endl;
00330       os << "      <origin ";
00331 
00332       tf::Quaternion qt (link->inertial->origin.rotation.x,
00333                          link->inertial->origin.rotation.y,
00334                          link->inertial->origin.rotation.z,
00335                          link->inertial->origin.rotation.w);
00336       tf::Matrix3x3 mat (qt);
00337       tf::Matrix3x3 tmat (mat.transpose());
00338       tf::Matrix3x3 imat (link->inertial->ixx, link->inertial->ixy, link->inertial->ixz,
00339                           link->inertial->ixy, link->inertial->iyy, link->inertial->iyz,
00340                           link->inertial->ixz, link->inertial->iyz, link->inertial->izz);
00341 #define DEBUG_MAT(mat)                                                  \
00342       cout << "#2f((" << mat[0][0] << " " << mat[0][1] << " " << mat[0][2] << ")"; \
00343       cout << "(" << mat[1][0] << " " << mat[1][1] << " " << mat[1][2] << ")"; \
00344       cout << "(" << mat[2][0] << " " << mat[2][1] << " " << mat[2][2] << "))" << endl;
00345 
00346       //DEBUG_MAT(mat);
00347       //DEBUG_MAT(tmat);
00348       //DEBUG_MAT(imat);
00349       imat = ( mat * imat * tmat );
00350       //DEBUG_MAT(imat);
00351 
00352       urdf::Pose t_pose (link->inertial->origin);
00353       t_pose.rotation.clear();
00354 
00355       PRINT_ORIGIN_XML(os, t_pose);
00356       os << "/>" << endl;
00357 
00358       os << "      <inertia ixx=\"" << imat[0][0] << "\" ";
00359       os << "ixy=\"" << imat[0][1] << "\" ";
00360       os << "ixz=\"" << imat[0][2] << "\" ";
00361       os << "iyy=\"" << imat[1][1] << "\" ";
00362       os << "iyz=\"" << imat[1][2] << "\" ";
00363       os << "izz=\"" << imat[2][2] << "\"/>" << endl;
00364       os << "    </inertial>" << endl;
00365     }
00366   }
00367   os << "  </link>" << endl;
00368 
00369 #ifdef GAZEBO_1_0
00370   if ( add_gazebo_description ) {
00371     os << "  <gazebo reference=\"" << link->name << "\">" << endl;
00372     os << "    <material>Gazebo/Grey</material>" << endl;
00373     os << "    <turnGravityOff>false</turnGravityOff>" << endl;
00374     os << "  </gazebo>" << endl;
00375   }
00376 #endif
00377 
00378   for (std::vector<boost::shared_ptr<Link> >::const_iterator child = link->child_links.begin(); child != link->child_links.end(); child++)
00379     addChildLinkNamesXML(*child, os);
00380 }
00381 
00382 void addChildJointNamesXML(boost::shared_ptr<const Link> link, ofstream& os)
00383 {
00384   double r, p, y;
00385   for (std::vector<boost::shared_ptr<Link> >::const_iterator child = link->child_links.begin(); child != link->child_links.end(); child++){
00386     (*child)->parent_joint->parent_to_joint_origin_transform.rotation.getRPY(r,p,y);
00387     std::string jtype;
00388     if ( (*child)->parent_joint->type == urdf::Joint::UNKNOWN ) {
00389       jtype = std::string("unknown");
00390     } else if ( (*child)->parent_joint->type == urdf::Joint::REVOLUTE ) {
00391       jtype = std::string("revolute");
00392     } else if ( (*child)->parent_joint->type == urdf::Joint::CONTINUOUS ) {
00393       jtype = std::string("continuous");
00394     } else if ( (*child)->parent_joint->type == urdf::Joint::PRISMATIC ) {
00395       jtype = std::string("prismatic");
00396     } else if ( (*child)->parent_joint->type == urdf::Joint::FLOATING ) {
00397       jtype = std::string("floating");
00398     } else if ( (*child)->parent_joint->type == urdf::Joint::PLANAR ) {
00399       jtype = std::string("planar");
00400     } else if ( (*child)->parent_joint->type == urdf::Joint::FIXED ) {
00401       jtype = std::string("fixed");
00402     } else {
00404     }
00405 
00406     os << "  <joint name=\"" <<  (*child)->parent_joint->name << "\" type=\"" << jtype << "\">" << endl;
00407     os << "    <parent link=\"" << link->name << "\"/>" << endl;
00408     os << "    <child  link=\"" <<  (*child)->name << "\"/>" << endl;
00409     os << "    <origin xyz=\"" <<  (*child)->parent_joint->parent_to_joint_origin_transform.position.x << " ";
00410     os << (*child)->parent_joint->parent_to_joint_origin_transform.position.y << " ";
00411     os << (*child)->parent_joint->parent_to_joint_origin_transform.position.z;
00412     os << "\" rpy=\"" << r << " " << p << " " << y << " " << "\"/>" << endl;
00413     os << "    <axis   xyz=\"" <<  (*child)->parent_joint->axis.x << " ";
00414     os << (*child)->parent_joint->axis.y << " " << (*child)->parent_joint->axis.z << "\"/>" << endl;
00415     {
00416       boost::shared_ptr<urdf::Joint> jt((*child)->parent_joint);
00417 
00418       if ( !!jt->limits ) {
00419         os << "    <limit ";
00420         os << "lower=\"" << jt->limits->lower << "\"";
00421         os << " upper=\"" << jt->limits->upper << "\"";
00422         os << " effort=\"" << jt->limits->effort << "\"";
00423         os << " velocity=\"" << jt->limits->velocity << "\"";
00424         os << " />" << endl;
00425       }
00426       if ( !!jt->dynamics ) {
00427         os << "    <dynamics ";
00428         os << "damping=\"" << jt->dynamics->damping << "\"";
00429         os << " friction=\"" << jt->dynamics->friction << "\"";
00430         os << " />" << endl;
00431       } else {
00432         os << "    <dynamics ";
00433         os << "damping=\"0.1\"";
00434         os << " friction=\"0\"";
00435         os << " />" << endl;
00436       }
00437       // <safty_controller />
00438     }
00439 
00440     os << "  </joint>" << endl;
00441 
00442     if ( add_gazebo_description ) {
00443       os << "  <transmission type=\"pr2_mechanism_model/SimpleTransmission\" name=\"";
00444       os << (*child)->parent_joint->name << "_trans \">" << endl;
00445       os << "    <actuator name=\"" << (*child)->parent_joint->name << "_motor\" />" << endl;
00446       os << "    <joint name=\"" << (*child)->parent_joint->name << "\" />" << endl;
00447       os << "    <mechanicalReduction>1</mechanicalReduction>" << endl;
00448       //os << "    <motorTorqueConstant>1</motorTorqueConstant>" << endl;
00449       //os << "    <pulsesPerRevolution>90000</pulsesPerRevolution>" << endl;
00450       os << "  </transmission>" << endl;
00451     }
00452     addChildJointNamesXML(*child, os);
00453   }
00454 }
00455 
00456 void printTreeXML(boost::shared_ptr<const Link> link, string name, string file)
00457 {
00458   std::ofstream os;
00459   os.open(file.c_str());
00460   os << "<?xml version=\"1.0\"?>" << endl;
00461   os << "<robot name=\"" << name << "\"" << endl;
00462   os << "       xmlns:xi=\"http://www.w3.org/2001/XInclude\"" << endl;
00463   os << "       xmlns:gazebo=\"http://playerstage.sourceforge.net/gazebo/xmlschema/#gz\"" << endl;
00464   os << "       xmlns:model=\"http://playerstage.sourceforge.net/gazebo/xmlschema/#model\"" << endl;
00465   os << "       xmlns:sensor=\"http://playerstage.sourceforge.net/gazebo/xmlschema/#sensor\"" << endl;
00466   os << "       xmlns:body=\"http://playerstage.sourceforge.net/gazebo/xmlschema/#body\"" << endl;
00467   os << "       xmlns:geom=\"http://playerstage.sourceforge.net/gazebo/xmlschema/#geom\"" << endl;
00468   os << "       xmlns:joint=\"http://playerstage.sourceforge.net/gazebo/xmlschema/#joint\"" << endl;
00469   os << "       xmlns:interface=\"http://playerstage.sourceforge.net/gazebo/xmlschema/#interface\"" << endl;
00470   os << "       xmlns:rendering=\"http://playerstage.sourceforge.net/gazebo/xmlschema/#rendering\"" << endl;
00471   os << "       xmlns:renderable=\"http://playerstage.sourceforge.net/gazebo/xmlschema/#renderable\"" << endl;
00472   os << "       xmlns:controller=\"http://playerstage.sourceforge.net/gazebo/xmlschema/#controller\"" << endl;
00473   os << "       xmlns:physics=\"http://playerstage.sourceforge.net/gazebo/xmlschema/#physics\">" << endl;
00474 
00475   addChildLinkNamesXML(link, os);
00476 
00477   addChildJointNamesXML(link, os);
00478 
00479   if ( add_gazebo_description ) {
00480 #ifdef GAZEBO_1_0
00481     // old gazebo (gazebo on ROS Fuerte)
00482     os << " <gazebo>" << endl;
00483     os << "   <controller:gazebo_ros_controller_manager" << endl;
00484     os << "      name=\"gazebo_ros_controller_manager\"" << endl;
00485     os << "      plugin=\"libgazebo_ros_controller_manager.so\">" << endl;
00486     os << "     <alwaysOn>true</alwaysOn>" << endl;
00487     os << "     <updateRate>1000.0</updateRate>" << endl;
00488     os << "   </controller:gazebo_ros_controller_manager>" << endl;
00489     os << "  </gazebo>" << endl;
00490 #endif
00491 #ifdef GAZEBO_1_3
00492     // for drcsim 1.3 and gazebo 1.3
00493     os << "  <gazebo>" << endl;
00494     os << "    <!--plugin filename=\"libMultiSenseSLPlugin.so\" name=\"multisense_plugin\" /-->" << endl;
00495     os << "    <!--plugin filename=\"libAtlasPlugin.so\" name=\"atlas_plugin\"/-->" << endl;
00496     os << "    <plugin filename=\"libgazebo_ros_joint_trajectory.so\" name=\"joint_trajectory_plugin\">" << endl;
00497     os << "      <topicName>joint_trajectory</topicName>" << endl;
00498     os << "      <updateRate>1000.0</updateRate>" << endl;
00499     os << "    </plugin>" << endl;
00500     os << "    <plugin filename=\"libgazebo_ros_controller_manager.so\" name=\"gazebo_ros_controller_manager\">" << endl;
00501     os << "      <alwaysOn>true</alwaysOn>" << endl;
00502     os << "      <updateRate>1000.0</updateRate>" << endl;
00503     os << "    </plugin>" << endl;
00504     os << "  </gazebo>" << endl;
00505 #endif
00506   }
00507 
00508   os << "</robot>" << endl;
00509   os.close();
00510 }
00511 
00512 namespace po = boost::program_options;
00513 // using namespace std;
00514 
00515 int main(int argc, char** argv)
00516 {
00517   string inputfile;
00518 
00519   po::options_description desc("Options for collada_to_urdf");
00520   desc.add_options()
00521     ("help", "produce help message")
00522     ("simple_visual,V", "use bounding box for visual")
00523     ("simple_collision,C", "use bounding box for collision")
00524     ("export_collision_mesh", "export collision mesh as STL")
00525     ("add_gazebo_description,G", "add description for using on gazebo")
00526     ("use_assimp_export,A", "use assimp library for exporting mesh")
00527     ("use_collision,U", "use collision geometry (default collision is the same as visual)")
00528     ("original_inertia_rotation,R", "does not rotate inertia frame")
00529     ("robot_name,N", po::value< vector<string> >(), "output robot name")
00530     ("mesh_output_dir", po::value< vector<string> >(), "directory for outputing")
00531     ("mesh_prefix", po::value< vector<string> >(), "prefix of mesh files")
00532     ("output_file,O", po::value< vector<string> >(), "output file")
00533     ("input_file", po::value< vector<string> >(), "input file")
00534     ;
00535 
00536   po::positional_options_description p;
00537   p.add("input_file", -1);
00538 
00539   po::variables_map vm;
00540   try {
00541     po::store(po::command_line_parser(argc, argv).
00542               options(desc).positional(p).run(), vm);
00543     po::notify(vm);
00544   }
00545   catch (po::error e) {
00546     cerr << ";; option parse error / " << e.what() << endl;
00547     return 1;
00548   }
00549 
00550   if (vm.count("help")) {
00551     cout << desc << "\n";
00552     return 1;
00553   }
00554   if (vm.count("simple_visual")) {
00555     use_simple_visual = true;
00556     cerr << ";; Using simple_visual" << endl;
00557   }
00558   if (vm.count("simple_collision")) {
00559     use_simple_collision = true;
00560     cerr << ";; Using simple_collision" << endl;
00561   }
00562   if (vm.count("add_gazebo_description")) {
00563     add_gazebo_description = true;
00564     cerr << ";; Adding gazebo description" << endl;
00565   }
00566   if (vm.count("use_assimp_export")) {
00567     use_assimp_export = true;
00568     cerr << ";; Use assimp export" << endl;
00569   }
00570   if (vm.count("original_inertia_rotation")) {
00571     rotate_inertia_frame = false;
00572     cerr << ";; Does not rotate inertia frame" << endl;
00573   }
00574   if (vm.count("export_collision_mesh")) {
00575     export_collision_mesh = true;
00576     cerr << ";; erxport collision mesh as STL" << endl;
00577   }
00578   if (vm.count("output_file")) {
00579     vector<string> aa = vm["output_file"].as< vector<string> >();
00580     cerr << ";; output file is: "
00581          <<  aa[0] << endl;
00582     output_file = aa[0];
00583   }
00584   if (vm.count("robot_name")) {
00585     vector<string> aa = vm["robot_name"].as< vector<string> >();
00586     cerr << ";; robot_name is: "
00587          <<  aa[0] << endl;
00588     arobot_name = aa[0];
00589   }
00590   if (vm.count("mesh_prefix")) {
00591     vector<string> aa = vm["mesh_prefix"].as< vector<string> >();
00592     cerr << ";; mesh_prefix is: "
00593          <<  aa[0] << endl;
00594     mesh_prefix = aa[0];
00595   }
00596   if (vm.count("mesh_output_dir")) {
00597     vector<string> aa = vm["mesh_output_dir"].as< vector<string> >();
00598     cerr << ";; Mesh output directory is: "
00599          <<  aa[0] << endl;
00600     mesh_dir = aa[0];
00601     // check directory existence
00602     boost::filesystem::path mpath( mesh_dir );
00603     try {
00604       if ( ! boost::filesystem::is_directory(mpath) ) {
00605         boost::filesystem::create_directory ( mpath );
00606       }
00607     }
00608     catch ( boost::filesystem::filesystem_error e ) {
00609       cerr << ";; mesh output directory error / " << e.what() << endl;
00610       return 1;
00611     }
00612   }
00613   if (vm.count("input_file")) {
00614     vector<string> aa = vm["input_file"].as< vector<string> >();
00615     cerr << ";; Input file is: "
00616          <<  aa[0] << endl;
00617     inputfile = aa[0];
00618   }
00619 
00620   std::string xml_string;
00621   std::fstream xml_file(inputfile.c_str(), std::fstream::in);
00622   while ( xml_file.good() )
00623   {
00624     std::string line;
00625     std::getline( xml_file, line);
00626     xml_string += (line + "\n");
00627   }
00628   xml_file.close();
00629 
00630   boost::shared_ptr<ModelInterface> robot;
00631   if( xml_string.find("<COLLADA") != std::string::npos )
00632   {
00633     ROS_DEBUG("Parsing robot collada xml string");
00634     robot = parseCollada(xml_string);
00635   }
00636   else
00637   {
00638     ROS_DEBUG("Parsing robot urdf xml string");
00639     robot = parseURDF(xml_string);
00640   }
00641 
00642   if (!robot){
00643     std::cerr << "ERROR: Model Parsing the xml failed" << std::endl;
00644     return -1;
00645   }
00646 
00647   if (arobot_name == "") {
00648     arobot_name = robot->getName();
00649   }
00650   if (output_file == "") {
00651     output_file =  arobot_name + ".urdf";
00652   }
00653   printTreeXML (robot->getRoot(), arobot_name, output_file);
00654 
00655   return 0;
00656 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Friends Defines


collada_tools
Author(s): Yohei Kakiuchi (youhei@jsk.t.u-tokyo.ac.jp)
autogenerated on Sat Mar 23 2013 19:48:48