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
+9 -2
View File
@@ -276,7 +276,8 @@ public enum mjtDyn : int{
mjDYN_FILTEREXACT = 3,
mjDYN_MUSCLE = 4,
mjDYN_DCMOTOR = 5,
mjDYN_USER = 6,
mjDYN_PID = 6,
mjDYN_USER = 7,
}
public enum mjtGain : int{
mjGAIN_FIXED = 0,
@@ -284,7 +285,8 @@ public enum mjtGain : int{
mjGAIN_MUSCLE = 2,
mjGAIN_DCMOTOR = 3,
mjGAIN_SO3 = 4,
mjGAIN_USER = 5,
mjGAIN_PID = 5,
mjGAIN_USER = 6,
}
public enum mjtBias : int{
mjBIAS_NONE = 0,
@@ -298,6 +300,11 @@ public enum mjtCtrlChart : int{
mjCHART_EXPMAP = 1,
mjCHART_QUAT = 2,
}
public enum mjtCtrlInput : int{
mjINPUT_POS = 1,
mjINPUT_VEL = 2,
mjINPUT_FF = 4,
}
public enum mjtObj : int{
mjOBJ_UNKNOWN = 0,
mjOBJ_BODY = 1,