Simulate closed loop system with saturated controller output in Matlab

36 views (last 30 days)
Hey,
I'd like to simulate a closed-loop system in Matlab (not Simulink) whereby the controller output (the input to the plant) is saturated.
Without saturation, I could simply do:
sysPlant = tf(4, [1 1 4]);
sysCtrl = pid(10,3,5,0.01);
sysClosedLoop = feedback(sysPlant*sysCtrl, 1);
step(sysClosedLoop, 10)
But is there a simple, elegant way to simulate that same closed-loop system but with a saturation on the controller output?
I know, this is trivial in Simulink, but is this possible in Matlab alone?
Thanks!

Answers (2)

Sam Chak
Sam Chak on 4 Sep 2024
It is entirely possible to simulate a closed-loop system in MATLAB using the ode45 solver. Since ode45 solves problems in the time domain, you will need to obtain the equivalent continuous-time model representation of the Plant transfer function and the PID controller transfer function. I believe all undergrad control theory textbooks cover this procedure, so I will not elaborate on the details.
A = [0 1
-4 -1];
B = [0
4];
C = [1 0];
D = 0;
Sp = ss(A, B, C, D)
Sp = A = x1 x2 x1 0 1 x2 -4 -1 B = u1 x1 0 x2 4 C = x1 x2 y1 1 0 D = u1 y1 0 Continuous-time state-space model.
Gp = tf(Sp) % verify if Gp has the same Plant TF
Gp = 4 ----------- s^2 + s + 4 Continuous-time transfer function.
Regarding saturation, which refers to a linear input–output mapping with lower and upper bounds, math-oriented control theorists typically use mathematical formulas (as they need to publish in journals), while non-math, tool-dependent, or AI-assisted control practitioners commonly use If-Else conditional statements.
x = linspace(-3, 3, 6001);
m = 1; % Slope
y = m*x; % Linear input–output mapping (straight line)
Lb = -1; % Lower bound
Ub = 1; % Upper bound
for i = 1:length(y)
if y(i) < Lb
sat(i) = Lb;
elseif y(i) > Ub
sat(i) = Ub;
else
sat(i) = y(i);
end
end
plot(x, sat), grid on, grid minor, ylim([-1.5, 1.5])
xlabel('x'), ylabel('sat(x)'), title('Saturation function')

Zinea
Zinea on 5 Sep 2024
Edited: Zinea on 5 Sep 2024
Simulating a closed-loop system with saturation on the controller output directly in MATLAB (without Simulink) requires a bit of manual intervention since MATLAB's built-in functions like feedback do not support saturation directly. However, you can achieve this by implementing a custom loop with saturation logic. Here's a simple way to do it:
  1. Define the plant and controller.
  2. Implement a custom simulation loop.
  3. Apply saturation to the controller output.
Here are a few points to be noted:
  1. The continuous-time plant and controller are converted to discrete-time using c2d to facilitate the simulation loop.
  2. The controller output is saturated using simple min and max functions.
  3. The loop iteratively calculates the error, computes the controller output, applies saturation, and updates the plant output.
Here's a basic example of how you can achieve the saturation for closed-loop:
% Define the plant and controller
sysPlant = tf(4, [1 1 4]);
sysCtrl = pid(10, 3, 5, 0.01);
% Define simulation parameters
tFinal = 10; % Final time
dt = 0.01; % Time step
time = 0:dt:tFinal;
% Define saturation limits
uMin = -10;
uMax = 10;
% Initialize variables
y = zeros(size(time)); % Output
u = zeros(size(time)); % Control input
e = zeros(size(time)); % Error
r = ones(size(time)); % Reference (step input)
% Convert the systems to discrete-time for simulation
sysPlantD = c2d(sysPlant, dt);
sysCtrlD = c2d(sysCtrl, dt);
% Get the discrete transfer function coefficients
[numPlant, denPlant] = tfdata(sysPlantD, 'v');
[numCtrl, denCtrl] = tfdata(sysCtrlD, 'v');
% Initialize states
xPlant = zeros(length(denPlant) - 1, 1);
xCtrl = zeros(length(denCtrl) - 1, 1);
% Simulation loop
for k = 1:length(time)-1
% Calculate the error
e(k) = r(k) - y(k);
% Controller output (before saturation)
[uCtrl, xCtrl] = filter(numCtrl, denCtrl, e(k), xCtrl);
% Apply saturation
u(k) = max(min(uCtrl, uMax), uMin);
% Plant output
[y(k+1), xPlant] = filter(numPlant, denPlant, u(k), xPlant);
end
% Plot the results
figure;
subplot(2,1,1);
plot(time, y);
title('System Output');
xlabel('Time (s)');
ylabel('Output');
subplot(2,1,2);
plot(time, u);
title('Control Input with Saturation');
xlabel('Time (s)');
ylabel('Control Input');
Output:
You may refer to the following documentation links for more information on the 'c2d
and 'filter' functions:

Products


Release

R2021a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!