From bd0db675d9f25e77b91365da9b7235c493ca2ae6 Mon Sep 17 00:00:00 2001
From: galperti <cristian.galperti@epfl.ch>
Date: Thu, 23 Jun 2022 14:02:21 +0200
Subject: [PATCH] struct based marte2 bus cfg writers

---
 functions/marte2cfg/bus2marte2cfg.m      | 49 ++++++++++++++++++++++++
 functions/marte2cfg/bus2marte2cfg_test.m | 30 +++++++++++++++
 functions/marte2cfg/dims2marte2.m        | 22 +++++++++++
 functions/marte2cfg/elems2marte2.m       | 20 ++++++++++
 functions/marte2cfg/type2marte2.m        | 38 ++++++++++++++++++
 5 files changed, 159 insertions(+)
 create mode 100644 functions/marte2cfg/bus2marte2cfg.m
 create mode 100644 functions/marte2cfg/bus2marte2cfg_test.m
 create mode 100644 functions/marte2cfg/dims2marte2.m
 create mode 100644 functions/marte2cfg/elems2marte2.m
 create mode 100644 functions/marte2cfg/type2marte2.m

diff --git a/functions/marte2cfg/bus2marte2cfg.m b/functions/marte2cfg/bus2marte2cfg.m
new file mode 100644
index 0000000..3e2d3c6
--- /dev/null
+++ b/functions/marte2cfg/bus2marte2cfg.m
@@ -0,0 +1,49 @@
+function [cfg] = bus2marte2cfg(bus, name, datasourcename, varargin)
+%Translates a simulink bus object into MARTe2 cfg description
+%   This function takes a Simuink.Bus object
+%   as input and prints out its MARTe2 configuration
+%   counterpart.
+%   Inputs:
+%     bus: the Simulink.Bus object to be analyzed
+%     name: its root name
+
+    
+if nargin<=3
+    assert(isa(bus,'Simulink.Bus'),'bus must be a Simulink.Bus object');
+    depth=0;
+    assignin('base','tempbus',bus);
+    busstruct=evalin('base','Simulink.Bus.createMATLABStruct(''tempbus'')');
+    evalin('base','clear tempbus');
+    basealiasname=name;;
+else
+    depth=varargin{1};
+    busstruct=bus;
+    basealiasname=varargin{2};
+end
+spacer='';
+for ii=1:depth, spacer=[spacer ' ']; end
+    
+if isa(busstruct,'struct')
+    % called on a bus, scan into
+    fprintf("%s%s={\n",spacer,name);
+    f=fields(busstruct);
+    for ii=1:numel(f)
+       if isa(busstruct.(f{ii}),'struct')
+         bus2marte2cfg(busstruct.(f{ii}),f{ii},datasourcename,depth+1,[basealiasname '-' f{ii}]);
+       else
+         %TODO: fill the TBC fields
+         martetype=type2marte2(busstruct.(f{ii}));
+         martedims=dims2marte2(busstruct.(f{ii}));
+         marteelems=elems2marte2(busstruct.(f{ii}));
+         fprintf("%s %s = { Type = %s NumberOfDimensions = %d NumberOfElements = %d DataSource = %s Alias = %s }\n",...
+             spacer,f{ii},martetype,martedims,marteelems,datasourcename,...
+             [basealiasname '-' f{ii}]);
+       end 
+    end
+    fprintf("%s}\n",spacer);
+else
+    error('SCDDScore:bus2marte2cfg', 'Wrong input datatype in bus parsing');
+end
+
+end
+
diff --git a/functions/marte2cfg/bus2marte2cfg_test.m b/functions/marte2cfg/bus2marte2cfg_test.m
new file mode 100644
index 0000000..7b85524
--- /dev/null
+++ b/functions/marte2cfg/bus2marte2cfg_test.m
@@ -0,0 +1,30 @@
+% bus2martecfg tester
+%
+% Target cfg file snippet to be automatically obtained
+%
+% outputbus1 = {
+%  sig1 = { Type = float32 NumberOfDimensions = 0 NumberOfElements = 1 DataSource = DDB1 Alias = outputbus1sig1 }
+%  sig2 = { Type = float32 NumberOfDimensions = 0 NumberOfElements = 1 DataSource = DDB1 Alias = outputbus1sig2 }
+%  sig3 = { Type = int32   NumberOfDimensions = 0 NumberOfElements = 1 DataSource = DDB1 Alias = outputbus1sig3 }
+%  subbus1 = {
+%    sig1 = { Type = float32 NumberOfDimensions = 0 NumberOfElements = 1 DataSource = DDB1 Alias = outputbus1sig4 }
+%    sig2 = { Type = float32 NumberOfDimensions = 0 NumberOfElements = 1 DataSource = DDB1 Alias = outputbus1sig5 }                    
+%  }
+% }
+
+% Test bus definition
+genstruct=struct;
+genstruct.sig1=single(zeros(2,2));
+genstruct.sig2=single(0);
+genstruct.sig3=int32(0);
+gensubstruct=struct;
+gensubstruct.sig1=single(0);
+gensubstruct.sig2=single(0);
+genstruct.subbus1=gensubstruct;
+genstruct.sig4=double(zeros(2,1));
+
+busInfo=Simulink.Bus.createObject(genstruct);
+testbus=eval(busInfo.busName);
+
+% Function call
+bus2marte2cfg(testbus, 'rootbus','DDB1');
diff --git a/functions/marte2cfg/dims2marte2.m b/functions/marte2cfg/dims2marte2.m
new file mode 100644
index 0000000..4efb502
--- /dev/null
+++ b/functions/marte2cfg/dims2marte2.m
@@ -0,0 +1,22 @@
+function [numberofdimensions] = dims2marte2(input)
+%Returns the MARTe2 NumberOfDimensions field of input
+%   MARTe2 defines this:
+%   scalars:  NumberOfDimensions = 0
+%   vectors:  NumberOfDimensions = 1
+%   matrices: NumberOfDimensions = 2
+%
+% https://vcis.f4e.europa.eu/marte2-docs/master/html/core/gams/datasource.html?highlight=numberofdimensions
+
+if isscalar(input)
+    numberofdimensions=0;
+elseif isvector(input)
+    numberofdimensions=1;
+elseif ismatrix(input)
+    numberofdimensions=2;
+else
+    warning('SCDDScore:dim2marte2','NumberOfDimensions not supported');
+    numberofdimensions=-1;
+end
+
+end
+
diff --git a/functions/marte2cfg/elems2marte2.m b/functions/marte2cfg/elems2marte2.m
new file mode 100644
index 0000000..ed85720
--- /dev/null
+++ b/functions/marte2cfg/elems2marte2.m
@@ -0,0 +1,20 @@
+function [numberofelements] = elems2marte2(input)
+%Returns the MARTe2 NumberOfElements of input 
+%   NumberOfElements is the total number
+%   of elements of the data
+
+nd=dims2marte2(input);
+
+if nd==0
+    % scalar
+    numberofelements=1;
+elseif nd==1
+    numberofelements=numel(input);
+elseif nd==2
+    numberofelements=numel(input);
+else
+    warning('SCDDScore:elems2marte2','NumberOfElements not supported');
+end    
+
+end
+
diff --git a/functions/marte2cfg/type2marte2.m b/functions/marte2cfg/type2marte2.m
new file mode 100644
index 0000000..03050ad
--- /dev/null
+++ b/functions/marte2cfg/type2marte2.m
@@ -0,0 +1,38 @@
+function [marte2type] = type2marte2(input)
+%Returns MARTe2 type of the input, if supported
+%   Returnd MARTe2 type of the input, if supported
+%   accordind to this map
+%   | C type name     | Model    | MARTe     |
+%   | :-------------- | :------- | :-------- |
+%   | `unsigned char` | `uint8`  | `uint8`   |
+%   | `signed char`   | `int8`   | `int8`    |
+%   | `char`          | `int8`   | `int8`    |
+%   | `unsigned short`| `uint16` | `uint16`  |
+%   | `short`         | `int16`  | `int16`   |
+%   | `unsigned int`  | `uint32` | `uint32`  |
+%   | `int`           | `int32`  | `int32`   |
+%   | `float`         | `single` | `float32` |
+%   | `double`        | `double` | `float64` |
+
+if      isa(input,'uint8')
+        marte2type='uint8';
+elseif  isa(input,'int8')
+        marte2type='int8';
+elseif  isa(input,'uint16')
+        marte2type='uint16';
+elseif  isa(input,'int16')
+        marte2type='int16';
+elseif  isa(input,'uint32')
+        marte2type='uint32';
+elseif  isa(input,'int32')
+        marte2type='int32';
+elseif  isa(input,'single')
+        marte2type='float32';
+elseif  isa(input,'double')
+        marte2type='float64';
+else
+        warning('SCDDScore:type2marte2','not available type conversion');
+        marte2type='n/a';
+
+end
+
-- 
GitLab