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

Jon*_*ler 4 matlab simulink

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

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

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

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

the*_*alk 5

经过一番进一步研究......

Matlab有一个"官方解决方案":

只需下载链接的m文件

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


为了记录,我的想法:

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

  • 以编程方式创建一个新模型
  • 添加Constant源块和aTerminator
  • 添加您想要了解中间直接馈通能力的块
  • 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
Run Code Online (Sandbox Code Playgroud)

当输入例如'Gain'它将返回1,当你输入'Integrator'它将返回0.

我古老的机器上的执行时间是1.3秒,并没有那么糟糕.

您可能仍需要做的事情:

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

试试一切,至少它是你工作的良好基础.


一个着名的例外是StateSpaceBlock,它可以有直接馈通和状态.但是这种"行为"没有太多标准块.如果你还需要处理第三方障碍,你可能会遇到麻烦,我不得不承认.

为状态空间可能的解决方案:如果一个比较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
Run Code Online (Sandbox Code Playgroud)