using Bro.Common.Base; using Bro.Common.Helper; using Bro.Common.Interface; using Bro.Common.Model; using Bro.M135.Common; using Bro.M141.Process; using Bro.UI.Model.Winform; using HalconDotNet; using Newtonsoft.Json; using NPOI.POIFS.Crypt.Dsig; using NPOI.SS.Formula.Functions; using NPOI.XSSF.Streaming.Values; using System.Collections.Concurrent; using System.Net.Sockets; using System.Text.RegularExpressions; using static Bro.Common.Helper.EnumHelper; using static NPOI.HSSF.Util.HSSFColor; using static Org.BouncyCastle.Crypto.Engines.SM2Engine; using static Org.BouncyCastle.Math.EC.ECCurve; using static ScottPlot.Plottable.PopulationPlot; namespace Bro.M141_AOI1.Process { [Process("AOI1", EnumHelper.DeviceAttributeType.Device)] public class AOI1Process : M141Process { #region constructor public AOI1Process() : base() { } public AOI1Process(string productCode) : base(productCode) { } #endregion AOI1Config ConfigAOI1 => Config as AOI1Config; public override void Open() { //string configPath = @"C:\Users\30263\Desktop\666.txt"; //string _configBackupStr = ""; //using (StreamReader reader = new StreamReader(configPath, System.Text.Encoding.UTF8)) //{ // _configBackupStr = reader.ReadToEnd(); //} //ProductModel p = JsonConvert.DeserializeObject(_configBackupStr, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All }); base.Open(); } [ProcessMethod("", "PositionCheck_P1", "工位1检测", InvokeType.TestInvoke)] public ResponseMessage PositionCheck_P1(IOperationConfig config, IDevice invokeDevice, IDevice sourceDevice) { var positionSet = M141Config.WorkPositionCollection.Where(u => u.IsEnabled).FirstOrDefault(u => u.TriggerValue == "1#"); if (positionSet == null) { throw new ProcessException($"P1检测未能获取对应的可用工位信息"); } var plcnum = Plc1.Read(positionSet.plcnum, 1, out _); config.TriggerStr = "1#,1,Str," + plcnum[0]; ResponseMessage msg = RunImageCheck_plc(config); msg.IsReply = false; return msg; } [ProcessMethod("", "PositionCheck_P2", "工位2检测", InvokeType.TestInvoke)] public ResponseMessage PositionCheck_P2(IOperationConfig config, IDevice invokeDevice, IDevice sourceDevice) { var positionSet = M141Config.WorkPositionCollection.Where(u => u.IsEnabled).FirstOrDefault(u => u.TriggerValue == "2#"); if (positionSet == null) { throw new ProcessException($"P2检测未能获取对应的可用工位信息"); } var plcnum = Plc1.Read(positionSet.plcnum, 1, out _); config.TriggerStr = "2#,1,Str," + plcnum[0]; ResponseMessage msg = RunImageCheck_plc(config); msg.IsReply = false; return msg; } [ProcessMethod("", "PositionCheck_P3", "工位3检测", InvokeType.TestInvoke)] public ResponseMessage PositionCheck_P3(IOperationConfig config, IDevice invokeDevice, IDevice sourceDevice) { var positionSet = M141Config.WorkPositionCollection.Where(u => u.IsEnabled).FirstOrDefault(u => u.TriggerValue == "3#"); if (positionSet == null) { throw new ProcessException($"P3检测未能获取对应的可用工位信息"); } var plcnum = Plc1.Read(positionSet.plcnum, 1, out _); config.TriggerStr = "3#,1,Str," + plcnum[0]; ResponseMessage msg = RunImageCheck_plc(config); msg.IsReply = false; return msg; } [ProcessMethod("ImageCheck", "ReadBarcode", "读码", InvokeType.TestInvoke)] public ResponseMessage ReadBarcode(IOperationConfig config, IDevice invokeDevice, IDevice sourceDevice) { ResponseMessage msg = new ResponseMessage(); if (config is IImageCheckOperationConfig opConfig) { if (invokeDevice is TcpClientWrapBase BarcodeScanner) { 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; string barcode = BarcodeScannerCommunicate(BarcodeScanner); List ret = new List(); if ("NOREAD".Equals(barcode.ToUpper())) { ret.Add(999); } else { ret.Add(1); } FillSpecResults(results[0].PID, results[0].Specs, ret, opConfig.Products[0].SEQUENCE); 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}"); } } return msg; } [ProcessMethod("ImageCheck", "ReadBarcode2", "读栏具码", InvokeType.TestInvoke)] public ResponseMessage ReadBarcode2(IOperationConfig config, IDevice invokeDevice, IDevice sourceDevice) { ResponseMessage msg = new ResponseMessage(); if (invokeDevice is TcpClientWrapBase BarcodeScanner2) { string barcode = BarcodeScannerCommunicate(BarcodeScanner2); if (string.IsNullOrEmpty(barcode) || "noread".Equals(barcode.ToLower())) { LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"栏具码获取失败"); Plc1.WriteSingleAddress(1524, 2, out _); Plc1.WriteSingleAddress(1514, 1, out _); } else { Plc1.WriteSingleAddress(1524, 1, out _); Plc1.WriteSingleAddress(1514, 1, out _); ConfigAOI1.basketcode = barcode; LogAsync(DateTime.Now, EnumHelper.LogLevel.Action, $"获取到栏具码为{barcode}"); } } return msg; } private string BarcodeScannerCommunicate(TcpClientWrapBase client) { string barcode = ""; for (int i = 0; i < 3; i++) { if (client.WriteAndRead("start", out string error, out barcode, true)) { barcode = barcode.Trim(' ', '\r', '\n'); if (CheckBarcodeValid(barcode)) { LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"{client.Name}扫码完成,反馈{barcode}"); return barcode; } else { LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"{client.Name}第{i + 1}扫码完成,反馈{barcode},不是合法条码"); Thread.Sleep(200); } } else { LogAsync(DateTime.Now, EnumHelper.LogLevel.Error, $"{client.Name}扫码失败,{error}"); break; } } return "NOREAD"; } private bool CheckBarcodeValid(string barcode) { bool isBarcodeValid = true; if (string.IsNullOrWhiteSpace(barcode) || barcode == "NA" || barcode == "NoRead") { isBarcodeValid = false; } return isBarcodeValid; } [ProcessMethod("ImageCheck", "CheckLineProfile", "检测产品线轮廓度", InvokeType.TestInvoke)] public ResponseMessage CheckLineProfile(IOperationConfig config, IDevice invokeDevice, IDevice sourceDevice) { ResponseMessage msg = new ResponseMessage(); try { 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(); List CheckPointList = GetPointListFromConfigSelection(opConfig.CheckPointList); msg.DataObj = results; CheckPointList = CheckPointList.OrderBy(u => u.index).ToList(); List pointdataF = new List(); foreach (var item in CheckPointList) { pointdataF.Add(item.X); pointdataF.Add(item.Y); } LogAsync(DateTime.Now, EnumHelper.LogLevel.Detail, $"检测产品线轮廓度输入点数据 {string.Join(',', pointdataF)}"); var tool = GetHalconTool(null, "", opConfig.AlgorithemPath); var ret = tool.RunProcedure(new Dictionary() { { "INPUT_Points", pointdataF.ToArray() } }, new Dictionary() { { "INPUT_Image", opConfig.ImageSet.HImage } }, new List() { "OUTPUT_Results", "OUTPUT_PointZ" }, null); if (ret == null) { LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"脚本{opConfig.AlgorithemPath}运行异常,返回值为null"); } else if (!ret.Item1) { LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"脚本{opConfig.AlgorithemPath}运行异常,{ret.Item4}"); } else { //List datasX = ret.Item2["OUTPUT_PointX"].HTupleToDouble(); //List datasY = ret.Item2["OUTPUT_PointY"].HTupleToDouble(); List datasZ = ret.Item2["OUTPUT_PointZ"].HTupleToDouble(); //LogAsync(DateTime.Now, EnumHelper.LogLevel.Detail, $"{results[0].PID}获取数据OUTPUT_PointX {string.Join(",", datasX.Select(u => u.ToString("f4")))}"); //LogAsync(DateTime.Now, EnumHelper.LogLevel.Detail, $"{results[0].PID}获取数据OUTPUT_PointY {string.Join(",", datasY.Select(u => u.ToString("f4")))}"); LogAsync(DateTime.Now, EnumHelper.LogLevel.Detail, $"{results[0].PID}获取数据OUTPUT_PointZ {string.Join(",", datasZ.Select(u => u.ToString("f4")))}"); if (datasZ.Count == CheckPointList.Count) { string Postion = "P" + opConfig.TriggerStr.Split('#')[0]; string csvhead = "Time,Pid,Postion"; string csvdata = $"{DateTime.Now.ToString("yyyyMMddHHmmss")}T,{results[0].PID},{Postion}"; for (int i = 0; i < CheckPointList.Count; i++) { CheckPointList[i].ActualZ = datasZ[i] + CheckPointList[i].compensateZ; csvhead += $",{CheckPointList[i].Name}_X"; csvhead += $",{CheckPointList[i].Name}_Y"; csvhead += $",{CheckPointList[i].Name}_Z"; csvdata += $",{CheckPointList[i].X.ToString("F4")}"; csvdata += $",{CheckPointList[i].Y.ToString("F4")}"; csvdata += $",{CheckPointList[i].ActualZ.ToString("F4")}"; } foreach (var item in results[0].Specs.AsParallel()) { var temcal = ConfigAOI1.MeasureItemBinds.FirstOrDefault(u => u.SpecCode == item.Code); if (temcal == null) { LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"检测项 {item.Code}未能获取计算公式"); } else { List pointdata = new List(); foreach (var item1 in temcal.MeasurePointNameCollection) { var point = CheckPointList.FirstOrDefault(u => u.Name == item1.MeasurePointName); if (point == null) { LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"未能找到检测项{item.Code}的点数据{item1.MeasurePointName}"); } else { if (item1.ContourEdge == ContourEdge.X) { pointdata.Add(point.X); } else if (item1.ContourEdge == ContourEdge.Y) { pointdata.Add(point.Y); } else if (item1.ContourEdge == ContourEdge.Z) { pointdata.Add(point.ActualZ); } } } LogAsync(DateTime.Now, EnumHelper.LogLevel.Detail, $"{results[0].PID} {item.Code}输入计算公式数据 {string.Join(",", pointdata.Select(u => u.ToString("f4")))}"); var toolcal = GetHalconTool(null, "", temcal.AlgorithemPath); var retcal = toolcal.RunProcedure(new Dictionary() { { "INPUT_Points", pointdata.ToArray() } }, null, new List() { "OUTPUT_Results" }, null); if (retcal != null && !ret.Item1) { LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"未能找到检测项{item.Code}的计算公式算法运行异常{retcal?.Item4}"); } else { item.ActualValue = retcal.Item2["OUTPUT_Results"].HTupleToDouble()[0]; LogAsync(DateTime.Now, EnumHelper.LogLevel.Detail, $"{results[0].PID}获取计算公式数据{item.Code} {item.GetMeasureValueStr()}"); } } } CSVRecordAsync($"ContourPointRecord_{Postion}.csv", csvdata, csvhead); } else { LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"脚本{opConfig.AlgorithemPath}输出数据长度异常"); throw new Exception(); } } } } catch (Exception re) { LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"{re.ToString()}"); } return msg; } } }