Skip to content

Commit 64af650

Browse files
yuvaltassacopybara-github
authored andcommitted
Add mjModel.tendon_type and the mjtTendon enum.
PiperOrigin-RevId: 1009752952 Change-Id: I3c3bc2564593e41af7b0ff0b0c0c80c8dab94653
1 parent 140c3b2 commit 64af650

29 files changed

Lines changed: 185 additions & 22 deletions

File tree

‎doc/APIreference/APItypes.rst‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,16 @@ Equality constraint types. These values are used in ``m->eq_type``.
297297
.. mujoco-include:: mjtEq
298298

299299

300+
.. _mjtTendon:
301+
302+
mjtTendon
303+
~~~~~~~~~
304+
305+
Tendon types. These values are used in ``m->tendon_type``.
306+
307+
.. mujoco-include:: mjtTendon
308+
309+
300310
.. _mjtWrap:
301311

302312
mjtWrap

‎doc/changelog.rst‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ General
6464
- Added a :ref:`castshadow<body-geom-castshadow>` attribute to :ref:`geom<body-geom>` (``mjsGeom.castshadow``,
6565
``mjModel.geom_castshadow``, ``mjvGeom.castshadow``; default ``true``) to disable shadow casting per geom in both the
6666
classic OpenGL and Filament renderers.
67+
- Added ``mjModel.tendon_type`` with values from the new :ref:`mjtTendon` enum, distinguishing fixed and spatial
68+
tendons. Previously, the type was implied by whether the first path element was a joint.
6769

6870
Engine
6971
^^^^^^

‎doc/includes/references.h‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,6 +1105,7 @@ typedef struct mjModel_ {
11051105
mjtNum* eq_data; // numeric data for constraint (neq x mjNEQDATA)
11061106

11071107
// tendons
1108+
int* tendon_type; // type of tendon (mjtTendon) (ntendon x 1)
11081109
int* tendon_adr; // address of first object in tendon's path (ntendon x 1)
11091110
int* tendon_num; // number of objects in tendon's path (ntendon x 1)
11101111
int* tendon_matid; // material id for rendering (ntendon x 1)
@@ -2607,6 +2608,10 @@ typedef enum mjtEq { // type of equality constraint
26072608
mjEQ_FLEXSTRAIN, // constrain strain of a trilinear/quadratic flex (B-bar)
26082609
mjEQ_DISTANCE // unsupported, will cause an error if used
26092610
} mjtEq;
2611+
typedef enum mjtTendon { // type of tendon
2612+
mjTENDON_FIXED = 0, // linear combination of joint coordinates
2613+
mjTENDON_SPATIAL // path through sites, around geoms
2614+
} mjtTendon;
26102615
typedef enum mjtWrap { // type of tendon wrap object
26112616
mjWRAP_NONE = 0, // null object
26122617
mjWRAP_JOINT, // constant moment arm

‎include/mujoco/mjmodel.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,7 @@ typedef struct mjModel_ {
738738
mjtNum* eq_data; // numeric data for constraint (neq x mjNEQDATA)
739739

740740
// tendons
741+
int* tendon_type; // type of tendon (mjtTendon) (ntendon x 1)
741742
int* tendon_adr; // address of first object in tendon's path (ntendon x 1)
742743
int* tendon_num; // number of objects in tendon's path (ntendon x 1)
743744
int* tendon_matid; // material id for rendering (ntendon x 1)

‎include/mujoco/mjtype.h‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,12 @@ typedef enum mjtEq { // type of equality constraint
223223
} mjtEq;
224224

225225

226+
typedef enum mjtTendon { // type of tendon
227+
mjTENDON_FIXED = 0, // linear combination of joint coordinates
228+
mjTENDON_SPATIAL // path through sites, around geoms
229+
} mjtTendon;
230+
231+
226232
typedef enum mjtWrap { // type of tendon wrap object
227233
mjWRAP_NONE = 0, // null object
228234
mjWRAP_JOINT, // constant moment arm

‎include/mujoco/mjxmacro.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,7 @@
646646
X ( mjtNum, eq_data, neq, mjNEQDATA )
647647

648648
#define MJMODEL_POINTERS_TENDON \
649+
X ( int, tendon_type, ntendon, 1 ) \
649650
X ( int, tendon_adr, ntendon, 1 ) \
650651
X ( int, tendon_num, ntendon, 1 ) \
651652
X ( int, tendon_matid, ntendon, 1 ) \
@@ -996,6 +997,7 @@
996997
X( eq_obj2id, 0, mjSC_IN, 0, 0 ) \
997998
X( eq_objtype, 0, mjSC_IN, 0, 0 ) \
998999
X( eq_data, 0, mjSC_INOUT, 0, 0 ) \
1000+
X( tendon_type, mjSC_IN, mjSC_IN, mjSC_IN, mjSC_IN ) \
9991001
X( tendon_adr, mjSC_IN, mjSC_IN, mjSC_IN, mjSC_IN ) \
10001002
X( tendon_num, mjSC_IN, mjSC_IN, mjSC_IN, mjSC_IN ) \
10011003
X( tendon_actuatorid, mjSC_OUT, 0, mjSC_IN, 0 ) \

‎mjx/mujoco/mjx/_src/io.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,7 @@ def _put_model_jax(
406406
(m.actuator_trntype, types.TrnType, mujoco.mjtTrn),
407407
(m.eq_type, types.EqType, mujoco.mjtEq),
408408
(m.sensor_type, types.SensorType, mujoco.mjtSensor),
409+
(m.tendon_type, types.TendonType, mujoco.mjtTendon),
409410
(m.wrap_type, types.WrapType, mujoco.mjtWrap),
410411
):
411412
missing = set(enum_field) - set(enum_type)

‎mjx/mujoco/mjx/_src/io_test.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ def assert_not_weak_type(x):
208208
np.testing.assert_allclose(mx.actuator_biastype, m.actuator_biastype)
209209
np.testing.assert_allclose(mx.actuator_trnid, m.actuator_trnid)
210210

211+
np.testing.assert_equal(mx.tendon_type, m.tendon_type)
211212
np.testing.assert_equal(mx.wrap_type, m.wrap_type)
212213
np.testing.assert_equal(mx.wrap_objid, m.wrap_objid)
213214
np.testing.assert_almost_equal(mx.wrap_prm, m.wrap_prm)

‎mjx/mujoco/mjx/_src/smooth.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
from mujoco.mjx._src.types import Model
3232
from mujoco.mjx._src.types import ModelJAX
3333
from mujoco.mjx._src.types import ObjType
34+
from mujoco.mjx._src.types import TendonType
3435
from mujoco.mjx._src.types import TrnType
3536
from mujoco.mjx._src.types import WrapType
3637
# pylint: enable=g-importing-member
@@ -892,7 +893,7 @@ def tendon(m: Model, d: Data) -> Data:
892893

893894
# process joint tendons
894895
(wrap_id_jnt,) = np.nonzero(m.wrap_type == WrapType.JOINT)
895-
(tendon_id_jnt,) = np.nonzero(np.isin(m.tendon_adr, wrap_id_jnt))
896+
(tendon_id_jnt,) = np.nonzero(m.tendon_type == TendonType.FIXED)
896897

897898
ntendon_jnt = tendon_id_jnt.size
898899
wrap_objid_jnt = m.wrap_objid[wrap_id_jnt]

‎mjx/mujoco/mjx/_src/types.py‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,18 @@ class EqType(enum.IntEnum):
237237
# unsupported: DISTANCE
238238

239239

240+
class TendonType(enum.IntEnum):
241+
"""Type of tendon.
242+
243+
Attributes:
244+
FIXED: linear combination of joint coordinates
245+
SPATIAL: path through sites, around geoms
246+
"""
247+
248+
FIXED = mujoco.mjtTendon.mjTENDON_FIXED # pyrefly: ignore[bad-assignment]
249+
SPATIAL = mujoco.mjtTendon.mjTENDON_SPATIAL # pyrefly: ignore[bad-assignment]
250+
251+
240252
class WrapType(enum.IntEnum):
241253
"""Type of tendon wrap object.
242254
@@ -828,6 +840,7 @@ class Model(PyTreeNode):
828840
eq_solref: jax.Array
829841
eq_solimp: jax.Array
830842
eq_data: jax.Array
843+
tendon_type: np.ndarray
831844
tendon_adr: np.ndarray
832845
tendon_num: np.ndarray
833846
tendon_limited: np.ndarray

0 commit comments

Comments
 (0)
⌂ 换网址