Add __setattr__ to _MjBindModel and _MjBindData.

This allows setting attributes with bind using a list of mjSpec objects as arguments.

PiperOrigin-RevId: 825456920
Change-Id: Ie6af956feab0a805175d7aaecf26e071401fbf05
This commit is contained in:
Alessio Quaglino
2025-10-29 02:54:08 -07:00
committed by Copybara-Service
parent 80eb511620
commit 010d919244
2 changed files with 16 additions and 2 deletions
+14 -2
View File
@@ -137,8 +137,10 @@ def from_zip(file: Union[str, IO[bytes]]) -> _specs.MjSpec:
class _MjBindModel:
"""Wrapper for MjModel that allows binding multiple specs."""
def __init__(self, elements: Sequence[Any]):
self.elements = elements
object.__setattr__(self, 'elements', elements)
def __getattr__(self, key: str):
items = []
@@ -146,10 +148,15 @@ class _MjBindModel:
items.extend(getattr(e, key))
return items
def __setattr__(self, key: str, value: Any):
raise AttributeError(f'Cannot set {key} on MjModel.')
class _MjBindData:
"""Wrapper for MjData that allows binding multiple specs."""
def __init__(self, elements: Sequence[Any]):
self.elements = elements
object.__setattr__(self, 'elements', elements)
def __getattr__(self, key: str):
items = []
@@ -157,6 +164,11 @@ class _MjBindData:
items.extend(getattr(e, key))
return items
def __setattr__(self, key: str, value: Any):
value_it = iter(value)
for element in self.elements:
setattr(element, key, next(value_it))
def _bind_model(
model: _structs.MjModel, specs: Union[Sequence[MjStruct], MjStruct]
+2
View File
@@ -1266,6 +1266,8 @@ class SpecsTest(absltest.TestCase):
np.testing.assert_array_equal(mj_model.bind(joints).qposadr, [7, 8])
np.testing.assert_array_equal(mj_data.bind([]).qpos, [])
np.testing.assert_array_equal(mj_model.bind([]).qposadr, [])
mj_data.bind(joints).qpos = np.array([1, 2])
np.testing.assert_array_equal(mj_data.bind(joints).qpos, [1, 2])
with self.assertRaisesRegex(
AttributeError, "object has no attribute 'invalid'"
):