Add mj_loadUSD function. Change simulate to use that instead of manual spec compilation.
PiperOrigin-RevId: 780608874 Change-Id: I333238c756fe76b371518a7cdf9452b93da3540a
This commit is contained in:
committed by
Copybara-Service
parent
e507e31922
commit
14972d2490
@@ -202,6 +202,7 @@ if(MUJOCO_BUILD_EXAMPLES)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(MUJOCO_WITH_USD)
|
if(MUJOCO_WITH_USD)
|
||||||
|
target_compile_definitions(mujoco PUBLIC mjUSEUSD)
|
||||||
add_subdirectory(src/experimental/usd)
|
add_subdirectory(src/experimental/usd)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,12 @@
|
|||||||
#include <mujoco/mujoco.h>
|
#include <mujoco/mujoco.h>
|
||||||
#include <pxr/usd/usd/common.h>
|
#include <pxr/usd/usd/common.h>
|
||||||
|
|
||||||
|
// Given a USD file parse to a spec, then compile and return the low-level model.
|
||||||
|
//
|
||||||
|
// Particular care is taken for physics data to be lossless but visual
|
||||||
|
// data such as materials may be lossy.
|
||||||
|
MJAPI mjModel* mj_loadUSD(const char* filename, const mjVFS* vfs, char* error, int error_sz);
|
||||||
|
|
||||||
// Given a USD stage, this function will do a best effort conversion to
|
// Given a USD stage, this function will do a best effort conversion to
|
||||||
// mjSpec.
|
// mjSpec.
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -177,7 +177,6 @@ if(SIMULATE_BUILD_EXECUTABLE)
|
|||||||
if (MUJOCO_WITH_USD)
|
if (MUJOCO_WITH_USD)
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
simulate
|
simulate
|
||||||
mujoco::usd
|
|
||||||
mujoco::usd::mjcf
|
mujoco::usd::mjcf
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
@@ -249,7 +248,7 @@ if(SIMULATE_BUILD_EXECUTABLE)
|
|||||||
)
|
)
|
||||||
|
|
||||||
if (MUJOCO_WITH_USD)
|
if (MUJOCO_WITH_USD)
|
||||||
target_compile_definitions(simulate PUBLIC SIMULATE_WITH_USD)
|
target_compile_definitions(simulate PUBLIC mjUSEUSD)
|
||||||
|
|
||||||
# Add support to RPATH for the samples.
|
# Add support to RPATH for the samples.
|
||||||
target_add_rpath(
|
target_add_rpath(
|
||||||
|
|||||||
+4
-31
@@ -25,11 +25,8 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#if defined(SIMULATE_WITH_USD)
|
#if defined(mjUSEUSD)
|
||||||
#include <mujoco/experimental/usd/usd.h>
|
#include <mujoco/experimental/usd/usd.h>
|
||||||
#include <pxr/pxr.h>
|
|
||||||
#include <pxr/usd/usd/common.h>
|
|
||||||
#include <pxr/usd/usd/stage.h>
|
|
||||||
#endif
|
#endif
|
||||||
#include <mujoco/mujoco.h>
|
#include <mujoco/mujoco.h>
|
||||||
#include "glfw_adapter.h"
|
#include "glfw_adapter.h"
|
||||||
@@ -244,34 +241,10 @@ mjModel* LoadModel(const char* file, mj::Simulate& sim) {
|
|||||||
if (!mnew) {
|
if (!mnew) {
|
||||||
mju::strcpy_arr(loadError, "could not load binary model");
|
mju::strcpy_arr(loadError, "could not load binary model");
|
||||||
}
|
}
|
||||||
#if defined(SIMULATE_WITH_USD)
|
#if defined(mjUSEUSD)
|
||||||
} else if (extension == ".usda" || extension == ".usd" ||
|
} else if (extension == ".usda" || extension == ".usd" ||
|
||||||
extension == ".usdc" || extension == ".usdz" ) {
|
extension == ".usdc" || extension == ".usdz" ) {
|
||||||
auto stage = pxr::UsdStage::Open(filename);
|
mnew = mj_loadUSD(filename, nullptr, loadError, kErrorLength);
|
||||||
if (!stage) {
|
|
||||||
mju::strcpy_arr(loadError, "could not open USD stage");
|
|
||||||
} else {
|
|
||||||
mjSpec* spec = mj_parseUSDStage(stage);
|
|
||||||
if (!spec) {
|
|
||||||
mju::strcpy_arr(loadError, "could not parse USD stage to mjSpec");
|
|
||||||
} else {
|
|
||||||
mjModel* model = mj_compile(spec, nullptr);
|
|
||||||
if (!model) {
|
|
||||||
mju::strcpy_arr(loadError,
|
|
||||||
"could not compile USD parsed mjSpec to mjModel:\n");
|
|
||||||
mju::strcat_arr(loadError, mjs_getError(spec));
|
|
||||||
} else {
|
|
||||||
// handle compile warning
|
|
||||||
if (mjs_isWarning(spec)) {
|
|
||||||
mju::strcpy_arr(
|
|
||||||
loadError,
|
|
||||||
"warning while compiling USD parsed mjSpec to mjModel:\n");
|
|
||||||
mju::strcat_arr(loadError, mjs_getError(spec));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mnew = model;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
mnew = mj_loadXML(filename, nullptr, loadError, kErrorLength);
|
mnew = mj_loadXML(filename, nullptr, loadError, kErrorLength);
|
||||||
@@ -537,7 +510,7 @@ int main(int argc, char** argv) {
|
|||||||
// scan for libraries in the plugin directory to load additional plugins
|
// scan for libraries in the plugin directory to load additional plugins
|
||||||
scanPluginLibraries();
|
scanPluginLibraries();
|
||||||
|
|
||||||
#if defined(SIMULATE_WITH_USD)
|
#if defined(mjUSEUSD)
|
||||||
// If USD is used, print the version.
|
// If USD is used, print the version.
|
||||||
std::printf("OpenUSD version v%d.%02d\n", PXR_MINOR_VERSION, PXR_PATCH_VERSION);
|
std::printf("OpenUSD version v%d.%02d\n", PXR_MINOR_VERSION, PXR_PATCH_VERSION);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
# Plugin target names (used for library and plugInfo.json)
|
# Plugin target names (used for library and plugInfo.json)
|
||||||
set(MJCF_PLUGIN_TARGET_NAME usdMjcf)
|
set(MJCF_PLUGIN_TARGET_NAME usdMjcf)
|
||||||
set(MJC_PHYSICS_PLUGIN_TARGET_NAME mjcPhysics)
|
set(MJC_PHYSICS_PLUGIN_TARGET_NAME mjcPhysics)
|
||||||
set(MJ_USD_TARGET_NAME mj_usd)
|
|
||||||
|
|
||||||
# Installation directory for USD plugins
|
# Installation directory for USD plugins
|
||||||
set(MJ_USD_INSTALL_DIR_LIB ${CMAKE_INSTALL_LIBDIR}/mujocoUsd)
|
set(MJ_USD_INSTALL_DIR_LIB ${CMAKE_INSTALL_LIBDIR}/mujocoUsd)
|
||||||
@@ -187,14 +186,12 @@ set_target_properties(${MJC_PHYSICS_PLUGIN_TARGET_NAME} PROPERTIES
|
|||||||
${DEFAULT_CXX_VISIBILITY_PROPS}
|
${DEFAULT_CXX_VISIBILITY_PROPS}
|
||||||
)
|
)
|
||||||
target_include_directories(${MJC_PHYSICS_PLUGIN_TARGET_NAME} PUBLIC
|
target_include_directories(${MJC_PHYSICS_PLUGIN_TARGET_NAME} PUBLIC
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/mjcPhysics"
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../../../include>
|
||||||
)
|
)
|
||||||
|
|
||||||
## mj_usd
|
## mj_usd
|
||||||
|
|
||||||
add_library(${MJ_USD_TARGET_NAME} SHARED)
|
target_sources(mujoco PRIVATE
|
||||||
add_library(mujoco::usd ALIAS ${MJ_USD_TARGET_NAME})
|
|
||||||
target_sources(${MJ_USD_TARGET_NAME} PRIVATE
|
|
||||||
kinematic_tree.cc
|
kinematic_tree.cc
|
||||||
kinematic_tree.h
|
kinematic_tree.h
|
||||||
layer_sink.cc
|
layer_sink.cc
|
||||||
@@ -212,8 +209,6 @@ if (USD_DIR)
|
|||||||
|
|
||||||
target_link_libraries(${MJC_PHYSICS_PLUGIN_TARGET_NAME} PRIVATE
|
target_link_libraries(${MJC_PHYSICS_PLUGIN_TARGET_NAME} PRIVATE
|
||||||
${OPENUSD_CORE_LIBS}
|
${OPENUSD_CORE_LIBS}
|
||||||
mujoco
|
|
||||||
tinyxml2
|
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(${MJCF_PLUGIN_TARGET_NAME} PRIVATE
|
target_link_libraries(${MJCF_PLUGIN_TARGET_NAME} PRIVATE
|
||||||
@@ -223,10 +218,8 @@ if (USD_DIR)
|
|||||||
${MJC_PHYSICS_PLUGIN_TARGET_NAME}
|
${MJC_PHYSICS_PLUGIN_TARGET_NAME}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(${MJ_USD_TARGET_NAME} PUBLIC
|
target_link_libraries(mujoco PUBLIC
|
||||||
${OPENUSD_CORE_LIBS}
|
${OPENUSD_CORE_LIBS}
|
||||||
mujoco
|
|
||||||
tinyxml2
|
|
||||||
${MJC_PHYSICS_PLUGIN_TARGET_NAME}
|
${MJC_PHYSICS_PLUGIN_TARGET_NAME}
|
||||||
)
|
)
|
||||||
elseif (HOUDINI_HFS_DIR)
|
elseif (HOUDINI_HFS_DIR)
|
||||||
@@ -237,11 +230,9 @@ elseif (HOUDINI_HFS_DIR)
|
|||||||
# so we need to manually link all the required libraries.
|
# so we need to manually link all the required libraries.
|
||||||
configure_houdini_target(${MJC_PHYSICS_PLUGIN_TARGET_NAME} PRIVATE PRIVATE)
|
configure_houdini_target(${MJC_PHYSICS_PLUGIN_TARGET_NAME} PRIVATE PRIVATE)
|
||||||
configure_houdini_target(${MJCF_PLUGIN_TARGET_NAME} PRIVATE PRIVATE)
|
configure_houdini_target(${MJCF_PLUGIN_TARGET_NAME} PRIVATE PRIVATE)
|
||||||
configure_houdini_target(${MJ_USD_TARGET_NAME} PUBLIC PUBLIC)
|
|
||||||
|
|
||||||
# Re-add inter-plugin dependencies after Houdini-specific linking
|
# Re-add inter-plugin dependencies after Houdini-specific linking
|
||||||
target_link_libraries(${MJCF_PLUGIN_TARGET_NAME} PRIVATE ${MJC_PHYSICS_PLUGIN_TARGET_NAME})
|
target_link_libraries(${MJCF_PLUGIN_TARGET_NAME} PRIVATE ${MJC_PHYSICS_PLUGIN_TARGET_NAME})
|
||||||
target_link_libraries(${MJ_USD_TARGET_NAME} PUBLIC ${MJC_PHYSICS_PLUGIN_TARGET_NAME})
|
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -272,6 +263,6 @@ install(FILES
|
|||||||
install(TARGETS
|
install(TARGETS
|
||||||
${MJCF_PLUGIN_TARGET_NAME}
|
${MJCF_PLUGIN_TARGET_NAME}
|
||||||
${MJC_PHYSICS_PLUGIN_TARGET_NAME}
|
${MJC_PHYSICS_PLUGIN_TARGET_NAME}
|
||||||
${MJ_USD_TARGET_NAME}
|
EXPORT ${PROJECT_NAME}
|
||||||
LIBRARY DESTINATION ${MJ_USD_INSTALL_DIR_LIB}
|
LIBRARY DESTINATION ${MJ_USD_INSTALL_DIR_LIB}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -41,8 +41,7 @@
|
|||||||
|
|
||||||
PXR_NAMESPACE_OPEN_SCOPE
|
PXR_NAMESPACE_OPEN_SCOPE
|
||||||
TF_DEFINE_PRIVATE_TOKENS(_layer_sink_tokens,
|
TF_DEFINE_PRIVATE_TOKENS(_layer_sink_tokens,
|
||||||
((xformOpTransform,
|
((xformOpTransform, "xformOp:transform:mujoco")));
|
||||||
"xformOp:transform:mujoco"))(Xform));
|
|
||||||
PXR_NAMESPACE_CLOSE_SCOPE
|
PXR_NAMESPACE_CLOSE_SCOPE
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|||||||
@@ -34,6 +34,10 @@
|
|||||||
#include "xml/xml.h"
|
#include "xml/xml.h"
|
||||||
#include "xml/xml_native_reader.h"
|
#include "xml/xml_native_reader.h"
|
||||||
#include "xml/xml_util.h"
|
#include "xml/xml_util.h"
|
||||||
|
#if defined(mjUSEUSD)
|
||||||
|
#include <mujoco/experimental/usd/usd.h>
|
||||||
|
#include <pxr/usd/usd/stage.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
//---------------------------------- Globals -------------------------------------------------------
|
//---------------------------------- Globals -------------------------------------------------------
|
||||||
|
|
||||||
@@ -126,7 +130,36 @@ mjModel* mj_loadXML(const char* filename, const mjVFS* vfs,
|
|||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(mjUSEUSD)
|
||||||
|
// parse USD file, compile it, and return low-level model.
|
||||||
|
// if vfs is not NULL, look up files in vfs before reading from disk
|
||||||
|
// error can be NULL; otherwise assumed to have size error_sz
|
||||||
|
mjModel* mj_loadUSD(const char* filename, const mjVFS* vfs, char* error, int error_sz) {
|
||||||
|
auto stage = pxr::UsdStage::Open(filename);
|
||||||
|
|
||||||
|
if (stage == nullptr) {
|
||||||
|
mjCopyError(error, "Failed to load USD stage from file.", error_sz);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse USD into mjSpec.
|
||||||
|
std::unique_ptr<mjSpec, std::function<void(mjSpec*)> > spec(
|
||||||
|
mj_parseUSDStage(stage),
|
||||||
|
[](mjSpec* s) {
|
||||||
|
mj_deleteSpec(s);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Compile new model.
|
||||||
|
mjModel* m = mj_compile(spec.get(), vfs);
|
||||||
|
if (!m) {
|
||||||
|
mjCopyError(error, mjs_getError(spec.get()), error_sz);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetGlobalModel().Set(spec.release());
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// update XML data structures with info from low-level model, save as MJCF
|
// update XML data structures with info from low-level model, save as MJCF
|
||||||
// returns 1 if successful, 0 otherwise
|
// returns 1 if successful, 0 otherwise
|
||||||
|
|||||||
Vendored
+71
@@ -0,0 +1,71 @@
|
|||||||
|
#usda 1.0
|
||||||
|
(
|
||||||
|
endTimeCode = 1
|
||||||
|
framesPerSecond = 24
|
||||||
|
metersPerUnit = 1
|
||||||
|
startTimeCode = 1
|
||||||
|
timeCodesPerSecond = 24
|
||||||
|
upAxis = "Y"
|
||||||
|
)
|
||||||
|
|
||||||
|
def Xform "World"
|
||||||
|
{
|
||||||
|
def Xform "Axle" (
|
||||||
|
prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsArticulationRootAPI"]
|
||||||
|
)
|
||||||
|
{
|
||||||
|
matrix4d xformOp:transform:set_initial_pos = ( (1, 0, 0, 0), (0, 0.9999197811020019, -0.012666150201413267, 0), (0, 0.012666150201413267, 0.9999197811020019, 0), (0, 0.012296309694647789, 0.970723032951355, 1) )
|
||||||
|
uniform token[] xformOpOrder = ["xformOp:transform:set_initial_pos"]
|
||||||
|
|
||||||
|
def Xform "Rod" (
|
||||||
|
prepend apiSchemas = ["PhysicsRigidBodyAPI"]
|
||||||
|
)
|
||||||
|
{
|
||||||
|
matrix4d xformOp:transform:set_initial_rod_pos = ( (1, 0, 0, 0), (0, 0.3255001489278845, 0.9455419890453967, 0), (0, -0.9455419890453967, 0.3255001489278845, 0), (0, 0.47277099452269833, -0.1627500744639423, 1) )
|
||||||
|
uniform token[] xformOpOrder = ["xformOp:transform:set_initial_rod_pos"]
|
||||||
|
|
||||||
|
def Cylinder "Geometry" (
|
||||||
|
prepend apiSchemas = ["PhysicsCollisionAPI"]
|
||||||
|
)
|
||||||
|
{
|
||||||
|
token axis = "Z"
|
||||||
|
float3[] extent = [(-0.01, -0.01, -0.5), (0.01, 0.01, 0.5)]
|
||||||
|
double height = 1
|
||||||
|
double radius = 0.01
|
||||||
|
matrix4d xformOp:transform = ( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, -0.03546595561524429, 1) )
|
||||||
|
uniform token[] xformOpOrder = ["xformOp:transform"]
|
||||||
|
}
|
||||||
|
|
||||||
|
def PhysicsRevoluteJoint "HingeJoint" (
|
||||||
|
prepend apiSchemas = ["PhysicsActuatorAPI"]
|
||||||
|
)
|
||||||
|
{
|
||||||
|
rel physics:body0 = </World/Axle>
|
||||||
|
rel physics:body1 = </World/Axle/Rod>
|
||||||
|
point3f physics:localPos0 = (0, 0, 0)
|
||||||
|
point3f physics:localPos1 = (0, 0, 0.5)
|
||||||
|
quatf physics:localRot0 = (0, 1, 0, 0)
|
||||||
|
quatf physics:localRot1 = (0, 1, 0, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def Cylinder "Geometry" (
|
||||||
|
prepend apiSchemas = ["PhysicsCollisionAPI"]
|
||||||
|
)
|
||||||
|
{
|
||||||
|
token axis = "Z"
|
||||||
|
float3[] extent = [(-0.01, -0.01, -0.1), (0.01, 0.01, 0.1)]
|
||||||
|
double height = 0.2
|
||||||
|
double radius = 0.01
|
||||||
|
matrix4d xformOp:transform = ( (0, 0, -1, 0), (0, 1, -0, 0), (1, 0, -0, 0), (0, 0, -0, 1) )
|
||||||
|
uniform token[] xformOpOrder = ["xformOp:transform"]
|
||||||
|
}
|
||||||
|
|
||||||
|
def PhysicsFixedJoint "FixedJoint"
|
||||||
|
{
|
||||||
|
rel physics:body0 = None
|
||||||
|
rel physics:body1 = </World/Axle>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user