Fuzzy PID Control with Type-2 FIS

This example compares a type-2 fuzzy PID controller with both a type-1 fuzzy PID controller and conventional PID controller. This example is adapted from [1].

Fuzzy PID Control

This example uses the following fuzzy logic controller (FLC) structure as described in [1]. The output of the controller (u) is found using the error (e) and the derivative of the error (e˙). Using scaling factors Ce and Cd, inputs e and e˙ are normalized to E and ΔE, respectively. The normalized ranges for both inputs are in the range [-1,1]. The fuzzy logic controller also produces a normalized output in the range [-1,1]. Additional scaling factors C0 and C1 map the fuzzy logic controller output U into u.

This example uses a delayed first-order system G(s) as the plant model.

G(s)=Ce-LsTs+1

Here, C, L, and T are the gain, time delay, and time constant, respectively.

The scaling factors Cd, C0, and C1 are defined as follows, where τc is the closed-loop time constant.

Cd=min(T,L2)×CeC0=1C×Ce(τc+L2)C1=max(T,L2)×C0

The input scaling factorCe is:

Ce1r(tr)-y(tr)

where r(tr) and y(tr) are the reference and system output values at time t=tr. These values correspond to the nominal operating point of the system.

This example compares the performance of type-1 and type-2 Sugeno fuzzy inference systems (FISs) using the Fuzzy Logic Controller Simulink® block.

Construct Type-1 FIS

Create a type-1 FIS using sugfis.

fis1 = sugfis;

Add input variables to the FIS.

fis1 = addInput(fis1,[-1 1],'Name','E');
fis1 = addInput(fis1,[-1 1],'Name','delE');

Add three uniformly distributed overlapping triangular membership functions (MFs) to each input. The MF names stand for negative (N), zero (Z), and positive (P).

fis1 = addMF(fis1,'E','trimf',[-2 -1 0],'Name','N');
fis1 = addMF(fis1,'E','trimf',[-1 0 1],'Name','Z');
fis1 = addMF(fis1,'E','trimf',[0 1 2],'Name','P');
fis1 = addMF(fis1,'delE','trimf',[-2 -1 0],'Name','N');
fis1 = addMF(fis1,'delE','trimf',[-1 0 1],'Name','Z');
fis1 = addMF(fis1,'delE','trimf',[0 1 2],'Name','P');

Plot the input membership functions.

figure
subplot(1,2,1)
plotmf(fis1,'input',1)
title('Input 1')
subplot(1,2,2)
plotmf(fis1,'input',2)
title('Input 2')

Add the output variable to the FIS.

fis1 = addOutput(fis1,[-1 1],'Name','U');

Add uniformly distributed constant functions to the output. The MF names stand for negative big (NB), negative medium (NM), zero (Z), positive medium (PM), and positive big (PB).

fis1 = addMF(fis1,'U','constant',-1,'Name','NB');
fis1 = addMF(fis1,'U','constant',-0.5,'Name','NM');
fis1 = addMF(fis1,'U','constant',0,'Name','Z');
fis1 = addMF(fis1,'U','constant',0.5,'Name','PM');
fis1 = addMF(fis1,'U','constant',1,'Name','PB');

Add rules to the FIS. These rules create a proportional control surface.

rules = [...
    "E==N & delE==N => U=NB"; ...
    "E==Z & delE==N => U=NM"; ...
    "E==P & delE==N => U=Z"; ...
    "E==N & delE==Z => U=NM"; ...
    "E==Z & delE==Z => U=Z"; ...
    "E==P & delE==Z => U=PM"; ...
    "E==N & delE==P => U=Z"; ...
    "E==Z & delE==P => U=PM"; ...
    "E==P & delE==P => U=PB" ...
    ];
fis1 = addRule(fis1,rules);

Plot the control surface.

figure
gensurf(fis1)
title('Control surface of type-1 FIS')

Construct Type-2 FIS

Convert the type-1 FIS, fis1, to a type-2 FIS.

fis2 = convertToType2(fis1);

The type-2 Sugeno system, fis2, uses type-2 membership functions for the input variables and type-1 membership functions for the output variables.

Define the footprint of uncertainty (FOU) for the input MFs as defined in [1]. To do so, set the lower MF scaling factor for each MF. For this example, set the lower MF lag values to 0.

scale = [0.2 0.9 0.2;0.3 0.9 0.3];
for i = 1:length(fis2.Inputs)
    for j = 1:length(fis2.Inputs(i).MembershipFunctions)
        fis2.Inputs(i).MembershipFunctions(j).LowerLag = 0;
        fis2.Inputs(i).MembershipFunctions(j).LowerScale = scale(i,j);
    end
end

Plot the type-2 input membership functions.

figure
subplot(1,2,1)
plotmf(fis2,'input',1)
title('Input 1')
subplot(1,2,2)
plotmf(fis2,'input',2)
title('Input 2')

The FOU adds additional uncertainty to the FIS and produces a nonlinear control surface.

figure
gensurf(fis2)
title('Control surface of type-2 FIS')

Conventional PID Controller

This example compares the fuzzy logic controller performance with that of the following conventional PID controller.

PID(s)=Kp+Kis+Kdsτfs+1

Here, Kp is proportional gain, Ki is integrator gain, Kd is derivative gain, and τf is the derivative filter time constant.

Configure Simulation

Define the nominal plant model.

C = 0.5;
L = 0.5;
T = 0.5;
G = tf(C,[T 1],'Outputdelay',L);

Generate the conventional PID controller parameters using pidtune.

pidController = pidtune(G,'pidf');

In this example, the reference (r) is a step signal and tr=0, which results in Ce=1 as follows.

Ce=1r(tr)-y(tr)=11-0=1.

Ce = 1;

To configure the simulation, use the following nominal controller parameters.

tauC = 0.2;

Cd = min(T,L/2)*Ce;
C0 = 1/(C*Ce*(tauC+L/2));
C1 = max(T,L/2)*C0;

To simulate the controllers, use the comparepidcontrollers Simulink model.

model = 'comparepidcontrollers';
load_system(model)

Simulate Nominal Process

Simulate the model at the nominal operating conditions.

out1 = sim(model);

Plot the step response of the system for all three controllers.

plotOutput(out1,['Nominal: C=' num2str(C) ', L='  num2str(L) ', T=' num2str(T)])

Obtain the step-response characteristics of the system for each controller.

stepResponseTable(out1)
ans=3×4 table
                  Rise Time (sec)    Overshoot (%)    Settling Time (sec)    Integral of Absolute Error
                  _______________    _____________    ___________________    __________________________

    PID               0.62412           11.234              4.5564                       1.04          
    Type-1 FLC         1.4267                0              4.1023                     1.1522          
    Type-2 FLC         1.8662                0               5.129                      1.282          

For the nominal process:

  • Both the type-1 and type-2 fuzzy logic controllers outperform the conventional PID controller in terms of overshoot.

  • The conventional PID controller, performs better with respect to rise-time and integral of absolute error (IAE).

  • The type-1 FLC performs better than the type-2 FLC in terms of rise-time, settling-time, and IAE.

Simulate Modified Process

Modify the plant model by increasing the gain, time delay, and time constant values as compared to the nominal process.

C = 0.85;
L = 0.6;
T = 0.6;
G = tf(C,[T 1],'Outputdelay',L);

Simulate the model using the updated plant parameters.

out2 = sim(model);

Plot the step response of the system for all three controllers.

plotOutput(out2,['Modified 1: C=' num2str(C) ',L='  num2str(L) ',T=' num2str(T)])

Obtain the step-response characteristics of the system for each controller.

stepResponseTable(out2)
ans=3×4 table
                  Rise Time (sec)    Overshoot (%)    Settling Time (sec)    Integral of Absolute Error
                  _______________    _____________    ___________________    __________________________

    PID               0.38464           80.641              29.452                     4.7486          
    Type-1 FLC        0.47262           24.877              4.6788                     1.1137          
    Type-2 FLC        0.47262           22.787              3.4561                      1.076          

For this modified process:

  • The conventional PID controller exhibits significant overshoot, larger settling-time, and higher IAE as compared to the fuzzy logic controllers

  • For all performance measures, the type-2 FLC produces the same or superior performance compared to the type-1 FLC.

Conclusion

Overall, the type-1 FLC produces superior performance for the nominal plant as compared to the conventional PID controller. The type-2 FLC shows more robust performance for the modified plant.

The robustness of the conventional PID controller can be improved using different methods, such as prediction or multiple PID controller configurations. On the other hand, the performance of a type-2 FLC can be improved by using a different:

  • Rulebase

  • Number of rules

  • FOU

For example, you can create a type-2 FLC that defines the FOU using both the lower MF scaling factor and lower MF lag.

For fis2, set the lower MF scale and lag values to 0.7 and 0.1, respectively for all input membership functions.

for i = 1:length(fis2.Inputs)
    for j = 1:length(fis2.Inputs(i).MembershipFunctions)
        fis2.Inputs(i).MembershipFunctions(j).LowerScale = 0.7;
        fis2.Inputs(i).MembershipFunctions(j).LowerLag = 0.1;
    end
end

Plot the updated membership functions.

figure
subplot(1,2,1)
plotmf(fis2,'input',1)
title('Input 1')
subplot(1,2,2)
plotmf(fis2,'input',2)
title('Input 2')

Simulate the model using the nominal plant, and plot the step responses for the controllers.

C = 0.5;
L = 0.5;
T = 0.5;
G = tf(C,[T 1],'Outputdelay',L);

out4 = sim(model);
close_system(model,0)
plotOutput(out4,['Nominal: C=' num2str(C) ', L='  num2str(L) ', T=' num2str(T)])

Obtain the step-response characteristics of the system for each controller.

stepResponseTable(out4)
ans=3×4 table
                  Rise Time (sec)    Overshoot (%)    Settling Time (sec)    Integral of Absolute Error
                  _______________    _____________    ___________________    __________________________

    PID               0.62412           11.234              4.5564                       1.04          
    Type-1 FLC         1.4267                0              4.1023                     1.1522          
    Type-2 FLC         1.2179                0              3.8746                     1.1087          

In this case, the updated FOU of type-2 FLC improves the rise-time of the step response .

However, the lower MF lag values also increase the overshoot in the case of the modified plant.

C = 0.85;
L = 0.6;
T = 0.6;
G = tf(C,[T 1],'Outputdelay',L);

out5 = sim(model);
plotOutput(out5,['Nominal: C=' num2str(C) ', L='  num2str(L) ', T=' num2str(T)])

stepResponseTable(out5)
ans=3×4 table
                  Rise Time (sec)    Overshoot (%)    Settling Time (sec)    Integral of Absolute Error
                  _______________    _____________    ___________________    __________________________

    PID               0.38464           80.641              29.452                     4.7486          
    Type-1 FLC        0.47262           24.877              4.6788                     1.1137          
    Type-2 FLC        0.47262           26.699              4.6812                     1.1278          

Therefore, to obtain desired step response characteristics, you can vary the lower MF scale and lag values to find a suitable combination.

You can further improve the fuzzy logic controller outputs using a Mamdani type FIS since it also provides lower MF scale and lag parameters for output membership functions. However, a Mamdani type-2 FLC introduces additional computational delay due to the expensive type-reduction process.

References

[1] Mendel, J. M., Uncertain Rule-Based Fuzzy Systems: Introduction and New Directions, Second Edition, Springer, 2017, pp. 229-234, 600-608.

Local Functions

function plotOutput(out,plotTitle)
figure
plot([0 20],[1 1])
hold on
plot(out.yout{1}.Values)
plot(out.yout{2}.Values)
plot(out.yout{3}.Values)
hold off
grid minor
xlabel('Time (sec)')
ylabel('Output')
title(plotTitle)
legend(["Reference","PID","Type-1 FLC","Type-2 FLC"],'Location',"best")
end
function t = stepResponseTable(out)
s = stepinfo(out.yout{1}.Values.Data,out.yout{1}.Values.Time);
stepResponseInfo(1).RiseTime = s.RiseTime;
stepResponseInfo(1).Overshoot = s.Overshoot;
stepResponseInfo(1).SettlingTime = s.SettlingTime;
stepResponseInfo(1).IAE = out.yout{4}.Values.Data(end);

s = stepinfo(out.yout{2}.Values.Data,out.yout{2}.Values.Time);
stepResponseInfo(2).RiseTime = s.RiseTime;
stepResponseInfo(2).Overshoot = s.Overshoot;
stepResponseInfo(2).SettlingTime = s.SettlingTime;
stepResponseInfo(2).IAE = out.yout{5}.Values.Data(end);

s = stepinfo(out.yout{3}.Values.Data,out.yout{3}.Values.Time);
stepResponseInfo(3).RiseTime = s.RiseTime;
stepResponseInfo(3).Overshoot = s.Overshoot;
stepResponseInfo(3).SettlingTime = s.SettlingTime;
stepResponseInfo(3).IAE = out.yout{6}.Values.Data(end);

t = struct2table(stepResponseInfo,"RowNames",["PID" "Type-1 FLC" "Type-2 FLC"]);
t.Properties.VariableNames{1} = 'Rise Time (sec)';
t.Properties.VariableNames{2} = [t.Properties.VariableNames{2} ' (%)'];
t.Properties.VariableNames{3} = 'Settling Time (sec)';
t.Properties.VariableNames{4} = 'Integral of Absolute Error';
end