Add recursive call to FindSpec for handling nested attachments.
PiperOrigin-RevId: 713629578 Change-Id: I23efa5a86bac187fc42eb955d29cc03cbacfd9e0
This commit is contained in:
committed by
Copybara-Service
parent
40ef08c8ed
commit
f7d38dac62
@@ -151,6 +151,7 @@ mjCMesh::mjCMesh(mjCModel* _model, mjCDef* _def) {
|
||||
|
||||
// set model, def
|
||||
model = _model;
|
||||
if (_model) compiler = &_model->spec.compiler;
|
||||
classname = (_def ? _def->name : (_model ? "main" : ""));
|
||||
|
||||
// in case this body is not compiled
|
||||
@@ -1981,6 +1982,7 @@ mjCSkin::mjCSkin(mjCModel* _model) {
|
||||
|
||||
// set model pointer
|
||||
model = _model;
|
||||
if (model) compiler = &model->spec.compiler;
|
||||
|
||||
// clear data
|
||||
spec_file_.clear();
|
||||
@@ -2638,6 +2640,7 @@ mjCFlex::mjCFlex(mjCModel* _model) {
|
||||
|
||||
// set model
|
||||
model = _model;
|
||||
if (_model) compiler = &_model->spec.compiler;
|
||||
|
||||
// clear internal variables
|
||||
nvert = 0;
|
||||
|
||||
@@ -236,7 +236,7 @@ void mjCModel::CopyList(std::vector<T*>& dest,
|
||||
}
|
||||
// copy the element from the other model to this model
|
||||
source[i]->ForgetKeyframes();
|
||||
mjSpec* origin = FindSpec(mjs_getString(source[i]->model->spec.modelname));
|
||||
mjSpec* origin = FindSpec(source[i]->compiler);
|
||||
dest.push_back(candidate);
|
||||
dest.back()->model = this;
|
||||
dest.back()->compiler = origin ? &origin->compiler : &spec.compiler;
|
||||
@@ -1228,9 +1228,13 @@ mjSpec* mjCModel::FindSpec(std::string name) const {
|
||||
|
||||
// find spec by mjsCompiler pointer
|
||||
mjSpec* mjCModel::FindSpec(const mjsCompiler* compiler_) const {
|
||||
for (auto spec : specs_) {
|
||||
if (&(static_cast<const mjCModel*>(spec->element)->GetSourceSpec()->compiler) == compiler_) {
|
||||
return spec;
|
||||
if (&GetSourceSpec()->compiler == compiler_) {
|
||||
return (mjSpec*)&spec;
|
||||
}
|
||||
for (auto s : specs_) {
|
||||
mjSpec* source = static_cast<mjCModel*>(s->element)->FindSpec(compiler_);
|
||||
if (source) {
|
||||
return source;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
|
||||
@@ -2033,6 +2033,19 @@ TEST_F(MujocoTest, ResizeParentKeyframe) {
|
||||
}
|
||||
|
||||
TEST_F(MujocoTest, DifferentUnitsAllowed) {
|
||||
static constexpr char gchild_xml[] = R"(
|
||||
<mujoco model="gchild">
|
||||
<compiler angle="radian"/>
|
||||
|
||||
<worldbody>
|
||||
<body name="gchild" euler="-1.5707963 0 0">
|
||||
<geom type="box" size="1 1 1"/>
|
||||
<joint name="gchild_joint" range="-3.1415926 3.1415926"/>
|
||||
</body>
|
||||
</worldbody>
|
||||
</mujoco>
|
||||
)";
|
||||
|
||||
static constexpr char child_xml[] = R"(
|
||||
<mujoco>
|
||||
<compiler angle="radian"/>
|
||||
@@ -2041,6 +2054,7 @@ TEST_F(MujocoTest, DifferentUnitsAllowed) {
|
||||
<body name="child" euler="-1.5707963 0 0">
|
||||
<geom type="box" size="1 1 1"/>
|
||||
<joint name="child_joint" range="-3.1415926 3.1415926"/>
|
||||
<frame name="frame" euler="1.5707963 0 0"/>
|
||||
</body>
|
||||
</worldbody>
|
||||
</mujoco>
|
||||
@@ -2059,19 +2073,27 @@ TEST_F(MujocoTest, DifferentUnitsAllowed) {
|
||||
)";
|
||||
|
||||
std::array<char, 1024> error;
|
||||
mjSpec* gchild =
|
||||
mj_parseXMLString(gchild_xml, 0, error.data(), error.size());
|
||||
mjSpec* child = mj_parseXMLString(child_xml, 0, error.data(), error.size());
|
||||
mjSpec* spec = mj_parseXMLString(parent_xml, 0, error.data(), error.size());
|
||||
ASSERT_THAT(spec, NotNull()) << error.data();
|
||||
mjs_attachBody(mjs_findFrame(spec, "frame"), mjs_findBody(child, "child"),
|
||||
mjs_attachBody(mjs_findFrame(child, "frame"),
|
||||
mjs_findBody(gchild, "gchild"),
|
||||
"gchild_", "");
|
||||
mjs_attachBody(mjs_findFrame(spec, "frame"),
|
||||
mjs_findBody(child, "child"),
|
||||
"child_", "");
|
||||
|
||||
mjModel* model = mj_compile(spec, 0);
|
||||
EXPECT_THAT(model, NotNull());
|
||||
EXPECT_THAT(model->njnt, 2);
|
||||
EXPECT_THAT(model->njnt, 3);
|
||||
EXPECT_NEAR(model->jnt_range[0], -mjPI, 1e-6);
|
||||
EXPECT_NEAR(model->jnt_range[1], mjPI, 1e-6);
|
||||
EXPECT_NEAR(model->jnt_range[2], -mjPI, 1e-6);
|
||||
EXPECT_NEAR(model->jnt_range[3], mjPI, 1e-6);
|
||||
EXPECT_NEAR(model->jnt_range[4], -mjPI, 1e-6);
|
||||
EXPECT_NEAR(model->jnt_range[5], mjPI, 1e-6);
|
||||
EXPECT_NEAR(model->body_quat[4], 1, 1e-12);
|
||||
EXPECT_NEAR(model->body_quat[5], 0, 1e-12);
|
||||
EXPECT_NEAR(model->body_quat[6], 0, 1e-12);
|
||||
@@ -2079,6 +2101,7 @@ TEST_F(MujocoTest, DifferentUnitsAllowed) {
|
||||
|
||||
mjSpec* copied_spec = mj_copySpec(spec);
|
||||
ASSERT_THAT(copied_spec, NotNull());
|
||||
mj_deleteSpec(gchild);
|
||||
mj_deleteSpec(child);
|
||||
mj_deleteSpec(spec);
|
||||
mj_deleteModel(model);
|
||||
@@ -2086,11 +2109,13 @@ TEST_F(MujocoTest, DifferentUnitsAllowed) {
|
||||
// check that deleting `parent` or `child` does not invalidate the copy
|
||||
mjModel* copied_model = mj_compile(copied_spec, 0);
|
||||
EXPECT_THAT(copied_model, NotNull());
|
||||
EXPECT_THAT(copied_model->njnt, 2);
|
||||
EXPECT_THAT(copied_model->njnt, 3);
|
||||
EXPECT_NEAR(copied_model->jnt_range[0], -mjPI, 1e-6);
|
||||
EXPECT_NEAR(copied_model->jnt_range[1], mjPI, 1e-6);
|
||||
EXPECT_NEAR(copied_model->jnt_range[2], -mjPI, 1e-6);
|
||||
EXPECT_NEAR(copied_model->jnt_range[3], mjPI, 1e-6);
|
||||
EXPECT_NEAR(copied_model->jnt_range[4], -mjPI, 1e-6);
|
||||
EXPECT_NEAR(copied_model->jnt_range[5], mjPI, 1e-6);
|
||||
EXPECT_NEAR(copied_model->body_quat[4], 1, 1e-12);
|
||||
EXPECT_NEAR(copied_model->body_quat[5], 0, 1e-12);
|
||||
EXPECT_NEAR(copied_model->body_quat[6], 0, 1e-12);
|
||||
|
||||
Reference in New Issue
Block a user