Add error reporting to model loading in engine tests, where missing

PiperOrigin-RevId: 795844607
Change-Id: I4163c53c05796c2e3036af28a98f58c15bb1c99c
This commit is contained in:
Yuval Tassa
2025-08-16 08:11:11 -07:00
committed by Copybara-Service
parent bbb70d98a4
commit 5a24eb2d34
16 changed files with 220 additions and 98 deletions
+4 -3
View File
@@ -238,7 +238,7 @@ TEST_F(MjCollisionBoxTest, DeepPenetration) {
mj_forward(model, data); mj_forward(model, data);
// expect 4 contact // expect 4 contact
EXPECT_EQ(data->ncon ,4); EXPECT_EQ(data->ncon, 4);
mj_deleteData(data); mj_deleteData(data);
mj_deleteModel(model); mj_deleteModel(model);
@@ -257,8 +257,9 @@ TEST_F(MjCollisionBoxTest, BoxSphere) {
</worldbody> </worldbody>
</mujoco> </mujoco>
)"; )";
mjModel* model = LoadModelFromString(xml); char error[1024];
ASSERT_THAT(model, NotNull()); mjModel* model = LoadModelFromString(xml, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
for (mjtNum z : {-.015, -.00501, -.005, -.00499, 0.0, 0.004}) { for (mjtNum z : {-.015, -.00501, -.005, -.00499, 0.0, 0.004}) {
+18 -9
View File
@@ -14,8 +14,11 @@
// Tests for engine/engine_collision_driver.c. // Tests for engine/engine_collision_driver.c.
#include <algorithm>
#include <cmath>
#include <cstddef> #include <cstddef>
#include <string> #include <string>
#include <utility>
#include <vector> #include <vector>
#include <gmock/gmock.h> #include <gmock/gmock.h>
@@ -68,7 +71,9 @@ TEST_F(MjCollisionTest, AllCollisions) {
} }
TEST_F(MjCollisionTest, EmptyModel) { TEST_F(MjCollisionTest, EmptyModel) {
mjModel* model = LoadModelFromString("<mujoco/>"); char error[1024];
mjModel* model = LoadModelFromString("<mujoco/>", error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
mj_fwdPosition(model, data); mj_fwdPosition(model, data);
@@ -117,8 +122,9 @@ TEST_F(MjCollisionTest, ContactCount) {
</worldbody> </worldbody>
</mujoco> </mujoco>
)"; )";
mjModel* m = LoadModelFromString(xml); char error[1024];
ASSERT_THAT(m, NotNull()); mjModel* m = LoadModelFromString(xml, error, sizeof(error));
ASSERT_THAT(m, NotNull()) << error;
mjData* d = mj_makeData(m); mjData* d = mj_makeData(m);
ASSERT_THAT(d, NotNull()); ASSERT_THAT(d, NotNull());
@@ -152,8 +158,9 @@ TEST_F(MjCollisionTest, FilterParent) {
</worldbody> </worldbody>
</mujoco> </mujoco>
)"; )";
mjModel* m = LoadModelFromString(xml); char error[1024];
ASSERT_THAT(m, NotNull()); mjModel* m = LoadModelFromString(xml, error, sizeof(error));
ASSERT_THAT(m, NotNull()) << error;
mjData* d = mj_makeData(m); mjData* d = mj_makeData(m);
ASSERT_THAT(d, NotNull()); ASSERT_THAT(d, NotNull());
@@ -186,8 +193,9 @@ TEST_F(MjCollisionTest, FilterParentDoesntAffectWorldBody) {
</worldbody> </worldbody>
</mujoco> </mujoco>
)"; )";
mjModel* m = LoadModelFromString(xml); char error[1024];
ASSERT_THAT(m, NotNull()); mjModel* m = LoadModelFromString(xml, error, sizeof(error));
ASSERT_THAT(m, NotNull()) << error;
mjData* d = mj_makeData(m); mjData* d = mj_makeData(m);
ASSERT_THAT(d, NotNull()); ASSERT_THAT(d, NotNull());
@@ -235,8 +243,9 @@ TEST_F(MjCollisionTest, PlaneInBody) {
</worldbody> </worldbody>
</mujoco> </mujoco>
)"; )";
mjModel* m = LoadModelFromString(xml); char error[1024];
ASSERT_THAT(m, NotNull()); mjModel* m = LoadModelFromString(xml, error, sizeof(error));
ASSERT_THAT(m, NotNull()) << error;
mjData* d = mj_makeData(m); mjData* d = mj_makeData(m);
ASSERT_THAT(d, NotNull()); ASSERT_THAT(d, NotNull());
mj_step(m, d); mj_step(m, d);
+3 -3
View File
@@ -20,8 +20,8 @@
#include <cstddef> #include <cstddef>
#include <vector> #include <vector>
#include <ccd/ccd.h> #include <ccd/ccd.h> // IWYU pragma: keep
#include <ccd/vec3.h> #include <ccd/vec3.h> // IWYU pragma: keep
#include "src/engine/engine_collision_convex.h" #include "src/engine/engine_collision_convex.h"
#include <mujoco/mujoco.h> #include <mujoco/mujoco.h>
@@ -31,7 +31,7 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
// uncomment to run tests with libccd // uncomment to run tests with libccd
//#define TEST_WITH_LIBCCD // #define TEST_WITH_LIBCCD
namespace mujoco { namespace mujoco {
namespace { namespace {
+3 -2
View File
@@ -47,8 +47,9 @@ static constexpr char kSdfModel[] = R"(
)"; )";
TEST_F(SdfTest, SdfPrimitive) { TEST_F(SdfTest, SdfPrimitive) {
mjModel* model = LoadModelFromString(kSdfModel); char error[1024];
ASSERT_THAT(model, NotNull()); mjModel* model = LoadModelFromString(kSdfModel, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
ASSERT_THAT(data, NotNull()); ASSERT_THAT(data, NotNull());
ASSERT_THAT(model->ngeom, kgeoms); ASSERT_THAT(model->ngeom, kgeoms);
+6 -4
View File
@@ -78,8 +78,9 @@ TEST_F(CoreConstraintTest, WeldRotJacobian) {
</worldbody> </worldbody>
</mujoco> </mujoco>
)"; )";
mjModel* model = LoadModelFromString(xml); char error[1024];
ASSERT_THAT(model, testing::NotNull()); mjModel* model = LoadModelFromString(xml, error, sizeof(error));
ASSERT_THAT(model, testing::NotNull()) << error;
ASSERT_EQ(model->nq, 7); ASSERT_EQ(model->nq, 7);
ASSERT_EQ(model->nv, 6); ASSERT_EQ(model->nv, 6);
static const int nv = 6; // for increased readability static const int nv = 6; // for increased readability
@@ -172,8 +173,9 @@ TEST_F(CoreConstraintTest, RestPenetration) {
</worldbody> </worldbody>
</mujoco> </mujoco>
)"; )";
mjModel* model = LoadModelFromString(xml); char error[1024];
ASSERT_THAT(model, testing::NotNull()); mjModel* model = LoadModelFromString(xml, error, sizeof(error));
ASSERT_THAT(model, testing::NotNull()) << error;
mjtNum gravity = -model->opt.gravity[2]; mjtNum gravity = -model->opt.gravity[2];
mjtNum damping_ratio = 0.8; mjtNum damping_ratio = 0.8;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
+10 -6
View File
@@ -18,6 +18,7 @@
#include "src/engine/engine_util_misc.h" #include "src/engine/engine_util_misc.h"
#include "src/engine/engine_util_sparse.h" #include "src/engine/engine_util_sparse.h"
#include <algorithm>
#include <string> #include <string>
#include <string_view> #include <string_view>
#include <vector> #include <vector>
@@ -61,8 +62,9 @@ TEST_F(CoreSmoothTest, MjDataWorldBodyValuesAreInitialized) {
</sensor> </sensor>
</mujoco> </mujoco>
)"; )";
mjModel* model = LoadModelFromString(xml); char error[1024];
ASSERT_THAT(model, NotNull()); mjModel* model = LoadModelFromString(xml, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
mj_resetDataDebug(model, data, 'd'); mj_resetDataDebug(model, data, 'd');
mj_forward(model, data); mj_forward(model, data);
@@ -98,8 +100,9 @@ TEST_F(CoreSmoothTest, MjKinematicsWorldXipos) {
</worldbody> </worldbody>
</mujoco> </mujoco>
)"; )";
mjModel* model = LoadModelFromString(xml); char error[1024];
ASSERT_THAT(model, NotNull()); mjModel* model = LoadModelFromString(xml, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
mj_resetDataDebug(model, data, 'd'); mj_resetDataDebug(model, data, 'd');
@@ -141,8 +144,9 @@ TEST_F(CoreSmoothTest, FixedTendonSortedIndices) {
</tendon> </tendon>
</mujoco> </mujoco>
)"; )";
mjModel* model = LoadModelFromString(xml); char error[1024];
ASSERT_THAT(model, NotNull()); mjModel* model = LoadModelFromString(xml, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
ASSERT_EQ(model->ntendon, 1); ASSERT_EQ(model->ntendon, 1);
ASSERT_EQ(model->nwrap, 3); ASSERT_EQ(model->nwrap, 3);
+3 -1
View File
@@ -159,7 +159,9 @@ TEST_F(DerivativeTest, DisabledActuators) {
</mujoco> </mujoco>
)"; )";
mjModel* m1 = LoadModelFromString(xml1); char error[1024];
mjModel* m1 = LoadModelFromString(xml1, error, sizeof(error));
ASSERT_THAT(m1, NotNull()) << error;
mjData* d1 = mj_makeData(m1); mjData* d1 = mj_makeData(m1);
d1->ctrl[0] = 6; d1->ctrl[0] = 6;
+55 -26
View File
@@ -83,7 +83,9 @@ TEST_P(ParametrizedForwardTest, ActLimited) {
</mujoco> </mujoco>
)"; )";
mjModel* model = LoadModelFromString(xml); char error[1024];
mjModel* model = LoadModelFromString(xml, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
model->opt.integrator = GetParam().integrator; model->opt.integrator = GetParam().integrator;
@@ -144,7 +146,9 @@ TEST_F(ForwardTest, DamperDampens) {
</actuator> </actuator>
</mujoco> </mujoco>
)"; )";
mjModel* model = LoadModelFromString(xml); char error[1024];
mjModel* model = LoadModelFromString(xml, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
// move the joint // move the joint
@@ -230,7 +234,9 @@ TEST_F(ImplicitIntegratorTest, EulerDampDisable) {
</mujoco> </mujoco>
)"; )";
mjModel* model = LoadModelFromString(xml); char error[1024];
mjModel* model = LoadModelFromString(xml, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
// step once, call mj_forward, save qvel and qacc // step once, call mj_forward, save qvel and qacc
@@ -250,7 +256,7 @@ TEST_F(ImplicitIntegratorTest, EulerDampDisable) {
// expect finite-differenced qacc to match to high precision // expect finite-differenced qacc to match to high precision
EXPECT_THAT(qacc_fd, Pointwise(DoubleNear(1e-14), qacc)); EXPECT_THAT(qacc_fd, Pointwise(DoubleNear(1e-14), qacc));
// reach the the same initial state // reach the same initial state
mj_resetData(model, data); mj_resetData(model, data);
mj_step(model, data); mj_step(model, data);
@@ -287,7 +293,9 @@ TEST_F(ImplicitIntegratorTest, EulerDampLimit) {
</mujoco> </mujoco>
)"; )";
mjModel* model = LoadModelFromString(xml); char error[1024];
mjModel* model = LoadModelFromString(xml, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
mjtNum diff_norm_prev = -1; mjtNum diff_norm_prev = -1;
@@ -343,7 +351,9 @@ TEST_F(ImplicitIntegratorTest, EulerImplicitEqivalent) {
</mujoco> </mujoco>
)"; )";
mjModel* model = LoadModelFromString(xml); char error[1024];
mjModel* model = LoadModelFromString(xml, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
// step 10 times with Euler, save copy of qpos as vector // step 10 times with Euler, save copy of qpos as vector
@@ -461,7 +471,9 @@ TEST_F(ForwardTest, ControlClamping) {
</actuator> </actuator>
</mujoco> </mujoco>
)"; )";
mjModel* model = LoadModelFromString(xml); char error[1024];
mjModel* model = LoadModelFromString(xml, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
// for the unclamped actuator, ctrl={1, 2} produce different accelerations // for the unclamped actuator, ctrl={1, 2} produce different accelerations
@@ -534,7 +546,9 @@ TEST_F(ForwardTest, MjcbControlDisabled) {
</actuator> </actuator>
</mujoco> </mujoco>
)"; )";
mjModel* model = LoadModelFromString(xml); char error[1024];
mjModel* model = LoadModelFromString(xml, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
// install global control callback // install global control callback
@@ -579,8 +593,9 @@ TEST_F(ForwardTest, gravcomp) {
</worldbody> </worldbody>
</mujoco> </mujoco>
)"; )";
mjModel* model = LoadModelFromString(xml); char error[1024];
ASSERT_THAT(model, NotNull()); mjModel* model = LoadModelFromString(xml, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
while (data->time < 1) { mj_step(model, data); } while (data->time < 1) { mj_step(model, data); }
@@ -615,8 +630,9 @@ TEST_F(ForwardTest, eq_active) {
</equality> </equality>
</mujoco> </mujoco>
)"; )";
mjModel* model = LoadModelFromString(xml); char error[1024];
ASSERT_THAT(model, NotNull()); mjModel* model = LoadModelFromString(xml, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
@@ -674,8 +690,9 @@ TEST_F(ForwardTest, NormalizeQuats) {
</sensor> </sensor>
</mujoco> </mujoco>
)"; )";
mjModel* model = LoadModelFromString(xml); char error[1024];
ASSERT_THAT(model, NotNull()); mjModel* model = LoadModelFromString(xml, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
mjData* data_u = mj_makeData(model); mjData* data_u = mj_makeData(model);
@@ -764,8 +781,9 @@ TEST_F(ForwardTest, MocapQuats) {
</sensor> </sensor>
</mujoco> </mujoco>
)"; )";
mjModel* model = LoadModelFromString(xml); char error[1024];
ASSERT_THAT(model, NotNull()); mjModel* model = LoadModelFromString(xml, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
mj_forward(model, data); mj_forward(model, data);
@@ -828,7 +846,9 @@ TEST_F(ForwardTest, MjcbActDynSecondOrderExpectsActnum) {
</actuator> </actuator>
</mujoco> </mujoco>
)"; )";
mjModel* model = LoadModelFromString(xml); char error[1024];
mjModel* model = LoadModelFromString(xml, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
// install global dynamics callback // install global dynamics callback
@@ -885,7 +905,9 @@ TEST_F(ActuatorTest, ExpectedAdhesionForce) {
</actuator> </actuator>
</mujoco> </mujoco>
)"; )";
mjModel* model = LoadModelFromString(xml); char error[1024];
mjModel* model = LoadModelFromString(xml, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
// iterate over cone type // iterate over cone type
@@ -1122,8 +1144,9 @@ TEST_F(FilterExactTest, ApproximatesContinuousTime) {
</actuator> </actuator>
</mujoco> </mujoco>
)"; )";
mjModel* model = LoadModelFromString(xml); char error[1024];
ASSERT_THAT(model, NotNull()); mjModel* model = LoadModelFromString(xml, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
const mjtNum kSimulationTime = 1.0; const mjtNum kSimulationTime = 1.0;
@@ -1182,8 +1205,9 @@ TEST_F(FilterExactTest, TimestepIndependent) {
</actuator> </actuator>
</mujoco> </mujoco>
)"; )";
mjModel* model = LoadModelFromString(xml); char error[1024];
ASSERT_THAT(model, NotNull()); mjModel* model = LoadModelFromString(xml, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
const mjtNum kSimulationTime = 1.0; const mjtNum kSimulationTime = 1.0;
@@ -1231,8 +1255,9 @@ TEST_F(FilterExactTest, ActEqualsCtrlWhenTauIsZero) {
</actuator> </actuator>
</mujoco> </mujoco>
)"; )";
mjModel* model = LoadModelFromString(xml); char error[1024];
ASSERT_THAT(model, NotNull()); mjModel* model = LoadModelFromString(xml, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
data->ctrl[0] = 0.5; data->ctrl[0] = 0.5;
data->act[0] = 0.0; data->act[0] = 0.0;
@@ -1337,7 +1362,9 @@ TEST_F(ActuatorTest, DisableActuator) {
</actuator> </actuator>
</mujoco> </mujoco>
)"; )";
mjModel* model = LoadModelFromString(xml); char error[1024];
mjModel* model = LoadModelFromString(xml, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
data->ctrl[0] = 1.0; data->ctrl[0] = 1.0;
@@ -1375,7 +1402,9 @@ TEST_F(ActuatorTest, DisableActuatorOutOfRange) {
</actuator> </actuator>
</mujoco> </mujoco>
)"; )";
mjModel* model = LoadModelFromString(xml); char error[1024];
mjModel* model = LoadModelFromString(xml, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
data->ctrl[0] = 1.0; data->ctrl[0] = 1.0;
+8 -2
View File
@@ -18,6 +18,7 @@
#include <string> #include <string>
#include <gmock/gmock.h>
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <mujoco/mjmodel.h> #include <mujoco/mjmodel.h>
#include <mujoco/mujoco.h> #include <mujoco/mujoco.h>
@@ -26,6 +27,7 @@
namespace mujoco { namespace mujoco {
namespace { namespace {
using ::testing::NotNull;
using InverseTest = MujocoTest; using InverseTest = MujocoTest;
const int kSteps = 70; const int kSteps = 70;
@@ -34,7 +36,9 @@ static const char* const kModelPath = "testdata/model.xml";
// test standard continuous-time inverse dynamics // test standard continuous-time inverse dynamics
TEST_F(InverseTest, ForwardInverseMatch) { TEST_F(InverseTest, ForwardInverseMatch) {
const std::string xml_path = GetTestDataFilePath(kModelPath); const std::string xml_path = GetTestDataFilePath(kModelPath);
mjModel* model = mj_loadXML(xml_path.c_str(), nullptr, nullptr, 0); char error[1024];
mjModel* model = mj_loadXML(xml_path.c_str(), nullptr, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
// simulate, call mj_forward // simulate, call mj_forward
@@ -59,7 +63,9 @@ TEST_F(InverseTest, ForwardInverseMatch) {
TEST_F(InverseTest, DiscreteInverseMatch) { TEST_F(InverseTest, DiscreteInverseMatch) {
// load and allocate // load and allocate
const std::string xml_path = GetTestDataFilePath(kModelPath); const std::string xml_path = GetTestDataFilePath(kModelPath);
mjModel* model = mj_loadXML(xml_path.c_str(), nullptr, nullptr, 0); char error[1024];
mjModel* model = mj_loadXML(xml_path.c_str(), nullptr, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
int nv = model->nv; int nv = model->nv;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
int nstate = mj_stateSize(model, mjSTATE_INTEGRATION); int nstate = mj_stateSize(model, mjSTATE_INTEGRATION);
+22 -8
View File
@@ -15,7 +15,6 @@
// Tests for engine/engine_island.c. // Tests for engine/engine_island.c.
#include <string> #include <string>
#include <vector>
#include <gmock/gmock.h> #include <gmock/gmock.h>
#include <gtest/gtest.h> #include <gtest/gtest.h>
@@ -30,6 +29,7 @@ namespace {
using ::testing::DoubleNear; using ::testing::DoubleNear;
using ::testing::ElementsAre; using ::testing::ElementsAre;
using ::testing::NotNull;
using ::testing::Pointwise; using ::testing::Pointwise;
using IslandTest = MujocoTest; using IslandTest = MujocoTest;
@@ -185,7 +185,9 @@ static const char* const kAbacusPath =
TEST_F(IslandTest, Abacus) { TEST_F(IslandTest, Abacus) {
const std::string xml_path = GetTestDataFilePath(kAbacusPath); const std::string xml_path = GetTestDataFilePath(kAbacusPath);
mjModel* model = mj_loadXML(xml_path.c_str(), nullptr, nullptr, 0); char error[1024];
mjModel* model = mj_loadXML(xml_path.c_str(), nullptr, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
// disable gravity // disable gravity
model->opt.disableflags |= mjDSBL_GRAVITY; model->opt.disableflags |= mjDSBL_GRAVITY;
@@ -292,7 +294,9 @@ static const char* const kTendonWrapPath =
TEST_F(IslandTest, DenseSparse) { TEST_F(IslandTest, DenseSparse) {
const std::string xml_path = GetTestDataFilePath(kTendonWrapPath); const std::string xml_path = GetTestDataFilePath(kTendonWrapPath);
mjModel* model = mj_loadXML(xml_path.c_str(), nullptr, nullptr, 0); char error[1024];
mjModel* model = mj_loadXML(xml_path.c_str(), nullptr, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
mjData* data1 = mj_makeData(model); mjData* data1 = mj_makeData(model);
mjData* data2 = mj_makeData(model); mjData* data2 = mj_makeData(model);
@@ -349,7 +353,9 @@ static const char* const kIlslandEfcPath =
TEST_F(IslandTest, IslandEfc) { TEST_F(IslandTest, IslandEfc) {
const std::string xml_path = GetTestDataFilePath(kIlslandEfcPath); const std::string xml_path = GetTestDataFilePath(kIlslandEfcPath);
mjModel* model = mj_loadXML(xml_path.c_str(), nullptr, nullptr, 0); char error[1024];
mjModel* model = mj_loadXML(xml_path.c_str(), nullptr, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
while (data->time < 0.2) { while (data->time < 0.2) {
@@ -369,7 +375,9 @@ TEST_F(IslandTest, IslandEfc) {
TEST_F(IslandTest, IslandFlex) { TEST_F(IslandTest, IslandFlex) {
const std::string xml_path = GetTestDataFilePath("testdata/flex.xml"); const std::string xml_path = GetTestDataFilePath("testdata/flex.xml");
mjModel* model = mj_loadXML(xml_path.c_str(), nullptr, nullptr, 0); char error[1024];
mjModel* model = mj_loadXML(xml_path.c_str(), nullptr, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
mjData* data1 = mj_makeData(model); mjData* data1 = mj_makeData(model);
mjData* data2 = mj_makeData(model); mjData* data2 = mj_makeData(model);
@@ -396,7 +404,9 @@ static const char* const k2H100Path = "engine/testdata/island/2humanoid100.xml";
TEST_F(IslandTest, IslandJacobian) { TEST_F(IslandTest, IslandJacobian) {
for (const char* local_path : {kIlslandEfcPath, k2H100Path}) { for (const char* local_path : {kIlslandEfcPath, k2H100Path}) {
const std::string xml_path = GetTestDataFilePath(local_path); const std::string xml_path = GetTestDataFilePath(local_path);
mjModel* m = mj_loadXML(xml_path.c_str(), nullptr, nullptr, 0); char error[1024];
mjModel* m = mj_loadXML(xml_path.c_str(), nullptr, error, sizeof(error));
ASSERT_THAT(m, NotNull()) << error;
int jac0 = m->opt.jacobian; int jac0 = m->opt.jacobian;
mjData* d = mj_makeData(m); mjData* d = mj_makeData(m);
@@ -496,7 +506,9 @@ TEST_F(IslandTest, IslandJacobian) {
TEST_F(IslandTest, IslandInertia) { TEST_F(IslandTest, IslandInertia) {
for (const char* local_path : {kIlslandEfcPath, k2H100Path}) { for (const char* local_path : {kIlslandEfcPath, k2H100Path}) {
const std::string xml_path = GetTestDataFilePath(local_path); const std::string xml_path = GetTestDataFilePath(local_path);
mjModel* m = mj_loadXML(xml_path.c_str(), nullptr, nullptr, 0); char error[1024];
mjModel* m = mj_loadXML(xml_path.c_str(), nullptr, error, sizeof(error));
ASSERT_THAT(m, NotNull()) << error;
int nv = m->nv; int nv = m->nv;
mjData* d = mj_makeData(m); mjData* d = mj_makeData(m);
mjtNum* M = (mjtNum*)mju_malloc(sizeof(mjtNum) * nv * nv); mjtNum* M = (mjtNum*)mju_malloc(sizeof(mjtNum) * nv * nv);
@@ -543,7 +555,9 @@ TEST_F(IslandTest, IslandInertia) {
TEST_F(IslandTest, IslandEfcElliptic) { TEST_F(IslandTest, IslandEfcElliptic) {
const std::string xml_path = GetTestDataFilePath(kIlslandEfcPath); const std::string xml_path = GetTestDataFilePath(kIlslandEfcPath);
mjModel* model = mj_loadXML(xml_path.c_str(), nullptr, nullptr, 0); char error[1024];
mjModel* model = mj_loadXML(xml_path.c_str(), nullptr, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
model->opt.cone = mjCONE_ELLIPTIC; model->opt.cone = mjCONE_ELLIPTIC;
+8 -4
View File
@@ -14,7 +14,6 @@
// Tests for engine/engine_core_smooth.c. // Tests for engine/engine_core_smooth.c.
#include <cstddef>
#include <string> #include <string>
#include <gmock/gmock.h> #include <gmock/gmock.h>
@@ -57,7 +56,9 @@ TEST_F(EllipsoidFluidTest, GeomsEquivalentToBodies) {
</mujoco> </mujoco>
)"; )";
mjModel* m2 = LoadModelFromString(two_bodies_xml); char error[1024];
mjModel* m2 = LoadModelFromString(two_bodies_xml, error, sizeof(error));
ASSERT_THAT(m2, NotNull()) << error;
mjData* d2 = mj_makeData(m2); mjData* d2 = mj_makeData(m2);
for (int i = 0; i < 6; i++) { for (int i = 0; i < 6; i++) {
d2->qvel[i] = (mjtNum) i+1; d2->qvel[i] = (mjtNum) i+1;
@@ -80,7 +81,8 @@ TEST_F(EllipsoidFluidTest, GeomsEquivalentToBodies) {
</mujoco> </mujoco>
)"; )";
mjModel* m1 = LoadModelFromString(one_body_xml); mjModel* m1 = LoadModelFromString(one_body_xml, error, sizeof(error));
ASSERT_THAT(m1, NotNull()) << error;
mjData* d1 = mj_makeData(m1); mjData* d1 = mj_makeData(m1);
for (int i = 0; i < 6; i++) { for (int i = 0; i < 6; i++) {
d1->qvel[i] = (mjtNum) i+1; d1->qvel[i] = (mjtNum) i+1;
@@ -126,7 +128,9 @@ TEST_F(EllipsoidFluidTest, DefaultsPropagate) {
</mujoco> </mujoco>
)"; )";
mjModel* model = LoadModelFromString(xml); char error[1024];
mjModel* model = LoadModelFromString(xml, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
EXPECT_THAT(GetVector(model->geom_fluid, 6), EXPECT_THAT(GetVector(model->geom_fluid, 6),
ElementsAre(0, 0, 0, 0, 0, 0)); ElementsAre(0, 0, 0, 0, 0, 0));
EXPECT_THAT(GetVector(model->geom_fluid + mjNFLUID, 6), EXPECT_THAT(GetVector(model->geom_fluid + mjNFLUID, 6),
+21 -13
View File
@@ -14,6 +14,9 @@
// Tests for ray casting. // Tests for ray casting.
#include <cstring>
#include <string>
#include <gmock/gmock.h> #include <gmock/gmock.h>
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <mujoco/mjdata.h> #include <mujoco/mjdata.h>
@@ -78,8 +81,9 @@ using ::testing::NotNull;
using RayTest = MujocoTest; using RayTest = MujocoTest;
TEST_F(RayTest, NoExclusions) { TEST_F(RayTest, NoExclusions) {
mjModel* model = LoadModelFromString(kRayCastingModel); char error[1024];
ASSERT_THAT(model, NotNull()); mjModel* model = LoadModelFromString(kRayCastingModel, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
ASSERT_THAT(data, NotNull()); ASSERT_THAT(data, NotNull());
@@ -100,8 +104,9 @@ TEST_F(RayTest, NoExclusions) {
} }
TEST_F(RayTest, Exclusions) { TEST_F(RayTest, Exclusions) {
mjModel* model = LoadModelFromString(kRayCastingModel); char error[1024];
ASSERT_THAT(model, NotNull()); mjModel* model = LoadModelFromString(kRayCastingModel, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
ASSERT_THAT(data, NotNull()); ASSERT_THAT(data, NotNull());
@@ -142,8 +147,9 @@ TEST_F(RayTest, Exclusions) {
} }
TEST_F(RayTest, ExcludeStatic) { TEST_F(RayTest, ExcludeStatic) {
mjModel* model = LoadModelFromString(kRayCastingModel); char error[1024];
ASSERT_THAT(model, NotNull()); mjModel* model = LoadModelFromString(kRayCastingModel, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
ASSERT_THAT(data, NotNull()); ASSERT_THAT(data, NotNull());
@@ -166,8 +172,9 @@ TEST_F(RayTest, ExcludeStatic) {
// ------------------------------- mj_multiRay -------------------------------- // ------------------------------- mj_multiRay --------------------------------
TEST_F(RayTest, MultiRayEqualsSingleRay) { TEST_F(RayTest, MultiRayEqualsSingleRay) {
mjModel* m = LoadModelFromString(kRayCastingModel); char error[1024];
ASSERT_THAT(m, NotNull()); mjModel* m = LoadModelFromString(kRayCastingModel, error, sizeof(error));
ASSERT_THAT(m, NotNull()) << error;
mjData* d = mj_makeData(m); mjData* d = mj_makeData(m);
ASSERT_THAT(d, NotNull()); ASSERT_THAT(d, NotNull());
mj_forward(m, d); mj_forward(m, d);
@@ -215,8 +222,9 @@ TEST_F(RayTest, MultiRayEqualsSingleRay) {
} }
TEST_F(RayTest, EdgeCases) { TEST_F(RayTest, EdgeCases) {
mjModel* m = LoadModelFromString(kSingleGeomModel); char error[1024];
ASSERT_THAT(m, NotNull()); mjModel* m = LoadModelFromString(kSingleGeomModel, error, sizeof(error));
ASSERT_THAT(m, NotNull()) << error;
ASSERT_THAT(m->nbvh, 1); ASSERT_THAT(m->nbvh, 1);
mjData* d = mj_makeData(m); mjData* d = mj_makeData(m);
ASSERT_THAT(d, NotNull()); ASSERT_THAT(d, NotNull());
@@ -398,8 +406,8 @@ TEST_F(RayTest, RayMeshPruning) {
_rayMeshTest(m); _rayMeshTest(m);
mj_deleteModel(m); mj_deleteModel(m);
m = LoadModelFromString(kCubeletModel); m = LoadModelFromString(kCubeletModel, error, sizeof(error));
ASSERT_THAT(m, NotNull()); ASSERT_THAT(m, NotNull()) << error;
_rayMeshTest(m); _rayMeshTest(m);
mj_deleteModel(m); mj_deleteModel(m);
} }
@@ -440,7 +448,7 @@ TEST_F(RayTest, RayHfield) {
char error[1024]; char error[1024];
mjModel* model = LoadModelFromString(xml, error, sizeof(error), 0); mjModel* model = LoadModelFromString(xml, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error; ASSERT_THAT(model, NotNull()) << error;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
+6 -2
View File
@@ -78,7 +78,9 @@ TEST_F(SensorTest, DisableSensors) {
</sensor> </sensor>
</mujoco> </mujoco>
)"; )";
mjModel* model = LoadModelFromString(xml); char error[1024];
mjModel* model = LoadModelFromString(xml, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
// before calling anything, check that sensors are initialised to 0 // before calling anything, check that sensors are initialised to 0
@@ -128,7 +130,9 @@ TEST_F(RelativeFrameSensorTest, ReferencePosMat) {
</sensor> </sensor>
</mujoco> </mujoco>
)"; )";
mjModel* model = LoadModelFromString(xml); char error[1024];
mjModel* model = LoadModelFromString(xml, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
mj_forward(model, data); mj_forward(model, data);
+46 -12
View File
@@ -70,7 +70,10 @@ static constexpr char AngMomTestingModel[] = R"(
// compare subtree angular momentum computed in two ways // compare subtree angular momentum computed in two ways
TEST_F(AngMomMatTest, CompareAngMom) { TEST_F(AngMomMatTest, CompareAngMom) {
mjModel* model = LoadModelFromString(AngMomTestingModel); char error[1024];
mjModel* model =
LoadModelFromString(AngMomTestingModel, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
int nv = model->nv; int nv = model->nv;
int bodyid = mj_name2id(model, mjOBJ_BODY, "link1"); int bodyid = mj_name2id(model, mjOBJ_BODY, "link1");
@@ -104,7 +107,10 @@ TEST_F(AngMomMatTest, CompareAngMom) {
// compare subtree angular momentum matrix: analytical and findiff // compare subtree angular momentum matrix: analytical and findiff
TEST_F(AngMomMatTest, CompareAngMomMats) { TEST_F(AngMomMatTest, CompareAngMomMats) {
mjModel* model = LoadModelFromString(AngMomTestingModel); char error[1024];
mjModel* model =
LoadModelFromString(AngMomTestingModel, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
int nv = model->nv; int nv = model->nv;
int bodyid = mj_name2id(model, mjOBJ_BODY, "link1"); int bodyid = mj_name2id(model, mjOBJ_BODY, "link1");
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
@@ -191,7 +197,10 @@ static constexpr char kJacobianTestingModel[] = R"(
// compare analytic and finite-differenced subtree-com Jacobian // compare analytic and finite-differenced subtree-com Jacobian
TEST_F(JacobianTest, SubtreeJac) { TEST_F(JacobianTest, SubtreeJac) {
mjModel* model = LoadModelFromString(kJacobianTestingModel); char error[1024];
mjModel* model =
LoadModelFromString(kJacobianTestingModel, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
int nv = model->nv; int nv = model->nv;
int bodyid = mj_name2id(model, mjOBJ_BODY, "main"); int bodyid = mj_name2id(model, mjOBJ_BODY, "main");
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
@@ -242,7 +251,10 @@ TEST_F(JacobianTest, SubtreeJac) {
// confirm that applying linear forces via the subtree-com Jacobian only creates // confirm that applying linear forces via the subtree-com Jacobian only creates
// the expected linear accelerations (no accelerations of internal joints) // the expected linear accelerations (no accelerations of internal joints)
TEST_F(JacobianTest, SubtreeJacNoInternalAcc) { TEST_F(JacobianTest, SubtreeJacNoInternalAcc) {
mjModel* model = LoadModelFromString(kJacobianTestingModel); char error[1024];
mjModel* model =
LoadModelFromString(kJacobianTestingModel, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
int nv = model->nv; int nv = model->nv;
int bodyid = mj_name2id(model, mjOBJ_BODY, "main"); int bodyid = mj_name2id(model, mjOBJ_BODY, "main");
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
@@ -407,7 +419,9 @@ static constexpr char kHinge[] = R"(
// compare mj_jacDot with finite-differenced mj_jac // compare mj_jacDot with finite-differenced mj_jac
TEST_F(JacobianTest, JacDot) { TEST_F(JacobianTest, JacDot) {
for (auto xml : {kHinge, kQuat, kTelescope, kFreeBall, kQuatlessPendulum}) { for (auto xml : {kHinge, kQuat, kTelescope, kFreeBall, kQuatlessPendulum}) {
mjModel* model = LoadModelFromString(xml); char error[1024];
mjModel* model = LoadModelFromString(xml, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
int nv = model->nv; int nv = model->nv;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
@@ -520,7 +534,10 @@ static constexpr char name2idTestingModel[] = R"(
)"; )";
TEST_F(Name2idTest, FindIds) { TEST_F(Name2idTest, FindIds) {
mjModel* model = LoadModelFromString(name2idTestingModel); char error[1024];
mjModel* model =
LoadModelFromString(name2idTestingModel, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
EXPECT_THAT(mj_name2id(model, mjOBJ_BODY, "world"), 0); EXPECT_THAT(mj_name2id(model, mjOBJ_BODY, "world"), 0);
EXPECT_THAT(mj_name2id(model, mjOBJ_BODY, "body1"), 1); EXPECT_THAT(mj_name2id(model, mjOBJ_BODY, "body1"), 1);
@@ -542,7 +559,10 @@ TEST_F(Name2idTest, FindIds) {
} }
TEST_F(Name2idTest, MissingIds) { TEST_F(Name2idTest, MissingIds) {
mjModel* model = LoadModelFromString(name2idTestingModel); char error[1024];
mjModel* model =
LoadModelFromString(name2idTestingModel, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
EXPECT_THAT(mj_name2id(model, mjOBJ_BODY, "abody3"), -1); EXPECT_THAT(mj_name2id(model, mjOBJ_BODY, "abody3"), -1);
EXPECT_THAT(mj_name2id(model, mjOBJ_GEOM, "abody2_geom2"), -1); EXPECT_THAT(mj_name2id(model, mjOBJ_GEOM, "abody2_geom2"), -1);
@@ -561,7 +581,10 @@ TEST_F(Name2idTest, MissingIds) {
} }
TEST_F(Name2idTest, EmptyIds) { TEST_F(Name2idTest, EmptyIds) {
mjModel* model = LoadModelFromString(name2idTestingModel); char error[1024];
mjModel* model =
LoadModelFromString(name2idTestingModel, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
EXPECT_THAT(mj_name2id(model, mjOBJ_BODY, ""), -1); EXPECT_THAT(mj_name2id(model, mjOBJ_BODY, ""), -1);
@@ -569,7 +592,10 @@ TEST_F(Name2idTest, EmptyIds) {
} }
TEST_F(Name2idTest, Namespaces) { TEST_F(Name2idTest, Namespaces) {
mjModel* model = LoadModelFromString(name2idTestingModel); char error[1024];
mjModel* model =
LoadModelFromString(name2idTestingModel, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
EXPECT_THAT(mj_name2id(model, mjOBJ_GEOM, "camera1"), 3); EXPECT_THAT(mj_name2id(model, mjOBJ_GEOM, "camera1"), 3);
@@ -631,7 +657,9 @@ static constexpr char ballJointModel[] = R"(
TEST_F(SupportTest, DifferentiatePosSubQuat) { TEST_F(SupportTest, DifferentiatePosSubQuat) {
const mjtNum eps = 1e-12; // epsilon for float comparison const mjtNum eps = 1e-12; // epsilon for float comparison
mjModel* model = LoadModelFromString(ballJointModel); char error[1024];
mjModel* model = LoadModelFromString(ballJointModel, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
int seed = 1; int seed = 1;
for (mjtNum angle : {0.0, 1e-5, 1e-2}) { for (mjtNum angle : {0.0, 1e-5, 1e-2}) {
@@ -850,7 +878,10 @@ static constexpr char GeomDistanceTestingModel[] = R"(
)"; )";
TEST_F(SupportTest, GeomDistance) { TEST_F(SupportTest, GeomDistance) {
mjModel* model = LoadModelFromString(GeomDistanceTestingModel); char error[1024];
mjModel* model =
LoadModelFromString(GeomDistanceTestingModel, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
mj_kinematics(model, data); mj_kinematics(model, data);
@@ -920,7 +951,10 @@ static constexpr char kSetKeyframeTestingModel[] = R"(
)"; )";
TEST_F(SupportTest, SetKeyframe) { TEST_F(SupportTest, SetKeyframe) {
mjModel* model = LoadModelFromString(kSetKeyframeTestingModel); char error[1024];
mjModel* model =
LoadModelFromString(kSetKeyframeTestingModel, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
data->ctrl[0] = 1; data->ctrl[0] = 1;
+3 -2
View File
@@ -82,8 +82,9 @@ TEST(TestMjArrayList, TestMjArrayListSingleThreaded) {
} }
TEST(TestMjArrayList, ZeroInitialCapacity) { TEST(TestMjArrayList, ZeroInitialCapacity) {
mjModel* m = LoadModelFromString("<mujoco/>", nullptr, 0); char error[1024];
ASSERT_THAT(m, NotNull()) << "Failed to load model"; mjModel* m = LoadModelFromString("<mujoco/>", error, sizeof(error));
ASSERT_THAT(m, NotNull()) << "Failed to load model: " << error;
mjData* d = mj_makeData(m); mjData* d = mj_makeData(m);
mj_markStack(d); mj_markStack(d);
mjArrayList* array_list = mjArrayList* array_list =
+4 -1
View File
@@ -34,6 +34,7 @@ using ::testing::DoubleNear;
using ::testing::ElementsAre; using ::testing::ElementsAre;
using ::testing::ElementsAreArray; using ::testing::ElementsAreArray;
using ::testing::HasSubstr; using ::testing::HasSubstr;
using ::testing::NotNull;
using ::testing::Pointwise; using ::testing::Pointwise;
using ::testing::StrEq; using ::testing::StrEq;
@@ -121,7 +122,9 @@ TEST_F(UtilMiscTest, SphereWrap) {
</mujoco> </mujoco>
)"; )";
mjModel* model = LoadModelFromString(xml); char error[1024];
mjModel* model = LoadModelFromString(xml, error, sizeof(error));
ASSERT_THAT(model, NotNull()) << error;
mjData* data = mj_makeData(model); mjData* data = mj_makeData(model);
// measure tendon length for keyframe 0 // measure tendon length for keyframe 0