⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pwa2hys.m

📁 由matlab开发的hybrid系统的描述语言
💻 M
📖 第 1 页 / 共 2 页
字号:
function [] = pwa2hys;
%===============================================================================
%
% Title:        pwa2hys.m                                             	
%                                                                       
% Project:      Hybrid systems   
%                                                             
% Purpose:      converts pwa approximation into hysdel code
%               
% Author:       Tobias Geyer
%                                                                       
% History:      date         subject                                       
%               2001.08.02   Initial Version   
% 				2001.12.10	 switch to disable generation of bounds
%							 (so far only implemented for DaMust)
%               2002.02.05   AdDa_2reg updated
%               2002.02.12	 0*xi and 1* are ommitted
%               2002.03.01	 handles now also the case with 1 region
%  
% Usage:        The pwa approximation 
%                 y{i} = f{i}*u + g{i}  if  Hi{i}*u <= Ki{i}  for i=1..r
%               is rewritten as HYSDEL code in a way explained in the respective
%               subfunction.
%
% Remark:       Only the hyperplanes which are seperating regions are kept for HYSDEL
%               I.e. the hyperplanes which deliminate the domain of the functions are not kept
%
% Requires:     con_list6 (from Mato)
%
% Input:        see the section 'Input variables'
%
% Output:       file containing the hysdel code
%
% Contact:      Tobias Geyer
%               Automatic Control Laboratory
%               ETH Zentrum, 
%               Zurich, Switzerland
%
%               geyer@aut.ee.ethz.ch
%
%               Comments and bug reports are highly appreciated
%
%===============================================================================


% ------------------- Input variables (adapt this part to your needs) ----------

% the names of the input and output variables
% eg. for 2 input variables x1, x2 and 1 output variable y define the 
% following: u{1}='x1', u{2}='x2'
%            y='y'
u=[]; u{1}='U4d'; u{2}='U4q'; %u{3}='Pl_z';
y=[]; y='U4m2'; 

% number of first delta-variable to be created
first_d = 1;	

% number of first z-variable to be created
first_z = 1;

% the filename of the .mat-file in which the pwa approximation is stored
in_fname = ['/home/geyer/hybrid/ABB/approx/pwa_' y '.mat'];

% the filename of the .hys-file in which the pwa approx. is written
out_fname = ['/home/geyer/hybrid/ABB/mld/' y '.hys'];

% shift upper and lower bounds in AD and DA section by Eps
Eps = 1e-2;

% switch to disable the generation of the bounds of the AD and DA sections
% (they are not needed anymore in the new verions of HYSDEL...)
do_bounds = 0;		% 0=disabled, 1=enabled

% ------------------- don't change the rest of the file ------------------------


% ------------------- interface to Gianni's pwa approximation ------------------

% run Gianni's code
eval(['load ' in_fname]);	% load Gianni's pwa approximation
% this gives: estimated_regions: est{i,1} <= est{i,2} and
%             theta_est

%estimated_regions = estimated_regions_sim;

regions = size(estimated_regions, 1);
Hi = []; 
Ki = [];
for i = 1:regions
	Hi{i} = estimated_regions{i,1};
	Ki{i} = estimated_regions{i,2};
end;
clear estimated_regions;
% this gives: Hi{i}*x <= Ki{i}

Po = theta_est;
clear theta_est



% ------------------- test integrity of input data -----------------------------
nu = size(u, 2);

% is the number of input variables correct?
nu_nesc = size( Hi{1}, 2 );
if nu ~= nu_nesc
	error(['Number of specified input variables is wrong. Expected '...
	num2str(nu_nesc) ' input variables.']);
end;



% --------------------- preliminary stuff --------------------------------------

% run Mato's code and get neighbouring edges of hyberplanes
if regions >= 2
	[BC, Hn, Kn] = con_list6(Hi, Ki);
	% this gives e.g.: 
	% BC{1} = [2 3 0 0 0]'
	% for region #1: 1st hyperplane is adjacent to region #2
	%                2nd hypberplane is adjacent to region #3
	%                3rd, 4th and 5th hypperplanes have no neighbours
else
	BC = []; Hn = []; Kn = [];
end;

% prepare the fields
AD = [];
DA = [];
MUST = [];



% -------------------- decide which conversion function to use -----------------

if regions > 2
		
	% old approach with one delta-variable for every hyperplane
    %[AD, DA, num_d] = AdDa(Hi, Ki, Po, BC, regions, y, u, nu, first_d, first_z, Eps);
    %disp('used AD - DA approach (one delta-variable for every hyperplane)')
	
	% new approach with one delta-variable for every region (according to BeMo99)
	[DA, MUST, num_d] = DaMust(Hi, Ki, Po, BC, regions, y, u, nu, first_d, first_z, Eps, do_bounds);
    disp('used DA - MUST approach (one delta-variable for every region)')	
    
elseif regions == 2
   
   	[AD, DA, num_d] = AdDa_2reg(Hi, Ki, Po, BC, regions, y, u, nu, Eps, do_bounds);	
	disp('used AD - DA approach for 2 regions (one delta-variable)')
   
else
	
	[MUST, num_d] = one_reg(Po{1}, y, u, nu);
    disp('used MUST approach for 1 region (no delta-variable)')	
	
end;



% ----------------- store the AUX, DA, CONTINUOUS and MUST sections -------------
tab = '    ';

% open file to write HYSDEL code
fid = fopen(out_fname, 'wt');

if regions > 1

	% write AUX section
	fprintf(fid, [tab 'AUX {\n']);

	fprintf(fid, [tab tab 'BOOL ']);
	if num_d > 1
		for i = 1:num_d-1,fprintf(fid, [y '_d' num2str(first_d+i-1) ', ']); end;
		fprintf(fid, [y '_d' num2str(first_d+num_d-1) ';\n']);
	else
		fprintf(fid, [y, '_d;\n']);
	end;

	fprintf(fid, [tab tab 'REAL ']);
	if num_d == 1
		fprintf(fid, [y '_z;\n']);
	else
		fprintf(fid, [y '_z, ']);
		for i = 1:num_d-1, fprintf(fid, [y '_z' num2str(first_z+i-1) ', ']); end;
		fprintf(fid, [y '_z' num2str(first_z+num_d-1) ';\n']);
	end;

	fprintf(fid, [tab '}\n\n']);

	% write AD section
	AD_length = size(AD, 2);
	if AD_length > 0
		fprintf(fid, [tab 'AD {\n']);
		for i = 1:AD_length, fprintf(fid, [tab tab AD{i} '\n']); end;
		fprintf(fid, [tab '}\n\n']);
	end;

	% write DA section
	fprintf(fid, [tab 'DA {\n']);
	for i = 1:regions, fprintf(fid, [tab tab DA{i} '\n']); end;
	fprintf(fid, [tab '}\n\n']);

	% write CONTINUOUS section
	%fprintf(fid, [tab 'CONTINUOUS {\n']);
	%fprintf(fid, [tab tab y ' = ']);
	%if num_d == 1
	%	fprintf(fid, [y '_z;\n']);
	%else
	%	for i = 1:num_d-1, fprintf(fid, [y '_z' num2str(first_z+i-1) '+']); end;
	%	fprintf(fid, [y '_z' num2str(first_z+num_d-1) ';\n']);
	%end;
	%fprintf(fid, [tab '}\n\n']);
	
end;

% write MUST section
MUST_length = size(MUST, 2);
if MUST_length > 0
	fprintf(fid, [tab 'MUST {\n']);
	for i = 1:MUST_length, fprintf(fid, [tab tab  MUST{i} '\n']); end;
	fprintf(fid, [tab '}\n']);
end;

% close file
fclose(fid);

%
disp(['pwa approximation over ' num2str(regions) ' regions.'])
disp(['wrote ' out_fname ' successfully.'])
disp(' ')







% ==============================================================================
% ==================== subfunctions ============================================
% ==============================================================================

% -------------------- DaMust --------------------------------------------------
function [DA, MUST, num_d] = DaMust(Hi, Ki, Po, BC, regions, y, u, nu, first_d, first_z, Eps, do_bounds);
%
% regions > 2
% the conversion is done according to BeMo99 p. 411,412
%
% i.e.  AUX {
%           BOOL Y_d1, ... Y_dr;	
%           REAL Y_z, Y_z1, ... Y_zr;
%       }
%       DA {
%           Y_z1 = {IF Y_d1 THEN f{1}*un + g{1} [M1, m1, 0]};	  
%           ...
%           Y_zr = {IF Y_dr THEN f{r}*un + g{r} [Mr, mr, 0]};
%       }
%       MUST {
%           Hi{1}*u - Ki{1} - N1 + N1*d1 <= 0;
%           ...
%           Hi{r}*u - Ki{r} - Nr + Nr*dr <= 0;
%           Y_d1 + ... + Y_dr = 1;
%           Y_z = Y_z1 + ... + Y_zr;
%       }
%
% where r = number of regions

% create DA entries
for r = 1:regions
	hi = Hi{r}; ki = Ki{r};
	po = Po{r};
	
	% add ... = {IF .. THEN 
	da = [y '_z' num2str(first_z+r-1) ' = {IF ' y '_d' num2str(first_d+r-1) ' THEN '];

	% add polynom
	for i = 1:nu
		if (po(i) >= 0) & (i > 1), da = [da '+']; end;
		da = [da num2str(po(i)) '*' u{i} ' '];
	end;
	if po(i+1) >= 0, da = [da '+']; end;
	da = [da num2str(po(i+1))];
		
	if do_bounds
		% get upper and lower bound 
		% i.e. evaluate pwa approximation po over all regions
		[up_bound, lo_bound] = bounds(po(1:nu), po(nu+1), Hi, Ki, regions);
		up_bound = up_bound + Eps;
		lo_bound = lo_bound - Eps;

		% add bounds
		da = [da ' [' num2str(up_bound) ', '];
		da = [da num2str(lo_bound) ', 0]'];
	end;
		
	% finish line
	da = [da '};'];
	
	% store new DA line
	DA{r} = da;	
end;


% create MUST section
m = 1;	% line counter of MUST section
for r = 1:regions
	bc_curr = BC{r};
	hi = Hi{r};
	ki = Ki{r};

	for c = 1:length(bc_curr)
		if ~bc_curr(c) == 0
			% we have found a hyperplane seperating two neighbouring regions
			% we will rewrite this hyperplane into the MUST section
			
			MUST{m} = '';
			
			% ex.: '-6.3511*I2d -2.6294*I2q '
			first = 1;
			for i = 1:nu
				if hi(c,i) ~= 0
					if (hi(c,i) >= 0) & ~first, MUST{m} = [MUST{m} '+']; end;
					if hi(c,i) == (-1), 
						MUST{m} = [MUST{m} '-'];
					elseif hi(c,i) ~= 1, 
						MUST{m} = [MUST{m} num2str(hi(c,i)) '*']; 
					end;
					MUST{m} = [MUST{m} u{i} ' '];
					first = 0;
				end;
			end;

			% ex.: '+5.0265'
			if -ki(c) >= 0, MUST{m} = [MUST{m} '+']; end;
			MUST{m} = [MUST{m} num2str(-ki(c)) ' '];
								
			% get upper bound 
			% i.e. evaluate hyperplane hp = hi(c,:) - ki(c) over all regions
			[hp_max, hp_min] = bounds(hi(c,:), -ki(c), Hi, Ki, regions);
			hp_max = hp_max + Eps;

			% ex.: ' -100'
			if -hp_max >= 0, MUST{m} = [MUST{m} '+']; end;
			MUST{m} = [MUST{m} num2str(-hp_max) ' '];
			
			% ex.: ' +100*(REAL d2) <= 0;'
			if hp_max >= 0, MUST{m} = [MUST{m} '+']; end;
			MUST{m} = [MUST{m} num2str(hp_max) '*(REAL ' y '_d' num2str(first_d+r-1) ') <= 0;'];
			
			% increase the line counter of the MUST section
			m = m+1;
		
		end;
	end;
		
end;

% create equality constraints in MUST section
% first: d1+d2+...dn - 1 <= 0;
MUST{m} = '';
for i = first_d:first_d+regions-2
	MUST{m} = [MUST{m} '(REAL ' y '_d' num2str(i) ') +'];
end;
MUST{m} = [MUST{m} '(REAL ' y '_d' num2str(i+1) ') -1 <= 0;'];
m = m+1;

% then: -d1-d2-...-dn + 1 <= 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -