3533 lines
186 KiB
C#
3533 lines
186 KiB
C#
using Advantech.Motion;
|
||
using HalconDotNet;
|
||
using Microsoft.VisualBasic;
|
||
using Models;
|
||
using Newtonsoft.Json;
|
||
using Newtonsoft.Json.Linq;
|
||
using OpenCvSharp;
|
||
using ProductionControl.Device;
|
||
using ProductionControl.Utils;
|
||
using SqlSugar;
|
||
using System;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using System.ComponentModel;
|
||
using System.Data;
|
||
using System.Diagnostics;
|
||
using System.Drawing;
|
||
using System.Drawing.Imaging;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using System.Security.Cryptography;
|
||
using System.Text;
|
||
using System.Threading;
|
||
using System.Threading.Tasks;
|
||
using System.Windows.Forms;
|
||
using static ProductionControl.Device.AxisDev;
|
||
using static ProductionControl.Device.DefectLib;
|
||
using static ProductionControl.Device.SizeLib;
|
||
|
||
namespace ProductionControl
|
||
{
|
||
public partial class FrmMain : Form
|
||
{
|
||
WebService webService = new WebService();
|
||
|
||
private List<string> productCodeList = new List<string>();
|
||
private DevContainer devContainer = new DevContainer();
|
||
private Service.ProductService svcProduct = new Service.ProductService();
|
||
private Service.OrderService svcOrder = new Service.OrderService();
|
||
private bool bExitApp = false;
|
||
//禁用蜂鸣器,门磁
|
||
private bool disableBuzzer, disableDoorSensor;
|
||
|
||
//线宽,张力,厚度,PT
|
||
private List<double> lstTension = new List<double>();
|
||
private List<double> lstHeight = new List<double>();
|
||
private List<double> lstLineWidth = new List<double>();
|
||
private List<double> lstPT = new List<double>();
|
||
|
||
private Queue<scannerGBmpLoc> scannerGBmpQueue = new Queue<scannerGBmpLoc>();
|
||
private Queue<scannerCBmpLoc> scannerCBmpQueue = new Queue<scannerCBmpLoc>();
|
||
//private int scannerCBmpIndex = 0;//scannerCBmpQueue中使用当前项的计数器
|
||
private int compBmpIndex = 0;//比对777图的索引
|
||
private int defectBmpNum = 0;
|
||
private int defectBmpNumResult = 0;
|
||
/// <summary>
|
||
/// 比对失败的图片
|
||
/// </summary>
|
||
private List<Bitmap> lstCompareFailZoomImage = new List<Bitmap>();
|
||
|
||
private object myLock=new object();
|
||
private WarningEnum warningLevel;//警告等级
|
||
private CurrentPTEnum currentPT;//当前点位
|
||
private CurrentStateEnum currentState;//当前状态
|
||
/// <summary>
|
||
/// 当前流程ID,暂停/继续时使用
|
||
/// </summary>
|
||
private int currProcessIndex = -1;
|
||
private Models.Product currProductModel = null;//当前产品
|
||
|
||
private bool autoMakeTagRuning = false;
|
||
private bool isProductRevise = false;
|
||
|
||
//产品-厚度base校正点位索引
|
||
private int ProductPT_HeightBaseNum = 0;
|
||
|
||
private Stopwatch stopWatch = new Stopwatch();
|
||
private Order order = new Order();
|
||
//--333输出变量供后面多个777使用
|
||
public HObject contoursAffineTrans1_Out;
|
||
|
||
private System.Timers.Timer timer = new System.Timers.Timer();
|
||
private class scannerGBmpLoc
|
||
{
|
||
public scannerGBmpLoc(Mat mat, double xmm, double ymm)
|
||
{
|
||
bmp = mat;
|
||
Xmm = xmm;
|
||
Ymm = ymm;
|
||
}
|
||
public Mat bmp { get; private set; }
|
||
public double Xmm { get; private set; }
|
||
public double Ymm { get; private set; }
|
||
}
|
||
private class scannerCBmpLoc
|
||
{
|
||
public scannerCBmpLoc(string path, double posX, double posY)
|
||
{
|
||
Path = path;
|
||
PosX=posX;
|
||
PosY=posY;
|
||
}
|
||
public scannerCBmpLoc(Bitmap bmp, double posX, double posY)
|
||
{
|
||
BMP = bmp;
|
||
PosX = posX;
|
||
PosY = posY;
|
||
}
|
||
public Bitmap BMP { get; private set; }
|
||
public string Path { get; private set; }
|
||
public double PosX { get; private set; }
|
||
public double PosY { get; private set; }
|
||
}
|
||
public FrmMain()
|
||
{
|
||
InitializeComponent();
|
||
this.dgvProcess.AutoGenerateColumns = false;
|
||
this.tsbtnCloseDev.Visible = false;
|
||
this.tsslLoginInfo.Text = $"操作员:{Config.loginUser.Code}({Config.loginUser.Name})";
|
||
this.tsslLoginTime.Text = $" 登录时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm")}";
|
||
|
||
//显示行号与列宽度自动调整
|
||
dgvProcess.RowHeadersVisible = true;
|
||
dgvProcess.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders;
|
||
dgvProcess.RowPostPaint += (sender, e) =>
|
||
{
|
||
Utils.Util.showRowNum_onDataGrid_RowPostPaint(this.dgvProcess, sender, e);
|
||
};
|
||
checkCustomerVer();
|
||
}
|
||
private void checkCustomerVer()
|
||
{
|
||
//if(Config.CustomerVer=="A")
|
||
// this.tsMenuOrderProduct.Visible = false;
|
||
}
|
||
private void FrmMian_Load(object sender, EventArgs e)
|
||
{
|
||
if (Config.loginUser.RoleInfo.Code!="admin")
|
||
checkRoleRight();
|
||
loadProductCodeList();
|
||
|
||
this.statusStrip1.LayoutStyle = System.Windows.Forms.ToolStripLayoutStyle.HorizontalStackWithOverflow;
|
||
this.tsslLoginTime.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
|
||
this.tsslLoginInfo.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
|
||
this.tsAxisState.Text = "";
|
||
|
||
//
|
||
webService.LogEvent = (warning, msg) =>
|
||
{
|
||
AddTextEvent("HTTP服务", msg, warning);
|
||
webService.LogEvent = null;
|
||
};
|
||
webService.start();
|
||
}
|
||
private void loadProductCodeList()
|
||
{
|
||
try
|
||
{
|
||
productCodeList = svcProduct.GetList().Select(m => m.Code).OrderBy(m=>m).ToList();
|
||
}
|
||
catch(Exception ex)
|
||
{
|
||
AddTextEvent("启动", "加载产品料号失败:" + ex.Message,WarningEnum.High);
|
||
}
|
||
}
|
||
private void checkRoleRight()
|
||
{
|
||
this.流程管理ToolStripMenuItem.Enabled = (Config.loginUser.RoleInfo.RightList.FirstOrDefault(m => m.Code == "Step") != null);
|
||
this.产品管理ToolStripMenuItem.Enabled = (Config.loginUser.RoleInfo.RightList.FirstOrDefault(m => m.Code == "Product") != null);
|
||
this.设备调试ToolStripMenuItem.Enabled = (Config.loginUser.RoleInfo.RightList.FirstOrDefault(m => m.Code == "Debug") != null);
|
||
|
||
//this.tsMenuOrderQuery.Enabled = (Config.loginUser.RoleInfo.RightList.FirstOrDefault(m => m.Code == "Order") != null);
|
||
//this.tsMenuStatistics.Enabled = (Config.loginUser.RoleInfo.RightList.FirstOrDefault(m => m.Code == "Statistics") != null);
|
||
|
||
this.角色管理ToolStripMenuItem.Enabled = (Config.loginUser.RoleInfo.RightList.FirstOrDefault(m => m.Code == "Role") != null);
|
||
this.用户管理ToolStripMenuItem.Enabled = (Config.loginUser.RoleInfo.RightList.FirstOrDefault(m => m.Code == "User") != null);
|
||
|
||
this.tsbtnProductRevise.Enabled = (Config.loginUser.RoleInfo.RightList.FirstOrDefault(m => m.Code == "HeightBase") != null);
|
||
this.tsMenuSysSetting.Enabled = (Config.loginUser.RoleInfo.RightList.FirstOrDefault(m => m.Code == "SysSetting") != null);
|
||
this.tsMenuCmdSetting.Enabled = (Config.loginUser.RoleInfo.RightList.FirstOrDefault(m => m.Code == "CmdSetting") != null);
|
||
this.tsMenuPTSetting.Enabled = (Config.loginUser.RoleInfo.RightList.FirstOrDefault(m => m.Code == "PTSetting") != null);
|
||
}
|
||
private void txtProductName_KeyPress(object sender, KeyPressEventArgs e)
|
||
{
|
||
//if (e.KeyChar == '\r' && devContainer.state && currentState == CurrentStateEnum.ScanBarcode)// && currentPT== CurrentPTEnum.UpPT )
|
||
//{
|
||
// runStep();
|
||
//}
|
||
}
|
||
//后台线程运行
|
||
/// <summary>
|
||
/// 中断工序运行
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
private bool isBreakProcessRun()
|
||
{
|
||
return warningLevel != WarningEnum.Normal || currentState != CurrentStateEnum.运行中;
|
||
}
|
||
private void runStep()
|
||
{
|
||
compBmpIndex = defectBmpNum = defectBmpNumResult = 0;
|
||
AddTextEvent("启动", "等待扫码枪扫码...");
|
||
if (devContainer.devCodeScanner != null)
|
||
{
|
||
devContainer.devCodeScanner.stop();
|
||
devContainer.devCodeScanner = null;
|
||
}
|
||
devContainer.devCodeScanner = new CodeScannerDev();
|
||
if (!devContainer.devCodeScanner.start())
|
||
{
|
||
AddTextEvent("扫码枪", "扫码枪初始化失败!");
|
||
return;
|
||
}
|
||
devContainer.devCodeScanner.ScanerEvent = (code) =>
|
||
{
|
||
if (!devContainer.state || currentState != CurrentStateEnum.等待扫码 || string.IsNullOrWhiteSpace(code))
|
||
return;
|
||
|
||
//
|
||
scannerGBmpQueue.Clear();
|
||
scannerCBmpQueue.Clear();
|
||
lstCompareFailZoomImage.Clear();
|
||
contoursAffineTrans1_Out = null;
|
||
Thread threadtest = new System.Threading.Thread(() =>
|
||
{
|
||
int errStep = 0;
|
||
try
|
||
{
|
||
var model = svcProduct.GetModelNav(code);
|
||
if (model != null && model.StepInfo.ProcessList.Count > 0)
|
||
{
|
||
errStep = 1;
|
||
//根据产品设置动态加载外观检测模型文件
|
||
string onnxFile;
|
||
if (!string.IsNullOrWhiteSpace(model.DefectModelFile))
|
||
onnxFile = $"{Application.StartupPath}\\onnxFiles\\{model.DefectModelFile}";
|
||
else
|
||
onnxFile = $"{Application.StartupPath}\\onnxFiles\\default.onnx";
|
||
devContainer.libDefect.loadModelFile(onnxFile);
|
||
|
||
//
|
||
errStep = 2;
|
||
string sn = "";
|
||
AutoResetEvent waitEvent = new AutoResetEvent(false);
|
||
this.Invoke(new System.Action(() =>
|
||
{
|
||
FrmInput frm = new FrmInput(null, "请输入网版编码:");
|
||
if (frm.ShowDialog() == DialogResult.OK && !string.IsNullOrWhiteSpace(frm.inputData))
|
||
sn = frm.inputData;
|
||
waitEvent.Set();
|
||
}));
|
||
errStep = 3;
|
||
waitEvent.WaitOne();
|
||
if (string.IsNullOrWhiteSpace(sn))
|
||
{
|
||
AddTextEvent("扫码枪", $"料号{code}未输入网版编码,流程中止!");
|
||
return;
|
||
}
|
||
AddTextEvent("扫码枪", $"料号:{code},网版编码:{sn}");
|
||
//是否闪退需观察
|
||
errStep = 4;
|
||
devContainer.devCodeScanner.stop();
|
||
devContainer.devCodeScanner = null;
|
||
errStep = 5;
|
||
//判断SN数量是否达到批次上限
|
||
//创建表达式
|
||
if (!string.IsNullOrWhiteSpace(model.BatchId) && model.TargetCount > 0)
|
||
{
|
||
var exp1 = Expressionable.Create<Order>()
|
||
.And(m => m.ProductId == model.Id)
|
||
.And(m => m.BatchId == model.BatchId)
|
||
.And(m => m.SN != sn)
|
||
.ToExpression();//注意 这一句 不能少
|
||
errStep = 6;
|
||
if (svcOrder.Count(exp1) >= model.TargetCount)
|
||
{
|
||
AddTextEvent("扫码枪", $"当前产品本批次检测数已达目标数量,请更换检测批次号!");
|
||
return;
|
||
}
|
||
|
||
errStep = 7;
|
||
}
|
||
//
|
||
|
||
this.Invoke(new System.Action(() =>
|
||
{
|
||
this.txtProductSN.Text = sn;
|
||
}));
|
||
|
||
//
|
||
model.HeightBaseDec = "";
|
||
currentState = CurrentStateEnum.运行中;
|
||
currentPT = CurrentPTEnum.Moving;
|
||
currProductModel = model;
|
||
AddTextEvent("扫码枪", $"{model.Name} {model.Spec} [{model.Code}]");
|
||
this.Invoke(new System.Action(() =>
|
||
{
|
||
this.txtProductCode.Text = model.Code;
|
||
this.txtProductName.Text = model.Name;
|
||
this.dgvProcess.DataSource = new BindingSource(model.StepInfo.ProcessList, null);
|
||
devContainer.libFor.clear();
|
||
devContainer.libIF.clear();
|
||
tsbtnSizeTag.Enabled = tsbtnSizeImage.Enabled = tsbtnDefectImage.Enabled = true;
|
||
}));
|
||
errStep = 8;
|
||
//
|
||
ProductPT_HeightBaseNum = 0;
|
||
this.setButtonEnabled(this.tsbtnPause, true);
|
||
this.setButtonEnabled(this.tsbtnStopNow, true);
|
||
order = new Order();
|
||
order.Qualified = true;//默认合格,中间有一项指标不合格则改为false
|
||
order.ProductId = currProductModel.Id;
|
||
order.StepId = (int)currProductModel.StepId;
|
||
order.SN = sn;
|
||
order.BatchId = currProductModel.BatchId;
|
||
errStep = 9;
|
||
int nextStepId = 0;
|
||
do
|
||
{
|
||
nextStepId = nextProcess(model, nextStepId);
|
||
} while (nextStepId >= 0 && !isBreakProcessRun());
|
||
errStep = 10;
|
||
}
|
||
else
|
||
AddTextEvent("扫码枪", model != null ? $"料号{code}不存在!" : $"产品({model.Name})未配置检测流程!");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
//AddTextEvent("扫码后", $"errcode({errStep}):" + ex.Message);//会有空对象引用,但不知哪里报的
|
||
//warning(WarningEnum.High);
|
||
}
|
||
});
|
||
threadtest.IsBackground = true;
|
||
threadtest.Start();
|
||
|
||
};
|
||
}
|
||
|
||
//model.Type=1 系统校正
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
/// <param name="model"></param>
|
||
/// <param name="stepIndex">0-n</param>
|
||
/// <returns>大于等于0正常工序; -1:结束 -2:异常</returns>
|
||
private int nextProcess(Models.Product model, int stepIndex)
|
||
{
|
||
try
|
||
{
|
||
//记录当前index
|
||
this.currProcessIndex = stepIndex;
|
||
this.Invoke(new System.Action(() =>
|
||
{
|
||
try
|
||
{
|
||
this.dgvProcess.Rows[stepIndex].Selected = true;
|
||
dgvProcess.CurrentCell = dgvProcess.Rows[stepIndex].Cells[1];
|
||
}
|
||
catch { }
|
||
}));
|
||
lock (myLock)
|
||
{
|
||
if (isBreakProcessRun())
|
||
return stepIndex;
|
||
}
|
||
//开始计时
|
||
if(!isProductRevise && model.StepInfo.StartTimeIndex>0 && model.StepInfo.StartTimeIndex==stepIndex+1)
|
||
stopWatch.Restart();
|
||
|
||
var processList = isProductRevise ? model.ReviseStepInfo.ProcessList : model.StepInfo.ProcessList;
|
||
var processInfo = processList[stepIndex];
|
||
string processName = processInfo.ProcessName;
|
||
//AddTextEvent($"{stepIndex + 1}-{processName}", $"工序开始...");
|
||
string jsonParams = null;//配方
|
||
|
||
if (model.ProductProcessList != null && model.ProductProcessList.Count > 0)//使用产品配方
|
||
{
|
||
ProductProcess productProcessParams = model.ProductProcessList.First(m => m.ProcessCode == processInfo.ProcessCode);
|
||
if (productProcessParams != null)
|
||
{
|
||
jsonParams = productProcessParams.ProcessParams;
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"使用产品专用配方:{jsonParams}");
|
||
}
|
||
}
|
||
if (jsonParams == null)//使用流程默认配方
|
||
{
|
||
jsonParams = processInfo.ProcessParams;
|
||
if (jsonParams == null) throw new Exception("配方为null!!");
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"使用流程默认配方:{jsonParams}");
|
||
}
|
||
|
||
//
|
||
JObject processParam = JObject.Parse(jsonParams);
|
||
if (!processParam.ContainsKey("Disable") || !processParam.Value<bool>("Disable"))
|
||
{
|
||
AutoResetEvent endEvent;
|
||
uint sleepPre = processParam.Value<uint>("SleepPre");
|
||
uint sleepLater = processParam.Value<uint>("SleepLater");
|
||
if (sleepPre > 0)
|
||
Thread.Sleep((int)sleepPre);
|
||
double limitThresholdVal, lowerThresholdVal; //张力,厚度,Size,Defect
|
||
|
||
//======Switch 工序类型
|
||
bool asynRun;
|
||
string gbxBmpPath = "";
|
||
Models.Attachment attachmentFile;
|
||
int liStatocStepIndex = stepIndex;
|
||
switch (processInfo.ProcessCode)
|
||
{
|
||
case "IOCard":
|
||
#region
|
||
var direction = (IODirectionEnum)processParam.Value<int>("Direction");
|
||
if (direction == IODirectionEnum.输入 || direction == IODirectionEnum.输入输出)
|
||
{
|
||
uint IN_Waiting_Timeout = processParam.Value<uint>("IN_Waiting_Timeout");
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"等待I/O输入信号{(IN_Waiting_Timeout > 0 ? $"(超时时长: {IN_Waiting_Timeout})" : "...")}");
|
||
string[] inValue = processParam.Value<JArray>("IN_OP_SHOW").ToObject<List<string>>().ToArray();
|
||
uint inWaitingTime = 0;
|
||
while (true)
|
||
{
|
||
if (isBreakProcessRun())
|
||
return stepIndex;
|
||
|
||
if (Util.compareIOInput(inValue, devContainer.devIOCard.DIData))
|
||
break;
|
||
|
||
Thread.Sleep(10);
|
||
inWaitingTime += 10;
|
||
if (IN_Waiting_Timeout>0 && inWaitingTime >= IN_Waiting_Timeout)
|
||
{
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"输入等待超时告警!", WarningEnum.High);
|
||
warning(WarningEnum.Low);//暂停
|
||
return stepIndex;
|
||
}
|
||
}
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"I/O输入信号对比完成!");
|
||
}
|
||
|
||
if (direction == IODirectionEnum.输出 || direction == IODirectionEnum.输入输出)
|
||
devContainer.io_output($"{stepIndex + 1}-{processName}", processParam);
|
||
#endregion
|
||
break;
|
||
case "Tension":
|
||
#region
|
||
//limitThresholdVal = processParam.Value<double>("LimitThresholdVal");
|
||
//lowerThresholdVal = processParam.Value<double>("LowerThresholdVal");
|
||
//double tensionValue = 0;
|
||
//int timeoutTension = 0;
|
||
//do
|
||
//{
|
||
// tensionValue = devContainer.devTension.getValue();
|
||
// setDgvContentCol(liStatocStepIndex, $"张力值:{tensionValue}");
|
||
// Thread.Sleep(10);
|
||
// timeoutTension += 10;
|
||
// if (tensionValue <= 0 && timeoutTension >= 600)//3秒超时
|
||
// {
|
||
// AddTextEvent($"{stepIndex + 1}-{processName}", $"张力测量失败,确认设备是否正常!", WarningEnum.High);
|
||
// warning(WarningEnum.Low);//暂停
|
||
// devContainer.io_output(CMDName.张力读取结束输出);
|
||
// currProcessIndex--;
|
||
// return stepIndex;
|
||
// }
|
||
//} while (tensionValue <= 0);
|
||
//devContainer.io_output(CMDName.张力读取结束输出);
|
||
|
||
//lstTension.Add(tensionValue);
|
||
//updateTensionValue(model.TensionBaseValue+model.TensionUpFloatValue,model.TensionBaseValue-model.TensionDownFloatValue);
|
||
//if (limitThresholdVal > 0 && tensionValue >= limitThresholdVal)
|
||
//{
|
||
// AddTextEvent($"{stepIndex + 1}-{processName}", $"读取数据:{tensionValue},达到上限阀值:{limitThresholdVal},进行下料...", WarningEnum.Low);
|
||
// currProcessIndex = stepIndex + 1;
|
||
// warning(WarningEnum.Low);//暂停
|
||
// return stepIndex;
|
||
//}
|
||
//else if (lowerThresholdVal > 0 && tensionValue < lowerThresholdVal)
|
||
//{
|
||
// AddTextEvent($"{stepIndex + 1}-{processName}", $"读取数据:{tensionValue},达到下限阀值:{lowerThresholdVal},进行下料...", WarningEnum.Low);
|
||
// currProcessIndex = stepIndex + 1;
|
||
// warning(WarningEnum.Low);//暂停
|
||
// return stepIndex;
|
||
//}
|
||
//AddTextEvent($"{stepIndex + 1}-{processName}", $"读取数据:{tensionValue}");
|
||
#endregion
|
||
break;
|
||
case "Height":
|
||
#region
|
||
if (Config.SkipHeight)
|
||
{
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"设备禁用,忽略此步骤!");
|
||
setDgvContentCol(liStatocStepIndex, $"设备禁用,忽略此步骤!");
|
||
break;
|
||
}
|
||
while (!devContainer.devAxis.isReady())//因启用轴异步功能,使用前需等待
|
||
{
|
||
Thread.Sleep(100);
|
||
if (isBreakProcessRun())
|
||
{
|
||
//currProcessIndex = stepIndex;//本工序没执行,step不变
|
||
return stepIndex;
|
||
}
|
||
}
|
||
|
||
limitThresholdVal = processParam.Value<double>("LimitThresholdVal");
|
||
lowerThresholdVal = processParam.Value<double>("LowerThresholdVal");
|
||
bool IsRevise = processParam.Value<bool>("IsRevise");
|
||
double relBaseValue = processParam.Value<double>("RelBaseValue"); //配方中相对偏移值
|
||
var heightValue = devContainer.devHeight.getHeight();
|
||
heightValue = Math.Round(heightValue, 2);//保留2位小数
|
||
File.AppendAllText(Application.StartupPath + "\\厚度测量记录.txt", heightValue+"\r\n");//TEMP
|
||
if (!IsRevise && heightValue < 0)
|
||
{
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"读取数据:{heightValue},异常数据,终止任务!", WarningEnum.Low);
|
||
warning(WarningEnum.Low);//暂停
|
||
return stepIndex;
|
||
}
|
||
//厚度Base校正
|
||
if (isProductRevise)
|
||
{
|
||
setDgvContentCol(liStatocStepIndex, $"厚度值:{heightValue}");
|
||
model.HeightBaseDec += heightValue + ";";
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"读取数据:{heightValue}");
|
||
}
|
||
else if (IsRevise)
|
||
{
|
||
var reviseHeight = heightValue + relBaseValue;
|
||
model.HeightBaseDec += reviseHeight + ";";
|
||
setDgvContentCol(liStatocStepIndex, $"base值:{reviseHeight} = 厚度值:{heightValue}+偏移值:{relBaseValue}");
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"base值:{reviseHeight} = 厚度值:{heightValue}+偏移值:{relBaseValue},校正索引队列:{model.HeightBaseDec}");
|
||
}
|
||
else
|
||
{
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"读取数据:{heightValue},base值:{model.HeightBaseDec},偏移值:{relBaseValue},当前base索引:{ProductPT_HeightBaseNum}");
|
||
double heightDev = 0;
|
||
var heightDev_BaseList=model.HeightBaseDec.Split(new char[] {';',','});
|
||
if (heightDev_BaseList.Count() > ProductPT_HeightBaseNum && heightDev_BaseList[ProductPT_HeightBaseNum].Trim() != "")
|
||
heightDev = Convert.ToDouble(heightDev_BaseList[ProductPT_HeightBaseNum].Trim());
|
||
ProductPT_HeightBaseNum++;
|
||
|
||
double heightValue2 =Math.Abs(heightDev - heightValue ) + relBaseValue;
|
||
heightValue2 = Math.Round(heightValue2, 2);
|
||
setDgvContentCol(liStatocStepIndex, $"厚度值:{heightValue2}");
|
||
lstHeight.Add(heightValue2);
|
||
updateHeightValue(model.HeightBaseValue + model.HeightUpFloatValue, model.HeightBaseValue - model.HeightDownFloatValue);
|
||
if (limitThresholdVal > 0 && heightValue2 >= limitThresholdVal)
|
||
{
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"读取数据:{heightValue2},达到上限阀值:{limitThresholdVal},进行下料...", WarningEnum.Low);
|
||
currProcessIndex = stepIndex + 1;
|
||
warning(WarningEnum.Low);//终止
|
||
return stepIndex;
|
||
}
|
||
else if (lowerThresholdVal > 0 && heightValue2 < lowerThresholdVal)
|
||
{
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"读取数据:{heightValue2},达到下限阀值:{lowerThresholdVal},进行下料...", WarningEnum.Low);
|
||
currProcessIndex = stepIndex + 1;
|
||
warning(WarningEnum.Low);//终止
|
||
return stepIndex;
|
||
}
|
||
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"厚度值:{heightValue2} (Base值:{heightDev} - 读取数据:{heightValue} + 偏移值:{relBaseValue})");
|
||
}
|
||
#endregion
|
||
break;
|
||
case "Axis":
|
||
#region 多轴后遗留问题:暂停后再启动不知哪几个轴已执行
|
||
JObject processParamTmp = new JObject();
|
||
//兼容旧版单轴
|
||
if (!processParam.ContainsKey("0") && !processParam.ContainsKey("1") && !processParam.ContainsKey("2") && !processParam.ContainsKey("3"))
|
||
{
|
||
processParam.Add("Enable", true);
|
||
processParamTmp.Add(processParam.Value<int>("AxisIndex").ToString(), processParam);
|
||
processParam = processParamTmp;
|
||
}
|
||
//-
|
||
foreach (var processParamSub in processParam.Properties())
|
||
{
|
||
processParam = processParamSub.Value as JObject;
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", processParam.ToString());
|
||
if (!processParam.ContainsKey("Disable") || !processParam.Value<bool>("Disable"))
|
||
{
|
||
//asynRun = processParam.Value<bool>("AsynRun");//异步
|
||
int AxisIndex = processParam.Value<int>("AxisIndex");
|
||
int DeviceType = processParam.Value<int>("DeviceType");
|
||
|
||
double VelLow = processParam.Value<double>("VelLow");
|
||
double VelHigh = processParam.Value<double>("VelHigh");
|
||
double Acc = processParam.Value<double>("Acc");
|
||
double Dec = processParam.Value<double>("Dec");
|
||
|
||
AxMoveMode MoveMode = (AxMoveMode)processParam.Value<int>("MoveMode");//绝对位置
|
||
double PPUValue = processParam.Value<double>("Value");
|
||
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"轴{AxisIndex}准备({(MoveMode == AxMoveMode.绝对位置 ? "绝对" : "相对")})运动至{PPUValue}(当前轴状态:{((AxisState)devContainer.devAxis.AxState[AxisIndex]).ToString()})...");
|
||
|
||
//移动Axis前等待厚度传感器收回
|
||
if (!Config.SkipHeight)
|
||
{
|
||
while (devContainer.devHeight.getHeight() < (double)Math.Abs(Config.HeightDev_SafeValue))
|
||
{
|
||
if (isBreakProcessRun())
|
||
return stepIndex;
|
||
Thread.Sleep(10);
|
||
}
|
||
}
|
||
while (!devContainer.devAxis.isReady(AxisIndex))
|
||
{
|
||
Thread.Sleep(100);
|
||
if (isBreakProcessRun())
|
||
return stepIndex;
|
||
}
|
||
devContainer.devAxis.setAxisVelParam(VelLow, VelHigh, Acc, Dec, AxisIndex);
|
||
if (!devContainer.devAxis.move_ptp(AxisIndex, PPUValue, MoveMode))
|
||
{
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"轴{AxisIndex}运动失败!", WarningEnum.Low);
|
||
warning(WarningEnum.Low);//终止
|
||
return stepIndex;
|
||
}
|
||
|
||
//多轴运行自动使用异步,全部执行后强制等待各轴完成 asynRun属性已无用
|
||
//AddTextEvent($"{stepIndex + 1}-{processName}", $"等待轴{AxisIndex}运行完成...");
|
||
//while (!asynRun && !devContainer.devAxis.isReady(AxisIndex))
|
||
//{
|
||
// Thread.Sleep(100);
|
||
// if (isBreakProcessRun())
|
||
// {
|
||
// currProcessIndex = stepIndex + 1;
|
||
// return stepIndex;
|
||
// }
|
||
//}
|
||
//if (devContainer.devAxis.isReady(AxisIndex))
|
||
// AddTextEvent($"{stepIndex + 1}-{processName}", $"轴{AxisIndex}运行完成,当前命令位置:{devContainer.devAxis.getCmdPos_mm(AxisIndex)},反馈位置:{devContainer.devAxis.getActualPos_mm(AxisIndex)}");
|
||
}
|
||
}
|
||
//多轴同时运行后强制等待各轴完成
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"等待轴组运行完成...");
|
||
while (!devContainer.devAxis.isReady())
|
||
{
|
||
Thread.Sleep(100);
|
||
if (isBreakProcessRun())
|
||
{
|
||
currProcessIndex = stepIndex + 1;
|
||
return stepIndex;
|
||
}
|
||
}
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"轴组运行完成。");
|
||
#endregion
|
||
break;
|
||
case "AxisTag":
|
||
#region
|
||
//asynRun = processParam.Value<bool>("AsynRun");//异步
|
||
string axisSizeTag= processParam.Value<string>("SizeTag");
|
||
int useIndex = processParam.Value<int>("UseIndex");//消费posePT中的索引
|
||
AxMoveMode TagMoveMode = (AxMoveMode)processParam.Value<int>("MoveMode");//绝对位置
|
||
var AxisIndexList = processParam.Value<JArray>("AxisIndexList").ToObject<List<int>>();
|
||
|
||
double TagVelLow = processParam.Value<double>("VelLow");
|
||
double TagVelHigh = processParam.Value<double>("VelHigh");
|
||
double TagAcc = processParam.Value<double>("Acc");
|
||
double TagDec = processParam.Value<double>("Dec");
|
||
var sizeTagObj = order.SizeTagDataList.LastOrDefault(m => m.SizeTag == axisSizeTag);//用最新的last
|
||
if (sizeTagObj == null)
|
||
{
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"偏移校正轴工序找不到数据提供者Tag:{axisSizeTag}!", WarningEnum.High);
|
||
warning(WarningEnum.High);
|
||
return stepIndex;
|
||
}
|
||
string[] posePT= sizeTagObj.posePT.Split(',');
|
||
if(posePT.Length < useIndex+ AxisIndexList.Count)
|
||
{
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"Tag:{axisSizeTag}对应消费索引:{useIndex},Axis数量:{AxisIndexList.Count} 超出postPT:{sizeTagObj.posePT} 范围!", WarningEnum.High);
|
||
warning(WarningEnum.High);
|
||
return stepIndex;
|
||
}
|
||
|
||
double[] TagPPUValue = new double[AxisIndexList.Count];
|
||
for (int i = 0; i < AxisIndexList.Count; i++)
|
||
TagPPUValue[i] = double.Parse(posePT[useIndex + i]);
|
||
string axisTagMsg = $"消费Tag:{axisSizeTag},索引:{useIndex}, 轴:{string.Join(",", AxisIndexList.ToList())},数据:{(TagMoveMode== AxMoveMode.绝对位置 ? "绝对" : "相对")}({string.Join(",", TagPPUValue.ToList())})";
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", axisTagMsg);
|
||
setDgvContentCol(liStatocStepIndex, axisTagMsg);
|
||
|
||
//移动Axis前等待厚度传感器收回
|
||
if (!Config.SkipHeight)
|
||
{
|
||
while (devContainer.devHeight.getHeight() < (double)Math.Abs(Config.HeightDev_SafeValue))
|
||
{
|
||
if (isBreakProcessRun())
|
||
return stepIndex; //如果是相对位置,这里返回会有问题
|
||
Thread.Sleep(10);
|
||
}
|
||
}
|
||
for (int i = 0; i < AxisIndexList.Count && i < TagPPUValue.Length; i++)
|
||
{
|
||
while (!devContainer.devAxis.isReady(AxisIndexList[i]))
|
||
{
|
||
Thread.Sleep(100);
|
||
if (isBreakProcessRun())
|
||
return stepIndex;
|
||
}
|
||
devContainer.devAxis.setAxisVelParam(TagVelLow, TagVelHigh, TagAcc, TagDec, AxisIndexList[i]);
|
||
if (!devContainer.devAxis.move_ptp(AxisIndexList[i], TagPPUValue[i], TagMoveMode))
|
||
{
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"轴{AxisIndexList[i]}运动失败!", WarningEnum.Low);
|
||
warning(WarningEnum.Low);//终止
|
||
return stepIndex;//如果是相对位置,这里返回会有问题
|
||
}
|
||
|
||
//AddTextEvent($"{stepIndex + 1}-{processName}", $"等待轴{AxisIndexList[i]}运行完成...");
|
||
//while (!asynRun && !devContainer.devAxis.isReady(AxisIndexList[i]))
|
||
//{
|
||
// Thread.Sleep(100);
|
||
// if (isBreakProcessRun())
|
||
// {
|
||
// currProcessIndex = stepIndex + 1;
|
||
// return stepIndex;//如果是相对位置,这里返回会有问题
|
||
// }
|
||
//}
|
||
//if (devContainer.devAxis.isReady(AxisIndexList[i]))
|
||
// AddTextEvent($"{stepIndex + 1}-{processName}", $"轴{AxisIndexList[i]}运行完成,当前命令位置:{devContainer.devAxis.getCmdPos_mm(AxisIndexList[i])},反馈位置:{devContainer.devAxis.getActualPos_mm(AxisIndexList[i])}");
|
||
}
|
||
if (sizeTagObj.ConsumeStepIndex == null) sizeTagObj.ConsumeStepIndex = "";
|
||
sizeTagObj.ConsumeStepIndex += $"{stepIndex + 1}-{useIndex}, ";//消费工序ID
|
||
|
||
//多轴同时运行后强制等待各轴完成
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"等待轴组运行完成...");
|
||
while (!devContainer.devAxis.isReady())
|
||
{
|
||
Thread.Sleep(100);
|
||
if (isBreakProcessRun())
|
||
{
|
||
currProcessIndex = stepIndex + 1;
|
||
return stepIndex;
|
||
}
|
||
}
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"轴组运行完成。");
|
||
#endregion
|
||
break;
|
||
case "Light":
|
||
#region
|
||
if (Config.SkipLight)
|
||
{
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"设备禁用,忽略此步骤!");
|
||
setDgvContentCol(liStatocStepIndex, $"设备禁用,忽略此步骤!");
|
||
break;
|
||
}
|
||
int ChannelIndex = processParam.Value<int>("ChannelIndex"); //通道
|
||
int DigitalValue = processParam.Value<int>("DigitalValue"); //亮度
|
||
int nowDiaitalValue = devContainer.devLight.getDigitalValue(ChannelIndex);
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"通道{ChannelIndex}当前值:{nowDiaitalValue},准备更新值:{DigitalValue}...");
|
||
devContainer.devLight.setDigitalValue(ChannelIndex, DigitalValue);
|
||
nowDiaitalValue = devContainer.devLight.getDigitalValue(ChannelIndex);
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"通道{ChannelIndex}更新后当前值:{nowDiaitalValue}。");
|
||
#endregion
|
||
break;
|
||
case "Scanner_GENTL":
|
||
#region
|
||
if (Config.SkipScannerGL)
|
||
{
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"设备禁用,忽略此步骤!");
|
||
setDgvContentCol(liStatocStepIndex, $"设备禁用,忽略此步骤!");
|
||
break;
|
||
}
|
||
while (!devContainer.devAxis.isReady())//因启用轴异步功能,使用前需等待
|
||
{
|
||
Thread.Sleep(100);
|
||
if (isBreakProcessRun())
|
||
{
|
||
//currProcessIndex = stepIndex;//本工序没执行,step不变
|
||
return stepIndex;
|
||
}
|
||
}
|
||
|
||
AIEngineLibEnum AIEngineLib = AIEngineLibEnum.缺陷库;
|
||
if(processParam.ContainsKey("AIEngineLib"))
|
||
AIEngineLib=(AIEngineLibEnum)processParam.Value<int>("AIEngineLib");
|
||
float ExposureTime = processParam.Value<float>("ExposureTime"); //曝光
|
||
float Gain = processParam.Value<float>("Gain"); //增益
|
||
float ResultingFrameRate = processParam.Value<float>("ResultingFrameRate"); //帧率
|
||
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"相机开始采集照片...");
|
||
devContainer.devScannerGentl.setParam(ExposureTime, Gain, ResultingFrameRate);
|
||
|
||
endEvent = new AutoResetEvent(false);
|
||
devContainer.devScannerGentl.ScanEvent = (num, bmpout) =>
|
||
{
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"相机采集照片完成。");
|
||
//----缺陷队列
|
||
bool cloneUse = false;
|
||
if (AIEngineLib == AIEngineLibEnum.缺陷库 || AIEngineLib == AIEngineLibEnum.缺陷与测量库)
|
||
{
|
||
cloneUse = true;
|
||
var mat = OpenCvSharp.Extensions.BitmapConverter.ToMat(bmpout);
|
||
scannerGBmpQueue.Enqueue(new scannerGBmpLoc(mat,
|
||
devContainer.devAxis.getActualPos_mm(1),
|
||
devContainer.devAxis.getActualPos_mm(2)));//Dequeue
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"缺陷图像队列数量: {scannerGBmpQueue.Count}");
|
||
}
|
||
if (AIEngineLib == AIEngineLibEnum.测量库 || AIEngineLib == AIEngineLibEnum.缺陷与测量库)
|
||
{
|
||
scannerCBmpQueue.Enqueue(new scannerCBmpLoc(
|
||
cloneUse?(Bitmap)bmpout.Clone(): bmpout,
|
||
devContainer.devAxis.getActualPos_mm(1),
|
||
devContainer.devAxis.getActualPos_mm(2)));//Dequeue
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"添加尺寸图像队列,X:{devContainer.devAxis.getActualPos_mm(1)},y:{devContainer.devAxis.getActualPos_mm(2)},数量: {scannerCBmpQueue.Count}");
|
||
}
|
||
endEvent.Set();//线程返回
|
||
};
|
||
//AddTextEvent($"{stepIndex + 1}-{processName}", $"软触发拍照...");
|
||
if (!devContainer.devScannerGentl.scan(1))//软触发拍照
|
||
{
|
||
devContainer.devScannerGentl.ScanEvent = null;
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"相机采集照片失败!", WarningEnum.Low);
|
||
warning(WarningEnum.Low);//终止
|
||
return stepIndex;
|
||
}
|
||
if (!endEvent.WaitOne(5000))
|
||
{
|
||
devContainer.devScannerGentl.ScanEvent = null;
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"相机采集照片超时!", WarningEnum.Low);
|
||
warning(WarningEnum.Low);//终止
|
||
return stepIndex;
|
||
}
|
||
devContainer.devScannerGentl.ScanEvent = null;
|
||
#endregion
|
||
break;
|
||
case "Scanner_CC":
|
||
#region
|
||
if (Config.SkipScannerCC)
|
||
{
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"设备禁用,忽略此步骤!");
|
||
setDgvContentCol(liStatocStepIndex, $"设备禁用,忽略此步骤!");
|
||
break;
|
||
}
|
||
while (!devContainer.devAxis.isReady())//因启用轴异步功能,使用前需等待
|
||
{
|
||
Thread.Sleep(100);
|
||
if (isBreakProcessRun())
|
||
{
|
||
//currProcessIndex = stepIndex;//本工序没执行,step不变
|
||
return stepIndex;
|
||
}
|
||
}
|
||
|
||
float ExposureTimeCC = processParam.Value<float>("ExposureTime"); //曝光
|
||
float GainCC = processParam.Value<float>("Gain"); //增益
|
||
float ResultingFrameRateCC = processParam.Value<float>("ResultingFrameRate"); //帧率
|
||
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"相机开始采集照片...");
|
||
devContainer.devScannerCC.setParam(ExposureTimeCC, GainCC, ResultingFrameRateCC);
|
||
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"相机参数设置完成。");
|
||
AutoResetEvent endEventCC = new AutoResetEvent(false);
|
||
//devContainer.devScannerCC.ScanEvent = (num, bmp2) =>
|
||
//{
|
||
// AddTextEvent($"{stepIndex + 1}-{processName}", $"相机采集照片完成.");
|
||
// scannerCBmpQueue.Enqueue(bmp2);//Dequeue
|
||
// endEventCC.Set();//线程返回
|
||
//};
|
||
devContainer.devScannerCC.ScanEventPath += new System.Action<int, string>((num, path2) =>
|
||
{
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"相机采集照片完成.");
|
||
scannerCBmpQueue.Enqueue(new scannerCBmpLoc(path2,
|
||
devContainer.devAxis.getActualPos_mm(0),
|
||
devContainer.devAxis.getActualPos_mm(2)));//Dequeue
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"添加尺寸图像队列,X:{ devContainer.devAxis.getActualPos_mm(1)},y: { devContainer.devAxis.getActualPos_mm(2)},数量: { scannerCBmpQueue.Count}");
|
||
endEventCC.Set();//线程返回
|
||
});
|
||
if (!devContainer.devScannerCC.scan(1))//软触发拍照
|
||
{
|
||
devContainer.devScannerCC.ScanEventPath = null;
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"相机采集照片失败!", WarningEnum.Low);
|
||
warning(WarningEnum.Low);//终止
|
||
return stepIndex;
|
||
}
|
||
|
||
if (!endEventCC.WaitOne(5000))
|
||
{
|
||
devContainer.devScannerCC.ScanEventPath = null;
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"相机采集照片超时!", WarningEnum.Low);
|
||
warning(WarningEnum.Low);//终止
|
||
return stepIndex;
|
||
}
|
||
devContainer.devScannerCC.ScanEventPath = null;
|
||
#endregion
|
||
break;
|
||
case "SmallAxis":
|
||
#region
|
||
if (Config.SkipSmallAxis)
|
||
{
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"设备禁用,忽略此步骤!");
|
||
setDgvContentCol(liStatocStepIndex, $"设备禁用,忽略此步骤!");
|
||
break;
|
||
}
|
||
int CmdPos = processParam.Value<int>("CmdPos"); //命令脉冲
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"开始由起始位置{devContainer.devSmallAxis.getCurrPPU()}运动到{CmdPos}...");
|
||
devContainer.devSmallAxis.gotoPos(CmdPos, true);
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"运动完成,当前位置:{devContainer.devSmallAxis.getCurrPPU()}");
|
||
#endregion
|
||
break;
|
||
case "Size":
|
||
#region
|
||
asynRun = processParam.Value<bool>("AsynRun");//异步
|
||
limitThresholdVal = processParam.Value<double>("LimitThresholdVal");
|
||
lowerThresholdVal = processParam.Value<double>("LowerThresholdVal");
|
||
int sizeIndex = processParam.Value<int>("Index");
|
||
string sizeTag = processParam.ContainsKey("SizeTag") ? processParam.Value<string>("SizeTag") : "";
|
||
if (scannerCBmpQueue.Count < 1)
|
||
{
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"尺寸检测异常,无源图像!!", WarningEnum.Low);
|
||
warning(WarningEnum.Low);//暂停
|
||
return stepIndex;
|
||
}
|
||
var bmpCBmpQueue = scannerCBmpQueue.Dequeue();
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"开始尺寸检测,index:{sizeIndex},posX:{bmpCBmpQueue.PosX},posY:{bmpCBmpQueue.PosY},图像队列数量: {scannerCBmpQueue.Count}...");
|
||
|
||
attachmentFile = model.AttachmentList.FirstOrDefault(x => x.Type == 0);
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"尺寸检测,index:{sizeIndex},{model.AttachmentList.Count}|{(attachmentFile == null ? "null": attachmentFile.NameTimestamp+ attachmentFile.ExtendName)}");
|
||
if (attachmentFile != null)
|
||
{
|
||
gbxBmpPath = Application.StartupPath + $"\\Attachment\\product\\{attachmentFile.NameTimestamp}";
|
||
if (!File.Exists(gbxBmpPath+ attachmentFile.ExtendName)) gbxBmpPath = "";
|
||
}
|
||
if ((sizeIndex == 333 || sizeIndex == 777) && gbxBmpPath == "")
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"尺寸检测,index:{sizeIndex},图纸不存在!", WarningEnum.Low);
|
||
//需要偏移校正,index=0时不能异步 //10,20,30...
|
||
endEvent = new AutoResetEvent(false);
|
||
devContainer.libSize.add(new SizeTask()
|
||
{
|
||
stepIndex = stepIndex,
|
||
processName = processName,
|
||
sizeTag = sizeTag,
|
||
engineName = processParam.Value<string>("EngineName"),
|
||
bmp = bmpCBmpQueue.BMP,//bmp/file_path二选一,优先bmp
|
||
file_path = bmpCBmpQueue.Path,
|
||
drawingPagePath = gbxBmpPath,
|
||
posX= bmpCBmpQueue.PosX,
|
||
posY= bmpCBmpQueue.PosY,
|
||
index = sizeIndex,// scannerCBmpIndex++,
|
||
ContoursAffineTrans1_Out=this.contoursAffineTrans1_Out,//只有777时才使用最近333输出的结果
|
||
finishEvent = (res) =>
|
||
{
|
||
try
|
||
{
|
||
//比对
|
||
if (res.index == 777)//比对
|
||
{
|
||
if (res.isSucceed)
|
||
{
|
||
setDgvContentCol(liStatocStepIndex, $"index:{res.index}-{compBmpIndex},posX:{res.posX},posY:{res.posY},图像比对:{(res.CompResult ? "通过" : "未通过")} ");
|
||
AddTextEvent($"{res.stepIndex + 1}-{res.processName}", $"图像比对,index:{res.index}-{compBmpIndex},posX:{res.posX},posY:{res.posY},结果:{(res.CompResult ? "通过" : "未通过")}");
|
||
//
|
||
if (order.CompareResult < 2)
|
||
order.CompareResult = res.CompResult ? 1 : 2;
|
||
updateCompareResult(res.CompResult);//更新比对看板
|
||
if (!res.CompResult)
|
||
{
|
||
AddTextEvent($"{res.stepIndex + 1}-{res.processName}", $"图像比对,未通过结果:{JsonConvert.SerializeObject(res.defectInfor2RestorationDesk)}");
|
||
//转为图纸上坐标位置
|
||
if (res.defectInfor2RestorationDeskPage != null && res.defectInfor2RestorationDeskPage.Count > 0)
|
||
{
|
||
//AddTextEvent($"{res.stepIndex + 1}-{res.processName}", $"转换到图纸后坐标数据:{JsonConvert.SerializeObject(res.defectInfor2RestorationDeskPage)}");
|
||
if (order.DefectInfoList == null)
|
||
order.DefectInfoList = new List<DefectInfo>();
|
||
foreach (var item in res.defectInfor2RestorationDeskPage)
|
||
order.DefectInfoList.Add(new DefectInfo()
|
||
{
|
||
Type = 1,
|
||
Code = item[3],
|
||
X = double.Parse(item[1]),
|
||
Y = double.Parse(item[2]),
|
||
ZXD = double.Parse(item[4]),
|
||
ModifyUserCode = Config.loginUser.Code,
|
||
CreateUserCode = Config.loginUser.Code,
|
||
});
|
||
}
|
||
|
||
//比对失败的图片 -- 用于修复台调用
|
||
Bitmap bmpCompareFailZoomImage = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(res.Zoom_Image_mat);
|
||
lstCompareFailZoomImage.Add(bmpCompareFailZoomImage);
|
||
if (Config.SizeBmp_Zoom_Image_SavePath != "" && Directory.Exists(Config.SizeBmp_Zoom_Image_SavePath))
|
||
{
|
||
string path = Util.createSubDir(Config.SizeBmp_Zoom_Image_SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
|
||
//path += $"Size_SN{order.SN}_I{res.index}_X{res.Defects_X}_Y{res.Defects_Y}_C0_{ model.StepInfo.Name}";
|
||
path += $"Size_SN{order.SN}_I{compBmpIndex}_X{res.posX}_Y{res.posY}_C0_{ model.StepInfo.Name}";
|
||
bmpCompareFailZoomImage.Save(path + ".bmp", ImageFormat.Bmp);
|
||
if (res.defectInfor2RestorationDesk != null && res.defectInfor2RestorationDesk.Count > 0)
|
||
File.WriteAllText(path + ".json", JsonConvert.SerializeObject(res.defectInfor2RestorationDesk));
|
||
}
|
||
//保存原图
|
||
if (Config.SizeBmp_Compare_SavePath != "" && Directory.Exists(Config.SizeBmp_Compare_SavePath))
|
||
{
|
||
string path = Util.createSubDir(Config.SizeBmp_Compare_SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
|
||
path += $"Size_SN{order.SN}_I{res.index}_X{res.posX}_Y{res.posY}_{ model.StepInfo.Name}.bmp";
|
||
AddTextEvent($"{res.stepIndex + 1}-{processName}", $"未通过图片保存:{path}");
|
||
if (res.bmp != null)
|
||
res.bmp.Save(path, ImageFormat.Bmp);
|
||
else
|
||
API.CopyFile(res.file_path, path, false);//比.NET(File.Copy)更快
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//warning(WarningEnum.Low);//暂停
|
||
setDgvContentCol(liStatocStepIndex, $"index:{res.index},图像比对失败!");
|
||
AddTextEvent($"{res.stepIndex + 1}-{res.processName}", $"图像比对失败,index:{res.index}-{compBmpIndex}.", WarningEnum.Low);
|
||
}
|
||
compBmpIndex++;
|
||
}
|
||
//MARK
|
||
else if (res.index == 111 || res.index == 222 || res.index == 333 || res.index == 444)
|
||
{
|
||
AddTextEvent($"{res.stepIndex + 1}-{processName}", $"Mark点 Index={res.index},结果记录...");
|
||
if (res.index == 333) this.contoursAffineTrans1_Out = res.ContoursAffineTrans1_Out;//不管成功失败都替换
|
||
if (res.isSucceed)
|
||
{
|
||
Thread.Sleep(100);
|
||
AddTextEvent($"{res.stepIndex + 1}-{processName}", $"Mark点 Index={res.index}; 当前值:{string.Join(",", res.MarkPointList)}");
|
||
JArray markDatas;
|
||
if (string.IsNullOrWhiteSpace(order.MarkData))
|
||
markDatas = new JArray() { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||
else
|
||
markDatas = JArray.Parse(order.MarkData);
|
||
for (int i = 0; i < res.MarkPointList.Count(); i++)
|
||
if (res.MarkPointList[i] != 0)
|
||
markDatas[i] = res.MarkPointList[i];
|
||
order.MarkData = markDatas.ToString();
|
||
setDgvContentCol(liStatocStepIndex, $"index:{res.index},Mark点:{order.MarkData} ");
|
||
AddTextEvent($"{res.stepIndex + 1}-{processName}", $"Mark点 Index={res.index};合并后:{order.MarkData}");
|
||
}
|
||
else
|
||
{
|
||
//warning(WarningEnum.Low);//暂停
|
||
setDgvContentCol(liStatocStepIndex, $"index:{res.index},Mark点计算失败!");
|
||
AddTextEvent($"{res.stepIndex + 1}-{processName}", $"Mark点计算失败,index:{res.index}.", WarningEnum.Low);
|
||
}
|
||
|
||
//保存
|
||
if (Config.SizeBmp_SavePath != "" && Directory.Exists(Config.SizeBmp_SavePath))
|
||
{
|
||
string path = Util.createSubDir(Config.SizeBmp_SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
|
||
path += $"Size_SN{order.SN}_I{res.index}_X{res.posX}_Y{res.posY}_{ model.StepInfo.Name}.bmp";
|
||
if (res.bmp != null)
|
||
res.bmp.Save(path, ImageFormat.Bmp);
|
||
else
|
||
API.CopyFile(res.file_path, path, false);//比.NET(File.Copy)更快
|
||
}
|
||
}
|
||
else
|
||
{
|
||
int roundIndex = res.index % 10;
|
||
if (res.isSucceed)
|
||
{
|
||
string tagOutData = "";
|
||
if (res.index == 3333 && !string.IsNullOrWhiteSpace(res.sizeTag))
|
||
{
|
||
tagOutData = $"Tag:{res.sizeTag},posePT:[{string.Join(",", res.posePT)}]";
|
||
if (res.posePT.Length < 2 || res.posePT.Length % 2 != 0)
|
||
{
|
||
AddTextEvent($"{res.stepIndex + 1}-{res.processName}", $"尺寸检测输出Tag对应posePT非法: {tagOutData}", WarningEnum.High);
|
||
warning(WarningEnum.High);//急停
|
||
return;
|
||
}
|
||
|
||
if (order.SizeTagDataList == null)
|
||
order.SizeTagDataList = new List<SizeTagData>();
|
||
order.SizeTagDataList.Add(new SizeTagData()
|
||
{
|
||
SizeTag = res.sizeTag,
|
||
CreateStepIndex = res.stepIndex + 1,
|
||
posePT= string.Join(",", res.posePT)// 回转 Array.ConvertAll(sNums , double.Parse);
|
||
});
|
||
|
||
}
|
||
|
||
setDgvContentCol(liStatocStepIndex, $"index:{res.index},PT1:{res.PT1},PT2:{res.PT2},Shanxian:{res.Shanxian},Circle_Xmm:{res.Circle_Xmm},Circle_Ymm:{res.Circle_Ymm},offsetX:{res.offsetX},offsetY:{res.offsetY}, {tagOutData}");
|
||
AddTextEvent($"{res.stepIndex + 1}-{res.processName}", $"尺寸检测完成 index:{res.index},PT1:{res.PT1},PT2:{res.PT2},Shanxian:{res.Shanxian},Circle_Xmm:{res.Circle_Xmm},Circle_Ymm:{res.Circle_Ymm},offsetX:{res.offsetX},offsetY:{res.offsetY}, {tagOutData} ");
|
||
//测量
|
||
//------TEST
|
||
if (res.index>20 && res.index<30)
|
||
{
|
||
lock (lstPT)
|
||
{
|
||
lstPT.Add(Math.Round(res.PT1, 4));
|
||
updatePTValueTest(model.PTBaseValue + model.PTUpFloatValue, model.PTBaseValue - model.PTDownFloatValue);
|
||
}
|
||
}
|
||
//------
|
||
if (roundIndex > 0)//1-9测量
|
||
{
|
||
if (res.index < 10)//11-13 (PT: 7-9 => 21-29(PT1)) 不用管,李工处理
|
||
{
|
||
//if (roundIndex >= 7)
|
||
//{
|
||
// lock (lstPT)
|
||
// {
|
||
// lstPT.Add(Math.Round(res.PT1, 4));
|
||
// lstPT.Add(res.index == 8 ? 0 : Math.Round(res.PT2, 4));
|
||
// updatePTValue(model.PTBaseValue + model.PTUpFloatValue, model.PTBaseValue - model.PTDownFloatValue);
|
||
// }
|
||
//}
|
||
|
||
lock (lstLineWidth)
|
||
{
|
||
lstLineWidth.Add(res.Shanxian > 0 ? Math.Round(res.Shanxian, 2) : 0);
|
||
updateLineWidthValue(model.LineWidthBaseValue + model.LineWidthUpFloatValue, model.LineWidthBaseValue - model.LineWidthDownFloatValue);
|
||
}
|
||
}
|
||
}
|
||
//校正偏移 10,20,30...:偏移
|
||
else
|
||
{
|
||
AxMoveMode axSizeMode = AxMoveMode.绝对位置;
|
||
double xPos = 0;
|
||
double yPos = 0;
|
||
//绝对偏移
|
||
if (res.offsetX != 0 || res.offsetY != 0)
|
||
{
|
||
xPos += res.offsetX;
|
||
yPos += res.offsetY;
|
||
AddTextEvent($"{res.stepIndex + 1}-{res.processName}", $"offsetX/Y绝对校正, 0轴:{xPos}mm, 2轴:{yPos}mm");
|
||
}
|
||
else if (res.Circle_Xmm != 0 || res.Circle_Ymm != 0)//相对偏移校正
|
||
{
|
||
axSizeMode = AxMoveMode.相对位置;
|
||
AddTextEvent($"{res.stepIndex + 1}-{res.processName}", $"原点相对校正, 0轴:{res.Circle_Xmm}mm, 2轴:{res.Circle_Ymm}mm");
|
||
if (res.Circle_Xmm != 0) xPos = res.Circle_Xmm;
|
||
if (res.Circle_Ymm != 0) yPos = res.Circle_Ymm;
|
||
}
|
||
//当前工序直接移动
|
||
if (xPos != 0 || yPos != 0)
|
||
{
|
||
devContainer.devAxis.setAxisVelParam(0.1, 1, 1, 1, 0);
|
||
devContainer.devAxis.setAxisVelParam(0.1, 1, 1, 1, 2);
|
||
if (xPos != 0) devContainer.devAxis.move_ptp(0, xPos, axSizeMode);
|
||
if (yPos != 0) devContainer.devAxis.move_ptp(2, yPos, axSizeMode);
|
||
while (!devContainer.devAxis.isReady(0) || !devContainer.devAxis.isReady(2))
|
||
{
|
||
Thread.Sleep(100);
|
||
if (isBreakProcessRun())
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
//保存
|
||
//string sizeFileName = Config.Size_SavePath + "\\" + DateTime.Now.ToString("yyyyMMdd_HHmmss_fff");
|
||
//API.CopyFile(res.file_path, defectFileName + ".bmp", false);//更快
|
||
//File.WriteAllText(defectFileName + ".json", JsonConvert.SerializeObject(res.informationList));
|
||
}
|
||
//失败
|
||
else
|
||
{
|
||
//------TEST
|
||
if (res.index > 20 && res.index < 30)
|
||
{
|
||
lock (lstPT)
|
||
{
|
||
lstPT.Add(0);
|
||
updatePTValueTest(model.PTBaseValue + model.PTUpFloatValue, model.PTBaseValue - model.PTDownFloatValue);
|
||
}
|
||
}
|
||
//------
|
||
|
||
if (roundIndex > 0)
|
||
{
|
||
//if (roundIndex >= 7)
|
||
//{
|
||
// lock (lstPT)
|
||
// {
|
||
// lstPT.Add(0);
|
||
// lstPT.Add(0);
|
||
// updatePTValue(model.PTBaseValue + model.PTUpFloatValue, model.PTBaseValue - model.PTDownFloatValue);
|
||
// }
|
||
//}
|
||
|
||
lock (lstLineWidth)
|
||
{
|
||
lstLineWidth.Add(0);
|
||
updateLineWidthValue(model.LineWidthBaseValue + model.LineWidthUpFloatValue, model.LineWidthBaseValue - model.LineWidthDownFloatValue);
|
||
}
|
||
}
|
||
setDgvContentCol(liStatocStepIndex, $"失败:{res.resultInfo}");
|
||
AddTextEvent($"{res.stepIndex + 1}-{res.processName}", $"尺寸检测失败index:{res.index}:{res.resultInfo}");
|
||
//warning(WarningEnum.Low);//暂停 这里不能暂停,stepIndex和scannerBmpQueue队列也不对了
|
||
}
|
||
|
||
//保存
|
||
if (Config.SizeBmp_SavePath != "" && Directory.Exists(Config.SizeBmp_SavePath))
|
||
{
|
||
string path = Util.createSubDir(Config.SizeBmp_SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
|
||
path += $"Size_SN{order.SN}_I{res.index}_X{res.posX}_Y{res.posY}_{ model.StepInfo.Name}.bmp";
|
||
if (res.bmp != null)
|
||
res.bmp.Save(path, ImageFormat.Bmp);
|
||
else
|
||
API.CopyFile(res.file_path, path, false);//比.NET(File.Copy)更快
|
||
}
|
||
}
|
||
}
|
||
catch(Exception ex)
|
||
{
|
||
AddTextEvent($"{res.stepIndex + 1}-{res.processName}", $"尺寸检测回调处理异常 index:{res.index},ex={ex.Message}");
|
||
}
|
||
|
||
//
|
||
//if (!asynRun)//是否异步执行endEvent.Set()都没问题
|
||
endEvent.Set();//roundIndex=0成功或失败线程返回
|
||
//---
|
||
if (res.bmp != null)
|
||
{
|
||
res.bmp.Dispose();
|
||
res.bmp = null;
|
||
}
|
||
else
|
||
{
|
||
API.DeleteFile(res.file_path);
|
||
}
|
||
}
|
||
});
|
||
|
||
//需等上面异步回调中的相对偏移校正完成再继续
|
||
if (!asynRun || sizeIndex % 10==0)
|
||
{
|
||
if (!endEvent.WaitOne(60000))
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"{sizeIndex}等待超时,忽略继续!", WarningEnum.Low);
|
||
}
|
||
#endregion
|
||
break;
|
||
case "Defect":
|
||
#region
|
||
limitThresholdVal = processParam.Value<double>("LimitThresholdVal");
|
||
lowerThresholdVal = processParam.Value<double>("LowerThresholdVal");
|
||
if (scannerGBmpQueue.Count < 1)
|
||
{
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"缺陷检测异常,无源图像!!", WarningEnum.Low);
|
||
warning(WarningEnum.Low);//终止
|
||
return stepIndex;
|
||
}
|
||
var bmpLoc = scannerGBmpQueue.Dequeue();
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"开始缺陷检测,源图索引:{defectBmpNum},图像队列数量: {scannerGBmpQueue.Count}...");
|
||
string[] aarCut_size = processParam.Value<string>("CutSize").Split(',');
|
||
string[] aarResize = processParam.Value<string>("Resize").Split(',');
|
||
//图纸
|
||
attachmentFile = model.AttachmentList.FirstOrDefault(x => x.Type == 0);
|
||
if (attachmentFile != null)
|
||
{
|
||
gbxBmpPath = Application.StartupPath + $"\\Attachment\\product\\{attachmentFile.NameTimestamp}";
|
||
if (!File.Exists(gbxBmpPath + attachmentFile.ExtendName)) gbxBmpPath = "";
|
||
}
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"图纸路径:{gbxBmpPath}");
|
||
devContainer.libDefect.add(new DefectTask()
|
||
{
|
||
stepIndex= stepIndex,
|
||
processName= processName,
|
||
drawingPagePath= gbxBmpPath,
|
||
index = defectBmpNum++,
|
||
bmp = bmpLoc.bmp,
|
||
Xmm = bmpLoc.Xmm,
|
||
Ymm = bmpLoc.Ymm,
|
||
cut_size = new System.Drawing.Size(Convert.ToInt32(aarCut_size[0]), Convert.ToInt32(aarCut_size[1])),
|
||
resize = new System.Drawing.Size(Convert.ToInt32(aarResize[0]), Convert.ToInt32(aarResize[1])),
|
||
thresholds = processParam.Value<float>("Thresholds"),
|
||
thresholdsClass = processParam.Value<string>("ThresholdsClass"),
|
||
recAreaThreshold= getProductAreaThreshol(model), //qxName,面积; qxName,面积; qxName,面积;
|
||
finishEvent = (res) =>
|
||
{
|
||
if (res.isSucceed)
|
||
{
|
||
setDgvContentCol(liStatocStepIndex, $"源图索引:{res.index},缺陷数:{res.defectCount},处理时间(ms):{string.Join("->", res.stopwatch.Select(i => i.ToString()).ToArray())}");
|
||
AddTextEvent($"{res.stepIndex + 1}-{res.processName}", $"缺陷检测完成(源图索引:{res.index}),缺陷数:{res.defectCount},处理时间(ms):{string.Join("->", res.stopwatch.Select(i => i.ToString()).ToArray())}");
|
||
string path;
|
||
if (res.defectCount > 0)
|
||
{
|
||
//UI显示小图 (含统计缺陷类型数量)
|
||
showDefectSmallBmps(res.bmps_tag, res.bmps_cut, res.Xmm, res.Ymm, res.informationList);
|
||
if (res.defectInfor2RestorationDeskPage != null && res.defectInfor2RestorationDeskPage.Count > 0)
|
||
{
|
||
AddTextEvent($"{res.stepIndex + 1}-{res.processName}", $"转换后坐标数据:{JsonConvert.SerializeObject(res.defectInfor2RestorationDeskPage)}");
|
||
if (order.DefectInfoList == null)
|
||
order.DefectInfoList = new List<DefectInfo>();
|
||
foreach (var item in res.defectInfor2RestorationDeskPage)
|
||
order.DefectInfoList.Add(new DefectInfo()
|
||
{
|
||
Type = 0,
|
||
Code = item[3],
|
||
X = double.Parse(item[1]),
|
||
Y = double.Parse(item[2]),
|
||
ZXD = double.Parse(item[4]),
|
||
ModifyUserCode = Config.loginUser.Code,
|
||
CreateUserCode = Config.loginUser.Code,
|
||
});
|
||
}
|
||
//保存原始大图
|
||
if (Config.Defect_SavePath != "" && Directory.Exists(Config.Defect_SavePath))
|
||
{
|
||
path = Util.createSubDir(Config.Defect_SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
|
||
path += $"Defect_SN{order.SN}_I{res.index}_X{res.Xmm}_Y{res.Ymm}_C{res.defectCount}_{ model.StepInfo.Name}";
|
||
//API.CopyFile(res.file_path, defectFileName + ".bmp", false);//比.NET(File.Copy)更快
|
||
//res.bmp.SaveImage(path + ".bmp");//opencv保存格式与BMP不同
|
||
OpenCvSharp.Extensions.BitmapConverter.ToBitmap(res.bmp).Save(path + ".bmp", ImageFormat.Bmp);
|
||
File.WriteAllText(path + ".json", JsonConvert.SerializeObject(res.informationList));
|
||
}
|
||
|
||
//保存小图
|
||
if (Config.Defect_Small_SavePath != "" && Directory.Exists(Config.Defect_Small_SavePath))
|
||
{
|
||
path = Util.createSubDir(Config.Defect_Small_SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
|
||
path += $"Defect_SN{order.SN}_I{res.index}_X{res.Xmm}_Y{res.Ymm}_{ model.StepInfo.Name}";
|
||
for (int i = 0; i < res.bmps_tag.Count(); i++)
|
||
res.bmps_tag[i].Save(path + $"_i{i}.bmp", ImageFormat.Bmp);
|
||
}
|
||
|
||
//保存压缩大图 -- 用于修复台调用
|
||
if (Config.Defect_Compress_SavePath != "" && Directory.Exists(Config.Defect_Compress_SavePath))
|
||
{
|
||
path = Util.createSubDir(Config.Defect_Compress_SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
|
||
path += $"Defect_SN{order.SN}_I{res.index}_X{res.Xmm}_Y{res.Ymm}_C{res.defectCount}_{ model.StepInfo.Name}";
|
||
//res.bmpCompress.SaveImage(path + ".bmp");//opencv保存格式与BMP不同
|
||
OpenCvSharp.Extensions.BitmapConverter.ToBitmap(res.bmpCompress).Save(path + ".bmp", ImageFormat.Bmp);
|
||
File.WriteAllText(path + ".json", JsonConvert.SerializeObject(res.defectInfor2RestorationDesk));
|
||
}
|
||
}
|
||
else//没有缺陷
|
||
{
|
||
if (Config.SaveAllDefectImg && Config.Defect_SavePath != "" && Directory.Exists(Config.Defect_SavePath))
|
||
{
|
||
path = Util.createSubDir(Config.Defect_SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
|
||
path += $"Defect_SN{order.SN}_I{res.index}_X{res.Xmm}_Y{res.Ymm}_C{res.defectCount}_{ model.StepInfo.Name}";
|
||
//API.CopyFile(res.file_path, defectFileName + ".bmp", false);//比.NET(File.Copy)更快
|
||
//res.bmp.SaveImage(path + ".bmp");//opencv保存格式与BMP不同
|
||
OpenCvSharp.Extensions.BitmapConverter.ToBitmap(res.bmp).Save(path + ".bmp", ImageFormat.Bmp);
|
||
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
setDgvContentCol(liStatocStepIndex, $"失败:{res.resultInfo}");
|
||
AddTextEvent($"{res.stepIndex + 1}-{res.processName}", $"缺陷检测失败:{res.resultInfo}");
|
||
//warning(WarningEnum.Low);//暂停 这里不能暂停,stepIndex和scannerBmpQueue队列也不对了
|
||
}
|
||
defectBmpNumResult++;
|
||
foreach (var item in res.bmps_cut)
|
||
item.Dispose();
|
||
res.bmp.Dispose();
|
||
res.bmp = null;
|
||
res.bmps_tag = null;
|
||
if (res.bmpCompress != null)
|
||
{
|
||
res.bmpCompress.Dispose();
|
||
res.bmpCompress = null;
|
||
}
|
||
System.GC.Collect();
|
||
}
|
||
});
|
||
#endregion
|
||
break;
|
||
case "For":
|
||
#region
|
||
long UniqueId = processParam.Value<long>("UniqueId");
|
||
int GotoStepIndex = processParam.Value<int>("GotoStepIndex");//1-n
|
||
int LimitNum = processParam.Value<int>("LimitNum");//1-n
|
||
bool Reset = processParam.Value<bool>("Reset");
|
||
if (GotoStepIndex - 1 == stepIndex)
|
||
{
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"For死循环!!!");
|
||
warning(WarningEnum.High);
|
||
return stepIndex;
|
||
}
|
||
if (!devContainer.libFor.dicData.ContainsKey(UniqueId))
|
||
devContainer.libFor.dicData.Add(UniqueId, 0);
|
||
//
|
||
int Num = devContainer.libFor.dicData[UniqueId];
|
||
Num++;
|
||
if (Num <= LimitNum)
|
||
{
|
||
if (Num == LimitNum)
|
||
{
|
||
setDgvContentCol(liStatocStepIndex, $"第[{Num}/{LimitNum}]次,循环完成");
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"第[{Num}/{LimitNum}]次,循环完成。");
|
||
}
|
||
else
|
||
{
|
||
setDgvContentCol(liStatocStepIndex, $"第[{Num}/{LimitNum}]次");
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"第[{Num}/{LimitNum}]次跳转到步骤[{GotoStepIndex}]...");
|
||
stepIndex = GotoStepIndex - 2;
|
||
}
|
||
devContainer.libFor.dicData[UniqueId] = Num;
|
||
}
|
||
else
|
||
{
|
||
setDgvContentCol(liStatocStepIndex, $"已失效不执行");
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"本循环已失效不执行!");
|
||
}
|
||
|
||
//达到limit重置0
|
||
if (devContainer.libFor.dicData[UniqueId] >= LimitNum && Reset)
|
||
{
|
||
devContainer.libFor.dicData[UniqueId] = 0;
|
||
setDgvContentCol(liStatocStepIndex, $"第[0/{LimitNum}]次");
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"计数器已重置。");
|
||
}
|
||
#endregion
|
||
break;
|
||
case "If":
|
||
#region
|
||
long UniqueId_if = processParam.Value<long>("UniqueId");
|
||
int GotoStepIndex_if = processParam.Value<int>("GotoStepIndex");//1-n
|
||
int LimitNum_if = processParam.Value<int>("LimitNum");//1-n
|
||
bool Reset_if = processParam.Value<bool>("Reset");
|
||
if (GotoStepIndex_if - 1 == stepIndex)
|
||
{
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"If死循环,不可自我跳转!!!");
|
||
warning(WarningEnum.High);
|
||
return stepIndex;
|
||
}
|
||
//
|
||
if (!devContainer.libIF.dicData.ContainsKey(UniqueId_if))
|
||
devContainer.libIF.dicData.Add(UniqueId_if, 0);
|
||
//
|
||
int Num_if = devContainer.libIF.dicData[UniqueId_if];
|
||
Num_if++;
|
||
if (Num_if <= LimitNum_if)
|
||
{
|
||
if (Num_if == LimitNum_if)
|
||
{
|
||
setDgvContentCol(liStatocStepIndex, $"第[{Num_if}/{LimitNum_if}]次,跳转至[{GotoStepIndex_if}]");
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"计数器[{Num_if}/{LimitNum_if}],跳转至步骤[{GotoStepIndex_if}]...");
|
||
stepIndex = GotoStepIndex_if - 2;
|
||
}
|
||
else
|
||
{
|
||
setDgvContentCol(liStatocStepIndex, $"第[{Num_if}/{LimitNum_if}]次,不跳转");
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"计数器[{Num_if}/{LimitNum_if}],不跳转。");
|
||
}
|
||
//
|
||
devContainer.libIF.dicData[UniqueId_if] = Num_if;
|
||
}
|
||
else
|
||
{
|
||
setDgvContentCol(liStatocStepIndex, $"已失效不执行");
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"本IF已失效不执行。");
|
||
}
|
||
|
||
//达到limit重置0
|
||
if (devContainer.libIF.dicData[UniqueId_if] >= LimitNum_if && Reset_if)
|
||
{
|
||
devContainer.libIF.dicData[UniqueId_if] = 0;
|
||
setDgvContentCol(liStatocStepIndex, $"第[0/{LimitNum_if}]次");
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"计数器已重置。");
|
||
}
|
||
#endregion
|
||
break;
|
||
default:
|
||
AddTextEvent($"{stepIndex + 1}-{processName}", $"未知工序:{processInfo.ProcessCode}");
|
||
warning(WarningEnum.High);
|
||
return stepIndex;
|
||
}
|
||
if (sleepLater > 0) Thread.Sleep((int)sleepLater);
|
||
}
|
||
|
||
//============结束,判断是否自动下料
|
||
if (stepIndex == processList.Count - 1)
|
||
{
|
||
//厚度校正 直接更新并保存
|
||
if (isProductRevise)
|
||
{
|
||
isProductRevise = false;
|
||
if (MessageBox.Show($"厚度校正完成,是否保存?\r\nBase值:{model.HeightBaseDec}", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
|
||
{
|
||
//保存 //更新指定列
|
||
if (svcProduct.Update(it => new Product() { HeightBaseDec = model.HeightBaseDec }, it => it.Id == model.Id))
|
||
AddTextEvent($"产品校正", $"保存成功。");
|
||
else
|
||
AddTextEvent($"产品校正", $"保存失败!!");
|
||
}
|
||
//下料
|
||
currentState = CurrentStateEnum.自动流程结束;
|
||
gotoDownPT();
|
||
}
|
||
else//生产
|
||
{
|
||
//等待缺陷图显示完成
|
||
while (defectBmpNum != defectBmpNumResult)
|
||
Thread.Sleep(100);
|
||
|
||
//判断是否合格
|
||
DefectCodeEnum defectCode;
|
||
string defectNames = "";
|
||
if (model.QualifiedCriterionList!= null && model.QualifiedCriterionList.Count >0)
|
||
{
|
||
int itemDefectCount;
|
||
foreach (var item in model.QualifiedCriterionList)
|
||
{
|
||
defectCode = EnumUtil.Convert2Enum<DefectCodeEnum>(item.DefectCode);
|
||
itemDefectCount = getDefectCountFromCode(order, defectCode);
|
||
if (item.MaxDefectCount>-1 && itemDefectCount > item.MaxDefectCount)
|
||
{
|
||
order.Qualified = false;
|
||
defectNames += $"{((DefectNameEnum)(int)defectCode).ToString()}({itemDefectCount}),";
|
||
}
|
||
}
|
||
}
|
||
|
||
stopWatch.Stop();
|
||
long timeLen = stopWatch.ElapsedMilliseconds / 1000;
|
||
this.BeginInvoke(new System.Action(() =>
|
||
{
|
||
lblTimeLen.Visible = true;
|
||
lblTimeLen.Text = $"检测时长: {timeLen} 秒";
|
||
if (defectNames != "")
|
||
{
|
||
lblDefectResult.Text = "未通过";
|
||
lblDefectResultCount.Text = defectNames.Substring(0, defectNames.Length - 1);
|
||
this.toolTip1.SetToolTip(lblDefectResultCount, lblDefectResultCount.Text);
|
||
lblDefectResult.ForeColor = lblDefectResultCount.ForeColor = Color.Red;
|
||
}
|
||
}));
|
||
order.TimeLen = timeLen;
|
||
order.DefectCount = (int)this.gboxDefectList.Tag;
|
||
order.Succeed = true;
|
||
order.ModifyUserCode = order.CreateUserCode = Config.loginUser.Code;
|
||
//如SN检测已存在,先删除
|
||
var oldSNOrder= svcOrder.GetFirst(m=> m.SN==order.SN);
|
||
if(oldSNOrder!=null)
|
||
{
|
||
AddTextEvent("删除记录", $"删除上一重复SN检测记录:SN={oldSNOrder.SN}, Date={oldSNOrder.CreateTime}");
|
||
svcOrder.DelNav(oldSNOrder);
|
||
}
|
||
if (!svcOrder.InsertNav(order))//导航插入
|
||
AddTextEvent("保存失败", $"保存生产记录失败!");
|
||
//更新本批次检测数量
|
||
if (!string.IsNullOrWhiteSpace(model.BatchId))
|
||
{
|
||
var expOrder = Expressionable.Create<Order>()
|
||
.And(m => m.ProductId == model.Id)
|
||
.And(m => m.BatchId == model.BatchId)
|
||
.ToExpression();//注意 这一句 不能少
|
||
currProductModel.CompleteCount = svcOrder.Count(expOrder);
|
||
}
|
||
//以主键为条件更新CompleteCount单列值
|
||
svcProduct.Update(it => new Product() { CompleteCount = currProductModel.CompleteCount }, it => it.Id == currProductModel.Id);
|
||
|
||
if (Config.MakeTag && order.DefectCount > 0)//要打标 and 有缺陷图
|
||
{
|
||
AddTextEvent("完成", $"工序结束,用时 {order.TimeLen} 秒;缺陷 {order.DefectCount} 张.");
|
||
//+(Config.MakeTag ? "开始自动打标...":"手动打标..."));
|
||
currentPT = CurrentPTEnum.MakeTag;
|
||
currentState = CurrentStateEnum.打标中;
|
||
setButtonEnabled(tsbtnGoDownPT, true);
|
||
setButtonEnabled(tsbtnReset, true);
|
||
setButtonEnabled(btnMakeTags, true);
|
||
//if (!Config.MakeTag)//自动打标
|
||
{
|
||
this.Invoke(new System.Action(() =>
|
||
{
|
||
btnMakeTag_Click(null, null);
|
||
}));
|
||
}
|
||
}
|
||
else//下料
|
||
{
|
||
AddTextEvent("完成", $"用时 {order.TimeLen} 秒,进行下料...");
|
||
currentState = CurrentStateEnum.自动流程结束;
|
||
gotoDownPT();
|
||
}
|
||
}
|
||
|
||
currProcessIndex = -1;
|
||
return -1;
|
||
}
|
||
else //继续
|
||
{
|
||
return ++stepIndex;
|
||
//return nextProcess(model, ++stepIndex);
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
AddTextEvent("工序", $"[{stepIndex+1}] Err:" + ex.Message+"\n"+ex.StackTrace);
|
||
warning(WarningEnum.Low);
|
||
return -2;
|
||
}
|
||
}
|
||
private Dictionary<string, float> getProductAreaThreshol(Product m)
|
||
{
|
||
Dictionary<string, float> dic = new Dictionary<string, float>();
|
||
foreach(var item in m.QualifiedCriterionList)
|
||
dic.Add(item.DefectCode, (float)(item.Size * 25.4 * 25.4 / m.HoleCount / m.HoleCount) );//网目 => mm^2
|
||
|
||
//全缺陷项
|
||
var lstDefect = Utils.EnumUtil.GetArrayList<DefectCodeEnum>();
|
||
foreach (DictionaryEntry item in lstDefect)
|
||
{
|
||
string code = item.Value.ToString();
|
||
if (!dic.ContainsKey(code))
|
||
dic.Add(code, 0);
|
||
}
|
||
|
||
return dic;
|
||
}
|
||
private void setDgvContentCol(int rowIndex, string info)
|
||
{
|
||
int row = rowIndex;//why -1 ???
|
||
this.Invoke(new System.Action(() =>
|
||
{
|
||
this.dgvProcess.Rows[row].Cells["colValue"].Value = info;
|
||
}));
|
||
}
|
||
/// <summary>
|
||
/// 报警,只响应low,high
|
||
/// </summary>
|
||
private void warning(WarningEnum level, bool buzzer = true)
|
||
{
|
||
if (level == WarningEnum.Normal)
|
||
return;
|
||
|
||
lock(myLock)
|
||
warningLevel = level;
|
||
if (level == WarningEnum.Low)//暂停
|
||
{
|
||
currentState = CurrentStateEnum.暂停;
|
||
pauseCommand(buzzer);
|
||
}
|
||
else if (level == WarningEnum.High)//急停
|
||
{
|
||
currentState = CurrentStateEnum.急停;
|
||
devContainer.devAxis.stopNow();
|
||
|
||
stopNowCommand();
|
||
}
|
||
|
||
//启用报警消除按钮
|
||
this.Invoke(new System.Action(() =>
|
||
{
|
||
tsbtnWarning.Enabled = true;
|
||
}));
|
||
}
|
||
private void updateTensionValue(double upperLimit,double lowerLimit)
|
||
{
|
||
int count = lstTension.Count();
|
||
if (count < 1) return;
|
||
switch (count)
|
||
{
|
||
case 1:
|
||
order.Tension1 = lstTension[count - 1];
|
||
AddTextEvent("张力值", $"张力1:{order.Tension1}");
|
||
break;
|
||
case 2:
|
||
order.Tension2 = lstTension[count - 1];
|
||
AddTextEvent("张力值", $"张力2:{order.Tension2}");
|
||
break;
|
||
case 3:
|
||
order.Tension3 = lstTension[count - 1];
|
||
AddTextEvent("张力值", $"张力3:{order.Tension3}");
|
||
break;
|
||
case 4:
|
||
order.Tension4 = lstTension[count - 1];
|
||
AddTextEvent("张力值", $"张力4:{order.Tension4}");
|
||
break;
|
||
case 5:
|
||
order.Tension5 = lstTension[count - 1];
|
||
AddTextEvent("张力值", $"张力5:{order.Tension5}");
|
||
break;
|
||
}
|
||
|
||
double value = Math.Round(lstTension.Average(), 2);
|
||
double valueMax = lstTension.Max();
|
||
double valueMin = lstTension.Min();
|
||
if (order != null) order.TensionValue = value;
|
||
Color color = (upperLimit+ lowerLimit>0 && (value > upperLimit || value < lowerLimit)) ? Color.Red : Color.White;
|
||
Color colorMax = (upperLimit + lowerLimit > 0 && (valueMax > upperLimit || valueMax < lowerLimit)) ? Color.Red : Color.White;
|
||
Color colorMin = (upperLimit + lowerLimit > 0 && (valueMin > upperLimit || valueMin < lowerLimit)) ? Color.Red : Color.White;
|
||
this.BeginInvoke(new System.Action(() =>
|
||
{
|
||
this.lblTension.Text = Math.Round(value, 2).ToString();
|
||
this.lblTension.ForeColor = color;
|
||
|
||
this.lblTensionMax.Text = Math.Round(valueMax, 2).ToString();
|
||
this.lblTensionMax.ForeColor = colorMax;
|
||
|
||
this.lblTensionMin.Text = Math.Round(valueMin, 2).ToString();
|
||
this.lblTensionMin.ForeColor = colorMin;
|
||
}));
|
||
//不合格
|
||
if (color == Color.Red) order.Qualified = false;
|
||
}
|
||
private void updateHeightValue(double upperLimit, double lowerLimit)
|
||
{
|
||
int count = lstHeight.Count();
|
||
if (count < 1) return;
|
||
AddTextEvent("厚度", string.Join(",", lstHeight));
|
||
switch (count)
|
||
{
|
||
case 1:
|
||
order.Height1 = lstHeight[count - 1];
|
||
AddTextEvent("厚度值", $"厚度1:{order.Height1}");
|
||
break;
|
||
case 2:
|
||
order.Height2 = lstHeight[count - 1];
|
||
AddTextEvent("厚度值", $"厚度2:{order.Height2}");
|
||
break;
|
||
case 3:
|
||
order.Height3 = lstHeight[count - 1];
|
||
AddTextEvent("厚度值", $"厚度3:{order.Height3}");
|
||
break;
|
||
case 4:
|
||
order.Height4 = lstHeight[count - 1];
|
||
AddTextEvent("厚度值", $"厚度4:{order.Height4}");
|
||
break;
|
||
case 5:
|
||
order.Height5 = lstHeight[count - 1];
|
||
AddTextEvent("厚度值", $"厚度5:{order.Height5}");
|
||
break;
|
||
}
|
||
|
||
double value = Math.Round(lstHeight.Average(), 2);
|
||
double valueMax = lstHeight.Max();
|
||
double valueMin = lstHeight.Min();
|
||
if (order != null) order.HeightValue = value;
|
||
Color color = (upperLimit + lowerLimit > 0 && (value > upperLimit || value < lowerLimit)) ? Color.Red : Color.White;
|
||
Color colorMax = (upperLimit + lowerLimit > 0 && (valueMax > upperLimit || valueMax < lowerLimit)) ? Color.Red : Color.White;
|
||
Color colorMin = (upperLimit + lowerLimit > 0 && (valueMin > upperLimit || valueMin < lowerLimit)) ? Color.Red : Color.White;
|
||
this.Invoke(new System.Action(() =>
|
||
{
|
||
this.lblHeight.Text = Math.Round(value, 2).ToString();
|
||
this.lblHeight.ForeColor = color;
|
||
|
||
this.lblHeightMax.Text = Math.Round(valueMax, 2).ToString();
|
||
this.lblHeightMax.ForeColor = colorMax;
|
||
|
||
this.lblHeightMin.Text = Math.Round(valueMin, 2).ToString();
|
||
this.lblHeightMin.ForeColor = colorMin;
|
||
}));
|
||
//不合格
|
||
if (color == Color.Red) order.Qualified = false;
|
||
}
|
||
private void updateLineWidthValue(double upperLimit, double lowerLimit)
|
||
{
|
||
int count = lstLineWidth.Count();
|
||
if (count < 1) return;
|
||
switch (count)
|
||
{
|
||
case 1:
|
||
order.LineWidth1 = lstLineWidth[count - 1];
|
||
AddTextEvent("线宽值", $"线宽1:{order.LineWidth1}");
|
||
break;
|
||
case 2:
|
||
order.LineWidth2 = lstLineWidth[count - 1];
|
||
AddTextEvent("线宽值", $"线宽2:{order.LineWidth2}");
|
||
break;
|
||
case 3:
|
||
order.LineWidth3 = lstLineWidth[count - 1];
|
||
AddTextEvent("线宽值", $"线宽3:{order.LineWidth3}");
|
||
break;
|
||
case 4:
|
||
order.LineWidth4 = lstLineWidth[count - 1];
|
||
AddTextEvent("线宽值", $"线宽4:{order.LineWidth4}");
|
||
break;
|
||
case 5:
|
||
order.LineWidth5 = lstLineWidth[count - 1];
|
||
AddTextEvent("线宽值", $"线宽5:{order.LineWidth5}");
|
||
break;
|
||
case 6:
|
||
order.LineWidth6 = lstLineWidth[count - 1];
|
||
AddTextEvent("线宽值", $"线宽6:{order.LineWidth6}");
|
||
break;
|
||
case 7:
|
||
order.LineWidth7 = lstLineWidth[count - 1];
|
||
AddTextEvent("线宽值", $"线宽7:{order.LineWidth7}");
|
||
break;
|
||
case 8:
|
||
order.LineWidth8 = lstLineWidth[count - 1];
|
||
AddTextEvent("线宽值", $"线宽8:{order.LineWidth8}");
|
||
break;
|
||
case 9:
|
||
order.LineWidth9 = lstLineWidth[count - 1];
|
||
AddTextEvent("线宽值", $"线宽9:{order.LineWidth9}");
|
||
break;
|
||
}
|
||
List<double> lstValidValue = new List<double>();
|
||
for (int i = 0; i < count; i++)
|
||
{
|
||
if (lstLineWidth[i] > 0)
|
||
lstValidValue.Add(lstLineWidth[i]);
|
||
}
|
||
if (lstValidValue.Count < 1) return;//WLQ 前面失败时会向lstLineWidth.add(0)
|
||
|
||
double value = Math.Round(lstValidValue.Average(), 2);
|
||
double valueMax = lstValidValue.Max();
|
||
double valueMin = lstValidValue.Min();
|
||
if (order != null) order.LineWidthValue = value;
|
||
Color color = (upperLimit + lowerLimit > 0 && (value > upperLimit || value < lowerLimit)) ? Color.Red : Color.White;
|
||
Color colorMax = (upperLimit + lowerLimit > 0 && (valueMax > upperLimit || valueMax < lowerLimit)) ? Color.Red : Color.White;
|
||
Color colorMin = (upperLimit + lowerLimit > 0 && (valueMin > upperLimit || valueMin < lowerLimit)) ? Color.Red : Color.White;
|
||
this.Invoke(new System.Action(() =>
|
||
{
|
||
this.lblLineWidth.Text = Math.Round(value, 2).ToString();
|
||
this.lblLineWidth.ForeColor = color;
|
||
|
||
this.lblLineWidthMax.Text = Math.Round(valueMax, 2).ToString();
|
||
this.lblLineWidthMax.ForeColor = colorMax;
|
||
|
||
this.lblLineWidthMin.Text = Math.Round(valueMin, 2).ToString();
|
||
this.lblLineWidthMin.ForeColor = colorMin;
|
||
}));
|
||
//不合格
|
||
if (color == Color.Red) order.Qualified = false;
|
||
}
|
||
private void updatePTValue(double upperLimit, double lowerLimit)
|
||
{
|
||
//每次加2个:PT1,PT2
|
||
int count = lstPT.Count();
|
||
if (count < 1) return;
|
||
switch (count)
|
||
{
|
||
case 2:
|
||
order.PT1 = lstPT[count - 2];
|
||
order.PT2 = lstPT[count - 1];
|
||
AddTextEvent("PT值",$"PT1:{order.PT1},PT2:{order.PT2}");
|
||
break;
|
||
case 4:
|
||
order.PT3 = lstPT[count - 2];
|
||
order.PT4 = lstPT[count - 1];
|
||
AddTextEvent("PT值", $"PT3:{order.PT3},PT4:{order.PT4}");
|
||
break;
|
||
case 6:
|
||
order.PT5 = lstPT[count - 2];
|
||
order.PT6 = lstPT[count - 1];
|
||
AddTextEvent("PT值", $"PT5:{order.PT5},PT6:{order.PT6}");
|
||
break;
|
||
}
|
||
|
||
List<double> lstValidValue = new List<double>();
|
||
for (int i = 0; i < count; i++)
|
||
{
|
||
if (lstPT[i] > 0)
|
||
lstValidValue.Add(lstPT[i]);
|
||
}
|
||
double value = Math.Round(lstValidValue.Average(), 4);
|
||
double valueMax = lstValidValue.Max();
|
||
double valueMin = lstValidValue.Min();
|
||
if (order != null) order.PTValue = value;
|
||
Color color = (upperLimit + lowerLimit > 0 && (value > upperLimit || value < lowerLimit)) ? Color.Red : Color.White;
|
||
Color colorMax = (upperLimit + lowerLimit > 0 && (valueMax > upperLimit || valueMax < lowerLimit)) ? Color.Red : Color.White;
|
||
Color colorMin = (upperLimit + lowerLimit > 0 && (valueMin > upperLimit || valueMin < lowerLimit)) ? Color.Red : Color.White;
|
||
this.Invoke(new System.Action(() =>
|
||
{
|
||
this.lblPT.Text = value.ToString();
|
||
this.lblPT.ForeColor = color;
|
||
|
||
this.lblPTMax.Text = Math.Round(valueMax, 4).ToString();
|
||
this.lblPTMax.ForeColor = colorMax;
|
||
|
||
this.lblPTMin.Text = Math.Round(valueMin, 4).ToString();
|
||
this.lblPTMin.ForeColor = colorMin;
|
||
}));
|
||
//不合格
|
||
if (color == Color.Red) order.Qualified = false;
|
||
}
|
||
private void updatePTValueTest(double upperLimit, double lowerLimit)
|
||
{
|
||
//每次加2个:PT1,PT2
|
||
int count = lstPT.Count();
|
||
if (count < 1) return;
|
||
switch (count)
|
||
{
|
||
case 1:
|
||
order.PT1 = lstPT[count - 1];
|
||
AddTextEvent("PT1", $"PT1:{order.PT1}");
|
||
break;
|
||
case 2:
|
||
order.PT2 = lstPT[count - 1];
|
||
AddTextEvent("PT2", $"PT2:{order.PT2}");
|
||
break;
|
||
case 3:
|
||
order.PT3 = lstPT[count - 1];
|
||
order.PT4 = 0;
|
||
AddTextEvent("PT3", $"PT3:{order.PT3}");
|
||
break;
|
||
case 4:
|
||
order.PT5 = lstPT[count - 1];
|
||
AddTextEvent("PT4", $"PT4:{order.PT5}");
|
||
break;
|
||
case 5:
|
||
order.PT6 = lstPT[count - 1];
|
||
AddTextEvent("PT5", $"PT5:{order.PT6}");
|
||
break;
|
||
}
|
||
|
||
List<double> lstValidValue = new List<double>();
|
||
for (int i = 0; i < count; i++)
|
||
{
|
||
if (lstPT[i] > 0)
|
||
lstValidValue.Add(lstPT[i]);
|
||
}
|
||
double value = Math.Round(lstValidValue.Average(), 4);
|
||
double valueMax = lstValidValue.Max();
|
||
double valueMin = lstValidValue.Min();
|
||
if (order != null) order.PTValue = value;
|
||
Color color = (upperLimit + lowerLimit > 0 && (value > upperLimit || value < lowerLimit)) ? Color.Red : Color.White;
|
||
Color colorMax = (upperLimit + lowerLimit > 0 && (valueMax > upperLimit || valueMax < lowerLimit)) ? Color.Red : Color.White;
|
||
Color colorMin = (upperLimit + lowerLimit > 0 && (valueMin > upperLimit || valueMin < lowerLimit)) ? Color.Red : Color.White;
|
||
this.Invoke(new System.Action(() =>
|
||
{
|
||
this.lblPT.Text = value.ToString();
|
||
this.lblPT.ForeColor = color;
|
||
|
||
this.lblPTMax.Text = Math.Round(valueMax, 4).ToString();
|
||
this.lblPTMax.ForeColor = colorMax;
|
||
|
||
this.lblPTMin.Text = Math.Round(valueMin, 4).ToString();
|
||
this.lblPTMin.ForeColor = colorMin;
|
||
}));
|
||
//不合格
|
||
if (color == Color.Red) order.Qualified = false;
|
||
}
|
||
private void updateCompareResult(bool compareResult)
|
||
{
|
||
this.Invoke(new System.Action(() =>
|
||
{
|
||
this.lblCompareResult.Text = (order.CompareResult==1 ? "通过" : "未通过");
|
||
if (!compareResult)
|
||
{
|
||
this.lblCompareResultCount.Text = (Convert.ToInt16(lblCompareResultCount.Text) + 1).ToString();
|
||
this.lblCompareResult.ForeColor = lblCompareResultCount.ForeColor=Color.Red;
|
||
//不合格
|
||
order.Qualified = false;
|
||
}
|
||
}));
|
||
}
|
||
private void resetUIValue()
|
||
{
|
||
this.Invoke(new System.Action(() =>
|
||
{
|
||
txtProductName.Text = txtProductCode.Text = txtProductSN.Text = "";
|
||
|
||
lstHeight.Clear();
|
||
lstLineWidth.Clear();
|
||
lstTension.Clear();
|
||
lstPT.Clear();
|
||
this.lblTension.Text = this.lblHeight.Text = this.lblLineWidth.Text = "0.00";
|
||
this.lblPT.Text = this.lblPTMax.Text= this.lblPTMin.Text="0.0000";
|
||
this.lblCompareResult.Text =this.lblDefectResult.Text = "无";
|
||
|
||
this.lblTensionMax.Text = this.lblHeightMax.Text = this.lblLineWidthMax.Text
|
||
= this.lblTensionMin.Text = this.lblHeightMin.Text = this.lblLineWidthMin.Text = "0.00";
|
||
|
||
this.lblCompareResultCount.Text = "0";
|
||
this.lblDefectResultCount.Text = "无";
|
||
this.toolTip1.SetToolTip(lblDefectResultCount, lblDefectResultCount.Text);
|
||
//
|
||
this.lblTension.ForeColor = this.lblHeight.ForeColor = this.lblLineWidth.ForeColor = this.lblPT.ForeColor = this.lblCompareResult.ForeColor= this.lblDefectResult.ForeColor=Color.White;
|
||
this.lblTensionMax.ForeColor = this.lblHeightMax.ForeColor = this.lblLineWidthMax.ForeColor = this.lblPTMax.ForeColor
|
||
= this.lblTensionMin.ForeColor = this.lblHeightMin.ForeColor = this.lblLineWidthMin.ForeColor = this.lblPTMin.ForeColor = Color.White;
|
||
this.lblCompareResultCount.ForeColor = this.lblDefectResultCount.ForeColor=Color.White;
|
||
|
||
this.dgvProcess.DataSource = null;
|
||
this.lstLog.Items.Clear();
|
||
this.clearDefectBmps();
|
||
|
||
this.picScanner1.Image = this.picScanner2.Image = null;
|
||
picScanner1.Refresh();
|
||
picScanner2.Refresh();
|
||
|
||
this.btnMakeTags.Enabled = false;
|
||
}));
|
||
}
|
||
//info: [{"1":[["92.7542","80.85799","99.54083","86.05363","dk","0.52"]]},
|
||
private void showDefectSmallBmps(Bitmap[] bmps, Mat[] bmps_cut, double Xmm, double Ymm, List<Dictionary<int, List<string>[]>> info)
|
||
{
|
||
this.Invoke(new System.Action(() =>
|
||
{
|
||
int imgWidth = this.pnlBmpList.ClientSize.Width - 50;
|
||
int imgHeight = (int)((bmps[0].Height * 1.0f / bmps[0].Width) * imgWidth + 0.5);
|
||
int splitWidth = 20;
|
||
int pnlWidth = this.pnlBmpList.ClientSize.Width;
|
||
int index = (int)this.gboxDefectList.Tag;
|
||
for (int x = 0; x < info.Count(); x++)
|
||
{
|
||
foreach (var item in info[x]) //单个info[x] = {"1":[["92.7542","80.85799","99.54083","86.05363","dk","0.52"]]}
|
||
{
|
||
//统计缺陷类型
|
||
countDefectClass(item.Value);//[["92.7542","80.85799","99.54083","86.05363","dk","0.52"]]
|
||
|
||
//
|
||
PictureBox picbox = new PictureBox();
|
||
picbox.Width = imgWidth;
|
||
picbox.Height = imgHeight;
|
||
CheckBox checkBox = new CheckBox();
|
||
picbox.Image = (Bitmap)bmps[x].Clone();
|
||
picbox.Name = "imgDefect_" + index;
|
||
picbox.Tag = item.Key + "," + Xmm + "," + Ymm;
|
||
|
||
checkBox.Tag = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(bmps_cut[item.Key]); //Mat转Bitmap ;//原始小图
|
||
checkBox.Name = "chkDefect_" + index;
|
||
checkBox.Text = $"第{index + 1}张";
|
||
checkBox.CheckedChanged += new System.EventHandler(this.CheckBox_CheckedChanged);
|
||
if (Config.MakeTag)//自动打标
|
||
{
|
||
checkBox.Checked = true;
|
||
checkBox.Enabled = false;
|
||
}
|
||
picbox.Click += new EventHandler(defectBmpBox_Click);
|
||
picbox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
|
||
picbox.BorderStyle = BorderStyle.FixedSingle;
|
||
picbox.Margin = new Padding((pnlWidth - picbox.Width) / 2, splitWidth,0, 0);
|
||
checkBox.Margin = new Padding((pnlWidth - checkBox.Width) / 2 + splitWidth,
|
||
0, 0, 0);
|
||
|
||
//
|
||
//if (this.pnlBmpList.Controls.Count > 0)
|
||
//{
|
||
// if ((this.pnlBmpList.Controls[this.pnlBmpList.Controls.Count - 1].Right + imgWidth + splitWidth) > this.pnlBmpList.Width)
|
||
// picbox.Location = new System.Drawing.Point(splitWidth, this.pnlBmpList.Controls[this.pnlBmpList.Controls.Count - 1].Bottom + splitWidth);
|
||
// else
|
||
// picbox.Location = new System.Drawing.Point(this.pnlBmpList.Controls[this.pnlBmpList.Controls.Count - 1].Right + splitWidth, this.pnlBmpList.Controls[this.pnlBmpList.Controls.Count - 1].Location.Y);
|
||
//}
|
||
//else
|
||
//{
|
||
// picbox.Location = new System.Drawing.Point(splitWidth, 0);
|
||
//}
|
||
//checkBox.Location = new System.Drawing.Point(picbox.Location.X + 5, picbox.Location.Y + 5);
|
||
//checkBox.ForeColor = Color.Black;
|
||
this.pnlBmpList.Controls.Add(picbox);
|
||
this.pnlBmpList.Controls.Add(checkBox);
|
||
break;
|
||
}
|
||
|
||
//
|
||
index++;
|
||
};
|
||
this.gboxDefectList.Tag = index;
|
||
this.gboxDefectList.Text = $"缺陷图像:{index} 张";
|
||
if (Config.MakeTag) {
|
||
lblDefectAddTag.Text = $"待打标数:{index}";
|
||
lblDefectAddTag.Tag = index;
|
||
}
|
||
pnlBmpList.VerticalScroll.Value = pnlBmpList.VerticalScroll.Maximum;
|
||
}));
|
||
}
|
||
//统计缺陷类型 [["92.7542","80.85799","99.54083","86.05363","dk","0.52"]]
|
||
private void countDefectClass(List<string>[] list)
|
||
{
|
||
string className;
|
||
for(int i=0; i<list.Length; i++)
|
||
{
|
||
className = list[i][4];
|
||
switch (className)
|
||
{
|
||
case "dk":
|
||
order.DKCount++;
|
||
break;
|
||
case "zw":
|
||
order.ZWCount++;
|
||
break;
|
||
case "gsyc":
|
||
order.GSYCCount++;
|
||
break;
|
||
case "xws":
|
||
order.XWSCount++;
|
||
break;
|
||
case "qk":
|
||
order.QKCount++;
|
||
break;
|
||
case "zk":
|
||
order.ZKCount++;
|
||
break;
|
||
case "pp":
|
||
order.PPCount++;
|
||
break;
|
||
case "hs":
|
||
order.HSCount++;
|
||
break;
|
||
case "yx":
|
||
order.YXCount++;
|
||
break;
|
||
case "xb":
|
||
order.XBCount++;
|
||
break;
|
||
case "sx":
|
||
order.SXCount++;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
private int getDefectCountFromCode(Order order, DefectCodeEnum defectCodeEnum)
|
||
{
|
||
switch (defectCodeEnum)
|
||
{
|
||
case DefectCodeEnum.dk:
|
||
return order.DKCount;
|
||
case DefectCodeEnum.zw:
|
||
return order.ZWCount;
|
||
case DefectCodeEnum.gsyc:
|
||
return order.GSYCCount;
|
||
case DefectCodeEnum.xws:
|
||
return order.XWSCount;
|
||
case DefectCodeEnum.qk:
|
||
return order.QKCount;
|
||
case DefectCodeEnum.zk:
|
||
return order.ZKCount;
|
||
case DefectCodeEnum.pp:
|
||
return order.PPCount;
|
||
case DefectCodeEnum.hs:
|
||
return order.HSCount;
|
||
case DefectCodeEnum.yx:
|
||
return order.YXCount;
|
||
case DefectCodeEnum.xb:
|
||
return order.XBCount;
|
||
case DefectCodeEnum.sx:
|
||
return order.SXCount;
|
||
default:
|
||
return 0;
|
||
}
|
||
}
|
||
private void CheckBox_CheckedChanged(object sender, EventArgs e)
|
||
{
|
||
CheckBox ck = (CheckBox)sender;
|
||
int cout = Convert.ToInt32(this.lblDefectAddTag.Tag);
|
||
if (ck.Checked)
|
||
cout++;
|
||
else
|
||
cout--;
|
||
|
||
lblDefectAddTag.Text = $"待打标数:{cout}";
|
||
lblDefectAddTag.Tag = cout;
|
||
}
|
||
|
||
private void defectBmpBox_Click(object sender, EventArgs e)
|
||
{
|
||
// if(autoMakeTagRuning) //自动打标中不可打开人工达标窗
|
||
PictureBox picbox = sender as PictureBox;
|
||
if (!devContainer.state || defectBmpNum != defectBmpNumResult || autoMakeTagRuning || currentState != CurrentStateEnum.自动流程结束)//检测中
|
||
{
|
||
//只查看
|
||
FrmPhoto frm = new FrmPhoto(this.pnlBmpList.Controls, Convert.ToInt32(picbox.Name.Split(new char[] { '_' })[1]));
|
||
frm.ShowDialog(this);
|
||
}
|
||
else//完成
|
||
{
|
||
FrmPhotoTag frm = new FrmPhotoTag(this.pnlBmpList.Controls, Convert.ToInt32(picbox.Name.Split(new char[] { '_' })[1])
|
||
,(defectBmpNum == defectBmpNumResult ? this.devContainer : null));
|
||
frm.ShowDialog(this);
|
||
|
||
//
|
||
if (devContainer.state && !Config.SkipScannerCC)
|
||
{
|
||
devContainer.devScannerCC.setMode(false);
|
||
devContainer.devScannerCC.setPreviewWin(this.picScanner1.Handle);
|
||
}
|
||
}
|
||
|
||
}
|
||
private void clearDefectBmps()
|
||
{
|
||
this.pnlBmpList.Controls.Clear();
|
||
this.gboxDefectList.Text = $"缺陷图像";
|
||
this.gboxDefectList.Tag = 0;
|
||
|
||
this.lblDefectAddTag.Text = "";
|
||
this.lblDefectAddTag.Tag = 0;
|
||
}
|
||
public delegate void AddTextDelegate(string tag, string msg, WarningEnum level);
|
||
/// <summary>
|
||
/// 异步输出日志
|
||
/// </summary>
|
||
/// <param name="tag">模板标识</param>
|
||
/// <param name="msg">内容</param>
|
||
/// <param name="type"></param>
|
||
private void AddTextEvent(string tag, string msg, WarningEnum level = WarningEnum.Normal)
|
||
{
|
||
try
|
||
{
|
||
if (InvokeRequired)
|
||
{
|
||
Invoke(new AddTextDelegate(AddTextEvent), new object[]
|
||
{
|
||
tag,
|
||
msg,
|
||
level
|
||
});
|
||
}
|
||
else
|
||
{
|
||
if (tag != null && tag != "")
|
||
tag = $" - [{tag}]";
|
||
|
||
var now = DateTime.Now;
|
||
msg = now.ToString("HH:mm:ss fff") + tag + " - " + msg;
|
||
//cont = MyHelper.subString(cont, 300);
|
||
|
||
//写日志,warn和error日志直接写
|
||
writeLog(now, level, msg);
|
||
|
||
//
|
||
//if (type > 0)
|
||
// cont = $"<color=\"{(type == 1 ? "Yellow" : "Red")}\">{cont}</color>";
|
||
|
||
msg = (level == WarningEnum.Normal ? "B" : level == WarningEnum.Low ? "Y" : "R") + msg;
|
||
this.Invoke(new System.Action(() =>
|
||
{
|
||
if (this.lstLog.Items.Count > 1000)
|
||
this.lstLog.Items.Clear();
|
||
lstLog.Items.Insert(0, msg);
|
||
}));
|
||
//日志滚动
|
||
//lstLog.SelectedIndex = lstLog.Items.Count - 1;
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
//MessageBox.Show("AddTextEvent ex=(" + ex.Message + ")", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, 0);
|
||
}
|
||
}
|
||
private void lstLog_DrawItem(object sender, DrawItemEventArgs e)
|
||
{
|
||
e.DrawBackground();
|
||
if (e.Index < 0) return;
|
||
|
||
string str = lstLog.Items[e.Index].ToString();
|
||
e.Graphics.DrawString(str.Substring(1), e.Font,
|
||
new SolidBrush(str[0] == 'R' ? Color.Red : (str[0] == 'Y' ? Color.Orange : Color.Black)),
|
||
e.Bounds);
|
||
}
|
||
private void writeLog(DateTime now, WarningEnum level, string text)
|
||
{
|
||
string directory = Config.LogPath + "\\" + DateTime.Now.ToString("yyyyMM") + "\\";
|
||
//if (type == 0) directory = Application.StartupPath + "\\Log\\Info\\";
|
||
//else if (type == 1) directory = Application.StartupPath + "\\Log\\Warn\\";
|
||
//else directory = Application.StartupPath + "\\Log\\Error\\";
|
||
|
||
if (!System.IO.Directory.Exists(directory))
|
||
System.IO.Directory.CreateDirectory(directory);
|
||
|
||
File.AppendAllText(directory + now.ToString("yyyyMMdd") + ".log", text + "\r\n");
|
||
}
|
||
|
||
private void FrmMian_FormClosing(object sender, FormClosingEventArgs e)
|
||
{
|
||
if (devContainer.state)
|
||
{
|
||
MessageBox.Show("请先停止生产后才能关闭程序!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||
e.Cancel = true;
|
||
return;
|
||
}
|
||
|
||
if (!bExitApp && MessageBox.Show($"确认退出?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
|
||
{
|
||
e.Cancel = true;
|
||
return;
|
||
}
|
||
}
|
||
private void FrmMian_FormClosed(object sender, FormClosedEventArgs e)
|
||
{
|
||
webService.stop();
|
||
Application.Exit();
|
||
System.GC.Collect();
|
||
System.Environment.Exit(0);
|
||
}
|
||
private void tsbtnOpenDev_Click(object sender, EventArgs e)
|
||
{
|
||
Config.LoadAllConfig();
|
||
//设置程序最小/大线程池
|
||
// Get the current settings.
|
||
int minWorker, minIOC;
|
||
ThreadPool.GetMinThreads(out minWorker, out minIOC);
|
||
ThreadPool.SetMinThreads(25, minIOC);
|
||
//ThreadPool.SetMaxThreads(256, 256);
|
||
|
||
this.tsbtnProductRevise.Enabled = false;
|
||
this.tsbtnOpenDev.Enabled = false;
|
||
//scannerCBmpIndex = 0;
|
||
|
||
isProductRevise = false;
|
||
this.resetUIValue();
|
||
currProcessIndex = -1;
|
||
currentState = CurrentStateEnum.等待复位;
|
||
warningLevel = WarningEnum.Normal;
|
||
currentPT = CurrentPTEnum.InitPT;
|
||
this.tsbtnWarning.Enabled=this.tsbtnGoDownPT.Enabled=this.tsbtnStart.Enabled=this.tsbtnStopNow.Enabled=this.tsbtnPause.Enabled=this.tsbtnReset.Enabled=false;
|
||
//后台线程回调事件
|
||
devContainer.StateChange = (state, msg) =>
|
||
{
|
||
if (state)
|
||
{
|
||
//全局中断
|
||
devContainer.devIOCard.INEvent = globalBreakEvent;
|
||
devContainer.OutDebugEvent = (tag, debugInfo) =>
|
||
{
|
||
AddTextEvent(tag, debugInfo);
|
||
};
|
||
//
|
||
AddTextEvent("设备启动", "请先进行复位操作!");
|
||
this.Invoke(new System.Action(() =>
|
||
{
|
||
this.tsbtnReset.Enabled = true;
|
||
tsbtnWarning.Enabled = this.tsbtnStart.Enabled = this.tsbtnGoDownPT.Enabled
|
||
= this.tsbtnPause.Enabled = this.tsbtnStopNow.Enabled = false;
|
||
|
||
this.tsbtnOpenDev.Enabled = true;
|
||
this.tsbtnOpenDev.Visible = false;
|
||
this.tsbtnCloseDev.Visible = true;
|
||
}));
|
||
|
||
timer.Elapsed += Timer_Elapsed;
|
||
timer.Interval = 500;
|
||
timer.Start();
|
||
}
|
||
else
|
||
{
|
||
AddTextEvent("设备启动", $"启动失败,{msg}", WarningEnum.High);
|
||
this.Invoke(new System.Action(() =>
|
||
{
|
||
this.tsbtnOpenDev.Enabled = true;
|
||
this.tsbtnOpenDev.Visible = true;
|
||
this.tsbtnCloseDev.Visible = false;
|
||
}));
|
||
}
|
||
|
||
};
|
||
devContainer.WarningEvent = (level, msg) =>
|
||
{
|
||
AddTextEvent("设备事件", msg, level);
|
||
if (level == WarningEnum.High)
|
||
warning(level,true);
|
||
};
|
||
devContainer.start(this.picScanner1.Handle, this.picScanner2.Handle);
|
||
}
|
||
|
||
private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
|
||
{
|
||
this.Invoke(new System.Action(() =>
|
||
{
|
||
this.tsAxisState.Text = $"[命令位:{devContainer.devAxis.CmdPos[0]} 反馈位:{devContainer.devAxis.ActualPos[0]}] | " +
|
||
$"[命令位:{devContainer.devAxis.CmdPos[1]} 反馈位:{devContainer.devAxis.ActualPos[1]}] | " +
|
||
$"[命令位:{devContainer.devAxis.CmdPos[2]} 反馈位:{devContainer.devAxis.ActualPos[2]}] | " +
|
||
$"[命令位:{devContainer.devAxis.CmdPos[3]} 反馈位:{devContainer.devAxis.ActualPos[3]}]";
|
||
}));
|
||
}
|
||
|
||
private void tsbtnCloseDev_Click(object sender, EventArgs e)
|
||
{
|
||
AddTextEvent("设备停止", $"设备停止...");
|
||
this.tsbtnProductRevise.Enabled = false;
|
||
this.tsbtnOpenDev.Visible = true;
|
||
this.tsbtnCloseDev.Visible = false;
|
||
this.btnMakeTags.Enabled = false;
|
||
this.lblTimeLen.Visible = false;
|
||
|
||
this.tsbtnReset.Enabled = tsbtnWarning.Enabled = this.tsbtnStart.Enabled = this.tsbtnGoDownPT.Enabled
|
||
= this.tsbtnPause.Enabled = this.tsbtnStopNow.Enabled = false;
|
||
|
||
this.tsbtnSizeTag.Enabled = tsbtnSizeImage.Enabled = tsbtnDefectImage.Enabled = false;
|
||
if (devContainer.state)
|
||
{
|
||
devContainer.devIOCard.reset();
|
||
devContainer.io_output(CMDName.IO默认输出);
|
||
}
|
||
timer.Stop();
|
||
devContainer.stop();
|
||
}
|
||
/// <summary>
|
||
/// 全局中断
|
||
/// </summary>
|
||
private void globalBreakEvent(int portIndex, byte data)
|
||
{
|
||
if (compareIOInput(CMDName.启动按钮) && this.tsbtnStart.Enabled)
|
||
startCommand();
|
||
else if (compareIOInput(CMDName.暂停按钮) && this.tsbtnPause.Enabled)
|
||
warning(WarningEnum.Low, false);
|
||
else if (compareIOInput(CMDName.复位按钮) && this.tsbtnReset.Enabled)
|
||
resetCommand();
|
||
else if (compareIOInput(CMDName.张力读取) && currentPT == CurrentPTEnum.Moving)
|
||
readTension();
|
||
else if (!this.disableBuzzer && compareIOInput(CMDName.门磁告警输入))
|
||
warning(WarningEnum.Low, true);
|
||
else if (!this.disableBuzzer && compareIOInput(CMDName.喷墨告警输入))
|
||
warning(WarningEnum.Low, true);
|
||
}
|
||
private bool compareIOInput(CMDName key)
|
||
{
|
||
JObject joJson = Config.CMDProcess[key];
|
||
IODirectionEnum direction = (IODirectionEnum)joJson.Value<int>("Direction");
|
||
if (direction == IODirectionEnum.输入 || direction == IODirectionEnum.输入输出)
|
||
{
|
||
return Util.compareIOInput(
|
||
joJson.Value<JArray>("IN_OP_SHOW").ToObject<List<string>>().ToArray(),
|
||
devContainer.devIOCard.DIData);
|
||
}
|
||
return false;
|
||
}
|
||
private void readTension()
|
||
{
|
||
if (Config.SkipTension)
|
||
{
|
||
AddTextEvent("张力读取", $"张力设备禁用,忽略此步骤!");
|
||
return;
|
||
}
|
||
devContainer.io_output(CMDName.张力读取);
|
||
double tensionValue = devContainer.devTension.getValue();
|
||
tensionValue=Math.Round(tensionValue, 2);//保留2位小数
|
||
AddTextEvent("张力读取", $"张力值:{tensionValue}");
|
||
devContainer.io_output(CMDName.张力读取,false,true,500);
|
||
lstTension.Add(tensionValue);
|
||
updateTensionValue(currProductModel.TensionBaseValue + currProductModel.TensionUpFloatValue, currProductModel.TensionBaseValue - currProductModel.TensionDownFloatValue);
|
||
}
|
||
/// <summary>
|
||
/// 启动
|
||
/// </summary>
|
||
private void startCommand()
|
||
{
|
||
this.setButtonEnabled(this.tsbtnProductRevise, false);
|
||
if (!devContainer.state || warningLevel != WarningEnum.Normal || currentState != CurrentStateEnum.等待启动)
|
||
return;
|
||
if (currentPT == CurrentPTEnum.MakeTag)
|
||
{
|
||
AddTextEvent("启动", "打标未结束,非可启动状态!", warningLevel);
|
||
return;
|
||
}
|
||
|
||
if (!devContainer.devAxis.isReady())
|
||
{
|
||
AddTextEvent("启动", "轴状态异常,不可启动!", warningLevel);
|
||
return;
|
||
}
|
||
if (!devContainer.devAxis.IsReset)
|
||
{
|
||
AddTextEvent("启动", "轴需先进行复位操作!", WarningEnum.High);
|
||
return;
|
||
}
|
||
|
||
devContainer.io_output(CMDName.启动按钮);
|
||
devContainer.io_output(CMDName.绿灯输出);
|
||
devContainer.io_output(CMDName.暂停按钮, false, true, 0);
|
||
devContainer.io_output(CMDName.红灯输出, false, true, 0);
|
||
devContainer.io_output(CMDName.黄灯输出, false, true, 0);
|
||
|
||
//暂停-》继续
|
||
if (currProcessIndex >= 0 && currentPT == CurrentPTEnum.Moving && currentState == CurrentStateEnum.等待启动)
|
||
{
|
||
AddTextEvent("启动", $"暂停 -> 继续 当前工序索引:{currProcessIndex + 1}");
|
||
threadProcess = new System.Threading.Thread(() =>
|
||
{
|
||
int nextStepId = currProcessIndex;
|
||
do
|
||
{
|
||
currentState = CurrentStateEnum.运行中;
|
||
nextStepId = nextProcess(currProductModel, nextStepId);
|
||
} while (nextStepId >= 0 && !isBreakProcessRun());
|
||
//nextProcess(currProductModel, currProcessIndex);
|
||
});
|
||
threadProcess.IsBackground = true;
|
||
threadProcess.Start();
|
||
this.setButtonEnabled(this.tsbtnPause, true);
|
||
this.setButtonEnabled(this.tsbtnStopNow, true);
|
||
}
|
||
else//开始/重新开始
|
||
{
|
||
//校正从复位-》运行,不会新启动
|
||
isProductRevise = false;
|
||
resetUIValue();
|
||
AddTextEvent("启动", "移动至上料位...");
|
||
gotoUpPT();
|
||
|
||
this.Invoke(new System.Action(() =>
|
||
{
|
||
//新开始
|
||
lblTimeLen.Visible = false;
|
||
runStep();
|
||
}));
|
||
this.setButtonEnabled(this.tsbtnPause, false);
|
||
this.setButtonEnabled(this.tsbtnStopNow, false);
|
||
}
|
||
|
||
this.setButtonEnabled(this.tsbtnStart, false);
|
||
this.setButtonEnabled(this.tsbtnReset, false);
|
||
this.setButtonEnabled(this.tsbtnGoDownPT, false);
|
||
}
|
||
/// <summary>
|
||
/// 暂停
|
||
/// </summary>
|
||
/// <param name="buzzer">是否响蜂鸣</param>
|
||
private void pauseCommand(bool buzzer = false)
|
||
{
|
||
devContainer.io_output(CMDName.暂停按钮);
|
||
if (buzzer)
|
||
{
|
||
devContainer.io_output(CMDName.红灯输出);
|
||
devContainer.io_output(CMDName.蜂鸣器输出);
|
||
}
|
||
else
|
||
devContainer.io_output(CMDName.黄灯输出);
|
||
devContainer.io_output(CMDName.启动按钮, false, true, 0);
|
||
devContainer.io_output(CMDName.绿灯输出, false, true, 0);
|
||
|
||
this.setButtonEnabled(this.tsbtnWarning, true);
|
||
this.setButtonEnabled(this.tsbtnGoDownPT, false);
|
||
this.setButtonEnabled(this.tsbtnStart, false);
|
||
this.setButtonEnabled(this.tsbtnPause, false);
|
||
this.setButtonEnabled(this.tsbtnStopNow, false);
|
||
this.setButtonEnabled(this.tsbtnReset, false);
|
||
AddTextEvent("暂停", $"当前工序索引:{currProcessIndex + 1}", WarningEnum.Low);
|
||
}
|
||
/// <summary>
|
||
/// 急停
|
||
/// </summary>
|
||
private void stopNowCommand()
|
||
{
|
||
if (!devContainer.state)
|
||
{
|
||
this.setButtonEnabled(this.tsbtnStopNow, false);
|
||
return;
|
||
}
|
||
|
||
devContainer.io_output(CMDName.Y轴复位输出, false, true, 0);
|
||
devContainer.io_output(CMDName.红灯输出);
|
||
if (!this.disableBuzzer) devContainer.io_output(CMDName.蜂鸣器输出);
|
||
devContainer.io_output(CMDName.暂停按钮, false, true, 0);
|
||
devContainer.io_output(CMDName.黄灯输出, false, true, 0);
|
||
devContainer.io_output(CMDName.启动按钮, false, true, 0);
|
||
devContainer.io_output(CMDName.绿灯输出, false, true, 0);
|
||
|
||
this.setButtonEnabled(this.tsbtnWarning, true);
|
||
this.setButtonEnabled(this.tsbtnGoDownPT, false);
|
||
this.setButtonEnabled(this.tsbtnStart, false);
|
||
this.setButtonEnabled(this.tsbtnPause, false);
|
||
this.setButtonEnabled(this.tsbtnStopNow, false);
|
||
this.setButtonEnabled(this.tsbtnReset, false);
|
||
AddTextEvent("急停", $"当前工序索引:{currProcessIndex + 1}", WarningEnum.High);
|
||
}
|
||
private bool reseting = false;
|
||
private void resetCommand()
|
||
{
|
||
currentState = CurrentStateEnum.等待复位;
|
||
warningLevel = WarningEnum.Normal;
|
||
currentPT = CurrentPTEnum.InitPT;
|
||
this.Invoke(new System.Action(() =>
|
||
{
|
||
lblTimeLen.Visible = false;
|
||
this.tsbtnWarning.Enabled = this.tsbtnGoDownPT.Enabled = this.tsbtnStart.Enabled = this.tsbtnStopNow.Enabled = this.tsbtnPause.Enabled = this.tsbtnReset.Enabled = false;
|
||
}));
|
||
|
||
try
|
||
{
|
||
if (devContainer.state && !reseting)
|
||
{
|
||
reseting = true;
|
||
isProductRevise = false;
|
||
resetUIValue();
|
||
AddTextEvent("复位", $"设备复位中...");
|
||
currProcessIndex = -1;
|
||
|
||
this.setButtonEnabled(this.tsbtnReset, false);
|
||
|
||
// I/O reset后,输出默认状态
|
||
AddTextEvent("复位", $"I/O复位中...");
|
||
if (!devContainer.devIOCard.reset())
|
||
{
|
||
AddTextEvent("复位", "I/O板卡复位失败!", WarningEnum.High);
|
||
return;
|
||
}
|
||
if (!devContainer.io_output(CMDName.IO默认输出))
|
||
{
|
||
//AddTextEvent("复位", "I/O板卡复位默认值失败!", WarningEnum.High);
|
||
//return;
|
||
}
|
||
|
||
//板卡复位输出灯
|
||
devContainer.io_output(CMDName.复位按钮);
|
||
devContainer.io_output(CMDName.黄灯输出, true);
|
||
|
||
//4.5X
|
||
if(!Config.SkipSmallAxis)
|
||
devContainer.devSmallAxis.gotoPos((int)SmallAxCmdPos.倍率4_5X, false);
|
||
|
||
//移动Axis前等待厚度传感器收回
|
||
AddTextEvent("复位", $"检测厚度传感器安全值...");
|
||
if (!Config.SkipHeight)
|
||
{
|
||
while (devContainer.devHeight.getHeight() < (double)Math.Abs(Config.HeightDev_SafeValue))
|
||
{
|
||
if (!devContainer.state || currentState != CurrentStateEnum.等待复位)
|
||
return;
|
||
Thread.Sleep(100);
|
||
Application.DoEvents();
|
||
}
|
||
}
|
||
|
||
//goto ORG
|
||
AddTextEvent("复位", $"轴正在回原点...");
|
||
devContainer.devAxis.closeJogMode();
|
||
devContainer.devAxis.resetAxisState(-1);//reset state
|
||
//AddTextEvent("复位", $"重置轴状态...");
|
||
for (int i = 0; i < Config.Axis_HomeMode.Length; i++)
|
||
{
|
||
//到起始位速度使用回HOME速度
|
||
devContainer.devAxis.setAxisVelParam((double)Config.Axis_HomeVelLow[i], (double)Config.Axis_HomeVelHigh[i],
|
||
(double)Config.Axis_HomeAcc[i], (double)Config.Axis_HomeDec[i], i);
|
||
if (i != 2)
|
||
{
|
||
//devContainer.devAxis.setAxisVelParam(40000,200000,5000000, 5000000,i,true);
|
||
devContainer.devAxis.home(i, (uint)Config.Axis_HomeMode[i], (uint)Config.Axis_HomeDir[i]);
|
||
}
|
||
else//Y轴 I/O控制回HOME
|
||
{
|
||
devContainer.io_output(CMDName.Y轴复位输出);
|
||
}
|
||
}
|
||
AddTextEvent("复位", $"等待轴状态完成...");
|
||
while (!devContainer.devAxis.isReady())
|
||
{
|
||
if (!devContainer.state || currentState != CurrentStateEnum.等待复位)
|
||
{
|
||
AddTextEvent("复位", $"当前状态:"+ ((CurrentStateEnum)currentState).ToString());
|
||
return;
|
||
}
|
||
//AddTextEvent("复位", $"轴0状态:"+ ((AxisState)devContainer.devAxis.AxState[0]).ToString());
|
||
//AddTextEvent("复位", $"轴1状态:" + ((AxisState)devContainer.devAxis.AxState[1]).ToString());
|
||
//AddTextEvent("复位", $"轴2状态:" + ((AxisState)devContainer.devAxis.AxState[2]).ToString());
|
||
//AddTextEvent("复位", $"轴3状态:" + ((AxisState)devContainer.devAxis.AxState[3]).ToString());
|
||
|
||
Thread.Sleep(1000);
|
||
Application.DoEvents();
|
||
}
|
||
//判断Y轴回原点完成I/O信号
|
||
AddTextEvent("复位", $"等待Y轴回HOME完成...");
|
||
while (!this.compareIOInput(CMDName.Y轴复位完成输入))
|
||
{
|
||
Thread.Sleep(100);
|
||
Application.DoEvents();
|
||
}
|
||
AddTextEvent("复位", $"Y轴回HOME已完成.");
|
||
devContainer.io_output(CMDName.Y轴复位输出, false, true, 0);
|
||
AddTextEvent("复位", $"重置Y轴反馈位置与命令位置.");
|
||
devContainer.devAxis.resetCmdPosition(2);
|
||
devContainer.devAxis.resetActualPosition(2);
|
||
|
||
//
|
||
if (devContainer.devAxis.isError())
|
||
throw new Exception("轴回原点失败!");
|
||
|
||
//
|
||
//goto InitPT
|
||
//AddTextEvent("复位", $"轴回原点完成,回到初始位...");
|
||
JArray arrPT = Config.joPTSetting.Value<JArray>("initPT");
|
||
for (int i = 0; i < arrPT.Count; i++)
|
||
{
|
||
if (!devContainer.state || currentState != CurrentStateEnum.等待复位)
|
||
return;
|
||
|
||
AddTextEvent($"复位", $"轴{i}准备运动至初始位:{(double)arrPT[i]}(当前轴状态:{((AxisState)devContainer.devAxis.AxState[i]).ToString()})...");
|
||
devContainer.devAxis.move_ptp(i, (double)arrPT[i], AxMoveMode.绝对位置);
|
||
}
|
||
while (!devContainer.devAxis.isReady())
|
||
{
|
||
if (!devContainer.state || warningLevel != WarningEnum.Normal)
|
||
return;
|
||
Thread.Sleep(100);
|
||
}
|
||
if (devContainer.devAxis.isError())
|
||
throw new Exception("轴移动至初始位失败!");
|
||
|
||
//
|
||
this.setButtonEnabled(this.tsbtnReset, true);
|
||
this.setButtonEnabled(this.tsbtnStart, true);
|
||
this.setButtonEnabled(this.tsbtnStopNow, true);
|
||
this.setButtonEnabled(this.tsbtnPause, false);
|
||
this.setButtonEnabled(this.tsbtnGoDownPT, false);
|
||
this.setButtonEnabled(this.tsbtnWarning, false);
|
||
|
||
devContainer.io_output(CMDName.复位按钮, false, true, 0);//熄灭
|
||
devContainer.io_output(CMDName.黄灯输出);//长亮
|
||
currentPT = CurrentPTEnum.InitPT;
|
||
currentState = CurrentStateEnum.等待启动;
|
||
AddTextEvent("复位", $"复位完成。");
|
||
this.setButtonEnabled(this.tsbtnProductRevise, true);
|
||
}
|
||
else
|
||
{
|
||
AddTextEvent("复位", "非可复位状态,请先停止后再复位!", WarningEnum.High);
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
AddTextEvent("复位", "复位失败 Err:" + ex.Message, WarningEnum.High);
|
||
warning(WarningEnum.High, true);
|
||
}
|
||
finally
|
||
{
|
||
reseting = false;
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 上料
|
||
/// </summary>
|
||
private void gotoUpPT()
|
||
{
|
||
try
|
||
{
|
||
JArray arrPT = Config.joPTSetting.Value<JArray>("upPT");
|
||
for (int i = 0; i < arrPT.Count; i++)
|
||
{
|
||
if (!devContainer.state || warningLevel != WarningEnum.Normal)
|
||
return;
|
||
|
||
AddTextEvent($"上料", $"轴{i}准备运动至上料位:{(double)arrPT[i]}(当前轴状态:{((AxisState)devContainer.devAxis.AxState[i]).ToString()})...");
|
||
devContainer.devAxis.move_ptp(i, (double)arrPT[i], AxMoveMode.绝对位置);
|
||
}
|
||
while (!devContainer.devAxis.isReady())
|
||
{
|
||
if (!devContainer.state || warningLevel != WarningEnum.Normal)
|
||
return;
|
||
Thread.Sleep(100);
|
||
}
|
||
if (devContainer.devAxis.isError())
|
||
throw new Exception("轴移动至上料位失败!");
|
||
|
||
//
|
||
currentPT = CurrentPTEnum.UpPT;
|
||
currentState = CurrentStateEnum.等待扫码;
|
||
AddTextEvent($"上料", "到达上料位!");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
AddTextEvent("上料", "上料初始失败 Err:" + ex.Message, WarningEnum.High);
|
||
warning(WarningEnum.High);
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 下料
|
||
/// </summary>
|
||
private void gotoDownPT()
|
||
{
|
||
try
|
||
{
|
||
if (currentState != CurrentStateEnum.打标中 && currentState != CurrentStateEnum.等待启动 && currentState != CurrentStateEnum.自动流程结束)
|
||
{
|
||
AddTextEvent($"下料", $"非可下料状态:{currentState.ToString()}");
|
||
return;
|
||
}
|
||
|
||
currentState = CurrentStateEnum.下料中;
|
||
isProductRevise = false;
|
||
|
||
JArray arrPT = Config.joPTSetting.Value<JArray>("downPT");
|
||
for (int i = 0; i < arrPT.Count; i++)
|
||
{
|
||
if (!devContainer.state || warningLevel != WarningEnum.Normal || currentState != CurrentStateEnum.下料中)
|
||
return;
|
||
|
||
AddTextEvent($"下料", $"轴{i}准备运动至下料位:{(double)arrPT[i]}(当前轴状态:{((AxisState)devContainer.devAxis.AxState[i]).ToString()})...");
|
||
devContainer.devAxis.move_ptp(i, (double)arrPT[i], AxMoveMode.绝对位置);
|
||
}
|
||
|
||
while (!devContainer.devAxis.isReady())
|
||
{
|
||
if (!devContainer.state || warningLevel != WarningEnum.Normal || currentState != CurrentStateEnum.下料中)
|
||
return;
|
||
Thread.Sleep(100);
|
||
}
|
||
if (devContainer.devAxis.isError())
|
||
throw new Exception("轴移动至下料位失败!");
|
||
|
||
//
|
||
currentPT = CurrentPTEnum.DownPT;
|
||
currentState = CurrentStateEnum.等待启动;
|
||
devContainer.io_output(CMDName.下料完成输出);
|
||
setButtonEnabled(tsbtnStart, true);
|
||
AddTextEvent($"下料", "下料完成!");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
AddTextEvent("下料", "下料失败 Err:" + ex.Message, WarningEnum.High);
|
||
warning(WarningEnum.High);
|
||
}
|
||
}
|
||
private void setButtonEnabled(ToolStripButton button, bool Enabled)
|
||
{
|
||
this.Invoke(new System.Action(() =>
|
||
{
|
||
button.Enabled = Enabled;
|
||
}));
|
||
}
|
||
private void setButtonEnabled(ToolStripMenuItem button, bool Enabled)
|
||
{
|
||
this.Invoke(new System.Action(() =>
|
||
{
|
||
button.Enabled = Enabled;
|
||
}));
|
||
}
|
||
private void setButtonEnabled(Control button, bool Enabled)
|
||
{
|
||
this.Invoke(new System.Action(() =>
|
||
{
|
||
button.Enabled = Enabled;
|
||
}));
|
||
}
|
||
|
||
private void FrmMian_Shown(object sender, EventArgs e)
|
||
{
|
||
}
|
||
|
||
private void FrmMian_Resize(object sender, EventArgs e)
|
||
{
|
||
|
||
}
|
||
|
||
private void 流程管理ToolStripMenuItem_Click(object sender, EventArgs e)
|
||
{
|
||
if (devContainer.state)
|
||
{
|
||
MessageBox.Show("请先停止生产,再进行流程修改!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||
return;
|
||
}
|
||
|
||
FrmStepList frm = new FrmStepList();
|
||
frm.ShowDialog();
|
||
}
|
||
|
||
private void 产品管理ToolStripMenuItem_Click(object sender, EventArgs e)
|
||
{
|
||
if (devContainer.state)
|
||
{
|
||
MessageBox.Show("请先停止生产,再进行产品修改!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||
return;
|
||
}
|
||
|
||
FrmProductList frm = new FrmProductList();
|
||
frm.ShowDialog();
|
||
loadProductCodeList();
|
||
}
|
||
private void tsbtnProductRevise_Click(object sender, EventArgs e)
|
||
{
|
||
if (!devContainer.state)
|
||
{
|
||
MessageBox.Show("请先启动设备!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
return;
|
||
}
|
||
if (currentPT != CurrentPTEnum.InitPT || currentState != CurrentStateEnum.等待启动)
|
||
{
|
||
MessageBox.Show("请先复位设备!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
return;
|
||
}
|
||
|
||
FrmProductList frm = new FrmProductList(true);
|
||
if (frm.ShowDialog() == DialogResult.Yes && frm.Product != null)//执行校正
|
||
{
|
||
AddTextEvent("校正", "开始执行产品base厚度校正...");
|
||
|
||
isProductRevise = true;
|
||
currProductModel = frm.Product;
|
||
currProductModel.HeightBaseDec = "";
|
||
this.txtProductCode.Text = currProductModel.Code;
|
||
this.txtProductName.Text = currProductModel.Name;
|
||
this.txtProductSN.Text = "";
|
||
this.dgvProcess.DataSource = new BindingSource(currProductModel.ReviseStepInfo.ProcessList, null);
|
||
devContainer.libFor.clear();
|
||
devContainer.libIF.clear();
|
||
|
||
//
|
||
this.setButtonEnabled(this.tsbtnStart, false);
|
||
this.setButtonEnabled(this.tsbtnPause, true);
|
||
this.setButtonEnabled(this.tsbtnStopNow, true);
|
||
threadProcess = new System.Threading.Thread(() =>
|
||
{
|
||
int nextStepId = 0;
|
||
do
|
||
{
|
||
currentState = CurrentStateEnum.运行中;
|
||
nextStepId = nextProcess(currProductModel, nextStepId);
|
||
} while (nextStepId >= 0 && !isBreakProcessRun());
|
||
});
|
||
threadProcess.IsBackground = true;
|
||
threadProcess.Start();
|
||
}
|
||
}
|
||
private void 设备调试ToolStripMenuItem_Click(object sender, EventArgs e)
|
||
{
|
||
if (devContainer.state)
|
||
{
|
||
MessageBox.Show("请先停止生产,再进行设备调试!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||
return;
|
||
}
|
||
|
||
FrmDebug3 frm = new FrmDebug3();
|
||
frm.ShowDialog();
|
||
}
|
||
|
||
private void 角色管理ToolStripMenuItem_Click(object sender, EventArgs e)
|
||
{
|
||
FrmRoleRight frm = new FrmRoleRight();
|
||
frm.ShowDialog(this);
|
||
}
|
||
|
||
private void 用户管理ToolStripMenuItem_Click(object sender, EventArgs e)
|
||
{
|
||
FrmUserList frm = new FrmUserList();
|
||
frm.ShowDialog(this);
|
||
}
|
||
|
||
private void 退出ToolStripMenuItem_Click(object sender, EventArgs e)
|
||
{
|
||
Application.Exit();
|
||
System.GC.Collect();
|
||
System.Environment.Exit(0);
|
||
}
|
||
|
||
private void 注销ToolStripMenuItem_Click(object sender, EventArgs e)
|
||
{
|
||
if (devContainer.state)
|
||
{
|
||
MessageBox.Show("请先停止生产再退出!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||
return;
|
||
}
|
||
|
||
if (MessageBox.Show($"确认退出?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
|
||
{
|
||
this.bExitApp = true;
|
||
Process.Start(Application.StartupPath + "\\ProductionControl.exe");
|
||
this.Close();
|
||
}
|
||
}
|
||
|
||
private void splitContainer1_Panel1_Resize(object sender, EventArgs e)
|
||
{
|
||
int allWidth = this.splitContainer1.Panel1.Width;
|
||
this.gpbProductInfo.Width = this.flpnlResultData.Width = this.gpbProcessList.Width = this.gpbLog.Width = allWidth;
|
||
|
||
//
|
||
this.txtProductName.Width = this.txtProductCode.Width = this.gpbProductInfo.Width - this.txtProductName.Left - 8;
|
||
this.txtProductSN.Width = this.txtBatchId.Width = (this.txtProductName.Width- lblBatchId.Width)/2;
|
||
this.lblBatchId.Left = this.txtProductSN.Right ;
|
||
this.txtBatchId.Left = this.lblBatchId.Right;
|
||
|
||
|
||
//
|
||
int spliceWidth = 5;
|
||
kanban1.Width = kanban2.Width = kanban3.Width = kanban4.Width = kanban5.Width = kanban6.Width = (flpnlResultData.Width-20) / 6;
|
||
}
|
||
|
||
|
||
private void 关于ToolStripMenuItem_Click(object sender, EventArgs e)
|
||
{
|
||
AboutBox1 aboutBox1 = new AboutBox1();
|
||
aboutBox1.Show();
|
||
}
|
||
|
||
|
||
private void 系统设置ToolStripMenuItem_Click(object sender, EventArgs e)
|
||
{
|
||
FrmSysSetting frmSetting = new FrmSysSetting();
|
||
frmSetting.ShowDialog();
|
||
}
|
||
|
||
|
||
|
||
private void dgvProcess_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
|
||
{
|
||
//string processCode;
|
||
//for (int i = 0; i < this.dgvProcess.Rows.Count; i++)
|
||
//{
|
||
//processCode = dgvProcess.Rows[i].Cells[0].Value.ToString();
|
||
//dgvProcess.Rows[i].Cells[1].Value = Config.dicDevType[processCode];
|
||
//}
|
||
}
|
||
|
||
private void tsbtnWarning_Click(object sender, EventArgs e)
|
||
{
|
||
//if (warningLevel == WarningEnum.Normal)
|
||
//{
|
||
// tsbtnWarning.Enabled = false;
|
||
// return;
|
||
//}
|
||
|
||
//重置AXIS状态
|
||
devContainer.devAxis.resetAxisState();
|
||
if (!devContainer.devAxis.isReady())
|
||
{
|
||
AddTextEvent("解除报警", "轴状态未恢复,解除报警失败!", warningLevel);
|
||
return;
|
||
}
|
||
if (devContainer.devAxis.isError())
|
||
{
|
||
AddTextEvent("解除报警", "轴IO状态异常,解除报警失败!", warningLevel);
|
||
return;
|
||
}
|
||
if (!this.disableDoorSensor && compareIOInput(CMDName.门磁告警输入))
|
||
{
|
||
AddTextEvent("解除报警", "门磁告警未清除 ,解除报警失败!", warningLevel);
|
||
return;
|
||
}
|
||
if (!this.disableDoorSensor && compareIOInput(CMDName.喷墨告警输入))
|
||
{
|
||
AddTextEvent("解除报警", "喷墨告警输入未清除 ,解除报警失败!", warningLevel);
|
||
return;
|
||
}
|
||
//关闭蜂鸣器
|
||
devContainer.io_output(CMDName.蜂鸣器输出, false, true, 0);
|
||
devContainer.io_output(CMDName.红灯输出, false, true, 0);
|
||
devContainer.io_output(CMDName.复位按钮, false, true, 0);
|
||
if (warningLevel == WarningEnum.High)
|
||
{
|
||
AddTextEvent("解除报警", "急停告警已解除,但必需进行复位操作!", warningLevel);
|
||
currentState = CurrentStateEnum.等待复位;
|
||
this.tsbtnReset.Enabled = true;
|
||
tsbtnWarning.Enabled = this.tsbtnStart.Enabled = this.tsbtnGoDownPT.Enabled
|
||
= this.tsbtnPause.Enabled = this.tsbtnStopNow.Enabled = this.btnMakeTags.Enabled= false;
|
||
}
|
||
else
|
||
{
|
||
devContainer.io_output(CMDName.黄灯输出);
|
||
AddTextEvent("解除报警", "告警已解除,请继续选择下一步操作!", warningLevel);
|
||
if (currentPT == CurrentPTEnum.MakeTag)
|
||
currentState = CurrentStateEnum.打标中;
|
||
else
|
||
currentState = CurrentStateEnum.等待启动;
|
||
|
||
tsbtnWarning.Enabled = false;
|
||
this.tsbtnStart.Enabled = this.tsbtnGoDownPT.Enabled = true;
|
||
this.tsbtnReset.Enabled = this.tsbtnPause.Enabled = this.tsbtnStopNow.Enabled = true;
|
||
}
|
||
warningLevel = WarningEnum.Normal;
|
||
}
|
||
private void tsbtnGoDownPT_Click(object sender, EventArgs e)
|
||
{
|
||
if (!devContainer.state || warningLevel!= WarningEnum.Normal)
|
||
return;
|
||
if (!devContainer.devAxis.isReady())
|
||
{
|
||
AddTextEvent("下料失败", "轴状态异常!", WarningEnum.Low);
|
||
return;
|
||
}
|
||
|
||
gotoDownPT();
|
||
}
|
||
//急停
|
||
private void tsbtnStopNow_Click(object sender, EventArgs e)
|
||
{
|
||
this.warning(WarningEnum.High);
|
||
}
|
||
private Thread threadProcess;
|
||
|
||
private void tsbtnStart_Click(object sender, EventArgs e)
|
||
{
|
||
this.startCommand();
|
||
}
|
||
|
||
private void tsbtnPause_Click(object sender, EventArgs e)
|
||
{
|
||
warning(WarningEnum.Low,false);
|
||
}
|
||
//复位
|
||
private void tsbtnReset_Click(object sender, EventArgs e)
|
||
{
|
||
this.resetCommand();
|
||
}
|
||
|
||
private void tsbtnGButSetting_Click(object sender, EventArgs e)
|
||
{
|
||
if (devContainer.state)
|
||
{
|
||
MessageBox.Show("请先停止生产,再进行设置!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||
return;
|
||
}
|
||
|
||
FrmCMDProcess from = new FrmCMDProcess();
|
||
from.ShowDialog();
|
||
}
|
||
|
||
private void tsbtnPTSetting_Click(object sender, EventArgs e)
|
||
{
|
||
if (devContainer.state)
|
||
{
|
||
MessageBox.Show("请先停止生产,再进行设置!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||
return;
|
||
}
|
||
|
||
FrmPTSetting from = new FrmPTSetting();
|
||
from.ShowDialog();
|
||
}
|
||
|
||
private void tsMenuModifyPW_Click(object sender, EventArgs e)
|
||
{
|
||
FrmModifyPW frm = new FrmModifyPW();
|
||
frm.ShowDialog();
|
||
}
|
||
|
||
//分拆面板平均分配
|
||
private void splitContainer1_ClientSizeChanged(object sender, EventArgs e)
|
||
{
|
||
if (this.WindowState == FormWindowState.Minimized)
|
||
return;
|
||
|
||
SplitContainer sc = (SplitContainer)sender;
|
||
sc.SplitterDistance = sc.Width / 7*3;
|
||
}
|
||
private void splitContainer3_ClientSizeChanged(object sender, EventArgs e)
|
||
{
|
||
if (this.WindowState == FormWindowState.Minimized)
|
||
return;
|
||
|
||
SplitContainer sc = (SplitContainer)sender;
|
||
sc.SplitterDistance = sc.Height / 2;
|
||
}
|
||
private void Menu查询统计_Click(object sender, EventArgs e)
|
||
{
|
||
FrmWeb frm = new FrmWeb("查询统计", $"reportRecordSN?CustomerVer={Config.CustomerVer}");
|
||
frm.Show();
|
||
}
|
||
|
||
private void tsMenuOrder_Click(object sender, EventArgs e)
|
||
{
|
||
//FrmOrderList frm = new FrmOrderList();
|
||
string subject = (sender as ToolStripMenuItem).Text;
|
||
FrmWeb frm = new FrmWeb(subject, $"reportRecordSN?CustomerVer={Config.CustomerVer}");
|
||
frm.Show();
|
||
}
|
||
private void tsMenuOrderProduct_Click(object sender, EventArgs e)
|
||
{
|
||
string subject = (sender as ToolStripMenuItem).Text;
|
||
FrmWeb frm = new FrmWeb(subject, $"reportRecordProduct?CustomerVer={Config.CustomerVer}");
|
||
frm.Show();
|
||
}
|
||
private void tsMenuStatistics_Click(object sender, EventArgs e)
|
||
{
|
||
string subject = (sender as ToolStripMenuItem).Text;
|
||
FrmWeb frm = new FrmWeb(subject, $"bigscreen/index.html", "http://127.0.0.1:18082/static/");
|
||
frm.Show();
|
||
}
|
||
private void toolStripButton1_Click(object sender, EventArgs e)
|
||
{
|
||
//Bitmap[] bmps = new Bitmap[2];
|
||
//bmps[0] = new Bitmap(@"f:\1.bmp");
|
||
//bmps[1] = new Bitmap(@"f:\111.bmp");
|
||
//List<Dictionary<int, List<string>[]>> list = new List<Dictionary<int, List<string>[]>>();
|
||
//Dictionary<int, List<string>[]> dir = new Dictionary<int, List<string>[]>();
|
||
//List<string>[] vs = new List<string>[1];
|
||
//vs[0] = new List<string>();
|
||
//dir.Add(0, vs);
|
||
//list.Add(dir);
|
||
//showDefectSmallBmps(bmps, list);
|
||
var bmp = Bitmap.FromFile("f:\\1.jpg");
|
||
int pnlWidth = this.pnlBmpList.ClientSize.Width;
|
||
for (int i = 0; i < 5; i++)
|
||
{
|
||
int x = i;
|
||
this.Invoke(new System.Action(() =>
|
||
{
|
||
int imgWidth = 224;
|
||
int imgHeight = 200;
|
||
int splitWidth = 10;
|
||
int index = Convert.ToInt32(this.gboxDefectList.Tag);
|
||
|
||
PictureBox picbox = new PictureBox();
|
||
picbox.Width = imgWidth;
|
||
picbox.Height = imgHeight;
|
||
CheckBox checkBox = new CheckBox();
|
||
picbox.Image = bmp;
|
||
picbox.Name = "imgDefect_" + index;
|
||
picbox.Tag ="1,2,3";
|
||
checkBox.Name = "chkDefect_" + index;
|
||
checkBox.Text = $"第{index + 1}张";
|
||
checkBox.CheckedChanged += new System.EventHandler(this.CheckBox_CheckedChanged);
|
||
|
||
picbox.Click += new EventHandler(defectBmpBox_Click);
|
||
picbox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
|
||
picbox.BorderStyle = BorderStyle.FixedSingle;
|
||
picbox.Margin = new Padding((pnlWidth - picbox.Width) / 2, splitWidth, 0, 0);
|
||
checkBox.Margin = new Padding((pnlWidth - checkBox.Width) / 2+ splitWidth, 0, 0, 0);
|
||
//
|
||
//if (this.pnlBmpList.Controls.Count > 0)
|
||
// {
|
||
// if ((this.pnlBmpList.Controls[this.pnlBmpList.Controls.Count - 1].Right + imgWidth + splitWidth) > this.pnlBmpList.Width)
|
||
// picbox.Location = new System.Drawing.Point(splitWidth, this.pnlBmpList.Controls[this.pnlBmpList.Controls.Count - 1].Bottom + splitWidth);
|
||
// else
|
||
// picbox.Location = new System.Drawing.Point(this.pnlBmpList.Controls[this.pnlBmpList.Controls.Count - 1].Right + splitWidth, this.pnlBmpList.Controls[this.pnlBmpList.Controls.Count - 1].Location.Y);
|
||
// }
|
||
// else
|
||
// {
|
||
// picbox.Location = new System.Drawing.Point(splitWidth, 0);
|
||
// }
|
||
// checkBox.Location = new System.Drawing.Point(picbox.Location.X + 5, picbox.Location.Y + 5);
|
||
// checkBox.ForeColor = Color.Black;
|
||
//}
|
||
this.pnlBmpList.Controls.Add(picbox);
|
||
this.pnlBmpList.Controls.Add(checkBox);
|
||
|
||
//
|
||
index++;
|
||
this.gboxDefectList.Tag = index;
|
||
this.gboxDefectList.Text = $"缺陷图像:{index} 张";
|
||
pnlBmpList.VerticalScroll.Value = pnlBmpList.VerticalScroll.Maximum;
|
||
}));
|
||
}
|
||
}
|
||
|
||
|
||
private void chkBuzzer_CheckedChanged(object sender, EventArgs e)
|
||
{
|
||
this.disableBuzzer = chkBuzzer.Checked;
|
||
if (devContainer.state && this.disableBuzzer)
|
||
devContainer.io_output(CMDName.蜂鸣器输出, false, true, 0);
|
||
}
|
||
|
||
private void chkDoorSensor_CheckedChanged(object sender, EventArgs e)
|
||
{
|
||
this.disableDoorSensor = chkDoorSensor.Checked;
|
||
}
|
||
|
||
private void tsbtnLight_Click(object sender, EventArgs e)
|
||
{
|
||
if (devContainer.state)
|
||
{
|
||
if(tsbtnLight.Text.Trim()== "开灯")
|
||
{
|
||
if(devContainer.io_output(CMDName.日光灯输出))
|
||
tsbtnLight.Text = " 关灯 ";
|
||
}
|
||
else
|
||
{
|
||
if (devContainer.io_output(CMDName.日光灯输出, false, true, 0))
|
||
tsbtnLight.Text = " 开灯 ";
|
||
}
|
||
}
|
||
}
|
||
|
||
private void btnMakeTag_Click(object sender, EventArgs e)
|
||
{
|
||
if(currentPT != CurrentPTEnum.MakeTag)
|
||
{
|
||
AddTextEvent("打标失败", "非可打标状态!");
|
||
return;
|
||
}
|
||
btnMakeTags.Enabled = false;
|
||
autoMakeTagRuning = true;
|
||
Thread threadtest = new System.Threading.Thread(() =>
|
||
{
|
||
try
|
||
{
|
||
if (!devContainer.state)
|
||
{
|
||
AddTextEvent("打标", "设备已停机!");
|
||
return;
|
||
}
|
||
if ((int)this.lblDefectAddTag.Tag < 1)
|
||
{
|
||
AddTextEvent("打标", "打标队列为空!");
|
||
return;
|
||
}
|
||
|
||
int tagIndex;
|
||
double Xmm, Ymm;
|
||
Bitmap currBmp;
|
||
string[] tags;
|
||
for (int i = 0; i < this.pnlBmpList.Controls.Count; i += 2)
|
||
{
|
||
CheckBox cb = this.pnlBmpList.Controls[i + 1] as CheckBox;
|
||
if (cb.Checked)
|
||
{
|
||
PictureBox picBox = this.pnlBmpList.Controls[i] as PictureBox;
|
||
tags = picBox.Tag.ToString().Split(',');
|
||
tagIndex = Convert.ToInt32(tags[0]);
|
||
Xmm = Convert.ToDouble(tags[1]);
|
||
Ymm = Convert.ToDouble(tags[2]);
|
||
currBmp = (Bitmap)picBox.Image;
|
||
|
||
//打标
|
||
AddTextEvent("打标", $"第{i / 2 + 1}/{this.pnlBmpList.Controls.Count / 2}张 [索引:{tagIndex}, X:{Xmm}mm, Y:{Ymm}mm]");
|
||
var list = devContainer.libDefect.makeTag(tagIndex, Xmm, Ymm, currBmp.Width, currBmp.Height);
|
||
devContainer.devAxis.move_ptp(1, list[0], AxMoveMode.绝对位置);
|
||
devContainer.devAxis.move_ptp(2, list[1], AxMoveMode.绝对位置);
|
||
while (!devContainer.devAxis.isReady(1) || !devContainer.devAxis.isReady(2))
|
||
{
|
||
Application.DoEvents();
|
||
Thread.Sleep(100);
|
||
if (!devContainer.state)
|
||
throw new Exception("设备停止,打标中止!");
|
||
}
|
||
//
|
||
if (!devContainer.io_output(CMDName.喷墨输出, false, true, 500))
|
||
throw new Exception("请确认[喷墨输出]指令设置是否正确!");
|
||
|
||
this.Invoke(new System.Action(() =>
|
||
{
|
||
cb.Checked = false;
|
||
}));
|
||
}
|
||
}
|
||
|
||
//自动下料
|
||
AddTextEvent("打标完成", $"批量打标完成,进行下料...");
|
||
currentState = CurrentStateEnum.自动流程结束;
|
||
gotoDownPT();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
AddTextEvent("打标失败", ex.Message, WarningEnum.High);
|
||
warning(WarningEnum.Low, true);
|
||
}
|
||
finally { autoMakeTagRuning=false; }
|
||
});
|
||
threadtest.IsBackground = true;
|
||
threadtest.Start();
|
||
}
|
||
|
||
private void btnInputCode_Click(object sender, EventArgs e)
|
||
{
|
||
txtProductCode_DoubleClick(null, null);
|
||
}
|
||
private void txtProductName_DoubleClick(object sender, EventArgs e)
|
||
{
|
||
txtProductCode_DoubleClick(null, null);
|
||
}
|
||
private void txtProductCode_DoubleClick(object sender, EventArgs e)
|
||
{
|
||
if (currentState != CurrentStateEnum.等待扫码) return;
|
||
|
||
FrmInput frm = new FrmInput(productCodeList, "请选择产品料号:");
|
||
if (frm.ShowDialog() != DialogResult.OK && string.IsNullOrWhiteSpace(frm.inputData))
|
||
return;
|
||
Task.Factory.StartNew(() =>
|
||
{
|
||
devContainer.devCodeScanner.ScanerEvent?.Invoke(frm.inputData);
|
||
});
|
||
|
||
//string code = Interaction.InputBox("请输入产品编码", "输入框", "", -1, -1).Trim();
|
||
//if(code != "")
|
||
//{
|
||
// Task.Factory.StartNew(() =>
|
||
// {
|
||
// devContainer.devCodeScanner.ScanerEvent?.Invoke(frm.inputData);
|
||
// });
|
||
//}
|
||
}
|
||
|
||
private void txtProductSN_DoubleClick(object sender, EventArgs e)
|
||
{
|
||
//if (currentState != CurrentStateEnum.等待扫码 || this.txtProductCode.Text.Trim()=="") return;
|
||
|
||
//string sn = Interaction.InputBox("请输入产品SN码", "输入框", "", -1, -1).Trim();
|
||
//if (sn != "")
|
||
//{
|
||
// this.txtProductSN.Text = sn;
|
||
// string code = this.txtProductCode.Text.Trim();
|
||
// Task.Factory.StartNew(() =>
|
||
// {
|
||
// devContainer.devCodeScanner.ScanerEvent?.Invoke(code);
|
||
// });
|
||
//}
|
||
}
|
||
private void 测试ToolStripMenuItem_Click(object sender, EventArgs e)
|
||
{
|
||
tsbtnDefectImage.Enabled = tsbtnSizeImage.Enabled=true;
|
||
return;
|
||
Form1 frm = new Form1();
|
||
frm.Show();
|
||
//tsbtnDefectImage_Click(null, null);
|
||
return;
|
||
try
|
||
{
|
||
//string ls = "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,182.257722637742,182.257727282667,0,0";
|
||
//List<string> list = new List<string>(ls.Split(','));
|
||
//lstPT = list.Select<string, double>(q => Convert.ToDouble(q)).ToList();
|
||
//updatePTValue(1,2);
|
||
//lstPT.Add(10);
|
||
//lstPT.Add(0);
|
||
//updatePTValue(1, 2);
|
||
//{
|
||
// lstLineWidth.Add(res.Shanxian > 0 ? res.Shanxian : 0);
|
||
// updateLineWidthValue(model.LineWidthBaseValue + model.LineWidthUpFloatValue, model.LineWidthBaseValue - model.LineWidthDownFloatValue);
|
||
//}
|
||
//return;
|
||
|
||
//loadProductCodeList();
|
||
//FrmInput frm = new FrmInput(null, "请选择产品编码:");
|
||
//if (frm.ShowDialog() != DialogResult.OK)
|
||
// return;
|
||
//var model = svcProduct.GetModelNav(frm.inputData);
|
||
//if (model == null)
|
||
// throw new Exception("没有此产品!");
|
||
//order.ProductId = model.Id;
|
||
//order.BatchId = model.BatchId;
|
||
//order.StepId = model.StepId==null? 0:(int)model.StepId;
|
||
//frm = new FrmInput(null, "请输入SN:");
|
||
//if (frm.ShowDialog() != DialogResult.OK)
|
||
// return;
|
||
//order.SN = frm.inputData;
|
||
|
||
//frm = new FrmInput(null, "请输入主机台Mark点数据:", "[0,0,0,0,0,0,0,0]");
|
||
//if (frm.ShowDialog() != DialogResult.OK)
|
||
// return;
|
||
//order.MarkData= frm.inputData;
|
||
//order.Tension1 = order.Tension2 = order.Tension3 = order.Tension4 = order.Tension5 = order.Tension5 + 3;
|
||
//order.PT1 = order.PT4 = order.PT5 = order.PT6 = order.PT6 + 1.33;
|
||
//order.LineWidth2 = order.LineWidth3 = order.LineWidth5 = order.LineWidth6 = +order.LineWidth6 + 1.22;
|
||
|
||
//order.HeightValue = order.Height1 = order.Height3 = order.Height4 = 55;
|
||
//order.DefectCount = order.DefectCount + 22;
|
||
//order.YXCount = order.PPCount = 33;
|
||
//order.TimeLen = 1000;
|
||
//order.Succeed = true;
|
||
//order.ModifyUserCode = order.CreateUserCode = Config.loginUser.Code;
|
||
|
||
//if (!svcOrder.Insert(order))
|
||
// AddTextEvent("保存失败", $"保存生产记录失败!");
|
||
//MessageBox.Show("成功!");
|
||
|
||
//---------------
|
||
this.lstCompareFailZoomImage.Add((Bitmap)Bitmap.FromFile(@"f:\1.bmp"));
|
||
this.lstCompareFailZoomImage.Add((Bitmap)Bitmap.FromFile(@"f:\2.bmp"));
|
||
this.lstCompareFailZoomImage.Add((Bitmap)Bitmap.FromFile(@"f:\3.bmp"));
|
||
}
|
||
catch(Exception ex)
|
||
{
|
||
MessageBox.Show(ex.Message);
|
||
}
|
||
}
|
||
|
||
private void toolStripSeparator4_Click(object sender, EventArgs e)
|
||
{
|
||
|
||
}
|
||
|
||
private void chkHttpLog_CheckedChanged(object sender, EventArgs e)
|
||
{
|
||
if (this.chkHttpLog.Checked)
|
||
{
|
||
webService.LogEvent = (warning, msg) =>
|
||
{
|
||
AddTextEvent("HTTP服务", msg, warning);
|
||
};
|
||
}
|
||
else
|
||
webService.LogEvent = null;
|
||
}
|
||
//打开比对失败的图片
|
||
private void lblCompareResult_Click(object sender, EventArgs e)
|
||
{
|
||
if (lstCompareFailZoomImage.Count < 1) return;
|
||
FrmPhotoShow frm = new FrmPhotoShow(lstCompareFailZoomImage);
|
||
frm.ShowDialog();
|
||
}
|
||
|
||
//过程变量查看
|
||
private void tsbtnSizeTag_Click(object sender, EventArgs e)
|
||
{
|
||
if (order == null || order.SizeTagDataList == null || order.SizeTagDataList.Count<1)
|
||
return;
|
||
|
||
FrmShowSizeTag frm = new FrmShowSizeTag(order);
|
||
frm.Show();
|
||
}
|
||
|
||
//缺陷+比对与图纸查看
|
||
private void tsbtnDefectImage_Click(object sender, EventArgs e)
|
||
{
|
||
//currProductModel = svcProduct.GetModelNav(53);
|
||
//order = svcOrder.GetModelNav("20230814002");
|
||
AddTextEvent("打开窗口", "1");
|
||
if (currProductModel ==null || order == null || order.DefectInfoList == null || order.DefectInfoList.Count < 1)
|
||
return;
|
||
AddTextEvent("打开窗口", "2");
|
||
//图纸
|
||
try
|
||
{
|
||
string gbxBmpPath = "";
|
||
var attachmentFile = currProductModel.AttachmentList.FirstOrDefault(x => x.Type == 0);
|
||
if (attachmentFile != null)
|
||
{
|
||
gbxBmpPath = Application.StartupPath + $"\\Attachment\\product\\{attachmentFile.NameTimestamp}";
|
||
if (!File.Exists(gbxBmpPath + ".bmp")) gbxBmpPath = "";
|
||
}
|
||
AddTextEvent("打开窗口", "3");
|
||
if (string.IsNullOrEmpty(gbxBmpPath))
|
||
{
|
||
MessageBox.Show("图纸文件不存在!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||
return;
|
||
}
|
||
AddTextEvent("打开窗口", "4");
|
||
if (!File.Exists(gbxBmpPath + ".jpg"))//转背景后的图纸文件
|
||
{
|
||
AddTextEvent("打开窗口", "5");
|
||
//换背景JPG
|
||
Mat mat = Cv2.ImRead(gbxBmpPath + ".bmp");
|
||
Cv2.CvtColor(mat, mat, ColorConversionCodes.RGB2GRAY);//转灰度图
|
||
for (int i = 0; i < mat.Height; i++)
|
||
{
|
||
for (int j = 0; j < mat.Width; j++)
|
||
{
|
||
if (mat.At<byte>(i, j) == 255)//白色
|
||
mat.Set<byte>(i, j, 0);
|
||
else
|
||
mat.Set<byte>(i, j, 255);
|
||
}
|
||
}
|
||
AddTextEvent("打开窗口", "6");
|
||
//灰转彩
|
||
//Cv2.CvtColor(mat, mat, ColorConversionCodes.GRAY2RGB);
|
||
//for (int i = 0; i < mat.Height; i++)
|
||
//{
|
||
// for (int j = 0; j < mat.Width; j++)
|
||
// {
|
||
// if (mat.At<byte>(i, j) == 255)//白色
|
||
// mat.Set<byte>(i, j, 0); //黄色
|
||
// }
|
||
//}
|
||
OpenCvSharp.Extensions.BitmapConverter.ToBitmap(mat).Save(gbxBmpPath + ".jpg", ImageFormat.Jpeg);
|
||
}
|
||
AddTextEvent("打开窗口", "7");
|
||
//
|
||
ToolStripButton btn = sender as ToolStripButton;
|
||
AddTextEvent("打开窗口", btn.Tag.ToString());
|
||
FrmShowDefectImage frm = new FrmShowDefectImage(gbxBmpPath + ".jpg", order, string.IsNullOrEmpty(btn.Tag.ToString()) ? 0 : Convert.ToInt32(btn.Tag.ToString()));
|
||
frm.Show();
|
||
AddTextEvent("打开窗口", "9");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show(ex.Message, "异常", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, 0);
|
||
}
|
||
}
|
||
|
||
private void tsbtnLog_Click(object sender, EventArgs e)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(Config.LogPath)) return;
|
||
string lsPath = (Config.LogPath + "\\" + DateTime.Now.ToString("yyyyMM") + "\\").Replace("\\\\", "\\");
|
||
if(!Directory.Exists(lsPath))
|
||
Directory.CreateDirectory(lsPath);
|
||
System.Diagnostics.Process.Start("explorer.exe", lsPath);
|
||
}
|
||
}
|
||
}
|