Interpret position and intvelocity setpoints on 3D rotational transmissions (ball joints, site+refsite) on the circle. The force uses the setpoint representative nearest the current length for smooth tracking beyond pi.

- Wrapping in force path is local; act is re-anchored at integration time.
- Remove hardcoded `actrange` for intvelocity actuators.

PiperOrigin-RevId: 949566477
Change-Id: I349fdf17eedfbb2174d698cc1a6a91d52810b4a3
This commit is contained in:
Yuval Tassa
2026-07-17 07:48:46 -07:00
committed by Copybara-Service
parent 9331c1cd9b
commit 56a93979e0
9 changed files with 301 additions and 39 deletions
+44 -26
View File
@@ -5531,16 +5531,23 @@ specify them independently.
:at:`joint`: :at-val:`string, optional`
This and the next four attributes determine the type of actuator transmission. All of them are optional, and exactly
one of them must be specified. If this attribute is specified, the actuator acts on the given joint. For **hinge**
and **slide** joints, the actuator length equals the joint position/angle times the first element of :at:`gear`. For
**ball** joints, the first three elements of gear define a 3d rotation axis in the child frame around which the
one of them must be specified. If this attribute is specified, the actuator acts on the given joint.
For **hinge** and **slide** joints, the actuator length equals the joint position/angle times the first element of
:at:`gear`.
For **ball** joints, the first three elements of gear define a 3d rotation axis in the child frame around which the
actuator produces torque. The actuator length is defined as the dot-product between this gear axis and the angle-axis
representation of the joint quaternion, and is in units of radian if :at:`gear` is normalized (generally scaled by
by the norm of :at:`gear`). Note that after total rotation of more than :math:`\pi`, the length will wrap to :math:`-
\pi`, and vice-versa. Therefore :el:`position` servos for ball joints should generally use tighter limits which
prevent this wrapping. For **free** joints, gear defines a 3d translation axis in the world frame followed by a 3d
rotation axis in the child frame. The actuator generates force and torque relative to the specified axes. The
actuator length for free joints is defined as zero (so it should not be used with position servos).
the norm of :at:`gear`). Note that the length is defined on a circle: after total rotation of more than :math:`\pi`
it wraps to :math:`-\pi`, and vice-versa. :ref:`position<actuator-position>` and
:ref:`intvelocity<actuator-intvelocity>` servos on such transmissions interpret their setpoint on the circle, driving
towards the nearest representative of the target, so targets can be wound continuously through any number of turns
and no control limits are required to prevent wrapping.
For **free** joints, gear defines a 3d translation axis in the world frame followed by a 3d rotation axis in the
child frame. The actuator generates force and torque relative to the specified axes. The actuator length for free
joints is defined as zero (so cannot be used with position servos).
.. _actuator-general-jointinparent:
@@ -5570,13 +5577,14 @@ specify them independently.
When using a :at:`site` transmission, measure the translation and rotation w.r.t the frame of the :at:`refsite`. In
this case the actuator *does* have length and :el:`position` actuators can be used to directly control an end
effector, see `refsite.xml
<https://github.com/google-deepmind/mujoco/tree/main/test/engine/testdata/actuation/refsite.xml>`__ example
model. As above, the length is the dot product of the :at:`gear` vector and the frame difference. So ``gear="0 1 0 0
0 0"`` means "Y-offset of :at:`site` in the :at:`refsite` frame", while ``gear="0 0 0 0 0 1"`` means rotation "Z-
rotation of :at:`site` in the :at:`refsite` frame". It is recommended to use a normalized :at:`gear` vector with
nonzeros in only the first 3 *or* the last 3 elements of :at:`gear`, so the actuator length will be in either length
units or radians, respectively. As with ball joints (see :at:`joint` above), for rotations which exceed a total angle
of :math:`\pi` will wrap around, so tighter limits are recommended.
<https://github.com/google-deepmind/mujoco/tree/main/test/engine/testdata/actuation/refsite.xml>`__ example model. As
above, the length is the dot product of the :at:`gear` vector and the frame difference. So ``gear="0 1 0 0 0 0"``
means "Y-offset of :at:`site` in the :at:`refsite` frame", while ``gear="0 0 0 0 0 1"`` means rotation "Z- rotation
of :at:`site` in the :at:`refsite` frame". It is recommended to use a normalized :at:`gear` vector with nonzeros in
only the first 3 *or* the last 3 elements of :at:`gear`, so the actuator length will be in either length units or
radians, respectively. As with ball joints (see :ref:`general/joint<actuator-general-joint>` above), rotational
lengths are defined on a circle and servo setpoints are interpreted on it; control limits are not required to prevent
wrapping.
.. _actuator-general-body:
@@ -5794,6 +5802,7 @@ gaintype fixed gainprm kp 0 0
biastype affine biasprm 0 -kp -kv
========= =================== ========= =============
On purely rotational transmissions, setpoints are interpreted on the circle; see :ref:`gear<actuator-general-gear>`.
This element has one custom attribute in addition to the common attributes:
@@ -5989,14 +5998,18 @@ This element creates an integrated-velocity servo. For more information, see the
:ref:`Activation clamping <CActRange>` section of the Modeling chapter. The underlying
:el:`general` attributes are set as follows:
========== =========== ========= =========
Attribute Setting Attribute Setting
========== =========== ========= =========
dyntype integrator dynprm 1 0 0
gaintype fixed gainprm kp 0 0
biastype affine biasprm 0 -kp -kv
actlimited true
========== =========== ========= =========
========= =========== ========= =========
Attribute Setting Attribute Setting
========= =========== ========= =========
dyntype integrator dynprm 1 0 0
gaintype fixed gainprm kp 0 0
biastype affine biasprm 0 -kp -kv
========= =========== ========= =========
Activation clamping is controlled by :at:`actlimited` and :at:`actrange`, like any stateful actuator. On purely
rotational transmissions, setpoints are interpreted on the circle, as for :ref:`position<actuator-position>`; the
integrated setpoint is re-anchored to a bounded representative at each timestep, so clamping is not required for
winding targets.
This element has one custom attribute in addition to the common attributes:
@@ -6016,6 +6029,8 @@ This element has one custom attribute in addition to the common attributes:
.. _actuator-intvelocity-forcelimited:
.. _actuator-intvelocity-actlimited:
.. _actuator-intvelocity-ctrlrange:
.. _actuator-intvelocity-forcerange:
@@ -6049,9 +6064,10 @@ This element has one custom attribute in addition to the common attributes:
.. _actuator-intvelocity-armature:
.. |actuator/intvelocity attrib list| replace::
:at:`name`, :at:`class`, :at:`group`, :at:`delay`, :at:`ctrllimited`, :at:`forcelimited`, :at:`ctrlrange`,
:at:`forcerange`, :at:`actrange`, :at:`lengthrange`, :at:`gear`, :at:`cranklength`, :at:`joint`, :at:`jointinparent`,
:at:`tendon`, :at:`cranksite`, :at:`slidersite`, :at:`site`, :at:`refsite`, :at:`user`, :at:`damping`, :at:`armature`
:at:`name`, :at:`class`, :at:`group`, :at:`delay`, :at:`ctrllimited`, :at:`forcelimited`, :at:`actlimited`,
:at:`ctrlrange`, :at:`forcerange`, :at:`actrange`, :at:`lengthrange`, :at:`gear`, :at:`cranklength`, :at:`joint`,
:at:`jointinparent`, :at:`tendon`, :at:`cranksite`, :at:`slidersite`, :at:`site`, :at:`refsite`, :at:`user`,
:at:`damping`, :at:`armature`
|actuator/intvelocity attrib list|
Same as in actuator/ :ref:`general <actuator-general>`.
@@ -9990,6 +10006,8 @@ refsite, tendon, slidersite, cranksite.
.. _default-intvelocity-forcelimited:
.. _default-intvelocity-actlimited:
.. _default-intvelocity-ctrlrange:
.. _default-intvelocity-forcerange: