10

我有一个 Simulink 模型,目前正在从脚本(即不是函数)运行。该脚本将变量值写入 MATLAB 工作区,运行模型仿真(使用这些值),然后模型将其他值写入工作区。如果我尝试将脚本转换为函数(即通过放置function [output] = runSim()在文件顶部),那么 Simulink 会抱怨它不知道变量,大概是因为它们不在 MATLAB 工作区中,而是在功能范围。

除了将它们粘贴到工作区之外,是否有一种优雅的方法可以为 Simulink 模型提供输入并从 Simulink 模型中获取输出?

4

4 回答 4

11

这并不明显,但您可以从sim()命令和调用函数的工作区输入/输出数据。我以前做过,并且有一个工作示例,但要到星期一才能到达那里进行验证。但是,请尝试Mathworks 网站上列出的解决方案:

解决方案:

在 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”属性设置为“current”以使用函数中的数据。

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

  1. 在较新的版本中,此选项已被弃用,因为它不符合 Parallel Computing Toolbox 和 PARFOR。我推荐的是:

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

于 2011-03-12T15:14:30.667 回答
2

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

于 2011-03-12T03:35:53.717 回答
0

Short answer: No.

I could be wrong, but let me give you some background. I work on a Simulink model that is very large, we have been working on it for years. To this day we still load all necessary variables in through the workspace. This has been a complaint of mine for a long time, so much that MathWorks has even addressed the issue by providing the Simulink.save_vars function. It sounds like you are already setting up variables with a script/function, so Simulink.save_vars won't be much use to you.

You can clean up the workspace by using structures for some of the variables, most Simulink blocks don't support structures, but some do. Also, avoid putting anything in the workspace other than variables that your model needs.

于 2011-03-12T00:18:38.803 回答
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 的大缺点。您必须明确知道如何在工作区中命名对类实例的引用(在本例中为“测试”)。您可以通过在构造函数中传递名称来解决它,或者您可以使用静态变量和方法,但这种方式不允许您动态更改输入信号。

于 2013-02-03T23:13:02.687 回答