2011-03-11 53 views
8

我有一个当前正在从脚本运行的Simulink模型(即不是函数)。该脚本将变量值写入MATLAB工作区,运行模型仿真(使用这些值),然后该模型将附加值写入工作区。如果我尝试将脚本转换为函数(即将function [output] = runSim()置于文件的顶部),那么Simulink会抱怨它不知道变量,可能是因为它们不在MATLAB工作区中,而是它们处于功能范围。如何在不将Simulink模型放入工作空间的情况下为Simulink模型提供输入

有没有一种优雅的方式来提供一个Simulink模型的输入,并从Simulink模型中取出输出,而不是将它们粘贴到工作空间中?

回答

9

这并不明显,但您可以从sim()命令和调用函数的工作区中输入/输出数据。我已经在&之前做过一个例子,但直到星期一才能到那里验证。然而,尝试将溶液列出on Mathworks's site

解决方案:

当 Simulink中使用可变掩模参数,基底工作区是Simulink中的 默认源工作区。 但是,通过使用SIMSET命令, 此工作空间可以更改。 SIM是 ,然后与由SIMSET创建的此选项结构 一起使用。以下是如何做到这一点的 示例。

options = simset('SrcWorkspace','current'); 
    sim('modelname',[],options) 

...虽然显然这让R2009b中由于与并行计算工具箱不兼容过时> :(貌似正确的解决方案是明确的变量推入仿真模型工作区(不同比基本工作区),使用assignin()

http://www.mathworks.com/matlabcentral/newsreader/view_thread/292544

你有2种选择:

  1. 对于R2009b中之前的版本中,看看SIMSET文档。它允许您将 设置为“当前”的“SrcWorkspace”属性 以使用您的 函数中的数据。

http://www.mathworks.com/support/solutions/en/data/1-1BWDA/?solution=1-1BWDA

  1. 在新版本中,此选项不建议使用,因为它不符合 与并行计算工具箱 和PARFOR。我的建议是:

http://www.mathworks.com/support/solutions/en/data/1-ASPEIV/?solution=1-ASPEIV

+0

此方法适用于模型引用并使用RTW编译? – Miebster 2011-03-12 22:11:30

+0

,你不得不问Mathworks的人;我从来没有使用过RTW,也没有深入到Simulink中,而是从M文件中运行模拟。 – 2011-03-12 22:24:03

+0

第一个选项在2009年工作...所以我只是会坚持下去,直到它咬我。谢谢! – JnBrymn 2011-03-14 22:07:08

0

简短的回答:第

我可能是错的,但让我告诉你一些背景。我在一个非常大的Simulink模型上工作,我们一直在努力工作多年。直到今天,我们仍然通过工作空间加载所有必要的变量。长期以来,这一直是我的抱怨,MathWorks甚至通过提供Simulink.save_vars函数解决了这个问题。这听起来像你已经用脚本/函数设置了变量,所以Simulink.save_vars对你来说不会有多大用处。

您可以使用某些变量的结构清理工作空间,大多数Simulink块不支持结构,但有些可以。另外,请避免在模型所需的变量之外放置任何东西。

+0

真的吗?呃...呕吐。 – JnBrymn 2011-03-12 00:34:14

+1

-1因为我已经完成了。 – 2011-03-12 15:04:45

2

您可以使用evalin()函数从您自己的函数中执行特定工作区中的MATLAB表达式(以字符串形式),在您的情况下为SIMULINK找到它们的“基础”。但是,如果您不想直接使用工作区,则可以使用From/To File模块将信号或变量从/存储到MAT文件。

0

好吧,我不知道如何从一个简单的功能做到这一点,但它确实很方便,从一个类的函数(方法)内做到这一点。它适用于版本2009b。

将代码放在文件Test.m:

classdef Test < handle 
    properties 
     mdl 
     % Default input signal 
     t = [0 1 1 2]' 
     u = [0 0 1 1]' 
    end 

    methods 
     function this = Test(mdl) % Constructor 
      this.mdl = mdl; 
     end 

     function sim(this) 
      % Load model 
      load_system(this.mdl); 
      % Prepare model configuration 
      conf = getActiveConfigSet(this.mdl); 
      cs = conf.copy(); 
      set_param(cs, 'StopTime', '4'); 
      set_param(cs, 'LoadExternalInput', 'on'); 
      set_param(cs, 'ExternalInput', '[test.t test.u]'); % <-- 1 
      % Run simulation 
      simout = sim(this.mdl, cs); 
      % Plot results 
      tout = simout.find('tout'); 
      yout = simout.find('yout'); 
      plot(tout, yout(:,1), 'b--'); 
     end 
    end 
end 

然后,只需:

>> test = Test('TestSim'); 
>> test.sim(); 

会发生什么?你创建了对象测试,它定义了字段t和u。然后在sim()方法中你可以对Simulink寻找输入'[test.t test.u]'。 Simulink和sim()方法都可以访问这些变量(我相信这是最重要的)。

好吧,它仍然有一个很大的缺点,用数字1标记。你必须明确知道如何在工作区中命名类实例的引用(在这种情况下是'test')。您可以通过在构造函数中传递名称来处理它,也可以使用静态变量和方法,但这种方式不允许您动态更改输入信号。

+0

嗯,这看起来优雅起初,但我很确定,测试对象仍然必须在基本工作区 - 所以这只是改变了OP的问题的位置。 另外,提示:小心命名事件“XXXXtest”或“textXXXX” - 你会遇到单元测试框架的问题,它会以这种方式命名为单元测试用例。 – thclark 2016-08-20 13:53:45

相关问题