Skip to content
Snippets Groups Projects
Commit 201b26fd authored by Federico Felici's avatar Federico Felici
Browse files

First working SCDsignal class with tests

parent f2eca788
No related branches found
No related tags found
No related merge requests found
classdef(Enumeration) ProductionState < Simulink.IntEnumType
enumeration
RUNNING(0)
STOPPED(1)
OUTDATED(2)
end
methods (Static = true)
% add methods, e.g. (See documentation)
% getDefaultValue :
% getDescription
% getHeaderFile % define RT code C header
function retVal = getDefaultValue()
% GETDEFAULTVALUE Returns the default enumerated value.
% This value must be an instance of the enumerated class.
% If this method is not defined, the first enumeration is used.
retVal = ProductionState.STOPPED;
end
end
end
\ No newline at end of file
classdef(Enumeration) QualityTag < Simulink.IntEnumType
enumeration
GOOD(0)
INVALID(1)
ERROR(2)
end
methods (Static = true)
% add methods, e.g. (See documentation)
% getDefaultValue :
% getDescription
% getHeaderFile % define RT code C header
function retVal = getDefaultValue()
% GETDEFAULTVALUE Returns the default enumerated value.
% This value must be an instance of the enumerated class.
% If this method is not defined, the first enumeration is used.
retVal = QualityTag.GOOD;
end
end
end
\ No newline at end of file
classdef SCDsignal
properties
Value {mustBeNumericOrLogical,mustBeNonempty} = 0;
QualityTag (1,1) QualityTag = 0;
ProductionState (1,1) ProductionState = 0;
end
methods
function S = SCDsignal(varargin)
% constructor
if numel(varargin)>=1 && ~isempty(varargin{1}), S.Value = varargin{1}; end
if numel(varargin)>=2 && ~isempty(varargin{2}), S.QualityTag = varargin{2}; end
if numel(varargin)>=3 && ~isempty(varargin{3}), S.ProductionState = varargin{3}; end
siz = S.size;
assert(~(siz(1)==1 && siz(2)>1),'SCDsignal:RowVector',...
'Row vectors are not supported due to matlab bug. Size=[%d %d]',siz(1),siz(2));
% to reproduce the bug:
% a=timeseries([1 2],1); Simulink.SimulationData.TimeseriesUtil.getSampleDimensions(a), a
end
function type = datatype(obj)
type = class(obj.Value);
end
function str = struct(obj)
% method to convert to structure
for ii=fieldnames(obj)'
myf = ii{:};
str.(myf) = obj.(myf);
end
end
function dimension = dimension(obj)
% dimension as required by buses etc.
siz = size(obj);
if siz(2) == 1, dimension = siz(1);
else, dimension = siz;
end
end
function siz = size(obj,dim)
% size of data
if nargin==1, siz = size(obj.Value);
else, siz = size(obj.Value,dim);
end
end
function valid = isvalid(obj)
% true if GOOD and RUNNING
isRunning = (obj.ProductionState == 'RUNNING');
isGood = (obj.QualityTag == 'GOOD');
valid = isRunning && isGood;
end
function [myBusObj] = createBus(obj)
% creates a bus object corresponding to this signal
tmp = Simulink.Bus.createObject(struct(obj));
myBusObj = evalin('base',tmp.busName);
evalin('base',sprintf('clear %s',tmp.busName));
myBusObj.Description = obj.BusName;
% 2D to 1D where possible
for iEl = 1:numel(myBusObj.Elements)
dims = myBusObj.Elements(iEl).Dimensions;
if all(dims == 1)
myBusObj.Elements(iEl).Dimensions = dims(1);
end
end
end
function Name = BusName(obj)
% Returns the bus name for this signal
type = class(obj.Value);
siz = size(obj.Value);
assert(numel(siz)==2,'3 or larger dimensional data not supported')
if all(siz == 1)
sizestr = '_Scalar';
elseif siz(2) == 1
sizestr = sprintf('_%d_Vector',siz(1));
else % matrix
sizestr = sprintf('_%d_%d_Matrix',siz(1),siz(2));
end
Name = sprintf('SCDBus_%s%s',type,sizestr);
end
end
end
\ No newline at end of file
classdef SCDsignal_test < matlab.unittest.TestCase
properties (MethodSetupParameter)
type = {'single','double','logical'}
m = {1,2,100};
n = {1,2};
end
properties
sig; % signal object to be tested
bus; % associated bus
end
methods (TestMethodSetup)
function check_size(testCase,m,n,type)
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(Test)
function test_creation(testCase)
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)
S = testCase.sig;
% dummy simulation data
value = timeseries(cast(rand(S.size),S.datatype),0);
quality = timeseries(QualityTag(0));
state = timeseries(ProductionState(0));
% use struct
datastruct.Value = value;
datastruct.Tag = quality;
datastruct.State = state;
assignin('base','sigBus',testCase.bus); % bus must be in base workspace for method below to work
inputSignal1 = Simulink.SimulationData.createStructOfTimeseries('sigBus',datastruct);
% use cells
datacell = {value,quality,state};
inputSignal2 = Simulink.SimulationData.createStructOfTimeseries('sigBus',datacell);
testCase.verifyEqual(inputSignal1,inputSignal2);
end
end
end
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment