淺談Simulink/StateFlow建模
淺談Simulink/StateFlow建模
在汽車、工業控制、航空航天等行業,系統與軟件開發中,基於模型的設計(Model based Design,簡稱MBD)逐步在替代傳統的手工代碼開發方式,在MBD領域,Matlab/Simulink作為通用化的建模與代碼生成工具及其相關配套的工具鏈經過多年的積累,已經在國內外以上行業中被應用到產品的開發中。
在筆者所處的行業,由於對象的強非線性、多變量耦合性、時變特性以及被控對象和控制器的復雜性,在算法、容錯處理以及控制邏輯多方面都有著較高和較復雜的要求,而且以上幾方面常常是耦合在一起。基於以上考慮,不論是對被控對象還是控制器,建模是一件非常必要的事情。而
Simulink是從學生時代就接觸的一種通用化建模工具,這一工具同樣也陪伴著走上工作崗位。工作的前兩年,因崗位關系,精力更多的投入到了控制算法的設計與驗證上,相關算法最終也可以用MBD方式生成代碼,同時也積累了一定的實際應用經驗,當前負責的業務經過積累,有了相對的突破。但,隨著接觸更多更復雜的項目,總感覺有點缺憾,畢竟,個人對其他容錯處理及控制業務邏輯的關註卻相對較少,一定程度上造成了自己視野偏窄,崗位更多的定位在仿真驗證上,這種外部限制也讓自己“鞭長莫及”,有些對自我提高有幫助的工作因不是自己負責,無法做到全身性的學習與工作結合,對整個控制對象的控制過程的理解自然會有所欠缺。好在後來上層對當前工作職責的界限也有了重新的認知,有幸能在新項目中全面貫徹應用層都進行建模的要求,而且,代碼的需求則直接源自更上層的需求以及模型,中遠期必然是走
一旦負責了整個應用層的建模,則必須將以上提到的容錯處理、算法以及邏輯上進行通盤考慮。其實,這時候作為建模人員,最重要的就是根據需求結合實現進行架構設計,這裏的架構設計,從我當前的認知來說,就是基於對工作場景的識別來進行功能的解耦與劃分,場景又可以分為大場景與小場景,大場景通常采用狀態機(StateFlow)來定義,小場景則既可以參考大場景來進行獨立設計成模塊也可以和功能模塊進行耦合,視具體情況和個人經驗而定,功能解耦則主要體現在不同功能最終需要用同一具體控制機構(被控對象與控制器之間還存在執行機構)來實現,這時候既要劃分不同的功能,又要有最終具體控制機構的綜合,在功能模塊中實現功能,在具體控制機構模塊中實現綜合,這裏的綜合更多的體現在優先級的判定與最終輸出量的抉擇上,以上的經驗也是經過很多項目的實踐和妥協得來的,未必說得上通用最優,但可以說是針對復雜對象進行控制建模的較好的方法,是一種不錯的架構設計實踐。
經過幾個月項目“錘煉”,多番需求的叠代與評審,多輪建模設計,在某個瞬間突然就開竅了,感覺一下子提高了需求的把控能力,無論是大方向還是具體細節,任何一個需求的更改,都能在腦子裏快速進行需求的分解並建立初步的Simulink模型,即將需求具體化,而所謂的建模,其實就是編碼實現,因為模塊化的建模即對應相應的函數代碼。
值得註意的是,Simulink模型通常都是基於數據流的,任何輸入必須對應相應的輸出,無論輸出是中間量還是最終量都有其對應的物理含義,即便這種含義是人為賦予的;這與C代碼在常規上還是區別的,在C語言中,某個全局變量可能隨時會根據不同的狀態進行變化,這樣容易導致某個變量在多個功能中賦值,這種到處賦值的危害是顯而易見的,除非實現約定好其中的某幾個,否則無約束必將導致混亂。在Simulink建模中同時被提及的還有StateFlow這一功能,StateFlow可以建立狀態機也可以進行流程設計,甚至可以調用Simulink模塊,調用非常靈活,但靈活帶來的也是復雜性,事實上StateFlow更接近於手工代碼,為了實現某個相對復雜的邏輯采用StateFlow來實現,既有狀態又有代碼,這種形式實際上就是把C代碼進行一種函數封裝,但顯然不具備通用性,與Simulink混用,用的不好很容易打斷數據流,讓人產生混亂,因此,從個人角度,一般不推薦大量使用StateFlow。建議在以下幾種場景下使用:
1、對於大量使用的基準模塊,若用StateFlow實現更簡單;
2、對於大的場景定義,推薦使用,同時不推薦把具體功能放在狀態機裏邊實現;
3、對於綜合模塊,推薦使用。
對於狀態中常用的功能,則通過產生標識(進入與推出條件完備)與輸出,由Simulink實現,來給綜合模塊進行抉擇。
限於工作性質,只能啰啰嗦嗦這麽多,估計也就自己聽懂了,畢竟以上經驗之談有行業的局限性,未必適合其他的,權當是前陣子工作的一個小結吧。
淺談Simulink/StateFlow建模