Transfer Function Control
Housekeeping
close all; clear; clc; s = tf('s');
LEAD CONTROLLER
Let's now formulate our lead controller for the frequency domain:
where: , ,
and break frequencies of: ,
a = 1;
b = 1;
c = 0.1;
d = 1;
wz = b/a;
wp = d/c;
wm = sqrt(wz*wp);
C_lead = (a*s+b)/(c*s+d);
f1 = figure();
f1.Position = [0 0 1000 800];
[mag, phase, w, sdmag, sdphase] = bode(C_lead);
w = squeeze(w);
mag = squeeze(mag);
phase = squeeze(phase);
mag = 20*log10(mag);
subplot(2,1,1);
semilogx(w, mag);
xline(wz, '--')
xline(wp, ':')
xline(wm, '-.')
xlabel('frequency (rad/s');
ylabel('mag');
legend('mag. gain','zero break freq','pole break freq','middle break freq', 'Location', 'northwest', 'FontSize', 10);
subplot(2,1,2); title('Pole Zero Map');
semilogx(w, phase);
xline(wz, '--')
xline(wp, ':')
xline(wm, '-.')
xlabel('frequency (rad/s)');
ylabel('phase (rad)');
legend('phase gain','zero break freq','pole break freq','middle break freq', 'Location', 'northwest', 'FontSize', 10);
Note that both the bulk of the magnitude and phase gain changes are both between the two break frequencies. At the middle-frequency, half of the gain, and the maximum phase shift will occur.
Lead compensators will have little effect on the magnitude both below and above the break frequency, with phase-shift decreasing the further from the middle-frequency the input moves. The gain is used to increase CL stability and response speed, and the increase in phase is used to increase the phase-margin.
The maximum phase shift at the middle frequency is given by: , where
The overall design steps to sizing a lead-compensator in the frequency domain is:
1: Determine the open-loop gain K to satisfy error or bandwidth requirements
2: Evaluate the Phase Margin of the uncompensated system using K value from Step 1.
3: Determine needed phase lead , allowing extra margin
4: Determine
5a: Choose to be at the gain crossover frequency.
5b: Let the lower break frequency is at and upper break frequency is at
6: Draw the compensated frequency controller with controller:
7: Iterate
LAG CONTROLLER
Similar to the lead controller, the Transfer Function for a lag controller can be represented as follows:
, where:
and break frequencies of: , and,
a = 0.1;
b = 1;
c = 1;
d = 1;
wz = b/a;
wp = d/c;
wm = sqrt(wz*wp);
C_lag = (a*s+b)/(c*s+d);
f2 = figure();
f2.Position = [0 0 1000 800];
[mag, phase, w, sdmag, sdphase] = bode(C_lag);
w = squeeze(w);
mag = squeeze(mag);
phase = squeeze(phase);
mag = 20*log10(mag);
subplot(2,1,1);
semilogx(w, mag);
xline(wz, '--')
xline(wp, ':')
xline(wm, '-.')
xline([wz, wp, wm], '--');
xlabel('frequency (rad/s)');
ylabel('mag');
legend('mag. gain','zero break freq','pole break freq','middle break freq', 'Location', 'northwest', 'FontSize', 10);
subplot(2,1,2); title('Pole Zero Map');
semilogx(w, phase);
xline([wz, wp, wm], '--');
xlabel('frequency (rad/s)');
ylabel('phase (rad)');
legend('phase gain','zero break freq','pole break freq','middle break freq', 'Location', 'northwest', 'FontSize', 10);
Note that both the bulk of the magnitude and phase gain changes are both between the two break frequencies. At the middle-frequency, half of the gain, and the maximum phase shift will occur.
Lag compensators will have little effect on the magnitude both below and above the break frequency, with phase-shift decreasing the further from the middle-frequency the input moves. The magnitude drop is usually applied to move the gain crossover frequency.
Generally, some frequency is found that satisfies the PM requirement, is placed well below () such that the gain reduction occurs without introducing phase-effects near and the gain reduction will move to a lower frequency where the desired PM is satisfied.
The maximum phase shift at the middle frequency is given by: , where
The overall design steps to sizing a lag-compensator in the frequency domain is:
1: Determine the open-loop gain K to satisfy error or bandwidth requirements
2a: Find the existing phase-margin, , at a desired gain crossover frequency, .
2b: If designing for a desired phase margin, allow extra margin (~ 5 to 10°) and find the associated gain crossover frequency, .
3: Determine the gain of the uncompensated system at .
4: Set Γ to the value from Step 3.
5: Choose and
6: Draw the compensated frequency controller with controller:
7: Iterate
COMBINED LEAD-LAG CONTROLLER
The combined process for designing a lead-lag controller in the frequency domain is:
1: Determine the open-loop gain K to satisfy error or bandwidth requirements.
2: Find the existing phase and gain at the desired gain crossover frequency using K
3: Determine the required phase lead , allowing extra (5°-10°) margin
4: Calculate γ and middle , zero , and pole crossover frequencies and build lead controller
5: Calculate gain added at due to lead controller:
6: Calculate gain needed from lag controller (in dB):
7: Solve for Γ where or and build lag controller:
8: Combine gain K, lead controller , and lag controller
9: Analyze and Iterate
Let's Design a Lead-Lag Controller!
Goal: Design C(s) to meet the following specifications:
1: Phase Margin (PM) of 45°
2: ≤ 5% steady-state error to unit ramp input
3: gain crossover frequency of 2 rad/s
Step 1: Determine open-loop gain 𝐾 to satisfy error or bandwidth requirements
Plant = 2/(s*(s+2)*(s+5));
K = 105;
OpenLoopSys = K*Plant;
Step 2: Find the existing phase and gain at desired crossover frequency.
We've now created the Open Loop system with the gain required for our steady state error, and the next move is to evaluate the current gain and phase at the desired crossover frequency.
[mag, phase, w, sdmag, sdphase] = bode(OpenLoopSys);
w = squeeze(w);
mag = squeeze(mag);
phase = squeeze(phase);
mag = 20*log10(mag);
gaincrossfreq = 2;
[~,gaincrossfreqloc] = min(abs(w-2)); % location of the closest frequency to 2 rad/s
M0 = mag(gaincrossfreqloc);
phi_0 = phase(gaincrossfreqloc);
f3 = figure();
f3.Position = [0 0 1000 800];
subplot(2,1,1);
semilogx(w, mag);
xline(gaincrossfreq, '--')
yline(M0, ':');
xlabel('frequency (rad/s)');
ylabel('mag');
subplot(2,1,2); title('Pole Zero Map');
semilogx(w, phase);
xline(gaincrossfreq, '--')
yline(phi_0, ':');
xlabel('frequency (rad/s)');
ylabel('phase (rad)');
Step 3: Determine needed phase lead , allowing extra margin
Specification: ,
PM = 45;
phi0_adj = 180 + phi_0;
extra = 6;
PHI0 = PM - phi0_adj + extra;
PHI_0_rad = PHI0*pi/180;
Step 4: Calculate γ and middle , zero , and pole crossover frequencies and build Lead Controller
gamma = (1+sin(PHI_0_rad))/(1-sin(PHI_0_rad));
wm = gaincrossfreq;
wz1 = wm/sqrt(gamma);
wp1 = wm*sqrt(gamma);
C_lead = gamma*((s+wz1)/(s+wp1));
Step 5: Calculate gain added at due to lead controller
Mlead = 10*log10(gamma);
STEP 6: Calculate gain needed from lag controller (in dB):
Mlag = -1*(M0+Mlead);
STEP 7: Calculate Γ, , and and build Lag Controller
Gamma = 10^((-1/20)*Mlag)
Gamma = 11.5069
wz2 = gaincrossfreq/10;
wp2 = wz2/Gamma;
C_lag = (s/wz2+1)/(s/wp2+1);
STEP 8: Combine gain K, lead controller , and lag controller
C_leadlag = K*C_lead*C_lag;
STEP 9: Analyze and Iterate
f3 = figure();
f3.Position = [0 0 1000 800];
bode(K*Plant); hold on;
bode(K*C_lead*Plant); hold on;
bode(K*C_lead*C_lag*Plant); hold off;
legend('K only','K + lead','K + lead + lag', 'Location', 'northeast', 'FontSize', 10);
t_start = 0;
t_step = 0.01;
t_stop = 25;
t = t_start:t_step:t_stop;
%u = ones(size(t));
u = t;
%u = sin(t);
System_Plant = feedback(Plant,1);
System_LeadPlant = feedback(C_lead*Plant,1);
System_LagPlant = feedback(C_lag*Plant,1);
System_LeadLagPlant = feedback(C_lead*C_lag*Plant,1);
System_KLeadLagPlant = feedback(K*C_lead*C_lag*Plant,1);
[y_Plant,t_Plant,x_Plant,p_Plant] = lsim(System_Plant, u, t);
[y_LeadPlant,t_LeadPlant,x_LeadPlant,p_LeadPlant] = lsim(System_LeadPlant, u, t);
[y_LagPlant,t_LagPlant,x_LagPlant,p_LagPlant] = lsim(System_LagPlant, u, t);
[y_LeadLagPlant,t_LeadLagPlant,x_LeadLagPlant,p_LeadLagPlant] = lsim(System_LeadLagPlant, u, t);
[y_KLeadLagPlant,t_KLeadLagPlant,x_KLeadLagPlant,p_KLeadLagPlant] = lsim(System_KLeadLagPlant, u, t);
y_axis_lim = max([y_Plant; y_LeadPlant; y_LagPlant; y_LeadLagPlant; y_KLeadLagPlant]);
f4 = figure();
f4.Position = [0 0 1300 800];
plot(t, u, '--'); hold on;
plot(t_Plant, y_Plant, 'LineWidth', 1.5); hold on;
plot(t_LeadPlant, y_LeadPlant, 'LineWidth', 1.5); hold on;
plot(t_LagPlant, y_LagPlant, 'LineWidth', 1.5); hold on;
plot(t_LeadLagPlant, y_LeadLagPlant, 'LineWidth', 1.5); hold on;
plot(t_KLeadLagPlant, y_KLeadLagPlant, 'LineWidth', 3); hold off;
xlabel('time');
ylabel('response');
xlim([0, t_stop]);
ylim([0 y_axis_lim]);
legend('input', 'Plant', 'Lead', 'Lag', 'LeadLag', 'K*LeadLag', 'Location', 'northeast', 'FontSize', 10);