Search All of the Math Forum:
Views expressed in these public forums are not endorsed by
Drexel University or The Math Forum.
|
|
Tiger
Posts:
43
Registered:
6/22/12
|
|
Dynamic/variable OutputPort.Dimensions?
Posted:
Dec 16, 2012 2:55 PM
|
|
Hi folks,
Below is a sample of a text file, called WFtest.txt, that I'm trying to read inside Simulink via a level-2 m-file. 1 0 10 10.8 1 1 1 15 2.55 NaN 1 2 10 54.3 3/4 1 3 15 33.1 1/2/5/6/8
I'm trying to extract one row at a time. The row number is indicated by a variable used as an input in my level2 m-file. My main problem here is reading the last column via textscan(). Mind you, I need to have it eventually converted to 'double' data format because SimEvent's Attributes can only be 'doubles', unfortunately, I hope it can handle others too in the future.
Sometimes, the last column may contain single values, which is fine, sometimes empty, which I handled it by putting a NaN which my code converts it into a NaN('double') if found. Sometimes, it has multiple values, which is the core of my question here. I can, in a seperate mock m-file, extract the different values, in the case of having multiple values in any cell in the last column of the text file, and then convert them into a 'double' format with a dminsion width = 1xn, where 'n' being the number of values in that cell.
However, when I tried embedding the whole thing inside a level-2 m-file, I started having issues with the output port concerning the last column values. I knew I would have such issue, but to be honest I searched around how to tackle it but it didn't work. Below is my level-2 m-file code, and I hope someone can advice me in making the dimensions variable depending on how many values it reads, each time, from that last column. ... function Level2_WF(block) setup(block);
function setup(block) % Register number of ports block.NumInputPorts = 1; % Indicating which row/line to read from the text file block.NumOutputPorts = 6; % Setup port properties to be dynamically inherited block.SetPreCompInpPortInfoToDynamic; block.SetPreCompOutPortInfoToDynamic; % Override input port properties block.InputPort(1).Dimensions = 1; block.InputPort(1).DatatypeID = 0; % double block.InputPort(1).Complexity = 'Real'; block.InputPort(1).SamplingMode = 'Sample'; block.InputPort(1).DirectFeedthrough = true; % Override output port properties block.OutputPort(1).Dimensions = 1; block.OutputPort(1).DatatypeID = 0; % double block.OutputPort(1).Complexity = 'Real'; block.OutputPort(1).SamplingMode = 'Sample'; block.OutputPort(2).Dimensions = 1; block.OutputPort(2).DatatypeID = 0; % double block.OutputPort(2).Complexity = 'Real'; block.OutputPort(2).SamplingMode = 'Sample'; block.OutputPort(3).Dimensions = 1; block.OutputPort(3).DatatypeID = 0; % double block.OutputPort(3).Complexity = 'Real'; block.OutputPort(3).SamplingMode = 'Sample'; block.OutputPort(4).Dimensions = 1; block.OutputPort(4).DatatypeID = 0; % double block.OutputPort(4).Complexity = 'Real'; block.OutputPort(4).SamplingMode = 'Sample'; block.OutputPort(5).Dimensions = -1; % How can I make this variable? block.OutputPort(5).DatatypeID = 0; % 0=double, -1=inherited block.OutputPort(5).Complexity = 'Real'; block.OutputPort(5).SamplingMode = 'Sample'; block.OutputPort(6).Dimensions = 1; block.OutputPort(6).DatatypeID = 0; % double block.OutputPort(6).Complexity = 'Real'; block.OutputPort(6).SamplingMode = 'Sample'; block.SampleTimes = [-1 0]; block.SimStateCompliance = 'DefaultSimState'; % Outputs: Called to generate block outputs in simulation step block.RegBlockMethod('Outputs', @Outputs);
function Outputs(block) fid = fopen('WFtest.txt'); % The following if-statement ensures the row number is a positive integer. if isempty(block.InputPort(1).Data) == 1 || block.InputPort(1).Data <= 0 block.InputPort(1).Data = 1; end a = textscan(fid, '%f %f %f %f %s', 1, 'delimiter', '', 'headerlines', block.InputPort(1).Data-1); block.OutputPort(1).Data = a{1}; % J_ID block.OutputPort(2).Data = a{2}; % T_ID block.OutputPort(3).Data = a{3}; % Cores block.OutputPort(4).Data = a{4}; % T_ET Deps = a{5}; % Raw values with '/' inbetween % The following if-statement checks if a{5} is NaN or not. if strcmp(Deps, 'NaN') == 1 block.OutputPort(5).Data = NaN('double'); % 1x1 double else block.OutputPort(5).Data = sscanf(cell2mat(Deps), '%d/')'; % Deps. (1xn double), Output(5)Dimensions to be dynamic, how? end block.OutputPort(6).Data = a{4} * 1.2; % Deadline fclose(fid) ...
It worked well for the first 2 rows, but it gave me the inevitable error (Invalid assignment in 'Level2_WF_test/Level-2 M-file S-Function (Reading from WF.txt)': attempt to assign a vector of width 2 to a vector of width 1.) for the third row, and it pointed at the 'sscanf' line in the code above.
Any advice? _________________ Many thanks.
|
|
|
|