140 lines
6.7 KiB
Matlab
140 lines
6.7 KiB
Matlab
% Copyright 2024 Volvo Car Corporation
|
||
% Licensed under Apache 2.0.
|
||
|
||
function apiData = parseCoreIdentifiers(model)
|
||
% parseCoreIdentifiers Find all Core Identifier blocks in model
|
||
% returns a structs with identifier information
|
||
%
|
||
% See also parseModelInfo
|
||
|
||
apiData = struct();
|
||
% Which types of identifier shall be search for
|
||
id_names = {'Events', 'IUMPR', 'FIDs', 'Ranking', 'TstId','TstId','Ranking'};
|
||
idFilenames = {'CoreIdNameDefinition_EventIDs.csv',
|
||
'CoreIdNameDefinition_IUMPR.csv',
|
||
'CoreIdNameDefinition_FunctionIDs.csv',
|
||
'CoreIdNameDefinition_Ranking.csv',
|
||
'CoreIdNameDefinition_Mode$06.csv',
|
||
'CoreIdNameDefinition_Mode$06.csv',
|
||
'CoreIdNameDefinition_Ranking.csv'};
|
||
id_names2Filenames = containers.Map(id_names, idFilenames);
|
||
% The name of the blocks using the above identifiers
|
||
blk_names = {'^Dem_SetEvent.*', '^Dem_RepIUMPR.*', '^FiM_GetFunction.*', ...
|
||
'^bdcore_RVLG_SetRV.*', '^bdsrv_S06_SetTestResult.*', ...
|
||
'^(Vcc|Dem)_SetDTR', '^(Vcc|Vc)_SetRanking'};
|
||
% Which port of the block is the identifier connected to
|
||
blk_port_nbr = [1,1,1,1,1,1,1];
|
||
%which block data shall be stored per block.
|
||
info = {'description', 'type', 'unit', 'offset', 'lsb', 'min', 'max', 'class'};
|
||
|
||
for blk_type_idx=1:length(id_names)
|
||
% remove name search once all Core blocks are replaced with ones
|
||
% with correct mask names!
|
||
name_search = find_system(model, 'FindAll', 'on', 'RegExp', 'on', 'LookUnderMasks', 'all', 'blocktype', 'SubSystem', 'Name', blk_names{blk_type_idx});
|
||
msk_search = find_system(model, 'FindAll', 'on', 'RegExp', 'on', 'LookUnderMasks', 'all', 'MaskType', blk_names{blk_type_idx});
|
||
search = union(name_search, msk_search);
|
||
if ~isfield(apiData, id_names{blk_type_idx})
|
||
apiData.(id_names{blk_type_idx}) = struct();
|
||
end
|
||
for i=1:length(search)
|
||
%Find source block for EventID
|
||
ports = get_param(search(i), 'PortHandles');
|
||
l_h = get(ports.Inport(blk_port_nbr(blk_type_idx)), 'line');
|
||
blk_h = get_param(l_h,'SrcBlockHandle');
|
||
block_name = get_blk_name(model, blk_h);
|
||
if ~isempty(block_name)
|
||
%TODO: g<>r API_blk till en cell array av structar
|
||
api_blk_tmp = [get_param(search(i), 'Parent') '/' get_param(search(i), 'Name')];
|
||
tmpStruct.path = api_blk_tmp;
|
||
tmpStruct.config = getCodeSwitches(api_blk_tmp);
|
||
if isfield(apiData.(id_names{blk_type_idx}), block_name)
|
||
apiData.(id_names{blk_type_idx}).(block_name).API_blk = [apiData.(id_names{blk_type_idx}).(block_name).API_blk ...
|
||
tmpStruct];
|
||
else
|
||
%APIData.(id_names{blk_type_idx}).(block_name) = struct();
|
||
apiData.(id_names{blk_type_idx}).(block_name).API_blk{1} = tmpStruct;
|
||
end
|
||
%Get targetlink block data
|
||
apiData.(id_names{blk_type_idx}).(block_name).blk_name = get(blk_h, 'name');
|
||
apiData.(id_names{blk_type_idx}).(block_name).subsystem = get(blk_h, 'parent');
|
||
apiData.(id_names{blk_type_idx}).(block_name).API_blk_type = get(search(i), 'MaskType');
|
||
for idx=1:length(info)
|
||
if strcmp(info{idx}, 'description')
|
||
apiData.(id_names{blk_type_idx}).(block_name).(info{idx}) = getCsvDescription(block_name, id_names2Filenames(id_names{blk_type_idx}));
|
||
else
|
||
apiData.(id_names{blk_type_idx}).(block_name).(info{idx}) = chkNan(tl_get(blk_h, ['output.' info{idx}]));
|
||
end
|
||
end
|
||
else
|
||
disp(['Warning: model ' model ' contains illegal identifier blocks']);
|
||
if isfield(apiData.(id_names{blk_type_idx}), 'IllegalBlk')
|
||
apiData.(id_names{blk_type_idx}).IllegalBlk.API_blk = [apiData.(id_names{blk_type_idx}).IllegalBlk.API_blk...
|
||
{[get_param(search(i), 'Parent') '/' get_param(search(i), 'Name')]}];
|
||
else
|
||
apiData.(id_names{blk_type_idx}).IllegalBlk.API_blk = [get_param(search(i), 'Parent') '/' get_param(search(i), 'Name')];
|
||
end
|
||
apiData.(id_names{blk_type_idx}).IllegalBlk.API_blk_type = get(search(i), 'MaskType');
|
||
apiData.(id_names{blk_type_idx}).IllegalBlk.description = ['Illegal block ID!: ' get_param(search(i), 'Parent') '/' get_param(search(i), 'Name')];
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
function blk_name = get_blk_name(model, block_h)
|
||
type = get_param(block_h,'MaskType');
|
||
if ~isempty(strfind(type,'NamedConstant'))
|
||
blk_name_tmp = get_param(block_h,'MaskValues');
|
||
blk_name = blk_name_tmp{1};
|
||
elseif ~isempty(strfind(type,'From'))
|
||
blk_tag = get_param(block_h,'GotoTag');
|
||
blk_to = find_system(model, 'FindAll', 'on', 'LookUnderMasks', 'all', 'BlockType', 'Goto', 'GotoTag', blk_tag);
|
||
ports = get_param(blk_to, 'PortHandles');
|
||
l_h = get(ports.Inport(1), 'line');
|
||
blk_h = get_param(l_h,'SrcBlockHandle');
|
||
blk_name = get_blk_name(model, blk_h);
|
||
else
|
||
o_name = tl_get(block_h,'output.name');
|
||
if ~isempty(o_name )
|
||
[tok mat] = regexp(model ,'(.+?)_Tmp$', 'tokens');
|
||
if mat > 0
|
||
model_tmp = tok{1};
|
||
else
|
||
model_tmp = model;
|
||
end
|
||
tmp_name = regexprep(o_name, '\$N', model_tmp);
|
||
blk_name = regexprep(tmp_name, '\$B', get(block_h,'name'));
|
||
else
|
||
blk_name = '';
|
||
end
|
||
end
|
||
end
|
||
|
||
function res = chkNan(value)
|
||
% Function which replaces NaN or empty fields with '-'
|
||
if ~ischar(value)
|
||
if isnan(value)
|
||
res = '-';
|
||
elseif isempty(value)
|
||
res = '-';
|
||
else
|
||
res = num2str(value);
|
||
end
|
||
else
|
||
res = value;
|
||
end
|
||
end
|
||
|
||
function description = getCsvDescription(blockName, filename)
|
||
% getCsvDescription Get description parametres from CSV files.
|
||
txt = readtable(filename);
|
||
% Using table column names is unsafe as the first row can become the
|
||
% column names. Eg. txt.Var1 can become txt.Models.
|
||
% Using columns instead.
|
||
blockNameColumn = 2;
|
||
descriptionColumn = 3;
|
||
description = txt{strcmp(txt{:, blockNameColumn}, blockName), descriptionColumn};
|
||
if isempty(description)
|
||
description = 'Description missing';
|
||
end
|
||
end
|