您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 

3768 行
203 KiB

  1. using Advantech.Motion;
  2. using HalconDotNet;
  3. using Microsoft.VisualBasic;
  4. using Models;
  5. using Newtonsoft.Json;
  6. using Newtonsoft.Json.Linq;
  7. using OpenCvSharp;
  8. using ProductionControl.Device;
  9. using ProductionControl.UI;
  10. using ProductionControl.Utils;
  11. using SqlSugar;
  12. using System;
  13. using System.Collections;
  14. using System.Collections.Generic;
  15. using System.ComponentModel;
  16. using System.Data;
  17. using System.Diagnostics;
  18. using System.Drawing;
  19. using System.Drawing.Imaging;
  20. using System.IO;
  21. using System.Linq;
  22. using System.Security.Cryptography;
  23. using System.Text;
  24. using System.Threading;
  25. using System.Threading.Tasks;
  26. using System.Web.Routing;
  27. using System.Windows.Forms;
  28. using static ProductionControl.Device.AxisDev;
  29. using static ProductionControl.Device.DefectLib;
  30. using static ProductionControl.Device.SizeLib;
  31. namespace ProductionControl
  32. {
  33. public partial class FrmMain : Form
  34. {
  35. WebService webService = new WebService();
  36. private List<string> productCodeList = new List<string>();
  37. private DevContainer devContainer = new DevContainer();
  38. private Service.ProductService svcProduct = new Service.ProductService();
  39. private Service.OrderService svcOrder = new Service.OrderService();
  40. Service.ClassesService svcClasses = new Service.ClassesService();
  41. private bool bExitApp = false;
  42. //禁用蜂鸣器,门磁
  43. private bool disableBuzzer, disableDoorSensor;
  44. //线宽,张力,厚度,PT
  45. private List<double> lstTension = new List<double>();
  46. private List<double> lstHeight = new List<double>();
  47. private List<double> lstLineWidth = new List<double>();
  48. private List<double> lstPT = new List<double>();
  49. private Queue<scannerGBmpLoc> scannerGBmpQueue = new Queue<scannerGBmpLoc>();
  50. private Queue<scannerCBmpLoc> scannerCBmpQueue = new Queue<scannerCBmpLoc>();
  51. //private int scannerCBmpIndex = 0;//scannerCBmpQueue中使用当前项的计数器
  52. private int compBmpIndex = 0;//比对777图的索引
  53. private int defectBmpNum = 0;
  54. private int defectBmpNumResult = 0;
  55. /// <summary>
  56. /// 比对失败的图片
  57. /// </summary>
  58. private List<Bitmap> lstCompareFailZoomImage = new List<Bitmap>();
  59. private object myLock=new object();
  60. private WarningEnum warningLevel;//警告等级
  61. private CurrentPTEnum currentPT;//当前点位
  62. private CurrentStateEnum currentState;//当前状态
  63. /// <summary>
  64. /// 当前流程ID,暂停/继续时使用
  65. /// </summary>
  66. private int currProcessIndex = -1;
  67. private Models.Product currProductModel = null;//当前产品
  68. private bool autoMakeTagRuning = false;
  69. private bool isProductRevise = false;
  70. //产品-厚度base校正点位索引
  71. private int ProductPT_HeightBaseNum = 0;
  72. private Stopwatch stopWatch = new Stopwatch();
  73. private Order order = new Order();
  74. //--333输出变量供后面多个777使用
  75. public HObject contoursAffineTrans1_Out;
  76. private System.Timers.Timer timer = new System.Timers.Timer();
  77. private class scannerGBmpLoc
  78. {
  79. public scannerGBmpLoc(Mat mat, double xmm, double ymm)
  80. {
  81. bmp = mat;
  82. Xmm = xmm;
  83. Ymm = ymm;
  84. }
  85. public Mat bmp { get; private set; }
  86. public double Xmm { get; private set; }
  87. public double Ymm { get; private set; }
  88. }
  89. private class scannerCBmpLoc
  90. {
  91. public scannerCBmpLoc(string path, double posX, double posY)
  92. {
  93. Path = path;
  94. PosX=posX;
  95. PosY=posY;
  96. }
  97. public scannerCBmpLoc(Bitmap bmp, double posX, double posY)
  98. {
  99. BMP = bmp;
  100. PosX = posX;
  101. PosY = posY;
  102. }
  103. public Bitmap BMP { get; private set; }
  104. public string Path { get; private set; }
  105. public double PosX { get; private set; }
  106. public double PosY { get; private set; }
  107. }
  108. public FrmMain()
  109. {
  110. InitializeComponent();
  111. this.dgvProcess.AutoGenerateColumns = false;
  112. this.tsbtnCloseDev.Visible = false;
  113. this.tsslLoginInfo.Text = $"操作员:{Config.loginUser.Code}({Config.loginUser.Name})";
  114. this.tsslLoginTime.Text = $" 登录时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm")}";
  115. //显示行号与列宽度自动调整
  116. dgvProcess.RowHeadersVisible = true;
  117. dgvProcess.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders;
  118. dgvProcess.RowPostPaint += (sender, e) =>
  119. {
  120. Utils.Util.showRowNum_onDataGrid_RowPostPaint(this.dgvProcess, sender, e);
  121. };
  122. checkCustomerVer();
  123. }
  124. private void checkCustomerVer()
  125. {
  126. //if(Config.CustomerVer=="A")
  127. // this.tsMenuOrderProduct.Visible = false;
  128. }
  129. private void FrmMian_Load(object sender, EventArgs e)
  130. {
  131. if (Config.loginUser.RoleInfo.Code!="admin")
  132. checkRoleRight();
  133. loadProductCodeList();
  134. this.statusStrip1.LayoutStyle = System.Windows.Forms.ToolStripLayoutStyle.HorizontalStackWithOverflow;
  135. this.tsslLoginTime.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
  136. this.tsslLoginInfo.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
  137. this.tsAxisState.Text = "";
  138. //
  139. webService.LogEvent = (warning, msg) =>
  140. {
  141. AddTextEvent("HTTP服务", msg, warning);
  142. webService.LogEvent = null;
  143. };
  144. webService.start();
  145. //读取硬盘剩余空间
  146. Config.CheckDisk();
  147. //测试
  148. }
  149. private void loadProductCodeList()
  150. {
  151. try
  152. {
  153. productCodeList = svcProduct.GetList().Select(m => m.Code).OrderBy(m=>m).ToList();
  154. }
  155. catch(Exception ex)
  156. {
  157. AddTextEvent("启动", "加载产品料号失败:" + ex.Message,WarningEnum.High);
  158. }
  159. }
  160. private void checkRoleRight()
  161. {
  162. this.流程管理ToolStripMenuItem.Enabled = (Config.loginUser.RoleInfo.RightList.FirstOrDefault(m => m.Code == "Step") != null);
  163. this.产品管理ToolStripMenuItem.Enabled = (Config.loginUser.RoleInfo.RightList.FirstOrDefault(m => m.Code == "Product") != null);
  164. this.设备调试ToolStripMenuItem.Enabled = (Config.loginUser.RoleInfo.RightList.FirstOrDefault(m => m.Code == "Debug") != null);
  165. //this.tsMenuOrderQuery.Enabled = (Config.loginUser.RoleInfo.RightList.FirstOrDefault(m => m.Code == "Order") != null);
  166. //this.tsMenuStatistics.Enabled = (Config.loginUser.RoleInfo.RightList.FirstOrDefault(m => m.Code == "Statistics") != null);
  167. this.角色管理ToolStripMenuItem.Enabled = (Config.loginUser.RoleInfo.RightList.FirstOrDefault(m => m.Code == "Role") != null);
  168. this.用户管理ToolStripMenuItem.Enabled = (Config.loginUser.RoleInfo.RightList.FirstOrDefault(m => m.Code == "User") != null);
  169. this.tsbtnProductRevise.Enabled = (Config.loginUser.RoleInfo.RightList.FirstOrDefault(m => m.Code == "HeightBase") != null);
  170. this.tsMenuSysSetting.Enabled = (Config.loginUser.RoleInfo.RightList.FirstOrDefault(m => m.Code == "SysSetting") != null);
  171. this.tsMenuCmdSetting.Enabled = (Config.loginUser.RoleInfo.RightList.FirstOrDefault(m => m.Code == "CmdSetting") != null);
  172. this.tsMenuPTSetting.Enabled = (Config.loginUser.RoleInfo.RightList.FirstOrDefault(m => m.Code == "PTSetting") != null);
  173. }
  174. private void txtProductName_KeyPress(object sender, KeyPressEventArgs e)
  175. {
  176. //if (e.KeyChar == '\r' && devContainer.state && currentState == CurrentStateEnum.ScanBarcode)// && currentPT== CurrentPTEnum.UpPT )
  177. //{
  178. // runStep();
  179. //}
  180. }
  181. /// <summary>
  182. /// 删除修复台重复sn图片
  183. /// </summary>
  184. private void DeleteRepairImage(string sn)
  185. {
  186. List<string> imagePath = new List<string>
  187. {
  188. Config.Defect_SavePath,
  189. Config.Defect_Small_SavePath,
  190. Config.Defect_Compress_SavePath,
  191. Config.SizeBmp_Zoom_Image_SavePath,
  192. Config.SizeBmp_SavePath,
  193. Config.SizeBmp_Compare_SavePath
  194. };
  195. //删除文件
  196. //Task.Factory.StartNew(() =>
  197. //{
  198. for (int i = 0; i < imagePath.Count; i++)
  199. {
  200. string dirPath = Util.createSubDir(imagePath[i],
  201. new List<string> { DateTime.Now.ToString("yyyyMMdd"), sn });
  202. if (!Directory.Exists(dirPath))
  203. {
  204. return;
  205. }
  206. string[] array = Directory.GetFiles(dirPath);
  207. foreach (string text in array)
  208. {
  209. try
  210. {
  211. API.OutputDebugString("清除文件:" + text + "...");
  212. File.Delete(text);
  213. }
  214. catch (Exception ex)
  215. {
  216. API.OutputDebugString("Ex1:" + ex.Message);
  217. }
  218. }
  219. }
  220. //});
  221. }
  222. //后台线程运行
  223. /// <summary>
  224. /// 中断工序运行
  225. /// </summary>
  226. /// <returns></returns>
  227. private bool isBreakProcessRun()
  228. {
  229. return warningLevel != WarningEnum.Normal || currentState != CurrentStateEnum.运行中;
  230. }
  231. private void runStep()
  232. {
  233. compBmpIndex = defectBmpNum = defectBmpNumResult = 0;
  234. AddTextEvent("启动", "等待扫码枪扫码...");
  235. if (devContainer.devCodeScanner != null)
  236. {
  237. devContainer.devCodeScanner.stop();
  238. devContainer.devCodeScanner = null;
  239. }
  240. devContainer.devCodeScanner = new CodeScannerDev();
  241. if (!devContainer.devCodeScanner.start())
  242. {
  243. AddTextEvent("扫码枪", "扫码枪初始化失败!");
  244. return;
  245. }
  246. //2023-12-06 无输入料号防呆
  247. if(string.IsNullOrEmpty(this.txtProductCode.Text))
  248. {
  249. AddTextEvent("料号", "未选择料号!");
  250. return;
  251. }
  252. //2023-10-20 不使用扫码枪事件处理
  253. //devContainer.devCodeScanner.ScanerEvent = (code) =>
  254. string code = this.txtProductCode.Text;
  255. {
  256. if (!devContainer.state || currentState != CurrentStateEnum.等待扫码 || string.IsNullOrWhiteSpace(code))
  257. return;
  258. //
  259. scannerGBmpQueue.Clear();
  260. scannerCBmpQueue.Clear();
  261. lstCompareFailZoomImage.Clear();
  262. contoursAffineTrans1_Out = null;
  263. Thread threadtest = new System.Threading.Thread(() =>
  264. {
  265. int errStep = 0;
  266. try
  267. {
  268. var model = svcProduct.GetModelNav(code);
  269. if (model != null && model.StepInfo.ProcessList.Count > 0)
  270. {
  271. errStep = 1;
  272. //根据产品设置动态加载外观检测模型文件
  273. string onnxFile;
  274. if (!string.IsNullOrWhiteSpace(model.DefectModelFile))
  275. onnxFile = $"{Application.StartupPath}\\onnxFiles\\{model.DefectModelFile}";
  276. else
  277. onnxFile = $"{Application.StartupPath}\\onnxFiles\\default.onnx";
  278. devContainer.libDefect.loadModelFile(onnxFile);
  279. //
  280. errStep = 2;
  281. string sn = "";
  282. AutoResetEvent waitEvent = new AutoResetEvent(false);
  283. this.Invoke(new System.Action(() =>
  284. {
  285. FrmInput frm = new FrmInput(null, "请输入网版编码:");
  286. if (frm.ShowDialog() == DialogResult.OK && !string.IsNullOrWhiteSpace(frm.inputData))
  287. sn = frm.inputData;
  288. waitEvent.Set();
  289. }));
  290. errStep = 3;
  291. waitEvent.WaitOne();
  292. if (string.IsNullOrWhiteSpace(sn))
  293. {
  294. AddTextEvent("扫码枪", $"料号{code}未输入网版编码,流程中止!");
  295. return;
  296. }
  297. AddTextEvent("扫码枪", $"料号:{code},网版编码:{sn}");
  298. //是否闪退需观察
  299. errStep = 4;
  300. devContainer.devCodeScanner.stop();
  301. devContainer.devCodeScanner = null;
  302. errStep = 5;
  303. //删除重复sn用于修复台的图片
  304. AddTextEvent("扫码枪", $"删除{sn}重复用于修复台的图片...");
  305. DeleteRepairImage(sn);
  306. //判断SN数量是否达到批次上限
  307. //创建表达式
  308. if (!string.IsNullOrWhiteSpace(model.BatchId) && model.TargetCount > 0)
  309. {
  310. var exp1 = Expressionable.Create<Order>()
  311. .And(m => m.ProductId == model.Id)
  312. .And(m => m.BatchId == model.BatchId)
  313. .And(m => m.SN != sn)
  314. .ToExpression();//注意 这一句 不能少
  315. errStep = 6;
  316. if (svcOrder.Count(exp1) >= model.TargetCount)
  317. {
  318. AddTextEvent("扫码枪", $"当前产品本批次检测数已达目标数量,请更换检测批次号!");
  319. return;
  320. }
  321. errStep = 7;
  322. }
  323. //
  324. this.Invoke(new System.Action(() =>
  325. {
  326. this.txtProductSN.Text = sn;
  327. }));
  328. //
  329. model.HeightBaseDec = "";
  330. currentState = CurrentStateEnum.运行中;
  331. currentPT = CurrentPTEnum.Moving;
  332. currProductModel = model;
  333. AddTextEvent("扫码枪", $"{model.Name} {model.Spec} [{model.Code}]");
  334. this.Invoke(new System.Action(() =>
  335. {
  336. this.txtProductCode.Text = model.Code;
  337. this.txtProductName.Text = model.Name;
  338. this.dgvProcess.DataSource = new BindingSource(model.StepInfo.ProcessList, null);
  339. devContainer.libFor.clear();
  340. devContainer.libIF.clear();
  341. tsbtnSizeTag.Enabled = tsbtnSizeImage.Enabled = tsbtnDefectImage.Enabled = true;
  342. }));
  343. errStep = 8;
  344. //
  345. ProductPT_HeightBaseNum = 0;
  346. this.setButtonEnabled(this.tsbtnPause, true);
  347. this.setButtonEnabled(this.tsbtnStopNow, true);
  348. order = new Order();
  349. order.Qualified = true;//默认合格,中间有一项指标不合格则改为false
  350. order.ProductId = currProductModel.Id;
  351. order.StepId = (int)currProductModel.StepId;
  352. order.SN = sn;
  353. order.BatchId = currProductModel.BatchId;
  354. //order.ProductInfo = model;
  355. errStep = 9;
  356. int nextStepId = 0;
  357. do
  358. {
  359. nextStepId = nextProcess(model, nextStepId);
  360. } while (nextStepId >= 0 && !isBreakProcessRun());
  361. errStep = 10;
  362. }
  363. else
  364. AddTextEvent("扫码枪", model != null ? $"料号{code}不存在!" : $"产品({model.Name})未配置检测流程!");
  365. }
  366. catch (Exception ex)
  367. {
  368. //AddTextEvent("扫码后", $"errcode({errStep}):" + ex.Message);//会有空对象引用,但不知哪里报的
  369. //warning(WarningEnum.High);
  370. }
  371. });
  372. threadtest.IsBackground = true;
  373. threadtest.Start();
  374. };
  375. }
  376. //model.Type=1 系统校正
  377. /// <summary>
  378. ///
  379. /// </summary>
  380. /// <param name="model"></param>
  381. /// <param name="stepIndex">0-n</param>
  382. /// <returns>大于等于0正常工序; -1:结束 -2:异常</returns>
  383. private int nextProcess(Models.Product model, int stepIndex)
  384. {
  385. try
  386. {
  387. //记录当前index
  388. this.currProcessIndex = stepIndex;
  389. this.Invoke(new System.Action(() =>
  390. {
  391. try
  392. {
  393. this.dgvProcess.Rows[stepIndex].Selected = true;
  394. dgvProcess.CurrentCell = dgvProcess.Rows[stepIndex].Cells[1];
  395. }
  396. catch { }
  397. }));
  398. lock (myLock)
  399. {
  400. if (isBreakProcessRun())
  401. return stepIndex;
  402. }
  403. //开始计时
  404. if(!isProductRevise && model.StepInfo.StartTimeIndex>0 && model.StepInfo.StartTimeIndex==stepIndex+1)
  405. stopWatch.Restart();
  406. var processList = isProductRevise ? model.ReviseStepInfo.ProcessList : model.StepInfo.ProcessList;
  407. var processInfo = processList[stepIndex];
  408. string processName = processInfo.ProcessName;
  409. //AddTextEvent($"{stepIndex + 1}-{processName}", $"工序开始...");
  410. string jsonParams = null;//配方
  411. if (model.ProductProcessList != null && model.ProductProcessList.Count > 0)//使用产品配方
  412. {
  413. ProductProcess productProcessParams = model.ProductProcessList.First(m => m.ProcessCode == processInfo.ProcessCode);
  414. if (productProcessParams != null)
  415. {
  416. jsonParams = productProcessParams.ProcessParams;
  417. AddTextEvent($"{stepIndex + 1}-{processName}", $"使用产品专用配方:{jsonParams}");
  418. }
  419. }
  420. if (jsonParams == null)//使用流程默认配方
  421. {
  422. jsonParams = processInfo.ProcessParams;
  423. if (jsonParams == null) throw new Exception("配方为null!!");
  424. AddTextEvent($"{stepIndex + 1}-{processName}", $"使用流程默认配方:{jsonParams}");
  425. }
  426. //
  427. JObject processParam = JObject.Parse(jsonParams);
  428. if (!processParam.ContainsKey("Disable") || !processParam.Value<bool>("Disable"))
  429. {
  430. AutoResetEvent endEvent;
  431. uint sleepPre = processParam.Value<uint>("SleepPre");
  432. uint sleepLater = processParam.Value<uint>("SleepLater");
  433. if (sleepPre > 0)
  434. Thread.Sleep((int)sleepPre);
  435. double limitThresholdVal, lowerThresholdVal; //张力,厚度,Size,Defect
  436. //======Switch 工序类型
  437. bool asynRun;
  438. string gbxBmpPath = "";
  439. Models.Attachment attachmentFile;
  440. int liStatocStepIndex = stepIndex;
  441. switch (processInfo.ProcessCode)
  442. {
  443. case "IOCard":
  444. #region
  445. var direction = (IODirectionEnum)processParam.Value<int>("Direction");
  446. if (direction == IODirectionEnum.输入 || direction == IODirectionEnum.输入输出)
  447. {
  448. uint IN_Waiting_Timeout = processParam.Value<uint>("IN_Waiting_Timeout");
  449. AddTextEvent($"{stepIndex + 1}-{processName}", $"等待I/O输入信号{(IN_Waiting_Timeout > 0 ? $"(超时时长: {IN_Waiting_Timeout})" : "...")}");
  450. string[] inValue = processParam.Value<JArray>("IN_OP_SHOW").ToObject<List<string>>().ToArray();
  451. uint inWaitingTime = 0;
  452. while (true)
  453. {
  454. if (isBreakProcessRun())
  455. return stepIndex;
  456. if (Util.compareIOInput(inValue, devContainer.devIOCard.DIData))
  457. break;
  458. Thread.Sleep(10);
  459. inWaitingTime += 10;
  460. if (IN_Waiting_Timeout>0 && inWaitingTime >= IN_Waiting_Timeout)
  461. {
  462. AddTextEvent($"{stepIndex + 1}-{processName}", $"输入等待超时告警!", WarningEnum.High);
  463. warning(WarningEnum.Low);//暂停
  464. return stepIndex;
  465. }
  466. }
  467. AddTextEvent($"{stepIndex + 1}-{processName}", $"I/O输入信号对比完成!");
  468. }
  469. if (direction == IODirectionEnum.输出 || direction == IODirectionEnum.输入输出)
  470. devContainer.io_output($"{stepIndex + 1}-{processName}", processParam);
  471. #endregion
  472. break;
  473. case "Tension":
  474. #region
  475. //limitThresholdVal = processParam.Value<double>("LimitThresholdVal");
  476. //lowerThresholdVal = processParam.Value<double>("LowerThresholdVal");
  477. //double tensionValue = 0;
  478. //int timeoutTension = 0;
  479. //do
  480. //{
  481. // tensionValue = devContainer.devTension.getValue();
  482. // setDgvContentCol(liStatocStepIndex, $"张力值:{tensionValue}");
  483. // Thread.Sleep(10);
  484. // timeoutTension += 10;
  485. // if (tensionValue <= 0 && timeoutTension >= 600)//3秒超时
  486. // {
  487. // AddTextEvent($"{stepIndex + 1}-{processName}", $"张力测量失败,确认设备是否正常!", WarningEnum.High);
  488. // warning(WarningEnum.Low);//暂停
  489. // devContainer.io_output(CMDName.张力读取结束输出);
  490. // currProcessIndex--;
  491. // return stepIndex;
  492. // }
  493. //} while (tensionValue <= 0);
  494. //devContainer.io_output(CMDName.张力读取结束输出);
  495. //lstTension.Add(tensionValue);
  496. //updateTensionValue(model.TensionBaseValue+model.TensionUpFloatValue,model.TensionBaseValue-model.TensionDownFloatValue);
  497. //if (limitThresholdVal > 0 && tensionValue >= limitThresholdVal)
  498. //{
  499. // AddTextEvent($"{stepIndex + 1}-{processName}", $"读取数据:{tensionValue},达到上限阀值:{limitThresholdVal},进行下料...", WarningEnum.Low);
  500. // currProcessIndex = stepIndex + 1;
  501. // warning(WarningEnum.Low);//暂停
  502. // return stepIndex;
  503. //}
  504. //else if (lowerThresholdVal > 0 && tensionValue < lowerThresholdVal)
  505. //{
  506. // AddTextEvent($"{stepIndex + 1}-{processName}", $"读取数据:{tensionValue},达到下限阀值:{lowerThresholdVal},进行下料...", WarningEnum.Low);
  507. // currProcessIndex = stepIndex + 1;
  508. // warning(WarningEnum.Low);//暂停
  509. // return stepIndex;
  510. //}
  511. //AddTextEvent($"{stepIndex + 1}-{processName}", $"读取数据:{tensionValue}");
  512. #endregion
  513. break;
  514. case "Height":
  515. #region
  516. if (Config.SkipHeight)
  517. {
  518. AddTextEvent($"{stepIndex + 1}-{processName}", $"设备禁用,忽略此步骤!");
  519. setDgvContentCol(liStatocStepIndex, $"设备禁用,忽略此步骤!");
  520. break;
  521. }
  522. while (!devContainer.devAxis.isReady())//因启用轴异步功能,使用前需等待
  523. {
  524. Thread.Sleep(100);
  525. if (isBreakProcessRun())
  526. {
  527. //currProcessIndex = stepIndex;//本工序没执行,step不变
  528. return stepIndex;
  529. }
  530. }
  531. limitThresholdVal = processParam.Value<double>("LimitThresholdVal");
  532. lowerThresholdVal = processParam.Value<double>("LowerThresholdVal");
  533. bool IsRevise = processParam.Value<bool>("IsRevise");
  534. double relBaseValue = processParam.Value<double>("RelBaseValue"); //配方中相对偏移值
  535. var heightValue = devContainer.devHeight.getHeight();
  536. heightValue = Math.Round(heightValue, 2);//保留2位小数
  537. File.AppendAllText(Application.StartupPath + "\\厚度测量记录.txt", heightValue+"\r\n");//TEMP
  538. if (!IsRevise && heightValue < 0)
  539. {
  540. AddTextEvent($"{stepIndex + 1}-{processName}", $"读取数据:{heightValue},异常数据,终止任务!", WarningEnum.Low);
  541. warning(WarningEnum.Low);//暂停
  542. return stepIndex;
  543. }
  544. //厚度Base校正
  545. if (isProductRevise)
  546. {
  547. setDgvContentCol(liStatocStepIndex, $"厚度值:{heightValue}");
  548. model.HeightBaseDec += heightValue + ";";
  549. AddTextEvent($"{stepIndex + 1}-{processName}", $"读取数据:{heightValue}");
  550. }
  551. else if (IsRevise)
  552. {
  553. var reviseHeight = heightValue + relBaseValue;
  554. model.HeightBaseDec += reviseHeight + ";";
  555. setDgvContentCol(liStatocStepIndex, $"base值:{reviseHeight} = 厚度值:{heightValue}+偏移值:{relBaseValue}");
  556. AddTextEvent($"{stepIndex + 1}-{processName}", $"base值:{reviseHeight} = 厚度值:{heightValue}+偏移值:{relBaseValue},校正索引队列:{model.HeightBaseDec}");
  557. }
  558. else
  559. {
  560. AddTextEvent($"{stepIndex + 1}-{processName}", $"读取数据:{heightValue},base值:{model.HeightBaseDec},偏移值:{relBaseValue},当前base索引:{ProductPT_HeightBaseNum}");
  561. double heightDev = 0;
  562. var heightDev_BaseList=model.HeightBaseDec.Split(new char[] {';',','});
  563. if (heightDev_BaseList.Count() > ProductPT_HeightBaseNum && heightDev_BaseList[ProductPT_HeightBaseNum].Trim() != "")
  564. heightDev = Convert.ToDouble(heightDev_BaseList[ProductPT_HeightBaseNum].Trim());
  565. ProductPT_HeightBaseNum++;
  566. double heightValue2 =Math.Abs(heightDev - heightValue ) + relBaseValue;
  567. heightValue2 = Math.Round(heightValue2, 2);
  568. setDgvContentCol(liStatocStepIndex, $"厚度值:{heightValue2}");
  569. lstHeight.Add(heightValue2);
  570. updateHeightValue(model.HeightBaseValue + model.HeightUpFloatValue, model.HeightBaseValue - model.HeightDownFloatValue);
  571. if (limitThresholdVal > 0 && heightValue2 >= limitThresholdVal)
  572. {
  573. AddTextEvent($"{stepIndex + 1}-{processName}", $"读取数据:{heightValue2},达到上限阀值:{limitThresholdVal},进行下料...", WarningEnum.Low);
  574. currProcessIndex = stepIndex + 1;
  575. warning(WarningEnum.Low);//终止
  576. return stepIndex;
  577. }
  578. else if (lowerThresholdVal > 0 && heightValue2 < lowerThresholdVal)
  579. {
  580. AddTextEvent($"{stepIndex + 1}-{processName}", $"读取数据:{heightValue2},达到下限阀值:{lowerThresholdVal},进行下料...", WarningEnum.Low);
  581. currProcessIndex = stepIndex + 1;
  582. warning(WarningEnum.Low);//终止
  583. return stepIndex;
  584. }
  585. AddTextEvent($"{stepIndex + 1}-{processName}", $"厚度值:{heightValue2} (Base值:{heightDev} - 读取数据:{heightValue} + 偏移值:{relBaseValue})");
  586. }
  587. #endregion
  588. break;
  589. case "Axis":
  590. #region 多轴后遗留问题:暂停后再启动不知哪几个轴已执行
  591. JObject processParamTmp = new JObject();
  592. //兼容旧版单轴
  593. if (!processParam.ContainsKey("0") && !processParam.ContainsKey("1") && !processParam.ContainsKey("2") && !processParam.ContainsKey("3"))
  594. {
  595. processParam.Add("Enable", true);
  596. processParamTmp.Add(processParam.Value<int>("AxisIndex").ToString(), processParam);
  597. processParam = processParamTmp;
  598. }
  599. //-
  600. foreach (var processParamSub in processParam.Properties())
  601. {
  602. processParam = processParamSub.Value as JObject;
  603. AddTextEvent($"{stepIndex + 1}-{processName}", processParam.ToString());
  604. if (!processParam.ContainsKey("Disable") || !processParam.Value<bool>("Disable"))
  605. {
  606. //asynRun = processParam.Value<bool>("AsynRun");//异步
  607. int AxisIndex = processParam.Value<int>("AxisIndex");
  608. int DeviceType = processParam.Value<int>("DeviceType");
  609. double VelLow = processParam.Value<double>("VelLow");
  610. double VelHigh = processParam.Value<double>("VelHigh");
  611. double Acc = processParam.Value<double>("Acc");
  612. double Dec = processParam.Value<double>("Dec");
  613. AxMoveMode MoveMode = (AxMoveMode)processParam.Value<int>("MoveMode");//绝对位置
  614. double PPUValue = processParam.Value<double>("Value");
  615. AddTextEvent($"{stepIndex + 1}-{processName}", $"轴{AxisIndex}准备({(MoveMode == AxMoveMode.绝对位置 ? "绝对" : "相对")})运动至{PPUValue}(当前轴状态:{((AxisState)devContainer.devAxis.AxState[AxisIndex]).ToString()})...");
  616. //移动Axis前等待厚度传感器收回
  617. if (!Config.SkipHeight)
  618. {
  619. while (devContainer.devHeight.getHeight() < (double)Math.Abs(Config.HeightDev_SafeValue))
  620. {
  621. if (isBreakProcessRun())
  622. return stepIndex;
  623. Thread.Sleep(10);
  624. }
  625. }
  626. while (!devContainer.devAxis.isReady(AxisIndex))
  627. {
  628. Thread.Sleep(100);
  629. if (isBreakProcessRun())
  630. return stepIndex;
  631. }
  632. devContainer.devAxis.setAxisVelParam(VelLow, VelHigh, Acc, Dec, AxisIndex);
  633. if (!devContainer.devAxis.move_ptp(AxisIndex, PPUValue, MoveMode))
  634. {
  635. AddTextEvent($"{stepIndex + 1}-{processName}", $"轴{AxisIndex}运动失败!", WarningEnum.Low);
  636. warning(WarningEnum.Low);//终止
  637. return stepIndex;
  638. }
  639. //多轴运行自动使用异步,全部执行后强制等待各轴完成 asynRun属性已无用
  640. //AddTextEvent($"{stepIndex + 1}-{processName}", $"等待轴{AxisIndex}运行完成...");
  641. //while (!asynRun && !devContainer.devAxis.isReady(AxisIndex))
  642. //{
  643. // Thread.Sleep(100);
  644. // if (isBreakProcessRun())
  645. // {
  646. // currProcessIndex = stepIndex + 1;
  647. // return stepIndex;
  648. // }
  649. //}
  650. //if (devContainer.devAxis.isReady(AxisIndex))
  651. // AddTextEvent($"{stepIndex + 1}-{processName}", $"轴{AxisIndex}运行完成,当前命令位置:{devContainer.devAxis.getCmdPos_mm(AxisIndex)},反馈位置:{devContainer.devAxis.getActualPos_mm(AxisIndex)}");
  652. }
  653. }
  654. //多轴同时运行后强制等待各轴完成
  655. AddTextEvent($"{stepIndex + 1}-{processName}", $"等待轴组运行完成...");
  656. while (!devContainer.devAxis.isReady())
  657. {
  658. Thread.Sleep(100);
  659. if (isBreakProcessRun())
  660. {
  661. currProcessIndex = stepIndex + 1;
  662. return stepIndex;
  663. }
  664. }
  665. AddTextEvent($"{stepIndex + 1}-{processName}", $"轴组运行完成。");
  666. #endregion
  667. break;
  668. case "AxisTag":
  669. #region
  670. //asynRun = processParam.Value<bool>("AsynRun");//异步
  671. string axisSizeTag= processParam.Value<string>("SizeTag");
  672. int useIndex = processParam.Value<int>("UseIndex");//消费posePT中的索引
  673. AxMoveMode TagMoveMode = (AxMoveMode)processParam.Value<int>("MoveMode");//绝对位置
  674. var AxisIndexList = processParam.Value<JArray>("AxisIndexList").ToObject<List<int>>();
  675. double TagVelLow = processParam.Value<double>("VelLow");
  676. double TagVelHigh = processParam.Value<double>("VelHigh");
  677. double TagAcc = processParam.Value<double>("Acc");
  678. double TagDec = processParam.Value<double>("Dec");
  679. var sizeTagObj = order.SizeTagDataList.LastOrDefault(m => m.SizeTag == axisSizeTag);//用最新的last
  680. if (sizeTagObj == null)
  681. {
  682. AddTextEvent($"{stepIndex + 1}-{processName}", $"偏移校正轴工序找不到数据提供者Tag:{axisSizeTag}!", WarningEnum.High);
  683. warning(WarningEnum.High);
  684. return stepIndex;
  685. }
  686. string[] posePT= sizeTagObj.posePT.Split(',');
  687. if(posePT.Length < useIndex+ AxisIndexList.Count)
  688. {
  689. AddTextEvent($"{stepIndex + 1}-{processName}", $"Tag:{axisSizeTag}对应消费索引:{useIndex},Axis数量:{AxisIndexList.Count} 超出postPT:{sizeTagObj.posePT} 范围!", WarningEnum.High);
  690. warning(WarningEnum.High);
  691. return stepIndex;
  692. }
  693. double[] TagPPUValue = new double[AxisIndexList.Count];
  694. for (int i = 0; i < AxisIndexList.Count; i++)
  695. TagPPUValue[i] = double.Parse(posePT[useIndex + i]);
  696. string axisTagMsg = $"消费Tag:{axisSizeTag},索引:{useIndex}, 轴:{string.Join(",", AxisIndexList.ToList())},数据:{(TagMoveMode== AxMoveMode.绝对位置 ? "绝对" : "相对")}({string.Join(",", TagPPUValue.ToList())})";
  697. AddTextEvent($"{stepIndex + 1}-{processName}", axisTagMsg);
  698. setDgvContentCol(liStatocStepIndex, axisTagMsg);
  699. //移动Axis前等待厚度传感器收回
  700. if (!Config.SkipHeight)
  701. {
  702. while (devContainer.devHeight.getHeight() < (double)Math.Abs(Config.HeightDev_SafeValue))
  703. {
  704. if (isBreakProcessRun())
  705. return stepIndex; //如果是相对位置,这里返回会有问题
  706. Thread.Sleep(10);
  707. }
  708. }
  709. for (int i = 0; i < AxisIndexList.Count && i < TagPPUValue.Length; i++)
  710. {
  711. while (!devContainer.devAxis.isReady(AxisIndexList[i]))
  712. {
  713. Thread.Sleep(100);
  714. if (isBreakProcessRun())
  715. return stepIndex;
  716. }
  717. devContainer.devAxis.setAxisVelParam(TagVelLow, TagVelHigh, TagAcc, TagDec, AxisIndexList[i]);
  718. if (!devContainer.devAxis.move_ptp(AxisIndexList[i], TagPPUValue[i], TagMoveMode))
  719. {
  720. AddTextEvent($"{stepIndex + 1}-{processName}", $"轴{AxisIndexList[i]}运动失败!", WarningEnum.Low);
  721. warning(WarningEnum.Low);//终止
  722. return stepIndex;//如果是相对位置,这里返回会有问题
  723. }
  724. //AddTextEvent($"{stepIndex + 1}-{processName}", $"等待轴{AxisIndexList[i]}运行完成...");
  725. //while (!asynRun && !devContainer.devAxis.isReady(AxisIndexList[i]))
  726. //{
  727. // Thread.Sleep(100);
  728. // if (isBreakProcessRun())
  729. // {
  730. // currProcessIndex = stepIndex + 1;
  731. // return stepIndex;//如果是相对位置,这里返回会有问题
  732. // }
  733. //}
  734. //if (devContainer.devAxis.isReady(AxisIndexList[i]))
  735. // AddTextEvent($"{stepIndex + 1}-{processName}", $"轴{AxisIndexList[i]}运行完成,当前命令位置:{devContainer.devAxis.getCmdPos_mm(AxisIndexList[i])},反馈位置:{devContainer.devAxis.getActualPos_mm(AxisIndexList[i])}");
  736. }
  737. if (sizeTagObj.ConsumeStepIndex == null) sizeTagObj.ConsumeStepIndex = "";
  738. sizeTagObj.ConsumeStepIndex += $"{stepIndex + 1}-{useIndex}, ";//消费工序ID
  739. //多轴同时运行后强制等待各轴完成
  740. AddTextEvent($"{stepIndex + 1}-{processName}", $"等待轴组运行完成...");
  741. while (!devContainer.devAxis.isReady())
  742. {
  743. Thread.Sleep(100);
  744. if (isBreakProcessRun())
  745. {
  746. currProcessIndex = stepIndex + 1;
  747. return stepIndex;
  748. }
  749. }
  750. AddTextEvent($"{stepIndex + 1}-{processName}", $"轴组运行完成。");
  751. #endregion
  752. break;
  753. case "Light":
  754. #region
  755. if (Config.SkipLight)
  756. {
  757. AddTextEvent($"{stepIndex + 1}-{processName}", $"设备禁用,忽略此步骤!");
  758. setDgvContentCol(liStatocStepIndex, $"设备禁用,忽略此步骤!");
  759. break;
  760. }
  761. int ChannelIndex = processParam.Value<int>("ChannelIndex"); //通道
  762. int DigitalValue = processParam.Value<int>("DigitalValue"); //亮度
  763. int nowDiaitalValue = devContainer.devLight.getDigitalValue(ChannelIndex);
  764. AddTextEvent($"{stepIndex + 1}-{processName}", $"通道{ChannelIndex}当前值:{nowDiaitalValue},准备更新值:{DigitalValue}...");
  765. devContainer.devLight.setDigitalValue(ChannelIndex, DigitalValue);
  766. nowDiaitalValue = devContainer.devLight.getDigitalValue(ChannelIndex);
  767. AddTextEvent($"{stepIndex + 1}-{processName}", $"通道{ChannelIndex}更新后当前值:{nowDiaitalValue}。");
  768. #endregion
  769. break;
  770. case "Scanner_GENTL":
  771. #region
  772. if (Config.SkipScannerGL)
  773. {
  774. AddTextEvent($"{stepIndex + 1}-{processName}", $"设备禁用,忽略此步骤!");
  775. setDgvContentCol(liStatocStepIndex, $"设备禁用,忽略此步骤!");
  776. break;
  777. }
  778. while (!devContainer.devAxis.isReady())//因启用轴异步功能,使用前需等待
  779. {
  780. Thread.Sleep(100);
  781. if (isBreakProcessRun())
  782. {
  783. //currProcessIndex = stepIndex;//本工序没执行,step不变
  784. return stepIndex;
  785. }
  786. }
  787. AIEngineLibEnum AIEngineLib = AIEngineLibEnum.缺陷库;
  788. if(processParam.ContainsKey("AIEngineLib"))
  789. AIEngineLib=(AIEngineLibEnum)processParam.Value<int>("AIEngineLib");
  790. float ExposureTime = processParam.Value<float>("ExposureTime"); //曝光
  791. float Gain = processParam.Value<float>("Gain"); //增益
  792. float ResultingFrameRate = processParam.Value<float>("ResultingFrameRate"); //帧率
  793. AddTextEvent($"{stepIndex + 1}-{processName}", $"相机开始采集照片...");
  794. devContainer.devScannerGentl.setParam(ExposureTime, Gain, ResultingFrameRate);
  795. endEvent = new AutoResetEvent(false);
  796. devContainer.devScannerGentl.ScanEvent = (num, bmpout) =>
  797. {
  798. AddTextEvent($"{stepIndex + 1}-{processName}", $"相机采集照片完成。");
  799. //----缺陷队列
  800. //bool cloneUse = false;
  801. if (AIEngineLib == AIEngineLibEnum.缺陷库 || AIEngineLib == AIEngineLibEnum.缺陷与测量库)
  802. {
  803. //cloneUse = true;
  804. var mat = OpenCvSharp.Extensions.BitmapConverter.ToMat(bmpout);
  805. scannerGBmpQueue.Enqueue(new scannerGBmpLoc(mat,
  806. devContainer.devAxis.getActualPos_mm(1),
  807. devContainer.devAxis.getActualPos_mm(2)));//Dequeue
  808. AddTextEvent($"{stepIndex + 1}-{processName}", $"缺陷图像队列数量: {scannerGBmpQueue.Count}");
  809. }
  810. if (AIEngineLib == AIEngineLibEnum.测量库 || AIEngineLib == AIEngineLibEnum.缺陷与测量库)
  811. {
  812. //v1.2.2. 修改传图
  813. //scannerCBmpQueue.Enqueue(new scannerCBmpLoc(
  814. // cloneUse?(Bitmap)bmpout.Clone(): bmpout,
  815. // devContainer.devAxis.getActualPos_mm(1),
  816. // devContainer.devAxis.getActualPos_mm(2)));//Dequeue
  817. scannerCBmpQueue.Enqueue(new scannerCBmpLoc(
  818. (Bitmap)bmpout.Clone(),
  819. devContainer.devAxis.getActualPos_mm(1),
  820. devContainer.devAxis.getActualPos_mm(2)));//Dequeue
  821. AddTextEvent($"{stepIndex + 1}-{processName}", $"添加尺寸图像队列,X:{devContainer.devAxis.getActualPos_mm(1)},y:{devContainer.devAxis.getActualPos_mm(2)},数量: {scannerCBmpQueue.Count}");
  822. }
  823. endEvent.Set();//线程返回
  824. };
  825. //AddTextEvent($"{stepIndex + 1}-{processName}", $"软触发拍照...");
  826. if (!devContainer.devScannerGentl.scan(1))//软触发拍照
  827. {
  828. devContainer.devScannerGentl.ScanEvent = null;
  829. AddTextEvent($"{stepIndex + 1}-{processName}", $"相机采集照片失败!", WarningEnum.Low);
  830. warning(WarningEnum.Low);//终止
  831. return stepIndex;
  832. }
  833. if (!endEvent.WaitOne(10000))
  834. {
  835. devContainer.devScannerGentl.ScanEvent = null;
  836. AddTextEvent($"{stepIndex + 1}-{processName}", $"相机采集照片超时!", WarningEnum.Low);
  837. warning(WarningEnum.Low);//终止
  838. return stepIndex;
  839. }
  840. devContainer.devScannerGentl.ScanEvent = null;
  841. #endregion
  842. break;
  843. case "Scanner_CC":
  844. #region
  845. if (Config.SkipScannerCC)
  846. {
  847. AddTextEvent($"{stepIndex + 1}-{processName}", $"设备禁用,忽略此步骤!");
  848. setDgvContentCol(liStatocStepIndex, $"设备禁用,忽略此步骤!");
  849. break;
  850. }
  851. while (!devContainer.devAxis.isReady())//因启用轴异步功能,使用前需等待
  852. {
  853. Thread.Sleep(100);
  854. if (isBreakProcessRun())
  855. {
  856. //currProcessIndex = stepIndex;//本工序没执行,step不变
  857. return stepIndex;
  858. }
  859. }
  860. float ExposureTimeCC = processParam.Value<float>("ExposureTime"); //曝光
  861. float GainCC = processParam.Value<float>("Gain"); //增益
  862. float ResultingFrameRateCC = processParam.Value<float>("ResultingFrameRate"); //帧率
  863. AddTextEvent($"{stepIndex + 1}-{processName}", $"相机开始采集照片...");
  864. devContainer.devScannerCC.setParam(ExposureTimeCC, GainCC, ResultingFrameRateCC);
  865. AddTextEvent($"{stepIndex + 1}-{processName}", $"相机参数设置完成。");
  866. AutoResetEvent endEventCC = new AutoResetEvent(false);
  867. //devContainer.devScannerCC.ScanEvent = (num, bmp2) =>
  868. //{
  869. // AddTextEvent($"{stepIndex + 1}-{processName}", $"相机采集照片完成.");
  870. // scannerCBmpQueue.Enqueue(bmp2);//Dequeue
  871. // endEventCC.Set();//线程返回
  872. //};
  873. devContainer.devScannerCC.ScanEventPath += new System.Action<int, string>((num, path2) =>
  874. {
  875. AddTextEvent($"{stepIndex + 1}-{processName}", $"相机采集照片完成.");
  876. scannerCBmpQueue.Enqueue(new scannerCBmpLoc(path2,
  877. devContainer.devAxis.getActualPos_mm(0),
  878. devContainer.devAxis.getActualPos_mm(2)));//Dequeue
  879. AddTextEvent($"{stepIndex + 1}-{processName}", $"添加尺寸图像队列,X:{ devContainer.devAxis.getActualPos_mm(0)},y: { devContainer.devAxis.getActualPos_mm(2)},数量: { scannerCBmpQueue.Count}");
  880. endEventCC.Set();//线程返回
  881. });
  882. if (!devContainer.devScannerCC.scan(1))//软触发拍照
  883. {
  884. devContainer.devScannerCC.ScanEventPath = null;
  885. AddTextEvent($"{stepIndex + 1}-{processName}", $"相机采集照片失败!", WarningEnum.Low);
  886. warning(WarningEnum.Low);//终止
  887. return stepIndex;
  888. }
  889. if (!endEventCC.WaitOne(10000))
  890. {
  891. devContainer.devScannerCC.ScanEventPath = null;
  892. AddTextEvent($"{stepIndex + 1}-{processName}", $"相机采集照片超时!", WarningEnum.Low);
  893. warning(WarningEnum.Low);//终止
  894. return stepIndex;
  895. }
  896. devContainer.devScannerCC.ScanEventPath = null;
  897. #endregion
  898. break;
  899. case "SmallAxis":
  900. #region
  901. if (Config.SkipSmallAxis)
  902. {
  903. AddTextEvent($"{stepIndex + 1}-{processName}", $"设备禁用,忽略此步骤!");
  904. setDgvContentCol(liStatocStepIndex, $"设备禁用,忽略此步骤!");
  905. break;
  906. }
  907. int CmdPos = processParam.Value<int>("CmdPos"); //命令脉冲
  908. AddTextEvent($"{stepIndex + 1}-{processName}", $"开始由起始位置{devContainer.devSmallAxis.getCurrPPU()}运动到{CmdPos}...");
  909. devContainer.devSmallAxis.gotoPos(CmdPos, true);
  910. AddTextEvent($"{stepIndex + 1}-{processName}", $"运动完成,当前位置:{devContainer.devSmallAxis.getCurrPPU()}");
  911. #endregion
  912. break;
  913. case "Size":
  914. #region
  915. asynRun = processParam.Value<bool>("AsynRun");//异步
  916. limitThresholdVal = processParam.Value<double>("LimitThresholdVal");
  917. lowerThresholdVal = processParam.Value<double>("LowerThresholdVal");
  918. int sizeIndex = processParam.Value<int>("Index");
  919. string sizeTag = processParam.ContainsKey("SizeTag") ? processParam.Value<string>("SizeTag") : "";
  920. //2023-10-27
  921. bool useMap = false;
  922. List<double> getPosList = new List<double>();
  923. try
  924. {
  925. useMap = processParam.Value<bool>("UseMapPoints");
  926. if (useMap) {
  927. var list = model.GetPointList.Split(',');
  928. List<double> dList = new List<double>();
  929. if (list.Length < 28)
  930. {
  931. for (int i = 0; i < 28; i++)
  932. {
  933. dList.Add(0);
  934. }
  935. }
  936. else
  937. {
  938. for (int i = 0; i < list.Length; i++)
  939. {
  940. dList.Add(double.Parse(list[i]));
  941. }
  942. }
  943. getPosList = dList;
  944. }
  945. else
  946. {
  947. for (int i = 0; i < 28; i++)
  948. getPosList.Add(0);
  949. }
  950. //getPosList = processParam.Value<JArray>("GetPointList").ToObject<List<double>>();
  951. }
  952. catch
  953. {
  954. for (int i = 0; i < 28; i++)
  955. getPosList.Add(0);
  956. }
  957. double[] getPosArray = getPosList.ToArray();
  958. if (scannerCBmpQueue.Count < 1)
  959. {
  960. AddTextEvent($"{stepIndex + 1}-{processName}", $"尺寸检测异常,无源图像!!", WarningEnum.Low);
  961. warning(WarningEnum.Low);//暂停
  962. return stepIndex;
  963. }
  964. var bmpCBmpQueue = scannerCBmpQueue.Dequeue();
  965. AddTextEvent($"{stepIndex + 1}-{processName}", $"开始尺寸检测,index:{sizeIndex},posX:{bmpCBmpQueue.PosX},posY:{bmpCBmpQueue.PosY},图像队列数量: {scannerCBmpQueue.Count}...");
  966. attachmentFile = model.AttachmentList.FirstOrDefault(x => x.Type == 0);
  967. AddTextEvent($"{stepIndex + 1}-{processName}", $"尺寸检测,index:{sizeIndex},{model.AttachmentList.Count}|{(attachmentFile == null ? "null": attachmentFile.NameTimestamp+ attachmentFile.ExtendName)}");
  968. if (attachmentFile != null)
  969. {
  970. gbxBmpPath = Application.StartupPath + $"\\Attachment\\product\\{attachmentFile.NameTimestamp}";
  971. if (!File.Exists(gbxBmpPath+ attachmentFile.ExtendName)) gbxBmpPath = "";
  972. }
  973. if ((sizeIndex == 333 || sizeIndex == 777) && gbxBmpPath == "")
  974. AddTextEvent($"{stepIndex + 1}-{processName}", $"尺寸检测,index:{sizeIndex},图纸不存在!", WarningEnum.Low);
  975. //2023-10-27
  976. //if ((sizeIndex == 3333)&&(getPosList != null) && (getPosList.Count() != 28))
  977. // AddTextEvent($"{stepIndex + 1}-{processName}", $"尺寸检测,index:{sizeIndex},图纸读点不存在!", WarningEnum.Low);
  978. if (useMap&&(sizeIndex == 3333) && (getPosArray != null) && (getPosArray.Count() == 28) && (getPosArray[0] != 0))
  979. AddTextEvent($"{stepIndex + 1}-{processName}", $"开始图纸读点,index:{sizeIndex},PT1:{getPosArray[0]},PT2:{getPosArray[2]},PT3:{getPosArray[4]},PT4:{getPosArray[6]},PT5:{getPosArray[8]}," +
  980. $"线宽1:[{getPosArray[10]},{getPosArray[11]}],线宽2:[{getPosArray[12]},{getPosArray[13]}],线宽3:[{getPosArray[14]},{getPosArray[15]}]," +
  981. $"线宽4:[{getPosArray[16]},{getPosArray[17]}],线宽5:[{getPosArray[18]},{getPosArray[19]}],线宽6:[{getPosArray[20]},{getPosArray[21]}]," +
  982. $"线宽7:[{getPosArray[22]},{getPosArray[23]}],线宽8:[{getPosArray[24]},{getPosArray[25]}],线宽9:[{getPosArray[26]},{getPosArray[27]}]");
  983. //需要偏移校正,index=0时不能异步 //10,20,30... 
  984. endEvent = new AutoResetEvent(false);
  985. devContainer.libSize.add(new SizeTask()
  986. {
  987. stepIndex = stepIndex,
  988. processName = processName,
  989. sizeTag = sizeTag,
  990. engineName = processParam.Value<string>("EngineName"),
  991. bmp = bmpCBmpQueue.BMP == null ? bmpCBmpQueue.BMP : (Bitmap)bmpCBmpQueue.BMP.Clone(),//bmp/file_path二选一,优先bmp
  992. file_path = bmpCBmpQueue.Path,
  993. drawingPagePath = gbxBmpPath,
  994. posX= bmpCBmpQueue.PosX,
  995. posY= bmpCBmpQueue.PosY,
  996. //2023-10-27
  997. PTandLinePos = getPosArray,
  998. index = sizeIndex,// scannerCBmpIndex++,
  999. ContoursAffineTrans1_Out=this.contoursAffineTrans1_Out,//只有777时才使用最近333输出的结果
  1000. finishEvent = (res) =>
  1001. {
  1002. try
  1003. {
  1004. //比对
  1005. if (res.index == 777)//比对
  1006. {
  1007. if (res.isSucceed)
  1008. {
  1009. setDgvContentCol(liStatocStepIndex, $"index:{res.index}-{compBmpIndex},posX:{res.posX},posY:{res.posY},图像比对:{(res.CompResult ? "通过" : "未通过")} ");
  1010. AddTextEvent($"{res.stepIndex + 1}-{res.processName}", $"图像比对,index:{res.index}-{compBmpIndex},posX:{res.posX},posY:{res.posY},结果:{(res.CompResult ? "通过" : "未通过")}");
  1011. //
  1012. if (order.CompareResult < 2)
  1013. order.CompareResult = res.CompResult ? 1 : 2;
  1014. updateCompareResult(res.CompResult);//更新比对看板
  1015. if (!res.CompResult)
  1016. {
  1017. AddTextEvent($"{res.stepIndex + 1}-{res.processName}", $"图像比对,未通过结果:{JsonConvert.SerializeObject(res.defectInfor2RestorationDesk)}");
  1018. //转为图纸上坐标位置
  1019. if (res.defectInfor2RestorationDeskPage != null && res.defectInfor2RestorationDeskPage.Count > 0)
  1020. {
  1021. //AddTextEvent($"{res.stepIndex + 1}-{res.processName}", $"转换到图纸后坐标数据:{JsonConvert.SerializeObject(res.defectInfor2RestorationDeskPage)}");
  1022. if (order.DefectInfoList == null)
  1023. order.DefectInfoList = new List<DefectInfo>();
  1024. foreach (var item in res.defectInfor2RestorationDeskPage)
  1025. order.DefectInfoList.Add(new DefectInfo()
  1026. {
  1027. Type = 1,
  1028. Code = item[3],
  1029. X = double.Parse(item[1]),
  1030. Y = double.Parse(item[2]),
  1031. ZXD = double.Parse(item[4]),
  1032. ModifyUserCode = Config.loginUser.Code,
  1033. CreateUserCode = Config.loginUser.Code,
  1034. });
  1035. }
  1036. //比对失败的图片 -- 用于修复台调用
  1037. Bitmap bmpCompareFailZoomImage = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(res.Zoom_Image_mat);
  1038. lstCompareFailZoomImage.Add(bmpCompareFailZoomImage);
  1039. if (Config.SizeBmp_Zoom_Image_SavePath != "" && Directory.Exists(Config.SizeBmp_Zoom_Image_SavePath))
  1040. {
  1041. string path = Util.createSubDir(Config.SizeBmp_Zoom_Image_SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  1042. //path += $"Size_SN{order.SN}_I{res.index}_X{res.Defects_X}_Y{res.Defects_Y}_C0_{ model.StepInfo.Name}";
  1043. path += $"Size_SN{order.SN}_I{compBmpIndex}_X{res.posX}_Y{res.posY}_C0_{ model.StepInfo.Name}";
  1044. bmpCompareFailZoomImage.Save(path + ".bmp", ImageFormat.Bmp);
  1045. if (res.defectInfor2RestorationDesk != null && res.defectInfor2RestorationDesk.Count > 0)
  1046. File.WriteAllText(path + ".json", JsonConvert.SerializeObject(res.defectInfor2RestorationDesk));
  1047. }
  1048. //保存原图
  1049. if (Config.SizeBmp_Compare_SavePath != "" && Directory.Exists(Config.SizeBmp_Compare_SavePath))
  1050. {
  1051. string path = Util.createSubDir(Config.SizeBmp_Compare_SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  1052. path += $"Size_SN{order.SN}_I{res.index}_X{res.posX}_Y{res.posY}_{ model.StepInfo.Name}.bmp";
  1053. AddTextEvent($"{res.stepIndex + 1}-{processName}", $"未通过图片保存:{path}");
  1054. if (res.bmp != null)
  1055. res.bmp.Save(path, ImageFormat.Bmp);
  1056. else
  1057. API.CopyFile(res.file_path, path, false);//比.NET(File.Copy)更快
  1058. }
  1059. }
  1060. }
  1061. else
  1062. {
  1063. //2023-12-29 加入比对失败当作NG处理
  1064. order.CompareResult = 2;
  1065. updateCompareResult(false);//更新比对看板
  1066. //warning(WarningEnum.Low);//暂停
  1067. setDgvContentCol(liStatocStepIndex, $"index:{res.index},图像比对失败!");
  1068. AddTextEvent($"{res.stepIndex + 1}-{res.processName}", $"图像比对失败,index:{res.index}-{compBmpIndex}.", WarningEnum.Low);
  1069. }
  1070. compBmpIndex++;
  1071. }
  1072. //MARK
  1073. else if (res.index == 111 || res.index == 222 || res.index == 333 || res.index == 444)
  1074. {
  1075. AddTextEvent($"{res.stepIndex + 1}-{processName}", $"Mark点 Index={res.index},结果记录...");
  1076. if (res.index == 333) this.contoursAffineTrans1_Out = res.ContoursAffineTrans1_Out;//不管成功失败都替换
  1077. if (res.isSucceed)
  1078. {
  1079. Thread.Sleep(100);
  1080. AddTextEvent($"{res.stepIndex + 1}-{processName}", $"Mark点 Index={res.index}; 当前值:{string.Join(",", res.MarkPointList)}");
  1081. JArray markDatas;
  1082. if (string.IsNullOrWhiteSpace(order.MarkData))
  1083. markDatas = new JArray() { 0, 0, 0, 0, 0, 0, 0, 0 };
  1084. else
  1085. markDatas = JArray.Parse(order.MarkData);
  1086. for (int i = 0; i < res.MarkPointList.Count(); i++)
  1087. if (res.MarkPointList[i] != 0)
  1088. markDatas[i] = res.MarkPointList[i];
  1089. order.MarkData = markDatas.ToString();
  1090. setDgvContentCol(liStatocStepIndex, $"index:{res.index},Mark点:{order.MarkData} ");
  1091. AddTextEvent($"{res.stepIndex + 1}-{processName}", $"Mark点 Index={res.index};合并后:{order.MarkData}");
  1092. }
  1093. else
  1094. {
  1095. //warning(WarningEnum.Low);//暂停
  1096. setDgvContentCol(liStatocStepIndex, $"index:{res.index},Mark点计算失败!");
  1097. AddTextEvent($"{res.stepIndex + 1}-{processName}", $"Mark点计算失败,index:{res.index}.", WarningEnum.Low);
  1098. //2023-10-20 make暂停
  1099. if (Config.OpenMarkErrorStop)
  1100. warning(WarningEnum.Low);//暂停
  1101. }
  1102. //保存
  1103. if (Config.SizeBmp_SavePath != "" && Directory.Exists(Config.SizeBmp_SavePath))
  1104. {
  1105. string path = Util.createSubDir(Config.SizeBmp_SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  1106. path += $"Size_SN{order.SN}_I{res.index}_X{res.posX}_Y{res.posY}_{ model.StepInfo.Name}.bmp";
  1107. if (res.bmp != null)
  1108. res.bmp.Save(path, ImageFormat.Bmp);
  1109. else
  1110. API.CopyFile(res.file_path, path, false);//比.NET(File.Copy)更快
  1111. }
  1112. }
  1113. else
  1114. {
  1115. int roundIndex = res.index % 10;
  1116. if (res.isSucceed)
  1117. {
  1118. string tagOutData = "";
  1119. if (res.index == 3333 && !string.IsNullOrWhiteSpace(res.sizeTag))
  1120. {
  1121. tagOutData = $"Tag:{res.sizeTag},posePT:[{string.Join(",", res.posePT)}]";
  1122. if (res.posePT.Length < 2 || res.posePT.Length % 2 != 0)
  1123. {
  1124. AddTextEvent($"{res.stepIndex + 1}-{res.processName}", $"尺寸检测输出Tag对应posePT非法: {tagOutData}", WarningEnum.High);
  1125. warning(WarningEnum.High);//急停
  1126. return;
  1127. }
  1128. //2023-10-27
  1129. AddTextEvent($"{res.stepIndex + 1}-{res.processName}", $"Tag对应posePT: {tagOutData}", WarningEnum.Normal);
  1130. if (order.SizeTagDataList == null)
  1131. order.SizeTagDataList = new List<SizeTagData>();
  1132. order.SizeTagDataList.Add(new SizeTagData()
  1133. {
  1134. SizeTag = res.sizeTag,
  1135. CreateStepIndex = res.stepIndex + 1,
  1136. posePT= string.Join(",", res.posePT)// 回转 Array.ConvertAll(sNums , double.Parse);
  1137. });
  1138. }
  1139. setDgvContentCol(liStatocStepIndex, $"index:{res.index},PT1:{res.PT1},PT2:{res.PT2},Shanxian:{res.Shanxian},Circle_Xmm:{res.Circle_Xmm},Circle_Ymm:{res.Circle_Ymm},offsetX:{res.offsetX},offsetY:{res.offsetY}, {tagOutData}");
  1140. AddTextEvent($"{res.stepIndex + 1}-{res.processName}", $"尺寸检测完成 index:{res.index},PT1:{res.PT1},PT2:{res.PT2},Shanxian:{res.Shanxian},Circle_Xmm:{res.Circle_Xmm},Circle_Ymm:{res.Circle_Ymm},offsetX:{res.offsetX},offsetY:{res.offsetY}, {tagOutData} ");
  1141. //测量
  1142. //------TEST
  1143. if (res.index>20 && res.index<30)
  1144. {
  1145. lock (lstPT)
  1146. {
  1147. lstPT.Add(Math.Round(res.PT1 + Config.PT_Offset, 4));
  1148. updatePTValueTest(model.PTBaseValue + model.PTUpFloatValue, model.PTBaseValue - model.PTDownFloatValue);
  1149. }
  1150. }
  1151. //------
  1152. if (roundIndex > 0)//1-9测量
  1153. {
  1154. if (res.index < 10)//11-13 (PT: 7-9 => 21-29(PT1)) 不用管,李工处理
  1155. {
  1156. //if (roundIndex >= 7)
  1157. //{
  1158. // lock (lstPT)
  1159. // {
  1160. // lstPT.Add(Math.Round(res.PT1, 4));
  1161. // lstPT.Add(res.index == 8 ? 0 : Math.Round(res.PT2, 4));
  1162. // updatePTValue(model.PTBaseValue + model.PTUpFloatValue, model.PTBaseValue - model.PTDownFloatValue);
  1163. // }
  1164. //}
  1165. lock (lstLineWidth)
  1166. {
  1167. lstLineWidth.Add(res.Shanxian > 0 ? Math.Round(res.Shanxian + Config.LineWidth_Offset, 2) : 0);
  1168. updateLineWidthValue(model.LineWidthBaseValue + model.LineWidthUpFloatValue, model.LineWidthBaseValue - model.LineWidthDownFloatValue);
  1169. }
  1170. }
  1171. }
  1172. //校正偏移 10,20,30...:偏移
  1173. else
  1174. {
  1175. AxMoveMode axSizeMode = AxMoveMode.绝对位置;
  1176. double xPos = 0;
  1177. double yPos = 0;
  1178. //绝对偏移
  1179. if (res.offsetX != 0 || res.offsetY != 0)
  1180. {
  1181. xPos += res.offsetX;
  1182. yPos += res.offsetY;
  1183. AddTextEvent($"{res.stepIndex + 1}-{res.processName}", $"offsetX/Y绝对校正, 0轴:{xPos}mm, 2轴:{yPos}mm");
  1184. }
  1185. else if (res.Circle_Xmm != 0 || res.Circle_Ymm != 0)//相对偏移校正
  1186. {
  1187. axSizeMode = AxMoveMode.相对位置;
  1188. AddTextEvent($"{res.stepIndex + 1}-{res.processName}", $"原点相对校正, 0轴:{res.Circle_Xmm}mm, 2轴:{res.Circle_Ymm}mm");
  1189. if (res.Circle_Xmm != 0) xPos = res.Circle_Xmm;
  1190. if (res.Circle_Ymm != 0) yPos = res.Circle_Ymm;
  1191. }
  1192. //当前工序直接移动
  1193. if (xPos != 0 || yPos != 0)
  1194. {
  1195. devContainer.devAxis.setAxisVelParam(0.1, 1, 1, 1, 0);
  1196. devContainer.devAxis.setAxisVelParam(0.1, 1, 1, 1, 2);
  1197. if (xPos != 0) devContainer.devAxis.move_ptp(0, xPos, axSizeMode);
  1198. if (yPos != 0) devContainer.devAxis.move_ptp(2, yPos, axSizeMode);
  1199. while (!devContainer.devAxis.isReady(0) || !devContainer.devAxis.isReady(2))
  1200. {
  1201. Thread.Sleep(100);
  1202. if (isBreakProcessRun())
  1203. break;
  1204. }
  1205. }
  1206. }
  1207. //保存
  1208. //string sizeFileName = Config.Size_SavePath + "\\" + DateTime.Now.ToString("yyyyMMdd_HHmmss_fff");
  1209. //API.CopyFile(res.file_path, defectFileName + ".bmp", false);//更快
  1210. //File.WriteAllText(defectFileName + ".json", JsonConvert.SerializeObject(res.informationList));
  1211. }
  1212. //失败
  1213. else
  1214. {
  1215. //------TEST
  1216. if (res.index > 20 && res.index < 30)
  1217. {
  1218. lock (lstPT)
  1219. {
  1220. lstPT.Add(0);
  1221. updatePTValueTest(model.PTBaseValue + model.PTUpFloatValue, model.PTBaseValue - model.PTDownFloatValue);
  1222. }
  1223. }
  1224. //------
  1225. if (roundIndex > 0)
  1226. {
  1227. //if (roundIndex >= 7)
  1228. //{
  1229. // lock (lstPT)
  1230. // {
  1231. // lstPT.Add(0);
  1232. // lstPT.Add(0);
  1233. // updatePTValue(model.PTBaseValue + model.PTUpFloatValue, model.PTBaseValue - model.PTDownFloatValue);
  1234. // }
  1235. //}
  1236. lock (lstLineWidth)
  1237. {
  1238. lstLineWidth.Add(0);
  1239. updateLineWidthValue(model.LineWidthBaseValue + model.LineWidthUpFloatValue, model.LineWidthBaseValue - model.LineWidthDownFloatValue);
  1240. }
  1241. }
  1242. setDgvContentCol(liStatocStepIndex, $"失败:{res.resultInfo}");
  1243. AddTextEvent($"{res.stepIndex + 1}-{res.processName}", $"尺寸检测失败index:{res.index}:{res.resultInfo}");
  1244. //warning(WarningEnum.Low);//暂停 这里不能暂停,stepIndex和scannerBmpQueue队列也不对了
  1245. }
  1246. //保存
  1247. if (Config.SizeBmp_SavePath != "" && Directory.Exists(Config.SizeBmp_SavePath))
  1248. {
  1249. string path = Util.createSubDir(Config.SizeBmp_SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  1250. path += $"Size_SN{order.SN}_I{res.index}_X{res.posX}_Y{res.posY}_{ model.StepInfo.Name}.bmp";
  1251. if (res.bmp != null)
  1252. res.bmp.Save(path, ImageFormat.Bmp);
  1253. else
  1254. API.CopyFile(res.file_path, path, false);//比.NET(File.Copy)更快
  1255. }
  1256. }
  1257. }
  1258. catch(Exception ex)
  1259. {
  1260. AddTextEvent($"{res.stepIndex + 1}-{res.processName}", $"尺寸检测回调处理异常 index:{res.index},ex={ex.Message}");
  1261. }
  1262. //
  1263. //if (!asynRun)//是否异步执行endEvent.Set()都没问题
  1264. endEvent.Set();//roundIndex=0成功或失败线程返回
  1265. //---
  1266. if (res.bmp != null)
  1267. {
  1268. res.bmp.Dispose();
  1269. res.bmp = null;
  1270. }
  1271. else
  1272. {
  1273. API.DeleteFile(res.file_path);
  1274. }
  1275. }
  1276. });
  1277. //需等上面异步回调中的相对偏移校正完成再继续
  1278. if (!asynRun || sizeIndex % 10==0)
  1279. {
  1280. if (!endEvent.WaitOne(60000))
  1281. AddTextEvent($"{stepIndex + 1}-{processName}", $"{sizeIndex}等待超时,忽略继续!", WarningEnum.Low);
  1282. }
  1283. #endregion
  1284. break;
  1285. case "Defect":
  1286. #region
  1287. limitThresholdVal = processParam.Value<double>("LimitThresholdVal");
  1288. lowerThresholdVal = processParam.Value<double>("LowerThresholdVal");
  1289. if (scannerGBmpQueue.Count < 1)
  1290. {
  1291. AddTextEvent($"{stepIndex + 1}-{processName}", $"缺陷检测异常,无源图像!!", WarningEnum.Low);
  1292. warning(WarningEnum.Low);//终止
  1293. return stepIndex;
  1294. }
  1295. var bmpLoc = scannerGBmpQueue.Dequeue();
  1296. AddTextEvent($"{stepIndex + 1}-{processName}", $"开始缺陷检测,源图索引:{defectBmpNum},图像队列数量: {scannerGBmpQueue.Count}...");
  1297. string[] aarCut_size = processParam.Value<string>("CutSize").Split(',');
  1298. string[] aarResize = processParam.Value<string>("Resize").Split(',');
  1299. //string[] arrThresClass = processParam.Value<string>("ThresholdsClass").Split(',');
  1300. //图纸
  1301. attachmentFile = model.AttachmentList.FirstOrDefault(x => x.Type == 0);
  1302. if (attachmentFile != null)
  1303. {
  1304. gbxBmpPath = Application.StartupPath + $"\\Attachment\\product\\{attachmentFile.NameTimestamp}";
  1305. if (!File.Exists(gbxBmpPath + attachmentFile.ExtendName)) gbxBmpPath = "";
  1306. }
  1307. AddTextEvent($"{stepIndex + 1}-{processName}", $"图纸路径:{gbxBmpPath}");
  1308. string modeltp = "pt";
  1309. Classes tClasses = svcClasses.GetById(model.ClassesId);
  1310. if (tClasses != null)
  1311. {
  1312. if (tClasses.Name == "乳剂")
  1313. modeltp = "rj";
  1314. else
  1315. modeltp = "pt";
  1316. }
  1317. string thr = "";
  1318. if (tClasses.Name == "乳剂")
  1319. thr = processParam.Value<string>("ThresholdsClass").Split(',').Length == 11 ?
  1320. processParam.Value<string>("ThresholdsClass") + ",0.3" : processParam.Value<string>("ThresholdsClass");
  1321. else
  1322. thr = processParam.Value<string>("ThresholdsClass").Split(',').Length == 11 ?
  1323. processParam.Value<string>("ThresholdsClass") + ",0.3,0.3" : processParam.Value<string>("ThresholdsClass").Split(',').Length == 12 ?
  1324. processParam.Value<string>("ThresholdsClass") + ",0.3" : processParam.Value<string>("ThresholdsClass");
  1325. devContainer.libDefect.add(new DefectTask()
  1326. {
  1327. ModelType = modeltp,
  1328. stepIndex = stepIndex,
  1329. processName= processName,
  1330. drawingPagePath= gbxBmpPath,
  1331. index = defectBmpNum++,
  1332. bmp = bmpLoc.bmp,
  1333. Xmm = bmpLoc.Xmm,
  1334. Ymm = bmpLoc.Ymm,
  1335. cut_size = new System.Drawing.Size(Convert.ToInt32(aarCut_size[0]), Convert.ToInt32(aarCut_size[1])),
  1336. resize = new System.Drawing.Size(Convert.ToInt32(aarResize[0]), Convert.ToInt32(aarResize[1])),
  1337. thresholds = processParam.Value<float>("Thresholds"),
  1338. thresholdsClass = thr,
  1339. recAreaThreshold= getProductAreaThreshol(model), //qxName,面积; qxName,面积; qxName,面积;
  1340. finishEvent = (res) =>
  1341. {
  1342. if (res.isSucceed)
  1343. {
  1344. setDgvContentCol(liStatocStepIndex, $"源图索引:{res.index},缺陷数:{res.defectCount},处理时间(ms):{string.Join("->", res.stopwatch.Select(i => i.ToString()).ToArray())}");
  1345. AddTextEvent($"{res.stepIndex + 1}-{res.processName}", $"缺陷检测完成(源图索引:{res.index}),缺陷数:{res.defectCount},处理时间(ms):{string.Join("->", res.stopwatch.Select(i => i.ToString()).ToArray())}");
  1346. string path = "";
  1347. if (res.defectCount > 0)
  1348. {
  1349. //UI显示小图 (含统计缺陷类型数量)
  1350. showDefectSmallBmps(res.bmps_tag, res.bmps_cut, res.Xmm, res.Ymm, res.informationList);
  1351. if (res.defectInfor2RestorationDeskPage != null && res.defectInfor2RestorationDeskPage.Count > 0)
  1352. {
  1353. AddTextEvent($"{res.stepIndex + 1}-{res.processName}", $"转换后坐标数据:{JsonConvert.SerializeObject(res.defectInfor2RestorationDeskPage)}");
  1354. if (order.DefectInfoList == null)
  1355. order.DefectInfoList = new List<DefectInfo>();
  1356. foreach (var item in res.defectInfor2RestorationDeskPage)
  1357. order.DefectInfoList.Add(new DefectInfo()
  1358. {
  1359. Type = 0,
  1360. Code = item[3],
  1361. X = double.Parse(item[1]),
  1362. Y = double.Parse(item[2]),
  1363. ZXD = double.Parse(item[4]),
  1364. ModifyUserCode = Config.loginUser.Code,
  1365. CreateUserCode = Config.loginUser.Code,
  1366. });
  1367. }
  1368. //保存原始大图
  1369. if (Config.Defect_SavePath != "" && Directory.Exists(Config.Defect_SavePath))
  1370. {
  1371. path = Util.createSubDir(Config.Defect_SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  1372. path += $"Defect_SN{order.SN}_I{res.index}_X{res.Xmm}_Y{res.Ymm}_C{res.defectCount}_{ model.StepInfo.Name}";
  1373. //API.CopyFile(res.file_path, defectFileName + ".bmp", false);//比.NET(File.Copy)更快
  1374. //res.bmp.SaveImage(path + ".bmp");//opencv保存格式与BMP不同
  1375. OpenCvSharp.Extensions.BitmapConverter.ToBitmap(res.bmp).Save(path + ".bmp", ImageFormat.Bmp);
  1376. File.WriteAllText(path + ".json", JsonConvert.SerializeObject(res.informationList));
  1377. }
  1378. //保存小图
  1379. if (Config.Defect_Small_SavePath != "" && Directory.Exists(Config.Defect_Small_SavePath))
  1380. {
  1381. path = Util.createSubDir(Config.Defect_Small_SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  1382. path += $"Defect_SN{order.SN}_I{res.index}_X{res.Xmm}_Y{res.Ymm}_{ model.StepInfo.Name}";
  1383. for (int i = 0; i < res.bmps_tag.Count(); i++)
  1384. res.bmps_tag[i].Save(path + $"_i{i}.bmp", ImageFormat.Bmp);
  1385. }
  1386. //保存原始小图
  1387. if (Config.Defect_SrcSmall_SavePath != "" && Directory.Exists(Config.Defect_SrcSmall_SavePath))
  1388. {
  1389. string sinfo = "";
  1390. int sterr = 0;
  1391. try
  1392. {
  1393. for (int i = 0; i < res.defectInfor2RestorationDesk.Count(); i++)
  1394. {
  1395. sterr = 1;
  1396. sinfo = JsonConvert.SerializeObject(res.defectInfor2RestorationDesk[i]);
  1397. int indext = int.Parse(res.defectInfor2RestorationDesk[i][0]);
  1398. double thres = double.Parse(res.defectInfor2RestorationDesk[i][4]);
  1399. if (thres >= Config.Defect_SrcSmall_Thres)
  1400. {
  1401. path = Util.createSubDir(Config.Defect_SrcSmall_SavePath,
  1402. new List<string> { order.CreateTime.ToString("yyyyMMdd"),
  1403. order.SN,
  1404. model.MainGrid == 1?"主栅":model.ClassesId == 7?"rj":"pi",
  1405. res.defectInfor2RestorationDesk[i][3]});
  1406. sterr = 2;
  1407. path += $"Defect_SN{order.SN}_I{res.index}_X{res.Xmm}_Y{res.Ymm}_{model.StepInfo.Name}";
  1408. res.bmps_cut[indext].ImWrite(path + $"_i{i}.bmp");
  1409. sterr = 3;
  1410. }
  1411. }
  1412. }catch (Exception ex)
  1413. {
  1414. AddTextEvent($"{res.stepIndex + 1}-{res.processName}", $"原始小图保存出错{sterr}-{sinfo}-{path}:{ex.Message}");
  1415. }
  1416. }
  1417. //保存压缩大图 -- 用于修复台调用
  1418. if (Config.Defect_Compress_SavePath != "" && Directory.Exists(Config.Defect_Compress_SavePath))
  1419. {
  1420. path = Util.createSubDir(Config.Defect_Compress_SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  1421. path += $"Defect_SN{order.SN}_I{res.index}_X{res.Xmm}_Y{res.Ymm}_C{res.defectCount}_{ model.StepInfo.Name}";
  1422. //res.bmpCompress.SaveImage(path + ".bmp");//opencv保存格式与BMP不同
  1423. OpenCvSharp.Extensions.BitmapConverter.ToBitmap(res.bmpCompress).Save(path + ".bmp", ImageFormat.Bmp);
  1424. File.WriteAllText(path + ".json", JsonConvert.SerializeObject(res.defectInfor2RestorationDesk));
  1425. }
  1426. }
  1427. else//没有缺陷
  1428. {
  1429. if (Config.SaveAllDefectImg && Config.Defect_SavePath != "" && Directory.Exists(Config.Defect_SavePath))
  1430. {
  1431. path = Util.createSubDir(Config.Defect_SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  1432. path += $"Defect_SN{order.SN}_I{res.index}_X{res.Xmm}_Y{res.Ymm}_C{res.defectCount}_{ model.StepInfo.Name}";
  1433. //API.CopyFile(res.file_path, defectFileName + ".bmp", false);//比.NET(File.Copy)更快
  1434. //res.bmp.SaveImage(path + ".bmp");//opencv保存格式与BMP不同
  1435. OpenCvSharp.Extensions.BitmapConverter.ToBitmap(res.bmp).Save(path + ".bmp", ImageFormat.Bmp);
  1436. }
  1437. }
  1438. }
  1439. else
  1440. {
  1441. setDgvContentCol(liStatocStepIndex, $"失败:{res.resultInfo}");
  1442. AddTextEvent($"{res.stepIndex + 1}-{res.processName}", $"缺陷检测失败:{res.resultInfo}");
  1443. //warning(WarningEnum.Low);//暂停 这里不能暂停,stepIndex和scannerBmpQueue队列也不对了
  1444. }
  1445. defectBmpNumResult++;
  1446. foreach (var item in res.bmps_cut)
  1447. item.Dispose();
  1448. res.bmp.Dispose();
  1449. res.bmp = null;
  1450. res.bmps_tag = null;
  1451. if (res.bmpCompress != null)
  1452. {
  1453. res.bmpCompress.Dispose();
  1454. res.bmpCompress = null;
  1455. }
  1456. System.GC.Collect();
  1457. }
  1458. });
  1459. #endregion
  1460. break;
  1461. case "For":
  1462. #region
  1463. long UniqueId = processParam.Value<long>("UniqueId");
  1464. int GotoStepIndex = processParam.Value<int>("GotoStepIndex");//1-n
  1465. int LimitNum = processParam.Value<int>("LimitNum");//1-n
  1466. bool Reset = processParam.Value<bool>("Reset");
  1467. if (GotoStepIndex - 1 == stepIndex)
  1468. {
  1469. AddTextEvent($"{stepIndex + 1}-{processName}", $"For死循环!!!");
  1470. warning(WarningEnum.High);
  1471. return stepIndex;
  1472. }
  1473. if (!devContainer.libFor.dicData.ContainsKey(UniqueId))
  1474. devContainer.libFor.dicData.Add(UniqueId, 0);
  1475. //
  1476. int Num = devContainer.libFor.dicData[UniqueId];
  1477. Num++;
  1478. if (Num <= LimitNum)
  1479. {
  1480. if (Num == LimitNum)
  1481. {
  1482. setDgvContentCol(liStatocStepIndex, $"第[{Num}/{LimitNum}]次,循环完成");
  1483. AddTextEvent($"{stepIndex + 1}-{processName}", $"第[{Num}/{LimitNum}]次,循环完成。");
  1484. }
  1485. else
  1486. {
  1487. setDgvContentCol(liStatocStepIndex, $"第[{Num}/{LimitNum}]次");
  1488. AddTextEvent($"{stepIndex + 1}-{processName}", $"第[{Num}/{LimitNum}]次跳转到步骤[{GotoStepIndex}]...");
  1489. stepIndex = GotoStepIndex - 2;
  1490. }
  1491. devContainer.libFor.dicData[UniqueId] = Num;
  1492. }
  1493. else
  1494. {
  1495. setDgvContentCol(liStatocStepIndex, $"已失效不执行");
  1496. AddTextEvent($"{stepIndex + 1}-{processName}", $"本循环已失效不执行!");
  1497. }
  1498. //达到limit重置0
  1499. if (devContainer.libFor.dicData[UniqueId] >= LimitNum && Reset)
  1500. {
  1501. devContainer.libFor.dicData[UniqueId] = 0;
  1502. setDgvContentCol(liStatocStepIndex, $"第[0/{LimitNum}]次");
  1503. AddTextEvent($"{stepIndex + 1}-{processName}", $"计数器已重置。");
  1504. }
  1505. #endregion
  1506. break;
  1507. case "If":
  1508. #region
  1509. long UniqueId_if = processParam.Value<long>("UniqueId");
  1510. int GotoStepIndex_if = processParam.Value<int>("GotoStepIndex");//1-n
  1511. int LimitNum_if = processParam.Value<int>("LimitNum");//1-n
  1512. bool Reset_if = processParam.Value<bool>("Reset");
  1513. if (GotoStepIndex_if - 1 == stepIndex)
  1514. {
  1515. AddTextEvent($"{stepIndex + 1}-{processName}", $"If死循环,不可自我跳转!!!");
  1516. warning(WarningEnum.High);
  1517. return stepIndex;
  1518. }
  1519. //
  1520. if (!devContainer.libIF.dicData.ContainsKey(UniqueId_if))
  1521. devContainer.libIF.dicData.Add(UniqueId_if, 0);
  1522. //
  1523. int Num_if = devContainer.libIF.dicData[UniqueId_if];
  1524. Num_if++;
  1525. if (Num_if <= LimitNum_if)
  1526. {
  1527. if (Num_if == LimitNum_if)
  1528. {
  1529. setDgvContentCol(liStatocStepIndex, $"第[{Num_if}/{LimitNum_if}]次,跳转至[{GotoStepIndex_if}]");
  1530. AddTextEvent($"{stepIndex + 1}-{processName}", $"计数器[{Num_if}/{LimitNum_if}],跳转至步骤[{GotoStepIndex_if}]...");
  1531. stepIndex = GotoStepIndex_if - 2;
  1532. }
  1533. else
  1534. {
  1535. setDgvContentCol(liStatocStepIndex, $"第[{Num_if}/{LimitNum_if}]次,不跳转");
  1536. AddTextEvent($"{stepIndex + 1}-{processName}", $"计数器[{Num_if}/{LimitNum_if}],不跳转。");
  1537. }
  1538. //
  1539. devContainer.libIF.dicData[UniqueId_if] = Num_if;
  1540. }
  1541. else
  1542. {
  1543. setDgvContentCol(liStatocStepIndex, $"已失效不执行");
  1544. AddTextEvent($"{stepIndex + 1}-{processName}", $"本IF已失效不执行。");
  1545. }
  1546. //达到limit重置0
  1547. if (devContainer.libIF.dicData[UniqueId_if] >= LimitNum_if && Reset_if)
  1548. {
  1549. devContainer.libIF.dicData[UniqueId_if] = 0;
  1550. setDgvContentCol(liStatocStepIndex, $"第[0/{LimitNum_if}]次");
  1551. AddTextEvent($"{stepIndex + 1}-{processName}", $"计数器已重置。");
  1552. }
  1553. #endregion
  1554. break;
  1555. default:
  1556. AddTextEvent($"{stepIndex + 1}-{processName}", $"未知工序:{processInfo.ProcessCode}");
  1557. warning(WarningEnum.High);
  1558. return stepIndex;
  1559. }
  1560. if (sleepLater > 0) Thread.Sleep((int)sleepLater);
  1561. }
  1562. //============结束,判断是否自动下料
  1563. if (stepIndex == processList.Count - 1)
  1564. {
  1565. //厚度校正 直接更新并保存
  1566. if (isProductRevise)
  1567. {
  1568. isProductRevise = false;
  1569. if (MessageBox.Show($"厚度校正完成,是否保存?\r\nBase值:{model.HeightBaseDec}", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
  1570. {
  1571. //保存 //更新指定列
  1572. if (svcProduct.Update(it => new Product() { HeightBaseDec = model.HeightBaseDec }, it => it.Id == model.Id))
  1573. AddTextEvent($"产品校正", $"保存成功。");
  1574. else
  1575. AddTextEvent($"产品校正", $"保存失败!!");
  1576. }
  1577. //下料
  1578. currentState = CurrentStateEnum.自动流程结束;
  1579. gotoDownPT();
  1580. }
  1581. else//生产
  1582. {
  1583. //等待缺陷图显示完成
  1584. while (defectBmpNum != defectBmpNumResult)
  1585. Thread.Sleep(100);
  1586. //判断是否合格
  1587. DefectCodeEnum defectCode;
  1588. string defectNames = "";
  1589. if (model.QualifiedCriterionList!= null && model.QualifiedCriterionList.Count >0)
  1590. {
  1591. int itemDefectCount;
  1592. foreach (var item in model.QualifiedCriterionList)
  1593. {
  1594. try
  1595. {
  1596. defectCode = EnumUtil.Convert2Enum<DefectCodeEnum>(item.DefectCode);
  1597. itemDefectCount = getDefectCountFromCode(order, defectCode);
  1598. if (item.MaxDefectCount > -1 && itemDefectCount > item.MaxDefectCount)
  1599. {
  1600. order.Qualified = false;
  1601. defectNames += $"{((DefectNameEnum)(int)defectCode).ToString()}({itemDefectCount}),";
  1602. }
  1603. }catch (Exception ex)
  1604. {
  1605. ;
  1606. }
  1607. }
  1608. }
  1609. stopWatch.Stop();
  1610. long timeLen = stopWatch.ElapsedMilliseconds / 1000;
  1611. this.BeginInvoke(new System.Action(() =>
  1612. {
  1613. lblTimeLen.Visible = true;
  1614. lblTimeLen.Text = $"检测时长: {timeLen} 秒";
  1615. if (defectNames != "")
  1616. {
  1617. lblDefectResult.Text = "未通过";
  1618. lblDefectResultCount.Text = defectNames.Substring(0, defectNames.Length - 1);
  1619. this.toolTip1.SetToolTip(lblDefectResultCount, lblDefectResultCount.Text);
  1620. lblDefectResult.ForeColor = lblDefectResultCount.ForeColor = Color.Red;
  1621. }
  1622. }));
  1623. order.TimeLen = timeLen;
  1624. order.DefectCount = (int)this.gboxDefectList.Tag;
  1625. order.Succeed = true;
  1626. order.ModifyUserCode = order.CreateUserCode = Config.loginUser.Code;
  1627. order.Abnormalities = "";//无异常
  1628. order.RepairCode = "";//无修复人员
  1629. //如SN检测已存在,先删除
  1630. var oldSNOrder= svcOrder.GetFirst(m=> m.SN==order.SN);
  1631. if(oldSNOrder!=null)
  1632. {
  1633. AddTextEvent("删除记录", $"删除上一重复SN检测记录:SN={oldSNOrder.SN}, Date={oldSNOrder.CreateTime}");
  1634. svcOrder.DelNav(oldSNOrder);
  1635. }
  1636. if (!svcOrder.InsertNav(order))//导航插入
  1637. AddTextEvent("保存失败", $"保存生产记录失败!");
  1638. //更新本批次检测数量
  1639. if (!string.IsNullOrWhiteSpace(model.BatchId))
  1640. {
  1641. var expOrder = Expressionable.Create<Order>()
  1642. .And(m => m.ProductId == model.Id)
  1643. .And(m => m.BatchId == model.BatchId)
  1644. .ToExpression();//注意 这一句 不能少
  1645. currProductModel.CompleteCount = svcOrder.Count(expOrder);
  1646. }
  1647. //以主键为条件更新CompleteCount单列值
  1648. svcProduct.Update(it => new Product() { CompleteCount = currProductModel.CompleteCount }, it => it.Id == currProductModel.Id);
  1649. if (Config.MakeTag && order.DefectCount > 0)//要打标 and 有缺陷图
  1650. {
  1651. AddTextEvent("完成", $"工序结束,用时 {order.TimeLen} 秒;缺陷 {order.DefectCount} 张.");
  1652. //+(Config.MakeTag ? "开始自动打标...":"手动打标..."));
  1653. currentPT = CurrentPTEnum.MakeTag;
  1654. currentState = CurrentStateEnum.打标中;
  1655. setButtonEnabled(tsbtnGoDownPT, true);
  1656. setButtonEnabled(tsbtnReset, true);
  1657. setButtonEnabled(btnMakeTags, true);
  1658. //if (!Config.MakeTag)//自动打标
  1659. {
  1660. this.Invoke(new System.Action(() =>
  1661. {
  1662. btnMakeTag_Click(null, null);
  1663. }));
  1664. }
  1665. }
  1666. else//下料
  1667. {
  1668. AddTextEvent("完成", $"用时 {order.TimeLen} 秒,进行下料...");
  1669. currentState = CurrentStateEnum.自动流程结束;
  1670. gotoDownPT();
  1671. }
  1672. }
  1673. currProcessIndex = -1;
  1674. return -1;
  1675. }
  1676. else //继续
  1677. {
  1678. return ++stepIndex;
  1679. //return nextProcess(model, ++stepIndex);
  1680. }
  1681. }
  1682. catch (Exception ex)
  1683. {
  1684. AddTextEvent("工序", $"[{stepIndex+1}] Err:" + ex.Message+"\n"+ex.StackTrace);
  1685. warning(WarningEnum.Low);
  1686. return -2;
  1687. }
  1688. }
  1689. private Dictionary<string, float> getProductAreaThreshol(Product m)
  1690. {
  1691. Dictionary<string, float> dic = new Dictionary<string, float>();
  1692. foreach(var item in m.QualifiedCriterionList)
  1693. dic.Add(item.DefectCode, (float)(item.Size * 25.4 * 25.4 / m.HoleCount / m.HoleCount) );//网目 => mm^2
  1694. //全缺陷项
  1695. var lstDefect = Utils.EnumUtil.GetArrayList<DefectCodeEnum>();
  1696. foreach (DictionaryEntry item in lstDefect)
  1697. {
  1698. string code = item.Value.ToString();
  1699. if (!dic.ContainsKey(code))
  1700. dic.Add(code, 0);
  1701. }
  1702. return dic;
  1703. }
  1704. private void setDgvContentCol(int rowIndex, string info)
  1705. {
  1706. int row = rowIndex;//why -1 ???
  1707. this.Invoke(new System.Action(() =>
  1708. {
  1709. this.dgvProcess.Rows[row].Cells["colValue"].Value = info;
  1710. }));
  1711. }
  1712. /// <summary>
  1713. /// 报警,只响应low,high
  1714. /// </summary>
  1715. private void warning(WarningEnum level, bool buzzer = true)
  1716. {
  1717. if (level == WarningEnum.Normal)
  1718. return;
  1719. lock(myLock)
  1720. warningLevel = level;
  1721. if (level == WarningEnum.Low)//暂停
  1722. {
  1723. currentState = CurrentStateEnum.暂停;
  1724. pauseCommand(buzzer);
  1725. }
  1726. else if (level == WarningEnum.High)//急停
  1727. {
  1728. currentState = CurrentStateEnum.急停;
  1729. devContainer.devAxis.stopNow();
  1730. stopNowCommand();
  1731. }
  1732. //启用报警消除按钮
  1733. this.Invoke(new System.Action(() =>
  1734. {
  1735. tsbtnWarning.Enabled = true;
  1736. }));
  1737. }
  1738. private void updateTensionValue(double upperLimit,double lowerLimit)
  1739. {
  1740. int count = lstTension.Count();
  1741. if (count < 1) return;
  1742. switch (count)
  1743. {
  1744. case 1:
  1745. order.Tension1 = lstTension[count - 1];
  1746. AddTextEvent("张力值", $"张力1:{order.Tension1}");
  1747. break;
  1748. case 2:
  1749. order.Tension2 = lstTension[count - 1];
  1750. AddTextEvent("张力值", $"张力2:{order.Tension2}");
  1751. break;
  1752. case 3:
  1753. order.Tension3 = lstTension[count - 1];
  1754. AddTextEvent("张力值", $"张力3:{order.Tension3}");
  1755. break;
  1756. case 4:
  1757. order.Tension4 = lstTension[count - 1];
  1758. AddTextEvent("张力值", $"张力4:{order.Tension4}");
  1759. break;
  1760. case 5:
  1761. order.Tension5 = lstTension[count - 1];
  1762. AddTextEvent("张力值", $"张力5:{order.Tension5}");
  1763. break;
  1764. }
  1765. double value = Math.Round(lstTension.Average(), 2);
  1766. double valueMax = lstTension.Max();
  1767. double valueMin = lstTension.Min();
  1768. if (order != null) order.TensionValue = value;
  1769. Color color = (upperLimit+ lowerLimit>0 && (value > upperLimit || value < lowerLimit)) ? Color.Red : Color.White;
  1770. Color colorMax = (upperLimit + lowerLimit > 0 && (valueMax > upperLimit || valueMax < lowerLimit)) ? Color.Red : Color.White;
  1771. Color colorMin = (upperLimit + lowerLimit > 0 && (valueMin > upperLimit || valueMin < lowerLimit)) ? Color.Red : Color.White;
  1772. this.BeginInvoke(new System.Action(() =>
  1773. {
  1774. this.lblTension.Text = Math.Round(value, 2).ToString();
  1775. this.lblTension.ForeColor = color;
  1776. this.lblTensionMax.Text = Math.Round(valueMax, 2).ToString();
  1777. this.lblTensionMax.ForeColor = colorMax;
  1778. this.lblTensionMin.Text = Math.Round(valueMin, 2).ToString();
  1779. this.lblTensionMin.ForeColor = colorMin;
  1780. }));
  1781. //不合格
  1782. if (color == Color.Red) order.Qualified = false;
  1783. }
  1784. private void updateHeightValue(double upperLimit, double lowerLimit)
  1785. {
  1786. int count = lstHeight.Count();
  1787. if (count < 1) return;
  1788. AddTextEvent("厚度", string.Join(",", lstHeight));
  1789. switch (count)
  1790. {
  1791. case 1:
  1792. order.Height1 = lstHeight[count - 1];
  1793. AddTextEvent("厚度值", $"厚度1:{order.Height1}");
  1794. break;
  1795. case 2:
  1796. order.Height2 = lstHeight[count - 1];
  1797. AddTextEvent("厚度值", $"厚度2:{order.Height2}");
  1798. break;
  1799. case 3:
  1800. order.Height3 = lstHeight[count - 1];
  1801. AddTextEvent("厚度值", $"厚度3:{order.Height3}");
  1802. break;
  1803. case 4:
  1804. order.Height4 = lstHeight[count - 1];
  1805. AddTextEvent("厚度值", $"厚度4:{order.Height4}");
  1806. break;
  1807. case 5:
  1808. order.Height5 = lstHeight[count - 1];
  1809. AddTextEvent("厚度值", $"厚度5:{order.Height5}");
  1810. break;
  1811. }
  1812. double value = Math.Round(lstHeight.Average(), 2);
  1813. double valueMax = lstHeight.Max();
  1814. double valueMin = lstHeight.Min();
  1815. if (order != null) order.HeightValue = value;
  1816. Color color = (upperLimit + lowerLimit > 0 && (value > upperLimit || value < lowerLimit)) ? Color.Red : Color.White;
  1817. Color colorMax = (upperLimit + lowerLimit > 0 && (valueMax > upperLimit || valueMax < lowerLimit)) ? Color.Red : Color.White;
  1818. Color colorMin = (upperLimit + lowerLimit > 0 && (valueMin > upperLimit || valueMin < lowerLimit)) ? Color.Red : Color.White;
  1819. this.Invoke(new System.Action(() =>
  1820. {
  1821. this.lblHeight.Text = Math.Round(value, 2).ToString();
  1822. this.lblHeight.ForeColor = color;
  1823. this.lblHeightMax.Text = Math.Round(valueMax, 2).ToString();
  1824. this.lblHeightMax.ForeColor = colorMax;
  1825. this.lblHeightMin.Text = Math.Round(valueMin, 2).ToString();
  1826. this.lblHeightMin.ForeColor = colorMin;
  1827. }));
  1828. //不合格
  1829. if (color == Color.Red) order.Qualified = false;
  1830. }
  1831. private void updateLineWidthValue(double upperLimit, double lowerLimit)
  1832. {
  1833. int count = lstLineWidth.Count();
  1834. if (count < 1) return;
  1835. switch (count)
  1836. {
  1837. case 1:
  1838. order.LineWidth1 = lstLineWidth[count - 1];
  1839. AddTextEvent("线宽值", $"线宽1:{order.LineWidth1}");
  1840. break;
  1841. case 2:
  1842. order.LineWidth2 = lstLineWidth[count - 1];
  1843. AddTextEvent("线宽值", $"线宽2:{order.LineWidth2}");
  1844. break;
  1845. case 3:
  1846. order.LineWidth3 = lstLineWidth[count - 1];
  1847. AddTextEvent("线宽值", $"线宽3:{order.LineWidth3}");
  1848. break;
  1849. case 4:
  1850. order.LineWidth4 = lstLineWidth[count - 1];
  1851. AddTextEvent("线宽值", $"线宽4:{order.LineWidth4}");
  1852. break;
  1853. case 5:
  1854. order.LineWidth5 = lstLineWidth[count - 1];
  1855. AddTextEvent("线宽值", $"线宽5:{order.LineWidth5}");
  1856. break;
  1857. case 6:
  1858. order.LineWidth6 = lstLineWidth[count - 1];
  1859. AddTextEvent("线宽值", $"线宽6:{order.LineWidth6}");
  1860. break;
  1861. case 7:
  1862. order.LineWidth7 = lstLineWidth[count - 1];
  1863. AddTextEvent("线宽值", $"线宽7:{order.LineWidth7}");
  1864. break;
  1865. case 8:
  1866. order.LineWidth8 = lstLineWidth[count - 1];
  1867. AddTextEvent("线宽值", $"线宽8:{order.LineWidth8}");
  1868. break;
  1869. case 9:
  1870. order.LineWidth9 = lstLineWidth[count - 1];
  1871. AddTextEvent("线宽值", $"线宽9:{order.LineWidth9}");
  1872. break;
  1873. }
  1874. List<double> lstValidValue = new List<double>();
  1875. for (int i = 0; i < count; i++)
  1876. {
  1877. if (lstLineWidth[i] > 0)
  1878. lstValidValue.Add(lstLineWidth[i]);
  1879. }
  1880. if (lstValidValue.Count < 1) return;//WLQ 前面失败时会向lstLineWidth.add(0)
  1881. double value = Math.Round(lstValidValue.Average(), 2);
  1882. double valueMax = lstValidValue.Max();
  1883. double valueMin = lstValidValue.Min();
  1884. if (order != null) order.LineWidthValue = value;
  1885. Color color = (upperLimit + lowerLimit > 0 && (value > upperLimit || value < lowerLimit)) ? Color.Red : Color.White;
  1886. Color colorMax = (upperLimit + lowerLimit > 0 && (valueMax > upperLimit || valueMax < lowerLimit)) ? Color.Red : Color.White;
  1887. Color colorMin = (upperLimit + lowerLimit > 0 && (valueMin > upperLimit || valueMin < lowerLimit)) ? Color.Red : Color.White;
  1888. this.Invoke(new System.Action(() =>
  1889. {
  1890. this.lblLineWidth.Text = Math.Round(value, 2).ToString();
  1891. this.lblLineWidth.ForeColor = color;
  1892. this.lblLineWidthMax.Text = Math.Round(valueMax, 2).ToString();
  1893. this.lblLineWidthMax.ForeColor = colorMax;
  1894. this.lblLineWidthMin.Text = Math.Round(valueMin, 2).ToString();
  1895. this.lblLineWidthMin.ForeColor = colorMin;
  1896. }));
  1897. //不合格
  1898. if (color == Color.Red) order.Qualified = false;
  1899. }
  1900. private void updatePTValue(double upperLimit, double lowerLimit)
  1901. {
  1902. //每次加2个:PT1,PT2
  1903. int count = lstPT.Count();
  1904. if (count < 1) return;
  1905. switch (count)
  1906. {
  1907. case 2:
  1908. order.PT1 = lstPT[count - 2];
  1909. order.PT2 = lstPT[count - 1];
  1910. AddTextEvent("PT值",$"PT1:{order.PT1},PT2:{order.PT2}");
  1911. break;
  1912. case 4:
  1913. order.PT3 = lstPT[count - 2];
  1914. order.PT4 = lstPT[count - 1];
  1915. AddTextEvent("PT值", $"PT3:{order.PT3},PT4:{order.PT4}");
  1916. break;
  1917. case 6:
  1918. order.PT5 = lstPT[count - 2];
  1919. order.PT6 = lstPT[count - 1];
  1920. AddTextEvent("PT值", $"PT5:{order.PT5},PT6:{order.PT6}");
  1921. break;
  1922. }
  1923. List<double> lstValidValue = new List<double>();
  1924. for (int i = 0; i < count; i++)
  1925. {
  1926. if (lstPT[i] > 0)
  1927. lstValidValue.Add(lstPT[i]);
  1928. }
  1929. double value = Math.Round(lstValidValue.Average(), 4);
  1930. double valueMax = lstValidValue.Max();
  1931. double valueMin = lstValidValue.Min();
  1932. if (order != null) order.PTValue = value;
  1933. Color color = (upperLimit + lowerLimit > 0 && (value > upperLimit || value < lowerLimit)) ? Color.Red : Color.White;
  1934. Color colorMax = (upperLimit + lowerLimit > 0 && (valueMax > upperLimit || valueMax < lowerLimit)) ? Color.Red : Color.White;
  1935. Color colorMin = (upperLimit + lowerLimit > 0 && (valueMin > upperLimit || valueMin < lowerLimit)) ? Color.Red : Color.White;
  1936. this.Invoke(new System.Action(() =>
  1937. {
  1938. this.lblPT.Text = value.ToString();
  1939. this.lblPT.ForeColor = color;
  1940. this.lblPTMax.Text = Math.Round(valueMax, 4).ToString();
  1941. this.lblPTMax.ForeColor = colorMax;
  1942. this.lblPTMin.Text = Math.Round(valueMin, 4).ToString();
  1943. this.lblPTMin.ForeColor = colorMin;
  1944. }));
  1945. //不合格
  1946. if (color == Color.Red) order.Qualified = false;
  1947. }
  1948. private void updatePTValueTest(double upperLimit, double lowerLimit)
  1949. {
  1950. //每次加2个:PT1,PT2
  1951. int count = lstPT.Count();
  1952. if (count < 1) return;
  1953. switch (count)
  1954. {
  1955. case 1:
  1956. order.PT1 = lstPT[count - 1];
  1957. AddTextEvent("PT1", $"PT1:{order.PT1}");
  1958. break;
  1959. case 2:
  1960. order.PT2 = lstPT[count - 1];
  1961. AddTextEvent("PT2", $"PT2:{order.PT2}");
  1962. break;
  1963. case 3:
  1964. order.PT3 = lstPT[count - 1];
  1965. order.PT4 = 0;
  1966. AddTextEvent("PT3", $"PT3:{order.PT3}");
  1967. break;
  1968. case 4:
  1969. order.PT5 = lstPT[count - 1];
  1970. AddTextEvent("PT4", $"PT4:{order.PT5}");
  1971. break;
  1972. case 5:
  1973. order.PT6 = lstPT[count - 1];
  1974. AddTextEvent("PT5", $"PT5:{order.PT6}");
  1975. break;
  1976. }
  1977. List<double> lstValidValue = new List<double>();
  1978. for (int i = 0; i < count; i++)
  1979. {
  1980. if (lstPT[i] > 0)
  1981. lstValidValue.Add(lstPT[i]);
  1982. }
  1983. double value = Math.Round(lstValidValue.Average(), 4);
  1984. double valueMax = lstValidValue.Max();
  1985. double valueMin = lstValidValue.Min();
  1986. if (order != null) order.PTValue = value;
  1987. Color color = (upperLimit + lowerLimit > 0 && (value > upperLimit || value < lowerLimit)) ? Color.Red : Color.White;
  1988. Color colorMax = (upperLimit + lowerLimit > 0 && (valueMax > upperLimit || valueMax < lowerLimit)) ? Color.Red : Color.White;
  1989. Color colorMin = (upperLimit + lowerLimit > 0 && (valueMin > upperLimit || valueMin < lowerLimit)) ? Color.Red : Color.White;
  1990. this.Invoke(new System.Action(() =>
  1991. {
  1992. this.lblPT.Text = value.ToString();
  1993. this.lblPT.ForeColor = color;
  1994. this.lblPTMax.Text = Math.Round(valueMax, 4).ToString();
  1995. this.lblPTMax.ForeColor = colorMax;
  1996. this.lblPTMin.Text = Math.Round(valueMin, 4).ToString();
  1997. this.lblPTMin.ForeColor = colorMin;
  1998. }));
  1999. //不合格
  2000. if (color == Color.Red) order.Qualified = false;
  2001. }
  2002. private void updateCompareResult(bool compareResult)
  2003. {
  2004. this.Invoke(new System.Action(() =>
  2005. {
  2006. this.lblCompareResult.Text = (order.CompareResult==1 ? "通过" : "未通过");
  2007. if (!compareResult)
  2008. {
  2009. this.lblCompareResultCount.Text = (Convert.ToInt16(lblCompareResultCount.Text) + 1).ToString();
  2010. this.lblCompareResult.ForeColor = lblCompareResultCount.ForeColor=Color.Red;
  2011. //不合格
  2012. order.Qualified = false;
  2013. }
  2014. }));
  2015. }
  2016. private void resetUIValue()
  2017. {
  2018. this.Invoke(new System.Action(() =>
  2019. {
  2020. //保持产品名称和料号
  2021. //txtProductName.Text = txtProductCode.Text = txtProductSN.Text = "";
  2022. txtProductSN.Text = "";
  2023. lstHeight.Clear();
  2024. lstLineWidth.Clear();
  2025. lstTension.Clear();
  2026. lstPT.Clear();
  2027. this.lblTension.Text = this.lblHeight.Text = this.lblLineWidth.Text = "0.00";
  2028. this.lblPT.Text = this.lblPTMax.Text= this.lblPTMin.Text="0.0000";
  2029. this.lblCompareResult.Text =this.lblDefectResult.Text = "无";
  2030. this.lblTensionMax.Text = this.lblHeightMax.Text = this.lblLineWidthMax.Text
  2031. = this.lblTensionMin.Text = this.lblHeightMin.Text = this.lblLineWidthMin.Text = "0.00";
  2032. this.lblCompareResultCount.Text = "0";
  2033. this.lblDefectResultCount.Text = "无";
  2034. this.toolTip1.SetToolTip(lblDefectResultCount, lblDefectResultCount.Text);
  2035. //
  2036. this.lblTension.ForeColor = this.lblHeight.ForeColor = this.lblLineWidth.ForeColor = this.lblPT.ForeColor = this.lblCompareResult.ForeColor= this.lblDefectResult.ForeColor=Color.White;
  2037. this.lblTensionMax.ForeColor = this.lblHeightMax.ForeColor = this.lblLineWidthMax.ForeColor = this.lblPTMax.ForeColor
  2038. = this.lblTensionMin.ForeColor = this.lblHeightMin.ForeColor = this.lblLineWidthMin.ForeColor = this.lblPTMin.ForeColor = Color.White;
  2039. this.lblCompareResultCount.ForeColor = this.lblDefectResultCount.ForeColor=Color.White;
  2040. this.dgvProcess.DataSource = null;
  2041. this.lstLog.Items.Clear();
  2042. this.clearDefectBmps();
  2043. this.picScanner1.Image = this.picScanner2.Image = null;
  2044. picScanner1.Refresh();
  2045. picScanner2.Refresh();
  2046. this.btnMakeTags.Enabled = false;
  2047. }));
  2048. }
  2049. //info: [{"1":[["92.7542","80.85799","99.54083","86.05363","dk","0.52"]]},
  2050. private void showDefectSmallBmps(Bitmap[] bmps, Mat[] bmps_cut, double Xmm, double Ymm, List<Dictionary<int, List<string>[]>> info)
  2051. {
  2052. this.Invoke(new System.Action(() =>
  2053. {
  2054. int imgWidth = this.pnlBmpList.ClientSize.Width - 50;
  2055. int imgHeight = (int)((bmps[0].Height * 1.0f / bmps[0].Width) * imgWidth + 0.5);
  2056. int splitWidth = 20;
  2057. int pnlWidth = this.pnlBmpList.ClientSize.Width;
  2058. int index = (int)this.gboxDefectList.Tag;
  2059. for (int x = 0; x < info.Count(); x++)
  2060. {
  2061. foreach (var item in info[x]) //单个info[x] = {"1":[["92.7542","80.85799","99.54083","86.05363","dk","0.52"]]}
  2062. {
  2063. //统计缺陷类型
  2064. countDefectClass(item.Value);//[["92.7542","80.85799","99.54083","86.05363","dk","0.52"]]
  2065. //
  2066. PictureBox picbox = new PictureBox();
  2067. picbox.Width = imgWidth;
  2068. picbox.Height = imgHeight;
  2069. CheckBox checkBox = new CheckBox();
  2070. picbox.Image = (Bitmap)bmps[x].Clone();
  2071. picbox.Name = "imgDefect_" + index;
  2072. picbox.Tag = item.Key + "," + Xmm + "," + Ymm;
  2073. checkBox.Tag = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(bmps_cut[item.Key]); //Mat转Bitmap ;//原始小图
  2074. checkBox.Name = "chkDefect_" + index;
  2075. checkBox.Text = $"第{index + 1}张";
  2076. checkBox.CheckedChanged += new System.EventHandler(this.CheckBox_CheckedChanged);
  2077. if (Config.MakeTag)//自动打标
  2078. {
  2079. checkBox.Checked = true;
  2080. checkBox.Enabled = false;
  2081. }
  2082. picbox.Click += new EventHandler(defectBmpBox_Click);
  2083. picbox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
  2084. picbox.BorderStyle = BorderStyle.FixedSingle;
  2085. picbox.Margin = new Padding((pnlWidth - picbox.Width) / 2, splitWidth,0, 0);
  2086. checkBox.Margin = new Padding((pnlWidth - checkBox.Width) / 2 + splitWidth,
  2087. 0, 0, 0);
  2088. //
  2089. //if (this.pnlBmpList.Controls.Count > 0)
  2090. //{
  2091. // if ((this.pnlBmpList.Controls[this.pnlBmpList.Controls.Count - 1].Right + imgWidth + splitWidth) > this.pnlBmpList.Width)
  2092. // picbox.Location = new System.Drawing.Point(splitWidth, this.pnlBmpList.Controls[this.pnlBmpList.Controls.Count - 1].Bottom + splitWidth);
  2093. // else
  2094. // picbox.Location = new System.Drawing.Point(this.pnlBmpList.Controls[this.pnlBmpList.Controls.Count - 1].Right + splitWidth, this.pnlBmpList.Controls[this.pnlBmpList.Controls.Count - 1].Location.Y);
  2095. //}
  2096. //else
  2097. //{
  2098. // picbox.Location = new System.Drawing.Point(splitWidth, 0);
  2099. //}
  2100. //checkBox.Location = new System.Drawing.Point(picbox.Location.X + 5, picbox.Location.Y + 5);
  2101. //checkBox.ForeColor = Color.Black;
  2102. this.pnlBmpList.Controls.Add(picbox);
  2103. this.pnlBmpList.Controls.Add(checkBox);
  2104. break;
  2105. }
  2106. //
  2107. index++;
  2108. };
  2109. this.gboxDefectList.Tag = index;
  2110. this.gboxDefectList.Text = $"缺陷图像:{index} 张";
  2111. if (Config.MakeTag) {
  2112. lblDefectAddTag.Text = $"待打标数:{index}";
  2113. lblDefectAddTag.Tag = index;
  2114. }
  2115. pnlBmpList.VerticalScroll.Value = pnlBmpList.VerticalScroll.Maximum;
  2116. }));
  2117. }
  2118. //统计缺陷类型 [["92.7542","80.85799","99.54083","86.05363","dk","0.52"]]
  2119. private void countDefectClass(List<string>[] list)
  2120. {
  2121. string className;
  2122. for(int i=0; i<list.Length; i++)
  2123. {
  2124. className = list[i][4];
  2125. switch (className)
  2126. {
  2127. case "dk":
  2128. order.DKCount++;
  2129. break;
  2130. case "zw":
  2131. order.ZWCount++;
  2132. break;
  2133. case "gsyc":
  2134. order.GSYCCount++;
  2135. break;
  2136. case "xws":
  2137. order.XWSCount++;
  2138. break;
  2139. case "qk":
  2140. order.QKCount++;
  2141. break;
  2142. case "zk":
  2143. order.ZKCount++;
  2144. break;
  2145. case "pp":
  2146. order.PPCount++;
  2147. break;
  2148. case "hs":
  2149. order.HSCount++;
  2150. break;
  2151. case "yx":
  2152. order.YXCount++;
  2153. break;
  2154. case "xb":
  2155. order.XBCount++;
  2156. break;
  2157. case "gsdl"://sx =>gsdl
  2158. order.SXCount++;
  2159. break;
  2160. default:
  2161. break;
  2162. }
  2163. }
  2164. }
  2165. private int getDefectCountFromCode(Order order, DefectCodeEnum defectCodeEnum)
  2166. {
  2167. switch (defectCodeEnum)
  2168. {
  2169. case DefectCodeEnum.dk:
  2170. return order.DKCount;
  2171. case DefectCodeEnum.zw:
  2172. return order.ZWCount;
  2173. case DefectCodeEnum.gsyc:
  2174. return order.GSYCCount;
  2175. case DefectCodeEnum.xws:
  2176. return order.XWSCount;
  2177. case DefectCodeEnum.qk:
  2178. return order.QKCount;
  2179. case DefectCodeEnum.zk:
  2180. return order.ZKCount;
  2181. case DefectCodeEnum.pp:
  2182. return order.PPCount;
  2183. case DefectCodeEnum.hs:
  2184. return order.HSCount;
  2185. case DefectCodeEnum.yx:
  2186. return order.YXCount;
  2187. case DefectCodeEnum.xb:
  2188. return order.XBCount;
  2189. case DefectCodeEnum.gsdl:
  2190. return order.SXCount;
  2191. default:
  2192. return 0;
  2193. }
  2194. }
  2195. private void CheckBox_CheckedChanged(object sender, EventArgs e)
  2196. {
  2197. CheckBox ck = (CheckBox)sender;
  2198. int cout = Convert.ToInt32(this.lblDefectAddTag.Tag);
  2199. if (ck.Checked)
  2200. cout++;
  2201. else
  2202. cout--;
  2203. lblDefectAddTag.Text = $"待打标数:{cout}";
  2204. lblDefectAddTag.Tag = cout;
  2205. }
  2206. private void defectBmpBox_Click(object sender, EventArgs e)
  2207. {
  2208. // if(autoMakeTagRuning) //自动打标中不可打开人工达标窗
  2209. PictureBox picbox = sender as PictureBox;
  2210. if (!devContainer.state || defectBmpNum != defectBmpNumResult || autoMakeTagRuning || currentState != CurrentStateEnum.自动流程结束)//检测中
  2211. {
  2212. //只查看
  2213. FrmPhoto frm = new FrmPhoto(this.pnlBmpList.Controls, Convert.ToInt32(picbox.Name.Split(new char[] { '_' })[1]));
  2214. frm.ShowDialog(this);
  2215. }
  2216. else//完成
  2217. {
  2218. FrmPhotoTag frm = new FrmPhotoTag(this.pnlBmpList.Controls, Convert.ToInt32(picbox.Name.Split(new char[] { '_' })[1])
  2219. ,(defectBmpNum == defectBmpNumResult ? this.devContainer : null));
  2220. frm.ShowDialog(this);
  2221. //
  2222. if (devContainer.state && !Config.SkipScannerCC)
  2223. {
  2224. devContainer.devScannerCC.setMode(false);
  2225. devContainer.devScannerCC.setPreviewWin(this.picScanner1.Handle);
  2226. }
  2227. }
  2228. }
  2229. private void clearDefectBmps()
  2230. {
  2231. this.pnlBmpList.Controls.Clear();
  2232. this.gboxDefectList.Text = $"缺陷图像";
  2233. this.gboxDefectList.Tag = 0;
  2234. this.lblDefectAddTag.Text = "";
  2235. this.lblDefectAddTag.Tag = 0;
  2236. }
  2237. public delegate void AddTextDelegate(string tag, string msg, WarningEnum level);
  2238. /// <summary>
  2239. /// 异步输出日志
  2240. /// </summary>
  2241. /// <param name="tag">模板标识</param>
  2242. /// <param name="msg">内容</param>
  2243. /// <param name="type"></param>
  2244. private void AddTextEvent(string tag, string msg, WarningEnum level = WarningEnum.Normal)
  2245. {
  2246. try
  2247. {
  2248. if (InvokeRequired)
  2249. {
  2250. Invoke(new AddTextDelegate(AddTextEvent), new object[]
  2251. {
  2252. tag,
  2253. msg,
  2254. level
  2255. });
  2256. }
  2257. else
  2258. {
  2259. if (tag != null && tag != "")
  2260. tag = $" - [{tag}]";
  2261. var now = DateTime.Now;
  2262. msg = now.ToString("HH:mm:ss fff") + tag + " - " + msg;
  2263. //cont = MyHelper.subString(cont, 300);
  2264. //写日志,warn和error日志直接写
  2265. writeLog(now, level, msg);
  2266. //
  2267. //if (type > 0)
  2268. // cont = $"<color=\"{(type == 1 ? "Yellow" : "Red")}\">{cont}</color>";
  2269. msg = (level == WarningEnum.Normal ? "B" : level == WarningEnum.Low ? "Y" : "R") + msg;
  2270. this.Invoke(new System.Action(() =>
  2271. {
  2272. if (this.lstLog.Items.Count > 1000)
  2273. this.lstLog.Items.Clear();
  2274. lstLog.Items.Insert(0, msg);
  2275. }));
  2276. //日志滚动
  2277. //lstLog.SelectedIndex = lstLog.Items.Count - 1;
  2278. }
  2279. }
  2280. catch (Exception ex)
  2281. {
  2282. //MessageBox.Show("AddTextEvent ex=(" + ex.Message + ")", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, 0);
  2283. }
  2284. }
  2285. private void lstLog_DrawItem(object sender, DrawItemEventArgs e)
  2286. {
  2287. e.DrawBackground();
  2288. if (e.Index < 0) return;
  2289. try
  2290. {
  2291. string str = lstLog.Items[e.Index].ToString();
  2292. e.Graphics.DrawString(str.Substring(1), e.Font,
  2293. new SolidBrush(str[0] == 'R' ? Color.Red : (str[0] == 'Y' ? Color.Orange : Color.Black)),
  2294. e.Bounds);
  2295. }
  2296. catch
  2297. {
  2298. ;
  2299. }
  2300. }
  2301. private void writeLog(DateTime now, WarningEnum level, string text)
  2302. {
  2303. string directory = Config.LogPath + "\\" + DateTime.Now.ToString("yyyyMM") + "\\";
  2304. //if (type == 0) directory = Application.StartupPath + "\\Log\\Info\\";
  2305. //else if (type == 1) directory = Application.StartupPath + "\\Log\\Warn\\";
  2306. //else directory = Application.StartupPath + "\\Log\\Error\\";
  2307. if (!System.IO.Directory.Exists(directory))
  2308. System.IO.Directory.CreateDirectory(directory);
  2309. File.AppendAllText(directory + now.ToString("yyyyMMdd") + ".log", text + "\r\n");
  2310. }
  2311. private void FrmMian_FormClosing(object sender, FormClosingEventArgs e)
  2312. {
  2313. if (devContainer.state)
  2314. {
  2315. MessageBox.Show("请先停止生产后才能关闭程序!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  2316. e.Cancel = true;
  2317. return;
  2318. }
  2319. if (!bExitApp && MessageBox.Show($"确认退出?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
  2320. {
  2321. e.Cancel = true;
  2322. return;
  2323. }
  2324. }
  2325. private void FrmMian_FormClosed(object sender, FormClosedEventArgs e)
  2326. {
  2327. webService.stop();
  2328. Application.Exit();
  2329. System.GC.Collect();
  2330. System.Environment.Exit(0);
  2331. }
  2332. private void tsbtnOpenDev_Click(object sender, EventArgs e)
  2333. {
  2334. //FrmGetPosByPic frr = new FrmGetPosByPic(new SizeLibProp());
  2335. //frr.ShowDialog();
  2336. Config.LoadAllConfig();
  2337. //设置程序最小/大线程池
  2338. // Get the current settings.
  2339. int minWorker, minIOC;
  2340. ThreadPool.GetMinThreads(out minWorker, out minIOC);
  2341. ThreadPool.SetMinThreads(25, minIOC);
  2342. //ThreadPool.SetMaxThreads(256, 256);
  2343. this.tsbtnProductRevise.Enabled = false;
  2344. this.tsbtnOpenDev.Enabled = false;
  2345. //scannerCBmpIndex = 0;
  2346. isProductRevise = false;
  2347. this.resetUIValue();
  2348. currProcessIndex = -1;
  2349. currentState = CurrentStateEnum.等待复位;
  2350. warningLevel = WarningEnum.Normal;
  2351. currentPT = CurrentPTEnum.InitPT;
  2352. this.tsbtnWarning.Enabled=this.tsbtnGoDownPT.Enabled=this.tsbtnStart.Enabled=this.tsbtnStopNow.Enabled=this.tsbtnPause.Enabled=this.tsbtnReset.Enabled=false;
  2353. //后台线程回调事件
  2354. devContainer.StateChange = (state, msg) =>
  2355. {
  2356. if (state)
  2357. {
  2358. //全局中断
  2359. devContainer.devIOCard.INEvent = globalBreakEvent;
  2360. devContainer.OutDebugEvent = (tag, debugInfo) =>
  2361. {
  2362. AddTextEvent(tag, debugInfo);
  2363. };
  2364. //
  2365. AddTextEvent("设备启动", "请先进行复位操作!");
  2366. this.Invoke(new System.Action(() =>
  2367. {
  2368. this.tsbtnReset.Enabled = true;
  2369. tsbtnWarning.Enabled = this.tsbtnStart.Enabled = this.tsbtnGoDownPT.Enabled
  2370. = this.tsbtnPause.Enabled = this.tsbtnStopNow.Enabled = false;
  2371. this.tsbtnOpenDev.Enabled = true;
  2372. this.tsbtnOpenDev.Visible = false;
  2373. this.tsbtnCloseDev.Visible = true;
  2374. }));
  2375. timer.Elapsed += Timer_Elapsed;
  2376. timer.Interval = 500;
  2377. timer.Start();
  2378. }
  2379. else
  2380. {
  2381. AddTextEvent("设备启动", $"启动失败,{msg}", WarningEnum.High);
  2382. this.Invoke(new System.Action(() =>
  2383. {
  2384. this.tsbtnOpenDev.Enabled = true;
  2385. this.tsbtnOpenDev.Visible = true;
  2386. this.tsbtnCloseDev.Visible = false;
  2387. }));
  2388. }
  2389. };
  2390. devContainer.WarningEvent = (level, msg) =>
  2391. {
  2392. AddTextEvent("设备事件", msg, level);
  2393. if (level == WarningEnum.High)
  2394. warning(level,true);
  2395. };
  2396. devContainer.start(this.picScanner1.Handle, this.picScanner2.Handle);
  2397. }
  2398. private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
  2399. {
  2400. this.Invoke(new System.Action(() =>
  2401. {
  2402. this.tsAxisState.Text = $"[命令位:{devContainer.devAxis.CmdPos[0]} 反馈位:{devContainer.devAxis.ActualPos[0]}] | " +
  2403. $"[命令位:{devContainer.devAxis.CmdPos[1]} 反馈位:{devContainer.devAxis.ActualPos[1]}] | " +
  2404. $"[命令位:{devContainer.devAxis.CmdPos[2]} 反馈位:{devContainer.devAxis.ActualPos[2]}] | " +
  2405. $"[命令位:{devContainer.devAxis.CmdPos[3]} 反馈位:{devContainer.devAxis.ActualPos[3]}]";
  2406. }));
  2407. }
  2408. private void tsbtnCloseDev_Click(object sender, EventArgs e)
  2409. {
  2410. AddTextEvent("设备停止", $"设备停止...");
  2411. this.tsbtnProductRevise.Enabled = false;
  2412. this.tsbtnOpenDev.Visible = true;
  2413. this.tsbtnCloseDev.Visible = false;
  2414. this.btnMakeTags.Enabled = false;
  2415. this.lblTimeLen.Visible = false;
  2416. this.tsbtnReset.Enabled = tsbtnWarning.Enabled = this.tsbtnStart.Enabled = this.tsbtnGoDownPT.Enabled
  2417. = this.tsbtnPause.Enabled = this.tsbtnStopNow.Enabled = false;
  2418. this.tsbtnSizeTag.Enabled = tsbtnSizeImage.Enabled = tsbtnDefectImage.Enabled = false;
  2419. if (devContainer.state)
  2420. {
  2421. devContainer.devIOCard.reset();
  2422. devContainer.io_output(CMDName.IO默认输出);
  2423. }
  2424. timer.Stop();
  2425. devContainer.stop();
  2426. }
  2427. /// <summary>
  2428. /// 全局中断
  2429. /// </summary>
  2430. private void globalBreakEvent(int portIndex, byte data)
  2431. {
  2432. if (compareIOInput(CMDName.启动按钮) && this.tsbtnStart.Enabled)
  2433. startCommand();
  2434. else if (compareIOInput(CMDName.暂停按钮) && this.tsbtnPause.Enabled)
  2435. warning(WarningEnum.Low, false);
  2436. else if (compareIOInput(CMDName.复位按钮) && this.tsbtnReset.Enabled)
  2437. resetCommand();
  2438. else if (compareIOInput(CMDName.张力读取) && currentPT == CurrentPTEnum.Moving)
  2439. readTension();
  2440. else if (!this.disableBuzzer && compareIOInput(CMDName.门磁告警输入))
  2441. warning(WarningEnum.Low, true);
  2442. else if (!this.disableBuzzer && compareIOInput(CMDName.喷墨告警输入))
  2443. warning(WarningEnum.Low, true);
  2444. }
  2445. private bool compareIOInput(CMDName key)
  2446. {
  2447. JObject joJson = Config.CMDProcess[key];
  2448. IODirectionEnum direction = (IODirectionEnum)joJson.Value<int>("Direction");
  2449. if (direction == IODirectionEnum.输入 || direction == IODirectionEnum.输入输出)
  2450. {
  2451. return Util.compareIOInput(
  2452. joJson.Value<JArray>("IN_OP_SHOW").ToObject<List<string>>().ToArray(),
  2453. devContainer.devIOCard.DIData);
  2454. }
  2455. return false;
  2456. }
  2457. private void readTension()
  2458. {
  2459. if (Config.SkipTension)
  2460. {
  2461. AddTextEvent("张力读取", $"张力设备禁用,忽略此步骤!");
  2462. return;
  2463. }
  2464. devContainer.io_output(CMDName.张力读取);
  2465. double tensionValue = devContainer.devTension.getValue() + Config.Tension_Offset;//加入张力偏差
  2466. tensionValue=Math.Round(tensionValue, 2);//保留2位小数
  2467. AddTextEvent("张力读取", $"张力值:{tensionValue}");
  2468. devContainer.io_output(CMDName.张力读取,false,true,500);
  2469. lstTension.Add(tensionValue);
  2470. updateTensionValue(currProductModel.TensionBaseValue + currProductModel.TensionUpFloatValue, currProductModel.TensionBaseValue - currProductModel.TensionDownFloatValue);
  2471. }
  2472. /// <summary>
  2473. /// 启动
  2474. /// </summary>
  2475. private void startCommand()
  2476. {
  2477. this.setButtonEnabled(this.tsbtnProductRevise, false);
  2478. //2023-10-23 运行前清除过期图片文件
  2479. Config.DelectPictureFile();
  2480. if (!devContainer.state || warningLevel != WarningEnum.Normal || currentState != CurrentStateEnum.等待启动)
  2481. return;
  2482. if (currentPT == CurrentPTEnum.MakeTag)
  2483. {
  2484. AddTextEvent("启动", "打标未结束,非可启动状态!", warningLevel);
  2485. return;
  2486. }
  2487. if (!devContainer.devAxis.isReady())
  2488. {
  2489. AddTextEvent("启动", "轴状态异常,不可启动!", warningLevel);
  2490. return;
  2491. }
  2492. if (!devContainer.devAxis.IsReset)
  2493. {
  2494. AddTextEvent("启动", "轴需先进行复位操作!", WarningEnum.High);
  2495. return;
  2496. }
  2497. devContainer.io_output(CMDName.启动按钮);
  2498. devContainer.io_output(CMDName.绿灯输出);
  2499. devContainer.io_output(CMDName.暂停按钮, false, true, 0);
  2500. devContainer.io_output(CMDName.红灯输出, false, true, 0);
  2501. devContainer.io_output(CMDName.黄灯输出, false, true, 0);
  2502. //暂停-》继续
  2503. if (currProcessIndex >= 0 && currentPT == CurrentPTEnum.Moving && currentState == CurrentStateEnum.等待启动)
  2504. {
  2505. AddTextEvent("启动", $"暂停 -> 继续 当前工序索引:{currProcessIndex + 1}");
  2506. threadProcess = new System.Threading.Thread(() =>
  2507. {
  2508. int nextStepId = currProcessIndex;
  2509. do
  2510. {
  2511. currentState = CurrentStateEnum.运行中;
  2512. nextStepId = nextProcess(currProductModel, nextStepId);
  2513. } while (nextStepId >= 0 && !isBreakProcessRun());
  2514. //nextProcess(currProductModel, currProcessIndex);
  2515. });
  2516. threadProcess.IsBackground = true;
  2517. threadProcess.Start();
  2518. this.setButtonEnabled(this.tsbtnPause, true);
  2519. this.setButtonEnabled(this.tsbtnStopNow, true);
  2520. }
  2521. else//开始/重新开始
  2522. {
  2523. //校正从复位-》运行,不会新启动
  2524. isProductRevise = false;
  2525. resetUIValue();
  2526. AddTextEvent("启动", "移动至上料位...");
  2527. gotoUpPT();
  2528. this.Invoke(new System.Action(() =>
  2529. {
  2530. //新开始
  2531. lblTimeLen.Visible = false;
  2532. runStep();
  2533. }));
  2534. this.setButtonEnabled(this.tsbtnPause, false);
  2535. this.setButtonEnabled(this.tsbtnStopNow, false);
  2536. }
  2537. this.setButtonEnabled(this.tsbtnStart, false);
  2538. this.setButtonEnabled(this.tsbtnReset, false);
  2539. this.setButtonEnabled(this.tsbtnGoDownPT, false);
  2540. }
  2541. /// <summary>
  2542. /// 暂停
  2543. /// </summary>
  2544. /// <param name="buzzer">是否响蜂鸣</param>
  2545. private void pauseCommand(bool buzzer = false)
  2546. {
  2547. devContainer.io_output(CMDName.暂停按钮);
  2548. if (buzzer)
  2549. {
  2550. devContainer.io_output(CMDName.红灯输出);
  2551. devContainer.io_output(CMDName.蜂鸣器输出);
  2552. }
  2553. else
  2554. devContainer.io_output(CMDName.黄灯输出);
  2555. devContainer.io_output(CMDName.启动按钮, false, true, 0);
  2556. devContainer.io_output(CMDName.绿灯输出, false, true, 0);
  2557. this.setButtonEnabled(this.tsbtnWarning, true);
  2558. this.setButtonEnabled(this.tsbtnGoDownPT, false);
  2559. this.setButtonEnabled(this.tsbtnStart, false);
  2560. this.setButtonEnabled(this.tsbtnPause, false);
  2561. this.setButtonEnabled(this.tsbtnStopNow, false);
  2562. this.setButtonEnabled(this.tsbtnReset, false);
  2563. AddTextEvent("暂停", $"当前工序索引:{currProcessIndex + 1}", WarningEnum.Low);
  2564. }
  2565. /// <summary>
  2566. /// 急停
  2567. /// </summary>
  2568. private void stopNowCommand()
  2569. {
  2570. if (!devContainer.state)
  2571. {
  2572. this.setButtonEnabled(this.tsbtnStopNow, false);
  2573. return;
  2574. }
  2575. devContainer.io_output(CMDName.Y轴复位输出, false, true, 0);
  2576. devContainer.io_output(CMDName.红灯输出);
  2577. if (!this.disableBuzzer) devContainer.io_output(CMDName.蜂鸣器输出);
  2578. devContainer.io_output(CMDName.暂停按钮, false, true, 0);
  2579. devContainer.io_output(CMDName.黄灯输出, false, true, 0);
  2580. devContainer.io_output(CMDName.启动按钮, false, true, 0);
  2581. devContainer.io_output(CMDName.绿灯输出, false, true, 0);
  2582. this.setButtonEnabled(this.tsbtnWarning, true);
  2583. this.setButtonEnabled(this.tsbtnGoDownPT, false);
  2584. this.setButtonEnabled(this.tsbtnStart, false);
  2585. this.setButtonEnabled(this.tsbtnPause, false);
  2586. this.setButtonEnabled(this.tsbtnStopNow, false);
  2587. this.setButtonEnabled(this.tsbtnReset, false);
  2588. AddTextEvent("急停", $"当前工序索引:{currProcessIndex + 1}", WarningEnum.High);
  2589. }
  2590. private bool reseting = false;
  2591. private void resetCommand()
  2592. {
  2593. currentState = CurrentStateEnum.等待复位;
  2594. warningLevel = WarningEnum.Normal;
  2595. currentPT = CurrentPTEnum.InitPT;
  2596. this.Invoke(new System.Action(() =>
  2597. {
  2598. lblTimeLen.Visible = false;
  2599. this.tsbtnWarning.Enabled = this.tsbtnGoDownPT.Enabled = this.tsbtnStart.Enabled = this.tsbtnStopNow.Enabled = this.tsbtnPause.Enabled = this.tsbtnReset.Enabled = false;
  2600. }));
  2601. try
  2602. {
  2603. if (devContainer.state && !reseting)
  2604. {
  2605. reseting = true;
  2606. isProductRevise = false;
  2607. resetUIValue();
  2608. AddTextEvent("复位", $"设备复位中...");
  2609. currProcessIndex = -1;
  2610. this.setButtonEnabled(this.tsbtnReset, false);
  2611. // I/O reset后,输出默认状态
  2612. AddTextEvent("复位", $"I/O复位中...");
  2613. if (!devContainer.devIOCard.reset())
  2614. {
  2615. AddTextEvent("复位", "I/O板卡复位失败!", WarningEnum.High);
  2616. return;
  2617. }
  2618. if (!devContainer.io_output(CMDName.IO默认输出))
  2619. {
  2620. //AddTextEvent("复位", "I/O板卡复位默认值失败!", WarningEnum.High);
  2621. //return;
  2622. }
  2623. //板卡复位输出灯
  2624. devContainer.io_output(CMDName.复位按钮);
  2625. devContainer.io_output(CMDName.黄灯输出, true);
  2626. //4.5X
  2627. if(!Config.SkipSmallAxis)
  2628. devContainer.devSmallAxis.gotoPos((int)SmallAxCmdPos.倍率4_5X, false);
  2629. //移动Axis前等待厚度传感器收回
  2630. AddTextEvent("复位", $"检测厚度传感器安全值...");
  2631. if (!Config.SkipHeight)
  2632. {
  2633. while (devContainer.devHeight.getHeight() < (double)Math.Abs(Config.HeightDev_SafeValue))
  2634. {
  2635. if (!devContainer.state || currentState != CurrentStateEnum.等待复位)
  2636. return;
  2637. Thread.Sleep(100);
  2638. Application.DoEvents();
  2639. }
  2640. }
  2641. //goto ORG
  2642. AddTextEvent("复位", $"轴正在回原点...");
  2643. devContainer.devAxis.closeJogMode();
  2644. devContainer.devAxis.resetAxisState(-1);//reset state
  2645. //AddTextEvent("复位", $"重置轴状态...");
  2646. for (int i = 0; i < Config.Axis_HomeMode.Length; i++)
  2647. {
  2648. //到起始位速度使用回HOME速度
  2649. devContainer.devAxis.setAxisVelParam((double)Config.Axis_HomeVelLow[i], (double)Config.Axis_HomeVelHigh[i],
  2650. (double)Config.Axis_HomeAcc[i], (double)Config.Axis_HomeDec[i], i);
  2651. if (i != 2)
  2652. {
  2653. //devContainer.devAxis.setAxisVelParam(40000,200000,5000000, 5000000,i,true);
  2654. devContainer.devAxis.home(i, (uint)Config.Axis_HomeMode[i], (uint)Config.Axis_HomeDir[i]);
  2655. }
  2656. else//Y轴 I/O控制回HOME
  2657. {
  2658. devContainer.io_output(CMDName.Y轴复位输出);
  2659. }
  2660. }
  2661. AddTextEvent("复位", $"等待轴状态完成...");
  2662. while (!devContainer.devAxis.isReady())
  2663. {
  2664. if (!devContainer.state || currentState != CurrentStateEnum.等待复位)
  2665. {
  2666. AddTextEvent("复位", $"当前状态:"+ ((CurrentStateEnum)currentState).ToString());
  2667. return;
  2668. }
  2669. //AddTextEvent("复位", $"轴0状态:"+ ((AxisState)devContainer.devAxis.AxState[0]).ToString());
  2670. //AddTextEvent("复位", $"轴1状态:" + ((AxisState)devContainer.devAxis.AxState[1]).ToString());
  2671. //AddTextEvent("复位", $"轴2状态:" + ((AxisState)devContainer.devAxis.AxState[2]).ToString());
  2672. //AddTextEvent("复位", $"轴3状态:" + ((AxisState)devContainer.devAxis.AxState[3]).ToString());
  2673. Thread.Sleep(1000);
  2674. Application.DoEvents();
  2675. }
  2676. //判断Y轴回原点完成I/O信号
  2677. AddTextEvent("复位", $"等待Y轴回HOME完成...");
  2678. while (!this.compareIOInput(CMDName.Y轴复位完成输入))
  2679. {
  2680. Thread.Sleep(100);
  2681. Application.DoEvents();
  2682. }
  2683. AddTextEvent("复位", $"Y轴回HOME已完成.");
  2684. devContainer.io_output(CMDName.Y轴复位输出, false, true, 0);
  2685. AddTextEvent("复位", $"重置Y轴反馈位置与命令位置.");
  2686. devContainer.devAxis.resetCmdPosition(2);
  2687. devContainer.devAxis.resetActualPosition(2);
  2688. //
  2689. if (devContainer.devAxis.isError())
  2690. throw new Exception("轴回原点失败!");
  2691. if (Config.OpenAxisXCalibration)
  2692. {
  2693. //2023-11-29 加入X1X2回原之后启动补偿
  2694. devContainer.io_output(CMDName.X1轴复位输出, false, true, 300);
  2695. devContainer.io_output(CMDName.X2轴复位输出, false, true, 300);
  2696. }
  2697. //
  2698. //goto InitPT
  2699. //AddTextEvent("复位", $"轴回原点完成,回到初始位...");
  2700. JArray arrPT = Config.joPTSetting.Value<JArray>("initPT");
  2701. for (int i = 0; i < arrPT.Count; i++)
  2702. {
  2703. if (!devContainer.state || currentState != CurrentStateEnum.等待复位)
  2704. return;
  2705. AddTextEvent($"复位", $"轴{i}准备运动至初始位:{(double)arrPT[i]}(当前轴状态:{((AxisState)devContainer.devAxis.AxState[i]).ToString()})...");
  2706. devContainer.devAxis.move_ptp(i, (double)arrPT[i], AxMoveMode.绝对位置);
  2707. }
  2708. while (!devContainer.devAxis.isReady())
  2709. {
  2710. if (!devContainer.state || warningLevel != WarningEnum.Normal)
  2711. return;
  2712. Thread.Sleep(100);
  2713. }
  2714. if (devContainer.devAxis.isError())
  2715. throw new Exception("轴移动至初始位失败!");
  2716. //
  2717. this.setButtonEnabled(this.tsbtnReset, true);
  2718. this.setButtonEnabled(this.tsbtnStart, true);
  2719. this.setButtonEnabled(this.tsbtnStopNow, true);
  2720. this.setButtonEnabled(this.tsbtnPause, false);
  2721. this.setButtonEnabled(this.tsbtnGoDownPT, false);
  2722. this.setButtonEnabled(this.tsbtnWarning, false);
  2723. devContainer.io_output(CMDName.复位按钮, false, true, 0);//熄灭
  2724. devContainer.io_output(CMDName.黄灯输出);//长亮
  2725. currentPT = CurrentPTEnum.InitPT;
  2726. currentState = CurrentStateEnum.等待启动;
  2727. AddTextEvent("复位", $"复位完成。");
  2728. this.setButtonEnabled(this.tsbtnProductRevise, true);
  2729. }
  2730. else
  2731. {
  2732. AddTextEvent("复位", "非可复位状态,请先停止后再复位!", WarningEnum.High);
  2733. }
  2734. }
  2735. catch (Exception ex)
  2736. {
  2737. AddTextEvent("复位", "复位失败 Err:" + ex.Message, WarningEnum.High);
  2738. warning(WarningEnum.High, true);
  2739. }
  2740. finally
  2741. {
  2742. reseting = false;
  2743. }
  2744. }
  2745. /// <summary>
  2746. /// 上料
  2747. /// </summary>
  2748. private void gotoUpPT()
  2749. {
  2750. try
  2751. {
  2752. JArray arrPT = Config.joPTSetting.Value<JArray>("upPT");
  2753. for (int i = 0; i < arrPT.Count; i++)
  2754. {
  2755. if (!devContainer.state || warningLevel != WarningEnum.Normal)
  2756. return;
  2757. AddTextEvent($"上料", $"轴{i}准备运动至上料位:{(double)arrPT[i]}(当前轴状态:{((AxisState)devContainer.devAxis.AxState[i]).ToString()})...");
  2758. devContainer.devAxis.move_ptp(i, (double)arrPT[i], AxMoveMode.绝对位置);
  2759. }
  2760. while (!devContainer.devAxis.isReady())
  2761. {
  2762. if (!devContainer.state || warningLevel != WarningEnum.Normal)
  2763. return;
  2764. Thread.Sleep(100);
  2765. }
  2766. if (devContainer.devAxis.isError())
  2767. throw new Exception("轴移动至上料位失败!");
  2768. //
  2769. currentPT = CurrentPTEnum.UpPT;
  2770. currentState = CurrentStateEnum.等待扫码;
  2771. AddTextEvent($"上料", "到达上料位!");
  2772. }
  2773. catch (Exception ex)
  2774. {
  2775. AddTextEvent("上料", "上料初始失败 Err:" + ex.Message, WarningEnum.High);
  2776. warning(WarningEnum.High);
  2777. }
  2778. }
  2779. /// <summary>
  2780. /// 下料
  2781. /// </summary>
  2782. private void gotoDownPT()
  2783. {
  2784. try
  2785. {
  2786. if (currentState != CurrentStateEnum.打标中 && currentState != CurrentStateEnum.等待启动 && currentState != CurrentStateEnum.自动流程结束)
  2787. {
  2788. AddTextEvent($"下料", $"非可下料状态:{currentState.ToString()}");
  2789. return;
  2790. }
  2791. currentState = CurrentStateEnum.下料中;
  2792. isProductRevise = false;
  2793. JArray arrPT = Config.joPTSetting.Value<JArray>("downPT");
  2794. for (int i = 0; i < arrPT.Count; i++)
  2795. {
  2796. if (!devContainer.state || warningLevel != WarningEnum.Normal || currentState != CurrentStateEnum.下料中)
  2797. return;
  2798. AddTextEvent($"下料", $"轴{i}准备运动至下料位:{(double)arrPT[i]}(当前轴状态:{((AxisState)devContainer.devAxis.AxState[i]).ToString()})...");
  2799. devContainer.devAxis.move_ptp(i, (double)arrPT[i], AxMoveMode.绝对位置);
  2800. }
  2801. while (!devContainer.devAxis.isReady())
  2802. {
  2803. if (!devContainer.state || warningLevel != WarningEnum.Normal || currentState != CurrentStateEnum.下料中)
  2804. return;
  2805. Thread.Sleep(100);
  2806. }
  2807. if (devContainer.devAxis.isError())
  2808. throw new Exception("轴移动至下料位失败!");
  2809. //
  2810. currentPT = CurrentPTEnum.DownPT;
  2811. currentState = CurrentStateEnum.等待启动;
  2812. devContainer.io_output(CMDName.下料完成输出);
  2813. setButtonEnabled(tsbtnStart, true);
  2814. AddTextEvent($"下料", "下料完成!");
  2815. }
  2816. catch (Exception ex)
  2817. {
  2818. AddTextEvent("下料", "下料失败 Err:" + ex.Message, WarningEnum.High);
  2819. warning(WarningEnum.High);
  2820. }
  2821. }
  2822. private void setButtonEnabled(ToolStripButton button, bool Enabled)
  2823. {
  2824. this.Invoke(new System.Action(() =>
  2825. {
  2826. button.Enabled = Enabled;
  2827. }));
  2828. }
  2829. private void setButtonEnabled(ToolStripMenuItem button, bool Enabled)
  2830. {
  2831. this.Invoke(new System.Action(() =>
  2832. {
  2833. button.Enabled = Enabled;
  2834. }));
  2835. }
  2836. private void setButtonEnabled(Control button, bool Enabled)
  2837. {
  2838. this.Invoke(new System.Action(() =>
  2839. {
  2840. button.Enabled = Enabled;
  2841. }));
  2842. }
  2843. private void FrmMian_Shown(object sender, EventArgs e)
  2844. {
  2845. }
  2846. private void FrmMian_Resize(object sender, EventArgs e)
  2847. {
  2848. }
  2849. private void 流程管理ToolStripMenuItem_Click(object sender, EventArgs e)
  2850. {
  2851. if (devContainer.state)
  2852. {
  2853. MessageBox.Show("请先停止生产,再进行流程修改!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  2854. return;
  2855. }
  2856. FrmStepList frm = new FrmStepList();
  2857. frm.ShowDialog();
  2858. }
  2859. private void 产品管理ToolStripMenuItem_Click(object sender, EventArgs e)
  2860. {
  2861. if (devContainer.state)
  2862. {
  2863. MessageBox.Show("请先停止生产,再进行产品修改!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  2864. return;
  2865. }
  2866. FrmProductList frm = new FrmProductList();
  2867. frm.ShowDialog();
  2868. loadProductCodeList();
  2869. }
  2870. private void tsbtnProductRevise_Click(object sender, EventArgs e)
  2871. {
  2872. if (!devContainer.state)
  2873. {
  2874. MessageBox.Show("请先启动设备!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
  2875. return;
  2876. }
  2877. if (currentPT != CurrentPTEnum.InitPT || currentState != CurrentStateEnum.等待启动)
  2878. {
  2879. MessageBox.Show("请先复位设备!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
  2880. return;
  2881. }
  2882. FrmProductList frm = new FrmProductList(true);
  2883. if (frm.ShowDialog() == DialogResult.Yes && frm.Product != null)//执行校正
  2884. {
  2885. AddTextEvent("校正", "开始执行产品base厚度校正...");
  2886. isProductRevise = true;
  2887. currProductModel = frm.Product;
  2888. currProductModel.HeightBaseDec = "";
  2889. this.txtProductCode.Text = currProductModel.Code;
  2890. this.txtProductName.Text = currProductModel.Name;
  2891. this.txtProductSN.Text = "";
  2892. this.dgvProcess.DataSource = new BindingSource(currProductModel.ReviseStepInfo.ProcessList, null);
  2893. devContainer.libFor.clear();
  2894. devContainer.libIF.clear();
  2895. //
  2896. this.setButtonEnabled(this.tsbtnStart, false);
  2897. this.setButtonEnabled(this.tsbtnPause, true);
  2898. this.setButtonEnabled(this.tsbtnStopNow, true);
  2899. threadProcess = new System.Threading.Thread(() =>
  2900. {
  2901. int nextStepId = 0;
  2902. do
  2903. {
  2904. currentState = CurrentStateEnum.运行中;
  2905. nextStepId = nextProcess(currProductModel, nextStepId);
  2906. } while (nextStepId >= 0 && !isBreakProcessRun());
  2907. });
  2908. threadProcess.IsBackground = true;
  2909. threadProcess.Start();
  2910. }
  2911. }
  2912. private void 设备调试ToolStripMenuItem_Click(object sender, EventArgs e)
  2913. {
  2914. if (devContainer.state)
  2915. {
  2916. MessageBox.Show("请先停止生产,再进行设备调试!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  2917. return;
  2918. }
  2919. FrmDebug3 frm = new FrmDebug3();
  2920. frm.ShowDialog();
  2921. }
  2922. private void 角色管理ToolStripMenuItem_Click(object sender, EventArgs e)
  2923. {
  2924. FrmRoleRight frm = new FrmRoleRight();
  2925. frm.ShowDialog(this);
  2926. }
  2927. private void 用户管理ToolStripMenuItem_Click(object sender, EventArgs e)
  2928. {
  2929. FrmUserList frm = new FrmUserList();
  2930. frm.ShowDialog(this);
  2931. }
  2932. private void 退出ToolStripMenuItem_Click(object sender, EventArgs e)
  2933. {
  2934. Application.Exit();
  2935. System.GC.Collect();
  2936. System.Environment.Exit(0);
  2937. }
  2938. private void 注销ToolStripMenuItem_Click(object sender, EventArgs e)
  2939. {
  2940. if (devContainer.state)
  2941. {
  2942. MessageBox.Show("请先停止生产再退出!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  2943. return;
  2944. }
  2945. if (MessageBox.Show($"确认退出?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
  2946. {
  2947. this.bExitApp = true;
  2948. Process.Start(Application.StartupPath + "\\ProductionControl.exe");
  2949. this.Close();
  2950. }
  2951. }
  2952. private void splitContainer1_Panel1_Resize(object sender, EventArgs e)
  2953. {
  2954. int allWidth = this.splitContainer1.Panel1.Width;
  2955. this.gpbProductInfo.Width = this.flpnlResultData.Width = this.gpbProcessList.Width = this.gpbLog.Width = allWidth;
  2956. //
  2957. this.txtProductName.Width = this.txtProductCode.Width = this.gpbProductInfo.Width - this.txtProductName.Left - 8;
  2958. this.txtProductSN.Width = this.txtBatchId.Width = (this.txtProductName.Width- lblBatchId.Width)/2;
  2959. this.lblBatchId.Left = this.txtProductSN.Right ;
  2960. this.txtBatchId.Left = this.lblBatchId.Right;
  2961. //
  2962. int spliceWidth = 5;
  2963. kanban1.Width = kanban2.Width = kanban3.Width = kanban4.Width = kanban5.Width = kanban6.Width = (flpnlResultData.Width-20) / 6;
  2964. //2023-10-17 更新log和步骤列表显示
  2965. this.gpbProcessList.Height = this.splitContainer1.Panel1.Height - this.gpbProcessList.Top - this.gpbLog.Height;
  2966. this.gpbLog.Top = this.splitContainer1.Panel1.Height - this.gpbLog.Height;
  2967. }
  2968. private void 关于ToolStripMenuItem_Click(object sender, EventArgs e)
  2969. {
  2970. AboutBox1 aboutBox1 = new AboutBox1();
  2971. aboutBox1.Show();
  2972. }
  2973. private void 系统设置ToolStripMenuItem_Click(object sender, EventArgs e)
  2974. {
  2975. FrmSysSetting frmSetting = new FrmSysSetting();
  2976. frmSetting.ShowDialog();
  2977. }
  2978. private void dgvProcess_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
  2979. {
  2980. //string processCode;
  2981. //for (int i = 0; i < this.dgvProcess.Rows.Count; i++)
  2982. //{
  2983. //processCode = dgvProcess.Rows[i].Cells[0].Value.ToString();
  2984. //dgvProcess.Rows[i].Cells[1].Value = Config.dicDevType[processCode];
  2985. //}
  2986. }
  2987. private void tsbtnWarning_Click(object sender, EventArgs e)
  2988. {
  2989. //if (warningLevel == WarningEnum.Normal)
  2990. //{
  2991. // tsbtnWarning.Enabled = false;
  2992. // return;
  2993. //}
  2994. //重置AXIS状态
  2995. devContainer.devAxis.resetAxisState();
  2996. if (!devContainer.devAxis.isReady())
  2997. {
  2998. AddTextEvent("解除报警", "轴状态未恢复,解除报警失败!", warningLevel);
  2999. return;
  3000. }
  3001. if (devContainer.devAxis.isError())
  3002. {
  3003. AddTextEvent("解除报警", "轴IO状态异常,解除报警失败!", warningLevel);
  3004. return;
  3005. }
  3006. if (!this.disableDoorSensor && compareIOInput(CMDName.门磁告警输入))
  3007. {
  3008. AddTextEvent("解除报警", "门磁告警未清除 ,解除报警失败!", warningLevel);
  3009. return;
  3010. }
  3011. if (!this.disableDoorSensor && compareIOInput(CMDName.喷墨告警输入))
  3012. {
  3013. AddTextEvent("解除报警", "喷墨告警输入未清除 ,解除报警失败!", warningLevel);
  3014. return;
  3015. }
  3016. //关闭蜂鸣器
  3017. devContainer.io_output(CMDName.蜂鸣器输出, false, true, 0);
  3018. devContainer.io_output(CMDName.红灯输出, false, true, 0);
  3019. devContainer.io_output(CMDName.复位按钮, false, true, 0);
  3020. if (warningLevel == WarningEnum.High)
  3021. {
  3022. AddTextEvent("解除报警", "急停告警已解除,但必需进行复位操作!", warningLevel);
  3023. currentState = CurrentStateEnum.等待复位;
  3024. this.tsbtnReset.Enabled = true;
  3025. tsbtnWarning.Enabled = this.tsbtnStart.Enabled = this.tsbtnGoDownPT.Enabled
  3026. = this.tsbtnPause.Enabled = this.tsbtnStopNow.Enabled = this.btnMakeTags.Enabled= false;
  3027. }
  3028. else
  3029. {
  3030. devContainer.io_output(CMDName.黄灯输出);
  3031. AddTextEvent("解除报警", "告警已解除,请继续选择下一步操作!", warningLevel);
  3032. if (currentPT == CurrentPTEnum.MakeTag)
  3033. currentState = CurrentStateEnum.打标中;
  3034. else
  3035. currentState = CurrentStateEnum.等待启动;
  3036. tsbtnWarning.Enabled = false;
  3037. this.tsbtnStart.Enabled = this.tsbtnGoDownPT.Enabled = true;
  3038. this.tsbtnReset.Enabled = this.tsbtnPause.Enabled = this.tsbtnStopNow.Enabled = true;
  3039. }
  3040. warningLevel = WarningEnum.Normal;
  3041. }
  3042. private void tsbtnGoDownPT_Click(object sender, EventArgs e)
  3043. {
  3044. if (!devContainer.state || warningLevel!= WarningEnum.Normal)
  3045. return;
  3046. if (!devContainer.devAxis.isReady())
  3047. {
  3048. AddTextEvent("下料失败", "轴状态异常!", WarningEnum.Low);
  3049. return;
  3050. }
  3051. gotoDownPT();
  3052. }
  3053. //急停
  3054. private void tsbtnStopNow_Click(object sender, EventArgs e)
  3055. {
  3056. this.warning(WarningEnum.High);
  3057. }
  3058. private Thread threadProcess;
  3059. private void tsbtnStart_Click(object sender, EventArgs e)
  3060. {
  3061. this.startCommand();
  3062. }
  3063. private void tsbtnPause_Click(object sender, EventArgs e)
  3064. {
  3065. warning(WarningEnum.Low,false);
  3066. }
  3067. //复位
  3068. private void tsbtnReset_Click(object sender, EventArgs e)
  3069. {
  3070. this.resetCommand();
  3071. }
  3072. private void tsbtnGButSetting_Click(object sender, EventArgs e)
  3073. {
  3074. if (devContainer.state)
  3075. {
  3076. MessageBox.Show("请先停止生产,再进行设置!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  3077. return;
  3078. }
  3079. FrmCMDProcess from = new FrmCMDProcess();
  3080. from.ShowDialog();
  3081. }
  3082. private void tsbtnPTSetting_Click(object sender, EventArgs e)
  3083. {
  3084. if (devContainer.state)
  3085. {
  3086. MessageBox.Show("请先停止生产,再进行设置!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  3087. return;
  3088. }
  3089. FrmPTSetting from = new FrmPTSetting();
  3090. from.ShowDialog();
  3091. }
  3092. private void tsMenuModifyPW_Click(object sender, EventArgs e)
  3093. {
  3094. FrmModifyPW frm = new FrmModifyPW();
  3095. frm.ShowDialog();
  3096. }
  3097. //分拆面板平均分配
  3098. private void splitContainer1_ClientSizeChanged(object sender, EventArgs e)
  3099. {
  3100. if (this.WindowState == FormWindowState.Minimized)
  3101. return;
  3102. SplitContainer sc = (SplitContainer)sender;
  3103. sc.SplitterDistance = sc.Width / 7*3;
  3104. }
  3105. private void splitContainer3_ClientSizeChanged(object sender, EventArgs e)
  3106. {
  3107. if (this.WindowState == FormWindowState.Minimized)
  3108. return;
  3109. SplitContainer sc = (SplitContainer)sender;
  3110. sc.SplitterDistance = sc.Height / 2;
  3111. }
  3112. private void Menu查询统计_Click(object sender, EventArgs e)
  3113. {
  3114. FrmWeb frm = new FrmWeb("查询统计", $"reportRecordSN?CustomerVer={Config.CustomerVer}");
  3115. frm.Show();
  3116. }
  3117. private void tsMenuOrder_Click(object sender, EventArgs e)
  3118. {
  3119. //FrmOrderList frm = new FrmOrderList();
  3120. string subject = (sender as ToolStripMenuItem).Text;
  3121. FrmWeb frm = new FrmWeb(subject, $"reportRecordSN?CustomerVer={Config.CustomerVer}");
  3122. frm.Show();
  3123. }
  3124. private void tsMenuOrderProduct_Click(object sender, EventArgs e)
  3125. {
  3126. string subject = (sender as ToolStripMenuItem).Text;
  3127. FrmWeb frm = new FrmWeb(subject, $"reportRecordProduct?CustomerVer={Config.CustomerVer}");
  3128. frm.Show();
  3129. }
  3130. private void tsMenuStatistics_Click(object sender, EventArgs e)
  3131. {
  3132. string subject = (sender as ToolStripMenuItem).Text;
  3133. FrmWeb frm = new FrmWeb(subject, $"bigscreen/index.html", "http://127.0.0.1:18082/static/");
  3134. frm.Show();
  3135. }
  3136. private void toolStripButton1_Click(object sender, EventArgs e)
  3137. {
  3138. //Bitmap[] bmps = new Bitmap[2];
  3139. //bmps[0] = new Bitmap(@"f:\1.bmp");
  3140. //bmps[1] = new Bitmap(@"f:\111.bmp");
  3141. //List<Dictionary<int, List<string>[]>> list = new List<Dictionary<int, List<string>[]>>();
  3142. //Dictionary<int, List<string>[]> dir = new Dictionary<int, List<string>[]>();
  3143. //List<string>[] vs = new List<string>[1];
  3144. //vs[0] = new List<string>();
  3145. //dir.Add(0, vs);
  3146. //list.Add(dir);
  3147. //showDefectSmallBmps(bmps, list);
  3148. var bmp = Bitmap.FromFile("f:\\1.jpg");
  3149. int pnlWidth = this.pnlBmpList.ClientSize.Width;
  3150. for (int i = 0; i < 5; i++)
  3151. {
  3152. int x = i;
  3153. this.Invoke(new System.Action(() =>
  3154. {
  3155. int imgWidth = 224;
  3156. int imgHeight = 200;
  3157. int splitWidth = 10;
  3158. int index = Convert.ToInt32(this.gboxDefectList.Tag);
  3159. PictureBox picbox = new PictureBox();
  3160. picbox.Width = imgWidth;
  3161. picbox.Height = imgHeight;
  3162. CheckBox checkBox = new CheckBox();
  3163. picbox.Image = bmp;
  3164. picbox.Name = "imgDefect_" + index;
  3165. picbox.Tag ="1,2,3";
  3166. checkBox.Name = "chkDefect_" + index;
  3167. checkBox.Text = $"第{index + 1}张";
  3168. checkBox.CheckedChanged += new System.EventHandler(this.CheckBox_CheckedChanged);
  3169. picbox.Click += new EventHandler(defectBmpBox_Click);
  3170. picbox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
  3171. picbox.BorderStyle = BorderStyle.FixedSingle;
  3172. picbox.Margin = new Padding((pnlWidth - picbox.Width) / 2, splitWidth, 0, 0);
  3173. checkBox.Margin = new Padding((pnlWidth - checkBox.Width) / 2+ splitWidth, 0, 0, 0);
  3174. //
  3175. //if (this.pnlBmpList.Controls.Count > 0)
  3176. // {
  3177. // if ((this.pnlBmpList.Controls[this.pnlBmpList.Controls.Count - 1].Right + imgWidth + splitWidth) > this.pnlBmpList.Width)
  3178. // picbox.Location = new System.Drawing.Point(splitWidth, this.pnlBmpList.Controls[this.pnlBmpList.Controls.Count - 1].Bottom + splitWidth);
  3179. // else
  3180. // picbox.Location = new System.Drawing.Point(this.pnlBmpList.Controls[this.pnlBmpList.Controls.Count - 1].Right + splitWidth, this.pnlBmpList.Controls[this.pnlBmpList.Controls.Count - 1].Location.Y);
  3181. // }
  3182. // else
  3183. // {
  3184. // picbox.Location = new System.Drawing.Point(splitWidth, 0);
  3185. // }
  3186. // checkBox.Location = new System.Drawing.Point(picbox.Location.X + 5, picbox.Location.Y + 5);
  3187. // checkBox.ForeColor = Color.Black;
  3188. //}
  3189. this.pnlBmpList.Controls.Add(picbox);
  3190. this.pnlBmpList.Controls.Add(checkBox);
  3191. //
  3192. index++;
  3193. this.gboxDefectList.Tag = index;
  3194. this.gboxDefectList.Text = $"缺陷图像:{index} 张";
  3195. pnlBmpList.VerticalScroll.Value = pnlBmpList.VerticalScroll.Maximum;
  3196. }));
  3197. }
  3198. }
  3199. private void chkBuzzer_CheckedChanged(object sender, EventArgs e)
  3200. {
  3201. this.disableBuzzer = chkBuzzer.Checked;
  3202. if (devContainer.state && this.disableBuzzer)
  3203. devContainer.io_output(CMDName.蜂鸣器输出, false, true, 0);
  3204. }
  3205. private void chkDoorSensor_CheckedChanged(object sender, EventArgs e)
  3206. {
  3207. this.disableDoorSensor = chkDoorSensor.Checked;
  3208. }
  3209. private void tsbtnLight_Click(object sender, EventArgs e)
  3210. {
  3211. if (devContainer.state)
  3212. {
  3213. if(tsbtnLight.Text.Trim()== "开灯")
  3214. {
  3215. if(devContainer.io_output(CMDName.日光灯输出))
  3216. tsbtnLight.Text = " 关灯 ";
  3217. }
  3218. else
  3219. {
  3220. if (devContainer.io_output(CMDName.日光灯输出, false, true, 0))
  3221. tsbtnLight.Text = " 开灯 ";
  3222. }
  3223. }
  3224. }
  3225. private void btnMakeTag_Click(object sender, EventArgs e)
  3226. {
  3227. if(currentPT != CurrentPTEnum.MakeTag)
  3228. {
  3229. AddTextEvent("打标失败", "非可打标状态!");
  3230. return;
  3231. }
  3232. btnMakeTags.Enabled = false;
  3233. autoMakeTagRuning = true;
  3234. Thread threadtest = new System.Threading.Thread(() =>
  3235. {
  3236. try
  3237. {
  3238. if (!devContainer.state)
  3239. {
  3240. AddTextEvent("打标", "设备已停机!");
  3241. return;
  3242. }
  3243. if ((int)this.lblDefectAddTag.Tag < 1)
  3244. {
  3245. AddTextEvent("打标", "打标队列为空!");
  3246. return;
  3247. }
  3248. int tagIndex;
  3249. double Xmm, Ymm;
  3250. Bitmap currBmp;
  3251. string[] tags;
  3252. for (int i = 0; i < this.pnlBmpList.Controls.Count; i += 2)
  3253. {
  3254. CheckBox cb = this.pnlBmpList.Controls[i + 1] as CheckBox;
  3255. if (cb.Checked)
  3256. {
  3257. PictureBox picBox = this.pnlBmpList.Controls[i] as PictureBox;
  3258. tags = picBox.Tag.ToString().Split(',');
  3259. tagIndex = Convert.ToInt32(tags[0]);
  3260. Xmm = Convert.ToDouble(tags[1]);
  3261. Ymm = Convert.ToDouble(tags[2]);
  3262. currBmp = (Bitmap)picBox.Image;
  3263. //打标
  3264. AddTextEvent("打标", $"第{i / 2 + 1}/{this.pnlBmpList.Controls.Count / 2}张 [索引:{tagIndex}, X:{Xmm}mm, Y:{Ymm}mm]");
  3265. var list = devContainer.libDefect.makeTag(tagIndex, Xmm, Ymm, currBmp.Width, currBmp.Height);
  3266. devContainer.devAxis.move_ptp(1, list[0], AxMoveMode.绝对位置);
  3267. devContainer.devAxis.move_ptp(2, list[1], AxMoveMode.绝对位置);
  3268. while (!devContainer.devAxis.isReady(1) || !devContainer.devAxis.isReady(2))
  3269. {
  3270. Application.DoEvents();
  3271. Thread.Sleep(100);
  3272. if (!devContainer.state)
  3273. throw new Exception("设备停止,打标中止!");
  3274. }
  3275. //
  3276. if (!devContainer.io_output(CMDName.喷墨输出, false, true, 500))
  3277. throw new Exception("请确认[喷墨输出]指令设置是否正确!");
  3278. this.Invoke(new System.Action(() =>
  3279. {
  3280. cb.Checked = false;
  3281. }));
  3282. }
  3283. }
  3284. //自动下料
  3285. AddTextEvent("打标完成", $"批量打标完成,进行下料...");
  3286. currentState = CurrentStateEnum.自动流程结束;
  3287. gotoDownPT();
  3288. }
  3289. catch (Exception ex)
  3290. {
  3291. AddTextEvent("打标失败", ex.Message, WarningEnum.High);
  3292. warning(WarningEnum.Low, true);
  3293. }
  3294. finally { autoMakeTagRuning=false; }
  3295. });
  3296. threadtest.IsBackground = true;
  3297. threadtest.Start();
  3298. }
  3299. private void btnInputCode_Click(object sender, EventArgs e)
  3300. {
  3301. txtProductCode_DoubleClick(null, null);
  3302. }
  3303. private void txtProductName_DoubleClick(object sender, EventArgs e)
  3304. {
  3305. txtProductCode_DoubleClick(null, null);
  3306. }
  3307. private void txtProductCode_DoubleClick(object sender, EventArgs e)
  3308. {
  3309. //不需要等待扫码才能选择
  3310. //if (currentState != CurrentStateEnum.等待扫码) return;
  3311. FrmInput frm = new FrmInput(productCodeList, "请选择产品料号:");
  3312. if (frm.ShowDialog() != DialogResult.OK && string.IsNullOrWhiteSpace(frm.inputData))
  3313. return;
  3314. //显示料号
  3315. //this.txtProductCode.Text = frm.inputData;
  3316. var model = svcProduct.GetModelNav(frm.inputData);
  3317. if (model != null && model.StepInfo.ProcessList.Count > 0)
  3318. {
  3319. this.txtProductCode.Text = model.Code;
  3320. this.txtProductName.Text = model.Name;
  3321. }
  3322. /*//屏蔽扫码枪事件
  3323. Task.Factory.StartNew(() =>
  3324. {
  3325. devContainer.devCodeScanner.ScanerEvent?.Invoke(frm.inputData);
  3326. });
  3327. */
  3328. //string code = Interaction.InputBox("请输入产品编码", "输入框", "", -1, -1).Trim();
  3329. //if(code != "")
  3330. //{
  3331. // Task.Factory.StartNew(() =>
  3332. // {
  3333. // devContainer.devCodeScanner.ScanerEvent?.Invoke(frm.inputData);
  3334. // });
  3335. //}
  3336. }
  3337. private void txtProductSN_DoubleClick(object sender, EventArgs e)
  3338. {
  3339. //if (currentState != CurrentStateEnum.等待扫码 || this.txtProductCode.Text.Trim()=="") return;
  3340. //string sn = Interaction.InputBox("请输入产品SN码", "输入框", "", -1, -1).Trim();
  3341. //if (sn != "")
  3342. //{
  3343. // this.txtProductSN.Text = sn;
  3344. // string code = this.txtProductCode.Text.Trim();
  3345. // Task.Factory.StartNew(() =>
  3346. // {
  3347. // devContainer.devCodeScanner.ScanerEvent?.Invoke(code);
  3348. // });
  3349. //}
  3350. }
  3351. private void 测试ToolStripMenuItem_Click(object sender, EventArgs e)
  3352. {
  3353. tsbtnDefectImage.Enabled = tsbtnSizeImage.Enabled=true;
  3354. return;
  3355. Form1 frm = new Form1();
  3356. frm.Show();
  3357. //tsbtnDefectImage_Click(null, null);
  3358. return;
  3359. try
  3360. {
  3361. //string ls = "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,182.257722637742,182.257727282667,0,0";
  3362. //List<string> list = new List<string>(ls.Split(','));
  3363. //lstPT = list.Select<string, double>(q => Convert.ToDouble(q)).ToList();
  3364. //updatePTValue(1,2);
  3365. //lstPT.Add(10);
  3366. //lstPT.Add(0);
  3367. //updatePTValue(1, 2);
  3368. //{
  3369. // lstLineWidth.Add(res.Shanxian > 0 ? res.Shanxian : 0);
  3370. // updateLineWidthValue(model.LineWidthBaseValue + model.LineWidthUpFloatValue, model.LineWidthBaseValue - model.LineWidthDownFloatValue);
  3371. //}
  3372. //return;
  3373. //loadProductCodeList();
  3374. //FrmInput frm = new FrmInput(null, "请选择产品编码:");
  3375. //if (frm.ShowDialog() != DialogResult.OK)
  3376. // return;
  3377. //var model = svcProduct.GetModelNav(frm.inputData);
  3378. //if (model == null)
  3379. // throw new Exception("没有此产品!");
  3380. //order.ProductId = model.Id;
  3381. //order.BatchId = model.BatchId;
  3382. //order.StepId = model.StepId==null? 0:(int)model.StepId;
  3383. //frm = new FrmInput(null, "请输入SN:");
  3384. //if (frm.ShowDialog() != DialogResult.OK)
  3385. // return;
  3386. //order.SN = frm.inputData;
  3387. //frm = new FrmInput(null, "请输入主机台Mark点数据:", "[0,0,0,0,0,0,0,0]");
  3388. //if (frm.ShowDialog() != DialogResult.OK)
  3389. // return;
  3390. //order.MarkData= frm.inputData;
  3391. //order.Tension1 = order.Tension2 = order.Tension3 = order.Tension4 = order.Tension5 = order.Tension5 + 3;
  3392. //order.PT1 = order.PT4 = order.PT5 = order.PT6 = order.PT6 + 1.33;
  3393. //order.LineWidth2 = order.LineWidth3 = order.LineWidth5 = order.LineWidth6 = +order.LineWidth6 + 1.22;
  3394. //order.HeightValue = order.Height1 = order.Height3 = order.Height4 = 55;
  3395. //order.DefectCount = order.DefectCount + 22;
  3396. //order.YXCount = order.PPCount = 33;
  3397. //order.TimeLen = 1000;
  3398. //order.Succeed = true;
  3399. //order.ModifyUserCode = order.CreateUserCode = Config.loginUser.Code;
  3400. //if (!svcOrder.Insert(order))
  3401. // AddTextEvent("保存失败", $"保存生产记录失败!");
  3402. //MessageBox.Show("成功!");
  3403. //---------------
  3404. this.lstCompareFailZoomImage.Add((Bitmap)Bitmap.FromFile(@"f:\1.bmp"));
  3405. this.lstCompareFailZoomImage.Add((Bitmap)Bitmap.FromFile(@"f:\2.bmp"));
  3406. this.lstCompareFailZoomImage.Add((Bitmap)Bitmap.FromFile(@"f:\3.bmp"));
  3407. }
  3408. catch(Exception ex)
  3409. {
  3410. MessageBox.Show(ex.Message);
  3411. }
  3412. }
  3413. private void toolStripSeparator4_Click(object sender, EventArgs e)
  3414. {
  3415. }
  3416. private void chkHttpLog_CheckedChanged(object sender, EventArgs e)
  3417. {
  3418. if (this.chkHttpLog.Checked)
  3419. {
  3420. webService.LogEvent = (warning, msg) =>
  3421. {
  3422. AddTextEvent("HTTP服务", msg, warning);
  3423. };
  3424. }
  3425. else
  3426. webService.LogEvent = null;
  3427. }
  3428. //打开比对失败的图片
  3429. private void lblCompareResult_Click(object sender, EventArgs e)
  3430. {
  3431. if (lstCompareFailZoomImage.Count < 1) return;
  3432. FrmPhotoShow frm = new FrmPhotoShow(lstCompareFailZoomImage);
  3433. frm.ShowDialog();
  3434. }
  3435. //过程变量查看
  3436. private void tsbtnSizeTag_Click(object sender, EventArgs e)
  3437. {
  3438. if (order == null || order.SizeTagDataList == null || order.SizeTagDataList.Count<1)
  3439. return;
  3440. FrmShowSizeTag frm = new FrmShowSizeTag(order);
  3441. frm.Show();
  3442. }
  3443. //缺陷+比对与图纸查看
  3444. private void tsbtnDefectImage_Click(object sender, EventArgs e)
  3445. {
  3446. //currProductModel = svcProduct.GetModelNav(53);
  3447. //order = svcOrder.GetModelNav("20230814002");
  3448. AddTextEvent("打开窗口", "1");
  3449. if (currProductModel ==null || order == null || order.DefectInfoList == null || order.DefectInfoList.Count < 1)
  3450. return;
  3451. AddTextEvent("打开窗口", "2");
  3452. //图纸
  3453. try
  3454. {
  3455. string gbxBmpPath = "";
  3456. var attachmentFile = currProductModel.AttachmentList.FirstOrDefault(x => x.Type == 0);
  3457. if (attachmentFile != null)
  3458. {
  3459. gbxBmpPath = Application.StartupPath + $"\\Attachment\\product\\{attachmentFile.NameTimestamp}";
  3460. if (!File.Exists(gbxBmpPath + ".bmp")) gbxBmpPath = "";
  3461. }
  3462. AddTextEvent("打开窗口", "3");
  3463. if (string.IsNullOrEmpty(gbxBmpPath))
  3464. {
  3465. MessageBox.Show("图纸文件不存在!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  3466. return;
  3467. }
  3468. AddTextEvent("打开窗口", "4");
  3469. if (!File.Exists(gbxBmpPath + ".jpg"))//转背景后的图纸文件
  3470. {
  3471. AddTextEvent("打开窗口", "5");
  3472. //换背景JPG
  3473. Mat mat = Cv2.ImRead(gbxBmpPath + ".bmp");
  3474. Cv2.CvtColor(mat, mat, ColorConversionCodes.RGB2GRAY);//转灰度图
  3475. for (int i = 0; i < mat.Height; i++)
  3476. {
  3477. for (int j = 0; j < mat.Width; j++)
  3478. {
  3479. if (mat.At<byte>(i, j) == 255)//白色
  3480. mat.Set<byte>(i, j, 0);
  3481. else
  3482. mat.Set<byte>(i, j, 255);
  3483. }
  3484. }
  3485. AddTextEvent("打开窗口", "6");
  3486. //灰转彩
  3487. //Cv2.CvtColor(mat, mat, ColorConversionCodes.GRAY2RGB);
  3488. //for (int i = 0; i < mat.Height; i++)
  3489. //{
  3490. // for (int j = 0; j < mat.Width; j++)
  3491. // {
  3492. // if (mat.At<byte>(i, j) == 255)//白色
  3493. // mat.Set<byte>(i, j, 0); //黄色
  3494. // }
  3495. //}
  3496. OpenCvSharp.Extensions.BitmapConverter.ToBitmap(mat).Save(gbxBmpPath + ".jpg", ImageFormat.Jpeg);
  3497. }
  3498. AddTextEvent("打开窗口", "7");
  3499. //
  3500. ToolStripButton btn = sender as ToolStripButton;
  3501. AddTextEvent("打开窗口", btn.Tag.ToString());
  3502. FrmShowDefectImage frm = new FrmShowDefectImage(gbxBmpPath + ".jpg", order, string.IsNullOrEmpty(btn.Tag.ToString()) ? 0 : Convert.ToInt32(btn.Tag.ToString()));
  3503. frm.Show();
  3504. AddTextEvent("打开窗口", "9");
  3505. }
  3506. catch (Exception ex)
  3507. {
  3508. MessageBox.Show(ex.Message, "异常", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, 0);
  3509. }
  3510. }
  3511. private void tsbtnLog_Click(object sender, EventArgs e)
  3512. {
  3513. if (string.IsNullOrWhiteSpace(Config.LogPath)) return;
  3514. string lsPath = (Config.LogPath + "\\" + DateTime.Now.ToString("yyyyMM") + "\\").Replace("\\\\", "\\");
  3515. if(!Directory.Exists(lsPath))
  3516. Directory.CreateDirectory(lsPath);
  3517. System.Diagnostics.Process.Start("explorer.exe", lsPath);
  3518. }
  3519. }
  3520. }