www.gusucode.com > fuzzy_featured 案例源码程序 matlab代码 > fuzzy_featured/fuzzypiddemo.m

    %% Using Lookup Table in Simulink to Implement Fuzzy PID Controller
% This example shows how to use a 2-D Lookup Table block to implement a
% fuzzy inference system for nonlinear fuzzy PID control. 
%
% The example uses Control System Toolbox(TM) and Simulink(R).

% Copyright 2010-2012 The MathWorks, Inc.

%% Overview
% A fuzzy inference system (FIS) maps given inputs to outputs using fuzzy
% logic. For example, a typical mapping of a two-input one-output fuzzy
% controller can be depicted in a 3-D plot. The plot is often referred to
% as the |control surface| plot such as the one shown below.

%%
% <<../fuzzypid_controlsurface.png>>

%%
% The typical FIS inputs are the signals of error (|e(k)|) and change of
% error (|e(k)-e(k-1)|). The FIS output is the control action inferred from
% the fuzzy rules. Fuzzy Logic Toolbox(TM) provides commands and GUI tools
% to design a FIS for a desired control surface. The designed FIS can then
% be simulated using the Fuzzy Logic Controller block in Simulink(R).

%%
% Nonlinear control surfaces can often be approximated by lookup tables to
% simplify the generated code and improve execution speed. For example, a
% Fuzzy Logic Controller block in Simulink can be replaced by a set of
% Lookup Table blocks, one lookup table for each output defined in the FIS.
% Fuzzy Logic Toolbox provides command such as |evalfis| to compute data
% used in those lookup tables.

%%
% In this example, we design a nonlinear fuzzy PID controller for a plant
% in Simulink. The plant is a single-input single-output system in discrete
% time and our design goal is simply to achieve good reference tracking
% performance.
Ts = 0.1;
Plant = c2d(zpk([],[-1 -3 -5],1),Ts);

%%
% We also show how to implement the fuzzy inference system with a 2-D
% lookup table that properly approximates the control surface and achieves
% the same control performance.

%% Fuzzy PID Controller Structure
% The fuzzy controller in this example is in the feedback loop and computes
% PID-like actions through fuzzy inference. The loop structure is displayed
% below in the Simulink diagram.

%%
open_system('sllookuptable')

%%
% The fuzzy PID controller uses a parallel structure[1] as shown below. It
% is a combination of fuzzy PI control and fuzzy PD control.

%%
open_system('sllookuptable/Fuzzy PID')

%% 
% We use the change of measurement |-(y(k)-y(k-1))|, instead of change of
% error |e(k)-e(k-1)|, as the second input signal to FIS to prevent the
% step change in reference signal from directly triggering the derivative
% action. Two gain blocks, |GCE| and |GCU| in the feed forward path from
% |r| to |u|, are used to ensure that the error signal |e| is used in
% proportional action when the fuzzy PID controller is linear.

%% Workflow for Designing a Fuzzy PID Controller
% Designing a fuzzy PID controller involves configuring the fuzzy inference
% system and setting the four scaling factors: |GE|, |GCE|, |GCU| and |GU|.
% In this example we applied the following design steps[2]:
%
%  1. Design a conventional linear PID controller 
%  2. Design an equivalent linear fuzzy PID controller
%  3. Adjust the fuzzy inference system to achieve nonlinear control surface
%  4. Fine-tune the nonlinear fuzzy PID controller

%% Step 1: Design a Conventional PID Controller
% The conventional PID controller is a discrete time PID controller with
% Backward Euler numerical integration method used in both the integral and
% derivative actions. The controller gains are |Kp|, |Ki| and |Kd|. The
% controller is implemented in Simulink as below:

%%
open_system('sllookuptable/Conventional PID')

%%
% Similar to the fuzzy PID controller, the input signal to the derivative
% action is |-y(k)|, instead of |e(k)|.

%%
% PID controller gains can be tuned either manually or using tuning
% formulas. In this example, we use the |pidtune| command from Control
% System Toolbox(TM) to obtain an initial PID design.

%%
C0 = pid(1,1,1,'Ts',Ts,'IF','B','DF','B'); % define PID structure
C = pidtune(Plant,C0) %#ok<*NOPTS> % design PID
[Kp, Ki, Kd] = piddata(C); % obtain PID gains

%% Step 2a: Design an Equivalent Linear Fuzzy PID Controller
% By configuring the FIS and selecting four scaling factors, we obtain a
% linear fuzzy PID control that reproduces the exact control performance as
% the conventional PID controller does.

%%
% First, configure the fuzzy inference system so that it produces a
% linear control surface from inputs |E| and |CE| to output |u|. The FIS
% settings summarized below are based on design choices described in [2]:
%
% * Use Mamdani style fuzzy inference system.
% * Use algebraic product for AND connective.
% * The ranges of both inputs are normalized to [-10 10].
% * The input sets are triangular and cross neighbor sets at membership value of 0.5.
% * The output range is [-20 20].
% * Use singletons as output, determined by the sum of the peak positions of the input sets.
% * Use the center of gravity method (COG) for defuzzification.

%%
% Construct fuzzy inference system:
FIS = newfis('FIS','mamdani','prod','probor','prod','sum');
%%
% Define input |E|:
FIS = addvar(FIS,'input','E',[-10 10]); 
FIS = addmf(FIS,'input',1,'Negative','trimf',[-20 -10 0]);
FIS = addmf(FIS,'input',1,'Zero','trimf',[-10 0 10]);
FIS = addmf(FIS,'input',1,'Positive','trimf',[0 10 20]);
%%
% Define input |CE|:
FIS = addvar(FIS,'input','CE',[-10 10]); 
FIS = addmf(FIS,'input',2,'Negative','trimf',[-20 -10 0]);
FIS = addmf(FIS,'input',2,'Zero','trimf',[-10 0 10]);
FIS = addmf(FIS,'input',2,'Positive','trimf',[0 10 20]);
%%
% Define output |u|:
FIS = addvar(FIS,'output','u',[-20 20]); 
FIS = addmf(FIS,'output',1,'LargeNegative','trimf',[-20 -20 -20]);
FIS = addmf(FIS,'output',1,'SmallNegative','trimf',[-10 -10 -10]);
FIS = addmf(FIS,'output',1,'Zero','trimf',[0 0 0]);
FIS = addmf(FIS,'output',1,'SmallPositive','trimf',[10 10 10]);
FIS = addmf(FIS,'output',1,'LargePositive','trimf',[20 20 20]);
%%
% Define the rules:
%
% # If |E| is Negative and |CE| is Negative then |u| is -20
% # If |E| is Negative and |CE| is Zero then |u| is -10
% # If |E| is Negative and |CE| is Positive then |u| is 0
% # If |E| is Zero and |CE| is Negative then |u| is -10
% # If |E| is Zero and |CE| is Zero then |u| is 0
% # If |E| is Zero and |CE| is Positive then |u| is 10
% # If |E| is Positive and |CE| is Negative then |u| is 0
% # If |E| is Positive and |CE| is Zero then |u| is 10
% # If |E| is Positive and |CE| is Positive then |u| is 20
ruleList = [1 1 1 1 1;...   % Rule 1
            1 2 2 1 1;...   % Rule 2
            1 3 3 1 1;...   % Rule 3
            2 1 2 1 1;...   % Rule 4
            2 2 3 1 1;...   % Rule 5
            2 3 4 1 1;...   % Rule 6
            3 1 3 1 1;...   % Rule 7
            3 2 4 1 1;...   % Rule 8
            3 3 5 1 1];     % Rule 9
FIS = addrule(FIS,ruleList);

%%
% In this example, we build the FIS using commands. You can also use the FIS
% Editor GUI tool to design the system. 

%%
% The linear control surface is plotted in 3-D below.
gensurf(FIS)

%%
% Next, we determine scaling factors |GE|, |GCE|, |GCU| and |GU| from the
% |Kp|, |Ki|, |Kd| gains used by the conventional PID controller. By
% comparing the expressions of the traditional PID and the linear fuzzy
% PID, the variables are related as:
%
% * Kp = GCU * GCE + GU * GE
% * Ki = GCU * GE
% * Kd = GU * GCE
%
% Assume the maximum reference step is 1, whereby the maximum error |e| is
% 1. Since the input range of |E| is [-10 10], we first fix |GE| at 10.
% |GCE|, |GCU| and |GCU| are then solved from the above equations.
GE = 10;
GCE = GE*(Kp-sqrt(Kp^2-4*Ki*Kd))/2/Ki;
GCU = Ki/GE;
GU = Kd/GCE;

%% Step 2b: Implement Fuzzy Inference System Using a 2-D Lookup Table
% The fuzzy controller block has two inputs (|E| and |CE|) and one output
% (|u|) that can be replaced by a 2-D lookup table.

%% 
% The 2-D lookup table for FIS is generated by looping through the input
% universe and computing the output with the |evalfis| command.
Step = 10; % use 3 break points for both E and CE inputs 
E = -10:Step:10; 
CE = -10:Step:10;
N = length(E);
LookUpTableData = zeros(N);
for i=1:N
   for j=1:N
      % compute output u for each combination of break points
      LookUpTableData(i,j) = evalfis([E(i) CE(j)],FIS); 
   end
end

%%
% The fuzzy PID controller using 2-D lookup table is shown below. Notice
% that we only replace the Fuzzy Logic Controller block with a 2-D Lookup
% Table block in the Simulink diagram.
open_system('sllookuptable/Fuzzy PID using Lookup Table')

%%
% When the control surface is linear as we already designed above, fuzzy
% PID controller using the 2-D lookup table should produce exactly the same
% result as the one using fuzzy logic controller block.

%% Step 2c: Simulate Closed-Loop Response in Simulink
% In the Simulink model, we use three different sub-systems, namely
% |Conventional PID|, |Fuzzy PID| and |Fuzzy PID using Lookup Table|, to
% control the same plant. The closed-loop responses to a step reference
% change are displayed in the scope and they are exactly the same (three
% response curves overlap each other).
open_system('sllookuptable/Scope')
sim('sllookuptable')

%% Step 3: Design Fuzzy PID Controller With Nonlinear Control Surface
% After verifying that the linear fuzzy PID controller is properly
% designed, adjust FIS settings such as its style, membership functions and
% rule base to obtain a desired nonlinear control surface.

%% 
% In this example, we choose to design a |steep| control surface using
% Sugeno style of FIS. Each input set has two terms (Positive and Negative)
% and the number of rules is reduced to four.

%%
% Construct fuzzy inference system:
FIS = newfis('FIS','sugeno');
%%
% Define input |E|:
FIS = addvar(FIS,'input','E',[-10 10]); 
FIS = addmf(FIS,'input',1,'Negative','gaussmf',[7 -10]);
FIS = addmf(FIS,'input',1,'Positive','gaussmf',[7 10]);
%%
% Define input |CE|:
FIS = addvar(FIS,'input','CE',[-10 10]); 
FIS = addmf(FIS,'input',2,'Negative','gaussmf',[7 -10]);
FIS = addmf(FIS,'input',2,'Positive','gaussmf',[7 10]);
%%
% Define output |u|:
FIS = addvar(FIS,'output','u',[-20 20]); 
FIS = addmf(FIS,'output',1,'Min','constant',-20);
FIS = addmf(FIS,'output',1,'Zero','constant',0);
FIS = addmf(FIS,'output',1,'Max','constant',20);
%%
% Define the rules:
%
% # If |E| is Negative and |CE| is Negative then |u| is -20
% # If |E| is Negative and |CE| is Positive then |u| is 0
% # If |E| is Positive and |CE| is Negative then |u| is 0
% # If |E| is Positive and |CE| is Positive then |u| is 20
ruleList = [1 1 1 1 1;...   % Rule 1
            1 2 2 1 1;...   % Rule 2
            2 1 2 1 1;...   % Rule 3
            2 2 3 1 1];     % Rule 4
FIS = addrule(FIS,ruleList);

%%
% The 3-D nonlinear control surface is plotted below. It has higher gain
% near the center of the |E| and |CE| plane than the linear surface has,
% which helps reduce the error more quickly when the error is small. When
% the error is large, controller becomes less aggressive so that control
% action is limited to avoid possible saturation.
gensurf(FIS)

%% 
% Before starting the simulation, update the lookup table with the new
% control surface data. Since the surface is nonlinear, add more break
% points to obtain a sufficient approximation.
Step = 1; % use 21 break points for both E and CE inputs 
E = -10:Step:10; 
CE = -10:Step:10;
N = length(E);
LookUpTableData = zeros(N);
for i=1:N
   for j=1:N
      % compute output u for each combination of break points
      LookUpTableData(i,j) = evalfis([E(i) CE(j)],FIS); 
   end
end

%%
% The closed-loop responses to a step reference change are displayed in the
% scope. 
sim('sllookuptable')

%%
% Compared with the traditional linear PID controller (the response curve
% with large overshoot), the nonlinear fuzzy PID controller reduces the
% over shoot by 50%, which is what we expected. The two response curves
% from the nonlinear fuzzy controllers almost overlap each other, which
% indicates that the 2-D lookup table approximates the fuzzy inference
% system very well.

%% Conclusion
% In this example, we design a nonlinear fuzzy PID controller and show that
% lookup table can be used to approximate the fuzzy inference system. By
% replacing a Fuzzy Logic Controller block with a Lookup Table block in
% Simulink, a fuzzy controller can be deployed with simplified generated
% code and improved execution speed.

%% References
% [1] Xu, J. X., Hang, C. C., Liu, C. (2000), Parallel structure and tuning
% of a fuzzy PID controller, Automatica, Vol. 36, page 673-684
%%
% [2] Jantzen, J. (1999), Tuning of Fuzzy PID Controllers, Technical
% Report, Dept. of Automation, Technical University of Denmark

%%
bdclose('sllookuptable');