寫一個具有model based design功能的Simulink需要哪些技術?難度如何?
01-03
Simulink自從有了model based design之後就如虎添翼,有點黑科技的感覺。我一直想做一個有類似的功能的開源項目:能夠和腳本語言交互,使用圖形方式建立模型進行模擬,並且可以將模型編譯成c代碼或者可執行代碼。請各位大神幫忙分析一下,或者給個思路,謝謝!
題主您好,我在CSDN與matlab論壇也看到過類似的問題,但是回答的專家往往從專業角度分析,把難度預估過大,甚至建議放棄。但事實上,類似的數值模擬軟體(基於可視化模塊的),我在大二時已獨立製作出來,名叫《SimuBlocks》,現已獲得第九屆全國計算機設計大賽一等獎,免費使用,暫未開源。下載地址為http://pan.baidu.com/share/link?shareid=1801351120uk=2870215393有圖有真相,這是軟體截圖:
(主界面)
(前面的窗口是示波器輸出,後面的是模型搭建區域,這裡是求解洛倫茲氣象方程組,輸出圖像是著名的洛倫茲吸引子)- 首先軟體核心是對模型網路的模擬計算,這一部分問題可細分為:如何描述模塊,如何描述網路,如何驅動整個網路的運算。作者選用的語言是C++,所以很自然用類來描述模塊,這樣做有很多好處,在此不一一贅述,但應該說明,使用面向對象也不是必須的,如也可採用函數+結構體來進行模塊描述;網路描述即對用戶給定的一組互相關聯的模塊進行記錄,如果是擅長演算法理論的同學在此可能聯想到樹,圖等數據結構,這可以理解,因為模擬網路直觀上的確是一張"圖",但是如果按此思路往下,可能就會想到專門構造一張圖結構來管理和描述模塊。但是作者認為,這裡如果採用第三方數據結構描述網路,在性能上會打折扣,而且程序會不美觀簡潔,而研究發現,通過對模塊類特殊的構造,可以讓網路由一個個模塊自身進行描述,而不靠第三方數據結構管理,具體細節在此省略;正是用了上述特性,在驅動網路計算上也變得簡單---從示波器模塊開始激活運算程序,利用模塊自身和網路的關聯,運算很快擴散開完成一趟。即便驅動運算上採用了較好的方法,但同為網路模擬軟體咱也"不能免俗"------這裡也要面對"代數環"問題,即網路存在反饋時,模塊的輸入又依賴輸出,如果不加控制就會陷入永久循環,這個問題作者採用了全局--局部時鐘非同步檢測的方法來解決,這個技術可以公開簡述下:全局網路上給定一個時間變數gT,每個模塊內部設定一個局部時間nT,初始時令gT為設定好的起始時刻,令nT為任意負數,使得二者初始非同步,gT由模塊外部程序控制增加(一趟計算後增加模擬步長dT),當模塊每次計算時,先檢查二者是否相同,如果不同則未產生代數環,按照預設功能程序計算並返回結果,同時令nT=gT;否則產生代數環,這時不做任何計算,直接返回上一時刻的結果(一份緩存)。將此演算法實現在會產生代數環的模塊內(積分模塊等),可以很好的解決此問題。 以上核心程序作者在控制台程序里完成,完全與圖形界面分離,以保證穩定性和方便移植其他平台。
- 核心完成後,接下來是可視化過程(使用MFC,無其他特殊庫,windows98以上系統測試均可運行),雖然這部分只是把核心程序整合到一個圖形化界面里,難度不大,但是工程量卻更大。首先是製作各模塊的圖標,這裡沒有像simulink那樣直接用程序畫圖標,是因為作者認為那樣太"簡單粗暴",雖然可以說模擬軟體不用太講究長相,但畢竟使用模擬計算的用戶也是人,也愛美嘛,所以作者就用flash設計製作圖標,並採用2D遊戲程序的一些繪圖技術,來表現整個模擬網路,相信使用過的同學應該會對視覺效果給予一些肯定,界面程序方面大致可歸為兩個類-----一個類管理模塊,數據上記錄模塊和埠位置等信息,功能上實現刪除和新增模塊等;另一個類管理連線,數據上記錄線條的結點位置以及關聯的模塊,功能上實現線條的增刪和動態分配空間等;可視化的另一大部分就是示波器與繪圖儀窗口,原理是驅動核心層開始計算後,連續從示波器模塊採集數據並存入堆內存,計算結束後,新建一個示波器窗口對象,把堆內存指針傳入,由顯示窗口進行分析繪圖。這裡也是總結了simulink輸出圖像操作上的一些不足,所以在圖像窗口中加入了隨滑鼠自由拖動,自由縮放的功能,並且在同一窗口內加入了諸如極值,零點,導數等數據分析功能。 (如圖是示波器按照散點模式進行顯示)
- 最後一部分是模型文件的保存與載入功能,這裡的工作量僅次於可視化,開始甚至由於預期很複雜而想過放棄此功能,但是後來偶然想到了一種記號法---即把各類模塊編號,保存時以數字代替具體模塊,描述有哪些模塊以及之間的連接關係,當然模塊運算參數,模塊位置以及線條信息的保存也是必須的;載入模型文件時按照序號和其他參數再次構造即可。 以上就是製作一個類似simulink軟體的簡略過程,自然還有不少細節未予描述,例如模塊的具體計算,誤差控制問題,圖像繪製問題等。另外到作者編輯本文時,最新版為3.1版(尚未上傳,預計本周內),已加入子系統封裝功能,而下一版本會加入自定義模塊---允許用戶使用lua腳本程序編輯模塊功能,實現自己的計算模塊,整個軟體打算到此完結,因為加入腳本介面後,模擬模塊可以由廣大用戶自行擴展,作者全當是提供了一個模擬框架,而且目前不考慮收費,就是收費也不會超過五元(相比simulink大家懂得),只希望自己祖國的模擬軟體越來越好,也希望以此軟體作為青春和大學的一個印記,不得不承認,或許一生都無法超越simulink那種軟體巨頭,無論是功能上還是模塊數量上,但是這並不妨礙我們寫出自己的模擬工具,無關攀比,只是一種情懷,一種喜悅:) (第一次在知乎寫份回答,不免有很多粗糙的地方還望見諒,如有任何問題可以在評論中問我,一定會儘可能解答清楚)
附上後來新版本的使用截圖
任意埠模塊做迭代,生成分形蕨題主是想自己弄一個類似Simulink的開源軟體吧。建議題主搜索一下domain specific language。這個難度很大,因為Simulink的核心是解微分方程的solver,所以MathWorks有首席數學家來解決這類問題。另外,code generation的正確性需要大量的驗證。
可以關注Modelica語言,開源的,圖形化,c介面,國外有拿這個自動生成代碼,控制硬體的
我做過一個非常簡單的教學項目。基於Arduino的直流電機位置控制。能實現功能: 不需要任何底層編程,Simulink 設計控制器,download 到arduino, 控制電機。
(直接來張圖吧,過段實驗要刪掉,因為在準備寫個教學論文)。推薦閱讀:
※內聯函數可以是虛函數嗎?
※請問mono unity Xamarin 這三者之間是什麼關係?
※初學者學編程,是看項目源碼學習,還是看著書一步步敲代碼見效?
※詳細介紹一下python和matplotlib,ipython的安裝使用方法?
※Python for 循環中 in 關鍵字含義是什麼?