【问题标题】:Determining direct-feedthrough paths without compilation/execution在不编译/执行的情况下确定直接馈通路径
【发布时间】:2013-11-23 06:59:51
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: matlab simulink


    【解决方案1】:

    来自documentation

    提示

    判断一个块是否有直接馈通:

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

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

    【讨论】:

      【解决方案2】:

      经过进一步研究...

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

      just download the linked m-file

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


      为了记录,我的想法:

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

      • 以编程方式创建新模型
      • 添加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
      

      【讨论】:

      • 你说得对,性能并不重要。你的方法听起来很有希望,我明天会尝试实现类似的东西。
      • 这行不通。作为一个简单的反例,考虑具有非零 D 项的状态空间块。它将有状态,但确实有直接馈送。
      • @PhilGoddard,但这些都是例外,OP 必须处理。对于块的市长,它应该以某种方式工作,看看我的脚本。我的意思是,这个解决方案总比没有解决方案好! ;) 在我看来,不值得投反对票。
      • @thewaywewalk:说得好。我认为这里有很好的信息(虽然我不是 Simulink 专家),并且在没有来自 OP 的代码的情况下,还有什么可以期待的?
      • @PhilGoddard 我还添加了一个简单的异常条件,使其适用于更多块,例如状态空间块。有了一些创造力,我认为可以让它适用于几乎所有的例外情况。
      【解决方案3】:

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

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

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

      如果编译模型时出错

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

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

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

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

      【讨论】:

        猜你喜欢
        • 2016-09-19
        • 2011-11-02
        • 2011-03-21
        • 2012-03-22
        • 2012-02-17
        • 2021-12-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多