diff --git a/src/xml/xml_native_reader.cc b/src/xml/xml_native_reader.cc index 3e313be8..6012112f 100644 --- a/src/xml/xml_native_reader.cc +++ b/src/xml/xml_native_reader.cc @@ -2561,7 +2561,8 @@ void mjXReader::OneActuator(XMLElement* elem, mjsActuator* actuator) { // damper else if (type == "damper") { - double kv = 0; + bool inherited = (actuator->gaintype == mjGAIN_AFFINE); + double kv = inherited ? -actuator->gainprm[2] : 0; ReadAttr(elem, "kv", 1, &kv, text); err = mjs_setToDamper(actuator, kv); } diff --git a/test/xml/xml_native_reader_test.cc b/test/xml/xml_native_reader_test.cc index 67220b48..1de30d3a 100644 --- a/test/xml/xml_native_reader_test.cc +++ b/test/xml/xml_native_reader_test.cc @@ -2984,6 +2984,29 @@ TEST_F(ActuatorParseTest, DampersDontRequireRange) { EXPECT_EQ(model->actuator_ctrlrange[1], 2); } +TEST_F(ActuatorParseTest, DamperInheritsKv) { + static constexpr char xml[] = R"( + + + + + + + + + + + + + + + )"; + std::array error; + MjModelPtr model = LoadModelFromString(xml, error.data(), error.size()); + ASSERT_THAT(model.get(), NotNull()) << error.data(); + EXPECT_EQ(model->actuator_gainprm[2], -5.0); +} + // adhesion actuators inherit from general defaults TEST_F(ActuatorParseTest, AdhesionInheritsFromGeneral) { static constexpr char xml[] = R"(