2011-03-11 170 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

相關問題