diff --git a/src/user/user_objects.cc b/src/user/user_objects.cc index e8a068b4..c2fff3d8 100644 --- a/src/user/user_objects.cc +++ b/src/user/user_objects.cc @@ -4064,7 +4064,7 @@ void mjCKey::Compile(const mjModel* m) { qpos[i] = (double)m->qpos0[i]; } } else if (qpos.size()!=m->nq) { - throw mjCError(this, "key %d: invalid qpos size", 0, id); + throw mjCError(this, "key %d: invalid qpos size, expected length %d", nullptr, id, m->nq); } // qvel: allocate or check size @@ -4074,7 +4074,7 @@ void mjCKey::Compile(const mjModel* m) { qvel[i] = 0; } } else if (qvel.size()!=m->nv) { - throw mjCError(this, "key %d: invalid qvel size", 0, id); + throw mjCError(this, "key %d: invalid qvel size, expected length %d", nullptr, id, m->nv); } // act: allocate or check size @@ -4084,7 +4084,7 @@ void mjCKey::Compile(const mjModel* m) { act[i] = 0; } } else if (act.size()!=m->na) { - throw mjCError(this, "key %d: invalid act size", 0, id); + throw mjCError(this, "key %d: invalid act size, expected length %d", nullptr, id, m->na); } // mpos: allocate or check size @@ -4101,7 +4101,7 @@ void mjCKey::Compile(const mjModel* m) { } } } else if (mpos.size()!=3*m->nmocap) { - throw mjCError(this, "key %d: invalid mpos size", 0, id); + throw mjCError(this, "key %d: invalid mpos size, expected length %d", nullptr, id, 3*m->nmocap); } // mquat: allocate or check size @@ -4119,7 +4119,7 @@ void mjCKey::Compile(const mjModel* m) { } } } else if (mquat.size()!=4*m->nmocap) { - throw mjCError(this, "key %d: invalid mquat size", 0, id); + throw mjCError(this, "key %d: invalid mquat size, expected length %d", nullptr, id, 4*m->nmocap); } // ctrl: allocate or check size @@ -4129,7 +4129,7 @@ void mjCKey::Compile(const mjModel* m) { ctrl[i] = 0; } } else if (ctrl.size()!=m->nu) { - throw mjCError(this, "key %d: invalid ctrl size", 0, id); + throw mjCError(this, "key %d: invalid ctrl size, expected length %d", nullptr, id, m->nu); } } diff --git a/test/user/user_objects_test.cc b/test/user/user_objects_test.cc index d9631aec..e0c6256b 100644 --- a/test/user/user_objects_test.cc +++ b/test/user/user_objects_test.cc @@ -39,9 +39,11 @@ using ::testing::NotNull; // ------------------------ test keyframes ------------------------------------- +using KeyframeTest = MujocoTest; + constexpr char kKeyframePath[] = "user/testdata/keyframe.xml"; -TEST_F(MujocoTest, KeyFrameTest) { +TEST_F(KeyframeTest, CheckValues) { const std::string xml_path = GetTestDataFilePath(kKeyframePath); mjModel* model = mj_loadXML(xml_path.c_str(), nullptr, nullptr, 0); ASSERT_THAT(model, NotNull()); @@ -59,7 +61,7 @@ TEST_F(MujocoTest, KeyFrameTest) { mj_deleteModel(model); } -TEST_F(MujocoTest, ResetDataKeyframeTest) { +TEST_F(KeyframeTest, ResetDataKeyframe) { const std::string xml_path = GetTestDataFilePath(kKeyframePath); mjModel* model = mj_loadXML(xml_path.c_str(), nullptr, nullptr, 0); ASSERT_THAT(model, NotNull()); @@ -91,6 +93,21 @@ TEST_F(MujocoTest, ResetDataKeyframeTest) { mj_deleteModel(model); } +TEST_F(KeyframeTest, BadSize) { + static constexpr char xml[] = R"( + + + + + + )"; + char error[1024]; + size_t error_sz = 1024; + mjModel* model = LoadModelFromString(xml, error, error_sz); + EXPECT_THAT(model, ::testing::IsNull()); + EXPECT_THAT(error, HasSubstr("invalid qpos size, expected length 0")); +} + // ------------- test relative frame sensor compilation------------------------- using RelativeFrameSensorParsingTest = MujocoTest;