# Understanding the incomplete CMSIS PID motor control documentation

I'm trying to understand the CMSIS PID Motor Control. Obvisouly it is a PID controller in parallel structure (instead of in series stucture or some sophisticated structure). It seems like there is no standardized way of how the "gains" are defined w.r.t. naming as well as valid value ranges. The derived gains A0, A1 and A2 may be calculated from the gains Kp, Ki, Kd. The state array is not documented at all.

It's an incremental form of PID, therefore the Ki shall not be zero (disabled integrator).

"series" as you call it:

$$u=K_p (\varepsilon + \dfrac{1}{T_i}\int\varepsilon\cdot dt \ + T_d\dfrac{d\varepsilon}{dt})$$

Parallel:

$$u=K_p \cdot \varepsilon + \dfrac{K_p}{T_i}\int\varepsilon\cdot dt \ + K_p\cdot T_d\dfrac{d\varepsilon}{dt}$$

$$u=K_p \cdot \varepsilon + K_i\int\varepsilon\cdot dt \ + K_d\dfrac{d\varepsilon}{dt}$$

incremental series:

$$u=K_p\int (\dfrac{d\varepsilon}{dt} + \dfrac{1}{T_i}\varepsilon\ + T_d\dfrac{d^2\varepsilon}{dt^2}) dt+C$$

Where C is the integration constant, actually the previous value of the function. The whole integral is the increment value. If the value hits the min/max constraints then in next cycle starts from there, so that's why disabling the integrator would remain biased at max or min.

You can compute the constans as:

$$K_i=K_p\dfrac{T_s}{T_i}$$ $$K_d=K_p\dfrac{T_d}{T_s}$$

See Chapter 4.1 how the PID algorithm is derived and you'll understand that CMSIS can be easily translated.

EDIT:

If you substitute ki, kd you can notice that the CMSIS PID is the same as Vladimír Bobál's Ziegler-Nichols BRM PID. You have all the needed theory in there + there is a Matlab library STCSL on Mathwork's webpage somewhere.

CMSIS:

EDIT 2:

Source code

  static __INLINE float32_t arm_pid_f32(
arm_pid_instance_f32 * S,
float32_t in)
{
float32_t out;

/* y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]  */
out = (S->A0 * in) +
(S->A1 * S->state[0]) + (S->A2 * S->state[1]) + (S->state[2]);

/* Update state */
S->state[1] = S->state[0];
S->state[0] = in;
S->state[2] = out;


• Thanks for the hint. As far as I know in practice Kp, Ki and Kd are determined experimentally or via autotune algorithms. – thinwybk May 4 at 13:05
• One of those heuristic algorithms for manual, incremental optimization is e.g. Ziegler–Nichols method. To what algorithm does match the equations for Ki and Kd you've provided above? – thinwybk May 4 at 13:22