Merge branch 'main' into open3d-removal
This commit is contained in:
@@ -568,7 +568,6 @@ PYBIND11_MODULE(_specs, m) {
|
||||
// ============================= MJSBODY =====================================
|
||||
mjsBody.def_property_readonly(
|
||||
"id", [](raw::MjsBody& self) -> int { return mjs_getId(self.element); });
|
||||
mjsBody.def("delete", [](raw::MjsBody& self) { mjs_delete(self.element); });
|
||||
mjsBody.def(
|
||||
"add_body",
|
||||
[](raw::MjsBody& self, raw::MjsDefault* default_) -> raw::MjsBody* {
|
||||
|
||||
@@ -98,6 +98,34 @@ class SpecsTest(absltest.TestCase):
|
||||
</mujoco>
|
||||
"""),)
|
||||
|
||||
def test_load_xml(self):
|
||||
filename = '../../test/testdata/model.xml'
|
||||
state_type = mujoco.mjtState.mjSTATE_INTEGRATION
|
||||
|
||||
# Load from file.
|
||||
spec1 = mujoco.MjSpec()
|
||||
spec1.from_file(filename)
|
||||
model1 = spec1.compile()
|
||||
data1 = mujoco.MjData(model1)
|
||||
mujoco.mj_step(model1, data1)
|
||||
size1 = mujoco.mj_stateSize(model1, state_type)
|
||||
state1 = np.empty(size1, np.float64)
|
||||
mujoco.mj_getState(model1, data1, state1, state_type)
|
||||
|
||||
# Load from string.
|
||||
spec2 = mujoco.MjSpec()
|
||||
with open(filename, 'r') as file:
|
||||
spec2.from_string(file.read().rstrip())
|
||||
model2 = spec2.compile()
|
||||
data2 = mujoco.MjData(model2)
|
||||
mujoco.mj_step(model2, data2)
|
||||
size2 = mujoco.mj_stateSize(model2, state_type)
|
||||
state2 = np.empty(size2, np.float64)
|
||||
mujoco.mj_getState(model2, data2, state2, state_type)
|
||||
|
||||
# Check that the state is the same.
|
||||
np.testing.assert_array_equal(state1, state2)
|
||||
|
||||
def test_compile_errors_with_line_info(self):
|
||||
spec = mujoco.MjSpec()
|
||||
|
||||
@@ -269,6 +297,30 @@ class SpecsTest(absltest.TestCase):
|
||||
model = spec.compile({'cube.obj': cube})
|
||||
self.assertEqual(model.nmeshvert, 8)
|
||||
|
||||
def test_delete(self):
|
||||
filename = '../../test/testdata/model.xml'
|
||||
|
||||
spec = mujoco.MjSpec()
|
||||
spec.from_file(filename)
|
||||
|
||||
model = spec.compile()
|
||||
self.assertIsNotNone(model)
|
||||
self.assertEqual(model.nsite, 11)
|
||||
self.assertEqual(model.nsensor, 11)
|
||||
|
||||
head = spec.find_body('head')
|
||||
self.assertIsNotNone(head)
|
||||
site = head.first_site()
|
||||
self.assertIsNotNone(site)
|
||||
|
||||
site.delete()
|
||||
spec.sensors[-1].delete()
|
||||
spec.sensors[-1].delete()
|
||||
|
||||
model = spec.compile()
|
||||
self.assertIsNotNone(model)
|
||||
self.assertEqual(model.nsite, 10)
|
||||
self.assertEqual(model.nsensor, 9)
|
||||
|
||||
if __name__ == '__main__':
|
||||
absltest.main()
|
||||
|
||||
@@ -16,7 +16,9 @@
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cctype>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
@@ -84,6 +86,22 @@ constexpr auto XArrayShapeImpl(const std::string_view dim1_str) {
|
||||
inline std::size_t NConMax(const mjData* d) {
|
||||
return d->narena / sizeof(mjContact);
|
||||
}
|
||||
|
||||
// strip path prefix from filename and make lowercase
|
||||
std::string StripPath(const char* name) {
|
||||
std::string filename(name);
|
||||
size_t start = filename.find_last_of("/\\");
|
||||
|
||||
// get name without path
|
||||
if (start != std::string::npos) {
|
||||
filename = filename.substr(start + 1, filename.size() - start - 1);
|
||||
}
|
||||
|
||||
// make lowercase
|
||||
std::transform(filename.begin(), filename.end(), filename.begin(),
|
||||
[](unsigned char c) { return std::tolower(c); });
|
||||
return filename;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
// ==================== MJOPTION ===============================================
|
||||
@@ -323,8 +341,9 @@ static raw::MjModel* LoadModelFileImpl(
|
||||
mj_defaultVFS(&vfs);
|
||||
vfs_ptr = &vfs;
|
||||
for (const auto& asset : assets) {
|
||||
std::string buffer_name = StripPath(asset.name);
|
||||
const int vfs_error = InterceptMjErrors(mj_addBufferVFS)(
|
||||
vfs_ptr, asset.name, asset.content, asset.content_size);
|
||||
vfs_ptr, buffer_name.c_str(), asset.content, asset.content_size);
|
||||
if (vfs_error) {
|
||||
throw py::value_error("assets dict is too big");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user