設(shè)置避坑指南:ode45與ode15s實(shí)戰(zhàn)經(jīng)驗(yàn))
做仿真這些年我?guī)缀趺刻於荚诟鷖imulink打交道。很多人覺得模型搭好就能出結(jié)果結(jié)果一跑就卡死、一跑就發(fā)散、一跑就報(bào)錯(cuò)最后排查一圈問題往往出在最不起眼的求解器配置上。這篇東西不講那些用戶手冊(cè)里抄來的套話就聊聊我在simulink求解器選擇與參數(shù)設(shè)置上踩過的坑、總結(jié)出的經(jīng)驗(yàn)以及一些網(wǎng)上不怎么會(huì)有人主動(dòng)告訴你的小訣竅。先把結(jié)論放前面求解器不是隨便選的它直接決定了仿真能不能算得動(dòng)、算得準(zhǔn)、算得快。這篇文章適合剛接觸simulink的初學(xué)者也適合那些已經(jīng)在做復(fù)雜模型但還沒認(rèn)真研究過求解器配置的工程師。你花五分鐘看完可能省下后面無數(shù)個(gè)加班調(diào)試的夜晚。1. 先搞明白你在解什么樣的數(shù)學(xué)問題很多人在配置求解器的時(shí)候眼睛只盯著那個(gè)下拉菜單里的“ode45”“ode15s”卻忽略了一個(gè)更本質(zhì)的問題你的模型到底是連續(xù)的、離散的還是混合的這三個(gè)詞決定了你想問題的方式對(duì)不對(duì)。1.1 連續(xù)與離散模型結(jié)構(gòu)決定求解器下限simulink模型里的每一個(gè)積分器、每一個(gè)連續(xù)狀態(tài)變量都代表一個(gè)微分方程。比如你搭一個(gè)電機(jī)模型里面的電感電流、轉(zhuǎn)子轉(zhuǎn)速都是連續(xù)狀態(tài)它們的變化規(guī)律要用微分方程描述。這時(shí)候你需要一個(gè)能解微分方程的數(shù)值積分算法也就是各種“ode”開頭的求解器。反過來如果你的模型里只有邏輯判斷、查表、單位延遲沒有積分器那它本質(zhì)上是離散系統(tǒng)用離散求解器就夠了。離散求解器不會(huì)去做什么積分運(yùn)算它按固定間隔推進(jìn)時(shí)間在每個(gè)時(shí)刻計(jì)算當(dāng)前輸出。這個(gè)區(qū)別特別重要因?yàn)楹芏嗳嗣髅鞔畹氖羌冸x散模型卻還在用ode45結(jié)果仿真跑了半天還沒跑完白浪費(fèi)計(jì)算資源。怎么判斷打開模型配置參數(shù)看左側(cè)的“Solver”選項(xiàng)卡Solver selection里如果顯示的是Variable-step說明當(dāng)前使用的是連續(xù)求解器。再到MATLAB命令窗口輸入下面的代碼看模型里有哪些連續(xù)狀態(tài)sldebug(bdroot) % 進(jìn)入調(diào)試模式后輸入 s 查看狀態(tài)或者更粗暴一點(diǎn)模型的求解器類型選成discrete之后如果仿真報(bào)錯(cuò)提示“contains continuous states but solver is set to discrete”那就說明模型里有連續(xù)部分需要換回連續(xù)求解器。如果選discrete之后能正常跑那你之前用ode45純屬殺雞用了牛刀。1.2 剛性系統(tǒng)為什么ode45會(huì)卡死“剛性”這個(gè)詞看起來玄乎理解起來其實(shí)很直白一個(gè)系統(tǒng)里同時(shí)存在變化極快和變化極慢的物理過程時(shí)間常數(shù)能差好幾個(gè)數(shù)量級(jí)。典型的例子是電機(jī)驅(qū)動(dòng)電氣時(shí)間常數(shù)在毫秒甚至微秒級(jí)而機(jī)械時(shí)間常數(shù)是秒級(jí)再比如電力電子電路開關(guān)頻率可能幾十kHz而負(fù)載慣量的響應(yīng)要好幾秒。對(duì)于這種系統(tǒng)默認(rèn)的ode45是顯式Runge-Kutta方法穩(wěn)定性是有邊界限制的。為了保證計(jì)算不發(fā)散求解器被迫把步長壓得非常小小到足以捕捉最快的那個(gè)動(dòng)態(tài)。結(jié)果就是你明明只仿真了1秒的物理時(shí)間求解器卻像螞蟻搬家一樣一步一步龜速爬完了幾十萬步。怎么判斷自己的模型有沒有剛性特征最簡單的方法是跑一遍仿真然后看診斷查看器里的求解器統(tǒng)計(jì)信息。如果“Number of successful steps”達(dá)到了幾萬甚至幾十萬而且仿真明明設(shè)置的是幾秒時(shí)間卡得跟PPT一樣那基本可以斷定是剛性系統(tǒng)。還有一種情況仿真剛開始沒幾步就報(bào)“Solver is taking a small step”之類的警告說明步長已經(jīng)被壓到最小步長邊界了。我之前做過一個(gè)永磁同步電機(jī)的PI控制仿真剛開始用默認(rèn)的ode451秒的仿真硬是跑了將近20分鐘最后還是超時(shí)中斷了。換成ode15s之后同樣3秒仿真只用了幾十秒就出結(jié)果精度還沒受影響。從那以后我養(yǎng)成了一個(gè)習(xí)慣一旦仿真異常慢第一件事就是懷疑剛性問題而不是去優(yōu)化所謂的“模型效率”。2. 求解器選型核心邏輯從ode45到ode15s的選擇思路明確了模型的類型和剛性特征之后選求解器就有一半的把握了。剩下的工作就是在變步長家族里選一個(gè)合適的哥或者在定步長家族里挑一個(gè)穩(wěn)得住的老實(shí)人。2.1 變步長求解器的適用場(chǎng)景與選擇順序變步長求解器的特點(diǎn)是在滿足容差要求的前提下仿真過程中自動(dòng)調(diào)整步長。動(dòng)態(tài)變化劇烈時(shí)步長自動(dòng)縮小動(dòng)態(tài)平緩時(shí)步長自動(dòng)放大目的是在精度和速度之間找平衡。ode45是simulink的默認(rèn)配置也是絕大多數(shù)模型的“萬金油”。它基于Dormand-Prince對(duì)偶公式的4階5級(jí)Runge-Kutta算法精確度高、適合大多數(shù)非剛性連續(xù)系統(tǒng)。我剛做仿真的時(shí)候幾乎所有模型都是ode45一把梭后來發(fā)現(xiàn)這個(gè)習(xí)慣說不上錯(cuò)但確實(shí)不夠講究。ode23可以理解成ode45的輕量版當(dāng)誤差要求不高、模型本身也比較“溫和”的時(shí)候它往往比ode45更快。ode113是一種變階變步長的Adams方法特別適合處理那些函數(shù)光滑、需要高精度的場(chǎng)景。但需要注意如果你的模型里有很多開關(guān)動(dòng)作、飽和限幅、不連續(xù)事件ode113經(jīng)常會(huì)退化表現(xiàn)反而不如ode45。我的選型順序很固定不知道選什么就用ode45跑一版看看仿真時(shí)長和結(jié)果精度如果慢得離譜換ode15s如果精度要求高但模型很平滑可以考慮ode113。這一套組合拳能覆蓋日常八成以上的仿真需求。2.2 剛性求解器怎么挑真正需要花心思的是剛性求解器的挑選。ode15s是剛性系統(tǒng)的首選它基于可變階的數(shù)值差分公式NDF既能解剛性問題也保留了不錯(cuò)的精度。工程上遇到剛性問題第一反應(yīng)直接切ode15s基本不會(huì)有坑。ode23t用的是梯形規(guī)則適合中等剛度、需要無阻尼振蕩特性的場(chǎng)景比如機(jī)械系統(tǒng)的自由振動(dòng)分析、電力系統(tǒng)的暫態(tài)計(jì)算。如果你要的結(jié)果對(duì)周期、相位特別敏感ode23t通常比ode15s更合適。ode23tb結(jié)合了TR-BDF2方法剛性問題里它處理得比較穩(wěn)尤其是當(dāng)事件檢測(cè)和剛性耦合在一起的時(shí)候它比ode15s更不容易在過零檢測(cè)上翻車。說實(shí)話這幾個(gè)剛性求解器之間的差異大多數(shù)工程師根本感知不到你只需要記住默認(rèn)先試ode15s不行再換ode23t。求解器方法類型適用場(chǎng)景我的推薦程度ode45顯式4/5階RK大多數(shù)非剛性連續(xù)系統(tǒng)默認(rèn)選擇ode23顯式2/3階RK低精度要求、輕量問題偶爾使用ode113變階Adams光滑問題、高精度需求特定場(chǎng)景ode15s可變階NDF剛性問題首選強(qiáng)烈推薦ode23t梯形規(guī)則中等剛度、周期敏感問題備用方案ode23tbTR-BDF2剛性事件檢測(cè)混合特殊情況2.3 定步長求解器何時(shí)必須用它變步長雖然靈活但有一個(gè)繞不開的硬傷仿真步長不可預(yù)測(cè)。步長一會(huì)兒大一會(huì)兒小導(dǎo)致在每個(gè)仿真時(shí)刻物理時(shí)間與計(jì)算時(shí)間之間沒有確定的對(duì)齊關(guān)系。這在普通離線仿真里不是問題但面對(duì)下面這幾種場(chǎng)景就不行了第一個(gè)場(chǎng)景是外部模式。simulink外部模式通過實(shí)時(shí)通信從目標(biāo)硬件嵌入式設(shè)備、dSPACE快速原型機(jī)等讀取信號(hào)或注入激勵(lì)這時(shí)候仿真必須和硬件保持嚴(yán)格的時(shí)間同步變步長根本對(duì)不上點(diǎn)。第二個(gè)場(chǎng)景是硬件在環(huán)測(cè)試實(shí)時(shí)仿真器必須在固定時(shí)間周期內(nèi)完成所有模型計(jì)算步長一旦不確定實(shí)時(shí)系統(tǒng)的硬實(shí)時(shí)約束就沒法滿足了。第三個(gè)場(chǎng)景是代碼生成。生成嵌入式C代碼時(shí)定步長模型生成的代碼邏輯更干凈不會(huì)帶上變步長求解器那套復(fù)雜的動(dòng)態(tài)步長調(diào)整邏輯。定步長求解器里最常用的是ode4即四階Runge-Kutta方法。它的精度和計(jì)算量比較均衡是實(shí)時(shí)仿真的常客。如果你的模型全是離散模塊那可以直接用discrete定步長求解器仿真速度飛快因?yàn)橥耆簧婕胺e分運(yùn)算。很多人不知道的是即使是定步長simulink也提供了ode1到ode8、ode14x這些連續(xù)求解器選項(xiàng)其中ode14x是隱式方法專門處理定步長下的剛性問題不過實(shí)時(shí)系統(tǒng)里我很少見有人真的用它計(jì)算量太大了得不償失。3. 步長、精度與仿真性能的平衡實(shí)用的參數(shù)調(diào)節(jié)技巧選定了求解器類型不等于一勞永逸。下一步是配置求解器參數(shù)這里面的水比很多人想象的深。最大步長、最小步長、相對(duì)容差、絕對(duì)容差這四個(gè)參數(shù)配合起來直接決定仿真輸出的質(zhì)量和速度。3.1 最大步長與最小步長的設(shè)置邏輯simulink里最大步長默認(rèn)是auto內(nèi)部通常會(huì)取仿真總時(shí)長除以50。這個(gè)邏輯對(duì)簡單模型問題不大但對(duì)包含高頻動(dòng)態(tài)的系統(tǒng)來說很要命。比如你的模型里有一個(gè)10kHz的PWM信號(hào)仿真時(shí)長為0.1秒默認(rèn)最大步長是0.002秒也就是2毫秒一步而PWM周期才0.0001秒一個(gè)周期被粗粗跨過去波形自然是錯(cuò)的。我的實(shí)踐經(jīng)驗(yàn)是最大步長設(shè)置成系統(tǒng)最快動(dòng)態(tài)周期的十分之一到五分之一之間寧可保守也不冒險(xiǎn)。比如前面那個(gè)10kHz的PWM最大步長就應(yīng)該設(shè)成1e-5秒左右。怎么知道你的模型有沒有更高的頻率成分可以用線性化分析工具或?qū)ο到y(tǒng)做一下頻域分析但最省事的辦法是看實(shí)際仿真波形如果一個(gè)PWM周期內(nèi)只有幾個(gè)采樣點(diǎn)那就把最大步長調(diào)小。最小步長這個(gè)參數(shù)平時(shí)看起來不起眼但它實(shí)際上是仿真的“安全閥”。當(dāng)變步長求解器發(fā)現(xiàn)無論怎么縮小步長都無法滿足容差要求時(shí)步長會(huì)不斷變小直到碰到最小步長就停下來然后報(bào)錯(cuò)。錯(cuò)誤提示通常是“Solver is taking a small step”或者“minimum step size violation”。很多人遇到這個(gè)報(bào)錯(cuò)第一反應(yīng)是把最小步長改小這其實(shí)是在給solve“續(xù)命”真正的根源是模型本身有剛性問題或者某個(gè)環(huán)節(jié)數(shù)值上出現(xiàn)了奇異性。改求解器、檢查模型才是正道。3.2 相對(duì)容差和絕對(duì)容差的正確姿勢(shì)相對(duì)容差RelTol和絕對(duì)容差A(yù)bsTol定義了求解器在每一步上的誤差允許范圍直接影響仿真精度和速度。RelTol默認(rèn)是1e-3意思是在計(jì)算過程中每一步的局部誤差不能超過當(dāng)前信號(hào)幅值的千分之一。對(duì)大多數(shù)演示性質(zhì)的仿真1e-3夠用但當(dāng)你拿仿真結(jié)果去寫報(bào)告、去做控制器參數(shù)整定、或者輸出到下一級(jí)工具進(jìn)行計(jì)算的時(shí)候我建議把RelTol調(diào)到1e-4甚至1e-5。絕對(duì)容差跟信號(hào)的量級(jí)有關(guān)。如果模型里有小信號(hào)和大信號(hào)混在一個(gè)系統(tǒng)里你用一個(gè)固定的AbsTol就很容易出問題設(shè)小了小信號(hào)附近的誤差要求會(huì)逼得求解器瘋狂縮小步長設(shè)大了小信號(hào)又會(huì)被淹沒在容差里。我常用的方式是給AbsTol設(shè)成跟各個(gè)狀態(tài)變量量綱相關(guān)的值或者干脆先讓它自動(dòng)跑一遍看哪里誤差大再針對(duì)性調(diào)整。有一個(gè)容易忽略的細(xì)節(jié)RelTol和AbsTol不是越大越快。因?yàn)閟imulink的誤差判斷是兩者的組合每個(gè)狀態(tài)下誤差要同時(shí)滿足相對(duì)和絕對(duì)兩個(gè)約束你把容差故意調(diào)大看似求解器能大步長前進(jìn)但結(jié)果一旦不收斂仿真報(bào)錯(cuò)重來反而更慢。3.3 零穿越檢測(cè)Simulink里最容易被忽略的坑零穿越檢測(cè)Zero-Crossing Detection是simulink里一個(gè)特別容易被誤解的功能。它的作用是讓求解器在信號(hào)過零比如開關(guān)切換、飽和模塊進(jìn)入和退出限幅、比較器翻轉(zhuǎn)時(shí)精確找到過零點(diǎn)而不是胡亂跨過去。默認(rèn)情況下這個(gè)功能是開的好處是仿真結(jié)果在那些不連續(xù)點(diǎn)上更準(zhǔn)確壞處是當(dāng)信號(hào)在零點(diǎn)附近來回抖動(dòng)比如震顫頻率很高時(shí)求解器會(huì)在每個(gè)過零點(diǎn)之間來回磨蹭仿真速度暴降甚至直接報(bào)錯(cuò)。最常見的錯(cuò)誤提示是“An error occurred while running the simulation and the simulation was terminated”伴隨Zero crossing相關(guān)警告。遇到這種情況很多人第一反應(yīng)是去設(shè)置里把零穿越檢測(cè)關(guān)掉。確實(shí)關(guān)閉之后仿真速度立竿見影地恢復(fù)但你要知道代價(jià)是過零點(diǎn)不再被精確定位仿真結(jié)果在某些時(shí)刻是“跳過去”的數(shù)字上看起來沒問題實(shí)際上已經(jīng)在錯(cuò)誤的時(shí)間點(diǎn)做了錯(cuò)誤的切換。我的建議是不要輕易全局關(guān)零穿越而是去找出那個(gè)抖動(dòng)的信號(hào)。抖動(dòng)的原因通常是一個(gè)帶有高增益或者反饋回路的環(huán)節(jié)在過零附近高頻震蕩。解決方案是在這個(gè)環(huán)節(jié)之前加一點(diǎn)遲滯比如用滯回比較器或者加一個(gè)低通濾波把高頻抖動(dòng)濾掉再不行就把零穿越設(shè)置的算法從Nonadaptive換成Adaptive讓求解器自己判斷什么時(shí)候值得做零穿越搜索。這幾個(gè)方案都比粗暴地關(guān)閉零穿越來得穩(wěn)。4. 特殊場(chǎng)景下的求解器配置進(jìn)階經(jīng)驗(yàn)解決了常規(guī)模型的求解器問題接下來聊聊幾個(gè)特殊場(chǎng)景。這些場(chǎng)景在純學(xué)習(xí)資料里很少被系統(tǒng)介紹但實(shí)際工程項(xiàng)目里幾乎都會(huì)遇到外部模式、聯(lián)合仿真、代碼生成以及各種求解器相關(guān)報(bào)錯(cuò)的排查思路。4.1 外部模式與硬件在環(huán)的定步長強(qiáng)約束很多從純仿真轉(zhuǎn)型做嵌入式驗(yàn)證的工程師第一次接觸外部模式時(shí)都會(huì)被同樣的報(bào)錯(cuò)卡住“Model must be configured for fixed-step”。這句話的本質(zhì)就是外部模式要求仿真時(shí)間與墻鐘時(shí)間同步變步長模式下每個(gè)步長的計(jì)算時(shí)間是不確定的無法保證同步simulink直接拒絕執(zhí)行。解決辦法很簡單把求解器切到定步長。但切完之后還有第二層問題——定步長模式下仿真速度直接跟步長相關(guān)步長越小CPU負(fù)擔(dān)越重外部模式下的實(shí)時(shí)性能越差。你需要結(jié)合模型的復(fù)雜度和目標(biāo)硬件算力找一個(gè)“跑得動(dòng)”的步長。我的經(jīng)驗(yàn)是普通電動(dòng)車VCU控制模型步長1ms通常沒問題如果模型復(fù)雜、包含大量查表和狀態(tài)機(jī)可能需要放大到2ms甚至5ms但要先確認(rèn)這個(gè)步長能否滿足你對(duì)系統(tǒng)動(dòng)態(tài)的分辨率需求。還有一個(gè)地方容易踩坑定步長模式下信號(hào)在Scope里的顯示精度變差了。很多人在變步長模式下習(xí)慣了看很精細(xì)的波形切到定步長后發(fā)現(xiàn)波形“毛糙”了就跑回來罵simulink。其實(shí)這是定步長采樣點(diǎn)數(shù)天生受限帶來的正常現(xiàn)象不是求解器壞了。4.2 聯(lián)合仿真Carsim、AMESim的求解器匹配聯(lián)合仿真可以說是求解器問題的高發(fā)區(qū)。Carsim與simulink聯(lián)合仿真時(shí)Carsim內(nèi)部有自己的一套求解器simulink只是通過接口模塊每個(gè)固定時(shí)間步交換一次數(shù)據(jù)。simulink這一側(cè)如果用的是變步長求解器接口模塊的采樣時(shí)間就必須仔細(xì)配置否則很容易出現(xiàn)“sample time mismatch”之類的報(bào)錯(cuò)。AMESim與simulink聯(lián)合仿真同理。AMESim用自己的積分器完成內(nèi)部動(dòng)態(tài)計(jì)算simulink每固定周期從接口讀取數(shù)值。兩個(gè)工具之間的通信步長必須一致而且往往是整數(shù)倍關(guān)系。我做過一個(gè)氣動(dòng)系統(tǒng)聯(lián)合仿真simulink步長1msAMESim通信步長也是1ms結(jié)果總是偶發(fā)數(shù)據(jù)突跳后來發(fā)現(xiàn)AMESim內(nèi)部為了穩(wěn)定自動(dòng)縮小了積分步長而simulink側(cè)采樣的1ms間隔太粗把AMESim內(nèi)部波形的峰值硬生生“掐”掉了。后來我把simulink側(cè)通信步長降到0.1ms問題就消失了。聯(lián)合仿真另一個(gè)常見問題是不同求解器處理不連續(xù)事件的能力不同。Carsim這種偏連續(xù)動(dòng)力學(xué)的工具內(nèi)部用了變步長到了simulink接口卻按定步長采樣如果simulink里同時(shí)有離散控制器很容易在步長切換瞬間產(chǎn)生數(shù)值振蕩。我的經(jīng)驗(yàn)是聯(lián)合仿真優(yōu)先保證simulink側(cè)采用定步長并且通信步長統(tǒng)一寧可多花點(diǎn)計(jì)算時(shí)間也別讓兩側(cè)步長“打架”。4.3 代碼生成前的求解器檢查做嵌入式代碼生成的人都知道模型里的連續(xù)狀態(tài)是“罪惡之源”。生成C代碼時(shí)連續(xù)狀態(tài)意味著要帶上求解器的數(shù)值積分邏輯生成的代碼體積膨脹移植性和運(yùn)行效率都會(huì)打折扣。所以代碼生成前我一般建議做兩件事第一把能離散化的連續(xù)環(huán)節(jié)全部離散化。電機(jī)模型、濾波器、積分環(huán)節(jié)能用離散積分器比如離散狀態(tài)空間、單位延遲加增益實(shí)現(xiàn)的就不要用連續(xù)積分器。模型變成純離散系統(tǒng)后求解器直接選擇discrete定步長生成的代碼里完全不會(huì)出現(xiàn)積分解算邏輯干凈得很。第二如果實(shí)在無法避免連續(xù)狀態(tài)就把求解器設(shè)置成定步長連續(xù)求解器如ode4同時(shí)將代碼生成配置里的“Solver”設(shè)置為“Fixed-step auto”這樣生成的代碼結(jié)構(gòu)更可預(yù)測(cè)調(diào)試的時(shí)候也更容易定位問題。我還見過一個(gè)有意思的坑有人在代碼生成時(shí)把求解器設(shè)成變步長生成的代碼在目標(biāo)硬件上跑得奇慢無比后來排查發(fā)現(xiàn)代碼里嵌套了一個(gè)負(fù)責(zé)動(dòng)態(tài)步長調(diào)整的復(fù)雜函數(shù)。這就屬于選型邏輯的問題代碼生成不是仿真調(diào)參別指著在嵌入式環(huán)境里讓求解器“聰明地”變步長老老實(shí)實(shí)定步長吧。4.4 常見求解器報(bào)錯(cuò)排查速查表下面這個(gè)表是我歷次調(diào)試中總結(jié)的高頻報(bào)錯(cuò)每條都附了排查思路。當(dāng)你仿真再次報(bào)錯(cuò)的時(shí)候直接過來查這張表往往比翻幾千頁文檔管用。報(bào)錯(cuò)提示常見原因解決辦法Solver is taking a small step剛性問題、模型存在奇異性改用ode15s/ode23tb檢查模型有無除零Zero crossing detected過零抖動(dòng)、信號(hào)震顫加遲滯/濾波改用Adaptive零穿越State derivatives must be finite模型運(yùn)算出現(xiàn)NaN/Inf檢查除法/指數(shù)模塊防止越界Minimum step size violation容差太緊或模型剛性太強(qiáng)增大最小步長先換剛性求解器Model must be configured for fixed-step外部模式/代碼生成要求定步長切換為fixed-step并設(shè)置Fixed-step sizeAlgebraic loop detected模型存在無延遲代數(shù)環(huán)添加單位延遲/Memory模塊斷開環(huán)路Start solver module failed外部工具接口初始化失敗檢查聯(lián)合仿真端口配置與版本匹配排查求解器報(bào)錯(cuò)有個(gè)通用思路先看錯(cuò)誤出現(xiàn)在仿真哪個(gè)時(shí)刻那個(gè)時(shí)刻模型在做什么再反推是數(shù)值問題、模型結(jié)構(gòu)問題還是參數(shù)問題。千萬別一上來就“無腦改步長”步長只是表象背后往往藏著模型的邏輯缺陷。4.5 一個(gè)命令行快速切換求解器的技巧最后分享一個(gè)用命令快速切換求解器的小技巧我平時(shí)經(jīng)常在用。打開模型后在MATLAB命令窗口執(zhí)行% 設(shè)置變步長ode15s容差1e-4 set_param(myModel, Solver, ode15s, RelTol, 1e-4); % 設(shè)置定步長ode4步長1ms set_param(myModel, Solver, ode4, FixedStep, 0.001); % 切換為離散求解器 set_param(myModel, Solver, FixedStepDiscrete);有時(shí)候同一個(gè)模型要跑多組對(duì)比實(shí)驗(yàn)比如剛性和非剛性兩種求解器分別跑一遍手動(dòng)在GUI里點(diǎn)來點(diǎn)去太累用腳本一次性設(shè)置并在循環(huán)里跑比手點(diǎn)高效得多。寫在最后我在實(shí)際項(xiàng)目里養(yǎng)成的一個(gè)固定習(xí)慣是拿到新模型先看它有沒有連續(xù)狀態(tài)、有沒有高頻開關(guān)、有沒有跨數(shù)量級(jí)的時(shí)間常數(shù)這三件事確認(rèn)完再動(dòng)手選求解器。很多人一上來就默認(rèn)ode45跑到底結(jié)果卡在步長上欲仙欲死這不是模型的問題是選型思路的問題。另外再提醒一句求解器設(shè)置這種“看似不起眼”的參數(shù)往往隱藏著項(xiàng)目成敗的細(xì)節(jié)?;ㄊ昼娮x完這篇內(nèi)容下次你跑仿真的時(shí)候可能會(huì)感謝自己提前做過這些功課。