classdef SCDclass_mdspar < matlab.mixin.Heterogeneous % Superclass for MDS+ parameters % the superclass matlab.mixin.Heterogeneous allows % bilding of lists of mixed kind parameters in the % expcode configuration (and later in C++ code) % For all subclasses, by default all NaN values are converted to 0 properties (Access = protected) mdsserver % The MDS+ server hosting the parameter mdstree % The MDS+ Tree hosting the parameter tdiexprmodel % TDI expression to retrieve data when invoked with -1 shot tdiexprshot % TDI expression to retrieve data when invoked with a give shotno, if empty the -1 is used tdiexprused % TDI expression actually used %tdiexprmarte % TDI expression actually used converted to MARTe cfg convections modelparam % Full expansion of the model target parameter (modeltpstruct+modeltargetpar) modelparammarte % Full expansion of the model target oarameter (modeltpstruct+modeltargetpar) with marte separators modeltpstruct % target tunable parameter structure, if left empty it will be filled once binding to an algorithm modeltargetpar % Model parameter w/o tunable parameters structure value % value of the parameter datadictionary % data dictionary hosting the parameter, if empty base workspace modelname % name of the Simulink model using the parameter getcommand % full command for getting the value (callable by matlab eval) classname % class name for logging marteclassname % class name for generating MARTe2 cfg file cparser % constructor parameters parser skippable % true if the parameters loading can be skipped during the actualization process and default value used, unused for now matlabseparator % structure separator character used in MAtlab/Simulink marteseparator % structure separator character used in MARTe2 assignvar % actualizedata specific assignstring % actualizedata specific denanstring % actualizedata specific caststring % actualizedata specific 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 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 properties verbose % Verbosity of the class end methods function obj=SCDclass_mdspar() obj.cparser=inputParser; addRequired(obj.cparser,'srctdimodel',@(x) ischar(x)); addRequired(obj.cparser,'destparam',@(x) ischar(x)); addParameter(obj.cparser,'srcsrv','tcvdata',@(x) ischar(x)); addParameter(obj.cparser,'srctree','tcv_shot',@(x) ischar(x)); addParameter(obj.cparser,'srctdishot','',@(x) ischar(x)); addParameter(obj.cparser,'modelname','',@(x) ischar(x)); addParameter(obj.cparser,'datadictname','',@(x) ischar(x)); 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)); obj.verbose=1; obj.matlabseparator='.'; obj.marteseparator='-'; end function obj=parseconstructorcommon(obj, srctdimodel, destparam, varargin) parse(obj.cparser,srctdimodel,destparam,varargin{:}{:}); obj.mdsserver=obj.cparser.Results.srcsrv; obj.mdstree=obj.cparser.Results.srctree; obj.tdiexprmodel=obj.cparser.Results.srctdimodel; if isempty(obj.cparser.Results.srctdishot) obj.tdiexprshot=obj.cparser.Results.srctdimodel; else obj.tdiexprshot=obj.cparser.Results.srctdishot; end obj.modeltargetpar=obj.cparser.Results.destparam; obj.modelname=obj.cparser.Results.modelname; obj.datadictionary=obj.cparser.Results.datadictname; obj.modeltpstruct=obj.cparser.Results.modeltpstruct; obj.skippable=obj.cparser.Results.skippable; if isempty(obj.cparser.Results.srctdimodel) obj.unlinked=1; else obj.unlinked=0; end if isnan(obj.cparser.Results.shot) obj.overrideshot=0; else obj.overrideshot=1; obj.overrideshotn=obj.cparser.Results.shot; end end function name=getmodelname(obj) name=obj.modelname; end end % Not abstract methods common to all child classes methods function 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; else localshot = shot; end s=mdsopen(obj.mdstree, localshot); str=sprintf('SCDclass_mdsparam (%s), failed opening MDS+ tree', obj.modelparam); assert(s==localshot, str); end function obj=setactualizecmds(obj, shot) 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.value]=obj.getdata(shot); if ~obj.actualizable, return; end obj=obj.setactualizecmds(shot); end end function obj=postactualizecommon(obj, shot) if(~obj.unlinked) if obj.verbose==1 if obj.overrideshot == 1 localshot = obj.overrideshotn; else localshot = shot; end fprintf('Actualizing parameter: ''%s'' <- ''%s'' (%s, shot %d)\n', obj.modelparam, obj.tdiexprused, obj.classname, localshot); end evalin('base', obj.assignstring); evalin('base', obj.denanstring); evalin('base', obj.caststring); else fprintf('Actualizing parameter: ''%s'', parameter unlinked, SKIPPED!\n', obj.modelparam); end end function [obj,value]=getdatacommon(obj, shot) obj=obj.actualizegetcmd('mdsvalue(''%s'')', shot); value=eval(obj.getcommand); 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 obj.actualizable=true; end end function obj=actualizegetcmd(obj, cmdstring, shot) if(shot==-1) obj.getcommand=sprintf(cmdstring, obj.tdiexprmodel); obj.tdiexprused=obj.tdiexprmodel; else obj.getcommand=sprintf(cmdstring, obj.tdiexprshot); obj.tdiexprused=obj.tdiexprshot; end obj.modelparam=[obj.modeltpstruct '.' obj.modeltargetpar]; obj.modelparammarte = strrep(obj.modelparam, obj.matlabseparator, obj.marteseparator); end function obj=actualizetdiexpr(obj, shot) if(shot==-1) obj.tdiexprused=obj.tdiexprmodel; else obj.tdiexprused=obj.tdiexprshot; end end function printinfocommon(obj) fprintf('%s (class %s):\n', obj.modelparam, obj.classname); fprintf(' Simulink model: ''%s'', data dictionary: ''%s''\n', obj.modelname, obj.datadictionary); if(~obj.unlinked) fprintf(' MDS+ source server: ''%s'', Tree: ''%s''\n', obj.mdsserver, obj.mdstree); fprintf(' MDS+ TDI expressions, model: ''%s''', obj.tdiexprmodel); if(strcmp(obj.tdiexprmodel, obj.tdiexprshot)) fprintf(', shot: same'); else fprintf(', shot: ''%s''', obj.tdiexprshot); end if obj.overrideshot == 1 fprintf(', WARNING: shot ovr to %d.\n', obj.overrideshotn); else fprintf('.\n'); end else fprintf(' UNLINKED!\n'); end end function out = gettargetparam(obj) out = obj.modelparam; end function out = gettargetparammarte(obj) out = obj.modelparammarte; end function [mdsserver] = getMDSserver(obj) mdsserver = obj.mdsserver; end function [mdstree] = getMDStree(obj) mdstree = obj.mdstree; end function obj = setparamstructure(obj, structname) %obj.modelparam = [structname '.' obj.modelparam]; if(isempty(obj.modeltpstruct)) obj.modeltpstruct = structname; end obj.modelparam=[obj.modeltpstruct '.' obj.modeltargetpar]; obj.modelparammarte = strrep(obj.modelparam, obj.matlabseparator, obj.marteseparator); end function obj = setmodelname(obj, modelname) if(isempty(obj.modelname)) obj.modelname = modelname; end end function obj = setdatadictionary(obj, ddname) if(isempty(obj.datadictionary)) obj.datadictionary = ddname; end end end methods function entrystring = genMARTe2entrycommon(obj, shot) obj=obj.actualizetdiexpr(shot); %entrystring = sprintf('+%-50s = { Class=%-30s Path=%-40s',obj.gettargetparammarte,obj.marteclassname,obj.tdiexprused); entrystring = sprintf('+%-50s = { Class=%-30s Path=%-40s',obj.gettargetparammarte,obj.marteclassname,obj.genMARTe2MDStdiexpression); end function str = genMARTe2MDSsourcestr(obj) %str = sprintf(' +MDSSource = {\n Class=SPCMDSSource\n Server=%s\n Tree=%s',obj.mdsserver,obj.mdstree); str = sprintf(' +Connection_%s_%s = {\n Class=MDSObjConnection\n Server=%s\n Tree=%s',obj.mdsserver,obj.mdstree,obj.mdsserver,obj.mdstree); end function str = genMARTe2MDStdiexpression(obj) % Duplicate first backslash % if(obj.tdiexprused(1)=='\' && not(obj.tdiexprused(2)=='\')) % martetdi=['\' obj.tdiexprused]; % else % martetdi=obj.tdiexprused; % end % Duplicate backslashes martetdi=strrep(obj.tdiexprused, '\', '\\'); %substitute every " with ' martetdi=strrep(martetdi, '"', ''''); %put double string quota martetdi=['"' martetdi '"']; str=martetdi; end end % Abstract method actually implemented by child classes methods (Abstract) % Gets data from MDS+ and actualizes it on the model, % Connects to MDS+ and opens the tree, to be % improved via container class of this class actualizedata(obj, shot) % Gets data from mds, mds connection is assumed already estabilished % and tree opened [obj, value] = getdata(obj, shot) % Generate C++ code %gencode(obj) % Generate MARTe2 configuration entry entrystring = genMARTe2entry(obj, shot) % Prints the parameter info summary printinfo(obj) end end