Add WASM binding for mj_compile.
It does not support model assets management via VFS yet. PiperOrigin-RevId: 844864882 Change-Id: I422d7896ed024fc6f5c3fa923a58cdc9059f3bee
This commit is contained in:
committed by
Copybara-Service
parent
eef71832db
commit
477a14dcb2
@@ -33,6 +33,7 @@
|
|||||||
#include <mujoco/mjmodel.h>
|
#include <mujoco/mjmodel.h>
|
||||||
#include <mujoco/mjvisualize.h>
|
#include <mujoco/mjvisualize.h>
|
||||||
#include <mujoco/mujoco.h>
|
#include <mujoco/mujoco.h>
|
||||||
|
#include <mujoco/mjspec.h>
|
||||||
#include "engine/engine_util_errmem.h"
|
#include "engine/engine_util_errmem.h"
|
||||||
#include "wasm/unpack.h"
|
#include "wasm/unpack.h"
|
||||||
|
|
||||||
@@ -7823,6 +7824,15 @@ std::unique_ptr<MjSpec> parseXMLString_wrapper(const std::string &xml) {
|
|||||||
return std::unique_ptr<MjSpec>(new MjSpec(ptr));
|
return std::unique_ptr<MjSpec>(new MjSpec(ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<MjModel> mj_compile_wrapper(const MjSpec& spec) {
|
||||||
|
mjSpec* spec_ptr = spec.get();
|
||||||
|
mjModel* model = mj_compile(spec_ptr, nullptr);
|
||||||
|
if (!model || mjs_isWarning(spec_ptr)) {
|
||||||
|
mju_error("%s", mjs_getError(spec_ptr));
|
||||||
|
}
|
||||||
|
return std::unique_ptr<MjModel>(new MjModel(model));
|
||||||
|
}
|
||||||
|
|
||||||
void error_wrapper(const String& msg) { mju_error("%s\n", msg.as<const std::string>().data()); }
|
void error_wrapper(const String& msg) { mju_error("%s\n", msg.as<const std::string>().data()); }
|
||||||
|
|
||||||
int mj_saveLastXML_wrapper(const String& filename, const MjModel& m) {
|
int mj_saveLastXML_wrapper(const String& filename, const MjModel& m) {
|
||||||
@@ -12308,6 +12318,7 @@ EMSCRIPTEN_BINDINGS(mujoco_bindings) {
|
|||||||
function("mj_comPos", &mj_comPos_wrapper);
|
function("mj_comPos", &mj_comPos_wrapper);
|
||||||
function("mj_comVel", &mj_comVel_wrapper);
|
function("mj_comVel", &mj_comVel_wrapper);
|
||||||
function("mj_compareFwdInv", &mj_compareFwdInv_wrapper);
|
function("mj_compareFwdInv", &mj_compareFwdInv_wrapper);
|
||||||
|
function("mj_compile", &mj_compile_wrapper);
|
||||||
function("mj_constraintUpdate", &mj_constraintUpdate_wrapper);
|
function("mj_constraintUpdate", &mj_constraintUpdate_wrapper);
|
||||||
function("mj_contactForce", &mj_contactForce_wrapper);
|
function("mj_contactForce", &mj_contactForce_wrapper);
|
||||||
function("mj_copyBack", &mj_copyBack_wrapper);
|
function("mj_copyBack", &mj_copyBack_wrapper);
|
||||||
|
|||||||
@@ -64,7 +64,6 @@ _SKIPPED_PLUGIN_FUNCTIONS: tuple[str, ...] = (
|
|||||||
# Functions that are bound as class methods
|
# Functions that are bound as class methods
|
||||||
_SKIPPED_CLASS_METHODS: tuple[str, ...] = (
|
_SKIPPED_CLASS_METHODS: tuple[str, ...] = (
|
||||||
# go/keep-sorted start
|
# go/keep-sorted start
|
||||||
"mj_compile",
|
|
||||||
"mj_copyData",
|
"mj_copyData",
|
||||||
"mj_copyModel",
|
"mj_copyModel",
|
||||||
"mj_copySpec",
|
"mj_copySpec",
|
||||||
@@ -192,6 +191,7 @@ _SKIPPED_UTILITY_FUNCTIONS: tuple[str, ...] = (
|
|||||||
# These functions are not bound automatically but are written by hand instead.
|
# These functions are not bound automatically but are written by hand instead.
|
||||||
MANUAL_WRAPPER_FUNCTIONS: tuple[str, ...] = (
|
MANUAL_WRAPPER_FUNCTIONS: tuple[str, ...] = (
|
||||||
# go/keep-sorted start
|
# go/keep-sorted start
|
||||||
|
"mj_compile",
|
||||||
"mj_saveLastXML",
|
"mj_saveLastXML",
|
||||||
"mj_setLengthRange",
|
"mj_setLengthRange",
|
||||||
"mju_error",
|
"mju_error",
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
#include <mujoco/mjmodel.h>
|
#include <mujoco/mjmodel.h>
|
||||||
#include <mujoco/mjvisualize.h>
|
#include <mujoco/mjvisualize.h>
|
||||||
#include <mujoco/mujoco.h>
|
#include <mujoco/mujoco.h>
|
||||||
|
#include <mujoco/mjspec.h>
|
||||||
#include "engine/engine_util_errmem.h"
|
#include "engine/engine_util_errmem.h"
|
||||||
#include "wasm/unpack.h"
|
#include "wasm/unpack.h"
|
||||||
|
|
||||||
@@ -406,6 +407,15 @@ std::unique_ptr<MjSpec> parseXMLString_wrapper(const std::string &xml) {
|
|||||||
return std::unique_ptr<MjSpec>(new MjSpec(ptr));
|
return std::unique_ptr<MjSpec>(new MjSpec(ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<MjModel> mj_compile_wrapper(const MjSpec& spec) {
|
||||||
|
mjSpec* spec_ptr = spec.get();
|
||||||
|
mjModel* model = mj_compile(spec_ptr, nullptr);
|
||||||
|
if (!model || mjs_isWarning(spec_ptr)) {
|
||||||
|
mju_error("%s", mjs_getError(spec_ptr));
|
||||||
|
}
|
||||||
|
return std::unique_ptr<MjModel>(new MjModel(model));
|
||||||
|
}
|
||||||
|
|
||||||
void error_wrapper(const String& msg) { mju_error("%s\n", msg.as<const std::string>().data()); }
|
void error_wrapper(const String& msg) { mju_error("%s\n", msg.as<const std::string>().data()); }
|
||||||
|
|
||||||
int mj_saveLastXML_wrapper(const String& filename, const MjModel& m) {
|
int mj_saveLastXML_wrapper(const String& filename, const MjModel& m) {
|
||||||
|
|||||||
@@ -1802,4 +1802,28 @@ describe('MuJoCo WASM Bindings', () => {
|
|||||||
unlinkXMLFile(tempXmlFilename);
|
unlinkXMLFile(tempXmlFilename);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should compile a spec from XML string', () => {
|
||||||
|
let spec = null;
|
||||||
|
let model = null;
|
||||||
|
try {
|
||||||
|
spec = mujoco.parseXMLString(TEST_XML);
|
||||||
|
expect(spec).not.toBeNull();
|
||||||
|
|
||||||
|
model = mujoco.mj_compile(spec);
|
||||||
|
expect(model).not.toBeNull();
|
||||||
|
expect(model.nq).toBeGreaterThan(0);
|
||||||
|
|
||||||
|
const jointId =
|
||||||
|
mujoco.mj_name2id(model, mujoco.mjtObj.mjOBJ_JOINT.value, 'myhinge');
|
||||||
|
expect(jointId).toBeGreaterThanOrEqual(0);
|
||||||
|
} finally {
|
||||||
|
if (spec) {
|
||||||
|
spec.delete();
|
||||||
|
}
|
||||||
|
if (model) {
|
||||||
|
model.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user