经过进一步研究...
Matlab有一个“官方解决方案”:
只需下载链接的 m 文件
这表明我的想法还不错;)
为了记录,我的想法是:
我认为这很容易做到。我还不能给你一些代码,但我会看看我能做什么。我的想法如下:
- 以编程方式创建新模型
- 添加一个
Constant
源块和一个Terminator
- 中间添加你想了解的直接馈通能力的Block
add_line
s
- 运行模拟并记录状态,这将为您提供
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
可以具有直接馈通和状态的块。但是这种“行为”并没有太多的标准块。如果您还必须处理第三方块,您可能会遇到一些麻烦,我不得不承认这一点。
状态空间的可能解决方案:如果xout
与yout
相比,可以找到另一个直接馈通指标:如果存在,则向量不相等。如果是这样,那么它们是相等的。只是一个例子,但我可以想象有可能找到更通用的方法来测试这样的事情。
除了simout
上面添加的块需要条件:
% if condition for blocks like state space
feedthrough = isempty(xout);
if ~feedthrough
a = simout.data;
if ~any(a == xout);
feedthrough = ~feedthrough;
end
end