Tecnomatix Plant Simulation 14 學習之路(三)
阿新 • • 發佈:2018-11-10
本篇部落格主要介紹模型建模過程,以及相應的程式碼和邏輯解釋
從執行模型的角度來說,首先是初始化
HandlingCost := 0
PartsNo :=0
InitPartsTable --初始化表格
GASequence.delete --刪除GA序列
for var i := 1 to Number_OF_Machine --與遺傳演算法有關,用於生成初始序列
GASequence[1, i] := i
next
InitPartsTable方法釋義如下
var Rows, Lines: integer var MachineName, BufName: string var Machine, Buf: object if Number_Of_Machine /= D_From_To_Chart.YDim --為整數代表True switch messageBox("設施數目不對,請核查…", 50, 13) --數字50表示按鈕組合是否取消,數字13表示帶有感嘆號的黃色三角形。 case 16 --1表示確定,2表示取消,16表示是,32表示否。 print "yes" case 32 print "no" else print "Cancel" end EventController.stop --事件停止執行 end PartsTable.delete --清空列表 for var i := 1 to Number_Of_Machine for var j := 1 to Number_Of_Machine if j < i --表格左下角部分 if D_From_To_Chart[j,i] <= 0 --如果左下角小於或者等於0 D_From_To_Chart[j,i] := D_From_To_Chart[i,j]; --右上角對稱對應值填補到左下角 end else if j = i --表格對角線部分 D_From_To_Chart[j,i] := 0 --置0 else if D_From_To_Chart[j,i] <= 0 --表格右上角部分 messageBox("距離小於等於零...",50, 13) --判斷是否有誤輸入值,否則不幹了 EventController.stop end end end next next for var m := 1 to Number_Of_Machine --刪除之前建立的機器物件以及前置快取區 MachineName := sprint("M", m) --MachineName = "M1" ... "M8" if existsObject(MachineName) --判斷MachineName是否存在,返回布林值 Machine := str_to_obj(MachineName) --字串轉物件,賦給Machine,這裡是刪機器"M1"..."M8" Machine.deleteObject --刪除物件 end BufName := sprint("BF", m) --BufName = "BF1"..."BF8" if existsObject(BufName) --判斷MachineName是否存在,返回布林值 Buf := str_to_obj(BufName) --字串轉物件,賦給Buf,這裡是刪機器"BF1"..."BF8" Buf.deleteObject --刪除物件 end next Lines := 0 for var n := 1 to Number_Of_Machine Rows := str_to_num(Omit(MachineSequence[1,n],1, 1)) --Omit函式,這裡是指從MachineSequence表裡從指定位置刪除內容(1,1),代表刪除第一個開始的一個元素,具體"M1”刪除了"M",留下了“1” MachineSequence[2, n] := Rows --把"1"..."8"放到第二列 for var p := 1 to Number_Of_Machine if W_From_To_Chart[p, Rows] > 0 --按行掃描,只要存在搬運物料就寫入表PartsTable Lines := Lines + 1 PartsTable[1, Lines] := str_to_obj(sprint(".", location.name,".Parts")) --寫模型名字 PartsTable[2, Lines] := W_From_To_Chart[p, Rows] --寫模型物料量 PartsTable[3, Lines] := sprint("Parts") --寫入名稱"Parts" PartsTable[5, Lines] := Rows --寫入表格W_From_To橫座標,即物料源地址 PartsTable[6, Lines] := p --寫入表格W_From_To縱座標,即物料目的地址 end next MachineName := sprint("M", Rows) --MachineName = "M1" ... "M8" Machine := .MaterialFlow.SingleProc.createObject(current, X_pos_init + D_From_To_Chart[Number_Of_Machine + 1, n], Y_pos_init +D_From_To_Chart[Number_Of_Machine + 2, n]) -- 建立處理過程物件(機器)指定存放位置,在D_From_To_Chart第9列和第10列存放,下面快取物件類似 Machine.Name := MachineName --定義名字賦給機器名 Machine.ProcTime := 5 --定義處理時間 Machine.label := sprint("機器_", Rows) --設定標籤 Machine.ExitCtrl := &Leave --每當機器處理完零件,零件離開觸發Leave方法 BufName := sprint("BF", Rows) --BufName = "BF1"..."BF8" Buf := .MaterialFlow.Buffer.createObject(current, X_pos_init + D_From_To_Chart[Number_Of_Machine + 1, n]-35, Y_pos_init + D_From_To_Chart[Number_Of_Machine+2, n]) -- 建立處理過程物件(前置快取區)指定存放位置,在D_From_To_Chart第9列和第10列存放,扣去橫座標相對位移35 Buf.Name := BufName Buf.Capacity := 5000 Buf.ProcTime := 0 .MaterialFlow.Connector.connect(Buf, Machine) --對應的前置快取區和機器相連 next
通過上述兩部初始化動作,八個前置快取區和八個機器就已經按如下順序放在對應的地點,並且PartsTable表格已經建立完畢,以下為部分示意圖
另外,關於從至表的填寫和校準工作也已經完成,也就是W_From_To_Chart表和D_From_To_Chart表已經佈置和核對,MachineSequence的第一、二列也完成
初始化之後,單擊執行按鈕。這裡便是Source物件的理解
在本模型當中,Source每間隔20s產生一個零件(物料),由於採用了序列模式,關聯了PartsTable表格,所以產生的零件(物料量)的種類不同,每種型別的個數也不一樣。並且對於每個具體的Parts(零件),它的源地址和目的地址設定好,當然每批同類型的零件都流向了同樣的目的地,源地址也相同。
零件流通方向大致示意圖如下,假設第一個加工零件,由Source的Load產生,放置於BF1前置快取區,再經過M1機器處理,離開執行Leave方法,再流向BF2快取區,再經過M2機器處理,最終到達Drain
關於Load方法,下面為程式碼和註解
var no, m: integer var Buf: object m := 0 no := @.getNo --獲取Parts(零件)編號,比如第一個過來的零件編號是1,接下來第二個過來就編號2了,注意編號唯一,共2347 for var i := 1 to PartsTable.YDim --PartsTable.YDim = 24, 對PartsTable錶行迴圈 if PartsNo = m and no <= PartsNo + PartsTable[2, i] --判斷是否是同一批次的零件 @._From := PartsTable[5, i] --該零件源地址標記 @._to := PartsTable[6, i] --該零件目的地址標記 if no = PartsNo + PartsTable[2, i] --同批次最後一個零件到來的時候,更新下一批,結合上一個if PartsNo = m的判斷 PartsNo := PartsNo + PartsTable[2, i] end i := PartsTable.YDim + 1 --跳出迴圈,值得注意下面m := m + PartsTable[2, i]會執行 end m := m + PartsTable[2, i] --m獲取每批次需要運輸的零件量 next Buf := str_to_obj(sprint("BF", @._From)) --建立當前零件流入的Buf(快取區) @.move(Buf) --把零件放置到快取區
關於Leave方法,下面為程式碼和註解
var i, j: integer
var Machine: object
Machine := str_to_obj(sprint("M", @._To)) --建立當前零件目的地址機器
if ?.name /= Machine.Name --判斷該零件的目的地屬性是否就是本機床,名字相同執行else部分,名字不同執行if下面程式碼團
Machine := str_to_obj(sprint("BF", @._To)) --放到下一個快取區
@.move(Machine) --移動到下一個機器
for var k := 1 to Number_Of_Machine --在MachineSequence表裡面找到對應的機器的源地址和目的地對應的D_From_To_Chart的移動距離
if MachineSequence[2, k] = @._From
i := k
end
if MachineSequence[2, k] = @._To
j := k
end
next
HandlingCost := HandlingCost + D_From_To_Chart[j, i] --目標函式(注意,因為零件已經時一個個上傳過來了,所以距離的累加其實預設乘以1零件數,求值方法巧妙)
else
@.move(Drain)
end
下一篇,把遺傳演算法運用到模型的思路捋一捋,還有程式碼分析過程。