diff --git a/test/simulink_codegen_tests/confsettingsmodformmi.txt b/build/simulink_codegen/confsettingsmodformmi.txt similarity index 100% rename from test/simulink_codegen_tests/confsettingsmodformmi.txt rename to build/simulink_codegen/confsettingsmodformmi.txt diff --git a/test/simulink_codegen_tests/ert_shrlib_scd.tlc b/build/simulink_codegen/ert_shrlib_scd.tlc similarity index 100% rename from test/simulink_codegen_tests/ert_shrlib_scd.tlc rename to build/simulink_codegen/ert_shrlib_scd.tlc diff --git a/test/simulink_codegen_tests/ert_unix.tmf b/build/simulink_codegen/ert_unix.tmf similarity index 100% rename from test/simulink_codegen_tests/ert_unix.tmf rename to build/simulink_codegen/ert_unix.tmf diff --git a/test/simulink_codegen_tests/export_shrlib_def_scd.tlc b/build/simulink_codegen/export_shrlib_def_scd.tlc similarity index 100% rename from test/simulink_codegen_tests/export_shrlib_def_scd.tlc rename to build/simulink_codegen/export_shrlib_def_scd.tlc diff --git a/code/classes/SCD.m b/code/classes/SCD.m index 024d86cf952a97d6eeb20d574f462c4e6c7589ed..a3f919f7bac031b6f18940646423b4345d538f89 100644 --- a/code/classes/SCD.m +++ b/code/classes/SCD.m @@ -1,6 +1,12 @@ classdef SCD - % main interface class just to get expcode - % E = SCD.load(expcode); + % main interface class for interacting with SCD expcodes + % + % H = SCD.load(expcode); % loads the obj for a desired expcode + % H = SCD.init(expcode,shot); % does load, setup, callinits, actualize + % + % C = SCD.getexpcodecontainer; % get expcode container + + properties (Access = private) E % expcode SCDexps % expcode code container @@ -14,16 +20,22 @@ classdef SCD SCDconf_setSIMconf; % set conf for simulation end + function H=setup(expcode) + % load and setup + H=SCD.load(expcode); + H.setup; + end + function H=init(expcode,shot) + assert(nargin==2,'must supply 2 inputs to init(expcode,shot)') H=SCD.load(expcode); H.setup; - H.callinits(shot); + H.callinits; H.actualize(shot); end function help() - SCDexps = SCD.getexpcodecontainer(); - SCDexps.printexpcodes; + help(mfilename); end function list() diff --git a/code/classes/SCDclass_algo.m b/code/classes/SCDclass_algo.m index d31df20d1abe6c3bcf4d39edd353daa7d8dd7123..fab4af62b916058d285aae8c87524160d145768c 100644 --- a/code/classes/SCDclass_algo.m +++ b/code/classes/SCDclass_algo.m @@ -221,13 +221,13 @@ classdef SCDclass_algo targetworkspace = 'global'; % default: global workspace (assigninGlobal) end - if ~iscell(targetstruct) + if ~iscell(targetstruct) && ~isempty(targetstruct) targetstruct = {targetstruct}; end if(~isempty(obj.stdinits)) for ii=1:numel(obj.stdinits) - if contains(obj.stdinits{ii}{2},targetstruct) + if ~isempty(targetstruct) && contains(obj.stdinits{ii}{2},targetstruct) warning('SCDclass_algo:addfpinitfcn','A function defining the structure %s has already been added, ignoring.\d',targetstruct) return end @@ -251,7 +251,7 @@ classdef SCDclass_algo end - function callinits(obj,shot) + function callinits(obj) % call initialization functions that set fixed parameters if ~isempty(obj.stdinits) for ii=1:numel(obj.stdinits) @@ -269,9 +269,7 @@ classdef SCDclass_algo initcmd=sprintf('%s(obj);', initfunction); [value{1:nout}] = eval(initcmd); elseif isa(initfunction,'function_handle') - if nargin(initfunction)==2 - argins = {obj,shot}; - elseif nargin(initfunction)==1 + if nargin(initfunction)==1 argins={obj}; elseif nargin(initfunction)==0 argins = {}; @@ -313,6 +311,9 @@ classdef SCDclass_algo sim(obj.modelname); end + function open(obj) + open(obj.modelname) + end end end diff --git a/code/classes/SCDclass_expcode.m b/code/classes/SCDclass_expcode.m index f3e1474af4fce2c9155ac74585b92c77250cb562..3bf3c93fd90f9321e6d2f3f5485f8bdbc6e4c9c0 100644 --- a/code/classes/SCDclass_expcode.m +++ b/code/classes/SCDclass_expcode.m @@ -1,8 +1,18 @@ classdef SCDclass_expcode - %A SCD expcode object - % This object is a virgin SCD expode - % its constructor builds an expode - % with all templates algorithms + %An SCD expcode object + % + % Methods: + % .open: Open baseline .slx model + % open(N): Open node N + % open(N,M): Open thread M of node N + % .build, build(N), build(N,M): Generate C code for node N, thread M + % .compile, compile(N), compile(N,M): Compile Simulink model for node N, thread M) + % .close_all: Close all Simulink block diagrams + % + % .printinfo: Print information about components of this expcode + % .printtasks: Print configured tasks + % .printwavegens: Print configured wavegen signals + %. properties (Access = private) activenodes % numerical list of configured active nodes @@ -30,6 +40,9 @@ classdef SCDclass_expcode end methods(Static) + function help + help(mfilename) + end function node = defaultnode(nodenr) node01.active = 0; @@ -339,7 +352,8 @@ classdef SCDclass_expcode nodestr=sprintf('node%02d',inode); obj.nodes(inode).varalgo(icpu) = varalgo; obj.nodes(inode).wrapper{icpu} = wrappername; - obj.nodes(inode).cpuactive(icpu) = 1; + obj.nodes(inode).cpuactive(icpu) = true; + obj.nodes(inode).active = true; %% save in wrapper list tempwrapper=cell(10,1); @@ -463,7 +477,7 @@ classdef SCDclass_expcode % parameters import obj.mdscontainer=obj.mdscontainer.importmdsobjects(expcode.mdscontainer); end - + function setup(obj) % This function sets up the TCV Simulink model % to simulate this experimental code. @@ -521,7 +535,7 @@ classdef SCDclass_expcode fprintf('Actualizing expcode %d, ''%s'', configuring wavegens ...\n',obj.maincode,obj.name); obj.actualizewavegens(shot); end - + function printparameters(obj) obj.mdscontainer.printparameters; end @@ -542,7 +556,7 @@ classdef SCDclass_expcode function actualizewavegens(obj,shot) obj.mdscontainer.modeltoactualize=obj.modeltoactualize; obj.mdscontainer.actualizewavegens(shot); - end + end function printinits(obj) if(~isempty(obj.stdinits)) @@ -551,8 +565,8 @@ classdef SCDclass_expcode end end end - - function callinits(obj,~) + + function callinits(obj) if(~isempty(obj.algoobjlist)) for ii=1:numel(obj.algoobjlist) if nargin==1 @@ -597,11 +611,12 @@ classdef SCDclass_expcode end obj.mdscontainer.printMARTe2parconfig(shot); end - + function printMARTe2wgbusconfig(obj, shot, ddname, busname, frequency) fprintf("+MDSWavegen_%s = {\n", busname); fprintf(" Class = MDSWavegen\n"); - fprintf(" Shot = %d\n",shot); + %fprintf(" Shot = %d\n",shot); + fprintf(" Shot = MDSSRCSHOT\n"); fprintf(" Frequency = %.2f\n",frequency); dim=obj.mdscontainer.printMARTe2wgbusconfig(shot, ddname, busname); fprintf(" Signals = {\n"); @@ -644,12 +659,8 @@ classdef SCDclass_expcode nodeinfo=obj.nodes(inode); for icpu = 1:nodeinfo.ncpu if nodeinfo.cpuactive(icpu) - if inode~=1 compileslx_list = [compileslx_list,... SCDclass_expcode.getslxname(inode,icpu)]; %#ok<AGROW> - else - warning('Do not compile node %d thread %d since this is just a dummy',inode,icpu); - end end end end @@ -662,6 +673,7 @@ classdef SCDclass_expcode % user passed nodes,threads to compile myslx = SCDclass_expcode.getslxname(varargin{:}); fprintf('building %s.slx\n',myslx) + compileslx_list{1} = myslx; end % set CodeGen folder for this expcode (allows fast rebuilding) @@ -690,9 +702,11 @@ classdef SCDclass_expcode methods (Access = private) - function obj=printlog(obj,str) + function obj=printlog(obj,str,varargin) + % printlog, allows sprintf()-like expressions if obj.loadverbose==1 - fprintf('Expcode %d, %s\n', obj.maincode, str); + fprintf('Expcode %d, ', obj.maincode, str); + fprintf(str,varargin{:}); fprintf('\n'); end end @@ -748,7 +762,7 @@ classdef SCDclass_expcode nodeddsourcesok={}; nodeddsourcesokitems=0; for ii=1:numel(nodeddsources) - if(strcmp(nodeddsources{ii}(1:7),'SCDwrap')) + if startsWith(nodeddsources{ii},'SCDwrap') temp={nodeddsources{ii}, 0}; nodeddsourcesok=[nodeddsourcesok; temp]; nodeddsourcesokitems=nodeddsourcesokitems+1; @@ -758,20 +772,17 @@ classdef SCDclass_expcode reqsourcesok={}; reqsourcesokitems=0; for ii=1:numel(reqsources) - if(strcmp(reqsources{ii}(1:7),'SCDwrap')) + if startsWith(reqsources{ii},'SCDwrap') temp={reqsources{ii}, 1}; reqsourcesok=[reqsourcesok; temp]; reqsourcesokitems=reqsourcesokitems+1; else - str=sprintf('Proposed wrapper data dictionary %s does not begin with SCDwrap, ignoring it.', reqsources{ii}); - warning(str); - %obj.printlog(str); + warning('Proposed wrapper data dictionary %s does not begin with SCDwrap, ignoring it.', reqsources{ii}); end - end % Finding which data sources to eliminate and which to add - if(nodeddsourcesokitems>0 && reqsourcesokitems>0) + if (nodeddsourcesokitems>0 && reqsourcesokitems>0) for ii=1:nodeddsourcesokitems todel=1; for jj=1:reqsourcesokitems @@ -799,8 +810,7 @@ classdef SCDclass_expcode if(nodeddsourcesokitems>0) for ii=1:nodeddsourcesokitems if(nodeddsourcesok{ii,2}==1) - str=sprintf('Removing wrapper data source %s from %s', char(nodeddsourcesok{ii,1}), datadictname); - obj.printlog(str); + obj.printlog('Removing wrapper data source %s from %s', char(nodeddsourcesok{ii,1}), datadictname); removeDataSource(nodedd, char(nodeddsourcesok{ii,1})); end end @@ -810,8 +820,7 @@ classdef SCDclass_expcode if(reqsourcesokitems>0) for ii=1:reqsourcesokitems if(reqsourcesok{ii,2}==1) - str=sprintf('Adding wrapper data source %s to %s', char(reqsourcesok{ii,1}), datadictname); - obj.printlog(str); + obj.printlog('Adding wrapper data source %s to %s', char(reqsourcesok{ii,1}), datadictname); addDataSource(nodedd, char(reqsourcesok{ii,1})); end end @@ -879,8 +888,7 @@ classdef SCDclass_expcode if(tcvddsourcesokitems>0) for ii=1:tcvddsourcesokitems if(tcvddsourcesok{ii,2}==1) - str=sprintf('Removing algorithm data source %s', char(tcvddsourcesok{ii,1})); - obj.printlog(str); + obj.printlog('Removing algorithm data source %s', char(tcvddsourcesok{ii,1})); removeDataSource(tcvdd, char(tcvddsourcesok{ii,1})); end end @@ -890,8 +898,7 @@ classdef SCDclass_expcode if(reqsourcesokitems>0) for ii=1:reqsourcesokitems if(reqsourcesok{ii,2}==1) - str=sprintf('Adding algorithm data source %s', char(reqsourcesok{ii,1})); - obj.printlog(str); + obj.printlog('Adding algorithm data source %s', char(reqsourcesok{ii,1})); addDataSource(tcvdd, char(reqsourcesok{ii,1})); end end @@ -928,7 +935,6 @@ classdef SCDclass_expcode else warning('SCDclass_expcode:setupwrappers','not supported node%02d cpu',inode); end - case {2,3,4,6,7} if(obj.wrapperlist{ii}{2}>=1 && obj.wrapperlist{ii}{2}<=4) obj.nodes(inode).varalgo(obj.wrapperlist{ii}{2})=obj.wrapperlist{ii}{3}; @@ -936,10 +942,8 @@ classdef SCDclass_expcode else warning('SCDclass_expcode:setupwrappers','not supported node%02d cpu',inode); end - otherwise warning('SCDclass_expcode:setupwrappers','not supported node'); - end end @@ -974,27 +978,43 @@ classdef SCDclass_expcode function obj = buildworkspacesimstructnode(obj,inode,dd) node = obj.nodes(inode); - try % get existing SCDsimdata + if evalin('base','exist(''SCDsimdata'',''var'')'); SCDsimdata = evalin('base','SCDsimdata'); - catch ME - if strcmp(ME.identifier,'MATLAB:UndefinedFunction') - SCDsimdata = struct(); % assign here if empty - else - rethrow(ME); - end + else + SCDsimdata = struct(); % assign here if empty end if node.haswavegen for ithread = 1:node.ncpu % get whatever is in data dictionary template in wrappers simstructname = sprintf('SCDnode%02d%02d_simdata',inode,ithread); - fprintf(' setting up %s\n',simstructname); - try - simstruct = dd.getEntry(simstructname).getValue; - catch - warning('%s not found in data dictionary, auto-generate from bus definition',simstructname) - wgbusname = sprintf('WG%02d%02dbus',inode,ithread); - simstruct = SCDconf_createsimdatastruct(dd,wgbusname); + wgbusname = sprintf('WG%02d%02dbus',inode,ithread); + + fprintf(' setting up %s',simstructname); + if dd.exist(simstructname) + simstruct = dd.getEntry(simstructname).getValue; + mybus=dd.getEntry(wgbusname).getValue; % get from data dictionary + if ~isstruct(simstruct) || ~isfield(simstruct,'wavegen') + fprintf('.. loaded simstruct wavegen is not compatible'); + regenerate = true; + elseif SCDconf_structbuscmp(simstruct.wavegen,mybus) + fprintf('... loaded WG from data dictionary\n'); + regenerate=false; + else + fprintf('... loaded WG structure from dd does not match bus definition...'); + regenerate=true; + end + else + regenerate=true; + fprintf('... could not find %s in data dictionary',simstructname); + end + + if regenerate + simstruct.wavegen = SCDconf_createstructfrombus(dd,wgbusname); % structure to match + %ddsource = dd.find('Name',wgbusname).DataSource; % dd containing bus + %wrapdd=Simulink.data.dictionary.open(ddsource).getSection('Design Data'); + %wrapdd.addEntry(simstructname,simstruct) + fprintf('... re-generated from bus %s\n',wgbusname') end SCDsimdata.(simstructname) = simstruct; end @@ -1005,7 +1025,7 @@ classdef SCDclass_expcode if node.hasadc adcbusname = sprintf('ADC%02dbus',inode); fprintf(' setting up %s.adc\n',simstructname); - SCDsimdata.(simstructname).adc = SCDconf_createsimdatastruct(dd,adcbusname); + SCDsimdata.(simstructname).adc = SCDconf_createstructfrombus(dd,adcbusname); end if node.hasethercat @@ -1013,18 +1033,16 @@ classdef SCDclass_expcode ethercatbusname = 'ETHCAT1IN'; fprintf(' setting up %s.ethercat\n',simstructname); SCDsimdata.(simstructname).ethercat = ... - SCDconf_createsimdatastruct(dd,ethercatbusname); + SCDconf_createstructfrombus(dd,ethercatbusname); end % add also RFM RFMbusname = 'RFMINbus'; - SCDsimdata.rfm = SCDconf_createsimdatastruct(dd,RFMbusname); + SCDsimdata.rfm = SCDconf_createstructfrombus(dd,RFMbusname); % assign result in base workspace assignin('base','SCDsimdata',SCDsimdata); end - - end end diff --git a/code/classes/SCDclass_mdsobjcontainer.m b/code/classes/SCDclass_mdsobjcontainer.m index a39f4a9de64a07fed5a86bfecb68807ef697268e..d0cc76ebbd9c2285ef5d21676fe0507000c0b882 100644 --- a/code/classes/SCDclass_mdsobjcontainer.m +++ b/code/classes/SCDclass_mdsobjcontainer.m @@ -202,7 +202,8 @@ classdef SCDclass_mdsobjcontainer prevServer = ''; % init % Header for MDS for loader - loaderStr = sprintf('\n\n+MDSParameters = {\n Class=MDSObjLoader\n Shot=%d\n',shot); + %loaderStr = sprintf('\n\n+MDSParameters = {\n Class=MDSObjLoader\n Shot=%d\n',shot); + loaderStr = sprintf('\n\n+MDSParameters = {\n Class=MDSObjLoader\n Shot=MDSSRCSHOT\n'); fprintf("%s",loaderStr); for ii=1:obj.numparams diff --git a/code/classes/SCDclass_mdspar.m b/code/classes/SCDclass_mdspar.m index 929ebee1692c19971c1297dc50be50473bd31323..7cfff7960e982b7b95ba4d40f4a0219c0500a5af 100644 --- a/code/classes/SCDclass_mdspar.m +++ b/code/classes/SCDclass_mdspar.m @@ -36,7 +36,7 @@ classdef SCDclass_mdspar < matlab.mixin.Heterogeneous unlinked % unlinked parameter, no actualization will be performed (this is set via an empty MDS source path) actualizable % true if after MDS data retrieval phase the parameter is actualizable - overrideshot % =1 if biult with overridden whot number in this case this shot number will be always used during actualization + overrideshot % =1 if instantiated with overridden shot number, in this case this shot number will be always used during actualization overrideshotn % shot number in case of overridden shot number end @@ -103,35 +103,46 @@ classdef SCDclass_mdspar < matlab.mixin.Heterogeneous % Not abstract methods common to all child classes methods - function mdsconnect(obj, shot) + function obj = mdsconnect(obj, shot) assert(~~exist('mdsconnect','file'),... 'SCD:NoMDS','mdsconnect not found, are the mds matlab tools installed?') mdsconnect(obj.mdsserver); + % If the class has been declared with a 'shot' parameter, then + % the shotnumber used for param loading is overridden by this + % parameter, otherwise it is taken from the global shot number + % given to the actualize command if obj.overrideshot == 1 - localshot = obj.overrideshotn; + localshot = obj.overrideshotn; else - localshot = shot; + localshot = shot; end - s=mdsopen(obj.mdstree, localshot); - str=sprintf('SCDclass_mdsparam (%s), failed opening MDS+ tree', obj.modelparam); - assert(s==localshot, str); + mdsconnect(obj.mdsserver); + [~,s] = mdsopen(obj.mdstree, localshot); + if ~rem(s,2) + warning('SCDclass_mdspar:MDSerror','MDS+ tree open error for parameter %s. Actualization skipped.',obj.modelparam); + obj.actualizable=false; + end + end + + function obj=setactualizecmds(obj) + pointspos=strfind(obj.modelparam,'.'); + baseparam=obj.modelparam(1:pointspos(1)-1); + structparam=obj.modelparam(pointspos(1):end); + obj.assignvar=sprintf('%s.Value%s',baseparam,structparam); + obj.assignstring=sprintf('%s=%s;',obj.assignvar,obj.getcommand); + obj.denanstring=sprintf('%s(isnan(%s))=0;',obj.assignvar,obj.assignvar); + obj.caststring=sprintf('%s=%s;',obj.assignvar,obj.assignvar); end function obj=preactualizecommon(obj, shot) if(~obj.unlinked) % Opening the tree - obj.mdsconnect(shot); - % Checking if data can be retrieved, updating get command + obj=obj.mdsconnect(shot); + if ~obj.actualizable, return; end + % Checking if data can be retrieved, updating get command [obj, obj.value]=obj.getdata(shot); if ~obj.actualizable, return; end - - pointspos=strfind(obj.modelparam,'.'); - baseparam=obj.modelparam(1:pointspos(1)-1); - structparam=obj.modelparam(pointspos(1):end); - obj.assignvar=sprintf('%s.Value%s',baseparam,structparam); - obj.assignstring=sprintf('%s=%s;',obj.assignvar,obj.getcommand); - obj.denanstring=sprintf('%s(isnan(%s))=0;',obj.assignvar,obj.assignvar); - obj.caststring=sprintf('%s=%s;',obj.assignvar,obj.assignvar); + obj=obj.setactualizecmds; end end @@ -156,9 +167,9 @@ classdef SCDclass_mdspar < matlab.mixin.Heterogeneous function [obj,value]=getdatacommon(obj, shot) obj=obj.actualizegetcmd('mdsvalue(''%s'')', shot); - + value=eval(obj.getcommand); - if(~isnumeric(value)) + if(~isnumeric(value) && ~isa(obj,'SCDclass_mdsparenum')) % TODO: better handle this exception warning('SCDclass_mdspar:MDSerror','MDS+ error for parameter %s: %s. Actualization skipped.',obj.modelparam, value); obj.actualizable=false; else @@ -198,7 +209,7 @@ classdef SCDclass_mdspar < matlab.mixin.Heterogeneous fprintf(', shot: ''%s''', obj.tdiexprshot); end if obj.overrideshot == 1 - fprintf(', WARNING: shot ovr to %d.\n', obj.overrideshotn); + fprintf(', WARNING: shot number override to %d.\n', obj.overrideshotn); else fprintf('.\n'); end diff --git a/code/classes/SCDclass_mdsparenum.m b/code/classes/SCDclass_mdsparenum.m new file mode 100644 index 0000000000000000000000000000000000000000..a99622c95336e27dfc0c7549d96798af587e433b --- /dev/null +++ b/code/classes/SCDclass_mdsparenum.m @@ -0,0 +1,114 @@ +classdef SCDclass_mdsparenum < SCDclass_mdspar + % A string enumerated MDS parameter, for uint16 enum codes + % + % behavior in MATLAB: + % if a string match between MDS string and matlab num string is + % asserted, the enum choice is loaded into the tun parameter + % if not a warning is issued and the param is left untouched + % behavior in MARTe2: + % the same than before but the enum map is used to load the + % equivalent uint16 code on the MARTe2 side tunable parameter + % if a string match is not detected, the parameter is invalidated + + properties(Access=private) + enumclass + valuemap + codemap + end + + methods + + function obj=SCDclass_mdsparenum(srctdimodel, destparam, varargin) + obj@SCDclass_mdspar(); + % Constructor parser customization definitions here + obj=obj.parseconstructorcommon(srctdimodel, destparam, varargin); + % Constructor parser customization results here + + obj.classname=mfilename; + obj.marteclassname='MDSParEnum'; + end + + function actualizedata(obj, shot) + obj=obj.preactualizecommon(shot); + + if(~obj.unlinked) + % Enumeration map fill + obj=obj.initenummap(); + + % value search + found=false; + for ii=1:numel(obj.valuemap) + if strcmp(obj.value,char(obj.valuemap(ii))) + found = true; + break; + end + end + + if ~found + warning('SCDclass_mdsparenum:actualize','No match between MDS and enum values, parameter %s not actualized', obj.assignvar); + return + end + + obj.assignstring=sprintf('%s=%s.%s;',obj.assignvar,obj.enumclass,obj.value); + obj.denanstring=''; + obj.caststring=''; + end + + obj.postactualizecommon(shot); + end + + function [obj, value] = getdata(obj, shot) + [obj,value]=obj.getdatacommon(shot); + end + + function printinfo(obj) + obj.printinfocommon; + end + + function entrystring = genMARTe2entry(obj, shot) + entrystring=obj.genMARTe2entrycommon(shot); + + % to populate obj.assignvar + obj=obj.setactualizecmds(shot); + + % Enumeration map fill + obj=obj.initenummap(); + + enumval ='EnumVal = {'; + enumcode ='EnumCode = {'; + for ii=1:numel(obj.valuemap) + enumval=[enumval '"' char(obj.valuemap(ii)) '"']; + if ii~=numel(obj.valuemap) + enumval=[enumval ',']; + end + end + enumval=[enumval, '}']; + for ii=1:numel(obj.codemap) + enumcode=[enumcode num2str(obj.codemap(ii))]; + if ii~=numel(obj.codemap) + enumcode=[enumcode ',']; + end + end + enumcode=[enumcode '}']; + + entrystring=[entrystring ' ' enumcode ' ' enumval '}']; + end + end + + methods(Access = private) + + function obj = initenummap(obj) + % TODO: probably Simulink.data.evalinGlobal better than + % evalin('base' + + basecmd = ['class(' obj.assignvar ');']; + obj.enumclass = evalin('base',basecmd); + basecmd = ['enumeration(' obj.assignvar ');']; + obj.valuemap = evalin('base',basecmd); + basecmd = ['uint16(enumeration(' obj.assignvar '));']; + obj.codemap = evalin('base',basecmd); + end + + end +end + diff --git a/code/classes/SCDclass_mdsparscalar.m b/code/classes/SCDclass_mdsparscalar.m index 22f7658cf0e5bc68848bb75747d4db7fa0049161..427ab08ef8d89060d99f0bef22367292b62adc6d 100644 --- a/code/classes/SCDclass_mdsparscalar.m +++ b/code/classes/SCDclass_mdsparscalar.m @@ -4,6 +4,7 @@ classdef SCDclass_mdsparscalar < SCDclass_mdspar properties end + methods function obj=SCDclass_mdsparscalar(srctdimodel, destparam, varargin) diff --git a/code/classes/SCDclass_mdsparvectorint.m b/code/classes/SCDclass_mdsparvectorint.m new file mode 100644 index 0000000000000000000000000000000000000000..ed6a1259fc34746bd28a44a735634de7d34effca --- /dev/null +++ b/code/classes/SCDclass_mdsparvectorint.m @@ -0,0 +1,40 @@ +classdef SCDclass_mdsparvectorint < SCDclass_mdspar + % A constant 1D vector integer (int32) MDS+ parameter + + properties + end + + methods + + function obj=SCDclass_mdsparvectorint(srctdimodel, destparam, varargin) + obj@SCDclass_mdspar(); + % Constructor parser customization definitions here + obj=obj.parseconstructorcommon(srctdimodel, destparam, varargin); + % Constructor parser customization results here + obj.classname=mfilename; + obj.marteclassname='MDSParVectorInt'; + end + + function actualizedata(obj, shot) + obj=obj.preactualizecommon(shot); + if ~obj.actualizable, return; end + obj.caststring=sprintf('%s=int32(%s);',obj.assignvar,obj.assignvar); + obj.postactualizecommon(shot); + end + + function [obj, value] = getdata(obj,shot) + [obj,value]=obj.getdatacommon(shot); + value=single(value); + end + + function printinfo(obj) + obj.printinfocommon; + end + + function entrystring = genMARTe2entry(obj, shot) + entrystring=[obj.genMARTe2entrycommon(shot) ' }']; + end + + end +end + diff --git a/code/classes/SCDclass_mdswgsigsingle.m b/code/classes/SCDclass_mdswgsigsingle.m index e4cbbe75c4a0c87d3c75ba01a9458653a8f96099..83d400d347510fa30d613745286a897ae1803a8d 100644 --- a/code/classes/SCDclass_mdswgsigsingle.m +++ b/code/classes/SCDclass_mdswgsigsingle.m @@ -46,36 +46,32 @@ classdef SCDclass_mdswgsigsingle < SCDclass_mdswg end value=obj.getdata(); - - baseparam=obj.wavegenbasestruct; - structparam=obj.wavegentarget; - wgentryval=evalin('base',baseparam); + baseparam=obj.wavegenbasestruct; % name of base workspace structure + structparam=obj.wavegentarget; % name of target field + wgentryval = evalin('base',baseparam); % structure of wavegen in base workspace - getcurrenttssize =sprintf('ddtssamples=numel(wgentryval.%s.Time);',structparam); - eval(getcurrenttssize); - if(ddtssamples~=numel(value.Time)) - % the dd timeseries has different dims w.r.t. the signals - % to be loaded, we have to load the timeseries as it is - - assigncmd =sprintf('wgentryval.%s=value;',structparam); - eval(assigncmd); - else - % the dd timeseries has the same size than the signals - % to be loaded, we can do a partial loading - - assigncmdtime =sprintf('wgentryval.%s.Time=value.Time;',structparam); - assigncmddata =sprintf('wgentryval.%s.Data(:,%d)=value.Data;',structparam,obj.destidx); + assert(isfield(wgentryval,structparam),... + 'Wavegen field %s does not exist in target structure %s. ',structparam,baseparam) - eval(assigncmdtime); - eval(assigncmddata); + % assign field from wavegen entry value + ddtssamples=numel(wgentryval.(structparam).Time); + if ddtssamples~=numel(value.Time) + % the dd timeseries has different dims w.r.t. the signals + % to be loaded, we have to load the timeseries as it is + wgentryval.(structparam)=value; + else + % the dd timeseries has the same size than the signals + % to be loaded, we can do a partial loading + wgentryval.(structparam).Time=value.Time; + wgentryval.(structparam).Data(:,obj.destidx)=value.Data; end assignin('base','temp',wgentryval); - assigncmd=sprintf('%s=temp;',baseparam); + assigncmd=sprintf('%s=temp;',baseparam); evalin('base',assigncmd); evalin('base','clear temp'); - + end function value=getdata(obj) diff --git a/code/classes/SCDclass_taskmdsloadprevADC.m b/code/classes/SCDclass_taskmdsloadprevADC.m index 9e02e5084513db923bef1ae3c94b09452f7098e7..2936a466aab223579c8842a50f7a635c5bd852d3 100644 --- a/code/classes/SCDclass_taskmdsloadprevADC.m +++ b/code/classes/SCDclass_taskmdsloadprevADC.m @@ -7,6 +7,10 @@ classdef SCDclass_taskmdsloadprevADC < SCDclass_task workspacedatabasestructure end + properties(Access=private) + logdecimate + end + methods function obj=SCDclass_taskmdsloadprevADC(id, varargin) @@ -25,18 +29,24 @@ classdef SCDclass_taskmdsloadprevADC < SCDclass_task obj.workspacedatabasestructure=''; end obj.classname=mfilename; + obj.logdecimate=20; end function init(obj, shot) mdsconnect(obj.mdsserver); mdsopen(obj.mdstree, shot); - - switch(obj.node) - case 1 - obj.actualizeNode01(shot); - case 2 - obj.actualizeNode02(shot); - end + + try + switch(obj.node) + case 1 + obj.actualizeNode(shot, 96); + case 2 + obj.actualizeNode(shot, 192); + end + catch + fprintf('\n'); + warning('SCDclass_taskmdsloadprevADC:init','Error initializing ADC bus for node %d.',obj.node); + end end function [obj, value] = getdata(obj,shot) @@ -47,10 +57,12 @@ classdef SCDclass_taskmdsloadprevADC < SCDclass_task case 1 [~,value]=obj.getdataNode01ACQ196(shot); case 2 + % Here we need to switch betweeen old and new acquisition unit + % TODO: add tcv standard in case data is not available if shot<65113 - [~,value]=obj.getdataNode02ACQ196(shot); %% Here we need to switch betweeen old and new acquisition unit and tcv standard also + [~,value]=obj.getdataNode02ACQ196(shot); else - [~,value]=obj.getdataNode02tst(shot); %% Here we need to switch betweeen old and new acquisition unit and tcv standard also + [~,value]=obj.getdataNode02ACQ2106(shot); end end end @@ -70,146 +82,135 @@ classdef SCDclass_taskmdsloadprevADC < SCDclass_task methods(Access = private) - function obj = actualizeNode01(obj, shot) + function obj = actualizeNode(obj, shot, nadcs) dd=SCDconf_getdatadict(obj.datadictionary); adcbus=dd.getEntry(obj.modelbus).getValue; [~,data]=obj.getdata(shot); T=timeseries; if obj.verbose==1 - fprintf('Actualizing data for bus: ''%s'' (%s, shot %d) ', obj.modelbus, obj.classname, shot); + fprintf('Actualizing data for bus: ''%s'' (%s, shot %d) 0%% ', obj.modelbus, obj.classname, shot); end - for ii=1:96 + for ii=1:nadcs T.Time=data.Time; T.Data=int16(data.Data(:,ii)); assignin('base','temp',T); assigncmd=sprintf('%s.%s=temp;',obj.workspacedatabasestructure, adcbus.Elements(ii).Name); evalin('base',assigncmd); - if obj.verbose==1 && mod(ii,4)==0 - fprintf('.'); + if obj.verbose==1 && mod(ii,obj.logdecimate)==0 + fprintf('%.0f%% ', ii/nadcs*100); end end evalin('base','clear temp'); if obj.verbose==1 - fprintf('\n'); + fprintf('100%% \n'); end end - - function obj = actualizeNode02(obj, shot) - dd=SCDconf_getdatadict(obj.datadictionary); - adcbus=dd.getEntry(obj.modelbus).getValue; - [~,data]=obj.getdata(shot); - T=timeseries; + +%% +% Node 01 loading functions + + function [obj, value] = getdataNode01ACQ196(obj, shot) + T=timeseries; + timebase=mdsvalue('dim_of(\top.crpprt01.board1.adc_01)'); %% TODO: check with marte + d_time = double(mdsvalueraw( '\top.crpprt01.params:d_time' ))*1.0e-6; + %timebase = round(timebase.*1/d_time)*d_time-d_time/2; + timebase = round(timebase.*1/d_time)*d_time-d_time/100; + T.Time=timebase; + T.Data=zeros(numel(timebase),96); + datamatrix=zeros(numel(timebase),96); if obj.verbose==1 - fprintf('Actualizing data for bus: ''%s'' (%s, shot %d) ', obj.modelbus, obj.classname, shot); + fprintf('Getting data for bus: ''%s'' (%s, shot %d) 0%% ', obj.modelbus, obj.classname, shot); end - for ii=1:192 - T.Time=data.Time; - T.Data=int16(data.Data(:,ii)); - assignin('base','temp',T); - assigncmd=sprintf('%s.%s=temp;',obj.workspacedatabasestructure, adcbus.Elements(ii).Name); - evalin('base',assigncmd); - if obj.verbose==1 && mod(ii,4)==0 - fprintf('.'); + for ii=1:96 + % Node 01 data are loaded in the stored order since + % up to now there is only old node 01 + + channelstr=sprintf('\\top.crpprt01.board1.adc_%02d.raw',physical2logical(ii)); + datamatrix(:,ii)=int16(mdsvalue(channelstr)); + if obj.verbose==1 && mod(ii,obj.logdecimate)==0 + fprintf('%.0f%% ', ii/96*100); end end - evalin('base','clear temp'); + T.Data=datamatrix; % this speeds up a lot the loading + value=T; if obj.verbose==1 - fprintf('\n'); - end + fprintf('100%% \n'); + end end - + +%% +% Node 02 loading functions + function [obj, value] = getdataNode02ACQ196(obj, shot) T=timeseries; - timebase=mdsvalue('dim_of(\top.crpprt02.board1.adc_01)'); %% TODO: check with marte + timebase=mdsvalue('dim_of(\top.crpprt02.board1.adc_01)'); d_time = double(mdsvalueraw( '\top.crpprt02.params:d_time' ))*1.0e-6; %timebase = round(timebase.*1/d_time)*d_time-d_time/2; timebase = round(timebase.*1/d_time)*d_time-d_time/100; T.Time=timebase; T.Data=zeros(numel(timebase),192); + datamatrix=zeros(numel(timebase),192); if obj.verbose==1 - fprintf('Getting data for bus: ''%s'' (%s, shot %d) ', obj.modelbus, obj.classname, shot); + fprintf('Getting data for bus: ''%s'' (%s, shot %d) 0%% ', obj.modelbus, obj.classname, shot); end for ii=1:96 % NOTE: physical2logical remapping is only for - % data acquired with the present ACQ196 system - % it must go away when using the new ACQ2106 system - %fprintf('Loading channel %d:%d ...\r',1,physical2logical(ii)); - + % data acquired with the ACQ196 system, not for the new + % 2106 based one channelstr=sprintf('\\top.crpprt02.board1.adc_%02d.raw',physical2logical(ii)); - T.Data(:,ii)=int16(mdsvalue(channelstr)); - if obj.verbose==1 && mod(ii,4)==0 - fprintf('.'); + datamatrix(:,ii)=int16(mdsvalue(channelstr)); + if obj.verbose==1 && mod(ii,obj.logdecimate)==0 + fprintf('%.0f%% ', ii/192*100); end end for ii=1:96 - %fprintf('Loading channel %d:%d ...\r',2,physical2logical(ii)); channelstr=sprintf('\\top.crpprt02.board2.adc_%02d.raw',physical2logical(ii)); - T.Data(:,ii+96)=int16(mdsvalue(channelstr)); - if obj.verbose==1 && mod(ii,4)==0 - fprintf('.'); + datamatrix(:,ii+96)=int16(mdsvalue(channelstr)); + if obj.verbose==1 && mod(ii,obj.logdecimate)==0 + fprintf('%.0f%% ', (ii+96)/192*100); end end + T.Data=datamatrix; % this speeds up a lot the loading value=T; if obj.verbose==1 - fprintf('\n'); + fprintf('100%%\n'); end end - function [obj, value] = getdataNode02tst(obj, shot) - % TODO: this should go away as soon as we use the official rtc - % tree - mdsopen('rtctst',shot); + function [obj, value] = getdataNode02ACQ2106(obj, shot) + if shot>65826 + mdsnodename='node02'; + else + mdsnodename='tcvrt02'; + end + mdsopen('rtc',shot); T=timeseries; - timebase=mdsvalue('dim_of(\top.tcvrt02.adc.adc_001)'); %% TODO: check with marte - d_time = double(mdsvalueraw( '\top.tcvrt02.params:d_time' ))*1.0e-6; + timebase=mdsvalue(['dim_of(\top.' mdsnodename '.adc.adc_001)']); + d_time = double(mdsvalueraw(['\top.' mdsnodename '.params:d_time']))*1.0e-6; %timebase = round(timebase.*1/d_time)*d_time-d_time/2; timebase = round(timebase.*1/d_time)*d_time-d_time/100; T.Time=timebase; T.Data=zeros(numel(timebase),192); + datamatrix=zeros(numel(timebase),192); if obj.verbose==1 - fprintf('Getting data for bus: ''%s'' (%s, shot %d) ', obj.modelbus, obj.classname, shot); + fprintf('Getting data for bus: ''%s'' (%s, shot %d) 0%% ', obj.modelbus, obj.classname, shot); end for ii=1:192 - channelstr=sprintf('\\top.tcvrt02.adc.adc_%03d.raw',ii); - T.Data(:,ii)=int16(mdsvalue(channelstr)); - if obj.verbose==1 && mod(ii,4)==0 - fprintf('.'); + channelstr=sprintf(['\\top.' mdsnodename '.adc.adc_%03d.raw'],ii); + %T.Data(:,ii)=int16(mdsvalue(channelstr)); + %T.Data(:,ii)=int16(mdsvalueraw(channelstr)); + datamatrix(:,ii)=int16(mdsvalueraw(channelstr)); + if obj.verbose==1 && mod(ii,obj.logdecimate)==0 + fprintf('%.0f%% ', ii/192*100); end end + T.Data=datamatrix; % this speeds up a lot the loading value=T; if obj.verbose==1 - fprintf('\n'); + fprintf('100%% \n'); end end - function [obj, value] = getdataNode01ACQ196(obj, shot) - T=timeseries; - timebase=mdsvalue('dim_of(\top.crpprt01.board1.adc_01)'); %% TODO: check with marte - d_time = double(mdsvalueraw( '\top.crpprt01.params:d_time' ))*1.0e-6; - %timebase = round(timebase.*1/d_time)*d_time-d_time/2; - timebase = round(timebase.*1/d_time)*d_time-d_time/100; - T.Time=timebase; - T.Data=zeros(numel(timebase),96); - if obj.verbose==1 - fprintf('Getting data for bus: ''%s'' (%s, shot %d) ', obj.modelbus, obj.classname, shot); - end - for ii=1:96 - % Node 01 data are loaded in the stored order since - % up to now there is only old node 01 - - channelstr=sprintf('\\top.crpprt01.board1.adc_%02d.raw',physical2logical(ii)); - T.Data(:,ii)=int16(mdsvalue(channelstr)); - if obj.verbose==1 && mod(ii,4)==0 - fprintf('.'); - end - end - value=T; - if obj.verbose==1 - fprintf('\n'); - end - end - - end end diff --git a/code/functions/SCDconf_createsimdatastruct.m b/code/functions/SCDconf_createstructfrombus.m similarity index 69% rename from code/functions/SCDconf_createsimdatastruct.m rename to code/functions/SCDconf_createstructfrombus.m index 591c3fc892e92ab06ea6a63487d918faf16bb623..63d4f29c41c5847c6d0745af8395edfc45771c41 100644 --- a/code/functions/SCDconf_createsimdatastruct.m +++ b/code/functions/SCDconf_createstructfrombus.m @@ -5,9 +5,19 @@ % and with zero data of the correct kind % This is enough for passing a ctrl-D with from Workspace bus kind blocks -function [out] = SCDconf_createsimdatastruct(dd,busname) +function [out] = SCDconf_createstructfrombus(varargin) +% Create data structure matching a bus signature +% From either a datadictionary+busname or from a bus directly +% [out] = SCDconf_createstructfrombus(dd,busname) +% [out] = SCDconf_createstructfrombus(bus) -bus=dd.getEntry(busname).getValue; % get from data dictionary +if nargin==1 + bus = varargin{1}; +else + dd = varargin{1}; + busname = varargin{2}; + bus=dd.getEntry(busname).getValue; % get from data dictionary +end bussize=size(bus.Elements); signalssize=bussize(1); @@ -16,7 +26,7 @@ for ii=1:signalssize if contains(element.DataType,'Bus: ') busname = erase(element.DataType,'Bus: '); % recursive call - out.(element.Name) = SCDconf_createsimdatastruct(dd,busname); + out.(element.Name) = SCDconf_createstructfrombus(dd,busname); else try cast(1,element.DataType); catch ME; error('non-numeric type'); end elementdims=element.Dimensions; diff --git a/code/functions/SCDconf_structbuscmp.m b/code/functions/SCDconf_structbuscmp.m new file mode 100644 index 0000000000000000000000000000000000000000..adfdd3acdf11d1e73f212c4a3d07a6ca58d3252e --- /dev/null +++ b/code/functions/SCDconf_structbuscmp.m @@ -0,0 +1,31 @@ +% Compare the structure of a bus to that of a structure, return 1 if they +% are the same. + +function [areequal] = SCDconf_structbuscmp(mystruct,mybus) + +nelem=numel(mybus.Elements); + +for ielem = 1:nelem + myelem = mybus.Elements(ielem); + myelementname = myelem.Name; + if ~isfield(mystruct,myelementname) + areequal = false; return; + end + + myfield = mystruct.(myelementname); + if startsWith(myelem.DataType,'Bus') + % recursive call + areequal = SCDconf_structbuscmp(mystruct,mybus); + if ~areequal; return; end + elseif ~isa(myfield,'timeseries') % check timeseries + areequal=false; return; + elseif ~isa(myfield.Data,myelem.DataType) % check data type + areequal=false; return; + elseif ~all(size(myfield.Data,2:ndims(myfield.Data))==myelem.Dimensions) % check dimension + areequal=false; return; + end +end + +% if we made it this far.. +areequal = true; +end diff --git a/tests/test_SCDclass.m b/tests/test_SCDclass.m new file mode 100644 index 0000000000000000000000000000000000000000..60c189f11030e9fd67cd9a4251d58f543dc724b5 --- /dev/null +++ b/tests/test_SCDclass.m @@ -0,0 +1,18 @@ +classdef test_SCDclass < matlab.unittest.TestCase + % test file for SCD interface class + + properties + expcode = 1; + shot = 65668; + end + + methods(Test) + function test_load(testCase) + SCD.load(testCase.expcode); + end + + function test_init(testCase) + SCD.init(testCase.expcode,testCase.shot); + end + end +end \ No newline at end of file diff --git a/tests/test_expcodes.m b/tests/test_expcodes.m index dd45ee96296c044aff64bd11afe5f75bc8bc3062..c9d161a771662926ef8bd386cf778a08e0e9ec0f 100644 --- a/tests/test_expcodes.m +++ b/tests/test_expcodes.m @@ -7,10 +7,9 @@ classdef test_expcodes < matlab.unittest.TestCase end properties(ClassSetupParameter) - %expcode_number = {'1','1005','1010'}; % list of expcodes to test - expcode_number = {'1','1005'}; % list of expcodes to test + expcode = {'1','1005','1006'}; % list of expcodes to test end - + methods(TestClassSetup) function setup_environment(testCase) testCase.addTeardown(@cd,pwd); @@ -27,15 +26,15 @@ classdef test_expcodes < matlab.unittest.TestCase SCDconf_setSIMconf; % set ConfigurationSettings for Simulation end - function setup_expcode(testCase,expcode_number) + function setup_expcode(testCase,expcode) % get this expcode object from expcode object container - fprintf('\n=== Testing expcode %s ===\n',expcode_number); - testCase.expcode_obj = getbymaincode(testCase.SCDexps,str2double(expcode_number)); + fprintf('\n=== Testing expcode %s ===\n',expcode); + testCase.expcode_obj = getbymaincode(testCase.SCDexps,str2double(expcode)); end end - methods(Test) + methods(Test,TestTags={'expcodes'}) function test_expcode_printinfo(testCase) testCase.expcode_obj.printinfo @@ -57,25 +56,28 @@ classdef test_expcodes < matlab.unittest.TestCase testCase.expcode_obj.printinits end - function test_expcode_setup(testCase) - fprintf('\n=== Testing callinits for expcode %d: %s === \n',... - testCase.expcode_obj.maincode,... - testCase.expcode_obj.name); - + function test_expcode_setup(testCase) fprintf('\n=== Testing setup for expcode %d: %s === \n',... - testCase.expcode_obj.maincode,... - testCase.expcode_obj.name); - + testCase.expcode_obj.maincode,... + testCase.expcode_obj.name); testCase.expcode_obj.setup; % run setup this exp code end function test_callinits(testCase) - testCase.expcode_obj.callinits; + fprintf('\n=== Testing callinits for expcode %d: %s === \n',... + testCase.expcode_obj.maincode,... + testCase.expcode_obj.name); + testCase.expcode_obj.callinits; + end + + function test_actualize(testCase) + testCase.expcode_obj.actualize(testCase.shot); end function test_expcode_compile_nodes(testCase) % compile each node separately first - + testCase.assumeFalse(testCase.expcode_obj.maincode==1006,'Skipping compile tests for 1006 which requires library') + for inode = 1:numel(testCase.expcode_obj.nodes) node = testCase.expcode_obj.nodes(inode); if node.active @@ -88,11 +90,16 @@ classdef test_expcodes < matlab.unittest.TestCase end end - function test_expcode_compile_all(testCase) - testCase.expcode_obj.compile; % compile whole tcv.slx with this expcode + function test_expcode_sim(testCase) + testCase.assumeFalse(testCase.expcode_obj.maincode==1006,'Skipping compile tests for 1006 which requires library') + + fprintf('\n === Testing Simulink simulation of tcv.slx for expcode %d: === \n',testCase.expcode_obj.maincode) + testCase.expcode_obj.sim; % simulate whole tcv.slx with this expcode end + function test_build(testCase) + testCase.assumeFalse(testCase.expcode_obj.maincode==1006,'Skipping build tests for 1006 which requires library') testCase.expcode_obj.build; end end diff --git a/tests/test_structbus.m b/tests/test_structbus.m new file mode 100644 index 0000000000000000000000000000000000000000..b054474ec7e5582b16d1fd69e6478ea45be28693 --- /dev/null +++ b/tests/test_structbus.m @@ -0,0 +1,71 @@ +classdef test_structbus < matlab.unittest.TestCase + + properties + testBus = test_structbus.getTestBus(); + end + + methods(Test,TestTags={'Unit'}) + function testDifferentStruct(testCase) + mystruct = struct('a',1); + testCase.assertFalse(SCDconf_structbuscmp(mystruct,testCase.testBus)); + end + + function testSameStruct(testCase) + mystruct = SCDconf_createstructfrombus(testCase.testBus); % generate to match bus + areequal = SCDconf_structbuscmp(mystruct,testCase.testBus); + testCase.assertTrue(areequal); + end + end + + methods(Static) + function testBus = getTestBus() + testBus = Simulink.Bus; + testBus.Description = ''; + testBus.DataScope = 'Auto'; + testBus.HeaderFile = ''; + testBus.Alignment = -1; + saveVarsTmp{1} = Simulink.BusElement; + saveVarsTmp{1}.Name = 'a'; + saveVarsTmp{1}.Complexity = 'real'; + saveVarsTmp{1}.Dimensions = 24; + saveVarsTmp{1}.DataType = 'single'; + saveVarsTmp{1}.Min = []; + saveVarsTmp{1}.Max = []; + saveVarsTmp{1}.DimensionsMode = 'Fixed'; + saveVarsTmp{1}.SamplingMode = 'Sample based'; + saveVarsTmp{1}.SampleTime = -1; + saveVarsTmp{1}.DocUnits = 'varies'; + saveVarsTmp{1}.Description = ['References for observable errors coming ' ... + 'from the A matrix']; + saveVarsTmp{1}(2, 1) = Simulink.BusElement; + saveVarsTmp{1}(2, 1).Name = 'b'; + saveVarsTmp{1}(2, 1).Complexity = 'real'; + saveVarsTmp{1}(2, 1).Dimensions = 8; + saveVarsTmp{1}(2, 1).DataType = 'single'; + saveVarsTmp{1}(2, 1).Min = []; + saveVarsTmp{1}(2, 1).Max = []; + saveVarsTmp{1}(2, 1).DimensionsMode = 'Fixed'; + saveVarsTmp{1}(2, 1).SamplingMode = 'Sample based'; + saveVarsTmp{1}(2, 1).SampleTime = -1; + saveVarsTmp{1}(2, 1).DocUnits = 'V'; + saveVarsTmp{1}(2, 1).Description = ['Feed-forwards for SCR E converters' ... + ' voltage commands']; + saveVarsTmp{1}(3, 1) = Simulink.BusElement; + saveVarsTmp{1}(3, 1).Name = 'hyb_FF_f_u'; + saveVarsTmp{1}(3, 1).Complexity = 'real'; + saveVarsTmp{1}(3, 1).Dimensions = 8; + saveVarsTmp{1}(3, 1).DataType = 'single'; + saveVarsTmp{1}(3, 1).Min = []; + saveVarsTmp{1}(3, 1).Max = []; + saveVarsTmp{1}(3, 1).DimensionsMode = 'Fixed'; + saveVarsTmp{1}(3, 1).SamplingMode = 'Sample based'; + saveVarsTmp{1}(3, 1).SampleTime = -1; + saveVarsTmp{1}(3, 1).DocUnits = 'V'; + saveVarsTmp{1}(3, 1).Description = ['Feed-forwards for SCR F converters' ... + ' voltage commands']; + + testBus.Elements = saveVarsTmp{1}; + end + end +end +