Last active
August 29, 2015 14:12
-
-
Save ajaykumarsampath/cfb0a1931a242e9daa1e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| %% MPC | |
| clear all | |
| clear classes | |
| clc | |
| % User-defined parameters: | |
| load('dwn_big.mat'); | |
| f0=0.1; | |
| k=3000; | |
| P.Hp=24; | |
| P.Hu=P.Hp-1; | |
| Hsim=100; % Simulation horizon >2 | |
| P.Wa=10; | |
| P.Wx = P.Wx/1e6; | |
| x0 = S.xmin + f0*(S.xmax-S.xmin); | |
| epsilon=1e-3; | |
| %svm data | |
| Dd = DemandData(:,1); % My data | |
| [yData,fData,sc_prms,Q,yscale]=svm_data(Dd,8760,k,200,P.Hp,1,1); | |
| %load('mdl/svm_model1'); % load the svm model | |
| load('eps_demand'); %load the epsion for the forecast | |
| eps=eps./yscale; | |
| %arima model | |
| load('mdl/B2.mat'); | |
| % The closed-loop with the MPC controller: | |
| CompTimes = zeros(Hsim-1,2); % 1st col: mpc_matrices time, 2nd column: computation time | |
| mpc_ops = struct('use_soft_constraints',true,'use_beta',false, 'use_sparse', true,'use_forecast',true); | |
| Pr_sim=4; | |
| Xmpc=cell(Pr_sim,1); | |
| Umpc=cell(Pr_sim,1); | |
| %Xmpc=zeros(S.nx, Hsim); | |
| %Umpc=zeros(S.nu, Hsim-1); | |
| x=x0; | |
| uMPC=[]; | |
| %Electricity cost | |
| Eprice=cell(Pr_sim,1); | |
| Eprice{1,1}=P.alpha2; | |
| EconCost=cell(Pr_sim,1); | |
| SmoothOpCost=cell(Pr_sim,1); | |
| SafetyStorageCost=cell(Pr_sim,1); | |
| Xmpc{1}(:,1)=x0; | |
| err_percent=[0 0.001 0.005 0.01]; | |
| for i=1:Pr_sim | |
| Xmpc{i}(:,1)=x0; | |
| Eprice{i,1}=P.alpha2+err_percent(i)*randn(size(P.alpha2)); | |
| end | |
| %% Compare all demands... | |
| %load dwn_big | |
| std_demand=zeros(S.nd,1); | |
| range_demand=zeros(S.nd,1); | |
| ele=zeros(S.nd,1); | |
| for i=1:S.nd | |
| temp=(DemandData(:,i)./DemandData(:,1)); | |
| std_demand(i,1)=std(temp); | |
| range_demand(i,1)=max(temp)-min(temp); | |
| ele(i,1)=DemandData(1,i)./DemandData(1,1); | |
| end | |
| %% | |
| pastDataLength=k-5; | |
| model='actual'; %selction of demand forecast method | |
| dmd_err=zeros(S.nd*P.Hp,2); | |
| %% | |
| ctrlops=struct('normalise', false, 'mode', 'batch','u0', []); | |
| for kk=1:Pr_sim | |
| P.alpha2=Eprice{kk,1}; | |
| for j=k:k+Hsim-2 | |
| if (~mod(j-k+1,10)) | |
| disp(['Iteration : ' num2str(j-k+1)]); | |
| end | |
| switch model | |
| case 'svm' | |
| disp('svm'); | |
| Q.Nt=j-201; | |
| Ypred=svmforecast(fData,yData,m,Q,1,sc_prms,yscale); | |
| Ypred=(Ypred./yscale)'; | |
| D=vec(kron(ele', Ypred)'); % Choose D=Dreal to let the controller know the future.. | |
| dmd_err(:,1)=vec(kron(ele', eps(:,1))'); % Choose D=Dreal to let the controller know the future... | |
| dmd_err(:,2)=vec(kron(ele', eps(:,2))'); % Choose D=Dreal to let the controller know the future... | |
| case 'arima' | |
| disp('arima'); | |
| Dpast1 = DemandData(j-pastDataLength+1:j,1); | |
| Ypred = forecast(mdl.fit,P.Hp,'Y0',Dpast1); | |
| D=vec(kron(ele', Ypred)'); % Choose D=Dreal to let the controller know the future... | |
| dmd_err(:,1)=vec(kron(ele', eps(:,1))'); % Choose D=Dreal to let the controller know the future... | |
| dmd_err(:,2)=vec(kron(ele', eps(:,2))'); % Choose D=Dreal to let the controller know the future... | |
| otherwise | |
| disp('actual'); | |
| D=vec(DemandData(j:j+P.Hp-1,:)'); % Future demand values - estimations/real? | |
| end | |
| Dreal=vec(DemandData(j:j+P.Hp-1,:)'); | |
| tic; | |
| if (j==k) | |
| MPC = MPCmatrices(S, P, x, D, j, dmd_err,mpc_ops); | |
| controller = MPController(MPC, ctrlops); | |
| else | |
| %controller = controller.update(x, D, j, uMPC); | |
| controller = controller.update(x,D,j); | |
| end | |
| CompTimes(j-k+1,1)=toc; | |
| tic; | |
| [uMPC, Jstar, ystar, flag]= controller.control(); | |
| %assert(flag==1 || flag==6,'CPLEX could not converge'); | |
| if (flag==6) | |
| disp('WARNING : Non-optimal!'); | |
| %disp(output); | |
| end | |
| assert(~isempty(uMPC), 'No control action could be computed'); | |
| CompTimes(j-k+1,2)=toc; | |
| Useq=ystar(1:S.nu*(P.Hu+1),1); | |
| Xseq = MPC.Sx*x + MPC.Su*Useq + MPC.Sd*D; | |
| % Check whether the control action(s) satisfy the constraints and | |
| % whether the predicted sequence of states satisfies the state bounds. | |
| assert(max(Xseq-MPC.Xmax)<epsilon,'X>Xmax'); | |
| assert(max(Xseq-MPC.Xmin)>epsilon,'X<Xmin'); | |
| assert(max(Useq-MPC.Umax)<epsilon,'U>Umax'); | |
| assert(max(Useq-MPC.Umin)>epsilon,'U<Umin'); | |
| MPC = controller.getMPC(); | |
| prInfeasibility=max(MPC.F ./ kron( ones(1,size(MPC.F,2)),... | |
| abs(MPC.phi) )*ystar-sign(MPC.phi)); | |
| disp(['Primal Infeas. : ' num2str(prInfeasibility)]); | |
| %assert(prInfeasibility<=1e-5,'Error: Inequality constraints not satisfied'); | |
| % Check whether the state dynamics is followed: | |
| assert(norm(MPC.G*ystar-MPC.gamma)<=epsilon,'Error: Equality constraints not satisfied'); | |
| dk = Dreal(1:S.nd); | |
| x = S.A*x + S.B*uMPC + S.Gd*dk; | |
| % Check whether the current state satisfied the constraints | |
| assert(sum(x> epsilon*ones(S.nx,1)+S.xmax)==0,'Critical Error: x>xmax'); | |
| assert(sum(x< -epsilon*ones(S.nx,1)+S.xmin)==0,'Critical Error: x<xmin'); | |
| assert(sum(uMPC<S.umin-epsilon*ones(S.nu,1))==0,'Critical Error: u<umin'); | |
| assert(sum(uMPC>S.umax+epsilon*ones(S.nu,1))==0,'Critical Error: u>umax'); | |
| Xmpc{kk}(:,j-k+2)=x; | |
| Umpc{kk}(:,j-k+1)=uMPC; | |
| end | |
| for i=1:Hsim-1 | |
| EconCost{kk}(i,1)=P.Wa*(P.alpha1'+P.alpha2(k+i-1,:))*Umpc{kk}(:,i); | |
| end | |
| DeltaU = zeros(S.nu, Hsim-2); | |
| SmoothOpCost{kk}= zeros(1, Hsim-2); | |
| for i=1:Hsim-2 | |
| DeltaU(:,i)=Umpc{kk}(:,i+1)-Umpc{kk}(:,i); | |
| SmoothOpCost{kk}(i) = DeltaU(:,i)'*P.Wu*DeltaU(:,i); | |
| end | |
| SafetyStorageCost{kk} = zeros(1, Hsim); | |
| for i=1:Hsim | |
| z=max(P.xs-Xmpc{kk}(:,i),zeros(S.nx,1)); | |
| SafetyStorageCost{kk}(i)=z'*P.Wx*z; | |
| end | |
| SafetyStorageCost{kk} = SafetyStorageCost{kk}/1e7; | |
| end | |
| disp('All assertions were fulfilled!'); | |
| %% Plot the response: | |
| % Plots of the response (repletion rate of the tanks) and the corresponding | |
| % water demand. | |
| for i=1:Pr_sim | |
| figure(1) | |
| plot(EconCost{i,1}(2:end)); | |
| title('Electricity cost'); | |
| hold all; | |
| figure(2) | |
| plot(SmoothOpCost{i,1}(2:end)); | |
| title('Smooth operation cost'); | |
| hold all; | |
| figure(3) | |
| plot(SafetyStorageCost{i,1}(2:end)); | |
| title('SafetyStorageCost'); | |
| hold all; | |
| average_cost(i,:)=[mean(EconCost{i,1}(2:end)) mean(SmoothOpCost{i,1}(2:end)) mean(SafetyStorageCost{i,1}(2:end))]; | |
| end | |
| figure(1) | |
| legend('actual','0.1% error','0.5% error','1% error') | |
| figure(2) | |
| legend('actual','0.1% error','0.5% error','1% error') | |
| figure(3) | |
| legend('actual','0.1% error','0.5% error','1% error') | |
| stat_to_plot=1; | |
| for i=1:Pr_sim | |
| figure(4) | |
| title('State of the system') | |
| plot(Xmpc{i}(stat_to_plot,:)) | |
| hold all; | |
| end | |
| legend('actual','0.1% error','0.5% error','1% error') | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| classdef MPController | |
| properties | |
| MPC_=MPCmatrices; | |
| uMPC_=[]; | |
| end | |
| methods (Access=public) | |
| function obj = MPController(varargin) | |
| %controller = MPController(MPC); | |
| if isempty(varargin) | |
| return; % return empty object | |
| else | |
| obj=MPController(); | |
| end | |
| obj.MPC_=varargin{1}; | |
| end | |
| function [uMPC, Jstar, ystar, flag, output, time] = equ_ele_control(obj) %controller eliminating the equality constraints | |
| %g=null(full(obj.MPC_.G)); | |
| %zo=obj.MPC_.G\obj.MPC_.gamma; | |
| G=full(obj.MPC_.G); | |
| n=size(G'); | |
| [Q,R,P]=qr(G'); | |
| R=R(1:n(2),1:n(2)); | |
| Y1=Q(:,1:n(2)); | |
| g=Q(:,n(2)+1:n(1)); | |
| X_y1=R'\(P'*obj.MPC_.gamma); | |
| %H=full(obj.MPC_.H); | |
| zo=Y1*X_y1; | |
| assert(norm(G*zo-obj.MPC_.gamma)<10^-5,'not particular solution'); | |
| f=obj.MPC_.f*g+zo'*obj.MPC_.H*g; | |
| H=sparse(g'*obj.MPC_.H*g); | |
| %size(H) | |
| Q=0.5*(H+H'); | |
| %size(Q) | |
| %size([obj.MPC_.phi-obj.MPC_.F*zo;zo-obj.MPC_.ymin;obj.MPC_.ymax-zo]) | |
| %size(g) | |
| %size(obj.MPC_.F*g) | |
| %size(sparse([sparse(obj.MPC_.F*g);-g;g])) | |
| l=sparse([sparse(obj.MPC_.F*g);-g;g]); | |
| tic; | |
| [ystar1, Jstar, flag, output]= ... | |
| cplexqcp(Q, f, l, ... | |
| [obj.MPC_.phi-obj.MPC_.F*zo;zo-obj.MPC_.ymin;obj.MPC_.ymax-zo], [], [], ... | |
| [], [], [],[], [],[]); | |
| time=toc; | |
| size(ystar1) | |
| size(l) | |
| S = obj.MPC_.getSystem(); | |
| ystar=g*ystar1+zo; | |
| uMPC = ystar(1:S.nu,1); | |
| end | |
| function [uMPC, Jstar, ystar, flag] = control(obj) | |
| %[ystar, Jstar, flag, output]= ... | |
| % cplexqcp(obj.MPC_.H, obj.MPC_.f, obj.MPC_.F, ... | |
| % obj.MPC_.phi, obj.MPC_.G, obj.MPC_.gamma, ... | |
| % [], [], [], obj.MPC_.ymin, obj.MPC_.ymax,[]); | |
| S = obj.MPC_.getSystem(); | |
| tic; | |
| model.Q=2*obj.MPC_.H; | |
| model.obj=obj.MPC_.f; | |
| model.lb=obj.MPC_.ymin; | |
| model.ub=obj.MPC_.ymax; | |
| model.A=sparse([obj.MPC_.G;obj.MPC_.F]); | |
| model.rhs=full([obj.MPC_.gamma;obj.MPC_.phi]); | |
| no_eq=size(obj.MPC_.G,1); | |
| %model.sense=char([61*ones(no_eq,1);60*ones(size(obj.phi,1),1)]); | |
| model.sense=[repmat('=',no_eq,1);repmat('<',size(obj.MPC_.phi,1),1)]; | |
| params.outputflag=0; | |
| result=gurobi(model,params); | |
| control.control_time=toc; | |
| if ~strcmp(result.status,'OPTIMAL') | |
| %control.flag=0; | |
| flag=6; | |
| warning('WARNING : Non-optimal!'); | |
| else | |
| %control.ystar=result.x; | |
| %control.Jstar=result.objval; | |
| %control.flag=1; | |
| flag=1; | |
| Jstar=result.objval; | |
| ystar=result.x; | |
| end | |
| uMPC = ystar(1:S.nu,1); | |
| end | |
| function obj = update(obj,x, D, j) | |
| obj.MPC_ = obj.MPC_.update(x, D, j); | |
| end | |
| function mpc = getMPC(obj) | |
| mpc = obj.MPC_; | |
| end | |
| end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment