How can I reduce oscilltions in control signal in LQI controller and why response is so similar even using different models?
Show older comments
I am trying to control a servomechanism that creates pressure by pulling a brake pedal. I have identified the system using System Identification Toolbox. I got the state space matrices, implemented an LQI controller and although the system works, the control signal oscillates when the impulse comes, even when changing reference signal from for example 5 bars to 0.

Although the oscillations in the beginning are small, I want to reduce them as much as possivle, since if the reference signal gets bigger, so do these oscillations. I have tried changing the model I am using and I tried to identify the system again, but surprisingly, this seems to always happen. I am confused why, when I change a model, the behavior is the same. Of course I tried changing the weight matrices Q and R, but even when the oscillations got lower, time of regulation got significantly longer and I want to avoid that too. I want to implement it "step by step", as I want to rewrite it later on to C.
I am completely new to control theory and I wonder what I am doing wrong, so I will be grateful for any help. My current code:
A = [-0.4628, 0.3217, 0.5789, -0.3823, -0.0507;
0.7593, 1.0396, -0.2008, -0.2438, -0.0678;
0.2106, 0.6490, 0.3973, 0.8735, 0.2070;
0.3128, 0.3380, 0.1524, 0.0914, -0.1088;
0.0353, 0.0419, -0.0355, 0.0682, 0.7576];
B = [0.0026;
0.0088;
-0.0036;
0.0490;
-0.1443];
C = [1.1099, 1.3983, 0.8999, -0.0136, 0.0652];
D = 0;
sys = ss(A, B, C, D, 0.01);
step(sys);
[A_size_row, A_size_column] = size(A);
Q = 4*eye(A_size_row+1);
R = 1;
A_aug = [A, zeros(A_size_column, 1); -C, 0];
B_aug = [B; 0];
[K, ~, ~] = lqr(A_aug, B_aug, Q, R);
K_i = K(6);
dt = 0.02;
T = 100; %in miliseconds
time = 0:dt:T;
x = [0;
0;
0;
0;
0];
x_i = 0;
y = [];
u = [];
ref = [];
states = [];
r=0;
for t = time
if t == 50
r = 5;
end
u_t = -K_x * x - K_i * x_i;
x_dot = A * x + B * u_t;
x = x + x_dot * dt;
y_t = C * x;
x_i_dot = r - y_t;
x_i = x_i + x_i_dot * dt;
y = [y, y_t];
u = [u, u_t];
ref = [ref, r];
states = [states, x];
end
figure;
subplot(3,1,1);
plot(time, ref, 'r--', 'LineWidth', 1.5);
hold on;
plot(time, y, 'b', 'LineWidth', 1.5);
xlabel('Time (miliseconds)');
ylabel('Output y');
title('System Output vs Reference Signal');
legend('Reference', 'Output');
grid on;
subplot(3,1,2);
plot(time, u, 'g', 'LineWidth', 1.5);
xlabel('Time (miliseconds)');
ylabel('Control Effort u');
title('Control Effort');
grid on;
subplot(3,1,3);
plot(time, states, 'LineWidth', 1.5);
xlabel('Time (miliseconds)');
ylabel('States');
title('States over Time');
legend('x1', 'x2', 'x3', 'x4', 'x5');
grid on;
1 Comment
Sometimes you cannot achieve everything you want via a particualar controller structure. So sometimes it is a good idea to play around with how you set your reference. So oneway to deal with it is, since your system is slow enough, you can apply a ramp input that reaches to the end value within 10 seconds instead of step:
A = [-0.4628, 0.3217, 0.5789, -0.3823, -0.0507;
0.7593, 1.0396, -0.2008, -0.2438, -0.0678;
0.2106, 0.6490, 0.3973, 0.8735, 0.2070;
0.3128, 0.3380, 0.1524, 0.0914, -0.1088;
0.0353, 0.0419, -0.0355, 0.0682, 0.7576];
B = [0.0026;
0.0088;
-0.0036;
0.0490;
-0.1443];
C = [1.1099, 1.3983, 0.8999, -0.0136, 0.0652];
D = 0;
sys = ss(A, B, C, D, 0.01);
% step(sys);
[A_size_row, A_size_column] = size(A);
Q = 4*eye(A_size_row+1);
R = 1;
A_aug = [A, zeros(A_size_column, 1); -C, 0];
B_aug = [B; 0];
[K, ~, ~] = lqr(A_aug, B_aug, Q, R);
K_i = K(6);
K_x = K(1:5);
dt = 0.02;
T = 100; %in miliseconds
time = 0:dt:T;
x = [0;
0;
0;
0;
0];
x_i = 0;
y = [];
u = [];
ref = [];
states = [];
r=0;
for t = time
if t >= 50 & t <= 60
r = (t-50)*.5;
elseif t>= 60
r = 5;
else
r = 0;
end
u_t = -K_x * x - K_i * x_i;
x_dot = A * x + B * u_t;
x = x + x_dot * dt;
y_t = C * x;
x_i_dot = r - y_t;
x_i = x_i + x_i_dot * dt;
y = [y, y_t];
u = [u, u_t];
ref = [ref, r];
states = [states, x];
end
figure;
subplot(3,1,1);
plot(time, ref, 'r--', 'LineWidth', 1.5);
hold on;
plot(time, y, 'b', 'LineWidth', 1.5);
xlabel('Time (miliseconds)');
ylabel('Output y');
title('System Output vs Reference Signal');
legend('Reference', 'Output');
grid on;
subplot(3,1,2);
plot(time, u, 'g', 'LineWidth', 1.5);
xlabel('Time (miliseconds)');
ylabel('Control Effort u');
title('Control Effort');
grid on;
ylim([-10 10])
subplot(3,1,3);
plot(time, states, 'LineWidth', 1.5);
xlabel('Time (miliseconds)');
ylabel('States');
title('States over Time');
legend('x1', 'x2', 'x3', 'x4', 'x5');
grid on;
Accepted Answer
More Answers (0)
Categories
Find more on Linear Model Identification in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!




