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"(