SIC-12/Framework/MECF.Framework.RT.EquipmentLibrary/HardwareUnits/MachineVision/HikVision/HikVisionMasterSDK.cs

519 lines
21 KiB
C#

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; } = "";
/// <summary>
/// 标记当前执行的程序流程
/// </summary>
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<double>($"{Name}.{nameof(Tolerance)}", 1);
SC.RegisterValueChangedCallback($"{Name}.{nameof(Tolerance)}", (newvalue) => { Tolerance = (double)newvalue; LoadSolution(); }); //实时修改
Tolerance2 = SC.GetValue<double>($"{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<HikGigeCamera>($"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();
}
}
}