📄 lpvsolpq.m
字号:
% [gam,xmat,ymat,xyopt] = ...% lpvsolpq(vlpv,dim,vnu,fghparm,gradfg,gamwt,slow,xyinit) % calculates the solution to the parameter-dependent OSF LPV control problem% with dynamic parameter measurement.%% INPUTS:% vlpv: (VARYING) matrix containing Np evaluations of the OLIC:% vlpv = vpck([olic1;...;olicNp],1:Np)% Any direct state measurements must be ordered last (in A and in Cy).% dim = [nmeas nctrl nsf NX NY Ngam]: number of measurements, controls, % directly measured states, X basis functions, Y basis functions, and % gamma basis functions. nsf = 0: OF plant. Ng = 0: nonparametric gamma.% vnu: Np*Nq-point VARYING (2s x nbnds) matrix grid of velocities for (p,q),% where q(s) = (psi s)/(s + psi) p(s) is a filtered estimate of dp/dt.% nbnds = 1: -vnu(i) < d(p,q)(i)/dt < vnu(i)% nbnds = 2: vnu(i,1) < d(p,q)(i)/dt < vnu(i,2)% nbnds > 2: vnu(1:s,j) is the j-th corner of the dp/dt polytope.% vnu(s+(1:s),j) is the j-th corner of the dq/dt polytope.% fghparm = abv(fparm,gparm,hparm): fparm, gparm, and hparm are Np*Nq-point% VARYING basis function data for X(p,q), Y(p,q), and gamma(p,q).% Each point of the varying matrix is ((NX+NY+Ngam) x 1).% gradfg = abv(gradf,gradg): gradf & gradg are Np*Nq-point% VARYING basis gradient data for X(p,q) & Y(p,q).% Each point of the varying matrix is ((NX+NY+Ngam) x 2s).% To be independent of p(i), use 1 for basis function, 0 for gradient.% gamwt: grid of scalar weights for parameter-varying gamma,% Ngam x 1 CONSTANT or Np*Nq-point VARYING % slow = [maxre; gest] (OPTIONAL): maxre = upper bound on |Re(clp poles)|,% gest = prior estimate of gam (same size as vunpck(gam))% xyinit: initial guess for the decision variables (OPTIONAL).%% OUTPUTS:% gam: optimal gamma (scalar CONSTANT or ngam-point VARYING)% xmat/ymat: The [X11 X12]/Y solutions, as NX/NY-point VARYING matrices.% xyopt: The vector of optimal decision variables.%% c. Lawton H. Lee (1997)function [gam,xmat,ymat,xyopt] = ... lpvsolnew(vlpv,dim,vnu,fghparm,gradfg,gamwt,slow,xyinit);if nargin < 5 | nargin > 8 disp('Between 5 and 8 input arguments required. See HELP for details.') return;endtstart = cputime;disp('Setting up LMIs...');% Get some problem dimensionsnmeas = dim(1); nctrl = dim(2); nsf = dim(3); NX = dim(4); NY = dim(5); Ng = dim(6);% If vlpv is a system matrix, pack it as a varying matrix.[type,dum2,dum3,npts] = minfo(vlpv);if type == 'syst' vlpv = vpck(vlpv,1); [type,dum2,dum3,npts] = minfo(vlpv);endviv = getiv(vlpv);% Get more problem dimensions[type,no,ni,nx] = minfo(xtracti(vlpv,1,1));nx1 = nx-nsf; nx2 = nsf;ny1 = nmeas-nsf; ny2 = nsf;nd = ni-nctrl; nd1 = nd-ny1;ne = no-nmeas; ne1 = ne-nctrl;% Analyze vnu, fghparm, gradfg dimensions[type,nparm,nbnds,npts1] = minfo(vnu);if type ~= 'vary' vnu = vpck(kron(ones(npts,1),vnu),kron(getiv(fghparm))); [type,nparm,nbnds,npts1] = minfo(vnu);endif nbnds > 2 GRID_PARMV = 1; else GRID_PARMV = 0; if nbnds == 1, vnu = sbs(mscl(vnu,-1),vnu); endend[dum1,nbasis,ncols,npts2] = minfo(fghparm);[dum1,ngbasis,nparmg,npts3] = minfo(gradfg);% If the olic doesn't depend on the filtered rate, then make copiesnq = npts2/npts;if round(nq) ~= nq error('Inconsistent number of q grid points')endif nq > 1 vlpv = vpck(vunpck(veval('kron',ones(nq,1),vlpv)),getiv(fghparm)); [type,dum2,dum3,npts] = minfo(vlpv); viv = getiv(vlpv); disp('Making copies of plant data')end% Check for dimension inconsistenciesif (nbasis ~= NX + NY + Ng) | (ngbasis ~= NX + NY) error('Number of basis functions inconsistent.');elseif ncols ~= 1 error('Basis functions must be vectors.');elseif nparmg ~= nparm | rem(nparm,2) > 0 error('Number of parameters inconsistent or odd.');elseif any(npts ~= [npts2 npts3]) disp(['There are ' int2str(npts) ' points in vlpv']) disp(['There are ' int2str(npts1) ' points in vnu']) disp(['There are ' int2str(npts2) ' points in fghparm']) disp(['There are ' int2str(npts3) ' points in gradfg']) error('Number of grid points inconsistent.');else fparm = sel(fghparm,1:NX,':'); gparm = sel(fghparm,NX+(1:NY),':'); hparm = sel(fghparm,NX+NY+(1:Ng),':'); gradf = sel(gradfg,1:NX,':'); gradg = sel(gradfg,NX+(1:NY),':'); nparm = nparm / 2;end% Identify parameters having finite, nonzero rate boundsparmx = any(vunpck(gradf)) & any(vunpck(vtp(vnu)));parmx = parmx(1:nparm) | parmx(nparm+(1:nparm));parmy = any(vunpck(gradg)) & any(vunpck(vtp(vnu)));parmy = parmy(1:nparm) | parmy(nparm+(1:nparm));nparmx = sum(parmx);nparmy = sum(parmy);if GRID_PARMV & nparmx > 0 nvertx = nbnds;else nvertx = 2^nparmx;endif GRID_PARMV & nparmy > 0nverty = nbnds;else nverty = 2^nparmy;end% Get matrix containing all combinations of +/- for nparm-dim vector.combmatx = corners(nparmx); % combmatx = 1 if nparmx = 0combmaty = corners(nparmy); % combmaty = 1 if nparmy = 0% Check for weight on gammaif ~exist('gamwt') gamwt = 1;endgamwt = vunpck(gamwt);if max(size(gamwt)) <= 1 PDGAM = 0; gamwt = 1;else PDGAM = 1; if size(gamwt,1) == 1 gamwt = gamwt'; end endngamwt = length(gamwt);% Check for parametric gammaif Ng > 0 PARGAM = 1; ngamvar = Ng;else PARGAM = 0; ngamvar = ngamwt;endif all(ngamwt ~= [1 npts]) error('Inconsistent dimensions for gamma weight.');elseif ~all(gamwt > eps) error('All weights on gamma must be positive.');end % Check for slow optionif ~exist('slow') slow = [];endif isempty(slow) SLOW = 0;else SLOW = 1; maxre = slow(1); gest = slow(2:length(slow));end% check for initial variable guessif ~exist('xyinit') xyinit = [];endif SLOW, disp('Using pole placement for ''slow'' controller dynamics'), endif PDGAM, disp('Using parameter-dependent gamma'), endif ~isempty(xyinit), disp('Using initial guess for variables'), end% Set up LMI variablessetlmis([]);for i = 1:NY Y = lmivar(1,[nx 1]);endfor i = 1:NX X11 = lmivar(1,[nx1 1]);endif nsf > 1 for i = 1:NX X12 = lmivar(2,[nx1 nx2]); endendfor i = 1:ngamvar gamma = lmivar(1,[1 0]);endnvarxy = (1+sign(nsf)) * NX + NY;nvardec = (nx1*(nx1+1)/2+sign(nsf)*nx1*nx2)*NX + nx*(nx+1)/2*NY + ngamvar;cobj = zeros(nvardec-ngamvar,1);if PARGAM cobj = [cobj; vunpck(vtp(hparm))'*gamwt];else cobj = [zeros(nvardec-ngamwt,1); gamwt];end% Add data to variable "lmis".for i = 1:npts disp([' Adding data for grid point ' int2str(i) ' of ' int2str(npts)]);% Get state-space data for grid point i sys = xtracti(vlpv,i,1); [A,Bd,Bu,Ce,Cy,Ded] = transfr(sys,nmeas,nctrl,nsf); B11 = Bd(1:nx1,1:nd1); B12 = Bd(1:nx1,nd1+1:nd); B21 = Bd(nx1+1:nx,1:nd1); B22 = Bd(nx1+1:nx,nd1+1:nd); Ce1 = Ce(1:ne1,:); Ce2 = Ce(ne1+1:ne,:); Cy1 = Cy(1:ny1,1:nx1); D11 = Ded(1:ne1,1:nd1); D12 = Ded(1:ne1,nd1+1:nd); D21 = Ded(ne1+1:ne,1:nd1); D22 = Ded(ne1+1:ne,nd1+1:nd); Dednorm = max(norm([D11 D12]),norm([D11;D21])); if Dednorm > 1, disp(['norm(Ded + Deu Dk Dyd) > ' num2str(Dednorm)]); end Ahat = A-Bu*Ce2; Bdhat = Bd-Bu*[D21 D22]; if ny1 == 0 % (i.e., no disturbed measurements) Atld11 = A(1:nx1,1:nx1); Atld21 = A(nx1+1:nx,1:nx1); else Atld11 = A(1:nx1,1:nx1)-B12*Cy1; Atld21 = A(nx1+1:nx,1:nx1)-B22*Cy1; Cetld = Ce(:,1:nx1)-[D12;D22]*Cy1; end indx = (nvertx+nverty+1)*(i-1); indx1 = indx+nverty; indx2 = (nvertx+nverty+1)*i; igam = min(ngamvar,i);% Get values of basis functions, gradient, and rate bound for parm_i. fdat = xtracti(fparm,i,1); gdat = xtracti(gparm,i,1); hdat = xtracti(hparm,i,1); gfdat = xtracti(gradf,i,1); ggdat = xtracti(gradg,i,1); nu = xtracti(vnu,i,1); if ne1 > 0 ezmaty = [eye(nx) zeros(nx,ne1)]; else ezmaty = 1; end if nd1 > 0 ezmatx = [eye(nx1) zeros(nx1,nd1)]; else ezmatx = 1; end for j = 1:nverty for k = 1:NY if abs(gdat(k)) > eps lmiterm([indx+j 1 1 k],gdat(k)*[Ahat;Ce1],ezmaty,'s');% lmiterm([indx+j 1 1 k],gdat(k),Ahat','s');% if ne1 > 0% lmiterm([indx+j 2 1 k],gdat(k)*Ce1,1);% end end ly = 0; parmv = zeros(2*nparm,1); for l = 1:nparm ll = nparm + l; if parmy(l) ~= 0 ly = ly + 1; if GRID_PARMV parmv(l) = nu(l,j); parmv(ll) = nu(ll,j); else parmv(l) = (nu(l,1)+nu(l,2))/2 + combmaty(j,ly)*(nu(l,1)-nu(l,2))/2; parmv(ll) = (nu(ll,1)+nu(ll,2))/2 + combmaty(j,ly)*(nu(ll,1)-nu(ll,2))/2; end end end if abs(ggdat(k,:)*parmv) > eps lmiterm([indx+j 1 1 k],-(ggdat(k,:)*parmv)*ezmaty',ezmaty);% lmiterm([indx+j 1 1 k],-ggdat(k,:)*parmv,1); end end lmiterm([indx+j 2 1 0],[Bdhat' [D11 D12]']); if PARGAM & PDGAM for k = 1:Ng if abs(hdat(k)) > eps lmiterm([indx+j 1 1 nvarxy+k],-hdat(k),daug(Bu*Bu',eye(ne1))); lmiterm([indx+j 2 2 nvarxy+k],-hdat(k),1); end end else lmiterm([indx+j 1 1 nvarxy+igam],-1,daug(Bu*Bu',eye(ne1))); lmiterm([indx+j 2 2 nvarxy+igam],-1,1); end% lmiterm([indx+j 1 1 nvarxy+igam],-Bu,Bu');% if ne1 == 0% lmiterm([indx+j 2 1 0],Bdhat');% lmiterm([indx+j 2 2 nvarxy+igam],-1,1);% else% lmiterm([indx+j 2 2 nvarxy+igam],-1,1);% lmiterm([indx+j 3 1 0],Bdhat');% lmiterm([indx+j 3 2 0],[D11 D12]');% lmiterm([indx+j 3 3 nvarxy+igam],-1,1);% end end for j = 1:nvertx for k = 1:NX if abs(fdat(k)) > eps lmiterm([indx1+j 1 1 k+NY],fdat(k)*ezmatx',[Atld11 B11],'s'); if nsf > 1 lmiterm([indx1+j 1 1 k+NY+NX],fdat(k)*ezmatx',[Atld21 B21],'s'); end% lmiterm([indx1+j 1 1 k+NY],fdat(k),Atld11,'s');% if nsf > 1% lmiterm([indx1+j 1 1 k+NY+NX],fdat(k),Atld21,'s');% end% if nd1 > 0% lmiterm([indx1+j 2 1 k+NY],fdat(k)*B11',1);% if nsf > 1% lmiterm([indx1+j 1 2 k+NY+NX],fdat(k),B21);% end% end end lx = 0; parmv = zeros(2*nparm,1); for l = 1:nparm ll = nparm + l; if parmx(l) ~= 0 lx = lx + 1; if GRID_PARMV parmv(l) = nu(l,j); parmv(ll) = nu(ll,j); else parmv(l) = (nu(l,1)+nu(l,2))/2 + combmatx(j,lx)*(nu(l,1)-nu(l,2))/2; parmv(ll) = (nu(ll,1)+nu(ll,2))/2 + combmatx(j,lx)*(nu(ll,1)-nu(ll,2))/2; end end end if abs(gfdat(k,:)*parmv) > eps lmiterm([indx1+j 1 1 k+NY],(gfdat(k,:)*parmv)*ezmatx',ezmatx);% lmiterm([indx1+j 1 1 k+NY],gfdat(k,:)*parmv,1); end end lmiterm([indx1+j 2 1 0],[Cetld [D11;D21]]); if PARGAM & PDGAM for k = 1:Ng if (abs(hdat(k)) > eps) if ny1 == 0 % (i.e. state feedback only) lmiterm([indx1+j 1 1 nvarxy+k],-hdat(k),daug(zeros(nx1),eye(nd1)));% % do nothing for 3x3 block version else lmiterm([indx1+j 1 1 nvarxy+k],-hdat(k),daug(Cy1'*Cy1,eye(nd1)));% lmiterm([indx1+j 1 1 nvarxy+igam],-Cy1',Cy1); end lmiterm([indx1+j 2 2 nvarxy+k],-hdat(k),1); end end else if ny1 == 0 % (i.e. state feedback only) lmiterm([indx1+j 1 1 nvarxy+igam],-1,daug(zeros(nx1),eye(nd1)));% % do nothing for 3x3 block version else lmiterm([indx1+j 1 1 nvarxy+igam],-1,daug(Cy1'*Cy1,eye(nd1)));% lmiterm([indx1+j 1 1 nvarxy+igam],-Cy1',Cy1); end lmiterm([indx1+j 2 2 nvarxy+igam],-1,1); end% if nd1 == 0% lmiterm([indx1+j 2 1 0],Cetld);% lmiterm([indx1+j 2 2 nvarxy+igam],-1,1);% else% lmiterm([indx1+j 2 2 nvarxy+igam],-1,1);% lmiterm([indx1+j 3 1 0],Cetld);% lmiterm([indx1+j 3 2 0],[D11;D21]);% lmiterm([indx1+j 3 3 nvarxy+igam],-1,1);% end enddelt = 1e-6;% Coupling LMI for k=1:NY if abs(gdat(k)) > eps lmiterm([-indx2 1 1 k],gdat(k),1); end end for k=1:NX if abs(fdat(k)) > eps lmiterm([-indx2 2 2 k+NY],fdat(k),1); end end lmiterm([-indx2 2 1 0],[eye(nx1) zeros(nx1,nx2)]); lmiterm([indx2 1 1 0],delt); lmiterm([indx2 2 2 0],delt); if SLOW Bd1 = [B11;B21]; Bd2 = [B12;B22]; C11 = Ce(1:ne1,1:nx1); C21 = Ce(ne1+1:ne,1:nx1); if PARGAM & PDGAM ggest = hdat'*gest; else ggest = gest(igam); end for k=1:NY if abs(gdat(k)) > eps lmiterm([-indx2 1 1 k],gdat(k)*Ahat/(2*maxre),1,'s'); lmiterm([-indx2 2 1 k],-gdat(k)*C11'*Ce1/(2*maxre*ggest),1); end end for k=1:NX if abs(fdat(k)) > eps lmiterm([-indx2 2 2 k+NY],1,fdat(k)*Atld11/(2*maxre),'s'); lmiterm([-indx2 2 1 k+NY],1,-fdat(k)*B11*Bd1'/(2*maxre*ggest)); if nsf > 0 lmiterm([-indx2 2 2 k+NY+NX],1,fdat(k)*Atld21/(2*maxre),'s'); lmiterm([-indx2 2 1 k+NY+NX],1,-fdat(k)*B21*Bd1'/(2*maxre*ggest)); end end end lmiterm([-indx2 2 1 0],([Bu Bd2]*[C21;Cy1])'/(2*maxre)); if PARGAM & PDGAM for k = 1:Ng if abs(hdat(k)) > eps lmiterm([-indx2 1 1 nvarxy+k],hdat(k),-Bu*Bu'/maxre); if ny1 > 0 lmiterm([-indx2 2 2 nvarxy+k],hdat(k),-Cy1'*Cy1/maxre); end end end else lmiterm([-indx2 1 1 nvarxy+igam],1,-Bu*Bu'/maxre); if ny1 > 0 lmiterm([-indx2 2 2 nvarxy+igam],1,-Cy1'*Cy1/maxre); end end endend % q grid loopend % grid point looplmis = getlmis;% Save data to file and display setup timedatesim = date; timesim = clock; ttwo = cputime; dtime = ttwo-tstart;if dtime < 60 disp(['Done. CPU Time = ' num2str(dtime) ' sec']);elseif dtime < 3600 disp(['Done. CPU Time = ' num2str(dtime/60) ' min']);else disp(['Done. CPU Time = ' num2str(dtime/3600) ' hrs!!']);end% Call MINCXtic[copt,xyopt] = mincx(lmis,cobj,[1e-2 200 1e7 10 0],xyinit,0);toc% Calculate solution time and display results.tthre = cputime;dtime1 = tthre-ttwo;dtime2 = tthre-tstart;timestr = 'Done with optimization. CPU Time (LINOBJ) = ';if dtime1 < 60 disp([timestr num2str(dtime1) ' sec']);elseif dtime2 < 3600 disp([timestr num2str(dtime1/60) ' min']);else disp([timestr num2str(dtime1/3600) ' hrs!!']);endif dtime2 < 60 disp([' CPU Time (total) = ' num2str(dtime2) ' sec']);elseif dtime2 < 3600 disp([' CPU Time (total) = ' num2str(dtime2/60) ' min']);else disp([' CPU Time (total) = ' num2str(dtime2/3600) ' hrs!!']);endif isempty(copt) disp(['Sorry. No feasible solution found.']); return;end% Form output argumentsgam = xyopt(nvardec-ngamvar+(1:ngamvar));if ngamvar == npts gamiv = getiv(fghparm);else gamiv = 1:ngamvar;endif PDGAM, gam = vpck(gam,gamiv); endxmat = [];ymat = [];for i = 1:NY ymat = [ymat;dec2mat(lmis,xyopt,i)];endfor i = 1:NX if nsf > 0 xmat = [xmat;dec2mat(lmis,xyopt,i+NY) dec2mat(lmis,xyopt,i+NY+NX)]; else xmat = [xmat;dec2mat(lmis,xyopt,i+NY)]; endendxmat = vpck(xmat,1:NX);ymat = vpck(ymat,1:NY);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -