Add mj_parseXML and mj_saveXML to xml_api.

PiperOrigin-RevId: 640099466
Change-Id: I75f763523c5bc8f6f7c2f2de6806d82ba37ebd4e
This commit is contained in:
Alessio Quaglino
2024-06-04 11:59:32 +01:00
committed by Saran Tunyasuvunakool
parent 1bf90af0e0
commit b35ae973e1
11 changed files with 143 additions and 37 deletions
+63 -15
View File
@@ -24,6 +24,8 @@
#include <mujoco/mjdata.h>
#include <mujoco/mjmodel.h>
#include <mujoco/mujoco.h>
#include "src/user/user_api.h"
#include "src/xml/xml_api.h"
#include "test/fixture.h"
namespace mujoco {
@@ -33,6 +35,21 @@ using ::testing::IsNull;
using ::testing::NotNull;
using ::testing::StartsWith;
static constexpr char xml[] = R"(
<mujoco>
<worldbody>
<body>
<joint/>
<geom size="1"/>
</body>
<body>
<joint/>
<geom size="0.5"/>
</body>
</worldbody>
</mujoco>
)";
// ---------------------------- test mj_loadXML --------------------------------
using LoadXmlTest = MujocoTest;
@@ -66,20 +83,6 @@ TEST_F(LoadXmlTest, InvalidXmlFailsToLoad) {
}
TEST_F(LoadXmlTest, MultipleBodies) {
static constexpr char xml[] = R"(
<mujoco>
<worldbody>
<body>
<joint/>
<geom size="1"/>
</body>
<body>
<joint/>
<geom size="0.5"/>
</body>
</worldbody>
</mujoco>
)";
std::array<char, 1000> error;
mjModel* model = LoadModelFromString(xml, error.data(), error.size());
@@ -92,7 +95,6 @@ TEST_F(LoadXmlTest, MultipleBodies) {
mj_deleteData(data);
mj_deleteModel(model);
}
using SaveLastXmlTest = MujocoTest;
TEST_F(SaveLastXmlTest, EmptyModel) {
@@ -112,5 +114,51 @@ TEST_F(SaveLastXmlTest, EmptyModel) {
mj_deleteModel(model);
}
TEST_F(MujocoTest, SaveXmlShortString) {
std::array<char, 1000> error;
mjSpec* spec = mj_parseXMLString(xml, 0, error.data(), error.size());
EXPECT_THAT(spec, NotNull()) << "Failed to parse spec: " << error.data();
mjModel* model = mjs_compile(spec, 0);
EXPECT_THAT(model, NotNull()) << "Failed to compile model: " << error.data();
std::array<char, 10> out;
EXPECT_THAT(mj_saveXMLString(spec, out.data(), out.size(),
error.data(), error.size()), 0);
EXPECT_STREQ(error.data(), "Output string too short, should be at least 273");
mjs_deleteSpec(spec);
mj_deleteModel(model);
}
TEST_F(MujocoTest, SaveXml) {
std::array<char, 1000> error;
mjSpec* spec = mj_parseXMLString(xml, 0, error.data(), error.size());
EXPECT_THAT(spec, NotNull()) << "Failed to parse spec: " << error.data();
mjModel* model = mjs_compile(spec, 0);
EXPECT_THAT(model, NotNull()) << "Failed to compile model: " << error.data();
std::array<char, 273> out;
EXPECT_THAT(mj_saveXMLString(spec, out.data(), out.size(), error.data(),
error.size()), 1) << error.data();
mjSpec* saved_spec = mj_parseXMLString(xml, 0, error.data(), error.size());
EXPECT_THAT(saved_spec, NotNull()) << "Invalid saved spec: " << error.data();
mjModel* saved_model = mjs_compile(saved_spec, 0);
EXPECT_THAT(saved_model, NotNull()) << "Invalid model: " << error.data();
mjtNum tol = 0;
std::string field = "";
EXPECT_LE(CompareModel(model, saved_model, field), tol)
<< "Expected and attached models are different!\n"
<< "Different field: " << field << '\n';
mjs_deleteSpec(spec);
mjs_deleteSpec(saved_spec);
mj_deleteModel(model);
mj_deleteModel(saved_model);
}
} // namespace
} // namespace mujoco