banboshi_V1/halftoneproject-master/AssistClient/FrmMain.cs

2277 lines
109 KiB
C#
Raw Normal View History

using Advantech.Motion;
using AssistClient.Device;
using AssistClient.Utils;
using Models;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OpenCvSharp;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Dynamic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Yolo5;
using static AssistClient.Device.SizeLib;
using Point = System.Drawing.Point;
using Size = System.Drawing.Size;
namespace AssistClient
{
public partial class FrmMain : Form
{
#region pic缩放变量
private double ratio = 1; // 图片的起始显示比例
private double ratioStep = 0.1;
private Size pic_size;
private int xPos;
private int yPos;
#endregion
private bool bExitApp = false;
private Service.ProductService svcProduct = new Service.ProductService();
private Service.OrderService svcOrder = new Service.OrderService();
private DevContainer devContainer = new DevContainer();
private Queue<scannerCBmpLoc> scannerCBmpQueue = new Queue<scannerCBmpLoc>();
private int sizeBmpNum = 0, sizeBmpNumResult = 0;
private string SN = "";
private int OrderId = 0;
private JArray currProductMarkList = null;
private int currDefectIndex = 0;
private List<DefectStruct> defectList = new List<DefectStruct>();
private Dictionary<string, Bitmap> defectBmpsDir = new Dictionary<string, Bitmap>();
private Dictionary<string, List<List<string>>> defectInfoDir = new Dictionary<string, List<List<string>>>();
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 System.Timers.Timer timer = new System.Timers.Timer();
Yolo_Class yolo = new Yolo_Class();
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.tsbtnCloseDev.Visible = false;
this.dgvProcess.AutoGenerateColumns = false;
//显示行号与列宽度自动调整
dgvProcess.RowHeadersVisible = true;
dgvProcess.RowHeadersWidth = 30;
dgvProcess.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
//dgvProcess.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders;//数据量过百绑定太变
dgvProcess.RowPostPaint += (sender, e) =>//序号列头
{
Utils.Util.showRowNum_onDataGrid_RowPostPaint(this.dgvProcess, sender, e);
};
for (int i = 0; i < dgvProcess.Columns.Count; i++)//禁止点击列头排序
dgvProcess.Columns[i].SortMode = DataGridViewColumnSortMode.NotSortable;
//模糊查询,Append自动填充
this.cbxSN.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
this.cbxSN.AutoCompleteSource = AutoCompleteSource.ListItems;
}
private void FrmMain_Load(object sender, EventArgs e)
{
this.tsbtnPause.Left = this.tsbtnGoDownPT.Left = this.gpbZAxis.Right + 10;
}
private void FrmMain_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 FrmMain_FormClosed(object sender, FormClosedEventArgs e)
{
Application.Exit();
System.GC.Collect();
System.Environment.Exit(0);
}
#region
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 tsMenuPTSetting_Click(object sender, EventArgs e)
{
if (devContainer.state)
{
MessageBox.Show("请先停止设备,再进行设置!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
FrmPTSetting from = new FrmPTSetting();
from.ShowDialog();
}
private void tsMenuCmdSetting_Click(object sender, EventArgs e)
{
if (devContainer.state)
{
MessageBox.Show("请先停止设备,再进行设置!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
FrmCMDProcess from = new FrmCMDProcess();
from.ShowDialog();
}
private void tsMenuSysSetting_Click(object sender, EventArgs e)
{
FrmSysSetting frmSetting = new FrmSysSetting();
frmSetting.ShowDialog();
}
#endregion
#region
private void reloadPic(Bitmap bmp, List<List<string>> defectInfor2RepairTable, DefectStruct defectInfo)
{
//绘框
if (defectInfor2RepairTable != null && defectInfo != null)
{
AddTextEvent("更新图片", $"打标:MainX={defectInfo.MainX},MainY={defectInfo.MainY},CurrIndex={defectInfo.CurrIndex},RepairTable={JsonConvert.SerializeObject(defectInfor2RepairTable)}", warningLevel);
Mat mat = OpenCvSharp.Extensions.BitmapConverter.ToMat(bmp);
mat = yolo.RepairTableDrawRec(defectInfor2RepairTable, defectInfo.MainX, defectInfo.MainY, defectInfo.CurrIndex, mat);
bmp = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(mat);
}
else
AddTextEvent("更新图片", "无需打标!", warningLevel);
var newSize = Util.getNewSize(splitContainer2.Panel1.ClientSize, new Size(bmp.Size.Width*100, bmp.Size.Height*100));
this.pnlPic.Size = newSize;
if (this.pnlPic.Width < splitContainer2.Panel1.ClientSize.Width)
this.pnlPic.Left = (splitContainer2.Panel1.ClientSize.Width - this.pnlPic.Width) / 2;
if (this.pnlPic.Height < splitContainer2.Panel1.ClientSize.Height)
this.pnlPic.Top = (splitContainer2.Panel1.ClientSize.Height - this.pnlPic.Height) / 2;
ratio = 1.0;// 图片的起始显示比例
Size size = bmp.Size;
//this.pnlPic.ClientSize = new Size(this.pnlPic.ClientSize.Width,
// (int)(this.pnlPic.ClientSize.Width * (size.Height * 1.0f / size.Width)));
this.pictureBox1.Size = this.pnlPic.ClientSize;
this.pictureBox1.Location = new Point(0, 0);
this.pictureBox1.Image = bmp;//del
pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
//2023-12-22 之前工程师写的存在bug屏蔽
pictureBox1.MouseWheel += new MouseEventHandler(pictureBox1_MouseWheel);
pictureBox1.MouseMove += pictureBox1_MouseMove;
pictureBox1.MouseDown += pictureBox1_MouseDown;
this.ActiveControl = this.pictureBox1; // 设置焦点
pic_size = this.pnlPic.ClientSize;
}
private void pictureBox1_MouseWheel(object sender, MouseEventArgs e)
{
//Point pictureBoxPoint = this.PointToClient(Cursor.Position);
////this.Text = $"{e.X}:{e.Y}; {pictureBoxPoint.X}:{pictureBoxPoint.Y}; {pictureBox1.Left}:{pictureBox1.Top}; " +
//// $"{this.pictureBox1.Width}:{this.pictureBox1.Height}; {this.Width}:{this.Height}; " +
//// $"Cursor:{Cursor.Position.X}:{Cursor.Position.Y}";
//if (e.Delta > 0)
//{
// ratio += ratioStep;
// if (ratio > 100) // 放大上限
// ratio = 100;
// else
// {
// int x = (int)(pictureBox1.Left - e.X * (e.X * 1.0d / pictureBox1.Width * ratioStep) + 0.5);
// int y = (int)(pictureBox1.Top - e.Y * (e.Y * 1.0d / pictureBox1.Height * ratioStep) + 0.5);
// //this.Text = $"{pictureBox1.Width}-{pic_size.Width};{ratio}{pictureBox1.Left}-{e.X}* 比例:{e.X*1.0d/pictureBox1.Width}={e.X}/{pictureBox1.Width} * {(ratioStep)}={x} | " +
// // $"{pictureBox1.Top}-{e.Y}* {e.Y * 1.0f / pictureBox1.Height * (ratio - 1.0d)}={y}";
// this.changePictureBoxSize(new Point(x, y), ratio);
// }
//}
//else if (ratio - ratioStep >= 1)
//{
// ratio -= ratioStep;
// //if (ratio < 0.1) // 放大下限
// // ratio = 0.1;
// //else
// int x = (int)(pictureBox1.Left + e.X * (e.X * 1.0d / pictureBox1.Width * ratioStep) + 0.5);
// int y = (int)(pictureBox1.Top + e.Y * (e.Y * 1.0d / pictureBox1.Height * ratioStep) + 0.5);
// this.changePictureBoxSize(new Point(x, y), ratio);
//}
}
private void changePictureBoxSize(Point location, double ratio)
{
//var picSize = pictureBox1.Size;
//picSize.Width = Convert.ToInt32(picSize.Width * ratio);
//picSize.Height = Convert.ToInt32(picSize.Height * ratio);
//pictureBox1.Size = picSize;
//if (location.X > 0) location.X = 0;
//if (location.Y > 0) location.Y = 0;
//if (picSize.Width + location.X < this.pnlPic.ClientSize.Width) location.X = -(picSize.Width - this.pnlPic.ClientSize.Width);
//if (picSize.Height + location.Y < this.pnlPic.ClientSize.Height) location.Y = -(picSize.Height - this.pnlPic.ClientSize.Height);
////Point location = new Point();
////location.X = (this.ClientSize.Width - this.pictureBox1.Width) / 2;
////location.Y = (this.ClientSize.Height - this.pictureBox1.Height) / 2;
//this.pictureBox1.Location = location;
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
//try
//{
// // 鼠标按下拖拽图片
// if (e.Button == MouseButtons.Left)
// {
// this.Text = $"{e.X}:{e.Y};{xPos}:{yPos}";
// // 限制拖拽出框
// if (pictureBox1.Width > this.pnlPic.ClientSize.Width
// || pictureBox1.Height > this.pnlPic.ClientSize.Height)
// {
// int moveX = e.X - xPos;
// int moveY = e.Y - yPos;
// if ((pictureBox1.Left + moveX) <= 0
// && (pictureBox1.Top + moveY) <= 0
// && (pictureBox1.Right + moveX) >= this.pnlPic.ClientSize.Width
// && (pictureBox1.Bottom + moveY) >= this.pnlPic.ClientSize.Height)
// {
// pictureBox1.Left += moveX;//设置x坐标.
// pictureBox1.Top += moveY;//设置y坐标.
// }
// }
// }
//}
//catch (Exception dd)
//{
// MessageBox.Show(dd.Message);
//}
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
//xPos = e.X;//当前x坐标.
//yPos = e.Y;//当前y坐标.
}
#endregion
#region Fun
private Thread threadProcess;
/// <summary>
/// 启动
/// </summary>
private void startCommand()
{
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//开始/重新开始
{
//校正从复位-》运行,不会新启动
resetUIValue();
AddTextEvent("启动", "移动至上料位...");
Task.Run(() => { loadOrderSNList(); });//加载SN
gotoUpPT();
this.Invoke(new System.Action(() =>
{
//新开始
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);
if(currentState== CurrentStateEnum.)
AddTextEvent("急停", $"当前工序索引:{currProcessIndex + 1}", WarningEnum.High);
else
AddTextEvent("急停", $"已急停,请人工处理。", WarningEnum.High);
}
private bool reseting = false;
private void resetCommand()
{
currentState = CurrentStateEnum.;
warningLevel = WarningEnum.Normal;
currentPT = CurrentPTEnum.InitPT;
this.Invoke(new System.Action(() =>
{
this.tsbtnWarning.Enabled = this.tsbtnGoDownPT.Enabled = this.tsbtnStart.Enabled
= this.tsbtnStopNow.Enabled = this.tsbtnPause.Enabled = this.tsbtnReset.Enabled
= this.gpbXYAxis.Enabled = gpbZAxis.Enabled = false;
}));
try
{
if (devContainer.state && !reseting)
{
reseting = true;
resetUIValue();
AddTextEvent("复位", $"设备复位中...");
this.setButtonEnabled(this.tsbtnReset, false);
if ((AxisState)devContainer.devAxis.AxState[0] == AxisState.STA_AX_EXT_JOG) devContainer.devAxis.closeJogMode(0);//关闭jog时自动停止
if ((AxisState)devContainer.devAxis.AxState[1] == AxisState.STA_AX_EXT_JOG) devContainer.devAxis.closeJogMode(1);//关闭jog时自动停止
// 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);//闪
//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);
//devContainer.devAxis.setAxisVelParam(40000,200000,5000000, 5000000,i,true);
devContainer.devAxis.home(i, (uint)Config.Axis_HomeMode[i], (uint)Config.Axis_HomeDir[i]);
}
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();
}
//
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.MODE1_Abs);
}
while (!devContainer.devAxis.isReady())
{
if (!devContainer.state || warningLevel != WarningEnum.Normal)
return;
Thread.Sleep(100);
//Application.DoEvents();
}
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);
this.setButtonEnabled(this.cbxSN, false);
this.Invoke(new System.Action(() =>
{//根据UI上是否勾选打开激光
chkLaser_CheckedChanged(null, null);
}));
//devContainer.io_output(CMDName.复位按钮, false, true, 0);//熄灭
devContainer.io_output(CMDName.);//长亮
currentPT = CurrentPTEnum.InitPT;
currentState = CurrentStateEnum.;
AddTextEvent("复位", $"复位完成。");
}
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.MODE1_Abs);
}
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.;
this.setButtonEnabled(cbxSN, true);
AddTextEvent($"上料", "到达上料位!");
}
catch (Exception ex)
{
AddTextEvent("上料", "上料初始失败 Err:" + ex.Message, WarningEnum.High);
warning(WarningEnum.High);
}
}
/// <summary>
/// 下料(暂当完成)
/// </summary>
private void gotoDownPT()
{
try
{
AddTextEvent("下料", "检测状态...");
if (!devContainer.state || warningLevel != WarningEnum.Normal)
{
AddTextEvent("下料失败", "轴状态异常!", WarningEnum.Low);
return;
}
AddTextEvent("下料", "开始下料!");
if (!devContainer.devAxis.isReady())
{
AddTextEvent("下料失败", "轴状态异常!", WarningEnum.Low);
return;
}
if (currentState != CurrentStateEnum. && currentState != CurrentStateEnum. && currentState != CurrentStateEnum.)
{
AddTextEvent($"下料", $"非可下料状态:{currentState.ToString()}");
return;
}
currentState = CurrentStateEnum.;
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.MODE1_Abs);
}
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., false, true, 0);
devContainer.devLight.setDigitalValue(1, 0);//关闭上光源
devContainer.devLight.setDigitalValue(2, 0);//关闭下光源
this.Invoke(new System.Action(() =>
{
this.chkLaser.Checked = false;
this.gpbXYAxis.Enabled = gpbZAxis.Enabled = false;
}));
setButtonEnabled(tsbtnStart, true);
setButtonEnabled(tsbtnGoDownPT, false);
AddTextEvent($"下料", "下料完成!");
//更新指定列
//2023-10-31 加入异常情况
FrmRepairInfo frmInfo = new FrmRepairInfo();
DialogResult dr = frmInfo.ShowDialog();
if (svcOrder.Update(it => new Order() {
State = dr == DialogResult.OK? 10 :5 ,
2023-11-01 15:13:54 +08:00
Abnormalities = frmInfo.RepairInfo,
RepairCode = Config.loginUser.Code
}, it => it.Id == OrderId))
AddTextEvent($"检测结束", $"保存检测结果成功。");
else
AddTextEvent($"检测结束", $"保存检测结果失败!",WarningEnum.High);
}
catch (Exception ex)
{
AddTextEvent("下料", "下料失败 Err:" + ex.Message, WarningEnum.High);
warning(WarningEnum.High);
}
}
private void openLowerLight()//下光源
{
var value = devContainer.devLight.getDigitalValue(2);
devContainer.devLight.setDigitalValue(2, value == 0 ? 255 : 0);
}
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;
}));
}
#endregion
#region nextProcess
/// <summary>
/// 中断工序运行
/// </summary>
/// <returns></returns>
private bool isBreakProcessRun()
{
return warningLevel != WarningEnum.Normal || currentState != CurrentStateEnum.;
}
private void runStep()
{
sizeBmpNum = sizeBmpNumResult = 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.devCodeScanner.isLock ||!devContainer.state
|| currentState != CurrentStateEnum. || string.IsNullOrWhiteSpace(code) )
return;
devContainer.devCodeScanner.isLock = true;
Thread threadtest = new System.Threading.Thread(() =>
{
try
{
//注需要重复输入SN时不能在此释放
//devContainer.devCodeScanner.stop();
//devContainer.devCodeScanner = null;
//
AddTextEvent("扫码枪", $"开始读取网版编码:{code} 数据...");
var modOrder = svcOrder.GetModelNav(code);//from sn
//AddTextEvent("扫码枪", $"读取网版编码:{code}DB数据完成");
string modeState = "";
if (modOrder == null)
AddTextEvent("扫码枪", $"网版编码{code}不存在!");
if (modOrder.State == 5)
{
modeState = $"网版编码{code}已被检测!";
AddTextEvent("扫码枪", $"网版编码{code}已被检测!");
loadOrderSNList();
}
else if (modOrder.State == 10)
{
modeState = $"网版编码{code}已被检测, 并且异常!";
2023-11-01 15:13:54 +08:00
AddTextEvent("扫码枪", $"网版编码{code}已被检测, 并且异常!");
loadOrderSNList();
}
2023-11-01 15:13:54 +08:00
if(!string.IsNullOrEmpty(modeState))
{
if(DialogResult.No == MessageBox.Show(modeState + "是否重新检测!", "网版已被检测", MessageBoxButtons.YesNo, MessageBoxIcon.Information))
{
return;
}
}
//2023-10-20
//else if (modOrder.ProductInfo == null)
if (modOrder.ProductInfo == null)
AddTextEvent("扫码枪", $"网版编码:{code}对应产品信息已不存在!");
else if (modOrder.DefectCount < 1)
AddTextEvent("扫码枪", $"网版编码:{code}没有缺陷!");
//else if (string.IsNullOrWhiteSpace(modOrder.MarkData))
// AddTextEvent("扫码枪", $"产品(网版编码:{code})在主机台未保存原始Mark点!");
else if (modOrder.ProductInfo.AssistStepInfo == null
|| modOrder.ProductInfo.AssistStepInfo.ProcessList.Count < 1)
AddTextEvent("扫码枪", $"产品({modOrder.ProductInfo.Name})未配置检测流程!");
else
{
if (string.IsNullOrWhiteSpace(modOrder.MarkData))
{
AddTextEvent("扫码枪", $"产品(网版编码:{code})在主机台未保存原始Mark点!");
modOrder.MarkData = "[0,0,0,0,0,0,0,0]";
}
else
AddTextEvent("主机台", $"主机台Mark数据:{modOrder.MarkData}");
currProductMarkList = JArray.Parse(modOrder.MarkData);
if (currProductMarkList.Count < 8)
{
AddTextEvent("主机台", $"产品(网版编码:{code})在主机台原始Mark点数量错误!");
return;
}
//异步读取
JObject parm = new JObject()
{
{"date",modOrder.CreateTime.ToString("yyyyMMdd") },
{"sn",code }
};
Task.Run(() => loadDefectInfo(parm));
//
devContainer.devCodeScanner.stop();
devContainer.devCodeScanner = null;
currentState = CurrentStateEnum.;
currentPT = CurrentPTEnum.Moving;
currProductModel = modOrder.ProductInfo;
AddTextEvent("扫码枪", $"网版编码:{code}({currProductModel.Name} {currProductModel.Spec} [{currProductModel.Code}])");
this.Invoke(new System.Action(() =>
{
this.cbxSN.Enabled = false;
this.txtBatchId.Text = modOrder.BatchId.ToString();
this.txtProductName.Text = currProductModel.Name;
this.txtProductCode.Text = currProductModel.Code;
this.txtCreateTime.Text = modOrder.CreateTime.ToString("yyyy-MM-dd HH:mm");
//this.dgvProcess.DataSource = new BindingSource(currProductModel.StepInfo.ProcessList, null);
devContainer.libFor.clear();
devContainer.libIF.clear();
}));
//
this.SN = code;
this.OrderId = modOrder.Id;
this.setButtonEnabled(this.tsbtnPause, true);
this.setButtonEnabled(this.tsbtnStopNow, true);
devContainer.devLight.setDigitalValue(2, 255);//下光源
int nextStepId = 0;
do
{
nextStepId = nextProcess(currProductModel, nextStepId);
} while (nextStepId >= 0 && !isBreakProcessRun());
}
}
catch (Exception ex)
{
AddTextEvent("扫码枪", $"读取网版编码信息失败:{ex.Message}");
}
finally
{
if (devContainer.devCodeScanner != null)
devContainer.devCodeScanner.isLock = false;
}
});
threadtest.IsBackground = true;
threadtest.Start();
};
}
private void loadDefectInfo(object parm)
{
try
{
JObject req = (JObject)parm;
currDefectIndex = 0;
defectList.Clear();
defectInfoDir.Clear();
defectBmpsDir.Clear();
//从主机台取缺陷文件名列表和JSON数组
var obj = WebApi.getDefectFromSN(req);
if (obj.Value<int>("code") != 200)
throw new Exception(obj.Value<string>("data"));
//
var defectInfo = obj.Value<JObject>("data"); //文件名列表(主机台已对文件名排序,这里不需再排序(主机台按各自index进行的排序比对在缺陷文件名后面)
if (defectInfo.Count < 1)
throw new Exception("主机台缺陷文件已不存在!");
//string date = req.Value<string>("date");
//string sn = req.Value<string>("sn");
getDefectBmpList(req, defectInfo);
}
catch (Exception ex)
{
AddTextEvent("网络访问",$"{ex.Message}",WarningEnum.High);
warning(WarningEnum.High);
}
}
/// <summary>
/// 通过文件名列表取各文件名对应BMP
/// </summary>
/// <param name="req"></param>
/// <param name="defectInfo">文件名列表</param>
private void getDefectBmpList(JObject req, JObject defectInfo)
{
int liStep = 0;
try
{
#region
foreach (var kv in defectInfo)
{
defectInfoDir.Add(kv.Key, JsonConvert.DeserializeObject<List<List<string>>>(kv.Value.ToString()));
//
//["4","3.9","-0.8","dk","0.39"],["index","X","Y","缺陷类型","缺陷的置信度"]
JArray arr = kv.Value as JArray;//二维数组
AddTextEvent("主机台", $"缺陷大项:{kv.Key},含小项:{arr.Count}.");
foreach (JArray arr2 in arr) {
var obj = new DefectStruct();
obj.Key = kv.Key;
obj.Index = Convert.ToInt32(arr2[0].ToString());
obj.X = Convert.ToDouble(arr2[1].ToString());
obj.Y = Convert.ToDouble(arr2[2].ToString());
obj.DefectName = Config.getDefectName(arr2[3].ToString());
obj.DefectCC = Convert.ToDouble(arr2[4].ToString());
defectList.Add(obj);
}
}
this.Invoke(new System.Action(() =>
{
//注这样绑定List中的对象必需得用{get;set;}方式定义属性,否则单独格为空内容
AddTextEvent("主机台", $"准备显示缺陷列表,共{defectList.Count}项.");
this.dgvProcess.DataSource = new BindingSource(defectList, null);
AddTextEvent("主机台", $"显示缺陷列表完成.");
this.gpbDefectList.Text = $"缺陷明细({defectList.Count}条)";
//2023-11-1 图纸对比缺陷标红
2023-11-01 15:13:54 +08:00
for (int i = 0; i < defectList.Count; i++)
{
string defName = (string)this.dgvProcess.Rows[i].Cells["colDefectName"].Value;
if ((defName == Config.getDefectName("ds"))||((defName == Config.getDefectName("yx"))))
this.dgvProcess.Rows[i].DefaultCellStyle.BackColor = Color.Red;
}
}));
#endregion
req.Add("file_name", "");
liStep = 1;
bool first = true;
int index = 1;
foreach (var kv in defectInfo)
{
req["file_name"] = kv.Key;
var obj = WebApi.getDefectBmpBase64(req);
if (!devContainer.state || warningLevel == WarningEnum.High ||
(currentState != CurrentStateEnum. && currentState != CurrentStateEnum. && currentState != CurrentStateEnum. && currentState != CurrentStateEnum.))
return;
if (obj.Value<int>("code") != 200)
throw new Exception(obj.Value<string>("data"));
Bitmap bmp = new Bitmap(new MemoryStream(Convert.FromBase64String(obj.Value<string>("data"))));
defectBmpsDir.Add(kv.Key, bmp);
AddTextEvent("网络访问", $"已读取第{index++}/{defectInfo.Count}张缺陷图片;");
if (first)
{
first = false;
this.Invoke(new System.Action(() =>
{
this.reloadPic(bmp,null,null);
pictureBox1.Tag = kv.Key;
}));
}
}
}
catch (Exception ex)
{
if (liStep == 0)
{
AddTextEvent("网络访问", $"解析主机缺陷报文失败:{ex.Message}",WarningEnum.High);
warning(WarningEnum.High);
}
else
AddTextEvent("网络访问", $"读取主机台缺陷Bmp图片失败{ex.Message}");
}
}
private void convert2LocXY()
{
//AddTextEvent($"缺陷项", $"转换缺陷项坐标值...");
// public string Key;
//public string Key0;//index
//public string Key1;//X
//public string Key2;//Y
//public string Key3;//缺陷类型
//public string Key4;//缺陷的置信度
currDefectIndex = 0;
defectList.Clear();
double X, Y;
int MainIndex;
foreach (var item in defectInfoDir)
{
//Key : Defect_SN{order.SN}_I{res.index}_X{res.Xmm}_Y{res.Ymm}_C{res.defectCount}
string[] str = item.Key.Split('_');
MainIndex = Convert.ToInt32(str[2].Substring(1));
X = Convert.ToDouble(str[3].Substring(1));
Y = Convert.ToDouble(str[4].Substring(1));
AddTextEvent("主机台", $"转换前,缺陷大项:{item.Key},含小项:{item.Value.Count}.");
var arr = yolo.ImageXY2RepairTable(item.Value, X, Y, Config.SizeRepairTablePath);
AddTextEvent("主机台", $"转换后,缺陷大项:{item.Key},含小项:{arr.Count}.");
int i = 0;
foreach (var arr2 in arr)
{
var obj = new DefectStruct();
obj.Key = item.Key;
obj.CurrIndex = i++;
obj.MainIndex = MainIndex;
obj.MainX = X;
obj.MainY = Y;
obj.Index = Convert.ToInt32(arr2[0].ToString());
obj.X = Convert.ToDouble(arr2[1].ToString());
obj.Y = Convert.ToDouble(arr2[2].ToString());
obj.DefectName = Config.getDefectName(arr2[3].ToString());
obj.DefectCC = Convert.ToDouble(arr2[4].ToString());
defectList.Add(obj);
}
}
//2024-03-05 将尺寸未通过排到最前
for (int i = (defectList.Count - 1); i >=0 ; i--)
{
if (defectList[i].DefectName == Config.getDefectName("wtg"))
{
defectList.Insert(0, defectList[i]);
defectList.RemoveAt(i + 1);
}
}
this.Invoke(new System.Action(() =>
{
this.dgvProcess.DataSource = null;
//注这样绑定List中的对象必需得用{get;set;}方式定义属性,否则单独格为空内容
this.dgvProcess.DataSource = new BindingSource(defectList, null);
this.gpbDefectList.Text = $"缺陷明细({defectList.Count}条)";
}));
gotoDefctListIndex(currDefectIndex);
}
private void gotoDefctListIndex(int index,int preIndex=-1)
{
try
{
AddTextEvent($"缺陷项", $"移至缺陷项:{index + 1}...");
this.Invoke(new System.Action(() =>
{
string key = defectList[index].Key;
if (defectBmpsDir.ContainsKey(key))
{
if (pictureBox1.Tag == null || pictureBox1.Tag.ToString() != key)
{
//reloadPic(defectBmpsDir[key], defectInfoDir[key], defectList[index]);
pictureBox1.Tag = key;
}
reloadPic(defectBmpsDir[key], defectInfoDir[key], defectList[index]);
}
else
AddTextEvent($"缺陷项", $"缺陷图:{defectList[index].Key}还未传输完成!");
if (preIndex > -1)
this.dgvProcess.Rows[preIndex].DefaultCellStyle.BackColor = Color.White;
this.dgvProcess.Rows[index].DefaultCellStyle.BackColor = Color.LightGreen;
this.dgvProcess.Rows[index].Selected = true;
this.dgvProcess.CurrentCell = this.dgvProcess.Rows[index].Cells["colResult"];
this.dgvProcess.Rows[index].Cells["colResult"].Value = "已检";
}));
if ((defectList[index].X <= 0) || (defectList[index].Y <= 0))
{
AddTextEvent($"缺陷项", $"移动报错,当前缺陷项({index + 1})坐标:X{defectList[index].X},Y{defectList[index].Y}", WarningEnum.Low);
return;
}
while (!devContainer.devAxis.isReady(0)) Thread.Sleep(100);
devContainer.devAxis.move_ptp(0, defectList[index].X, AxMoveMode.MODE1_Abs);
while (!devContainer.devAxis.isReady(1)) Thread.Sleep(100);
devContainer.devAxis.move_ptp(1, defectList[index].Y, AxMoveMode.MODE1_Abs);
AddTextEvent($"缺陷项", $"移动完成,当前缺陷项({index + 1})坐标:X{defectList[index].X},Y{defectList[index].Y}");
}
catch (Exception ex)
{
AddTextEvent("缺陷项", "轴移动失败:" + ex.Message, WarningEnum.High);
warning(WarningEnum.High, true);
}
}
private void gotoNextPic()
{
if (currDefectIndex>= defectList.Count-1) return;
this.Invoke(new System.Action(() =>
{
for(int i= currDefectIndex+1;i< defectList.Count; i++)
{
if (this.pictureBox1.Tag == null || this.pictureBox1.Tag.ToString() != defectList[i].Key)
{
AddTextEvent($"缺陷项", $"移至下张图:{i+1}...");
int preIndex = currDefectIndex;
currDefectIndex = i;
gotoDefctListIndex(currDefectIndex, preIndex);
return;
}
}
}));
}
private void gotoPrePic()
{
if (currDefectIndex < 1) return;
this.Invoke(new System.Action(() =>
{
if (this.pictureBox1.Tag == null) return;
for (int i = currDefectIndex-1; i >=0; i--)
{
if (this.pictureBox1.Tag.ToString() != defectList[i].Key)
{
AddTextEvent($"缺陷项", $"移至上张图:{i + 1}...");
int preIndex = currDefectIndex;
currDefectIndex = i;
gotoDefctListIndex(currDefectIndex, preIndex);
return;
}
}
}));
}
private class DefectStruct
{
//Defect_{order.SN}_{res.index}_X{res.Xmm}_Y{res.Ymm}
public string Key { get; set; }
public int CurrIndex { get; set; }//当前缺陷在本大图中的索引0-n
public int MainIndex { get; set; }//大图
public double MainX { get; set; }//大图X 大相机拍照时原始X,Y轴坐标
public double MainY { get; set; }//大图X
//["4","3.9","-0.8","dk","0.39"],["index","X","Y","缺陷类型","缺陷的置信度"]
public int Index { get; set; }
public double X { get; set; }
public double Y { get; set; }
public string DefectName { get; set; }//缺陷类型
public double DefectCC { get; set; }//缺陷的置信度
//2023-10-30 修复情况
public string Restoratory { get; set; }
}
private double[] convert(JArray data)
{
double[] result = new double[data.Count];
for (int i = 0; i < data.Count; i++)
result[i]=Convert.ToDouble(data[i]);
return result;
}
/// <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;
}
var processList = model.AssistStepInfo.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;
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;
//======Switch 工序类型
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 "Axis":
#region
bool 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.MODE1_Abs ? "" : "")})运动至{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;
}
AddTextEvent($"{stepIndex + 1}-{processName}", $"等待轴{AxisIndex}运行完成...");
while (!asynRun && !devContainer.devAxis.isReady(AxisIndex))
{
Thread.Sleep(100);
if (isBreakProcessRun())
{
currProcessIndex = stepIndex + 1;
return stepIndex;
}
}
AddTextEvent($"{stepIndex + 1}-{processName}", $"轴{AxisIndex}运行完成,当前命令位置:{devContainer.devAxis.getCmdPos_mm(AxisIndex)},反馈位置:{devContainer.devAxis.getActualPos_mm(AxisIndex)}");
#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_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,
// devContainer.devAxis.getActualPos_mm(0),
// devContainer.devAxis.getActualPos_mm(1))
// 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(1)));//Dequeue
AddTextEvent($"{stepIndex + 1}-{processName}", $"图像队列数量: {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 "Size":
#region
limitThresholdVal = processParam.Value<double>("LimitThresholdVal");
lowerThresholdVal = processParam.Value<double>("LowerThresholdVal");
int sizeIndex = processParam.Value<int>("Index");
double xPos = 0;
double yPos = 0;
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},图像队列数量: {scannerCBmpQueue.Count}...");
//需要偏移校正index=0时不能异步
endEvent = new AutoResetEvent(false);
sizeBmpNum++;
devContainer.libSize.add(new SizeTask()
{
index = sizeIndex,
stepIndex = stepIndex,//仅供回调时用
engineName = processParam.Value<string>("EngineName"),
bmp = bmpCBmpQueue.BMP,//bmp/file_path二选一优先bmp
file_path = bmpCBmpQueue.Path,
posX = bmpCBmpQueue.PosX,
posY = bmpCBmpQueue.PosY,
MarkPointList= convert(currProductMarkList),
finishEvent = (res) =>
{
if(res.isSucceed)
{
AddTextEvent($"{stepIndex + 1}-{processName}", $"尺寸检测完成index:{res.index}。");
}
else
{
//setDgvContentCol(liStatocStepIndex, $"失败:{res.resultInfo}");
AddTextEvent($"{res.stepIndex + 1}-{processName}", $"尺寸检测失败index:{res.index}:{res.resultInfo}");
//warning(WarningEnum.Low);//暂停 这里不能暂停stepIndex和scannerBmpQueue队列也不对了
}
sizeBmpNumResult++;
string sizeSavePath = Config.SizeBmp_Path + "\\" + DateTime.Now.ToString("yyyyMMdd") + "\\";
if (!Directory.Exists(sizeSavePath))
Directory.CreateDirectory(sizeSavePath);
sizeSavePath += $"SN{this.SN}_I{res.index}_X{res.posX}_Y{res.posY}.bmp";
if (res.bmp != null)
{
res.bmp.Save(sizeSavePath,ImageFormat.Bmp);
res.bmp.Dispose();
res.bmp = null;
}
else
{
//File.Copy(res.file_path, defectFileName + ".bmp", true);
API.CopyFile(res.file_path, sizeSavePath, false);//更快
File.Delete(res.file_path);
}
}
});
#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)
{
setButtonEnabled(tsbtnPause, false);//后面手动模式暂停无意义
//等待Mark图处理完成
while (sizeBmpNum != sizeBmpNumResult)
Thread.Sleep(100);
//
this.Invoke(new System.Action(() =>
{
this.chkLaser.Checked = true;
this.gpbXYAxis.Enabled = gpbZAxis.Enabled = true;
}));
AddTextEvent("完成", $"Mark点计算工序结束开始转换主机台缺陷坐标...");
convert2LocXY();
AddTextEvent("完成", $"开始进行人工修复...");
currentPT = CurrentPTEnum.MakeTag;
currentState = CurrentStateEnum.;
setButtonEnabled(tsbtnGoDownPT, true);
setButtonEnabled(tsbtnReset, true);
//==
currProcessIndex = -1;
return -1;
}
else //继续
{
return ++stepIndex;
//return nextProcess(model, ++stepIndex);
}
}
catch (Exception ex)
{
if (devContainer.devAxis.isError())
{
AddTextEvent("工序", $"[{stepIndex}] Err:" + ex.Message);
warning(WarningEnum.High);
}
else
{
AddTextEvent("工序", $"[{stepIndex}] Err:" + ex.Message);
warning(WarningEnum.Low);
}
return -2;
}
}
#endregion
#region Fun
/// <summary>
/// 全局中断
/// </summary>
private void globalBreakEvent(int portIndex, byte data)
{
AddTextEvent("中断命令", $"{portIndex}-HEX:{Convert.ToString(data, 16)}");
if (compareIOInput(CMDName.) && this.tsbtnStart.Enabled)
2024-03-13 11:12:05 +08:00
{
AddTextEvent("中断命令", $"启动-按钮");
startCommand();
2024-03-13 11:12:05 +08:00
AddTextEvent("中断命令", $"启动-完成");
}
else if (compareIOInput(CMDName.) && this.tsbtnPause.Enabled)
2024-03-13 11:12:05 +08:00
{
AddTextEvent("中断命令", $"暂停-按钮");
warning(WarningEnum.Low, false);
2024-03-13 11:12:05 +08:00
AddTextEvent("中断命令", $"暂停-完成");
}
else if (compareIOInput(CMDName.) && this.tsbtnGoDownPT.Enabled)
2024-03-13 11:12:05 +08:00
{
AddTextEvent("中断命令", $"完成-按钮");
gotoDownPT();
2024-03-13 11:12:05 +08:00
AddTextEvent("中断命令", $"完成-完成");
}
else if (compareIOInput(CMDName.))
2024-03-13 11:12:05 +08:00
{
AddTextEvent("中断命令", $"下光源-按钮");
openLowerLight();
2024-03-13 11:12:05 +08:00
AddTextEvent("中断命令", $"下光源-完成");
}
else if (compareIOInput(CMDName.) && currentState == CurrentStateEnum. && currDefectIndex > 0)
2024-03-13 11:12:05 +08:00
{
AddTextEvent("中断命令", $"上一张图-按钮");
gotoPrePic();
2024-03-13 11:12:05 +08:00
AddTextEvent("中断命令", $"上一张图-完成");
}
else if (compareIOInput(CMDName.) && currentState == CurrentStateEnum. && currDefectIndex < defectList.Count - 1)
2024-03-13 11:12:05 +08:00
{
AddTextEvent("中断命令", $"下一张图-按钮");
gotoNextPic();
2024-03-13 11:12:05 +08:00
AddTextEvent("中断命令", $"下一张图-完成");
}
else if (compareIOInput(CMDName.) && currentState == CurrentStateEnum. && currDefectIndex > 0)
2024-03-13 11:12:05 +08:00
{
AddTextEvent("中断命令", $"上一缺陷-按钮");
gotoDefctListIndex(--currDefectIndex, currDefectIndex + 1);
2024-03-13 11:12:05 +08:00
AddTextEvent("中断命令", $"上一缺陷-完成");
}
else if (compareIOInput(CMDName.) && currentState == CurrentStateEnum. && currDefectIndex < defectList.Count - 1)
2024-03-13 11:12:05 +08:00
{
AddTextEvent("中断命令", $"下一缺陷-按钮");
gotoDefctListIndex(++currDefectIndex, currDefectIndex - 1);
2024-03-13 11:12:05 +08:00
AddTextEvent("中断命令", $"下一缺陷-完成");
}
else if (compareIOInput(CMDName.) && this.tsbtnReset.Enabled)
2024-03-13 11:12:05 +08:00
{
AddTextEvent("中断命令", $"复位-按钮");
resetCommand();
2024-03-13 11:12:05 +08:00
AddTextEvent("中断命令", $"复位-完成");
}
//
if (devContainer.state && warningLevel == WarningEnum.Normal
&& currentState == CurrentStateEnum. && currentPT == CurrentPTEnum.MakeTag)
{
int axisIndex = 0;
bool isJog_axis = (AxisState)devContainer.devAxis.AxState[axisIndex] == AxisState.STA_AX_EXT_JOG;
if(!handleJog(axisIndex, CMDName.,1) && !handleJog(axisIndex, CMDName.,0))
{
if (isJog_axis)
{
AddTextEvent("中断命令", $"轴{axisIndex}关闭JOG模式");
devContainer.devAxis.closeJogMode(axisIndex);//关闭jog时自动停止
}
}
axisIndex = 1;
isJog_axis = (AxisState)devContainer.devAxis.AxState[axisIndex] == AxisState.STA_AX_EXT_JOG;
if (!handleJog(axisIndex, CMDName.,0) && !handleJog(axisIndex, CMDName.,1))
{
if (isJog_axis)
{
AddTextEvent("中断命令", $"轴{axisIndex}关闭JOG模式");
devContainer.devAxis.closeJogMode(axisIndex);//关闭jog时自动停止
}
}
}
}
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 bool handleJog(int axisIndex,CMDName cmd,ushort dir)
{
if (compareIOInput(cmd) && currentState == CurrentStateEnum.)
{
AddTextEvent("中断命令", $"{cmd.ToString()}:开");
devContainer.devAxis.openJogMode(axisIndex);
devContainer.devAxis.setAxisVelParam((double)Config.Axis_JogVelLow[axisIndex], (double)Config.Axis_JogVelLow[axisIndex],
(double)Config.Axis_JogVelLow[axisIndex], (double)Config.Axis_JogVelLow[axisIndex], axisIndex, true);
devContainer.devAxis.jog(axisIndex, dir);//jog move
return true;
}
return false;
}
/// <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();
}
//启用报警消除按钮
setButtonEnabled(tsbtnWarning, true);
}
private void resetUIValue()
{
currProcessIndex = -1;
currProductModel = null;
currProductMarkList = null;
scannerCBmpQueue.Clear();
defectBmpsDir.Clear();
this.Invoke(new System.Action(() =>
{
cbxSN.Enabled = false;
cbxSN.Text = txtProductCode.Text = txtProductName.Text = txtBatchId.Text =
txtBatchId.Text = txtCreateTime.Text = "";
this.gpbDefectList.Text = $"缺陷明细";
this.dgvProcess.DataSource = null;
this.lstLog.Items.Clear();
this.pictureBox1.Image = null;
pictureBox1.Refresh();
}));
}
private void delDirFiles(string dirPath)
{
try
{
var files = Directory.EnumerateFiles(dirPath, "*.bmp", SearchOption.TopDirectoryOnly);
foreach (string file in files)
API.DeleteFile(file);
}
catch (Exception ex)
{
}
}
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");
}
#endregion
private void tsbtnOpenDev_Click(object sender, EventArgs e)
{
Config.LoadAllConfig();
if(string.IsNullOrWhiteSpace(Config.DBConStr)|| string.IsNullOrWhiteSpace(Config.ServerIP))
{
AddTextEvent("设备启动", "启动失败,请先设置数据库和主机台通讯地址!",WarningEnum.High);
return;
}
//设置程序最小/大线程池
// Get the current settings.
int minWorker, minIOC;
ThreadPool.GetMinThreads(out minWorker, out minIOC);
ThreadPool.SetMinThreads(25, minIOC);
//ThreadPool.SetMaxThreads(256, 256);
this.tsbtnOpenDev.Enabled = false;
scannerCBmpQueue.Clear();
//scannerCBmpIndex = 0;
this.resetUIValue();
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
= this.gpbXYAxis.Enabled = gpbZAxis.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.chkLaser.Enabled = true;
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.chkLaser.Enabled = false;
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);
};
AddTextEvent("设备启动", "启动");
devContainer.start(IntPtr.Zero, IntPtr.Zero);
}
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]} ({((AxisState)devContainer.devAxis.AxState[0]).ToString()})] | " +
$"[命令位:{devContainer.devAxis.CmdPos[1]} 反馈位:{devContainer.devAxis.ActualPos[1]} ({((AxisState)devContainer.devAxis.AxState[1]).ToString()})] | " +
$"[命令位:{devContainer.devAxis.CmdPos[2]} 反馈位:{devContainer.devAxis.ActualPos[2]} ({((AxisState)devContainer.devAxis.AxState[2]).ToString()})] | " +
$"[命令位:{devContainer.devAxis.CmdPos[3]} 反馈位:{devContainer.devAxis.ActualPos[3]} ({((AxisState)devContainer.devAxis.AxState[3]).ToString()})] | ";
}));
}
private void tsbtnCloseDev_Click(object sender, EventArgs e)
{
AddTextEvent("设备停止", $"设备停止...");
this.tsbtnOpenDev.Visible = true;
this.tsbtnCloseDev.Visible = false;
this.chkLaser.Enabled = false;
this.tsbtnReset.Enabled = tsbtnWarning.Enabled = this.tsbtnStart.Enabled = this.tsbtnGoDownPT.Enabled
= this.tsbtnPause.Enabled = this.tsbtnStopNow.Enabled
= this.gpbXYAxis.Enabled = this.gpbZAxis.Enabled = false;
if (devContainer.state)
{
devContainer.devIOCard.reset();
devContainer.io_output(CMDName.IO默认输出);
}
timer.Stop();
devContainer.stop();
}
private void dgvProcess_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex < 0 || !devContainer.state || currentState != CurrentStateEnum.)
return;
int preIndex = currDefectIndex;
currDefectIndex = e.RowIndex;
gotoDefctListIndex(currDefectIndex, preIndex);
}
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();
}
private void loadOrderSNList()
{
try
{
//ConditionalType: 0-等于 3-大于等于 5-小于等于 6-IN "CSharpTypeName":"int"
JArray domainList =new JArray();
domainList.Add(new JObject()
{
{"FieldName","State" },
{"FieldValue",0 },//0-初始; 5-已检测
{"ConditionalType",0 },
});
domainList.Add(new JObject()
{
{"FieldName","DefectCount" },
{"FieldValue",1 },
{"ConditionalType",3 },
});
domainList.Add(new JObject()
{
{"FieldName","CreateTime" },
{"FieldValue",DateTime.Now.AddDays(-1) },
{"ConditionalType",3 },
});
var list = svcOrder.GetList("Order", "SN", domainList.ToString(), "SN DESC");
List<string> snList = new List<string>();
foreach(var item in list)
snList.Add(item.ToList().Select(m => m.Value.ToString()).ToArray()[0]);
this.Invoke(new System.Action(() =>
{
this.cbxSN.Text = "";
this.cbxSN.Items.Clear();
this.cbxSN.Items.AddRange(snList.ToArray());
}));
}
catch (Exception ex)
{
AddTextEvent("启动", "加载已检测网版编码失败:" + ex.Message, WarningEnum.Low);
}
}
private void splitContainer1_SizeChanged(object sender, EventArgs e)
{
this.gpbProductInfo.Width = this.gpbDefectList.Width = splitContainer1.Panel2.Width-10;
this.gpbProductInfo.Top = this.splitContainer1.ClientSize.Height- this.gpbProductInfo.Height;
this.gpbDefectList.Height = this.gpbProductInfo.Top-10;
this.cbxSN.Width= this.txtProductCode.Width = this.txtProductName.Width
= this.txtBatchId.Width = this.txtCreateTime.Width = this.gpbProductInfo.Width- this.cbxSN.Left-5;
//this.dgvProcess.Width = gpbDefectList.Width - 10;
//this.dgvProcess.Height = this.splitContainer1.ClientSize.Height - this.gpbProductInfo.Height;
//
}
private void splitContainer2_SizeChanged(object sender, EventArgs e)
{
this.tsbtnPause.Left = this.tsbtnGoDownPT.Left = this.splitContainer1.SplitterDistance- this.tsbtnPause.Width - 10;
this.gpbZAxis.Left = this.tsbtnPause.Left - this.gpbZAxis.Width-10;
this.gpbXYAxis.Left = this.gpbZAxis.Left - this.gpbXYAxis.Width - 10;
this.gpbLog.Width = this.gpbXYAxis.Left - 10;
this.splitContainer2.SplitterDistance = this.ClientRectangle.Height - gpbLog.Height - 10;
}
private void tsbtnReset_Click(object sender, EventArgs e)
{
Task.Run(() => this.resetCommand());
}
private void tsbtnStart_Click(object sender, EventArgs e)
{
Task.Run(() => this.startCommand());
}
private void tsbtnPause_Click(object sender, EventArgs e)
{
warning(WarningEnum.Low, false);
}
private void tsbtnGoDownPT_Click(object sender, EventArgs e)
{
AddTextEvent("下料", "准备下料。。。");
// Task.Run(() => this.gotoDownPT());
gotoDownPT();
}
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 = 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 ToolStripMenuItem_Click(object sender, EventArgs e)
{
//devContainer.start(IntPtr.Zero, IntPtr.Zero);
//devContainer.state = true;
//currentState = CurrentStateEnum.等待扫码;
//cbxSN.Enabled = true;
//runStep();
//Bitmap bmp = (Bitmap)Bitmap.FromFile(Application.StartupPath + "\\test.bmp");
//AddTextEvent("", $"{this.splitContainer1.Width},{this.pnlPic.Width},bmp:{bmp.Width}");
//pnlPic.BackColor = Color.Red;
//reloadPic(bmp);
//for (int i = 0; i < 100; i++)
// this.dgvProcess.Rows.Add(i, i, i, i, i, i, i, i, i, i, i);
//this.dgvProcess.Rows[1].DefaultCellStyle.BackColor = Color.LightGreen;
//loadOrderSNList();
}
private void btnFront_MouseDown(object sender, MouseEventArgs e)
{
if (devContainer.state && currentState == CurrentStateEnum.)
{
ushort dir;
int axisIndex;
PictureBox btn = sender as PictureBox;
switch (btn.Name)
{
case "btnFront":
dir = 1;
axisIndex = 1;
break;
case "btnBack":
dir = 0;
axisIndex = 1;
break;
case "btnLeft":
dir = 1;
axisIndex = 0;
break;
case "btnRight":
dir = 0;
axisIndex = 0;
break;
case "btnZUp":
dir = 0;
axisIndex = 2;
break;
case "btnZDown":
dir = 1;
axisIndex = 2;
break;
default:
return;
}
//
devContainer.devAxis.openJogMode(axisIndex);
devContainer.devAxis.setAxisVelParam((double)Config.Axis_JogVelLow[axisIndex], (double)Config.Axis_JogVelLow[axisIndex],
(double)Config.Axis_JogVelLow[axisIndex], (double)Config.Axis_JogVelLow[axisIndex], axisIndex, true);
devContainer.devAxis.jog(axisIndex, dir);//jog move
}
}
private void btnFront_MouseUp(object sender, MouseEventArgs e)
{
devContainer.devAxis.closeJogMode();
}
private void chkLaser_CheckedChanged(object sender, EventArgs e)
{
if (!devContainer.state) return;
if(chkLaser.Checked)
devContainer.io_output(CMDName.);
else
devContainer.io_output(CMDName., false, true, 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);
}
private void FrmMain_KeyUp(object sender, KeyEventArgs e)
{
//AddTextEvent("KEY",e.KeyCode.ToString());
switch (e.KeyCode)
{
//case Keys.Left://上一张图
// if (devContainer.state && currentState == CurrentStateEnum.打标中 && currDefectIndex > 0)
// gotoPrePic();
// break;
case Keys.F:// Keys.Right://下一张图
if (devContainer.state && currentState == CurrentStateEnum. && currDefectIndex < defectList.Count - 1)
gotoNextPic();
break;
case Keys.K://Keys.Up://上一缺陷
if (devContainer.state && currentState == CurrentStateEnum. && currDefectIndex > 0)
gotoDefctListIndex(--currDefectIndex, currDefectIndex+1);
break;
case Keys.P://Keys.Down://下一缺陷
if (devContainer.state && currentState == CurrentStateEnum. && currDefectIndex < defectList.Count - 1)
gotoDefctListIndex(++currDefectIndex, currDefectIndex-1);
break;
}
}
private void ToolStripMenuItem_Click(object sender, EventArgs e)
{
}
private void cbxSN_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
if (currentState != CurrentStateEnum.) return;
string sn = this.cbxSN.Text.Trim();
if (string.IsNullOrWhiteSpace(sn))
return;
//FrmInput frm = new FrmInput(productCodeList, "请选择产品编码:");
//if (frm.ShowDialog() != DialogResult.OK && string.IsNullOrWhiteSpace(frm.inputData))
// return;
Task.Factory.StartNew(() =>
{
devContainer.devCodeScanner.ScanerEvent?.Invoke(sn);
});
}
}
private void tsbtnGoDownPT_Click_1(object sender, EventArgs e)
{
AddTextEvent("下料", "准备下料。。。");
// Task.Run(() => this.gotoDownPT());
gotoDownPT();
}
private void cbxSN_KeyPress(object sender, KeyPressEventArgs e)
{
//if (e.KeyChar == (char)Keys.Enter)
//{
// if (currentState != CurrentStateEnum.等待扫码) return;
// string sn = this.cbxSN.Text.Trim();
// if (string.IsNullOrWhiteSpace(sn))
// return;
// //FrmInput frm = new FrmInput(productCodeList, "请选择产品编码:");
// //if (frm.ShowDialog() != DialogResult.OK && string.IsNullOrWhiteSpace(frm.inputData))
// // return;
// Task.Factory.StartNew(() =>
// {
// devContainer.devCodeScanner.ScanerEvent?.Invoke(sn);
// });
//}
}
}
}