4

我目前正在开发一个用 M-Script 编写的工具,该工具对给定的 simulink 模型执行一组检查。这个工具不编译/执行模型,我正在使用find_systemget_param检索我需要的所有信息,以便运行我的工具的例程。

我已经到了需要确定某个块是否具有直接馈通的地步。我不完全确定如何做到这一点。想到了两种可能的解决方案:

  • 属性可能会存储此信息,并且可以通过get_param. 对此进行调查后,我找不到任何此类财产。
  • 某些块类型具有直接馈通(Sum、Logic、...),而另一些则没有(Unit Delay、Integrator),因此我可以使用块类型来确定块是否具有直接馈通。由于我不是经验丰富的 Simulink 建模师,因此我不确定是否可以仅通过查看模块类型来判断模块是否具有直接馈通。此外,这将需要一个包含所有 Simulink 模块类型的查找表。这是一项不可能完成的任务,因为其他模块类型可能会通过第三方模块添加到 Simulink。

非常感谢任何帮助或指向可能的解决方案的指针。

4

3 回答 3

5

经过进一步研究...

Matlab有一个“官方解决方案”:

只需下载链接的 m 文件

这表明我的想法还不错;)


为了记录,我的想法是:

我认为这很容易做到。我还不能给你一些代码,但我会看看我能做什么。我的想法如下:

  • 以编程方式创建新模型
  • 添加一个Constant源块和一个Terminator
  • 中间添加你想了解的直接馈通能力的Block
  • add_lines
  • 运行模拟并记录状态,这将为您提供xout工作区中的变量。
  • 如果有直接馈通,则该向量为空,否则为空。
  • 可能您需要包含一些try/catch针对特殊情况的错误捕获

这样,您可以通过将模块迁移到另一个模型来分析直接馈通的模块,而无需编译您的实际主模型。这不是最快的解决方案,但我无法想象性能对您来说如此重要。


在这里,这个脚本适用于我的示例:

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

例如当输入时'Gain'它会返回1,当你输入时'Integrator'它会返回0

我的旧机器上的执行时间是 1.3 秒,还不错。

您可能仍然需要做的事情:

  • 添加另一个参数,以定义块是连续时间还是离散时间,并相应地设置求解器。
  • 测试一些“非凡”的块,也许它并不适用于所有事情。我还实现了任何可以处理逻辑的东西,但实际上常量是1这样的,它也应该可以工作。

只要尝试一切,至少它是你工作的一个很好的基础。


一个著名的例外是StateSpace可以具有直接馈通和状态的块。但是这种“行为”并没有太多的标准块。如果您还必须处理第三方块,您可能会遇到一些麻烦,我不得不承认这一点。

状态空间的可能解决方案:如果xoutyout相比,可以找到另一个直接馈通指标:如果存在,则向量不相等。如果是这样,那么它们是相等的。只是一个例子,但我可以想象有可能找到更通用的方法来测试这样的事情。

除了simout上面添加的块需要条件:

% if condition for blocks like state space
feedthrough = isempty(xout);
if ~feedthrough
    a = simout.data;
    if ~any(a == xout);
        feedthrough = ~feedthrough;
    end
end
于 2013-11-11T15:15:20.183 回答
1

基于与@thewaywewalk 类似的方法,您可以设置一个包含代数环的临时模型,类似于,

在此处输入图像描述

(请注意,您可以将 State-Space 模块替换为您想要测试的任何模块。)

如果存在代数环,则将诊断设​​置为错误输出,

在此处输入图像描述

如果编译模型时出现错误

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

(并且您应该检查是否发生了代数循环错误),然后该块具有直接馈送。如果没有发生错误,则该块没有直接馈送。此时,您需要使用终止模型

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

如果块有多个输入或输出,那么您需要遍历它们的所有组合。

于 2013-11-11T17:10:28.770 回答
1

文档中:

小费

要确定块是否具有直接馈通:

  1. 双击块。模块参数对话框打开。
  2. 单击模块参数对话框中的帮助按钮。块参考页面打开。
  3. 滚动到块参考页面的特性部分,其中列出了该块是否具有直接馈通。

虽然我找不到程序化的等价物......

于 2013-11-11T13:12:44.183 回答