DHDHSoftware/DHSoftware/MainWindow.cs
2025-03-07 09:06:46 +08:00

748 lines
28 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using AntdUI;
using AntdUI.Svg;
using DH.Devices.Camera;
using DH.Devices.PLC;
using DH.Devices.Vision;
using DHSoftware.Languages;
using DHSoftware.Models;
using DHSoftware.Utils;
using DVPCameraType;
using Microsoft.Win32;
using OpenCvSharp;
using System;
using System.CodeDom;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows.Forms;
using static AntdUI.Math3D;
using Camera = DHSoftware.Models.Camera;
namespace DHSoftware
{
public partial class MainWindow : AntdUI.Window
{
private UserControl currControl;
private bool isUpdatingTabs = false;//用于阻止Tabs更新
private bool isLight = true;
// 定义一个语言切换事件
public event EventHandler LanguageChanged;
private System.Windows.Forms.Timer refreshTimer;
private int testCounter = 1;
Dictionary<string, List<string>> _cameraRelatedDetectionDict = null;
public MainWindow()
{
InitializeComponent();
refreshTimer = new System.Windows.Forms.Timer();
refreshTimer.Interval = 1000; // 1秒间隔
refreshTimer.Tick += RefreshTimer_Tick;
//refreshTimer.Start();
//初始化数据
InitData();
//绑定事件
BindEventHandler();
tabImgDisplay.Pages.Clear();
List<Camera> Cameras = new List<Camera>
{
new Camera
{
DeviceName = "Cam1",
Alias = "相机1",
ImagePath = @"D:\1.jpeg"
},
new Camera
{
DeviceName = "Cam2",
Alias = "相机2",
ImagePath = @"D:\2.jpeg"
},
new Camera
{
DeviceName = "Cam3",
Alias = "相机3",
ImagePath = @"D:\3.jpeg"
},
new Camera
{
DeviceName = "Cam4",
Alias = "相机4",
ImagePath = @"D:\4.jpeg"
},
new Camera
{
DeviceName = "Cam5",
Alias = "相机5",
ImagePath = @"D:\5.jpeg"
}
};
if (Cameras.Count > 0)
{
tabImgDisplay.Controls.Clear();
foreach (var cam in Cameras)
{
AntdUI.TabPage tabPage = new AntdUI.TabPage();
tabPage.Name = $"tab{cam.DeviceName}";
tabPage.Text = cam.Alias;
//ImgDisplayControl imgDisplayControl = new ImgDisplayControl();
//imgDisplayControl.Name = $"img{cam.DeviceName}";
//imgDisplayControl.Dock = DockStyle.Fill;
//tabPage.Controls.Add(imgDisplayControl);
PictureBox pictureBox = new PictureBox();
pictureBox.Name = $"pic{cam.DeviceName}";
pictureBox.Dock = DockStyle.Fill;
pictureBox.SizeMode = PictureBoxSizeMode.Zoom;
tabPage.Controls.Add(pictureBox);
tabImgDisplay.Pages.Add(tabPage);
}
}
}
private void RefreshTimer_Tick(object sender, EventArgs e)
{
// 获取相机1的控件通过控件名称查找
var targetControl = FindControlRecursive(tabImgDisplay, "picCam1") as PictureBox;
if (targetControl != null)
{
// 生成测试路径(示例路径)
string testPath = $@"D:\{testCounter}.png"; // 循环1-5的图片
testCounter++;
// 加载并显示图片
targetControl.Image = Image.FromFile(testPath);
if (testCounter == 5)
{
testCounter = 1;
}
targetControl.Parent.Invalidate();
}
}
// 递归查找控件的方法
private Control FindControlRecursive(Control parent, string name)
{
if (parent.Name == name) return parent;
foreach (Control child in parent.Controls)
{
var found = FindControlRecursive(child, name);
if (found != null) return found;
}
return null;
}
// 触发事件
protected virtual void OnLanguageChanged(EventArgs e)
{
LanguageChanged?.Invoke(this, e);
}
private void InitData()
{
//根据系统亮暗初始化一次
isLight = ThemeHelper.IsLightMode();
button_color.Toggle = !isLight;
ThemeHelper.SetColorMode(this, isLight);
//初始化消息弹出位置
Config.ShowInWindow = true;
}
private void BindEventHandler()
{
buttonSZ.Click += ButtonSZ_Click;
button_color.Click += Button_color_Click;
//监听系统深浅色变化
SystemEvents.UserPreferenceChanged += SystemEvents_UserPreferenceChanged;
}
private void SystemEvents_UserPreferenceChanged(object sender, UserPreferenceChangedEventArgs e)
{
if (e.Category == UserPreferenceCategory.General)
{
isLight = ThemeHelper.IsLightMode();
button_color.Toggle = !isLight;
ThemeHelper.SetColorMode(this, isLight);
}
}
private void Button_color_Click(object sender, EventArgs e)
{
isLight = !isLight;
//这里使用了Toggle属性切换图标
button_color.Toggle = !isLight;
ThemeHelper.SetColorMode(this, isLight);
}
private void ButtonSZ_Click(object sender, EventArgs e)
{
}
public List<Do3ThinkCamera> Cameras { get; } = new List<Do3ThinkCamera>();
public Dictionary<string, SimboObjectDetection> Dectection { get; } = new Dictionary<string, SimboObjectDetection>();
public XinJEPLCTcpNet PLC { get; } = new XinJEPLCTcpNet();
private void MainWindow_Load(object sender, EventArgs e)
{
}
private void MainWindow_FormClosed(object sender, FormClosedEventArgs e)
{
foreach (var camera in Cameras)
{
camera.CameraDisConnect();
}
PLC.PLCDisConnect();
}
private void segmented1_SelectIndexChanged(object sender, EventArgs e)
{
// Get the index of the selected item
int selectedIndex = segmented1.SelectIndex;
// Handle each button based on its index
switch (selectedIndex)
{
case 0: // "启动" (Start)
HandleStartButton();
break;
case 1: // "停止" (Stop)
HandleStopButton();
break;
case 2: // "复位" (Reset)
HandleResetButton();
break;
case 3: // "设置" (Settings)
HandleSettingsButton();
break;
case 4: // "登录" (Login)
HandleLoginButton();
break;
default:
break;
}
}
public bool CurrentMachine = false;
public volatile int ProductNum_Total = 0;
public volatile int ProductNum_OK = 0;
private readonly object _cameraSummaryLock = new object();
public DateTime sraerttime;
private void HandleStartButton()
{
CurrentMachine = true;
List<VisionEngine> detectionList = new List<VisionEngine>();
detectionList.Add(new VisionEngine("相机1", MLModelType.ObjectDetection, @"D:\DHSoftware\DHSoftware\Models\yolov3.cfg", false, "Cam1"));
detectionList.Add(new VisionEngine("相机2", MLModelType.ObjectDetection, @"D:\DHSoftware\DHSoftware\Models\yolov3.cfg", false, "Cam2"));
detectionList.Add(new VisionEngine("相机3", MLModelType.ObjectDetection, @"D:\DHSoftware\DHSoftware\Models\yolov3.cfg", false, "Cam3"));
detectionList.Add(new VisionEngine("相机4", MLModelType.ObjectDetection, @"D:\DHSoftware\DHSoftware\Models\yolov3.cfg", false, "Cam4"));
_cameraRelatedDetectionDict = new();
detectionList.ForEach(detection =>
{
// detection.CameraCollects.ForEach(cam =>
{
List<string> Dets = new List<string>
{
detection.Id
};
if (!_cameraRelatedDetectionDict.ContainsKey(detection.CameraSourceId))
{
_cameraRelatedDetectionDict.Add(detection.CameraSourceId, Dets);
}
else
{
_cameraRelatedDetectionDict[detection.CameraSourceId].Add(detection.Id);
}
}
//);
});
//Add the code for the "启动" button click here
Do3ThinkCamera do3ThinkCamera1 = new Do3ThinkCamera();
do3ThinkCamera1.dvpStreamFormat = dvpStreamFormat.S_MONO8;
do3ThinkCamera1.CameraName = "Cam1";
Do3ThinkCamera do3ThinkCamera2 = new Do3ThinkCamera();
do3ThinkCamera2.dvpStreamFormat = dvpStreamFormat.S_RGB24;
do3ThinkCamera2.CameraName = "Cam2";
Cameras.Add(do3ThinkCamera1);
Cameras.Add(do3ThinkCamera2);
do3ThinkCamera1.CameraConnect();
do3ThinkCamera2.CameraConnect();
do3ThinkCamera1.OnHImageOutput += OnCameraHImageOutput;
do3ThinkCamera2.OnHImageOutput += OnCameraHImageOutput;
var simbo1 = new SimboObjectDetection
{
};
MLInit mLInit;
string inferenceDevice = "CPU";
mLInit = new MLInit($"D:\\PROJECTS\\MaodingTest1\\Vision\\cam1.onnx", "images", inferenceDevice, 640, 640);
simbo1.Load(mLInit);
Dectection.Add(do3ThinkCamera1.CameraName, simbo1);
var simbo2 = new SimboObjectDetection
{
};
MLInit mLInit2;
string inferenceDevice2 = "CPU";
mLInit2 = new MLInit($"D:\\PROJECTS\\MaodingTest1\\Vision\\cam2.onnx", "images", inferenceDevice2, 640, 640);
simbo2.Load(mLInit2);
Dectection.Add(do3ThinkCamera2.CameraName, simbo2);
PLC.IP = "192.168.6.6";
PLC.Port = 502;
PLC.PLCConnect();
PLC.OnNewPieces -= MainMotion_NewPieces;
PLC.OnNewPieces += MainMotion_NewPieces;
ProductBaseCount = 2;
for (int i = 0; i < ProductBaseCount * ProductListMulti; i++)
{
ConcurrentDictionary<uint, ProductData> products = new ConcurrentDictionary<uint, ProductData>();
_productLists.Add(products);
}
sraerttime=DateTime.Now;
}
private uint PieceCount = 0;
private List<ConcurrentDictionary<uint, ProductData>> _productLists = new List<ConcurrentDictionary<uint, ProductData>>();
private int ProductListMulti = 2;
private int ProductBaseCount = 0;
private int PieceNumberToIndex(uint pn)
{
// 物料编号,取余 集合数量
//int multiple = (int)(pn / ProductBaseCount) % 2;
//int offset = (int)(pn % ProductBaseCount);
//int ret = (ProductBaseCount * multiple) + offset;
//int ret = (int)(pn % ProductBaseCount);
int ret = (int)(pn % (ProductBaseCount * ProductListMulti));
return ret;
}
DateTime _ctTime = DateTime.Now;
public async void MainMotion_NewPieces(int axisIndex, uint pieceNumber)
{
//if (MachineState != MachineState.Running && MachineState != MachineState.Warning)
//{
// return;
//}
PieceCount++;
Task.Run(() => {
this.BeginInvoke(new MethodInvoker(delegate () { richTextBox1.AppendText("入料成功" + PieceCount); }));
});
int index = PieceNumberToIndex(pieceNumber);
// productDatas.Add(pData);
//转盘2 的物料是不是重新覆盖之前的pDta
if (axisIndex == 1)
{
ProductData pData = new ProductData("", pieceNumber, ProductBaseCount);
_productLists[index][pieceNumber] = pData;
}
DateTime dtNow = DateTime.Now;
UpdateCT(null, (float)(dtNow - _ctTime).TotalSeconds);
_ctTime = dtNow;
}
public async Task UpdateCT(object objData, float ctTime)
{
await Task.Run(() =>
{
//OnUpdateCT?.Invoke(objData, ctTime);
});
}
private void OnCameraHImageOutput(DateTime dt, CameraBase camera, Mat imageSet)
{
// 获取该相机的拍照计数
uint productNumber = (uint)camera.SnapshotCount;
Task.Run(async () =>
{
// 拍照计数与物件编号一致,查找对应的产品
ProductData product = null;
//内外壁模组多个相机的处理方法
//计算队列的方法不变
int index = PieceNumberToIndex(productNumber);
// 找到产品存放在哪个队列里
ConcurrentDictionary<uint, ProductData> tmpDic = _productLists[index];
try
{
int retryTimes = 100;
while (product == null && retryTimes > 0)
{
if (tmpDic.ContainsKey(productNumber))
{
product = tmpDic[productNumber];
}
else
{
Thread.Sleep(20);
}
retryTimes--;
}
// 如果产品为空,则销毁图片,提示错误
if (null == product)
{
List<uint> pnList = tmpDic.Keys.ToList();
string pnStr = "";
if (pnList != null && pnList.Count > 0)
{
pnStr = string.Join(",", pnList);
}
//LogAsync(DateTime.Now, LogLevel.Error, $"{camera.Name} 未找到产品,编号:{productNumber},队列{index}数量:{tmpDic.Count},列表:{pnStr}");
imageSet.Dispose();
return;
}
// LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 找到产品{productNumber},队列{index}数量:{tmpDic.Count}");
if (!_cameraRelatedDetectionDict.ContainsKey(camera.CameraName))
{
if (imageSet != null)
{
imageSet?.Dispose();
imageSet = null;
}
imageSet.Dispose();
// LogAsync(DateTime.Now, LogLevel.Warning, $"{camera.Name} 找到产品{productNumber}但是没有推理1");
return;
}
double totalTime = 0.0;
List<ResultState> resultStates = new List<ResultState>();
List<string>? detectionDict = _cameraRelatedDetectionDict[camera.CameraName];
if (detectionDict.Count == 0)
{
//LogAsync(DateTime.Now, LogLevel.Warning, $"{camera.Name} 找到产品{productNumber}但是没有推理3");
}
for (int i = 0; i < detectionDict.Count; i++)
{
string d = detectionDict[i];
try
{
// LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 推理进度1.3,产品{productNumber}");
var req = new MLRequest();
req.mImage = imageSet.Clone();
req.ResizeWidth = 640;
req.ResizeHeight = 640;
req.confThreshold = 0.5f;
req.iouThreshold = 0.3f;
req.out_node_name = "output0";
req.in_lable_path = "D:\\PROJECTS\\MaodingTest1\\Vision\\cam1.txt";
//req.LabelNames = dc.GetLabelNames();
req.Score = 0.5f;
//HOperatorSet.WriteImage(req.HImage, "png", 0, @"D:\\666.png");
var result = Dectection[camera.CameraName].RunInference(req);
this.BeginInvoke(new MethodInvoker(delegate () {
pictureBox1.Image = result.ResultMap; richTextBox1.AppendText("推理成功" + productNumber+ result.IsSuccess+ "\n"); }));
//DetectStationResult temp;
////LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 推理进度1.4,产品{productNumber}");
//// 检测结果
//if (temp != null)
//{
// // LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 推理进度1.5,产品{productNumber}");
// //var totalElapsed = (temp.EndTime - temp.VisionImageSet.ImageTime).TotalMilliseconds;
// //totalTime += totalElapsed;
// resultStates.Add(temp.ResultState);
// product.ResultCollection.Add(temp);
// // LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 推理进度1.6,产品{productNumber}");
//}
//else
//{
// //LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 检测失败,物料编号:{productNumber},检测项:{d}");
//}
imageSet.Dispose();
}
catch (Exception ex)
{
// LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 推理异常,物料编号:{productNumber},检测项:{d}, {ex.GetExceptionMessage}");
}
}
//detectionDict.ForEach(d =>
//{
//});
// LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 推理进度2产品{productNumber}");
imageSet.Dispose();
product.InferenceOne(() =>
{
;
}, () =>
{
;
});
// LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 推理完成,产品{productNumber}");
if (!product.InferenceFinished())
{
//if (!(camera.Name == "Cam8"))
//{
// return;
//}
return;
}
ProductNum_Total++;
CalculateOEE();
this.BeginInvoke(new MethodInvoker(delegate () {
int currentScrollPosition = richTextBox1.GetPositionFromCharIndex(richTextBox1.TextLength).Y;
richTextBox1.AppendText($"统计结果成功,{productNumber}吹气!\n");
// 设置回原来的滚动位置
richTextBox1.SelectionStart = richTextBox1.TextLength;
richTextBox1.ScrollToCaret();
}));
//LogAsync(DateTime.Now, LogLevel.Information, $"推理完成,产品{product.PieceNumber}获取结果");
// 统计产品结果
//Task resultTask = product.SetProductResult(_totalDetectionNum, X017Config.IsTBDPriority, labelCategoryLists);
//await resultTask.ContinueWith(t =>
//{
// try
// {
// UpdateTriggerCount(DateTime.Now, "获取结果");
// UpdateResult(DateTime.Now, camera, product.ProductResult.GetEnumDescription());
// UpdateResultNew(DateTime.Now, camera, "合计");
// LogAsync(DateTime.Now, LogLevel.Information, $"产品{product.PieceNumber}获取结果:{product.ProductResult} {(product.IsA2B ? "产品IsA2B" : "")}");
// }
// catch (Exception ex)
// {
// LogAsync(DateTime.Now, LogLevel.Information, $"产品{product.PieceNumber}获取结果异常:{product.ProductResult} {(product.IsA2B ? "产品IsA2B" : "")}" +
// $"异常信息:{ex.GetExceptionMessage}");
// }
// // 吹气
// DateTime dtNow = DateTime.Now;
// product.BlowOutTime = dtNow;
// var setting = X017Config.ProductBlowSettings.FirstOrDefault(s => product.ProductResult.Equals(s.ProductResult));
// if (setting != null)
// {
// uint NGNumC = 0;
// uint OKNumC = 0;
// CMCDLL_NET.MCF_Sorting_Get_Lose_Blow_NG_Count_Net(ref NGNumC, 0);
// CMCDLL_NET.MCF_Sorting_Get_Lose_Blow_OK_Count_Net(ref OKNumC, 0);
// _mainMotion.Blow(product.PieceNumber, setting.BindBlow);
// LogAsync(DateTime.Now, LogLevel.Action, $"产品{product.PieceNumber}吹气{NGNumC}+ {OKNumC}");
// //if (product.ProductResult == ResultState.OK)
// //{
// // //OKProcessNum++;
// // OKNum++;
// //}
// }
// //判断超时出队
// foreach (var kvp in tmpDic)
// {
// try
// {
// ProductData dataN = kvp.Value;
// TimeSpan timeDifference = DateTime.Now - dataN.CreateTime;
// if (timeDifference.TotalMinutes >= 1)
// {
// //出队
// bool isremoved = tmpDic.TryRemove(kvp.Key, out _);
// if (isremoved)
// {
// LogAsync(DateTime.Now, LogLevel.Error, $"====产品{kvp.Key}超时出列成功" +
// $"产品结果:{dataN.ProductResult.GetEnumDescription()} {dataN.ProductResult}" +
// $"当前队列产品数量:{tmpDic.Count}====");
// try
// {
// //重新生成实例 销毁之前的实例
// var saveData = dataN.GetProductData();
// var productDefects = dataN.GetDetectDetailData();
// SaveProductDataAsync(saveData, productDefects);
// dataN = null;
// }
// catch (Exception) { }
// dataN?.Dispose();
// }
// else
// {
// LogAsync(DateTime.Now, LogLevel.Error, $"=====产品{kvp.Key}超时出列失败" +
// $"当前队列产品数量:{tmpDic.Count}=====");
// }
// }
// }
// catch (Exception ex)
// {
// LogAsync(DateTime.Now, LogLevel.Error, $"=====产品{kvp.Key}超时出列失败" +
// $"当前队列产品数量:{tmpDic.Count}====={ex.GetExceptionMessage}");
// }
// }
// 出列
ProductData temp = null;
int tryTimes = 5;
while (temp == null && tryTimes > 0)
{
var isSuccess = tmpDic.Remove(productNumber, out temp);
if (isSuccess)
{
// LogAsync(DateTime.Now, LogLevel.Assist, $"产品{productNumber}出列成功:{isSuccess}" +
//$"产品结果:{temp.ProductResult.GetEnumDescription()}" +
//$"当前队列产品数量:{tmpDic.Count}");
}
tryTimes--;
Thread.Sleep(1);
}
if (temp == null)
{
//LogAsync(DateTime.Now, LogLevel.Assist, $"产品{productNumber}出列失败," +
// $"当前队列产品数量:{tmpDic.Count}");
}
else
{
try
{
//重新生成实例 销毁之前的实例
var saveData = temp.GetProductData();
}
catch (Exception) { }
finally
{
// temp.Dispose();
temp = null;
}
}
// UpdateCT((float)(dtNow - _ctTime).TotalSeconds);
//_ctTime = dtNow;
// });
}
catch (Exception ex)
{
//LogAsync(DateTime.Now, LogLevel.Error, $"流程检测未捕获的异常:{ex.GetExceptionMessage()}");
product?.Dispose();
}
});
}
private void HandleStopButton()
{
Cameras.Clear();
Dectection.Clear();
// Add the code for the "停止" button click here
PLC.TurntableStop();
CurrentMachine = true;
}
public int UPH=0;
public void CalculateOEE()
{
TimeSpan timeSpan = DateTime.Now - sraerttime;
UPH = (int)(ProductNum_Total / timeSpan.TotalHours) + 100;
//UPM = (int)UPH / 60;
this.BeginInvoke(new MethodInvoker(delegate () {
label1.Text = UPH.ToString();
}));
}
private void HandleResetButton()
{
// Add the code for the "复位" button click here
MessageBox.Show("复位按钮按下");
}
private void HandleSettingsButton()
{
// Add the code for the "设置" button click here
MessageBox.Show("设置按钮按下");
}
private void HandleLoginButton()
{
// Add the code for the "登录" button click here
MessageBox.Show("登录按钮按下");
}
}
}