Add filterexact and actearly options to MuJoCo.

When filterexact is a new dyntype which is just like the existing `filter`, but the activation state is integrated with exact integration, instead of simple Euler integration.

When actearly is specified on a general actuator, `qfrc_actuator` is computed using the next timestep's `act` value, instead of the current value.

PiperOrigin-RevId: 554438423
Change-Id: If901e4988fa6b518d6f3097f149770665a189a4b
This commit is contained in:
Nimrod Gileadi
2023-08-07 04:49:42 -07:00
committed by Copybara-Service
parent f0f535ed04
commit 2c3297b3e7
17 changed files with 441 additions and 79 deletions
+18 -10
View File
@@ -1744,6 +1744,8 @@ if omitted.
.. _default-general-biasprm:
.. _default-general-actearly:
:el-prefix:`default/` |-| **general** (?)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -5086,20 +5088,21 @@ specify them independently.
.. _actuator-general-dyntype:
:at:`dyntype`: :at-val:`[none, integrator, filter, muscle, user], "none"`
:at:`dyntype`: :at-val:`[none, integrator, filter, filterexact, muscle, user], "none"`
Activation dynamics type for the actuator. The available dynamics types were already described in the :ref:`Actuation
model <geActuation>` section. Repeating that description in somewhat different notation (corresponding to the mjModel
and mjData fields involved) we have:
========== ==================================
Keyword Description
========== ==================================
none No internal state
integrator act_dot = ctrl
filter act_dot = (ctrl - act) / dynprm[0]
muscle act_dot = mju_muscleDynamics(...)
user act_dot = mjcb_act_dyn(...)
========== ==================================
=========== ======================================
Keyword Description
=========== ======================================
none No internal state
integrator act_dot = ctrl
filter act_dot = (ctrl - act) / dynprm[0]
filterexact Like filter but with exact integration
muscle act_dot = mju_muscleDynamics(...)
user act_dot = mjcb_act_dyn(...)
=========== ======================================
.. _actuator-general-gaintype:
@@ -5156,6 +5159,11 @@ specify them independently.
so the user can enter as many parameters as needed. These defaults are not compatible with muscle actuators; see
:ref:`muscle <actuator-muscle>` below.
.. _actuator-general-actearly:
:at:`actearly`: :at-val:`[false, true], "false"`
If true, force computation will use the next value of the activation variable rather than the current one.
Setting this flag reduces the delay between the control and accelerations by one time-step.
.. _actuator-motor:
+2 -2
View File
@@ -348,7 +348,7 @@
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`gaintype<default-general-gaintype>` | :ref:`biastype<default-general-biastype>` | :ref:`dynprm<default-general-dynprm>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`gainprm<default-general-gainprm>` | :ref:`biasprm<default-general-biasprm>` | | |
| | | | :ref:`gainprm<default-general-gainprm>` | :ref:`biasprm<default-general-biasprm>` | :ref:`actearly<default-general-actearly>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |_| default |br| |_| |L| | | .. table:: |
@@ -982,7 +982,7 @@
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`biastype<actuator-general-biastype>` | :ref:`dynprm<actuator-general-dynprm>` | :ref:`gainprm<actuator-general-gainprm>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`biasprm<actuator-general-biasprm>` | | | |
| | | | :ref:`biasprm<actuator-general-biasprm>` | :ref:`actearly<actuator-general-actearly>` | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |_| actuator |br| |_| |L| | | .. table:: |
+11
View File
@@ -2,6 +2,17 @@
Changelog
=========
Upcoming version (not yet released)
-----------------------------------
General
^^^^^^^
- Added a new :ref:`dyntype<actuator-general-dyntype>`, ``filterexact``, which updates first-order filter states with
the exact formula rather than with Euler integration.
- Added an actuator attribute, :ref:`actearly<actuator-general-actearly>`, which uses semi-implicit integration for
actuator forces: using the next step's actuator state to compute the current actuator forces at the current timestep.
Version 2.3.7 (July 20, 2023)
-----------------------------
+20 -2
View File
@@ -314,8 +314,9 @@ independent of the other actuators. The activation types currently implemented a
.. math::
\begin{aligned}
\text{integrator}: & & \dot{w}_i &= u_i \\
\text{filter}: & & \dot{w}_i &= (u_i - w_i) / t \\
\text{integrator}: & & \dot{w}_i &= u_i \\
\text{filter}: & & \dot{w}_i &= (u_i - w_i) / t \\
\text{filterexact}: & & \dot{w}_i &= (u_i - w_i) / t \\
\end{aligned}
where :math:`t` is an actuator-specific time constant stored in ``mjModel.actuator_dynprm``. In addition the type can
@@ -323,6 +324,19 @@ be "user", in which case :math:`w_i` is computed by the user-defined callback :r
be "none" which corresponds to a regular actuator with no activation state. The dimensionality of :math:`w` equals
the number of actuators whose activation type is different from "none".
For ``filterexact`` activation dynamics, Euler integration of :math:`\dot{w}` is replaced with the analytic integral:
.. math::
\begin{aligned}
\text{filter}: & & w_{i+1} &= w_i + h (u_i - w_i) / t \\
\text{filterexact}: & & w_{i+1} &= w_i + (u_i - w_i) (1 - e^{-h / t}) \\
\end{aligned}
The two expressions converge to the same value in the :math:`h \rightarrow 0` limit.
Note that Euler-integrated filters diverge for :math:`t < h`, while exactly-integrated filters are stable for any
:math:`t > 0`.
.. _geActuatorForce:
Force generation
@@ -359,6 +373,10 @@ This quantity is stored in ``mjData.qfrc_actuator``. It is added to the applied
with any user-defined forces in joint or Cartesian coordinates (which are stored in ``mjData.qfrc_applied`` and
``mjData.xfrc_applied`` respectively).
Optionally, the :ref:`actearly<actuator-general-actearly>` attribute on an actuator computes ``mjData.qfrc_actuator``
based on the value of :math:`w_{i+1}` after integration, reducing the delay between changes to :math:`u` and
:math:`t`.
.. _gePassive:
Passive forces
+2
View File
@@ -485,6 +485,7 @@ typedef enum mjtDyn_ { // type of actuator dynamics
mjDYN_NONE = 0, // no internal dynamics; ctrl specifies force
mjDYN_INTEGRATOR, // integrator: da/dt = u
mjDYN_FILTER, // linear filter: da/dt = (u-a) / tau
mjDYN_FILTEREXACT, // linear filter: da/dt = (u-a) / tau, with exact integration
mjDYN_MUSCLE, // piece-wise linear filter with two time constants
mjDYN_USER // user-defined dynamics type
} mjtDyn;
@@ -1148,6 +1149,7 @@ struct mjModel_ {
mjtNum* actuator_dynprm; // dynamics parameters (nu x mjNDYN)
mjtNum* actuator_gainprm; // gain parameters (nu x mjNGAIN)
mjtNum* actuator_biasprm; // bias parameters (nu x mjNBIAS)
mjtByte* actuator_actearly; // step activation before force (nu x 1)
mjtNum* actuator_ctrlrange; // range of controls (nu x 2)
mjtNum* actuator_forcerange; // range of forces (nu x 2)
mjtNum* actuator_actrange; // range of activations (nu x 2)