00001
00021 #define BOOST_NO_CXX11_SCOPED_ENUMS
00022
00023 #include <ros/ros.h>
00024 #include <ros/package.h>
00025 #include <boost/foreach.hpp>
00026 #include <boost/filesystem.hpp>
00027 #include <ros_uri/ros_uri.hpp>
00028 #include "object_database/ObjectDatabase.h"
00029 #include "object_database/ObjectDatabaseRecognizer.h"
00030 #include <boost/regex.hpp>
00031 #include <boost/algorithm/string.hpp>
00032
00033 namespace object_database
00034 {
00035 ObjectDatabase::ObjectDatabase(fs::path configurationFilePath) :
00036 mGlobalNodeHandle("asr_object_database"),
00037 mConfigurationFilePath(configurationFilePath)
00038 {
00039
00040 mConfig.read(configurationFilePath);
00041
00042
00043 this->readAllObjectDatabaseRecognizers();
00044
00045 mRecognizerListServiceHandle =
00046 mGlobalNodeHandle.advertiseService("recognizer_list",
00047 &ObjectDatabase::processRecognizerListRequest, this);
00048 mObjectTypeListServiceHandle =
00049 mGlobalNodeHandle.advertiseService("object_type_list",
00050 &ObjectDatabase::processObjectTypeListRequest, this);
00051 mObjectMetaDataServiceHandle =
00052 mGlobalNodeHandle.advertiseService("object_meta_data",
00053 &ObjectDatabase::processObjectMetaDataRequest, this);
00054
00055
00056 mRecognizerListMeshesServiceHandle =
00057 mGlobalNodeHandle.advertiseService("recognizer_list_meshes",
00058 &ObjectDatabase::processRecognizerListMeshesRequest, this);
00059
00060 mObjectTypeGeneratorServiceHandle =
00061 mGlobalNodeHandle.advertiseService("generate_object_type",
00062 &ObjectDatabase::processObjectTypeGeneratorRequest, this);
00063
00064 }
00065
00066 bool ObjectDatabase::processRecognizerListRequest(RecognizerList::Request &req,
00067 RecognizerList::Response &res)
00068 {
00069
00070 ObjectDatabaseRecognizerPtrMap objectTypes = mConfig.getObjectCategories();
00071 BOOST_FOREACH(ObjectDatabaseRecognizerPtrMap::value_type mapTuple, objectTypes)
00072 {
00073 res.recognizer_list.push_back(mapTuple.second->getKeyword());
00074 }
00075
00076
00077 std::sort(res.recognizer_list.begin(), res.recognizer_list.end());
00078
00079 return true;
00080 }
00081
00082 bool ObjectDatabase::processObjectTypeListRequest(ObjectTypeList::Request &req,
00083 ObjectTypeList::Response &res)
00084 {
00085
00086 std::string recognizerName = req.recognizer;
00087
00088
00089 ObjectDatabaseRecognizerPtrCollection collection;
00090
00091 if (recognizerName == "all")
00092 {
00093
00094
00095 BOOST_FOREACH(ObjectDatabaseRecognizerPtrMap::value_type mapVal, mConfig.getObjectCategories())
00096 {
00097 collection.push_back(mapVal.second);
00098 }
00099 } else
00100 {
00101
00102 ObjectDatabaseRecognizerPtr recognizerPtr = mConfig.getRecognizer(recognizerName);
00103
00104
00105 ObjectDatabaseRecognizerPtr nullPtr;
00106 if (recognizerPtr == nullPtr)
00107 {
00108 ROS_DEBUG("No object type definition for name '%s' found", recognizerName.c_str());
00109 return false;
00110 }
00111
00112
00113 collection.push_back(recognizerPtr);
00114 }
00115
00116 ROS_DEBUG("Collection contains %lu ObjectTypes", collection.size());
00117
00118
00119 BOOST_FOREACH(ObjectDatabaseRecognizerPtr recognizerPtr, collection)
00120 {
00121
00122 recognizerPtr->readEntries();
00123
00124
00125 ObjectDatabaseEntryPtrMap entryPtrMap = recognizerPtr->getEntries();
00126 BOOST_FOREACH(ObjectDatabaseEntryPtrMapPair entryPtrMapPair, entryPtrMap)
00127 {
00128 res.object_type_list.push_back(entryPtrMapPair.first);
00129 }
00130 }
00131
00132
00133 std::sort(res.object_type_list.begin(), res.object_type_list.end());
00134
00135 ROS_DEBUG("Object List contains %lu items", res.object_type_list.size());
00136 ROS_DEBUG("Reached end of processing object list request");
00137
00138 return true;
00139 }
00140
00141 bool ObjectDatabase::processObjectMetaDataRequest(ObjectMetaData::Request &req, ObjectMetaData::Response &res)
00142 {
00143 ObjectDatabaseRecognizerPtrMap recognizerPtrMap = mConfig.getObjectCategories();
00144 std::string object_type = req.object_type;
00145 std::string recognizer = req.recognizer;
00146
00147
00148 res.object_folder = std::string();
00149 res.is_valid = false;
00150
00151 for(ObjectDatabaseRecognizerPtrMap::value_type val : recognizerPtrMap) {
00152 ObjectDatabaseEntryPtr objectEntryPtr = val.second->getEntry(object_type);
00153 if ((objectEntryPtr) && (objectEntryPtr->getRecognizer()->getKeyword() == recognizer)){
00154 res.object_folder = ros_uri::package_uri(objectEntryPtr->getPath().string(), "asr_object_database");
00155 res.object_mesh_resource = ros_uri::package_uri(objectEntryPtr->getRvizMeshResourcePath().string(), "asr_object_database");
00156 res.normal_vectors = objectEntryPtr->getNormalVectors();
00157 res.deviations = objectEntryPtr->getDeviationsFromFile();
00158 res.is_valid = true;
00159 res.is_rotation_invariant = objectEntryPtr->getRotationInvarianceFromFile();
00160 break;
00161 }
00162 }
00163
00164 return true;
00165 }
00166
00167 bool ObjectDatabase::processRecognizerListMeshesRequest(RecognizerListMeshes::Request &req, RecognizerListMeshes::Response &res) {
00168
00169 std::string recognizerName = req.recognizer;
00170
00171
00172 ObjectDatabaseRecognizerPtrCollection collection;
00173
00174 if (recognizerName == "all")
00175 {
00176
00177
00178 BOOST_FOREACH(ObjectDatabaseRecognizerPtrMap::value_type mapVal, mConfig.getObjectCategories())
00179 {
00180 collection.push_back(mapVal.second);
00181 }
00182 } else
00183 {
00184
00185 ObjectDatabaseRecognizerPtr recognizerPtr = mConfig.getRecognizer(recognizerName);
00186
00187
00188 ObjectDatabaseRecognizerPtr nullPtr;
00189 if (recognizerPtr == nullPtr)
00190 {
00191 ROS_DEBUG("No object type definition for name '%s' found", recognizerName.c_str());
00192 return false;
00193 }
00194
00195
00196 collection.push_back(recognizerPtr);
00197 }
00198
00199 ROS_DEBUG("Collection contains %lu ObjectTypes", collection.size());
00200
00201
00202 BOOST_FOREACH(ObjectDatabaseRecognizerPtr recognizerPtr, collection)
00203 {
00204
00205 recognizerPtr->readEntries();
00206
00207
00208 ObjectDatabaseEntryPtrMap entryPtrMap = recognizerPtr->getEntries();
00209 BOOST_FOREACH(ObjectDatabaseEntryPtrMapPair entryPtrMapPair, entryPtrMap)
00210 {
00211 std::string mesh_path = ros_uri::package_uri(entryPtrMapPair.second->getRvizMeshResourcePath().string(), "asr_object_database");
00212 if (mesh_path != "package://asr_object_database/") {
00213 res.meshes.push_back(mesh_path);
00214 }
00215 }
00216 }
00217
00218
00219 ROS_DEBUG("Object meshes list contains %lu items", res.meshes.size());
00220 ROS_DEBUG("Reached end of processing object meshes request");
00221
00222 return true;
00223 }
00224
00225 bool ObjectDatabase::processObjectTypeGeneratorRequest(ObjectTypeGenerator::Request &req, ObjectTypeGenerator::Response &res)
00226 {
00227
00228 const fs::path sourcepath(req.sourcefile.c_str());
00229 if (!fs::exists(sourcepath))
00230 {
00231 ROS_ERROR("File does not exist.");
00232 return false;
00233 }
00234
00235
00236 std::string fileending = req.sourcefile.substr(req.sourcefile.find_last_of("_"));
00237 if (fileending.compare("_tex.obj") != 0)
00238 {
00239 ROS_ERROR("File has to end with '_tex.obj.'");
00240 return false;
00241 }
00242
00243
00244 std::string::size_type const q(req.sourcefile.find_last_of('.'));
00245 const fs::path mtlSourcePath ((req.sourcefile.substr(0, q) + ".obj.mtl").c_str());
00246 if (!fs::exists(mtlSourcePath))
00247 {
00248 ROS_ERROR("No .mtl file can be found in given directory.");
00249 return false;
00250 }
00251
00252
00253 std::string extfilename = req.sourcefile.substr(req.sourcefile.find_last_of("/\\") + 1);
00254 std::string::size_type const p(extfilename.find_first_of('_'));
00255 std::string filename = extfilename.substr(0, p);
00256
00257
00258 std::string packagepath = ros::package::getPath("asr_object_database");
00259
00260
00261 std::string predestpath = packagepath + "/rsc/databases/textured_objects/" + filename + "/" + filename + ".obj";
00262 const fs::path destpath(predestpath.c_str());
00263
00264 std::string prenewDirectory = packagepath + "/rsc/databases/textured_objects/" + filename;
00265 const fs::path newDirectory(prenewDirectory.c_str());
00266
00267 if (!fs::exists(newDirectory))
00268 {
00269 fs::create_directory(newDirectory);
00270 }
00271
00272 fs::copy_file(sourcepath, destpath, fs::copy_option::overwrite_if_exists);
00273
00274
00275 std::string::size_type const r(extfilename.find_last_of('.'));
00276 std::string premtlDestPath = prenewDirectory + "/" + extfilename.substr(0, r) + ".obj.mtl";
00277 const fs::path mtlDestPath = premtlDestPath.c_str();
00278
00279
00280 fs::copy_file(mtlSourcePath, mtlDestPath, fs::copy_option::overwrite_if_exists);
00281
00282
00283 std::string prepngSourcePath = req.sourcefile.substr(0, q) + ".png";
00284 const fs::path pngSourcePath = prepngSourcePath.c_str();
00285
00286 if (!fs::exists(pngSourcePath))
00287 {
00288 ROS_ERROR("No .png file could be found in the given directory.");
00289 return false;
00290 }
00291
00292
00293 std::string prepngDestPath = prenewDirectory + "/" + extfilename.substr(0, r) + ".png";
00294 const fs::path pngDestPath = prepngDestPath.c_str();
00295
00296
00297 if (!fs::exists(pngDestPath))
00298 {
00299 fs::copy_file(pngSourcePath, pngDestPath);
00300 }
00301
00302
00303 std::string predaefilepath = packagepath + "/rsc/databases/textured_objects/" + filename + "/" + filename + ".dae";
00304 const fs::path daefilepath(predaefilepath.c_str());
00305 if (!fs::exists(daefilepath))
00306 {
00307 std::string databaseFolder = prenewDirectory + "/";
00308 const char *navigateToDatabaseFolder = databaseFolder.c_str();
00309 chdir(navigateToDatabaseFolder);
00310 std::string mlsoutput = filename + ".dae";
00311 const char *meshlabserver = ("meshlabserver -i " + filename+".obj" + " -o " + mlsoutput +
00312 " -om vc vn wt").c_str();
00313 system(meshlabserver);
00314 }
00315 return true;
00316 }
00317
00318 void ObjectDatabase::readAllObjectDatabaseRecognizers()
00319 {
00320 ObjectDatabaseRecognizerPtrMap recognizerMap = mConfig.getObjectCategories();
00321 ROS_DEBUG("Start reading all object types");
00322 BOOST_FOREACH(ObjectDatabaseRecognizerPtrMap::value_type mapValue, recognizerMap)
00323 {
00324 ROS_DEBUG("Reading %s", mapValue.first.c_str());
00325 mapValue.second->readEntries();
00326 }
00327 }
00328 }