【问题标题】:How do I provide input to a Simulink model without placing it in the workspace如何在不将其放置在工作区中的情况下向 Simulink 模型提供输入
【发布时间】:2011-07-13 20:18:43
【问题描述】:

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

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

【问题讨论】:

    标签: matlab simulink


    【解决方案1】:

    好吧,我不知道如何从一个简单的函数中做到这一点,但从一个类函数(方法)中做到这一点真的很方便。它适用于 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 对象仍然必须在基础工作区中 - 所以这只会改变 OP 问题的位置。另外,一个提示:小心命名“XXXXtest”或“textXXXX” - 你会遇到 unittest 框架的问题,它会选择以这种方式命名的类文件作为单元测试用例。
    【解决方案2】:

    简短回答:不。

    我可能是错的,但让我给你一些背景知识。我在一个非常大的 Simulink 模型上工作,我们多年来一直在研究它。直到今天,我们仍然通过工作区加载所有必要的变量。这一直是我的抱怨,以至于 MathWorks 甚至通过提供 Simulink.save_vars 函数解决了这个问题。听起来您已经在使用脚本/函数设置变量,所以 Simulink.save_vars 对您没有多大用处。

    您可以通过为某些变量使用结构来清理工作区,大多数 Simulink 模块不支持结构,但有些支持。此外,请避免在工作区中放置模型需要的变量以外的任何内容。

    【讨论】:

      【解决方案3】:

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

      解决方案:

      在使用可变掩码参数时 Simulink,基础工作区是 Simulink 的默认源工作区。 但是,通过使用 SIMSET 命令, 可以更改此工作区。 SIM是 然后与此选项结构一起使用 由 SIMSET 创建。以下是一个 如何执行此操作的示例。

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

      ...虽然由于与并行计算工具箱不兼容,这显然在 R2009b 中已被弃用 >:( 看起来正确的解决方案是使用 @987654322 将变量显式推送到模拟的模型工作区(不同于基本工作区) @。

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

      你有两个选择:

      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

      【讨论】:

      • 此方法是否适用于模型引用和使用 RTW 编译?
      • 你得问问 Mathworks 的人;除了从 M 文件运行模拟之外,我从未使用过 RTW,也从未深入了解过 Simulink。
      • 第一个选项在 2009a 年有效...所以我会坚持下去,直到它咬我。谢谢!
      • @MajorApus 我们正在使用 RTW,第一个解决方案似乎有效。
      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-07-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-08
        相关资源
        最近更新 更多