Add policies for global attribute conflict resolution upon attach
For example when loading parent_merge.xml: ``` WARNING: Attach conflict when attaching 'child' to 'parent_merge', policy is 'merge' timestep: parent has 0.005, child has 0.002, taking the minimum iterations: parent has 50, child has 100, taking the maximum flag 'Damper': added from child ``` When loading parent_error.xml: ``` XML Error: Attach conflict when attaching 'child' to 'parent_error', policy is 'error' timestep: parent has 0.005, child has 0.002 iterations: parent has 50, child has 100 Element 'attach', line 10 ``` PiperOrigin-RevId: 933620810 Change-Id: Ib477863b5ef763474d27fb4be5a4148be1d5d500
This commit is contained in:
committed by
Copybara-Service
parent
30357c38a3
commit
410c73168c
@@ -3897,5 +3897,80 @@ TEST_F(ActuatorParseTest, DampingArmatureDefaultsPropagate) {
|
||||
mj_deleteModel(model);
|
||||
}
|
||||
|
||||
TEST_F(XMLReaderTest, AttachConflictXMLWarning) {
|
||||
mock_warning_handler.ExpectWarnings();
|
||||
std::array<char, 1024> error;
|
||||
std::string path = GetTestDataFilePath("xml/testdata/parent_warn.xml");
|
||||
mjSpec* spec = mj_parseXML(path.c_str(), nullptr, error.data(), error.size());
|
||||
ASSERT_THAT(spec, NotNull()) << error.data();
|
||||
|
||||
// one grouped warning per attach, containing gravity and damper flag
|
||||
// (constraint is only authored by child, not a conflict)
|
||||
EXPECT_EQ(mjs_numWarnings(spec), 1);
|
||||
std::string w = mjs_getWarning(spec, 0);
|
||||
EXPECT_THAT(w, HasSubstr("gravity: parent has 0 0 -10, child has 0 0 0,"
|
||||
" keeping parent value"));
|
||||
EXPECT_THAT(w, HasSubstr("flag 'Damper'"));
|
||||
|
||||
mjModel* m = mj_compile(spec, nullptr);
|
||||
ASSERT_THAT(m, NotNull());
|
||||
// Gravity should be parent's value (0 0 -10)
|
||||
EXPECT_MJTNUM_EQ(m->opt.gravity[0], 0);
|
||||
EXPECT_MJTNUM_EQ(m->opt.gravity[1], 0);
|
||||
EXPECT_MJTNUM_EQ(m->opt.gravity[2], -10);
|
||||
|
||||
mj_deleteModel(m);
|
||||
mj_deleteSpec(spec);
|
||||
}
|
||||
|
||||
TEST_F(XMLReaderTest, AttachConflictXMLMerge) {
|
||||
mock_warning_handler.ExpectWarnings();
|
||||
std::array<char, 1024> error;
|
||||
std::string path = GetTestDataFilePath("xml/testdata/parent_merge.xml");
|
||||
mjSpec* spec = mj_parseXML(path.c_str(), nullptr, error.data(), error.size());
|
||||
ASSERT_THAT(spec, NotNull()) << error.data();
|
||||
|
||||
// one grouped warning per attach, containing timestep, iterations, and flag
|
||||
EXPECT_GE(mjs_numWarnings(spec), 1);
|
||||
std::string w = mjs_getWarning(spec, 0);
|
||||
EXPECT_THAT(w, HasSubstr("timestep: parent has 0.005, child has 0.002,"
|
||||
" taking the minimum"));
|
||||
EXPECT_THAT(w, HasSubstr("iterations: parent has 50, child has 100,"
|
||||
" taking the maximum"));
|
||||
|
||||
mjModel* m = mj_compile(spec, nullptr);
|
||||
ASSERT_THAT(m, NotNull());
|
||||
// Timestep should be min (0.002)
|
||||
EXPECT_MJTNUM_EQ(m->opt.timestep, 0.002);
|
||||
// Iterations should be max (100)
|
||||
EXPECT_EQ(m->opt.iterations, 100);
|
||||
|
||||
mj_deleteModel(m);
|
||||
mj_deleteSpec(spec);
|
||||
}
|
||||
|
||||
TEST_F(XMLReaderTest, AttachConflictXMLError) {
|
||||
std::array<char, 1024> error;
|
||||
std::string path = GetTestDataFilePath("xml/testdata/parent_error.xml");
|
||||
mjSpec* spec = mj_parseXML(path.c_str(), nullptr, error.data(), error.size());
|
||||
|
||||
// Should fail to parse because of conflict in timestep in error mode
|
||||
EXPECT_THAT(spec, IsNull());
|
||||
EXPECT_THAT(error.data(),
|
||||
HasSubstr("timestep: parent has 0.005, child has 0.002"));
|
||||
}
|
||||
|
||||
TEST_F(XMLReaderTest, AttachConflictXMLMergeUnmergableError) {
|
||||
std::array<char, 1024> error;
|
||||
std::string path =
|
||||
GetTestDataFilePath("xml/testdata/parent_merge_unmergable.xml");
|
||||
mjSpec* spec = mj_parseXML(path.c_str(), nullptr, error.data(), error.size());
|
||||
|
||||
// Should fail to parse because gravity is unmergeable in merge mode
|
||||
EXPECT_THAT(spec, IsNull());
|
||||
EXPECT_THAT(error.data(),
|
||||
HasSubstr("gravity: parent has 0 0 -10, child has 0 0 0"));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace mujoco
|
||||
|
||||
Reference in New Issue
Block a user