diff --git a/algos/cfs-template/algo_cfgtemplate1_harness_run.m b/algos/cfs-template/algo_cfgtemplate1_harness_run.m new file mode 100644 index 0000000000000000000000000000000000000000..c24b0265dc6fa107b140a272c047911afb492573 --- /dev/null +++ b/algos/cfs-template/algo_cfgtemplate1_harness_run.m @@ -0,0 +1,69 @@ +function algo_template_harness_run(obj) +% run harness and check the result + +% load tunable control parameters from mds +shot = 100; % shot reference +obj.actualize(shot); + +% Input Data - must be structure of timeseries matching input bus structure +% time = 0:obj.gettiming.dt:1; +% data = single(sin(2*pi*time*10)'); +% % NB: these struct name and types must match the corresponding data bus +% tsStructData = struct('simple_signal',timeseries(data,time,'Name','Test Input Data')); + +% SimIn object to customize configuration of Simulation run for test +SimIn = Simulink.SimulationInput([obj.getname '_harness']); + +% Create template Input dataset for this model +% Dataset = createInputDataset(obj.getname); + +% assign input data signal to Simulink.Signal object +% DataIn = Simulink.SimulationData.Signal; +% DataIn.Values = tsStructData; + +% assign as first element in input data set +% isig = find(contains(Dataset.getElementNames,'signal_in')); % find input signal index +% Dataset = Dataset.setElement(isig,DataIn); %#ok<FNDSB> +% SimIn.ExternalInput = Dataset; % assign this as external input for simulation + +% Custom parameters for this run to save outport data +SimIn = SimIn.setModelParameter('SaveOutput','on'); % set to save outport signals +SimIn = SimIn.setModelParameter('SignalLogging','on'); % set to save log signals +SimIn = SimIn.setModelParameter('OutputSaveName','SimOut'); +SimIn = SimIn.setModelParameter('SaveFormat','Dataset'); +SimIn = SimIn.setModelParameter('StartTime',num2str(obj.gettiming().t_start)); +SimIn = SimIn.setModelParameter('StopTime',num2str(obj.gettiming().t_stop)); +SimIn = SimIn.setModelParameter('FixedStep',num2str(obj.gettiming().dt)); + +% simulate - simulate only single types to save time +result = sim(SimIn); + +% check output port data +tp = Simulink.data.evalinGlobal(obj.getname,'algo_template_tp.Value'); +fp = Simulink.data.evalinGlobal(obj.getname,'algo_template_fp'); + +input = evalin('base','algo_template_inbus1'); +input1 = input.signal1.Data; +input2 = input.signal2.Data; + +output1 = result.simout.signal1.Data; +output2 = result.simout.signal2.Data; + +size(input1) +size(output1) + +maxerror1 = 0.1; +maxerror2 = 0.1; +assert(max(abs(output1 - input1.*tp.gain))<maxerror1,'Wrong output 1!'); +assert(max(abs(output2 - (input2.*tp.refmodel.gain+fp.refmodel.offset)))<maxerror2,'Wrong output 2!'); + +% check logs which contain a SCDsignal type data +% logsout = result.logsout; +% +% signal = logsout.getElement('SCDsignal type bus').Values.Value; +% Quality = logsout.getElement('SCDsignal type bus').Values.QualityTag; +% State = logsout.getElement('SCDsignal type bus').Values.ProductionState; +% +% assert(all(State .Data == ProductionState.RUNNING),'ProductionState must be RUNNING'); +% assert(all(Quality.Data == QualityTag.GOOD ),'QualityTag must be RUNNING' ); +end diff --git a/algos/cfs-template/algo_cfstemplate1.slx b/algos/cfs-template/algo_cfstemplate1.slx new file mode 100644 index 0000000000000000000000000000000000000000..2759c85d3e689413b87a5c682b8a256cc4371ef1 Binary files /dev/null and b/algos/cfs-template/algo_cfstemplate1.slx differ diff --git a/algos/cfs-template/algo_cfstemplate1_harness.slx b/algos/cfs-template/algo_cfstemplate1_harness.slx new file mode 100644 index 0000000000000000000000000000000000000000..6beba1d4535228191471cd1460a5ca438f669736 Binary files /dev/null and b/algos/cfs-template/algo_cfstemplate1_harness.slx differ diff --git a/algos/cfs-template/algo_cfstemplate1_inBus_def.m b/algos/cfs-template/algo_cfstemplate1_inBus_def.m new file mode 100644 index 0000000000000000000000000000000000000000..9cf6ec1c29c05725798261f335cdc3aa5f60574f --- /dev/null +++ b/algos/cfs-template/algo_cfstemplate1_inBus_def.m @@ -0,0 +1,33 @@ +% Bus object: SCDalgo_template_inBus +clear elems; +elems(1) = Simulink.BusElement; +elems(1).Name = 'signal1'; +elems(1).Dimensions = 1; +elems(1).DimensionsMode = 'Fixed'; +elems(1).DataType = 'single'; +elems(1).SampleTime = -1; +elems(1).Complexity = 'real'; +elems(1).Min = []; +elems(1).Max = []; +elems(1).DocUnits = ''; +elems(1).Description = ''; + +elems(2) = Simulink.BusElement; +elems(2).Name = 'signal2'; +elems(2).Dimensions = 1; +elems(2).DimensionsMode = 'Fixed'; +elems(2).DataType = 'single'; +elems(2).SampleTime = -1; +elems(2).Complexity = 'real'; +elems(2).Min = []; +elems(2).Max = []; +elems(2).DocUnits = ''; +elems(2).Description = ''; + +algo_template_inBus = Simulink.Bus; +algo_template_inBus.HeaderFile = ''; +algo_template_inBus.Description = ''; +algo_template_inBus.DataScope = 'Auto'; +algo_template_inBus.Alignment = -1; +algo_template_inBus.Elements = elems; +clear elems; diff --git a/algos/cfs-template/algo_cfstemplate1_loadfp.m b/algos/cfs-template/algo_cfstemplate1_loadfp.m new file mode 100644 index 0000000000000000000000000000000000000000..2fd64eb55fe35ec632a907cc6088d207c78baafb --- /dev/null +++ b/algos/cfs-template/algo_cfstemplate1_loadfp.m @@ -0,0 +1,6 @@ +function fp = algo_template_loadfp(obj) + +%% Load other fixed parameters +fp.timing = obj.gettiming; +fp.refmodel.offset = 1; % a fixed parameter +end \ No newline at end of file diff --git a/algos/cfs-template/algo_cfstemplate1_loadtp.m b/algos/cfs-template/algo_cfstemplate1_loadtp.m new file mode 100644 index 0000000000000000000000000000000000000000..1c08d9286f2f173a425caf3672d100c7adcde017 --- /dev/null +++ b/algos/cfs-template/algo_cfstemplate1_loadtp.m @@ -0,0 +1,11 @@ +function TP = algo_template_loadtp() +% Setup tunable control params + +TP.enable = true; +TP.gain = single(2); +TP.refmodel.gain = single(4); % another gain used in referenced model +TP.rowvect = int32([1 2 3]); +TP.colvect = int16([1 2 3]'); +TP.matrix = int8([1 2; 3 4]); + +end diff --git a/algos/cfs-template/algo_cfstemplate1_outBus_def.m b/algos/cfs-template/algo_cfstemplate1_outBus_def.m new file mode 100644 index 0000000000000000000000000000000000000000..3acb8cd5d98cbcc0aa9c2deebd1c1f91dc8df786 --- /dev/null +++ b/algos/cfs-template/algo_cfstemplate1_outBus_def.m @@ -0,0 +1,35 @@ +% Bus object: SCDalgo_template_outBus +clear elems; +elems(1) = Simulink.BusElement; +elems(1).Name = 'signal1'; +elems(1).Dimensions = 1; +elems(1).DimensionsMode = 'Fixed'; +%elems(1).DataType = 'Bus:SCDBus_single_11_Vector'; +elems(1).DataType = 'single'; +elems(1).SampleTime = -1; +elems(1).Complexity = 'real'; +elems(1).Min = []; +elems(1).Max = []; +elems(1).DocUnits = ''; +elems(1).Description = ''; + +elems(2) = Simulink.BusElement; +elems(2).Name = 'signal2'; +elems(2).Dimensions = 1; +elems(2).DimensionsMode = 'Fixed'; +%elems(2).DataType = 'Bus:SCDBus_int32_Scalar'; +elems(2).DataType = 'single'; +elems(2).SampleTime = -1; +elems(2).Complexity = 'real'; +elems(2).Min = []; +elems(2).Max = []; +elems(2).DocUnits = ''; +elems(2).Description = ''; + +algo_template_outBus = Simulink.Bus; +algo_template_outBus.HeaderFile = ''; +algo_template_outBus.Description = ''; +algo_template_outBus.DataScope = 'Auto'; +algo_template_outBus.Alignment = -1; +algo_template_outBus.Elements = elems; +clear elems; diff --git a/algos/cfs-template/algo_cfstemplate1_signal_buses.m b/algos/cfs-template/algo_cfstemplate1_signal_buses.m new file mode 100644 index 0000000000000000000000000000000000000000..82c52b2d9e153d06db5d81c609e7203fd7c81de3 --- /dev/null +++ b/algos/cfs-template/algo_cfstemplate1_signal_buses.m @@ -0,0 +1,47 @@ +function [busNames,Buses] = algo_template_signal_buses() +% [busNames,Buses] = SCDalgo_template_signal_buses() +% Define some buses needed for the template + +%% Define signal buses for various SCDsignal types +% Data examples for which to create buses +D = {... + ones(11,1,'single'),... + ones(3,3,'single'),... + int32(1)}; + +% Create buses for these signals and add them to the list +[Buses,busNames] = deal(cell(numel(D),1)); % init +for ii = 1:numel(D) + mydata = D{ii}; + mysig = SCDsignal(mydata); % create SCDsignal object for this data example + mybus = mysig.createBus; % create Bus for this signal using object method + % Store + Buses{ii} = mybus; + busNames{ii} = mybus.Description; +end + +%% Add output structure: a bus that includes only SCDsignal data types + +% First add 3 busElements for the three signals defined above +for ii=1:3 +elems(ii) = Simulink.BusElement; +elems(ii).Name = sprintf('signal%d',ii); +elems(ii).Dimensions = 1; +elems(ii).DimensionsMode = 'Fixed'; +elems(ii).DataType = sprintf('Bus: %s',busNames{ii}); +end + +% Define output bus with these elements +outBus = Simulink.Bus; +outBus.HeaderFile = ''; +outBus.Description = ''; +outBus.DataScope = 'Auto'; +outBus.Alignment = -1; +outBus.Elements = elems; +clear elems; + +% append to list +busNames{end+1} = 'algo_template_bus1'; +Buses{end+1} = outBus; + +end diff --git a/algos/cfs-template/algo_cfstemplate1_test.m b/algos/cfs-template/algo_cfstemplate1_test.m new file mode 100644 index 0000000000000000000000000000000000000000..d37df45c34dd9e4235cc6bddf911856aed141cea --- /dev/null +++ b/algos/cfs-template/algo_cfstemplate1_test.m @@ -0,0 +1,7 @@ +classdef algo_template_test < SCDalgo_test + + properties + algoobj = algoobj_template(); + end + +end \ No newline at end of file diff --git a/algos/cfs-template/algoobj_cfstemplate1.m b/algos/cfs-template/algoobj_cfstemplate1.m new file mode 100644 index 0000000000000000000000000000000000000000..80ce3b87bc1ef0030c59c55e37b42eeb978000ab --- /dev/null +++ b/algos/cfs-template/algoobj_cfstemplate1.m @@ -0,0 +1,42 @@ +function obj = algoobj_cfstemplate1() + +%% Doublets SPC controller algorithm +obj = SCDclass_algo('algo_cfstemplate1'); + +%% Timing of the algorithm +obj=obj.settiming(-1,1e-3,1.0); + +%% Fixed parameters init functions +obj=obj.addfpinitfcn('algo_cfstemplate1_loadfp','algo_cfstemplate1_fp'); + +%% Tunable parameters structure name +obj=obj.addtunparamstruct('algo_cfstemplate1_tp', @()algo_cfstemplate1_loadtp(), false); + +%% Tunable parameters +parshot=10; +obj=obj.addparameter(SCDclass_mdsparnumeric('kb1','enable' ,'srcsrv','spcpc171.epfl.ch','srctree','martetest','shot',parshot)); +obj=obj.addparameter(SCDclass_mdsparnumeric('ks1','gain' ,'srcsrv','spcpc171.epfl.ch','srctree','martetest','shot',parshot)); +obj=obj.addparameter(SCDclass_mdsparnumeric('kv1','rowvect' ,'srcsrv','spcpc171.epfl.ch','srctree','martetest','shot',parshot)); +obj=obj.addparameter(SCDclass_mdsparnumeric('kv2','colvect' ,'srcsrv','spcpc171.epfl.ch','srctree','martetest','shot',parshot)); +obj=obj.addparameter(SCDclass_mdsparnumeric('km1','matrix' ,'srcsrv','spcpc171.epfl.ch','srctree','martetest','shot',parshot)); + +%% Wavegens +obj=obj.addwavegenbasetruct('algo_cfstemplate1_inbus'); +obj=obj.addwavegen(SCDclass_mdswgsigsingle( 'ai.ch001','signal1' ,'srcsrv','spcpc171.epfl.ch','srctree','martetest','shot',parshot)); +obj=obj.addwavegen(SCDclass_mdswgsigsingle( 'ai.ch002','signal2' ,'srcsrv','spcpc171.epfl.ch','srctree','martetest','shot',parshot)); + + +%% Buses +obj = obj.addbus('algo_template_inBus', 'algo_template_inBus_def' ); +obj = obj.addbus('algo_template_outBus', 'algo_template_outBus_def' ); + % function handle that returns cell arays of buses and busnames to be + % registered +obj = obj.addbus('',@() algo_template_signal_buses()); + +%% Tasks + +%% Print (optional) +obj.printinfo; + +end +