22 #define BOOST_NO_SCOPED_ENUMS
23 #define BOOST_NO_CXX11_SCOPED_ENUMS
35 #include <VirtualRobot/XML/BaseIO.h>
36 #include <VirtualRobot/Visualization/CoinVisualization/CoinVisualizationFactory.h>
37 #include <VirtualRobot/Visualization/VisualizationNode.h>
39 #include <SimoxUtility/algorithm/string/string_tools.h>
41 #include <Inventor/lists/SbStringList.h>
47 namespace fs = std::filesystem;
53 SimoxSceneImporter::SimoxSceneImporter() :
54 TEMPDIR(
"simoxsceneimport__tmp"),
55 LONGTERM_SNAPSHOT_PREFIX(
"Snapshot_")
72 filesDBName = getProperty<std::string>(
"FilesDbName").getValue();
73 sceneFile = getProperty<std::string>(
"SceneFile").getValue();
74 snapshotName = getProperty<std::string>(
"SnapshotName").getValue();
78 dataBasePrx = getProxy<CommonStorageInterfacePrx>(
"CommonStorage");
80 longtermMemoryPrx = getProxy<LongtermMemoryInterfacePrx>(
"LongtermMemory");
82 memoryPrx = getProxy<WorkingMemoryInterfacePrx>(
"WorkingMemory");
83 objectInstancesMemoryPrx = memoryPrx->getObjectInstancesSegment();
85 priorKnowledgePrx = getProxy<PriorKnowledgeInterfacePrx>(
"PriorKnowledge");
86 classesSegmentPrx = priorKnowledgePrx->getObjectClassesSegment();
90 ScenePtr scene = loadSceneFromXML(sceneFile);
94 ARMARX_ERROR <<
"Error loading file " << sceneFile <<
" Aborting.";
100 if (!importScene(scene))
102 ARMARX_ERROR <<
"Error importing " << sceneFile <<
" Aborting.";
106 std::string prefixedSnapshotName = snapshotName;
111 prefixedSnapshotName = std::string(SimoxSceneImporter::LONGTERM_SNAPSHOT_PREFIX) + snapshotName;
112 ARMARX_WARNING <<
"Snapshot name must start with <" << SimoxSceneImporter::LONGTERM_SNAPSHOT_PREFIX <<
">. Changing to " << prefixedSnapshotName;
115 if (longtermMemoryPrx->saveWorkingMemorySnapshot(prefixedSnapshotName, memoryPrx))
117 ARMARX_INFO <<
"Snapshot " << prefixedSnapshotName <<
" saved. Import complete!";
123 fs::path fpath(fileName);
125 if (!fs::exists(fpath))
127 ARMARX_ERROR <<
"File " << fileName <<
" does not exist! Aborting.";
135 scene = SceneIO::loadScene(fileName);
137 catch (VirtualRobotException& e)
139 ARMARX_ERROR <<
"Could not load " << fileName <<
"\n\t" << e.what();
149 if (!scene || !objectInstancesMemoryPrx)
155 std::string prefixedSnapshotName = std::string(memoryx::PRIOR_COLLECTION_PREFIX) + snapshotName;
156 fs::path tmpImportDirectory = fs::path(SimoxSceneImporter::TEMPDIR) / fs::path(prefixedSnapshotName);
158 fs::remove_all(tmpImportDirectory);
159 fs::create_directories(tmpImportDirectory);
171 size_t robotCount = scene->getRobots().size();
175 ARMARX_WARNING <<
"Skipping " << robotCount <<
" robot defintions in scene file. Robots are not processed!";
179 std::map<VirtualRobot::ObstaclePtr, ObjectInstanceBasePtr> objectInstances;
181 int objectInstanceCount = createObjectInstances<ObstaclePtr>(tmpScene->getObstacles(), objectInstances);
183 objectInstanceCount += createObjectInstances<ManipulationObjectPtr>(tmpScene->getManipulationObjects(), objectInstances);
185 importObjectsIntoPriorKnowledge(objectInstances);
187 for (
auto instancePair : objectInstances)
189 objectInstancesMemoryPrx->addEntity(instancePair.second);
192 ARMARX_INFO <<
"Added " << objectInstanceCount <<
" instances to working memory";
206 std::stringstream ss;
207 ss <<
"<Scene name='" << scene->getName() <<
"'>\n\n";
209 fs::path sceneFileComplete = sceneFile;
210 std::string scenePath = sceneFileComplete.parent_path().c_str();
211 fs::path sceneFileNew = tmpPath / sceneFileComplete.filename();
214 std::vector<ObstaclePtr> obstacles = scene->getObstacles();
216 std::vector<ManipulationObjectPtr> manipulationObjects = scene->getManipulationObjects();
217 obstacles.insert(obstacles.end(), manipulationObjects.begin(), manipulationObjects.end());
220 for (ObstaclePtr obstacle : obstacles)
222 std::vector<std::string> absoluteVisualizationFilenames;
225 getAbsoluteVisualizationFilenames(obstacle, absoluteVisualizationFilenames);
228 std::map<std::string, std::string> newFilenames;
229 copyFilesToTempDir(absoluteVisualizationFilenames, tmpPath, scenePath, newFilenames);
232 setNewVisualizationFilenames(obstacle, newFilenames);
235 std::string origFilename = obstacle->getFilename();
237 if (origFilename.empty())
240 origFilename += obstacle->getName();
241 origFilename +=
".xml";
245 fs::path localFile = tmpPath / fs::path(origFilename).filename();
246 std::string localTmpFile = localFile.string();
247 ARMARX_INFO <<
"Saving modified ManipulationObject to " << localTmpFile <<
" (original file: " << scenePath <<
"/" << origFilename <<
")";
249 fs::path absPath = fs::absolute(tmpPath);
250 saveObstacleAsManipulationObject(obstacle, localTmpFile, absPath.string());
253 ss <<
"\t<ManipulationObject name='" << obstacle->getName() <<
"'>\n";
254 ss <<
"\t\t<File>" << localFile.filename().string() <<
"</File>\n";
255 ss << obstacle->getPhysics().toXML(2);
256 ss <<
"\t</ManipulationObject>\n\n";
262 ARMARX_LOG <<
"Saving scenefile from " << sceneFile <<
" to " << sceneFileNew.c_str();
263 std::string sceneString = ss.str();
264 BaseIO::writeXMLFile(sceneFileNew.c_str(), sceneString,
true);
266 return SceneIO::loadScene(sceneFileNew.string());
270 void SimoxSceneImporter::getAbsoluteVisualizationFilenames(ObstaclePtr obstacle, std::vector<std::string>& absoluteFilenames)
272 if (obstacle->getVisualization())
274 SoNode* visuNode = CoinVisualizationFactory::getCoinVisualization(obstacle->getVisualization());
277 std::string visuFile = obstacle->getVisualization()->getFilename();
279 if (!visuFile.empty())
281 absoluteFilenames.push_back(visuFile);
285 if (obstacle->getCollisionModel() && obstacle->getCollisionModel()->getVisualization())
287 SoNode* colNode = CoinVisualizationFactory::getCoinVisualization(obstacle->getCollisionModel()->getVisualization());
289 std::string visuFile = obstacle->getCollisionModel()->getVisualization()->getFilename();
291 if (!visuFile.empty())
293 absoluteFilenames.push_back(visuFile);
299 void SimoxSceneImporter::copyFilesToTempDir(
const std::vector<std::string>&
files,
const std::string& tmpPath,
const std::string& origPath, std::map<std::string, std::string>& newFilenameMapping)
301 fs::path tmpDir = tmpPath;
303 for (
size_t i = 0; i <
files.size(); i++)
305 fs::path origFile =
files[i];
306 std::string relativePath = fs::absolute(
files[i]).string();
307 VirtualRobot::BaseIO::makeRelativePath(fs::absolute(origPath).
string(), relativePath);
308 fs::path tmpFile = tmpDir / fs::path(relativePath);
311 <<
"\n -> relPathS:" << relativePath
312 <<
"\n -> tmpFile:" << tmpFile.c_str();
314 if (!fs::exists(origFile))
316 ARMARX_ERROR <<
"File does not exist:" << origFile.c_str();
320 if (!fs::is_regular_file(origFile))
322 ARMARX_ERROR <<
"Not a regular file: " << origFile.c_str();
326 if (fs::is_directory(origFile))
328 ARMARX_ERROR <<
"File is a directory:" << origFile.c_str();
332 ARMARX_LOG <<
"Copying file from " << origFile.c_str() <<
" to " << tmpFile.c_str();
333 fs::create_directories(tmpFile.parent_path());
339 fs::copy_file(origFile, tmpFile, fs::copy_options::overwrite_existing);
340 newFilenameMapping[origFile.string()] = fs::absolute(tmpFile).string();
345 void SimoxSceneImporter::setNewVisualizationFilenames(ObstaclePtr obstacle, std::map<std::string, std::string>& newFilenames)
347 if (obstacle->getVisualization())
349 std::string visuFile = obstacle->getVisualization()->getFilename();
350 std::string newVisuFile = newFilenames[visuFile];
352 if (!newVisuFile.empty())
354 obstacle->getVisualization()->setFilename(newVisuFile, obstacle->getVisualization()->usedBoundingBoxVisu());
358 if (obstacle->getCollisionModel() && obstacle->getCollisionModel()->getVisualization())
360 std::string visuFile = obstacle->getCollisionModel()->getVisualization()->getFilename();
361 std::string newVisuFile = newFilenames[visuFile];
363 if (!newVisuFile.empty())
365 obstacle->getCollisionModel()->getVisualization()->setFilename(newVisuFile, obstacle->getCollisionModel()->getVisualization()->usedBoundingBoxVisu());
366 ARMARX_INFO <<
" COLLISION> " << obstacle->getCollisionModel()->getVisualization()->getFilename();
372 bool SimoxSceneImporter::saveObstacleAsManipulationObject(ObstaclePtr
object,
const std::string& xmlFile,
const std::string& tmpPath)
374 THROW_VR_EXCEPTION_IF(!
object,
"NULL object");
376 std::string xmlString =
object->toXML(tmpPath);
379 ManipulationObject* manip =
dynamic_cast<ManipulationObject*
>(
object.get());
383 xmlString = manip->toXML(tmpPath);
387 xmlString = simox::alg::replace_all(xmlString,
"<Obstacle",
"<ManipulationObject");
388 xmlString = simox::alg::replace_all(xmlString,
"</Obstacle",
"</ManipulationObject");
390 return BaseIO::writeXMLFile(xmlFile, xmlString,
true);
394 template <
typename T>
395 int SimoxSceneImporter::createObjectInstances(std::vector<T> obstacles, std::map<ObstaclePtr, ObjectInstanceBasePtr>& objectInstances)
399 for (
size_t i = 0; i < obstacles.size(); i++)
401 T obstacle = obstacles[i];
402 ObjectInstanceBasePtr obstacleInstance = createInstance(obstacle);
404 if (obstacle && obstacleInstance)
406 objectInstances[obstacle] = obstacleInstance;
415 ObjectInstanceBasePtr SimoxSceneImporter::createInstance(
SceneObjectPtr sceneObject)
422 std::string objectName = sceneObject->getName();
425 objectInstance->setExistenceCertainty(1.0f);
428 objectInstance->setClass(objectName, 1.0f);
431 Eigen::Vector3f position = sceneObject->getGlobalPose().block(0, 3, 3, 1);
433 objectInstance->setPosition(objectPosition);
437 objectInstance->setOrientation(objectOrientation);
439 return objectInstance;
443 void SimoxSceneImporter::importObjectsIntoPriorKnowledge(std::map<VirtualRobot::ObstaclePtr, ObjectInstanceBasePtr>& objectInstances)
447 std::map<VirtualRobot::ObstaclePtr, ObjectInstanceBasePtr>::iterator it;
449 for (it = objectInstances.begin(); it != objectInstances.end(); it++)
451 Obstacle* obstacle = it->first.get();
453 ManipulationObject* manip =
dynamic_cast<ManipulationObject*
>(obstacle);
460 std::string simoxFilename = obstacle->getFilename();
462 fs::path visuFName = obstacle->getVisualization()->getFilename();
463 fs::path collisionFName = obstacle->getCollisionModel()->getVisualization()->getFilename();
465 if (collisionFName.empty())
467 collisionFName = visuFName;
472 newClass->setName(obstacle->getName());
475 ARMARX_INFO <<
"Store file: " << visuFName.string();
477 ARMARX_INFO <<
"visuFName.string(): " << visuFName.string();
478 ARMARX_INFO <<
"collisionFName.string(): " << collisionFName.string();
479 simoxWrapper->setAndStoreManipulationFile(simoxFilename, filesDBName);
481 EntityBasePtr ent = classesSegmentPrx->getEntityByName(newClass->getName());
485 ARMARX_IMPORTANT <<
"Updating existing entity " << ent->getName() <<
"(Id: " << ent->getId() <<
")";
486 classesSegmentPrx->updateEntity(ent->getId(), ent);
490 classesSegmentPrx->addEntity(newClass);