1. 程式人生 > >Tecnomatix Plant Simulation 14 學習之路(三)

Tecnomatix Plant Simulation 14 學習之路(三)

本篇部落格主要介紹模型建模過程,以及相應的程式碼和邏輯解釋

從執行模型的角度來說,首先是初始化

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

 

 

下一篇,把遺傳演算法運用到模型的思路捋一捋,還有程式碼分析過程。