Add the pid actuator: setpoint inputs, integral action, slew rate limiting.

<pid kp kv|dampratio [ki imax] [slewmax]> is a PID controller with real position and velocity setpoint inputs on a single force output, plus an optional feedforward input. With a zero velocity setpoint it reproduces <position> bit-exactly; the input signature is any subset of [pos, vel, ff], selected with input="..." and recorded as mjtCtrlInput bits in
actuator_ctrlspec; absent setpoint inputs are fixed at zero, so the control vector contains no inert entries.

kp and kv are single-sourced in the affine bias parameters (biasprm[1,2]) with no gainprm mirror: every consumer of the position-servo shape
(dampratio conversion, inheritrange, qDeriv) reads one location, which is what makes the bit-exact <position> parity possible. Controller state uses dyntype 'pid' with slot-gated activations in the order [slew, integral], following the dcmotor slot idiom: slewmax (dynprm[1]) rate limits the effective position setpoint through an activation holding it;
ki (gainprm[0]) integrates the position error -- wrapped on rotational transmissions -- with anti-windup clamping of the integrand at imax (dynprm[0]). Both features require the pos input. Servo input unpacking is shared with the dcmotor controller (unpackServoInputs); per-input ranges are exposed as posrange/velrange/ffrange.

This subsumes the functionality of the mujoco.pid plugin with proper activation state: correct under all integrators, visible to keyframes, act sensors and reset. Migration: kp/ki/kd map to kp/ki/kv, plugin imax is in force units (divide by ki), slewmax carries over; the single ctrl becomes input="pos".

PiperOrigin-RevId: 957588898
Change-Id: Id2786836ca6e76f58e5b5cc8323fc23be0a53784
This commit is contained in:
Yuval Tassa
2026-08-01 04:28:10 -07:00
committed by Copybara-Service
parent 7bc1aa9b05
commit 279df98cd0
33 changed files with 1504 additions and 62 deletions
+10
View File
@@ -357,6 +357,16 @@ Orientation input charts of so3 actuators. These values are used in ``m->actuato
.. mujoco-include:: mjtCtrlChart
.. _mjtCtrlInput:
mjtCtrlInput
~~~~~~~~~~~~
Input bitflags of servo-family (pd, dcmotor) actuators. These values are used in ``m->actuator_ctrlspec``.
.. mujoco-include:: mjtCtrlInput
.. _mjtObj:
mjtObj
+9
View File
@@ -5315,6 +5315,15 @@ Set actuator to velocity servo; return error if any.
Set actuator to orientation servo.
.. _mjs_setToPID:
`mjs_setToPID <#mjs_setToPID>`__
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. mujoco-include:: mjs_setToPID
Set actuator to PID controller.
.. _mjs_setToDamper:
`mjs_setToDamper <#mjs_setToDamper>`__
+265 -19
View File
@@ -5664,25 +5664,27 @@ specify them independently.
.. _actuator-general-dyntype:
:at:`dyntype`: :at-val:`[none, integrator, filter, filterexact, muscle, user], "none"`
:at:`dyntype`: :at-val:`[none, integrator, filter, filterexact, pid, 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]
filterexact Like filter but with exact integration
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
pid act_dot = position error; see :ref:`pid<actuator-pid>`
dcmotor DC motor electrical dynamics, see :ref:`dcmotor<actuator-dcmotor>`
muscle act_dot = mju_muscleDynamics(...)
user act_dot = mjcb_act_dyn(...)
============= ======================================
.. _actuator-general-gaintype:
:at:`gaintype`: :at-val:`[fixed, affine, muscle, so3, user], "fixed"`
:at:`gaintype`: :at-val:`[fixed, affine, muscle, pid, so3, user], "fixed"`
The gain and bias together determine the output of the force generation mechanism, which is currently assumed to be
affine. As already explained in :ref:`Actuation model <geActuation>`, the general formula is:
scalar_force = gain_term \* (act or ctrl) + bias_term.
@@ -5695,6 +5697,7 @@ specify them independently.
fixed gain_term = gainprm[0]
affine gain_term = gain_prm[0] + gain_prm[1]*length + gain_prm[2]*velocity
muscle gain_term = mju_muscleGain(...)
pid PID controller with setpoint inputs, see :ref:`pid<actuator-pid>`
so3 geodesic orientation servo, computed jointly over 3 force outputs, see :ref:`orientation<actuator-orientation>`
user gain_term = mjcb_act_gain(...)
======= ===============================
@@ -5739,12 +5742,23 @@ 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-velrange:
:at:`velrange`: :at-val:`real(2), "0 0"`
Range of the velocity-setpoint input of a :ref:`pid<actuator-pid>` actuator.
.. _actuator-general-ffrange:
:at:`ffrange`: :at-val:`real(2), "0 0"`
Range of the feedforward input of a :ref:`pid<actuator-pid>` actuator.
.. _actuator-general-input:
:at:`input`: :at-val:`string, optional`
Input signature of the actuator: which controls make up its control block, recorded in
``mjModel.actuator_ctrlspec``. Available for gaintype "so3", where it selects the orientation chart: "expmap"
(3 controls, the default) or "quat" (4 controls); see :ref:`orientation/input<actuator-orientation-input>`.
``mjModel.actuator_ctrlspec``. For gaintype "so3" it selects the orientation chart: "expmap" (3 controls, the
default) or "quat" (4 controls); see :ref:`orientation/input<actuator-orientation-input>`. For gaintype "pid" it is
a token list selecting the input subset; see :ref:`pid/input<actuator-pid-input>`.
.. _actuator-general-actearly:
@@ -5954,6 +5968,146 @@ This element has one custom attribute in addition to the common attributes:
:ref:`position<actuator-position>` attribute and in the :ref:`default class<default-position-inheritrange>`,
saved XMLs always convert it to explicit :at:`ctrlrange` at the actuator.
.. _actuator-pid:
:el-prefix:`actuator/` |-| **pid** |*|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This element creates a PID controller with position and velocity setpoint inputs on a single force output, with optional
integral action and feedforward. With the default input signature ``[pos, vel]`` the force is
:math:`k_p (u_{pos} - l) + k_v (u_{vel} - v)` where :math:`l, v` are the actuator length and velocity; with a zero
velocity setpoint this is identical to :ref:`position<actuator-position>`. The input signature is any subset of
``[pos, vel, ff]``, selected by :ref:`input<actuator-pid-input>`: an absent setpoint input is fixed at zero, and the
``ff`` input adds a feedforward force. Integral action is enabled by :ref:`ki<actuator-pid-ki>`: the position error is integrated in
:ref:`act<siPhysicsState>` and contributes :math:`k_i \cdot act` to the force, with anti-windup clamping by
:ref:`imax<actuator-pid-imax>`.
:ref:`slewmax<actuator-pid-slewmax>` limits the rate of change of the effective position setpoint. Each of these
features, when enabled, adds one activation state, in the order [slew, integral]. The underlying
:ref:`general<actuator-general>` attributes are set as follows:
========= ===================== ========= =========
Attribute Setting Attribute Setting
========= ===================== ========= =========
dyntype none or pid dynprm imax 0 0
gaintype pid gainprm ki 0 0
biastype affine biasprm 0 -kp -kv
========= ===================== ========= =========
This element has custom attributes in addition to the common attributes:
.. _actuator-pid-name:
.. _actuator-pid-class:
.. _actuator-pid-group:
.. _actuator-pid-nsample:
.. _actuator-pid-interp:
.. _actuator-pid-delay:
.. _actuator-pid-ctrllimited:
.. _actuator-pid-forcelimited:
.. _actuator-pid-ctrlrange:
.. _actuator-pid-forcerange:
.. _actuator-pid-lengthrange:
.. _actuator-pid-gear:
.. _actuator-pid-damping:
.. _actuator-pid-armature:
.. _actuator-pid-cranklength:
.. _actuator-pid-user:
.. _actuator-pid-joint:
.. _actuator-pid-jointinparent:
.. _actuator-pid-tendon:
.. _actuator-pid-slidersite:
.. _actuator-pid-cranksite:
.. _actuator-pid-site:
.. _actuator-pid-refsite:
.. _actuator-pid-kp:
:at:`kp`: :at-val:`real, "1"`
Position feedback gain.
.. _actuator-pid-kv:
:at:`kv`: :at-val:`real, "0"`
Velocity feedback gain: applied to the velocity error when the ``vel`` input is present, and as pure damping
otherwise. When using this attribute, it is recommended to use the implicitfast or implicit
:ref:`integrators<geIntegration>`.
.. _actuator-pid-dampratio:
:at:`dampratio`: :at-val:`real, "0"`
Damping applied by the actuator, using damping ratio units, as for
:ref:`position/dampratio<actuator-position-dampratio>`. This attribute is exclusive with :at:`kv`.
.. _actuator-pid-ki:
:at:`ki`: :at-val:`real, "0"`
Integral gain. A nonzero value enables integral action: the position error is integrated in
:ref:`act<siPhysicsState>` (:ref:`dyntype<actuator-general-dyntype>` "pid") and contributes :math:`k_i \cdot act`
to the force.
Requires the ``pos`` input.
.. _actuator-pid-imax:
:at:`imax`: :at-val:`real, "0"`
Anti-windup limit on the integral state: accumulation stops beyond ±\ :at:`imax`. The default value 0 means
"unclamped".
.. _actuator-pid-slewmax:
:at:`slewmax`: :at-val:`real, "0"`
Maximum rate of change of the effective position setpoint. When positive, the commanded setpoint is rate-limited
through an activation state holding the effective setpoint, as for the
:ref:`dcmotor controller<actuator-dcmotor-controller>`. The default value 0 means "unlimited".
.. _actuator-pid-input:
:at:`input`: :at-val:`string, "pos vel"`
Input signature: a space-separated subset of the tokens "pos", "vel" and "ff", packed in this canonical order.
Absent setpoint inputs are fixed at zero, so the control vector contains no inert entries.
.. _actuator-pid-posrange:
:at:`posrange`: :at-val:`real(2), "0 0"`
Range of the position-setpoint input; an alias of :ref:`ctrlrange<actuator-general-ctrlrange>` (the first
input).
.. _actuator-pid-velrange:
:at:`velrange`: :at-val:`real(2), "0 0"`
Range of the velocity-setpoint input.
.. _actuator-pid-ffrange:
:at:`ffrange`: :at-val:`real(2), "0 0"`
Range of the feedforward input.
.. _actuator-pid-inheritrange:
:at:`inheritrange`: :at-val:`real, "0"`
Identical to :ref:`position/inheritrange<actuator-position-inheritrange>`, setting :at:`posrange` from the
transmission target's :at:`range`.
.. _actuator-orientation:
:el-prefix:`actuator/` |-| **orientation** |*|
@@ -5976,7 +6130,7 @@ preserving its direction; the lower bound must be 0.
:ref:`Actuator sensors<sensor-actuatorpos>` report one value per force output. The integrator variant, which
stores the orientation setpoint in :ref:`act<siPhysicsState>`, is available via :ref:`general<actuator-general>` with
:ref:`dyntype<actuator-general-dyntype>` "integrator" and is expmap-only. The video on the right shows this `example
model <https://github.com/google-deepmind/mujoco/blob/main/test/engine/testdata/sensor/actuation/orientation.xml>`__.
model <https://github.com/google-deepmind/mujoco/blob/main/test/engine/testdata/actuation/orientation.xml>`__.
The underlying :el:`general` attributes are set as follows:
========= ======= ========= =========
@@ -6056,9 +6210,8 @@ This element has custom attributes in addition to the common attributes:
:el-prefix:`actuator/` |-| **velocity** |*|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This element creates a velocity servo. Note that in order to create a PD controller, one has to define two actuators: a
position servo and a velocity servo. This is because MuJoCo actuators are SISO while a PD controller takes two control
inputs (reference position and reference velocity).
This element creates a velocity servo. Note that a PD controller with both position and velocity setpoint inputs is
provided by the :ref:`pid<actuator-pid>` actuator.
When using this actuator, it is recommended to use the implicitfast or implicit :ref:`integrators<geIntegration>`.
The underlying :el:`general` attributes are set as follows:
@@ -6802,7 +6955,7 @@ Associate this actuator with an :ref:`engine plugin<exPlugin>`. Either :at:`plug
.. _actuator-plugin-dyntype:
:at:`dyntype`: :at-val:`[none, integrator, filter, filterexact, muscle, user], "none"`
:at:`dyntype`: :at-val:`[none, integrator, filter, filterexact, pid, muscle, user], "none"`
Activation dynamics type for the actuator. The available dynamics types were already described in the :ref:`Actuation
model <geActuation>` section. If :ref:`dyntype<actuator-general-dyntype>` is not "none", an activation variable will
be added to the actuator. This variable will be added after any activation state computed by the plugin (see
@@ -10020,6 +10173,10 @@ if omitted.
.. _default-general-biasprm:
.. _default-general-velrange:
.. _default-general-ffrange:
.. _default-general-input:
.. _default-general-actearly:
@@ -10199,6 +10356,95 @@ All :ref:`intvelocity <actuator-intvelocity>` attributes are available here exce
site, refsite, tendon, slidersite, cranksite.
.. _default-pid:
.. _default-pid-ctrllimited:
.. _default-pid-forcelimited:
.. _default-pid-ctrlrange:
.. _default-pid-posrange:
.. _default-pid-velrange:
.. _default-pid-ffrange:
.. _default-pid-forcerange:
.. _default-pid-inheritrange:
.. _default-pid-gear:
.. _default-pid-damping:
.. _default-pid-armature:
.. _default-pid-cranklength:
.. _default-pid-user:
.. _default-pid-group:
.. _default-pid-nsample:
.. _default-pid-interp:
.. _default-pid-delay:
.. _default-pid-kp:
.. _default-pid-kv:
.. _default-pid-dampratio:
.. _default-pid-ki:
.. _default-pid-imax:
.. _default-pid-slewmax:
.. _default-pid-input:
:el-prefix:`default/` |-| **pid** |?|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
All :ref:`pid <actuator-pid>` attributes are available here except: name, class, joint, jointinparent,
site, refsite, tendon, slidersite, cranksite.
.. _default-orientation:
.. _default-orientation-forcelimited:
.. _default-orientation-ctrlrange:
.. _default-orientation-forcerange:
.. _default-orientation-user:
.. _default-orientation-group:
.. _default-orientation-nsample:
.. _default-orientation-interp:
.. _default-orientation-delay:
.. _default-orientation-kp:
.. _default-orientation-kv:
.. _default-orientation-dampratio:
.. _default-orientation-input:
:el-prefix:`default/` |-| **orientation** |?|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
All :ref:`orientation <actuator-orientation>` attributes are available here except: name, class, joint, site, refsite.
.. _default-damper:
.. _default-damper-forcelimited:
+240
View File
@@ -2378,6 +2378,12 @@
.. grid-item::
:ref:`input<actuator-general-input>`
.. grid-item::
:ref:`velrange<actuator-general-velrange>`
.. grid-item::
:ref:`ffrange<actuator-general-ffrange>`
.. grid-item::
:ref:`dyntype<actuator-general-dyntype>`
@@ -2793,6 +2799,114 @@
:ref:`input<actuator-orientation-input>`
.. dropdown:: :ref:`pid<actuator-pid>` |*|
.. grid:: 2 3 4 4
:gutter: 0
.. grid-item::
:ref:`name<actuator-pid-name>`
.. grid-item::
:ref:`class<actuator-pid-class>`
.. grid-item::
:ref:`group<actuator-pid-group>`
.. grid-item::
:ref:`nsample<actuator-pid-nsample>`
.. grid-item::
:ref:`interp<actuator-pid-interp>`
.. grid-item::
:ref:`delay<actuator-pid-delay>`
.. grid-item::
:ref:`ctrllimited<actuator-pid-ctrllimited>`
.. grid-item::
:ref:`forcelimited<actuator-pid-forcelimited>`
.. grid-item::
:ref:`ctrlrange<actuator-pid-ctrlrange>`
.. grid-item::
:ref:`posrange<actuator-pid-posrange>`
.. grid-item::
:ref:`velrange<actuator-pid-velrange>`
.. grid-item::
:ref:`ffrange<actuator-pid-ffrange>`
.. grid-item::
:ref:`forcerange<actuator-pid-forcerange>`
.. grid-item::
:ref:`inheritrange<actuator-pid-inheritrange>`
.. grid-item::
:ref:`lengthrange<actuator-pid-lengthrange>`
.. grid-item::
:ref:`gear<actuator-pid-gear>`
.. grid-item::
:ref:`damping<actuator-pid-damping>`
.. grid-item::
:ref:`armature<actuator-pid-armature>`
.. grid-item::
:ref:`cranklength<actuator-pid-cranklength>`
.. grid-item::
:ref:`user<actuator-pid-user>`
.. grid-item::
:ref:`joint<actuator-pid-joint>`
.. grid-item::
:ref:`jointinparent<actuator-pid-jointinparent>`
.. grid-item::
:ref:`tendon<actuator-pid-tendon>`
.. grid-item::
:ref:`slidersite<actuator-pid-slidersite>`
.. grid-item::
:ref:`cranksite<actuator-pid-cranksite>`
.. grid-item::
:ref:`site<actuator-pid-site>`
.. grid-item::
:ref:`refsite<actuator-pid-refsite>`
.. grid-item::
:ref:`kp<actuator-pid-kp>`
.. grid-item::
:ref:`kv<actuator-pid-kv>`
.. grid-item::
:ref:`dampratio<actuator-pid-dampratio>`
.. grid-item::
:ref:`ki<actuator-pid-ki>`
.. grid-item::
:ref:`imax<actuator-pid-imax>`
.. grid-item::
:ref:`slewmax<actuator-pid-slewmax>`
.. grid-item::
:ref:`input<actuator-pid-input>`
.. dropdown:: :ref:`damper<actuator-damper>` |*|
.. grid:: 2 3 4 4
@@ -5927,6 +6041,12 @@
.. grid-item::
:ref:`input<default-general-input>`
.. grid-item::
:ref:`velrange<default-general-velrange>`
.. grid-item::
:ref:`ffrange<default-general-ffrange>`
.. grid-item::
:ref:`dyntype<default-general-dyntype>`
@@ -6165,6 +6285,126 @@
:ref:`dampratio<default-intvelocity-dampratio>`
.. dropdown:: :ref:`orientation<default-orientation>` :octicon:`dot`
.. grid:: 2 3 4 4
:gutter: 0
.. grid-item::
:ref:`forcelimited<default-orientation-forcelimited>`
.. grid-item::
:ref:`ctrlrange<default-orientation-ctrlrange>`
.. grid-item::
:ref:`forcerange<default-orientation-forcerange>`
.. grid-item::
:ref:`user<default-orientation-user>`
.. grid-item::
:ref:`group<default-orientation-group>`
.. grid-item::
:ref:`nsample<default-orientation-nsample>`
.. grid-item::
:ref:`interp<default-orientation-interp>`
.. grid-item::
:ref:`delay<default-orientation-delay>`
.. grid-item::
:ref:`kp<default-orientation-kp>`
.. grid-item::
:ref:`kv<default-orientation-kv>`
.. grid-item::
:ref:`dampratio<default-orientation-dampratio>`
.. grid-item::
:ref:`input<default-orientation-input>`
.. dropdown:: :ref:`pid<default-pid>` :octicon:`dot`
.. grid:: 2 3 4 4
:gutter: 0
.. grid-item::
:ref:`ctrllimited<default-pid-ctrllimited>`
.. grid-item::
:ref:`forcelimited<default-pid-forcelimited>`
.. grid-item::
:ref:`ctrlrange<default-pid-ctrlrange>`
.. grid-item::
:ref:`posrange<default-pid-posrange>`
.. grid-item::
:ref:`velrange<default-pid-velrange>`
.. grid-item::
:ref:`ffrange<default-pid-ffrange>`
.. grid-item::
:ref:`forcerange<default-pid-forcerange>`
.. grid-item::
:ref:`inheritrange<default-pid-inheritrange>`
.. grid-item::
:ref:`gear<default-pid-gear>`
.. grid-item::
:ref:`damping<default-pid-damping>`
.. grid-item::
:ref:`armature<default-pid-armature>`
.. grid-item::
:ref:`cranklength<default-pid-cranklength>`
.. grid-item::
:ref:`user<default-pid-user>`
.. grid-item::
:ref:`group<default-pid-group>`
.. grid-item::
:ref:`nsample<default-pid-nsample>`
.. grid-item::
:ref:`interp<default-pid-interp>`
.. grid-item::
:ref:`delay<default-pid-delay>`
.. grid-item::
:ref:`kp<default-pid-kp>`
.. grid-item::
:ref:`kv<default-pid-kv>`
.. grid-item::
:ref:`dampratio<default-pid-dampratio>`
.. grid-item::
:ref:`ki<default-pid-ki>`
.. grid-item::
:ref:`imax<default-pid-imax>`
.. grid-item::
:ref:`slewmax<default-pid-slewmax>`
.. grid-item::
:ref:`input<default-pid-input>`
.. dropdown:: :ref:`damper<default-damper>` :octicon:`dot`
.. grid:: 2 3 4 4
+17
View File
@@ -5,6 +5,23 @@ Changelog
Upcoming version (not yet released)
-----------------------------------
Actuation
^^^^^^^^^
- Added the :ref:`pid<actuator-pid>` actuator: a PID controller with real position and velocity setpoint inputs,
optional integral action (:ref:`ki<actuator-pid-ki>`, integrating the position error with
:ref:`imax<actuator-pid-imax>` anti-windup), setpoint rate limiting (:ref:`slewmax<actuator-pid-slewmax>`), and an
optional feedforward input. This subsumes the functionality of the ``mujoco.pid`` plugin with proper activation
state: correct under all integrators and visible to keyframes and sensors. With a zero velocity setpoint it is
identical to :ref:`position<actuator-position>`. The input signature is any subset of ``[pos, vel, ff]``, selected
by :ref:`input<actuator-pid-input>`; absent setpoint inputs are fixed at zero, so the control vector contains no
inert entries.
.. admonition:: Breaking ABI changes
:class: caution
- :ref:`mjsActuator` gained ``velrange`` and ``ffrange`` fields, changing its size and layout. The :ref:`mjtGain`
and :ref:`mjtDyn` enums gained ``pid`` members, shifting the values of ``mjGAIN_USER`` and ``mjDYN_USER``.
Engine
^^^^^^
+12
View File
@@ -2244,6 +2244,8 @@ typedef struct mjsActuator_ { // actuator specification
double dynprm[mjNDYN]; // dynamics parameters
int actdim; // number of activation variables
int ctrlspec; // input signature, scoped by gaintype; 0: type default
double velrange[2]; // range of the velocity-setpoint input (pid)
double ffrange[2]; // range of the feedforward input (pid)
mjtBool actearly; // apply next activations to qfrc
// transmission
@@ -2513,6 +2515,7 @@ typedef enum mjtDyn { // type of actuator dynamics
mjDYN_FILTEREXACT, // linear filter: da/dt = (u-a) / tau, with exact integration
mjDYN_MUSCLE, // piecewise linear filter with two time constants
mjDYN_DCMOTOR, // DC motor electrical dynamics
mjDYN_PID, // PID controller states: slew, integral
mjDYN_USER // user-defined dynamics type
} mjtDyn;
typedef enum mjtGain { // type of actuator gain
@@ -2521,6 +2524,7 @@ typedef enum mjtGain { // type of actuator gain
mjGAIN_MUSCLE, // muscle FLV curve computed by mju_muscleGain()
mjGAIN_DCMOTOR, // DC motor gain: K or K/R
mjGAIN_SO3, // geodesic servo on an SO3 transmission: force = kp * log(error)
mjGAIN_PID, // PID controller: position and velocity setpoint inputs
mjGAIN_USER // user-defined gain type
} mjtGain;
typedef enum mjtBias { // type of actuator bias
@@ -2535,6 +2539,11 @@ typedef enum mjtCtrlChart { // so3 input signature (actuator_ctrlspec): or
mjCHART_EXPMAP = 1, // exponential-map orientation target: 3 controls
mjCHART_QUAT = 2 // quaternion orientation target: 4 controls
} mjtCtrlChart;
typedef enum mjtCtrlInput { // servo input signature (actuator_ctrlspec): present-input bits
mjINPUT_POS = 1, // position setpoint input
mjINPUT_VEL = 2, // velocity setpoint input
mjINPUT_FF = 4 // feedforward input
} mjtCtrlInput;
typedef enum mjtObj { // type of MujoCo object
mjOBJ_UNKNOWN = 0, // unknown object type
mjOBJ_BODY, // body
@@ -3989,6 +3998,9 @@ const char* mjs_setToIntVelocity(mjsActuator* actuator, double kp, double kv[1],
const char* mjs_setToVelocity(mjsActuator* actuator, double kv);
const char* mjs_setToOrientation(mjsActuator* actuator, double kp, double kv[1],
double dampratio[1], int ctrlspec);
const char* mjs_setToPID(mjsActuator* actuator, double kp, double kv[1], double dampratio[1],
double ki[1], double imax[1], double slewmax[1], double inheritrange,
int ctrlspec);
const char* mjs_setToDamper(mjsActuator* actuator, double kv);
const char* mjs_setToCylinder(mjsActuator* actuator, double timeconst,
double bias, double area, double diameter);