banboshi_V1/halftoneproject-master/AssistClient/FrmMain.cs
2023-10-31 13:19:29 +08:00

2174 lines
102 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

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

using 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;
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(pic_size.Width * ratio);
picSize.Height = Convert.ToInt32(pic_size.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
{
if (!devContainer.state || warningLevel != WarningEnum.Normal)
return;
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($"下料", "下料完成!");
//更新指定列
if (svcOrder.Update(it => new Order() { State = 5 }, 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数据完成");
if (modOrder == null)
AddTextEvent("扫码枪", $"网版编码{code}不存在!");
if (modOrder.State == 5)
{
AddTextEvent("扫码枪", $"网版编码{code}已被检测!");
loadOrderSNList();
}
else 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}条)";
}));
#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);
}
}
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 = "已检";
}));
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; }//缺陷的置信度
}
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)
startCommand();
else if (compareIOInput(CMDName.) && this.tsbtnPause.Enabled)
warning(WarningEnum.Low, false);
else if (compareIOInput(CMDName.) && this.tsbtnGoDownPT.Enabled)
gotoDownPT();
else if (compareIOInput(CMDName.))
openLowerLight();
else if (compareIOInput(CMDName.) && currentState == CurrentStateEnum. && currDefectIndex > 0)
gotoPrePic();
else if (compareIOInput(CMDName.) && currentState == CurrentStateEnum. && currDefectIndex < defectList.Count - 1)
gotoNextPic();
else if (compareIOInput(CMDName.) && currentState == CurrentStateEnum. && currDefectIndex > 0)
gotoDefctListIndex(--currDefectIndex, currDefectIndex + 1);
else if (compareIOInput(CMDName.) && currentState == CurrentStateEnum. && currDefectIndex < defectList.Count - 1)
gotoDefctListIndex(++currDefectIndex, currDefectIndex - 1);
else if (compareIOInput(CMDName.) && this.tsbtnReset.Enabled)
resetCommand();
//
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);
};
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)
{
Task.Run(() => this.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 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);
// });
//}
}
}
}