<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4024.13">
  <POU Name="FB_Visu" Id="{479aab94-0b41-4fc1-b99e-58aae65276a6}" SpecialFunc="None">
    <Declaration><![CDATA[FUNCTION_BLOCK FB_Visu
VAR
	// ============================== 轴 NCTOPLC 的输入结构体 =====================================
	
	// 这里没用AXIS_REF是因为轴变量不能多次绑定，而 NCTOPLC_AXIS_REF 的某些状态字是可以多次绑定的，在模拟程序中，只会用到一些状态字去检测轴的一些 NC 参数
	
	MainAxisState			AT %I*		: NCTOPLC_AXIS_REF;			// 运输皮带 	NCTOPLC 的输入结构体
	MetalAxisState			AT %I*		: NCTOPLC_AXIS_REF;			// 金属分拣皮带 NCTOPLC 的输入结构体
	PlasticAxisState		AT %I*		: NCTOPLC_AXIS_REF;			// 塑料分拣皮带 NCTOPLC 的输入结构体
	bresetAxis				AT %Q*      : BOOL;						// 如果主程序当中的轴出现 NC 报错，那需要在 HMI 当中做一个按钮去复位轴报错
	
	// =================================== 设备的一些状态 ===============================
	bComprAirEnabled		AT %I*		: BOOL;						// 如果为TRUE，则设备的气缸空气被压缩
	bPowerEnabled			AT %I*		: BOOL;						// 如果为TRUE，则设备已经使能
	bClampToWork			AT %I*		: BOOL;						// 如果为TRUE，则正位气缸存在输出
	bBarrierToWork			AT %I*		: BOOL;						// 如果为TRUE，则栏杆气缸存在输出
	bMetalToWork			AT %I*		: BOOL;						// 如果为TRUE，则金属分拣气缸存在输出
	bPlasticToWork			AT %I*		: BOOL;						// 如果为TRUE，则塑料分拣气缸存在输出
	
	// ====================================== 错误信息 ====================================
	bError					AT %I*		: BOOL;						// 如果为TRUE，则设备存在错误
	bClampError				AT %I*		: BOOL;						// 如果为TRUE，则正位气缸存在错误
	sClampErrMsg			AT %I*		: STRING;					// 正位气缸的错误信息
	bMetalCylError			AT %I*		: BOOL;						// 如果为TRUE，则金属分拣气缸存在错误
	sMetalErrMsg			AT %I*		: STRING;					// 金属分拣气缸的错误信息
	bPlasticCylError		AT %I*		: BOOL;						// 如果为TRUE，则塑料分拣气缸存在错误
	sPlasticErrMsg			AT %I*		: STRING;					// 塑料分拣气缸的错误信息
	sMessageMainAxis		AT %I*		: STRING;					// 运输皮带的错误信息
	sMessageMetalAxis		AT %I*		: STRING;					// 金属分拣出料皮带的错误信息
	sMessagePlasticAxis		AT %I*		: STRING;					// 塑料分拣出料皮带的错误信息

	
	// ============================ PackML状态机的状态标志位 ==============================
	bStarted				AT %I*		: BOOL;						// 如果为TRUE，则设备在运行状态
	bStopped				AT %I*		: BOOL;						// 如果为TRUE，则设备在停止状态
	bReset					AT %I*		: BOOL;						// 如果为TRUE，则设备在复位中状态
	bAborted				AT %I*		: BOOL;						// 如果为TRUE，则设备在中止状态
	bIdle					AT %I*		: BOOL;						// 如果为TRUE，则设备在空闲状态
	bAuto					AT %I*		: BOOL;						// 如果为TRUE，则设备在自动模式
	bSemi					AT %I*		: BOOL;						// 如果为TRUE，则设备在半自动模式
	bManual					AT %I*		: BOOL;						// 如果为TRUE，则设备在手动模式
	bMaintenance			AT %I*		: BOOL;						// 如果为TRUE，则设备在维护模式
	
	bStartButtonOff			AT %I*		: BOOL;						// 自复位启动按钮的中间变量

	// ============================ HMI 按钮输入的状态 ==================================
	
	// HMI按钮信号直接传递给bButtonXXXOut，绑定给主程序信号处理功能块的In，然后经过主程序信号处理功能块的Out绑定回来，用来做一些 HMI 按钮颜色，切换的逻辑
	
	bButtonPowerIn			AT %I*		: BOOL;						// 使能按钮的状态
	bButtonComprAirIn		AT %I*		: BOOL;						// 气缸压缩按钮的状态
	bButtonStartIn			AT %I*		: BOOL;						// 启动按钮的状态
	bButtonStopIn			AT %I*		: BOOL;						// 停止按钮的状态
	bButtonResetIn			AT %I*		: BOOL;						// 复位按钮的状态
	bButtonAbortIn			AT %I*		: BOOL;						// 中止按钮的状态
	
	bButtonAutoIn			AT %I*		: BOOL;						// 自动模式按钮的状态
	bButtonSemiIn			AT %I*		: BOOL;						// 半自动模式按钮的状态
	bButtonManuIn			AT %I*		: BOOL;						// 手动模式按钮的状态
	bButtonMaintenanceIn	AT %I*		: BOOL;						// 维护模式按钮的状态

	bButtonMainFwIn			AT %I*		: BOOL;						// 正向点动输送皮带按钮的状态
	bButtonMainBwIn			AT %I*		: BOOL;						// 反向点动输送皮带按钮的状态
	bButtonMetalFwIn		AT %I*		: BOOL;						// 正向点动金属分拣出料皮带按钮的状态
	bButtonMetalBwIn		AT %I*		: BOOL;						// 反向点动金属分拣出料皮带按钮的状态
	bButtonPlasticFwIn		AT %I*		: BOOL;						// 正向点动塑料分拣出料皮带按钮的状态
	bButtonPlasticBwIn		AT %I*		: BOOL;						// 反向点动塑料分拣出料皮带按钮的状态
	
	bButtonClampToWorkIn	AT %I*		: BOOL;						// 正位气缸输出按钮的状态
	bButtonBarrierToWorkIn	AT %I*		: BOOL;						// 栏杆气缸输出按钮的状态
	bButtonMetalToWorkIn	AT %I*		: BOOL;						// 金属分拣气缸输出按钮的状态
	bButtonPlasticToWorkIn	AT %I*		: BOOL;						// 塑料分拣气缸输出按钮的状态


	
	// ============================== HMI 按钮的输出信号 ===============================
	
	// 绑定给主程序信号处理功能块的In
	
	bButtonPowerOut			AT %Q*		: BOOL;						// 使能按钮的信号
	bButtonComprAirOut		AT %Q*		: BOOL;						// 气缸压缩按钮的信号
	bButtonStartOut			AT %Q*		: BOOL;						// 启动按钮的信号
	bButtonStopOut			AT %Q*		: BOOL;						// 停止按钮的信号
	bButtonResetOut			AT %Q*		: BOOL;						// 复位按钮的信号
	
	bButtonAutoOut			AT %Q*		: BOOL;						// 自动模式按钮的信号	
	bButtonSemiOut			AT %Q*		: BOOL;						// 半自动模式按钮的信号
	bButtonManuOut			AT %Q*		: BOOL;						// 手动模式按钮的信号
	bButtonMaintenanceOut	AT %Q*		: BOOL;						// 维护模式按钮的信号	
	
	bButtonMainFwOut		AT %Q*		: BOOL;						// 正向点动输送皮带按钮的信号
	bButtonMainBwOut		AT %Q*		: BOOL;						// 反向点动输送皮带按钮的信号
	bButtonMetalFwOut		AT %Q*		: BOOL;						// 正向点动金属分拣出料皮带按钮的信号
	bButtonMetalBwOut		AT %Q*		: BOOL;						// 反向点动金属分拣出料皮带按钮的信号
	bButtonPlasticFwOut		AT %Q*		: BOOL;						// 正向点动塑料分拣出料皮带按钮的信号
	bButtonPlasticBwOut		AT %Q*		: BOOL;						// 反向点动塑料分拣出料皮带按钮的信号
	
	bButtonClampToWorkOut	AT %Q*		: BOOL;						// 正位气缸输出按钮的信号
	bButtonBarrierToWorkOut	AT %Q*		: BOOL;						// 栏杆气缸输出按钮的信号
	bButtonMetalToWorkOut	AT %Q*		: BOOL;						// 金属分拣气缸输出按钮的信号
	bButtonPlasticToWorkOut	AT %Q*		: BOOL;						// 塑料分拣气缸输出按钮的信号

	
	// =========================== 模拟程序当中元素的坐标参数 ===========================
	fYClamp								: LREAL;					// 正位气缸的纵坐标
	fYBarrier							: LREAL;					// 栏杆气缸的纵坐标
	fYMetal								: LREAL;					// 金属分拣气缸的纵坐标
	fYPlastic							: LREAL;					// 塑料分拣气缸的纵坐标
	aBoxX								: ARRAY[1..4] OF LREAL;		// 物料的横坐标数组
	aBoxY								: ARRAY[1..4] OF LREAL;		// 物料的纵坐标数组

	// ============================= 物料移动参数 =========================================
	nLastBox						: INT;						// 在运输皮带当中物料的序号，			如：nLastBox := 1，则一号物料在运输当中
	aBoxMetalMove					: ARRAY[1..4] OF BOOL;		// 第几个物料在被金属分拣气缸分拣，		如：aBoxMetalMove[1] := TRUE，则一号物料在被金属分拣气缸分拣
	aBoxMetalFree					: ARRAY[1..4] OF BOOL;		// 第几个物料没在被金属分拣气缸分拣		如：aBoxMetalFree[1] := TRUE，则一号物料没有在被金属分拣气缸分拣
	aBoxPlasticMove					: ARRAY[1..4] OF BOOL;		// 第几个物料在被塑料分拣气缸分拣		如：aBoxPlasticMove[1] := TRUE，则一号物料在被金属分拣气缸分拣
	aBoxPlasticFree					: ARRAY[1..4] OF BOOL;		// 第几个物料没在被塑料分拣气缸分拣		如：aBoxPlasticFree[1] := TRUE，则一号物料没有在被塑料分拣气缸分拣
	aBoxMainBelt					: ARRAY[1..4] OF BOOL;		// 第几个物料在运输皮带当中运输			如：aBoxMainBelt[1] := TRUE，则一号物料在运输当中
	aBoxMetalBelt					: ARRAY[1..4] OF BOOL;		// 第几个物料在金属分拣皮带当中运出		如：aBoxMetalBelt[1] := TRUE，则一号物料在运输当中
	aBoxPlasticBelt					: ARRAY[1..4] OF BOOL;		// 第几个物料在塑料分拣皮带当中运出		如：aBoxPlasticBelt[1] := TRUE，则一号物料在运输当中
	
	fMainVelo						: LREAL;					// 运输皮带的转动速度
	fMetalVelo						: LREAL;					// 金属分拣皮带的转动速度
	fPlasticVelo					: LREAL;					// 塑料分拣皮带的转动速度
	
	bAccident						: BOOL;						// 如果为TRUE，则出现意外事故			如：撞机
	nState							: INT;						// 物料的索引							如：nState := 1，则当前是1号物料
	
	// ================================= 信息 ==========================================
	nMessages						: INT;						// 信息的个数
	sMessageClamp					: STRING;					// 正位气缸的信息
	sMessageMetalCyl				: STRING;					// 金属分拣气缸的信息
	sMessagePlasticCyl				: STRING;					// 塑料分拣气缸的信息

	
	// ============================= 轴运动的参数 =======================================
	nAngleMain						: INT;						// 输送皮带转动时旋转的角度（HMI）
	nAngleMetal						: INT;						// 金属分拣皮带转动时旋转的角度（HMI）
	nAnglePlastic					: INT;						// 塑料分拣皮带转动时旋转的角度（HMI）
	fbTimerMainAxis					: TON;						// 输送皮带转动时到 HMI 图标开始转动的计时器 TON 功能块 
	fbTimerMetalAxis				: TON;						// 金属分拣皮带转动时到 HMI 图标开始转动的计时器 TON 功能块 
	fbTimerPlasticAxis				: TON;						// 塑料分拣皮带转动时到 HMI 图标开始转动的计时器 TON 功能块 
	tMoveAxis						: TIME := T#0MS;			// 皮带转动时到 HMI 图标开始转动的延迟时间，这里随机设置一个40ms较短的时间

	// ========================= 按钮颜色的相关参数 ====================================
	nButtonColorStart				: DWORD;					// 启动按钮的颜色
	bButtonColorStart				: BOOL;						// 如果为TRUE，则切换启动按钮的颜色
	nButtonColorStop				: DWORD;					// 停止按钮的颜色
	bButtonColorStop				: BOOL;						// 如果为TRUE，则切换停止按钮的颜色
	nButtonColorReset				: DWORD;					// 复位按钮的颜色
	bButtonColorReset				: BOOL;						// 如果为TRUE，则切换停止按钮的颜色
	nButtonColorAuto				: DWORD;					// 自动模式按钮的颜色
	bButtonColorAuto				: BOOL;						// 如果为TRUE，则切换自动模式按钮的颜色
	nButtonColorSemi				: DWORD;					// 半自动模式按钮的颜色
	bButtonColorSemi				: BOOL;						// 如果为TRUE，则切换半自动模式按钮的颜色
	nButtonColorManu				: DWORD;					// 手动模式按钮的颜色
	bButtonColorManu				: BOOL;						// 如果为TRUE，则切换手动模式按钮的颜色
	nButtonColorMaint				: DWORD;					// 维护模式按钮的颜色
	bButtonColorMaint				: BOOL;						// 如果为TRUE，则切换维护模式按钮的颜色
	nButtonColorClamp				: DWORD;					// 手动控制正位气缸按钮的颜色
	bButtonColorClamp				: BOOL;						// 如果为TRUE，则切换手动控制正位气缸按钮的颜色
	nButtonColorBarrier				: DWORD;					// 手动控制栏杆气缸按钮的颜色
	bButtonColorBarrier				: BOOL;						// 如果为TRUE，则切换手动控制栏杆气缸按钮的颜色
	nButtonColorMetalCyl			: DWORD;					// 手动控制金属分拣气缸按钮的颜色
	bButtonColorMetalCyl			: BOOL;						// 如果为TRUE，则切换金属分拣气缸按钮的颜色
	nButtonColorPlasticCyl			: DWORD;					// 手动控制塑料分拣气缸按钮的颜色
	bButtonColorPlasticCyl			: BOOL;						// 如果为TRUE，则切换塑料分拣气缸按钮的颜色
	nButtonColorMainFw				: DWORD;					// 手动控制输送皮带正转按钮的颜色
	bButtonColorMainFw				: BOOL;						// 如果为TRUE，则切换手动控制输送皮带正转按钮的颜色
	nButtonColorMainBw				: DWORD;					// 手动控制输送皮带反转按钮的颜色
	bButtonColorMainBw				: BOOL;						// 如果为TRUE，则切换手动控制输送皮带反转按钮的颜色
	nButtonColorMetalFw				: DWORD;					// 手动控制金属分拣皮带正转按钮的颜色
	bButtonColorMetalFw				: BOOL;						// 如果为TRUE，则切换手动控制金属分拣皮带正转按钮的颜色
	nButtonColorMetalBw				: DWORD;					// 手动控制金属分拣皮带反转按钮的颜色
	bButtonColorMetalBw				: BOOL;						// 如果为TRUE，则切换手动控制金属分拣皮带反转按钮的颜色
	nButtonColorPlasticFw			: DWORD;					// 手动控制塑料分拣皮带正转按钮的颜色
	bButtonColorPlasticFw			: BOOL;						// 如果为TRUE，则切换 手动控制塑料分拣皮带正转按钮的颜色
	nButtonColorPlasticBw			: DWORD;					// 手动控制塑料分拣皮带反转按钮的颜色
	bButtonColorPlasticBw			: BOOL;						// 如果为TRUE，则切换手动控制塑料分拣皮带反转按钮的颜色
	nButtonColorComprAir			: DWORD;					// 压缩气缸空气按钮的颜色
	bButtonColorComprAir			: BOOL;						// 如果为TRUE，则切换压缩气缸空气按钮的颜色

	// ================================== 其他 =======================================
	RandomGenerator					: DRAND;					// 随机函数生成的功能块
	RandomNumber					: LREAL;					// 随机数（0-1）
	bRandomChangeColor				: BOOL;						// 如果为TRUE，则随机的切换物料颜色
	ArrChangeColor					: ARRAY[1..4] OF BOOL	:= [TRUE,FALSE,FALSE,TRUE];	// 物料的随机颜色：如：ArrChangeColor[1]:= true; 则1号物料是灰色
	
	bButtonColorAutoNew				: BOOL;						// 如果为TRUE，则当前控制模式为自动模式且无报错，用来启用 HMI 当中的自动按钮
	bButtonColorSemiNew				: BOOL;						// 如果为TRUE，则当前控制模式为半自动模式且无报错，用来启用 HMI 当中的半自动按钮
	bButtonColorManuNew				: BOOL;						// 如果为TRUE，则当前控制模式为手动模式且无报错，用来启用 HMI 当中的手动按钮
	bButtonColorMaintNew			: BOOL;						// 如果为TRUE，则当前控制模式为维护模式且无报错，用来启用 HMI 当中的维护按钮
END_VAR
VAR CONSTANT
	// ================================== 颜色 =======================================
	cYellow 									: DWORD	:= 16#00FFFF80;		// 黄色的ARGB对应的16进制值
	cGreen 										: DWORD	:= 16#0080FF00;		// 绿色的ARGB对应的16进制值
	cPink 										: DWORD	:= 16#00FF8080;		// 粉色的ARGB对应的16进制值
	
	// ============================ HMI图标移动参数 ===================================
	cVelocityDenominator						: LREAL := 250.0;			// 速度比例分母。HMI 图标旋转的速度是实际轴速度的一个比值。
	cAxisMovementSemiPlusAuto					: INT 	:= 2;				// 半自动和自动模式下，HMI 轴每个PLC周期的移动角度
	cAxisMovementManual							: INT 	:= 1;				// 手动模式下，HMI 轴每个PLC周期的移动角度
	cClampMovement								: LREAL := 0.1;				// 每个PLC周期正位气缸的移动量
	cBarrierMovement							: LREAL := 1.0;				// 每个PLC周期栏杆气缸的移动量
	cMetalPlasticCylMovement					: LREAL := 1.0;				// 每个PLC周期塑料/金属分拣气缸的移动量
	
	// ========================= HMI图标各个位置的标定参数 ============================
	cYClampCylStartPos							: LREAL := 0.0;				// 正位气缸的基始位置纵坐标
	cYClampCylEndPos							: LREAL := 3.0;				// 正位气缸的目标位置纵坐标
	cYBarrierCylStartPos						: LREAL := 0.0;				// 栏杆气缸的基始位置纵坐标
	cYBarrierCylEndPos							: LREAL := 63.0;			// 栏杆气缸的目标位置纵坐标
	cYMetalPlasticCylStartPos					: LREAL := 0.0;				// 金属/塑料分拣气缸的基始位置纵坐标
	cYMetalPlasticCylEndPos						: LREAL := -73.0;			// 金属/塑料分拣气缸的目标位置纵坐标
	
	// =========================== 物料宽度、距离参数 ==================================
	cBoxWidth									: LREAL := 60.0;			// HMI 当中物料的宽度
	cBarrierWidth								: LREAL := 30.0;			// HMI 当中栏杆气缸的宽度
	cDiffBarrierToStartOfMetalCyl				: LREAL := 191.0;			// HMI 当中从栏杆气缸到金属分拣气缸左侧位置的距离，单位为像素或实际测量单位
	cDiffBarrierToEndOfMetalCyl					: LREAL := 261.0;			// HMI 当中从栏杆气缸到金属分拣气缸右侧位置的距离，单位为像素或实际测量单位
	cDiffBarrierToStartOfPlasticCyl				: LREAL := 441.0;			// HMI 当中从栏杆气缸到塑料分拣气缸左侧位置的距离，单位为像素或实际测量单位
	cYMetalPlasticCylOnMainBelt					: LREAL := -9.0;			// HMI 当中金属和塑料分拣气缸到达主传送带时的位置纵坐标
	cYBoxesOnMetalPlasticBelt_min				: LREAL := -65.0;			// HMI 当中物料在金属或塑出料皮带上时的最小位置的纵坐标
	cYBoxesOnMetalPlasticBelt_max				: LREAL := -140.0;			// HMI 当中物料在金属或塑出料皮带上时的最大位置的纵坐标
	
	// ======================== 输送皮带当中物料的距离参数 ==============================
	cYforAllBoxesOnMainBelt						: LREAL := -5.0;			// HMI 当中物料在输送皮带上的纵坐标
	cYforAllBoxesNotOnMainBelt					: LREAL := -60.0;			// HMI 当中物料不在输送皮带上的纵坐标
	
	cYforAllBoxesStartPosMainBelt				: LREAL := 0.0;				// HMI 当中物料在输送皮带的第一个位置时的纵坐标
	cXforAllBoxesStartPosMainBelt				: LREAL := -240.0;			// HMI 当中物料在输送皮带的第一个位置时的横坐标
	cXforAllBoxesLastPossiblePosMainBelt		: LREAL := 461.0;			// HMI 当中物料在输送皮带上，可以移动到的最后位置横坐标
	
	cXforAllBoxesCorrectPushMetalCyl_min		: LREAL := 180;				// HMI 当中被金属分拣气缸推到金属出料皮带时，物料最小位置的横坐标
	cXforAllBoxesCorrectPushMetalCyl_max		: LREAL := 211;				// HMI 当中被金属分拣气缸推到金属出料皮带时，物料最大位置的横坐标
	cXforAllBoxesIncorrectPushMetalCyl_min		: LREAL := 131;				// HMI 当中被金属分拣气缸推出，但未推到金属出料皮带时，物料最小位置的横坐标
	cXforAllBoxesIncorrectPushMetalCyl_max		: LREAL := 261;				// HMI 当中被金属分拣气缸推出，但未推到金属出料皮带时，物料最大位置的横坐标
	
	cXforAllBoxesCorrectPushPlasticCyl_min		: LREAL := 430;				// MMI 当中被塑料分拣气缸推到塑料出料皮带时，物料最小位置的横坐标
	cXforAllBoxesCorrectPushPlasticCyl_max		: LREAL := 461;				// HMI 当中被塑料分拣气缸推到塑料出料皮带时，物料最大位置的横坐标
	cXforAllBoxesIncorrectPushPlasticCyl_min	: LREAL := 381;				// HMI 当中被塑料分拣气缸推出，但未推到塑料出料皮带时，物料最小位置的横坐标
	
	// Box 1
	cXforBox1_MainBelt_Diff2to1_min				: LREAL := 1;				// 物料 2 到物料 1 之间的最小距离，以便物料 1 能够在输送皮带上移动
	cXforBox1_MainBelt_Diff2to1_max				: LREAL := 121;				// 物料 2 到物料 1 之间的最大距离，以便物料 1 能够在输送皮带上移动 
	cXforBox1_MainBelt_Diff3to1_min				: LREAL := 61;				// 物料 3 到物料 1 之间的最小距离，以便物料 1 能够在输送皮带上移动（1+60）
	cXforBox1_MainBelt_Diff3to1_max				: LREAL := 181;				// 物料 3 到物料 1 之间的最大距离，以便物料 1 能够在输送皮带上移动
	cXforBox1_MainBelt_Diff4to1_min				: LREAL := 121;				// 物料 4 到物料 1 之间的最小距离，以便物料 1 能够在输送皮带上移动（1+120）
	cXforBox1_MainBelt_Diff4to1_max				: LREAL := 241;				// 物料 4 到物料 1 之间的最大距离，以便物料 1 能够在输送皮带上移动
	
	// Box 2
	cXforBox2_MainBelt_Diff1to2_min				: LREAL := -1;				// 物料 1 到物料 2 之间的最小距离，以便物料 2 能够在输送皮带上移动
	cXforBox2_MainBelt_Diff1to2_max				: LREAL := -121;			// 物料 1 到物料 2 之间的最大距离，以便物料 2 能够在输送皮带上移动
	cXforBox2_MainBelt_Diff3to2_min				: LREAL := 121;				// 物料 3 到物料 2 之间的最小距离，以便物料 2 能够在输送皮带上移动
	cXforBox2_MainBelt_Diff3to2_max				: LREAL := 1;				// 物料 3 到物料 2 之间的最小距离，以便物料 2 能够在输送皮带上移动
	cXforBox2_MainBelt_Diff4to2_min				: LREAL := 181;				// 物料 4 到物料 2 之间的最小距离，以便物料 2 能够在输送皮带上移动
	cXforBox2_MainBelt_Diff4to2_max				: LREAL := 61;				// 物料 4 到物料 2 之间的最小距离，以便物料 2 能够在输送皮带上移动

	// Box 3
	cXforBox3_MainBelt_Diff1to3_min				: LREAL := -61;				// 物料 1 到物料 3 之间的最小距离，以便物料 3 能够在输送皮带上移动
	cXforBox3_MainBelt_Diff1to3_max				: LREAL := -181;			// 物料 1 到物料 3 之间的最大距离，以便物料 3 能够在输送皮带上移动
	cXforBox3_MainBelt_Diff2to3_min				: LREAL := -1;				// 物料 2 到物料 3 之间的最小距离，以便物料 3 能够在输送皮带上移动
	cXforBox3_MainBelt_Diff2to3_max				: LREAL := -121;			// 物料 2 到物料 3 之间的最大距离，以便物料 3 能够在输送皮带上移动
	cXforBox3_MainBelt_Diff4to3_min				: LREAL := 121;				// 物料 4 到物料 3 之间的最小距离，以便物料 3 能够在输送皮带上移动
	cXforBox3_MainBelt_Diff4to3_max				: LREAL := 1;				// 物料 4 到物料 3 之间的最大距离，以便物料 3 能够在输送皮带上移动
	
	// Box 4
	cXforBox4_MainBelt_Diff1to4_min				: LREAL := -121;			// 物料 1 到物料 4 之间的最小距离，以便物料 4 能够在输送皮带上移动
	cXforBox4_MainBelt_Diff1to4_max				: LREAL := -241;			// 物料 1 到物料 4 之间的最大距离，以便物料 4 能够在输送皮带上移动
	cXforBox4_MainBelt_Diff2to4_min				: LREAL := -61;				// 物料 2 到物料 4 之间的最小距离，以便物料 4 能够在输送皮带上移动
	cXforBox4_MainBelt_Diff2to4_max				: LREAL := -181;			// 物料 2 到物料 4 之间的最大距离，以便物料 4 能够在输送皮带上移动
	cXforBox4_MainBelt_Diff3to4_min				: LREAL := -1;				// 物料 3 到物料 4 之间的最小距离，以便物料 4 能够在输送皮带上移动
	cXforBox4_MainBelt_Diff3to4_max				: LREAL := -121;			// 物料 4 到物料 4 之间的最大距离，以便物料 4 能够在输送皮带上移动
	
	// ========================= 金属分拣皮带当中物料的距离参数 ===========================
	// Box 1
	cXforBox1OnMetalBelt_min					: LREAL := 240;				// 物料 1 在金属分拣皮带上时位置的最小横坐标
	cXforBox1OnMetalBelt_max					: LREAL := 271;				// 物料 1 在金属分拣皮带上时位置的最大横坐标
	// Box 2
	cXforBox2OnMetalBelt_min					: LREAL := 300;				// 物料 2 在金属分拣皮带上时位置的最小横坐标
	cXforBox2OnMetalBelt_max					: LREAL := 331;				// 物料 2 在金属分拣皮带上时位置的最大横坐标
	// Box 3
	cXforBox3OnMetalBelt_min					: LREAL := 360;				// 物料 3 在金属分拣皮带上时位置的最小横坐标
	cXforBox3OnMetalBelt_max					: LREAL := 391;				// 物料 3 在金属分拣皮带上时位置的最大横坐标
	// Box 4
	cXforBox4OnMetalBelt_min					: LREAL := 420;				// 物料 4 在金属分拣皮带上时位置的最小横坐标
	cXforBox4OnMetalBelt_max					: LREAL := 451;				// 物料 4 在金属分拣皮带上时位置的最大横坐标
	
	// ========================= 塑料分拣皮带当中物料的距离参数 =========================
	// Box 1
	cXforBox1OnPlasticBelt_min					: LREAL := 470;				// 物料 1 在塑料分拣皮带上时位置的最小横坐标
	cXforBox1OnPlasticBelt_max					: LREAL := 521;				// 物料 1 在塑料分拣皮带上时位置的最大横坐标
	// Box 2
	cXforBox2OnPlasticBelt_min					: LREAL := 530;				// 物料 2 在塑料分拣皮带上时位置的最小横坐标
	cXforBox2OnPlasticBelt_max					: LREAL := 581;				// 物料 2 在塑料分拣皮带上时位置的最大横坐标
	// Box 3
	cXforBox3OnPlasticBelt_min					: LREAL := 590;				// 物料 3 在塑料分拣皮带上时位置的最小横坐标
	cXforBox3OnPlasticBelt_max					: LREAL := 641;				// 物料 3 在塑料分拣皮带上时位置的最大横坐标
	// Box 4
	cXforBox4OnPlasticBelt_min					: LREAL := 650;				// 物料 4 在塑料分拣皮带上时位置的最小横坐标
	cXforBox4OnPlasticBelt_max					: LREAL := 701;				// 物料 4 在塑料分拣皮带上时位置的最大横坐标
END_VAR
]]></Declaration>
    <Implementation>
      <ST><![CDATA[// =========================================================
// 复位
	
	IF bReset THEN
		Reset();
	END_IF
	
// =========================================================
// 出现事故立即切断使能
	
	IF bAccident THEN
		IF bButtonPowerOut THEN
			bButtonPowerOut := FALSE;
		END_IF
		
		IF bStopped THEN
			bAccident := FALSE;
		END_IF
	END_IF

// =========================================================
// 方法调用

	// 轴图标旋转
	AxisRotation();
	
	// 按钮信号、颜色、物料状态
	ButtonSignals();
	ButtonColors();
	LastBox();
	ErrorMessages();
	
	// 气缸移动
	Barrier_Clamp_Cyl();
	Metal_Plastic_Cyl();
	
	// 物料移动
	AxisMoveBoxes();
	CylinderMoveBoxes();
	
	// 随机刷新物料的颜色
	RandomColor();

// =========================================================
// 启用禁用模式按钮
    bButtonColorAutoNew                 := bButtonColorAuto  AND NOT bError;
	bButtonColorSemiNew                 := bButtonColorSemi  AND NOT bError;
	bButtonColorManuNew                 := bButtonColorManu  AND NOT bError; 
	bButtonColorMaintNew                := bButtonColorMaint AND NOT bError; ]]></ST>
    </Implementation>
    <Folder Name="Methods" Id="{f76ec303-c4d0-48d1-a29f-a677799ce426}" />
    <Folder Name="Properties" Id="{1fa5e61a-7c92-49de-9422-3a966dab4d23}" />
    <Method Name="AxisMoveBoxes" Id="{327ea6a2-76ca-4e34-990c-a639b73a51fa}" FolderPath="Methods\">
      <Declaration><![CDATA[METHOD PRIVATE AxisMoveBoxes
VAR_INPUT
END_VAR
]]></Declaration>
      <Implementation>
        <ST><![CDATA[// ======================== 检测各个物料是否在输送皮带上的位置 =================================
		
	aBoxMainBelt[1] := 	// 物料 1 在输送皮带上
						aBoxY[1] >= cYforAllBoxesOnMainBelt											
						AND (	(aBoxX[2] - aBoxX[1] - fMainVelo) >= cXforBox1_MainBelt_Diff2to1_max
							OR 	(aBoxX[2] - aBoxX[1] - fMainVelo) <= cXforBox1_MainBelt_Diff2to1_min
							OR 	aBoxY[2] < cYforAllBoxesNotOnMainBelt)	
						AND (	(aBoxX[3] - aBoxX[1] - fMainVelo) >= cXforBox1_MainBelt_Diff3to1_max
							OR 	(aBoxX[3] - aBoxX[1]- fMainVelo) <= cXforBox1_MainBelt_Diff3to1_min
							OR 	aBoxY[3] < cYforAllBoxesNotOnMainBelt)
						AND (	(aBoxX[4] - aBoxX[1] - fMainVelo) >= cXforBox1_MainBelt_Diff4to1_max
							OR 	(aBoxX[4] - aBoxX[1]- fMainVelo) <= cXforBox1_MainBelt_Diff4to1_min
							OR	aBoxY[4] < cYforAllBoxesNotOnMainBelt);
						
	aBoxMainBelt[2] := 	// 物料 2 在输送皮带上
						aBoxY[2] >= cYforAllBoxesOnMainBelt										
						AND (	(aBoxX[1] - aBoxX[2] - fMainVelo) >= cXforBox2_MainBelt_Diff1to2_min 
							OR 	(aBoxX[1] - aBoxX[2] - fMainVelo) <= cXforBox2_MainBelt_Diff1to2_max 
							OR 	aBoxY[1] < cYforAllBoxesNotOnMainBelt)										
						AND (	(aBoxX[3] - aBoxX[2] - fMainVelo) >= cXforBox2_MainBelt_Diff3to2_min 
							OR 	(aBoxX[3] - aBoxX[2] - fMainVelo) <= cXforBox2_MainBelt_Diff3to2_max 
							OR 	aBoxY[3] < cYforAllBoxesNotOnMainBelt)									
						AND (	(aBoxX[4] - aBoxX[2] - fMainVelo) >= cXforBox2_MainBelt_Diff4to2_min 
							OR 	(aBoxX[4] - aBoxX[2] - fMainVelo) <= cXforBox2_MainBelt_Diff4to2_max 
							OR 	aBoxY[4] < cYforAllBoxesNotOnMainBelt);
	
	aBoxMainBelt[3] :=  // 物料 3 在输送皮带上
						aBoxY[3] >= cYforAllBoxesOnMainBelt											
						AND (	(aBoxX[1] - aBoxX[3] - fMainVelo) >= cXforBox3_MainBelt_Diff1to3_min
							OR 	(aBoxX[1] - aBoxX[3] - fMainVelo) <= cXforBox3_MainBelt_Diff1to3_max
							OR 	aBoxY[1] < cYforAllBoxesNotOnMainBelt)											
						AND (	(aBoxX[2] - aBoxX[3] - fMainVelo) >= cXforBox3_MainBelt_Diff2to3_min
							OR 	(aBoxX[2] - aBoxX[3] - fMainVelo) <= cXforBox3_MainBelt_Diff2to3_max 
							OR 	aBoxY[2] < cYforAllBoxesNotOnMainBelt)										
						AND (	(aBoxX[4] - aBoxX[3] - fMainVelo) >= cXforBox3_MainBelt_Diff4to3_min
							OR 	(aBoxX[4] - aBoxX[3] - fMainVelo) <= cXforBox3_MainBelt_Diff4to3_max
							OR 	aBoxY[4] < cYforAllBoxesNotOnMainBelt);
						
	aBoxMainBelt[4] := 	// 物料 4 在输送皮带上
						aBoxY[4] >= cYforAllBoxesOnMainBelt										
						AND (	(aBoxX[1] - aBoxX[4] - fMainVelo) >= cXforBox4_MainBelt_Diff1to4_min
							OR 	(aBoxX[1] - aBoxX[4] - fMainVelo) <= cXforBox4_MainBelt_Diff1to4_max
							OR 	aBoxY[1] < cYforAllBoxesNotOnMainBelt)										
						AND (	(aBoxX[2] - aBoxX[4] - fMainVelo) >= cXforBox4_MainBelt_Diff2to4_min
							OR 	(aBoxX[2] - aBoxX[4] - fMainVelo) <= cXforBox4_MainBelt_Diff2to4_max
							OR 	aBoxY[2] < cYforAllBoxesNotOnMainBelt)										
						AND (	(aBoxX[3] - aBoxX[4] - fMainVelo) >= cXforBox4_MainBelt_Diff3to4_min
							OR 	(aBoxX[3] - aBoxX[4] - fMainVelo) <= cXforBox4_MainBelt_Diff3to4_max
							OR 	aBoxY[3] < cYforAllBoxesNotOnMainBelt);
					
// ========================= 物料在皮带上的正向运动过程 ================================
		
	IF (NOT (BIT_TO_BOOL(MainAxisState.StateDWord.2))) AND (bAuto OR bSemi OR bButtonMainFwIn) THEN
		FOR nState := 1 TO 4 BY 1 DO
			
			IF aBoxMainBelt[nState] THEN	
				IF aBoxX[nState] >= (cBoxWidth*nState + cBarrierWidth) AND aBoxX[nState] < (cBoxWidth*nState + cDiffBarrierToEndOfMetalCyl - 1) THEN
					IF fYMetal <= cYMetalPlasticCylOnMainBelt THEN
						IF aBoxX[nState] < (cBoxWidth*nState + cDiffBarrierToStartOfMetalCyl - cBoxWidth + 0.25)
						AND aBoxX[nState] > (cBoxWidth*nState + cDiffBarrierToStartOfMetalCyl - cBoxWidth - 0.15) THEN
							aBoxX[nState] := cBoxWidth*nState + cDiffBarrierToStartOfMetalCyl - cBoxWidth;
						ELSIF aBoxX[nState] <= (cBoxWidth*nState + cDiffBarrierToStartOfMetalCyl - cBoxWidth - 0.15) THEN
							aBoxX[nState] := aBoxX[nState] + fMainVelo;
						END_IF
					ELSE
						aBoxX[nState] := aBoxX[nState] + fMainVelo;
					END_IF
				END_IF

				IF aBoxX[nState] >= (cBoxWidth*nState + cDiffBarrierToEndOfMetalCyl - 1) THEN
					IF fYPlastic <= cYMetalPlasticCylOnMainBelt THEN
						IF aBoxX[nState] < (cBoxWidth*nState + cDiffBarrierToStartOfPlasticCyl - cBoxWidth + 0.25)
						AND aBoxX[nState] > (cBoxWidth*nState + cDiffBarrierToStartOfPlasticCyl - cBoxWidth - 0.15) THEN
							aBoxX[nState] := cBoxWidth*nState + cDiffBarrierToStartOfPlasticCyl - cBoxWidth;
						ELSIF aBoxX[nState] <= (cBoxWidth*nState + cDiffBarrierToStartOfPlasticCyl - cBoxWidth - 0.15) THEN
							aBoxX[nState] := aBoxX[nState] + fMainVelo;
						END_IF
					ELSE
						aBoxX[nState] := aBoxX[nState] + fMainVelo;
					END_IF
				END_IF
				
				IF fYBarrier >= (cBoxWidth + 1) AND aBoxX[nState] >= cBoxWidth*(nState - 1) AND aBoxX[nState] <  (cBoxWidth*nState + cBarrierWidth) THEN
					IF aBoxX[nState] + fMainVelo < (cBoxWidth*nState + cBarrierWidth) THEN
						 aBoxX[nState] := aBoxX[nState] + fMainVelo;
					ELSIF aBoxX[nState] < (cBoxWidth*nState + cBarrierWidth) THEN
						aBoxX[nState] := (cBoxWidth*nState + cBarrierWidth);
					END_IF
				END_IF
				
				IF aBoxX[nState] + fMainVelo < -cBoxWidth*(3 - nState) THEN
					aBoxX[nState] := aBoxX[nState] + fMainVelo;
				ELSIF aBoxX[nState] < -cBoxWidth*(nState + 1) THEN
					aBoxX[nState] := -cBoxWidth*(nState + 1);
				END_IF
													
				IF fYClamp >= 1 AND aBoxX[nState] >= -cBoxWidth*(nState + 1) THEN
					IF aBoxX[nState] + fMainVelo < cBoxWidth*(nState - 1) THEN
						aBoxX[nState] := aBoxX[nState] + fMainVelo;
					ELSIF aBoxX[nState] < cBoxWidth*(nState - 1) THEN
						aBoxX[nState] := cBoxWidth*(nState - 1);
					END_IF
				END_IF
			END_IF
		END_FOR
	END_IF

// ========================= 物料在皮带上的反向运动过程 ================================
	
	IF (NOT (BIT_TO_BOOL(MainAxisState.StateDWord.2)))  AND bButtonMainBwIn THEN 
		FOR nState := 1 TO 4 BY 1 DO
			IF aBoxMainBelt[nState] THEN
				IF aBoxX[nState] >= (cBoxWidth*nState + cBoxWidth + cBarrierWidth) AND aBoxX[nState] < (cBoxWidth*nState + cDiffBarrierToEndOfMetalCyl + 1) THEN
					IF NOT (aBoxX[nState] < (cBoxWidth*nState + cDiffBarrierToEndOfMetalCyl + 0.25)
					AND aBoxX[nState] > (cBoxWidth*nState + cDiffBarrierToEndOfMetalCyl - 0.15)
					AND P_fYMetal <= cYMetalPlasticCylOnMainBelt) THEN
						aBoxX[nState] := aBoxX[nState] + fMainVelo;
					ELSE
						aBoxX[nState] := cBoxWidth*nState + cDiffBarrierToEndOfMetalCyl;
					END_IF
				END_IF

				IF aBoxX[nState] >= (cBoxWidth*nState + cDiffBarrierToEndOfMetalCyl + 1) THEN
					aBoxX[nState] := aBoxX[nState] + fMainVelo;
				END_IF

				IF aBoxX[nState] > cBoxWidth*(nState - 1) AND aBoxX[nState] < (cBoxWidth*nState + cBoxWidth + cBarrierWidth) THEN
					IF NOT (aBoxX[nState] < (cBoxWidth*nState + cBarrierWidth + 0.25)
					AND aBoxX[nState] > (cBoxWidth*nState + cBarrierWidth - 0.15)
					AND fYBarrier < (cBoxWidth + 1)) THEN
						aBoxX[nState] := aBoxX[nState] + fMainVelo;
					ELSE
						aBoxX[nState] := cBoxWidth*nState + cBarrierWidth;
					END_IF
				END_IF

				IF fYBarrier >= (cBoxWidth + 1) AND aBoxX[nState] < cBoxWidth*(nState + 1) AND aBoxX[nState] > cBoxWidth*(nState - 1) THEN
					aBoxX[nState] := aBoxX[nState] + fMainVelo;
				END_IF	
										
				IF fYClamp >= 1 AND aBoxX[nState] <= cBoxWidth*(nState-1) AND aBoxX[nState] > -cBoxWidth*(3-nState) THEN
					aBoxX[nState] := aBoxX[nState] + fMainVelo;
				END_IF
				
				IF aBoxX[nState] > -cBoxWidth*(4-nState) AND aBoxX[nState] <= -cBoxWidth*(3-nState) THEN
					aBoxX[nState] := aBoxX[nState] + fMainVelo;
				END_IF
			END_IF
		END_FOR	
	END_IF

// ===========================检测各个物料在金属出料皮带当中是否正在被运输==============================

	aBoxMetalBelt[1] := 
						aBoxX[1] > cXforBox1OnMetalBelt_min AND aBoxX[1] <= cXforBox1OnMetalBelt_max											
						AND ((aBoxY[2] - aBoxY[1] - fMetalVelo) >= cBoxWidth OR (aBoxY[2] - aBoxY[1] - fMetalVelo) <= -cBoxWidth
							OR NOT (aBoxX[2] > cXforBox2OnMetalBelt_min AND aBoxX[2] <= cXforBox2OnMetalBelt_max))
						AND ((aBoxY[3] - aBoxY[1]- fMetalVelo) >= cBoxWidth OR (aBoxY[3] - aBoxY[1]- fMetalVelo) <= -cBoxWidth
							OR NOT (aBoxX[3] > cXforBox3OnMetalBelt_min AND aBoxX[3] <= cXforBox3OnMetalBelt_max))
						AND ((aBoxY[4] - aBoxY[1]- fMetalVelo) >= cBoxWidth OR (aBoxY[4] - aBoxY[1]- fMetalVelo) <= -cBoxWidth
							OR NOT (aBoxX[4] > cXforBox4OnMetalBelt_min AND aBoxX[4] <= cXforBox4OnMetalBelt_max));	
						
	aBoxMetalBelt[2] := aBoxX[2] > cXforBox2OnMetalBelt_min AND aBoxX[2] <= cXforBox2OnMetalBelt_max										
						AND ((aBoxY[1] - aBoxY[2] - fMetalVelo) >= cBoxWidth OR (aBoxY[1] - aBoxY[2] - fMetalVelo) <= -cBoxWidth
							OR NOT (aBoxX[1] > cXforBox1OnMetalBelt_min AND aBoxX[1] <= cXforBox1OnMetalBelt_max))
						AND ((aBoxY[3] - aBoxY[2]- fMetalVelo) >= cBoxWidth OR (aBoxY[3] - aBoxY[2]- fMetalVelo) <= -cBoxWidth
							OR NOT (aBoxX[3] > cXforBox3OnMetalBelt_min AND aBoxX[3] <= cXforBox3OnMetalBelt_max))
						AND ((aBoxY[4] - aBoxY[2]- fMetalVelo) >= cBoxWidth OR (aBoxY[4] - aBoxY[2]- fMetalVelo) <= -cBoxWidth
							OR NOT (aBoxX[4] > cXforBox4OnMetalBelt_min AND aBoxX[4] <= cXforBox4OnMetalBelt_max));	
						
	aBoxMetalBelt[3] := aBoxX[3] > cXforBox3OnMetalBelt_min AND aBoxX[3] <= cXforBox3OnMetalBelt_max										
						AND ((aBoxY[1] - aBoxY[3] - fMetalVelo) >= cBoxWidth OR (aBoxY[1] - aBoxY[3] - fMetalVelo) <= -cBoxWidth
							OR NOT (aBoxX[1] > cXforBox1OnMetalBelt_min AND aBoxX[1] <= cXforBox1OnMetalBelt_max))
						AND ((aBoxY[2] - aBoxY[3]- fMetalVelo) >= cBoxWidth OR (aBoxY[2] - aBoxY[3]- fMetalVelo) <= -cBoxWidth
							OR NOT (aBoxX[2] > cXforBox2OnMetalBelt_min AND aBoxX[2] <= cXforBox2OnMetalBelt_max))
						AND ((aBoxY[4] - aBoxY[3]- fMetalVelo) >= cBoxWidth OR (aBoxY[4] - aBoxY[3]- fMetalVelo) <= -cBoxWidth
							OR NOT (aBoxX[4] > cXforBox4OnMetalBelt_min AND aBoxX[4] <= cXforBox4OnMetalBelt_max));	
						
	aBoxMetalBelt[4] := aBoxX[4] > cXforBox4OnMetalBelt_min AND aBoxX[4] <= cXforBox4OnMetalBelt_max										
						AND ((aBoxY[1] - aBoxY[4] - fMetalVelo) >= cBoxWidth OR (aBoxY[1] - aBoxY[4] - fMetalVelo) <= -cBoxWidth
							OR NOT (aBoxX[1] > cXforBox1OnMetalBelt_min AND aBoxX[1] <= cXforBox1OnMetalBelt_max))
						AND ((aBoxY[2] - aBoxY[4] - fMetalVelo) >= cBoxWidth OR (aBoxY[2] - aBoxY[4] - fMetalVelo) <= -cBoxWidth
							OR NOT (aBoxX[2] > cXforBox2OnMetalBelt_min AND aBoxX[2] <= cXforBox2OnMetalBelt_max))
						AND ((aBoxY[3] - aBoxY[4]- fMetalVelo) >= cBoxWidth OR (aBoxY[3] - aBoxY[4]- fMetalVelo) <= -cBoxWidth
							OR NOT (aBoxX[3] > cXforBox3OnMetalBelt_min AND aBoxX[3] <= cXforBox3OnMetalBelt_max));
// =========================================================
// 被分拣出料完成之后，回到初始位置、刷新随机颜色

		FOR nState := 1 TO 4 BY 1 DO	
		IF(NOT (BIT_TO_BOOL(MetalAxisState.StateDWord.2)))  THEN
			IF 	aBoxMetalBelt[nState] THEN
					IF bAuto OR bSemi OR (NOT bAuto AND bButtonMetalFwIn) THEN	
						IF aBoxY[nState] <= (cYBoxesOnMetalPlasticBelt_min + 0.1) AND aBoxY[nState] > cYBoxesOnMetalPlasticBelt_max THEN
							aBoxY[nState] := aBoxY[nState] + fMetalVelo;
						END_IF
						
					ELSIF NOT bAuto AND bButtonMetalBwIn THEN
						IF aBoxY[nState] + fMetalVelo <= (cYBoxesOnMetalPlasticBelt_min - 0.1) THEN
							aBoxY[nState] := aBoxY[nState] + fMetalVelo;
						END_IF
					END_IF
			END_IF
		END_IF	
		
		IF aBoxY[nState] <= (cYBoxesOnMetalPlasticBelt_max  )AND nLastBox = 0 THEN
			aBoxY[nState] := cYforAllBoxesStartPosMainBelt;
			aBoxX[nState] := cXforAllBoxesStartPosMainBelt + nState*cBoxWidth;
			IF bRandomChangeColor THEN
				ArrChangeColor[nState]	:= TRUE;
			ELSE
				ArrChangeColor[nState]	:= FALSE;
			END_IF
		END_IF

	END_FOR


// ===========================检测各个物料在塑料出料皮带当中是否正在被运输==============================
	
	aBoxPlasticBelt[1] := aBoxX[1] > cXforBox1OnPlasticBelt_min AND aBoxX[1] <= cXforBox1OnPlasticBelt_max											
						AND ((aBoxY[2] - aBoxY[1] - fPlasticVelo) >= cBoxWidth OR (aBoxY[2] - aBoxY[1] - fPlasticVelo) <= -cBoxWidth
								OR NOT (aBoxX[2] > cXforBox2OnPlasticBelt_min AND aBoxX[2] <= cXforBox2OnPlasticBelt_max))
						AND ((aBoxY[3] - aBoxY[1]- fPlasticVelo) >= cBoxWidth OR (aBoxY[3] - aBoxY[1]- fPlasticVelo) <= -cBoxWidth
								OR NOT (aBoxX[3] > cXforBox3OnPlasticBelt_min AND aBoxX[3] <= cXforBox3OnPlasticBelt_max))
						AND ((aBoxY[4] - aBoxY[1]- fPlasticVelo) >= cBoxWidth OR (aBoxY[4] - aBoxY[1]- fPlasticVelo) <= -cBoxWidth
								OR NOT (aBoxX[4] > cXforBox4OnPlasticBelt_min AND aBoxX[4] <= cXforBox4OnPlasticBelt_max));	
						
	aBoxPlasticBelt[2] := aBoxX[2] > cXforBox2OnPlasticBelt_min AND aBoxX[2] <= cXforBox2OnPlasticBelt_max									
						AND ((aBoxY[1] - aBoxY[2] - fPlasticVelo) >= cBoxWidth OR (aBoxY[1] - aBoxY[2] - fPlasticVelo) <= -cBoxWidth
								OR NOT (aBoxX[1] > cXforBox1OnPlasticBelt_min AND aBoxX[1] <= cXforBox1OnPlasticBelt_max))
						AND ((aBoxY[3] - aBoxY[2]- fPlasticVelo) >= cBoxWidth OR (aBoxY[3] - aBoxY[2]- fPlasticVelo) <= -cBoxWidth
								OR NOT (aBoxX[3] > cXforBox3OnPlasticBelt_min AND aBoxX[3] <= cXforBox3OnPlasticBelt_max))
						AND ((aBoxY[4] - aBoxY[2]- fPlasticVelo) >= cBoxWidth OR (aBoxY[4] - aBoxY[2]- fPlasticVelo) <= -cBoxWidth
								OR NOT (aBoxX[4] > cXforBox4OnPlasticBelt_min AND aBoxX[4] <= cXforBox4OnPlasticBelt_max));	
						
	aBoxPlasticBelt[3] := aBoxX[3] > cXforBox3OnPlasticBelt_min AND aBoxX[3] <= cXforBox3OnPlasticBelt_max										
						AND ((aBoxY[1] - aBoxY[3] - fPlasticVelo) >= cBoxWidth OR (aBoxY[1] - aBoxY[3] - fPlasticVelo) <= -cBoxWidth
								OR NOT (aBoxX[1] > cXforBox1OnPlasticBelt_min AND aBoxX[1] <= cXforBox1OnPlasticBelt_max))
						AND ((aBoxY[2] - aBoxY[3]- fPlasticVelo) >= cBoxWidth OR (aBoxY[2] - aBoxY[3]- fPlasticVelo) <= -cBoxWidth
								OR NOT (aBoxX[2] > cXforBox2OnPlasticBelt_min AND aBoxX[2] <= cXforBox2OnPlasticBelt_max))
						AND ((aBoxY[4] - aBoxY[3]- fPlasticVelo) >= cBoxWidth OR (aBoxY[4] - aBoxY[3]- fPlasticVelo) <= -cBoxWidth
								OR NOT (aBoxX[4] > cXforBox4OnPlasticBelt_min AND aBoxX[4] <= cXforBox4OnPlasticBelt_max));	
						
	aBoxPlasticBelt[4] := aBoxX[4] > cXforBox4OnPlasticBelt_min AND aBoxX[4] <= cXforBox4OnPlasticBelt_max										
						AND ((aBoxY[1] - aBoxY[4] - fPlasticVelo) >= cBoxWidth OR (aBoxY[1] - aBoxY[4] - fPlasticVelo) <= -cBoxWidth
								OR NOT (aBoxX[1] > cXforBox1OnPlasticBelt_min AND aBoxX[1] <= cXforBox1OnPlasticBelt_max))
						AND ((aBoxY[2] - aBoxY[4] - fPlasticVelo) >= cBoxWidth OR (aBoxY[2] - aBoxY[4] - fPlasticVelo) <= -cBoxWidth
								OR NOT (aBoxX[2] > cXforBox2OnPlasticBelt_min AND aBoxX[2] <= cXforBox2OnPlasticBelt_max))
						AND ((aBoxY[3] - aBoxY[4]- fPlasticVelo) >= cBoxWidth OR (aBoxY[3] - aBoxY[4]- fPlasticVelo) <= -cBoxWidth
								OR NOT (aBoxX[3] > cXforBox3OnPlasticBelt_min AND aBoxX[3] <= cXforBox3OnPlasticBelt_max));

// =========================================================
// 被分拣出料完成之后，回到初始位置、刷新随机颜色

	FOR nState := 1 TO 4 BY 1 DO	
		IF (NOT (BIT_TO_BOOL(PlasticAxisState.StateDWord.2)))  THEN
				IF 	aBoxPlasticBelt[nState] THEN	
					IF bAuto OR bSemi OR (NOT bAuto AND bButtonPlasticFwIn) THEN
						IF aBoxY[nState] <= (cYBoxesOnMetalPlasticBelt_min + 0.1) AND aBoxY[nState] > cYBoxesOnMetalPlasticBelt_max THEN
							aBoxY[nState] := aBoxY[nState] + fPlasticVelo;
						END_IF
						
					ELSIF NOT bAuto AND bButtonPlasticBwIn THEN
						IF aBoxY[nState] + fPlasticVelo <= (cYBoxesOnMetalPlasticBelt_min - 0.1) THEN
							aBoxY[nState] := aBoxY[nState] + fPlasticVelo;
						END_IF
					END_IF
				END_IF
		END_IF
		
		IF aBoxY[nState] <= cYBoxesOnMetalPlasticBelt_max AND nLastBox = 0 THEN
			aBoxY[nState] := cYforAllBoxesStartPosMainBelt;
			aBoxX[nState] := cXforAllBoxesStartPosMainBelt + nState*cBoxWidth;
			IF bRandomChangeColor THEN
				ArrChangeColor[nState]	:= TRUE;
			ELSE
				ArrChangeColor[nState]	:= FALSE;
			END_IF
						 
		END_IF
	END_FOR

// =========================================================]]></ST>
      </Implementation>
    </Method>
    <Method Name="AxisRotation" Id="{55e198e7-d351-467f-8751-d94bc775dd4a}" FolderPath="Methods\">
      <Declaration><![CDATA[METHOD PRIVATE AxisRotation
VAR_INPUT
END_VAR
]]></Declaration>
      <Implementation>
        <ST><![CDATA[// =========================================================
// 换算轴图标的旋转速度：实际速度/固定常数
	
	IF bAuto OR bSemi OR bButtonMainFwIn THEN
		fMainVelo := ( MainAxisState.ActVelo / cVelocityDenominator);
	ELSIF bButtonMainBwIn THEN
		fMainVelo := -( MainAxisState.ActVelo / cVelocityDenominator);
	END_IF
	
	IF bAuto OR bSemi OR bButtonMetalFwIn THEN
		fMetalVelo := -( MainAxisState.ActVelo / cVelocityDenominator);
	ELSIF bButtonMetalBwIn THEN
		fMetalVelo := ( MainAxisState.ActVelo / cVelocityDenominator);
	END_IF
	
	IF bAuto OR bSemi OR bButtonPlasticFwIn THEN
		fPlasticVelo := -( MainAxisState.ActVelo / cVelocityDenominator);
	ELSIF bButtonPlasticBwIn THEN
		fPlasticVelo := ( MainAxisState.ActVelo / cVelocityDenominator);
	END_IF

// =========================================================
// 输送皮带上轴 HMI 图标的运动
		
		IF (bAuto OR bSemi) AND (NOT (((BIT_TO_BOOL(MainAxisState.StateDWord.2)= TRUE))))THEN
			nAngleMain := nAngleMain + cAxisMovementSemiPlusAuto;
			
		ELSIF bButtonMainFwIn THEN
			nAngleMain := nAngleMain + cAxisMovementManual;
			
		ELSIF bButtonMainBwIn THEN
			nAngleMain := nAngleMain - cAxisMovementManual;
			
		ELSIF ((BIT_TO_BOOL(MainAxisState.StateDWord.2)= TRUE)) THEN
			nAngleMain := nAngleMain ;
		END_IF

// =========================================================
// 金属分拣皮带上轴 HMI 图标的运动
		
		IF (bAuto OR bSemi) AND (NOT (((BIT_TO_BOOL(MetalAxisState.StateDWord.2)= TRUE)))) THEN
			nAngleMetal := nAngleMetal + cAxisMovementSemiPlusAuto;
			
		ELSIF bButtonMetalFwIn THEN
			nAngleMetal := nAngleMetal + cAxisMovementManual;
			
		ELSIF bButtonMetalBwIn THEN
			nAngleMetal := nAngleMetal - cAxisMovementManual;
			
		ELSIF ((BIT_TO_BOOL(MetalAxisState.StateDWord.2)= TRUE)) THEN
			nAngleMetal := nAngleMetal ;
		END_IF

// =========================================================
// 塑料分拣皮带上轴 HMI 图标的运动
		
		IF (bAuto OR bSemi) AND (NOT (((BIT_TO_BOOL(PlasticAxisState.StateDWord.2)= TRUE)))) THEN
			nAnglePlastic := nAnglePlastic + cAxisMovementSemiPlusAuto;
			
		ELSIF bButtonPlasticFwIn THEN
			nAnglePlastic := nAnglePlastic + cAxisMovementManual;
			
		ELSIF bButtonPlasticBwIn THEN
			nAnglePlastic := nAnglePlastic - cAxisMovementManual;
			
		ELSIF ((BIT_TO_BOOL(PlasticAxisState.StateDWord.2)= TRUE)) THEN
			nAnglePlastic := nAnglePlastic ;
		END_IF

// =========================================================]]></ST>
      </Implementation>
    </Method>
    <Method Name="Barrier_Clamp_Cyl" Id="{1e662da8-56a7-4c10-9b30-894f2e236cd7}" FolderPath="Methods\">
      <Declaration><![CDATA[METHOD PRIVATE Barrier_Clamp_Cyl
VAR_INPUT
END_VAR
]]></Declaration>
      <Implementation>
        <ST><![CDATA[// =========================================================
// 移动正位气缸
	
	IF bClampToWork THEN
		IF (fYClamp + cClampMovement) < cYClampCylEndPos THEN
			fYClamp := fYClamp + cClampMovement;
		ELSE
			fYClamp := cYClampCylEndPos;
		END_IF
		
	ELSE
		IF (fYClamp - cClampMovement) > cYClampCylStartPos THEN
			fYClamp := fYClamp - cClampMovement;
		ELSE
			fYClamp := cYClampCylStartPos;
		END_IF
	END_IF

// =========================================================
// =========================================================
// 移动栏杆气缸
	
	IF bBarrierToWork THEN
		IF (fYBarrier + cBarrierMovement) < cYBarrierCylEndPos THEN
			fYBarrier := fYBarrier + cBarrierMovement;
		ELSE
			fYBarrier := cYBarrierCylEndPos;
		END_IF
		
	ELSE
		IF (fYBarrier - cBarrierMovement) > cYBarrierCylStartPos THEN
			fYBarrier := fYBarrier - cBarrierMovement;
		ELSE
			fYBarrier := cYBarrierCylStartPos;
		END_IF
	END_IF

// =========================================================
// 检测物料与气缸的位置是否重叠，检测事故发生
	
	IF fYBarrier <= cBoxWidth AND NOT bBarrierToWork THEN
		FOR nState := 1 TO 4 BY 1 DO
			IF aBoxX[nState] > (-cBoxWidth + 0.11 + cBoxWidth*nState) AND aBoxX[nState] < (cBoxWidth*nState + cBarrierWidth) AND aBoxY[nState] = 0
			AND NOT bStopped THEN
				bAccident := TRUE;
			END_IF
		END_FOR
	END_IF

// =========================================================]]></ST>
      </Implementation>
    </Method>
    <Method Name="ButtonColors" Id="{68d73339-e331-4d8e-9613-0aa036aadaba}" FolderPath="Methods\">
      <Declaration><![CDATA[METHOD PRIVATE ButtonColors
VAR_INPUT
END_VAR
]]></Declaration>
      <Implementation>
        <ST><![CDATA[// ========================== 启动按钮颜色 ===============================

// 选择模式之后		
	IF (bAccident OR (bPowerEnabled AND (NOT bStarted OR (bSemi AND bStarted))
		AND NOT bButtonStopIn AND NOT bButtonAbortIn AND NOT bButtonResetIn
		AND (bAuto OR bSemi OR bManual OR bMaintenance))) AND NOT (bError AND bIdle) THEN
		
			IF bButtonStartOut THEN
				nButtonColorStart := cGreen;			// 按下则按钮是绿色
			ELSE
				nButtonColorStart := cYellow;			// 未按下则按钮是黄色
			END_IF
			
			bButtonColorStart := TRUE;
	ELSE
		bButtonColorStart := FALSE;
	END_IF

// ========================== 停止按钮颜色 ===============================

// 选择模式之后		
	IF (bStarted OR bIdle) AND (bAuto OR bSemi OR bManual OR bMaintenance) THEN
		IF bButtonStopOut THEN
			nButtonColorStop := cGreen;					// 按下则按钮是绿色
		ELSE
			nButtonColorStop := cYellow;				// 未按下则按钮是黄色
		END_IF
		
		bButtonColorStop := TRUE;
	ELSE
		bButtonColorStop := FALSE;
	END_IF

// ========================== 复位按钮颜色 ===============================

// 出现停机或者重新上使能之后		
	IF bStopped AND bPowerEnabled THEN
		IF bButtonResetOut THEN
			nButtonColorReset := cGreen;				// 按下则按钮是绿色
		ELSE
			nButtonColorReset := cYellow;				// 未按下则按钮是黄色
		END_IF
		
		bButtonColorReset := TRUE;
	ELSE
		bButtonColorReset := FALSE;
	END_IF

// ========================== 模式按钮颜色 ===============================

// 使能之后，各个模式的按钮都变为黄色，按下对应的模式按钮之后，变成绿色	
	IF bPowerEnabled THEN
		IF NOT bAuto THEN
			IF bIdle THEN
				nButtonColorAuto 	:= cYellow;
				bButtonColorAuto 	:= TRUE;
			ELSE
				bButtonColorAuto 	:= FALSE;
			END_IF
		ELSE
			nButtonColorAuto 		:= cGreen;
			bButtonColorAuto 		:= TRUE;
		END_IF
		
		IF NOT bSemi THEN
			IF bIdle THEN
				nButtonColorSemi 	:= cYellow;
				bButtonColorSemi 	:= TRUE;
			ELSE
				bButtonColorSemi 	:= FALSE;
			END_IF
		ELSE
			nButtonColorSemi 		:= cGreen;
			bButtonColorSemi 		:= TRUE;
		END_IF
		
		IF NOT bManual THEN
			IF bIdle THEN
				nButtonColorManu 	:= cYellow;
				bButtonColorManu 	:= TRUE;
			ELSE
				bButtonColorManu 	:= FALSE;
			END_IF
		ELSE
			nButtonColorManu 		:= cGreen;
			bButtonColorManu 		:= TRUE;
		END_IF
		
		IF NOT bMaintenance THEN
			IF bIdle THEN
				nButtonColorMaint 	:= cYellow;
				bButtonColorMaint 	:= TRUE;
			ELSE
				bButtonColorMaint 	:= FALSE;
			END_IF
		ELSE
			nButtonColorMaint 		:= cGreen;
			bButtonColorMaint 		:= TRUE;
		END_IF
	END_IF

// ========================= 手动控制气缸和皮带的按钮 ================================

// 在手动或者维护模式下			
	IF (bManual OR bMaintenance) AND bStarted THEN
		
		// 气缸到目标位置，则按钮变为粉色。基始位置为黄色
		IF bButtonClampToWorkOut THEN
			nButtonColorClamp 	:= cPink;
		ELSE
			nButtonColorClamp 	:= cYellow;
		END_IF
		
		IF bButtonBarrierToWorkOut THEN
			nButtonColorBarrier := cPink;
		ELSE
			nButtonColorBarrier := cYellow;
		END_IF
		
		IF bButtonMetalToWorkOut THEN
			nButtonColorMetalCyl := cPink;
		ELSE
			nButtonColorMetalCyl := cYellow;
		END_IF
		
		IF bButtonPlasticToWorkOut THEN
			nButtonColorPlasticCyl := cPink;
		ELSE
			nButtonColorPlasticCyl := cYellow;
		END_IF
		
		bButtonColorClamp 		:= TRUE;
		bButtonColorBarrier 	:= TRUE;
		bButtonColorMetalCyl 	:= TRUE;
		bButtonColorPlasticCyl 	:= TRUE;
		
	// 轴正转，则正转按钮为粉色，否则为黄色。轴反转，则反转按钮为粉色，否则为黄色。
		IF bButtonMainBwOut THEN
			nButtonColorMainBw := cPink;
		ELSE
			nButtonColorMainBw := cYellow;
		END_IF
		
		IF bButtonMainFwOut THEN
			nButtonColorMainFw := cPink;
		ELSE
			nButtonColorMainFw := cYellow;
		END_IF
		
		IF bButtonMetalBwOut THEN
			nButtonColorMetalBw := cPink;
		ELSE
			nButtonColorMetalBw := cYellow;
		END_IF
		
		IF bButtonMetalFwOut THEN
			nButtonColorMetalFw := cPink;
		ELSE
			nButtonColorMetalFw := cYellow;
		END_IF
		
		IF bButtonPlasticBwOut THEN
			nButtonColorPlasticBw := cPink;
		ELSE
			nButtonColorPlasticBw := cYellow;
		END_IF
		
		IF bButtonPlasticFwOut THEN
			nButtonColorPlasticFw := cPink;
		ELSE
			nButtonColorPlasticFw := cYellow;
		END_IF
		
		bButtonColorMainBw 		:= NOT bButtonMainFwOut;
		bButtonColorMainFw 		:= NOT bButtonMainBwOut;
		bButtonColorMetalBw 	:= NOT bButtonMetalFwOut;
		bButtonColorMetalFw 	:= NOT bButtonMetalBwOut;
		bButtonColorPlasticBw 	:= NOT bButtonPlasticFwOut;
		bButtonColorPlasticFw 	:= NOT bButtonPlasticBwOut;
	ELSE
		bButtonColorClamp 		:= FALSE;
		bButtonColorBarrier 	:= FALSE;
		bButtonColorMetalCyl 	:= FALSE;
		bButtonColorPlasticCyl 	:= FALSE;
		bButtonColorMainBw 		:= FALSE;
		bButtonColorMainFw 		:= FALSE;
		bButtonColorMetalBw 	:= FALSE;
		bButtonColorMetalFw 	:= FALSE;
		bButtonColorPlasticBw 	:= FALSE;
		bButtonColorPlasticFw 	:= FALSE;
	END_IF
		
// =========================手动压缩气缸空气按钮================================

// 维护模式下			
	IF bMaintenance AND bStarted THEN
		IF bButtonComprAirIn THEN
			nButtonColorComprAir := cGreen;				// 按下则按钮是绿色
		ELSE
			nButtonColorComprAir := cYellow;			// 未按下则按钮是黄色
		END_IF
		
		bButtonColorComprAir := TRUE;
	ELSE
		bButtonColorComprAir := FALSE;
	END_IF

// =========================================================


]]></ST>
      </Implementation>
    </Method>
    <Method Name="ButtonSignals" Id="{198e6a7d-ceab-43b4-a4a5-f3f71a362b46}" FolderPath="Methods\">
      <Declaration><![CDATA[METHOD PRIVATE ButtonSignals
VAR_INPUT
END_VAR
]]></Declaration>
      <Implementation>
        <ST><![CDATA[// =========================================================
// 请求按钮根据实际状态自复位

	IF bStartButtonOff THEN
		bButtonStartOut := FALSE;
	END_IF
	
	IF bStopped THEN
		bButtonStopOut := FALSE;
	END_IF
	
	IF bReset THEN
		bButtonResetOut := FALSE;
	END_IF
	
	IF bManual THEN
		bButtonManuOut := FALSE;
	END_IF
	
	IF bAuto THEN
		bButtonAutoOut := FALSE;
	END_IF
	
	IF bSemi THEN
		bButtonSemiOut := FALSE;
	END_IF
	
	IF bMaintenance THEN
		bButtonMaintenanceOut := FALSE;
	END_IF

// =========================================================]]></ST>
      </Implementation>
    </Method>
    <Method Name="CylinderMoveBoxes" Id="{b8510bdd-8024-4ccc-a66e-873af45b1bb0}" FolderPath="Methods\">
      <Declaration><![CDATA[METHOD PRIVATE CylinderMoveBoxes
VAR_INPUT
END_VAR
]]></Declaration>
      <Implementation>
        <ST><![CDATA[// =========================================================
// 金属分拣气缸，检测物料在金属皮带上的位置
// 检测第几个物料没在被金属分拣气缸分拣		如：aBoxMetalFree[1] := TRUE，则一号物料没有在被金属分拣气缸分拣
	
	aBoxMetalFree[1] := 	NOT (aBoxX[2] > cXforBox2OnMetalBelt_min AND aBoxX[2] <= cXforBox2OnMetalBelt_max AND (aBoxY[1] - aBoxY[2]) <= (cBoxWidth + 1))
						AND NOT (aBoxX[3] > cXforBox3OnMetalBelt_min AND aBoxX[3] <= cXforBox3OnMetalBelt_max AND (aBoxY[1] - aBoxY[3]) <= (cBoxWidth + 1))
						AND NOT (aBoxX[4] > cXforBox4OnMetalBelt_min AND aBoxX[4] <= cXforBox4OnMetalBelt_max AND (aBoxY[1] - aBoxY[4]) <= (cBoxWidth + 1));
	
	aBoxMetalFree[2] := 	NOT (aBoxX[1] > cXforBox1OnMetalBelt_min AND aBoxX[1] <= cXforBox1OnMetalBelt_max AND (aBoxY[2] - aBoxY[1]) <= (cBoxWidth + 1))
						AND NOT (aBoxX[3] > cXforBox3OnMetalBelt_min AND aBoxX[3] <= cXforBox3OnMetalBelt_max AND (aBoxY[2] - aBoxY[3]) <= (cBoxWidth + 1))
						AND NOT (aBoxX[4] > cXforBox4OnMetalBelt_min AND aBoxX[4] <= cXforBox4OnMetalBelt_max AND (aBoxY[2] - aBoxY[4]) <= (cBoxWidth + 1));
						
	aBoxMetalFree[3] := 	NOT (aBoxX[1] > cXforBox1OnMetalBelt_min AND aBoxX[1] <= cXforBox1OnMetalBelt_max AND (aBoxY[3] - aBoxY[1]) <= (cBoxWidth + 1))
						AND NOT (aBoxX[2] > cXforBox2OnMetalBelt_min AND aBoxX[2] <= cXforBox2OnMetalBelt_max AND (aBoxY[3] - aBoxY[2]) <= (cBoxWidth + 1))
						AND NOT (aBoxX[4] > cXforBox4OnMetalBelt_min AND aBoxX[4] <= cXforBox4OnMetalBelt_max AND (aBoxY[3] - aBoxY[4]) <= (cBoxWidth + 1));
						
	aBoxMetalFree[4] := 	NOT (aBoxX[1] > cXforBox1OnMetalBelt_min AND aBoxX[1] <= cXforBox1OnMetalBelt_max AND (aBoxY[4] - aBoxY[1]) <= (cBoxWidth + 1))
						AND NOT (aBoxX[2] > cXforBox2OnMetalBelt_min AND aBoxX[2] <= cXforBox2OnMetalBelt_max AND (aBoxY[4] - aBoxY[2]) <= (cBoxWidth + 1))
						AND NOT (aBoxX[3] > cXforBox3OnMetalBelt_min AND aBoxX[3] <= cXforBox3OnMetalBelt_max AND (aBoxY[4] - aBoxY[3]) <= (cBoxWidth + 1));

// =========================================================
// 金属分拣气缸移动金属物料
	
	FOR nState := 1 TO 4 BY 1 DO
		IF bMetalToWork AND aBoxMetalMove[nState] AND aBoxMetalFree[nState] THEN
			IF (fYMetal - cMetalPlasticCylMovement) >= (cYMetalPlasticCylEndPos + cMetalPlasticCylMovement) THEN
				fYMetal := fYMetal - cMetalPlasticCylMovement;
				
				IF (fYMetal - aBoxY[nState]) <= cYMetalPlasticCylOnMainBelt THEN
					aBoxY[nState] := aBoxY[nState] - cMetalPlasticCylMovement;
				END_IF
				
			ELSIF fYMetal = (cYMetalPlasticCylEndPos + cMetalPlasticCylMovement) AND (fYMetal - aBoxY[nState]) <= cYMetalPlasticCylOnMainBelt THEN
				aBoxY[nState] := aBoxY[nState] - 2*cMetalPlasticCylMovement;
				
			ELSE
				aBoxMetalMove[nState] := FALSE;
			END_IF
		END_IF	
	END_FOR

// =========================================================
// 塑料分拣气缸，检测物料在塑料皮带上的位置
// 检测第几个物料没在被塑料分拣气缸分拣		如：aBoxPlasticFree[1] := TRUE，则一号物料没有在被塑料分拣气缸分拣

	aBoxPlasticFree[1] := 	NOT (aBoxX[2] > (cXforBox2OnPlasticBelt_min + 20) AND aBoxX[2] <= cXforBox2OnPlasticBelt_max AND (aBoxY[1] - aBoxY[2]) <= (cBoxWidth + 1))
						AND NOT (aBoxX[3] > (cXforBox3OnPlasticBelt_min + 20) AND aBoxX[3] <= cXforBox3OnPlasticBelt_max AND (aBoxY[1] - aBoxY[3]) <= (cBoxWidth + 1))
						AND NOT (aBoxX[4] > (cXforBox4OnPlasticBelt_min + 20) AND aBoxX[4] <= cXforBox4OnPlasticBelt_max AND (aBoxY[1] - aBoxY[4]) <= (cBoxWidth + 1));
	
	aBoxPlasticFree[2] := 	NOT (aBoxX[1] > (cXforBox1OnPlasticBelt_min + 20) AND aBoxX[1] <= cXforBox1OnPlasticBelt_max AND (aBoxY[2] - aBoxY[1]) <= (cBoxWidth + 1))
						AND NOT (aBoxX[3] > (cXforBox3OnPlasticBelt_min + 20) AND aBoxX[3] <= cXforBox3OnPlasticBelt_max AND (aBoxY[2] - aBoxY[3]) <= (cBoxWidth + 1))
						AND NOT (aBoxX[4] > (cXforBox4OnPlasticBelt_min + 20) AND aBoxX[4] <= cXforBox4OnPlasticBelt_max AND (aBoxY[2] - aBoxY[4]) <= (cBoxWidth + 1));
						
	aBoxPlasticFree[3] := 	NOT (aBoxX[1] > (cXforBox1OnPlasticBelt_min + 20) AND aBoxX[1] <= cXforBox1OnPlasticBelt_max AND (aBoxY[3] - aBoxY[1]) <= (cBoxWidth + 1))
						AND NOT (aBoxX[2] > (cXforBox2OnPlasticBelt_min + 20) AND aBoxX[2] <= cXforBox2OnPlasticBelt_max AND (aBoxY[3] - aBoxY[2]) <= (cBoxWidth + 1))
						AND NOT (aBoxX[4] > (cXforBox4OnPlasticBelt_min + 20) AND aBoxX[4] <= cXforBox4OnPlasticBelt_max AND (aBoxY[3] - aBoxY[4]) <= (cBoxWidth + 1));
						
	aBoxPlasticFree[4] := 	NOT (aBoxX[1] > (cXforBox1OnPlasticBelt_min + 20) AND aBoxX[1] <= cXforBox1OnPlasticBelt_max AND (aBoxY[4] - aBoxY[1]) <= (cBoxWidth + 1))
						AND NOT (aBoxX[2] > (cXforBox2OnPlasticBelt_min + 20) AND aBoxX[2] <= cXforBox2OnPlasticBelt_max AND (aBoxY[4] - aBoxY[2]) <= (cBoxWidth + 1))
						AND NOT (aBoxX[3] > (cXforBox3OnPlasticBelt_min + 20) AND aBoxX[3] <= cXforBox3OnPlasticBelt_max AND (aBoxY[4] - aBoxY[3]) <= (cBoxWidth + 1));
					
// =========================================================
// 塑料分拣气缸移动塑料物料

	FOR nState := 1 TO 4 BY 1 DO
		IF bPlasticToWork AND aBoxPlasticMove[nState] AND aBoxPlasticFree[nState] THEN
			IF (fYPlastic - cMetalPlasticCylMovement) >= (cYMetalPlasticCylEndPos + cMetalPlasticCylMovement) THEN
				fYPlastic := fYPlastic - cMetalPlasticCylMovement;
				
				IF (fYPlastic - aBoxY[nState]) <= cYMetalPlasticCylOnMainBelt THEN
					aBoxY[nState] := aBoxY[nState] - cMetalPlasticCylMovement;
				END_IF
				
			ELSIF fYPlastic = (cYMetalPlasticCylEndPos + cMetalPlasticCylMovement) AND (fYPlastic - aBoxY[nState]) <= cYMetalPlasticCylOnMainBelt THEN
				aBoxY[nState] := aBoxY[nState] - 2*cMetalPlasticCylMovement;
				
			ELSE
				aBoxPlasticMove[nState] := FALSE;
			END_IF
		END_IF	
	END_FOR

// =========================================================]]></ST>
      </Implementation>
    </Method>
    <Method Name="ErrorMessages" Id="{b4dd5860-6722-4d1a-bd1e-a2ee42d94484}" FolderPath="Methods\">
      <Declaration><![CDATA[METHOD PRIVATE ErrorMessages
VAR_INPUT
END_VAR
]]></Declaration>
      <Implementation>
        <ST><![CDATA[// =========================== 错误信息 ==============================

	// 正位气缸错误条数以及信息
	IF bClampError THEN
		nMessages 			:= nMessages + 1;
		sMessageClamp 		:= CONCAT('Error of clamp cylinder: ', sClampErrMsg);	
	ELSE
		sMessageClamp 		:= '';
	END_IF
	
	// 金属分拣气缸错误条数以及信息
	IF bMetalCylError THEN
		nMessages 			:= nMessages + 1;
		sMessageMetalCyl 	:= CONCAT('Error of metal cylinder: ', sMetalErrMsg);
	ELSE
		sMessageMetalCyl 	:= '';
	END_IF
	
	// 塑料分拣气缸错误条数以及信息
	IF bPlasticCylError THEN
		nMessages 			:= nMessages + 1;
		sMessagePlasticCyl 	:= CONCAT('Error of plastic cylinder: ', sPlasticErrMsg);
	ELSE
		sMessagePlasticCyl 	:= '';
	END_IF
	
// =========================================================]]></ST>
      </Implementation>
    </Method>
    <Method Name="LastBox" Id="{1efee56b-cdba-4275-96f0-da2f234c12ef}" FolderPath="Methods\">
      <Declaration><![CDATA[METHOD PRIVATE LastBox
VAR_INPUT
END_VAR
]]></Declaration>
      <Implementation>
        <ST><![CDATA[// =========================================================
// 检查输送皮带当中第几号物料在运输当中
	
	IF 		(aBoxX[1] >= (cXforAllBoxesStartPosMainBelt + 1*cBoxWidth - 0.05))
	AND		(aBoxX[1] < (cXforAllBoxesStartPosMainBelt + 2*cBoxWidth - 1.5)) AND (aBoxY[1] = 0) THEN
		nLastBox := 1;
		
	ELSIF 	(aBoxX[2] >= (cXforAllBoxesStartPosMainBelt + 2*cBoxWidth - 0.05))
	AND 	(aBoxX[2] < (cXforAllBoxesStartPosMainBelt + 3*cBoxWidth - 1.5)) AND (aBoxY[2] = 0) THEN
		nLastBox := 2;	
		
	ELSIF 	(aBoxX[3] >= (cXforAllBoxesStartPosMainBelt + 3*cBoxWidth - 0.05))
	AND 	(aBoxX[3] < (cXforAllBoxesStartPosMainBelt + 4*cBoxWidth - 1.5)) AND (aBoxY[3] = 0) THEN
		nLastBox := 3;	
		
	ELSIF 	(aBoxX[4] >= cXforAllBoxesStartPosMainBelt + 4*cBoxWidth - 0.05)
	AND 	(aBoxX[4] < (cXforAllBoxesStartPosMainBelt + 5*cBoxWidth - 1.5)) AND (aBoxY[4] = 0) THEN
		nLastBox := 4;	
		
	ELSE
		nLastBox := 0;
	END_IF		

// =========================================================]]></ST>
      </Implementation>
    </Method>
    <Method Name="Metal_Plastic_Cyl" Id="{991a9593-fd32-419b-bf21-1dffee7fb012}" FolderPath="Methods\">
      <Declaration><![CDATA[METHOD PRIVATE Metal_Plastic_Cyl
VAR_INPUT
END_VAR
]]></Declaration>
      <Implementation>
        <ST><![CDATA[// =========================================================
// 移动金属分拣气缸
	
	IF bMetalToWork THEN
		IF NOT (aBoxMetalMove[1] OR aBoxMetalMove[2] OR aBoxMetalMove[3] OR aBoxMetalMove[4]) THEN
			IF ((fYMetal - cMetalPlasticCylMovement) >= cYMetalPlasticCylEndPos) THEN
				fYMetal := fYMetal - cMetalPlasticCylMovement;
			END_IF
			
		ELSE
			FOR nState := 1 TO 4 BY 1 DO
				IF aBoxMetalMove[nState] THEN
					IF ((fYMetal - cMetalPlasticCylMovement) >= (aBoxY[nState] - cYMetalPlasticCylOnMainBelt - 0.1))
					AND ((fYMetal - cMetalPlasticCylMovement) >= cYMetalPlasticCylEndPos) THEN
						fYMetal := fYMetal - cMetalPlasticCylMovement;
					END_IF
				END_IF
			END_FOR
		END_IF
		
	ELSE
		IF ((fYMetal + cMetalPlasticCylMovement) < cYMetalPlasticCylStartPos) THEN
			fYMetal := fYMetal + cMetalPlasticCylMovement;
		ELSE
			fYMetal := cYMetalPlasticCylStartPos;
		END_IF
	END_IF

// =========================================================
// 检测物料与金属分拣气缸的位置，判断物料是否正在被金属分拣气缸分拣，是否撞机
	
	IF (fYMetal < (cYMetalPlasticCylOnMainBelt + 0.1)) AND (fYMetal > (cYMetalPlasticCylOnMainBelt - 0.1)) AND bMetalToWork THEN
		FOR nState := 1 TO 4 BY 1 DO
			IF (aBoxY[nState] >= cYforAllBoxesOnMainBelt) THEN

				IF (aBoxX[nState] > (cXforAllBoxesCorrectPushMetalCyl_min + cBoxWidth*nState))
				AND (aBoxX[nState] <= (cXforAllBoxesCorrectPushMetalCyl_max + cBoxWidth*nState)) THEN
					aBoxMetalMove[nState] := TRUE;
				END_IF
				
				IF ((aBoxX[nState] > (cXforAllBoxesIncorrectPushMetalCyl_min + cBoxWidth*nState)
						AND aBoxX[nState] <= (cXforAllBoxesCorrectPushMetalCyl_min + cBoxWidth*nState))
					OR (aBoxX[nState] > (cXforAllBoxesCorrectPushMetalCyl_max + cBoxWidth*nState)
						AND aBoxX[nState] < (cXforAllBoxesIncorrectPushMetalCyl_max + cBoxWidth*nState)))
				AND NOT bStopped THEN
					bAccident := TRUE;
				END_IF
				
			END_IF
		END_FOR
	END_IF

// =========================================================
// =========================================================
// 移动塑料分拣气缸
	
	IF bPlasticToWork THEN
		IF NOT (aBoxPlasticMove[1] OR aBoxPlasticMove[2] OR aBoxPlasticMove[3] OR aBoxPlasticMove[4]) THEN
			IF ((fYPlastic - cMetalPlasticCylMovement) >= cYMetalPlasticCylEndPos) THEN
				fYPlastic := fYPlastic - cMetalPlasticCylMovement;
			END_IF
			
		ELSE
			FOR nState := 1 TO 4 BY 1 DO
				IF aBoxPlasticMove[nState] THEN
					IF ((fYPlastic - cMetalPlasticCylMovement) >= (aBoxY[nState] - cYMetalPlasticCylOnMainBelt - 0.1))
					AND ((fYPlastic - cMetalPlasticCylMovement) >= cYMetalPlasticCylEndPos) THEN
						fYPlastic := fYPlastic - cMetalPlasticCylMovement;
					END_IF
				END_IF
			END_FOR
		END_IF
		
	ELSE
		IF ((fYPlastic + cMetalPlasticCylMovement) < cYMetalPlasticCylStartPos) THEN
			fYPlastic := fYPlastic + cMetalPlasticCylMovement;
		ELSE
			fYPlastic := cYMetalPlasticCylStartPos;
		END_IF
	END_IF

// =========================================================
// 检测物料与塑料分拣气缸的位置，判断物料是否正在被塑料分拣气缸分拣，是否撞机
		
	IF ((aBoxX[1] > (cXforAllBoxesLastPossiblePosMainBelt + 1*cBoxWidth))
		OR (aBoxX[2] > (cXforAllBoxesLastPossiblePosMainBelt + 2*cBoxWidth))
		OR (aBoxX[3] > (cXforAllBoxesLastPossiblePosMainBelt + 3*cBoxWidth))
		OR (aBoxX[4] > (cXforAllBoxesLastPossiblePosMainBelt + 4*cBoxWidth)))
	AND NOT bStopped THEN
		bAccident := TRUE;
	END_IF
		
	IF (fYPlastic < (cYMetalPlasticCylOnMainBelt + 0.1)) AND (fYPlastic > (cYMetalPlasticCylOnMainBelt - 0.1)) AND bPlasticToWork THEN
		FOR nState := 1 TO 4 BY 1 DO
			IF aBoxY[nState] >= cYforAllBoxesOnMainBelt THEN
				
				IF (aBoxX[nState] > (cXforAllBoxesCorrectPushPlasticCyl_min + cBoxWidth*nState))
				AND (aBoxX[nState] <= (cXforAllBoxesCorrectPushPlasticCyl_max + cBoxWidth*nState)) THEN
					aBoxPlasticMove[nState] := TRUE;
				END_IF
				
				IF (aBoxX[nState] > (cXforAllBoxesIncorrectPushPlasticCyl_min + cBoxWidth*nState))
				AND (aBoxX[nState] <= (cXforAllBoxesCorrectPushPlasticCyl_min + cBoxWidth*nState))
				AND NOT bStopped THEN
					bAccident := TRUE;
				END_IF	
				
			END_IF
		END_FOR
	END_IF

// =========================================================]]></ST>
      </Implementation>
    </Method>
    <Property Name="P_ArrChangeColor" Id="{bacc89d9-f59b-402d-9ea4-eda6bef57ff9}" FolderPath="Properties\">
      <Declaration><![CDATA[PROPERTY P_ArrChangeColor : ARRAY [1..4] OF BOOL]]></Declaration>
      <Get Name="Get" Id="{e4b90468-5ea2-43c5-9a39-28ed99c937cf}">
        <Declaration><![CDATA[VAR
END_VAR
]]></Declaration>
        <Implementation>
          <ST><![CDATA[P_ArrChangeColor	:= ArrChangeColor;]]></ST>
        </Implementation>
      </Get>
    </Property>
    <Property Name="P_ArrfBoxX" Id="{e48324ab-4047-4b0d-933c-fd9921dea379}" FolderPath="Properties\">
      <Declaration><![CDATA[PROPERTY P_ArrfBoxX : ARRAY [1..4] OF LREAL]]></Declaration>
      <Get Name="Get" Id="{661988fa-77ed-4c78-b0cf-84bc18c12bb5}">
        <Declaration><![CDATA[VAR
END_VAR
]]></Declaration>
        <Implementation>
          <ST><![CDATA[P_ArrfBoxX	:= ABoxX;]]></ST>
        </Implementation>
      </Get>
    </Property>
    <Property Name="P_ArrfBoxY" Id="{2f674f62-fb0d-46eb-a1ce-9e43663c0ff4}" FolderPath="Properties\">
      <Declaration><![CDATA[PROPERTY P_ArrfBoxY : ARRAY [1..4] OF LREAL]]></Declaration>
      <Get Name="Get" Id="{d8719e5c-604b-4cf0-a7f7-40d193b2eb37}">
        <Declaration><![CDATA[VAR
END_VAR
]]></Declaration>
        <Implementation>
          <ST><![CDATA[P_ArrfBoxY	:= ABoxY;]]></ST>
        </Implementation>
      </Get>
    </Property>
    <Property Name="P_fYBarrier" Id="{4be62cbd-794f-454b-9747-37792aeb9588}" FolderPath="Properties\">
      <Declaration><![CDATA[PROPERTY P_fYBarrier : LREAL]]></Declaration>
      <Get Name="Get" Id="{4ebdf65f-999f-4013-888d-411487901970}">
        <Declaration><![CDATA[VAR
END_VAR
]]></Declaration>
        <Implementation>
          <ST><![CDATA[P_fYBarrier	:= fYBarrier;]]></ST>
        </Implementation>
      </Get>
    </Property>
    <Property Name="P_fYClamp" Id="{19678d54-ed49-4ee6-9220-e9004f2c7161}" FolderPath="Properties\">
      <Declaration><![CDATA[PROPERTY P_fYClamp : LREAL]]></Declaration>
      <Get Name="Get" Id="{8b977fe9-0fdc-4265-8cc2-2aa8f93e8038}">
        <Declaration><![CDATA[VAR
END_VAR
]]></Declaration>
        <Implementation>
          <ST><![CDATA[P_fYClamp	:= fYClamp;]]></ST>
        </Implementation>
      </Get>
    </Property>
    <Property Name="P_fYMetal" Id="{68e83f92-912c-40db-a118-9705a17e0d4e}" FolderPath="Properties\">
      <Declaration><![CDATA[PROPERTY P_fYMetal : LREAL]]></Declaration>
      <Get Name="Get" Id="{bf349a4b-06b8-4641-a900-1070d2f22be4}">
        <Declaration><![CDATA[VAR
END_VAR
]]></Declaration>
        <Implementation>
          <ST><![CDATA[P_fYMetal	:= fYMetal;]]></ST>
        </Implementation>
      </Get>
    </Property>
    <Property Name="P_fYPlastic" Id="{24b02fca-38cc-4d9d-8fde-d341db0972b7}" FolderPath="Properties\">
      <Declaration><![CDATA[PROPERTY P_fYPlastic : LREAL]]></Declaration>
      <Get Name="Get" Id="{7ce9ed4b-8dbb-46f6-94d7-d2adebc7b450}">
        <Declaration><![CDATA[VAR
END_VAR
]]></Declaration>
        <Implementation>
          <ST><![CDATA[P_fYPlastic	:= fYPlastic;]]></ST>
        </Implementation>
      </Get>
    </Property>
    <Method Name="RandomColor" Id="{d86aaba3-b8e0-4930-9ff5-e808d197c93c}" FolderPath="Methods\">
      <Declaration><![CDATA[METHOD PRIVATE RandomColor
VAR_INPUT
END_VAR
]]></Declaration>
      <Implementation>
        <ST><![CDATA[// =========================================================

// 随机数（0..1）生成器
RandomGenerator(Seed:= 1 , Num=> RandomNumber);

// 随机BOOL变量生成器
IF RandomNumber >0.5 THEN
	bRandomChangeColor	:= TRUE;
ELSE
	bRandomChangeColor	:= FALSE;
END_IF

// =========================================================]]></ST>
      </Implementation>
    </Method>
    <Method Name="Reset" Id="{5f0e050d-a274-4be5-b5c9-4d95fa493864}" FolderPath="Methods\">
      <Declaration><![CDATA[METHOD PRIVATE Reset
VAR_INPUT
END_VAR
]]></Declaration>
      <Implementation>
        <ST><![CDATA[// ========================== 复位Visu相关变量 ===============================
	
	// 气缸按钮
	bButtonClampToWorkOut 		:= FALSE;
	bButtonBarrierToWorkOut 	:= FALSE;
	bButtonMetalToWorkOut 		:= FALSE;
	bButtonPlasticToWorkOut 	:= FALSE;
	
	// 轴控按钮
	bButtonMainBwOut 			:= FALSE;
	bButtonMainFwOut 			:= FALSE;
	bButtonMetalBwOut 			:= FALSE;
	bButtonMetalFwOut 			:= FALSE;
	bButtonPlasticBwOut			:= FALSE;
	bButtonPlasticFwOut			:= FALSE;
	
	// 模式以及状态按钮
	bButtonStartOut 			:= FALSE;
	bButtonStopOut 				:= FALSE;
	bButtonResetOut 			:= FALSE;
	bButtonComprAirOut 			:= FALSE;
	bButtonManuOut 				:= FALSE;
	bButtonAutoOut 				:= FALSE;
	bButtonSemiOut 				:= FALSE;
	bButtonMaintenanceOut		:= FALSE;
	
	// 物料状态的相关变量
	FOR nState := 1 TO 4 BY 1 DO
		aBoxX[nState] 			:= 0;
		aBoxY[nState] 			:= 0;
		
		aBoxMetalMove[nState] 	:= FALSE;
		aBoxPlasticMove[nState]	:= FALSE;
		aBoxMainBelt[nState]	:= FALSE;
		aBoxMetalBelt[nState] 	:= FALSE;
		aBoxPlasticBelt[nState]	:= FALSE;
	END_FOR
	
	// 事故标志位
	bAccident := FALSE;

// =========================================================]]></ST>
      </Implementation>
    </Method>
    <LineIds Name="FB_Visu">
      <LineId Id="3" Count="5" />
      <LineId Id="978" Count="0" />
      <LineId Id="31" Count="31" />
      <LineId Id="359" Count="2" />
      <LineId Id="63" Count="0" />
      <LineId Id="2" Count="0" />
      <LineId Id="672" Count="3" />
      <LineId Id="661" Count="0" />
    </LineIds>
    <LineIds Name="FB_Visu.AxisMoveBoxes">
      <LineId Id="3" Count="0" />
      <LineId Id="6" Count="2" />
      <LineId Id="10" Count="2" />
      <LineId Id="14" Count="2" />
      <LineId Id="18" Count="5" />
      <LineId Id="25" Count="2" />
      <LineId Id="29" Count="2" />
      <LineId Id="33" Count="5" />
      <LineId Id="40" Count="2" />
      <LineId Id="44" Count="2" />
      <LineId Id="48" Count="5" />
      <LineId Id="55" Count="2" />
      <LineId Id="59" Count="2" />
      <LineId Id="63" Count="4" />
      <LineId Id="69" Count="2" />
      <LineId Id="402" Count="0" />
      <LineId Id="72" Count="0" />
      <LineId Id="74" Count="0" />
      <LineId Id="76" Count="6" />
      <LineId Id="84" Count="3" />
      <LineId Id="89" Count="1" />
      <LineId Id="92" Count="6" />
      <LineId Id="100" Count="4" />
      <LineId Id="106" Count="7" />
      <LineId Id="115" Count="5" />
      <LineId Id="122" Count="10" />
      <LineId Id="134" Count="4" />
      <LineId Id="140" Count="8" />
      <LineId Id="150" Count="3" />
      <LineId Id="155" Count="9" />
      <LineId Id="166" Count="3" />
      <LineId Id="171" Count="4" />
      <LineId Id="177" Count="7" />
      <LineId Id="187" Count="2" />
      <LineId Id="191" Count="1" />
      <LineId Id="194" Count="1" />
      <LineId Id="197" Count="25" />
      <LineId Id="328" Count="2" />
      <LineId Id="359" Count="2" />
      <LineId Id="363" Count="0" />
      <LineId Id="365" Count="14" />
      <LineId Id="394" Count="3" />
      <LineId Id="393" Count="0" />
      <LineId Id="380" Count="0" />
      <LineId Id="383" Count="0" />
      <LineId Id="381" Count="0" />
      <LineId Id="223" Count="0" />
      <LineId Id="251" Count="0" />
      <LineId Id="253" Count="2" />
      <LineId Id="258" Count="1" />
      <LineId Id="261" Count="1" />
      <LineId Id="264" Count="26" />
      <LineId Id="407" Count="0" />
      <LineId Id="292" Count="4" />
      <LineId Id="298" Count="0" />
      <LineId Id="300" Count="14" />
      <LineId Id="322" Count="0" />
      <LineId Id="324" Count="0" />
      <LineId Id="326" Count="1" />
      <LineId Id="325" Count="0" />
      <LineId Id="323" Count="0" />
      <LineId Id="315" Count="2" />
      <LineId Id="321" Count="0" />
    </LineIds>
    <LineIds Name="FB_Visu.AxisRotation">
      <LineId Id="89" Count="18" />
      <LineId Id="83" Count="0" />
      <LineId Id="88" Count="0" />
      <LineId Id="3" Count="2" />
      <LineId Id="12" Count="7" />
      <LineId Id="75" Count="0" />
      <LineId Id="71" Count="1" />
      <LineId Id="20" Count="0" />
      <LineId Id="22" Count="2" />
      <LineId Id="31" Count="8" />
      <LineId Id="76" Count="0" />
      <LineId Id="73" Count="1" />
      <LineId Id="40" Count="0" />
      <LineId Id="42" Count="3" />
      <LineId Id="52" Count="7" />
      <LineId Id="79" Count="0" />
      <LineId Id="77" Count="1" />
      <LineId Id="60" Count="0" />
      <LineId Id="62" Count="0" />
      <LineId Id="2" Count="0" />
    </LineIds>
    <LineIds Name="FB_Visu.Barrier_Clamp_Cyl">
      <LineId Id="3" Count="48" />
      <LineId Id="2" Count="0" />
    </LineIds>
    <LineIds Name="FB_Visu.ButtonColors">
      <LineId Id="3" Count="0" />
      <LineId Id="218" Count="0" />
      <LineId Id="5" Count="16" />
      <LineId Id="219" Count="0" />
      <LineId Id="22" Count="0" />
      <LineId Id="24" Count="27" />
      <LineId Id="220" Count="0" />
      <LineId Id="53" Count="54" />
      <LineId Id="221" Count="1" />
      <LineId Id="109" Count="99" />
      <LineId Id="2" Count="0" />
      <LineId Id="213" Count="1" />
      <LineId Id="212" Count="0" />
    </LineIds>
    <LineIds Name="FB_Visu.ButtonSignals">
      <LineId Id="3" Count="30" />
      <LineId Id="2" Count="0" />
    </LineIds>
    <LineIds Name="FB_Visu.CylinderMoveBoxes">
      <LineId Id="3" Count="41" />
      <LineId Id="88" Count="0" />
      <LineId Id="46" Count="38" />
      <LineId Id="2" Count="0" />
    </LineIds>
    <LineIds Name="FB_Visu.ErrorMessages">
      <LineId Id="3" Count="0" />
      <LineId Id="31" Count="24" />
      <LineId Id="2" Count="0" />
    </LineIds>
    <LineIds Name="FB_Visu.LastBox">
      <LineId Id="3" Count="22" />
      <LineId Id="2" Count="0" />
    </LineIds>
    <LineIds Name="FB_Visu.Metal_Plastic_Cyl">
      <LineId Id="3" Count="32" />
      <LineId Id="37" Count="6" />
      <LineId Id="45" Count="6" />
      <LineId Id="121" Count="0" />
      <LineId Id="52" Count="45" />
      <LineId Id="99" Count="0" />
      <LineId Id="119" Count="0" />
      <LineId Id="101" Count="4" />
      <LineId Id="107" Count="4" />
      <LineId Id="120" Count="0" />
      <LineId Id="112" Count="3" />
      <LineId Id="2" Count="0" />
    </LineIds>
    <LineIds Name="FB_Visu.P_ArrChangeColor.Get">
      <LineId Id="2" Count="0" />
    </LineIds>
    <LineIds Name="FB_Visu.P_ArrfBoxX.Get">
      <LineId Id="2" Count="0" />
    </LineIds>
    <LineIds Name="FB_Visu.P_ArrfBoxY.Get">
      <LineId Id="2" Count="0" />
    </LineIds>
    <LineIds Name="FB_Visu.P_fYBarrier.Get">
      <LineId Id="2" Count="0" />
    </LineIds>
    <LineIds Name="FB_Visu.P_fYClamp.Get">
      <LineId Id="2" Count="0" />
    </LineIds>
    <LineIds Name="FB_Visu.P_fYMetal.Get">
      <LineId Id="2" Count="0" />
    </LineIds>
    <LineIds Name="FB_Visu.P_fYPlastic.Get">
      <LineId Id="2" Count="0" />
    </LineIds>
    <LineIds Name="FB_Visu.RandomColor">
      <LineId Id="16" Count="2" />
      <LineId Id="6" Count="0" />
      <LineId Id="20" Count="0" />
      <LineId Id="7" Count="5" />
      <LineId Id="19" Count="0" />
      <LineId Id="5" Count="0" />
    </LineIds>
    <LineIds Name="FB_Visu.Reset">
      <LineId Id="3" Count="0" />
      <LineId Id="5" Count="36" />
      <LineId Id="47" Count="0" />
      <LineId Id="42" Count="1" />
      <LineId Id="2" Count="0" />
    </LineIds>
  </POU>
</TcPlcObject>