I have been implementing discrete PI controller in the incremental (velocity) form in C++. I have been looking for the anti-windup mechanism. One idea which I have can be described by following pseudocode:
integral_gain = proportional_gain*sampling_period/(2*integral_time_constant);
// e(k)
error = reference_value - actual_value;
// dup(k)= kp*[e(k) - e(k-1)]
proportional_increment = proportional_gain * (error - error_previous);
// trapezoidal integration rule i.e. dui(k) = ki*[e(k) + e(k-1)]
integral_increment = integral_gain * (error + error_previous);
// du(k) = dup(k) + dui(k)
action_increment = proportional_increment + integral_increment;
// u(k) = u(k-1) + du(k)
tmp = action_previous + action_increment;
// anti-windup
if (tmp > action_max) {
action = action_max;
} else if (tmp < action_min) {
action = action_min;
} else {
action = tmp;
}
// u(k-1) = u(k)
action_previous = action;
// e(k-1) = e(k)
error_previous = error;
In math:
Let $x_k$ be the "action". Further, define an anti-windup function as
$$f_{aw}(x) = \begin{cases} x_{max} & x > x_{max} \\ x_{min} & x < x_{min} \\ x & \mathrm {otherwise} \end{cases} $$
Then calculate $x_k$ from:
$$ \Delta p = k_p (e_k - e_{k-1}) \\ \Delta i = k_i (e_k + e_{k-1}) \\ x_k = f_{aw} \left ( x_{k-1} + \Delta p + \Delta i \right) $$
I am not really sure whether the anti-windup mechanism mentioned above will be appropriate despite the fact that the incremental form is used. Can anybody help?