Alert: This article is mostly for fun. The Lorenz System isn't very useful in the context of firmware development, but it generates beautiful solutions and its implementation has a lot of similarities with some very important tools such as IIR/FIR filters, controllers, transfer functions... Having said that, enjoy the article!
The Lorenz system is a set of ODEs that was first studied by the mathematician Edward Lorenz in the 1960s. The Lorenz system is a simplified model of atmospheric convection, which describes the behavior of a fluid in motion.
The Lorenz system consists of three nonlinear, first-order ODEs that describe the evolution of three variables: x, y, and z. The system is given by:
dx/dt = σ(y - x)
dy/dt = x(ρ - z) - y
dz/dt = xy - βz
where σ, ρ, and β are parameters that control the behavior of the system. The variables x, y, and z represent the state of the system at any given time, and the derivatives dx/dt, dy/dt, and dz/dt represent the rate of change of the variables with respect to time.
The Lorenz system is known for exhibiting chaotic behavior, which means that small changes in the initial conditions can lead to vastly different outcomes. This makes it an important model in the study of chaos theory and nonlinear dynamics.
Let's check out the implementation in structured text:
Declaration:
FUNCTION_BLOCK FB_Lorenz
VAR_INPUT
// values of the previous iteration of x, y and z
xk_1 : LREAL;
yk_1 : LREAL;
zk_1 : LREAL;
// parameters, their choice will determine the geometry of the solution but they can also
// make the system unstable (plc goes to exception mode)
sigma : LREAL;
rho : LREAL;
beta : LREAL;
END_VAR
VAR_OUTPUT
// current solution of the system
xk : LREAL;
yk : LREAL;
zk : LREAL;
END_VAR
VAR
// sampling time of your PLC
Ts : LREAL := 0.01;
END_VAR
POU Body:
xk := xk_1 + Ts*(sigma*(yk_1-xk_1));
yk := yk_1 + Ts*(xk_1*(rho-zk_1)-yk_1);
zk := zk_1 + Ts*(xk_1*yk_1 - beta*zk_1);
Parametrizing and calling the POU from the main:
Declaration:
PROGRAM MAIN
VAR
fbLorenz : FB_Lorenz; // instance of the FB
x : LREAL := 8; // initial conditions
y : LREAL := 1;
z : LREAL := 1;
i : INT;
END_VAR
Call:
fbLorenz(
sigma:= 10,
rho:= 28,
beta:= 8/3,
xk_1:= x, // cyclically feed the results into itself,
yk_1:= y, // math oroborus!
zk_1:= z,
xk=> x,
yk=> y,
zk=> z);
Try playing with the initial conditions and the parameters, there are a lot of different cool charts that you can get. Be aware that certain parameters can numerically explode and put your PLC in exception mode.
Comentários