Simulate closed loop system with saturated controller output in Matlab
39 views (last 30 days)
Show older comments
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!
0 Comments
Answers (2)
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)
Gp = tf(Sp) % verify if Gp has the same Plant TF
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')
0 Comments
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:
- Define the plant and controller.
- Implement a custom simulation loop.
- Apply saturation to the controller output.
Here are a few points to be noted:
- The continuous-time plant and controller are converted to discrete-time using ‘c2d’ to facilitate the simulation loop.
- The controller output is saturated using simple ‘min’ and ‘max’ functions.
- 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:
0 Comments
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!