位置式\增量式PID、模糊PID、BRF-PID的Matlab實現以及封裝
阿新 • • 發佈:2021-01-26
位置式\增量式PID、模糊PID、BRF-PID的Matlab實現以及封裝
位置式\增量式PID、模糊PID、BRF-PID的Matlab實現以及封裝
簡要
PID控制由於結構簡單,控制效果好,在工業上有廣泛的應用,從出現到至今已經有一百多年的歷史;PID控制本質是一種線性控制器,它是比例(P)、積分(I)、微分(D)的線性組合,所以一旦引數確定,控制效果就已經確定,在面對非線性系統時候,控制效果不是太理想。所謂的智慧PID就是通過把智慧演算法與PID相結合,各取所長得到智慧PID演算法,其演算法本質就是通過規則或者學習演算法來線上的改變PID的三個引數,從而面對時變、非線性系統時,能有較強的魯棒性。
本文主要包括位置式\增量式PID、模糊PID、BRF-PID的Matlab實現以及封裝,其中包括了完整的程式碼。Matlab也是一門面向物件語言,利用面向物件的強大功能,本文通過策略模式把演算法經行了封裝,方便以後使用。以下是完整的程式碼實現:
Model類
此類負責儲存資料
classdef Model < handle % 策略模式:定義一系列的演算法,把它們一個個封裝起來,並且使它們可以互相替換 % 此類物件中存放資料,而在Strategy中存放演算法,此類可以選擇不同的演算法 properties sampleTime % 取樣時間 simTime % 模擬時間 rin % 輸入 sys_Plant % 被控物件傳遞函式 dsys % 離散模型 den % 離散模型分母 num % 離散訊號分子 ui yi i strategyObj % 策略物件 end methods function obj = Model(sampleTime,simTime,rin,plant) % 初始化資料。 obj.initialize(sampleTime,simTime,rin) % 建立模型及初始化其他引數 obj.buildPlant(plant); end function initialize(obj,sampleTime,simTime,rin) obj.sampleTime = sampleTime; obj.simTime = simTime; obj.i = obj.simTime/obj.sampleTime; if strcmp(rin,'step') obj.rin = ones(obj.i,1); elseif strcmp(rin,'impulse') obj.rin = zeros(obj.i,1); obj.rin(1) = 1/obj.sampleTime; elseif strcmp(rin,'square wave') x = 1:obj.i; obj.rin = sign(sin(2*pi*obj.sampleTime.*x)); end end % 被控物件傳遞函式建立及其他引數初始化。 function buildPlant(obj,plant) s = tf('s'); obj.sys_Plant = eval(plant); % 零階保持器離散化 obj.dsys = c2d(obj.sys_Plant,obj.sampleTime,'z'); [obj.num,obj.den] = tfdata(obj.dsys,'v'); % 其他初始化 obj.initialize_other(); end function initialize_other(obj) n = length(obj.den); obj.ui = zeros(n-1,1); obj.yi = zeros(n-1,1); end function progress(obj) obj.initialize_other() obj.strategyObj.progress(obj); end end end
Strategy 類
此類為抽象類,定義演算法介面
classdef Strategy < handle % 策略模式 % 策略抽象基類,定義演算法介面,有PID_Strategy,FuzzyPID_Strategy,BRF_PID_Strategy,SingleNeuralPID_Strategy等子類。 properties PID_param = [0 0 0]; % 向量依次代表pid三個引數 yout % 輸出 stepTime % 離散時間 stepRin % 離散輸入 error % 誤差變化 PID % PID三個引數變化過程 end methods function obj = Strategy(P,I,D) obj.PID_param = [P I D]; end end methods(Abstract) progress(obj) end end
PID_Strategy類
此類為位置式、增量式PID演算法的具體實現。
classdef PID_Strategy < Strategy
properties
displacementPID % 位置式PID和增量式PID切換,0代表增量式PID,1代表位置式PID
end
methods
function obj = PID_Strategy(P,I,D,displacementPID)
obj = [email protected](P,I,D);
obj.displacementPID = displacementPID;
end
function progress(obj,modelObj)
x = [0 0 0]';
i = modelObj.i;
obj.stepRin = modelObj.rin;
obj.yout = zeros(i,1);
time = zeros(i,1);
% 位置式PID
u = zeros(i,1); % 控制器輸出
e = zeros(i,1); % 誤差
e_1 = 0; % 上一時刻誤差
% 增量式PID
du = u;
u_1 = 0;
e_2 = 0;
for k = 1:i
time(k) = k*modelObj.sampleTime;
% 輸出
obj.yout(k) = modelObj.num(2:end)*modelObj.ui - modelObj.den(2:end)*modelObj.yi;
% 誤差
e(k) = obj.stepRin(k) - obj.yout(k);
% 位置式PID演算法
if obj.displacementPID
u(k) = obj.PID_param*x;
if u(k) >= 10
u(k) = 10;
end
if u(k) <= -10
u(k) = -10;
end
x(1) = e(k);
x(2) = x(2) + e(k)*modelObj.sampleTime;
x(3) = e(k) - e_1;
% 增量式PID演算法
else
du(k) = obj.PID_param*x;
u(k) = u_1 + du(k);
if u(k) >= 10
u(k) = 10;
end
if u(k) <= -10
u(k) = -10;
end
x(1) = e(k) - e_1;
x(2) = e(k);
x(3) = e(k) - 2*e_1 + e_2;
u_1 = u(k);
e_2 = e_1;
end
% 跟新資料
modelObj.ui(2:end) = modelObj.ui(1:end-1);
modelObj.ui(1) = u(k);
modelObj.yi(2:end) = modelObj.yi(1:end-1);
modelObj.yi(1) = obj.yout(k);
e_1 = e(k);
end
obj.stepTime = time;
figure
plot(time,obj.yout)
grid on
obj.error = e;
end
end
end
Fuzzy_PID_Strategy類
此類為模糊PID的具體實現
classdef Fuzzy_PID_Strategy < Strategy
% 模糊PID控制演算法。二輸入,三輸出
properties
fid % 模糊邏輯控制檔案
end
methods
function obj = Fuzzy_PID_Strategy(P,I,D,file)
obj = [email protected](P,I,D);
obj.fid = readfis(file);
end
function progress(obj,modelObj)
x = [0 0 0]';
i = modelObj.i;
obj.PID = zeros(i,3);
obj.stepRin = modelObj.rin;
obj.yout = zeros(i,1);
time = zeros(i,1);
u = zeros(i,1); % 控制器輸出
e = zeros(i,1); % 誤差
e_1 = 0; % 上一時刻誤差
ec_1 = 0; % 上一時刻誤差變化
for k = 1:i
time(k) = k*modelObj.sampleTime;
% 根據模糊規則輸出PID變化
deltaPID = evalfis(obj.fid,[e_1,ec_1]);
obj.PID(k,:) = obj.PID_param + deltaPID;
u(k) = obj.PID(k,:)*x;
if u(k) >= 10
u(k) = 10;
end
if u(k) <= -10
u(k) = -10;
end
% 輸出
obj.yout(k) = modelObj.num(2:end)*modelObj.ui - modelObj.den(2:end)*modelObj.yi;
% 誤差
e(k) = obj.stepRin(k) - obj.yout(k);
x(1) = e(k);
x(2) = x(2) + e(k)*modelObj.sampleTime;
x(3) = e(k) - e_1;
% 跟新資料
modelObj.ui(2:end) = modelObj.ui(1:end-1);
modelObj.ui(1) = u(k);
modelObj.yi(2:end) = modelObj.yi(1:end-1);
modelObj.yi(1) = obj.yout(k);
e_1 = e(k);
ec_1 = x(3);
end
obj.stepTime = time;
figure
plot(time,obj.yout)
grid on
obj.error = e;
end
end
end
BRF_PID_Strategy類
此類為徑向基函式PID的具體實現
classdef BRF_PID_Strategy < Strategy
% 徑向基函式網路PID演算法,核函式為高斯基函式,網路為3-6-1形式
properties
alpha % RBF網路學習效率
eta % RBF網路動量因子
b = 4 % 高斯基函式寬度
c % 高斯基函式中心矩陣
hide_num = 6 % 隱含層個數
out_range % 模型輸出範圍
etaPID = [0.2 0.2 0.2] % PID三個引數學習效率
ymout % BRF網路逼近輸出
dyout % BRF網路雅可比陣
displacementPID % 位置式PID和增量式PID切換,0代表增量式PID,1代表位置式PID
end
methods
function obj = BRF_PID_Strategy(P,I,D,etaPID,alpha,eta,b,out_range,hide_num,displacementPID)
obj = [email protected](P,I,D);
obj.etaPID = etaPID;
obj.alpha = alpha;
obj.eta = eta;
obj.b = b;
obj.out_range = out_range;
obj.hide_num = hide_num;
obj.displacementPID = displacementPID;
obj.c = [linspace(out_range(1),out_range(2),obj.hide_num);
linspace(out_range(1),out_range(2),obj.hide_num);
linspace(out_range(1),out_range(2),obj.hide_num)];
end
function progress(obj,modelObj)
x = [0 0 0]';
y_1 = 0; % 上一時刻輸出
% 初始化神經網路各引數
w = zeros(obj.hide_num,1); % 初始權矩陣
w_1 = w;
w_2 = w_1;
h = zeros(obj.hide_num,1); % 初始化高斯基函式輸出
RBF_input = [0 0 0]'; % 初始化神經網路輸入
% 初始化模型輸入輸出引數
i = modelObj.i;
obj.PID = zeros(i,3);
obj.stepRin = modelObj.rin;
obj.yout = zeros(i,1);
obj.ymout = zeros(i,1);
obj.dyout = zeros(i,1);
time = zeros(i,1);
% 位置式PID
u = zeros(i,1); % 控制器輸出
e = zeros(i,1); % 誤差
e_1 = 0; % 上一時刻誤差
% 增量式PID
du = u;
u_1 = 0;
e_2 = 0;
for k = 1:i
time(k) = k*modelObj.sampleTime;
% 輸出
obj.yout(k) = modelObj.num(2:end)*modelObj.ui - modelObj.den(2:end)*modelObj.yi;
for j = 1:obj.hide_num
h(j) = exp(-norm(RBF_input - obj.c(:,j))^2/(2*obj.b^2));
end
obj.ymout(k) = w'*h;
d_w = obj.alpha*(obj.yout(k) - obj.ymout(k))*h;
w = w_1 + d_w + obj.eta*(w_1 - w_2);
yu = w.*h.*(-x(1) + obj.c(1,:))'/obj.b^2;
obj.dyout(k) = sum(yu);
% 誤差
e(k) = obj.stepRin(k) - obj.yout(k);
obj.PID_param = obj.PID_param + e(k)*obj.dyout(k)*x'.*obj.etaPID;
obj.PID(k,:) = obj.PID_param;
% 位置式PID演算法
if obj.displacementPID
u(k) = obj.PID_param*x;
if u(k) >= 10
u(k) = 10;
end
if u(k) <= -10
u(k) = -10;
end
x(1) = e(k);
x(2) = x(2) + e(k)*modelObj.sampleTime;
x(3) = e(k) - e_1;
RBF_input = [u(k) obj.yout(k) y_1]';
% 增量式PID演算法
else
du(k) = obj.PID_param*x;
u(k) = u_1 + du(k);
if u(k) >= 10
u(k) = 10;
end
if u(k) <= -10
u(k) = -10;
end
x(1) = e(k) - e_1;
x(2) = e(k);
x(3) = e(k) - 2*e_1 + e_2;
RBF_input = [du(k) obj.yout(k) y_1]';
u_1 = u(k);
e_2 = e_1;
end
% 跟新資料
modelObj.ui(2:end) = modelObj.ui(1:end-1);
modelObj.ui(1) = u(k);
modelObj.yi(2:end) = modelObj.yi(1:end-1);
modelObj.yi(1) = obj.yout(k);
e_1 = e(k);
w_2 = w_1;
w_1 = w;
y_1 = obj.yout(k);
end
obj.stepTime = time;
obj.error = e;
figure
plot(time,obj.yout)
grid on
figure
plot(time,obj.yout,'r',time,obj.ymout,'b');
end
end
end
測試
測試物件為三階的一型系統,取樣時間 T S = 0.001 s T_S=0.001s TS=0.001s,模擬時長 T = 0.5 s T=0.5s T=0.5s,輸入為單位越階。
%% PID演算法/增量式PID演算法除錯
a = Model(0.001,0.5,'step','523500/(s^3+87.35*s^2+10470*s)');
a.strategyObj = PID_Strategy(1,0,0,1);
% a.strategyObj = PID_Strategy(1,0,0,0);
a.progress()
%% 神經網路PID/神經網路增量式PID演算法除錯
% a = Model(0.001,0.5,'step','523500/(s^3+87.35*s^2+10470*s)');
% isa(a.strategyObj,'Strategy')
% a.strategyObj = BRF_PID_Strategy(0.8,0,0,[0.9,0.9,0.2],0.4,0.01,2,[-1,1],6,1);
% a.progress()