diff --git a/dm_control/mjcf/element_test.py b/dm_control/mjcf/element_test.py index a8deace1..8b5be9b8 100644 --- a/dm_control/mjcf/element_test.py +++ b/dm_control/mjcf/element_test.py @@ -800,6 +800,30 @@ def testDictLikeInterface(self): with self.assertRaisesRegex(TypeError, 'does not support item deletion'): del elem['foo'] + @parameterized.parameters('general', 'motor', 'position', 'velocity', + 'intvelocity', 'damper', 'cylinder', 'muscle') + def testActuatorArmatureAndDamping(self, actuator_type): + # MuJoCo accepts `armature` and `damping` on these actuators, and the + # section of the schema already allowed both, but the + # elements themselves did not list them. + xml_string = """ + + + + + + + + + <{} name="a" joint="j" armature="0.7" damping="2.5"/> + + +""".format(actuator_type) + mujoco = parser.from_xml_string(xml_string) + actuator = mujoco.find('actuator', 'a') + self.assertEqual(actuator.armature, 0.7) + np.testing.assert_array_equal(actuator.damping, [2.5]) + def testSetAndGetAttributes(self): mujoco = element.RootElement(model='test') diff --git a/dm_control/mjcf/schema.xml b/dm_control/mjcf/schema.xml index 029ceb88..94ddf4c1 100644 --- a/dm_control/mjcf/schema.xml +++ b/dm_control/mjcf/schema.xml @@ -2102,6 +2102,8 @@ + + @@ -2135,6 +2137,8 @@ + + @@ -2160,6 +2164,8 @@ + + @@ -2190,6 +2196,8 @@ + + @@ -2218,6 +2226,8 @@ + + @@ -2267,6 +2277,8 @@ + + @@ -2293,6 +2305,8 @@ + + @@ -2322,6 +2336,8 @@ + + diff --git a/dm_control/mjcf/xml_validation_test.py b/dm_control/mjcf/xml_validation_test.py index 58a0ad42..a10bced3 100644 --- a/dm_control/mjcf/xml_validation_test.py +++ b/dm_control/mjcf/xml_validation_test.py @@ -67,6 +67,25 @@ def testXmlFromZip(self): model = parser.from_zip(_ZIPPED_MODEL) validate(model.to_xml_string(), model.get_assets()) + def testActuatorArmatureAndDampingRoundTrip(self): + model = parser.from_xml_string(""" + + + + + + + + + + + +""") + validate(model.to_xml_string()) + mjmodel = wrapper.MjModel.from_xml_string(model.to_xml_string()) + self.assertEqual(mjmodel.actuator_armature[0], 0.7) + self.assertEqual(mjmodel.actuator_damping[0], 2.5) + if __name__ == '__main__': absltest.main()