diff --git a/code/classes/SCDclass_algo.m b/code/classes/SCDclass_algo.m index b036b9c18eb620a8342317d7eebe9d4bcfb7295a..12931ac9df6d42b6ded20c21846a6a664fd59be2 100644 --- a/code/classes/SCDclass_algo.m +++ b/code/classes/SCDclass_algo.m @@ -12,6 +12,7 @@ classdef SCDclass_algo datadictionary % Name of the used data dictionary stdinits % Standard inits scripts for fixed parameters timing % Timing info structure + exportedtpsdefaults % default tunable parameters defining functions end methods @@ -24,6 +25,7 @@ classdef SCDclass_algo obj.mdscontainer = SCDclass_mdsobjcontainer; obj.taskcontainer = SCDclass_taskcontainer; obj.exportedtps = {}; + obj.exportedtpsdefaults = {}; obj.stdinits = {}; obj.datadictionary = ''; obj.timing.t_start=0; @@ -66,6 +68,15 @@ classdef SCDclass_algo %% Setup function setup(obj) + % setup() + % + % calls updatetemplatetp and + % buildworkspacetpstruct + % + % an algorithm block diagram + % should pass ctrl-d (instandalone opening) + % after this call + obj.updatetemplatetp; obj.buildworkspacetpstruct; end %% General purpose getters @@ -112,46 +123,108 @@ classdef SCDclass_algo out = obj.exportedtps; end - function obj = addtunparamstruct(obj, structname) + function obj = addtunparamstruct(obj, structname, varargin) + % obj = addtunparamstruct(structname, varargin) + % + % adds a tunable parameter to the algo object + % inputs: + % structname: name of the tunable param (string) + % varargin{1}: a function handle to get + % its default value, this function takes no arguments + % and must return either a struct or a Simulink.Parameter + % + % example: obj=obj.addtunparamstruct('SCDalgo_doublet_tp', + % @()SCDalgo_doublet_loadtp()); if(~ismember(structname, obj.exportedtps)) obj.exportedtps{end+1}=structname; else error('SCDclass_algo:addtunparamsstruct','Tunable parameter struct already present, cannot add!'); - end - end - - function obj = settemplatetp(obj,TP) - % sets default tunable parameter structure in data dictionary - if ~isa(TP,'Simulink.Parameter') - assert(isstruct(TP),'TP must be a structure'); - P = Simulink.Parameter; - P.Value = TP; - else - P = TP; - end - DD = obj.opendatadictionarydesigndata; - tmplname = sprintf('%s_tp_tmpl',obj.getname); - if DD.exist(tmplname) - oldEntry = DD.getEntry(tmplname); - if isequal(oldEntry.getValue.Value,TP) - fprintf('%s: keep old template %s since not changed\n',mfilename,tmplname); - return; + end + if nargin==3 + if ~isa(varargin{1}, 'function_handle') + error('SCDclass_algo:addtunparamstruct', 'third argument, if present, must be a function handle'); + else + obj.exportedtpsdefaults{end+1} = varargin{1}; + end + +% % sets default tunable parameter structure in data dictionary +% TP=varargin{1}; +% if ~isa(TP,'Simulink.Parameter') +% assert(isstruct(TP),'default must be a structure'); +% P = Simulink.Parameter; +% P.Value = TP; +% else +% P = TP; +% end +% obj.exportedtpsdefaults{end+1} = P; else - DD.deleteEntry(tmplname); fprintf('deleted previous entry, '); + obj.exportedtpsdefaults{end+1} = []; + end + end + + function obj = updatetemplatetp(obj) + % obj = updatetemplatetp() + % + % For every configured tunparams structure + % if a default value function is present it is + % updated in the template version of the tun params + % in the algo data dictionary. + % The default value function of a tunparams can be given + % as an optional third argument of addtunparamstruct + % method + DD = obj.opendatadictionarydesigndata; + for ii=1:numel(obj.exportedtps) + if ~isempty(obj.exportedtpsdefaults{ii}) + % get current value of parameters from the function + % handle + fprintf(' %s: calling %s\n', obj.getname, char(obj.exportedtpsdefaults{ii})); + TP=obj.exportedtpsdefaults{ii}(); + if ~isa(TP,'Simulink.Parameter') + assert(isstruct(TP),'default function must return either a Simulink.Parameter or a structure'); + P = Simulink.Parameter; + P.Value = TP; + else + P = TP; + end + P.CoderInfo.StorageClass='ExportedGlobal'; + % updates default tunable parameters structure in data dictionary + tmplname = sprintf('%s_tmpl',obj.exportedtps{ii}); + if DD.exist(tmplname) + replace = false; + oldEntry = DD.getEntry(tmplname); + try + if isequal(oldEntry.getValue.Value,P.Value) + %fprintf('%s: keep old template %s since not changed\n',obj.getname,tmplname); + continue; + else + replace=true; + end + catch ME + replace=true; + end + if replace + DD.deleteEntry(tmplname); fprintf(' %s: deleted previous entry, ', obj.getname); + fprintf('added new %s\n',tmplname); + DD.addEntry(tmplname,P); + end + else + fprintf(' %s: added new %s\n',obj.getname, tmplname); + DD.addEntry(tmplname,P); + end + end end - end - fprintf('added new %s\n',tmplname); - DD.addEntry(tmplname,P) end function obj = buildworkspacetpstruct(obj) + % obj = buildworkspacetpstruct(obj) + % % this funtion builds a workspace structures containing % replicas of all tunable parameters structurea in the data % dictionaries, this structure is the one actually used - % for loading simulation wavegen data + % for loading simulation data from MDS % It is better not to use directly data dictionaries structures % to avoid flooding dds with big sim data sets (and - % consequently the SCD SVN itself + % consequently the SCD GIT itself if(isempty(obj.datadictionary)) warning('SCDclass_algo:buildworkspacetpstruct','Methods ignored for this object, data dictionary isn''t configured'); diff --git a/code/classes/SCDclass_expcode.m b/code/classes/SCDclass_expcode.m index 7462ab70e2ae4019573d20540350a5c437cfabd4..be7beab075bf89a0133060be3d8b515943b22bbf 100644 --- a/code/classes/SCDclass_expcode.m +++ b/code/classes/SCDclass_expcode.m @@ -1,18 +1,30 @@ classdef SCDclass_expcode %An SCD expcode object % - % Methods: + % Main 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 + % .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 = public) + % Main properties + name % Expcode main name + maincode % Expcode numerical code + status % Expcode development status + end + + properties (Access = protected) + loadverbose % Verbosity level of the loading (currently 0 or 1) + nodes % array of node properties structs + end properties (Access = private) activenodes % numerical list of configured active nodes @@ -27,18 +39,13 @@ classdef SCDclass_expcode exportedtps % list of tunable parameters variable to be exported stdinits % list of standard inits scripts modeltoactualize % name of the algorithm to actualize ('all' means all coonfigured) + algos % list of algorithms objects end - properties - % Main properties - name % Expcode main name - maincode % Expcode numerical code - status % Expcode development status - loadverbose % Verbosity level of the loading (currently 0 or 1) - - nodes % array of node properties structs - end - +%% +%% STATIC METHODS +%% + methods(Static) function help help(mfilename) @@ -223,11 +230,19 @@ classdef SCDclass_expcode fprintf(closemsg,bdroot); close_system(bdroot,saveflag) end + + %TODO: add datadict closure + %Simulink.data.dictionary.closeAll end end - + +%% +%% PUBLIC METHODS +%% + methods +%% Constructor function obj=SCDclass_expcode() % All templates constructor @@ -248,6 +263,7 @@ classdef SCDclass_expcode obj.algoddlist={}; obj.wrapperlist={}; obj.exportedtps = []; + obj.algos={}; obj.mdscontainer = SCDclass_mdsobjcontainer; obj.taskcontainer = SCDclass_taskcontainer; @@ -257,7 +273,149 @@ classdef SCDclass_expcode end obj.nodes = tmp; clear tmp; end + +%% Main expcode handling methods + + function open(~,varargin) + openslx = SCDclass_expcode.getslxname(varargin{:}); + fprintf('Opening %s.slx\n',openslx) + open(openslx); + end + + function setup(obj) + % This function sets up the TCV Simulink model + % to simulate this experimental code. + % NOTE THAT it doesn't actualize tunable parameters + % and wavegens, call actualizedata for that + fprintf('Setting up expcode %d, ''%s'', configuring wrappers ...\n',obj.maincode,obj.name); + obj=obj.setupwrappers; + obj.setupvaralgo; + fprintf('Setting up expcode %d, ''%s'', configuring data dictionaries ...\n',obj.maincode,obj.name); + obj.setupwrapdd; + obj.setupalgodd; + fprintf('Setting up expcode %d, ''%s'', configuring default tunable parameters ...\n',obj.maincode,obj.name); + obj.updatedefaulttp; + fprintf('Setting up expcode %d, ''%s'', configuring global data ...\n',obj.maincode,obj.name); + obj.setupmain; + fprintf('Setting up expcode %d, ''%s'', configuring main workspace variables ...\n',obj.maincode,obj.name); + obj.buildworkspacesimstruct; + obj.buildworkspacetpstruct; + + % Set cache and codegen folders + obj.setcachefolder; + obj.setcodegenfolder; + + end + + function actualize(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.modeltoactualize='all'; + else + obj.modeltoactualize=p.Results.model; + end + + obj.actualizedata(shot); + fprintf('Actualizing expcode %d, ''%s'', performing tasks ...\n',obj.maincode,obj.name); + obj.taskcontainer.modeltoexecute=obj.modeltoactualize; + obj.taskcontainer.exectasksoninit(shot); + end + + function callinits(obj) + if(~isempty(obj.algoobjlist)) + for ii=1:numel(obj.algoobjlist) + if nargin==1 + obj.algoobjlist{ii}.callinits(); + elseif nargin==2 + error('this use is deprecated, add tasks instead') + else + error('invalid number of arguments for callinits'); + end + end + end + end + function updatemdsmodel(obj, algo) + obj.updatemds(algo, -1); + end + + function compile(~,varargin) + myslx = SCDclass_expcode.getslxname(varargin{:}); + fprintf('Compiling %s.slx\n',myslx) + try + eval(sprintf('%s([],[],[],''compile'')',myslx)); + eval(sprintf('%s([],[],[],''term'')',myslx)); + catch ME + rethrow(ME) + end + end + + function sim(~,varargin) + SCDconf_setSIMconf + myslx = SCDclass_expcode.getslxname(varargin{:}); + fprintf('Simulating %s.slx\n',myslx) + sim(myslx) + end + + + function build(obj,varargin) + + if numel(varargin)==0 + fprintf('\n=== Building all threads for %s ===\n',obj.name); + % make list of nodes to build + compileslx_list = cell(0); + for inode=1:8 + nodeinfo=obj.nodes(inode); + for icpu = 1:nodeinfo.ncpu + if nodeinfo.cpuactive(icpu) + compileslx_list = [compileslx_list,... + SCDclass_expcode.getslxname(inode,icpu)]; %#ok<AGROW> + end + end + end + + if isempty(compileslx_list) + fprintf('No active nodes found, no .slx to compile. Done\n'); + return + end + else + % 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) + CodeGenFolder = obj.setcodegenfolder; + + % check env variable + assert(~isempty(getenv('RTCCODE_LIBPATH')),'RTCCODE_LIBPATH environment variable needs to be defined to compile'); + + % set configuration settings for compilation + SCDconf_setCODEconf('configurationSettingsCODEicc') + + % Build + try + SCDclass_expcode.build_nodes(compileslx_list); + catch ME + % if fails on first attempt, clear build folder and retry + fprintf(' **** FIRST ATTEMPT BUILDING %s FAILED **** \n',obj.name) + fprintf(' Error message:\n %s\n',getReport(ME)); + fprintf(' Try again clearning build folder\n') + + system(sprintf('rm -rf %s/*',CodeGenFolder)); + SCDclass_expcode.build_nodes(compileslx_list); + end + end + +%% Printing methods + function printinfo(obj) fprintf('*****************************************************\n'); fprintf('* SCD expcode: ''%s'', main code: %d\n',obj.name,obj.maincode); @@ -292,25 +450,80 @@ classdef SCDclass_expcode fprintf('* Configured init scripts: %d (use printinits method for details)\n', numel(obj.stdinits)); end - function CacheFolder = setcachefolder(obj) - %% Set Cache Folder for experimental code (avoid conflicts with other tmp files) - CacheFolder = fullfile(fileparts(mfilename('fullpath')),'..','..',... - 'gencodes',sprintf('CacheFolder-%d',obj.maincode)); - fprintf('Setting Simulink Cache folder to %s\n',CacheFolder) - Simulink.fileGenControl('set',... - 'CacheFolder',CacheFolder,... - 'createdir',true); + function printtasks(obj) + obj.taskcontainer.printtasks; + end + + function printinits(obj) + if(~isempty(obj.stdinits)) + for ii=1:numel(obj.stdinits) + fprintf('%s -> %s\n',char(obj.stdinits{ii}{1}),char(obj.stdinits{ii}{2})); + end + 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 CodeGenFolder = setcodegenfolder(obj) - CodeGenFolder = fullfile(fileparts(mfilename('fullpath')),'..','..',... - 'gencodes',sprintf('CodeGenFolder-%d',obj.maincode)); - - fprintf('Setting code generation folder to %s\n',CodeGenFolder) - Simulink.fileGenControl('set',... - 'CodeGenFolder',CodeGenFolder,... - 'createdir',true); + function printMARTe2parconfig(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.mdscontainer.modeltogenerate='all'; + else + obj.mdscontainer.modeltogenerate=p.Results.model; + end + obj.mdscontainer.printMARTe2parconfig(shot); + end + + function printMARTe2wgbusconfig(obj, shot, busname, frequency, varargin) + % printMARTe2wgbusconfig(obj, shot, busname, frequency, varargin) + % + % prints cfg file for loading busname Simulink.Bus + % as a wavegen (or a set of them) in MARTe2 + % shot can be -1 or a fixed shot (usually -1), but currently + % the Shot= entry is populated by a fixed macro + % frequency is the frequency of signal generation in MARTe2 + % the optional parameter 'ddname' can be given to specify + % the data dictionary where the bus definition is, if omitted + % tcv.sldd is used + + p=inputParser; + addParameter(p,'ddname','tcv.sldd',@(x) ischar(x)); + parse(p,varargin{:}); + ddname = p.Results.ddname; + + dim=obj.mdscontainer.printMARTe2wgbusconfig(shot, ddname, busname, frequency); + end + + function printparameters(obj) + obj.mdscontainer.printparameters; end + + function printwavegens(obj) + obj.mdscontainer.printwavegens; + end + + +%% Configuration methods function obj = addwrapper(obj, inode, icpu, varalgo, wrappername, varargin) @@ -348,13 +561,13 @@ classdef SCDclass_expcode end end - %% update node info + % update node info nodestr=sprintf('node%02d',inode); obj.nodes(inode).varalgo(icpu) = varalgo; obj.nodes(inode).wrapper{icpu} = wrappername; obj.nodes(inode).cpuactive(icpu) = true; obj.nodes(inode).active = true; - %% save in wrapper list + % save in wrapper list tempwrapper=cell(10,1); tempwrapper{1}=p.Results.node; @@ -387,6 +600,7 @@ classdef SCDclass_expcode % Checking and importing algorithm name if(~ismember(algo.getname,obj.algonamelist)) obj.algonamelist{end+1}=algo.getname; + obj.algos{end+1}=algo; else warning('SCDclass_expcode:addalgorithm','algorithm ''%s'' already present in the expcode, skipping!',algo.getname); return; @@ -478,229 +692,50 @@ classdef SCDclass_expcode obj.mdscontainer=obj.mdscontainer.importmdsobjects(expcode.mdscontainer); end - function setup(obj) - % This function sets up the TCV Simulink model - % to simulate this experimental code. - % NOTE THAT it doesn't actualize tunable parameters - % and wavegens, call actualizedata for that - fprintf('Setting up expcode %d, ''%s'', configuring wrappers ...\n',obj.maincode,obj.name); - obj=obj.setupwrappers; - obj.setupvaralgo; - fprintf('Setting up expcode %d, ''%s'', configuring data dictionaries ...\n',obj.maincode,obj.name); - obj.setupwrapdd; - obj.setupalgodd; - fprintf('Setting up expcode %d, ''%s'', configuring global data ...\n',obj.maincode,obj.name); - obj.setupmain; - fprintf('Setting up expcode %d, ''%s'', configuring main workspace variables ...\n',obj.maincode,obj.name); - obj.buildworkspacesimstruct; - obj.buildworkspacetpstruct; - - % Set cache and codegen folders - obj.setcachefolder; - obj.setcodegenfolder; - end - - function actualize(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.modeltoactualize='all'; - else - obj.modeltoactualize=p.Results.model; - end - - obj.actualizedata(shot); - fprintf('Actualizing expcode %d, ''%s'', performing tasks ...\n',obj.maincode,obj.name); - obj.taskcontainer.modeltoexecute=obj.modeltoactualize; - obj.taskcontainer.exectasksoninit(shot); - end - - function actualizedata(obj, shot) - % This function actualizes configured - % tunable parameters and wavegens timeseries - % according to the given shot - - currentexpcode=Simulink.data.evalinGlobal('tcv','scd.expcode'); - if(currentexpcode~=obj.maincode) - error('SCDclass_expcode:wrongexpcodeloaded','Cannot perform data actualization, the loaded expcode is not matching, try to setup the expcode first'); - end - fprintf('Actualizing expcode %d, ''%s'', configuring tunable parameters ...\n',obj.maincode,obj.name); - obj.actualizeparameters(shot) - fprintf('Actualizing expcode %d, ''%s'', configuring wavegens ...\n',obj.maincode,obj.name); - obj.actualizewavegens(shot); - end - - function printparameters(obj) - obj.mdscontainer.printparameters; - end - - function printwavegens(obj) - obj.mdscontainer.printwavegens; - end - - function printtasks(obj) - obj.taskcontainer.printtasks; - end - - function actualizeparameters(obj,shot) - obj.mdscontainer.modeltoactualize=obj.modeltoactualize; - obj.mdscontainer.actualizeparameters(shot); - end - - function actualizewavegens(obj,shot) - obj.mdscontainer.modeltoactualize=obj.modeltoactualize; - obj.mdscontainer.actualizewavegens(shot); - end - - function printinits(obj) - if(~isempty(obj.stdinits)) - for ii=1:numel(obj.stdinits) - fprintf('%s -> %s\n',char(obj.stdinits{ii}{1}),char(obj.stdinits{ii}{2})); - end - end - end + %% Default values setup methods - function callinits(obj) - if(~isempty(obj.algoobjlist)) - for ii=1:numel(obj.algoobjlist) - if nargin==1 - obj.algoobjlist{ii}.callinits(); - elseif nargin==2 - error('this use is deprecated, add tasks instead') - else - error('invalid number of arguments for callinits'); - end - end - 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 - % only on it, otherwise they will be performed on all - % configured models - addParameter(p,'model','',@(x) ischar(x)); - parse(p,varargin{:}); + function updatedefaulttp(obj) + % updatedefaulttp() + % + % updates _tmpl tunparams structures + % for every defined updating function + % To define an update function see SCDclass_algo.addtunparamstruct - if(isempty(p.Results.model)) - obj.mdscontainer.modeltogenerate='all'; - else - obj.mdscontainer.modeltogenerate=p.Results.model; + for ii=1:numel(obj.algonamelist) +% if strcmp(algo, obj.algonamelist{ii}) + obj.algos{ii}.updatetemplatetp(); +% end 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 = MDSSRCSHOT\n"); - fprintf(" Frequency = %.2f\n",frequency); - dim=obj.mdscontainer.printMARTe2wgbusconfig(shot, ddname, busname); - fprintf(" Signals = {\n"); - fprintf(" wavegen_%s = { Type = float32 NumberOfElements = %d }\n", busname, dim ); - fprintf(" }\n"); - fprintf("}\n"); end - function compile(~,varargin) - myslx = SCDclass_expcode.getslxname(varargin{:}); - fprintf('Compiling %s.slx\n',myslx) - try - eval(sprintf('%s([],[],[],''compile'')',myslx)); - eval(sprintf('%s([],[],[],''term'')',myslx)); - catch ME - rethrow(ME) - end - end - - function sim(~,varargin) - SCDconf_setSIMconf - myslx = SCDclass_expcode.getslxname(varargin{:}); - fprintf('Simulating %s.slx\n',myslx) - sim(myslx) - end + end + +%% PRIVATE METHODS + + methods (Access = private) + +%% Matlab environmental setup methods - function open(~,varargin) - openslx = SCDclass_expcode.getslxname(varargin{:}); - fprintf('Opening %s.slx\n',openslx) - open(openslx); + function CacheFolder = setcachefolder(obj) + % Set Cache Folder for experimental code (avoid conflicts with other tmp files) + CacheFolder = fullfile(fileparts(mfilename('fullpath')),'..','..',... + 'gencodes',sprintf('CacheFolder-%d',obj.maincode)); + fprintf('Setting Simulink Cache folder to %s\n',CacheFolder) + Simulink.fileGenControl('set',... + 'CacheFolder',CacheFolder,... + 'createdir',true); end - function build(obj,varargin) - - if numel(varargin)==0 - fprintf('\n=== Building all threads for %s ===\n',obj.name); - % make list of nodes to build - compileslx_list = cell(0); - for inode=1:8 - nodeinfo=obj.nodes(inode); - for icpu = 1:nodeinfo.ncpu - if nodeinfo.cpuactive(icpu) - compileslx_list = [compileslx_list,... - SCDclass_expcode.getslxname(inode,icpu)]; %#ok<AGROW> - end - end - end - - if isempty(compileslx_list) - fprintf('No active nodes found, no .slx to compile. Done\n'); - return - end - else - % 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) - CodeGenFolder = obj.setcodegenfolder; - - % check env variable - assert(~isempty(getenv('RTCCODE_LIBPATH')),'RTCCODE_LIBPATH environment variable needs to be defined to compile'); - - % set configuration settings for compilation - SCDconf_setCODEconf('configurationSettingsCODEicc') - - % Build - try - SCDclass_expcode.build_nodes(compileslx_list); - catch ME - % if fails on first attempt, clear build folder and retry - fprintf(' **** FIRST ATTEMPT BUILDING %s FAILED **** \n',obj.name) - fprintf(' Error message:\n %s\n',getReport(ME)); - fprintf(' Try again clearning build folder\n') - - system(sprintf('rm -rf %s/*',CodeGenFolder)); - SCDclass_expcode.build_nodes(compileslx_list); - end + function CodeGenFolder = setcodegenfolder(obj) + CodeGenFolder = fullfile(fileparts(mfilename('fullpath')),'..','..',... + 'gencodes',sprintf('CodeGenFolder-%d',obj.maincode)); + + fprintf('Setting code generation folder to %s\n',CodeGenFolder) + Simulink.fileGenControl('set',... + 'CodeGenFolder',CodeGenFolder,... + 'createdir',true); end - end - - methods (Access = private) function obj=printlog(obj,str,varargin) % printlog, allows sprintf()-like expressions @@ -914,6 +949,9 @@ classdef SCDclass_expcode inode = obj.activenodes(ii); buildworkspacesimstructnode(obj,inode,dd); end + + evalin('base', 'SCDrefdata = SCDsimdata;'); + end function obj = setupmain(obj) @@ -1043,8 +1081,59 @@ classdef SCDclass_expcode % assign result in base workspace assignin('base','SCDsimdata',SCDsimdata); end - end + +%% Actualization methods + + function actualizedata(obj, shot) + % This function actualizes configured + % tunable parameters and wavegens timeseries + % according to the given shot + + currentexpcode=Simulink.data.evalinGlobal('tcv','scd.expcode'); + if(currentexpcode~=obj.maincode) + error('SCDclass_expcode:wrongexpcodeloaded','Cannot perform data actualization, the loaded expcode is not matching, try to setup the expcode first'); + end + fprintf('Actualizing expcode %d, ''%s'', configuring tunable parameters ...\n',obj.maincode,obj.name); + obj.actualizeparameters(shot) + fprintf('Actualizing expcode %d, ''%s'', configuring wavegens ...\n',obj.maincode,obj.name); + obj.actualizewavegens(shot); + end + + + + function actualizeparameters(obj,shot) + obj.mdscontainer.modeltoactualize=obj.modeltoactualize; + obj.mdscontainer.actualizeparameters(shot); + end + + function actualizewavegens(obj,shot) + obj.mdscontainer.modeltoactualize=obj.modeltoactualize; + obj.mdscontainer.actualizewavegens(shot); + end +%% MDS update methods + + function updatemds(obj, algo, shot) + if shot~=-1 + error('SCDclass_expcode:updatemds','update permitted only on the model shot'); + end + +% % first update algorithm tunparams default locally +% for ii=1:numel(obj.algonamelist) +% if strcmp(algo, obj.algonamelist{ii}) +% obj.algos{ii}.updatetemplatetp(); +% end +% end +% % then update mds + obj.mdscontainer.modeltogenerate=algo; + obj.mdscontainer.autopopulateMDSparams(shot); + obj.mdscontainer.autopopulateMDSwavegens(shot); + end + + + end + + end diff --git a/code/classes/SCDclass_mdsobjcontainer.m b/code/classes/SCDclass_mdsobjcontainer.m index c27b4d36729f44245c8915fa609acd2e8127541a..88b21e74f854f5811dedd5238d9d3bd6f81257ed 100644 --- a/code/classes/SCDclass_mdsobjcontainer.m +++ b/code/classes/SCDclass_mdsobjcontainer.m @@ -250,6 +250,22 @@ classdef SCDclass_mdsobjcontainer end end + function autopopulateMDSparams(obj, shot) + for ii=1:obj.numparams + if(strcmp(obj.modeltogenerate,obj.mdsparams(ii).getmodelname)) + obj.mdsparams(ii).autopopulatemds(shot); + end + end + end + + function autopopulateMDSwavegens(obj, shot) + for ii=1:obj.numwavegens + if(strcmp(obj.modeltogenerate,obj.mdswavegens(ii).getmodelname)) + obj.mdswavegens(ii).autopopulatemds(shot); + end + end + end + function iorder = getParamsServerTreeOrder(obj) % find server-tree order of parameters mdsservertree = cell(numel(obj.mdsparams),2); @@ -260,6 +276,16 @@ classdef SCDclass_mdsobjcontainer [~,iorder] = sortrows(mdsservertree); end + function iorder = geWavegensServerTreeOrder(obj) + % find server-tree order of wavegens + mdsservertree = cell(numel(obj.mdswavegens),2); + for ii=1:numel(obj.mdswavegens) + mdsservertree{ii,1} = obj.mdswavegens(ii).getMDSserver; + mdsservertree{ii,2} = obj.mdswavegens(ii).getMDStree; + end + [~,iorder] = sortrows(mdsservertree); + end + function printMARTe2wgconfig(obj, shot) for ii=1:obj.numwavegens if(strcmp(obj.modeltogenerate,'all')) @@ -274,20 +300,25 @@ classdef SCDclass_mdsobjcontainer end end - function overalldim = printMARTe2wgbusconfig(obj, shot, ddname, busname) + function overalldim = printMARTe2wgbusconfig(obj, shot, ddname, busname, frequency) dd=SCDconf_getdatadict(ddname); bus=dd.getEntry(busname).getValue; nelems=numel(bus.Elements); server=''; tree=''; dimension=0; + overalldim=0; + nwavegen=1; + + fprintf("+MDSWavegen_%s_%d = {\n", busname, nwavegen); + fprintf(" Class = MDSWavegen\n"); + fprintf(" Shot = MDSSRCSHOT\n"); + fprintf(" Frequency = %.2f\n",frequency); for elem=1:nelems signame=bus.Elements(elem).Name; found=false; for wgs=1:obj.numwavegens - %signame - %obj.mdswavegens(wgs).gettarget if(strcmp(obj.mdswavegens(wgs).gettarget,signame)) found=true; break; @@ -296,13 +327,36 @@ classdef SCDclass_mdsobjcontainer if(~found) error('SCDclass_mdsobjcontainer:wgnotfound','Signal %s not found in configured wavegens objects', signame); else + + actserver=obj.mdswavegens(wgs).getMDSserver; acttree=obj.mdswavegens(wgs).getMDStree; if(~strcmp(actserver,server) || ~strcmp(acttree,tree)) if(~strcmp(server,'') || ~strcmp(tree,'')) - error('SCDclass_mdsobjcontainer:multipleconnections','multiple MDS+ connections/trees not supported within the same wavegen generator'); + + fprintf(" Signals = {\n"); + fprintf(" wavegen_%s_%d = { Type = float32 NumberOfElements = %d }\n", busname, nwavegen, dimension); + fprintf(" }\n"); + fprintf("}\n"); + + nwavegen=nwavegen+1; + overlalldim=overalldim+dimension; + dimension=0; + + fprintf("+MDSWavegen_%s_%d = {\n", busname, nwavegen); + fprintf(" Class = MDSWavegen\n"); + fprintf(" Shot = MDSSRCSHOT\n"); + fprintf(" Frequency = %.2f\n",frequency); + server=actserver; + tree=acttree; + fprintf(' Server=%s\n', server); + fprintf(' Tree=%s\n', tree) + + % error('SCDclass_mdsobjcontainer:multipleconnections','multiple MDS+ connections/trees not supported within the same wavegen generator'); else + + server=actserver; tree=acttree; fprintf(' Server=%s\n', server); @@ -316,9 +370,19 @@ classdef SCDclass_mdsobjcontainer end end - - overalldim=dimension; - + fprintf(" Signals = {\n"); + fprintf(" wavegen_%s_%d = { Type = float32 NumberOfElements = %d }\n", busname, nwavegen, dimension); + fprintf(" }\n"); + fprintf("}\n"); + + + if nwavegen>1 + warning('SCDclass_mdsobjcontainer:multipleconnections','multiple MDS+ connections/trees detected, an IOGAM must be used to concatenate wavegens outputs at MARTe2 RTThread level'); + end + + %overalldim=dimension; + %overlalldim=overalldim+dimension; + end function iorder = getWavegensServerTreeOrder(obj) diff --git a/code/classes/SCDclass_mdspar.m b/code/classes/SCDclass_mdspar.m index ab66017586d512876acb6fe8d3615859c34f888e..8050f10b875315d76556bd04ee4696f0f329aca4 100644 --- a/code/classes/SCDclass_mdspar.m +++ b/code/classes/SCDclass_mdspar.m @@ -38,6 +38,9 @@ classdef SCDclass_mdspar < matlab.mixin.Heterogeneous 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 + + mdshelpstr % MDS help string used in tree autopopulation + mdsvalidationstr % MDS validation string used in autopopulation end properties @@ -58,6 +61,8 @@ classdef SCDclass_mdspar < matlab.mixin.Heterogeneous addParameter(obj.cparser,'modeltpstruct','',@(x) ischar(x)); % desttp ? addParameter(obj.cparser,'skippable','false',@(x) ischar(x)); addParameter(obj.cparser,'shot',NaN,@(x) isnumeric(x) && isscalar(x)); + addParameter(obj.cparser,'mdshelp','',@(x) ischar(x)); + addParameter(obj.cparser,'mdsvalid','1',@(x) ischar(x)); obj.verbose=1; obj.matlabseparator='.'; @@ -93,7 +98,8 @@ classdef SCDclass_mdspar < matlab.mixin.Heterogeneous obj.overrideshot=1; obj.overrideshotn=P.shot; end - + obj.mdshelpstr=P.mdshelp; + obj.mdsvalidationstr=P.mdsvalid; end function name=getmodelname(obj) @@ -289,6 +295,69 @@ classdef SCDclass_mdspar < matlab.mixin.Heterogeneous str=martetdi; end + function str = genTDIpopulatecmd(obj) + obj=obj.actualizegetcmd('%s', 1); + tdistr = 'rtcalgo_putparam('; + tdistr = [tdistr '''' obj.tdiexprused ''',']; + str=tdistr; + + end + + function autopopulatemds(obj, shot) + + % original TDI: + % _nodeval = _node//'.value'; + % _nodecom = _node//'.comment'; + % _nodevalid = _validity; + % _expr = 'build_param('//_nodeval//','//_nodecom//','//_nodevalid//')'; + % TreePut(_node,_expr); + % TreePut(_nodeval,'$', _value); + % TreePut(_nodecom,'$', _comment); + + + obj=obj.actualizegetcmd('%s', shot); + node = obj.tdiexprused; + nodeval = [node '.value']; + nodecom = [node '.comment']; + + % workspace version of tunparams + valsrc = [obj.modeltpstruct '.Value.' obj.modeltargetpar]; + val = evalin('base', valsrc); + + % template version of tunparams + %valsrc = [obj.modeltpstruct '_tmpl.Value.' obj.modeltargetpar] + %val = Simulink.data.evalinGlobal(obj.modelname, valsrc); + + fprintf('Changing MDS node: ''%s'' <- %s\n',node, valsrc); + obj.mdsconnect(shot); + + writeval = ['build_param(' nodeval ',' nodecom ',' obj.mdsvalidationstr ')']; + retval=mdsput(node, writeval, 'x'); + if isnumeric(retval) + if ~rem(retval,2) + warning('SCDclass_mdspar:MDSerror','Error writing node build_param.'); + end + else + warning('SCDclass_mdspar:MDSerror','Error writing node build_param.'); + end + + retval=mdsput(nodecom, obj.mdshelpstr); + if isnumeric(retval) + if ~rem(retval,2) + warning('SCDclass_mdspar:MDSerror','Error writing node comment.'); + end + else + warning('SCDclass_mdspar:MDSerror','Error writing node comment.'); + end + + writeval=obj.casttomds(val); + mdsput(nodeval, writeval); + checkval=mdsvalueraw(nodeval); + if ~any(writeval==checkval) + warning('SCDclass_mdspar:MDSerror','Error writing node value.'); + end + + end end @@ -315,6 +384,9 @@ classdef SCDclass_mdspar < matlab.mixin.Heterogeneous % Prints the parameter info summary printinfo(obj) + % cast for mdsput + out = casttomds(obj, in) + end end diff --git a/code/classes/SCDclass_mdspar3Dmatrix.m b/code/classes/SCDclass_mdspar3Dmatrix.m index 7287fb0990fda6a6ff996c191d51a663c3c9a280..a52d4a3f6e45dffd880efe992a77d376d229b104 100644 --- a/code/classes/SCDclass_mdspar3Dmatrix.m +++ b/code/classes/SCDclass_mdspar3Dmatrix.m @@ -37,6 +37,9 @@ classdef SCDclass_mdspar3Dmatrix < SCDclass_mdspar entrystring=[entrystring ' }']; end + function out = casttomds(obj, in) + out = single(in); + end end end diff --git a/code/classes/SCDclass_mdsparboolean.m b/code/classes/SCDclass_mdsparboolean.m index 53c87384fdf46952514ed924f22b710fe659d419..93c89e2d570cd30b1306bd2148f69efd25cf6e56 100644 --- a/code/classes/SCDclass_mdsparboolean.m +++ b/code/classes/SCDclass_mdsparboolean.m @@ -35,7 +35,9 @@ classdef SCDclass_mdsparboolean < SCDclass_mdspar entrystring=[entrystring ' }']; end - + function out = casttomds(obj, in) + out = uint8(in); + end end end diff --git a/code/classes/SCDclass_mdsparenum.m b/code/classes/SCDclass_mdsparenum.m index a99622c95336e27dfc0c7549d96798af587e433b..77a72d18a2af15fa81d9dfd4a9c5aeb1814ba0bd 100644 --- a/code/classes/SCDclass_mdsparenum.m +++ b/code/classes/SCDclass_mdsparenum.m @@ -69,7 +69,8 @@ classdef SCDclass_mdsparenum < SCDclass_mdspar entrystring=obj.genMARTe2entrycommon(shot); % to populate obj.assignvar - obj=obj.setactualizecmds(shot); + %obj=obj.setactualizecmds(shot); + obj=obj.setactualizecmds(); % Enumeration map fill obj=obj.initenummap(); @@ -93,6 +94,11 @@ classdef SCDclass_mdsparenum < SCDclass_mdspar entrystring=[entrystring ' ' enumcode ' ' enumval '}']; end + + function out = casttomds(obj, in) + warning('SCDclass_mdsparenum:casttomdserror','Cast to mds not available for this class.'); + out = []; + end end methods(Access = private) diff --git a/code/classes/SCDclass_mdsparfixdimvector.m b/code/classes/SCDclass_mdsparfixdimvector.m index 22299103f6ce6057a6cbed02b1b9457c8b719824..49e0bf3583e99202f1f185f29f984e5dcad3a459 100644 --- a/code/classes/SCDclass_mdsparfixdimvector.m +++ b/code/classes/SCDclass_mdsparfixdimvector.m @@ -54,8 +54,10 @@ classdef SCDclass_mdsparfixdimvector < SCDclass_mdspar entrystring=[entrystring ' Dim=' num2str(obj.dimension)]; entrystring=[entrystring ' }']; end - + function out = casttomds(obj, in) + out = single(in); + end end end diff --git a/code/classes/SCDclass_mdsparfixdimvectoridx.m b/code/classes/SCDclass_mdsparfixdimvectoridx.m index f6dd7bb8a0f832bbf4be1ab07327ff746afe8aba..709cad629230a385120c730140b924c5f5c3a43a 100644 --- a/code/classes/SCDclass_mdsparfixdimvectoridx.m +++ b/code/classes/SCDclass_mdsparfixdimvectoridx.m @@ -59,7 +59,10 @@ classdef SCDclass_mdsparfixdimvectoridx < SCDclass_mdspar entrystring=[entrystring ' StartIdx=' num2str(obj.idxstart) ' StopIdx=' num2str(obj.idxstop) ' }']; end - + function out = casttomds(obj, in) + warning('SCDclass_mdsparfixdimvectoridx:casttomdserror','Cast to mds not available for this class.'); + out = []; + end end end diff --git a/code/classes/SCDclass_mdsparfixdimvectorint.m b/code/classes/SCDclass_mdsparfixdimvectorint.m index 810b25c48ba0ae6f8a18daa09752098f96876206..da10c99559fa43fb65f05b351ca9671a1eaf9ec9 100644 --- a/code/classes/SCDclass_mdsparfixdimvectorint.m +++ b/code/classes/SCDclass_mdsparfixdimvectorint.m @@ -55,6 +55,10 @@ classdef SCDclass_mdsparfixdimvectorint < SCDclass_mdspar entrystring=[entrystring ' }']; end + function out = casttomds(obj, in) + out = int32(in); + end + end end diff --git a/code/classes/SCDclass_mdsparmatrix.m b/code/classes/SCDclass_mdsparmatrix.m index c62e0b36fc6795cd7d2f4b28863e112037881f55..02317a2aced409caa62b6ef1fe94a5777670e20d 100644 --- a/code/classes/SCDclass_mdsparmatrix.m +++ b/code/classes/SCDclass_mdsparmatrix.m @@ -35,7 +35,10 @@ classdef SCDclass_mdsparmatrix < SCDclass_mdspar entrystring=obj.genMARTe2entrycommon(shot); entrystring=[entrystring ' }']; end - + + function out = casttomds(obj, in) + out = single(in); + end end end diff --git a/code/classes/SCDclass_mdsparmatrixbool.m b/code/classes/SCDclass_mdsparmatrixbool.m index 5bd1f929e595d08da380c419e55313461ba4bebf..6be487555ed85f8154f0ddfe033ddfc001638656 100644 --- a/code/classes/SCDclass_mdsparmatrixbool.m +++ b/code/classes/SCDclass_mdsparmatrixbool.m @@ -35,7 +35,10 @@ classdef SCDclass_mdsparmatrixbool < SCDclass_mdspar entrystring=obj.genMARTe2entrycommon(shot); entrystring=[entrystring ' }']; end - + + function out = casttomds(obj, in) + out = uint8(in); + end end end diff --git a/code/classes/SCDclass_mdsparscalar.m b/code/classes/SCDclass_mdsparscalar.m index 427ab08ef8d89060d99f0bef22367292b62adc6d..45ce4ada72e936ca0c19afa467f846797e7ad43b 100644 --- a/code/classes/SCDclass_mdsparscalar.m +++ b/code/classes/SCDclass_mdsparscalar.m @@ -37,7 +37,9 @@ classdef SCDclass_mdsparscalar < SCDclass_mdspar entrystring=[entrystring ' }']; end - + function out = casttomds(obj, in) + out = single(in); + end end end diff --git a/code/classes/SCDclass_mdsparscalarint.m b/code/classes/SCDclass_mdsparscalarint.m index ce8d5030a8257cc2f3646edbfae8d81168bfd725..7f2bdd60de63955816816f0b5bb74747ee335b0e 100644 --- a/code/classes/SCDclass_mdsparscalarint.m +++ b/code/classes/SCDclass_mdsparscalarint.m @@ -35,7 +35,9 @@ classdef SCDclass_mdsparscalarint < SCDclass_mdspar entrystring=[entrystring ' }']; end - + function out = casttomds(obj, in) + out = int32(in); + end end end diff --git a/code/classes/SCDclass_mdsparscalartaridx.m b/code/classes/SCDclass_mdsparscalartaridx.m index 3835533b660ebfad9b48def50051bff6a9d3cd2f..7a216a1e80c7caef9a99f26f1de64d216f1db11e 100644 --- a/code/classes/SCDclass_mdsparscalartaridx.m +++ b/code/classes/SCDclass_mdsparscalartaridx.m @@ -38,7 +38,12 @@ classdef SCDclass_mdsparscalartaridx < SCDclass_mdspar function entrystring = genMARTe2entry(obj, shot) entrystring =sprintf('%s Idx=%d}',obj.genMARTe2entrycommon(shot),obj.targetidx); end - + + function out = casttomds(obj, in) + warning('SCDclass_mdsparscalartaridx:casttomdserror','Cast to mds not available for this class.'); + out = []; + end + end end diff --git a/code/classes/SCDclass_mdsparvector.m b/code/classes/SCDclass_mdsparvector.m index 78192478389980998443e3ca0b8d3fc3940e6caa..033d1be36e5e6383d07986caf7781cc7fa548953 100644 --- a/code/classes/SCDclass_mdsparvector.m +++ b/code/classes/SCDclass_mdsparvector.m @@ -35,6 +35,9 @@ classdef SCDclass_mdsparvector < SCDclass_mdspar entrystring=[obj.genMARTe2entrycommon(shot) ' }']; end + function out = casttomds(obj, in) + out = single(in); + end end end diff --git a/code/classes/SCDclass_mdsparvectorbool.m b/code/classes/SCDclass_mdsparvectorbool.m index 66845e904ec3f500bb4090bd3efa7f3765e0a746..38f7893cbd1dcf923a1460932c1d41d72cdae541 100644 --- a/code/classes/SCDclass_mdsparvectorbool.m +++ b/code/classes/SCDclass_mdsparvectorbool.m @@ -34,8 +34,10 @@ classdef SCDclass_mdsparvectorbool < SCDclass_mdspar entrystring=obj.genMARTe2entrycommon(shot); entrystring=[entrystring ' }']; end - + function out = casttomds(obj, in) + out = uint8(in); + end end end diff --git a/code/classes/SCDclass_mdsparvectorint.m b/code/classes/SCDclass_mdsparvectorint.m index ed6a1259fc34746bd28a44a735634de7d34effca..6ed4fde11bc792aab8961f838a1a1d931b744918 100644 --- a/code/classes/SCDclass_mdsparvectorint.m +++ b/code/classes/SCDclass_mdsparvectorint.m @@ -34,7 +34,10 @@ classdef SCDclass_mdsparvectorint < SCDclass_mdspar function entrystring = genMARTe2entry(obj, shot) entrystring=[obj.genMARTe2entrycommon(shot) ' }']; end - + + function out = casttomds(obj, in) + out = int32(in); + end end end diff --git a/code/classes/SCDclass_mdswg.m b/code/classes/SCDclass_mdswg.m index ab927704e0123ff2e1fa31bf5384e94cdeaea2d0..8ed0d10a56d3759e4d5d7d096fa83b4fef9c7b60 100644 --- a/code/classes/SCDclass_mdswg.m +++ b/code/classes/SCDclass_mdswg.m @@ -9,7 +9,7 @@ classdef SCDclass_mdswg < matlab.mixin.Heterogeneous mdsserver % The MDS+ server hosting the parameter mdstree % The MDS+ Tree hosting the parameter tdiexpr % TDI expression to retrieve data - wavegenbasestruct % Wavegen base structure hosting the wavegen toimeseries struct + wavegenbasestruct % Wavegen base structure hosting the wavegen timeseries struct wavegentarget % Wavegen target to be filled value % commandile output of the wavegen datadictionary % data dictionary hosting the parameter, if empty base workspace @@ -22,6 +22,9 @@ classdef SCDclass_mdswg < matlab.mixin.Heterogeneous timebasestart % timebase start time variable timebasedt % timebase dt variable timebasestop % timebase stop time variable + + mdshelpstr % MDS help string used in tree autopopulation + mdsvalidationstr % MDS validation string used in autopopulation end properties @@ -38,7 +41,9 @@ classdef SCDclass_mdswg < matlab.mixin.Heterogeneous addParameter(obj.cparser,'srcsrv','tcvdata',@(x) ischar(x)); addParameter(obj.cparser,'srctree','tcv_shot',@(x) ischar(x)); addParameter(obj.cparser,'modelname','',@(x) ischar(x)); - + addParameter(obj.cparser,'mdshelp','',@(x) ischar(x)); + addParameter(obj.cparser,'mdsvalid','1',@(x) ischar(x)); + obj.verbose=1; obj.wavegenbasestruct=''; end @@ -51,7 +56,8 @@ classdef SCDclass_mdswg < matlab.mixin.Heterogeneous obj.tdiexpr=obj.cparser.Results.srctdi; obj.wavegentarget=obj.cparser.Results.destwavegen; obj.modelname=obj.cparser.Results.modelname; - + obj.mdshelpstr=obj.cparser.Results.mdshelp; + obj.mdsvalidationstr=obj.cparser.Results.mdsvalid; end end @@ -136,6 +142,56 @@ classdef SCDclass_mdswg < matlab.mixin.Heterogeneous martetdi=['"' martetdi '"']; str=martetdi; end + + function obj = autopopulatemdscommon(obj, shot, basenode, dim, data, units, srcval) + + fprintf('Changing MDS node: ''%s'' <- %s\n',basenode,srcval); + + node = basenode; + nodeval = [node '.data']; + nodedim = [node '.dim']; + nodecom = [node '.comment']; + nodevalid = obj.mdsvalidationstr; + signal = ['build_signal(build_with_units(' nodeval ',"' units '"),*,build_with_units(' nodedim ',"s"))']; + expr = ['build_param(' signal ',' nodecom ',' nodevalid ')']; + + obj.mdsconnect(shot); + retval=mdsput(node, expr, 'x'); + if isnumeric(retval) + if ~rem(retval,2) + warning('SCDclass_mdswg:MDSerror','Error writing node build_param.'); + end + else + warning('SCDclass_mdswg:MDSerror','Error writing node build_param.'); + end + + retval=mdsput(nodeval, data); + if isnumeric(retval) + if ~rem(retval,2) + warning('SCDclass_mdswg:MDSerror','Error writing node data.'); + end + else + warning('SCDclass_mdswg:MDSerror','Error writing node data.'); + end + + retval=mdsput(nodedim, dim); + if isnumeric(retval) + if ~rem(retval,2) + warning('SCDclass_mdswg:MDSerror','Error writing node dim.'); + end + else + warning('SCDclass_mdswg:MDSerror','Error writing node dim.'); + end + + retval=mdsput(nodecom, obj.mdshelpstr); + if isnumeric(retval) + if ~rem(retval,2) + warning('SCDclass_mdswg:MDSerror','Error writing node comment.'); + end + else + warning('SCDclass_mdswg:MDSerror','Error writing node comment.'); + end + end end @@ -161,6 +217,10 @@ classdef SCDclass_mdswg < matlab.mixin.Heterogeneous % Prints the parameter info summary printinfo(obj) + + % Populates the corresponding MDS node with workspace values + autopopulatemds(obj, shot) + end end diff --git a/code/classes/SCDclass_mdswgsigarray1.m b/code/classes/SCDclass_mdswgsigarray1.m index d045e040fd5a62702e5df3659c2d4bbb9195f17f..0b961d2ba53fc22afff1712c718a6e95630da62c 100644 --- a/code/classes/SCDclass_mdswgsigarray1.m +++ b/code/classes/SCDclass_mdswgsigarray1.m @@ -153,8 +153,7 @@ classdef SCDclass_mdswgsigarray1 < SCDclass_mdswg entrystring=obj.genMARTe2entrycommon(shot); entrystring=[entrystring ' StartIdx=' num2str(obj.srcstartidx) ' StopIdx=' num2str(obj.srcstopidx) ' }']; end - - + % * S_uint8 = { % * NodeName = "S_uint8" // node of the tree node @@ -175,7 +174,25 @@ classdef SCDclass_mdswgsigarray1 < SCDclass_mdswg end end - + function autopopulatemds(obj, shot) + baseparam=strrep(obj.wavegenbasestruct,'SCDsimdata','SCDrefdata'); % name of base workspace structure + + structparam=obj.wavegentarget; % name of target field + wgentryval = evalin('base',baseparam); % structure of wavegen in base workspace + + sourceidxs=obj.srcstartidx:obj.srcstopidx; + destidxs=obj.deststartidx:obj.deststopidx; + assert(numel(sourceidxs)==numel(destidxs), 'SCDclass_mdswgsigarray1: destination channel count is different w.r.t. source'); + + for ii = obj.deststartidx:obj.deststopidx + data = wgentryval.(structparam).Data(:,ii); + dim = wgentryval.(structparam).Time; + units = wgentryval.(structparam).DataInfo.Units; + mdschannel=sprintf(obj.tdiexpr, sourceidxs(ii)); + + obj.autopopulatemdscommon(shot, mdschannel, dim, data, units, [baseparam '.' structparam '[' num2str(ii) ']']); + end + end end end diff --git a/code/classes/SCDclass_mdswgsigsingle.m b/code/classes/SCDclass_mdswgsigsingle.m index 4bf6ba108b59da0dc54cc4a79a0d010219f5879c..638f24ad612e380cf785a849189b7ab08f993e4b 100644 --- a/code/classes/SCDclass_mdswgsigsingle.m +++ b/code/classes/SCDclass_mdswgsigsingle.m @@ -2,7 +2,7 @@ classdef SCDclass_mdswgsigsingle < SCDclass_mdswg % This class loads a signal from MDS+ and puts it into % the target wavegen timeseries, the signal postition % in the target timeseries structure is remapped according to - % the optional destidx constructor parameter. If it is not + % the optional destindex constructor parameter. If it is not % specified, no remapping takes places (1-1 load) properties @@ -121,110 +121,24 @@ classdef SCDclass_mdswgsigsingle < SCDclass_mdswg end function entrystring = genMARTe2entry(obj, shot) + if obj.destidx~=1 + error('SCDclass_mdswgsigsingle:marteerror', 'MARTe2 remapping not yet implemented'); + end entrystring=[obj.genMARTe2entrycommon(shot) ' }']; end + function autopopulatemds(obj, shot) + baseparam=strrep(obj.wavegenbasestruct,'SCDsimdata','SCDrefdata'); % name of base workspace structure + + structparam=obj.wavegentarget; % name of target field + wgentryval = evalin('base',baseparam); % structure of wavegen in base workspace + + data = wgentryval.(structparam).Data(:,obj.destidx); + dim = wgentryval.(structparam).Time; + units = wgentryval.(structparam).DataInfo.Units; + + obj.autopopulatemdscommon(shot, obj.tdiexpr, dim, data, units, [baseparam '.' structparam '[' num2str(obj.destidx) ']']); + end end end - - - -% methods(Access=protected) -% -% function actualizedatadd(obj, shot) -% % Actualizes data in the data dictionary -% % BEWARE at saving and committing big dimension useless -% % data dictionaries -% -% errstr=sprintf('%s:actualizedatadd', obj.classname); -% error(errstr,'actualizing wavegens on data dictionaries not supported'); -% -% mdsconnect(obj.mdsserver); -% mdsopen(obj.mdstree, shot); -% -% if obj.verbose==1 -% fprintf('Actualizing (DATADICT!) wavegen: ''%s'' [%d] <- ''%s'' (%s, shot %d)\n', ... -% obj.wavegentarget, obj.destidx, ... -% obj.tdiexpr, ... -% obj.classname, shot); -% end -% -% value=obj.getdata(); -% -% % We need to access the data dictionary directly here, -% % no way to used automatic dd assign and eval functions, -% % they do not work with timeseries -% -% d=Simulink.data.dictionary.open(sprintf('%s.sldd',obj.modelname)); -% dd=getSection(d, 'Design Data'); -% -% pointspos=strfind(obj.wavegentarget,'.'); -% baseparam=obj.wavegentarget(1:pointspos(1)-1); -% structparam=obj.wavegentarget(pointspos(1)+1:end); -% wgentry=dd.getEntry(baseparam); -% wgentryval=wgentry.getValue; -% -% 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); -% -% eval(assigncmdtime); -% eval(assigncmddata); -% end -% -% wgentry.setValue(wgentryval); -% -% end -% -% -% -% function cleandata(obj) -% -% error('SCDclass_mdswgsigsingle:cleandata','cleandata has been deprecated'); -% -% -% if obj.verbose==1 -% fprintf('Cleaning wavegen: %s [%d] (%s)\n', ... -% obj.wavegentarget, obj.destidx, ... -% obj.classname); -% end -% -% d=Simulink.data.dictionary.open(sprintf('%s.sldd',obj.modelname)); -% dd=getSection(d, 'Design Data'); -% -% pointspos=strfind(obj.wavegentarget,'.'); -% baseparam=obj.wavegentarget(1:pointspos(1)-1); -% structparam=obj.wavegentarget(pointspos(1)+1:end); -% wgentry=dd.getEntry(baseparam); -% wgentryval=wgentry.getValue; -% -% datasizecmd=sprintf('datasize=size(wgentryval.%s.Data);',structparam); -% eval(datasizecmd); -% datasize=datasize(2); -% -% emptyts=timeseries; -% emptyts.Time=[0;1]; -% emptyts.Data=single(zeros(2,datasize)); -% -% assigncmd=sprintf('wgentryval.%s=emptyts;',structparam); -% eval(assigncmd); -% wgentry.setValue(wgentryval); -% -% -% end -% -% -% end -% diff --git a/test/disablesignalslog.m b/test/disablesignalslog.m deleted file mode 100644 index 84d69c0b5a34df05ddb646b95197e46381914f16..0000000000000000000000000000000000000000 --- a/test/disablesignalslog.m +++ /dev/null @@ -1,36 +0,0 @@ -% DEPRECATED JUST AFTER WRITTEN, USE DEL IN THE SIMULATION DATA INSPECTOR -% TO DELETE LOGGED SIGNALS -% This function parses automatically -% all signals of the given modelname -% (comprising all submodels) -% and asks whether to disable log for -% signals (which are marked for logging) - -function disablesignalslog(topmodelname) - disp('Getting mdlrefs info ...'); - [models,blocks]=find_mdlrefs(topmodelname); - for mod=1:numel(models) - fprintf(['Analyzing model ' char(models{mod}) '\n']); - disablesignalslogsinglemodel(models{mod}); - end -end - -function disablesignalslogsinglemodel(modelname) -load_system(modelname); -mdlsignals = find_system(modelname,'FindAll','on','LookUnderMasks','all','FollowLinks','on','type','line','SegmentType','trunk'); -ph = get_param(mdlsignals,'SrcPortHandle'); -for i=1: length(ph) - try - if strcmp(get_param(ph{i},'datalogging'),'on') - answer=input(['MDL: ' modelname ' SIG: ' get_param(ph{i},'Name') ' log is ' get_param(ph{i},'datalogging') ', turn off? [Y/N]:'],'s'); - if strcmp(answer,'Y') - set_param(ph{i},'datalogging','off'); - end - end - catch ME - continue; - end -end -save_system(modelname); -close_system(modelname); -end \ No newline at end of file diff --git a/tools/disablesignalslog.m b/tools/disablesignalslog.m new file mode 100644 index 0000000000000000000000000000000000000000..7138dcb3346a45b5381e0147a8bc158c5c547ece --- /dev/null +++ b/tools/disablesignalslog.m @@ -0,0 +1,57 @@ +% This function parses automatically +% all signals of the given modelname +% (comprising all submodels) +% and asks whether to disable log for +% signals (which are marked for logging) +% +% the function asks before removing any logging +% unless the additional parameter couple 'force', 1 +% is given in varargin +% +% it seems that the Simulink Data Inspector +% is resilient to this changes +% try this: +% 1) Simulink.sdi.clear +% 2) restart Matlab +% 3) Delete signals manually there + + +function disablesignalslog(topmodelname,varargin) + P=inputParser; + P.addParameter('force',0); + P.parse(varargin{:}); + + force=P.Results.force; + + disp('Getting mdlrefs info ...'); + [models,blocks]=find_mdlrefs(topmodelname); + for mod=1:numel(models) + fprintf(['Analyzing model ' char(models{mod}) '\n']); + disablesignalslogsinglemodel(models{mod},force); + end +end + +function disablesignalslogsinglemodel(modelname,force) +load_system(modelname); +mdlsignals = find_system(modelname,'FindAll','on','LookUnderMasks','all','FollowLinks','on','type','line','SegmentType','trunk'); +ph = get_param(mdlsignals,'SrcPortHandle'); +for i=1: length(ph) + try + if strcmp(get_param(ph{i},'datalogging'),'on') + if ~force + answer=input(['MDL: ' modelname ' SIG: ' get_param(ph{i},'Name') ' log is ' get_param(ph{i},'datalogging') ', turn off? [Y/N]:'],'s'); + else + fprintf(['MDL: ' modelname ' SIG: ' get_param(ph{i},'Name') ' disabling logging.\n']); + answer='Y'; + end + if strcmp(upper(answer),'Y') + set_param(ph{i},'datalogging','off'); + end + end + catch ME + continue; + end +end +save_system(modelname); +close_system(modelname); +end \ No newline at end of file