% MATLAB script file m4.m is for Project 4 on
% power system stabilizer in Chapter 10
% It is to be used with the SIMULINK file s4.m
% m4.m determines the steady-state values for initializing
% the Simulink simulation s4.m and computes the
% the transfer functions for designing a PSS
% with slip as the input signal.
% ************* INPUT BLOCK **************************
% Computed transfer function is dependent on system parameters
% and operating condition:
% Inputs required:
% pu parameters of generator and ac network Thevenin's equiv,
% operating condition at generator's terminal.
% parameters of excitation system
% Clear all variables in Matlab worksapce
clear variables;
% load per unit parameters of generator and excitation system
set1
% load parameters of pss
Ks = 120;
Tw = 1.;
T1 = 0.024;
T2 = 0.002;
T3 = 0.024;
T4 = 0.24;
pss_limit = 0.1;
% Enter option to simulate or to determine
% transfer functions
opt_sim = menu('Simulation or Transfer Function?',...
'Simulation','Transfer functions');
% set up loop for repeating multiple cases
repeat_run = 'Y'; % set initially to yes for 1 or more cases
while repeat_run == 'Y'
% Input the following per unit parameters via the keyboard
% Type in after K>>
% re = 0.027; for real part of ac thevenin's source impedance
% xe = 0.1; for imag part of ac thevenin's source impedance
% Vi = 1.0 + 0*j for phasor voltage at infinite bus
% Si = 0.8 + 0.6*j for delivered complex power(lagging Q>0)
disp('Enter pu of re, xe, Vt and St via keyboard');
disp('Example: re = 0.027; xe = 0.1; Vi = 1 +j*0; Si = 0.8 +j*0.6')
disp('Type ''return'' following K>> prompt to continue');
keyboard
% ************* END OF INPUT BLOCK ***************
% Calculate base quantities
we = 2*pi*Frated;
wb = we;
wbm=wb*(2/Poles);
Sbase = Prated/Pfrated;
% Use peak values of phase quantites for voltage and current
Vbase = Vrated*sqrt(2/3);
Ibase = sqrt(2)*(Sbase/(sqrt(3)*Vrated));
Zbase = Vbase/Ibase;
% Determine steady state phasor and q-d variables
% Phasor reference axis is along the q axis of a synchronous qd frame,
% aligned along Vi, the infinite bus voltage.
% Transfer function expressions use rotor
% reference frame with q-axis aligned to internal E_q.
% Stator resistance rs, though ignored for TF, is included
% in steady-state calculation to obtain correct values
% for simulation, especially the value of Dz.
Ie = conj(Si/Vi);
Eqe = Vi + ((rs+re) + (xq+xe)*j)*Ie;
Vte = Vi + (re + xe*j)*Ie
deltat = angle(Vte);
delta = angle(Eqe);
Eqo = abs(Eqe);
I = (conj(Eqe)/Eqo)*Ie; % I = Ie*(cos(delta) - sin(delta)*j);
Iqo = real(I);
Ido = -imag(I);
Vio = abs(Vi);
Vto = (conj(Eqe)/Eqo)*Vte; % Vto = Vt*(cos(delta) - sin(delta)*j);
Vqo = real(Vto);
Vdo = -imag(Vto);
Sto = Vto*conj(I)
Eqpo = Vqo + xpd*Ido + rs*Iqo;
Edpo = Vdo - xpq*Iqo + rs*Ido
Efo = Eqo + (xd-xq)*Ido;
delio = delta
Pmecho = real(Sto);
% initialize excitation variables
VR = KE*Efo;
Vs = Efo*KF/TF;
Vref =abs(Vto)
Dz = (re+rs)*(re+rs) + (xe + xq)*(xe + xpd);
% ********** END OF STEADY-STATE CALCULATIONS ***********
% ********** BEGIN SIMULATION RUNS ***********
if (opt_sim == 1) % enter simulation mode
% set PSS_sw for operation without pss
pss_sw = -5 % threshold of sw being set at zero
% set up run time and DTmech signal for load cycling
tstop = 30;
time_Dtmech=[0 7.5 7.5 15 15 22.5 22.5 30];
DT = 0.1 % size of pu torque perturbation about operating point
tmech_Dtmech=[0 0 DT DT -DT -DT 0 0];
% Transfer back to keyboard for simulation
disp('Entering simulation mode - m4.m has set up')
disp(' PSS_sw, tstop and Dtmech in s4.m')
disp(' for you to perform simulation without pss.');
disp(' ');
disp('After your simulation run, type return.')
disp('m4.m will store results of first run for later plotting')
disp('and also set up condition for the next run with pss.')
keyboard
% store run results before making new run
yvt = y(:,1); % store value of |Vt|
ypgen = y(:,2); % store value of Pgen
yqgen = y(:,3); % store value of Qgen
ydel = y(:,4); % store value of delta
ytime = y(:,5); % store time array for this run
% set PSS_sw for operation with pss
pss_sw = 5 % threshold of sw being set at zero
disp('Conditions set for a repeat run with pss.')
disp('Type return for plots in figure window')
keyboard
subplot(4,1,1)
plot(ytime,yvt,':',y(:,5),y(:,1),'-')
axis([0,inf,0.6,1.2]) % resize yaxis
xlabel('Time in sec')
ylabel('|Vt|')
subplot(4,1,2)
plot(ytime,ydel,':',y(:,5),y(:,4),'-')
xlabel('Time in sec')
ylabel('delta')
subplot(4,1,3)
plot(ytime,ypgen,':',y(:,5),y(:,2),'-')
xlabel('Time in sec')
ylabel('Pgen')
subplot(4,1,4)
plot(ytime,yqgen,':',y(:,5),y(:,3),'-')
xlabel('Time in sec')
ylabel('Qgen')
end % if opt_sim
% ********** END SIMULATION RUNS ***********
% ********** BEGINNING OF TRANSFER FUNCTION CALCULATIONS *********
if (opt_sim == 2)
Vq_ratio = Vqo/Vto;
Vd_ratio = Vdo/Vto;
co = cos(delta);
si = sin(delta);
% compute nonlinear gains in transfer functions
K1 = (Eqo*Vio/Dz)*(re*si + (xe+xpd)*co) + ...
(Iqo*Vio/Dz)*((xq-xpd)*(xe+xq)*si - re*(xe-xpd)*co);
K2 = re*Eqo/Dz + Iqo*( 1 + (xq-xpd)*(xe+xq)/Dz );
K3 = 1/(1 + (xd-xpd)*(xe+xq)/Dz);
K4 = (Vio*(xd-xpd)/Dz)*((xe+xq)*si - re*co);
K5 = (Vio*Vq_ratio*xpd/Dz)*( re*co - (xe+xq)*si ) ...
+ (Vio*Vd_ratio*xq/Dz)*( re*si + (xe+xpd)*co );
K6 = Vq_ratio*( 1 - xpd*(xe+xq)/Dz ) + Vd_ratio*xq*re/Dz;
% ***** Block dealing with Exc(s) *******
% construct numerator s polynomial of Exc(s)
Exc_num = KA*[TF 1];
% construct denominator s polynomial of Exc(s)
Exc_den = [TA*TE*TF (TA*TE + TA*TF + TE*TF) (TA + TE + TF + KA*KF) 1];
% compute and display zeros and poles of Exc(s)
disp('Poles and zeros of Exc(s)');
[z,p,k] = tf2zp(Exc_num,Exc_den)
% Enter option to generate plots of excitation system Exc(s)
opt_Exc = menu('Plots of Exciter block transfer function?',...
'Plot Frequency Response of Exc(s)','No plots');
if (opt_Exc == 1),
% generate Bode plot of Exc(s)
freq = logspace(-1, 3, 500)';
w = 2*pi*freq;
[m,p]=bode(Exc_num,Exc_den,w);
clf;
disp('Displaying Bode plot of Exc(s)');
subplot(211); semilogx(freq,20*log10(m)); grid;
ylabel('Gain dB')
xlabel('Freq (Hz)')
title('Gain vs. frequency of Exc(s)')
subplot(212); semilogx(freq,p); grid;
ylabel('Phase (deg)');
xlabel('Freq (Hz)');
title('Phase vs. frequency of Exc(s)')
% compute gain and phase margins
[Exc_Gm,Exc_Pm,freq_cg,freq_cp] = margin(m,p,freq);
disp('Type ''return'' for GEP(s)');
keyboard
end
% Generate the transfer function GEP(s)
format short e
G_num = K3*Exc_num;
G_den = conv([K3*Tpdo 1],Exc_den);
GEP_num = K2*G_num
% Pad zeros to equalize vector length to compute GEP_den
lp = length(G_den); lq = length(G_num);
if lp == lq,
elseif lp > lq
G_num = [zeros(1,lp-lq) G_num]
else G_den =[zeros(1,lq-lp) G_den]
end
GEP_den = G_den + K6*G_num
% compute zeros and poles
[zz,pp,kk] = tf2zp(GEP_num,GEP_den)
% Option to generate plots of GEP(s) with slip as input
opt_GEP = menu('Plot GEP(s)?','Plot Frequency Response of GEP(s)','No plots');
if (opt_GEP == 1),
% generate Bode plot of GEP(s) with slip as input
freq = logspace(-1, 3, 500)';
w = 2*pi*freq;
[m_GEP,p_GEP]=bode(GEP_num,GEP_den,w);
clf;
disp('Displaying Bode plot of GEP(s)');
subplot(211); semilogx(freq,20*log10(m_GEP)); grid;
ylabel('Gain dB')
xlabel('Freq (Hz)')
title('Gain vs. frequency of GEP(s)')
subplot(212); semilogx(freq,p_GEP); grid;
ylabel('Phase (deg)');
xlabel('Freq (Hz)');
title('Phase vs. frequency of GEP(s)')
% compute gain and phase margins
[GEP_Gm,GEP_Pm,freq_cg,freq_cp] = margin(m_GEP,p_GEP,freq);
disp('Keyboard entry of the value of DPSS');
disp('Example: >>K DPSS = 6');
disp('Type ''return'' for PSS(s)');
DPSS=[];
keyboard
end
while isempty(DPSS),
disp('Enter value of DPSS, Example: K>> DPSS = 6');
disp('and type ''return'' for PSS(s)');
keyboard
end % if isempty
% Use PSS(s) GEP(s) = -DPSS or PSS(s) = -DPSS*GEP_den/GEP_num
% Plot inverse of GEP(s) to get ideal PSS(s) with speed input
if (opt_GEP == 2)|(opt_GEP == 3),
[m_PSS,p_PSS]=bode(-DPSS*GEP_den,GEP_num,w);
clf;
disp('Displaying Bode plot of PSS(s)');
subplot(211); semilogx(freq,20*log10(m_PSS)); grid;
ylabel('Gain dB')
xlabel('Freq (Hz)')
title('Gain vs. frequency of PSS(s)')
subplot(212); semilogx(freq,p_PSS); grid;
ylabel('Phase (deg)');
xlabel('Freq (Hz)');
title('Phase vs. frequency of PSS(s)')
disp('Type ''return'' for PSS(s) with K4 and K5 contributions');
keyboard
end
% Include the contributions of Ddelta via K4 and K5 in
% determining PSS(s)
% contibutions via K5
numK5 = [0 K5*wb];
denK5 = [1 0];
[a5,b5,c5,d5] = tf2ss(numK5,denK5);
% contribution via K4
numK4 = K4*wb*Exc_den;
denK4 = conv([1 0],[Exc_num]);
% determine parallel combination
denK45 = conv(denK4,denK5);
numK451 = conv(numK4,denK5);
numK452 = conv(denK4,numK5);
% Pad zeros to equalize vector length for addition
lp = length(numK451); lq = length(numK452);
if lp == lq,
elseif lp > lq
numK452 = [zeros(1,lp-lq) numK452];
else numK451 =[zeros(1,lq-lp) numK451];
end
% add the two numerator terms
numK45 = numK451 + numK452;
% now add numK45/denK45 to DPSS/GEP(s)
den_PSS = conv(GEP_num,denK45);
num_PSS1 = conv((-DPSS*GEP_den),denK45);
num_PSS2 = conv(GEP_num,numK45);
% Pad zeros to equalize vector length for addition
lp = length(num_PSS1); lq = length(num_PSS2);
if lp == lq,
elseif lp > lq
num_PSS2 = [zeros(1,lp-lq) num_PSS2];
else num_PSS1 =[zeros(1,lq-lp) num_PSS1];
end
num_PSS = num_PSS1 + num_PSS2;
% Generate Bode plots of PSS(s) for slip input
% with K4 and K5 contributions
freq = logspace(-1, 3, 500)';
w = 2*pi*freq;
[m_PSS,p_PSS]=bode(num_PSS,den_PSS,w);
clf;
disp('Displaying Bode plot of PSS(s) with K4 and K5');
subplot(211); semilogx(freq,20*log10(m_PSS)); grid;
ylabel('Gain dB')
xlabel('Freq (Hz)')
title('Gain vs. frequency of PSS(s) with K4 and K5')
subplot(212); semilogx(freq,p_PSS); grid;
ylabel('Phase (deg)');
xlabel('Freq (Hz)');
title('Phase vs. frequency of PSS(s) with K4 and K5')
disp('Type ''return'' for next computation');
keyboard
end % if of opt_sim
% prompt for repeat with new system condition
repeat_run = input('Repeat with new system condition? Y/N: ','s');
if isempty(repeat_run) % if empty return a No to terminate
repeat_run = 'N';
end
end % while repeat_run