Throw an error if multiple orientation specifiers are used in the same element.
- Applies to [orientation specifiers](https://mujoco.readthedocs.io/en/latest/modeling.html#frame-orientations) in `body`, `inertial`, `geom`, `site`, `camera`. - Before this change the check was done only for multiple *alternative* specifiers, but not for `quat` and an alternative specifier. - Moved the check from the compiler to the parser. - Added tests. PiperOrigin-RevId: 453201981 Change-Id: I20907361f211dae904e734cd083e9df0efe4f654
This commit is contained in:
committed by
Copybara-Service
parent
652bab3eec
commit
16baac9353
@@ -120,16 +120,6 @@ mjCAlternative::mjCAlternative() {
|
||||
// used for geom, site, body and camera frames
|
||||
const char* mjCAlternative::Set(double* quat, double* inertia,
|
||||
bool degree, const char* sequence) {
|
||||
// check for multiple defitions
|
||||
int ndef = (int)mjuu_defined(axisangle[0]) +
|
||||
(int)mjuu_defined(xyaxes[0]) +
|
||||
(int)mjuu_defined(zaxis[0]) +
|
||||
(int)mjuu_defined(euler[0]) +
|
||||
(int)mjuu_defined(fullinertia[0]);
|
||||
if (ndef>1) {
|
||||
return "too many alternative definitions";
|
||||
}
|
||||
|
||||
// set quat using axisangle
|
||||
if (mjuu_defined(axisangle[0])) {
|
||||
// convert to radians if necessary, normalize axis
|
||||
|
||||
+8
-5
@@ -52,9 +52,12 @@ void mjXBase::SetModel(mjCModel* _model) {
|
||||
// read alternative orientation specification
|
||||
void mjXBase::ReadAlternative(XMLElement* elem, mjCAlternative& alt) {
|
||||
string text;
|
||||
ReadAttr(elem, "axisangle", 4, alt.axisangle, text);
|
||||
ReadAttr(elem, "xyaxes", 6, alt.xyaxes, text);
|
||||
ReadAttr(elem, "zaxis", 3, alt.zaxis, text);
|
||||
ReadAttr(elem, "euler", 3, alt.euler, text);
|
||||
ReadAttr(elem, "fullinertia", 6, alt.fullinertia, text);
|
||||
int read = (int)(elem->Attribute("quat") != 0) +
|
||||
(ReadAttr(elem, "axisangle", 4, alt.axisangle, text) ? 1 : 0) +
|
||||
(ReadAttr(elem, "xyaxes", 6, alt.xyaxes, text) ? 1 : 0) +
|
||||
(ReadAttr(elem, "zaxis", 3, alt.zaxis, text) ? 1 : 0) +
|
||||
(ReadAttr(elem, "euler", 3, alt.euler, text) ? 1 : 0) +
|
||||
(ReadAttr(elem, "fullinertia", 6, alt.fullinertia, text) ? 1 : 0);
|
||||
if (read > 1)
|
||||
throw mjXError(elem, "multiple orientation specifiers for the same field are not allowed");
|
||||
}
|
||||
|
||||
@@ -1120,9 +1120,9 @@ void mjXReader::OneGeom(XMLElement* elem, mjCGeom* pgeom) {
|
||||
ReadAttr(elem, "mass", 1, &pgeom->_mass, text);
|
||||
ReadAttr(elem, "density", 1, &pgeom->density, text);
|
||||
ReadAttr(elem, "fromto", 6, pgeom->fromto, text);
|
||||
ReadAlternative(elem, pgeom->alt);
|
||||
ReadAttr(elem, "pos", 3, pgeom->pos, text);
|
||||
ReadAttr(elem, "quat", 4, pgeom->quat, text);
|
||||
ReadAlternative(elem, pgeom->alt);
|
||||
|
||||
GetXMLPos(elem, pgeom);
|
||||
}
|
||||
|
||||
@@ -192,6 +192,49 @@ TEST_F(UserDataTest, AllowsSpaces) {
|
||||
mj_deleteModel(model);
|
||||
}
|
||||
|
||||
TEST_F(UserDataTest, InvalidDoubleOrientation) {
|
||||
std::string prefix = "<mujoco><worldbody><";
|
||||
std::string suffix = "/></worldbody></mujoco>";
|
||||
std::vector<std::string> orientations = {
|
||||
R"( quat="0 1 0 0" )",
|
||||
R"( euler="1.7 2.9 0.1" )",
|
||||
R"( zaxis="1.7 2.9 0.1" )",
|
||||
R"( axisangle="1.7 2.9 0.1 0" )",
|
||||
R"( xyaxes="1.7 2.9 0.1 0.4 1.4 0.6" )",
|
||||
};
|
||||
std::vector<std::string> fields = {
|
||||
"geom", "body", "camera", "site"
|
||||
};
|
||||
for (auto const& field : fields) {
|
||||
for (auto const& orient1 : orientations) {
|
||||
for (auto const& orient2 : orientations) {
|
||||
if (orient1 == orient2) continue;
|
||||
std::string xml = prefix + field + orient1 + orient2 + suffix;
|
||||
std::array<char, 1024> error;
|
||||
mjModel* model = LoadModelFromString(xml.c_str(), error.data(), error.size());
|
||||
ASSERT_THAT(model, IsNull());
|
||||
EXPECT_THAT(error.data(), HasSubstr("multiple orientation specifiers for the same field"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(UserDataTest, InvalidInertialOrientation) {
|
||||
static constexpr char xml[] = R"(
|
||||
<mujoco>
|
||||
<worldbody>
|
||||
<body>
|
||||
<inertial pos="0 0 0" mass="1" quat="1 0 0 0" fullinertia="1 1 1 0 0 0"/>
|
||||
</body>
|
||||
</worldbody>
|
||||
</mujoco>
|
||||
)";
|
||||
std::array<char, 1024> error;
|
||||
mjModel* model = LoadModelFromString(xml, error.data(), error.size());
|
||||
ASSERT_THAT(model, IsNull());
|
||||
EXPECT_THAT(error.data(), HasSubstr("multiple orientation specifiers for the same field"));
|
||||
}
|
||||
|
||||
// ------------- test relative frame sensor parsing ----------------------------
|
||||
|
||||
using RelativeFrameSensorParsingTest = MujocoTest;
|
||||
|
||||
Reference in New Issue
Block a user