diff --git a/VirtualRobot/CMakeLists.txt b/VirtualRobot/CMakeLists.txt index e45cbda8656aedc080df656b4c31bcc140247b02..525131154eba63df6b8c0ba7172cc6e808e4b308 100644 --- a/VirtualRobot/CMakeLists.txt +++ b/VirtualRobot/CMakeLists.txt @@ -77,6 +77,12 @@ XML/RobotIO.cpp XML/SceneIO.cpp XML/ObjectIO.cpp XML/FileIO.cpp +XML/mjcf/exceptions.cpp +XML/mjcf/MasslessBodySanitizer.cpp +XML/mjcf/MjcfDocument.cpp +XML/mjcf/MujocoIO.cpp +XML/mjcf/utils.cpp +XML/mjcf/xml_visitors.cpp IK/IKSolver.cpp IK/AdvancedIKSolver.cpp IK/DifferentialIK.cpp @@ -223,6 +229,12 @@ XML/RobotIO.h XML/SceneIO.h XML/ObjectIO.h XML/FileIO.h +XML/mjcf/exceptions.h +XML/mjcf/MasslessBodySanitizer.h +XML/mjcf/MjcfDocument.h +XML/mjcf/MujocoIO.h +XML/mjcf/utils.h +XML/mjcf/xml_visitors.h IK/IKSolver.h IK/AdvancedIKSolver.h IK/DifferentialIK.h diff --git a/VirtualRobot/XML/RobotIO.cpp b/VirtualRobot/XML/RobotIO.cpp index 6a1c80483cb2022264fd3604f223c9f42e93856d..6feadd35d418aa914a83e9281287bf9ecc923a3d 100644 --- a/VirtualRobot/XML/RobotIO.cpp +++ b/VirtualRobot/XML/RobotIO.cpp @@ -15,6 +15,7 @@ #include "../RobotConfig.h" #include "../RuntimeEnvironment.h" #include "rapidxml.hpp" +#include "mjcf/MujocoIO.h" #include <vector> @@ -1512,6 +1513,24 @@ namespace VirtualRobot } return true; + } + + void RobotIO::saveMJCF(RobotPtr robot, const std::string& filename, + const std::string& basePath, const std::string& meshDir) + { + + + + + + + + + + + + + } diff --git a/VirtualRobot/XML/RobotIO.h b/VirtualRobot/XML/RobotIO.h index e9dd02e86febdff633291ce283bae354bf3ad1d0..b59a213e52d845b0fab0bad2bb030788b5646fa6 100644 --- a/VirtualRobot/XML/RobotIO.h +++ b/VirtualRobot/XML/RobotIO.h @@ -58,19 +58,19 @@ namespace VirtualRobot }; /*! - Loads robot from file. - @param xmlFile The file - @param loadMode Standard: eFull, When eStructure is used no visualization and collision models are loaded for faster access. - @return Returns an empty pointer, when file access failed. + Loads robot from file. + @param xmlFile The file + @param loadMode Standard: eFull, When eStructure is used no visualization and collision models are loaded for faster access. + @return Returns an empty pointer, when file access failed. */ static RobotPtr loadRobot(const std::string& xmlFile, RobotDescription loadMode = eFull); /*! - Creates Robot from string. - @param xmlString The input string. - @param basePath If any \<childFromRobot\> tags are given, the path for searching the robot files can be specified. - @param loadMode Standard: eFull, When eStructure is used no visualization and collision models are loaded for faster access. - */ + Creates Robot from string. + @param xmlString The input string. + @param basePath If any \<childFromRobot\> tags are given, the path for searching the robot files can be specified. + @param loadMode Standard: eFull, When eStructure is used no visualization and collision models are loaded for faster access. + */ static RobotPtr createRobotFromString(const std::string& xmlString, const std::string& basePath = "", RobotDescription loadMode = eFull); @@ -84,6 +84,16 @@ namespace VirtualRobot static bool saveXML(RobotPtr robot, const std::string& filename, const std::string& basePath, const std::string& modelDir = "models", bool storeEEF = true, bool storeRNS = true, bool storeSensors = true, bool storeModelFiles = true); + /*! + @brief saveMJCF + @param robot The robot to save. + @param filename The filename without path. + @param basePath The directory to store the robot to + @param meshDir The local directory where all mesh files should be stored to. + */ + static void saveMJCF(RobotPtr robot, const std::string& filename, const std::string& basePath, const std::string& meshDir = "mesh"); + + protected: struct ChildFromRobotDef diff --git a/VirtualRobot/examples/MjcfConverter/mjcf/MjcfMasslessBodySanitizer.cpp b/VirtualRobot/XML/mjcf/MasslessBodySanitizer.cpp similarity index 100% rename from VirtualRobot/examples/MjcfConverter/mjcf/MjcfMasslessBodySanitizer.cpp rename to VirtualRobot/XML/mjcf/MasslessBodySanitizer.cpp diff --git a/VirtualRobot/examples/MjcfConverter/mjcf/MjcfMasslessBodySanitizer.h b/VirtualRobot/XML/mjcf/MasslessBodySanitizer.h similarity index 100% rename from VirtualRobot/examples/MjcfConverter/mjcf/MjcfMasslessBodySanitizer.h rename to VirtualRobot/XML/mjcf/MasslessBodySanitizer.h diff --git a/VirtualRobot/examples/MjcfConverter/mjcf/MjcfDocument.cpp b/VirtualRobot/XML/mjcf/MjcfDocument.cpp similarity index 100% rename from VirtualRobot/examples/MjcfConverter/mjcf/MjcfDocument.cpp rename to VirtualRobot/XML/mjcf/MjcfDocument.cpp diff --git a/VirtualRobot/examples/MjcfConverter/mjcf/MjcfDocument.h b/VirtualRobot/XML/mjcf/MjcfDocument.h similarity index 100% rename from VirtualRobot/examples/MjcfConverter/mjcf/MjcfDocument.h rename to VirtualRobot/XML/mjcf/MjcfDocument.h diff --git a/VirtualRobot/examples/MjcfConverter/MjcfConverter.cpp b/VirtualRobot/XML/mjcf/MujocoIO.cpp similarity index 78% rename from VirtualRobot/examples/MjcfConverter/MjcfConverter.cpp rename to VirtualRobot/XML/mjcf/MujocoIO.cpp index c9d7237a07b2cbc7275dc855a729f40188eb7b7b..4627d3c68ab97164732b9ed87f9d51434878303b 100644 --- a/VirtualRobot/examples/MjcfConverter/MjcfConverter.cpp +++ b/VirtualRobot/XML/mjcf/MujocoIO.cpp @@ -1,30 +1,29 @@ -#include "MjcfConverter.h" +#include "MujocoIO.h" +#include "utils.h" +#include "xml_visitors.h" #include <VirtualRobot/RobotNodeSet.h> #include <VirtualRobot/XML/RobotIO.h> -#include "mjcf/utils.h" -#include "mjcf/xml_visitors.h" - - using namespace VirtualRobot; +using namespace mjcf; namespace tx = tinyxml2; namespace fs = boost::filesystem; -using Element = mjcf::Element; -MjcfConverter::MjcfConverter() : + +MujocoIO::MujocoIO() : masslessBodySanitizer(document, robot) { } -void MjcfConverter::convert(const std::string& inputSimoxXmlFile, - const std::string& outputDirectory) +void MujocoIO::saveMJCF(RobotPtr robot, const std::string& filename, const std::string& basePath, const std::string& meshDir) { - setPaths(inputSimoxXmlFile, outputDirectory); - - loadInputFile(); + this->robot = robot; + this->outputDirectory = basePath; + this->outputFileName = filename; + this->outputMeshRelDirectory = meshDir; document.reset(new mjcf::Document()); @@ -67,57 +66,14 @@ void MjcfConverter::convert(const std::string& inputSimoxXmlFile, writeOutputFile(); } -void MjcfConverter::setPaths(const std::string& inputFilename, - const std::string& outputDirectory) -{ - this->inputFilePath = inputFilename; - - inputFileDirectory = inputFilePath.parent_path(); - inputFileName = inputFilePath.filename(); - - this->outputDirectory = outputDirectory; - outputFileName = this->outputDirectory / inputFileName; - - outputMeshRelDirectory = "mesh"; - - - auto ensureDirExists = [](const fs::path& path) - { - if (!fs::exists(path)) - { - fs::create_directory(path); - } - }; - - ensureDirExists(outputDirectory); - ensureDirExists(outputDirectory / outputMeshRelDirectory); - - assert(!inputFileDirectory.empty()); -} -void MjcfConverter::makeEnvironment() +void MujocoIO::makeEnvironment() { document->addSkyboxTexture(Eigen::Vector3f(.8f, .9f, .95f), Eigen::Vector3f(.4f, .6f, .8f)); } -void MjcfConverter::loadInputFile() -{ - assert(!inputFilePath.empty()); - - std::cout << "Loading robot via RobotIO: " << inputFilePath << std::endl; - try - { - robot = RobotIO::loadRobot(inputFilePath.string(), RobotIO::eFull); - assert(robot); - } - catch (const VirtualRobotException&) - { - throw; // rethrow - } -} - -void MjcfConverter::writeOutputFile() +void MujocoIO::writeOutputFile() { assert(!outputFileName.empty()); std::cout << "Writing to " << outputFileName << std::endl; @@ -125,7 +81,7 @@ void MjcfConverter::writeOutputFile() } -void MjcfConverter::addNodeBodies() +void MujocoIO::addNodeBodies() { nodeBodies.clear(); @@ -143,7 +99,7 @@ void MjcfConverter::addNodeBodies() } } -void MjcfConverter::addNodeBodyMeshes() +void MujocoIO::addNodeBodyMeshes() { bool meshlabserverAviable = system("which meshlabserver > /dev/null 2>&1") == 0; bool notAvailableReported = false; @@ -232,7 +188,7 @@ void MjcfConverter::addNodeBodyMeshes() -Element* MjcfConverter::addNodeBody(RobotNodePtr node) +Element* MujocoIO::addNodeBody(RobotNodePtr node) { Element* element = nodeBodies[node->getName()]; if (element) @@ -253,7 +209,7 @@ Element* MjcfConverter::addNodeBody(RobotNodePtr node) return element; } -void MjcfConverter::addContactExcludes() +void MujocoIO::addContactExcludes() { RobotNodePtr rootNode = robot->getRootNode(); @@ -281,7 +237,7 @@ void MjcfConverter::addContactExcludes() } } -void MjcfConverter::addActuators() +void MujocoIO::addActuators() { std::vector<const mjcf::Element*> jointElements = getAllElements("joint"); @@ -292,7 +248,7 @@ void MjcfConverter::addActuators() } } -std::vector<const mjcf::Element*> MjcfConverter::getAllElements(const std::string& elemName) +std::vector<const mjcf::Element*> MujocoIO::getAllElements(const std::string& elemName) { mjcf::ListElementsVisitor visitor(elemName); document->worldbody()->Accept(&visitor); diff --git a/VirtualRobot/examples/MjcfConverter/MjcfConverter.h b/VirtualRobot/XML/mjcf/MujocoIO.h similarity index 74% rename from VirtualRobot/examples/MjcfConverter/MjcfConverter.h rename to VirtualRobot/XML/mjcf/MujocoIO.h index 17a5dc73d213b5df484812a22cfbb3e8f846e0ad..b8e5614ad1866f9cbd6469d9c38a7e0bf3a2b82e 100644 --- a/VirtualRobot/examples/MjcfConverter/MjcfConverter.h +++ b/VirtualRobot/XML/mjcf/MujocoIO.h @@ -5,29 +5,31 @@ #include <VirtualRobot/Robot.h> -#include "mjcf/exceptions.h" -#include "mjcf/MjcfDocument.h" -#include "mjcf/MjcfMasslessBodySanitizer.h" +#include "exceptions.h" +#include "MjcfDocument.h" +#include "MasslessBodySanitizer.h" namespace VirtualRobot { +namespace mjcf +{ + - class MjcfConverter + class MujocoIO { public: - MjcfConverter(); + MujocoIO(); - void convert(const std::string& inputSimoxXmlFile, - const std::string& outputDirectory); + void saveMJCF(RobotPtr robot, const std::string& filename, + const std::string& basePath, const std::string& meshDir); private: - void loadInputFile(); void writeOutputFile(); void setPaths(const std::string& inputFilename, @@ -52,10 +54,6 @@ namespace VirtualRobot // Paths - boost::filesystem::path inputFilePath; - boost::filesystem::path inputFileName; - boost::filesystem::path inputFileDirectory; - boost::filesystem::path outputDirectory; boost::filesystem::path outputFileName; @@ -81,5 +79,6 @@ namespace VirtualRobot std::map<std::string, std::string> mergedBodyNames; }; - + +} } diff --git a/VirtualRobot/examples/MjcfConverter/mjcf/exceptions.cpp b/VirtualRobot/XML/mjcf/exceptions.cpp similarity index 100% rename from VirtualRobot/examples/MjcfConverter/mjcf/exceptions.cpp rename to VirtualRobot/XML/mjcf/exceptions.cpp diff --git a/VirtualRobot/examples/MjcfConverter/mjcf/exceptions.h b/VirtualRobot/XML/mjcf/exceptions.h similarity index 100% rename from VirtualRobot/examples/MjcfConverter/mjcf/exceptions.h rename to VirtualRobot/XML/mjcf/exceptions.h diff --git a/VirtualRobot/examples/MjcfConverter/mjcf/utils.cpp b/VirtualRobot/XML/mjcf/utils.cpp similarity index 100% rename from VirtualRobot/examples/MjcfConverter/mjcf/utils.cpp rename to VirtualRobot/XML/mjcf/utils.cpp diff --git a/VirtualRobot/examples/MjcfConverter/mjcf/utils.h b/VirtualRobot/XML/mjcf/utils.h similarity index 100% rename from VirtualRobot/examples/MjcfConverter/mjcf/utils.h rename to VirtualRobot/XML/mjcf/utils.h diff --git a/VirtualRobot/examples/MjcfConverter/mjcf/xml_visitors.cpp b/VirtualRobot/XML/mjcf/xml_visitors.cpp similarity index 100% rename from VirtualRobot/examples/MjcfConverter/mjcf/xml_visitors.cpp rename to VirtualRobot/XML/mjcf/xml_visitors.cpp diff --git a/VirtualRobot/examples/MjcfConverter/mjcf/xml_visitors.h b/VirtualRobot/XML/mjcf/xml_visitors.h similarity index 100% rename from VirtualRobot/examples/MjcfConverter/mjcf/xml_visitors.h rename to VirtualRobot/XML/mjcf/xml_visitors.h diff --git a/VirtualRobot/examples/MjcfConverter/CMakeLists.txt b/VirtualRobot/examples/MjcfConverter/CMakeLists.txt index 73fa315aabafb627dfa6d5ad6f0eda02a954ff9b..5222b8e0d0144f87bca9458ced6c81f04097345b 100644 --- a/VirtualRobot/examples/MjcfConverter/CMakeLists.txt +++ b/VirtualRobot/examples/MjcfConverter/CMakeLists.txt @@ -10,23 +10,9 @@ if (Boost_FOUND) set(SOURCES main.cpp - MjcfConverter.cpp - - mjcf/exceptions.cpp - mjcf/utils.cpp - mjcf/xml_visitors.cpp - mjcf/MjcfDocument.cpp - mjcf/MjcfMasslessBodySanitizer.cpp ) set(HEADERS - MjcfConverter.h - - mjcf/exceptions.h - mjcf/utils.h - mjcf/xml_visitors.h - mjcf/MjcfDocument.h - mjcf/MjcfMasslessBodySanitizer.h ) set(LIBS diff --git a/VirtualRobot/examples/MjcfConverter/main.cpp b/VirtualRobot/examples/MjcfConverter/main.cpp index c50c22877d93bf03a4270f13a32dc7bb8cbed672..23e05a7d9dad9c3cc17c0092107cf39651c4123e 100644 --- a/VirtualRobot/examples/MjcfConverter/main.cpp +++ b/VirtualRobot/examples/MjcfConverter/main.cpp @@ -2,7 +2,7 @@ #include <VirtualRobot/RuntimeEnvironment.h> -#include "MjcfConverter.h" +#include <VirtualRobot/XML/RobotIO.h> using namespace VirtualRobot; @@ -11,9 +11,8 @@ int main(int argc, char* argv[]) { VirtualRobot::RuntimeEnvironment::considerKey("robot"); VirtualRobot::RuntimeEnvironment::processCommandLine(argc, argv); -// VirtualRobot::RuntimeEnvironment::print(); - std::string inputFilename; + boost::filesystem::path inputFilename; if (VirtualRobot::RuntimeEnvironment::hasValue("robot")) { @@ -34,14 +33,25 @@ int main(int argc, char* argv[]) return 0; } - boost::filesystem::path outputDir(inputFilename); + boost::filesystem::path outputDir = inputFilename; outputDir.remove_filename(); outputDir /= "mjcf"; std::cout << "Input file: " << inputFilename << std::endl; std::cout << "Output dir: " << outputDir << std::endl; - MjcfConverter converter; - converter.convert(inputFilename, outputDir.string()); + std::cout << "Loading robot ..." << std::endl; + RobotPtr robot; + try + { + robot = RobotIO::loadRobot(inputFilename.string(), RobotIO::eFull); + assert(robot); + } + catch (const VirtualRobotException&) + { + throw; // rethrow + } + + RobotIO::saveMJCF(robot, inputFilename.filename().string(), outputDir.string()); }