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<MeasureBind> measureBinds = new List<MeasureBind>();
|
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<string>()).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<string> trigerStr = new List<string>();
|
[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<string, HalconDotNet.HObject>() {
|
{ "INPUT_Image", opConfig.ImageSet.HImage } },
|
new List<string>() { "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<string> trigerStr2 = new List<string>();
|
[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<MeasureBind> measureBinds = new List<MeasureBind>();
|
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<string>()).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<bool, Dictionary<string, HTuple>, Dictionary<string, HObject>, string, int> ret = null;
|
|
ret = tool.RunProcedure(new Dictionary<string, HTuple>() { { "INPUT_BiaodingTupe", AOI3BConfig1.BDBD.ToArray() }, { "INPUT_xxzx", AOI3BConfig1.BDYX.ToArray() }, { "INPUT_muban", AOI3BConfig1.BDMD.ToArray() } }, new Dictionary<string, HalconDotNet.HObject>() { { "INPUT_Image", imgSet.HImage } }, new List<string>() { "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<int, List<double>> P2data = new Dictionary<int, List<double>>();
|
//Dictionary<int, List<double>> P2data2 = new Dictionary<int, List<double>>();
|
|
[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<bool, Dictionary<string, HTuple>, Dictionary<string, HObject>, string, int> ret = null;
|
|
ret = tool.RunProcedure(null, new Dictionary<string, HalconDotNet.HObject>() { { "INPUT_Image", opConfig.ImageSet.HImage } }, new List<string>() { "OUTPUT_Results_1", "OUTPUT_Results_2", "OUTPUT_TransmitData" }, null);
|
|
|
//var ret = tool.RunProcedure(null, new Dictionary<string, HalconDotNet.HObject>() { { "INPUT_Image", opConfig.ImageSet.HImage } }, new List<string>() { "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<bool, Dictionary<string, HTuple>, Dictionary<string, HObject>, string, int> ret = null;
|
|
List<double> tem = new List<double>();
|
|
|
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<string, HTuple>() { { "INPUT_TransmitData", tem.ToArray() } }, null, new List<string>() { "OUTPUT_Results_1", "OUTPUT_Results_2" }, null);
|
|
P2data.Clear();
|
P2data = new Dictionary<int, List<double>>();
|
}
|
|
|
|
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<double>();
|
yList = new List<double>();
|
uList = new List<double>();
|
vList = new List<double>();
|
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<string, HalconDotNet.HObject>() { { "INPUT_Image", opConfig.ImageSet.HImage } }, new List<string>() { "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<double> xList = new List<double>();
|
List<double> yList = new List<double>();
|
List<double> uList = new List<double>();
|
List<double> vList = new List<double>();
|
List<string> BDphoto = new List<string>();
|
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<bool, Dictionary<string, HTuple>, Dictionary<string, HObject>, string, int> ret = null;
|
|
ret = tool.RunProcedure(null, new Dictionary<string, HalconDotNet.HObject>() { { "INPUT_Image", imgSet.HImage } }, new List<string>() { "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<bool, Dictionary<string, HTuple>, Dictionary<string, HObject>, string, int> ret = null;
|
|
ret = tool.RunProcedure(null, new Dictionary<string, HalconDotNet.HObject>() { { "INPUT_Image", imgSet.HImage } }, new List<string>() { "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<double> xList2 = new List<double>() { xList[9], xList[10], xList[11] };
|
List<double> yList2 = new List<double>() { 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<double>() { 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<bool, Dictionary<string, HTuple>, Dictionary<string, HObject>, string, int> ret = null;
|
|
ret = tool.RunProcedure(new Dictionary<string, HTuple>() { { "INPUT_Tuple", AOI3BConfig1.BDBD.ToArray() } }, new Dictionary<string, HalconDotNet.HObject>() { { "INPUT_Image", imgSet.HImage } }, new List<string>() { "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;
|
}
|
|
|
}
|
}
|