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

下一篇,把遗传算法运用到模型的思路捋一捋,还有代码分析过程。

猜你喜欢

转载自blog.csdn.net/weixin_40211315/article/details/80200523