使用 parsim 輕松實現(xiàn) Simulink 模型并行仿真
很久以前,我曾寫了一系列帖子重點介紹并行運算,以及并行運算需要考慮的種種情況。在 R2017a 里,新增加了一個功能 parsim,讓這一切都變得簡單多了。我們來看看這個新的 parsim 是怎么工作的!
注:這里的并行運算指的是一個模型在不同的參數(shù)配置下運行多次,并非把一個模型拆分在不同的核上并行的內(nèi)容。
Simulink.SimulationInput
我們在用并行運算工具箱來多次運行模型的時候,一般都會改變些什么,來實現(xiàn)不同的仿真。
在這里,我們可以通過 Simulink.SimulationInput 對象來實現(xiàn)。首先,我們?yōu)槟P托陆ㄈ舾蓚€ Simulink.SimulationInput 對象,然后通過它來定義不同的配置,包括初始狀態(tài)、模型參數(shù)、模塊參數(shù)、輸入信息以及模型使用的各種變量。
這是一個簡單的碰撞模型:
配置不同的 Restitution 系數(shù),再實現(xiàn)并行仿真,如下圖:
我們從 -0.9 到 -0.2 取 10 個不同的系數(shù)值,然后構造了一個長度為 10 的Simulink.SimulationInput 對象數(shù)組。接著使用 setBlockParameter 方法,給指定的模塊 blk 的參數(shù) 'Gain' 設置了不同的值。最后調(diào)用 parsim ,把Simulink.SimulationInput 數(shù)組作為輸入?yún)?shù),進行并行運算。
計算完畢,就會得到一組Simulink.SimulationOutput 作為返回值。
一些更真實的場景應用
在工作空間定義變量
在 parsim 出來之前,模型并行仿真的一大難點在于怎么去管理模型里的各種變量。我在之前的貼子里還介紹了各種管理攻略,比如各個模塊的參數(shù)值不再直接寫在對話框里,而是使用腳本來構造。比如這里的重力加速度 g 和恢復系數(shù) Cr。
輸出的處理
在很多情況下,仿真會產(chǎn)生大量數(shù)據(jù)。尤其在遠程計算機集群上仿真的時候,一般都不需要傳遞全部的數(shù)據(jù)。所以,我們可以對這些記錄的數(shù)據(jù)做后處理,然后傳遞我們真正感興趣的那部分。
如下圖,這里構造了一個后處理函數(shù) detectFallen,輸入仿真結果,返回一個結構體。這里返回的是球跳了多長時間,以及彈跳了多少次。
接著,我們跟剛才一樣構造 Simulink.SimulationInput 對象數(shù)組。有所不同的是,這里是使用 setVariable 方法來為 workspace 里的變量 Cr 設置不同的值。之后,把剛才構造的函數(shù)句柄賦給 Simulink.SimulationInput 對象的 postSimFcn 屬性。
代碼如下:
注意,在調(diào)用 parsim 時,我還使用了 UseFastRestart 來進一步加速仿真。這樣設置后,模型在每一個 worker 上只會編譯以及初始化一次。
錯誤處理
我喜歡 parsim 的另一個地方是它對仿真出錯的處理方法。
比如下面這個例子,返回的 Simulink.SimulationOutput 對象里包括了錯誤提示信息以及錯誤發(fā)生之前仿真數(shù)據(jù)。
這些信息可以幫助我們理解模型哪里出了錯,也不需要重新仿真模型。
如果你基于這些記錄數(shù)據(jù),也看不出模型哪里出了問題,那么你還可以在本地機器上使用同樣的參數(shù)配置來重新運行模型。這時候,你可以使用 SimulaitonInput 對象的 applyToModel 方法。
就如它名字所說,這個函數(shù)會把這個 SimulationInput 對象里的信息來配置本地模型,包括模型配置、參數(shù)值、變量值。這樣你就可以很容易得到一個跟遠程出錯的模型一模一樣的模型,在本地調(diào)試。
注:比如 sldemo_bounce2.slx,對應的 in(1) 里指定了比如 Cr 值是0.9,那么 in(1).applyToModel 就會自動把這個模型用到的 workspace 里的 Cr 修改為0.9,等等。