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

📄 compile_sys_info.m

📁 CheckMate is a MATLAB-based tool for modeling, simulating and investigating properties of hybrid dyn
💻 M
字号:
function sysinfo = compile_sys_info(sys)

% Compile and/or add system information to be used in the validation
% tool.
%
% Syntax:
%   "sysinfo = compile_sys_info(sys)"
%
% Description:
%   "compile_sys_info(sys)" adds necessary `clock` and `to workspace`
%   blocks to the CheckMate model "sys" and returns pertinent system
%   information in a structure with the following fields.
%
%   * ".clk" structure containing the name, handle, and output variable of
%   the clock block.
%
%   * ".scsbList" structure array containing the name, handle, and output
%   variable of each switched continuous system block (SCSB) in the system
%
%   * ".fsmbList" structure array containing the name, handle, and output
%   variable of each finite state machine block (FSMB) in the system
%
%   * ".pthbList" structure array containing the name, handle, and output
%   variable of each polyhedral threshold block (PTHB) in the system
%
%   * ".AR" composite analysis region (AR) composed from ARs of all SCSBs
%   in the system
%
%   * ".ICS" composite initial continuous (ICS) set composed from ICS of
%   each SCSBs in the system
%
% See Also:
%   validate

% Find a 'Clock' block. Add one if not found.
clk = find_system(sys,'SearchDepth',1,'BlockType','Clock');
if isempty(clk)
  clkname = unique_name(sys,'clock');
  add_block('built-in/Clock',[sys '/' clkname]);
end

% Find Simulink handles for switched continuous system blocks (SCSB),
% finite state machine blocks (FSMB), and polyhedral threshold blocks
% (PTHB) in the CheckMate model.
scsbHandle = find_masked_blocks(sys,'SwitchedContinuousSystem');
fsmbHandle = find_masked_blocks(sys,'Stateflow');
pthbHandle = find_masked_blocks(sys,'PolyhedralThreshold');
% Find the clock block handle.
clk = find_system(sys,'SearchDepth',1,'BlockType','Clock');
clkHandle = get_param(clk{1},'Handle');

clk = check_to_ws(sys,clkHandle);
scsbList = check_to_ws(sys,scsbHandle);
fsmbList = check_to_ws(sys,fsmbHandle);
pthbList = check_to_ws(sys,pthbHandle);

% Compile list of states for each finite state machine block.
machine_id = get_machine_id(sys);
if isempty(machine_id)
  fprintf(1,['\007Error: Cannot find machine id for ''' sys '''!!!\n'])
  return
end
for k = 1:length(fsmbHandle)
  block_name = get_param(fsmbHandle(k),'Name');
  chart_id = find_chart_id(machine_id,block_name);
  if isempty(chart_id)
    error(['Cannot find chart id for ''' block_name '''.'])
    return
  end
  state_id = sf('find','all','state.chart',chart_id);
  if isempty(state_id)
    error(['No state found for FSM block ''' block_name '''.'])
  end
  parent_chart = sf('get',state_id(1),'.chart');
  transitionsAll = sf('get',parent_chart,'.transitions');
  states = {};
  for l = 1:length(state_id)
    state_number = get_state_number(state_id(l));
    states{state_number}.name = sf('get',state_id(l),'.name');
    transitions = sf('find',transitionsAll,'.src.id',state_id(l));
    states{state_number}.terminal = isempty(transitions);
  end
  fsmbList{k}.states = states;
end

sysinfo = {};
sysinfo.clk = clk;
sysinfo.scsbList = scsbList;
sysinfo.fsmbList = fsmbList;
sysinfo.pthbList = pthbList;
sysinfo.AR = get_analysis_region(scsbHandle);
sysinfo.ICS = get_initial_continuous_set(scsbHandle);

return

% ----------------------------------------------------------------------------

function machine_id = get_machine_id(sys)

% the Stateflow function returns all block names whose begining substring
% matches with the name given in sys. thus, we have to make sure that we get
% an exact match.

possible_id = sf('find','all','machine.name',sys);
machine_id = [];
for k = 1:length(possible_id)
  name = sf('get',possible_id(k),'.name');
  if strcmp(name,sys)
    machine_id = possible_id(k);
    break;
  end
end
return

% ----------------------------------------------------------------------------

function chart_id = find_chart_id(machine_id,block_name)

possible_id = sf('find','all','chart.machine',machine_id, ...
                 'chart.name',block_name);
chart_id = [];
for l = 1:length(possible_id)
  name = sf('get',possible_id(l),'.name');
  if strcmp(name,block_name)
    chart_id = possible_id(l);
    break;
  end
end
return


% ----------------------------------------------------------------------------

function state_number = get_state_number(state_id)

% We assume the label strings in the Stateflow diagram have the following 
% format.
%
%      <state_name>
%      entry: <output_variable> = <state_number>;
%

labelString = sf('get',state_id,'.labelString');
% Skip all the white spaces at the end.
k = length(labelString);
while (k >= 1) & (isspace(labelString(k)) | (labelString(k) == ';'))
  k = k - 1;
end
% Search backwards until a non-numeric character is found.
labelString = labelString(1:k);
while (k >= 1) & (labelString(k) >= '0') & (labelString(k) <= '9')
  k = k - 1;
end
labelString = labelString(k+1:length(labelString));
state_number = str2num(labelString);
return

% -----------------------------------------------------------------------------

function list = check_to_ws(sys,blkHandle)

for k = 1:length(blkHandle)
  dstk = find_dst_port(blkHandle(k),'1');
  list{k}.handle = blkHandle(k);
  list{k}.name = get_param(blkHandle(k),'Name');
  found = 0;
  for l = 1:length(dstk)
    blocktype = get_param(dstk{l}.block,'BlockType');
    if strcmp(blocktype,'ToWorkspace')
      list{k}.variable = get_param(dstk{l}.block,'VariableName');
      found = 1;
      break;
    end
  end
  if ~found
    % Add 'To Workspace' to capture the output of each block as needed 
    block_name = get_param(blkHandle(k),'Name');
    block_pos = get_param(blkHandle(k),'Position');
    width = 7*(length(block_name)+4);
    height = 20;
    xoffset = 1.2*(block_pos(3)-block_pos(1)) + 20;
    yoffset = -1.2*height;
    anchor = block_pos(1:2) + [xoffset yoffset];
    block_pos = [anchor anchor+[width height]];
    towsname = unique_name(sys,'To Workspace');
    add_block('built-in/To Workspace',[sys '/' towsname], ...
              'Position',block_pos,'VariableName',[block_name '_out'], ...
              'MaxDataPoints','inf');
    add_line(sys,[block_name '/1'],[towsname '/1'])
    list{k}.variable = [block_name '_out'];
  end
end

return

% -----------------------------------------------------------------------------

function name = unique_name(sys,prefix);

name = prefix;
count = 0;
while ~isempty(find_system(sys,'SearchDepth',1,'Name',name))
  count = count + 1;
  name = [prefix num2str(count)];
end
return

% ----------------------------------------------------------------------------

function AR = get_analysis_region(scsbH)

% Compose overall analysis region from analysis region for each SCS block.
CAR = [];
dAR = [];
for k = 1:length(scsbH)
  ARk = evalin('base',get_param(scsbH(k),'AR'));
  [CE,dE,Ck,dk] = linearcon_data(ARk);
  if ~isempty(CE) | ~isempty(dE)
    blockname = get_param(scsbH(k),'name');
    error(['Invalid analysis region for block ''' ...
           blockname '''.'])
  end
  CAR = [          CAR                zeros(size(CAR,1),size(Ck,2))
                   zeros(size(Ck,1),size(CAR,2))           Ck                ];
  dAR = [dAR; dk];		 
end
AR = linearcon([],[],CAR,dAR);
return

% ----------------------------------------------------------------------------

function X0 = get_initial_continuous_set(scsbH)

% Get initial continuous set (ICS) for each SCS block. Each ICS is a cell
% array of @linearcon objects.
ICS = {};
for k = 1:length(scsbH)
  ICS{k} = evalin('base',get_param(scsbH(k),'ICS'));
  if (length(ICS{k}) < 1)
    blockname = get_param(scsbH(k),'name');
    error(['Invalid initial continuous set specified for block ''' ...
           blockname '''.'])
  end
end

X0 = {};
idx = ones(1,length(scsbH));
stop = 0;
while ~stop
  % Compose combinations of overall ICS from ICS for each SCS block.
  ICS_CE = []; ICS_dE = [];
  ICS_CI = []; ICS_dI = [];
  for k = 1:length(scsbH)
    [CEk,dEk,CIk,dIk] = linearcon_data(ICS{k}{idx(k)});
    ICS_CE = [           ICS_CE            zeros(size(ICS_CE,1),size(CEk,2))
                    zeros(size(CEk,1),size(ICS_CE,2))           CEk               ];
    ICS_dE = [ICS_dE; dEk];		 
    ICS_CI = [           ICS_CI            zeros(size(ICS_CI,1),size(CIk,2))
                    zeros(size(CIk,1),size(ICS_CI,2))           CIk               ];
    ICS_dI = [ICS_dI; dIk];
  end
  % Put each combination into the cell array
  X0{length(X0)+1} = linearcon(ICS_CE,ICS_dE,ICS_CI,ICS_dI);

  % Increment the combination index
  k = length(scsbH);
  while (k >= 1)
    idx(k) = idx(k) + 1;
    if (idx(k) > length(ICS{k}))
      idx(k) = 1;
      k = k - 1;
    else
      k = -1;
    end
  end
  stop = (k == 0);
end

return

⌨️ 快捷键说明

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