Open lole-elol opened 2 years ago
I am looking at the code (https://github.com/tttapa/Control-Surface-Motor-Fader/blob/master/Motor-Controller/Controller.hpp#L91) and have the same question. Too bad it hasn't been addressed in a couple of years.
I agree with @lole-elol's statements. I think this code might be a vestige of some other PID loop project/implementation. There is no mention of backward
in any of the discussion such as at https://tttapa.github.io/Pages/Arduino/Control-Theory/Motor-Fader/PID-Cpp-Implementation.html. @tttapa, can you clarify?
Edit to add: backward
refers to the backward Euler discretization method as discussed here: https://tttapa.github.io/Pages/Arduino/Control-Theory/Motor-Fader/PID-Controllers.html#backward-euler but the code as written will always use the forward method.
Since the initial integral is zero, the recursion is homogeneous, which means that we can scale it arbitrarily without affecting the result. For example, using the substitution $e_i^\prime[k] = T_s^{-1}\, e_i[k]$:
\begin{aligned}
e_i[k] &= e_i[k-1] +T_s\, e[k-1] \\
u_i[k] &= K_i e_i[k-1] \\
\text{is }&\text{equivalent to} \\
e_i^\prime[k] &= e_i^\prime[k-1] + e[k-1] \\
u_i[k] &= K_i T_s\, e_i^\prime[k-1] \\
\end{aligned}
You can verify this using the following code: https://godbolt.org/z/s4qr785bG
#include <iostream>
#include <ranges>
int main() {
const float Ts = 0.123;
int32_t errors[] {3, 2, 6, 2, 5, 5, 2, -1, 6, 3};
float integral = 0;
int32_t integralʹ = 0;
for (auto [k, error] : std::views::enumerate(errors)) {
std::cout << " eᵢ[" << k << "] = " << integral << "\n";
std::cout << "Ts eᵢʹ[" << k << "] = " << Ts * integralʹ << "\n";
integral = integral + Ts * error;
integralʹ = integralʹ + error;
}
}
Backward indeed refers to backward Euler integration. It is disabled by default: you could enable it if you wanted to, but the same effect can be achieved by changing Ki and Kp.
Hi Pieter,
first, thanks for your great article and deep introduction to this topic.
However, I cannot quite follow you in one point, in the provided Implementation for the PID controller you are using Ki already multiplied by Ts.
For the integral, you provided the following expression: $$e_i[k] = e_i[k-1] +T_s e[k-1] $$
In the code, the integral is computed as
int32_t newIntegral = integral + error
and then added to the PID algorithm asI don't understand how this implementation corresponds to the mathematical expression.
From my point of view, it should be implemented as follows
Maybe I'm overlooking something, could someone help me out here ?