00001
00002
00003
00004
00005
00006
00007 #include <urdf/model.h>
00008 #include <iostream>
00009 #include <fstream>
00010 using namespace std;
00011
00012
00013 #define INTENDATION_STEP 4 // how much blanks are used as one intendation step in XML file
00014 #define HTTP "http:/"
00015 #define SRDL_COMP_URI "/ias.cs.tum.edu/kb/srdl2-comp.owl"
00016 #define SRDL_COMP "srdl2comp"
00017 #define HAS_SUCCEEDING_LINK_NAME "succeedingLink"
00018 #define HAS_SUCCEEDING_JOINT_NAME "succeedingJoint"
00019 #define HAS_SUCCESSOR_NAME "successorInKinematicChain"
00020 #define LINK_NAME "UrdfLink"
00021 #define JOINT_NAME "UrdfJoint"
00022 #define REVOLUTE_JOINT_NAME "RevoluteUrdfJoint"
00023 #define CONTINUOUS_JOINT_NAME "ContinuousUrdfJoint"
00024 #define PRISMATIC_JOINT_NAME "PrismaticUrdfJoint"
00025 #define FIXED_JOINT_NAME "FixedUrdfJoint"
00026 #define FLOATING_JOINT_NAME "FloatingUrdfJoint"
00027 #define PLANAR_JOINT_NAME "PlanarUrdfJoint"
00028 #define HAS_URDF_NAME "urdfName"
00029
00030
00031 class urdfImporter{
00032
00033
00034 string ontologyFilename;
00035 string ontologyUri;
00036 string srdlUri;
00037 string urdfFilename;
00038 urdf::Model model;
00039 ofstream out;
00040 string namePrefix;
00041
00042 public:
00043
00044
00045 int controllMethod(int argc, char** argv) {
00046
00047
00048
00049 ros::init(argc, argv, "urdfConverter");
00050
00051
00052 ROS_INFO("Parsing URDF file ...");
00053 urdfFilename = argv[1];
00054 if (!model.initFile(urdfFilename)){
00055 ROS_ERROR("Failed to parse urdf file");
00056 ROS_ERROR("Please make sure to provide a valid urdf file");
00057 ROS_ERROR("Urdf files can be checked with the ROS command 'rosrun urdf check_urdf my_urdf.xml'");
00058 return -1;
00059 }
00060 ROS_INFO("Successfully parsed urdf file");
00061
00062
00063
00064 cout << "Please enter file name of ontology file: ";
00065 getline(cin, ontologyFilename);
00066
00067 out.open(ontologyFilename.c_str());
00068
00069
00070
00071 writeHeader();
00072
00073
00074 ROS_INFO("Writing urdf model ...");
00075 writeModel();
00076
00077
00078
00079 writeFooter();
00080
00081
00082 out.close();
00083 ROS_INFO("Ontology file has been written.");
00084 return 0;
00085 }
00086
00087
00088 void writeHeader() {
00089
00090
00091
00092 cout << "Please enter ontology url: ";
00093 getline(cin, ontologyUri);
00094
00095
00096
00097 cout << "Please enter the path to the srdl2-cap.owl ontology: ";
00098 getline(cin, srdlUri);
00099
00100
00101 out << "<?xml version=\"1.0\"?>\n\n";
00102 out << "<!DOCTYPE rdf:RDF [ \n" <<
00103 " <!ENTITY owl \"http://www.w3.org/2002/07/owl#\" >\n" <<
00104 " <!ENTITY " << SRDL_COMP << " \"" << HTTP << SRDL_COMP_URI << "#\" >\n" <<
00105 " <!ENTITY rdf \"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" >\n" <<
00106 " <!ENTITY rdfs \"http://www.w3.org/2000/01/rdf-schema#\">\n" <<
00107 "]>\n\n";
00108 out << "<rdf:RDF xmlns=\"" << ontologyUri << "#\"\n" <<
00109 " xml:base=\"" << ontologyUri << "\"\n" <<
00110 " xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n" <<
00111 " xmlns:owl=\"http://www.w3.org/2002/07/owl#\"\n" <<
00112 " xmlns:rdfs=\"http://www.w3.org/2000/01/rdf-schema#\"\n" <<
00113 " xmlns:" << SRDL_COMP << "=\"" << HTTP << SRDL_COMP_URI << "#\">\n\n";
00114 out << " <owl:Ontology rdf:about=\"\"> \n" <<
00115 " <owl:imports rdf:resource=\"file://" << srdlUri << "\"/>\n" <<
00116 " </owl:Ontology>\n\n";
00117 }
00118
00119
00120 void writeToStreamIntended(string line, int intendation) {
00121
00122
00123 for (int i=0; i<intendation; i++) {
00124 out << " ";
00125 }
00126
00127
00128 out << line;
00129 out << "\n";
00130 }
00131
00132
00133 void writeModel() {
00134
00135
00136 cout << "Please enter a prefix that will be put in front of all instance names: ";
00137 getline(cin, namePrefix);
00138
00139
00140
00141 out << " <!--\n" <<
00142 " ///////////////////////////////////////////////////////////////////////////////////////\n" <<
00143 " //\n" <<
00144 " // Datatype Properties\n" <<
00145 " //\n" <<
00146 " ///////////////////////////////////////////////////////////////////////////////////////\n" <<
00147 " -->\n\n";
00148
00149 out << " <!-- " << HTTP << SRDL_COMP_URI << "#" << HAS_URDF_NAME << " -->\n" <<
00150 " <owl:DatatypeProperty rdf:about=\"&" << SRDL_COMP << ";" << HAS_URDF_NAME << "\"/>\n\n";
00151
00152
00153 out << " <!--\n" <<
00154 " ///////////////////////////////////////////////////////////////////////////////////////\n" <<
00155 " //\n" <<
00156 " // Object Properties\n" <<
00157 " //\n" <<
00158 " ///////////////////////////////////////////////////////////////////////////////////////\n" <<
00159 " -->\n\n";
00160
00161 out << " <!-- " << HTTP << SRDL_COMP_URI << "#" << HAS_SUCCESSOR_NAME << " -->\n" <<
00162 " <owl:ObjectProperty rdf:about=\"&" << SRDL_COMP << ";" << HAS_SUCCESSOR_NAME << "\"/>\n\n";
00163
00164 out << " <!-- " << HTTP << SRDL_COMP_URI << "#" << HAS_SUCCEEDING_JOINT_NAME << " -->\n" <<
00165 " <owl:ObjectProperty rdf:about=\"&" << SRDL_COMP << ";" << HAS_SUCCEEDING_JOINT_NAME << "\"/>\n\n";
00166
00167 out << " <!-- " << HTTP << SRDL_COMP_URI << "#" << HAS_SUCCEEDING_LINK_NAME << " -->\n" <<
00168 " <owl:ObjectProperty rdf:about=\"&" << SRDL_COMP << ";" << HAS_SUCCEEDING_LINK_NAME << "\"/>\n\n";
00169
00170 out << " <!--\n" <<
00171 " ///////////////////////////////////////////////////////////////////////////////////////\n" <<
00172 " //\n" <<
00173 " // Individuals\n" <<
00174 " //\n" <<
00175 " ///////////////////////////////////////////////////////////////////////////////////////\n" <<
00176 " -->\n\n\n";
00177
00178
00179 map<string, boost::shared_ptr<urdf::Link> > linkMap = model.links_;
00180 map<string, boost::shared_ptr<urdf::Link> >::iterator it_link;
00181 string linkKey, linkName;
00182 boost::shared_ptr<urdf::Link> linkPtr;
00183 vector<boost::shared_ptr<urdf::Joint> > childJoints;
00184 boost::shared_ptr<urdf::Joint> jointPtr;
00185 string jointName;
00186 unsigned int j;
00187 for(it_link = linkMap.begin(); it_link != linkMap.end(); it_link++) {
00188
00189 linkKey = (*it_link).first;
00190 linkName = namePrefix + linkKey;
00191 linkPtr = (*it_link).second;
00192 childJoints = linkPtr->child_joints;
00193
00194
00195
00196 out << " <!-- " << ontologyUri << "#" << linkName << " -->\n";
00197
00198 out << " <owl:NamedIndividual rdf:about=\"#" << linkName << "\">\n";
00199
00200 out << " <rdf:type rdf:resource=\"&" << SRDL_COMP << ";" << LINK_NAME << "\"/>\n";
00201
00202 out << " <" << SRDL_COMP << ":" << HAS_URDF_NAME << ">" << linkKey << "</" << SRDL_COMP << ":" << HAS_URDF_NAME << ">\n" ;
00203
00204
00205 for(j=0; j < childJoints.size(); j++) {
00206 jointPtr = childJoints[j];
00207 jointName = namePrefix + jointPtr->name;
00208
00209
00210 out << " <" << SRDL_COMP << ":" << HAS_SUCCEEDING_JOINT_NAME << " rdf:resource=\"#" << jointName << "\"/>\n";
00211
00212 }
00213
00214
00215 out << " </owl:NamedIndividual>\n\n";
00216 }
00217
00218
00219 map<string, boost::shared_ptr<urdf::Joint> > jointMap = model.joints_;
00220 map<string, boost::shared_ptr<urdf::Joint> >::iterator it_joint;
00221 string jointKey;
00222 string childLinkName;
00223 int jointType;
00224 string jointTypeName;
00225 for(it_joint = jointMap.begin(); it_joint != jointMap.end(); it_joint++) {
00226
00227 jointKey = (*it_joint).first;
00228 jointName = namePrefix + jointKey;
00229 jointPtr = (*it_joint).second;
00230 childLinkName = namePrefix + jointPtr->child_link_name;
00231 jointType = jointPtr->type;
00232
00233
00234 switch (jointType)
00235 {
00236 case 1:
00237 jointTypeName = REVOLUTE_JOINT_NAME;
00238 break;
00239 case 2:
00240 jointTypeName = CONTINUOUS_JOINT_NAME;
00241 break;
00242 case 3:
00243 jointTypeName = PRISMATIC_JOINT_NAME;
00244 break;
00245 case 4:
00246 jointTypeName = FLOATING_JOINT_NAME;
00247 break;
00248 case 5:
00249 jointTypeName = PLANAR_JOINT_NAME;
00250 break;
00251 case 6:
00252 jointTypeName = FIXED_JOINT_NAME;
00253 break;
00254 default:
00255 jointTypeName = JOINT_NAME;
00256 }
00257
00258
00259
00260 out << " <!-- " << ontologyUri << "#" << jointName << " -->\n";
00261
00262 out << " <owl:NamedIndividual rdf:about=\"#" << jointName << "\">\n";
00263
00264 out << " <rdf:type rdf:resource=\"&" << SRDL_COMP << ";" << jointTypeName << "\"/>\n";
00265
00266 out << " <" << SRDL_COMP << ":" << HAS_URDF_NAME << ">" << jointKey << "</" << SRDL_COMP << ":" << HAS_URDF_NAME << ">\n" ;
00267
00268 out << " <" << SRDL_COMP << ":" << HAS_SUCCEEDING_LINK_NAME << " rdf:resource=\"#" << childLinkName << "\"/>\n";
00269
00270
00271 out << " </owl:NamedIndividual>\n\n";
00272 }
00273 }
00274
00275 void printAllLinks(urdf::Model &model) {
00276 cout << "Iterating over links\n";
00277 map<string, boost::shared_ptr<urdf::Link> > linkMap = model.links_;
00278 map<string, boost::shared_ptr<urdf::Link> >::iterator it;
00279 for (it = linkMap.begin(); it != linkMap.end(); it++) {
00280 cout << (*it).first << " => " << (*it).second << endl;
00281 }
00282 }
00283
00284
00285
00286 void writeFooter(){
00287 out << "</rdf:RDF>";
00288 }
00289
00290 };
00291
00292
00293 int main(int argc, char** argv){
00294
00295
00296 if (argc != 2){
00297 ROS_ERROR("Need a urdf file as argument");
00298 return -1;
00299 }
00300
00301
00302 int feedback;
00303 urdfImporter c;
00304 feedback = c.controllMethod(argc, argv);
00305 return feedback;
00306 }
00307