Re-implement VFS internals in C++, removing the constraints of the previous implementation.
PiperOrigin-RevId: 649433087 Change-Id: Icaa3e6b7f2ef14f56b04fef2f4360b46d8b5f022
This commit is contained in:
committed by
Copybara-Service
parent
118b6810b3
commit
57e6760ec9
@@ -409,19 +409,6 @@ class MuJoCoBindingsTest(parameterized.TestCase):
|
||||
np.testing.assert_array_equal(self.model.geom_size[1], [0.5, 0.5, 0.5])
|
||||
np.testing.assert_array_equal(model_copy.geom_size[1], [0.1, 0.1, 0.1])
|
||||
|
||||
def test_assets_array_filename_too_long(self):
|
||||
# Longest allowed filename (excluding null byte)
|
||||
limit = mujoco.mjMAXVFSNAME - 1
|
||||
contents = b'<mujoco/>'
|
||||
valid_filename = 'a' * limit
|
||||
mujoco.MjModel.from_xml_path(valid_filename, {valid_filename: contents})
|
||||
invalid_filename = 'a' * (limit + 1)
|
||||
expected_message = (
|
||||
f'Filename length 1000 exceeds 999 character limit: {invalid_filename}')
|
||||
with self.assertRaisesWithLiteralMatch(ValueError, expected_message):
|
||||
mujoco.MjModel.from_xml_path(invalid_filename,
|
||||
{invalid_filename: contents})
|
||||
|
||||
def test_mjdata_can_copy(self):
|
||||
self.data.qpos = [0, 0, 0.1*np.sqrt(2) - 0.001,
|
||||
np.cos(np.pi/8), np.sin(np.pi/8), 0, 0, 0,
|
||||
@@ -856,9 +843,6 @@ Return the current version of MuJoCo as a null-terminated string.
|
||||
Euler integrator, semi-implicit in velocity.
|
||||
""")
|
||||
|
||||
def test_int_constant(self):
|
||||
self.assertEqual(mujoco.mjMAXVFSNAME, 1000)
|
||||
|
||||
def test_float_constant(self):
|
||||
self.assertEqual(mujoco.mjMAXVAL, 1e10)
|
||||
self.assertEqual(mujoco.mjMINVAL, 1e-15)
|
||||
|
||||
@@ -57,8 +57,6 @@ PYBIND11_MODULE(_constants, pymodule) {
|
||||
X(mjMINIMP);
|
||||
X(mjMAXIMP);
|
||||
X(mjMAXCONPAIR);
|
||||
X(mjMAXVFS);
|
||||
X(mjMAXVFSNAME);
|
||||
X(mjNEQDATA);
|
||||
X(mjNDYN);
|
||||
X(mjNGAIN);
|
||||
|
||||
@@ -317,24 +317,22 @@ static raw::MjModel* LoadModelFileImpl(
|
||||
const std::string& filename,
|
||||
const std::vector<VfsAsset>& assets,
|
||||
LoadFunc&& loadfunc) {
|
||||
std::unique_ptr<mjVFS, void(*)(mjVFS*)> vfs(nullptr, [](mjVFS*){});
|
||||
mjVFS vfs;
|
||||
mjVFS* vfs_ptr = nullptr;
|
||||
if (!assets.empty()) {
|
||||
// mjVFS should be allocated on the heap, because it's ~2MB
|
||||
vfs = decltype(vfs)(new mjVFS, [](mjVFS* vfs) {
|
||||
mj_deleteVFS(vfs);
|
||||
delete vfs;
|
||||
});
|
||||
mj_defaultVFS(vfs.get());
|
||||
mj_defaultVFS(&vfs);
|
||||
vfs_ptr = &vfs;
|
||||
for (const auto& asset : assets) {
|
||||
const int vfs_error = InterceptMjErrors(mj_addBufferVFS)(
|
||||
vfs.get(), asset.name, asset.content, asset.content_size);
|
||||
vfs_ptr, asset.name, asset.content, asset.content_size);
|
||||
if (vfs_error) {
|
||||
throw py::value_error("assets dict is too big");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
raw::MjModel* model = loadfunc(filename.c_str(), vfs.get());
|
||||
raw::MjModel* model = loadfunc(filename.c_str(), vfs_ptr);
|
||||
mj_deleteVFS(vfs_ptr);
|
||||
if (model && !model->buffer) {
|
||||
mj_deleteModel(model);
|
||||
model = nullptr;
|
||||
@@ -351,12 +349,6 @@ ConvertAssetsDict(
|
||||
std::vector<VfsAsset> out;
|
||||
if (assets.has_value()) {
|
||||
for (const auto& [name, content] : *assets) {
|
||||
if (name.length() >= mjMAXVFSNAME) {
|
||||
std::ostringstream error;
|
||||
error << "Filename length " << name.length() << " exceeds "
|
||||
<< mjMAXVFSNAME - 1 << " character limit: " << name;
|
||||
throw py::value_error(error.str());
|
||||
}
|
||||
out.emplace_back(name.c_str(), PYBIND11_BYTES_AS_STRING(content.ptr()),
|
||||
py::len(content));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user