Problem Statement
_transformations.py provides homogeneous 4x4 transform helpers (generate_rot_T, invert_T_pas, invert_T_act, and apply_T_to_vectors) but no equivalents for bare 3x3 rotation matrices, so the MuJoCo boundary code does rotation math inline with raw NumPy. The bare operations that need covering are: inverting a passive rotation (currently a .T; the TODO comment in MuJoCoModel.get_state already proposes naming this invert_R_pas), inverting an active rotation (the np.linalg.inv followed by .T in the MuJoCoModel constructor), extracting the 3x3 rotation block from a 4x4 transform (currently T[:3, :3]), and applying a rotation matrix to vectors (currently xmat @ qvel and R @ omega, the 3x3 analog of apply_T_to_vectors). This is correctness-neutral consistency work: the inline math is right, it is just unnamed, unvalidated, and repeated.
Location(s): pterasoftware/_transformations.py, pterasoftware/_mujoco_model.py, docs/MUJOCO_CONVENTIONS.md, tests/unit/test_mujoco_model.py, tests/unit/fixtures/mujoco_model_fixtures.py
Proposed Solution
- Add the missing rotation-matrix helpers to
_transformations.py, modeled on the existing 4x4 helpers.
- Route the inline math in
pterasoftware/_mujoco_model.py through them, in both __init__ (the quaternion-construction chain that slices the rotation out of a 4x4 transform, inverts, and transposes) and get_state (the .T the TODO comment flags), deleting that TODO comment in the process.
- Update the code snippets in
docs/MUJOCO_CONVENTIONS.md so the documented mapping uses the helpers wherever one fits. The unit conversions np.deg2rad and np.rad2deg and the already-helper R_to_quat_wxyz stay as they are.
- Update the convention unit tests in
tests/unit/test_mujoco_model.py (the state["R_pas_E_to_BP1"].T and R @ omega lines), and decide whether make_pitched_mujoco_model_fixture in mujoco_model_fixtures.py keeps its current generate_rot_T plus invert_T_pas path or adopts a new helper.
Hints for New Contributors
Welcome! Start by reading CONTRIBUTING.md and setting up the development environment it describes. Because this task touches vector-valued variables, read docs/ANGLE_VECTORS_AND_TRANSFORMATIONS.md and docs/AXES_POINTS_AND_FRAMES.md before writing any code; they define the naming conventions (R_pas_A_to_B, active versus passive, and so on) the new helpers must follow. docs/MUJOCO_CONVENTIONS.md explains the boundary code you will be updating. A reasonable plan:
- Study the existing 4x4 helpers in
_transformations.py and their tests in tests/unit/test_transformations.py; the new helpers should mirror their naming, docstring, type-hint, and validation patterns.
- Add the rotation-matrix helpers with unit tests alongside the existing transformation tests.
- Update the consumers listed above, one file at a time.
- Run the test suite as described in
docs/RUNNING_TESTS_AND_TYPE_CHECKS.md, and run the pre-commit hooks over your changed files.
Problem Statement
_transformations.pyprovides homogeneous 4x4 transform helpers (generate_rot_T,invert_T_pas,invert_T_act, andapply_T_to_vectors) but no equivalents for bare 3x3 rotation matrices, so the MuJoCo boundary code does rotation math inline with raw NumPy. The bare operations that need covering are: inverting a passive rotation (currently a.T; the TODO comment inMuJoCoModel.get_statealready proposes naming thisinvert_R_pas), inverting an active rotation (thenp.linalg.invfollowed by.Tin theMuJoCoModelconstructor), extracting the 3x3 rotation block from a 4x4 transform (currentlyT[:3, :3]), and applying a rotation matrix to vectors (currentlyxmat @ qvelandR @ omega, the 3x3 analog ofapply_T_to_vectors). This is correctness-neutral consistency work: the inline math is right, it is just unnamed, unvalidated, and repeated.Location(s):
pterasoftware/_transformations.py,pterasoftware/_mujoco_model.py,docs/MUJOCO_CONVENTIONS.md,tests/unit/test_mujoco_model.py,tests/unit/fixtures/mujoco_model_fixtures.pyProposed Solution
_transformations.py, modeled on the existing 4x4 helpers.pterasoftware/_mujoco_model.pythrough them, in both__init__(the quaternion-construction chain that slices the rotation out of a 4x4 transform, inverts, and transposes) andget_state(the.Tthe TODO comment flags), deleting that TODO comment in the process.docs/MUJOCO_CONVENTIONS.mdso the documented mapping uses the helpers wherever one fits. The unit conversionsnp.deg2radandnp.rad2degand the already-helperR_to_quat_wxyzstay as they are.tests/unit/test_mujoco_model.py(thestate["R_pas_E_to_BP1"].TandR @ omegalines), and decide whethermake_pitched_mujoco_model_fixtureinmujoco_model_fixtures.pykeeps its currentgenerate_rot_Tplusinvert_T_paspath or adopts a new helper.Hints for New Contributors
Welcome! Start by reading
CONTRIBUTING.mdand setting up the development environment it describes. Because this task touches vector-valued variables, readdocs/ANGLE_VECTORS_AND_TRANSFORMATIONS.mdanddocs/AXES_POINTS_AND_FRAMES.mdbefore writing any code; they define the naming conventions (R_pas_A_to_B, active versus passive, and so on) the new helpers must follow.docs/MUJOCO_CONVENTIONS.mdexplains the boundary code you will be updating. A reasonable plan:_transformations.pyand their tests intests/unit/test_transformations.py; the new helpers should mirror their naming, docstring, type-hint, and validation patterns.docs/RUNNING_TESTS_AND_TYPE_CHECKS.md, and run the pre-commit hooks over your changed files.