📄 plan_surgetank.m
字号:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% This program implements a controller that uses a planning% strategy for the surge tank example.%% Kevin Passino% Version: 4/19/01%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Initialize variablesclear% Set the length of the simulationNnc=300;T=0.1; % Sampling rate% As a reference input, we use a square wave (define one extra % point since at the last time we need the reference value at% the last time plus one)timeref=1:Nnc;r(timeref)=3.25-3*square((2*pi/150)*timeref); % A square wave input%r(timeref)=3.25*ones(1,Nnc+1)-3*(2*rand(1,Nnc+1)-ones(1,Nnc+1)); % A noise inputref=r(1:Nnc); % Then, use this one for plottingtime=1:Nnc;time=T*time; % Next, make the vector real time% We assume that the parameters of the surge tank (truth model) are:abar=0.01; % Parameter characterizing tank shape (nominal value is 0.01)%abar=0.05; % Parameter characterizing tank shape bbar=0.2; % Parameter characterizing tank shape (nominal value is 0.2)cbar=1; % Clogging factor representing dirty filter in pump (nominally, 1)%cbar=0.8; % Clogging factor representing dirty filter in pump (dirty case)dbar=1; % Related to diameter of output pipe g=9.8; % Gravity% Controller parameters% Model used in planning strategy:abarm=0.002; % Parameter characterizing tank shape bbarm=0.2; % Parameter characterizing tank shape cbarm=0.9; % Clogging factor representing dirty filter in pump dbarm=0.8; % Related to diameter of output pipe % Next, use a set of preset controllers (think of each as a plan template)% In this case we use PI controllers, with a grid of Kp, Ki gains around the % ones that we had designed for the PI controller for the **model**% Guess at values Kp=0.01;Ki=0.3;%Kpvec=Kp; % Vector of gains in the region of Kp, Ki%Kivec=Ki;Kpvec=0:0.05:0.2; % Vector of gains in the region of Kp, Ki%Kivec=Ki;Kivec=0.15:0.05:0.4;%Kpvec=0.2:0.2:1.8; % Vector of gains in the region of Kp, Ki%Kivec=0.05:0.01:0.11;% Set weights of cost function used to select plansw1=1;w2=1;% Set the length of time that will project into the future, NNN=[20]; % To test just one value for N%NN=[1,5,10,15,17,20,25,30,33,35,36,37,38,39,40,45,50]; % To test multiple values of the projection lengthN=max(NN); % For initialization, and allocation of variables below% First, compare the truth model characteristics to the modelheight=0:.1:10;for i=1:length(height)crosssect_truth(i,1)=abs(abar*height(i)+bbar);crosssect_model(i,1)=abarm*height(i)^2 +bbarm;endfigure(1)clfplot(height,crosssect_truth,'k-',height,crosssect_model,'k--')gridylabel('Cross-sectional area')xlabel('Height')title('Cross-sectional area for plant (solid) and model (dashed)')%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Next, start the main loop:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%for kk=1:length(NN) N=NN(kk); % Next projection length h=0*ones(1,Nnc+1); % Allocate memory hp=0*ones(1,Nnc+1); hmm=0*ones(1,Nnc+1); h(1)=1; % Initial liquid level hp(1)=1; % Initial liquid level (for plant with a PI controller) hmm(1)=1; % Initial liquid level (for model with a PI controller) % Allocate memory for projection variables hm=0*ones(N+1,length(Kpvec),length(Kivec)); em=0*ones(N,length(Kpvec),length(Kivec)); um=0*ones(N,length(Kpvec),length(Kivec)); J=0*ones(length(Kpvec),length(Kivec)); rowindex=0*ones(1,Nnc); colindex=0*ones(1,Nnc); % Also, allocate memory for the control inputs and error up=0*ones(1,Nnc); umm=0*ones(1,Nnc); u=0*ones(1,Nnc); ep=0*ones(1,Nnc); emm=0*ones(1,Nnc); e=0*ones(1,Nnc); % Initialize controller integrator: sume=0; sumep=0; sumemm=0;for k=1:Nnc %--------------------------------------------------------------- % Define the controller (for plant), where test single Kp, Ki gains ep(k)=r(k)-hp(k); sumep=sumep+ep(k); % Compute integral approx. up(k)=Kp*ep(k)+Ki*sumep; % In implementation, the input flow is restricted % by some physical contraints. So we have to put a % limit for the input flow that is chosen as 50. if up(k)>50 up(k)=50; end if up(k)<-50 up(k)=-50; end % Plant equations Ap=abs(abar*hp(k)+bbar); % Cross-sectional area alphap=hp(k)-T*dbar*sqrt(2*g*hp(k))/Ap; % Nonlinear dynamics betap=T*cbar/Ap; hp(k+1)=alphap+betap*up(k); % Compute plant output hp(k+1)=max([0.001,hp(k+1)]); % Constraint liquid not to go % negative %--------------------------------------------------------------- % Define the controller (for model), also where test single Kp, Ki % gains - here for the purpose of seeing how good the model is % (test model validity by seeing if it reacts similarly to the plant % for the same control system). emm(k)=r(k)-hmm(k); sumemm=sumemm+emm(k); % Compute integral approx. umm(k)=Kp*emm(k)+Ki*sumemm; % In implementation, the input flow is restricted % by some physical contraints. So we have to put a % limit for the input flow that is chosen as 50. if umm(k)>50 umm(k)=50; end if umm(k)<-50 umm(k)=-50; end % Model equations Amm=abarm*hmm(k)^2 +bbarm; % Cross-sectional area (model) alphamm=hmm(k)-T*dbarm*sqrt(2*g*hmm(k))/Amm; % Nonlinear dynamics (model) betamm=T*cbarm/Amm; hmm(k+1)=alphamm+betamm*umm(k); % Compute plant output hmm(k+1)=max([0.001,hmm(k+1)]); % Constraint liquid not to go % negative %--------------------------------------------------------------- % Define the planner that uses the model to control the plant % (of course this is the primary thing that we want to study) e(k)=r(k)-h(k); % Compute error sume=sume+e(k); % Compute integral approx. % Projection into the future for each controller: hm(1,:,:)=h(k)*ones(length(Kpvec),length(Kivec)); % Initialize prediction with current % liquid level for ii=1:length(Kpvec) for jj=1:length(Kivec) % The first two loops pick a controller % Initialize integral with current error integral sume, or 0 % (analgous to how we start the loop for the main controller) sumem=sume; for j=1:N % This loop simulates it at N time points em(j,ii,jj)=r(k)-hm(j,ii,jj); % Error for each model (assumes that r(k) will stay % constant over the projection window) sumem=sumem+em(j,ii,jj); % Compute integator for each controller um(j,ii,jj)=Kpvec(ii)*em(j,ii,jj)+Kivec(jj)*sumem; % Compute controller output if um(j,ii,jj)>50 % Compute saturation um(j,ii,jj)=50; end if um(j,ii,jj)<-50 um(j,ii,jj)=-50; end Am=abarm*hm(j,ii,jj)^2 +bbarm; % Cross-sectional area (model) alpham=hm(j,ii,jj)-T*dbarm*sqrt(2*g*hm(j,ii,jj))/Am; % Nonlinear dynamics (model) betam=T*cbarm/Am; hm(j+1,ii,jj)=alpham+betam*um(j,ii,jj); % Compute plant output hm(j+1,ii,jj)=max([0.001,hm(j+1,ii,jj)]); % Constraint liquid not to go % negative end % Compute the cost function for the controller that was just simulated J(ii,jj)=w1*(r(k)*ones(N+1,1)-hm(1:N+1,ii,jj))'*(r(k)*ones(N+1,1)-hm(1:N+1,ii,jj))+... w2*um(1:N,ii,jj)'*um(1:N,ii,jj); end end % Find the indices of the best controller (plan) [val,rowindex(k)]=min(min(J')); % Gives the min value (val) and its row index [val,colindex(k)]=min(min(J)); % Gives the min value and its column index % Pick the input to be the one that came from the plan that did best in % the projection u(k)=um(1,rowindex(k),colindex(k)); % Next, put the chosen input to the plant % Input saturation if u(k)>50 u(k)=50; end if u(k)<-50 u(k)=-50; end % Plant equations A=abs(abar*h(k)+bbar); % Cross-sectional area alpha=h(k)-T*dbar*sqrt(2*g*h(k))/A; % Nonlinear dynamics beta=T*cbar/A; h(k+1)=alpha+beta*u(k); % Compute plant output h(k+1)=max([0.001,h(k+1)]); % Constraint liquid not to go % negativeendhh=h(timeref);trackerrorenergy(kk)=0.5*(ref'-hh')'*(ref'-hh');inputenergy(kk)=0.5*u*u';end%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Plot the results% Plant: Controlled by PI controller % Strip off last computed value of hhhp=hp(timeref);figure(2)clfsubplot(211)plot(time,hhp,'k-',time,ref,'k--')gridylabel('Liquid height, h')title('Liquid level h and reference input r (plant)')subplot(212)plot(time,up,'k-')gridtitle('Tank input, u')xlabel('Time, k')axis([min(time) max(time) -50 50])% Model: Controlled by PI controller% Strip off last computed value of hmmhhm=hmm(timeref);figure(3)clfsubplot(211)plot(time,hhm,'k-',time,ref,'k--')gridylabel('Liquid height, h_m')title('Liquid level h_m and reference input r (model)')subplot(212)plot(time,umm,'k-')gridtitle('Tank input, u_m')xlabel('Time, k')axis([min(time) max(time) -50 50])% Difference between plant and model: Controlled by PI controller% Strip off last computed value of hmmfigure(4)clfsubplot(211)plot(time,hhp-hhm,'k-')gridtitle('Liquid height error')subplot(212)plot(time,up-umm,'k-')gridtitle('Tank input error')xlabel('Time, k')%-----------------------------------------------------------% Planning system results% Strip off last computed value of hhh=h(timeref);figure(5)clfsubplot(211)plot(time,hh,'k-',time,ref,'k--')gridylabel('Liquid height, h')title('Liquid level h and reference input r')subplot(212)plot(time,u,'k-')gridtitle('Tank input, u')xlabel('Time, k')axis([min(time) max(time) -50 50])figure(6)clfplot(time,rowindex,'k-',time,colindex,'k--')axis([min(time) max(time) 0 max(length(Kpvec),length(Kivec))])gridtitle('Indices of plan (row=solid, column=dashed)')ylabel('Row and column indices')xlabel('Time, k')% Next, study the effect of the projection length Nfigure(7)clfplot(NN,trackerrorenergy,'b-',NN,trackerrorenergy,'ro')title('Tracking energy vs. projection length N')xlabel('Projection length N')figure(8)clfplot(NN,inputenergy,'b-',NN,inputenergy,'ro')title('Control energy vs. projection length N')xlabel('Projection length N')%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% End of program%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -