Raise an exception in MJX if given a model with tendons.

Fixes #1149

PiperOrigin-RevId: 578278430
Change-Id: Ie633975b830379ca554438307a6e674675eaf8e7
This commit is contained in:
Baruch Tabanpour
2023-10-31 13:08:52 -07:00
committed by Copybara-Service
parent 7e419276ca
commit 45878b7eef
3 changed files with 37 additions and 8 deletions
+2
View File
@@ -18,6 +18,8 @@ MJX
3. Fixed bug where mixed ``jnt_limited`` joints were not being constrained correctly. 3. Fixed bug where mixed ``jnt_limited`` joints were not being constrained correctly.
4. Made ``device_put`` type validation more verbose (fixes :github:issue:`1113`). 4. Made ``device_put`` type validation more verbose (fixes :github:issue:`1113`).
5. Removed empty EFC rows from `MJX`, for joints with no limits (fixes :github:issue:`1117`). 5. Removed empty EFC rows from `MJX`, for joints with no limits (fixes :github:issue:`1117`).
6. Fixed bug where equality constraints became inactive (fixes :github:issue:`1129`).
7. Added an error when loading a model with tendons (fixes :github:issue:`1149`).
Python bindings Python bindings
^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
+3
View File
@@ -126,6 +126,9 @@ def _validate(m: mujoco.MjModel):
): ):
raise NotImplementedError('Only condim=3 is supported.') raise NotImplementedError('Only condim=3 is supported.')
if m.ntendon:
raise NotImplementedError('Tendons are not supported.')
# check collision geom types # check collision geom types
candidate_set = collision_driver.collision_candidates(m) candidate_set = collision_driver.collision_candidates(m)
for g1, g2, *_ in candidate_set: for g1, g2, *_ in candidate_set:
+32 -8
View File
@@ -121,45 +121,45 @@ class ValidateInputTest(absltest.TestCase):
'<mujoco><option integrator="implicit"/><worldbody/></mujoco>' '<mujoco><option integrator="implicit"/><worldbody/></mujoco>'
) )
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
_ = mjx.device_put(m) mjx.device_put(m)
def test_cone(self): def test_cone(self):
m = mujoco.MjModel.from_xml_string( m = mujoco.MjModel.from_xml_string(
'<mujoco><option cone="elliptic"/><worldbody/></mujoco>' '<mujoco><option cone="elliptic"/><worldbody/></mujoco>'
) )
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
_ = mjx.device_put(m) mjx.device_put(m)
def test_trn(self): def test_trn(self):
m = test_util.load_test_file('ant.xml') m = test_util.load_test_file('ant.xml')
m.actuator_trntype[0] = mujoco.mjtTrn.mjTRN_SITE m.actuator_trntype[0] = mujoco.mjtTrn.mjTRN_SITE
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
_ = mjx.device_put(m) mjx.device_put(m)
def test_dyn(self): def test_dyn(self):
m = test_util.load_test_file('ant.xml') m = test_util.load_test_file('ant.xml')
m.actuator_dyntype[0] = mujoco.mjtDyn.mjDYN_MUSCLE m.actuator_dyntype[0] = mujoco.mjtDyn.mjDYN_MUSCLE
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
_ = mjx.device_put(m) mjx.device_put(m)
def test_gain(self): def test_gain(self):
m = test_util.load_test_file('ant.xml') m = test_util.load_test_file('ant.xml')
m.actuator_gaintype[0] = mujoco.mjtGain.mjGAIN_MUSCLE m.actuator_gaintype[0] = mujoco.mjtGain.mjGAIN_MUSCLE
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
_ = mjx.device_put(m) mjx.device_put(m)
def test_bias(self): def test_bias(self):
m = test_util.load_test_file('ant.xml') m = test_util.load_test_file('ant.xml')
m.actuator_gaintype[0] = mujoco.mjtGain.mjGAIN_MUSCLE m.actuator_gaintype[0] = mujoco.mjtGain.mjGAIN_MUSCLE
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
_ = mjx.device_put(m) mjx.device_put(m)
def test_condim(self): def test_condim(self):
m = test_util.load_test_file('ant.xml') m = test_util.load_test_file('ant.xml')
for i in [1, 4, 6]: for i in [1, 4, 6]:
m.geom_condim[0] = i m.geom_condim[0] = i
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
_ = mjx.device_put(m) mjx.device_put(m)
def test_geoms(self): def test_geoms(self):
m = mujoco.MjModel.from_xml_string(""" m = mujoco.MjModel.from_xml_string("""
@@ -177,7 +177,31 @@ class ValidateInputTest(absltest.TestCase):
</mujoco> </mujoco>
""") """)
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
_ = mjx.device_put(m) mjx.device_put(m)
def test_tendon(self):
m = mujoco.MjModel.from_xml_string("""
<mujoco>
<worldbody>
<body name="left_thigh" pos="0 0.1 -0.04">
<joint axis="0 1 0" name="left_hip_y" type="hinge"/>
<geom fromto="0 0 0 0 -0.01 -.34" name="left_thigh1" size="0.06" type="capsule"/>
<body name="left_shin" pos="0 -0.01 -0.403">
<joint axis="0 -1 0" name="left_knee" pos="0 0 .02" range="-160 -2" type="hinge"/>
<geom fromto="0 0 0 0 0 -.3" name="left_shin1" size="0.049" type="capsule"/>
</body>
</body>
</worldbody>
<tendon>
<fixed name="left_hipknee">
<joint coef="-1" joint="left_hip_y"/>
<joint coef="1" joint="left_knee"/>
</fixed>
</tendon>
</mujoco>
""")
with self.assertRaises(NotImplementedError):
mjx.device_put(m)
if __name__ == '__main__': if __name__ == '__main__':