為什么永遠(yuǎn)不要用 Memory 塊打破連續(xù)代數(shù)循環(huán)
我看到很多用戶在解決代數(shù)循環(huán)時遇到了麻煩,所以這周我想解釋為什么你永遠(yuǎn)不應(yīng)該用一個Memory 塊來打破一個連續(xù)的代數(shù)循環(huán)。
問題
假設(shè)我有一個帶有控制回路的簡單模型:
如果工廠模型是直接饋通,這將導(dǎo)致代數(shù)環(huán)。雖然 Simulink 在大多數(shù)情況下都可以求解代數(shù)環(huán),但它通常會減慢仿真速度,并且當(dāng)求解無法收斂時,可能會導(dǎo)致如下錯誤:
用內(nèi)存塊打破循環(huán)
要打破代數(shù)循環(huán),您需要在循環(huán)中插入一個非直接饋通塊。大多數(shù)用戶首先想到的是單元延遲或內(nèi)存塊。
如果代數(shù)循環(huán)中的模塊具有離散的采樣時間,則插入 Unit Delay 通常是最佳解決方案。當(dāng)然,這會改變系統(tǒng)的動態(tài),這是您需要評估的,看看這是否適合您的應(yīng)用程序。
如果循環(huán)中的塊具有連續(xù)的采樣時間,許多用戶嘗試插入一個內(nèi)存塊。Memory 模塊在某種意義上類似于 Unit Delay 模塊,它將其輸入延遲一個時間步長,但它適用于可變步長信號。讓我們看看它對我們的模型做了什么。
至少,現(xiàn)在模型模擬完成了,我們可以看看結(jié)果:
然而,在模擬模型時,我們很快注意到它的模擬速度非常慢。如果我從模型中記錄數(shù)據(jù),我可以看到在兩秒鐘內(nèi)模擬這個模型需要超過 500,000 步!
如果我們繪制可變步長求解器所采取的步數(shù),我們可以看到在步長輸入之后,求解器開始采取大約 1e-6 秒的步數(shù)并卡在那里。
為什么會這樣?這是因為 Memory 模塊的輸出不是連續(xù)的,它正在驅(qū)動一個具有連續(xù)狀態(tài)的模塊,即 State-Space 模塊。每次 Memory 模塊的輸出發(fā)生變化時,求解器都需要重置,從而強制我們觀察到的小步長。我們知道這種情況是有問題的,我們有一個 Model Advisor 檢查:檢查驅(qū)動衍生端口的非連續(xù)信號
解決方案:使用 Transfer Function 模塊中斷循環(huán)
正如 Model Advisor 所建議的,打破這個代數(shù)循環(huán)的推薦方法是使用連續(xù)塊。我通常更喜歡的是一階傳遞函數(shù)。像內(nèi)存塊一樣,這將在系統(tǒng)中引入新的動態(tài)。訣竅是使傳遞函數(shù)的時間常數(shù)足夠小,不會顯著影響系統(tǒng)的動力學(xué)。在這種情況下,我使用了 1e-6。
通過這種更改,模型給出了類似的結(jié)果,但模擬幾乎立即完成,只用了 633 個時間步:
參考文獻(xiàn):
https://blogs.mathworks.com/simulink/2015/07/18/why-you-should-never-break-an-algebraic-loop-with-with-a-memory-block/