4

I am currently working on a tool written in M-Script that executes a set of checks on a given simulink model. This tool does not compile/execute the model, I'm using find_system and get_param to retrieve all the information I need in order to run the routines of my tool.

I've reached a point where I need to determine whether a certain block has direct-feedthrough or not. I am not entirely sure how to do this. Two possible solutions come to mind:

  • A property might store this information and might be accessible via get_param. After investigating this, I could not find any such property.
  • Some block types have direct-feedthrough (Sum, Logic, ...), some other do not (Unit Delay, Integrator), so I could use the block type to determine whether a block has direct-feedthrough or not. Since I'm not an experienced Simulink modeller, I'm not sure if its possible to tell whether a block has direct-feedthrough by solely looking at its block type. Also, this would require a lookup table including all Simulink block types. An impossible task, since additional block types might get added to Simulink via third party modules.

Any help or pointers to possible solutions are greatly appreciated.

3 Answers3

4

after some further research...

There is an "official solution" by Matlab:

just download the linked m-file

It shows that my idea was not that bad ;)


and for the record, my idea:

I think it's doable quite easily. I cannot present you some code yet, but I'll see what I can do. My idea is the following:

  • programatically create a new model
  • Add a Constant source block and a Terminator
  • add the Block you want to get to know the direct feedthrough ability in the middle
  • add_lines
  • run the simulation and log the states, which will give you the xout variable in the workspace.
  • If there is direct feedthrough the vector is empty, otherwise not.
  • probably you need to include some try/catch error catching for special cases

This way you can analyse a block for direct feedthrough by just migrating it to another model, without compiling your actual main model. It's not the fastest solution, but I can not imagine that performance matters that much for you.


Here we go, this script works fine for my examples:

function feedthrough = hasfeedthrough( input )

% get block path
blockinfo = find_system('simulink','Name',input);
blockpath = blockinfo{1};

% create new system
new_system('feed');
open_system('feed');

% add test model elements
src = add_block('simulink/Sources/Constant','feed/Constant');
src_ports = get_param(src,'PortHandles');
src_out = src_ports.Outport;
dest = add_block('simulink/Sinks/To Workspace','feed/simout');
dest_ports = get_param(dest,'PortHandles');
dest_in = dest_ports.Inport;
test = add_block(blockpath,'feed/test');
test_ports = get_param(test,'PortHandles');
test_in = test_ports.Inport;
test_out = test_ports.Outport;
add_line('feed',src_out,test_in);
add_line('feed',test_out,dest_in);

% setup simulation
set_param('feed','StopTime','0.1');
set_param('feed','Solver','ode3');
set_param('feed','FixedStep','0.05');
set_param('feed','SaveState','on');

% run simulation and get states
sim('feed');

% if condition for blocks like state space
feedthrough = isempty(xout);
if ~feedthrough
    a = simout.data;
    if ~any(a == xout);
        feedthrough = ~feedthrough;
    end
end

delete system
close_system('feed',1)
delete('feed');

end

When enter for example 'Gain' it will return 1, when you enter 'Integrator' it will return 0.

Execution time on my ancient machine is 1.3sec, not that bad.

Things you probably still have to do:

  • add another parameter, to define whether the block is continuous or discrete time and set the solver accordingly.
  • test some "extraordinary" blocks, maybe it's not working for everything. Also I haven implemented anything which could deal with logic, but actually the constant is 1 so it should work as well.

Just try out everything, at least it's a good base for you to work on.


A famous exception is the StateSpace Block which can have direct feedthrough AND states. But there are not sooo much standard blocks with this "behaviour". If you also have to deal with third party blocks you could get into some trouble, I have to admit that.

possible solution for the state space: if one compares xout with yout than one can find another indicator for direct feedthrough: if there is, the vectors are not equal. If so, than they are equal. Just an example, but I can imagine that it is possible to find more general ways to test things like that.

besides the added simout block above one needs the condition:

% if condition for blocks like state space
feedthrough = isempty(xout);
if ~feedthrough
    a = simout.data;
    if ~any(a == xout);
        feedthrough = ~feedthrough;
    end
end
Robert Seifert
  • 25,078
  • 11
  • 68
  • 113
  • You're right, performance does not really matter. Your approach sounds promising, I'll try to implement something like that tomorrow. –  Nov 11 '13 at 15:34
  • This won't work. As a simple counter example consider a state-space block with a non-zero D term. It will have states but does have direct feed through. – Phil Goddard Nov 11 '13 at 15:57
  • @PhilGoddard, but these are exceptions, the OP has to deal with. For the mayority of the blocks it should work somehow, have a look at my script. I mean, this solution is better than no solution! ;) In my eyes it's not worth a downvote. – Robert Seifert Nov 11 '13 at 16:04
  • @thewaywewalk: Well said. I think there is good information here (although I am not a Simulink expert), and in the absence of code from the OP, what else can be expected? – chappjc Nov 11 '13 at 16:20
  • @PhilGoddard I've also added a simple exception condition which makes it work for some more blocks, e.g. the state space block. With some creativity I'd assume one could make it work for almost all exceptions. – Robert Seifert Nov 11 '13 at 16:40
  • I agree, there is good information here, but the approach requires the OP to be aware of all possible exceptions that they may run across. Since they are working on a script that is being used to "check" their model (presumably to automatically indicate modelling errors), if I was in their situation it would cause me to lose sleep wondering if I have indeed captured all possible situations. – Phil Goddard Nov 11 '13 at 16:47
  • @PhilGoddard I found a solution by the Matlab developers. It's quite similiar to my idea, just thought to the end :) – Robert Seifert Nov 11 '13 at 17:03
  • @PhilGoddard It's an R&D project which is eventually going to be used in production, so yeah, this is the situation I'm currently in. –  Nov 12 '13 at 10:42
  • @thewaywewalk Thanks for all the effort :) –  Nov 12 '13 at 10:43
1

From the documentation:

Tip

To determine if a block has direct feedthrough:

  1. Double-click the block. The block parameter dialog box opens.
  2. Click the Help button in the block parameter dialog box. The block reference page opens.
  3. Scroll to the Characteristics section of the block reference page, which lists whether or not that block has direct feedthrough.

I couldn't find a programmatic equivalent though...

am304
  • 13,758
  • 2
  • 22
  • 40
1

Based on a similar approach to the one by @thewaywewalk, you could set up a temporary model that contains an algebraic loop, similar to,

enter image description here

(Note that you would replace the State-Space block with any block that you want to test.)

Then set the diagnostics to error out if there is an algebraic loop,

enter image description here

If an error occurs when the model is compiled

>> modelname([],[],[],'compile');

(and you should check that it is the Algebraic Loop error that has occured), then the block has direct feed though. If no error occurs then the block does not have direct feed though. At this point you would need to terminate the model using

>> modelname([],[],[],'term');

If the block has multiple inports or outprts then you'll need to iterate over all combinations of them.

Phil Goddard
  • 10,571
  • 1
  • 16
  • 28