在没有编译/执行的情况下确定直接馈通路径

时间:2013-11-11 12:57:39

标签: matlab simulink

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

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

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

非常感谢任何有关可能解决方案的帮助或指示。

3 个答案:

答案 0 :(得分:5)

经过一些进一步的研究......

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

just download the linked m-file

这表明我的想法并不那么糟糕;)


并且为了记录,我的想法是:

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

  • 以编程方式创建新模型
  • 添加Constant源块和Terminator
  • 添加您想要了解中间直接馈通能力的阻止
  • add_lineŠ
  • 运行模拟并记录状态,这将在工作区中为您提供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

答案 1 :(得分:1)

来自documentation

  

提示

     

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

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

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

答案 2 :(得分:1)

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

enter image description here

(请注意,您将使用要测试的任何块替换State-Space块。)

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

enter image description here

如果编译模型时发生错误

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

(你应该检查它是否发生了代数循环错误),然后该块有直接反馈。 如果没有错误发生,那么该块没有直接馈送。 此时,您需要使用

终止模型
>> modelname([],[],[],'term');

如果块有多个inports或outprts,那么你需要迭代它们的所有组合。

相关问题