diff --git a/code/classes/SCDclass_expcode.m b/code/classes/SCDclass_expcode.m index 10eac0c227b80c33ab967a085a7ed28415a1a8ac..6746b24f6a1b274ab3d59b602143d0f9763905dd 100644 --- a/code/classes/SCDclass_expcode.m +++ b/code/classes/SCDclass_expcode.m @@ -506,6 +506,22 @@ classdef SCDclass_expcode end end + function printMARTe2taskconfig(obj, shot, varargin) + p=inputParser; + % if a model name is given, operations will be performed + % only on it, otherwise they will be performed on all + % configured models + addParameter(p,'model','',@(x) ischar(x)); + parse(p,varargin{:}); + + if(isempty(p.Results.model)) + obj.taskcontainer.modeltogenerate='all'; + else + obj.taskcontainer.modeltogenerate=p.Results.model; + end + obj.taskcontainer.printMARTe2taskconfig(shot); + end + function printMARTe2parconfig(obj, shot, varargin) p=inputParser; % if a model name is given, operations will be performed @@ -522,6 +538,7 @@ classdef SCDclass_expcode obj.mdscontainer.printMARTe2parconfig(shot); end + function printMARTe2wgbusconfig(obj, shot, ddname, busname, frequency) fprintf("+MDSWavegen_%s = {\n", busname); fprintf(" Class = MDSWavegen\n"); diff --git a/code/classes/SCDclass_task.m b/code/classes/SCDclass_task.m index 145d698665226195ae394070d582069aff107264..b95f6c0e0938a984b56a973091cd73af3f685962 100644 --- a/code/classes/SCDclass_task.m +++ b/code/classes/SCDclass_task.m @@ -20,6 +20,7 @@ classdef SCDclass_task < matlab.mixin.Heterogeneous value % value from MDS+ getcommand % full command for getting the value (callable by matlab eval) + marteclassname % marte class name end properties @@ -65,6 +66,18 @@ classdef SCDclass_task < matlab.mixin.Heterogeneous name=obj.modelname; end + function [mdsserver] = getMDSserver(obj) + mdsserver = obj.mdsserver; + end + + function [mdstree] = getMDStree(obj) + mdstree = obj.mdstree; + end + + function str = genMARTe2MDSsourcestr(obj) + str = sprintf(' +Connection_%s_%s = {\n Class=MDSObjConnection\n Server=%s\n Tree=%s',obj.mdsserver,obj.mdstree,obj.mdsserver,obj.mdstree); + end + end % Not abstract methods common to all child classes @@ -118,6 +131,39 @@ classdef SCDclass_task < matlab.mixin.Heterogeneous end + methods(Access=protected) + + function entrystring = genMARTe2entrycommon(obj, shot) + obj=obj.actualizetdiexpr(shot); + %entrystring = sprintf('+%-50s = { Class=%-30s Path=%-40s',obj.gettargetparammarte,obj.marteclassname,obj.tdiexprused); + entrystring = sprintf('+%-50s = { Class=%-30s Path=%-40s',obj.id,obj.marteclassname,obj.genMARTe2MDStdiexpression); + end + + function str = genMARTe2MDStdiexpression(obj) + % Duplicate first backslash +% if(obj.tdiexprused(1)=='\' && not(obj.tdiexprused(2)=='\')) +% martetdi=['\' obj.tdiexprused]; +% else +% martetdi=obj.tdiexprused; +% end + % Duplicate backslashes + martetdi=strrep(obj.tdiexprused, '\', '\\'); + %substitute every " with ' + martetdi=strrep(martetdi, '"', ''''); + %put double string quota + martetdi=['"' martetdi '"']; + str=martetdi; + end + + function obj=actualizetdiexpr(obj, shot) + if(shot==-1) + obj.tdiexprused=obj.tdiexprmodel; + else + obj.tdiexprused=obj.tdiexprshot; + end + end + + end % Abstract method actually implemented by child classes methods (Abstract) @@ -133,8 +179,8 @@ classdef SCDclass_task < matlab.mixin.Heterogeneous % and tree opened [obj, value] = getdata(obj, shot) - % Generate C++ code - %gencode(obj) + % Generate MARTe2 configuration entry + entrystring = genMARTe2entry(obj, shot) % Prints the parameter info summary printinfo(obj) diff --git a/code/classes/SCDclass_taskcontainer.m b/code/classes/SCDclass_taskcontainer.m index fecf97020f2e39c5c42422e830df1048d545f2a4..d01a012e305027fffd2f985f4aca47d113b23d6a 100644 --- a/code/classes/SCDclass_taskcontainer.m +++ b/code/classes/SCDclass_taskcontainer.m @@ -9,6 +9,7 @@ classdef SCDclass_taskcontainer numtasks % number of configured tasks tasks % tasks list modeltoexecute % model name whose tasks will be executed 'all' for all + modeltogenerate % model name whose tasks will be generate 'all' for all, TODO: check overlap with the previous end methods @@ -99,8 +100,56 @@ classdef SCDclass_taskcontainer end - + function printMARTe2taskconfig(obj, shot) + switch obj.modeltogenerate + case 'all' + iorder = getParamsServerTreeOrder(obj); % order entries following mdsserver, mdstree order + prevServer = ''; % init + + % Header for MDS for loader + loaderStr = sprintf('\n\n+MDSTasks = {\n Class=MDSObjLoader\n Shot=%d\n',shot); + fprintf("%s",loaderStr); + + for ii=1:obj.numtasks + mytask = obj.tasks(iorder(ii)); + + currentServer = mytask.getMDSserver; + + % generate header for MDSsource if necessary + if ~strcmp(currentServer,prevServer) %if a new server needs to be opened + if ii~=1, fprintf(' }\n'), end % close bracket for previous one + % print new source header + fprintf("%s\n",mytask.genMARTe2MDSsourcestr); + end + prevServer = currentServer; + % generate data source entry + str = mytask.genMARTe2entry(shot); + fprintf(" %s\n",str); + end + fprintf(" }\n}\n\n"); + + otherwise + for ii=1:obj.numparams + if(strcmp(obj.modeltogenerate,obj.tasks(ii).getmodelname)) + str=obj.tasks(ii).genMARTe2entry(shot); + fprintf(" %s\n",str); + end + end + end + end + + function iorder = getParamsServerTreeOrder(obj) + % find server-tree order of parameters + mdsservertree = cell(numel(obj.tasks),2); + for ii=1:numel(obj.tasks) + mdsservertree{ii,1} = obj.tasks(ii).getMDSserver; + mdsservertree{ii,2} = obj.tasks(ii).getMDStree; + end + [~,iorder] = sortrows(mdsservertree); + end + + end end diff --git a/code/classes/SCDclass_taskmdscheckbusnames.m b/code/classes/SCDclass_taskmdscheckbusnames.m index 757b859db8fa42dc32bf96ad4e020b4cfe2c7c78..5755ccbaa00d35a387f11e250842dcc0508a5d75 100644 --- a/code/classes/SCDclass_taskmdscheckbusnames.m +++ b/code/classes/SCDclass_taskmdscheckbusnames.m @@ -3,13 +3,17 @@ classdef SCDclass_taskmdscheckbusnames < SCDclass_task % of a Simulink bus against the list names given by the tdi expression % some rules apply: % 1) : in MDS+ fields are subsituted by _ - % 2) check is performed up to the minimum number of elemes ether if the + % 2) check is performed up to the minimum number of elemes either if the % MDS+ node or in the simulink one. % if MDS+ begins with a number, a leading 's' is added to its name % if MDS+ name is empty the check is skipped (Q: is it safe ?, at least not on -1 shot!) + % for being MARTe compatible the list of channels names are retrieved + % from MDS+ with the TDI consolidate() function (which must be present + % server side) and all names are transferred as a single long string properties modelbus + nelems end methods @@ -17,9 +21,13 @@ classdef SCDclass_taskmdscheckbusnames < SCDclass_task function obj=SCDclass_taskmdscheckbusnames(id, varargin) obj@SCDclass_task(id, varargin); obj.cparser.addRequired('modelbus',@(x) ischar(x)); + obj.cparser.addRequired('nelems',@(x) (isnumeric(x) && x>0)); + obj=obj.parseconstructorcommon(id, varargin); - obj.modelbus=obj.cparser.Results.modelbus; + obj.modelbus=obj.cparser.Results.modelbus; + obj.nelems=obj.cparser.Results.nelems; obj.classname=mfilename; + obj.marteclassname='MDSParBusChecker'; end function init(obj, shot) @@ -34,19 +42,27 @@ classdef SCDclass_taskmdscheckbusnames < SCDclass_task d=Simulink.data.dictionary.open(sprintf('%s',obj.datadictionary)); dd=getSection(d, 'Design Data'); - busElems=dd.getEntry(obj.modelbus).getValue.Elements; - %assert(numel(busElems)==numel(value), 'SCDclass_mdscheckbus: Number of elements must match.'); - - lastcheck=min(numel(busElems), numel(value)); + %% MDS+ string cell array buildup from the consolidated full string + mdsnamelength = numel(value) / obj.nelems; + cnt=1; + for ii=1:numel(obj.nelems) + mdsnames{ii}=value(cnt:cnt+mdsnamelength-1); + cnt=cnt+mdsnamelength; + end + %% Original version, not compatible with MARTe + % (C++ MDS+ thin client used there desn't support the retrieval + % of array of strings) - for ii=1:lastcheck - if numel(char(value{ii}))==0 || numel(strfind(char(value{ii}),' '))==numel(char(value{ii})) - continue + %assert(numel(busElems)==numel(value), 'SCDclass_mdscheckbus: Number of elements must match.'); + lastcheck=min(numel(busElems), numel(mdsnames)); + for ii=1:lastcheck + if numel(char(mdsnames{ii}))==0 || numel(strfind(char(mdsnames{ii}),' '))==numel(char(mdsnames{ii})) + continue end - strsrc=upper(deblank(strrep(char(value{ii}),':','_'))); + strsrc=upper(deblank(strrep(char(mdsnames{ii}),':','_'))); if(isstrprop(strsrc(1),'digit')) strsrc=['S' strsrc]; end @@ -54,7 +70,9 @@ classdef SCDclass_taskmdscheckbusnames < SCDclass_task strdst=upper(deblank(busElems(ii).Name)); assert(strcmp(strsrc,strdst), 'SCDclass_mdscheckbus: names mismatching, MDS+ name: ''%s'', Bus name: ''%s''', strsrc, strdst); - end + end + + end %function term(obj, shot) @@ -62,8 +80,7 @@ classdef SCDclass_taskmdscheckbusnames < SCDclass_task %end function [obj, value] = getdata(obj,shot) - obj=obj.actualizegetcmd('mdsvalue(''%s'')', shot); - + obj=obj.actualizegetcmd('mdsvalue(''consolidate(%s)'')', shot); value=eval(obj.getcommand); end @@ -72,6 +89,23 @@ classdef SCDclass_taskmdscheckbusnames < SCDclass_task fprintf(' Checked model bus: %s\n',obj.modelbus); end + function entrystring = genMARTe2entry(obj, shot) + mdsconnect(obj.mdsserver); + mdsopen(obj.mdstree, shot); + [obj,value]=obj.getdata(shot); + entrystring=obj.genMARTe2entrycommon(shot); + entrystring=[entrystring 'NElems = ' num2str(obj.nelems) ' ']; + entrystring=[entrystring 'Against = "' value]; + entrystring=[entrystring '" }']; + end + + + end + + methods(Access=private) + + + end end diff --git a/code/classes/SCDclass_taskmdsloadprevADC.m b/code/classes/SCDclass_taskmdsloadprevADC.m index 817d0e7607e02b5beb9c67c04d9f0af41129f8db..8720ad93db03bfeb2e69eb0db7468b2ef2c4ff5e 100644 --- a/code/classes/SCDclass_taskmdsloadprevADC.m +++ b/code/classes/SCDclass_taskmdsloadprevADC.m @@ -50,6 +50,12 @@ classdef SCDclass_taskmdsloadprevADC < SCDclass_task fprintf(' Init model bus: %s, node: %d, ws base struct: %s\n',obj.modelbus, obj.node, obj.workspacedatabasestructure); end + + function entrystring = genMARTe2entry(obj, shot) + % TODO: this is a workaround which works by chance, need a more accurate fix + entrystring = ''; + end + end methods(Access = private)