Skip to content
Snippets Groups Projects
SCDsignal_test.m 5.08 KiB
classdef SCDsignal_test < matlab.unittest.TestCase
  
  properties (MethodSetupParameter)
    type = {'logical','single','int32','single'};
    m    = {1,       100,      3,        3      };
    n    = {1,         1,      3,       10      };
  end
  
  properties
    sig; % signal object to be tested
    bus; % associated bus
    modelname = 'SCDsignal_tester'; % slx model name for signal testing
  end
  
  methods (TestClassSetup)
    function load_slx(testCase)
      % load SLX used for testing
       load_system(testCase.modelname);
    end
  end
  
  methods (TestMethodSetup,ParameterCombination = 'sequential')
    function build_sig_and_bus(testCase,m,n,type)
      % build signal and associated bus used for testing
      testCase.assumeFalse(n>1 && m==1,'skip row vector cases due to matlab bug');
      
      data = cast(rand(m,n),type); % example single time slice data for this signal
      testCase.sig = SCDsignal(data);
      testCase.bus = testCase.sig.createBus;
    end
  end
  
  methods (TestMethodTeardown)
    function clear_workspace(testCase)
      if ~isempty(testCase.sig)
        % Clear bus variable in workspace
        evalin('base',sprintf('clear %s',testCase.sig.BusName));
      end
    end
  end
  
  methods (TestClassTeardown)
    function close_simulink(testCase)
      % close open simulink model
      close_system(testCase.modelname,0);
    end
  end
  
  methods(Test)
    function test_bus_size(testCase)
      % test size of bus
      S = testCase.sig;
      sigBus = testCase.bus;
      
      % check resulting bus size
      d = S.dimension;
      for ii=1:numel(d)
        testCase.assertEqual(sigBus.Elements(1).Dimensions(ii),d(ii));
      end
    end
    
    function test_slx(testCase)
      % test using bus and signals in an SLX simulation
      S = testCase.sig;
      
      %% Prepare dummy simulation data
      time    = 0:1:10; % time vector
      dataslice = cast(rand(S.datasize),S.datatype);
      if S.datasize(2)==1 % scalar or vector
        data = repmat(dataslice',numel(time),1);
      else % matrix
        data = repmat(dataslice,1,1,numel(time));
      end
       
      % timeseries
      tsvalue   = timeseries(data,time);
      tsquality = timeseries(QualityTag(0),time);
      tsstate   = timeseries(ProductionState(0),time);
      
      % build structure of timeseries: use struct
      datastruct.Value = tsvalue;
      datastruct.Tag   = tsquality;
      datastruct.State = tsstate;
      
      assignin('base','sigBus',testCase.bus); % bus must be in base workspace for method below to work
      inputSignal1 = Simulink.SimulationData.createStructOfTimeseries('sigBus',datastruct);
      
      % build structure of timeseries: use cells
      datacell = {tsvalue,tsquality,tsstate};
      inputSignal2 = Simulink.SimulationData.createStructOfTimeseries('sigBus',datacell);
      
      % check that both methods give the same result
      testCase.verifyEqual(inputSignal1,inputSignal2);
      
      %% Send signal to test slx and test throughput
      busname = 'SCDbusToBeTested';
      assignin('base',busname,testCase.bus)
      
      % SimIn object to configure Simulation
      SimIn = Simulink.SimulationInput(testCase.modelname);
      
      % Create dataset
      Dataset = createInputDataset(testCase.modelname);
      
      % assign input data signal to Simulink.Signal object
      DataIn = Simulink.SimulationData.Signal;
      DataIn.Values = inputSignal1;

      % assign as first element in input data set
      Dataset = Dataset.setElement(1,DataIn);
      % assign this as external input for simulation
      SimIn.ExternalInput = Dataset;
      
      % Custom parameters for this run to save outport data
      SimIn = SimIn.setModelParameter('SaveOutput','on'); % set to save outport signals
      SimIn = SimIn.setModelParameter('OutputSaveName','SimOut');
      SimIn = SimIn.setModelParameter('SaveFormat','Dataset');
      SimIn = SimIn.setModelParameter('StartTime',num2str(time(1)));
      SimIn = SimIn.setModelParameter('StopTime',num2str(time(end)));
      SimIn = SimIn.setModelParameter('FixedStep',num2str(mean(diff(time))));

      % simulate - simulate only single types to save time
      result = sim(SimIn);
      
      % check that output data came through unchanged
      out = result.SimOut{1}.Values;
      in = inputSignal1;
      testCase.verifyEqual(in.Value.data,out.Value.data,...
        'input and output values not equal');
      testCase.verifyEqual(in.ProductionState.Data,out.ProductionState.Data,...
        'input and output ProductionStates not equal');
      testCase.verifyEqual(in.QualityTag.Data,out.QualityTag.Data,...
        'input and output QualityTag not equal');
    end
    
    function test_struct_to_bus(testCase)
      %% Test creation of complex bus from structure which may contain
      % SCDsignals at leaves
      S_sub = struct('sig1',{testCase.sig},'sig2',single(rand(5,5)));
      S = struct('a',single(1),'b',single(ones(3,1)),'c',true(4,2),'sub',S_sub,'sig',{SCDsignal(single(ones(4,1)))});
      testCase.verifyWarningFree(@() SCDsignal_struct_to_bus(S,'myTestBus','Bus with several data types for testing'));
    end
  end
end