using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Device; using Aitex.Core.RT.Event; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using System; using System.Drawing; using System.Drawing.Imaging; using System.IO; using CalculatorModuleCs; using GlobalVariableModuleCs; using IfModuleCs; using ImageSourceModuleCs; using IMVSCircleFitModuCs; using IMVSLineFindModuCs; using SaveImageCs; using VM.Core; using VM.PlatformSDKCS; namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.MachineVision.HikVision { public class HikVisionMasterSDK : BaseDevice, IDevice { string _sol = ""; private PeriodicJob _thread; private bool _isInit = false; public HikVisionMasterSDK(string module, string scRoot, string name,bool isInit) : base(module, name, name, name) { IsProcessing = false; _sol = SC.SafeGetStringValue($"{Name}.VMSolutionAddress", "D:\\VMSolution\\123.sol"); _thread = new PeriodicJob(200, OnTimer, $"{Module}.{Name} MonitorHandler", true); _isInit = isInit; } public string Command { get; set; } = ""; /// /// 标记当前执行的程序流程 /// public string ProjectName { get; set; } = ""; public bool ModuleStatus { get; set; } = false; public bool Result { get; set; } = false; public double[] SampleCircle { get; set; } = new double[3]; public double[] CurrentCircle { get; set; } = new double[3]; public double[] SampleData { get; set; } public double[] SampleData2 { get; set; } public double Distance { get; set; } = 0; public double Tolerance { get; set; } = 1; public double Tolerance2 { get; set; } = 1; public bool IsProcessing { get; set; } = false; public bool LoadFile { get; set; } = false; public byte[] OutputImage { get; set; } = null; public byte[] PreviewImage1 { get; set; } = null; public byte[] PreviewImage2 { get; set; } = null; public byte[] PreviewImage3 { get; set; } = null; public byte[] PreviewImage4 { get; set; } = null; public string LocalImageFilePath { get; set; } public bool Initialize() { LocalImageFilePath = SC.SafeGetStringValue($"{Name}.{nameof(LocalImageFilePath)}", "D:\\VMImage\\Input"); if (!Directory.Exists(LocalImageFilePath)) { // 创建文件夹 Directory.CreateDirectory(LocalImageFilePath); Console.WriteLine($"Folder '{LocalImageFilePath}' created successfully."); } string s = SC.SafeGetStringValue($"{Name}.SampleData", "100,200,200,300,300,100"); //隐藏项 string s2 = SC.SafeGetStringValue($"{Name}.SampleData2", "100,200,200,300,300,100"); //隐藏项 SampleData = ConvertSample(s); SampleData2 = ConvertSample(s2); if (SampleData == null || SampleData2 == null) { EV.PostAlarmLog(Module, $"SampleData failed"); return true; } Tolerance = SC.GetValue($"{Name}.{nameof(Tolerance)}", 1); SC.RegisterValueChangedCallback($"{Name}.{nameof(Tolerance)}", (newvalue) => { Tolerance = (double)newvalue; LoadSolution(); }); //实时修改 Tolerance2 = SC.GetValue($"{Name}.{nameof(Tolerance2)}", 1); SC.RegisterValueChangedCallback($"{Name}.{nameof(Tolerance2)}", (newvalue) => { Tolerance2 = (double)newvalue; LoadSolution(); }); //实时修改 DATA.Subscribe($"{Module}.{Name}.{nameof(ProjectName)}", () => ProjectName); DATA.Subscribe($"{Module}.{Name}.{nameof(ModuleStatus)}", () => ModuleStatus); DATA.Subscribe($"{Module}.{Name}.{nameof(IsProcessing)}", () => IsProcessing); DATA.Subscribe($"{Module}.{Name}.{nameof(SampleCircle)}", () => SampleCircle); DATA.Subscribe($"{Module}.{Name}.{nameof(CurrentCircle)}", () => CurrentCircle); DATA.Subscribe($"{Module}.{Name}.{nameof(Distance)}", () => Distance); DATA.Subscribe($"{Module}.{Name}.{nameof(OutputImage)}", () => OutputImage); DATA.Subscribe($"{Module}.{Name}.{nameof(Result)}", () => Result); DATA.Subscribe($"{Module}.{Name}.{nameof(LoadFile)}", () => LoadFile); DATA.Subscribe($"{Module}.{Name}.{nameof(PreviewImage1)}", () => PreviewImage1); DATA.Subscribe($"{Module}.{Name}.{nameof(PreviewImage2)}", () => PreviewImage2); DATA.Subscribe($"{Module}.{Name}.{nameof(PreviewImage3)}", () => PreviewImage3); DATA.Subscribe($"{Module}.{Name}.{nameof(PreviewImage4)}", () => PreviewImage4); if (!_isInit) { return true; } OP.Subscribe($"{Module}.{Name}.ExecuteLocalFile", (string cmd, object[] args) => ExecuteLocalFile((string)args[0])); OP.Subscribe($"{Module}.{Name}.SetSample", (string cmd, object[] args) => SetSample((string)args[0])); OP.Subscribe($"{Module}.{Name}.ReloadSolution", (string cmd, object[] args) => LoadSolution()); OP.Subscribe($"{Module}.{Name}.ExecuteGrab", (string cmd, object[] args) => ExecuteGrab((string)args[0])); LoadSolution(); return true; } private double[] ConvertSample(string s) { var ss = s.Split(','); if (ss.Length != 6) return null; double[] ff = new double[6]; try { for (int i = 0; i < ff.Length; i++) { ff[i] = Convert.ToDouble(ss[i]); } } catch (Exception) { return null; } return ff; } private bool SetSample(string command) { if (command == "GroupCheck") { ProjectName = "FindEdge"; } else if (command.Contains("WaferPlaceCheck")) { ProjectName = "FindEdge2"; } else { EV.PostInfoLog(Module, $"VM command error"); return false; } IMVSLineFindModuTool module1 = (IMVSLineFindModuTool)VmSolution.Instance[$"{ProjectName}.FindEdge1"]; IMVSLineFindModuTool module2 = (IMVSLineFindModuTool)VmSolution.Instance[$"{ProjectName}.FindEdge2"]; IMVSLineFindModuTool module3 = (IMVSLineFindModuTool)VmSolution.Instance[$"{ProjectName}.FindEdge3"]; GlobalVariableModuleTool globalVar = (GlobalVariableModuleTool)VmSolution.Instance["全局变量1"]; if (globalVar == null || module1 == null || module2 == null || module3 == null) return false; if (ProjectName == "FindEdge") { globalVar.SetGlobalVar("point1x", module1.ModuResult.Midpoint.X.ToString()); globalVar.SetGlobalVar("point1y", module1.ModuResult.Midpoint.Y.ToString()); globalVar.SetGlobalVar("point2x", module2.ModuResult.Midpoint.X.ToString()); globalVar.SetGlobalVar("point2y", module2.ModuResult.Midpoint.Y.ToString()); globalVar.SetGlobalVar("point3x", module3.ModuResult.Midpoint.X.ToString()); globalVar.SetGlobalVar("point3y", module3.ModuResult.Midpoint.Y.ToString()); SampleData[0] = module1.ModuResult.Midpoint.X; SampleData[1] = module1.ModuResult.Midpoint.Y; SampleData[2] = module2.ModuResult.Midpoint.X; SampleData[3] = module2.ModuResult.Midpoint.Y; SampleData[4] = module3.ModuResult.Midpoint.X; SampleData[5] = module3.ModuResult.Midpoint.Y; } else if (ProjectName == "FindEdge2") { globalVar.SetGlobalVar("point1x_2", module1.ModuResult.Midpoint.X.ToString()); globalVar.SetGlobalVar("point1y_2", module1.ModuResult.Midpoint.Y.ToString()); globalVar.SetGlobalVar("point2x_2", module2.ModuResult.Midpoint.X.ToString()); globalVar.SetGlobalVar("point2y_2", module2.ModuResult.Midpoint.Y.ToString()); globalVar.SetGlobalVar("point3x_2", module3.ModuResult.Midpoint.X.ToString()); globalVar.SetGlobalVar("point3y_2", module3.ModuResult.Midpoint.Y.ToString()); SampleData2[0] = module1.ModuResult.Midpoint.X; SampleData2[1] = module1.ModuResult.Midpoint.Y; SampleData2[2] = module2.ModuResult.Midpoint.X; SampleData2[3] = module2.ModuResult.Midpoint.Y; SampleData2[4] = module3.ModuResult.Midpoint.X; SampleData2[5] = module3.ModuResult.Midpoint.Y; } var ss = $"{module1.ModuResult.Midpoint.X},{module1.ModuResult.Midpoint.Y},{module2.ModuResult.Midpoint.X},{module2.ModuResult.Midpoint.Y},{module3.ModuResult.Midpoint.X},{module3.ModuResult.Midpoint.Y}"; if (ProjectName == "FindEdge") { SC.SetItemValue($"{Name}.SampleData", ss); } else if (ProjectName == "FindEdge2") { SC.SetItemValue($"{Name}.SampleData2", ss); } return true; } private bool SetInitSample(double[] sampleArray1,double tolerance1, double[] sampleArray2, double tolerance2) { if (sampleArray1.Length !=6 || sampleArray2.Length != 6) { return false; } GlobalVariableModuleTool globalVar = (GlobalVariableModuleTool)VmSolution.Instance["全局变量1"]; if (globalVar == null) return false; try { globalVar.SetGlobalVar("point1x", sampleArray1[0].ToString()); globalVar.SetGlobalVar("point1y", sampleArray1[1].ToString()); globalVar.SetGlobalVar("point2x", sampleArray1[2].ToString()); globalVar.SetGlobalVar("point2y", sampleArray1[3].ToString()); globalVar.SetGlobalVar("point3x", sampleArray1[4].ToString()); globalVar.SetGlobalVar("point3y", sampleArray1[5].ToString()); globalVar.SetGlobalVar("tolerance", tolerance1.ToString()); globalVar.SetGlobalVar("point1x_2", sampleArray2[0].ToString()); globalVar.SetGlobalVar("point1y_2", sampleArray2[1].ToString()); globalVar.SetGlobalVar("point2x_2", sampleArray2[2].ToString()); globalVar.SetGlobalVar("point2y_2", sampleArray2[3].ToString()); globalVar.SetGlobalVar("point3x_2", sampleArray2[4].ToString()); globalVar.SetGlobalVar("point3y_2", sampleArray2[5].ToString()); globalVar.SetGlobalVar("tolerance2", tolerance2.ToString()); } catch (Exception ex) { return false; } return true; } private int _count = 0; private bool OnTimer() { if (IsProcessing) { if (ProjectName!="FindEdge" && ProjectName != "FindEdge2") { return true; } VmProcedure process = (VmProcedure)VmSolution.Instance[ProjectName]; if (process.IsRunning) { _count++; if (_count > 10) { _count = 0; OutputImage = null; CurrentCircle = new double[3] { 0,0,0 }; SampleCircle = new double[3] { 0,0,0 }; Distance = 0; Result = false; ModuleStatus = false; IsProcessing = false; EV.PostInfoLog(Module, $"VM TimeOver"); } return true; } else { try { IMVSCircleFitModuTool module1 = (IMVSCircleFitModuTool)VmSolution.Instance[$"{ProjectName}.圆拟合1"]; IMVSCircleFitModuTool module2 = (IMVSCircleFitModuTool)VmSolution.Instance[$"{ProjectName}.圆拟合2"]; CalculatorModuleTool module3 = (CalculatorModuleTool)VmSolution.Instance[$"{ProjectName}.变量计算1"]; SaveImageTool module4 = (SaveImageTool)VmSolution.Instance[$"{ProjectName}.OutputImage"]; IfModuleTool module5 = (IfModuleTool)VmSolution.Instance[$"{ProjectName}.条件检测2"]; if (module4.ModuResult.ModuStatus == 1) OutputImage = BitmapToBytes(module4.ModuResult.OutputImage.ToBitmap()); else OutputImage = null; if (Command == "WaferPlaceCheck") { PreviewImage1 = OutputImage; } else if (Command == "GroupCheck1") { PreviewImage2 = OutputImage; } else if (Command == "GroupCheck2") { PreviewImage3 = OutputImage; } else if (Command == "GroupCheck3") { PreviewImage4 = OutputImage; } var point1 = module1.ModuResult.OutputCircle.CenterPoint; var radius1 = module1.ModuResult.OutputCircle.Radius; var point2 = module2.ModuResult.OutputCircle.CenterPoint; var radius2 = module2.ModuResult.OutputCircle.Radius; var result = module3.ModuResult.GetOutputFloat("distance").pFloatVal; if (point1 == null || point2 == null || result == null) { CurrentCircle = new double[3] { 0, 0, 0 }; SampleCircle = new double[3] { 0, 0, 0 }; Distance = 0; Result = false; ModuleStatus = false; IsProcessing = false; EV.PostInfoLog(Module, $"VM Failed"); return true; } CurrentCircle = new double[3] { point1.X, point1.Y, radius1 }; SampleCircle = new double[3] { point2.X, point2.Y, radius2 }; Distance = result.Length == 1 ? result[0] : -1; Result = module5.ModuResult.NIfResult == 1; ModuleStatus = module4.ModuResult.ModuStatus == 1; } catch (Exception ex) { OutputImage = null; CurrentCircle = new double[3] { 0, 0, 0 }; SampleCircle = new double[3] { 0, 0, 0 }; Distance = 0; Result = false; ModuleStatus = false; IsProcessing = false; EV.PostInfoLog(Module, $"VM Test Failed"); } IsProcessing = false; } } else _count = 0; return true; } public byte[] BitmapToBytes(Bitmap bitmap) { using (MemoryStream ms = new MemoryStream()) { bitmap.Save(ms, ImageFormat.Bmp); // 推荐Bmp格式保证数据完整性:ml-citation{ref="1,5" data="citationList"} return ms.ToArray(); // 比GetBuffer()更精确获取有效数据:ml-citation{ref="12" data="citationList"} } } public bool ExecuteGrab(string command) { if (IsProcessing) { EV.PostInfoLog(Module, $"VM processing"); return true; } var ccd = DEVICE.GetDevice($"LoadLock.HikGigeCamera"); if (ccd == null) { EV.PostInfoLog(Module, $"ccd no install"); return true; } if (ccd.ImageData == null) { EV.PostInfoLog(Module, $"ccd no picture"); return true; } if (command.Contains("WaferPlaceCheck")) { ProjectName = "FindEdge2"; } else if (command.Contains("GroupCheck")) { ProjectName = "FindEdge"; } else { EV.PostInfoLog(Module, $"VM command error"); return true; } try { ModuleStatus = false; Result = false; VmProcedure process = (VmProcedure)VmSolution.Instance[$"{ProjectName}"]; ImageSourceModuleTool module = (ImageSourceModuleTool)VmSolution.Instance[$"{ProjectName}.Picture"]; if (null == process || module == null) return true; module.ModuParams.ImageSourceType = ImageSourceParam.ImageSourceTypeEnum.SDK; module.SetImageData(ccd.ImageData); process.Run(command); IsProcessing = true; Command = command; } catch (VmException ex) { EV.PostAlarmLog(Module, $"Excute VM Procedure Failed {ex}"); return true; } return true; } public bool ExecuteLocalFile(string command) { if (IsProcessing) { EV.PostInfoLog(Module, $"VM processing"); return true; } try { if (command.Contains("WaferPlaceCheck")) { ProjectName = "FindEdge2"; } else if (command.Contains("GroupCheck")) { ProjectName = "FindEdge"; } else { EV.PostInfoLog(Module, $"VM command error"); return true; } VmProcedure process = (VmProcedure)VmSolution.Instance[$"{ProjectName}"]; if (null == process) return true; ImageSourceModuleTool module = (ImageSourceModuleTool)VmSolution.Instance[$"{ProjectName}.Picture"]; if (module.ModuParams.ImageSourceType == ImageSourceParam.ImageSourceTypeEnum.SDK) { module.ModuParams.ImageSourceType = ImageSourceParam.ImageSourceTypeEnum.LocalImage; module.ClearAllInputImage(); string[] filePaths = Directory.GetFiles(LocalImageFilePath); foreach (var item in filePaths) { module.AddInputImageByPath(item); } module.ModuParams.AutoPlay = true; } process.Run(command); IsProcessing = true; Command = command; } catch (VmException ex) { EV.PostAlarmLog(Module, $"Excute VM Procedure Failed {ex}"); return true; } return true; } public void Reset() { //if (!_isInit) //{ // return; //} //LoadSolution(); } private bool LoadSolution() { LoadFile = false; try { VmSolution.Load(_sol); ImageSourceModuleTool module = (ImageSourceModuleTool)VmSolution.Instance["FindEdge.Picture"]; module.ModuParams.ImageSourceType = ImageSourceParam.ImageSourceTypeEnum.LocalImage; module.ClearAllInputImage(); string[] filePaths = Directory.GetFiles(LocalImageFilePath); foreach (var item in filePaths) { module.AddInputImageByPath(item); } module.ModuParams.AutoPlay = true; module = (ImageSourceModuleTool)VmSolution.Instance["FindEdge2.Picture"]; module.ModuParams.ImageSourceType = ImageSourceParam.ImageSourceTypeEnum.LocalImage; module.ClearAllInputImage(); filePaths = Directory.GetFiles(LocalImageFilePath); foreach (var item in filePaths) { module.AddInputImageByPath(item); } module.ModuParams.AutoPlay = true; } catch (Exception ex) { EV.PostAlarmLog(Module, $"Load VM file {_sol} Failed {ex}"); return false; } if (!SetInitSample(SampleData, Tolerance, SampleData2, Tolerance2)) { EV.PostAlarmLog(Module, $"Set SampleData failed"); return false; } EV.PostInfoLog(Module, $"Load VisionMaster Success"); LoadFile = true; return true; } public void Terminate() { VmSolution.Instance?.Dispose(); } } }