using Bro.Common.Base; using Bro.Common.Helper; using Bro.Common.Interface; using Bro.Common.Model; using Bro.M141.Process; using Bro.Process; using HalconDotNet; using NPOI.SS.Formula.Functions; using ScottPlot.MarkerShapes; using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Net.Sockets; using System.Runtime.CompilerServices; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using Windows.Devices.Radios; using static Bro.Common.Helper.EnumHelper; using static Org.BouncyCastle.Math.EC.ECCurve; namespace Bro.M141_AOI3B.Process { [Process("AOI3B", EnumHelper.DeviceAttributeType.Device)] public class AOI3BProcess : M141Process { #region constructor public AOI3BProcess() : base() { } public AOI3BProcess(string productCode) : base(productCode) { } #endregion ManualResetEvent _snapHandle = new ManualResetEvent(false); AOI3BConfig AOI3BConfig1 => Config as AOI3BConfig; TcpListenerWrap TcpListenerx = null; public override void Open() { base.Open(); TcpListenerx = DeviceCollection.FirstOrDefault(u => u is TcpListenerWrap) as TcpListenerWrap; //if (TcpListenerx == null) //{ // LogAsync(DateTime.Now, EnumHelper.LogLevel.Warning, $"未设置TCP监听实例"); //} } [ProcessMethod("", "PositionCheck_P1_F", "工位1检测飞拍", InvokeType.TestInvoke)] public ResponseMessage PositionCheck_P1_F(IOperationConfig config, IDevice invokeDevice, IDevice sourceDevice) { ResponseMessage msg = new ResponseMessage(); msg.Result = 1; msg.IsReply = false; trigerStr.Clear(); List measureBinds = new List(); string inputSequence = ""; try { RunImageCheckPreTreat1(config, out measureBinds, out inputSequence); } catch (Exception ex) { LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"检测预处理异常,{ex.GetExceptionMessage()}"); msg.Result = -1; msg.Message = ex.Message; msg.IsReply = true; msg.DataStr = $"1#,C,NG,NG,NOREAD,NOREAD"; return msg; } //预处理完成,拍照准备就绪 var sourceData = config.TriggerSource.Split(':'); string ip = ""; int port = 0; if (sourceData.Length >= 2) { ip = sourceData[0]; port = int.Parse(sourceData[1]); } TcpListenerx.WriteAndRead("1#,OK", out _, out _, false, ip, port); int measureNums = measureBinds.Count; bool WaitSignalstate = true; //_isLastCheckFlag = false; measureBinds.GroupBy(u => u.CameraId).AsParallel().ForAll(c => { var camera = DeviceCollection.FirstOrDefault(u => u.Id == c.Key) as CameraBase; foreach (var i in c.ToList().OrderBy(u => u.ImageIndex).ToList()) { string index = (i.ImageIndex + 1).ToString(); if (AOI3BConfig1.P1SFstate) { if (!WaitSignal(index)) { WaitSignalstate = false; break; } } var products = i.ProductIndices.Select(pi => { return FindProductBySequence($"{inputSequence}_{pi}", true); }).ToList(); IImageSet imgSet = null; try { imgSet = CollectHImage(camera, i.SnapshotOpConfig); lock (trigerStr) { trigerStr.Add(index + "over"); } if (imgSet == null) { LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"工位1{camera?.Name}取像{i?.ImageIndex}失败 图像为空"); break; } } catch (Exception ex) { LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"工位1{camera?.Name}取像{i?.ImageIndex}异常,{ex.ToString()}"); break; } RunImageCheckAsync(products, config.TriggerStr, config.TriggerSource, imgSet, i).ContinueWith(t => { Interlocked.Decrement(ref measureNums); }); } }); //bool WaitSignalstate = true; if (!WaitSignalstate) { LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"图片采集信息不全"); msg.IsReply = true; msg.DataStr = $"1#,C,NG,NG,NOREAD,NOREAD"; return msg; } while (measureNums > 0) { Thread.Sleep(50); } //检测完成后清理图片缓存 measureBinds.Select(u => u.CameraId).Distinct().ToList().ForEach(u => { var camera = DeviceCollection.FirstOrDefault(c => c.Id == u) as CameraBase; camera.ClearImageBufferQueue(); LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"{camera.Name}相机工位1检测后清理缓存"); }); string positionName = measureBinds[0].WorkPosition; var pList = CheckPositionDoneAsync1(positionName, inputSequence, config, new List()).GetAwaiter().GetResult(); return msg; } public bool WaitSignal(string index, string p = "p1") { DateTime dt = DateTime.Now; while ((DateTime.Now - dt).TotalMilliseconds < AOI3BConfig1.PhotolayoutTime) { if (p.Equals("p1")) { lock (trigerStr) { if (trigerStr.Contains(index)) { return true; } } } else { lock (trigerStr2) { if (trigerStr2.Contains(index)) { return true; } } } Thread.Sleep(50); } return false; } List trigerStr = new List(); [ProcessMethod("", "PositionCheck_P1_photo", "工位1拍照", InvokeType.TestInvoke)] public ResponseMessage PositionCheck_P1_photo(IOperationConfig config, IDevice invokeDevice, IDevice sourceDevice) { ResponseMessage msg = new ResponseMessage(); msg.IsReply = false; string index = config.TriggerStr.Split(",")[config.TriggerStr.Split(",").Length - 1]; lock (trigerStr) { trigerStr.Add(index); } msg.DataStr = config.TriggerStr + ",OK"; var sourceData = config.TriggerSource.Split(':'); string ip = ""; int port = 0; if (sourceData.Length >= 2) { ip = sourceData[0]; port = int.Parse(sourceData[1]); } WaitSignal(index + "over"); TcpListenerx.WriteAndRead(config.TriggerStr + ",OK", out _, out _, false, ip, port); return msg; } [ProcessMethod("ImageCheck", "GetProductBarcode_P1", "工位1获取产品条码", InvokeType.TestInvoke)] public ResponseMessage GetProductBarcode_P1(IOperationConfig config, IDevice invokeDevice, IDevice sourceDevice) { ResponseMessage msg = new ResponseMessage(); if (config is IImageCheckOperationConfig opConfig) { var results = opConfig.Products.Select(u => { DetectResult result = new DetectResult(); result.PID = u.PID; result.Specs = GetSpecListFromConfigSelection(opConfig.SpecCollection); return result; }).ToList(); msg.DataObj = results; var tool = GetHalconTool(null, "", opConfig.AlgorithemPath); var ret = tool.RunProcedure(null, new Dictionary() { { "INPUT_Image", opConfig.ImageSet.HImage } }, new List() { "OUTPUT_Flag", "OUTPUT_Results", "OUTPUT_Barcode" }); if (!ret.Item1 || ret.Item2["OUTPUT_Flag"].I != 1) { LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"工位1条码检测工具运行失败,{ret.Item4}"); msg.Result = -1; return msg; } FillSpecResults(results[0].PID, results[0].Specs, ret.Item2["OUTPUT_Results"].HTupleToDouble(), opConfig.Products[0].SEQUENCE); //var barcodeSpec = results[0].Specs.FirstOrDefault(u => u.Code == AOI2Config.BarcodeSpecCode); string barcode = ret.Item2["OUTPUT_Barcode"].S; opConfig.Products[0].SN = barcode; opConfig.Products[0].Details.ForEach(u => u.SN = barcode); LogAsync(DateTime.Now, EnumHelper.LogLevel.Action, $"产品{opConfig.Products[0].PID}条码获取为{barcode}"); UpdateProductSNIntoDB(opConfig.Products[0].PID, barcode); } else { LogAsync(DateTime.Now, EnumHelper.LogLevel.Error, $"产品条码获取失败1"); } return msg; } [ProcessMethod("", "PositionCheck_P2", "工位2检测", InvokeType.TestInvoke)] public ResponseMessage PositionCheck_P2(IOperationConfig config, IDevice invokeDevice, IDevice sourceDevice) { ResponseMessage msg = RunImageCheck(config); msg.IsReply = false; if (msg.Result != 1) { msg.IsReply = true; msg.DataStr = "2#,C,NG,NG,NOREAD,NOREAD"; } return msg; } List trigerStr2 = new List(); [ProcessMethod("", "PositionCheck_P2_F", "工位2检测飞拍", InvokeType.TestInvoke)] public ResponseMessage PositionCheck_P2_F(IOperationConfig config, IDevice invokeDevice, IDevice sourceDevice) { ResponseMessage msg = new ResponseMessage(); msg.Result = 1; msg.IsReply = false; trigerStr2.Clear(); P2data.Clear(); List measureBinds = new List(); string inputSequence = ""; try { RunImageCheckPreTreat1(config, out measureBinds, out inputSequence); } catch (Exception ex) { LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"检测预处理异常,{ex.GetExceptionMessage()}"); msg.Result = -1; msg.Message = ex.Message; msg.IsReply = true; msg.DataStr = $"2#,NG"; return msg; } //预处理完成,拍照准备就绪 var sourceData = config.TriggerSource.Split(':'); string ip = ""; int port = 0; if (sourceData.Length >= 2) { ip = sourceData[0]; port = int.Parse(sourceData[1]); } TcpListenerx.WriteAndRead("2#,OK", out _, out _, false, ip, port); int measureNums = measureBinds.Count; bool WaitSignalstate = true; //_isLastCheckFlag = false; measureBinds.GroupBy(u => u.CameraId).AsParallel().ForAll(c => { var camera = DeviceCollection.FirstOrDefault(u => u.Id == c.Key) as CameraBase; foreach (var i in c.ToList().OrderBy(u => u.ImageIndex).ToList()) { string index = (i.ImageIndex + 1).ToString(); if (AOI3BConfig1.P2SFstate) { if (!WaitSignal(index, "p2")) { WaitSignalstate = false; break; } } var products = i.ProductIndices.Select(pi => { return FindProductBySequence($"{inputSequence}_{pi}", true); }).ToList(); IImageSet imgSet = null; try { imgSet = CollectHImage(camera, i.SnapshotOpConfig); lock (trigerStr2) { trigerStr2.Add(index + "over"); } } catch (Exception ex) { LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"工位2{camera.Name}取像{i.ImageIndex}异常,{ex.GetExceptionMessage()}"); } RunImageCheckAsyncForSB(products, config.TriggerStr, config.TriggerSource, imgSet, i).ContinueWith(t => { Interlocked.Decrement(ref measureNums); }); } }); //bool WaitSignalstate = true; if (!WaitSignalstate) { LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"图片采集信息不全"); msg.IsReply = true; msg.DataStr = $"2#,C,NG,NG,NOREAD,NOREAD"; return msg; } while (measureNums > 0) { Thread.Sleep(50); } //if (_isLastCheckFlag) //{ // LogAsync(DateTime.Now, EnumHelper.LogLevel.Error, $"当前流程已过期,退出检测,不执行反馈"); // msg.IsReply = false; // return msg; //} //检测完成后清理图片缓存 measureBinds.Select(u => u.CameraId).Distinct().ToList().ForEach(u => { var camera = DeviceCollection.FirstOrDefault(c => c.Id == u) as CameraBase; camera.ClearImageBufferQueue(); LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"{camera.Name}相机工位2检测后清理缓存"); }); string positionName = measureBinds[0].WorkPosition; var pList = CheckPositionDoneAsyncforsb(positionName, inputSequence, config, new List()).GetAwaiter().GetResult(); return msg; } [ProcessMethod("", "PositionCheck_P2_photo", "工位2拍照", InvokeType.TestInvoke)] public ResponseMessage PositionCheck_P2_photo(IOperationConfig config, IDevice invokeDevice, IDevice sourceDevice) { ResponseMessage msg = new ResponseMessage(); msg.IsReply = false; string index = config.TriggerStr.Split(",")[config.TriggerStr.Split(",").Length - 1]; lock (trigerStr2) { trigerStr2.Add(index); } msg.DataStr = config.TriggerStr + ",OK"; var sourceData = config.TriggerSource.Split(':'); string ip = ""; int port = 0; if (sourceData.Length >= 2) { ip = sourceData[0]; port = int.Parse(sourceData[1]); } WaitSignal(index + "over", "p2"); Thread.Sleep(300); TcpListenerx.WriteAndRead(config.TriggerStr + ",OK", out _, out _, false, ip, port); return msg; } [ProcessMethod("ImageCheck", "PositionCheck_P0", "工位0引导", InvokeType.TestInvoke)] public ResponseMessage PositionCheck_P0(IOperationConfig config, IDevice invokeDevice, IDevice sourceDevice) { ResponseMessage msg = new ResponseMessage(); msg.IsReply = true; msg.DataStr = "0#,NG,0,0,0,0,0,0"; if (config is IImageCheckOperationConfig opConfig) { if (string.IsNullOrEmpty(opConfig.AlgorithemPath)) { LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"P0标定配置异常,请检查配置"); } else { var camera = invokeDevice as CameraBase; if (camera == null) { LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"P0配置相机为空,请检查配置"); msg.DataStr = ""; return msg; } IImageSet imgSet = null; try { imgSet = CollectHImage(camera, AOI3BConfig1.P0SnapshotOpConfig); } catch (Exception ex) { LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"工位0取像异常,{ex.GetExceptionMessage()}"); return msg; } var tool = GetHalconTool(null, "", opConfig.AlgorithemPath); Tuple, Dictionary, string, int> ret = null; ret = tool.RunProcedure(new Dictionary() { { "INPUT_BiaodingTupe", AOI3BConfig1.BDBD.ToArray() }, { "INPUT_xxzx", AOI3BConfig1.BDYX.ToArray() }, { "INPUT_muban", AOI3BConfig1.BDMD.ToArray() } }, new Dictionary() { { "INPUT_Image", imgSet.HImage } }, new List() { "OUTPUT_Results_1", "OUTPUT_Results_2" }, null); if (!ret.Item1) { LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"脚本{opConfig.AlgorithemPath}运行异常,{ret.Item4}"); msg.DataStr = "0#,NG,0,0,0,0,0,0"; } else { var datas = ret.Item2[$"OUTPUT_Results_1"].HTupleToDouble(); msg.DataStr = "0#,OK"; LogAsync(DateTime.Now, EnumHelper.LogLevel.Detail, $"引导坐标脚本输出数据 {string.Join(",", datas)}"); if (datas != null && datas.Count == 6) { datas[0] += AOI3BConfig1.CompensateValueBD.X1; datas[1] += AOI3BConfig1.CompensateValueBD.Y1; datas[2] += AOI3BConfig1.CompensateValueBD.Z1; datas[3] += AOI3BConfig1.CompensateValueBD.X2; datas[4] += AOI3BConfig1.CompensateValueBD.Y2; datas[5] += AOI3BConfig1.CompensateValueBD.Z2; for (int i = 0; i < datas.Count; i++) { msg.DataStr += $",{datas[i]}"; } } LogAsync(DateTime.Now, EnumHelper.LogLevel.Detail, $"引导坐标脚本补偿后数据数据 {string.Join(",", datas)}"); } } } return msg; } [ProcessMethod("", "PositionCheck_P0_SN", "工位0检测", InvokeType.TestInvoke)] public ResponseMessage PositionCheck_P0_SN(IOperationConfig config, IDevice invokeDevice, IDevice sourceDevice) { ResponseMessage msg = RunImageCheck1(config); msg.IsReply = false; if (msg.Result != 1) { msg.IsReply = true; msg.DataStr = "0#,2,NG,NOREAD,NOREAD"; } return msg; } Dictionary> P2data = new Dictionary>(); //Dictionary> P2data2 = new Dictionary>(); [ProcessMethod("ImageCheck", "ImageCheckOperationP2out", "数据输出", InvokeType.TestInvoke)] public ResponseMessage ImageCheckOperationP2out(IOperationConfig config, IDevice invokeDevice, IDevice sourceDevice) { ResponseMessage msg = new ResponseMessage(); if (config is IImageCheckOperationConfig opConfig) { var results = opConfig.Products.Select(u => { DetectResult result = new DetectResult(); result.PID = u.PID; result.Specs = GetSpecListFromConfigSelection(opConfig.SpecCollection); return result; }).ToList(); msg.DataObj = results; var tool = GetHalconTool(null, "", opConfig.AlgorithemPath); Tuple, Dictionary, string, int> ret = null; ret = tool.RunProcedure(null, new Dictionary() { { "INPUT_Image", opConfig.ImageSet.HImage } }, new List() { "OUTPUT_Results_1", "OUTPUT_Results_2", "OUTPUT_TransmitData" }, null); //var ret = tool.RunProcedure(null, new Dictionary() { { "INPUT_Image", opConfig.ImageSet.HImage } }, new List() { "OUTPUT_Results_1", "OUTPUT_Results_2" }, null); if (!ret.Item1) { LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"脚本{opConfig.AlgorithemPath}运行异常,{ret.Item4}"); } else { //if (opConfig.Outindex==1) //{ // P2data1.Clear(); //} opConfig.Products.ForEach(p => { var pResult = results.FirstOrDefault(u => u.PID == p.PID); string i = p.SEQUENCE[p.SEQUENCE.Length - 1].ToString(); //var datas = ret.Item2[$"OUTPUT_Results_{i}"].HTupleToDouble(); var Tdatas = ret.Item2["OUTPUT_TransmitData"].HTupleToDouble(); ///*if*/ (i == "1") //{ lock (P2data) { P2data[opConfig.Outindex] = Tdatas; } //} //else //{ // P2data2[opConfig.Outindex] = Tdatas; //} LogAsync(DateTime.Now, EnumHelper.LogLevel.Detail, $"数据交互输出产品{i}序号{opConfig.Outindex} {string.Join(",", Tdatas)}"); //if (pResult != null && datas.Count > 0) //{ // FillSpecResults(pResult.PID, pResult.Specs, datas, p.SEQUENCE); //} }); } } return msg; } [ProcessMethod("ImageCheck", "ImageCheckOperationP2in", "数据输入,二次进算法", InvokeType.TestInvoke)] public ResponseMessage ImageCheckOperationP2in(IOperationConfig config, IDevice invokeDevice, IDevice sourceDevice) { ResponseMessage msg = new ResponseMessage(); if (config is IImageCheckOperationConfig opConfig) { try { var results = opConfig.Products.Select(u => { DetectResult result = new DetectResult(); result.PID = u.PID; result.Specs = GetSpecListFromConfigSelection(opConfig.SpecCollection); return result; }).ToList(); msg.DataObj = results; var tool = GetHalconTool(null, "", opConfig.AlgorithemPath); Tuple, Dictionary, string, int> ret = null; List tem = new List(); DateTime dt = DateTime.Now; while ((DateTime.Now - dt).TotalMilliseconds < AOI3BConfig1.PhotolayoutTime) { lock (P2data) { if (P2data.Count >= opConfig.Outindex) { break; } } Thread.Sleep(5); } lock (P2data) { P2data.OrderBy(u => u.Key).ToList().ForEach(x => { tem.AddRange(x.Value); tem.Add(-998); }); tem.RemoveAt(tem.Count - 1); LogAsync(DateTime.Now, EnumHelper.LogLevel.Detail, $"二次进算法输入数据in {string.Join(",", tem)}"); ret = tool.RunProcedure(new Dictionary() { { "INPUT_TransmitData", tem.ToArray() } }, null, new List() { "OUTPUT_Results_1", "OUTPUT_Results_2" }, null); P2data.Clear(); P2data = new Dictionary>(); } if (!ret.Item1) { LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"脚本{opConfig.AlgorithemPath}运行异常,{ret.Item4}"); } else { opConfig.Products.ForEach(p => { var pResult = results.FirstOrDefault(u => u.PID == p.PID); string i = p.SEQUENCE[p.SEQUENCE.Length - 1].ToString(); var datas = ret.Item2[$"OUTPUT_Results_{i}"].HTupleToDouble(); LogAsync(DateTime.Now, EnumHelper.LogLevel.Detail, $"二次进算法输出数据out {string.Join(",", datas)}"); if (pResult != null && datas.Count > 0) { FillSpecResults(pResult.PID, pResult.Specs, datas, p.SEQUENCE); } }); } } catch (Exception ee) { LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"二次进算法异常 {ee.ToString()}"); } } return msg; } [ProcessMethod("ImageCheck", "PositionCheck_P0BD", "工位0检测标定", InvokeType.CalibInvoke)] public ResponseMessage PositionCheck_P0BD(IOperationConfig config, IDevice invokeDevice, IDevice sourceDevice) { ResponseMessage msg = new ResponseMessage(); msg.IsReply = false; string trg = config.TriggerStr; if (!config.TriggerStr.ToLower().Contains("start")) { return msg; } xList = new List(); yList = new List(); uList = new List(); vList = new List(); BDphoto.Clear(); if (config.TriggerStr.Split(',')[1] == "1") { msg = PositionCheck_P0BD1(config, invokeDevice, sourceDevice); } else { msg = PositionCheck_P0BD2(config, invokeDevice, sourceDevice); } if (msg.DataStr.Contains("OK")) { msg.DataStr = trg + ",OK"; } else { msg.DataStr = trg + ",NG"; } return msg; } [ProcessMethod("", "PositionCheck_P0BD_photo", "工位0检测标定拍照", InvokeType.TestInvoke)] public ResponseMessage PositionCheck_P0BD_photo(IOperationConfig config, IDevice invokeDevice, IDevice sourceDevice) { ResponseMessage msg = new ResponseMessage(); msg.IsReply = false; if (config.TriggerStr.ToLower().Contains("start")) { return msg; } string index = config.TriggerStr.Split(",")[2]; lock (BDphoto) { BDphoto.Add(index); } uList.Add(Convert.ToDouble(config.TriggerStr.Split(",")[3]) / 1000); vList.Add(Convert.ToDouble(config.TriggerStr.Split(",")[4]) / 1000); var sourceData = config.TriggerSource.Split(':'); string ip = ""; int port = 0; if (sourceData.Length >= 2) { ip = sourceData[0]; port = int.Parse(sourceData[1]); } waitBD(index + "over"); TcpListenerx.WriteAndRead(config.TriggerStr + ",OK", out _, out _, false, ip, port); return msg; } [ProcessMethod("ImageCheck", "GetProductBarcode_P0", "工位0获取产品条码", InvokeType.TestInvoke)] public ResponseMessage GetProductBarcode_P0(IOperationConfig config, IDevice invokeDevice, IDevice sourceDevice) { ResponseMessage msg = new ResponseMessage(); if (config is IImageCheckOperationConfig opConfig) { try { var results = opConfig.Products.Select(u => { DetectResult result = new DetectResult(); result.PID = u.PID; result.Specs = GetSpecListFromConfigSelection(opConfig.SpecCollection); return result; }).ToList(); msg.DataObj = results; var tool = GetHalconTool(null, "", opConfig.AlgorithemPath); var ret = tool.RunProcedure(null, new Dictionary() { { "INPUT_Image", opConfig.ImageSet.HImage } }, new List() { "OUTPUT_Flag", "OUTPUT_Results", "OUTPUT_Barcode" }); if (!ret.Item1 || ret.Item2["OUTPUT_Flag"].I != 1) { LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"工位0条码检测工具运行失败,{ret.Item4}"); msg.Result = -1; return msg; } string barcode = ret.Item2["OUTPUT_Barcode"].S; LogAsync(DateTime.Now, EnumHelper.LogLevel.Action, $"条码获取为{barcode}"); string barcode1 = barcode.Split(',')[0]; string barcode2 = barcode.Split(',')[1]; if (barcode.Contains("NOREAD")) { msg.Result = -1; msg.Message = "条码读取失败"; } opConfig.Products[0].SN = barcode1; opConfig.Products[0].Details.ForEach(u => u.SN = barcode1); UpdateProductSNIntoDB(opConfig.Products[0].PID, barcode1); opConfig.Products[1].SN = barcode2; opConfig.Products[1].Details.ForEach(u => u.SN = barcode2); UpdateProductSNIntoDB(opConfig.Products[1].PID, barcode2); } catch (Exception e) { msg.Result = -1; LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"条码异常 {e.ToString()}"); } } return msg; } List xList = new List(); List yList = new List(); List uList = new List(); List vList = new List(); List BDphoto = new List(); object bdobject = new object(); public bool waitBD(string index) { DateTime dt = DateTime.Now; while ((DateTime.Now - dt).TotalMilliseconds < AOI3BConfig1.PhotolayoutTime) { lock (BDphoto) { if (BDphoto.Contains(index)) { return true; } } Thread.Sleep(10); } return false; } public ResponseMessage PositionCheck_P0BD1(IOperationConfig config, IDevice invokeDevice, IDevice sourceDevice) { bool issave = true; ResponseMessage msg = new ResponseMessage(); if (config is IImageCheckOperationConfig opConfig) { var camera = invokeDevice as CameraBase; if (camera == null) { LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"P0配置相机为空,请检查配置"); msg.DataStr = ""; return msg; } for (int i = 0; i < 9; i++) { if (!waitBD((i + 1).ToString())) { issave = false; break; } IImageSet imgSet = null; try { imgSet = CollectHImage(camera, AOI3BConfig1.P0SnapshotOpConfig); } catch (Exception ex) { LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"工位0检测标定1取像异常,{ex.GetExceptionMessage()}"); return msg; } var tool = GetHalconTool(null, "", opConfig.AlgorithemPath); Tuple, Dictionary, string, int> ret = null; ret = tool.RunProcedure(null, new Dictionary() { { "INPUT_Image", imgSet.HImage } }, new List() { "OUTPUT_Results", }, null); if (!ret.Item1) { issave = false; break; LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"脚本{opConfig.AlgorithemPath}运行异常,{ret.Item4}"); } else { var datas = ret.Item2[$"OUTPUT_Results"].HTupleToDouble(); if (datas == null || datas.Contains(-999) || datas.Count < 2) { issave = false; break; } xList.Add(datas[0]); yList.Add(datas[1]); LogAsync(DateTime.Now, EnumHelper.LogLevel.Detail, $"工位0检测标定1 序号{(i + 1).ToString()}输出数据{string.Join(",", datas)}"); } lock (BDphoto) { BDphoto.Add((i + 1).ToString() + "over"); } } if (xList.Count == 9 && yList.Count == 9 && uList.Count == 9 && vList.Count == 9) { //HOperatorSet.VectorToHomMat2d(new HTuple(uList.ToArray()), new HTuple(vList.ToArray()), new HTuple(xList.ToArray()), new HTuple(yList.ToArray()), out HTuple matrix); HOperatorSet.VectorToHomMat2d(new HTuple(xList.ToArray()), new HTuple(yList.ToArray()), new HTuple(uList.ToArray()), new HTuple(vList.ToArray()), out HTuple matrix); double sum = 0; for (int i = 0; i < xList.Count; i++) { HOperatorSet.AffineTransPoint2d(matrix, uList[i], vList[i], out HTuple m, out HTuple n); sum += Math.Sqrt((Math.Pow((m.D - xList[i]), 2) + Math.Pow((n.D - yList[i]), 2))); } sum = (sum / (double)xList.Count); var Matrix = matrix.HTupleToDouble(); AOI3BConfig1.BDBD = Matrix; LogAsync(DateTime.Now, EnumHelper.LogLevel.Detail, $"标定1结果OK,数据:{string.Join(",", Matrix)}; 标定点数量:{xList.Count}; 单点误差:{sum.ToString()}脉冲"); //msg.IsReply = true; //msg.DataStr = config.TriggerStr + ",OK"; } else { issave = false; msg.IsReply = false; LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"标定1失败,数据缺失"); } for (int i = 9; i < 12; i++) { if (!waitBD((i + 1).ToString())) { issave = false; break; } IImageSet imgSet = null; try { imgSet = CollectHImage(camera, AOI3BConfig1.P0SnapshotOpConfig); } catch (Exception ex) { LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"工位0检测标定1取像异常,{ex.GetExceptionMessage()}"); return msg; } var tool = GetHalconTool(null, "", opConfig.AlgorithemPath); Tuple, Dictionary, string, int> ret = null; ret = tool.RunProcedure(null, new Dictionary() { { "INPUT_Image", imgSet.HImage } }, new List() { "OUTPUT_Results", }, null); if (!ret.Item1) { issave = false; break; LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"脚本{opConfig.AlgorithemPath}运行异常,{ret.Item4}"); } else { var datas = ret.Item2[$"OUTPUT_Results"].HTupleToDouble(); if (datas == null || datas.Contains(-999) || datas.Count < 2) { issave = false; break; } xList.Add(datas[0]); yList.Add(datas[1]); LogAsync(DateTime.Now, EnumHelper.LogLevel.Detail, $"工位0检测标定2 序号{(i + 1).ToString()}输出数据{string.Join(",", datas)}"); } lock (BDphoto) { BDphoto.Add((i + 1).ToString() + "over"); } } if (xList.Count == 12 && yList.Count == 12 && uList.Count == 12 && vList.Count == 12) { List xList2 = new List() { xList[9], xList[10], xList[11] }; List yList2 = new List() { yList[9], yList[10], yList[11] }; //HOperatorSet.AffineTransPoint2d(new HTuple(AOI3BConfig1.BDBD.ToArray()), new HTuple(xList2.ToArray()), new HTuple(yList2.ToArray()), out HTuple qx, out HTuple qy); ////HOperatorSet.GenRegionPolygon(out HObject Region, new HTuple(xList2.ToArray()), new HTuple(yList2.ToArray())); //HOperatorSet.GenRegionPolygon(out HObject Region, qx, qy); //HOperatorSet.GenContourRegionXld(Region, out HObject Contours, "border"); //HOperatorSet.FitCircleContourXld(Contours, "algebraic", -1, 0, 0, 3, 2, out HTuple Row, out HTuple column, out HTuple Radius, out HTuple StartPhi, out HTuple EndPhi, out HTuple PointOrder); HOperatorSet.AffineTransPoint2d(new HTuple(AOI3BConfig1.BDBD.ToArray()), new HTuple(xList2.ToArray()), new HTuple(yList2.ToArray()), out HTuple qx, out HTuple qy); HOperatorSet.GenContourPolygonXld(out HObject Region, qx, qy); HOperatorSet.FitCircleContourXld(Region, "algebraic", -1, 0, 0, 3, 2, out HTuple Row, out HTuple column, out HTuple Radius, out HTuple StartPhi, out HTuple EndPhi, out HTuple PointOrder); LogAsync(DateTime.Now, EnumHelper.LogLevel.Detail, $"标定2结果OK :X轴{Row.D},Y轴{column.D}"); AOI3BConfig1.BDYX = new List() { Row.D, column.D }; //SaveProcessConfig(AOI3BConfig1); //msg.IsReply = true; //msg.DataStr = config.TriggerStr + ",OK"; } else { issave = false; msg.IsReply = false; LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"标定失败,数据缺失"); } if (issave) { SaveProcessConfig(AOI3BConfig1); msg.IsReply = true; msg.DataStr = config.TriggerStr + ",OK"; } else { msg.IsReply = true; msg.DataStr = config.TriggerStr + ",NG"; } } return msg; } public ResponseMessage PositionCheck_P0BD2(IOperationConfig config, IDevice invokeDevice, IDevice sourceDevice) { ResponseMessage msg = new ResponseMessage(); if (config is IImageCheckOperationConfig opConfig) { var camera = invokeDevice as CameraBase; if (camera == null) { LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"P0配置相机为空,请检查配置"); msg.DataStr = ""; return msg; } for (int i = 12; i < 13; i++) { if (!waitBD((i + 1).ToString())) { break; } IImageSet imgSet = null; try { imgSet = CollectHImage(camera, AOI3BConfig1.P0SnapshotOpConfig); } catch (Exception ex) { LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"工位0检测标定2取像异常,{ex.GetExceptionMessage()}"); return msg; } //INPUT_Tuple var tool = GetHalconTool(null, "", AOI3BConfig1.BD2AlgorithemPath); Tuple, Dictionary, string, int> ret = null; ret = tool.RunProcedure(new Dictionary() { { "INPUT_Tuple", AOI3BConfig1.BDBD.ToArray() } }, new Dictionary() { { "INPUT_Image", imgSet.HImage } }, new List() { "OUTPUT_Results_1", "OUTPUT_Results_2" }, null); if (!ret.Item1) { msg.IsReply = true; msg.DataStr = config.TriggerStr + ",NG"; LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"脚本{opConfig.AlgorithemPath}运行异常,{ret.Item4}"); } else { var datas = ret.Item2[$"OUTPUT_Results_2"].HTupleToDouble(); AOI3BConfig1.BDMD = datas; LogAsync(DateTime.Now, EnumHelper.LogLevel.Detail, $"工位0检测标定2 序号{(i + 1).ToString()}输出数据{string.Join(",", datas)}"); msg.IsReply = true; msg.DataStr = config.TriggerStr + ",OK"; SaveProcessConfig(AOI3BConfig1); } lock (BDphoto) { BDphoto.Add((i + 1).ToString() + "over"); } } } return msg; } } }