diff --git a/Rs.DeweyTester/Flow/SubFlow/FiveProductTestFlow.cs b/Rs.DeweyTester/Flow/SubFlow/FiveProductTestFlow.cs new file mode 100644 index 0000000..084ca55 --- /dev/null +++ b/Rs.DeweyTester/Flow/SubFlow/FiveProductTestFlow.cs @@ -0,0 +1,486 @@ +using Rs.Controls; +using Rs.Framework; +using Rs.Motion; +using Rs.MotionPlat.Commom; +using Rs.MotionPlat.Entitys; +using Rs.MotionPlat.Flow.Common; +using Rs.MotionPlat.Flow.SafePosFlow; +using Rs.MotionPlat.Vision; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace Rs.MotionPlat.Flow.SubFlow +{ + enum EFiveProductTestFlowStep + { + + 到料仓拍照位上方, + 等待到料仓拍照位上方, + 料仓取料拍照, + 到料仓取料位上方, + 等待到料仓取料位上方, + 到料仓取料位下方, + 等待到料仓取料位下方, + 料仓取料完成抬起, + 等待料仓取料完成抬起, + 料仓取料真空吸检测, + + + 到料仓放料位上方, + 等待到料仓放料位上方, + 到料仓放料位下方, + 等待到料仓放料位下方, + 料仓放料完成抬起, + 等待料仓放料完成抬起, + 料仓放料完成粘料检测 + } + + public class FiveProductTestFlow + { + private Task mainTask; + private FiveProductTestFlow() { } + + private static FiveProductTestFlow instance; + public static FiveProductTestFlow Instance + { + get + { + if (instance == null) + { + instance = new FiveProductTestFlow(); + } + return instance; + } + } + private AlarmEntity alarmEntity; + Stopwatch timeout = new Stopwatch(); + EFiveProductTestFlowStep flowStep = EFiveProductTestFlowStep.到料仓拍照位上方; + + int scanNum = 0; + string logInfo = string.Empty; + string alarmInfo = string.Empty; + + private bool stop = true; + private bool run = true; + TargetPosition targetPosition = new TargetPosition(); + ErrorCode errCode = ErrorCode.Ok; + /// + /// 当前取料穴位 + /// + TraySlot curTakeSlot = null; + /// + /// 当前取料穴位的点位 + /// + SlotPoint curTakeSlotPoint = null; + //Nozzle curNozzle = null; + Nozzle curTakeNozzle = null; + Nozzle curDumpNozzle = null; + TestFixture curFixture = null; + //放料穴位 + TraySlot curDumpSlot = null; + /// + /// 最后一次换料的治具编号 + /// + private int lastFixtureIndex = 0; + /// + /// 已经取走的产品数量 + /// + private int takedNum = 0; + //相机拍照结果 + VisionResult vResult = new VisionResult(); + ProductLocationResult vProductResult = new ProductLocationResult(); + + List needGrrFixtureList = new List(); + /// + /// 测试完成的数量 + /// + private int testFinishedNum = 0; + + private void Reset() + { + curTakeSlot = null; + curTakeSlotPoint = null; + curTakeNozzle = null; + curDumpNozzle = null; + curFixture = null; + curDumpSlot = null; + lastFixtureIndex = 0; + takedNum = 0; + testFinishedNum = 0; + VirtualBarCode.Reset(); + } + + public void Init() + { + mainTask = new Task(Run); + mainTask.Start(); + } + + public void Deinit() + { + run = false; + } + + int takeNum = 0; + private void Run() + { + while (run) + { + if (stop || !GlobalVar.DeviceIsAuto) + { + Thread.Sleep(10); + continue; + } + switch (flowStep) + { + #region 料仓取料 + case EFiveProductTestFlowStep.到料仓拍照位上方: + curTakeSlot = GlobalTray.InputTray.GetSlot(ESlotStatus.Have); + if (curTakeSlot != null) + { + curTakeSlotPoint = TrayPointManager.GetSlotPoint(ETrayType.Input, curTakeSlot.Index); + if (curTakeSlotPoint != null) + { + targetPosition.X = curTakeSlotPoint.X; + targetPosition.Y1 = GlobalVar.StockSideY1; + targetPosition.Y2 = curTakeSlotPoint.Y; + double curLoadX = Ops.GetCurPosition(AxisControl.LoadX); + if (curLoadX - GlobalVar.FixtureSafePosX > 50) + { + DischargeModuleGoSafePosFlow.Instance.GoSafePostion(ESafePosSide.PlaceToStock); + } + if (GroupAxisMove.XY1Y2MovePos(targetPosition, GlobalVar.WholeSpeed)) + { + AxisPosPrint.PrintXY1Y2TargetPos("轴loadx,loady1,loady2已停止运动,", targetPosition, GetClassName()); + flowStep = EFiveProductTestFlowStep.等待到料仓拍照位上方; + } + } + } + else + { + //没有料了,判断是否需要换料 + GlobalTray.GrabTray.ChangeStatus(ESlotStatus.Have); + } + break; + case EFiveProductTestFlowStep.等待到料仓拍照位上方: + if (Ops.IsStop("LoadX", "LoadY1", "LoadY2")) + { + AxisPosPrint.PrintXY1Y2CurrentPos("轴loadx,loady1,loady2已停止运动,", GetClassName()); + if (AxisArrived.LoadXY1Y2IsArrived(targetPosition.X, targetPosition.Y1, targetPosition.Y2)) + { + AxisPosPrint.PrintXY1Y2CurrentPos("已运动到料仓拍照位上方,", GetClassName()); + flowStep = EFiveProductTestFlowStep.料仓取料拍照; + } + else + { + flowStep = EFiveProductTestFlowStep.到料仓拍照位上方; + } + } + break; + case EFiveProductTestFlowStep.料仓取料拍照: + UpCameraHelper.Grab(); + string msg = VisionHelper.OneGrabOne();//.Grab(EVisionScene.SingleScanBarcode); + vProductResult.Parse(msg); + if (vProductResult != null && (vProductResult.Result == EOneGrabSixteenResult.Ok || vProductResult.Result== EOneGrabSixteenResult.LocationOkScanBarcodeFail)) + { + flowStep = EFiveProductTestFlowStep.到料仓取料位上方; + } + else if (vProductResult != null && vProductResult.Result == EOneGrabSixteenResult.LocationOkScanBarcodeFail) + { + GrrScanFailFrm scanFail = new GrrScanFailFrm((act, qrcode) => { + if (act == 1) + { + vProductResult.SN = qrcode; + flowStep = EFiveProductTestFlowStep.到料仓取料位上方; + } + }); + scanFail.ShowDialog(); + //vProductResult.SN = VirtualBarCode.Code; + + } + else + { + alarmEntity = AlarmCollection.Get(AlarmConstID.料仓取料拍照失败); + Msgbox.ShowDialog(alarmEntity, EButtonType.Retry); + } + break; + case EFiveProductTestFlowStep.到料仓取料位上方: + //获取空闲吸嘴 + curTakeNozzle = NozzleManager.GetIdelNozzle(); + if (curTakeNozzle != null) + { + targetPosition = NozzleManager.GetToTraySlot(ETrayType.Input, curTakeSlot.Index, curTakeNozzle.NozzleIndex); + if (curTakeNozzle != null) + { + targetPosition.X += vProductResult.OffsetX + offsetX; + targetPosition.Y2 += vProductResult.OffsetY +offsetY; + if (GroupAxisMove.XY1Y2MovePos(targetPosition, GlobalVar.WholeSpeed)) + { + AxisPosPrint.PrintXY1Y2TargetPos("到料仓取料位上方,", targetPosition, GetClassName()); + flowStep = EFiveProductTestFlowStep.等待到料仓取料位上方; + } + } + } + + break; + case EFiveProductTestFlowStep.等待到料仓取料位上方: + if (Ops.IsStop("LoadX", "LoadY1", "LoadY2") || GlobalVar.VirtualAxis) + { + AxisPosPrint.PrintXY1Y2CurrentPos("轴XY1Y2已停止运动,", GetClassName()); + if (AxisArrived.LoadXY1Y2IsArrived(targetPosition.X, targetPosition.Y1, targetPosition.Y2)) + { + AxisPosPrint.PrintXY1Y2CurrentPos("已运动到等待到料仓取料位上方,", GetClassName()); + flowStep = EFiveProductTestFlowStep.到料仓取料位下方; + } + else + { + flowStep = EFiveProductTestFlowStep.到料仓取料位上方; + } + } + break; + case EFiveProductTestFlowStep.到料仓取料位下方: + targetPosition.NozzleZ = NozzleManager.GetNozzleToTrayTakeProductPos(ETrayType.Input, curTakeNozzle.NozzleIndex); + errCode = AxisControl.GetAxis($"NozzleZ{curTakeNozzle.NozzleIndex}").MovePos(targetPosition.NozzleZ, GlobalVar.WholeSpeed); + if (errCode == ErrorCode.Ok) + { + logInfo = $"{GetClassName()}到料仓取料位下方"; + MessageQueue.Instance.Insert(logInfo); + flowStep = EFiveProductTestFlowStep.等待到料仓取料位下方; + } + break; + case EFiveProductTestFlowStep.等待到料仓取料位下方: + if (Ops.IsStop($"NozzleZ{curTakeNozzle.NozzleIndex}")) + { + logInfo = $"{GetClassName()}已运动到料仓取料位下方"; + MessageQueue.Instance.Insert(logInfo); + if (GlobalVar.RunSpace) + { + flowStep = EFiveProductTestFlowStep.料仓取料完成抬起; + } + else + { + Ops.On($"吸料真空{curTakeNozzle.NozzleIndex}吸"); + Thread.Sleep(100); + flowStep = EFiveProductTestFlowStep.料仓取料完成抬起; + } + } + break; + case EFiveProductTestFlowStep.料仓取料完成抬起: + if (NozzleManager.GotoSafePos(curTakeNozzle.NozzleIndex)) + { + logInfo = $"{GetClassName()}料仓取料完成抬起"; + MessageQueue.Instance.Insert(logInfo); + flowStep = EFiveProductTestFlowStep.等待料仓取料完成抬起; + } + break; + case EFiveProductTestFlowStep.等待料仓取料完成抬起: + if (Ops.IsStop($"NozzleZ{curTakeNozzle.NozzleIndex}")) + { + logInfo = $"{GetClassName()}料仓取料完成已抬起"; + MessageQueue.Instance.Insert(logInfo); + flowStep = EFiveProductTestFlowStep.料仓取料真空吸检测; + } + break; + case EFiveProductTestFlowStep.料仓取料真空吸检测: + if (Ops.IsOn($"吸料真空{curTakeNozzle.NozzleIndex}检测") || GlobalVar.RunSpace) + { + takedNum++; + curTakeNozzle.Product = new TestProduct() { SN = "", FromSlotIndex = curTakeSlot.Index }; + curTakeNozzle.Status = ENozzleStatus.ToUnload; + GlobalTray.NozzleTray.ChangeStatus(curTakeNozzle.NozzleIndex, ESlotStatus.Have); + GlobalTray.InputTray.ChangeStatus(curTakeSlot.Index, ESlotStatus.NotHave); + logInfo = $"{GetClassName()}料仓{curTakeSlot.Index}号穴位取料完成真空检测OK,产品SN:{curTakeNozzle.Product.SN}被吸嘴{curTakeNozzle.NozzleIndex}取走"; + MessageQueue.Instance.Insert(logInfo); + flowStep = EFiveProductTestFlowStep.到料仓放料位上方; + } + else + { + alarmEntity = AlarmCollection.Get(AlarmConstID.GRR取料失败报警); + Msgbox.ShowDialog(alarmEntity, EButtonType.Retry); + flowStep = EFiveProductTestFlowStep.到料仓取料位上方; + } + break; + #endregion + + + + + //料仓放料 + + case EFiveProductTestFlowStep.到料仓放料位上方: + curDumpNozzle = NozzleManager.GetToUnloadNozzle(); + if (curDumpNozzle != null) + { + //吸嘴放料,加测吸嘴上的产品的测试结果,决定把料放到哪个料仓 + //目前先都方到OK料仓 + //curDumpSlot = GlobalTray.GrrTray.GetSlot(ESlotStatus.NotHave); + curDumpSlot = GlobalTray.OkTary.GetSlot(ESlotStatus.NotHave); + if (curDumpSlot != null) + { + double curLoadX = Ops.GetCurPosition(AxisControl.LoadX); + if (curLoadX - GlobalVar.FixtureSafePosX > 50) + { + DischargeModuleGoSafePosFlow.Instance.GoSafePostion(ESafePosSide.PlaceToStock); + } + targetPosition = NozzleManager.GetToTraySlot(ETrayType.Ok, curDumpSlot.Index, curDumpNozzle.NozzleIndex); + if (GroupAxisMove.XY1Y2MovePos(targetPosition, GlobalVar.WholeSpeed)) + { + AxisPosPrint.PrintXY1Y2TargetPos("到料仓放料位上方,", targetPosition, GetClassName()); + flowStep = EFiveProductTestFlowStep.等待到料仓放料位上方; + } + } + else + { + GlobalTray.GrrTray.ChangeStatus(ESlotStatus.NotHave); + } + } + break; + case EFiveProductTestFlowStep.等待到料仓放料位上方: + if (Ops.IsStop("LoadX", "LoadY1", "LoadY2")) + { + AxisPosPrint.PrintXY1Y2CurrentPos("轴loadx,loady1,loady2已停止运动,", GetClassName()); + if (AxisArrived.LoadXY1Y2IsArrived(targetPosition.X, targetPosition.Y1, targetPosition.Y2)) + { + AxisPosPrint.PrintXY1Y2CurrentPos("已运动到料仓放料位上方,", GetClassName()); + flowStep = EFiveProductTestFlowStep.到料仓放料位下方; + } + else + { + flowStep = EFiveProductTestFlowStep.到料仓放料位上方; + } + } + break; + case EFiveProductTestFlowStep.到料仓放料位下方: + targetPosition.NozzleZ = NozzleManager.GetNozzleToTrayTakeProductPos(ETrayType.Ok, curDumpNozzle.NozzleIndex); + if (NozzleManager.Go(curDumpNozzle, targetPosition.NozzleZ, GlobalVar.WholeSpeed)) + { + logInfo = $"{GetClassName()}到料仓放料位下方"; + MessageQueue.Instance.Insert(logInfo); + flowStep = EFiveProductTestFlowStep.等待到料仓放料位下方; + } + break; + case EFiveProductTestFlowStep.等待到料仓放料位下方: + if (Ops.IsStop($"NozzleZ{curDumpNozzle.NozzleIndex}")) + { + logInfo = $"{GetClassName()}已运动到料仓放料位下方"; + MessageQueue.Instance.Insert(logInfo); + if (GlobalVar.RunSpace) + { + flowStep = EFiveProductTestFlowStep.料仓放料完成抬起; + } + else + { + curDumpNozzle.VacSuction(EIoOperate.Close, GetClassName()); + curDumpNozzle.VacBreak(EIoOperate.Open, GetClassName()); + curDumpNozzle.VacBreak(EIoOperate.Close, GetClassName()); + flowStep = EFiveProductTestFlowStep.料仓放料完成抬起; + } + } + break; + case EFiveProductTestFlowStep.料仓放料完成抬起: + if (NozzleManager.GotoSafePos(curDumpNozzle.NozzleIndex)) + { + logInfo = $"{GetClassName()}料仓放料完成抬起"; + MessageQueue.Instance.Insert(logInfo); + flowStep = EFiveProductTestFlowStep.等待料仓放料完成抬起; + } + break; + case EFiveProductTestFlowStep.等待料仓放料完成抬起: + if (Ops.IsStop($"NozzleZ{curDumpNozzle.NozzleIndex}")) + { + + logInfo = $"{GetClassName()}料仓放料完成已抬起"; + MessageQueue.Instance.Insert(logInfo); + takedNum++; + if(takedNum<5) + { + flowStep = EFiveProductTestFlowStep.到料仓拍照位上方; + } + else + { + run = false; + } + } + break; + } + Thread.Sleep(5); + } + } + + public void Start() + { + stop = false; + } + public void Stop() + { + stop = true; + } + private string GetClassName() + { + return "GrrFlow-"; + } + + private double offsetX = 0; + private double offsetY = 0; + public void SetOffset(double x,double y) + { + offsetX = x; + offsetY = y; + } + + /// + /// 获取吸嘴取料取不起来时,吸嘴在原取料位的偏移 + /// 奇数向下偏移 + /// 偶数向上偏移 + /// + /// + /// + private double GetVacOffsetHeight(int fetchNum) + { + if (fetchNum == 0) return 0; + //先判断是奇数还是偶数 + int count = 0; + int oddOrEven = fetchNum & 0x01; + + double offsetDisct = 0.0; + if (oddOrEven == 1) + { + count = (fetchNum / 2) + 1; + offsetDisct = -0.1 * count; + } + + else if (oddOrEven == 0) + { + count = (fetchNum / 2); + offsetDisct = 0.1 * count; + } + return offsetDisct; + } + + public string GetCurStep() + { + return flowStep.ToString(); + } + + public void VirtualAxisSleep() + { + if (GlobalVar.VirtualAxis) + { + Thread.Sleep(GlobalVar.VirtualAxisMoveTime); + } + } + + + private void GotoNextFixture() + { + lastFixtureIndex = ((lastFixtureIndex + 1) % needGrrFixtureList.Count); + } + + + } +} diff --git a/Rs.DeweyTester/Rs.DeweyTester.csproj b/Rs.DeweyTester/Rs.DeweyTester.csproj index a760dc4..34bc211 100644 --- a/Rs.DeweyTester/Rs.DeweyTester.csproj +++ b/Rs.DeweyTester/Rs.DeweyTester.csproj @@ -139,6 +139,7 @@ + diff --git a/Rs.DeweyTester/TestFrm.Designer.cs b/Rs.DeweyTester/TestFrm.Designer.cs index e27b13e..4dcfd64 100644 --- a/Rs.DeweyTester/TestFrm.Designer.cs +++ b/Rs.DeweyTester/TestFrm.Designer.cs @@ -56,6 +56,11 @@ this.label1 = new System.Windows.Forms.Label(); this.textBox1 = new System.Windows.Forms.TextBox(); this.groupBox3 = new System.Windows.Forms.GroupBox(); + this.button1 = new System.Windows.Forms.Button(); + this.label3 = new System.Windows.Forms.Label(); + this.textBox2 = new System.Windows.Forms.TextBox(); + this.label4 = new System.Windows.Forms.Label(); + this.textBox3 = new System.Windows.Forms.TextBox(); this.groupBox1.SuspendLayout(); this.groupBox2.SuspendLayout(); this.groupBox3.SuspendLayout(); @@ -405,11 +410,60 @@ this.groupBox3.TabStop = false; this.groupBox3.Text = "相机"; // + // button1 + // + this.button1.Location = new System.Drawing.Point(29, 339); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(190, 68); + this.button1.TabIndex = 33; + this.button1.Text = "5个产品单拍测试"; + this.button1.UseVisualStyleBackColor = true; + this.button1.Click += new System.EventHandler(this.button1_Click_2); + // + // label3 + // + this.label3.AutoSize = true; + this.label3.ForeColor = System.Drawing.Color.White; + this.label3.Location = new System.Drawing.Point(39, 238); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(41, 12); + this.label3.TabIndex = 28; + this.label3.Text = "X偏移:"; + // + // textBox2 + // + this.textBox2.Location = new System.Drawing.Point(92, 238); + this.textBox2.Name = "textBox2"; + this.textBox2.Size = new System.Drawing.Size(100, 21); + this.textBox2.TabIndex = 34; + // + // label4 + // + this.label4.AutoSize = true; + this.label4.ForeColor = System.Drawing.Color.White; + this.label4.Location = new System.Drawing.Point(39, 285); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(41, 12); + this.label4.TabIndex = 28; + this.label4.Text = "Y偏移:"; + // + // textBox3 + // + this.textBox3.Location = new System.Drawing.Point(92, 285); + this.textBox3.Name = "textBox3"; + this.textBox3.Size = new System.Drawing.Size(100, 21); + this.textBox3.TabIndex = 34; + // // TestFrm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(1336, 854); + this.Controls.Add(this.textBox3); + this.Controls.Add(this.textBox2); + this.Controls.Add(this.label4); + this.Controls.Add(this.button1); + this.Controls.Add(this.label3); this.Controls.Add(this.groupBox3); this.Controls.Add(this.groupBox2); this.Controls.Add(this.groupBox1); @@ -421,6 +475,7 @@ this.groupBox2.PerformLayout(); this.groupBox3.ResumeLayout(false); this.ResumeLayout(false); + this.PerformLayout(); } @@ -453,5 +508,10 @@ private System.Windows.Forms.Label label1; private System.Windows.Forms.ComboBox comboBox1; private System.Windows.Forms.Label label2; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.TextBox textBox2; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.TextBox textBox3; } } \ No newline at end of file diff --git a/Rs.DeweyTester/TestFrm.cs b/Rs.DeweyTester/TestFrm.cs index 4efe484..4419b79 100644 --- a/Rs.DeweyTester/TestFrm.cs +++ b/Rs.DeweyTester/TestFrm.cs @@ -247,5 +247,10 @@ namespace Rs.MotionPlat }); } + + private void button1_Click_2(object sender, EventArgs e) + { + FiveProductTestFlow.Instance.Init(); + } } }